/* Painel ADM — folha unica, servida daqui. Sem CDN: a CSP do painel proibe
   qualquer origem externa, e uma folha de estilo de terceiro num painel
   administrativo e um caminho de execucao que nao precisa existir. */

:root {
    --fundo: #14171c;
    --painel: #1c2027;
    --painel-2: #222831;  /* realce de linha; estava cravado a mao no tr:hover */
    --borda: #2b313b;
    /* Risco ENTRE linhas de uma lista. Separado da --borda de proposito: a
       --borda e a cor da MOLDURA do cartao, e usa-la entre linhas fazia cada
       linha ler-se como um cartao proprio. */
    --risco: #333a45;
    --texto: #dfe3e8;
    --fraco: #98a1ad;
    --destaque: #6fb2ff;
    --perigo: #ff6b6b;
    /* Ambar do painel antigo (--warn). O que e informativo — "herda o preco do
       Iteminfo", "aba fora da legenda" — nao pode ser vermelho: o item
       continua a ser vendido, nao ha avaria nenhuma. */
    --aviso: #ffb020;
    --bom: #63d18a;
}

* { box-sizing: border-box; }

body {
    margin: 0;
    background: var(--fundo);
    color: var(--texto);
    font: 15px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

nav {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: .7rem 1.2rem;
    background: var(--painel);
    border-bottom: 1px solid var(--borda);
    flex-wrap: wrap;
}
nav a { color: var(--fraco); text-decoration: none; }
nav a:hover { color: var(--texto); }
nav a.marca { display: flex; align-items: center; margin-right: .5rem; }
/* A logo tem 440x152 com muita transparencia em volta; a altura fixa e o
   `width: auto` mantem a proporcao sem depender do tamanho do PNG. */
nav a.marca img { height: 26px; width: auto; display: block; }
nav .direita { margin-left: auto; display: flex; align-items: center; gap: .6rem; }
nav .quem { color: var(--fraco); font-size: .9em; }

main { padding: 1.2rem; max-width: 1400px; margin: 0 auto; }

h1 { font-size: 1.4rem; margin: 0 0 1rem; }
h2 { font-size: 1.1rem; margin: 1.6rem 0 .6rem; color: var(--fraco); font-weight: 600; }

a { color: var(--destaque); }

/* `.cartoes` era declarado DUAS vezes neste arquivo — aqui como flex e mais
   abaixo (menu de balanceamento) como `grid: repeat(auto-fit, minmax(300px,
   1fr))`. A segunda ganhava, entao os sete numeros da visao geral saiam com
   300px de largura cada um: uma tira de cartoes enormes onde deviam estar
   contadores. A declaracao flex saiu em 16-08-2026 e as telas que a queriam
   (visao geral, conta, personagem, cla) passaram a `.w-chapas`, que e a peca
   certa para um contador. Ficou UMA `.cartoes`, e ela e a grelha de cartoes
   do balanceamento. */
.cartao {
    background: var(--painel);
    border: 1px solid var(--borda);
    border-radius: 8px;
    padding: .8rem 1rem;
    min-width: 150px;
}
.cartao .rotulo { color: var(--fraco); font-size: .8rem; text-transform: uppercase; }
.cartao .valor { font-size: 1.5rem; font-weight: 600; }

table { width: 100%; border-collapse: collapse; background: var(--painel);
        border: 1px solid var(--borda); border-radius: 8px; overflow: hidden; }
th, td { padding: .5rem .7rem; text-align: left; border-bottom: 1px solid var(--borda); }
th { color: var(--fraco); font-size: .8rem; text-transform: uppercase; font-weight: 600; }
tr:last-child td { border-bottom: none; }
tbody tr:hover { background: #222831; }
td.numero, th.numero { text-align: right; font-variant-numeric: tabular-nums; }

.rotulo-online { color: var(--bom); }
.rotulo-banido { color: var(--perigo); }
.fraco { color: var(--fraco); }

/* `.linha` e nao `form.linha`: a tela da loja usa <div class=linha> para a
   caixa de filtro, que nao submete nada e por isso nao pode ser um form. */
.linha { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap;
         margin: .8rem 0; }

input[type=text], input[type=password], input[type=number], input[type=search],
textarea, select {
    background: #11141a;
    border: 1px solid var(--borda);
    color: var(--texto);
    border-radius: 6px;
    padding: .45rem .6rem;
    font: inherit;
}
textarea { width: 100%; min-height: 60vh; font-family: ui-monospace, Consolas, monospace;
           font-size: 13px; }

button {
    background: var(--destaque);
    color: #0d1117;
    border: none;
    border-radius: 6px;
    padding: .45rem .9rem;
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}
button.perigo { background: var(--perigo); color: #fff; }
button.discreto { background: transparent; color: var(--fraco); font-weight: 400;
                  border: 1px solid var(--borda); }
button:hover { filter: brightness(1.1); }

.aviso, .erro, .ok {
    border-radius: 8px; padding: .7rem 1rem; margin: .8rem 0;
    border: 1px solid var(--borda); background: var(--painel);
}
.erro { border-color: var(--perigo); color: var(--perigo); }
.ok { border-color: var(--bom); color: var(--bom); }

.entrada { max-width: 340px; margin: 12vh auto; }
.logo-entrada { display: block; width: 100%; max-width: 260px; height: auto;
                margin: 0 auto 1.2rem; }
.entrada .cartao { padding: 1.5rem; }
.entrada label { display: block; margin: .6rem 0 .2rem; color: var(--fraco); font-size: .85rem; }
.entrada input { width: 100%; }
.entrada button { width: 100%; margin-top: 1rem; }

code { background: #11141a; padding: .1rem .3rem; border-radius: 4px; font-size: .9em; }
.paginacao { display: flex; gap: .8rem; margin-top: .8rem; align-items: center; }

/* ---- Loja ----------------------------------------------------------------
   Uma linha por item, em CSS grid, com a MESMA lista de pistas de coluna no
   cabecalho e em cada linha (--grade-loja). E o que faz as colunas alinharem
   de cima a baixo: nenhuma pista depende do conteudo.

   Porque NAO se copiou a linha do painel antigo: la, `.input { min-width:
   240px }` anulava o `width: 7rem` que o proprio autor escrevera para o campo
   do item, e TODOS os seis campos saiam com 240px. Medido na marcacao antiga:
   linha de 103px e o "Remover" na segunda fila, so parando de embrulhar acima
   de ~2200px de viewport. O defeito que o dono chamou de lixo estava la
   primeiro; copia-lo a letra era repeti-lo.

   O rotulo de cada campo sai da linha e passa a cabecalho de coluna pegajoso —
   idioma que o painel antigo JA tinha em `.table thead th` (sticky, .72rem,
   MAIUSCULO) e que nunca usara nesta tela. Repetir 5 rotulos x 81 linhas
   custava 405 rotulos e uma altura de linha inteira.

   Tudo em px de proposito: `ch`/`rem` resolvem contra a fonte de CADA elemento
   (o cabecalho e 11px, a linha 13px, a raiz 15px) e as mesmas pistas dariam
   larguras diferentes no cabecalho e nas linhas.

   MEDIDO com os 81 itens reais: linha 95px -> 42px, documento 8521px -> 4591px,
   colunas a bater ao pixel a 1876 / 1600 / 1400 / 1280 / 1100 / 1024px.
   -------------------------------------------------------------------------- */

/* --- Busca no catalogo --------------------------------------------------- */
/* 8ch cortava 150000 — e este e o campo onde se digita um preco novo as cegas. */
.achados input[type=number] {
    width: 96px; padding: .3rem .4rem; text-align: right;
    font-variant-numeric: tabular-nums;
}
.achados th, .achados td { padding: .35rem .5rem; }
td.icone { width: 40px; padding: .2rem .3rem; }
td.icone img {
    display: block; width: 32px; height: 32px; image-rendering: pixelated;
    background: #11141a; border-radius: 4px;
}
/* Item sem PNG: um quadrado do tamanho do icone, para a coluna nao dancar. */
.sem-icone {
    display: inline-flex; align-items: center; justify-content: center;
    width: 32px; height: 32px; border-radius: 4px; flex: 0 0 auto;
    background: #11141a; border: 1px dashed var(--borda);
    color: var(--fraco); font-size: .8rem;
}
details.cartao { padding: .8rem 1rem; margin: .8rem 0; }
details.cartao summary { cursor: pointer; }
details.cartao summary .fraco { margin-left: .5rem; font-weight: 400; }

/* --- Atalhos para as seccoes ---------------------------------------------
   81 itens sao ~4600px de rolagem. As ancoras levam a qualquer aba sem rolar;
   e HTML puro, nao passa pelo loja.js. */
.atalhos { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin: .8rem 0; }
.atalhos a {
    display: inline-block; padding: 3px 10px; border-radius: 999px;
    border: 1px solid var(--borda); background: var(--painel);
    color: var(--fraco); font-size: 12px; text-decoration: none;
}
.atalhos a:hover { color: var(--texto); border-color: var(--destaque); }
.atalhos a b { color: var(--texto); font-weight: 600; }
.atalhos a i { font-style: normal; font-variant-numeric: tabular-nums; }

/* --- Um cartao por aba da loja ------------------------------------------- */
section.secao {
    padding: 0 16px 10px;   /* o topo vem do .secao-topo, que e pegajoso */
    margin-bottom: 12px;

    /* AS COLUNAS. Larguras dimensionadas pelo MAIOR valor real do dataset e
       nao pelo caso tipico — com `width: 9ch`, 46 dos 81 precos ficavam
       cortados, e o algarismo que se perde num campo alinhado a direita e o da
       ESQUERDA: lia-se 50000 onde estao gravados 750000, num campo que vale
       dinheiro ao vivo. O input preenche a pista (`width: 100%`), entao quem
       manda na largura e a coluna, nunca o conteudo. */
    --grade-loja:
        20px                 /* #      posicao na vitrine                    */
        32px                 /*        icone (clicavel: abre o seletor)      */
        66px                 /* id     cabe 6 digitos (max real 46038)       */
        minmax(140px, 360px) /* nome   trunca com reticencias, nunca embrulha*/
        150px                /* seccao <select>, largura FIXA                */
        74px                 /* preco  cabe 7 digitos (max real 750000)      */
        74px                 /* venda                                        */
        46px                 /* nivel  max="999"                             */
        minmax(120px, 1fr)   /* aviso  a folga da linha cai toda aqui        */
        54px                 /* setas                                        */
        74px;                /* remover                                      */
}
/* Loja sem abas: o <select> nao e emitido, entao a pista dele TEM de sair —
   senao tudo o que vem depois sobe uma coluna e o cabecalho deixa de bater. */
section.secao.sem-abas {
    --grade-loja:
        20px 32px 66px minmax(140px, 360px)
        74px 74px 46px minmax(120px, 1fr) 54px 74px;
}
section.secao[hidden] { display: none; }

/* Titulo + rotulos de coluna, colados ao topo enquanto se percorre a seccao.
   Sticky e limitado pelo pai: cada cartao prende o SEU cabecalho e larga-o
   quando a seccao acaba, entao ve-se sempre que aba se esta a editar.
   NAO por `overflow-x: auto` no cartao: overflow cria contexto de rolagem e o
   sticky deixa de se agarrar. */
.secao-topo {
    position: sticky; top: 0; z-index: 2;
    background: var(--painel);
    padding: 12px 0 0;
}
section.secao h3 { margin: 0 0 6px; font-size: 14px; letter-spacing: .3px; }
section.secao h3 .fraco { font-weight: 400; font-size: 12px; margin-left: 7px; }

.cabecalho-loja, .linha-loja {
    display: grid;
    grid-template-columns: var(--grade-loja);
    align-items: center;
    gap: 0 8px;
}
.cabecalho-loja {
    padding: 0 4px 5px;
    color: var(--fraco);
    font-size: 11px; font-weight: 600;
    text-transform: uppercase; letter-spacing: .6px;
    white-space: nowrap;
    box-shadow: 0 1px 0 var(--risco);
}
.cabecalho-loja .num { text-align: right; }

/* A linha. Sem rotulo empilhado, a altura passa a ser ditada pelo icone de
   32px: 42px, igual nas 81. `relative` para o seletor de item se ancorar. */
.linha-loja { padding: 5px 4px; border-radius: 4px; position: relative; }
.linha-loja[hidden] { display: none; }
/* A queixa era "nao se ve onde acaba um item". Faixa alternada + risco + o
   realce do rato: com ~1300px por linha, e isto que impede ler o Nivel de uma
   linha e o Preco de outra. */
.linha-loja:nth-child(odd) { background: rgba(255, 255, 255, .03); }
/* Risco entre linhas VISIVEIS. `inset box-shadow` e nao `border-top` para a
   altura nao variar 1px na primeira linha; e o combinador de irmaos
   `:not([hidden])` para que, depois de filtrar, a primeira linha que sobra nao
   fique com um risco solto por cima — sem uma linha de JS. */
.linha-loja:not([hidden]) ~ .linha-loja:not([hidden]) {
    box-shadow: inset 0 1px 0 var(--risco);
}
.linha-loja:hover, .linha-loja:focus-within { background: var(--painel-2); }

/* Tabular porque `renumerar()` reescreve este numero a cada seta/remocao e a
   coluna nao pode dancar. */
.linha-ordem {
    text-align: right; color: var(--fraco);
    font-variant-numeric: tabular-nums; font-size: 11px;
}
img.linha-icone, span.linha-icone {
    width: 32px; height: 32px; image-rendering: pixelated;
    background: #11141a; border-radius: 4px;
}
/* O icone e o nome abrem o seletor de item: e o gesto que o dono pediu
   ("clicar e escrever o nome"). O cursor tem de o anunciar. */
.js-trocar-item { cursor: pointer; }
.js-trocar-item:hover img.linha-icone,
.linha-loja.escolhendo img.linha-icone { outline: 1px solid var(--destaque); }

/* A unica coluna elastica. `min-width: 0` para poder encolher dentro da
   grelha; reticencias em vez de embrulhar, senao um nome longo faz a linha
   crescer para duas alturas e as 81 deixam de ser iguais. */
.linha-nome {
    min-width: 0; font-size: 13px;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.linha-nome .tipo { color: var(--fraco); font-size: 11.5px; margin-left: 6px; }

.linha-loja input[type=number], .linha-loja select {
    width: 100%; min-width: 0;
    padding: 5px 6px; font-size: 13px; line-height: 1.25;
    border-radius: 4px;
}
.linha-loja input[type=number] {
    text-align: right; font-variant-numeric: tabular-nums;
}
/* As setinhas do Chrome comem ~13px do lado direito, que e onde ficam os
   digitos num campo alinhado a direita, e deixam alterar um preco por engano
   ao rolar a pagina com o rato por cima. `type=number` fica, logo min/max
   continuam a valer. */
.linha-loja input[type=number], .achados input[type=number] {
    appearance: textfield; -moz-appearance: textfield;
}
.linha-loja input[type=number]::-webkit-outer-spin-button,
.linha-loja input[type=number]::-webkit-inner-spin-button,
.achados input[type=number]::-webkit-outer-spin-button,
.achados input[type=number]::-webkit-inner-spin-button {
    -webkit-appearance: none; margin: 0;
}
.linha-loja input:focus, .linha-loja select:focus { border-color: var(--destaque); }

/* Coluna propria, sempre presente mesmo vazia. Era um <span> opcional no meio
   da linha: quando aparecia roubava largura ao nome e arrastava tudo o que
   vinha depois para a esquerda — o olho perdia a coluna justamente nas linhas
   que pedem atencao. */
.linha-aviso {
    padding-left: 2px; color: var(--aviso); font-size: 11px; line-height: 1.2;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.linha-aviso.herda { color: var(--fraco); }

/* Acao secundaria e destrutiva era SEMPRE fantasma e minuscula no painel
   antigo (.btn-sm + .btn-ghost); `.discreto` e o equivalente exato. */
.linha-mover { display: flex; gap: 2px; }
.linha-loja .discreto {
    padding: 3px 6px; font-size: 11px; line-height: 1.3; font-weight: 400;
    border-radius: 4px;
}
.linha-mover .discreto { flex: 1 1 0; min-width: 0; font-size: 12px; padding: 2px 0; }
.linha-loja .js-remover-linha { width: 100%; }
.linha-loja .discreto:hover { filter: none; color: var(--texto); border-color: var(--destaque); }
.linha-loja .js-remover-linha:hover { color: var(--perigo); border-color: var(--perigo); }

/* `.badge-worn` do painel antigo: "desconhecido" e "fora da legenda" sao
   AMBAR. Vermelho para um id que so nao esta no Iteminfo e alarme a mais —
   o item continua a ser vendido. */
.etiqueta {
    display: inline-block; padding: 0 4px; border-radius: 3px;
    font-size: 10px; line-height: 1.5; font-weight: 600;
    background: var(--painel-2); border: 1px solid var(--borda); color: var(--fraco);
}
.etiqueta.atencao {
    color: var(--aviso); border-color: rgba(255, 176, 32, .5);
    background: rgba(255, 176, 32, .1);
}

p.vazia { color: var(--fraco); font-style: italic; padding: 10px 4px; margin: 0; font-size: 13px; }

dl.kv { display: grid; grid-template-columns: max-content 1fr; gap: .3rem .8rem;
        margin: .5rem 0; }
dl.kv dt { color: var(--fraco); font-size: .85rem; }
dl.kv dd { margin: 0; font-size: .9rem; }

/* --- Seletor de item ------------------------------------------------------
   Aberto ao clicar no icone/nome. `position: absolute` e obrigatorio, e nao
   estetica: um filho normal de `.linha-loja` seria uma CELULA DA GRELHA e
   empurraria todas as colunas seguintes. Absoluto sai do fluxo e a grelha nem
   o ve. */
.seletor {
    position: absolute; z-index: 6; top: calc(100% - 4px); left: 56px;
    width: 420px; max-width: calc(100vw - 80px);
    background: var(--painel); border: 1px solid var(--destaque);
    border-radius: 6px; padding: 8px; box-shadow: 0 8px 24px rgba(0, 0, 0, .5);
}
.seletor-busca { width: 100%; }
.seletor-lista {
    list-style: none; margin: 8px 0 0; padding: 0;
    max-height: 320px; overflow-y: auto;
}
.seletor-lista .opcao {
    display: flex; align-items: center; gap: 8px;
    padding: 4px 6px; border-radius: 4px; cursor: pointer;
}
.seletor-lista .opcao:hover, .seletor-lista .opcao.ativa { background: var(--painel-2); }
.seletor-lista .opcao img {
    width: 32px; height: 32px; image-rendering: pixelated;
    background: #11141a; border-radius: 4px; flex: 0 0 auto;
}
.seletor-lista .opcao-corpo { display: flex; flex-direction: column; min-width: 0; }
.seletor-lista .opcao-corpo strong {
    font-size: 13px; font-weight: 600;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.seletor-lista .opcao-corpo .fraco { font-size: 11px; }

/* ---------------------------------------------------------------- */
/* Atributos: o orcamento do slot do .cvf                            */
/* ---------------------------------------------------------------- */
/* Cada registo numa "pastilha" propria, e nao uma frase corrida: sao
   dois numeros que se leem em paralelo (Iteminfo e SetItem) e o que
   interessa e comparar as folgas de relance. Ambar e nao vermelho —
   estar a 97% do slot e informativo, nao e avaria; o vermelho fica
   para o `.erro` que envolve o bloco quando de facto NAO cabe. */
.folga {
  display: inline-block;
  margin-right: 1.2em;
  white-space: nowrap;
}

/* ---------------------------------------------------------------- */
/* O personagem vestido                                              */
/* ---------------------------------------------------------------- */
/* Boneco a esquerda e formulario a direita, lado a lado enquanto
   houver largura. `flex-wrap` e nao media query: a unica coisa que
   decide e se os dois cabem, e o painel e usado tanto num ecra largo
   como numa janela encostada. */
.com-boneco {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 16px;
}
.com-boneco > form {
  flex: 1 1 460px;
  min-width: 0;             /* senao a tabela de atributos nao encolhe */
}
.boneco {
  flex: 0 0 auto;
  max-width: 100%;
}
/* O canvas e desenhado a 360x440; `max-width` deixa-o encolher em
   janela estreita sem deformar. O fundo escuro e o do jogo — os
   sprites tem contorno claro e desapareceriam num fundo branco. */
.boneco canvas {
  display: block;
  max-width: 100%;
  height: auto;
  background: #1b1f24;
  border-radius: 6px;
}
.boneco h3 {
  margin-top: 0;
}

/* ---------------------------------------------------------------- */
/* Menu de balanceamento                                             */
/* ---------------------------------------------------------------- */
/* Cartoes que se reorganizam pela largura, sem media query: o painel
   e usado tanto em ecra largo como em janela encostada. */
.cartoes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 14px;
  align-items: start;
}
.cartoes h2 {
  margin-top: 0;
  font-size: 1.05rem;
}
.familias {
  list-style: none;
  padding: 0;
  margin: 0;
  columns: 2;
}
.familias li {
  break-inside: avoid;
  padding: 1px 0;
}
/* A tabela de comparacao tem uma coluna por atributo e transborda em
   janela estreita. O SCROLL fica no invólucro e nao no cartao: overflow
   no cartao criaria contexto de formatacao e mataria o cabecalho. */
.rolavel {
  overflow-x: auto;
}

/* ---------------------------------------------------------------- */
/* Ficha do item: barras de status                                   */
/* ---------------------------------------------------------------- */
.ficha-cabeca {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.ficha-cabeca h1 { margin: 0; }
.chip {
  border: 1px solid currentColor;
  border-radius: 999px;
  padding: 1px 9px;
  font-size: .78rem;
  opacity: .85;
}
/* Uma grelha de 5 pistas e nao floats: rotulo, barra elastica, cursor,
   numero e teto ficam alinhados em TODAS as linhas, que e o que faz a
   comparacao a vista funcionar. */
.stat {
  display: grid;
  grid-template-columns: 150px minmax(90px, 1fr) 130px 76px 62px;
  align-items: center;
  gap: 8px;
  padding: 3px 0;
}
.stat label { font-weight: 600; }
.stat-barra {
  position: relative;
  height: 12px;
  border-radius: 6px;
  background: rgba(127, 127, 127, .22);
  overflow: hidden;
}
.stat-fill {
  height: 100%;
  width: 0;                      /* o JS e que o enche */
  background: currentColor;
  opacity: .75;
  transition: width .08s linear;
}
/* Risco no valor que esta HOJE no cliente: mostra o tamanho do passo. */
.stat-marca {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 2px;
  background: rgba(255, 255, 255, .7);
}
.stat.mudado label { text-decoration: underline; }
.stat.acima .stat-fill { background: var(--erro, #e05252); opacity: 1; }
.stat-teto { text-align: right; }
.cartao-interno { margin: 12px 0; }

/* Os quatro arquetipos lado a lado, como na ficha da wiki. */
.arquetipos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 8px;
}
.arquetipos figure { margin: 0; text-align: center; }
.arquetipos canvas {
  display: block;
  width: 100%;
  height: auto;
  background: #1b1f24;
  border-radius: 6px;
}
.arquetipos figcaption {
  font-size: .75rem;
  text-transform: uppercase;
  letter-spacing: .04em;
  opacity: .7;
}

/* ---------------------------------------------------------------- */
/* Mapas das salas: arrastar a linha para mudar a ordem              */
/* ---------------------------------------------------------------- */
/* A pega tem de se ver, senao ninguem descobre que a linha se arrasta.
   O cursor `grab` e a unica affordance que o HTML5 drag and drop nao da
   sozinho. */
.w-arrasta {
  cursor: grab;
  color: var(--fraco);
  user-select: none;
  padding-right: 2px;
  font-size: 13px;
}
tr.js-linha[draggable="true"] .js-pega { cursor: grab; white-space: nowrap; }
/* As duas caixas do servidor (COOP e PVP) vivem na MESMA celula e nao podem
   partir para duas linhas: separadas, deixam de se ler como um par. */
.w-nowrap { white-space: nowrap; }
.w-nowrap label { margin-right: 6px; }
tr.w-arrastando { opacity: .45; }
/* Enquanto se arrasta, o texto das outras linhas nao pode ser selecionado —
   arrastar por cima de uma tabela seleciona conteudo e o gesto parece partido. */
tbody:has(tr.w-arrastando) { user-select: none; }

/* ---- Grade de itens (/balanceamento/grade) --------------------------------
   Uma grelha de divs (nao <table>) com scroll virtual: cada linha tem ALTURA
   FIXA (--grade-alt) e so as visiveis existem no DOM. As colunas sao os status
   do tooltip do jogo, como barras (as cores sao as `.w-cor-*` da ficha); o
   resto do item vive na ficha lateral. */
.grade-cartao { --grade-alt: 40px; --grade-stats: 6; --grade-extras: 0px; --grade-dps: 56px; }
.grade-cabeca { flex-wrap: wrap; gap: 8px 12px; }
.grade-familia { font: inherit; font-size: 12px; padding: .2rem .4rem; background: var(--w-poco); color: var(--w-texto); border: 1px solid var(--w-linha); }
.grade-dica { margin: 0 0 10px; font-size: 12px; color: var(--w-texto-2); }
.grade-dica b { color: var(--w-texto); }
.grade-filtros { display: flex; flex-direction: column; gap: 6px; margin-bottom: 10px; font-size: 12px; color: var(--w-texto-2); }
.grade-filtro { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; }
.grade-filtro__r { color: var(--w-fraco); font-size: 10px; text-transform: uppercase; letter-spacing: .06em; min-width: 6em; }
.grade-filtro--busca input[type=search] { width: 16em; }
.grade-filtro--busca label { margin-left: 8px; white-space: nowrap; }
.grade-filtros select, .grade-escala select { font: inherit; font-size: 12px; padding: .15rem .3rem; background: var(--w-poco); color: var(--w-texto); border: 1px solid var(--w-linha); }

.grade-vp { height: min(64vh, 900px); overflow: auto; border: 1px solid var(--w-linha); border-radius: 4px; background: var(--w-poco); position: relative; }
.grade-linha { display: grid; grid-template-columns: 28px 44px 36px minmax(180px, 1.4fr) 86px repeat(var(--grade-stats), minmax(96px, 1fr)) var(--grade-extras) var(--grade-dps); align-items: center; gap: 0 8px; height: var(--grade-alt); padding: 0 8px; box-sizing: border-box; border-bottom: 1px solid rgba(148, 163, 184, .06); font-size: 12px; }
.grade-linha--cabeca { position: sticky; top: 0; z-index: 3; height: 32px; background: var(--w-cartao-topo); border-bottom: 1px solid var(--w-linha); font-size: 10px; text-transform: uppercase; letter-spacing: .06em; color: var(--w-fraco); }
.grade-linha--cabeca .grade-c[data-ordem] { cursor: pointer; user-select: none; }
.grade-linha--cabeca .grade-c--stat { color: var(--cor-atributo, var(--w-texto-2)); }
.grade-linha--cabeca .grade-c--ordem { color: var(--w-ciano); }
.grade-linha--cabeca .grade-c--ordem::after { content: " \25BE"; }
.grade-linha--cabeca .grade-c--ordem.grade-c--asc::after { content: " \25B4"; }
.grade-linha:hover:not(.grade-linha--cabeca) { background: rgba(148, 163, 184, .05); }
.grade-linha--marcada { background: rgba(56, 224, 255, .06); }
.grade-linha--tocada { box-shadow: inset 3px 0 0 var(--w-ciano); }
.grade-linha--aberta { background: rgba(245, 195, 77, .08); outline: 1px solid rgba(245, 195, 77, .35); outline-offset: -1px; }
.grade-c { min-width: 0; white-space: nowrap; overflow: hidden; }
.grade-c--marca input { margin: 0; }
.grade-c--rank { color: var(--w-fraco); font-variant-numeric: tabular-nums; }
.grade-c--icone img { width: 28px; height: 28px; image-rendering: pixelated; display: block; cursor: pointer; }
.grade-c--nome { cursor: pointer; line-height: 1.15; }
.grade-c--nome b { display: block; overflow: hidden; text-overflow: ellipsis; color: var(--w-texto); font-weight: 600; }
.grade-c--nome:hover b { color: var(--w-ciano-claro); }
.grade-c--nome small { display: block; color: var(--w-fraco); font-size: 10px; overflow: hidden; text-overflow: ellipsis; }
.grade-c--nome small .ouro { color: var(--w-ouro); }
.grade-c--pontos, .grade-c--dps, .grade-c--num { text-align: right; font-variant-numeric: tabular-nums; }
.grade-c--pontos { font-weight: 800; color: var(--w-texto); }
.grade-c--dps { color: var(--w-texto-2); }
/* A celula de status: barra atras (arrasta-se), numero a direita (escreve-se
   no lugar, sem spinner). O desenho da wiki, com a edicao por cima. */
.grade-stat { display: grid; grid-template-columns: minmax(0, 1fr) 3.6em; align-items: center; gap: 6px; height: 28px; border-radius: 3px; }
/* Balas/Pentes: so o numero, sem barra — DEPOIS da base para ganhar a ela */
.grade-stat.grade-stat--so-numero { grid-template-columns: 1fr; gap: 0; }
.grade-stat.grade-stat--so-numero .grade-stat__num { color: var(--w-texto); }
.grade-stat__pista { height: 10px; border-radius: 3px; background: rgba(148, 163, 184, .1); overflow: hidden; cursor: ew-resize; position: relative; touch-action: none; }
.grade-stat__pista::after { content: ""; position: absolute; inset: -9px 0; }
.grade-stat__pista i { display: block; height: 100%; width: 0; background: linear-gradient(90deg, var(--cor-de, #2f9e59), var(--cor-ate, #5be584)); pointer-events: none; }
.grade-stat__pista:hover, .grade-stat__pista--arrasto { box-shadow: 0 0 0 1px var(--cor-atributo, var(--w-linha-viva)); }
.grade-stat__pista--arrasto i { filter: brightness(1.25); }
.grade-stat__num { width: 100%; box-sizing: border-box; font: inherit; font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums; text-align: right; padding: .15rem .3rem; background: transparent; border: 1px solid transparent; border-radius: 3px; color: var(--cor-atributo, var(--w-texto)); cursor: text; }
.grade-stat__num:hover { border-color: var(--w-linha); }
.grade-stat__num:focus { outline: 0; background: var(--w-poco); border-color: var(--w-ciano); color: var(--w-texto); }
.grade-stat--zero .grade-stat__num { color: var(--w-fraco); font-weight: 400; }
.grade-stat--topo .grade-stat__pista { box-shadow: 0 0 0 1px var(--cor-atributo, var(--w-linha-forte)); }
.grade-stat--pendente .grade-stat__num { color: var(--w-ouro); }
.grade-stat--mudada .grade-stat__num { color: var(--w-ciano-claro); border-color: rgba(56, 224, 255, .45); }
/* sem setinhas em nenhum campo numerico da grade nem da ficha */
.grade-cartao input[type=number]::-webkit-inner-spin-button, .grade-cartao input[type=number]::-webkit-outer-spin-button,
.grade-ficha input[type=number]::-webkit-inner-spin-button, .grade-ficha input[type=number]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
.grade-cartao input[type=number], .grade-ficha input[type=number] { -moz-appearance: textfield; appearance: textfield; }

.grade-rodape { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 16px; margin-top: 10px; font-size: 12px; color: var(--w-texto-2); }
.grade-escala { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.grade-escala__r { font-weight: 600; color: var(--w-texto); min-width: 7em; }
.grade-escala__valor { width: 5.5em; }
.grade-escala__menor { font-size: 11px; padding: .2rem .5rem; }
.grade-acoes { display: flex; gap: 8px; align-items: center; }

/* A ficha lateral: painel fixo a direita com os campos que nao sao barra. */
.grade-ficha { position: fixed; top: 0; right: 0; bottom: 0; width: min(420px, 95vw); z-index: 40; background: var(--w-cartao-topo); border-left: 1px solid var(--w-linha-forte); box-shadow: -12px 0 40px rgba(0, 0, 0, .55); display: flex; flex-direction: column; font-size: 12px; color: var(--w-texto-2); }
.grade-ficha[hidden] { display: none; }
.grade-ficha__topo { display: flex; align-items: center; gap: 10px; padding: 12px 14px; border-bottom: 1px solid var(--w-linha); }
.grade-ficha__topo img { image-rendering: pixelated; background: var(--w-poco); border: 1px solid var(--w-linha); }
.grade-ficha__titulo { flex: 1; min-width: 0; }
.grade-ficha__titulo b { display: block; color: var(--w-texto); font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.grade-ficha__fechar { width: 30px; height: 30px; border-radius: 50%; border: 0; background: rgba(148, 163, 184, .12); color: var(--w-texto-2); font-size: 18px; line-height: 30px; padding: 0; cursor: pointer; flex: 0 0 auto; }
.grade-ficha__fechar:hover { background: rgba(56, 224, 255, .2); color: var(--w-texto); }
.grade-ficha__corpo { flex: 1; overflow: auto; padding: 10px 14px; }
.grade-ficha__pe { display: flex; justify-content: space-between; align-items: center; gap: 8px; padding: 10px 14px; border-top: 1px solid var(--w-linha); }
.ficha-grupo { margin: 0 0 12px; }
.ficha-grupo h4 { margin: 0 0 4px; font-size: 10px; text-transform: uppercase; letter-spacing: .06em; color: var(--w-fraco); }
.ficha-campo { display: grid; grid-template-columns: 1fr 9em; align-items: center; gap: 8px; padding: 3px 0; border-bottom: 1px solid rgba(148, 163, 184, .06); }
.ficha-campo label { color: var(--w-texto-2); }
.ficha-campo label small { display: block; color: var(--w-fraco); font-size: 10px; }
.ficha-campo input, .ficha-campo select, .ficha-campo textarea { width: 100%; box-sizing: border-box; font: inherit; font-size: 12px; padding: .2rem .3rem; background: var(--w-poco); color: var(--w-texto); border: 1px solid var(--w-linha); }
.ficha-campo--texto { grid-template-columns: 1fr; }
.ficha-campo--texto textarea { min-height: 3.5em; resize: vertical; }
.ficha-campo--mudado input, .ficha-campo--mudado select, .ficha-campo--mudado textarea { border-color: var(--w-ciano); color: var(--w-ciano-claro); }
.ficha-campo--pendente input, .ficha-campo--pendente select, .ficha-campo--pendente textarea { border-color: rgba(245, 195, 77, .6); }
.ficha-campo .ficha-release { color: var(--w-fraco); font-size: 10px; }
.ficha-servidor label::after { content: " \25CF"; color: var(--w-ouro); font-size: 8px; vertical-align: super; }
.ficha-jogo { margin: 0 0 12px; padding: 8px 10px; background: #0b0d10; border: 1px solid #8c6f2a; color: #d8dbe0; }
.ficha-jogo__nome { color: #f2c04a; font-weight: 700; font-size: 13px; margin-bottom: 4px; }
.ficha-jogo__linha { display: grid; grid-template-columns: 7em 1fr 2.6em; gap: 6px; align-items: center; font-size: 11px; padding: 1px 0; }
.ficha-jogo__linha i { display: block; height: 6px; background: linear-gradient(90deg, #d9862b, #f5b043); }
.ficha-jogo__linha span:last-child { text-align: right; color: #f2c04a; font-weight: 600; }
.ficha-jogo__cab { color: #8b97b0; font-size: 11px; }
.ficha-jogo__cab b { color: #d8dbe0; font-weight: 500; margin-right: 8px; }
.ficha-jogo__cab .jogo-vermelho { color: #ff5d6c; }


