/* A paleta original girava em torno de #0a0c0a — quase preto puro — com os textos
   secundários em cinza apagado, o que deixava a página pesada e cansativa de ler.
   O fundo subiu para um grafite e o --ink-dim clareou: o texto secundário saiu de
   6,7:1 para ~9:1 sobre o fundo, e os cards agora se destacam dele em vez de
   sumirem. Os terminais continuam mais escuros que a página de propósito — é o que
   os faz parecer telas embutidas.

   Os cinzas são todos da mesma família fria. Antes o fundo puxava azul enquanto
   borda, tinta e terminal puxavam o verde-oliva da paleta velha, e bordas
   esverdeadas sobre painel azulado davam um aspecto sujo. Agora o verde aparece
   só onde é intencional: o --phosphor dos valores e do log dentro dos terminais. */
:root {
  --bg: #14171a;
  --bg-panel: #1c2024;
  --bg-terminal: #0d1114;
  --border: #3d444c;
  --ink: #e8ecf0;
  --ink-dim: #b0b8c0;
  --copper: #c98a4e;
  --bitcoin: #f7931a;
  --bitcoin-dim: #c97710;
  --phosphor: #4fe38a;
  --danger: #ff5d5d;
  --radius: 8px;
  --font-mono: ui-monospace, "Cascadia Code", "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
  --font-sans: -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background-color: var(--bg);
  background-image: radial-gradient(circle, rgba(201,138,78,0.20) 1px, transparent 1.2px);
  background-size: 26px 26px;
  color: var(--ink);
  font-family: var(--font-sans);
  line-height: 1.6;
}

.wrap {
  max-width: 1240px;
  margin: 0 auto;
  padding: 0 24px;
}

a { color: var(--bitcoin); text-decoration: none; }
a:hover { text-decoration: underline; }

a:focus-visible,
button:focus-visible {
  outline: 2px solid var(--phosphor);
  outline-offset: 2px;
  text-decoration: none;
}

/* Sem isto o primeiro tab stop de toda visita é a nav sticky, e quem navega por
   teclado precisa atravessar os quatro links antes de chegar ao conteúdo.

   fixed, não absolute: com absolute o "top: 12px" do estado focado é medido a
   partir do topo do DOCUMENTO, então bastava a página estar rolada para o link
   aparecer fora da tela — focado e invisível, que é o pior dos mundos. */
.skip-link {
  position: fixed;
  left: 12px;
  top: -60px;
  z-index: 20;
  font-family: var(--font-mono);
  font-size: 0.82rem;
  font-weight: 600;
  background: var(--bitcoin);
  color: #1a1200;
  padding: 10px 16px;
  border-radius: var(--radius);
  transition: top 0.15s ease;
}
.skip-link:focus { top: 12px; text-decoration: none; }

/* O alvo do skip-link recebe tabindex="-1" para o foco realmente ir até lá; sem
   isto o navegador só rola a página e o foco fica no body, fazendo o Tab seguinte
   voltar para a nav — ou seja, o skip-link não pulava nada. O contorno é removido
   porque a seção só é focável por programa, nunca por teclado. */
section[tabindex="-1"]:focus { outline: none; }

@media (prefers-reduced-motion: reduce) {
  .skip-link { transition: none; }
}

code {
  font-family: var(--font-mono);
  background: rgba(255,255,255,0.07);
  padding: 2px 6px;
  border-radius: 4px;
  font-size: 0.88em;
  /* URLs e caminhos longos não têm onde quebrar: a 320px o
     http://IP_DO_BITAXE/api/system/info ficava 272px de largura e empurrava a
     página inteira na horizontal. Dentro de <pre> não se aplica — lá o próprio
     contêiner rola, e quebrar um comando de gravação no meio seria pior. */
  overflow-wrap: anywhere;
}

pre code { overflow-wrap: normal; }

/* Topbar */
.topbar {
  position: sticky;
  top: 0;
  z-index: 10;
  /* Acompanha --bg: a barra é translúcida, então precisa da mesma cor de fundo
     para não aparecer uma faixa de tom diferente sobre o conteúdo que passa. */
  background: rgba(20,23,26,0.92);
  backdrop-filter: blur(6px);
  border-bottom: 1px solid var(--border);
}

.topbar-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 58px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: 0.98rem;
}

.brand-mark {
  color: var(--bg);
  background: var(--bitcoin);
  border-radius: 4px;
  padding: 2px 6px;
  font-size: 0.78rem;
  letter-spacing: 0.02em;
}

.brand-name em { color: var(--ink-dim); font-style: normal; }

/* Os links da nav são .btn .btn-primary .btn-sm, no mesmo estilo do "Ver no
   aliexpress". O botão já passa dos 24px de alvo mínimo da WCAG 2.5.8, e cabe
   nos 58px da barra. */
.topbar nav {
  display: flex;
  gap: 8px;
  font-family: var(--font-mono);
}

.topbar nav a { white-space: nowrap; }

/* Sections */
.section { padding: 40px 0; }


/* The topbar is sticky, so an anchor jump would otherwise park the heading
   underneath it. Kept slightly above the 58px bar height for breathing room. */
section[id] { scroll-margin-top: 70px; }
/* Faixa alternada como painel, não de ponta a ponta: o fundo ia de uma borda
   da tela à outra. O painel fica na largura da .wrap e, abaixo dela, sempre a
   16px das bordas da tela. O padding interno de 24px da .wrap continua. */
.section-alt > .wrap {
  width: calc(100% - 32px);
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding-top: 28px;
  padding-bottom: 28px;
}

.section h2 {
  font-family: var(--font-mono);
  font-size: 1.5rem;
  margin: 0 0 6px;
  letter-spacing: -0.01em;
}
.section-sub { color: var(--ink-dim); margin: 0 0 20px; max-width: 620px; font-size: 0.95rem; }

/* Hero */
.hero { padding: 40px 0 36px; }

/* Hero + proof terminals side by side. The text column is capped near 560px so
   the lead stays inside a readable line length; the terminals take the rest,
   which is what used to be 292px of dead space to the right of the hero. */
/* Fundo curto e a seção seguinte sobe junto: somando os dois paddings padrão
   (32 + 40) sobravam 72px vazios entre a nota da API e "O que mudou". */
.hero-split { padding: 30px 0 12px; }
.hero-split + .section { padding-top: 20px; }

/* 1060px, not 1000px: the two minmax mins plus the gap need 960px of content,
   and at a 1000px viewport the padded .wrap only offers 952px — it would overflow. */
@media (min-width: 1060px) {
  .hero-split .hero-inner {
    display: grid;
    grid-template-columns: minmax(400px, 0.85fr) minmax(520px, 1.15fr);
    gap: 40px;
    align-items: start;
  }
}

.hero-text { min-width: 0; }
.hero-proof { min-width: 0; }

/* Stacked layout: the grid gap no longer applies, so the terminals would sit
   flush against the CTA buttons. */
@media (max-width: 1059px) {
  .hero-proof { margin-top: 30px; }
}

.proof-title {
  font-family: var(--font-mono);
  font-size: 1.05rem;
  margin: 0 0 4px;
  letter-spacing: -0.01em;
}

.proof-sub { color: var(--ink-dim); margin: 0 0 12px; font-size: 0.88rem; }

.badge {
  display: inline-block;
  font-family: var(--font-mono);
  padding: 4px 10px;
  border-radius: 4px;
  background: rgba(247,147,26,0.1);
  border: 1px solid rgba(247,147,26,0.35);
  color: var(--bitcoin);
  font-size: 0.78rem;
  font-weight: 600;
  margin-bottom: 14px;
}

.hero h1 {
  font-family: var(--font-mono);
  font-size: 1.65rem;
  font-weight: 700;
  margin: 0 0 10px;
  max-width: 700px;
  letter-spacing: -0.01em;
}

.lead {
  color: var(--ink-dim);
  max-width: 620px;
  font-size: 0.95rem;
}

.cta-row { margin-top: 14px; display: flex; gap: 12px; flex-wrap: wrap; }

.btn {
  display: inline-block;
  font-family: var(--font-mono);
  padding: 11px 18px;
  border-radius: var(--radius);
  font-weight: 600;
  font-size: 0.88rem;
  text-decoration: none !important;
  border: 1px solid transparent;
}

.btn-sm { padding: 8px 14px; font-size: 0.8rem; }

/* Texto branco a pedido. Branco sobre o laranja --bitcoin dá 2,30:1 (3,43:1 no
   hover), abaixo dos 4,5:1 do AA que o resto da página cumpre; o #1a1200 que
   estava aqui dava 8,09:1. */
.btn-primary { background: var(--bitcoin); color: #fff; }
.btn-primary:hover { background: var(--bitcoin-dim); }

.btn-ghost { border-color: var(--border); color: var(--ink); }
.btn-ghost:hover { border-color: var(--bitcoin); color: var(--bitcoin); }

/* Serial monitor signature */
.terminal-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 16px;
}

.terminal-card {
  background: var(--bg-terminal);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}

.terminal-bar {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 9px 14px;
  background: rgba(255,255,255,0.03);
  border-bottom: 1px solid var(--border);
}

.terminal-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--phosphor);
  opacity: 0.55;
}

/* Sinaliza os cards em que o fetch ao vivo (ver o script no fim do body)
   conseguiu resposta do Bitaxe — só acontece para quem abre a página na
   mesma LAN dos aparelhos, então na maioria das visitas o ponto fica no
   opacity:0.55 estático acima, sem a pulsação. */
.terminal-card.is-live .terminal-dot {
  opacity: 1;
  animation: live-pulse 2s ease-in-out infinite;
}

@keyframes live-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.5; }
}

@media (prefers-reduced-motion: reduce) {
  .terminal-card.is-live .terminal-dot { animation: none; }
}

.terminal-title {
  font-family: var(--font-mono);
  font-size: 0.74rem;
  color: var(--ink-dim);
}

.terminal-rows {
  padding: 10px 16px 4px;
  font-family: var(--font-mono);
}

.t-row {
  display: grid;
  grid-template-columns: 5.5em auto 1fr;
  align-items: baseline;
  gap: 10px;
  padding: 5px 0;
  border-bottom: 1px dashed rgba(255,255,255,0.09);
}
.t-row:last-child { border-bottom: none; }

.t-key {
  color: var(--ink-dim);
  font-size: 0.74rem;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

.t-val {
  color: var(--phosphor);
  font-weight: 700;
  font-size: 0.92rem;
}
.t-val small { font-size: 0.7rem; font-weight: 600; color: var(--ink-dim); }

.t-hint {
  color: var(--ink-dim);
  font-size: 0.74rem;
  text-align: right;
}

.terminal-footer {
  padding: 4px 16px 12px;
  font-family: var(--font-mono);
  font-size: 0.72rem;
}

.log-meta { color: #3a9b63; }

.capture-note {
  margin: 12px 0 0;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--ink-dim);
}

/* Em repouso o cursor fica fraco: presente, mas sem chamar atenção.
   Piscar o tempo todo não informava nada — agora o piscar é o evento. */
.cursor {
  display: inline-block;
  width: 7px;
  background: var(--phosphor);
  opacity: 0.3;
}

/* Pisca enquanto a classe estiver posta. Quem decide por quanto tempo é o JS,
   que estende a janela a cada share nova — por isso 'infinite' aqui, e não uma
   contagem fixa: uma contagem terminaria no meio de uma janela renovada.

   Uma piscada por segundo — cinco dentro da janela de 5 s.

   Esta é a única animação da página que ignora 'prefers-reduced-motion' de
   propósito. Com a preferência ligada a regra virava 'animation: none', e o
   cursor ficava simplesmente aceso os 5 s inteiros: um liga/desliga só, que é
   exatamente o contrário do pedido. É um cursor de terminal a 1 Hz, limitado a
   5 s e do tamanho de um caractere — movimento mínimo, e o sinal se perde sem
   ele. */
.cursor.is-nova-share {
  animation: pisca-pisca 1s steps(1) infinite;
}

/* steps(1) e não uma transição: aceso e apagado secos, como o cursor do
   terminal, sem meio-tom entre um estado e outro. */
@keyframes pisca-pisca {
  0%, 49% { opacity: 1; }
  50%, 100% { opacity: 0; }
}

/* Fix cards */
/* Agrupamento das correções por natureza. Os críticos vêm primeiro porque são
   os que afetam quem já está minerando; o resto desce em ordem de urgência. */
.cards-group { margin-bottom: 24px; }
.cards-group:last-child { margin-bottom: 0; }

.cards-group-title {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-mono);
  font-size: 0.82rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-dim);
  margin: 0 0 4px;
}
/* A régua ocupa o espaço restante, separando os grupos sem uma borda sólida que
   competiria visualmente com os cards. */
.cards-group-title::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--border);
}

.cards-group-count {
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--ink-dim);
  background: rgba(255,255,255,0.06);
  padding: 1px 8px;
  border-radius: 999px;
}

.cards-group-sub {
  color: var(--ink-dim);
  font-size: 0.88rem;
  margin: 0 0 14px;
  max-width: 620px;
}

/* Cada grupo herda a cor da própria categoria, a mesma já usada nas tags dos
   cards, para título e etiqueta contarem a mesma história. */
.cards-group--criticos .cards-group-title { color: var(--danger); }
.cards-group--criticos .cards-group-count { color: var(--danger); background: rgba(255,93,93,0.14); }
.cards-group--estabilidade .cards-group-title { color: var(--phosphor); }
.cards-group--estabilidade .cards-group-count { color: var(--phosphor); background: rgba(79,227,138,0.14); }
.cards-group--seguranca .cards-group-title { color: var(--copper); }
.cards-group--seguranca .cards-group-count { color: var(--copper); background: rgba(201,138,78,0.16); }
/* Novidade usa o laranja Bitcoin, distinto das três categorias de correção:
   é adição, não conserto. */
.cards-group--novidades .cards-group-title { color: var(--bitcoin); }
.cards-group--novidades .cards-group-count { color: var(--bitcoin); background: rgba(247,147,26,0.14); }
.card-feature .tag { color: var(--bitcoin); background: rgba(247,147,26,0.14); }

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 16px;
  /* Esticados de propósito (a pedido): com "start" as bordas de baixo de cada
     fileira ficavam desencontradas. O custo é o espaço vazio passar para dentro
     dos cards mais curtos da fileira. */
  align-items: stretch;
}

/* Pinned to 3 columns instead of auto-fit: with the wider wrap, auto-fit fits 4
   tracks and the 6 cards leave two empty slots on the second row. */
@media (min-width: 900px) {
  .cards { grid-template-columns: repeat(3, 1fr); }
}

.card {
  position: relative;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 20px;
}

.card::before,
.card::after {
  content: "";
  position: absolute;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--border);
  top: 10px;
}
.card::before { left: 10px; }
.card::after { right: 10px; }

.card-critical {
  border-color: rgba(255,93,93,0.4);
  background: linear-gradient(180deg, rgba(255,93,93,0.06), var(--bg-panel));
}
.card-critical::before,
.card-critical::after { background: rgba(255,93,93,0.5); }

.tag {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 700;
  color: var(--ink-dim);
  background: rgba(255,255,255,0.06);
  padding: 3px 9px;
  border-radius: 999px;
  margin-bottom: 10px;
}

.card-critical .tag { color: var(--danger); background: rgba(255,93,93,0.14); }
.card-stability .tag { color: var(--phosphor); background: rgba(79,227,138,0.14); }
.card-security .tag { color: var(--copper); background: rgba(201,138,78,0.16); }

.card h3 { margin: 0 0 8px; font-size: 1rem; font-family: var(--font-mono); font-weight: 600; }
.card p { margin: 0; color: var(--ink-dim); font-size: 0.9rem; }

/* Downloads */
.downloads {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 14px;
}

.dl-card {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 16px 18px;
  display: flex;
  align-items: center;
  gap: 14px;
}

.dl-ext {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  font-weight: 700;
  color: var(--copper);
  border: 1px solid var(--copper);
  border-radius: 4px;
  padding: 4px 6px;
  flex-shrink: 0;
}

.dl-info { flex: 1; min-width: 0; }
.dl-info h3 { margin: 0 0 4px; font-size: 0.95rem; font-family: var(--font-mono); }
.dl-info p { margin: 0; color: var(--ink-dim); font-size: 0.85rem; }

.dl-info .dl-hash {
  margin-top: 4px;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  line-height: 1.45;
  /* Was a custom #6f7c6c, which landed at 4.26:1 — below the 4.5:1 that WCAG AA
     asks for at this size. --ink-dim is 8.4:1 on the panel background. */
  color: var(--ink-dim);
  word-break: break-all;
}
.dl-hash span { color: var(--copper); font-weight: 700; }

.dl-verify { margin: 12px 0 8px; font-size: 0.82rem; color: var(--ink-dim); }

.verify-list {
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 0.82rem;
  color: var(--ink-dim);
}
.verify-list li { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.verify-list li + li { margin-top: 4px; }

.verify-list span {
  flex-shrink: 0;
  width: 4.5em;
  font-family: var(--font-mono);
  font-size: 0.74rem;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--copper);
}

/* Passo a passo de atualização — acento cobre: é instrução, não perigo.
   max-width: na largura toda da .wrap cada linha passava de 160 caracteres;
   760px deixa em torno de 100, perto do .section-sub (620px). Centralizado para
   não ficar colado na borda esquerda com um vazio à direita. */
.flash-box {
  max-width: 760px;
  margin: 18px auto 0;
  background: var(--bg-panel);
  border: 1px solid rgba(184,121,63,0.45);
  border-radius: var(--radius);
  padding: 18px 20px;
}

.flash-box h3 {
  margin: 0 0 10px;
  color: var(--copper);
  font-family: var(--font-mono);
  font-size: 1rem;
}

.flash-box p { margin: 0 0 8px; color: var(--ink-dim); font-size: 0.9rem; }
.flash-box p:last-child { margin-bottom: 0; }

.offset-list {
  list-style: none;
  margin: 0 0 12px;
  padding: 0;
  font-family: var(--font-mono);
  font-size: 0.88rem;
}
.offset-list li + li { margin-top: 6px; }
.offset-list span { color: var(--ink-dim); font-size: 0.8rem; }

/* Passo a passo do update pelo AxeOS. Os nomes de tela (Update, Browse) ficam em
   negrito porque são o que a pessoa procura na interface, em inglês. */
.ota-steps { margin: 4px 0 12px; padding-left: 22px; }
.ota-steps li { color: var(--ink-dim); font-size: 0.9rem; }
.ota-steps li + li { margin-top: 8px; }
.ota-steps strong { color: var(--ink); }
.ota-steps em { color: var(--ink); font-style: normal; font-family: var(--font-mono); font-size: 0.84rem; }

/* O caminho USB fica recolhido: é plano B para aparelho sem interface, não o
   caminho principal. */
.usb-fallback {
  margin-top: 14px;
  border-top: 1px solid var(--border);
  padding-top: 12px;
}
.usb-fallback summary {
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: 0.88rem;
  color: var(--copper);
}
.usb-fallback[open] summary { margin-bottom: 10px; }

.flash-box pre {
  background: var(--bg-terminal);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 10px 14px;
  overflow-x: auto;
  margin: 8px 0 12px;
}

.flash-box pre code { background: transparent; padding: 0; color: var(--phosphor); }

/* Affiliate */
.affiliate-card {
  display: flex;
  gap: 20px;
  align-items: center;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 18px;
  flex-wrap: wrap;
}

.affiliate-card > a { flex-shrink: 0; display: block; }

.affiliate-img {
  width: 100px;
  height: 100px;
  object-fit: cover;
  border-radius: var(--radius);
  border: 1px solid var(--border);
}

.affiliate-info { flex: 1; min-width: 200px; }
.affiliate-info h3 { margin: 0 0 6px; font-size: 1rem; }
.affiliate-desc { color: var(--ink-dim); margin: 0 0 8px; font-size: 0.9rem; }
.affiliate-price { font-family: var(--font-mono); font-weight: 700; color: var(--bitcoin); margin: 0 0 12px; font-size: 0.85rem; }

.disclosure { margin-top: 10px; font-size: 0.78rem; color: var(--ink-dim); }

/* Doação em cripto
   Cobre no rótulo da moeda pelo mesmo motivo dos hashes e offsets: é metadado
   técnico, não chamada para ação — o laranja aqui competiria com os botões. */
.donate-title {
  /* Alvo do fallback dos chips flutuantes (#doacao): mesma folga do section[id]. */
  scroll-margin-top: 70px;
  margin: 28px 0 6px;
  font-family: var(--font-mono);
  font-size: 1rem;
  color: var(--copper);
}

.donate-sub { margin: 0 0 14px; font-size: 0.88rem; color: var(--ink-dim); max-width: 620px; }

.donate-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 12px;
}

.donate-card {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px 16px;
}

.donate-head { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; margin-bottom: 8px; }

.donate-coin {
  font-family: var(--font-mono);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--copper);
}

/* A rede fica ao lado da moeda, não escondida no rodapé do card: enviar um
   token na rede errada é irreversível. */
.donate-net { font-size: 0.74rem; color: var(--ink-dim); }

/* O fundo claro e a margem de ~4 módulos já vêm no próprio PNG: sobre o grafite
   da página, um QR sem essa margem clara falha na leitura de várias câmeras. */
.donate-qr {
  display: block;
  width: 136px;
  height: auto;
  margin: 0 0 10px;
  border-radius: 6px;
}

.donate-addr {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  line-height: 1.5;
  color: var(--ink-dim);
  background: var(--bg-terminal);
  border-radius: 6px;
  padding: 8px 10px;
  word-break: break-all;
}

/* hidden até o script confirmar que a área de transferência existe: um botão
   "copiar" que não copia é pior que botão nenhum. */
.donate-copy {
  margin-top: 8px;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--ink-dim);
  background: none;
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 4px 12px;
  cursor: pointer;
}
.donate-copy:hover { border-color: var(--copper); color: var(--copper); }
.donate-copy[hidden] { display: none; }

/* Floating affiliate card
   Sits in the left gutter above 1670px; below that it becomes a slim fixed bar.
   The threshold is pure geometry: the gutter is (viewport - scrollbar - the
   1240px .wrap) / 2 plus the wrap's 24px padding, and it has to clear the card's
   200px + 14px offset with room to spare. Widening .wrap from 1040px to 1240px
   ate 100px of gutter on each side, so this went from 1500px to 1670px. */
.affiliate-float {
  position: fixed;
  top: 74px;
  left: 14px;
  z-index: 9;
  width: 200px;
  background: var(--bg-panel);
  border: 1px solid rgba(247,147,26,0.38);
  border-radius: var(--radius);
  padding: 14px;
  box-shadow: 0 12px 28px rgba(0,0,0,0.55);
}

.affiliate-float[hidden] { display: none; }

/* Suprimida pelo IntersectionObserver em index.html enquanto #apoie está na
   tela — opacity, não display/hidden, para não interferir no estado "fechado
   pelo usuário" nem disparar o :has(...) que libera o padding-bottom do body. */
.affiliate-float--near-apoie {
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease;
}

@media (prefers-reduced-motion: reduce) {
  .affiliate-float--near-apoie { transition: none; }
}

.float-close {
  position: absolute;
  top: 6px;
  right: 6px;
  /* 22px ficava abaixo do alvo mínimo de 24px da WCAG 2.5.8 — e é o único jeito
     de dispensar o anúncio, então errar aqui custa caro no celular. */
  width: 28px;
  height: 28px;
  padding: 0;
  line-height: 1;
  background: transparent;
  border: 0;
  border-radius: 4px;
  color: var(--ink-dim);
  font-size: 1.1rem;
  cursor: pointer;
}
.float-close:hover { color: var(--ink); background: rgba(255,255,255,0.07); }

.float-label {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--bitcoin);
  margin-bottom: 10px;
}

.float-thumb { display: block; }

.float-thumb img {
  display: block;
  width: 100%;
  /* Needed because the <img> now carries width/height attributes: without this
     the attribute height wins and aspect-ratio is ignored. */
  height: auto;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border: 1px solid var(--border);
  border-radius: 6px;
}

.float-title {
  margin: 10px 0 2px;
  font-family: var(--font-mono);
  font-size: 0.84rem;
  font-weight: 600;
}

.float-spec { margin: 0; font-size: 0.75rem; color: var(--ink-dim); }

/* Versão mínima da seção de doação: só atalhos. Os QRs não vêm junto porque
   no tamanho da barra (46px) nenhuma câmera lê — quem precisa deles cai em
   #doacao pelo href. Mesmo traço pill do .donate-copy, para ler como "a mesma
   coisa, menor". */
.float-donate {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 5px;
  margin: 10px 0;
}

.float-donate-label {
  flex-basis: 100%;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  color: var(--ink-dim);
}

.float-coin {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  line-height: 1;
  white-space: nowrap;
  color: var(--ink-dim);
  text-decoration: none;
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 5px 8px;
}
.float-coin:hover { border-color: var(--copper); color: var(--copper); }

.float-cta { display: block; text-align: center; }

@media (max-width: 1669px) {
  /* Must stay above the fixed bar's own height, or the footer ends up under it. */
  body { padding-bottom: 88px; }

  /* Fechada a barra, a reserva vira 88px de espaço morto no fim da página. */
  body:has(.affiliate-float[hidden]) { padding-bottom: 0; }

  .affiliate-float {
    top: auto;
    bottom: 0;
    left: 0;
    right: 0;
    width: auto;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 44px 10px 14px;
    border-width: 1px 0 0;
    border-radius: 0;
  }

  .float-label { display: none; }

  .float-thumb img {
    width: 46px;
    height: 46px;
    aspect-ratio: auto;
  }

  /* O espaço livre passa do texto para os chips: centralizados entre o produto
     e o botão, em linha única — a barra não pode crescer além do padding-bottom
     de 88px reservado no body. */
  .float-text { flex: 0 1 auto; min-width: 0; }
  .float-title { margin: 0; }

  .float-donate {
    flex: 1;
    flex-wrap: nowrap;
    justify-content: center;
    margin: 0;
  }
  .float-donate-label { flex-basis: auto; white-space: nowrap; }

  .float-close {
    top: 50%;
    right: 10px;
    transform: translateY(-50%);
  }

  .float-cta { flex-shrink: 0; }
}

/* Abaixo disso produto + chips + botão não cabem numa linha: os chips saem e a
   doação fica só na seção normal da página. Medido no pior caso, com os chips
   mostrando "copiado …xxxx": precisam de ~418px, e em 800px sobravam só 355 (o
   rótulo quebrava e a barra crescia). .98 e não 899px: com zoom fracionário a
   largura cai entre 899 e 900 e escaparia das duas regras. */
@media (max-width: 899.98px) {
  .float-donate { display: none; }
  /* Sem os chips, o texto volta a ocupar o espaço livre e empurrar o botão. */
  .float-text { flex: 1; }
}

@media (max-width: 460px) {
  .float-spec { display: none; }
  .float-cta { font-size: 0.74rem; padding: 8px 10px; }

  /* Keep the bar one line tall, otherwise it grows past body's padding-bottom
     and covers the footer. */
  .float-title {
    font-size: 0.72rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}

/* Footer */
.footer {
  padding: 20px 0;
  border-top: 1px solid var(--border);
  color: var(--ink-dim);
  font-size: 0.82rem;
  font-family: var(--font-mono);
}

@media (max-width: 600px) {
  .hero h1 { font-size: 1.35rem; }

  /* The stacked topbar below is taller than the 58px desktop one. */
  section[id] { scroll-margin-top: 92px; }

  /* Brand and nav no longer fit side by side: stack them and let the nav
     scroll sideways instead of wrapping the brand onto three lines. */
  .topbar-inner {
    height: auto;
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
    padding-top: 10px;
    padding-bottom: 10px;
  }

  .brand { white-space: nowrap; }

  .topbar nav {
    width: 100%;
    gap: 6px;
    overflow-x: auto;
    scrollbar-width: none;
    -ms-overflow-style: none;
  }

  .topbar nav::-webkit-scrollbar { display: none; }

  .topbar nav a {
    font-size: 0.74rem;
    padding: 6px 10px;
  }
}

/* Impressão / salvar em PDF
   O miolo desta página é um procedimento de gravação — muita gente imprime ou
   gera PDF para seguir com o aparelho na bancada. No tema escuro isso sai numa
   mancha de tinta ilegível, com a barra fixa cobrindo o rodapé em toda página.
   Aqui a página vira preto no branco, o anúncio e a navegação somem, e os
   endereços dos links externos são impressos porque em papel não dá para clicar. */
@media print {
  /* Repintar por token em vez de por seletor: qualquer coisa que use --ink-dim,
     --border ou --phosphor acompanha automaticamente. Listar seletor a seletor
     deixava badge, tags e as unidades dos terminais lavados no papel. */
  :root {
    --bg: #fff;
    --bg-panel: #fff;
    --bg-terminal: #fff;
    --border: #999;
    --ink: #000;
    --ink-dim: #444;
    --copper: #6b4a1f;
    --bitcoin: #8a5200;
    --bitcoin-dim: #8a5200;
    --phosphor: #000;
    --danger: #9b0000;
  }

  body {
    background: #fff;
    background-image: none;
    padding-bottom: 0;
    font-size: 11pt;
  }

  /* Navegação, anúncio e chamadas para ação não têm função no papel. */
  .topbar,
  .skip-link,
  .affiliate-float,
  .cta-row,
  .cursor,
  #apoie { display: none; }

  .wrap { max-width: none; padding: 0; }
  .section, .hero { padding: 12pt 0; }

  /* Sem os tons translúcidos do tema escuro, que somem no branco. */
  .t-row { border-bottom: 1px dashed #ccc; }
  .terminal-bar { background: #f0f0f0; }
  .tag { background: #f0f0f0; }
  .log-meta { color: #444; }
  code { background: #f0f0f0; color: #000; }

  /* Botões viram texto com contorno: bloco laranja chapado gasta tinta e não
     clica em papel nenhum. */
  .btn-primary { background: none; color: #000; border: 1px solid #999; }

  pre {
    background: #f6f6f6;
    border: 1px solid #999;
    /* No papel não há para onde rolar: o comando precisa quebrar. */
    overflow-x: visible;
    white-space: pre-wrap;
  }
  pre code { overflow-wrap: anywhere; color: #000; }

  /* Um card ou um passo do procedimento cortado ao meio pela quebra de página
     é exatamente o tipo de erro que faz alguém gravar no offset errado. */
  .card,
  .dl-card,
  .terminal-card,
  .flash-box,
  pre,
  li { break-inside: avoid; }

  h2, h3, h4 { break-after: avoid; }

  /* Em papel o link não é clicável — sem isto o leitor fica sem a URL. */
  main a[href^="http"]::after {
    content: " (" attr(href) ")";
    font-size: 0.85em;
    word-break: break-all;
  }
}
