/* ==========================================================================
   NEXUS theme-final / 04-sections.css
   Só o que é transversal a mais de uma seção. Layout específico de uma
   seção vive em assets/css/sections/<id>.css (território de outros agentes).

   .section, .section--tight, .section__head, .section__head--center e
   .eyebrow de base já existem em 02-base.css (§5 desse arquivo) e não são
   redefinidos aqui, só estendidos: .section--flush, variantes extras de
   .section__head e o restante da lista do contrato (.rail, .stat,
   .stat-rail, .media-frame, .prose, divisor de seção).

   Só consome tokens de 01-tokens.css. Nenhum hex, nenhum px de raio,
   nenhuma família de fonte literal. Motion: só transform e opacity; duração
   multiplicada por var(--motion); marquee pausa via @container style
   (--motion: 0), no mesmo espírito do body::before de 02-base.css.

   Índice:
   1. Seção: complemento de ritmo (.section--flush, .section--band)
   2. Cabeçalho de seção: variantes extras de alinhamento
   3. Rail (marquee horizontal)
   4. Régua de provas (.stat, .stat-rail)
   5. Moldura de mídia (.media-frame)
   6. Prosa (.prose)
   7. Divisor de seção (linha luminosa horizontal)
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Seção: complemento de ritmo
   -------------------------------------------------------------------------- */

/* Seção sem respiro próprio: usada quando o conteúdo interno já traz seu
   padding (ex.: um media-frame de borda a borda) ou quando duas seções
   precisam ficar coladas por decisão de design. */
.section--flush {
  padding-block: 0;
}

/* Alterna a superfície de fundo entre seções vizinhas sem que uma precise
   conhecer a outra: ritmo vertical resolvido por classe, não por seletor
   de irmão. Opcional, aplicado seção a seção pelo partial. */
.section--band {
  background-color: hsl(var(--surface-2) / 0.6);
}

/* --------------------------------------------------------------------------
   2. Cabeçalho de seção: variantes extras de alinhamento
   .section__head e .section__head--center já vivem em 02-base.css.
   -------------------------------------------------------------------------- */

.section__head--end {
  margin-inline-start: auto;
  justify-items: end;
  text-align: end;
}

/* título e lead à esquerda, ação (link ou botão) à direita, na mesma linha
   quando cabe; empilha em telas estreitas porque é flex-wrap, não grid de
   colunas fixas */
.section__head--split {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-6);
  max-width: none;
}

/* Mesma medida de `.section__head` (02-base.css) e mesmo motivo (item
   "título de seção apertado", 06/08/2026): o filho direto aqui é o `<div>`
   que empacota eyebrow/h2/lead (portfolio.js, govtech.js — nenhum dos dois
   põe o `<h2>` como filho direto de `.section__head--split`), então
   estreitar ESTE `max-width` estreitava o título por tabela, mesmo ele
   nunca tendo medida própria. `.lead` continua com a própria largura de
   leitura de sempre — regra dele mesmo (02-base.css, `.lead{max-width:var(
   --measure)}`), independente da largura do pai, então widen aqui não
   estica parágrafo nenhum.

   `flex-basis` além de `max-width` (medido: só o `max-width` não bastou).
   O `<div>` é item de um FLEX container (`.section__head--split`), não
   fica em fluxo de bloco normal — item flex sem `flex-grow`/`flex-basis`
   próprios usa `flex-basis: auto`, que "abraça" o CONTEÚDO (shrink-to-fit)
   em vez de encher o espaço disponível como um bloco faria. Na prática o
   `<div>` nunca crescia até o teto novo: ficava do tamanho que o `.lead`
   (limitado a `--measure` por conta própria) já preenchia, sem nunca pedir
   os 44rem extras. `flex-basis` no mesmo valor do `max-width` faz o
   tamanho PREFERIDO do item já nascer no teto (não mais "o que o conteúdo
   pedir"), e `flex-grow` fica de fora de propósito — não é para crescer
   além do teto se sobrar espaço, e não deve competir por espaço com um
   eventual segundo filho (a "ação à direita" que dá nome à variante). */
.section__head--split > * {
  flex: 0 1 min(100%, 44rem);
  max-width: min(100%, 44rem);
}

/* --------------------------------------------------------------------------
   3. Rail: marquee horizontal infinito
   Estrutura esperada:
   <div class="rail"><div class="rail__track">…itens, já duplicados por
   JS para o loop ficar contínuo…</div></div>
   -------------------------------------------------------------------------- */

.rail {
  position: relative;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(
    to right,
    transparent,
    black var(--rail-fade, 6%),
    black calc(100% - var(--rail-fade, 6%)),
    transparent
  );
  mask-image: linear-gradient(
    to right,
    transparent,
    black var(--rail-fade, 6%),
    black calc(100% - var(--rail-fade, 6%)),
    transparent
  );
}

.rail__track {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  inline-size: max-content;
  animation: nx-marquee var(--rail-dur, 34s) linear infinite;
}

.rail__item {
  flex: none;
}

.rail:hover .rail__track,
.rail:focus-within .rail__track {
  animation-play-state: paused;
}

/* pausa também quando o estúdio desliga o motion, mesma técnica de
   @container style(...) usada em 01-tokens.css para os padrões de fundo */
@container style(--motion: 0) {
  .rail__track {
    animation-play-state: paused;
  }
}

@keyframes nx-marquee {
  from {
    transform: translate3d(0, 0, 0);
  }
  to {
    transform: translate3d(-50%, 0, 0);
  }
}

/* --------------------------------------------------------------------------
   4. Régua de provas (.stat, .stat-rail)
   Reaproveitada em mais de um lugar: provas (seção 3) e onde mais precisar
   de números em linha.
   -------------------------------------------------------------------------- */

.stat {
  display: grid;
  gap: var(--space-1);
}

.stat__value {
  display: inline-flex;
  align-items: baseline;
  gap: var(--space-1);
  font-family: var(--font-display);
  font-size: var(--fs-h2);
  font-weight: 700;
  line-height: 1;
  letter-spacing: var(--tracking-display);
  color: hsl(var(--foreground));
  font-variant-numeric: tabular-nums;
}

.stat__unit {
  font-size: var(--fs-lead);
  font-weight: 600;
  color: hsl(var(--primary));
}

.stat__label {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: var(--tracking-mono);
  text-transform: uppercase;
  color: hsl(var(--muted-foreground));
}

.stat-rail {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 160px), 1fr));
  gap: var(--space-6);
  padding-block: var(--space-8);
  border-block: var(--hairline) solid hsl(var(--border));
}

.stat-rail .stat {
  padding-inline-start: var(--space-6);
  border-inline-start: var(--hairline) solid hsl(var(--border));
}

.stat-rail .stat:first-child {
  padding-inline-start: 0;
  border-inline-start: 0;
}

/* colunas viram linha única por item quando a tela é estreita: a borda
   lateral deixaria de fazer sentido, então vira borda superior */
@media (max-width: 480px) {
  .stat-rail {
    grid-template-columns: 1fr;
  }

  .stat-rail .stat {
    padding-inline-start: 0;
    border-inline-start: 0;
    padding-block-start: var(--space-4);
    border-block-start: var(--hairline) solid hsl(var(--border));
  }

  .stat-rail .stat:first-child {
    padding-block-start: 0;
    border-block-start: 0;
  }
}

/* §7.2 do contrato: paisagem com altura curta colapsa a régua para duas
   colunas, para não empurrar a dobra */
@media (max-height: 700px) and (orientation: landscape) {
  .stat-rail {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* --------------------------------------------------------------------------
   5. Moldura de mídia
   Aspect-ratio previsível para imagem e vídeo, sem salto de layout, com
   máscara de gradiente sutil nas bordas. --media-ratio é sobrescrito pelas
   variantes ou por style inline quando a mídia tem proporção própria.
   -------------------------------------------------------------------------- */

.media-frame {
  position: relative;
  overflow: hidden;
  aspect-ratio: var(--media-ratio, 16 / 10);
  border-radius: var(--radius-lg);
  border: var(--hairline) solid hsl(var(--border));
  background-color: hsl(var(--muted));
}

.media-frame img,
.media-frame video,
.media-frame picture,
.media-frame canvas {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  /* `border-radius: inherit` (06/08/2026, item 1 da rodada: "borda vazando
     nas imagens, de novo" — o defeito já tinha sido apontado e voltou).
     CAUSA, na CAMADA COMPARTILHADA em vez de cartão a cartão desta vez:
     `.media-frame` recorta com `overflow: hidden` + `border-radius` (acima),
     mas qualquer filho que ganhe `transform` próprio (paralaxe, crossfade,
     hover-zoom, scale de estado ativo — todos passam por
     `.media-frame img/video`) é promovido a uma CAMADA DE COMPOSIÇÃO própria
     (GPU); alguns motores (Safari/WebKit em especial) clipam essa camada ao
     RETÂNGULO do elemento, não à forma arredondada do ancestral — a faixa
     fina que escapa é literalmente o canto QUADRADO da camada composta
     assomando por trás do canto ARREDONDADO que o `overflow` do pai deveria
     recortar. Já tinha sido corrigido cartão a cartão (`.case-block__shot`
     ganhou `border-radius: inherit` sozinho, achado de 06/08/2026) — por
     isso "voltou": a mesma causa se repete em QUALQUER `.media-frame`
     arredondado cujo filho ganhe transform, e cartão a cartão nunca cobre o
     próximo caso. Correção não depende do motor acertar o clip do pai: dá à
     PRÓPRIA imagem/vídeo o raio do PAI IMEDIATO (`inherit` — cada
     `.media-frame` já declara o raio que quer, `var(--radius-lg)` por
     padrão ou `0` onde a pele pede quadro reto, como `.portfolio__card-media`
     — `inherit` acompanha esse valor local sem precisar repetir token
     nenhum aqui). Mesmo clipada ao retângulo dela mesma, a forma já nasce
     arredondada — não sobra canto quadrado para vazar, em nenhum
     `.media-frame` do site, com ou sem transform. */
  border-radius: inherit;
}

/* Véu de legibilidade. Usa --scrim (tinta escura nos dois temas), nunca
   --background: no tema claro --background é quase branco e o véu clareava
   a foto em vez de assentá-la, derrubando o contraste de qualquer texto
   posto por cima para baixo de AA (§8). Com --scrim o gradiente escurece
   igual nos dois temas e o texto sobre mídia usa --scrim-foreground. */
.media-frame::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(to top, hsl(var(--scrim) / 0.55), transparent 32%),
    linear-gradient(to bottom, hsl(var(--scrim) / 0.22), transparent 22%);
  opacity: var(--media-mask-opacity, 1);
}

.media-frame--square {
  --media-ratio: 1 / 1;
}

.media-frame--portrait {
  --media-ratio: 4 / 5;
}

.media-frame--wide {
  --media-ratio: 21 / 9;
}

.media-frame--no-mask::after {
  display: none;
}

/* mix-blend-mode: screen é o único efeito de vídeo permitido pelo §6 do
   contrato, além de reveal/marquee/parallax controlado. Só que "screen"
   mistura o vídeo com o que estiver ATRÁS dele: no tema claro o fundo da
   página tem 99% de luminosidade e o vídeo simplesmente apagava, deixando
   uma caixa vazia na dobra.
   Correção: a moldura vira um grupo de isolamento com fundo próprio de
   tinta escura (--scrim). O "screen" passa a acontecer contra esse fundo
   local, e não contra a página, então o efeito fica idêntico e estável nos
   dois temas, sem tocar em nenhum partial e sem trocar o modo de mistura. */
.media-frame--blend {
  isolation: isolate;
  background-color: hsl(var(--scrim));
}

.media-frame--blend video {
  mix-blend-mode: screen;
}

/* Rede de segurança do §7.1 (nada de caixa cinza vazia na dobra): o "screen"
   só é seguro porque existe o grupo de isolamento acima. Onde o motor não
   souber isolar, o blend é desligado por completo e o vídeo aparece como
   vídeo. Antes cair no vídeo cru do que repetir o defeito de o vídeo sumir
   no tema claro. */
@supports not (isolation: isolate) {
  .media-frame--blend video {
    mix-blend-mode: normal;
  }
}

/* --------------------------------------------------------------------------
   6. Prosa
   Blocos de texto longo (depoimento estendido, ressalva institucional,
   resposta de due diligence) com medida máxima de 68ch.
   -------------------------------------------------------------------------- */

.prose {
  display: grid;
  gap: var(--space-5);
  max-width: var(--measure);
  color: hsl(var(--foreground));
  font-size: var(--fs-base);
  line-height: var(--lh-body);
}

.prose h2,
.prose h3,
.prose h4 {
  color: hsl(var(--foreground));
}

.prose h2 {
  font-size: var(--fs-h3);
}

.prose h3 {
  font-size: var(--fs-lead);
}

.prose p {
  color: hsl(var(--muted-foreground));
}

.prose strong {
  color: hsl(var(--foreground));
  font-weight: 650;
}

.prose a {
  color: hsl(var(--primary));
  text-underline-offset: 0.22em;
}

.prose ul,
.prose ol {
  display: grid;
  gap: var(--space-2);
  padding-inline-start: var(--space-6);
  color: hsl(var(--muted-foreground));
}

.prose blockquote {
  padding-inline-start: var(--space-5);
  border-inline-start: calc(var(--hairline) * 2) solid hsl(var(--primary));
  color: hsl(var(--muted-foreground));
  font-style: normal;
}

/* --------------------------------------------------------------------------
   7. Divisor de seção
   Linha luminosa horizontal, distinta do .separator neutro de 03-ui.css:
   aqui o fade nas pontas é o ponto, não a cor de borda pura.
   -------------------------------------------------------------------------- */

.section-divider {
  inline-size: 100%;
  block-size: var(--hairline);
  border: 0;
  background: linear-gradient(
    to right,
    transparent,
    hsl(var(--border)) 20%,
    hsl(var(--border)) 80%,
    transparent
  );
}

.section-divider--glow {
  background: linear-gradient(to right, transparent, hsl(var(--primary) / 0.6) 50%, transparent);
}
