/* hub.css — a folha da PÁGINA do hub da área de membros (/membros/).
 *
 * Carregada por último, depois de
 *   /ds/sitio/tokens.css → sistema.css → elementos.css → elementos-sitio.css
 *   → /css/sitio-web.css
 * com `class="sitio"` no <body>. A ordem importa: fora dela a cascata
 * inverte. Ver membros_site/pagina.py (CSS_DO_SITIO) e a seção "O que um
 * redesign NÃO pode quebrar" de sites/CLAUDE.md.
 *
 * `ds/sitio/` é SAÍDA COMPILADA — nunca editada. Todo ajuste mora aqui,
 * escopado, com o motivo escrito junto.
 *
 * Régua e relatório continuam em membros.css + o pacote antigo (/ds/, sem
 * `sitio/`), e é de propósito: os dois pacotes declaram os MESMOS nomes de
 * token com valores diferentes (`--mesa` é #343434 no antigo e #04080c no
 * novo). Uma página carrega um ou o outro, nunca os dois.
 */

/* ── 1 · O que nem o pacote nem o cromo compartilhado trazem ──────────── */

/* O `.ico`, o pular-para-o-conteúdo e a correção de especificidade do
 * `.cromo__marca` estavam duplicados aqui até 14/08/2026, copiados de
 * css/home.css porque não havia camada comum. Agora há:
 * `/css/sitio-chrome.css` (ver CSS_DO_SITIO em pagina.py), e as três saíram
 * daqui — duas cópias do mesmo valor é a maneira mais silenciosa de duas
 * superfícies divergirem.
 *
 * O que sobrou é o rodapé, que aquele arquivo não cobre. */

.rodape__legal,
.rodape__redes {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}
.rodape__marca { display: inline-flex; align-items: center; gap: 6px; }

/* css/sitio-web.css §8 põe o flex de três colunas em `.rodape .sitio__miolo`
   e css/home.css cuida do estreito com um `flex-wrap` — mas aquela regra
   mira `.rodape`, que aqui não é mais quem distribui. Sem isto, as três
   peças do rodapé continuam numa linha só e a página inteira passa a rolar
   de lado a 320px (medido: scrollWidth 376 contra clientWidth 320). */
@media (max-width: 900px) {
  .rodape .sitio__miolo {
    flex-wrap: wrap;
    justify-content: center;
    gap: 10px 24px;
    text-align: center;
  }
  .rodape { white-space: normal; }
  .rodape__legal, .rodape__redes { justify-content: center; gap: 12px; }
}

/* ── 2 · A navegação sem botão que não abre ───────────────────────────── */

/* A área de membros SEMPRE teve os atributos `data-menu-toggle` /
 * `data-menu-painel` no cabeçalho e NUNCA importou `js/home/menu.js`: o
 * botão do menu compacto não abria nada. Abaixo de 1180px a navegação
 * inteira ficava inalcançável, e nada nisso falha alto.
 *
 * Aqui o botão não existe (ver `_TOPO_SITIO` em pagina.py). Abaixo do
 * ponto de virada o cromo empilha em duas linhas e a navegação vira uma
 * fita rolável na horizontal, sempre visível, sem JS nenhum. Um controle
 * que não faz nada é pior que controle nenhum. */
@media (max-width: 1180px) {
  .cromo { height: auto; }
  .cromo__miolo {
    flex-wrap: wrap;
    gap: 12px 20px;
    padding-block: 12px;
  }
  .cromo__nav {
    /* `/css/sitio-chrome.css` põe `display: grid` no `.cromo__nav` abaixo
       deste mesmo ponto de virada — lá a nav mora DENTRO do painel do menu
       compacto, e cada elo é uma linha. Aqui não há painel: a nav é a fita.
       Sem esta linha os quatro elos empilham na vertical e o cabeçalho
       cresce, sem erro nenhum no console. */
    display: flex;
    order: 3;
    width: 100%;
    margin-left: 0;
    gap: 20px;
    overflow-x: auto;
    /* A fita rola; a barra em si some porque o conteúdo dela é curto e o
       corte seria só ruído. Rolagem escondida NÃO é conteúdo escondido:
       os quatro elos cabem em ~360px e nenhum é cortado a 320px. */
    scrollbar-width: none;
    padding-bottom: 2px;
  }
  .cromo__nav::-webkit-scrollbar { display: none; }
  .cromo__fim { margin-left: auto; gap: 10px; }
}

/* ── 3 · A abertura ───────────────────────────────────────────────────── */

/* Sem retrato e sem o campo reativo do herói da home: os dois pedem
 * material (foto recortada) e JS (js/sitio/campo.js) que esta página não
 * tem. `.sitio__grade` é a única peça de fundo do pacote que é CSS puro —
 * usada aqui como o terreno da faixa, com a mesma máscara radial que ela
 * já traz. Vazio declarado: nenhuma arte inventada pra ocupar o lugar. */
.abertura { padding-top: 8px; padding-bottom: 40px; overflow-x: hidden; }
.abertura__miolo { position: relative; z-index: 1; padding-top: 56px; }

.abertura__manchete {
  font-family: var(--voz-funcional);
  font-size: var(--sitio-manchete-corpo);
  line-height: var(--sitio-manchete-entrelinha);
  font-weight: var(--sitio-manchete-peso);
  letter-spacing: -.022em;
  margin: 22px 0 0;
  color: var(--sitio-tinta-cheia);
}
.abertura__deck {
  margin: 22px 0 0;
  max-width: 62ch;
  font-size: var(--sitio-deck-corpo);
  line-height: var(--sitio-deck-entrelinha);
  color: var(--sitio-tinta-secundaria);
  text-wrap: pretty;
}
.abertura__linha {
  margin: 30px 0 0;
  font-family: var(--voz-sistema);
  font-size: var(--sitio-mono-corpo);
  line-height: var(--sitio-mono-entrelinha);
  color: var(--sitio-terminal);
}
.abertura__linha {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 20px;
}
.abertura__linha b { font-weight: 400; color: var(--sitio-tinta-fraca); }
/* --sitio-sintaxe-comentario não existe no pacote do sítio (só no antigo,
   dentro do bloco de sintaxe da peça de vídeo). A secundária é a tinta de
   "texto de apoio" daqui e mede 5,99:1 — o comentário é a data da régua,
   informação de verdade, não enfeite. */
.abertura__eco { color: var(--sitio-tinta-secundaria); }

/* O medidor do pacote é `display:flex` com divisórias verticais, calibrado
 * pra quatro itens numa linha de 1240px. Abaixo disso vira grade de duas
 * colunas — a divisória à esquerda de cada item vira falsa quando o item
 * é o primeiro da linha, então some junto e a separação passa a ser o
 * respiro. */
.abertura .medidor { margin-top: 34px; flex-wrap: wrap; row-gap: 24px; }
/* O pacote põe o rótulo do medidor em --sitio-tinta-fraca: medido, 3,21:1
   sobre --sitio-fundo, abaixo do piso de 4,5:1 pra texto de 12px. Aqui o
   rótulo é o que diz o que o número significa — sem ele o número não é
   informação nenhuma. Tinta secundária mede 5,99:1. */
.abertura .medidor__chave { color: var(--sitio-tinta-secundaria); }
@media (max-width: 680px) {
  .abertura .medidor { display: grid; grid-template-columns: 1fr 1fr; gap: 22px 20px; }
  .abertura .medidor__item { padding-left: 0; border-left: 0; }
}

/* ── 4 · As seções ────────────────────────────────────────────────────── */

.secao__cabeca { align-items: flex-end; }
/* `.sitio__miolo` soma DUAS sangrias: a largura de css/sitio-web.css já é
   `100% - 2 × --sitio-sangria`, e por cima o pacote ainda declara
   `padding: 0 24px` — que, sem box-sizing de borda, é somado à largura em
   vez de caber dentro dela. Só aparece no muito estreito, porque só lá a
   soma passa do vão: medido, scrollWidth 324 contra clientWidth 320 a
   320px, ou seja a página rolando de lado por 4px.
   Abaixo de 680px `--sitio-sangria` já vale 20px de cada lado e cumpre o
   papel sozinha — o padding interno vira o excedente e sai. Acima disso
   nada muda: as duas sangrias somadas cabem de sobra e mexer ali mudaria
   a largura de leitura numa faixa que ninguém pediu pra mexer. */
@media (max-width: 680px) {
  .sitio__miolo { padding-inline: 0; }
  .secao { padding-top: 48px; }
  .secao__cabeca { flex-direction: column; align-items: flex-start; gap: 16px; }
}
.secao__deck { max-width: 68ch; }
.secao__vazio {
  margin-top: 24px;
  padding: 20px 22px;
  border: 1px dashed var(--sitio-traco-forte);
  border-radius: var(--sitio-raio);
  color: var(--sitio-tinta-secundaria);
  font-size: 14px;
}
/* `.secao__elo` é <a>: mesma armadilha de especificidade do .cromo__marca. */
.sitio a.secao__elo { color: var(--sitio-sinal); white-space: nowrap; }
.sitio a.secao__elo:hover { color: var(--sitio-sinal-forte); }

/* ── 5 · O bloco de acesso (#acao-membro) ─────────────────────────────── */

/* `.membros` (elementos-sitio.css) é só a GRADE — o painel de acesso da
 * home, que a Task 31 removeu de lá, nunca teve superfície própria: ele
 * herdava a do bloco em volta. Aqui ele é o bloco, então recebe a mesma
 * receita de superfície que `.prompt` e `.ficha` já usam no pacote
 * (traço + raio + superfície + relevo + luz de bordo). Composição dos
 * tokens do sistema, não desenho novo. */
#acao-membro {
  margin-top: 28px;
  border: 1px solid var(--sitio-traco);
  border-radius: var(--sitio-raio);
  background-color: var(--sitio-superficie);
  box-shadow: var(--sitio-relevo), var(--sitio-luz-de-bordo);
}
.membros__oferta { min-width: 0; }
.membros__grau { margin: 0 0 4px; }
.acesso p { margin: 0; }
/* O pacote põe a nota em --sitio-tinta-fraca a 11px. Aqui ela carrega o
   texto que explica o que o login faz com a conta do Google — é a frase
   que decide se a pessoa autoriza o app, não legenda decorativa. Sobe pra
   tinta secundária (medido ~7:1 sobre --sitio-superficie, contra ~3,3:1 da
   fraca) e pra 12px/19px. */
.acesso__nota { color: var(--sitio-tinta-secundaria); font-size: 12px; line-height: 19px; }
/* O botão de entrar é escrito pelo membros.js (ver §5, mais abaixo) — sem
   portão de pé, esta regra não tem em que casar, e é isso mesmo. */
.acesso__acao { display: flex; }
.acesso__acao .acao { width: 100%; }
/* `<h3>` desde 14/08/2026: é o título de um painel dentro da seção 02, não
   de uma seção irmã — ver o comentário em `_acao_visitante`. */
.acesso h3 {
  margin: 0;
  font-family: var(--voz-funcional);
  font-size: var(--sitio-ficha-corpo);
  line-height: var(--sitio-ficha-entrelinha);
  font-weight: 400;
  letter-spacing: -.014em;
  color: var(--sitio-tinta-cheia);
}

@media (max-width: 900px) {
  /* A coluna de 340px do pacote não cabe: a grade vira uma coluna e o fio
     vertical vira um fio horizontal — a divisão continua legível, deitada. */
  #acao-membro { grid-template-columns: minmax(0, 1fr); gap: 22px; }
  #acao-membro .membros__fio { height: 1px; }
  .acesso { align-self: stretch; }
}

/* O estado de MEMBRO. `membros.js` esvazia #acao-membro, escreve o bloco
 * com createElement/textContent e marca `data-estado="membro"` — nada
 * disso existe no HTML servido, nem escondido por `hidden` ou por CSS.
 * Este seletor é o que desfaz a grade de duas colunas do estado de
 * visitante; ele NÃO revela nada, porque não há nada pra revelar até o JS
 * ter construído o bloco. */
#acao-membro[data-estado="membro"] {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px 28px;
}
.acao-membro-logado {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px 28px;
  width: 100%;
}
.acao-membro-logado__saudacao {
  margin: 0;
  font-family: var(--voz-funcional);
  font-size: var(--sitio-ficha-corpo);
  line-height: var(--sitio-ficha-entrelinha);
  color: var(--sitio-tinta-cheia);
}
.acao-membro-logado__saudacao strong { font-weight: 500; }
.acao-membro-logado__acoes {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0;
  flex-wrap: wrap;
}

/* O botão de login, também escrito pelo JS (a rota /membros/entrar é
 * proxiada pelo nginx, nunca um arquivo em dist/ — o mesmo motivo pelo
 * qual /membros/sair já nascia no cliente desde a Task 8).
 *
 * `.acesso__youtube` do pacote é `background:#ff0000;color:#fff`, e essa
 * dupla mede 4,0:1 — abaixo do piso de 4,5:1 pra texto. Pior: a cor nem
 * chega a aplicar, porque `.acesso__youtube` (0,1,0) perde de `.sitio a`
 * (0,1,1) e o rótulo renderiza âmbar sobre vermelho. O achado está
 * registrado em css/sitio-web.css §5, que perdeu a correção quando a home
 * tirou o painel; aqui ele volta a existir, então a correção volta junto.
 *
 * #c00000 com #ffffff mede 6,04:1. Escurecer o fundo, nunca clarear o
 * :hover — clarear pioraria. Escopado com o elemento pra vencer de fato. */
.sitio a.acesso__youtube {
  justify-content: center;
  background-color: #c00000;
  color: #ffffff;
  border-color: transparent;
}
.sitio a.acesso__youtube:hover { background-color: #a80000; color: #ffffff; }
.sitio a.acesso__youtube:focus-visible {
  outline: 2px solid var(--sitio-sinal);
  outline-offset: 2px;
}
.acesso__youtube svg { width: 18px; height: 18px; }

/* ── 6 · Os cartões de relatório ──────────────────────────────────────── */

.fichas {
  display: grid;
  /* `auto-fit`, não `auto-fill`: com DOIS relatórios a diferença é uma
     coluna vazia de 300px à direita contra dois cartões que dividem a
     linha inteira. Colunas que não recebem item colapsam. */
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 16px;
  margin-top: 28px;
}
.ficha--relatorio .ficha__corpo { gap: 12px; padding: 22px; }
.ficha__selos {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  font-family: var(--voz-sistema);
  font-size: 11px;
  letter-spacing: .06em;
  /* --sitio-tinta-fraca mede 3,1:1 sobre a superfície — abaixo do piso
     de 4,5:1 pra texto. A secundária mede 5,99:1. */
  color: var(--sitio-tinta-secundaria);
}
.ficha__chave { text-transform: uppercase; letter-spacing: .12em; }
.ficha__porte { display: inline-flex; align-items: center; gap: 8px; }
.ficha__porte-nome { color: var(--sitio-tinta-cheia); }
/* O cartão inteiro é a área de clique, não só o título: o <a> se estende
 * por cima da ficha com um ::after posicionado. O link continua sendo UM
 * <a> de verdade no HTML (leitor de tela e Tab enxergam um só), e o texto
 * do cartão continua selecionável fora dele. */
.ficha--relatorio { position: relative; }
.sitio .ficha__nome a { color: var(--sitio-tinta-cheia); }
.ficha__nome a::after { content: ""; position: absolute; inset: 0; }
.ficha--relatorio:hover .ficha__nome a { color: var(--sitio-sinal); }
.ficha__nome a:focus-visible {
  outline: 2px solid var(--sitio-sinal);
  outline-offset: 4px;
  border-radius: 3px;
}
.ficha--relatorio .ficha__pe {
  justify-content: space-between;
  align-items: center;
  padding: 0 22px 22px;
  color: var(--sitio-tinta-secundaria);
}
.ficha__marca {
  font-family: var(--voz-sistema);
  font-size: 11px;
  letter-spacing: .12em;
  text-transform: uppercase;
  /* --sitio-tinta-fraca mede ~3,3:1 sobre a superfície; a secundária ~7:1.
     Mesma medida que css/home.css já fez pro .ficha__breve. */
  color: var(--sitio-tinta-secundaria);
}

/* ── 6b · O relatório solitário vira o destaque da seção ──────────────── */

/* Enquanto houver UM relatório publicado, a seção 03 é a única do hub que
   não preenche a largura — e é justamente a que converte: o único destino
   pago da página. Medido antes desta regra: 620px de cartão numa trilha de
   1192px (52% em 1440 e 1920, 58% em 1180), com a seção 02 acima e a 04
   abaixo ocupando tudo. Um bloco pequeno e encostado à esquerda num campo
   vazio não lê como "este é o item principal"; lê como "faltou carregar
   alguma coisa".
   A marcação é a MESMA dos outros cartões — quem decide é o
   `:has(> :only-child)`. Quando o segundo relatório entrar, a grade volta
   sozinha, sem ninguém precisar lembrar de desfazer nada. */
.fichas:has(> :only-child) { grid-template-columns: minmax(0, 1fr); }

@media (min-width: 901px) {
  /* `display: contents` no corpo pra que selos, nome e deck virem itens da
     MESMA grade do cartão — sem isso o rail da esquerda não teria como
     alinhar com o texto. O corpo é um `<div>` sem papel semântico, então
     não some da árvore de acessibilidade (o defeito conhecido do
     `display:contents` vale pra elementos COM papel: listas, botões). */
  .fichas:has(> :only-child) .ficha--relatorio {
    display: grid;
    grid-template-columns: 188px minmax(0, 1fr) minmax(0, auto);
    grid-template-areas:
      "meta nome acao"
      "meta deck acao";
    align-items: center;
    column-gap: 36px;
    row-gap: 12px;
    padding: 34px 36px;
  }
  .fichas:has(> :only-child) .ficha--relatorio .ficha__corpo { display: contents; }

  /* O rail: rótulo, selo com o porte por extenso, data — na vertical,
     separado do texto pelo mesmo fio que divide o painel de acesso. */
  .fichas:has(> :only-child) .ficha__selos {
    grid-area: meta;
    align-self: stretch;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    gap: 12px;
    padding-right: 28px;
    border-right: 1px solid var(--sitio-traco);
  }
  .fichas:has(> :only-child) .ficha__nome { grid-area: nome; }
  .fichas:has(> :only-child) .ficha__deck {
    grid-area: deck;
    /* A escala de deck do sítio, não os 14px do cartão de grade: aqui o
       veredito é a única frase do bloco e tem largura de sobra. */
    font-size: var(--sitio-deck-corpo);
    line-height: var(--sitio-deck-entrelinha);
    max-width: 62ch;
  }
  /* O pé deixa de ser rodapé e vira a ação, ancorada à direita. A área de
     clique continua sendo o cartão inteiro (`.ficha__nome a::after`), e o
     link continua sendo UM <a> só. */
  .fichas:has(> :only-child) .ficha__pe {
    grid-area: acao;
    align-self: center;
    gap: 10px;
    padding: 13px 18px;
    border: 1px solid var(--sitio-traco-forte);
    border-radius: var(--sitio-raio-fino);
  }
  /* --sitio-sinal (#f09400) sobre --sitio-superficie (#080d13) mede 8,3:1. */
  .fichas:has(> :only-child) .ficha__pe,
  .fichas:has(> :only-child) .ficha__marca { color: var(--sitio-sinal); }
  .fichas:has(> :only-child) .ficha--relatorio:hover .ficha__pe {
    border-color: color-mix(in srgb, var(--sitio-sinal) 55%, transparent);
    background-color: color-mix(in srgb, var(--sitio-sinal) 10%, transparent);
  }
}

/* ── 7 · O que a bateria mede ─────────────────────────────────────────── */

.bateria {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 16px;
  margin-top: 28px;
}
.bateria__grupo {
  border: 1px solid var(--sitio-traco);
  border-radius: var(--sitio-raio);
  background-color: var(--sitio-superficie);
  box-shadow: var(--sitio-relevo-baixo), var(--sitio-luz-de-bordo);
  padding: 18px 20px 8px;
}
.bateria__rotulo {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  font-family: var(--voz-sistema);
  font-size: var(--sitio-rotulo-corpo);
  line-height: var(--sitio-rotulo-entrelinha);
  letter-spacing: var(--sitio-rotulo-espacamento);
  text-transform: uppercase;
  /* --sitio-tinta-fraca mede 3,1:1 sobre a superfície — abaixo do piso
     de 4,5:1 pra texto. A secundária mede 5,99:1. */
  color: var(--sitio-tinta-secundaria);
}
.bateria__rotulo i {
  font-style: normal;
  color: var(--sitio-sinal);
  font-variant-numeric: tabular-nums;
}
.bateria__lista { list-style: none; margin: 6px 0 0; padding: 0; }
.bateria__lista li {
  display: grid;
  grid-template-columns: 86px minmax(0, 1fr);
  gap: 14px;
  align-items: baseline;
  padding: 11px 0;
  border-top: 1px solid var(--sitio-traco);
  font-size: 14px;
  line-height: 21px;
  color: var(--sitio-tinta-secundaria);
}
.bateria__lista li:first-child { border-top: 0; }
.bateria__lista b {
  font-family: var(--voz-sistema);
  font-weight: 400;
  font-size: 12px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--sitio-tinta-cheia);
}

/* ── 7b · A legenda do porte ──────────────────────────────────────────── */

/* Vinte e dois selos de uma letra, sem legenda em lugar nenhum, numa página
   que se vende como "aqui você entende o método". Pior: `F` marca 16 das
   21 linhas, e `F` sozinho lê como NOTA. A legenda fecha a seção 04 — as
   células dizem o que todo modelo enfrenta, o porte diz quem é o modelo.
   Mesma receita de superfície dos painéis acima; nada de peça nova. */
.portes {
  margin-top: 16px;
  padding: 18px 20px 20px;
  border: 1px solid var(--sitio-traco);
  border-radius: var(--sitio-raio);
  background-color: var(--sitio-superficie);
  box-shadow: var(--sitio-relevo-baixo), var(--sitio-luz-de-bordo);
}
.portes__rotulo {
  margin: 0;
  font-family: var(--voz-sistema);
  font-size: var(--sitio-rotulo-corpo);
  line-height: var(--sitio-rotulo-entrelinha);
  letter-spacing: var(--sitio-rotulo-espacamento);
  text-transform: uppercase;
  color: var(--sitio-tinta-secundaria);
}
.portes__deck {
  margin: 8px 0 0;
  max-width: 78ch;
  font-size: 14px;
  line-height: 22px;
  color: var(--sitio-tinta-secundaria);
  text-wrap: pretty;
}
.portes__deck b { font-weight: 500; color: var(--sitio-tinta-cheia); }
.portes__lista {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 4px 28px;
  margin: 16px 0 0;
}
.porte {
  display: grid;
  gap: 6px;
  padding-top: 14px;
  border-top: 1px solid var(--sitio-traco);
}
.porte__chave { display: flex; align-items: center; gap: 10px; }
.porte__nome {
  font-family: var(--voz-sistema);
  font-size: 12px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--sitio-tinta-cheia);
}
.porte dd { margin: 0; }
.porte__definicao { font-size: 14px; line-height: 21px; color: var(--sitio-tinta-secundaria); }
.porte__onde {
  font-family: var(--voz-sistema);
  font-size: 12px;
  line-height: 19px;
  /* Sem `opacity` pra "rebaixar": medido, .82 sobre a secundária cai pra
     4,38:1 e fura o piso de 4,5:1 — a diferença de peso aqui vem da voz de
     sistema e do corpo menor, não de apagar a cor. A secundária mede
     5,99:1 sobre a superfície. */
  color: var(--sitio-tinta-secundaria);
}

/* ── 8 · As linhas que só existem na régua ────────────────────────────── */

/* Antes eram cartões do MESMO tamanho do único relatório publicado: vinte
 * becos sem saída com o peso visual do item clicável, e ~3.800px de
 * rolagem. Viraram linhas de livro-caixa — e ainda assim eram vinte delas
 * de altura cheia: 1.030px de caixa dentro de 1.290px de seção (medido a
 * 1440), pra uma seção que é, no fundo, "o que mais já passou por aqui".
 *
 * Agora é uma JANELA: altura fixa, rolagem própria, e uma busca que filtra
 * ao vivo escrita por `membros.js` (ver §8b). Duas coisas mudaram junto:
 *
 * 1. A caixa ganhou margem interna (`padding: 8px`). As réguas de cada
 *    linha iam de borda a borda do cartão e encostavam nela — o defeito que
 *    o dono chamou de "sem margem". O texto continua a 20px da borda do
 *    cartão (8 daqui + 12 da linha); o que mudou é que o TRAÇO para antes.
 * 2. Quem rola é `.linhas-regua__janela`, e a chave das colunas ficou
 *    DENTRO dela, `sticky`. Fora, ela sairia da vista na primeira rolada, e
 *    com barra de rolagem visível passaria a medir uma largura diferente da
 *    das linhas de dado — o desalinhamento que
 *    `tests/test_membros_hub_navegador.py` guarda mede exatamente isso. */
.linhas-regua {
  margin: 28px 0 0;
  border: 1px solid var(--sitio-traco);
  border-radius: var(--sitio-raio);
  background-color: var(--sitio-superficie);
  box-shadow: var(--sitio-relevo-baixo), var(--sitio-luz-de-bordo);
  overflow: hidden;
  padding: 8px;
}
/* A janela. 296px cabe seis linhas inteiras e corta a sétima pela metade,
   que é o que faz alguém entender que há mais coisa embaixo sem precisar de
   nenhuma affordance extra.

   `tabindex="0"` vem da marcação (pagina.py): região rolável que só o mouse
   alcança é armadilha de teclado. `scrollbar-gutter: stable` reserva a
   calha sempre — sem ela, filtrar até a lista caber faz a barra sumir e as
   três colunas pularem para o lado. */
.linhas-regua__janela {
  max-height: 296px;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-gutter: stable;
  border-radius: var(--sitio-raio-fino);
}
.linhas-regua__janela:focus-visible {
  outline: 2px solid var(--sitio-sinal);
  outline-offset: 2px;
}
.linhas-regua ul { list-style: none; margin: 0; padding: 0; }
.linha-regua {
  display: grid;
  /* A coluna do meio era `auto`. Deixou de ser porque cada linha é a sua
     PRÓPRIA grade: com `auto`, a chave ("porte", ~46px) e o selo ("F",
     ~30px) resolvem larguras diferentes e a chave não cai sobre a coluna
     que ela nomeia. 120px cabe o par mais largo (`M` + `LOCAL`, medido em
     108px) e todo mundo alinha pela direita. */
  grid-template-columns: minmax(0, 1fr) 120px 120px;
  gap: 16px;
  align-items: center;
  /* 12px na horizontal, não 20: os outros 8 são o `padding` da caixa, que é
     o que tira o traço de cima da borda. O texto continua onde estava. */
  padding: 12px;
  border-top: 1px solid var(--sitio-traco);
}
.linha-regua:first-child { border-top: 0; }
/* Some com a linha filtrada. Classe, e não o atributo `hidden`: o hub tem
   um teste que conta `[hidden]` no DOM renderizado e exige zero — a regra
   ali é que nada de membro pode existir escondido, e a forma de garantir
   isso é o atributo não aparecer em lugar nenhum desta página. */
.linha-regua.is-fora { display: none; }
/* A chave das colunas: sem ela a coluna do meio é uma letra sem dimensão
   declarada. Fica na voz de sistema, no corpo de rótulo, e não compete com
   as linhas de dado. Fundo opaco porque ela é `sticky`: sem ele, as linhas
   passam por baixo e se leem através dela. */
.linhas-regua__chaves {
  position: sticky;
  top: 0;
  z-index: 1;
  background-color: var(--sitio-superficie);
  margin: 0;
  border-top: 0;
  padding-top: 12px;
  padding-bottom: 10px;
  font-family: var(--voz-sistema);
  font-size: 11px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--sitio-tinta-secundaria);
  /* "ÚLTIMA BATERIA" mede ~109px com este tracking: a coluna da data foi de
     104px pra 120px pra caber numa linha só. Os 16px saem da coluna do
     nome, que é `1fr`. */
  white-space: nowrap;
}
.linhas-regua__chaves span:nth-child(2),
.linhas-regua__chaves span:last-child { text-align: right; }
.linhas-regua__chaves + ul .linha-regua:first-child { border-top: 1px solid var(--sitio-traco); }
.linha-regua__nome {
  font-size: 14px;
  line-height: 21px;
  color: var(--sitio-tinta-cheia);
  /* Nomes combinados ("GPT-5.6 Luna / Terra / Sol · Fable 5") são longos e
     não têm ponto de quebra confortável — deixa quebrar em vez de esticar
     a página. */
  overflow-wrap: anywhere;
}
.linha-regua__tier { display: flex; align-items: center; justify-content: flex-end; gap: 8px; }
.linha-regua__data {
  font-family: var(--voz-sistema);
  font-size: 12px;
  /* --sitio-tinta-fraca mede 3,1:1 sobre a superfície — abaixo do piso
     de 4,5:1 pra texto. A secundária mede 5,99:1. */
  color: var(--sitio-tinta-secundaria);
  text-align: right;
  font-variant-numeric: tabular-nums;
}
/* Era `--sitio-tinta-fraca`, que mede 3,1:1 sobre a superfície. Passava
   porque o conteúdo era um glifo de vão, e vão não é texto. Agora são duas
   palavras de verdade ("sem data"), e texto de verdade tem piso de 4,5:1 —
   fica na secundária, que mede 5,99:1, como o resto da coluna. */
.linha-regua__sem-data { color: var(--sitio-tinta-secundaria); }

/* ── 8b · A busca que filtra a janela ─────────────────────────────────── */

/* Toda esta faixa nasce em `static/membros.js`, nunca no HTML servido — ver
 * o docstring de `_linhas_restantes` em pagina.py. Sem JS nada disto existe
 * e a lista chega inteira, que é o estado certo pra falhar.
 *
 * VAZIO DECLARADO: o pacote do sítio não tem família de campo de busca nem
 * de barra de ferramentas. Tem UM campo de texto, `.acesso__campo`
 * (elementos-sitio.css), e é dele que a peça é feita — a marcação compõe
 * `.acesso__campo` com `.busca-regua__campo`, e o que está aqui embaixo é
 * só a diferença (altura menor, porque esta faixa é o cabeçalho de uma
 * janela e não o miolo do bloco de acesso). Copiar os valores de lá pra cá
 * teria dado a mesma tela hoje e duas superfícies divergentes depois. */
.busca-regua {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 6px 12px 14px;
}
.busca-regua__rotulo {
  font-family: var(--voz-sistema);
  font-size: 11px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--sitio-tinta-secundaria);
}
.busca-regua__campo { height: 38px; }
/* O `x` que o Chrome/Safari desenham em `type="search"` some com a folha do
   pacote (o input é `background: transparent`) e reaparece como um quadrado
   claro. O Escape limpa o campo, e é o que a dica do rótulo promete. */
.busca-regua__campo input::-webkit-search-cancel-button { display: none; }
.busca-regua__contagem {
  margin: 0;
  font-family: var(--voz-sistema);
  font-size: 12px;
  color: var(--sitio-tinta-secundaria);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.busca-regua__contagem b { color: var(--sitio-tinta-cheia); font-weight: 400; }
/* O anúncio pra leitor de tela. Ele existe SEPARADO da contagem visível de
   propósito: a visível atualiza a cada tecla (é o retorno imediato de quem
   vê), e esta espera a digitação parar. Um `aria-live` na contagem visível
   faria o leitor recitar um número novo a cada letra. */
.busca-regua__anuncio {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
/* O nada encontrado. Mora dentro da janela, onde as linhas estariam. */
.linhas-regua__vazio {
  margin: 0;
  padding: 20px 12px 24px;
  font-size: 13px;
  line-height: 21px;
  color: var(--sitio-tinta-secundaria);
}
.linhas-regua__vazio b { color: var(--sitio-tinta-cheia); font-weight: 400; }
.linhas-regua__vazio.is-fora { display: none; }

@media (max-width: 560px) {
  /* Rótulo e contagem saem das laterais e a faixa vira duas linhas: com
     três colunas num viewport estreito o campo fica com ~90px e não cabe
     nem o termo digitado. O rótulo continua no DOM (é o `<label>` do
     campo), só deixa de disputar largura com ele. */
  .busca-regua {
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 8px 12px;
  }
  .busca-regua__rotulo { grid-column: 1; }
  .busca-regua__contagem { grid-column: 2; text-align: right; }
  .busca-regua__campo { grid-column: 1 / -1; grid-row: 2; }

  .linha-regua {
    grid-template-columns: minmax(0, 1fr) auto;
    row-gap: 6px;
  }
  .linha-regua__data { grid-column: 1 / -1; text-align: left; }
  /* Sem colunas fixas não há coluna pra nomear: a data desce pra própria
     linha e a chave de três palavras passaria a mentir sobre o arranjo.
     Some. Quem usa leitor de tela não perde nada — o rótulo do porte
     viaja no próprio selo (`aria-label`), e a legenda inteira está na
     seção 04, acima. */
  .linhas-regua__chaves { display: none; }
}

/* ── 9 · Os selos de tier ─────────────────────────────────────────────── */

/* `_tier()` é compartilhado com régua e relatório, que ainda leem
 * membros.css (pacote antigo). Aqui as MESMAS classes ganham os tokens do
 * sítio. Nada de `--escala--1`/`--espaco-1`/`--fonte-mono`: medido, esses
 * três nunca existiram em nenhum dos dois pacotes — membros.css os cita há
 * meses e o navegador descarta a declaração inteira, calado. */
.selo {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 5px;
  font-family: var(--voz-sistema);
  font-size: 11px;
  line-height: 16px;
  letter-spacing: .06em;
  border: 1px solid var(--sitio-traco-forte);
  color: var(--sitio-tinta-secundaria);
}
/* O tier é UMA letra (P/M/F). Largura mínima + numeração tabular pra que a
 * coluna alinhe entre linhas, em vez de dançar conforme o glifo. */
.selo-tier { min-width: 2.2em; text-align: center; font-variant-numeric: tabular-nums; }
/* --casa (#52a5ba) sobre --sitio-superficie mede 6,7:1. O selo LOCAL é a
 * única distinção de tier que o vídeo trata como categoria à parte. */
.selo-local {
  border-color: color-mix(in srgb, var(--casa) 45%, transparent);
  color: var(--casa);
}

/* ── Movimento ────────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  .sitio *,
  .sitio *::before,
  .sitio *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}
