/* talents.css — janela de Talentos (js/ui/windows/talents.js; docs/specs/talents.md §1). Medidas em px de arte: calc(N * var(--px)).
   592×276: o corpo tem 580 × 234 (576 do miolo + os 2 + 2 que o `.window-body` puxa da moldura; 260 − título 14 − rodapé 12).
   À esquerda a VISTA da árvore (#tal-view, 364×234, a câmera de widgets/mapCamera.js com `geo.view`), 4 de vão e o painel
   (#tal-side, o resto: 212). Dentro da vista, o board (#tal-board) mede 364×234 × `--tz` (1 = inteira, 2 = perto) e anda
   pela câmera em px de arte inteiros; toda medida da árvore é `N * var(--tz) * var(--px)` — a arte escala em inteiro, nunca
   em transição. Cores só de tokens de base.css; o vermelho do caminho investido é o --c-danger (a referência do Diablo IV
   acende o tronco em vermelho). */
.tal-win { display: flex; gap: calc(4 * var(--px)); overflow: hidden; }
/* o rodapé encosta no corpo (o `.window-footer` desce 2): é o que devolve à vista os 234 da árvore inteira */
.tal-footer { margin-top: 0; }

/* ---- a vista e o board ------------------------------------------------------------------------------------------- */
.tal-view {
  position: relative; flex: none; overflow: hidden;
  width: calc(364 * var(--px)); height: calc(234 * var(--px));
  /* o gesto é da câmera (arrasto, pinça, dois toques): o navegador não rola nem amplia a página por cima dela */
  touch-action: none; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none;
  background: var(--c-bg);
}
.tal-view.is-near { cursor: grab; }
.tal-view.is-grabbing { cursor: grabbing; }
.tal-board {
  position: absolute; left: 0; top: 0;
  width: calc(364 * var(--tz) * var(--px)); height: calc(234 * var(--tz) * var(--px));
  /* o ladrilho tem 26×26 = uma célula da grade, alinhado com a área da árvore (13 de ar à esquerda, 1 em cima) */
  background: var(--ui-tal_backdrop, none) calc(13 * var(--tz) * var(--px)) calc(var(--tz) * var(--px)) / calc(26 * var(--tz) * var(--px)) calc(26 * var(--tz) * var(--px)) repeat, var(--c-bg);
  image-rendering: pixelated;
}
.tal-edges { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; shape-rendering: crispEdges; }
/* C28 (análise crítica de 2026-09-22, `B41-talents.png`): a 0,35 sobre o fundo quase preto da árvore o conector saía
   em ~#3f3c38 — praticamente invisível em 1×, e uma árvore em que não se vê quem liga a quem não é uma árvore.
   0,8 mantém a hierarquia (ligado vermelho e pendente dourado continuam gritando mais) e faz o traço existir. */
.tal-edges line { stroke-width: 2; stroke: var(--c-text-dim); opacity: 0.8; }
.tal-edges line.is-on { stroke: var(--c-danger); opacity: 1; }
.tal-edges line.is-pending { stroke: var(--c-gold); opacity: 1; }
/* o nó é a CÉLULA de 26 (o alvo de toque: 26 na inteira, 52 no perto); `--x`/`--y` = o centro no board (talentView.js ›
   boardCenter), `--fs` = o lado da moldura pelo tipo (20 · 24 · 28) */
.tal-node {
  position: absolute; padding: 0; border: 0; background: none; cursor: pointer;
  left: calc((var(--x) - 13) * var(--tz) * var(--px)); top: calc((var(--y) - 13) * var(--tz) * var(--px));
  width: calc(26 * var(--tz) * var(--px)); height: calc(26 * var(--tz) * var(--px));
}
.tal-frame, .tal-icon, .tal-rank { position: absolute; pointer-events: none; }
.tal-frame {
  left: calc((26 - var(--fs)) / 2 * var(--tz) * var(--px)); top: calc((26 - var(--fs)) / 2 * var(--tz) * var(--px));
  width: calc(var(--fs) * var(--tz) * var(--px)); height: calc(var(--fs) * var(--tz) * var(--px));
  background: var(--frame, none) 0 0 / 100% 100% no-repeat, var(--c-shade); image-rendering: pixelated;
}
.tal-icon {
  left: calc(5 * var(--tz) * var(--px)); top: calc(5 * var(--tz) * var(--px));
  width: calc(16 * var(--tz) * var(--px)); height: calc(16 * var(--tz) * var(--px));
  background: none center / 100% 100% no-repeat; image-rendering: pixelated;
}
.tal-rank {
  right: 0; bottom: calc(-2 * var(--tz) * var(--px));
  font-size: calc(6 * var(--tz) * var(--px)); line-height: 1; color: var(--c-text); text-shadow: 0 var(--px) 0 var(--c-bg);
  /* placa por cima dos vizinhos: o contador do nó ao lado da raiz caía sob a moldura de 28 e o contorno do selecionado (a
     raiz, na visão geral) — na inteira o "3/3" do nó 1 lia "3/8" (prova N2 dos Talentos, 2026-10-04) */
  z-index: 1; padding: 0 var(--px); background: var(--c-bg);
}
/* o mouse por cima só REALÇA (§1: quem seleciona é o toque); o selecionado ganha o contorno claro e o pendente o dourado */
.tal-node:hover .tal-frame { filter: brightness(1.3); }
.tal-node.is-pending .tal-frame { box-shadow: 0 0 0 var(--px) var(--c-gold); }
.tal-node.is-selected .tal-frame { outline: var(--px) solid var(--c-text); outline-offset: var(--px); }
.tal-node.is-locked { cursor: default; }
.tal-node.is-locked .tal-icon { opacity: 0.45; }
.tal-node.is-closed { opacity: 0.45; }
/* SÓ a pedra-angular que dá para pegar agora ganha o contorno dourado (§1) — que segue a borda da moldura, não um quadrado */
.tal-node.is-keystone.is-open .tal-frame { filter: drop-shadow(0 0 var(--px) var(--c-gold)) drop-shadow(0 0 var(--px) var(--c-gold)); }
.tal-node.is-keystone.is-open:hover .tal-frame { filter: brightness(1.3) drop-shadow(0 0 var(--px) var(--c-gold)) drop-shadow(0 0 var(--px) var(--c-gold)); }

/* os dois cantos de cima: ↖ o cadeado do nível, ↗ o zoom (−/+ de 24, o molde da carta) */
.tal-lock, .tal-zoom { position: absolute; top: calc(2 * var(--px)); z-index: 1; display: flex; align-items: center; gap: calc(2 * var(--px)); }
.tal-lock { left: calc(2 * var(--px)); padding: var(--px); background: var(--c-bg); }
.tal-zoom { right: calc(2 * var(--px)); }
.tal-zoom-btn { width: calc(24 * var(--px)); min-height: calc(24 * var(--px)); padding: 0; }

/* ---- o painel ------------------------------------------------------------------------------------------------------ */
.tal-side { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: calc(2 * var(--px)); overflow: hidden; }
/* a visão geral é UMA caixa que rola (o mecanismo de css/scroll-fade.css): os três cartões e o Total. No pior caso (três
   efeitos de 4 linhas + 8 fichas) ela rola com o degradê no pé, nunca corta */
.tal-overview { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: calc(4 * var(--px)); line-height: 1.15; }
.tal-overview > * { flex: none; }
.tal-detail { flex: 1; min-height: 0; overflow-y: auto; line-height: 1.15; display: flex; flex-direction: column; gap: calc(2 * var(--px)); }
.tal-detail > * { flex: none; }
/* a barra do TOPO do detalhe, fora da caixa que rola: o nome (até duas linhas, quebra só entre palavras) e o −1 e o Subir de
   24. No topo porque o balão do Aplicar e do Pagar abre PARA CIMA do rodapé e, no pé do painel, cobria os dois (revisão N2,
   2026-10-04); o × que voltava à visão geral saiu (G6: o × do título volta, `back()`). A recusa (`#tal-msg`) vem logo abaixo. */
.tal-detail-bar { display: flex; align-items: center; gap: calc(3 * var(--px)); flex: none; min-height: calc(24 * var(--px)); line-height: 1.15; }
.tal-node-name { flex: 1; min-width: 0; overflow-wrap: normal; }
.tal-step-row { display: flex; gap: calc(3 * var(--px)); flex: none; }
.tal-step-btn { min-height: calc(24 * var(--px)); min-width: calc(40 * var(--px)); }
.tal-msg { flex: none; }
.tal-footer-group { display: flex; align-items: center; gap: calc(3 * var(--px)); width: 100%; }
.tal-grow { flex: 1; min-width: 0; }
.tal-power { flex: none; white-space: nowrap; margin: 0 calc(3 * var(--px)); }

/* ---- gramática de enxugamento (docs/ux-casos.md §17) -------------------------------------------------------
   Nenhuma cor nova e nenhum ícone novo: tokens de base.css e peças que já existem em `manifest.ui`. */
/* Ícone 16×16 da série única (stat, cadeado): inerte, `aria-hidden`, nunca informa sozinho. */
.tal-ico {
  display: inline-block; flex: none;
  width: calc(16 * var(--px)); height: calc(16 * var(--px));
  background: none center / 100% 100% no-repeat; image-rendering: pixelated;
}
/* G2 — selo: moldura + palavra curta + cor (o mesmo desenho de `.attr-seal` e de `.clan-war-phase`). */
.tal-seal { flex: none; padding: 0 calc(2 * var(--px)); border: var(--px) solid currentColor; }
/* os selos do nó em UMA fila: [tipo] · 1/3 · [pendente] · [ramo exclusivo] (eram três linhas de largura cheia). A fila tem
   24 porque é a 1.ª da caixa que rola: o alvo do selo "ramo exclusivo" cresce DENTRO dela (para cima a caixa o recortaria) */
.tal-node-head { display: flex; align-items: center; flex-wrap: wrap; gap: calc(3 * var(--px)); min-height: calc(24 * var(--px)); }
.tal-node-rank { flex: none; white-space: nowrap; }
/* modificadores em fichas de ícone + valor, no lugar de "Agora: +4 Força, +2% Vida máxima" */
/* `width: fit-content`: a pista pontilhada é o RODAPÉ deste grupo, e um grupo de largura cheia desenhava um risco de
   ponta a ponta no painel — a listra que o teste de erro (b) do G4 proíbe. Ela termina onde o último valor termina. */
.tal-mods-group { display: flex; flex-direction: column; gap: var(--px); width: fit-content; max-width: 100%; }
.tal-mods { display: flex; align-items: center; gap: calc(3 * var(--px)); flex-wrap: wrap; min-height: calc(16 * var(--px)); }
.tal-mod { display: inline-flex; align-items: center; gap: var(--px); white-space: nowrap; }
/* As pistas são alvos de TOQUE (o balão abre no dedo; celular deitado): ≥ 24 de altura por um `::after` absoluto (o molde de
   rank.css), sem mexer no layout. Cada uma cresce para o lado LIVRE: o selo `Total` e o "Toque num talento" dentro da fila
   de 24 do Total, o selo "ramo exclusivo" dentro da fila de 24 dos selos do nó, as fichas para baixo (o texto do efeito). */
.tal-sum-hint, .tal-sum-seal, .tal-node-exclusive, .tal-mods-group, .tal-lock .tal-seal { position: relative; }
.tal-sum-hint::after, .tal-sum-seal::after, .tal-node-exclusive::after, .tal-mods-group::after, .tal-lock .tal-seal::after { content: ''; position: absolute; left: 0; right: 0; }
/* a linha tem 9,2 de arte (8 × 1,15): 8 para cada lado dá 25,2 — o lint pede 24 já com o ::after (7 dava 23,2) */
.tal-sum-hint::after, .tal-sum-seal::after { top: calc(-8 * var(--px)); bottom: calc(-8 * var(--px)); }
.tal-lock .tal-seal::after { top: 0; bottom: calc(-14 * var(--px)); }
/* o selo tem 11,2 (9,2 + a borda) centrado na fila de 24: −6 em cima (fica dentro da caixa) e −8 embaixo dão 25,2 */
.tal-node-exclusive::after { top: calc(-6 * var(--px)); bottom: calc(-8 * var(--px)); }
.tal-mods-group::after { top: 0; bottom: calc(-8 * var(--px)); }
/* os três ramos como CARTÕES EMPILHADOS (§1): à esquerda a moldura da pedra-angular (28, `tal_node_keystone_<estado>`) com o
   ícone dela; à direita o nome, o `x/21` (só com gasto) e o efeito inteiro da pedra. O escolhido ganha a palavra (G2: a cor
   nunca vem sozinha) e o fechado ganha o cadeado de verdade. */
.tal-specs { display: flex; flex-direction: column; }
.tal-spec {
  min-width: 0; min-height: calc(30 * var(--px));
  display: grid; grid-template-columns: calc(28 * var(--px)) minmax(0, 1fr) auto; column-gap: calc(3 * var(--px)); row-gap: var(--px);
  align-items: start; padding: var(--px);
  border: 0; background: var(--c-shade); color: inherit; font: inherit; line-height: 1.15; text-align: left; cursor: pointer;
}
.tal-spec.is-chosen { outline: var(--px) solid var(--c-danger); }
.tal-spec.is-closed { opacity: 0.4; }
.tal-spec:focus-visible { outline: var(--px) solid var(--c-gold); }
.tal-spec-frame {
  grid-column: 1; grid-row: 1 / span 2; position: relative;
  width: calc(28 * var(--px)); height: calc(28 * var(--px));
  background: var(--frame, none) 0 0 / 100% 100% no-repeat, var(--c-bg); image-rendering: pixelated;
}
/* a pedra aberta: o MESMO contorno dourado do nó da árvore */
.tal-spec.is-open .tal-spec-frame { filter: drop-shadow(0 0 var(--px) var(--c-gold)) drop-shadow(0 0 var(--px) var(--c-gold)); }
.tal-spec-icon {
  position: absolute; left: calc(6 * var(--px)); top: calc(6 * var(--px));
  width: calc(16 * var(--px)); height: calc(16 * var(--px)); background: none center / 100% 100% no-repeat; image-rendering: pixelated;
}
.tal-spec-spent { grid-column: 3; grid-row: 1; white-space: nowrap; }
.tal-spec-effect { grid-column: 2 / span 2; grid-row: 2; min-width: 0; }
/* o nome do ramo NÃO se trunca: "Quebra-Mur…" é um nome próprio pela metade. Ele quebra em duas linhas, como antes. */
/* P35 (classes-v3): quebra SÓ entre palavras — `anywhere` partia "Sangrad/or", "Entropist/a", "Guardiã/o das/Horas". */
.tal-spec-name { grid-column: 2; grid-row: 1; min-width: 0; overflow-wrap: normal; hyphens: manual; }
/* P37 (classes-v3): o selo "sua" e o cadeado SAEM da linha do nome e montam no canto superior direito do cartão, fora do
   fluxo do texto — na linha, "Armadilheiro" pintava 17 px de texto por cima do selo e "Guardião das Horas" caía em 3
   linhas. A marca PENDURA sobre a moldura: a base dela para na borda do padding (top −7 + 8 de altura = 1 = o padding do
   cartão), então nenhuma linha do nome a alcança, e o nome ganha a largura inteira. Desde os cartões EMPILHADOS numa caixa
   que rola, o espaço que a marca sobe tem de estar DENTRO da caixa (o que passa da borda de cima dela é recortado): a fila
   desce 7 e o vão entre cartões é 7. As medidas são explícitas (altura 8 nas duas) porque `talentSpecBadge.test.js` faz
   esta conta sem motor de layout. */
.tal-specs { margin-top: calc(7 * var(--px)); gap: calc(7 * var(--px)); }
.tal-spec { position: relative; }
.tal-spec-seal, .tal-spec-lock { position: absolute; top: calc(-7 * var(--px)); right: 0; }
.tal-spec-seal {
  color: var(--c-danger); font-size: calc(6 * var(--px));
  box-sizing: border-box; height: calc(8 * var(--px)); line-height: calc(6 * var(--px)); background: var(--c-bg);
}
.tal-spec-lock { width: calc(8 * var(--px)); height: calc(8 * var(--px)); }
/* o TOTAL (§1): a fila de 24 com o selo e as passivas ligadas (ou `—` e o "Toque num talento"), e a grade de 3 colunas de
   fichas `[ícone] +12`; a que o pendente muda é `+4 → +8` em dourado e ocupa duas colunas (não cabe em uma de 68) */
.tal-sum { display: flex; flex-direction: column; gap: calc(2 * var(--px)); }
.tal-sum-head { display: flex; align-items: center; flex-wrap: wrap; gap: calc(3 * var(--px)); min-height: calc(24 * var(--px)); }
.tal-sum-dash { flex: none; }
.tal-passive {
  position: relative; flex: none; padding: 0; border: 0; cursor: pointer;
  width: calc(24 * var(--px)); height: calc(24 * var(--px)); background: var(--c-shade);
}
.tal-passive.is-pending { box-shadow: inset 0 0 0 var(--px) var(--c-gold); }
.tal-passive:focus-visible { outline: var(--px) solid var(--c-gold); }
.tal-passive-icon {
  position: absolute; left: calc(4 * var(--px)); top: calc(4 * var(--px)); pointer-events: none;
  width: calc(16 * var(--px)); height: calc(16 * var(--px)); background: none center / 100% 100% no-repeat; image-rendering: pixelated;
}
.tal-sum-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--px) calc(3 * var(--px)); }
.tal-sum-grid .tal-mod.is-pending { grid-column: span 2; }
/* a troca do reset numa fila: [moeda] −12.500 · +12 livres · [moeda] seu 500K */
.tal-reset-line { display: flex; align-items: center; gap: calc(4 * var(--px)); flex-wrap: wrap; }
/* a ficha do preço leva a pista (a palavra "ouro" e a pergunta inteira, G1) e é alvo de toque: ~10 de altura → 24 por um ::after
   (6 sobre o pé da árvore, 8 sobre a moldura de baixo), sem mexer na fila do rodapé (lint alvo-pequeno, E2E de 2026-10-04: com 7
   embaixo o lint mediu 23) */
.tal-reset-line .gold-label.has-more { position: relative; }
.tal-reset-line .gold-label.has-more::after { content: ''; position: absolute; left: 0; right: 0; top: calc(-6 * var(--px)); bottom: calc(-8 * var(--px)); }
