/* css/tutoriais-hub.css — a folha do ÍNDICE de tutoriais (`/tutoriais/`).

   Última na ordem de carga:
     /ds/sitio/tokens.css → sistema.css → elementos.css → elementos-sitio.css
     → css/sitio-web.css → css/sitio-chrome.css → ESTA.

   O sistema desenha `.cromo`, `.secao`, `.ficha`, `.medidor`, `.prompt`,
   `.chip`, `.recado`, `.acao`, `.rodape` e `.sitio__grade`. Aqui moram só
   três coisas: a grade que arranja essas peças na página, a ficha técnica de
   cada guia (`.hub-spec` — o pacote não tem lista de definição, e isto é dito,
   não fingido de peça do sistema) e os poucos overrides escopados por classe,
   cada um com o motivo escrito em cima.

   Nenhuma cor literal: só tokens do sítio. */

/* ── 0 · Utilidades ────────────────────────────────────── */

/* Rótulo que existe pra leitor de tela e não pra tela. O pacote não traz um
   equivalente (`.sr-only` era da camada antiga, `css/ds-web.css`, que esta
   página não carrega mais). */
.hub-oculto {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ── 1 · A abertura ────────────────────────────────────── */

/* `.sitio__grade` (elementos-sitio.css) é `position:absolute;inset:0` com
   máscara radial — precisa de um pai posicionado, senão ancora no <body> e a
   malha cobre a página inteira. `isolation` prende o z-index dela ao bloco. */
.hub-abertura {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  border-bottom: 1px solid var(--sitio-traco);
}
.hub-abertura > .sitio__miolo {
  position: relative;
  z-index: 1;
}

.hub-capa {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 320px);
  gap: 56px;
  align-items: start;
  padding-bottom: 56px;
}

.hub-manchete {
  font-size: var(--sitio-manchete-corpo);
  line-height: var(--sitio-manchete-entrelinha);
  letter-spacing: -.022em;
  max-width: 16ch;
}
.hub-manchete__acento { color: var(--sitio-sinal); }

.hub-capa__deck {
  max-width: 62ch;
  font-size: var(--sitio-deck-corpo);
  line-height: var(--sitio-deck-entrelinha);
  margin-top: 20px;
}

/* `.medidor` (elementos-sitio.css) é `display:flex` sem quebra: na home ele
   mora numa linha larga e sobra espaço. Aqui divide a coluna com o recado, e
   os quatro itens precisam poder quebrar em duas linhas antes de estourar. O
   separador é `border-left` no item; ao quebrar, o primeiro de cada linha
   ficaria com fio à esquerda encostando na margem — daí o `row-gap` maior,
   que dá ar suficiente pra leitura sem precisar medir quem abre linha. */
.hub-numeros {
  flex-wrap: wrap;
  row-gap: 24px;
  margin-top: 40px;
}

/* O recado nasce girado 1,2° (o papel colado na mesa). Ele encosta na
   manchete de propósito: é a primeira coisa que responde "por onde eu
   começo?", e a resposta não pode estar depois de quatro cartões. */
.hub-recado {
  margin-top: 64px;
  justify-self: end;
  max-width: 320px;
}
/* Sobre papel claro, `--sitio-sinal` mede 1,98:1 — reprovado. O token
   escurecido vem de `css/sitio-web.css` (seção 3), que já o usa em
   `.rodape__legal a` pelo mesmo motivo. */
.hub-recado a {
  color: var(--sitio-papel-realce);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.hub-recado a:hover { color: var(--sitio-papel-realce-forte); }

/* ── 2 · O filtro ──────────────────────────────────────── */

.hub-lista { padding-top: 56px; }

.hub-filtro { margin-top: 32px; }
.hub-filtro[hidden] { display: none; }

.hub-filtro__estado {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--sitio-traco);
}
.hub-filtro__conta {
  margin: 0;
  font-family: var(--voz-sistema);
  font-size: 12px;
  color: var(--sitio-tinta-secundaria);
  font-variant-numeric: tabular-nums;
}
.hub-filtro__limpar[hidden] { display: none; }

/* `.chip` (elementos-sitio.css) não repõe indicador de foco, e o padrão do
   navegador some contra a borda escura dele. Mesmo tratamento que
   `css/sitio-web.css` já dá ao `.prompt__entrada`, pelo mesmo motivo. */
.hub-filtro .chip:focus-visible {
  outline: 2px solid var(--sitio-sinal);
  outline-offset: 2px;
}

/* `type="search"` traz o "✕" nativo do WebKit — azul de sistema, do tamanho
   que o navegador quiser, no meio de uma caixa de terminal. A página já tem
   duas saídas próprias (o botão "Limpar filtro" e o Esc), então o controle
   nativo é ruído duplicado, não afordância a mais. */
.hub-filtro .prompt__entrada::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
}

/* A dica anuncia um atalho de TECLADO. Onde não há teclado ela é só ruído
   que promete uma coisa que não existe — mesma decisão que a home toma com as
   setas do carrossel do canal. */
.hub-filtro .prompt__dica { user-select: none; }
@media (hover: none) {
  .hub-filtro .prompt__dica { display: none; }
}

/* ── 3 · A grade de guias ──────────────────────────────── */

/* Duas colunas, não `auto-fit`: com quatro guias, `auto-fit` monta três
   colunas na largura do miolo (1240) e deixa o quarto sozinho e esticado numa
   linha própria — uma assimetria que o olho lê como erro. Duas colunas dão
   2×2 exato hoje e 3×2 quando forem seis.

   Com um resultado só, a linha fica com metade vazia — de propósito. A
   alternativa (esticar o cartão pra largura do miolo) faz um cartão de 1240px
   com uma miniatura de 700px de altura, e faz a largura do cartão MUDAR
   conforme o filtro: o texto reflui a cada tecla digitada. Vão vazio previsível
   é melhor que layout que se mexe embaixo de quem está lendo. */
.hub-guias {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 24px;
  margin-top: 32px;
}

/* `.ficha` é `display:flex` (elementos-sitio.css), e display vence o atributo
   `hidden` — sem isto o filtro roda, marca tudo certo, e nenhum cartão some.
   Falha silenciosa clássica: o contador diz "1 de 4" com os quatro na tela. */
.hub-guia[hidden] { display: none; }

.hub-guia { position: relative; }

/* `.ficha__cena` é 176px de altura fixa (elementos-sitio.css), calibrada pros
   pictogramas 640×352 da home. Aqui a cena é a miniatura do vídeo — 1280×720
   com texto embutido na arte —, e um recorte `cover` de 600×176 (3,4:1) corta
   fora justamente o texto. A proporção real preserva a arte inteira, e a
   miniatura é o reconhecimento mais rápido que o índice tem: quem viu o vídeo
   identifica o guia antes de ler o título. `image-rendering` volta pro padrão
   porque `pixelated` (do pacote, correto pra pixel art) destrói uma foto. */
.hub-guia__cena {
  height: auto;
  aspect-ratio: 16 / 9;
}
.hub-guia__thumb {
  width: 100%;
  height: 100%;
  object-fit: cover;
  image-rendering: auto;
}

.hub-guia__selo {
  position: absolute;
  top: 12px;
  left: 12px;
  z-index: 1;
  font-family: var(--voz-sistema);
  font-size: 10px;
  letter-spacing: .12em;
  text-transform: uppercase;
  padding: 5px 9px;
  border-radius: 5px;
  color: var(--sitio-tinta-cheia);
  background-color: color-mix(in srgb, var(--sitio-rebaixo) 82%, transparent);
  border: 1px solid var(--sitio-traco-forte);
  backdrop-filter: blur(4px);
}
/* `.ficha__cena > *` é `position:absolute;inset:0;width/height:100%` no
   pacote — regra pensada pra imagem de fundo. O selo é rótulo, não camada:
   sem isto ele estica pela cena inteira e o texto pousa no canto de uma caixa
   invisível de 600×338. */
.hub-guia__cena > .hub-guia__selo {
  position: absolute;
  inset: auto auto auto 12px;
  top: 12px;
  width: auto;
  height: auto;
}

.hub-guia__tarjas {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
/* A tarja de tema herda `--ficha-tinta` (o tema colore o cartão). A de nível
   não é tema: é medida, e medida é neutra. */
.hub-guia__nivel {
  color: var(--sitio-tinta-secundaria);
  background-color: var(--sitio-superficie-alta);
  border: 1px solid var(--sitio-traco);
}

/* `.sitio a` pinta todo link de âmbar. O título do cartão é título antes de
   ser link — o âmbar aqui competiria com o marcador da seção e com o "Abrir
   guia" do pé, que são os dois lugares onde âmbar quer dizer "clique".

   `a.hub-guia__elo`, não `.hub-guia__elo`: `.sitio a` é (0,1,1) e a classe
   sozinha é (0,1,0) — perde por especificidade, e a única pista de que perdeu
   é o título ficar laranja. Mesmo motivo do `a.cromo__marca` em
   `css/sitio-chrome.css`. */
a.hub-guia__elo,
a.hub-guia__elo:hover {
  color: var(--sitio-tinta-cheia);
  text-decoration: none;
}
/* A área de clique é o cartão inteiro, mas o NOME acessível do link é só o
   título — o alvo grande fica pro mouse e pro toque, sem transformar sessenta
   palavras de ficha técnica no rótulo de um único link. */
.hub-guia__elo::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: var(--sitio-raio);
}
/* …com uma janela recortada: a ficha técnica sobe pra cima do alvo. Uma camada
   que cobre o cartão inteiro rouba os eventos de mouse do texto embaixo, e com
   eles a SELEÇÃO — ninguém copia "Node.js 18+" nem "R$ 95/mês" de um cartão
   assim. Levantar só a ficha devolve a seleção justamente onde há valor pra
   copiar, e de quebra separa os dois gestos: no resto do cartão você ESCOLHE
   (cursor de link, clique navega), na ficha você LÊ (cursor de texto, clique
   não tira você da página no meio da leitura). */
.hub-guia .hub-spec {
  position: relative;
  z-index: 1;
  cursor: auto;
}
.hub-guia__elo:focus-visible {
  outline: 2px solid var(--sitio-sinal);
  outline-offset: 3px;
  border-radius: var(--sitio-raio-miudo);
}

/* ── 4 · A ficha técnica ───────────────────────────────── */

/* O pacote não tem lista de definição — nem `.spec`, nem `.tabela`, nem nada
   com esta forma. Ela é peça DESTA página, e o nome (`hub-`) diz isso: não se
   passa por componente do sistema. O que ela usa do sistema são só tokens.

   Por que ela existe: um índice é uma promessa, e a promessa que um índice de
   tutorial deve é "você vai saber, antes de clicar, se isto é pra você".
   Precisa / No fim / Custa são as três perguntas que fazem alguém abandonar um
   tutorial no meio — e todas as três têm resposta escrita dentro dos guias. */
.hub-spec {
  display: grid;
  gap: 0;
  margin: 6px 0 0;
}
.hub-spec__linha {
  display: grid;
  grid-template-columns: 78px minmax(0, 1fr);
  gap: 16px;
  align-items: baseline;
  padding: 10px 0;
  border-top: 1px solid var(--sitio-traco);
}
.hub-spec__chave {
  font-family: var(--voz-sistema);
  font-size: 10px;
  line-height: 20px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--sitio-tinta-fraca);
}
.hub-spec__valor {
  margin: 0;
  font-size: 14px;
  line-height: 22px;
  color: var(--sitio-tinta-secundaria);
  text-wrap: pretty;
}
.hub-spec__valor code {
  font-family: var(--voz-sistema);
  font-size: .92em;
  color: var(--sitio-tinta-cheia);
}

/* ── 5 · O pé do cartão ────────────────────────────────── */

/* `.ficha__pe` é `justify-content:flex-end` (o "+" da home mora sozinho à
   direita). Aqui o pé carrega duas coisas de peso diferente. */
.hub-guia__pe {
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  padding-top: 4px;
  border-top: 1px solid var(--sitio-traco);
  margin: 0 20px;
  padding-inline: 0;
}
.hub-guia__meta {
  font-family: var(--voz-sistema);
  font-size: 11px;
  color: var(--sitio-tinta-fraca);
  font-variant-numeric: tabular-nums;
}
.hub-guia__abrir {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--voz-sistema);
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ficha-tinta, var(--sitio-sinal));
  white-space: nowrap;
}
.hub-guia__abrir svg {
  transition: transform var(--t-toque) var(--e-entrada);
}
.hub-guia:hover .hub-guia__abrir svg { transform: translateX(3px); }

/* ── 6 · O vazio ───────────────────────────────────────── */

.hub-vazio {
  margin-top: 24px;
  padding: 40px 24px;
  border: 1px dashed var(--sitio-traco-forte);
  border-radius: var(--sitio-raio);
  background-color: var(--sitio-superficie);
  text-align: center;
}
.hub-vazio[hidden] { display: none; }
.hub-vazio__rotulo {
  margin: 0;
  font-family: var(--voz-sistema);
  font-size: 10px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--sitio-tinta-fraca);
}
.hub-vazio__texto {
  margin: 10px 0 0;
  font-size: var(--sitio-deck-corpo);
  line-height: var(--sitio-deck-entrelinha);
  color: var(--sitio-tinta-secundaria);
}
.hub-vazio__texto strong {
  font-weight: 400;
  color: var(--sitio-tinta-cheia);
}
.hub-vazio__acoes {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  justify-content: center;
  margin-top: 24px;
}

/* ── 7 · O rodapé ──────────────────────────────────────── */

/* `.rodape` é `white-space:nowrap` no pacote (a home põe três coisas curtas
   nele). Aqui são três grupos, um deles com cinco redes: sem permitir quebra,
   eles se sobrepõem antes de o miolo estreitar. */
.rodape .sitio__miolo {
  flex-wrap: wrap;
  row-gap: 12px;
  white-space: normal;
}
.hub-redes {
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
  font-family: var(--voz-sistema);
  font-size: 12px;
}
.hub-redes a { color: var(--sitio-papel-realce); }
.hub-redes a:hover { color: var(--sitio-papel-realce-forte); }
.rodape__legal {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px;
}

/* ── 8 · O reflow ──────────────────────────────────────── */

/* 1180 é o breakpoint do cromo compacto (css/sitio-chrome.css) — a página
   inteira muda de postura no mesmo ponto, e não num terceiro valor inventado
   só pra esta folha. */
@media (max-width: 1180px) {
  .hub-capa {
    grid-template-columns: minmax(0, 1fr);
    gap: 32px;
  }
  .hub-recado {
    margin-top: 8px;
    justify-self: start;
  }
  .hub-manchete { max-width: none; }
}

/* Abaixo de 900 a coluna de um cartão fica estreita demais pra ficha técnica:
   a chave (78px) come mais de um quinto da largura e o valor quebra em duas
   palavras por linha. Uma coluna só. */
@media (max-width: 900px) {
  .hub-guias { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 680px) {
  .hub-lista { padding-top: 32px; }
  /* `.secao__cabeca` é flex com `justify-content:space-between` e o elo do
     canal na ponta direita: numa coluna de 350px o título e o elo brigam pelo
     mesmo espaço e os dois quebram em palavras soltas. */
  .hub-lista .secao__cabeca {
    flex-direction: column;
    align-items: flex-start;
    gap: 20px;
  }
  /* `.prompt__campo` é flex sem wrap (elementos-sitio.css): o input tem
     largura mínima de UA (~170px) que o `flex:1` não vence, e a dica não
     quebra — a soma estoura a coluna (medido: documento 411px numa tela de
     390). Mesma correção que a home aplica ao mesmo componente. */
  .hub-filtro .prompt__campo { flex-wrap: wrap; row-gap: 6px; }
  .hub-filtro .prompt__campo .prompt__dica { flex: 1 0 100%; padding-left: 30px; }
  .hub-numeros { gap: 20px; }
  /* O separador vertical do medidor não sobrevive a quatro itens numa tela de
     390px: vira fio solto no meio de linhas de uma coluna. */
  .medidor__item {
    padding-left: 20px;
  }
  .hub-spec__linha {
    grid-template-columns: minmax(0, 1fr);
    gap: 2px;
  }
  .hub-guia__pe {
    flex-wrap: wrap;
    gap: 8px;
  }
}
