/* ==========================================================================
   NEXUS theme-final / sections/modelos.css
   Território exclusivo da seção #modelos (B2B, B2C, B2G, white label).

   Reusa .section, .container, .section__head, .eyebrow, .lead (02-base.css)
   e .badge (03-ui.css) sem redefinição.

   REDESENHO DA RODADA DE AGOSTO DE 2026, por pedido do dono.
   Antes: grade de quatro cartões verticais que, entre 1000px e 1559px,
   caía em três colunas mais um órfão, com duas células vazias na segunda
   linha. Agora: UMA FAIXA HORIZONTAL POR MODELO, quatro faixas empilhadas.
   Numeral romano, sigla, título e descrição distribuídos na largura da
   faixa; a fotografia entra como faixa lateral à direita, revelada ao lado
   do painel de texto. Uma linha por modelo significa que não existe mais
   linha incompleta: o defeito acaba por geometria, não por ajuste de
   trilha mínima.

   DUAS APRESENTAÇÕES, UMA FOLHA, ZERO PERGUNTA SOBRE PELE.
   A escolha entre faixa horizontal e cartão empilhado é feita por CONTAINER
   QUERY do próprio item (bloco 3), nunca por media query da janela nem por
   seletor de pele. Isso importa porque a pele de superfície remonta
   #modelos como matriz de quatro colunas contíguas (§12.2 do contrato):
   lá o item mede cerca de 300px e recebe sozinho a apresentação empilhada,
   idêntica à que sempre teve, sem que esta folha nem o partial precisem
   saber que a pele existe. O mesmo vale para o mobile, que é o mesmo caso
   geométrico: item estreito.

   Cor do texto sobre a foto continua saindo do par --scrim / --scrim-*, e o
   véu continua sendo propriedade do PRÓPRIO bloco de texto, que é a correção
   estrutural registrada na rodada anterior (ver bloco 5). Nenhuma cor é
   escrita fora de var(--...), nenhum hex, nenhum raio em px.

   Motion: só transform e opacity. A entrada em cascata das faixas é do
   inicializador de partials/modelos.js (IntersectionObserver nativo, zero
   dependência), e obedece a prefers-reduced-motion e a --motion.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Título da seção
   -------------------------------------------------------------------------- */

.modelos__title {
  font-family: var(--font-display);
  font-size: var(--fs-h2);
  font-weight: 600;
  line-height: var(--lh-display);
  letter-spacing: var(--tracking-display);
  color: hsl(var(--foreground));
}

/* --------------------------------------------------------------------------
   2. Pilha
   Uma faixa por linha, quatro linhas. Sem contagem de colunas para escolher,
   sem trilha mínima para calibrar, sem órfão possível.

   A pele de superfície sobrescreve esta regra para quatro colunas
   (`[data-skin="surface"] .modelos__grid`, 0,2,0, folha carregada depois):
   é a assinatura de matriz dela, registrada no §12.2, e continua de pé.
   -------------------------------------------------------------------------- */

/* Cabeçalho em coluna única (agosto/2026, pedido do dono: "lead abaixo do
   título, em todos"). Mesmo caso de #capacidades e #confianca: a pele
   surface reabre .section__head em duas faixas a partir de 900px
   (08-skin-surface.css §4.3) para as seções que ainda não pediram exceção;
   #modelos entra na mesma lista de #cases/#tese/#metodo/#govtech, por
   especificidade de ID, sem tocar a folha da pele. */
#modelos > .container > .section__head {
  grid-template-columns: minmax(0, 1fr);
}

#modelos > .container > .section__head > .lead {
  grid-column: 1;
  max-width: var(--measure);
}

.modelos__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);

  /* Quatro faixas de mesma altura. O texto dos quatro modelos varia de duas
     a três linhas na mesma largura, e sem isto a primeira faixa saía 42px
     mais baixa que as outras três: numa pilha de peças idênticas, 42px de
     diferença lê como erro de alinhamento, não como respiro. */
  grid-auto-rows: 1fr;
  gap: var(--space-5);
  list-style: none;
  margin: 0;
  padding: 0;
}

/* O item é o CONTAINER de consulta do bloco 3. `inline-size` contém só o
   eixo horizontal: a altura continua vindo do conteúdo. */
/* `grid` e não `block`: o item precisa ESTICAR o cartão até a altura da
   linha, senão `grid-auto-rows: 1fr` iguala as linhas e a faixa mais curta
   fica boiando dentro da própria linha (medido: 232px de faixa dentro de
   uma linha de 278px). É a mesma razão pela qual a pele de superfície já
   declarava `display: grid` no item dela.

   O item é também o CONTAINER de consulta do bloco 6. `inline-size` contém
   só o eixo horizontal: a altura continua vindo do conteúdo. */
.modelos__item {
  display: grid;
  min-width: 0;
  container-type: inline-size;
  container-name: modelo-item;
}

/* --------------------------------------------------------------------------
   3. A faixa (item largo) e o cartão (item estreito)
   O bloco 4 descreve a apresentação BASE, que é a empilhada: é ela que vale
   no item estreito, no mobile e dentro da matriz da pele de superfície. O
   bloco 6 é a container query que vira a peça de lado quando há largura.
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   4. Cartão empilhado (apresentação base)
   Imagem full bleed em absolute, véu em absolute, conteúdo em fluxo normal
   empurrado para o rodapé por flex + justify-content: flex-end.
   -------------------------------------------------------------------------- */

.modelos__card {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  overflow: hidden;
  min-height: clamp(23rem, 19rem + 10vw, 29rem);
  border-radius: var(--radius-lg);
  border: var(--hairline) solid hsl(var(--border));
  background-color: hsl(var(--muted));
  text-decoration: none;
  transition: border-color calc(var(--dur-fast) * var(--motion)) var(--ease-out);
}

.modelos__card:hover {
  border-color: hsl(var(--primary) / 0.55);
}

.modelos__card:focus-visible {
  outline: 2px solid hsl(var(--ring));
  outline-offset: 2px;
  border-color: hsl(var(--primary) / 0.55);
}

.modelos__img {
  position: absolute;
  inset: 0;
  z-index: 0;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  transform: scale(1);
  transition: transform calc(var(--dur-slow) * var(--motion)) var(--ease-out);
}

.modelos__card:hover .modelos__img,
.modelos__card:focus-visible .modelos__img {
  transform: scale(1.06);
}

/* Véu ambiente da foto. Tinta escura dos dois lados (--scrim), nunca
   --background: com --background o tema claro clareava a foto em vez de
   assentá-la. Este gradiente NÃO carrega obrigação de contraste: quem
   sustenta o texto é o véu do próprio bloco de texto, no bloco 5. */
.modelos__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(
    to top,
    hsl(var(--scrim) / 0.62) 0%,
    hsl(var(--scrim) / 0.40) 42%,
    hsl(var(--scrim) / 0.18) 72%,
    hsl(var(--scrim) / 0.24) 100%
  );
}

/* --------------------------------------------------------------------------
   5. Bloco de texto e o véu que o sustenta

   REGRA HERDADA DA RODADA ANTERIOR, e ela é a razão de o véu morar aqui e
   não no gradiente irmão: véu calibrado em PORCENTAGEM DA ALTURA do cartão
   não é âncora. Basta --density mudar (a pele de vidro roda 1.14), ou
   --scale subir 28% num 3840x2160, para o bloco de texto crescer e subir
   para a faixa de alfa baixo do gradiente, sobre a parte clara da foto. Foi
   assim que o título do cartão B2G mediu 2,80:1 em index2.html.

   O véu é propriedade do bloco de texto, que é uma caixa em fluxo e por
   construção tem exatamente a altura (e, na faixa, a largura) do texto que
   hospeda, em qualquer densidade, escala, pele ou viewport. Composto sobre o
   pixel mais claro que uma foto pode ter (branco puro), --scrim-foreground
   mede 16,8:1 e --scrim-muted-foreground mede 11,5:1 aqui dentro.
   -------------------------------------------------------------------------- */

.modelos__content {
  position: relative;
  z-index: 2;
  display: grid;
  gap: var(--space-3);
  padding: var(--space-6);
  background-color: hsl(var(--scrim) / 0.94);
}

/* Transição do véu do texto para a foto, no eixo em que o véu termina.
   Empilhado, o véu termina em cima: a esfumaçada sobe. Altura em --space-*,
   proporcional à densidade e independente da altura do cartão. */
.modelos__content::before {
  content: "";
  position: absolute;
  inset-inline: 0;
  inset-block-end: 100%;
  block-size: var(--space-14);
  background: linear-gradient(
    to top,
    hsl(var(--scrim) / 0.94) 0%,
    hsl(var(--scrim) / 0.62) 38%,
    hsl(var(--scrim) / 0.24) 70%,
    hsl(var(--scrim) / 0) 100%
  );
  pointer-events: none;
}

/* Numeral e sigla na mesma linha. O numeral saiu do canto absoluto do
   cartão e entrou no fluxo do bloco de texto: dentro da faixa ele é a
   primeira coluna da distribuição pedida pelo dono, e no cartão empilhado
   ele passa a dividir a linha com a sigla em vez de flutuar sobre a parte
   clara da foto, que era justamente o pior caso de contraste do elemento. */
.modelos__marca {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

/* O PRATO DO NUMERAL SAIU, e a razão é que o motivo dele acabou.

   O prato (um retângulo de `hsl(var(--scrim) / 0.82)` atrás do glifo) foi a
   correção da rodada anterior para um numeral que pousava NO TOPO DA FOTO,
   onde nenhum véu de rodapé alcançava e a tinta media de 1,10:1 a 2,48:1
   contra o pixel claro da fotografia. Neste redesenho o numeral não pousa
   mais sobre foto: ele entrou no fluxo do bloco de texto, ou seja, está
   sobre o mesmo véu opaco de 0,94 que sustenta o título e a descrição, e
   tem exatamente a mesma conta de contraste deles.

   Mantido o prato, ele virava um retângulo cinza visível em volta de cada
   algarismo, porque 0,82 sobre 0,94 é mais claro que o véu: uma caixa que o
   olho lê como erro de renderização. Tinta opaca (--scrim-faint-foreground),
   nunca alfa, continua igual. */
.modelos__numeral {
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  font-weight: 700;
  line-height: 1;
  color: hsl(var(--scrim-faint-foreground));
}

.modelos__sigla {
  justify-self: start;
}

.modelos__card-title {
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  font-weight: 600;
  line-height: var(--lh-tight);
  color: hsl(var(--scrim-foreground));
}

/* Sem truncamento: o cartão inteiro é um link para o contato, não abre nada
   que mostre o resto, então reticências esconderiam informação sem oferecer
   caminho para ela. */
.modelos__card-text {
  max-width: var(--measure);
  font-size: var(--fs-sm);
  line-height: 1.55;
  color: hsl(var(--scrim-muted-foreground));
}

/* Só a seta, sem rótulo: pedido do dono. O link não fica mudo porque o
   aria-label do <a> em partials/modelos.js diz a frase inteira, e a seta é
   aria-hidden por ser decorativa. */
.modelos__cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 2.25em;
  block-size: 2.25em;
  border-radius: var(--radius-full);
  border: var(--hairline) solid hsl(var(--scrim-faint-foreground));
  color: hsl(var(--scrim-foreground));
  justify-self: start;
}

.modelos__cta .nx-icon {
  transition: transform calc(var(--dur-fast) * var(--motion)) var(--ease-out);
}

.modelos__card:hover .modelos__cta .nx-icon,
.modelos__card:focus-visible .modelos__cta .nx-icon {
  transform: translate(0.15em, -0.15em);
}

/* --------------------------------------------------------------------------
   6. Faixa horizontal (item largo)

   Container query, não media query: o gatilho é a largura do ITEM. Em
   46rem o painel de texto ainda tem folga para as três colunas internas
   (marca, título, descrição) mais a seta, e sobra a faixa lateral da foto.
   Abaixo disso vale o cartão empilhado do bloco 4, que é o caso do mobile e
   o caso da matriz de quatro colunas da pele de superfície.
   -------------------------------------------------------------------------- */

@container modelo-item (min-width: 46rem) {
  /* Duas colunas: painel de texto e faixa de foto. A faixa lateral é a
     única largura escrita nesta folha, e é clamp de rem com teto e piso,
     não porcentagem solta: em 3840px ela não vira metade da peça, e em
     46rem ela não desaparece. */
  .modelos__card {
    display: grid;
    grid-template-columns: minmax(0, 1fr) clamp(10rem, 26%, 22rem);
    align-items: stretch;
    min-height: clamp(11rem, 8rem + 5vw, 15rem);
  }

  /* O painel ocupa a primeira coluna e distribui na largura: marca
     (numeral e sigla e título), descrição e seta.

     13ª rodada, pedido do dono: o texto ocupava só um pedaço da faixa e o
     resto ficava vazio. A causa era a coluna da descrição em
     `fit-content(52ch)` — ela parava de crescer bem antes do fim do
     painel — somada a um quarto trilho, `minmax(0, 1fr)`, que não tinha
     conteúdo nenhum: existia só para "gastar" a sobra, e sobrava escuro e
     vazio. Correção: três trilhos, não quatro. Título e descrição são
     AMBOS fr, dividem entre si tudo que sobra depois da seta, e a
     descrição corre até perto da seta em vez de secar cedo. Quem ainda
     trava o comprimento da linha de leitura é `--measure`, na regra base
     do bloco 5: um teto de legibilidade escrito no PRÓPRIO texto, não uma
     trilha de grade capada por baixo dele. */
  .modelos__content {
    /* 13ª rodada, terceiro pedido do dono nesta faixa (com medição dele no
       DevTools): o painel parava na primeira coluna e o texto "não ia para a
       imagem toda". Agora o painel atravessa o cartão INTEIRO, por cima da
       foto, e quem devolve a foto ao olhar é o véu virando gradiente
       horizontal: opaco onde o texto pesa, diluindo até quase zero na borda
       direita. O texto pode correr até o fim do cartão sem perder o assento
       de contraste, e a seta assenta sobre a área mais escura do véu. */
    grid-column: 1 / -1;
    grid-row: 1;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.5fr) auto;
    align-items: center;
    column-gap: var(--space-7);
    row-gap: var(--space-2);
    padding: var(--space-7) var(--space-7);
    background-color: transparent;
    background-image: linear-gradient(
      to right,
      hsl(var(--scrim) / 0.94) 0%,
      hsl(var(--scrim) / 0.94) 58%,
      hsl(var(--scrim) / 0.66) 80%,
      hsl(var(--scrim) / 0.28) 100%
    );
  }

  .modelos__marca {
    grid-column: 1;
    grid-row: 1;
    align-self: end;
  }

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

  /* Título ganha destaque na faixa larga: aqui ele tem a coluna inteira
     para si, não a largura estreita do cartão empilhado, e o pedido do
     dono foi hierarquia clara entre título e descrição. */
  .modelos__card-title {
    grid-column: 1;
    grid-row: 2;
    align-self: start;
    font-size: calc(var(--fs-h3) * 1.2);
  }

  .modelos__card-text {
    grid-column: 2;
    grid-row: 1 / span 2;
    align-self: center;
    /* 13ª rodada, segundo pedido do dono sobre esta faixa: mesmo com a trilha
       em fr, o teto `--measure` da regra base ainda secava a linha no meio do
       cartão e sobrava um vão escuro até a seta e a foto. Na faixa larga o
       teto sai e a descrição contempla a largura toda do painel; o cartão
       empilhado do mobile continua com o teto da regra base. */
    max-width: none;
  }

  /* Respiro entre a descrição e a seta: colada no texto, a seta lia como
     pontuação da última linha, não como um controle clicável à parte. O
     `column-gap` do painel já cresceu junto (acima); esta margem soma um
     respiro extra específico da seta. */
  .modelos__cta {
    grid-column: 3;
    grid-row: 1 / span 2;
    align-self: center;
    justify-self: start;
    margin-inline-start: var(--space-2);
  }

  /* A esfumaçada muda de eixo junto com o layout: o véu do texto agora
     termina do lado DIREITO, então a transição para a foto é horizontal.
     Continua ancorada na caixa do próprio texto (inset-inline-start: 100%),
     que é o que a torna imune a densidade, escala e altura. */
  /* Com o painel atravessando o cartão e o véu diluindo no próprio
     background, a esfumaçada lateral perde a função nesta faixa. */
  .modelos__content::before {
    display: none;
  }
}

/* --------------------------------------------------------------------------
   7. Faixa muito larga
   Acima de 74rem de item o título cede um pouco mais de peso relativo e a
   descrição ganha ainda mais coluna, para a distribuição não parecer curta
   demais num 4K; o teto de leitura continua sendo `--measure`, no texto.
   -------------------------------------------------------------------------- */

@container modelo-item (min-width: 74rem) {
  .modelos__content {
    grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.7fr) auto;
    padding-inline: var(--space-10);
  }
}
