/* ============================================================
   Movimento — o vocabulário do S-MOV promovido a componente do site.
   Nove padrões, duas curvas, quatro durações (ver design/site-moderno/Movimento.dc.html).
   Toda peça respeita prefers-reduced-motion; sem ponteiro fino, o cursor nativo volta.
   Usa os tokens do site.css (--bg, --fg, --fg-soft, --fg-faint, --line, --rosa, --azul, --roxo).
   ============================================================ */
:root {
  --casa: cubic-bezier(.22,.9,.3,1);
  --mola: cubic-bezier(.34,1.56,.64,1);
  --glow-a: rgba(50,0,120,.18); --glow-b: rgba(202,45,126,.16); --glow-c: rgba(58,82,200,.16);
  --grid-a: rgba(202,45,126,.22); --grid-b: rgba(58,82,200,.22);
  --mx: 0; --my: 0;
}
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) {
  --glow-a: rgba(50,0,120,.55); --glow-b: rgba(202,45,126,.30); --glow-c: rgba(58,82,200,.32);
  --grid-a: rgba(202,45,126,.30); --grid-b: rgba(58,82,200,.32);
}}
:root[data-theme="dark"] {
  --glow-a: rgba(50,0,120,.55); --glow-b: rgba(202,45,126,.30); --glow-c: rgba(58,82,200,.32);
  --grid-a: rgba(202,45,126,.30); --grid-b: rgba(58,82,200,.32);
}

/* ---- rótulo HUD ---- */
.hud { display: inline-flex; align-items: center; gap: .6rem; font: 400 .68rem/1 var(--mono); letter-spacing: .16em; text-transform: uppercase; color: var(--fg-faint); padding: .5rem .7rem; position: relative; }
.hud::before, .hud::after { content: ""; position: absolute; width: 8px; height: 8px; border: 1px solid var(--fg-faint); opacity: .7; }
.hud::before { left: 0; top: 0; border-right: 0; border-bottom: 0; } .hud::after { right: 0; bottom: 0; border-left: 0; border-top: 0; }
.hud i { width: 6px; height: 6px; border-radius: 50%; background: var(--rosa); box-shadow: 0 0 10px var(--rosa); }

/* ---- cursor: ponto + anel que atrasa ---- */
.cur, .cur-anel { position: fixed; left: 0; top: 0; pointer-events: none; z-index: 9000; border-radius: 50%; transform: translate(-50%,-50%); will-change: transform; }
.cur { width: 6px; height: 6px; background: var(--rosa); }
.cur-anel { width: 34px; height: 34px; border: 1px solid var(--rosa); opacity: .7; transition: width .25s var(--casa), height .25s var(--casa), opacity .25s, background .25s; }
html.mao .cur-anel { width: 64px; height: 64px; opacity: .9; background: color-mix(in srgb, var(--rosa) 12%, transparent); }
html.texto .cur-anel { width: 4px; height: 36px; border-radius: 2px; opacity: .5; }
@media (hover: none), (prefers-reduced-motion: reduce) { .cur, .cur-anel { display: none; } }
@media (hover: hover) and (prefers-reduced-motion: no-preference) { body.com-cursor, body.com-cursor a, body.com-cursor button { cursor: none; } }

/* ---- hero em profundidades ---- */
/* ── título em máquina de escrever ──────────────────────────────────────
   Cada caractere entra com um atraso próprio. NÃO usa `.sobe`: lá o degradê
   mora em `.l > span` com `color: transparent`, e um span DENTRO dele herdaria
   a cor transparente sem ter fundo — as letras sumiriam. */
.maquina .mq { opacity: 0; animation: mq-entra .01s linear forwards;
               animation-delay: calc(var(--i) * 26ms); }
@keyframes mq-entra { to { opacity: 1; } }
.maquina .cursor {
  display: inline-block; width: .06em; height: .82em; margin-left: .06em;
  background: var(--rosa); vertical-align: -.06em; opacity: 0;
  /* acende só quando a digitação termina: piscar no fim de um texto ainda
     invisível parece defeito, não cursor */
  animation: mq-entra .01s linear forwards, mq-pisca .9s steps(1) infinite;
  animation-delay: calc(var(--n) * 26ms), calc(var(--n) * 26ms);
}
@keyframes mq-pisca { 50% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  .maquina .mq { opacity: 1; animation: none; }
  .maquina .cursor { display: none; }
}

/* ── carrossel das dores ────────────────────────────────────────────────
   Um cartão por vez, com os outros em `hidden` (do HTML, não display:none em
   CSS) — é o que o leitor de tela precisa para saber o que está fora. Sem JS
   todos aparecem: a página perde a organização e não perde conteúdo. */
.dores { margin: .2rem 0 1.4rem; max-width: 52ch; }
.dores-trilha { list-style: none; margin: 0; padding: 0; min-height: 7.2rem; }
.dor { animation: dor-entra .5s var(--mola, ease) both; }
@keyframes dor-entra { from { opacity: 0; transform: translateY(8px); } }
.dor-titulo {
  margin: 0 0 .45rem; font-weight: 700; font-size: 1.08rem; color: var(--fg);
  letter-spacing: -.015em;
}
.dor-titulo::before { content: "\201C"; }
.dor-titulo::after  { content: "\201D"; }
.dor-sol { margin: 0; font-size: 1rem; color: var(--fg-soft); }
.dor-sol b { color: var(--fg); font-weight: 600; }
.dores-pontos { display: flex; gap: .5rem; margin-top: .9rem; }
.dores-pontos button {
  width: 26px; height: 5px; padding: 0; border: 0; border-radius: 99px;
  background: var(--line); cursor: pointer; transition: background .25s, width .25s;
}
.dores-pontos button[aria-selected="true"] { background: var(--rosa); width: 40px; }
.dores-pontos button:focus-visible { outline: 2px solid var(--rosa-texto); outline-offset: 3px; }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
@media (prefers-reduced-motion: reduce) { .dor { animation: none; } }

/* ── a primeira tela: chamada E faixa, sem rolagem ─────────────────────
   A seção ocupa a altura da janela MENOS a faixa, que fica colada no rodapé
   enquanto a página está no topo. `svh` (small viewport height) e não `vh`:
   no celular o `vh` conta a barra do navegador que some ao rolar, e a faixa
   ficaria fora da tela justamente na abertura.
   ⚠ O padding vinha de um `style=""` inline na <section> e vencia qualquer
   folha — por isso ele saiu do HTML e mora aqui. */
.hero-mov {
  position: relative; overflow: hidden; isolation: isolate;
  /* desconta tambem o cabecalho: sem isso a secao passa por baixo da faixa e o
     navegador ja nasce com barra de rolagem na abertura */
  min-height: calc(100svh - var(--faixa-h, 3.05rem) - var(--topo-h, 3.9rem));
  display: grid; align-items: center;
  padding-block: clamp(1.8rem, 4.5vw, 3.4rem) clamp(1.4rem, 3vw, 2.2rem);
}
/* o título continua grande, mas cabe em 3 linhas na maioria dos monitores */
.hero-mov h1 { font-size: clamp(2.2rem, 4.7vw, 3.7rem); }
.hero-mov .lead { max-width: 52ch; }
@media (max-height: 760px) {
  .hero-mov h1 { font-size: clamp(2rem, 3.9vw, 2.9rem); }
  .hero-mov .lead { font-size: 1rem; }
}
.cena { position: absolute; inset: 0; z-index: -1; pointer-events: none; }
.cena .foto { position: absolute; inset: -4%; width: 108%; height: 108%; object-fit: cover; opacity: .55; mix-blend-mode: screen; transform: translate(calc(var(--mx)*-10px), calc(var(--my)*-10px)); }
:root[data-theme="light"] .cena .foto { opacity: .18; mix-blend-mode: multiply; }
@media (prefers-color-scheme: light) { :root:not([data-theme="dark"]) .cena .foto { opacity: .18; mix-blend-mode: multiply; } }
.aurora { position: absolute; inset: -40%; background: conic-gradient(from 0deg at 50% 50%, var(--glow-a), var(--glow-b), var(--glow-c), var(--glow-a)); filter: blur(90px); opacity: .75; animation: auroraSpin 26s linear infinite; }
@keyframes auroraSpin { to { transform: translate(calc(var(--mx)*-18px), calc(var(--my)*-18px)) rotate(360deg); } }
.piso { position: absolute; left: -20%; right: -20%; bottom: -14%; height: 58%; background-image: linear-gradient(var(--grid-a) 1px, transparent 1px), linear-gradient(90deg, var(--grid-b) 1px, transparent 1px); background-size: 44px 44px; transform: perspective(520px) rotateX(62deg) translateX(calc(var(--mx)*26px)); transform-origin: 50% 0; -webkit-mask-image: linear-gradient(to top, rgba(0,0,0,.85), transparent 85%); mask-image: linear-gradient(to top, rgba(0,0,0,.85), transparent 85%); animation: piso 3.2s linear infinite; }
@keyframes piso { to { background-position: 0 44px, 0 0; } }
.foco { position: absolute; width: 520px; height: 520px; border-radius: 50%; left: var(--px, 50%); top: var(--py, 40%); transform: translate(-50%,-50%); background: radial-gradient(circle, color-mix(in srgb, var(--rosa) 22%, transparent), transparent 62%); filter: blur(30px); transition: left .12s linear, top .12s linear; }
.circuito { position: absolute; inset: 0; width: 100%; height: 100%; opacity: .55; }
.circuito path { fill: none; stroke: var(--azul); stroke-width: 1.2; stroke-linecap: round; stroke-dasharray: 8 180; animation: energia 5.5s linear infinite; }
.circuito path:nth-child(2) { stroke: var(--rosa); animation-delay: -2s; }
@keyframes energia { to { stroke-dashoffset: -376; } }
@media (prefers-reduced-motion: reduce) { .aurora, .piso, .circuito path { animation: none; } .foco { display: none; } }

/* ---- a grade do hero da home ----
   🔴 SITE-2 r2 (29/09): as duas colunas vinham num `style=""` inline, sem ponto de quebra. Em 375 px o
   título ficava espremido em ~190 px («Managemen» cortado) e o sinal S·O·S caía em cima do parágrafo.
   Abaixo de 861 px vira UMA coluna e o sinal desce, menor, depois das chamadas. */
.hero-grade { display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, .75fr); gap: 3rem; align-items: center; }
.hero-glossario { margin: .9rem 0 0; font: 400 .82rem/1.4 var(--mono); }
.hero-glossario a { color: var(--rosa-texto); text-decoration: none; }
.hero-glossario a:hover, .hero-glossario a:focus-visible { text-decoration: underline; }
@media (max-width: 860px) {
  .hero-grade { grid-template-columns: minmax(0, 1fr); gap: 1.4rem; }
  .hero-grade > .sinal { width: min(46vw, 170px); }
}

/* ---- o sinal S·O·S ---- */
.sinal { width: min(100%, 300px); aspect-ratio: 1; display: grid; place-items: center; position: relative; margin-inline: auto; }
.sinal svg { width: 100%; height: 100%; overflow: visible; transform: rotateX(calc(var(--my)*-8deg)) rotateY(calc(var(--mx)*10deg)); transition: transform .2s linear; }
.sinal .p { fill: var(--fg); opacity: .16; transition: opacity .12s; }
.sinal .p.aceso { opacity: 1; fill: url(#gsinal); filter: drop-shadow(0 0 10px var(--rosa)); }

/* ---- título que sobe palavra a palavra ---- */
.sobe .l { display: inline-block; overflow: hidden; vertical-align: bottom; }
.sobe .l > span { display: inline-block; animation: sobe .9s var(--casa) both; animation-delay: calc(var(--i) * 70ms); }
@keyframes sobe { from { transform: translateY(105%); } to { transform: none; } }
@media (prefers-reduced-motion: reduce) { .sobe .l > span { animation: none; } }

/* ---- botão magnético ---- */
.btn.magnet { --tx: 0px; --ty: 0px; transform: translate(var(--tx), var(--ty)); transition: transform .35s var(--mola), background .25s, color .25s, border-color .25s; position: relative; overflow: hidden; }
.btn.magnet::before { content: ""; position: absolute; inset: 0; background: radial-gradient(circle at var(--bx, 50%) var(--by, 50%), rgba(255,255,255,.35), transparent 55%); opacity: 0; transition: opacity .3s; pointer-events: none; }
.btn.magnet:hover::before { opacity: 1; }

/* ---- cartão com holofote ---- */
.holofote { --px: 50%; --py: 50%; --rx: 0deg; --ry: 0deg; position: relative; overflow: hidden; transform: perspective(900px) rotateX(var(--rx)) rotateY(var(--ry)); transition: transform .25s var(--casa), border-color .25s; }
.holofote::before { content: ""; position: absolute; inset: 0; background: radial-gradient(360px circle at var(--px) var(--py), color-mix(in srgb, var(--rosa) 14%, transparent), transparent 55%); opacity: 0; transition: opacity .3s; pointer-events: none; }
.holofote:hover::before { opacity: 1; } .holofote:hover { border-color: color-mix(in srgb, var(--rosa) 55%, var(--line)); }
.holofote > * { position: relative; }

/* ---- faixa em marquee: REMOVIDA em 16/09, e a remoção é a correção ----
   🔴 Este bloco estilizava `.faixa` — e `.faixa` também é o nome da faixa de DESTAQUE
   dentro de cada etapa da esteira (`esteira.css`), usada 30+ vezes nas páginas. Duas
   componentes diferentes com o mesmo nome de classe, uma folha impondo à outra
   `white-space: nowrap`, `overflow: hidden` e `display: inline-flex` com `gap: 3rem`.

   O efeito era o relatado pelo titular com foto: a frase «Sem a credencial de domínio
   no endpoint. A senha é…» sumindo na borda direita. O texto não quebrava linha porque
   herdava o `nowrap` de um MARQUISE, e o corte vinha do `overflow: hidden` dele. Em
   390px o vazamento medido chegava a 1.108px. Nada disso aparece lendo `esteira.css`,
   onde a regra da faixa está correta.

   *Colisão de nome de classe entre componentes não dá erro, não aparece no arquivo que
   se está lendo, e o sintoma sai a três arquivos de distância da causa.*

   O marquise atual é o `.faixa-corre` (padrão 22, mais abaixo), que já tem regra
   própria e nome que não colide. O único HTML que usava o legado foi migrado.
   ⚠ `@keyframes desliza` fica: o `.faixa-corre` usa. */
@keyframes desliza { to { transform: translateX(-50%); } }

/* ---- número com régua ---- */
.num { padding: 1.5rem; border-left: 2px solid var(--rosa); background: var(--bg-inset); }
.num .v { font: 800 clamp(2.6rem, 5vw, 4rem)/1 var(--display); letter-spacing: -.04em; font-variant-numeric: tabular-nums; }
.num .v small { font-size: .45em; color: var(--fg-faint); font-weight: 500; margin-left: .15em; }
.num .o { margin: .6rem 0 .2rem; font-weight: 600; }
.num .regua { margin: 0; font: 400 .8rem/1.5 var(--mono); color: var(--fg-faint); }

/* ---- revelar ao rolar (a base é VISÍVEL; a classe só entra por JS, abaixo da dobra) ---- */
.rev { transition: opacity .8s var(--casa), transform .8s var(--casa); }
.rev.oculto { opacity: 0; transform: translateY(26px); }
@media (prefers-reduced-motion: reduce) { .rev, .rev.oculto { opacity: 1; transform: none; transition: none; } }

/* ════════════════════════════════════════════════════════════════════════════
   S-MOV · padrões 10–13 — o TEXTO se move (referências trazidas pelo titular em
   15/09: lusion.co, eszterbial.com, experience.staratlas.com).

   🔴 A regra do vocabulário não mudou: continuam DUAS curvas e QUATRO durações.
   O que entra aqui é *o que o texto faz*, não um efeito novo por efeito — os três
   sites citados têm em comum uma coisa só, e é esta: **a tipografia é o elemento
   que se move**, não um enfeite ao lado dela.

   ⚠ O que deliberadamente NÃO veio dessas referências, e por quê:
   · WebGL/three.js — o site não tem build nem dependência (README), e o padrão 07
     já provou que holofote e profundidade saem com duas variáveis CSS;
   · rolagem sequestrada (scroll hijacking) — quebra teclado, leitor de tela e o
     "fim da página" que o comprador corporativo usa para achar o preço;
   · preloader com contador 0→100 — é meio segundo cobrado de TODO visitante para
     encobrir carregamento que aqui não existe (HTML estático). Num portfólio ele
     compra expectativa; numa página que precisa vender software, atrasa a frase.
   ════════════════════════════════════════════════════════════════════════════ */

/* ---- 10 · revelação por LINHA, com máscara (eszterbial) ----
   Cada linha sobe de dentro da própria caixa, uma depois da outra. A máscara é o
   `overflow:hidden` do `<span>` externo — o texto não some, ele ENTRA. */
/* ⚠ NÃO é o `.sobe`, e a diferença é de significado: o `.sobe` anima PALAVRA a palavra
   (bom para um título curto, em que cada palavra é um argumento); este anima a LINHA
   inteira como bloco — é o que serve a frase longa, porque a leitura não é interrompida
   no meio dela. Duplicar seria erro; escolher errado, também. */
.linhas { display: block; }
/* 🔴 16/09 · O `padding-bottom` + `margin-bottom` negativo NÃO é gambiarra de alinhamento:
   é o conserto de um corte medido. A máscara que faz a linha «subir» é um `overflow:
   hidden` colado na caixa do texto, e com `line-height` abaixo de 1 — que é o que dá o
   aperto tipográfico dos títulos — a caixa termina ACIMA da descida das letras. O «g» de
   «já», o «q» de «qual» e o «ç» de «devolução» saíam raspados em 2 a 7px.

   *O corte não vem do texto ser grande demais: vem da máscara ser justa demais. E ele é
   pequeno o bastante para nunca aparecer numa conferida — some numa fonte, reaparece em
   outra, e nunca na largura de quem está revisando.*

   O `padding` abre espaço para a descida dentro da máscara; o `margin` negativo devolve
   o espaço ao layout, para o título não passar a ocupar mais altura do que ocupava. */
.linhas > .ln { display: block; overflow: hidden; padding-bottom: .12em; margin-bottom: -.12em; }
.linhas > .ln > i {
  display: block; font-style: inherit;
  transform: translateY(105%);
  transition: transform .9s var(--casa);
  transition-delay: calc(var(--i, 0) * 90ms);   /* stagger: 90 ms entre linhas */
}
.linhas.dentro > .ln > i { transform: translateY(0); }

/* ---- 11 · palavra GIGANTE guiada pela rolagem (staratlas/eszterbial) ----
   A palavra atravessa a tela conforme a página rola. Usa timeline de rolagem
   nativa onde existe; onde não existe, ela simplesmente fica parada e legível —
   o conteúdo nunca depende do efeito. */
.gigante {
  font: 800 clamp(3.2rem, 13vw, 11rem)/.92 var(--display);
  letter-spacing: -.055em; text-transform: uppercase;
  color: transparent; -webkit-text-stroke: 1px var(--line);
  white-space: nowrap; margin: 0; user-select: none;
}
.gigante.cheia { color: var(--fg); -webkit-text-stroke: 0; }
.faixa-gigante { overflow: hidden; padding-block: clamp(1rem, 4vw, 3rem); }
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .faixa-gigante .gigante {
      animation: atravessa linear both;
      animation-timeline: view();
      animation-range: entry 0% exit 100%;
    }
    @keyframes atravessa { from { transform: translateX(8%); } to { transform: translateX(-8%); } }
  }
}

/* ---- 12 · palavra que ACENDE conforme a leitura avança ----
   Um parágrafo-manifesto em que cada palavra ganha cor ao entrar na faixa de
   leitura. Responde à pergunta do vocabulário — *por que isto se move?* — assim:
   o movimento marca ONDE a pessoa está no argumento, e para quando ela para. */
.acende { color: var(--fg-faint); transition: color .25s var(--casa); }
.acende b { font-weight: inherit; color: inherit; transition: color .25s var(--casa); }
.acende b.on { color: var(--fg); }

/* ---- 13 · cifra que CONTA ao aparecer ----
   Só o número anima; a régua ao lado nunca. (Regra da casa: nenhum número de
   escala sem a régua declarada — e régua que se move vira enfeite.) */
.conta { font-variant-numeric: tabular-nums; }
@media (prefers-reduced-motion: reduce) {
  .linhas > .ln > i { transform: none; transition: none; }
  .faixa-gigante .gigante { animation: none; }
}

/* ════════════════════════════════════════════════════════════════════════════
   S-MOV · padrões 14–16 — NADA DE FUNDO SÓLIDO, NENHUM BOTÃO PARADO

   Pedido do titular (15/09): *«nada de fundo sólido e sem movimento, botões sem
   animações; devemos adotar as práticas dos sites que enviei como base»*
   (play.staratlas.com · experience.staratlas.com · eszterbial.com · lusion.co).

   🔴 O que esses sites fazem com o fundo, e que aqui faltava: o fundo **não é uma
   cor**, é uma composição de camadas lentas que nunca chamam o olho. A régra do
   vocabulário continua valendo — a faixa «ambiente» (3,2 s · 5,5 s · 26 s) existe
   justamente para isto: *movimento que a pessoa percebe é movimento que atrapalha
   a leitura*. Nada aqui acelera quando a pessoa está lendo.

   ⚠ Custo declarado: são gradientes com `filter: blur()` em elementos grandes. Para
   não pesar, cada camada é `position:fixed` e única na página (não uma por seção),
   e tudo sai inteiro em `prefers-reduced-motion`.
   ════════════════════════════════════════════════════════════════════════════ */

/* ---- 14 · o FUNDO VIVO da página (uma instância, atrás de tudo) ---- */
.fundo-vivo { position: fixed; inset: 0; z-index: -1; overflow: hidden; pointer-events: none; }
.fundo-vivo::before {           /* aurora cônica, 26 s — a camada mais funda */
  content: ""; position: absolute; inset: -30%;
  background: conic-gradient(from 0deg,
    var(--glow-a), var(--glow-b), var(--glow-c), var(--glow-a));
  filter: blur(90px); opacity: .85;
  animation: fundo-gira 26s linear infinite;
  transform: translate3d(calc(var(--mx, 0) * -18px), calc(var(--my, 0) * -18px), 0);
}
.fundo-vivo::after {            /* grade em perspectiva, 3,2 s — a do login do produto */
  content: ""; position: absolute; left: -20%; right: -20%; bottom: -12%; height: 62%;
  background-image: linear-gradient(var(--grid-a) 1px, transparent 1px),
                    linear-gradient(90deg, var(--grid-b) 1px, transparent 1px);
  background-size: 26px 26px;
  transform: perspective(300px) rotateX(64deg);
  transform-origin: 50% 0;
  animation: fundo-grade 3.2s linear infinite;
  -webkit-mask-image: linear-gradient(to top, #000, transparent 78%);
          mask-image: linear-gradient(to top, #000, transparent 78%);
  opacity: .5;
}
/* a MALHA: o desenho que cresce com a rolagem (ver `scripts/malha.js`).
   Fica ACIMA da aurora e da grade — que são cor — e ABAIXO do piso das seções, que é
   o que garante o contraste do texto. A ordem importa: malha sobre o texto seria um
   enfeite atravessando a leitura. */
.fundo-vivo .malha { position: absolute; inset: 0; display: block; }
@keyframes fundo-gira  { to { transform: rotate(360deg); } }
@keyframes fundo-grade { to { background-position: 0 26px, 0 0; } }

/* A seção deixa de ser um retângulo chapado: ela tem um halo que responde ao
   ponteiro e some nas bordas. É o «holofote» do padrão 07, em escala de seção. */
.secao-viva { position: relative; isolation: isolate; }
.secao-viva::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: radial-gradient(60% 55% at calc(50% + var(--mx, 0) * 40px) calc(35% + var(--my, 0) * 30px),
              var(--glow-b), transparent 68%);
  opacity: .55; transition: opacity .4s var(--casa);
}

/* ---- 15 · BOTÃO VIVO — nenhum botão parado ----
   Três camadas: o brilho que nasce onde o ponteiro está (como o cursor-luz das
   agências), a varredura que atravessa na entrada, e o `--mola` na saída. */
.btn, .prod-aba, .tema-btn { position: relative; overflow: hidden; }
.btn::after, .prod-aba::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(120px 120px at var(--bx, 50%) var(--by, 50%),
              rgba(255,255,255,.28), transparent 60%);
  opacity: 0; transition: opacity .25s var(--casa);
}
.btn:hover::after, .prod-aba:hover::after { opacity: 1; }
.btn::before {                   /* varredura diagonal, só na entrada do ponteiro */
  content: ""; position: absolute; top: 0; bottom: 0; width: 45%;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,.22), transparent);
  transform: translateX(-160%) skewX(-14deg); pointer-events: none;
}
.btn:hover::before { animation: varre .7s var(--casa) 1; }
@keyframes varre { to { transform: translateX(320%) skewX(-14deg); } }
.btn:active { transform: translateY(1px) scale(.99); }

/* ---- 16 · a BORDA que acende ao entrar em vista ----
   Substitui o `border-top` chapado entre seções: a linha desenha da esquerda para a
   direita quando a seção entra. Uma régua que aparece, em vez de uma que já estava. */
.linha-acende { position: relative; }
.linha-acende::after {
  content: ""; position: absolute; left: 0; top: 0; height: 1px; width: 0;
  background: linear-gradient(90deg, var(--rosa), var(--azul), transparent);
  transition: width 1.1s var(--casa);
}
.linha-acende.dentro::after { width: 100%; }

@media (prefers-reduced-motion: reduce) {
  .fundo-vivo::before, .fundo-vivo::after { animation: none; }
  .btn:hover::before { animation: none; }
  .linha-acende::after { transition: none; width: 100%; }
}

/* ---- 🔴 CORREÇÃO: `.titulo-gradiente` + `.sobe` deixava o título INVISÍVEL ----
   Achado em 15/09 ao verificar a home no navegador, e **pré-existente** — provado
   com o código desta sprint removido (`git stash`): a primeira frase do site,
   *«Vinte anos de suporte a quem usa a máquina, num produto só»*, não aparecia.

   A causa é a soma de duas regras que funcionam sozinhas:
   · `.titulo-gradiente` pinta o texto com `background-clip: text` + `color: transparent`;
   · `.sobe` embrulha cada palavra em `.l > span`, e o `.l` tem `overflow: hidden`.

   O `overflow` cria um novo contexto de recorte: o gradiente do `<h1>` não alcança o
   texto dentro do span, e o que sobra é `color: transparent` — texto perfeitamente
   presente no DOM, perfeitamente invisível na tela. Nenhum medidor de contraste pega
   isso (o elemento existe, a cor computada é transparente), e o `tsc`/validador não
   olha pintura: *foi o navegador, e só ele, que mostrou.*

   A correção pinta o gradiente EM CADA palavra. O visual muda um pouco — a rampa
   passa a acontecer por palavra em vez de na frase inteira — e essa é a escolha certa
   entre «ligeiramente diferente» e «não existe». */
.titulo-gradiente.sobe .l > span,
.titulo-gradiente .linhas .ln > i {
  background: linear-gradient(90deg, var(--fg), var(--rosa));
  -webkit-background-clip: text; background-clip: text;
  color: transparent;
}

/* ════════════════════════════════════════════════════════════════════════════
   S-MOV · 05b — o cursor vira SETA, e o círculo sai

   Pedido do titular (15/09): *«deixe o ponteiro do mouse com uma seta realmente
   animada, sem o círculo que aparece ao movimentar o mouse»*.

   O que muda em relação ao padrão 05: o **anel** (`.cur-anel`) deixa de existir, e
   o ponto vira uma **seta** desenhada em SVG que:
   · segue o ponteiro com o mesmo `lerp .35` de antes (o movimento não ficou mais
     lento — mudou a forma, não a física);
   · **inclina na direção em que está indo** — a seta aponta para onde o movimento
     vai, que é a única animação de cursor que carrega informação em vez de enfeite;
   · **cresce e gira levemente** sobre link e botão, no lugar da lavagem que o anel
     fazia;
   · **encolhe** sobre texto, para não tapar a palavra que a pessoa está lendo.

   ⚠ O cursor nativo continua escondido apenas quando o nosso está de fato ativo
   (ponteiro fino, sem redução de movimento) — a classe `com-cursor` já governava
   isso e foi mantida. Em toque, nada disso existe. */
.cur-seta {
  position: fixed; left: 0; top: 0; width: 22px; height: 22px;
  pointer-events: none; z-index: 9001; will-change: transform;
  transform: translate(-50%, -50%);
  transition: opacity .25s var(--casa);
  opacity: 0;               /* SITE-2 r2: invisível até o ponteiro se mexer (movimento.js) */
}
.cur-seta.visivel { opacity: 1; }
.cur-seta svg { display: block; width: 100%; height: 100%; overflow: visible; }
/* 🔴 UMA transformação, no GRUPO. Ver o comentário no `movimento.js`: a lâmina e a
   dobra tinham cada uma o seu `transform` e a sua `transform-origin` (20% 15% contra
   50% 20%), e no `:hover` — que é quando a cor muda — a dobra saía de cima da lâmina.
   O avião virava um triângulo chapado exatamente no estado que mais se vê. */
.cur-seta .aviao {
  transform-origin: 50% 40%;
  transition: transform .22s var(--mola);
}
html.mao .cur-seta .aviao   { transform: scale(1.45) rotate(-12deg); }
html.texto .cur-seta .aviao { transform: scale(.7); }

.cur-seta .lamina {
  fill: var(--rosa);
  stroke: color-mix(in srgb, var(--fg) 45%, transparent);
  stroke-width: .7; stroke-linejoin: round;
  filter: drop-shadow(0 2px 6px rgba(0,0,0,.35));
  transition: fill .2s var(--casa);
}
/* a ASA de baixo: a mesma cor, mais escura — é o que faz o desenho ser lido como PAPEL
   DOBRADO e não como triângulo. Sem ela, o vinco é um risco solto no meio de uma cor
   chapada, e o olho não monta o volume. */
.cur-seta .asa {
  fill: color-mix(in srgb, var(--rosa) 62%, #000);
  stroke: none;
  transition: fill .2s var(--casa);
}
/* sobre link/botão: o avião cresce e inclina — o convite de clique, sem o anel */
html.mao .cur-seta .lamina { fill: var(--azul); }
html.mao .cur-seta .asa    { fill: color-mix(in srgb, var(--azul) 62%, #000); }
/* o rastro: um risco curto atrás da seta, que só aparece em movimento rápido */
.cur-seta .rastro {
  stroke: var(--rosa); stroke-width: 1.6; stroke-linecap: round;
  opacity: 0; transition: opacity .18s var(--casa);
}
.cur-seta.correndo .rastro { opacity: .55; }

/* 🔴 O anel morre aqui: continua no HTML das 33 páginas (removê-lo de todas seria
   33 edições para um elemento invisível), mas não é mais desenhado nem movido. */
.cur-anel { display: none !important; }
.cur { display: none !important; }

@media (hover: none), (prefers-reduced-motion: reduce) { .cur-seta { display: none; } }

/* ════════════════════════════════════════════════════════════════════════════
   S-MOV · 17 — a IMAGEM SURGE (pedido do titular: «as imagens devem ter
   animações de surgimento»)

   Três camadas, e cada uma responde a uma pergunta:
   · **a máscara** — a imagem é revelada por uma cortina que sobe, em vez de
     aparecer pronta. É o mesmo gesto do padrão 10 (linha de texto), então a
     página inteira se move com um vocabulário só;
   · **o zoom lento** — depois de revelada, ela continua respirando (8 s). Sem
     isso, o bloco fica morto ao lado de um fundo que se move;
   · **a inclinação ao ponteiro** — herda o padrão 07 (holofote), 6° no máximo.

   🔴 **O selo «ambientação».** Estas fotos são de ambiente — pessoas, sala,
   contexto — e as telas que aparecem DENTRO delas não são o produto. A regra da
   casa é *toda tela publicada nasce da tela real*, e por isso a área do monitor
   leva um véu de gradiente e a legenda diz o que a foto é. *Foto de ambiente com
   tela inventada, publicada sem aviso, vira "print do produto" na primeira vez
   que alguém recortar a imagem.* */
.amb { position: relative; overflow: hidden; border-radius: 18px; border: 1px solid var(--line); }
.amb img { display: block; width: 100%; height: auto; transform: scale(1.06); transition: transform 1.2s var(--casa); }
.amb::after {                     /* o véu: escurece a metade superior, onde ficam os monitores */
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(8,6,15,.55) 0%, rgba(8,6,15,.12) 42%, transparent 70%),
              radial-gradient(70% 60% at 50% 0%, rgba(202,45,126,.18), transparent 65%);
}

/* ---- 23 · a FOTO no tema escuro ----------------------------------------------
   Pedido do titular (16/09): a imagem deve mudar com o tema. A troca de ARQUIVO está
   armada no `imagens-tema.js` e entra sozinha quando os renders escuros existirem.
   O que funciona HOJE é o tratamento — e ele não é cosmético.

   🔴 As sete fotos são de escritório claro, com janela de dia e teto aceso. Coladas
   numa página de fundo `#08060f` elas viram um retângulo de 1600px de luz no meio da
   leitura: o olho perde a adaptação ao escuro a cada rolagem, e o texto ao redor
   parece apagado sem que nenhum número de contraste mude. *Contraste do texto passa
   na régua; o incômodo vem da foto ao lado dele, que a régua não mede.*

   O véu fecha, a foto perde um pouco de brilho e ganha o violeta da paleta. Ela
   continua legível como ambientação — que é tudo o que ela precisa ser. */
:root[data-theme="dark"] .amb img,
:root:not([data-theme="light"]) .amb img {
  filter: brightness(.74) contrast(1.06) saturate(.92);
}
:root[data-theme="dark"] .amb::after,
:root:not([data-theme="light"]) .amb::after {
  background: linear-gradient(180deg, rgba(8,6,15,.72) 0%, rgba(8,6,15,.34) 45%, rgba(8,6,15,.22) 100%),
              radial-gradient(70% 60% at 50% 0%, rgba(202,45,126,.22), transparent 65%);
}
/* ⚠ Só o `@media` casa com o estado «sem escolha» — o seletor `:not([data-theme="light"])`
   acima cobre isso, mas sem o `@media` ele pegaria também quem está no claro por padrão
   do sistema. A regra de cima vale para a escolha explícita; esta, para o sistema. */
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) .amb img { filter: none; }
  :root:not([data-theme="dark"]) .amb::after {
    background: linear-gradient(180deg, rgba(8,6,15,.55) 0%, rgba(8,6,15,.12) 42%, transparent 70%),
                radial-gradient(70% 60% at 50% 0%, rgba(202,45,126,.18), transparent 65%);
  }
}
.amb .amb-sel {                   /* o selo que diz o que a imagem é */
  position: absolute; left: .8rem; bottom: .8rem; z-index: 2;
  font: 400 .68rem/1 var(--mono, ui-monospace, monospace); letter-spacing: .1em; text-transform: uppercase;
  color: #e9e4f7; background: rgba(8,6,15,.62); border: 1px solid rgba(255,255,255,.18);
  border-radius: 999px; padding: .34rem .7rem; backdrop-filter: blur(6px);
}
/* surgimento: a cortina sobe e a imagem assenta */
.amb { clip-path: inset(0 0 100% 0); transition: clip-path 1.1s var(--casa); }
.amb.dentro { clip-path: inset(0 0 0 0); }
.amb.dentro img { transform: scale(1); }
.amb:hover img { transform: scale(1.04) rotate(.35deg); }

@media (prefers-reduced-motion: reduce) {
  .amb { clip-path: none; transition: none; }
  .amb img { transform: none; transition: none; }
}

/* ---- ✈ o cursor é um AVIÃO DE PAPEL, e o rastro PULSA (pedido do titular, 15/09) ----
   A dobra central é o que faz o desenho ser lido como papel: sem ela, é um triângulo.
   Ela é mais clara que o corpo de propósito — é a luz batendo na quina do papel. */
.cur-seta .dobra {
  stroke: color-mix(in srgb, var(--fg) 75%, transparent);
  stroke-width: 1; stroke-linecap: round; opacity: .85;
  transition: transform .22s var(--mola);
}

/* o rastro: traço pontilhado atrás do avião, que PULSA em vez de só aparecer.
   ⚠ A pulsação é curta (0,9 s) e só existe em movimento: rastro que pulsa com o
   ponteiro parado vira pisca-pisca no canto do olho de quem está lendo. */
.cur-seta .rastro { stroke-dashoffset: 0; }
.cur-seta.correndo .rastro { animation: rastro-pulsa .9s var(--casa) infinite; }
@keyframes rastro-pulsa {
  0%   { opacity: 0;   stroke-dashoffset: 0;  stroke-width: 1.6; }
  35%  { opacity: .65; stroke-width: 2.1; }
  100% { opacity: 0;   stroke-dashoffset: -14; stroke-width: 1.2; }
}

/* ---- FAQ (bloco de objeção + cauda longa de busca) ---- */
.faq-item {
  border: 1px solid var(--line); border-radius: 14px; background: var(--bg-soft);
  margin-bottom: .7rem; overflow: hidden;
  transition: border-color .25s var(--casa), background .25s var(--casa);
}
.faq-item[open] { border-color: var(--rosa); background: var(--bg-inset); }
.faq-item summary {
  cursor: pointer; padding: 1rem 1.1rem; font-weight: 600; list-style: none;
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
}
/* 🔴 DOIS seletores, não um: `::-webkit-details-marker` é o do WebKit antigo e
   `::marker` é o dos navegadores atuais. Com só o primeiro, o triângulo nativo (▼)
   continuava aparecendo ao lado do meu «+» — achado ao abrir a página, não ao ler
   o CSS. E o `display: block` no summary é o que faz o `list-style: none` valer. */
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::marker { content: ""; }
.faq-item summary::after {
  content: "+"; font: 400 1.3rem/1 var(--mono, monospace); color: var(--rosa-texto);
  transition: transform .3s var(--mola);
}
.faq-item[open] summary::after { transform: rotate(45deg); }
.faq-item summary:hover { color: var(--rosa-texto); }
.faq-item p { margin: 0; padding: 0 1.1rem 1.1rem; color: var(--fg-soft); }
.faq-item[open] p { animation: faq-abre .35s var(--casa) both; }
@keyframes faq-abre { from { opacity: 0; transform: translateY(-6px); } }
@media (prefers-reduced-motion: reduce) {
  .cur-seta.correndo .rastro { animation: none; opacity: .5; }
  .faq-item[open] p { animation: none; }
}

/* ════════════════════════════════════════════════════════════════════════════
   S-MOV · 18 — o CARTÃO-HUD: canto chanfrado e borda que acende

   Das quatro referências do titular, o traço de cartão que mais se repete é o do
   `play.staratlas.com`: **canto chanfrado** (o retângulo com um vértice cortado) e
   uma **borda que acende em gradiente** quando o ponteiro chega. É um vocabulário de
   HUD — painel de instrumento —, e ele cai bem aqui porque o produto É um painel de
   operação, não uma página de portfólio.

   Como é feito, e por que assim:
   · o chanfro é `clip-path` numa camada de FUNDO, não no cartão — recortar o cartão
     cortaria o texto na diagonal quando ele fosse longo;
   · a borda em gradiente é uma segunda camada sob a primeira, com 1px de folga: é o
     truque clássico e o único que não exige `background-clip: border-box` (que já
     custou caro nesta casa — ver a correção do título invisível);
   · o brilho segue o ponteiro reaproveitando `--bx/--by`, que o padrão 15 já publica.

   ⚠ Aplicado por classe (`.hud-card`), nunca global: cartão de texto longo continua
   com canto redondo, porque chanfro em bloco de leitura vira enfeite que atrapalha. */
.hud-card { position: relative; isolation: isolate; border: 0; background: transparent; }
.hud-card::before,          /* a borda em gradiente (camada de baixo) */
.hud-card::after {          /* o preenchimento (camada de cima, 1px menor) */
  content: ""; position: absolute; inset: 0; z-index: -1;
  clip-path: polygon(0 0, calc(100% - 18px) 0, 100% 18px, 100% 100%, 18px 100%, 0 calc(100% - 18px));
}
.hud-card::before {
  background: linear-gradient(135deg, var(--line), var(--line));
  transition: background .35s var(--casa);
}
.hud-card::after { inset: 1px; background: var(--bg-soft); }
.hud-card:hover::before {
  background: linear-gradient(135deg, var(--rosa), var(--azul) 55%, var(--roxo, var(--rosa)));
}
/* o brilho do ponteiro, reaproveitando as variáveis do padrão 15 */
.hud-card:hover::after {
  background:
    radial-gradient(240px 240px at var(--bx, 50%) var(--by, 50%), rgba(202,45,126,.14), transparent 62%),
    var(--bg-inset);
}
.hud-card { transition: transform .4s var(--casa); }
.hud-card:hover { transform: translateY(-3px); }

/* a etiqueta monoespaçada do HUD — o rótulo curto que o Star Atlas usa no canto */
.hud-tag {
  display: inline-flex; align-items: center; gap: .4rem; margin-bottom: .6rem;
  font: 400 .66rem/1 var(--mono, ui-monospace, monospace); letter-spacing: .14em;
  text-transform: uppercase; color: var(--fg-faint);
}
.hud-tag::before { content: ""; width: 5px; height: 5px; border-radius: 50%; background: var(--rosa); }
.hud-card:hover .hud-tag { color: var(--rosa-texto); }

@media (prefers-reduced-motion: reduce) { .hud-card:hover { transform: none; } }

/* ════════════════════════════════════════════════════════════════════════════
   S-MOV · 19–21 — ONDE EU ESTOU: o menu marca a seção, o logo vive, a rolagem tem régua

   Pedido do titular (15/09): *«o marcador no menu de navegação não existe para
   demonstrar em qual seção está da página, e o ITSOS deve ter animações, e os
   marcadores de rolagem devem ser modernos»*.

   🔴 Os três respondem à MESMA pergunta — *onde eu estou nesta página?* — e é por
   isso que entram juntos: uma página longa sem resposta a essa pergunta é uma
   página em que a pessoa rola até cansar. Nas quatro referências do titular, essa
   resposta está sempre visível, e nunca como uma barra de rolagem do sistema.
   ════════════════════════════════════════════════════════════════════════════ */

/* ---- 19 · o MENU marca a seção (scroll spy) ----
   A marca é uma linha que desliza sob o item, não uma cor trocada: a cor sozinha
   compete com o `aria-current` da página ativa e as duas viram a mesma coisa. */
.topbar .nav { position: relative; }
.topbar .nav a { position: relative; }
.topbar .nav a::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -4px; height: 2px;
  background: linear-gradient(90deg, var(--rosa), var(--azul));
  border-radius: 2px; transform: scaleX(0); transform-origin: left;
  transition: transform .4s var(--casa);
}
.topbar .nav a:hover::after { transform: scaleX(1); }
.topbar .nav a.aqui { color: var(--fg); }
.topbar .nav a.aqui::after { transform: scaleX(1); }

/* ---- 20 · o LOGO vive ----
   O ponto do «O» pulsa na cadência do sinal (a mesma do padrão 04) e as letras
   respondem ao ponteiro. ⚠ A pulsação é lenta e de baixa amplitude de propósito:
   logo que pisca forte no topo de uma página de leitura é o oposto de marca. */
/* A folga entre o simbolo e o logotipo e a MARGEM do simbolo, nao o `gap`.
   O texto solto «IT» e um item de flex, entao o `gap` separaria IT de SOS tambem
   — e esse .1em e justamente o respiro entre as duas metades do logotipo.
   ⚠ Este arquivo carrega DEPOIS do site.css e vence o que estiver la: foi por isso
   que dois ajustes de folga feitos no site.css nao surtiram efeito nenhum. */
.brand { position: relative; display: inline-flex; align-items: center; gap: .1em; }
.brand-sos { margin-right: .7em; }
.brand span { position: relative; display: inline-block; transition: transform .5s var(--mola); }
.brand:hover span { transform: translateY(-2px) rotate(-3deg); }
.brand::after {
  content: ""; position: absolute; right: -10px; top: 50%; width: 6px; height: 6px;
  border-radius: 50%; background: var(--rosa); transform: translateY(-50%);
  animation: brand-pulsa 3.4s var(--casa) infinite;
}
@keyframes brand-pulsa {
  0%, 62%, 100% { opacity: .35; box-shadow: 0 0 0 0 rgba(202,45,126,0); }
  70%           { opacity: 1;   box-shadow: 0 0 0 4px rgba(202,45,126,.22); }
  78%           { opacity: .35; box-shadow: 0 0 0 0 rgba(202,45,126,0); }
  86%           { opacity: 1;   box-shadow: 0 0 0 4px rgba(202,45,126,.22); }
}

/* ---- 21 · a RÉGUA de rolagem ----
   Duas peças: a barra fina de progresso no topo, e os pontos de seção à direita,
   que dizem quantas seções faltam — informação que a barra sozinha não dá. */
.regua-topo {
  position: fixed; left: 0; top: 0; height: 2px; z-index: 9002;
  width: var(--lido, 0%); background: linear-gradient(90deg, var(--rosa), var(--azul));
  transition: width .1s linear; pointer-events: none;
}
.regua-pontos {
  position: fixed; right: 14px; top: 50%; transform: translateY(-50%);
  display: flex; flex-direction: column; gap: 10px; z-index: 9002;
}
.regua-pontos button {
  width: 9px; height: 9px; padding: 0; border-radius: 50%; cursor: pointer;
  border: 1px solid var(--fg-faint); background: transparent;
  transition: transform .3s var(--mola), background .3s var(--casa), border-color .3s var(--casa);
}
.regua-pontos button:hover { transform: scale(1.35); border-color: var(--rosa); }
.regua-pontos button.aqui { background: var(--rosa); border-color: var(--rosa); transform: scale(1.25); }
.regua-pontos button:focus-visible { outline: 2px solid var(--rosa); outline-offset: 3px; }
/* ⚠ Some em tela estreita: 12 pontos numa lateral de celular tapam o conteúdo. */
@media (max-width: 900px) { .regua-pontos { display: none; } }

/* a barra de rolagem do sistema, alinhada ao tema (Firefox + WebKit) */
html { scrollbar-width: thin; scrollbar-color: var(--rosa) transparent; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: linear-gradient(180deg, var(--rosa), var(--azul));
  border-radius: 999px; border: 3px solid var(--bg);
}
::-webkit-scrollbar-thumb:hover { background: var(--rosa); }

@media (prefers-reduced-motion: reduce) {
  .brand::after { animation: none; opacity: .6; }
  .regua-topo { transition: none; }
}

/* ---- 22 · a FAIXA QUE CORRE (funcionalidades embarcadas) ----
   Pedido do titular (15/09): a linha que anda da direita para a esquerda com os
   recursos do produto. ⚠ Ela existia no CSS e no protótipo e **nunca tinha entrado
   nas páginas** — não foi removida, foi esquecida na passagem de um para o outro.

   Três decisões:
   · **pausa no hover** — texto que corre e não pode ser lido é ruído, e alguém vai
     querer ler um item específico;
   · **máscara nas pontas** — o texto nasce e morre em fade, em vez de ser cortado
     na borda, que é o que denuncia um marquee mal feito;
   · **`aria-hidden` no trilho** e rótulo na caixa — senão o leitor de tela lê os
     vinte itens duas vezes (o trilho é duplicado por construção). */
.faixa-corre {
  overflow: hidden; padding: .9rem 0; margin: 2rem 0;
  border-block: 1px solid var(--line); background: var(--bg-inset);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.faixa-corre .trilho {
  display: flex; width: max-content; gap: 2.4rem;
  animation: corre 46s linear infinite;
}
.faixa-corre:hover .trilho { animation-play-state: paused; }

/* ── a faixa como RODAPE INICIAL ────────────────────────────────────────
   Ela nascia no fluxo, logo abaixo da dobra: em monitor alto o visitante so a
   via se rolasse — e ela e a lista do que o produto faz. Enquanto a pagina esta
   no topo ela fica colada no fim da tela; ao primeiro scroll, solta e volta ao
   fluxo. O irmao seguinte recebe a altura dela para a soltura nao dar salto. */
:root { --faixa-h: 3.05rem; }
html.faixa-fixa .faixa-corre.faixa-inicial {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40; margin: 0;
  backdrop-filter: blur(6px);
}
html.faixa-fixa .faixa-corre.faixa-inicial + * { margin-top: var(--faixa-h); }

/* os termos viraram atalho: precisam de alvo de clique, foco visivel e hover */
.faixa-corre a {
  display: inline-flex; align-items: center; white-space: nowrap;
  font: 500 .92rem/1 var(--texto); color: var(--fg-soft);
  text-decoration: none; padding: .35rem .1rem; border-radius: .4rem;
  transition: color .18s;
}
.faixa-corre a:hover { color: var(--fg); text-decoration: underline; }
.faixa-corre a:focus-visible { outline: 2px solid var(--rosa-texto); outline-offset: 3px; }
.faixa-corre .trilho-copia { display: inline-flex; align-items: center; gap: 2.4rem; }
/* o trilho pausa no hover; com foco de teclado tambem, senao o atalho foge do dedo */
.faixa-corre:focus-within .trilho { animation-play-state: paused; }
.faixa-corre span {
  display: inline-flex; align-items: center; gap: 2.4rem; white-space: nowrap;
  font: 500 .92rem/1 var(--texto); color: var(--fg-soft);
}
.faixa-corre span::after { content: "◆"; font-size: .5rem; color: var(--rosa-texto); }
@keyframes corre { to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) {
  .faixa-corre .trilho { animation: none; flex-wrap: wrap; width: auto; }
  .faixa-corre { -webkit-mask-image: none; mask-image: none; }
}

/* ---- 🔴 CORREÇÃO DE CONTRASTE: a seção precisa de chão próprio ----
   Achado pelo `medir-contraste.py` em 15/09: **59 textos abaixo do mínimo da WCAG**
   nos dois temas, com razões de até 1,05 — texto praticamente invisível.

   A causa é o padrão 14 que eu mesmo criei: o `.fundo-vivo` é `position: fixed` e
   fica ATRÁS do body; como as seções não tinham fundo próprio, o texto caía direto
   sobre a aurora animada. Contraste sobre fundo que se move não é um número — é uma
   faixa, e o pior ponto dela é o que vale.

   A correção não é escurecer texto por texto: é dar CHÃO à seção. O fundo continua
   vivo e visível nas bordas e entre blocos; sob a leitura, ele fica atrás de uma
   camada opaca o bastante para o contraste ser previsível.

   ⚠ 80%, e o número foi MEDIDO, não escolhido. Com o texto escondido e a animação
   congelada, comparei a mesma faixa da página com e sem o `.fundo-vivo`: a 92% o fundo
   animado alterava no máximo 3–4 de 255 por canal atrás do texto — ou seja, o efeito
   pelo qual se paga CPU era invisível justamente onde a página é lida. A 50% chega a
   27/255, que já desloca a razão. A 80% o desvio é ≤10/255 e o fundo aparece.
   *Opacidade escolhida no olho vira 92% «por segurança» e mata o recurso inteiro.*

   ⚠ E a régua que aprovou isso NÃO foi o `medir-contraste.py`: ele compõe a cadeia de
   ancestrais, e o `.fundo-vivo` é `fixed`, fora da árvore — ele é cego para este fundo.
   Varrer o piso de 92% a 68% dava 0 falhas em todos, o que parecia aprovação e era
   silêncio. Quem respondeu foi a comparação por pixel, com controle sem o fundo.

   🔴 16/09 · A PRIMEIRA versão disto era `main > section::after`, e ela NUNCA pegou.
   `.linha-acende::after` — a borda que acende, logo acima nesta folha — tem
   especificidade (0,1,1) contra os (0,0,3) do seletor de tipo. A classe vence, e o
   piso perdia em silêncio em quase toda seção da página. Pior: o `opacity: .92` não
   é propriedade de fundo, então ele *vazava* para a regra vencedora e apagava a
   linha decorativa — a correção estava produzindo um segundo defeito.
   *Pseudo-elemento é recurso único por elemento: quem escreve `::after` sem procurar
   o `::after` que já existe não está acrescentando camada, está disputando uma.*

   A versão atual não disputa nada: o chão é o `background` da PRÓPRIA seção. Ela é
   estática no fluxo, a arte do fundo é `fixed` em `z-index: -1`, e por isso a cor da
   seção pinta por cima da arte sem precisar de camada nenhuma. */
main > section {
  position: relative;
  background: color-mix(in srgb, var(--bg) 80%, transparent);
}
/* a capa é a exceção declarada: ela É o fundo, e o texto dela nasce sobre a arte
   com contraste próprio (medido à parte na `capa`). */
main > section.hero-mov, main > section:has(.capa) { background: transparent; }

/* ---- 24 · O NOME: o sinal em Morse desenhado na grade 3×3 --------------------
   Pedido do titular (16/09): o significado do nome não estava em lugar nenhum do
   repositório, e o sinal do logotipo piscava há semanas sem que a página dissesse o
   que ele era.

   A grade É o desenho: três pontos, três traços, três pontos. O traço do meio é o
   mais longo porque é «a linha que liga» — e isso não é licença gráfica, é o que o
   titular definiu. O pulso segue a cadência real do Morse (ponto 1 unidade, traço 3),
   e não uma animação genérica: *marca cuja animação não respeita o próprio código que
   ela desenha é decoração com cara de significado.* */
.nome-sinal {
  display: grid; grid-template-columns: auto 1fr; gap: clamp(1.2rem, 3vw, 2.2rem);
  align-items: center; margin-block: 1.6rem;
  padding: clamp(1rem, 2.4vw, 1.6rem);
  border: 1px solid var(--line); border-radius: 18px; background: var(--bg-soft);
}
@media (max-width: 620px) { .nome-sinal { grid-template-columns: 1fr; } }
.nome-morse {
  /* ⚠ coluna FIXA em 46px, não `1fr`. Com `1fr` a largura da coluna sai do conteúdo, e o
     traço do meio (40px, o mais largo) esticava a coluna central: o desenho deixava de ser
     uma grade 3×3 regular e os traços encostavam nos vizinhos. Grade cujo espaçamento
     depende do que está dentro dela não é grade. */
  display: grid; grid-template-columns: repeat(3, 46px); gap: .55rem .3rem;
  place-items: center; flex: none;
}
.nome-morse .mp { width: 12px; height: 12px; border-radius: 50%; background: var(--rosa); }
.nome-morse .mt { width: 30px; height: 6px;  border-radius: 3px;  background: var(--roxo); }
/* ⚠ o traço do meio escapa da célula de propósito — é a linha que liga */
.nome-morse .mt.longo { width: 40px; background: var(--rosa); }
.nome-morse .mp, .nome-morse .mt { animation: morsePulsa 5.4s var(--casa) infinite; }
.nome-morse > :nth-child(1) { animation-delay: 0s; }
.nome-morse > :nth-child(2) { animation-delay: .34s; }
.nome-morse > :nth-child(3) { animation-delay: .68s; }
.nome-morse > :nth-child(4) { animation-delay: 1.19s; }
.nome-morse > :nth-child(5) { animation-delay: 1.87s; }
.nome-morse > :nth-child(6) { animation-delay: 2.55s; }
.nome-morse > :nth-child(7) { animation-delay: 3.23s; }
.nome-morse > :nth-child(8) { animation-delay: 3.57s; }
.nome-morse > :nth-child(9) { animation-delay: 3.91s; }
@keyframes morsePulsa {
  0%, 4%   { opacity: .28; transform: scale(.9); }
  6%, 11%  { opacity: 1;   transform: scale(1.12); }
  16%,100% { opacity: .28; transform: scale(.9); }
}
/* 🔴 «no arquivo estático, um ponto fica aceso» — o titular definiu o estado parado, e
   ele vale exatamente aqui: sem animação, a marca não pode virar nove pontos apagados. */
@media (prefers-reduced-motion: reduce) {
  .nome-morse .mp, .nome-morse .mt { animation: none; opacity: .32; }
  .nome-morse > :nth-child(1) { opacity: 1; }
}

/* ---- vidro fosco em todas as páginas ----
   18/09 · pedido do titular: primeiro só nas abas do portfólio da home, depois na página
   do InvenTI, agora no site inteiro. Os cartões trocam o fundo sólido por translúcido +
   desfoque. O desfoque só aparece porque há algo atrás: o `.fundo-vivo` (aurora + grade)
   que este arquivo injeta em toda página — e toda página carrega este arquivo.
   O prefixo `body` existe só por especificidade: vence a regra-base de cada componente
   (em site.css, formulario.css, planilha.css), carregue ela antes ou depois desta.
   ⚠ Fora de propósito: campos de formulário, menus e botões. Campo translúcido perde
   contraste de leitura, e é onde o visitante digita. */
body .card,
body .resolve-item,
body .faq-item,
body .limits,
body .canal,
body .nome-sinal,
body .campos,
body .numero {
  background: color-mix(in srgb, var(--bg-soft) 58%, transparent);
  border-color: color-mix(in srgb, var(--fg) 14%, transparent);
  backdrop-filter: blur(16px) saturate(160%);
  -webkit-backdrop-filter: blur(16px) saturate(160%);
  box-shadow: var(--sombra);
}
/* blocos de destaque com borda lateral rosa: translúcidos, sem perder a borda */
body .num,
body .sla,
body .raro-prova {
  background: color-mix(in srgb, var(--bg-inset) 62%, transparent);
  backdrop-filter: blur(14px) saturate(150%);
  -webkit-backdrop-filter: blur(14px) saturate(150%);
}
body .faq-item[open],
body .resolve-item:hover,
body .resolve-item.destaque,
body .canal:hover {
  background: color-mix(in srgb, var(--bg-inset) 72%, transparent);
  border-color: var(--rosa);
}
body .numero.destaque { border-color: var(--accent); }
/* hud-card: o preenchimento é o ::after (a borda em gradiente é o ::before, 1px maior) */
body .hud-card::after {
  background: color-mix(in srgb, var(--bg-soft) 58%, transparent);
  backdrop-filter: blur(16px) saturate(160%);
  -webkit-backdrop-filter: blur(16px) saturate(160%);
}
body .hud-card:hover::after {
  background:
    radial-gradient(240px 240px at var(--bx, 50%) var(--by, 50%), rgba(202,45,126,.14), transparent 62%),
    color-mix(in srgb, var(--bg-inset) 72%, transparent);
}
body .hud-card::before {
  background: linear-gradient(135deg, color-mix(in srgb, var(--fg) 22%, transparent), color-mix(in srgb, var(--fg) 8%, transparent));
}
body .hud-card:hover::before {
  background: linear-gradient(135deg, var(--rosa), var(--azul) 55%, var(--roxo, var(--rosa)));
}
/* o palco da esteira mantém as manchas de cor, mas sobre uma base translúcida */
body .esteira-palco {
  background:
    radial-gradient(64rem 26rem at 12% -20%, color-mix(in srgb, var(--roxo) 34%, transparent), transparent 70%),
    radial-gradient(48rem 24rem at 92% 120%, color-mix(in srgb, var(--rosa) 22%, transparent), transparent 68%),
    color-mix(in srgb, var(--bg-soft) 55%, transparent);
  border-color: color-mix(in srgb, var(--fg) 14%, transparent);
  backdrop-filter: blur(18px) saturate(160%);
  -webkit-backdrop-filter: blur(18px) saturate(160%);
}
