/* ============================================================
   INSTITUTO CRIANÇAS DE FUTURO — MARCA V1 · BASE
   Componentes reutilizáveis. Carregar depois de tokens.css.

   Regra que vale para o arquivo inteiro: nenhum componente daqui
   carrega texto estrutural. Conteúdo vem do HTML, que por sua vez
   espelha content/institutional.json.
   ============================================================ */

/* ---------- RESET ---------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* O header é sticky: sem isto a âncora para embaixo dele. */
  scroll-padding-top: 100px;
}

body {
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: 400;
  color: var(--txt-primary);
  background: var(--white);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

img, svg, video { display: block; max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }
ul, ol { list-style: none; }

/* §32 — movimento reduzido desliga tudo. Requisito, não cortesia. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
  }
}

/* ---------- ACESSIBILIDADE ---------- */
.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--navy); color: var(--white);
  padding: var(--s-3) var(--s-5);
  border-radius: 0 0 var(--r-sm) 0;
  font-family: var(--font-body); font-weight: 600;
}
.skip-link:focus { left: 0; }

/* §10 — o mesmo anel em tudo que recebe foco. #2F6FD9 dá 4.78:1 sobre
   branco, acima do mínimo de 3:1 para objeto de interface. */
:focus-visible {
  outline: 3px solid rgba(47, 111, 217, .55);
  outline-offset: 3px;
  border-radius: 2px;
}

/* Toda seção é alvo de âncora do menu. */
section[id] { scroll-margin-top: 100px; }

/* Visível só para leitor de tela. Existe para fechar buracos na
   hierarquia de headings sem inventar título na tela: uma seção que
   pula de h1 para h3 quebra o outline do documento, e o §33 pede
   sequência correta. Não usar `display:none` — isso a esconderia
   também de quem navega por leitor de tela, que é justamente o
   público que ela serve. */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* ---------- TIPOGRAFIA ---------- */
h1, h2, h3, h4 {
  font-family: var(--font-head);
  color: var(--txt-primary);
  letter-spacing: var(--ls-title);
  line-height: var(--lh-title);
  text-wrap: balance;
}
h1 { font-size: var(--fs-h1); font-weight: 700; line-height: var(--lh-display); letter-spacing: var(--ls-display); }
h2 { font-size: var(--fs-h2); font-weight: 700; }
h3 { font-size: var(--fs-h3); font-weight: 600; }
h4 { font-size: var(--fs-h4); font-weight: 600; }

/* 68ch fica dentro da faixa de 65–75 caracteres por linha, que é onde o
   olho volta para o começo da linha seguinte sem se perder. */
p { max-width: 68ch; text-wrap: pretty; }
p + p { margin-top: var(--s-4); }

/* `pretty` no parágrafo e `balance` no título resolvem coisas
   diferentes: balance iguala o comprimento das linhas de um título
   curto; pretty evita a ÓRFÃ — aquela última linha do parágrafo com uma
   palavra só, que deixa a coluna com um degrau no fim. */
li, dd, figcaption { text-wrap: pretty; }

/* Seleção de texto na cor da marca. Detalhe pequeno, mas o azul padrão
   do sistema é a única cor da página que não foi escolhida por ninguém. */
::selection { background: var(--teal); color: var(--navy); }

.lead { font-size: var(--fs-body-lg); color: var(--txt-secondary); max-width: 62ch; }
.small { font-size: var(--fs-small); }
.caption { font-size: var(--fs-small); color: var(--txt-muted); }
.txt-2 { color: var(--txt-secondary); }

/* txt-muted dá 4.09:1 sobre off-white e REPROVA — mas passa sobre
   branco, o que torna o erro invisível em revisão. A regra vira
   estrutura: dentro de qualquer superfície off-white, muted sobe
   sozinho para secondary (6.51:1). */
.s-offwhite .caption, .s-offwhite .txt-muted,
.s-family  .caption, .s-teen .caption, .s-kids .caption { color: var(--txt-secondary); }

/* ---------- CONTAINER E GRID ---------- */
.wrap {
  width: 100%; max-width: var(--container);
  margin-inline: auto; padding-inline: var(--gutter);
}
.wrap-wide { max-width: var(--container-wide); }
.wrap-text { max-width: var(--container-text); }

section { padding-block: var(--sec-gap); position: relative; }

/* §8 — 12 colunas no desktop, 8 no tablet, 4 no mobile. */
.grid { display: grid; gap: var(--s-6); }
.g-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.g-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.g-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

/* Duas colunas assimétricas, para as seções de conteúdo + imagem. */
.split {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: clamp(2rem, 1rem + 4vw, 4.5rem);
  align-items: center;
}
.split-5-7 { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
.split-6-6 { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
/* §20 — a Teen inverte a ordem visual sem mexer na ordem do documento,
   para que a leitura por teclado e leitor de tela continue igual. */
.split-inverso > :first-child { order: 2; }

/* ---------- SUPERFÍCIES ---------- */
.s-white    { background: var(--white); }
.s-bg       { background: var(--background); }
.s-offwhite { background: var(--off-white); }
.s-navy     { background: var(--navy); color: var(--white); }
.s-kids     { background: var(--bg-kids); }
.s-teen     { background: var(--bg-teen); }
.s-family   { background: var(--bg-family); }

.s-navy h1, .s-navy h2, .s-navy h3, .s-navy h4 { color: var(--white); }
.s-navy p, .s-navy .lead { color: rgba(255, 255, 255, .82); }
.s-navy .eyebrow { color: var(--teal); }

/* ---------- RÓTULO E TÍTULO DE SEÇÃO ---------- */
.eyebrow {
  display: inline-flex; align-items: center; gap: var(--s-3);
  font-family: var(--font-body);
  font-size: var(--fs-label); font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--txt-secondary);
  margin-bottom: var(--s-4);
}
.eyebrow::before {
  content: ""; width: 24px; height: 2px; border-radius: 2px;
  background: var(--teal); flex: none;
}
.s-navy .eyebrow::before { background: var(--teal); }

.titulo + .lead, h2 + .lead, h1 + .lead { margin-top: var(--s-5); }

/* ---------- BOTÕES ----------
   §10 — 52px de altura, raio 12px, padding 24px. Alvo de toque
   confortável e raio próprio: nesta marca botão não é pílula. */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--s-2);
  min-height: 52px; padding-inline: var(--s-6);
  font-family: var(--font-body);
  font-size: var(--fs-button); font-weight: 600;
  border-radius: var(--r-btn);
  border: 1px solid transparent;
  background: var(--navy); color: var(--white);
  cursor: pointer;
  transition: background var(--dur-state) ease,
              transform var(--dur-state) ease,
              border-color var(--dur-state) ease,
              color var(--dur-state) ease;
}
.btn:hover { background: #142750; transform: translateY(-2px); }

/* Feedback de TOQUE. Hover não existe em tela sensível ao toque: sem um
   estado :active, o dedo aperta o botão e nada acontece até a página
   trocar. O afundar de 1px é o que confirma que o toque foi registrado. */
.btn:active { transform: translateY(0); transition-duration: 60ms; }

.btn-2 { background: transparent; color: var(--navy); border-color: var(--navy); }
.btn-2:hover { background: rgba(13, 27, 61, .06); color: var(--navy); }

/* Sobre navy os dois invertem. Texto branco sobre coral dá 2.80:1 e
   reprova, então CTA em bloco escuro é branco com tinta navy — nunca
   um acento quente. */
.s-navy .btn { background: var(--white); color: var(--navy); }
.s-navy .btn:hover { background: var(--off-white); }

/* `background: transparent` é obrigatório aqui. O elemento carrega as
   duas classes (`btn btn-2`), e `.s-navy .btn` acima já pintou o fundo
   de branco — sem redeclarar, o secundário virava um botão branco com
   letra branca, invisível. Foi exatamente o que aconteceu no CTA final
   antes desta linha existir. */
.s-navy .btn-2 {
  background: transparent;
  color: var(--white);
  border-color: rgba(255, 255, 255, .45);
}
.s-navy .btn-2:hover { background: rgba(255, 255, 255, .12); color: var(--white); }

.btn-bloco { width: 100%; }

/* Link com seta, para navegação em texto. O teal cheio reprova como
   texto sobre claro (2.49:1), então o link é navy e o teal fica só na
   seta e no sublinhado — cor como reforço, nunca como único portador. */
.lnk {
  display: inline-flex; align-items: center; gap: var(--s-2);
  font-family: var(--font-body);
  font-size: var(--fs-button); font-weight: 600;
  color: var(--navy);
  box-shadow: inset 0 -2px 0 var(--teal);
  transition: gap var(--dur-state) ease, box-shadow var(--dur-state) ease;
}
.lnk::after { content: "›"; font-size: 1.25em; line-height: 1; color: var(--teal); }
.lnk:hover { gap: var(--s-3); box-shadow: inset 0 -3px 0 var(--teal); }
.s-navy .lnk { color: var(--white); }

/* ---------- CARTÃO ---------- */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: clamp(1.5rem, 1.1rem + 1.4vw, 1.75rem);
}
.card-sombra { box-shadow: var(--sh-card); }
/* Só anima transform e box-shadow: os dois rodam no compositor, sem
   forçar recálculo de layout a cada quadro. Animar width/height ou top
   aqui produziria o mesmo efeito visual custando reflow. */
.card-hover { transition: box-shadow var(--dur-state) ease, transform var(--dur-state) ease; }
.card-hover:hover { box-shadow: var(--sh-hover); transform: translateY(-3px); }
.card-hover:active { transform: translateY(-1px); transition-duration: 60ms; }
.s-navy .card {
  background: rgba(255, 255, 255, .08);
  border-color: rgba(255, 255, 255, .16);
}

/* Régua de cor no topo, para os cards que carregam categoria. A cor
   nunca é a única informação: o título escrito vem junto. */
.card-regua { border-top: 4px solid var(--c, var(--teal)); }

/* Ícone em círculo, na cor da categoria a 14% — claro o bastante para
   o traço escuro por cima continuar legível. */
.ic {
  width: 48px; height: 48px; flex: none;
  display: grid; place-items: center;
  border-radius: var(--r-circle);
  background: color-mix(in srgb, var(--c, var(--teal)) 14%, transparent);
  color: var(--navy);
  margin-bottom: var(--s-4);
}
.s-navy .ic { background: rgba(255, 255, 255, .12); color: var(--white); }

/* ---------- LISTA DE ITENS DO PROGRAMA ---------- */
.lista-check { display: grid; gap: var(--s-3); margin-top: var(--s-6); }
.lista-check li {
  position: relative; padding-left: var(--s-7);
  font-size: var(--fs-body); color: var(--txt-secondary);
}
.lista-check li::before {
  content: ""; position: absolute; left: 0; top: .45em;
  width: 8px; height: 8px; border-radius: var(--r-circle);
  background: var(--c, var(--teal));
}
.s-navy .lista-check li { color: rgba(255, 255, 255, .82); }

/* ---------- TAG ----------
   Sobre fundo claro a tag usa tinta navy: o acento entra como fundo
   lavado e como borda, nunca como cor de letra. */
.tag {
  display: inline-flex; align-items: center;
  padding: var(--s-2) var(--s-4);
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--c, var(--teal)) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--c, var(--teal)) 40%, transparent);
  font-family: var(--font-body);
  font-size: var(--fs-label); font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--navy);
  margin-bottom: var(--s-5);
}

/* ---------- FOTO ----------
   A MESMA imagem serve desktop e mobile. O recorte é feito aqui, por
   aspect-ratio + object-fit, e não gerando dois arquivos: no desktop ela
   aparece em pé (4:5 ou 1:1) e no mobile deitada (4:3).

   Por isso as fotos foram enquadradas com respiro vertical — o recorte
   do mobile tira altura, e assunto colado na borda ficaria decapitado. */
.foto {
  margin: 0;
  aspect-ratio: var(--ar, 4 / 5);
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--surface-soft);   /* cor de espera enquanto carrega */
}
.foto picture { display: block; width: 100%; height: 100%; }
.foto img {
  display: block;
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center;
}

/* ---------- PLACEHOLDER DE ASSET ----------
   §40 — enquanto a foto final não existe, o bloco declara o id, a
   proporção e a descrição. Nunca entra foto de banco no piloto:
   imagem genérica passa por decisão tomada e some do radar. */
.asset {
  position: relative;
  display: grid; place-content: center; gap: var(--s-2);
  aspect-ratio: var(--ar, 4 / 5);
  border-radius: var(--r-lg);
  background: var(--surface-soft);
  border: 2px dashed var(--border);
  padding: var(--s-6);
  text-align: center;
}
.asset-id {
  font-family: var(--font-body);
  font-size: var(--fs-label); font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--navy);
}
.asset-meta { font-size: var(--fs-small); color: var(--txt-secondary); max-width: 34ch; margin-inline: auto; }
.asset-ar {
  font-family: var(--font-head); font-size: var(--fs-small); font-weight: 600;
  color: var(--teal);
}

/* ---------- CABEÇALHO ----------
   §12 — relativo no topo, sticky depois de 40px de rolagem. A classe
   .fixo é aplicada por JS. */
.topo {
  position: sticky; top: 0; z-index: 100;
  background: rgba(255, 255, 255, .94);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid transparent;
  transition: box-shadow var(--dur-state) ease, border-color var(--dur-state) ease;
}
.topo.fixo {
  box-shadow: 0 1px 24px rgba(13, 27, 61, .08);
  border-bottom-color: var(--border);
}
.topo .barra {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-6); min-height: 80px;
}
.topo-logo img { height: 44px; width: auto; }

.menu { display: flex; align-items: center; gap: var(--s-7); }
.menu a {
  font-family: var(--font-body);
  font-size: var(--fs-small); font-weight: 500;
  color: var(--txt-secondary);
  transition: color var(--dur-state) ease;
}
.menu a:hover,
.menu a[aria-current] { color: var(--navy); }

/* Seção atual do menu. O traço embaixo é o portador do estado; a cor
   mais escura vem junto porque cor sozinha não pode carregar
   informação — quem não distingue os dois tons ainda vê o traço. */
.menu a { position: relative; padding-block: var(--s-2); }
.menu a::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0;
  height: 2px; border-radius: 2px;
  background: var(--teal);
  transform: scaleX(0); transform-origin: left;
  transition: transform var(--dur-state) var(--ease);
}
.menu a[aria-current]::after { transform: scaleX(1); }
.topo .btn { min-height: 44px; font-size: var(--fs-small); }

.menu-btn { display: none; }

/* ---------- RODAPÉ ---------- */
.rodape { background: var(--bg-footer); color: rgba(255, 255, 255, .72); padding-block: var(--s-13) var(--s-8); }
.rodape a { color: rgba(255, 255, 255, .72); transition: color var(--dur-state) ease; }
.rodape a:hover { color: var(--white); }
.rodape .colunas { display: grid; grid-template-columns: 1.6fr 1fr 1fr 1fr; gap: var(--s-9); }
.rodape-logo img { height: 52px; margin-bottom: var(--s-5); }
.rodape h3 {
  font-family: var(--font-body);
  font-size: var(--fs-label); font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--teal);
  margin-bottom: var(--s-5);
}
.rodape li + li { margin-top: var(--s-3); }
.rodape li a { font-size: var(--fs-small); }
.rodape-fim {
  margin-top: var(--s-11); padding-top: var(--s-7);
  border-top: 1px solid rgba(255, 255, 255, .14);
  display: flex; flex-wrap: wrap; gap: var(--s-4) var(--s-7);
  justify-content: space-between; align-items: center;
  font-size: var(--fs-small);
}
.sociais { display: flex; gap: var(--s-5); }

/* ---------- REVEAL ----------
   §32 — fade com deslocamento de até 20px, execução única.

   O estado inicial invisível vive atrás de `.js`, que o próprio script
   carimba no <html> assim que roda. Sem isso, o CSS esconderia o
   conteúdo e dependeria do JavaScript para devolvê-lo — e uma página
   que precisa de JS para ter texto é uma página que fica em branco
   quando o script falha, atrasa ou é bloqueado. Progressive
   enhancement de verdade: a animação é o extra, nunca o requisito. */
.js .rv {
  opacity: 0; transform: translateY(20px);
  transition: opacity var(--dur-reveal) var(--ease), transform var(--dur-reveal) var(--ease);
}
.js .rv.in { opacity: 1; transform: none; }

/* ---------- REVEAL EM GRUPO ----------
   A regra é animar 1–2 elementos por tela; a página tinha 26 alvos
   observados individualmente, um por card. Aqui o observador acompanha
   só o CONTÊINER, e a cascata entre os filhos vem de transition-delay
   no CSS.

   Ganho duplo: 5 observações em vez de 26, e o escalonamento deixa de
   depender de setTimeout em JavaScript — que disputa a thread principal
   justamente enquanto a seção entra em cena. */
.js .rv-grupo > * {
  opacity: 0; transform: translateY(16px);
  transition: opacity var(--dur-reveal) var(--ease), transform var(--dur-reveal) var(--ease);
}
.js .rv-grupo.in > * { opacity: 1; transform: none; }
.js .rv-grupo.in > :nth-child(1) { transition-delay: 0ms; }
.js .rv-grupo.in > :nth-child(2) { transition-delay: 70ms; }
.js .rv-grupo.in > :nth-child(3) { transition-delay: 140ms; }
.js .rv-grupo.in > :nth-child(4) { transition-delay: 210ms; }
.js .rv-grupo.in > :nth-child(5) { transition-delay: 280ms; }
/* Teto de 350ms: a partir do sexto item todos entram juntos. Cascata
   longa demais vira espera, não elegância. */
.js .rv-grupo.in > :nth-child(n + 6) { transition-delay: 350ms; }

@media (prefers-reduced-motion: reduce) {
  .js .rv, .js .rv-grupo > * { opacity: 1; transform: none; transition: none; }
}

/* ============================================================
   TABLET — 8 colunas
   ============================================================ */
@media (max-width: 1023px) {
  .g-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  /* `minmax(0, 1fr)` e não `1fr`: um track `1fr` tem min-width AUTO, ou
     seja, ele nunca encolhe abaixo do conteúdo mínimo dos filhos — e
     cresce para além do container quando algum filho pede mais. Foi
     exatamente isso que fez a seção Teen estourar 21px em 320px
     enquanto Kids e Família, com a mesma estrutura, cabiam. O zero no
     minmax é o que autoriza o track a encolher e o texto a quebrar. */
  .split, .split-5-7, .split-6-6 { grid-template-columns: minmax(0, 1fr); gap: var(--s-9); }
  .split-inverso > :first-child { order: 0; }
  .rodape .colunas { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--s-8); }
}

/* ============================================================
   MOBILE — 4 colunas
   ============================================================ */
@media (max-width: 767px) {
  /* minmax(0, …) pelo mesmo motivo do bloco de tablet: `1fr` sozinho
     não encolhe abaixo do conteúdo e produz rolagem horizontal. */
  .g-2, .g-3, .g-4 { grid-template-columns: minmax(0, 1fr); }

  /* §13 e §19–21: no mobile toda foto vira 4:3, mais larga e mais baixa.
     Sobrescreve o --ar declarado no HTML. */
  .foto { aspect-ratio: 4 / 3; }

  /* ---------- FOTO SANGRANDO NO MOBILE ----------
     A foto sai do padding do .wrap e encosta nas duas bordas da tela.

     A margem negativa usa --gutter, NÃO 100vw. `width: 100vw` conta a
     barra de rolagem e produz alguns pixels de rolagem horizontal em
     desktop — exatamente o defeito que o medidor de overflow existe
     para pegar. Puxando pelo gutter, a conta fecha com o padding real
     do contêiner, seja qual for o valor do clamp naquela largura.

     Sem raio: encostada na borda, a quina arredondada deixaria quatro
     triângulos de fundo aparecendo e leria como erro de corte. */
  .foto-sangra {
    margin-inline: calc(var(--gutter) * -1);
    border-radius: 0;
  }
  .grid { gap: var(--s-4); }
  .rodape .colunas { grid-template-columns: minmax(0, 1fr); gap: var(--s-8); }
  .topo .barra { min-height: 68px; flex-wrap: wrap; gap: var(--s-3); }
  .topo-logo { margin-right: auto; }
  .topo-logo img { height: 36px; }
  .btn { width: 100%; }
  .topo .btn, .lista-check .btn { width: auto; }

  /* ---------- MENU MOBILE ----------
     §12 — painel abaixo do header, fecha no clique e no Escape.
     Disclosure em fluxo, não drawer sobreposto: drawer é modal e
     exigiria overlay, trava de rolagem, aria-modal e focus trap —
     quatro mecanismos que só resolvem problemas que ele mesmo cria. */
  .menu-btn {
    display: grid; place-items: center; align-content: center;
    width: 44px; height: 44px; flex: none;
    border: 1px solid var(--border);
    border-radius: var(--r-sm);
    color: var(--navy);
    transition: background var(--dur-state) ease, color var(--dur-state) ease;
  }
  .menu-btn .barrinha { display: block; width: 18px; height: 2px; border-radius: 2px; background: currentColor; }
  .menu-btn .barrinha + .barrinha { margin-top: 4px; }
  .menu-btn[aria-expanded="true"] { background: var(--navy); color: var(--white); border-color: var(--navy); }

  /* Fechado, sai do fluxo E da ordem de tabulação de uma vez só. */
  .topo .menu {
    display: none;
    flex-basis: 100%; flex-direction: column; align-items: stretch;
    gap: 0; padding-bottom: var(--s-3);
  }
  .topo .menu[data-aberto] { display: flex; }
  .topo .menu a {
    min-height: 52px; display: flex; align-items: center;
    font-size: var(--fs-body); color: var(--navy);
    border-top: 1px solid var(--border);
  }
}
