/* shared/chassi.css
   Sistema visual dos brandbooks Terranova.

   Estrutura, medidas e comportamento seguem o formato de brandbook web
   consagrado (cadernos, listas numeradas, specimen tipografico, swatch
   com HEX/RGB/CMYK). O codigo e nosso.

   Toda cor e toda familia tipografica vem de tokens.css, emitido por
   marca. Os valores abaixo existem so para o arquivo abrir sozinho no
   navegador durante desenvolvimento.

   Defeito critico corrigido aqui: :root sem camada e :root em camada tem
   a MESMA especificidade; em especificidade empatada, quem carrega por
   ultimo no documento vence. tokens.css entra antes de chassi.css no
   template, entao este bloco, vindo depois com a mesma especificidade,
   sempre vencia a cascata e mascarava os tokens reais de qualquer marca.
   A regra de cascade layers do CSS resolve isso sem depender de ordem:
   declaracao sem camada sempre vence declaracao dentro de QUALQUER
   camada, nao importa a ordem de carregamento nem a especificidade do
   seletor. Colocando o fallback dentro de uma camada nomeada, o :root
   normal de tokens.css (sem camada) passa a vencer sempre, e o fallback
   continua valendo quando chassi.css abre sozinho (nada sem camada entra
   para disputar). */
@layer chassi-fallback {
  :root {
    --bg: #f3f3f3;
    --ink: #191919;
    --accent: #13e6ae;
    --sans: system-ui, sans-serif;
    --mono: ui-monospace, monospace;
    --display: var(--sans);
    --grad-marca: linear-gradient(90deg, var(--accent), var(--ink));
  }
}
/* fim dos fallbacks */

/* Este :root (sem camada, de proposito) e estrutural do chassi, nao
   fallback de marca: --muted, --line e --linha-forte sao derivadas de
   --ink (a marca nao tem como declarar as tres sozinha, senao colidiriam
   com a mesma propriedade vindas de fontes diferentes), e --container,
   --gutter e --ritmo sao medida de layout, nao token de identidade visual.
   Por isso NAO entram em @layer chassi-fallback: se entrassem, um tema
   que por acidente declarasse uma dessas seis chaves (ex.: tema.gutter)
   venceria a cascata e mudaria o layout do chassi de um jeito que ninguem
   pediu. A garantia de que nenhuma marca real declara essas chaves nao e
   so este comentario: brandbook/tokens.py rejeita a carga com ErroDeMarca
   se tema colidir com qualquer uma delas, e dois testes estaticos
   (tests/test_render.py::test_html_importa_tokens_e_chassi_nessa_ordem e
   tests/test_tokens.py::test_chaves_reservadas_do_chassi_batem_com_o_css_de_verdade)
   travam que nenhuma custom property declarada aqui fora de @layer bata
   com uma chave de tema possivel, e que a lista reservada em tokens.py
   bate exatamente com o que este bloco declara.

   --linha-forte (achados 19/24 da auditoria adversarial): --line (18% de
   --ink) mede so ~1,7:1 de contraste contra o --bg da FalaTerranova, bom
   o bastante pro friso decorativo entre itens de uma lista, mas abaixo do
   minimo 3:1 que WCAG 2.1 1.4.11 exige do indicador visual de um
   componente de interface (o contorno de um swatch de cor, o contorno de
   um botao). 50% foi calibrado (tests/test_chassi.py, medido com os
   tokens reais da FalaTerranova) para passar 3:1 nos dois temas, normal
   e invertido. */
:root {
  --muted: color-mix(in srgb, var(--ink) 55%, transparent);
  --line: color-mix(in srgb, var(--ink) 18%, transparent);
  --linha-forte: color-mix(in srgb, var(--ink) 50%, transparent);
  --container: 1440px;
  --gutter: 32px;
  --ritmo: 160px;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html {
  background: var(--bg);
  transition: background-color .8s cubic-bezier(.4, 0, .2, 1);
  scroll-behavior: smooth;
}

body {
  background: transparent;
  color: var(--ink);
  font-family: var(--sans);
  line-height: 1.4;
  -webkit-font-smoothing: antialiased;
  transition: color .8s cubic-bezier(.4, 0, .2, 1);
}

/* A inversao de tema troca fundo e tinta (html vira var(--ink), body vira
   var(--bg)), entao --muted, --line e --linha-forte tambem precisam
   trocar de base: sem isso os tres continuam misturados com --ink, que
   dentro de html.is-dark e a cor do FUNDO, nao mais da tinta. O resultado
   sem esta redefinicao e texto secundario (.item__text, .rotulo,
   .item__num) na mesma cor do fundo, contraste ~1:1, praticamente
   invisivel. As porcentagens de --muted/--line sobem em relacao ao :root
   (55% vira 62%, 18% vira 22%) porque a mistura aqui parte de --bg sobre
   um fundo --ink que pode ser mais claro que --ink era no :root; 62%/22%
   foram medidos no navegador para continuar passando AA (4.5:1) em texto
   normal com os tokens da FalaTerranova. --linha-forte fica em 50% dos
   dois lados (medido: passa 3:1 nos dois temas com os tokens da
   FalaTerranova, ver tests/test_chassi.py). */
html.is-dark {
  background: var(--ink);
  --muted: color-mix(in srgb, var(--bg) 62%, transparent);
  --line: color-mix(in srgb, var(--bg) 22%, transparent);
  --linha-forte: color-mix(in srgb, var(--bg) 50%, transparent);
}
html.is-dark body { color: var(--bg); }

/* .menu e .hdr pintam a propria superficie opaca a partir de --bg (abaixo),
   em vez de herdar do body: sem esta contraparte, a troca de tema muda a
   tinta herdada do body para var(--bg) mas deixa essas duas superficies
   ainda pintadas em var(--bg) tambem, texto na mesma cor do fundo,
   contraste 1:1. Medido no navegador antes desta correcao: com html.is-dark
   ativo, .menu background e .menu__lista a color chegavam ao MESMO rgb.
   Regra geral: todo componente que pinta uma superficie opaca a partir de
   --bg precisa desta contraparte. */
html.is-dark .menu,
html.is-dark .hdr { background: var(--ink); }

a { color: inherit; text-decoration: none; }
img, svg { max-width: 100%; display: block; }
/* Achados 10/13 da auditoria de tipografia: a folha de estilo do
   navegador (user agent) ja tem "code { font-family: monospace }" com a
   mesma especificidade de elemento; herdar var(--mono) do ancestral NAO
   basta, porque uma declaracao explicita (mesmo a do proprio navegador)
   sempre vence heranca, especificidade a parte. Isso deixava dois grupos
   de <code> presos no monospace generico do SO em vez do Mono da marca:
   os quatro blocos <pre class="colavel"><code> (achado 13: system prompt
   e prompts de imagem, o material que o usuario copia; pre.colavel
   computava a pilha certa, mas o <code> filho nao herdava) e o <code>
   inline dentro de paragrafo de conteudo (achado 10: um hex de cor e o
   nome de um arquivo, citados como codigo no meio da prosa). brand.json
   declara Mono para "numeros e dados"; codigo e dado tanto quanto os
   outros. Uma regra de elemento aqui, carregada depois da folha do
   navegador, resolve os dois de uma vez. */
code { font-family: var(--mono); }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

.wrap { max-width: var(--container); margin: 0 auto; width: 100%; }

.rotulo {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--muted);
}

/* Header ------------------------------------------------------------ */
/* background: var(--bg), nao transparent: o header e sticky e fica por
   cima do conteudo que rola por baixo dele. Transparente, o texto que
   passa por baixo (titulo de item, chip de swatch) divide o mesmo pixel
   da marca e da navegacao. A troca para var(--ink) em html.is-dark
   acompanha a mesma troca que html/body ja fazem, poucas linhas acima. */
.hdr {
  position: sticky; top: 0; z-index: 10;
  display: flex; justify-content: space-between; align-items: center;
  padding: 22px var(--gutter);
  border-bottom: 1px solid var(--line);
  background: var(--bg);
  transition: background-color .8s cubic-bezier(.4, 0, .2, 1), border-color .8s;
}
/* display: inline-flex + align-items (achado importante da auditoria de
   acabamento: a marca nao aparecia como imagem em header, hero nem
   rodape, so como texto): .hdr__logo entra ANTES do nome dentro do mesmo
   link, e sem flex o img (elemento com baseline propria) desalinha
   verticalmente do texto de 15px ao lado. */
.hdr__brand { display: inline-flex; align-items: center; gap: 8px; font-size: 15px; font-weight: 500; }
.hdr__brand sup { font-size: 9px; opacity: .7; }
.hdr__logo { height: 22px; width: auto; }
.hdr__nav { display: flex; align-items: center; gap: 32px; }
/* :where(.hdr__nav), nao ".hdr__nav": :where() tem especificidade ZERO
   por definicao (CSS Selectors nivel 4), entao a regra inteira passa a
   valer (0,0,1), a especificidade de um seletor de elemento sozinho
   (button ou a). Com ".hdr__nav button, .hdr__nav a" (0,1,1: uma classe
   mais um elemento), esta regra base tinha especificidade MAIOR que
   .copiar, .cta e .hdr__lang (todas 0,1,0, uma classe so) e vencia
   font-size/border/font-family dos tres dentro do header, goste ou nao da
   ordem de carregamento (especificidade maior sempre vence, independente
   de quem vem depois no arquivo). Medido no navegador antes desta
   correcao: o botao "copiar o brandbook" do header saia em 14px/sans/sem
   borda, em vez de 10px/mono com pilula como todo outro .copiar da
   pagina. */
:where(.hdr__nav) button, :where(.hdr__nav) a { font-size: 14px; cursor: pointer; background: none; border: 0; color: inherit; font-family: inherit; }
.hdr__nav .cta {
  border: 1px solid currentColor; border-radius: 999px;
  padding: 8px 16px; font-size: 13px; font-weight: 500;
  transition: background-color .15s, color .15s;
}
.hdr__nav .cta:hover { background: var(--accent); color: var(--bg); border-color: var(--accent); }
.hdr__lang { font-family: var(--mono); font-size: 12px; opacity: .35; }

/* Hero e meta ------------------------------------------------------- */
.hero { padding: 64px var(--gutter) 48px; border-bottom: 1px solid var(--line); }
/* Logo decorativo acima do titulo (achado importante da auditoria de
   acabamento): o hero e o primeiro conteudo que qualquer visitante ve, e
   media ate esta correcao nao tinha uma unica imagem. 40px de altura fica
   proporcional ao menor degrau "grande" da propria escada de tamanho da
   marca (180px, pensado para avatar/perfil), sem competir com o titulo
   gigante logo abaixo. */
.hero__logo { height: 40px; width: auto; margin-bottom: 24px; }
/* overflow-wrap: rede de seguranca para um wordmark de uma palavra so
   sem espaco onde quebrar (marca.hero.titulo pode ser o mesmo nome da
   marca que aparece no rodape). Achados critico 12 / importante 7 da
   auditoria adversarial: depois de corrigir .item__body e .ft__wordmark,
   ainda sobrava excesso de scroll horizontal em 320px de viewport,
   rastreado ate aqui (o hero e o primeiro conteudo da pagina, sempre
   visivel, nunca tinha ganhado esta rede). Nao reusa .ft__wordmark: o
   hero e a peca tipografica maior da pagina, com o proprio clamp
   (56..140px), maior que o do rodape de proposito. */
.hero__title {
  font-family: var(--display);
  font-size: clamp(56px, 9vw, 140px);
  font-weight: 500; line-height: .96; letter-spacing: -.035em;
  overflow-wrap: anywhere;
  margin-bottom: 24px;
}
.hero__sub { font-size: clamp(20px, 2vw, 28px); line-height: 1.25; max-width: 58ch; }

.meta { padding: 48px var(--gutter); border-bottom: 1px solid var(--line); }
.meta__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 32px; }
.meta__col { display: flex; flex-direction: column; gap: 14px; }
.meta__val { font-size: 16px; }
.meta__val a { border-bottom: 1px solid currentColor; width: fit-content; display: block; }

/* Divisor de caderno ------------------------------------------------ */
.part {
  min-height: 100vh; display: flex; align-items: stretch;
  padding: var(--ritmo) var(--gutter);
}
.part__inner { display: flex; flex-direction: column; justify-content: space-between; gap: var(--ritmo); flex: 1; }
/* Sem white-space: nowrap de proposito. O tamanho (12.8vw ate 175px) e
   calibrado para um titulo de cerca de 12 caracteres ocupar a largura
   inteira; com nowrap, qualquer titulo maior que isso vaza do container
   e leva scroll horizontal para a pagina inteira ("Identidade visual"
   mediu 1451px num container de 1201px). Deixando quebrar, o titulo que
   cabe continua identico e o que nao cabe vai para a segunda linha. */
/* overflow-wrap/word-break: rede de seguranca para uma palavra unica de
   TITULO DE CADERNO sem espaco onde quebrar (nao o wordmark do rodape,
   que tem a propria classe .ft__wordmark desde a correcao do achado
   critico 13 da auditoria adversarial: reusar esta classe gigante para
   o wordmark quebrava o NOME DA MARCA no meio). Quebra entre palavras
   normais fica identica a antes; so entra em acao quando uma palavra
   sozinha nao cabe. Sem isso, medido no navegador: scrollWidth do
   documento excedia clientWidth em 173px no desktop e 86px no mobile,
   com um titulo de caderno de uma palavra so vazando do container. */
/* clamp baixado de (48, 12.8vw, 175) para (40, 8vw, 120) (defeito 3 do
   enunciado de acabamento): o titulo de CADERNO e subordinado ao titulo
   da MARCA no hero (.hero__title, clamp(56, 9vw, 140)), mas o piso, a
   inclinacao e o teto antigos rendiam maior que o hero em toda largura de
   viewport (medido: "CONCEITO" 42% maior que "FalaTerranova" no hero),
   hierarquia tipografica invertida. Os tres numeros nao sao so "um pouco
   menor": piso 40 < piso 56, inclinacao 8vw < 9vw e teto 120 < 140 juntos
   garantem part__title(v) < hero__title(v) em QUALQUER largura de
   viewport, nao so nos pontos medidos (as duas sao funcoes monotonas nao
   decrescentes de v; piso e inclinacao menores mantem a curva do titulo
   de caderno sempre abaixo da curva do hero, inclusive depois que uma
   das duas bate no proprio teto). */
.part__title {
  font-family: var(--display);
  font-size: clamp(40px, 8vw, 120px);
  font-weight: 700; line-height: .9; letter-spacing: -.035em;
  text-transform: uppercase;
  overflow-wrap: anywhere;
  word-break: break-word;
}
.part__body { max-width: 62ch; display: flex; flex-direction: column; gap: 16px; }
.part__body p { font-size: clamp(18px, 1.4vw, 22px); line-height: 1.5; }

/* Secao e lista numerada -------------------------------------------- */
.section { padding: var(--ritmo) var(--gutter); }
.section__inner { display: flex; flex-direction: column; gap: 120px; }
/* align-items: flex-start (defeito 1 do enunciado de acabamento): sem
   ele, o eixo cruzado de um flex column usa o default stretch, e o botao
   "copiar como markdown" (um <button>, largura intrinseca por padrao)
   estica para a largura INTEIRA do container. Medido antes desta
   correcao: pilula de 1201x26px com o texto de 10px centralizado, o
   elemento mais largo da pagina, repetido em toda secao (8 ocorrencias).
   flex-start deixa cada filho (rotulo, titulo, botao) na propria largura
   de conteudo, empilhados a esquerda, que e o que a pilula do botao
   sempre pareceu ser visualmente mesmo antes da correcao existir. */
.section__head { display: flex; flex-direction: column; align-items: flex-start; gap: 24px; }
.section__title {
  font-family: var(--display);
  font-size: clamp(36px, 4.8vw, 64px);
  font-weight: 700; line-height: .95; letter-spacing: -.02em;
}
.section__intro { font-size: clamp(16px, 1.2vw, 19px); line-height: 1.45; max-width: 58ch; color: var(--muted); }

.items { display: flex; flex-direction: column; }
.item {
  display: grid; grid-template-columns: 120px 1fr; gap: 48px;
  padding: 48px 0; border-top: 1px solid var(--line); align-items: start;
}
.item:last-child { border-bottom: 1px solid var(--line); }
.item__num { font-family: var(--mono); font-size: 13px; color: var(--muted); padding-top: 8px; transition: color .2s; }
/* overflow-wrap: anywhere aqui (nao so em .part__title) e propriedade
   herdada: cobre item__lead, item__text, item__title e o <a> interno de
   uma vez so, porque uma URL longa (o caso real: a rota brandbook.md do
   caderno "Para agentes") pode aparecer em qualquer um deles. Achados
   critico 12 / importante 7: o fix anterior tratou so o wordmark do
   rodape; o min-content de uma URL sem onde quebrar dentro de
   .item__lead vazava a coluna do grid .item e arrastava os irmaos junto
   (47px de excesso em 320px, 7px em 360px, medido no navegador). Texto
   curto ou com espaco fica identico; so entra em acao quando uma string
   inquebravel nao cabe. */
.item__body { display: flex; flex-direction: column; gap: 24px; max-width: 64ch; overflow-wrap: anywhere; }
.item__title { font-size: clamp(22px, 2.4vw, 34px); font-weight: 600; line-height: 1.1; letter-spacing: -.018em; }
.item__lead { font-size: clamp(16px, 1.2vw, 19px); font-weight: 500; line-height: 1.45; }
.item__text { font-size: clamp(14px, 1vw, 16px); line-height: 1.55; color: var(--muted); }
.item:hover .item__num { color: var(--accent); }

/* Swatch de cor ----------------------------------------------------- */
.swatches { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 2px; }
/* border: var(--linha-forte), nao var(--line): quando a cor declarada do
   swatch (--chip, setada inline pelo render) coincide com --bg da pagina,
   o retangulo do chip so fica identificavel pelo contorno do cartao.
   var(--line) mede so ~1,7:1 contra o --bg da FalaTerranova; --linha-forte
   passa 3:1 (WCAG 1.4.11, indicador de componente de interface). Achado
   importante 19 da auditoria adversarial: medido, o swatch "Azul escuro"
   (mesmo hex do --bg da marca) virava um buraco quase invisivel. */
.swatch { display: flex; flex-direction: column; border: 1px solid var(--linha-forte); }
/* --chip nao esta na lista emitida por tokens.css nem e definida neste
   arquivo: e setada via atributo style inline, item a item, pelo render.
   O fallback evita fundo ausente se o render esquecer de setar o
   atributo. Deriva de --bg via color-mix, nao de um token --bg-alt fixo:
   nem toda marca declara bg_alt em tema (a FalaTerranova nao declara), e
   um --bg-alt hardcoded no fallback de dev seria superficie morta que
   convida uma marca futura a declarar tema.bg_alt achando que o chassi
   usa esse nome (achado menor da auditoria adversarial: chassi.css tinha
   --bg-alt declarado no bloco de fallback sem nenhum var(--bg-alt) restante
   no arquivo depois desta troca para color-mix; removido). */
.swatch__chip { aspect-ratio: 4 / 3; background: var(--chip, color-mix(in srgb, var(--bg) 85%, var(--ink) 15%)); }
.swatch__data { padding: 20px; display: flex; flex-direction: column; gap: 10px; }
.swatch__nome { font-size: 20px; font-weight: 600; }
/* column-gap (defeito 2 do enunciado de acabamento): sem ele, quando dt
   ("Contraste no fundo") mais dd ("6.36:1 passa em AA") somam mais do que
   a largura disponivel do cartao, justify-content: space-between nao tem
   espaco livre nenhum para distribuir e os dois textos ficam colados sem
   nenhum espaco entre si (medido: "CMYK26 0 7 2" e "Contraste no
   fundo6.36:1 passa em AA" lidos como uma palavra so, 32 colisoes na
   pagina da FalaTerranova). gap e reservado ANTES de space-between
   distribuir o espaco sobrando, entao garante um minimo mesmo quando o
   conteudo quase preenche o cartao inteiro. */
.swatch__linha { display: flex; justify-content: space-between; column-gap: 12px; font-family: var(--mono); font-size: 12px; }
.swatch__linha dt { color: var(--muted); }
.swatch__pendente { opacity: .5; }
/* Achados 2/14 da auditoria de tipografia: esta regra pedia font-style:
   italic, mas .swatch__linha (o pai) da font-family: var(--mono), e
   nenhuma marca deste repo tem face italica de Mono (nem binario no
   projeto, nem um arquivo localmente disponivel com a MESMA versao do
   Mono ja embarcado, pra manter metrica consistente entre normal e
   italico). Sem @font-face italico, o navegador SINTETIZA o obliquo
   (cisalha a Regular), medido pela auditoria: largura identica entre
   italic e normal na mesma familia, a assinatura do fake italic. Em vez
   de publicar mais uma face deformada pelo rasterizador (mesma classe de
   problema do specimen na fonte errada, que esta correcao de tipografia
   inteira existe pra fechar), a distincao visual de "pendente"/"nao
   validado" passa a valer so por opacity, ja calibrada pra AA nos dois
   temas logo abaixo. Se um dia a marca ganhar uma face Mono italica
   verificada, a marcacao pode voltar aqui. */
/* Achado menor 23 (auditoria adversarial): opacity .5 passa em AA no
   tema normal (o unico que a FalaTerranova usa: is-dark nunca ativa pra
   ela), mas no tema invertido hipotetico (uma marca futura com fundo
   claro nativo, onde is-dark ativa de verdade) 0.5 mede 3,57:1 contra o
   fundo trocado, abaixo do minimo AA 4.5:1 de texto normal. .6 passa em
   4,99:1 com os tokens da FalaTerranova usados como par de referencia
   (medido em tests/test_chassi.py). */
html.is-dark .swatch__pendente { opacity: .6; }

.hierarquia { display: flex; width: 100%; height: 96px; }
.hierarquia__faixa { display: flex; align-items: flex-end; padding: 12px; font-family: var(--mono); font-size: 11px; }

.combos { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 2px; }
/* Mesmo achado 19 do .swatch acima: sem NENHUMA borda antes desta
   correcao, um combo cujo --chip (bg do par) coincidisse com --bg da
   pagina flutuava sem contorno algum. Medido na FalaTerranova: 3 dos 6
   pares aprovados compartilham --bg com a pagina. */
.combo { aspect-ratio: 3 / 2; display: grid; place-items: center; font-weight: 700; font-size: 20px; border: 1px solid var(--linha-forte); }
.combo__meta { font-family: var(--mono); font-size: 11px; margin-top: 8px; }

/* Paleta de apoio ----------------------------------------------------- */
/* Mesmo .swatch/.swatches da paleta principal por dentro; o que muda e
   so a moldura desta faixa (rotulo proprio + traco pontilhado acima),
   sinal visual de que estas cores nao entram na hierarquia da marca e
   por isso nunca ganham a barra de proporcao (.hierarquia). */
.swatches-apoio { display: flex; flex-direction: column; gap: 24px; margin-top: 64px; padding-top: 64px; border-top: 1px dashed var(--line); }

/* Specimen tipografico ---------------------------------------------- */
.specimen { display: flex; flex-direction: column; gap: 32px; padding: 48px 0; border-top: 1px solid var(--line); }
.specimen__head { display: grid; grid-template-columns: 2fr repeat(3, 1fr); gap: 32px; align-items: baseline; }
/* font-weight: 700 aqui e so um piso de exibicao (visivel se este bloco
   abrir sozinho, sem HTML gerado por render.py). Na pagina de verdade,
   brandbook/render.py._specimens() SEMPRE seta font-weight no atributo
   style inline do elemento (via _peso_forte), que tem especificidade
   maior e vence esta regra. Achado importante 1 da auditoria de
   tipografia: antes desta correcao, este 700 fixo forcava negrito
   sintetico em toda familia sem face 700 real (Roboto e IBM Plex Mono na
   FalaTerranova, as duas com pesos: [400]); nao mexer aqui sem manter o
   inline de render.py coerente. */
.specimen__nome { font-size: clamp(32px, 4vw, 56px); font-weight: 700; letter-spacing: -.02em; }
.specimen__pangram { font-size: clamp(24px, 3vw, 40px); line-height: 1.15; }
.specimen__alfabeto { font-size: clamp(16px, 1.6vw, 22px); line-height: 1.6; word-break: break-all; color: var(--muted); }
.specimen__peso { display: grid; grid-template-columns: 120px 1fr; gap: 24px; padding: 12px 0; border-top: 1px solid var(--line); align-items: baseline; }
.specimen__amostra { font-size: clamp(18px, 2vw, 28px); }

/* Figura de conteudo -------------------------------------------------- */
/* Imagem opcional dentro de um item de prosa (brandbook.render._figura),
   reaproveitada tambem dentro de .quebra (ver mais abaixo), onde o
   seletor mais especifico ".quebra .figura" sobrescreve o layout estatico
   por um full-bleed absoluto. */
.figura { display: flex; flex-direction: column; gap: 8px; }
.figura img { width: 100%; height: auto; border: 1px solid var(--linha-forte); }
.figura__rotulo {
  font-family: var(--mono); font-size: 10px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted);
}

/* Logo sobre o par de fundos ------------------------------------------ */
/* Uma versao de logo, mostrada de verdade: positiva sobre o fundo claro
   da marca, negativa (quando existe) sobre o fundo escuro, lado a lado.
   E o que torna verificavel a regra "positiva em fundo claro, negativa em
   fundo escuro" que antes so existia como texto, nunca demonstrada. */
.par-de-fundos { display: flex; flex-wrap: wrap; gap: 16px; margin-bottom: 8px; }
.par-de-fundos__item { display: flex; flex-direction: column; gap: 8px; width: 200px; }
.par-de-fundos__painel {
  display: flex; align-items: center; justify-content: center;
  aspect-ratio: 4 / 3; padding: 24px; border: 1px solid var(--linha-forte);
}
.par-de-fundos__painel img { width: 100%; max-width: 160px; }
.par-de-fundos__legenda {
  font-family: var(--mono); font-size: 10px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--muted); text-align: center;
}

/* Area de respiro, desenhada -------------------------------------- */
/* Mostra a marca com a area de respiro marcada em volta dela
   (brandbook.render._area_de_respiro): fecha a lacuna estrutural que o
   comparador apontou (o brandbook de referencia tem uma secao "Area de
   respiro", o nosso brandbook nao tinha nenhuma).

   .respiro__quadro reaproveita o mesmo par de fundo claro/escuro que
   .par-de-fundos__painel ja usa: um painel com o fundo que a variante do
   logo exibida pede, positiva sobre claro ou negativa sobre escuro.

   .respiro__moldura e o retangulo de referencia (position: relative) para
   as quatro camadas absolutas dentro dela se posicionarem por cima da
   imagem. border com var(--accent): mesmo verde de assinatura ja usado,
   comedido, em numeracao e filete (escada-visual__legenda, filete-marca),
   nunca hex cru.

   ALTERADO (achado critico da auditoria adversarial: "a secao desenha a
   borda da tinta, nao o respiro; a regra fica invisivel"). Antes desta
   correcao so existia .respiro__linha, colada na borda da tinta -- o
   desenho marcava onde o respiro COMECA, nunca onde ele TERMINA, entao
   nao dava pra derivar quanto espaco reservar so olhando a figura.
   Quatro camadas agora, nesta ordem de pintura (ver o docstring de
   brandbook.render._area_de_respiro para o raciocinio completo):

   1. .respiro__zona: a hachura, ATRAS da imagem (por isso .respiro__img
      precisa de position: relative tambem -- sem isso ela e um elemento
      normal, que SEMPRE pinta atras de qualquer descendente posicionado
      do mesmo contexto de empilhamento, mesmo vindo antes no DOM; com
      position: relative, os quatro elementos empilham na ordem do DOM,
      que e a ordem que este comentario segue). So aparece onde a margem
      do arquivo e transparente, porque a tinta opaca por cima cobre o
      resto -- o proprio recorte do logo faz o papel de mascara.
   2. .respiro__img: a marca em si.
   3. .respiro__linha: MESMA posicao de antes (a borda da tinta).
   4. .respiro__limite: dashed na borda EXTERNA da moldura -- o limite
      real do espaco reservado, o que faltava.
   5. .respiro__cota: o rotulo "1x" dentro da folga do topo, entre as
      duas linhas -- a unidade fica mensuravel no proprio desenho, nao so
      citada no texto ao lado. */
.respiro__quadro {
  display: flex; align-items: center; justify-content: center;
  padding: 24px; border: 1px solid var(--linha-forte); margin-bottom: 8px;
}
/* width: min(260px, 100%) na MOLDURA (nao na imagem): a moldura e filha
   direta de .respiro__quadro, que tem largura definida pelo layout da
   pagina, entao a porcentagem do min() resolve contra uma base real. Se a
   porcentagem estivesse no <img> (filho de .respiro__moldura, que e
   inline-flex sem largura propria) o calculo seria circular -- a largura
   do pai dependeria do filho, que dependeria de uma porcentagem do pai --
   e o navegador resolve esse ciclo tratando a porcentagem como 0 (medido
   no navegador: computedWidth do <img> saia "0px"). */
.respiro__moldura { position: relative; width: min(260px, 100%); }
.respiro__zona {
  position: absolute; inset: 0;
  background-image: repeating-linear-gradient(45deg, var(--accent) 0 1px, transparent 1px 7px);
  opacity: .3;
}
.respiro__img { display: block; width: 100%; position: relative; }
.respiro__linha { position: absolute; border: 1px dashed var(--accent); pointer-events: none; }
.respiro__limite { position: absolute; inset: 0; border: 1px dashed var(--accent); pointer-events: none; }
.respiro__cota {
  position: absolute; left: 50%; transform: translate(-50%, -50%);
  font-family: var(--mono); font-size: 10px; font-weight: 600;
  color: var(--accent); padding: 1px 4px; white-space: nowrap;
}

/* Gradiente do logotipo, publicado --------------------------------- */
/* Achado C2 do backlog do comparador: o dont "Nao alterar as cores do
   gradiente" nunca dizia quais cores eram, e o unico grafismo colorido
   fora da secao Cores (o mesmo gradiente, via Faixa.svg) pintava com
   stops que brand.json nao documentava. Preview via --grad-marca (nunca
   hex cru aqui), com a borda forte de todo swatch/chip da pagina. */
.gradiente-marca { height: 56px; width: 100%; background: var(--grad-marca); border: 1px solid var(--linha-forte); margin-bottom: 8px; }

/* Escada de tamanho, desenhada -------------------------------------- */
/* O mesmo logo, repetido nos seis tamanhos reais da marca, lado a lado:
   o leitor VE a reducao acontecer, em vez de so ler uma lista de numeros
   em px (brandbook.render._escada_visual).

   flex-wrap: nowrap + overflow-x: auto (achado importante da auditoria de
   acabamento, defeito medido no navegador): com wrap, a soma dos seis
   paineis (px do degrau + 32px de padding cada) mais os cinco gaps de 32px
   fecha em 1235px, mas o container util a 1280px de viewport (a largura
   mais comum) mede so 1201px com barra de rolagem. O quinto e o sexto
   degrau (os dois MENORES) quebravam pra segunda linha, voltando pro
   inicio esquerdo, abaixo do maior deles: uma escada cujo degrau menor
   aparece embaixo do maior deixa de ler como comparacao de tamanho. A
   quebra e intermitente por design de viewport (some a partir de 1440,
   volta abaixo de ~1300), a mesma assinatura de defeito ja registrada em
   .combos. nowrap + scroll horizontal resolve para qualquer largura, sem
   depender de acertar um breakpoint especifico.

   O MESMO nowrap fecha o agravante medido a 375px: com wrap, o container
   mais estreito que 320px forcava a regra global "img { max-width: 100% }"
   a encolher o PRIMEIRO degrau para 303px enquanto a legenda continuava
   dizendo "320px" (a pagina mostrando um logo menor do que afirma).
   flex-shrink: 0 no degrau (abaixo) garante que a linha nunca encolhe os
   filhos para caber: ela rola, e cada imagem sempre renderiza no width
   exato que o estilo inline pede, casando com a legenda em qualquer
   viewport.

   ALTERADO (achado importante da auditoria adversarial: "em 1280 o ultimo
   degrau fica cortado", "no celular os degraus de simbolo ficam fora da
   tela"): a correcao da escada nao-monotonica em
   brandbook.render._largura_de_exibicao_do_degrau tambem encolheu os dois
   ultimos paineis (os que mostram o simbolo), porque o simbolo passou a
   ser exibido na MESMA escala de unidade-de-desenho por pixel que o
   lockup, em vez do mesmo numero de px cru -- o total da soma dos seis
   paineis + cinco gaps caiu de 1235px pra ~1187px, ja cabendo nos 1201px
   de container util a 1280px de viewport sem precisar rolar. Isso NAO
   resolve celular/tablet (nenhum viewport estreito cabe o PRIMEIRO
   painel, 352px, sozinho): overflow-x: auto continua sendo o mecanismo
   correto pra qualquer largura, e .escada-visual__dica (abaixo) da a
   pista visivel que faltava -- antes, a unica pista de que dava pra rolar
   era a propria barra de rolagem do navegador, sem rotulo nenhum. */
.escada-visual {
  display: flex; align-items: flex-end; flex-wrap: nowrap; gap: 32px;
  padding: 32px 0; border-top: 1px solid var(--line); margin-bottom: 8px;
  overflow-x: auto;
}
.escada-visual__degrau { display: flex; flex-direction: column; align-items: center; gap: 12px; flex-shrink: 0; }
.escada-visual__painel {
  display: flex; align-items: flex-end; justify-content: center;
  padding: 16px;
}
.escada-visual__painel img { flex-shrink: 0; }
/* color: var(--accent) fixo, nao so no hover (ao contrario de
   .item__num acima): e um dos dois usos deliberados e comedidos do verde
   de assinatura fora da secao de Cores que o enunciado de acabamento pede
   ("o verde em filete de divisor ou em numeracao"). Aqui e numeracao: o
   tamanho em px de cada degrau da escada. */
.escada-visual__legenda { font-family: var(--mono); font-size: 11px; color: var(--accent); }
/* .escada-visual__legenda-bloco (achado importante da auditoria
   adversarial: "os numeros e as marcas da escada perderam a linha de base
   comum"): a legenda e o badge opcional (Proposto/Simbolo) moram juntos
   num wrapper com min-height fixa, calculada pra caber as DUAS linhas
   (legenda 11px * 1.4 de line-height + a margem do badge + o badge
   11px * 1.4, arredondado com folga). Sem essa altura fixa, um degrau SEM
   badge (bloco de uma linha so) fica mais curto que um degrau COM badge
   (duas linhas), e o align-items: flex-end do container acima bottom-
   alinha a COLUNA inteira -- pra colunas de altura diferente, isso empurra
   a legenda do degrau mais curto pra baixo da dos vizinhos mais altos,
   mesmo os dois tendo a MESMA imagem de referencia. Com a altura do bloco
   sempre igual, a posicao da legenda para de depender de ter badge ou
   nao. text-align: center porque os filhos (p e span) passam a ser blocos
   comuns (nao mais flex items), sem o align-items: center do pai pra
   centralizar cada um pela propria largura. */
.escada-visual__legenda-bloco { min-height: 33px; text-align: center; }
/* Achado importante da auditoria de acabamento: as seis legendas saiam com
   a MESMA autoridade visual (mesmo peso, mesma cor de assinatura), mesmo
   quando dois dos seis tamanhos sao PROPOSTOS por quem montou o brand.json
   (px_origem: "proposto"), sem lastro no brandbook impresso. .rotulo (a
   mesma classe mono/caixa-alta/--muted usada em toda ressalva de
   procedencia da pagina) marca a diferenca sem exigir nova cor: o degrau
   medido continua so em --accent, o proposto ganha a nota ao lado, em tom
   secundario. .escada-visual__variante (degradacao pro simbolo, item 1)
   reaproveita a MESMA regra: e o mesmo tipo de aviso secundario, so que
   avisando qual ARQUIVO esta em tela, nao a procedencia da medida. */
.escada-visual__proposto, .escada-visual__variante { display: block; margin-top: 2px; }
/* O rotulo que diz que da pra rolar (achado importante da auditoria
   adversarial: "a unica pista de que da pra rolar e a barra de rolagem,
   sem rotulo"). Sempre presente (nao so abaixo de um breakpoint): mesmo
   numa largura em que os seis degraus cabem sem rolar, avisar que a faixa
   e rolavel nao atrapalha ninguem, e a largura em que passam a caber
   varia com o navegador/zoom de quem le. */
.escada-visual__dica {
  font-family: var(--mono); font-size: 11px; color: var(--muted);
  margin-top: 4px;
}

/* Elementos graficos --------------------------------------------------- */
/* Friso decorativo no topo da secao: o elemento marcado
   usar_como_filete=true em brand.json (brandbook.render._filete_de_elemento),
   o outro uso deliberado do verde fora da secao de Cores ("um arco ou
   faixa como elemento de secao"). object-fit: cover recorta a faixa (que
   e um retangulo largo no proprio arquivo) numa tira fina, sem distorcer
   o gradiente interno. */
.filete-marca { width: 100%; height: 12px; object-fit: cover; display: block; margin-bottom: 48px; }
.elementos-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 2px; }
.elemento { display: flex; flex-direction: column; gap: 16px; padding: 32px; border: 1px solid var(--line); }
/* aspect-ratio + object-fit: cover (achado menor da auditoria de
   acabamento): antes, a moldura tinha so min-height e a imagem escalava
   pela LARGURA (max-width: 100%), entao um elemento com proporcao muito
   larga e fina (Faixa rodape.svg, pensada para um friso de rodape)
   media so 3px de altura de render dentro do card, um fio. O card virava
   praticamente ilegivel para qualquer elemento cuja proporcao real nao
   seja proxima de quadrada. Com area fixa e object-fit: cover (o mesmo
   recorte que .filete-marca ja usa para a faixa no topo da secao), todo
   elemento renderiza numa altura sempre legivel, mostrando um recorte
   central do proprio grafismo em vez de espremer a imagem inteira. */
.elemento__moldura {
  display: flex; align-items: center; justify-content: center;
  aspect-ratio: 3 / 2; padding: 24px; border: 1px solid var(--linha-forte);
  overflow: hidden;
}
.elemento__moldura img { width: 100%; height: 100%; object-fit: cover; }

/* Quebra full-bleed entre cadernos ------------------------------------- */
/* Sem casca de .section: sem .wrap, sem rotulo, sem titulo, sem botao de
   copiar. E um respiro visual entre dois cadernos (brandbook.render._quebra),
   nao conteudo navegavel, entao nunca ganha id proprio nem entra no menu.
   ".quebra .figura" sobrescreve o layout estatico de .figura (acima) para
   um full-bleed absoluto que preenche a secao inteira. */
.quebra { position: relative; min-height: 60vh; overflow: hidden; }
.quebra .figura { position: absolute; inset: 0; display: block; }
.quebra .figura img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; border: 0;
}
/* color: var(--ink), nao um hex fixo: a imagem aprovada para esta secao
   foi desenhada com os 55% da esquerda escuros de proposito, calibrados
   para aguentar texto claro por cima (ver o LEIA-ME das imagens
   aprovadas). Para a FalaTerranova --ink e branco, o que a imagem pede;
   uma marca futura que reusar .quebra com uma imagem diferente precisa
   escolher uma imagem cujo canto de leitura combine com o proprio --ink,
   a mesma logica ja documentada em _tema_de_troca (render.py) para o par
   bg/ink. */
.quebra .figura__rotulo {
  position: absolute; z-index: 1; left: var(--gutter); bottom: 32px;
  margin: 0; color: var(--ink);
}

/* Dos and donts ------------------------------------------------------ */
.donts-header { display: flex; align-items: flex-end; gap: 32px; padding: 24px 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
/* line-height 1 (nao .88): caixa de linha menor que o corpo da fonte corta
   as extremidades que til e cedilha ocupam ("NAO FACA" tem os dois).
   Medido antes desta correcao: o til do primeiro A encostava no filete
   superior da faixa e a cedilha do C descia sobre a borda do primeiro
   cartao da grade. align-items: flex-end no pai (acima) alinha o rotulo
   pequeno pela base da palavra grande, em vez de baseline (que colava o
   rotulo no meio da letra). */
.donts-header__word { font-size: clamp(64px, 9vw, 140px); font-weight: 700; line-height: 1; letter-spacing: -.04em; text-transform: uppercase; }
.donts-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); border-top: 1px solid var(--line); border-left: 1px solid var(--line); }
.dont-card { display: flex; flex-direction: column; gap: 16px; padding: 40px 32px; border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); transition: background-color .25s; }
/* Mesma ressalva de .specimen__nome acima: font-weight: 700 aqui e so
   piso de exibicao sem HTML gerado. brandbook/render.py._donts() sempre
   seta font-weight inline (via _peso_forte, resolvendo a familia de
   verdade atras de var(--mono) na propria marca), que vence esta regra
   por especificidade. Achado importante 1: sem o inline, este 700 fixo
   forcava negrito sintetico sempre que a familia de --mono nao tem face
   700 real. */
.dont-card__num { font-family: var(--mono); font-size: clamp(32px, 3.5vw, 52px); font-weight: 700; line-height: 1; color: var(--muted); }
.dont-card__par { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.dont-card__par figcaption { font-family: var(--mono); font-size: 10px; letter-spacing: .12em; text-transform: uppercase; margin-top: 8px; }

/* Downloads --------------------------------------------------------- */
.dl { display: flex; flex-direction: column; gap: 2px; }
.dl__pacote { display: flex; justify-content: space-between; align-items: center; gap: 24px; padding: 32px; border: 1px solid var(--line); flex-wrap: wrap; }
.dl__linha { display: grid; grid-template-columns: 48px 1fr auto; gap: 24px; padding: 24px 0; border-top: 1px solid var(--line); align-items: center; }
.dl__formatos { display: flex; gap: 8px; flex-wrap: wrap; }
/* border: var(--linha-forte) (achado menor 24): a borda e o unico
   contorno deste chip, um controle interativo (link de download), entao
   precisa dos 3:1 de WCAG 1.4.11; var(--line) media so ~1,7:1. */
.dl__formatos a { font-family: var(--mono); font-size: 11px; letter-spacing: .08em; border: 1px solid var(--linha-forte); border-radius: 999px; padding: 6px 12px; }
.dl__formatos a:hover { border-color: var(--accent); color: var(--accent); }

/* Bloco de texto para colar ------------------------------------------ */
/* System prompt e prompts de imagem saem em <pre>, que por padrao nao
   quebra linha: uma frase longa vira uma linha unica de milhares de
   pixels e leva scroll horizontal pra pagina inteira. pre-wrap quebra,
   overflow-x: auto segura o que nao quebra (uma URL comprida, por
   exemplo) dentro do proprio bloco. */
.colavel {
  font-family: var(--mono);
  font-size: 13px;
  line-height: 1.5;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  overflow-x: auto;
  border: 1px solid var(--line);
  padding: 20px;
}

/* Copiar para IA ----------------------------------------------------- */
/* border: var(--linha-forte) (achado menor 24): mesma razao do
   .dl__formatos a acima, este e o unico contorno visual do botao. */
.copiar { font-family: var(--mono); font-size: 10px; letter-spacing: .12em; text-transform: uppercase; border: 1px solid var(--linha-forte); border-radius: 999px; padding: 6px 12px; background: none; color: inherit; cursor: pointer; }
.copiar:hover { border-color: var(--accent); color: var(--accent); }
.copiar[data-feito="1"] { border-color: var(--accent); color: var(--accent); }

/* Menu overlay ------------------------------------------------------- */
.menu { position: fixed; inset: 0; z-index: 20; background: var(--bg); padding: 22px var(--gutter); display: none; overflow-y: auto; }
.menu[data-aberto="1"] { display: block; }
.menu__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 48px; margin-top: 64px; }
.menu__lista { display: flex; flex-direction: column; gap: 10px; margin-top: 16px; }
.menu__lista a { font-size: clamp(18px, 2vw, 24px); }

/* Footer ------------------------------------------------------------- */
/* padding horizontal em var(--gutter), nao em 56px fixo: toda outra faixa
   da pagina (.section, .part, .hdr) usa --gutter (32px no desktop, 20px
   abaixo de 900px) para a coluna alinhar; 56px fixo desalinhava o rodape
   do resto do conteudo e, no mobile, sobrava so 56px pro wordmark, que
   agora tem o proprio teto de fonte calibrado para caber (ver
   .ft__wordmark abaixo). */
.ft { padding: 64px var(--gutter); min-height: 700px; display: flex; flex-direction: column; justify-content: flex-end; gap: 48px; }
/* Classe propria, NAO .part__title: achado critico da auditoria
   adversarial (regressao do proprio fix anterior). O rodape reusava
   .part__title (clamp ate 175px, pensado pra titulo de caderno em tela
   cheia) para o wordmark de uma palavra so ("FalaTerranova", 13
   caracteres). Nesse tamanho, o nome nao cabe numa linha em nenhuma
   largura de desktop comum, e overflow-wrap: anywhere (que existe pra
   evitar scroll horizontal) quebrava o NOME DA MARCA no meio
   ("FALATERRANO" / "VA"), medido em 1280x800 e 375x812. clamp(28px, 6vw,
   72px) foi calibrado (largura media de caractere ~0.62 do tamanho da
   fonte, bold uppercase sans) para "FalaTerranova" caber numa linha so
   da 320px de viewport ate desktop largo, sem precisar quebrar; o
   overflow-wrap continua como rede de seguranca para uma marca futura
   com nome mais longo, nao como comportamento esperado desta. */
.ft__wordmark {
  font-family: var(--display);
  font-size: clamp(28px, 6vw, 72px);
  font-weight: 700; line-height: 1; letter-spacing: -.02em;
  text-transform: uppercase;
  overflow-wrap: anywhere;
  word-break: break-word;
  /* margin-bottom (achado importante da auditoria de acabamento): sem
     ele, a base do wordmark encostava direto em .ft__info (0px medido no
     navegador), os rotulos "Brandbook"/"Fonte canonica"/etc colados na
     letra. .filete-marca (o friso decorativo logo acima do wordmark, ver
     brandbook.render._rodape) ja resolve o espaco ACIMA com a propria
     margin-bottom de 48px; este e o espaco ABAIXO. */
  margin-bottom: 32px;
}
/* Logo decorativo entre o friso e o wordmark (mesmo achado do hero/header
   acima): 32px fica visivelmente menor que o wordmark gigante ao lado,
   coerente com a hierarquia "logo acompanha o nome, nao compete com ele"
   ja usada no cabecalho. */
.ft__logo { height: 32px; width: auto; margin-bottom: 16px; }
.ft__info { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 32px; }
/* overflow-wrap: mesma rede de seguranca de .item__body/.hero__title
   acima, para a coluna "Fonte canonica" (o link do dominio da marca) nao
   vazar em viewport estreito. Ultimo pedaco dos achados critico 12 /
   importante 7: 4px de excesso sobravam em 360px depois das outras tres
   correcoes, rastreados ate aqui. */
.ft__col { font-size: 14px; line-height: 1.7; color: var(--muted); overflow-wrap: anywhere; }

/* Reveal e movimento -------------------------------------------------- */
/* Este bloco depende de uma classe "js" no <html>, setada cedo por um
   snippet inline no <head> do template (fora deste arquivo). A logica e
   invertida de proposito: o conteudo comeca visivel por padrao e so fica
   escondido quando o proprio documento confirma que o JavaScript esta
   ativo. Assim, se o script nao rodar (desabilitado, bloqueado por
   extensao, erro de carregamento, ou um agente que so le o HTML puro), o
   conteudo marcado com reveal nunca fica preso em opacidade zero para
   sempre. A transicao fica numa regra a parte, sem o :not(), pra nao
   desaparecer do elemento no exato momento em que is-inview e adicionada. */
html.js .reveal { transition: opacity .6s, transform .6s; }
html.js .reveal:not(.is-inview) { opacity: 0; transform: translateY(16px); }
.reveal.is-inview { opacity: 1; transform: none; }

/* Segunda rede de seguranca: em navegadores que suportam a media feature
   scripting, isso confirma que nao ha JavaScript ativo e mantem o reveal
   visivel mesmo que a classe html.js nunca tenha sido setada. O !important
   e necessario: "html.js .reveal:not(.is-inview)" tem especificidade
   (0,3,1), maior que ".reveal" sozinho (0,1,0). Especificidade maior vence
   a cascata independente de media query ou ordem no arquivo, entao sem
   !important esta regra perderia e o reveal continuaria escondido mesmo
   com scripting: none confirmado. */
@media (scripting: none) {
  .reveal { opacity: 1 !important; transform: none !important; }
}

@media (hover: none) {
  .item.is-inview .item__num { color: var(--accent); }
}

/* A preferencia do usuario por menos movimento sempre vence: mesmo
   raciocinio de especificidade do bloco scripting: none acima. Sem
   !important aqui, quem tem prefers-reduced-motion: reduce ligado E
   html.js presente (JavaScript carregou normalmente) continuaria com
   opacity: 0 vinda de "html.js .reveal:not(.is-inview)", porque (0,3,1)
   e maior que (0,1,0) independente da media query estar ativa. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: .001ms !important; animation-duration: .001ms !important; }
  .reveal { opacity: 1 !important; transform: none !important; }
  html { scroll-behavior: auto; }
}

@media (max-width: 900px) {
  :root { --ritmo: 96px; --gutter: 20px; }
  .meta__grid { grid-template-columns: 1fr; }
  .item { grid-template-columns: 1fr; gap: 16px; }
  .specimen__head { grid-template-columns: 1fr; }
}

/* Header no celular: os quatro alvos (PT, "copiar o brandbook", CTA
   "Baixar assets", Menu) num flex de gap 32px nao cabem num viewport
   estreito. Medido antes desta correcao, em 375px: .hdr com scrollWidth
   448 dentro de clientWidth 375, o botao Menu inteiramente fora da faixa
   visivel (unico ponto de acesso ao indice do brandbook no celular). A
   CTA de download continua acessivel por outro caminho (a secao de
   Downloads e o rodape tem o link do pacote de logos). O botao de copiar
   TUDO (o brandbook inteiro) nao tinha outro caminho equivalente: cada
   secao so tem "copiar como markdown" do proprio fragmento, nenhuma copia
   o livro inteiro (achado menor da auditoria adversarial, que corrigiu a
   afirmacao errada que estava aqui antes). A correcao foi dar ao menu
   overlay (que continua acessivel no celular) o proprio botao
   data-copiar="tudo" (ver brandbook/render.py::_menu), entao esconder
   ".copiar" e ".cta" AQUI, especificamente de dentro do cabecalho sticky
   (".hdr .hdr__nav", nao ".hdr__nav" sozinho, que tambem casaria com a
   barra do menu e esconderia o botao novo), nao tira mais funcionalidade
   do documento, so tira do header. */
@media (max-width: 640px) {
  .hdr__nav { gap: 16px; }
  .hdr .hdr__nav .copiar,
  .hdr .hdr__nav .cta { display: none; }
}
