:root {
  --bg: #0a0d0f;
  --panel: #141a1de6;
  --panel-solid: #141a1d;
  --panel-2: #1b2327;
  --line: #2c373c;
  --line-soft: #222b2f;
  --text: #ccd6d8;
  --muted: #7a8a90;
  --accent: #3fbfa8;
  --accent-dim: #2a7d6e;
  --copper: #c8823c;
  --danger: #d0574f;
  --hp: #4fbf8b;
  --mana: #4f8fd0;
  --exp: #c8a13c;
  --stamina: #7e6bc4;
  --font-title: "Cinzel Decorative", "Cinzel", Georgia, serif;
  --font-heading: "Cinzel", Georgia, serif;
  /*
   * ---- A fonte dos NÚMEROS ----
   *
   * A Cinzel é uma capitular romana: ela foi desenhada para escrever NOME em
   * pedra, e os algarismos dela são largos, com serifa grossa e sem largura
   * fixa. "209.704.568" saía trôpego, com os pontos brigando com as serifas — e
   * a Cinzel Decorative, que estava no banco e no market, é pior ainda: ela tem
   * floreio no traço.
   *
   * Números querem o contrário disso: condensados, de largura igual (para a
   * coluna não dançar quando o valor muda) e sem enfeite. A Oswald entra só
   * para eles — o resto da interface continua na Cinzel, e a mistura de uma
   * display com uma condensada para dados é a receita de sempre.
   */
  --font-numero: "Oswald", "Cinzel", Georgia, serif;
}

* { box-sizing: border-box; }
/* display explícito nas regras abaixo venceria o atributo hidden sem isto */
[hidden] { display: none !important; }
html, body { height: 100%; }
/*
 * Nada de seleção de texto arrastando pela tela.
 *
 * Este é um jogo, e quase todo arrasto aqui é um gesto: mover janela, puxar
 * item para a lixeira, redimensionar. O navegador não sabe disso e pintava de
 * azul tudo que passasse debaixo do ponteiro — a barra de cima inteira virava
 * um bloco azul quando o arrasto começava com o botão direito.
 *
 * Onde ainda se lê e se copia, a seleção volta: os campos de texto (senão não
 * dá nem para corrigir o que se digitou) e o histórico do chat, que é a única
 * coisa aqui que alguém quer copiar.
 */
body {
  user-select: none;
  -webkit-user-select: none;
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 13px/1.45 "Segoe UI", system-ui, sans-serif;
  overflow: hidden;
}
button, input, select { font: inherit; color: inherit; }
canvas.sprite { image-rendering: pixelated; }
img.ui-icon { image-rendering: pixelated; width: 18px; height: 18px; flex: none; object-fit: contain; }
/*
 * A moeda da loja e' arte desenhada, e nao sprite do jogo.
 *
 * O `pixelated` do resto dos icones e' nearest-neighbour: reduzir 32px para 18
 * assim JOGA FORA quase metade das linhas do desenho, e o que sobra fica
 * quebrado e sujo. Arte com sombra e brilho quer o redimensionamento suave do
 * navegador, que e' o que esta regra devolve.
 */
img.ui-icon[src$="/coin-store.png"] { image-rendering: auto; }
h1, h2, h3, h4 { font-family: var(--font-heading); }

/* Barra de rolagem fina, na cor do tema. */
* { scrollbar-width: thin; scrollbar-color: var(--accent-dim) #0d1315; }
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: #0d1315; border-radius: 4px; }
::-webkit-scrollbar-thumb { background: var(--accent-dim); border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: var(--accent); }
::-webkit-scrollbar-corner { background: transparent; }

/* ---------- mapa em tela cheia ---------- */

#map {
  /* A posição e o tamanho saem do MapView: o campo de visão é fixo em 23x13. */
  /* Ponteiro normal, e não mira. O client do Tibia usa a seta do sistema no
     mapa; a mira dava a impressão de um jogo de tiro e escondia o tile que
     estava debaixo dela. */
  position: fixed; left: 0; top: 0; image-rendering: pixelated; z-index: 0; cursor: default;
}
/* Nomes, barras de vida e números de dano: resolução da tela, sem serrilhado. */
#map-overlay { position: fixed; inset: 0; z-index: 1; pointer-events: none; }

/*
 * ---- A caixa que diz ao mapa onde ele cabe ----
 *
 * Invisível e sem toque: ela não é vista nem clicada, só medida (ver
 * `areaDoMapa`, em map.mjs).
 *
 * Os dois zeros são o computador: a caixa é a janela inteira, e o mapa se
 * desenha exatamente como sempre se desenhou. Quem mexe neles é o bloco de
 * celular, para abrir espaço para os controles embaixo sem tapar o jogo.
 */
:root { --mapa-topo: 0px; --mapa-baixo: 0px; }
#area-do-mapa {
  position: fixed;
  left: 0; right: 0;
  top: var(--mapa-topo); bottom: var(--mapa-baixo);
  z-index: -1; pointer-events: none;
}

/* A tarja do rodapé do telefone em pé. No computador não existe. */
#deck-do-celular { display: none; }
body { background: #06080a; }
/*
 * ---- No celular, o navegador nao pode achar que e' uma pagina ----
 *
 * Tres gestos do Android atrapalham um jogo e nao servem para nada aqui:
 *
 *   - o toque duplo que da' zoom: num jogo em que se bate clicando, o segundo
 *     clique rapido vira zoom em vez de segundo golpe;
 *   - o puxao para baixo que recarrega a pagina: no meio de uma caçada isso e'
 *     perder a sessao por um gesto de rolagem que nao rolou nada;
 *   - o "efeito elastico" nas bordas, que balança a tela inteira.
 *
 * `manipulation` mantem o zoom por PINÇA, que e' o unico dos tres que ajuda
 * alguem — e e' a razao de nao usar `user-scalable=no` no viewport.
 */
html, body {
  touch-action: manipulation;
  overscroll-behavior: none;
  -webkit-tap-highlight-color: transparent;
}

#stage-empty {
  position: fixed; bottom: calc(var(--barra-altura, 69px) + 27px); left: 50%; transform: translateX(-50%);
  text-align: center; color: var(--muted); z-index: 5;
  background: #0b1113d9; border: 1px solid var(--line); border-radius: 10px; padding: 14px 26px;
}
#stage-empty h3 { font-family: var(--font-title); font-weight: 700; color: var(--text); margin: 0 0 4px; font-size: 16px; }
#stage-empty p { margin: 0; font-size: 12px; }
#stage-empty button {
  margin-top: 10px; padding: 7px 18px; cursor: pointer; border-radius: 6px;
  background: var(--accent-dim); border: 1px solid var(--accent); color: #eafffb;
}

#notice {
  position: fixed; top: 72px; left: 50%; transform: translateX(-50%); z-index: 40;
  background: #0d1214f2; border: 1px solid var(--line); border-radius: 6px;
  padding: 8px 16px; font-size: 12px; opacity: 0; transition: opacity .3s; pointer-events: none;
}
#notice.show { opacity: 1; }

/* ---------- portão: conta e personagens ---------- */

/*
 * Porta de entrada: login, contas e criação de personagem.
 *
 * O fundo é a arte do jogo com um véu por cima — sem o véu o texto dos cards
 * some na faixa âmbar e na violeta da arte das vocações. A moldura do card é a
 * mesma pedra ornamentada do resto do jogo, em 9 fatias.
 */
#gate {
  position: fixed; inset: 0; display: grid; place-items: center; z-index: 60;
  overflow-y: auto; padding: 24px;
  background:
    linear-gradient(180deg, rgba(8, 14, 14, .6), rgba(8, 14, 14, .88)),
    url('/client/assets/ui/gate-bg.webp') center / cover no-repeat;
  background-attachment: fixed;
  background-color: #080e0e;
}
/*
 * A volta para a porta da rua.
 *
 * Canto de cima a esquerda, discreta: ela nao disputa com o formulario, e esta
 * onde a mao procura quando quer sair de uma tela.
 */
#gate-voltar {
  position: absolute; top: 18px; left: 20px; z-index: 2;
  padding: 8px 14px; border-radius: 6px;
  font-family: var(--font-heading); font-size: 11px; letter-spacing: .08em;
  text-transform: uppercase; text-decoration: none;
  color: var(--muted); background: #0b111399; border: 1px solid var(--line);
}
#gate-voltar:hover { color: var(--accent); border-color: var(--accent-dim); }

/* Na criação o fundo vira a arte das cinco zonas, uma por vocação. */
#gate.creating {
  background:
    linear-gradient(180deg, rgba(8, 14, 14, .6), rgba(8, 14, 14, .88)),
    url('/client/assets/ui/gate-vocations.webp') center / cover no-repeat;
  background-attachment: fixed;
  background-color: #080e0e;
}

/*
 * Moldura de painel em 9 fatias — uma classe só, usada por todo modal que a
 * quiser, em vez de repetir o `border-image` em cada um.
 *
 * A arte veio 1254x1254 com 21px de margem preta em volta — aparada, ficou
 * 1212x1212 e o ornamento do canto vai até ~104px: daí a fatia 110. (O 96 das
 * specs foi medido numa versão de 1024, sem contar a margem.) Fica
 * de fora o `border-image-width`, que sem valor acompanha a `border-width` —
 * assim a variante larga muda uma linha só. `stretch`, nunca `repeat`: a borda
 * é uma régua lisa e emendar cópias dela deixa costura à vista.
 */
.ui-frame {
  border-style: solid;
  border-width: 48px;
  border-image-source: url('/client/assets/ui/panel-frame.webp');
  border-image-slice: 110 fill;
  border-image-repeat: stretch;
  border-radius: 0;
  background: none;
  box-shadow: none;
  padding: 0;
  image-rendering: auto; /* arte em alta, não pixel art */
}
.ui-frame--wide { border-width: 64px; }
/*
 * A mesma moldura, na medida de um CARD.
 *
 * 48px de borda em volta de um card de 120px de altura não sobra miolo nenhum:
 * a arte come o conteúdo. 20px mantém os cantos ornamentados reconhecíveis e
 * deixa o card ser um card. É a moldura que o dono pediu nas boss tasks e nas
 * entregas — as duas telas em que se olha para uma coisa de cada vez.
 */
.ui-frame--card { border-width: 20px; }
/*
 * ---- A moldura miuda: a do MODAL, num quadro pequeno ----
 *
 * A previa de magia cabe numa coluna de 232px, e a `panel-frame.webp` da
 * `.ui-frame` e' um ornamento grande demais para esse tamanho: esticado para
 * 16px de espessura ele vira um borrao escuro sem desenho.
 *
 * A moldura de painel (`padrao.png`), que e' a mesma do `.modal-box` e a mesma
 * que o jogador ve em toda janela do jogo, tem a régua fina e sobrevive ao
 * encolhimento. As proporcoes das fatias sao as do modal; so' a espessura muda.
 */
/*
 * ---- A bordinha preta era a PROPRIA arte ----
 *
 * A moldura desenhava uma faixa escura por dentro do ornamento, e nenhum ajuste
 * de tamanho a tirava, porque ela nao vinha do CSS: vinha do arquivo.
 *
 * A `padrao.png` tem 1362x1155 e e' a moldura de JANELA — a arte inclui o
 * interior do painel, e as fatias que estavam escritas aqui (150/110/130/110)
 * pegavam alem do ornamento: a regua da lateral acaba no pixel 81, e a fatia ia
 * ate 110. Aqueles 29 pixels de miolo escuro entravam na borda e eram esticados
 * junto com ela. Numa janela isso nao aparece — o fundo por dentro tambem e'
 * escuro e a faixa se funde com ele. Aqui, com o desenho colorido da magia
 * encostando nela, virava um contorno preto.
 *
 * Por fora acontecia o contrario e dava no mesmo: a arte tem ~47px de margem
 * TRANSPARENTE em volta, tambem dentro da fatia, e sobre o fundo escuro do
 * modal ela le como mais uma faixa preta.
 *
 * `padrao-aparada.png` e' a mesma moldura sem as duas sobras: gerada a partir da
 * `padrao.png`, aparada na margem transparente e cortada exatamente onde o
 * ornamento termina, montada como um atlas de 9 fatias de
 * 54x128 (as fatias sao as bordas em tamanho real; o miolo virou 2px, que o
 * `fill` estica). Nao sobra preto de lado nenhum porque nao ha mais preto na
 * arte para sobrar — as quatro bordas do atlas sao opacas de ponta a ponta.
 *
 * O corte e' medido no MEIO de cada lado, onde a regua e' reta, e nao pela caixa
 * do que nao e' transparente: os cantos florescem alguns pixels para fora da
 * regua, e ir ate' eles deixaria de volta um vao transparente no meio dos lados
 * — a mesma bordinha escura por outro caminho. O que se perde e' a pontinha do
 * floreio do canto, uns tres pixels no tamanho em que isto e' desenhado.
 *
 * As espessuras seguem as fatias: 100 em cima (a barra de titulo da moldura) e
 * ~26 nos outros tres lados. Cada lado escala por conta propria — por isso o
 * topo pode ser mais grosso sem esticar a regua das laterais.
 */
.ui-frame--miudo {
  border-style: solid;
  border-width: 22px 14px 14px 14px;
  border-image-source: url(/client/assets/ui/padrao-aparada.png);
  border-image-slice: 100 27 26 25 fill;
  border-image-repeat: stretch;
  border-radius: 0;
  background: none;
  padding: 0;
}

@media (max-width: 600px) {
  .ui-frame, .ui-frame--wide { border-width: 28px; }
}

.gate-box { width: 380px; max-width: 100%; text-align: center; }
/*
 * A tela de personagens é mais larga que a de login: ali cabem dois campos e um
 * botão, aqui cabem cinco vidas com retrato, estado e barras. Manter as duas na
 * mesma medida obrigava uma das duas a ficar errada — e era esta.
 */
.gate-box.escolhendo { width: 620px; }
/* Quem tem a moldura não leva padding: o respiro é do miolo. */
.gate-inner { padding: 20px 24px; }
/* A criação precisa de largura: as cinco vocações ficam numa fileira só. */
.gate-box.creating { width: 1180px; }

.logo {
  width: 100%; max-width: 280px; height: auto; display: block; margin: 0 auto 18px;
  user-select: none; -webkit-user-drag: none;
}
.gate-box.creating .logo { max-width: 340px; }
@media (max-width: 600px) { .logo { max-width: 200px; } }

.gate-box h2 { font-size: 13px; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); margin: 0 0 14px; }
/*
 * O rodapé da escolha: "criar" e "sair" na mesma linha.
 *
 * Empilhados, os dois botões davam o mesmo peso a duas coisas de importância
 * muito diferente e ainda esticavam a caixa. Lado a lado, o de criar fica com o
 * dobro da largura — ele é o que se clica.
 */
.gate-box.escolhendo #character-slots { margin: 0 0 12px; }
/*
 * ---- Os três botões da escolha, ALINHADOS ----
 *
 * `inline-flex` (era `inline-block`) por causa do ícone: ele e o texto viram
 * dois itens centrados um ao lado do outro, com o `gap` no lugar de um espaço
 * em branco que o navegador colapsaria.
 *
 * `margin-top: 0` é o conserto do desalinhamento. `.gate-box button.primary`
 * nasce com 4px e `.gate-box button.ghost` com 8px — margens pensadas para
 * botões EMPILHADOS num formulário. Lado a lado numa linha flex, os 4px a menos
 * do "Criar personagem" subiam só ele: as bases batiam (o `stretch` iguala a
 * caixa com a margem) e os topos ficavam a 4px de distância. Quem espaça esta
 * linha é o `gap` do flex, e não a margem de cada um.
 */
.gate-box.escolhendo #new-character,
.gate-box.escolhendo #do-logout,
.gate-box.escolhendo #do-delete-character {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  width: auto; margin-top: 0;
}
/*
 * O ícone não encolhe nem estica: `flex: none` o mantém em 14px mesmo quando o
 * botão fica apertado, e é o texto que quebra — nunca o desenho, que ilegível
 * não serve para nada.
 */
.escolha-acoes .ico, .senha-google-aviso .ico {
  width: 14px; height: 14px; flex: none;
  fill: none; stroke: currentColor; stroke-width: 1.4;
  stroke-linecap: round; stroke-linejoin: round;
}
/* O escudo da verificação é cheio: em 14px, um contorno vira um borrão. */
.senha-google-aviso .ico { width: 12px; height: 12px; fill: currentColor; stroke: none; }
.senha-google-aviso button { display: inline-flex; align-items: center; gap: 5px; }
/* `wrap` porque agora sao TRES botoes: num celular estreito o terceiro desce
   em vez de espremer os outros dois a ponto de o texto quebrar letra a letra. */
.escolha-acoes { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; align-items: stretch; }
.escolha-acoes #new-character { flex: 2; }
/*
 * ---- "Sair da conta" NÃO estica ----
 *
 * Ele era `flex: 1`, e isso só ficava bom enquanto "Criar personagem" estivesse
 * do lado para disputar a linha. Na conta CHEIA o botão de criar some — e o de
 * sair herdava a linha inteira: 347px de "Sair da conta" ao lado de um "Excluir
 * personagem" de 119px. O botão mais largo da tela passava a ser o que ninguém
 * veio clicar.
 *
 * `0 1 auto` o deixa do tamanho do próprio texto, como o de excluir. Com o de
 * criar presente, o espaço que sobra vai todo para ele, que é o certo: quem
 * cresce é a ação principal. Sem ele, os dois ficam compactos e centrados.
 */
.escolha-acoes #do-logout { flex: 0 1 auto; }
/*
 * ---- O botão de excluir personagem ----
 *
 * Ele não ganha `flex` nenhum: os dois de cima dividem a linha, e este fica do
 * tamanho do próprio texto, encostado no de sair. É a hierarquia da tela dita
 * em largura — criar é o que se clica, sair é o que se usa, e excluir é o que
 * se procura quando se quer mesmo.
 *
 * A borda é vermelha e o fundo não: um botão vermelho CHEIO, ao lado de um
 * fantasma, puxa o clique para si — e este é o único da tela que não tem volta.
 */
/*
 * Só a VISIBILIDADE. O `display: inline-block; width: auto` que estava aqui
 * vinha DEPOIS do bloco lá em cima e desfazia o `inline-flex` dele — o botão
 * voltava a ser uma caixa comum, e o `gap` entre o ícone e o texto sumia junto.
 * Quem diz como os três botões se dispõem é aquele bloco, e num lugar só.
 */
.gate-box.escolhendo #do-delete-character { width: auto; }
.escolha-acoes #do-delete-character {
  flex: none; width: auto; padding: 8px 11px; font-size: 11px;
  border-color: #7a3a35; color: var(--danger);
}
.escolha-acoes #do-delete-character:hover { border-color: var(--danger); color: #ffb3ab; }

/*
 * ---- As duas telas de excluir ----
 *
 * Um véu por cima do portão inteiro, e não um trecho que aparece dentro do
 * card: quem chegou aqui precisa terminar ou cancelar, e uma caixa no meio da
 * lista deixaria os cards dos outros personagens clicáveis atrás dela — um
 * clique fora de hora e a pessoa entra num personagem no meio de apagar outro.
 */
#excluir-overlay {
  position: fixed; inset: 0; z-index: 120; display: grid; place-items: center;
  background: #04060799; padding: 16px;
}
#excluir-overlay[hidden] { display: none; }
.excluir-caixa {
  width: min(380px, 100%); padding: 20px; text-align: left;
  background: var(--panel); border-radius: 10px;
}
.excluir-caixa h3 { margin: 0 0 6px; font-family: var(--font-heading); color: var(--danger); }
.excluir-caixa label {
  display: grid; gap: 4px; margin-top: 14px; font-size: 11px; color: var(--muted);
  text-transform: uppercase; letter-spacing: .06em;
}
.excluir-caixa input {
  width: 100%; padding: 9px 11px; background: rgba(6, 10, 11, .85);
  border: 1px solid var(--line); border-radius: 6px; color: var(--text);
}
.excluir-caixa input:focus { outline: none; border-color: var(--danger); }
/*
 * ---- Onde o botão da Google é desenhado ----
 *
 * A caixa de confirmação tem duas chaves alternativas: o campo de senha, ou
 * este espaço. O GIS desenha aqui dentro um iframe de largura própria, e por
 * isso a regra não pinta nada — ela só o centraliza e lhe dá o mesmo respiro
 * que o `label` da senha tem acima do campo dela (14px), para as duas versões
 * da caixa terem o mesmo ritmo.
 */
#excluir-google-slot {
  display: flex; justify-content: center; min-height: 44px; margin-top: 16px;
}

/*
 * ---- O atalho para a OUTRA chave, na conta hibrida ----
 *
 * A caixa pergunta uma chave so' — a que a pessoa usou para entrar —, e este
 * link leva a' outra. Discreto de proposito: ele nao e' uma acao da tela, e' a
 * saida para quem caiu na pergunta errada. Um segundo botao do tamanho do
 * "Apagar personagem" competiria com ele pela atencao, e o que apaga tem de ser
 * o unico que chama.
 */
.excluir-troca {
  display: block; width: 100%; margin-top: 14px; padding: 4px; cursor: pointer;
  background: none; border: none; font-size: 11px; color: var(--muted);
  text-decoration: underline; text-underline-offset: 3px;
}
.excluir-troca:hover { color: var(--text); }
.excluir-troca[hidden] { display: none; }

.excluir-acoes { display: flex; gap: 8px; margin-top: 16px; }
.excluir-acoes button {
  flex: 1; padding: 9px; cursor: pointer; border-radius: 6px;
  background: transparent; border: 1px solid var(--line); color: var(--muted);
}
.excluir-acoes button.perigo { border-color: #7a3a35; color: var(--danger); }
.excluir-acoes button.perigo:hover { border-color: var(--danger); color: #ffb3ab; }
.excluir-acoes button.ghost:hover { border-color: var(--accent-dim); color: var(--text); }
#excluir-erro { display: block; margin-top: 12px; color: var(--danger); min-height: 16px; font-size: 12px; }

/*
 * ---- Criar senha na conta da Google ----
 *
 * A caixa é a da exclusão (mesmo véu, mesma moldura), mas não é perigo nenhum:
 * o título e o foco saem da cor de perigo para a de destaque do jogo.
 */
#senha-overlay {
  position: fixed; inset: 0; z-index: 120; display: grid; place-items: center;
  background: #04060799; padding: 16px;
}
#senha-overlay[hidden] { display: none; }
#senha-overlay .excluir-caixa h3 { color: var(--accent); }
#senha-overlay .excluir-caixa input:focus { border-color: var(--accent); }
#senha-overlay .excluir-caixa input[readonly] { color: var(--muted); }
#senha-overlay .excluir-acoes button.primary { border-color: var(--accent); color: var(--accent); }
#senha-google-slot { display: flex; justify-content: center; min-height: 44px; margin-top: 16px; }
#senha-erro { display: block; margin-top: 12px; color: var(--danger); min-height: 16px; font-size: 12px; }
.senha-google-aviso {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 6px 10px;
  margin: 0 auto 10px; max-width: 476px; font-size: 11px; color: var(--muted); text-align: center;
}
.senha-google-aviso[hidden] { display: none; }
.senha-google-aviso button {
  padding: 3px 10px; font-size: 11px; cursor: pointer; border-radius: 5px;
  background: transparent; border: 1px solid var(--accent); color: var(--accent);
}
.senha-google-aviso button:hover { background: rgba(63, 191, 168, 0.12); }

/*
 * ---- As três caixas da SEGURANÇA DA CONTA ----
 *
 * Esqueci minha senha, o código da entrada e o ligar/desligar da verificação em
 * duas etapas. As três reaproveitam a moldura da exclusão (mesmo véu, mesma
 * caixa) e, como a de criar senha, trocam a cor de perigo pela de destaque: só
 * o "desligar a verificação" continua vermelho, porque é o único que ENFRAQUECE
 * a conta.
 */
#esqueci-overlay, #tfa-overlay, #seg-overlay {
  position: fixed; inset: 0; z-index: 120; display: grid; place-items: center;
  background: #04060799; padding: 16px;
}
#esqueci-overlay[hidden], #tfa-overlay[hidden], #seg-overlay[hidden] { display: none; }
#esqueci-overlay .excluir-caixa h3,
#tfa-overlay .excluir-caixa h3,
#seg-overlay .excluir-caixa h3 { color: var(--accent); }
#esqueci-overlay .excluir-caixa input:focus,
#tfa-overlay .excluir-caixa input:focus,
#seg-overlay .excluir-caixa input:focus { border-color: var(--accent); }
#esqueci-overlay .excluir-acoes button.primary,
#tfa-overlay .excluir-acoes button.primary,
#seg-overlay .excluir-acoes button.primary { border-color: var(--accent); color: var(--accent); }
/* O único perigo destas caixas: desligar a proteção. Ele volta ao vermelho. */
#seg-passo-desligar h3 { color: var(--danger) !important; }
#esqueci-erro, #tfa-erro, #seg-erro {
  display: block; margin-top: 12px; color: var(--danger); min-height: 16px; font-size: 12px;
}
#seg-erro.bom, #esqueci-erro.bom, #tfa-erro.bom { color: var(--accent); }

/*
 * O campo do código.
 *
 * Grande, espaçado e centralizado: são seis dígitos lidos de um celular ou
 * copiados de um papel, um de cada vez. Num campo de formulário comum a pessoa
 * perde o lugar no meio e recomeça.
 */
.campo-codigo {
  text-align: center; letter-spacing: .3em; font-size: 17px;
  font-variant-numeric: tabular-nums;
}

/* O mesmo discreto do `.excluir-troca`: saída, e não ação da tela. */
.link-discreto {
  display: block; width: 100%; margin-top: 12px; padding: 4px; cursor: pointer;
  background: none; border: none; font-size: 11px; color: var(--muted);
  text-decoration: underline; text-underline-offset: 3px;
}
.link-discreto:hover { color: var(--text); }
.link-discreto[hidden] { display: none; }
.tfa-reserva { text-align: center; }

/* ---- escolher o caminho: aplicativo ou e-mail ---- */
.seg-modos { display: grid; gap: 8px; margin-top: 14px; }
.seg-modo {
  display: flex; gap: 10px; align-items: flex-start; padding: 10px 12px; cursor: pointer;
  border: 1px solid var(--line); border-radius: 8px;
  /* O `label` herdaria o maiúsculo dos rótulos da caixa; aqui há frase inteira. */
  text-transform: none; letter-spacing: 0; margin-top: 0;
}
/* `display: flex` vence o `[hidden]` do navegador: sem esta linha, esconder a
   opção de e-mail (servidor sem SMTP) não a esconderia. */
.seg-modo[hidden] { display: none; }
.seg-modo:hover { border-color: var(--accent-dim); }
/* A opção escolhida se destaca sozinha — sem isso as duas parecem iguais e a
   pessoa não vê qual está marcada sem procurar a bolinha. */
.seg-modo:has(input:checked) { border-color: var(--accent); background: rgba(63, 191, 168, .06); }
.seg-modo input { width: auto; margin-top: 3px; accent-color: var(--accent); }
.seg-modo span { display: grid; gap: 3px; }
.seg-modo b { color: var(--text); font-size: 12px; }
.seg-modo small { color: var(--muted); font-size: 11px; line-height: 1.45; }

/* ---- o QR e o segredo escrito ---- */
.seg-qr { display: flex; justify-content: center; margin: 12px 0 8px; }
/* Fundo branco e uma borda de silêncio em volta: leitor de QR precisa do
   contraste, e num painel escuro o quadrado preto some. */
.seg-qr canvas, .seg-qr svg { background: #fff; padding: 10px; border-radius: 6px; }
/*
 * O segredo escrito quebra ENTRE os grupos de quatro, e nunca dentro de um.
 *
 * Com `break-all` ele partia no meio ("…HGDE XX / LY 3YDE") e quem estivesse
 * copiando à mão perdia a conta das letras — que é exatamente a pessoa que usa
 * este campo, porque não conseguiu ler o QR.
 */
.seg-segredo {
  margin: 0; text-align: center; font-family: ui-monospace, Consolas, monospace;
  font-size: 12px; letter-spacing: .08em; color: var(--muted);
  word-break: normal; overflow-wrap: normal;
}

/* ---- os códigos de reserva ---- */
.seg-reservas {
  display: grid; grid-template-columns: 1fr 1fr; gap: 6px 12px;
  margin: 12px 0 0; padding: 12px; list-style: none; counter-reset: reserva;
  background: rgba(6, 10, 11, .85); border: 1px solid var(--line); border-radius: 8px;
}
.seg-reservas li {
  font-family: ui-monospace, Consolas, monospace; font-size: 12.5px;
  color: var(--text); letter-spacing: .04em;
}
@media (max-width: 420px) { .seg-reservas { grid-template-columns: 1fr; } }

.gate-tabs { display: flex; gap: 6px; margin-bottom: 16px; }
.gate-tabs button {
  flex: 1; padding: 8px; cursor: pointer; border-radius: 6px; font-family: var(--font-heading);
  background: var(--panel-2); border: 1px solid var(--line);
}
.gate-tabs button[aria-selected="true"] { border-color: var(--accent); color: var(--accent); }

.gate-box form { display: grid; gap: 10px; text-align: left; }
.gate-box label { display: grid; gap: 4px; font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: .06em; }
.gate-box input {
  width: 100%; padding: 9px 11px; background: rgba(6, 10, 11, .85);
  border: 1px solid var(--line); border-radius: 6px; color: var(--text);
}
.gate-box input:focus { outline: none; border-color: var(--accent-dim); }
.gate-box button.primary {
  width: 100%; padding: 10px; margin-top: 4px; cursor: pointer; font-weight: 600; letter-spacing: .04em;
  background: linear-gradient(180deg, var(--accent-dim), #1f5f54);
  border: 1px solid var(--accent-dim); border-radius: 6px; color: #eafffb;
}
.gate-box button.primary:hover { filter: brightness(1.15); }
.gate-box button.ghost {
  width: 100%; padding: 8px; margin-top: 8px; cursor: pointer;
  background: transparent; border: 1px solid var(--line); border-radius: 6px; color: var(--muted);
}
.gate-box small { display: block; margin-top: 12px; color: var(--danger); min-height: 16px; font-size: 12px; }
.gate-note { color: var(--muted); font-size: 11px; margin: 8px 0 0; }
.gate-or { display: flex; align-items: center; gap: 10px; margin: 16px 0 12px; color: var(--muted); font-size: 11px; }
.gate-or::before, .gate-or::after { content: ""; flex: 1; height: 1px; background: var(--line); }
#google-slot { display: flex; justify-content: center; min-height: 4px; }

/* ---------- criação de personagem ---------- */

.create-top { display: flex; gap: 16px; align-items: flex-end; flex-wrap: wrap; }
.create-top label { flex: 1; min-width: 220px; }
.create-actions { display: flex; gap: 10px; margin-top: 6px; }
.create-actions button { margin-top: 0; }

/*
 * Os dois sexos com o boneco dentro.
 *
 * Cada botão passou a ter figura e legenda, então ele deixou de ser uma pílula
 * de texto e virou um card pequeno — a mesma linguagem dos cinco de vocação ao
 * lado, para os dois grupos não parecerem coisas de famílias diferentes.
 */
.sex-picker { display: flex; gap: 8px; }
/*
 * O botão SEM caixa: só o símbolo e a palavra.
 *
 * Ele tinha fundo, borda e cantos arredondados — a mesma linguagem dos cards de
 * vocação —, e ali isso era demais: os cards têm conteúdo para emoldurar, este
 * tem um ícone de 40px. A moldura ficava maior que o assunto, e o símbolo, que
 * já vem com a própria placa desenhada, parecia uma figura dentro de um quadro
 * dentro de outro.
 *
 * O que a caixa fazia — dizer qual dos dois está escolhido — continua sendo
 * feito, pela opacidade do ícone e pela cor da palavra.
 */
.sex-picker button {
  display: grid; justify-items: center; gap: 3px;
  background: none; border: none; padding: 2px 6px;
  transition: none;
}
.sex-picker button span { font-size: 10px; letter-spacing: .06em; text-transform: uppercase; }
/*
 * O símbolo tem placa de pedra própria na arte, então ele não leva moldura nem
 * fundo daqui — só o arredondamento, para a quina da arte não brigar com a do
 * botão. `image-rendering: auto` porque é arte em alta, e não pixel art como o
 * resto do jogo.
 */
.sexo-icone {
  /*
   * Redondo, e não quadrado.
   *
   * A placa de pedra está PINTADA na arte, com a mesma cor do símbolo — tentei
   * recortá-la por brilho e por saturação, e nenhuma das duas separa: a moldura
   * da placa pegou o mesmo vermelho do desenho. Recorte automático sairia com
   * borda serrilhada.
   *
   * O círculo resolve o que incomodava — a quina — sem depender de recorte: a
   * placa vira um medalhão atrás do símbolo, que é uma coisa que existe de
   * propósito em vez de um retângulo sobrando. Para tirá-la de vez, a arte
   * precisa nascer com fundo transparente.
   */
  width: 40px; height: 40px; display: block; border-radius: 50%;
  image-rendering: auto;
  filter: drop-shadow(0 2px 4px #000b);
  opacity: .45; transition: opacity .16s ease, filter .16s ease;
}
/* Só o escolhido fica cheio — os dois acesos ao mesmo tempo não escolheriam. */
.sex-picker button[aria-selected="true"] .sexo-icone {
  opacity: 1; filter: drop-shadow(0 2px 4px #000b) brightness(1.06);
}
/* A palavra do escolhido acende; a do outro fica no cinza de sempre. */
.sex-picker button[aria-selected="true"] span { color: var(--accent); }

/*
 * O aviso do campo de nome.
 *
 * Cinza quando é só a regra ("De 3 a 20 letras"), vermelho quando é uma recusa
 * — e o mesmo elemento nos dois casos, para o texto não empurrar o formulário
 * para baixo ao aparecer. Uma linha que surge e some faz a tela pular embaixo
 * do dedo de quem está digitando.
 */
/*
 * ---- O rótulo e o aviso na mesma linha ----
 *
 * "Nome" na esquerda, o recado na direita, o campo logo abaixo. É uma linha só
 * acima do campo em vez de duas, e por isso o "Nome" volta a ficar colado no
 * que ele nomeia — e a caixa, colada nos cards de vocação.
 *
 * `align-items: baseline` porque os dois têm tamanhos diferentes: alinhados
 * pelo topo, o aviso miúdo flutuava acima da linha do rótulo.
 */
.campo-topo { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }

/*
 * O lugar do aviso é reservado mesmo vazio — ele nasce sem texto e só aparece
 * na primeira tecla. Sem a altura mínima, ele surgir empurraria o campo e os
 * cards para baixo, embaixo do dedo de quem está digitando.
 */
.campo-aviso {
  min-height: 13px; text-align: right;
  font-size: 10px; letter-spacing: .02em; text-transform: none;
  color: var(--muted); transition: color .15s ease;
}
.campo-aviso.ruim { color: #ef8a7a; }
/* Nome que serve: verde discreto, o mesmo do resto do jogo. */
.campo-aviso.ok { color: #6ddb96; }
/* Campo recusado ganha a borda do aviso, para o olho ligar as duas coisas. */
.gate-box input[aria-invalid="true"] { border-color: #ef8a7a88; }
/* Criar desligado: ele existe, mas ainda não é para clicar. */
.create-actions button[disabled] { opacity: .45; cursor: not-allowed; filter: saturate(.4); }
/*
 * O que sobrou da versão de texto dos dois botões de sexo.
 *
 * O fundo, a borda e o cantinho arredondado saíram junto com a caixa — eles
 * moravam AQUI, depois da regra nova lá em cima, e por isso continuavam
 * vencendo: o navegador lê de cima para baixo e a última igual manda. Foi por
 * isso que a caixa não sumiu da primeira vez.
 *
 * Ficam o cursor e a tipografia, que a versão com ícone também quer.
 */
.sex-picker button {
  cursor: pointer; font-family: var(--font-heading); font-size: 12px; color: var(--muted);
}

/*
 * ---- A lista de personagens em duas colunas ----
 *
 * Numa coluna só, cinco cards empilhados faziam uma caixa altíssima e estreita
 * — uma tira de 380px de largura por quase mil de altura, com o rodapé da
 * moldura perdido lá embaixo. O olho lia aquilo como uma lista de menu, não
 * como uma escolha entre cinco pessoas.
 *
 * `auto-fit` com 260px: até dois cards cabem lado a lado numa tela normal, e
 * quem tiver só um continua com ele ocupando a linha inteira em vez de metade.
 * A caixa fica quase quadrada, que é a proporção em que a moldura foi desenhada
 * para ser vista.
 */
.character-list {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 10px; margin-bottom: 16px;
}
.character-card {
  display: flex; align-items: center; gap: 12px; text-align: left; cursor: pointer;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px; padding: 10px 12px; color: inherit;
}
.character-card:hover { border-color: var(--accent); }
/*
 * ---- A moldura fina do card de personagem ----
 *
 * Sem arte. A moldura desenhada foi tentada e não coube: numa peça de 110px de
 * altura o ornamento da quina vira um borrão dourado, e o card passa a ser
 * "uma moldura com um personagem dentro" em vez de um personagem.
 *
 * Aqui a moldura é feita de fios, nas cores do jogo, e são QUATRO — cada um com
 * um trabalho:
 *
 *   1px escuro por fora     descola o card do fundo, que também é escuro
 *   1px teal na borda       a cor do jogo; é ela que diz "isto é um card"
 *   1px claro por dentro    o fio duplo, que é o que faz parecer moldura e não
 *                           um retângulo com contorno
 *   véu teal no miolo       tira o preto chapado de dentro
 *
 * A sombra projetada por baixo levanta o card do fundo. É o que o ornamento
 * fazia com desenho, feito com luz.
 */
.character-card--vitrine {
  border: 1px solid #3fbfa866;
  border-radius: 9px;
  background: linear-gradient(180deg, #13221f, #0c1517);
  padding: 11px 13px;
  gap: 13px;
  align-items: center;
  box-shadow:
    0 0 0 1px #00000077,
    inset 0 0 0 1px #ffffff10,
    inset 0 0 26px #3fbfa814,
    0 5px 16px #00000066;
  transition: border-color .18s ease, box-shadow .18s ease;
}
/* No hover os fios acendem — a cor não muda, a intensidade sim. */
.character-card--vitrine:hover {
  border-color: #6fe3cd;
  box-shadow:
    0 0 0 1px #00000077,
    inset 0 0 0 1px #ffffff1a,
    inset 0 0 30px #3fbfa826,
    0 5px 18px #00000077,
    0 0 20px #3fbfa844;
}
/* Aquele em que você já está não acende: ele não é um destino. */
.character-card--vitrine.atual { opacity: .55; }
.character-card--vitrine.atual:hover {
  border-color: #3fbfa866;
  box-shadow:
    0 0 0 1px #00000077,
    inset 0 0 0 1px #ffffff10,
    inset 0 0 26px #3fbfa814,
    0 5px 16px #00000066;
}
.character-card b { display: block; font-family: var(--font-heading); font-size: 14px; }
.character-card span { color: var(--muted); font-size: 11px; }
/*
 * ---- O ícone da vocação, na linha do level ----
 *
 * É o MESMO ícone de perícia que a ficha do personagem usa (`sk-sword`,
 * `sk-distance`, `sk-magic`, `sk-fist`), escolhido pela primeira perícia da
 * vocação — ver `VOCATION_INFO`, em auth.mjs. Reaproveitar a tabela que já
 * existe evita uma segunda lista de "vocação → desenho" para alguém esquecer de
 * atualizar no dia em que entrar uma vocação nova.
 *
 * Os 13px e o `vertical-align` o encaixam na linha de 11px sem empurrar a
 * altura do cartão — a lista tem cinco deles, e um pixel a mais em cada um é
 * cinco na tela.
 */
.character-card .vocacao-ico {
  width: 13px; height: 13px; vertical-align: -2px; margin-right: 4px;
  image-rendering: pixelated;
}
/*
 * A linha do "o que ele está fazendo".
 *
 * Três estados e três cores, e o ponto é o que se lê de longe: verde para quem
 * está caçando (rendendo), âmbar para quem está treinando ou parado na cidade,
 * apagado para quem não está no mundo. A cor vai no ponto e não no texto porque
 * o texto muda de tamanho conforme o nome da hunt, e uma linha inteira colorida
 * competiria com o nome do personagem logo acima.
 */
.character-fazendo {
  display: flex; align-items: center; gap: 4px; margin-top: 2px;
  font-style: normal; font-size: 11px; color: var(--muted);
}
.character-ponto {
  width: 6px; height: 6px; border-radius: 50%; flex: none;
  background: currentColor; box-shadow: 0 0 6px currentColor;
}
/*
 * Verde para quem está de pé no mundo agora (e ocupa vaga no teto de dois);
 * amarelo para o que rende com a aba fechada. Duas famílias, duas cores: é a
 * única distinção que muda a decisão de em quem entrar.
 */
.character-fazendo.online { color: #6ddb96; }
/* Laranja para o offline: o amarelo dourado do jogo já é a cor do ouro e da
   exp, e a distinção com o verde ficava fraca de relance. */
.character-fazendo.offline { color: #f0913f; }

/*
 * ---- A barra da atividade, dentro do card ----
 *
 * Quatro cores para quatro réguas, e nenhuma delas por acaso:
 *
 *   vermelha  as cargas da arma de exercise, que ACABAM e custam Mineiroidle Coins
 *   dourada   a experiencia, a mesma cor da barra de exp do HUD
 *   verde     as 42h de stamina, idem
 *   teal      as 12h do treino offline, a cor do tanque em panels.mjs
 *
 * Repetir a cor que a coisa ja tem em outro lugar do jogo e' o que evita a
 * pessoa ter de aprender uma legenda so' para esta caixa.
 */
.character-barra { height: 12px; margin-top: 5px; width: 100%; }
/* Duas barras seguidas quase se encostam: a segunda respira um pouco menos. */
.character-barra + .character-barra { margin-top: 3px; }
.character-barra span { font-size: 9px; line-height: 11px; }
.character-barra.cargas i { --liq-a: #ef6a52; --liq-b: #a81f14; }
.character-barra.exp i { --liq-a: #f0cf7a; --liq-b: #a8781f; }
/* Perícia: o roxo da stamina do `.track`, que já é a cor do que se treina. */
.character-barra.pericia i { --liq-a: #9184d6; --liq-b: #4c3f8f; }
.character-barra.stamina i { --liq-a: #6ddb96; --liq-b: #25794a; }
.character-barra.treino i { --liq-a: #57d6bd; --liq-b: var(--accent-dim, #2a8d7c); }
/*
 * O bloco de texto do card cede espaco; o retrato nao.
 *
 * `min-width: 0` e' o que deixa a barra e o nome encolherem DENTRO do flex —
 * sem ele o conteudo empurra o card e a barra escapa para fora dele, que foi o
 * que aconteceu na primeira versao.
 */
.character-card > div { flex: 1; min-width: 0; }
.character-fazendo.parado { color: #55646a; }
.character-fazendo.parado .character-ponto { box-shadow: none; }

/*
 * ---- A troca rápida, dentro da caixa de trocar de personagem ----
 *
 * Os mesmos cards da lista, empilhados. Uma coluna e não uma grade: são no
 * máximo quatro (cinco menos o atual), e em coluna cada um mantém a largura
 * inteira para o nome da hunt caber sem cortar — que é a informação nova e a
 * razão de a lista estar aqui.
 */
/* Os cards abrem a caixa, entao a folga fica embaixo deles e nao em cima. */
.troca-rapida { display: grid; gap: 10px; margin-bottom: 16px; }

/*
 * ---- Os cards na moldura do jogo ----
 *
 * Eles eram um retângulo cinza com borda de 1px — a cara de um formulário, no
 * meio de uma tela que é toda de pedra e metal. Aqui eles ganham a mesma
 * `padrao-aparada.png` das janelas, pela mesma `border-image`.
 *
 * Uso a arte MIÚDA (14px de moldura) e não a grande: o card tem 90px de altura,
 * e uma moldura de 48px comeria o retrato e o texto juntos. Com 14 sobra o
 * desenho da quina, que é o que se reconhece.
 *
 * O `border-image` substitui a borda inteira, então o realce do hover não pode
 * ser `border-color` — não há cor de borda para mudar. Vira um brilho por
 * dentro, que é o mesmo recurso que os slots do inventário usam.
 */
.troca-rapida .character-card {
  border-style: solid;
  border-width: 22px 14px 14px 14px;
  border-image-source: url(/client/assets/ui/padrao-aparada.png);
  border-image-slice: 100 27 26 25 fill;
  border-image-repeat: stretch;
  border-radius: 0;
  background: none;
  padding: 0 4px;
  gap: 14px;
  transition: box-shadow .15s ease, filter .15s ease;
}
.troca-rapida .character-card:hover {
  box-shadow: inset 0 0 18px #c8a13c55;
  filter: brightness(1.12);
}
/* O retrato ganha um nicho escuro, como os slots do equipamento. */
.troca-rapida .character-card canvas {
  background: #0e1417; border: 1px solid var(--line-soft); border-radius: 6px;
  box-shadow: inset 0 0 10px #0009;
}
/*
 * Aquele em que você já está fica visivelmente fora de alcance: apagado, sem
 * brilho no hover e sem cursor de clique. Ele está na lista para a conta não
 * parecer ter um personagem a menos, não para ser clicado.
 */
.character-card.atual { opacity: .55; cursor: default; }
.troca-rapida .character-card.atual:hover { box-shadow: none; filter: none; }
.character-fazendo.atual-marca { color: var(--accent); }
/*
 * O card e os botões de convidar/chamar do outro char: os botões ficam colados
 * embaixo do card, alinhados à direita, para não competir com o clique de entrar.
 */
/*
 * `troca-char` e não `troca-item`: esse nome já é da mesa de troca de itens.
 *
 * Os botões ficam DENTRO do card, no canto direito — pedido do dono. O card é
 * um `<button>` e botão não mora dentro de botão, então eles são irmãos dele,
 * pousados por cima com `position: absolute`, e o card reserva a faixa da
 * direita (`padding-right`) para o nome e as barras não passarem por baixo.
 */
.troca-char { position: relative; }
.troca-char .character-card { width: 100%; }
/*
 * Uma fileira de três pílulas no canto de cima, à direita — na altura do nome,
 * onde o card tem sobra. Pequenas e com ícone: são atalhos, e o card continua
 * sendo o personagem, não uma barra de botões.
 */
.troca-char-acoes {
  position: absolute; top: 28px; right: 22px;
  display: flex; gap: 5px;
}
.troca-char-acoes button {
  display: inline-flex; align-items: center; gap: 4px;
  height: 22px; min-height: 0; padding: 0 9px; border-radius: 11px; text-transform: none; font-family: inherit;
  font-size: 10.5px; letter-spacing: .02em; white-space: nowrap; line-height: 1;
  color: #bfe9df; background: linear-gradient(180deg, #16302b, #0d1c1a);
  border: 1px solid #3fbfa855; box-shadow: inset 0 1px 0 #ffffff12, 0 1px 3px #0008;
  transition: border-color .15s ease, color .15s ease, box-shadow .15s ease;
}
.troca-char-acoes button:hover:not(:disabled) {
  color: #eafff9; border-color: #6fe3cd; box-shadow: inset 0 1px 0 #ffffff1a, 0 0 10px #3fbfa844;
}
.troca-char-acoes button:disabled { opacity: .45; cursor: default; }
.troca-char-acoes button b { font-size: 12px; font-weight: normal; color: #6fe3cd; }
@media (max-width: 520px) {
  .troca-char .character-card { padding-bottom: 30px; }
  .troca-char-acoes { top: auto; bottom: 20px; right: 20px; left: 20px; justify-content: flex-end; flex-wrap: wrap; }
}

/* O painel ⚙ Configurar de outro char. */
.config-outro-linha { display: flex; flex-wrap: wrap; gap: 10px; margin: 8px 0 14px; }
.config-outro-campo { display: grid; gap: 3px; min-width: 120px; }
.config-outro-campo .rotulo { font-size: 11px; color: var(--muted); }
/*
 * Os seletores são clones dos do rodapé, mas o desenho de lá vem do CONTAINER
 * do rodapé — clonado para cá, o `select` caía no branco do navegador.
 */
.config-outro-campo select {
  background: var(--panel-2); color: var(--text); color-scheme: dark;
  border: 1px solid var(--line); border-radius: 6px;
  padding: 6px 8px; font-size: 12px; font-family: inherit; cursor: pointer;
}
.config-outro-campo select:hover { border-color: var(--accent-dim); }
.config-outro-campo select:focus { outline: none; border-color: var(--accent); }
.config-outro-campo select option { background: #0e1417; color: var(--text); }
/* A formação da party dentro do painel: os seletores com o mesmo desenho escuro. */
.config-outro-formacao { display: grid; gap: 8px; margin: 8px 0 14px; }
.config-outro-formacao .party-config { display: grid; gap: 3px; }
.config-outro-formacao .party-config span { font-size: 11px; color: var(--muted); }
.config-outro-formacao .party-config em { font-size: 11px; color: var(--muted); }
.config-outro-formacao select {
  max-width: 260px; background: var(--panel-2); color: var(--text); color-scheme: dark;
  border: 1px solid var(--line); border-radius: 6px; padding: 6px 8px; font-size: 12px; font-family: inherit;
}
.config-outro-formacao select option { background: #0e1417; color: var(--text); }
.config-outro-barra { display: grid; grid-template-columns: repeat(auto-fill, minmax(44px, 1fr)); gap: 6px; margin-bottom: 14px; }
.config-outro-slot {
  position: relative; height: 44px; display: grid; place-items: center; padding: 0;
  background: #0e1417; border: 1px solid var(--line-soft); border-radius: 6px; color: var(--muted);
}
.config-outro-slot:hover { border-color: var(--accent); }
.config-outro-slot.desligado { opacity: .45; }
.config-outro-slot { touch-action: none; user-select: none; }
.config-outro-slot.arrastando { opacity: .5; cursor: grabbing; }
.config-outro-slot.alvo { border-color: #6fe3cd; box-shadow: 0 0 10px #3fbfa866; }
.config-outro-slot em { position: absolute; left: 3px; top: 1px; font-size: 9px; font-style: normal; color: var(--muted); }

/* As cinco vocações numa fileira só, cada uma alinhada com a sua zona de cor
   na arte do fundo: knight, paladin, druid, sorcerer e monk, da esquerda para a
   direita. */
/*
 * ---- A escolha da vocação ----
 *
 * Cinco cards numa fileira, e a mesma linguagem da lista de personagens: borda
 * verde com brilho, fundo em degradê, o retrato num nicho escuro. Antes eram
 * cinco retângulos cinza — a tela em que se escolhe a vocação de um personagem
 * que vai durar meses parecia um formulário de cadastro.
 *
 * As alturas são iguais (`1fr` nas linhas internas) porque as descrições têm
 * comprimentos diferentes: sem isso o card do monge ficava um degrau abaixo dos
 * outros e a fileira ficava serrilhada embaixo.
 */
.vocation-picker { display: grid; grid-template-columns: repeat(5, 1fr); gap: 12px; align-items: stretch; }
.vocation-picker button {
  background: linear-gradient(180deg, #12211f, #0d1618);
  border: 1px solid var(--line); border-radius: 12px;
  padding: 16px 12px 14px; cursor: pointer; display: grid; justify-items: center; gap: 7px; color: inherit;
  /* nome, boneco, ícones, descrição — a descrição leva a sobra. */
  grid-template-rows: auto auto auto 1fr;
  transition: border-color .16s ease, box-shadow .16s ease, transform .16s ease;
}
.vocation-picker button:hover {
  border-color: var(--accent-dim); transform: translateY(-2px);
  box-shadow: inset 0 0 20px #3fbfa81f, 0 0 16px #3fbfa833;
}
/*
 * A escolhida acende de verdade: é a única decisão desta tela que não dá para
 * desfazer depois, e ela tem de ser inconfundível de relance.
 */
.vocation-picker button[aria-selected="true"] {
  border-color: var(--accent);
  box-shadow: inset 0 0 24px #3fbfa833, 0 0 0 1px #3fbfa855, 0 0 22px #3fbfa866;
  transform: translateY(-2px);
}
/*
 * ---- O cenário de cada vocação ----
 *
 * Cada botão ganha o canto do mundo de onde aquela vocação vem. A arte tem a
 * metade de baixo escura de propósito (foi assim que ela foi pedida), e é ali
 * que caem o nome e a descrição.
 *
 * O DEGRADÊ POR CIMA não é enfeite e não pode sair: ele garante o texto legível
 * mesmo que uma das cinco artes saia mais clara que as outras. Sem ele, a
 * legibilidade da tela dependeria de o gerador ter obedecido ao pedido — e
 * depender disso é depender de sorte.
 *
 * ---- Os três números, e o que cada um segura ----
 *
 *   73 (45%) no topo    o cenário aparece; é a faixa que identifica a vocação
 *   c2 (76%) no meio    a transição, atrás do nome
 *   d9 (85%) embaixo    onde fica a descrição, a parte que PRECISA ser lida
 *
 * Eram 60/91/97 e a arte quase não passava. Estes são 15 pontos mais claros em
 * cada parada. Se um dia uma arte nova entrar mais clara e o texto sumir, é
 * aqui que se mexe — e o número de baixo é o último a ceder, porque descrição
 * ilegível é pior do que cenário apagado.
 *
 * `top center`: a parte interessante das cinco está no alto (os escudos, o
 * suporte de arcos, o círculo de runas). Centralizando, o corte esconderia
 * justamente o que identifica a vocação.
 */
.vocation-picker button {
  background-size: cover;
  background-position: top center;
  background-repeat: no-repeat;
}
.vocation-picker button[data-vocation="knight"] {
  background-image: linear-gradient(180deg, #0d161873 12%, #0d1618c2 52%, #0d1618d9), url('/client/assets/ui/vocacao-knight.webp');
}
.vocation-picker button[data-vocation="paladin"] {
  background-image: linear-gradient(180deg, #0d161873 12%, #0d1618c2 52%, #0d1618d9), url('/client/assets/ui/vocacao-paladin.webp');
}
.vocation-picker button[data-vocation="druid"] {
  background-image: linear-gradient(180deg, #0d161873 12%, #0d1618c2 52%, #0d1618d9), url('/client/assets/ui/vocacao-druid.webp');
}
.vocation-picker button[data-vocation="sorcerer"] {
  background-image: linear-gradient(180deg, #0d161873 12%, #0d1618c2 52%, #0d1618d9), url('/client/assets/ui/vocacao-sorcerer.webp');
}
.vocation-picker button[data-vocation="monk"] {
  background-image: linear-gradient(180deg, #0d161873 12%, #0d1618c2 52%, #0d1618d9), url('/client/assets/ui/vocacao-monk.webp');
}
/* A escolhida clareia um pouco o cenário — o degradê abre. */
.vocation-picker button[aria-selected="true"] { background-blend-mode: normal; filter: brightness(1.08) saturate(1.05); }

/*
 * ---- O boneco e as perícias, lado a lado ----
 *
 * Os ícones ficam numa coluna à direita do boneco, e não numa fileira embaixo:
 * o card é mais alto que largo, e três ícones deitados roubariam a largura que
 * a descrição precisa. Em pé, eles acompanham a altura do boneco e não custam
 * linha nenhuma.
 *
 * `justify-content: center` no conjunto porque o Paladin tem um ícone e o
 * Knight tem três — sem isso o boneco de cada card pararia num lugar diferente,
 * e a fileira de cinco ficaria desalinhada.
 */
/*
 * A fileira de ícones, entre o boneco e a descrição.
 *
 * Ao lado do boneco eles empurravam tudo para a esquerda e comiam largura da
 * descrição — e o card é estreito. Aqui são a ponte entre o que se vê (o
 * boneco) e o que se lê (a frase).
 *
 * `flex-wrap` porque o Druid e o Sorcerer têm quatro peças na fileira (a
 * perícia, o separador e dois elementos): numa tela apertada elas quebram para
 * a linha de baixo em vez de espremer o card.
 */
.vocation-skills { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 6px; }
/*
 * O respiro entre as perícias e os elementos: um risco de um pixel.
 *
 * Sem ele as duas famílias viram uma lista só, e o `magic` do druida pareceria
 * ter algo a ver com o gelo ao lado. São coisas diferentes — uma é o que ele
 * treina, a outra é do que ele é feito.
 */
.vocation-sep {
  width: 1px; height: 14px; background: var(--line); opacity: .7; margin: 0 2px;
}
.vocation-skills img {
  width: 20px; height: 20px; display: block; image-rendering: pixelated;
  opacity: .85; filter: drop-shadow(0 1px 2px #000b);
}
/* Na escolhida eles acendem junto com o resto do card. */
.vocation-picker button[aria-selected="true"] .vocation-skills img { opacity: 1; }

/*
 * O palco: o boneco e o efeito no mesmo lugar da grade.
 *
 * `place-items: center` empilha os dois pelo centro, e a tela do efeito é maior
 * que o boneco — ela transborda para os lados sem empurrar nada, porque está
 * fora do fluxo (`position: absolute`).
 */
.vocation-palco { position: relative; display: grid; place-items: center; }
.vocation-efeito {
  position: absolute; width: 96px; height: 96px;
  image-rendering: pixelated;
  /* Não rouba o clique do botão que a contém. */
  pointer-events: none;
}

/*
 * O boneco SEM caixa.
 *
 * Ele tinha um nicho escuro atrás, como os slots do equipamento — e fazia
 * sentido enquanto o card era liso. Com o cenário atrás, o nicho virou um
 * retângulo chapado plantado no meio da armaria: uma caixa dentro de outra.
 *
 * O que ele resolvia continua resolvido de outro jeito. O boneco precisa se
 * destacar do fundo, e quem faz isso agora é a sombra projetada — ela segue o
 * contorno do desenho em vez de desenhar um quadrado em volta dele. Duas
 * camadas: uma escura e colada, que separa do cenário, e um halo largo e
 * quente, que dá o mesmo volume que o nicho dava.
 */
.vocation-picker canvas {
  background: none; border: none; padding: 0;
  filter: drop-shadow(0 2px 3px #000c) drop-shadow(0 0 10px #0d161899);
}
.vocation-picker canvas { image-rendering: pixelated; }
/* Na escolhida o halo do boneco esquenta um pouco, no verde do jogo. */
.vocation-picker button[aria-selected="true"] canvas { filter: drop-shadow(0 2px 3px #000c) drop-shadow(0 0 12px #3fbfa866); }
.vocation-picker b { font-family: var(--font-heading); font-size: 14px; letter-spacing: .03em; }
.vocation-picker em { font-style: normal; font-size: 11px; color: var(--muted); text-align: center; line-height: 1.35; }

@media (max-width: 900px), (max-height: 540px) and (pointer: coarse) {
  .gate-box.creating { width: 100%; }
  .vocation-picker { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 600px) {
  .vocation-picker { grid-template-columns: repeat(2, 1fr); }
  /* `fixed` trava e pisca no Safari do iPhone. */
  #gate, #gate.creating { background-attachment: scroll; }
}

/* ---------- topbar ---------- */

/* Topbar 20% mais alta, com os ícones acompanhando: em 52px eles ficavam
   miúdos demais ao lado da placa da loja. */
/*
 * ---- A faixa de "em obras" ----
 *
 * Ela mora ACIMA da barra de cima, encostada na esquerda, e nao fecha: o jogo
 * esta em desenvolvimento e quem entra tem de saber disso o tempo todo, nao so'
 * no primeiro segundo. Um aviso que se fecha e' um aviso que ninguem leu.
 *
 * O vermelho e' o `--danger` do tema, escurecido: alto o bastante para nao
 * passar batido, baixo o bastante para nao competir com a barra de vida.
 */
/*
 * Ela fica LOGO ABAIXO da barra de cima, colada nela, e empurra o HUD.
 *
 * A barra e' `position: fixed`, entao a faixa tambem precisa ser — posta no
 * fluxo normal do HTML ela ficava POR BAIXO da barra, invisivel: presente, com
 * o texto certo e com 30px de altura medidos no navegador, e nada na tela.
 *
 * O que sobra dela e' uma variavel: `--altura-do-aviso` desce de
 * `body.com-aviso` para o HUD, que se pendurava na altura da barra. Sem a faixa
 * a variavel vale zero e a tela fica exatamente como era.
 *
 * O `z-index` e' 29 — um a MENOS que o da barra. Assim a sombra da barra cai
 * por cima da faixa, e nao o contrario.
 */
#aviso-dev {
  position: fixed; top: var(--altura-da-topbar); left: 0; right: 0; z-index: 29;
  display: flex; align-items: center; gap: 8px;
  height: 24px; padding: 0 14px;
  background: linear-gradient(90deg, #4a1512, #240c0a 55%, #1409087f);
  border-bottom: 1px solid #7d2620;
  font-family: var(--font-heading); font-size: 11px; letter-spacing: .09em;
  color: #ff9a91; text-transform: uppercase; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
}
#aviso-dev::before { content: '⚠'; font-size: 12px; }
#aviso-dev[hidden] { display: none; }
/*
 * O botão de reportar dentro da faixa.
 *
 * `margin-left: auto` o joga para a direita: encostado no texto do aviso, ele
 * parecia parte da frase. Na ponta ele é o que é — uma ação.
 */
#aviso-dev-report {
  margin-left: auto; flex: none;
  background: #ffffff14; border: 1px solid #ff9a9155; border-radius: 999px;
  color: #ffd0cb; cursor: pointer;
  font-family: var(--font-heading); font-size: 10px; letter-spacing: .09em;
  text-transform: uppercase; padding: 2px 12px;
}
#aviso-dev-report:hover { background: #ffffff26; border-color: #ffb3ab; color: #fff; }
#cartaz-beta-report {
  margin-top: 8px; cursor: pointer;
  background: linear-gradient(180deg, #7d2620, #4a1512); border: 1px solid #ff9a9166;
  border-radius: 8px; color: #ffe3e0; padding: 7px 16px;
  font-family: var(--font-heading); font-size: 12px; letter-spacing: .06em;
}
#cartaz-beta-report:hover { border-color: #ffb3ab; color: #fff; }

/* ---------- a janela do report ---------- */

.report-tipos { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 12px; }
.report-tipos button {
  display: grid; gap: 4px; justify-items: center; padding: 14px 10px; cursor: pointer;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px;
}
.report-tipos button:hover { border-color: var(--accent); }
.report-tipos button[aria-selected="true"] { border-color: var(--accent); background: #16241f; }
.report-tipos b { font-family: var(--font-heading); font-size: 14px; }
.report-tipos em { font-style: normal; font-size: 11px; color: var(--muted); text-align: center; }
.report-texto {
  width: 100%; min-height: 130px; resize: vertical; box-sizing: border-box;
  background: #0f1517; border: 1px solid var(--line); border-radius: 8px;
  color: var(--text); font: 13px/1.5 "Segoe UI", system-ui, sans-serif; padding: 10px;
}
.report-texto:focus { outline: none; border-color: var(--accent); }
.report-anexo { display: flex; align-items: center; gap: 10px; margin: 10px 0; flex-wrap: wrap; }
/*
 * Verdes, como todo botão de ação do jogo.
 *
 * Brancos eles pareciam link do navegador dentro de uma janela que não tem
 * nenhum — e o olho não os lia como "clique aqui". A cor é a mesma do `Enviar`
 * ali embaixo, porque fazem parte do mesmo gesto.
 */
.report-anexo button {
  cursor: pointer; border-radius: 6px; padding: 7px 16px;
  border: 1px solid var(--accent-dim); background: var(--accent-dim); color: #eafffb;
  font-family: var(--font-heading); font-weight: 600; letter-spacing: .05em;
}
.report-anexo button:hover { border-color: var(--accent); filter: brightness(1.12); }
/* Tirar o print desfaz, e desfazer é vermelho aqui — o mesmo par do treino. */
.report-anexo button.danger { background: #7d2620; border-color: #c0533f; color: #ffe3e0; }
.report-anexo em { font-style: normal; font-size: 11px; color: var(--muted); }
/*
 * ---- As duas prévias, lado a lado e rotuladas ----
 *
 * Duas fotos do mesmo instante são parecidas o bastante para o jogador achar
 * que mandou a mesma coisa duas vezes; o rótulo embaixo é o que separa "o mapa"
 * de "a tela com as janelas".
 */
.report-previas { display: flex; gap: 10px; flex-wrap: wrap; margin: 4px 0 10px; }
.report-previa-caixa { margin: 0; flex: 1 1 220px; min-width: 0; }
.report-previa-caixa figcaption {
  margin-top: 4px; font-size: 10px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--muted);
}
.report-previa {
  max-width: 100%; max-height: 190px; border: 1px solid var(--line); border-radius: 6px; display: block;
}
/*
 * O botão da foto da tela é o único que dispara uma permissão do navegador, e
 * por isso é o único que se anuncia: sem esse destaque, a caixa de "quer
 * compartilhar esta aba?" apareceria vinda de um botão igual aos outros dois.
 */
.report-anexo button.destaque { border-color: var(--accent); box-shadow: 0 0 8px #6fe0c233; }
.report-anexo button:disabled { opacity: .6; cursor: progress; }
.report-contexto { font-size: 11px; color: var(--muted); margin: 6px 0 12px; }

/* ---------- O cartaz de beta ----------
   A faixa fina de cima e' o lembrete que fica; este e' o aviso que se le' uma
   vez.

   Centralizado no alto da AREA DE JOGO, e nao no alto da janela: posto la em
   cima ele cobria a placa da loja e tres icones da barra — um aviso que
   esconde o jogo cobra caro por ser lido. Aqui ele desce logo abaixo da barra e
   da faixa fina (por isso a soma com `--altura-do-aviso`, que vale zero quando
   nao ha faixa), fica sobre o mapa e nao tapa botao nenhum. */
#cartaz-beta {
  position: fixed; top: calc(var(--altura-da-topbar) + var(--altura-do-aviso, 0px) + 14px);
  left: 50%; transform: translateX(-50%); z-index: 60;
  width: min(560px, calc(100vw - 40px));
  padding: 16px 44px 16px 20px;
  background: linear-gradient(160deg, #58191500, #4a1512 12%, #2a0d0b 78%, #1a0908);
  border: 1px solid #a33228; border-radius: 10px;
  box-shadow: 0 14px 40px #000000a6, inset 0 1px 0 #ff9a9126;
  text-align: center; pointer-events: auto;
  animation: cartaz-entra .5s cubic-bezier(.2, .9, .25, 1) both;
}
#cartaz-beta[hidden] { display: none; }
#cartaz-beta b {
  display: block; font-family: var(--font-heading);
  font-size: 19px; letter-spacing: .1em; text-transform: uppercase;
  color: #ffb4aa; text-shadow: 0 2px 12px #ff4a3a4d;
}
#cartaz-beta p { margin: 7px 0 0; font-size: 12px; line-height: 1.5; color: #e2a9a2; }
#cartaz-beta::before {
  content: '⚠'; position: absolute; left: 16px; top: 50%; transform: translateY(-50%);
  font-size: 22px; color: #ff7a6a; opacity: .55;
}
#cartaz-beta-fechar {
  position: absolute; top: 8px; right: 10px;
  width: 26px; height: 22px; padding: 0;
  background: #00000059; border: 1px solid #a3322859; border-radius: 5px;
  color: #ffb4aa; font-size: 15px; line-height: 1; cursor: pointer;
}
#cartaz-beta-fechar:hover { background: #a3322859; color: #fff; }
@keyframes cartaz-entra {
  from { opacity: 0; transform: translate(-50%, -14px); }
  to { opacity: 1; transform: translate(-50%, 0); }
}

body.com-aviso { --altura-do-aviso: 24px; }

/* ---------- a faixa de novidades ---------- */

/*
 * Ela mora logo ABAIXO da faixa de obra (por isso a soma com
 * `--altura-do-aviso`, que vale zero quando não há aviso), e o HUD desce mais
 * uma faixa quando ela está na tela — ver `body.com-novidades`.
 *
 * Dourada, e não vermelha: a faixa de obra avisa de um risco, esta anuncia uma
 * entrega. Duas tarjas da mesma cor no mesmo canto seriam lidas como uma só.
 */
/*
 * ---- Centrada, e não de ponta a ponta ----
 *
 * A primeira versão ocupava a largura toda, como a faixa de obra. Numa tela
 * cheia ela passava POR CIMA do cabeçalho das janelas encostadas na direita —
 * inventário e bolsa —, e o "ver o que mudou" ficava em cima do título delas.
 *
 * Uma placa centrada resolve os dois lados: ela não encosta em janela nenhuma
 * e lê mais como anúncio do que como alerta, que é o que ela é.
 */
#faixa-novidades {
  position: fixed; z-index: 29;
  top: calc(var(--altura-da-topbar) + var(--altura-do-aviso, 0px));
  left: 50%; transform: translateX(-50%); max-width: min(760px, 86vw);
  display: flex; align-items: center; gap: 10px;
  height: 28px; padding: 0 16px; cursor: pointer;
  background: linear-gradient(180deg, #55430f, #241d0a);
  border: 1px solid #7d6420; border-top: none; border-radius: 0 0 10px 10px;
  box-shadow: 0 6px 18px #000a;
  font-family: var(--font-heading); font-size: 11px; letter-spacing: .09em;
  color: #f0d79a; text-transform: uppercase; white-space: nowrap;
  overflow: hidden; text-align: left;
}
#faixa-novidades[hidden] { display: none; }
#faixa-novidades:hover { background: linear-gradient(180deg, #6d5615, #322810); color: #fff3d6; border-color: var(--exp); }

/* O selo pulsa como o "+" da bolsa, e pelo mesmo motivo: ele é a única coisa
   nova na tela, e uma tarja parada some no fundo depois do segundo dia. */
#faixa-novidades .selo {
  flex: none; padding: 2px 10px; border-radius: 999px;
  background: #ffffff14; border: 1px solid var(--exp);
  color: var(--exp); font-weight: 700;
  animation: pulso-dourado 2.4s ease-in-out infinite;
}
/* O texto do meio é o único que pode encolher: o selo e o "ver o que mudou"
   são o anúncio e a ação, e cortar qualquer um dos dois deixaria a faixa muda. */
#faixa-novidades .resumo {
  flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  text-transform: none; letter-spacing: .02em; font-size: 12px; color: #d8c79f;
  font-family: "Segoe UI", system-ui, sans-serif;
}
#faixa-novidades .abrir { flex: none; color: #fff3d6; text-decoration: underline; }

@media (prefers-reduced-motion: reduce) {
  #faixa-novidades .selo { animation: none; }
}

/*
 * ---- A faixa do Auto Boss ----
 *
 * Mesma forma da de novidades (mesmo lugar, mesma altura, mesmo recorte), com
 * a cor do jogo em vez da dourada: uma e' um anuncio que se le uma vez, a outra
 * e' um estado que fica. Quando as duas aparecem juntas, esta desce.
 */
/*
 * ---- A barra de vida do BOSS ----
 *
 * Larga de proposito: ela existe para ser lida de relance no meio da luta, e o
 * que se le de relance e o COMPRIMENTO do trilho, nao o numero. Os numeros vem
 * junto para quem quiser conferir.
 *
 * O `top` e escrito pelo `empilharNoTopo`, em javascript, e nao aqui: as faixas
 * de cima aparecem e somem, e um numero cravado no css estaria errado metade do
 * tempo. O valor daqui e so o comeco, para o primeiro quadro nao nascer torto.
 */
#barra-do-boss {
  position: fixed; z-index: 28;
  top: calc(var(--altura-da-topbar) + var(--altura-do-aviso, 0px) + 8px);
  left: 50%; transform: translateX(-50%);
  width: min(620px, 82vw); padding: 8px 14px 10px 8px;
  display: flex; align-items: center; gap: 11px;
  background: linear-gradient(180deg, #1a0f12f2, #0c0709f2);
  border: 1px solid #7a2f36; border-radius: 12px;
  box-shadow: 0 8px 26px #000b, inset 0 1px 0 #ffffff12;
  /* O brilho de fora acompanha o aperto: ver `.aperto`, mais abaixo. */
  transition: border-color .4s linear, box-shadow .4s linear;
  pointer-events: none;
}

/*
 * A moldura do retrato. `overflow: hidden` porque o canvas do outfit é o corpo
 * inteiro da criatura e algumas passam da caixa — cortar pelas bordas é o que
 * faz bosses de tamanhos muito diferentes caberem na mesma moldura.
 */
.boss-cara {
  flex: none; width: 46px; height: 46px;
  display: grid; place-items: center; overflow: hidden;
  border-radius: 9px;
  background: radial-gradient(circle at 50% 35%, #5a1c22, #240c10 70%);
  border: 1px solid #8c3a42; box-shadow: inset 0 2px 8px #0009;
}
.boss-cara canvas, .boss-cara img { max-width: 100%; max-height: 100%; }

.boss-corpo { flex: 1; min-width: 0; }
.boss-topo { display: flex; align-items: baseline; gap: 10px; margin-bottom: 5px; }
#boss-nome {
  font-family: var(--font-title); font-size: 15px; letter-spacing: .03em;
  color: #ffd9c2; text-shadow: 0 1px 3px #000, 0 0 12px #ff6a4a30;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
#boss-nome { flex: none; max-width: 46%; }
#boss-conta { font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; flex: none; margin-left: auto; }

/*
 * ---- As resistências ----
 *
 * Entre o nome e a contagem, e no fim da fila quando falta espaço: numa tela
 * estreita o que não pode sumir é o nome e a vida. `overflow: hidden` em vez de
 * quebrar linha — a barra tem altura fixa e uma segunda linha a empurraria por
 * cima do jogo.
 */
.boss-elementos { display: flex; gap: 5px; overflow: hidden; flex: 1; min-width: 0; }
.boss-el {
  display: inline-flex; align-items: center; gap: 3px; flex: none;
  padding: 1px 5px 1px 3px; border-radius: 6px;
  font-size: 10px; font-weight: 700; font-variant-numeric: tabular-nums;
  border: 1px solid transparent;
}
.boss-el img { width: 13px; height: 13px; image-rendering: pixelated; }
.boss-el i { font-style: normal; }
/* Resiste: o jogador PERDE dano batendo assim. Fraco: é por aqui que dói. */
.boss-el.resiste { background: #3a1216; border-color: #7e2b33; color: #ff9d92; }
.boss-el.fraco { background: #122c18; border-color: #2f7040; color: #86e39a; }
.boss-trilho {
  position: relative; height: 19px; border-radius: 10px; overflow: hidden;
  background: #2a0e12; border: 1px solid #00000080;
  box-shadow: inset 0 2px 5px #0009;
}

/*
 * O RASTRO do dano: a faixa clara que fica para trás quando a vida cai de uma
 * vez. Ela vive atrás do preenchimento e some por baixo dele — o que se vê é só
 * o pedaço que acabou de sair.
 */
#boss-rastro {
  position: absolute; inset: 0 auto 0 0; display: block; height: 100%;
  background: linear-gradient(180deg, #ffd9a0, #e08a4a);
  opacity: .5;
}
#boss-cheio {
  position: relative; display: block; height: 100%; width: 100%;
  background: linear-gradient(180deg, #ff6b5e, #b81f2c 60%, #7d101c);
  box-shadow: inset 0 1px 0 #ffffff40;
  /* A largura anda macio: o dano de area tira dez por cento de uma vez, e o
     pulo seco esconde o quanto saiu. */
  transition: width .22s linear, background .4s linear;
}
/* Abaixo de um terco ela esquenta: e o aviso de que a luta esta virando. */
#barra-do-boss.aperto #boss-cheio { background: linear-gradient(180deg, #ffb057, #d9631a 60%, #8a3a08); }
#barra-do-boss.aperto {
  border-color: #b06a2a;
  /* E a moldura inteira acende. O aviso tem de ser visto por quem está
     olhando o próprio personagem, e não a barra. */
  box-shadow: 0 8px 26px #000b, inset 0 1px 0 #ffffff12, 0 0 22px #d9631a55;
}
#barra-do-boss.aperto .boss-cara { border-color: #c07a33; }
#boss-pct {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-size: 11px; font-weight: 700; color: #fff; letter-spacing: .04em;
  text-shadow: 0 1px 2px #000, 0 0 6px #0008; font-variant-numeric: tabular-nums;
}

/*
 * ---- A caixa de castigo (mute, ban, ban de IP) ----
 *
 * O tempo numa linha so: numero, unidade e a caixinha do permanente. Foi o
 * pedido literal — "escolher o tempo em dias horas ou minutos e botao de
 * confirmar" — e uma linha so e o que deixa a escolha inteira visivel de uma vez.
 */
.castigo-tempo { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 10px 0 8px; }
.castigo-rotulo { font-size: 12px; color: var(--muted); }
.castigo-tempo input[type="number"] {
  width: 76px; padding: 6px 8px; border-radius: 6px;
  background: var(--panel-2); border: 1px solid var(--line); color: var(--text);
}
.castigo-tempo select {
  padding: 6px 8px; border-radius: 6px;
  background: var(--panel-2); border: 1px solid var(--line); color: var(--text);
}
.castigo-tempo input:disabled, .castigo-tempo select:disabled { opacity: .45; }
.castigo-perm { display: flex; align-items: center; gap: 5px; font-size: 12px; color: var(--muted); cursor: pointer; }
.castigo-motivo {
  width: 100%; padding: 7px 9px; border-radius: 6px; margin-bottom: 4px;
  background: var(--panel-2); border: 1px solid var(--line); color: var(--text);
}

#faixa-autoboss {
  position: fixed; z-index: 29;
  top: calc(var(--altura-da-topbar) + var(--altura-do-aviso, 0px));
  left: 50%; transform: translateX(-50%); max-width: min(760px, 86vw);
  display: flex; align-items: center; gap: 10px;
  height: 28px; padding: 0 8px 0 16px;
  background: linear-gradient(180deg, #123028, #0b1a16);
  border: 1px solid var(--accent-dim); border-top: none; border-radius: 0 0 10px 10px;
  box-shadow: 0 6px 18px #000a;
  font-family: var(--font-heading); font-size: 11px; letter-spacing: .09em;
  color: #cfe9e0; text-transform: uppercase; white-space: nowrap;
  overflow: hidden;
}
#faixa-autoboss[hidden] { display: none; }
#faixa-autoboss .selo {
  flex: none; padding: 2px 10px; border-radius: 999px;
  background: #ffffff14; border: 1px solid var(--accent);
  color: var(--accent); font-weight: 700;
}
#faixa-autoboss .resumo {
  flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  text-transform: none; letter-spacing: .02em; font-size: 12px; color: #9fbdb3;
  font-family: "Segoe UI", system-ui, sans-serif;
}
#faixa-autoboss button {
  flex: none; cursor: pointer; border-radius: 6px; padding: 3px 12px;
  background: #2a1416; border: 1px solid #7d3a3a; color: #ffb3b3;
  font-family: var(--font-heading); font-size: 10px; letter-spacing: .08em;
  text-transform: uppercase;
}
#faixa-autoboss button:hover { background: #3a1b1e; border-color: #b45a5a; color: #ffd6d6; }
/* Com a faixa de novidades na tela, esta fica logo abaixo dela. */
body.com-novidades #faixa-autoboss { top: calc(var(--altura-da-topbar) + var(--altura-do-aviso, 0px) + 30px); }

/* ---------- A faixa do Server Save ----------
   Mesmo lugar e mesma forma das outras duas faixas do alto, e de proposito: o
   jogo ja' ensinou que aviso importante nasce ali. O que muda e' a COR, que e'
   a de perigo, e o fato de ela nao ter botao — nao ha' nada para a pessoa
   fazer, e um botao sugeriria que ha'.

   Ela pulsa so' no ultimo minuto. Pulsar os quinze minutos inteiros vira
   ruido, e quando o momento chega ninguem mais repara. */
#faixa-serversave {
  position: fixed; z-index: 30;
  top: calc(var(--altura-da-topbar) + var(--altura-do-aviso, 0px));
  left: 50%; transform: translateX(-50%); max-width: min(760px, 92vw);
  display: flex; align-items: center; gap: 10px;
  height: 28px; padding: 0 16px;
  background: linear-gradient(180deg, #3a1410, #1d0a08);
  border: 1px solid #8c3b2f; border-top: none; border-radius: 0 0 10px 10px;
  box-shadow: 0 6px 18px #000a;
  font-family: var(--font-heading); font-size: 11px; letter-spacing: .09em;
  color: #ffd8cf; text-transform: uppercase; white-space: nowrap; overflow: hidden;
}
#faixa-serversave[hidden] { display: none; }
#faixa-serversave .selo {
  flex: none; padding: 2px 10px; border-radius: 999px;
  background: #ff6a4d1f; border: 1px solid #ff8a6d;
  color: #ffb9a6; font-weight: 700;
}
#faixa-serversave .resumo {
  flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  text-transform: none; letter-spacing: .02em; font-size: 12px; color: #f0c2b6;
  font-family: "Segoe UI", system-ui, sans-serif;
}
/* O ultimo minuto, e a hora em si: aí sim pisca. */
#faixa-serversave.urgente {
  border-color: #ff8a6d;
  animation: serversave-pulsa 1.1s ease-in-out infinite;
}
@keyframes serversave-pulsa {
  0%, 100% { box-shadow: 0 6px 18px #000a; }
  50% { box-shadow: 0 6px 26px #ff6a4d66; }
}
/* ---------------------------------------------------------------------------
 * As barras dos bosses da arena de Boss Diários
 *
 * "dentro da sala de boss diário tem que ter a vida dos bosses que estão lá
 *  sabe? igual a vida que aparece em bosses"
 *
 * Mesma linguagem da barra de sala de boss — mesmo trilho, mesma cor, mesmo
 * "aperto" abaixo de um terço —, mas uma LINHA por boss e sem retrato: na arena
 * podem estar três ao mesmo tempo, e três retratos daquele tamanho tapariam o
 * mapa que a pessoa foi ver.
 * ------------------------------------------------------------------------- */
#barras-da-arena {
  position: fixed; z-index: 28; pointer-events: none;
  top: calc(var(--altura-da-topbar) + var(--altura-do-aviso, 0px) + 8px);
  /* Centrada por margem, e não por `translateX(-50%)`: os -50% de uma largura
     ímpar caem em meio pixel e lavam o texto. Ver a nota do `#cartaz-boss`. */
  inset-inline: 0; margin-inline: auto;
  /* Larga como a barra de sala: ela carrega as mesmas resistências. */
  width: min(620px, 86vw);
  display: grid; gap: 5px;
}
#barras-da-arena[hidden] { display: none; }

.arena-boss {
  position: relative;
  display: flex; align-items: center; gap: 9px;
  padding: 6px 10px 7px 6px;
  background: linear-gradient(180deg, #1a0f12f2, #0c0709f2);
  border: 1px solid #7a2f36; border-radius: 10px;
  box-shadow: 0 6px 20px #000a, inset 0 1px 0 #ffffff12;
  transition: border-color .4s linear, box-shadow .4s linear;
}
/* O retrato: a mesma moldura da barra de sala, menor — são várias empilhadas. */
.arena-cara { width: 34px; height: 34px; border-radius: 8px; }
.arena-corpo { flex: 1; min-width: 0; }
.arena-topo { display: flex; align-items: center; gap: 9px; margin-bottom: 4px; }
.arena-topo b {
  font-family: var(--font-title); font-size: 12.5px; letter-spacing: .03em;
  color: #ffd9c2; text-shadow: 0 1px 3px #000;
  /* `min-width: 0` é o que deixa o nome ENCOLHER numa linha flex: sem ele o
     nome longo empurra a contagem e o botão de loot para fora da barra. */
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.arena-conta {
  margin-left: auto; flex: none;
  font-size: 10.5px; color: var(--muted); font-variant-numeric: tabular-nums;
}

/*
 * ---- As resistências têm linha própria, e QUEBRAM ----
 *
 * Na barra de sala elas moram entre o nome e a contagem, com `overflow: hidden`
 * para nunca virar duas linhas. Ali cabem, porque a barra só tem nome,
 * elementos e vida.
 *
 * Aqui não cabiam: a linha de cima ainda tem o retrato, a contagem e o botão de
 * Loot, e o corte comia o último chip pela metade — ficava o ícone e um "−".
 * Então elas descem e podem quebrar. Uma linha a mais numa barra que já tem
 * três é mais barato do que esconder uma fraqueza.
 */
.arena-elementos {
  display: flex; flex-wrap: wrap; gap: 4px;
  overflow: visible; margin-bottom: 4px;
}
.arena-elementos .boss-el { padding: 0 4px 0 2px; font-size: 9px; }
.arena-elementos .boss-el img { width: 11px; height: 11px; }

/*
 * ---- O botão de loot, e a grade que ele abre ----
 *
 * "e o ícone de loot que mostraria o que eles dropa".
 *
 * A pilha inteira é `pointer-events: none` para não engolir o clique de quem
 * está mirando num bicho. São o botão e a grade que voltam a aceitar o dedo, e
 * só eles.
 *
 * A grade fica pendurada FORA da linha: a barra de vida tem de continuar do
 * tamanho de uma barra de vida, e quarenta itens dentro dela desfariam isso.
 */
.arena-loot-botao, .arena-loot-caixa { pointer-events: auto; }
.arena-loot-botao {
  flex: none; cursor: pointer; padding: 3px 9px; border-radius: 7px;
  background: #ffffff0d; border: 1px solid #8c3a4299; color: #ffc9a8;
  font-family: var(--font-heading); font-size: 9px; letter-spacing: .1em;
  text-transform: uppercase;
  transition: border-color .15s ease, color .15s ease, background .15s ease;
}
.arena-loot-botao:hover, .arena-loot-botao.aberto {
  background: #ff6a4d26; border-color: #ff8a6d; color: #fff0e6;
}
.arena-loot-caixa {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 2;
  width: min(330px, 86vw); max-height: 46vh; overflow-y: auto;
  padding: 9px 10px; border-radius: 10px;
  background: #100a09f7; border: 1px solid #7a2f36;
  box-shadow: 0 14px 34px #000000c4;
}
.arena-loot-caixa[hidden] { display: none; }
.arena-loot-caixa b {
  display: block; margin-bottom: 7px;
  font-family: var(--font-heading); font-size: 10.5px; letter-spacing: .07em;
  text-transform: uppercase; color: #ffb9a6; text-shadow: none;
}
.arena-loot-caixa .bag { gap: 4px; }
.arena-loot-caixa .empty { margin: 0; font-size: 11.5px; }
/* Mais baixo que o trilho da sala: são várias linhas empilhadas. */
.arena-trilho { height: 13px; border-radius: 7px; }
.arena-cheio {
  position: relative; display: block; height: 100%; width: 100%;
  background: linear-gradient(180deg, #ff6b5e, #b81f2c 60%, #7d101c);
  box-shadow: inset 0 1px 0 #ffffff40;
  transition: width .22s linear, background .4s linear;
}
.arena-pct {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-size: 9.5px; font-weight: 700; color: #fff; letter-spacing: .04em;
  text-shadow: 0 1px 2px #000, 0 0 6px #0008; font-variant-numeric: tabular-nums;
}
/* O mesmo aviso da barra de cima: abaixo de um terço a luta está virando. */
.arena-boss.aperto { border-color: #b06a2a; box-shadow: 0 6px 20px #000a, 0 0 18px #d9631a4d; }
.arena-boss.aperto .arena-cheio { background: linear-gradient(180deg, #ffb057, #d9631a 60%, #8a3a08); }

/* ---------------------------------------------------------------------------
 * O cartaz do boss que acabou de nascer
 *
 * "bem bonito com o icone de boss e dps desaparece apos 10 segundos".
 *
 * ---- Por que ele NAO e' mais uma faixa do alto ----
 *
 * As faixas de cima (novidades, auto boss, server save) sao ESTADOS: ficam
 * enquanto a coisa dura, e por isso vivem fora do caminho, coladas na barra.
 * Este e' um ACONTECIMENTO — aconteceu uma vez, dura dez segundos, e se passar
 * batido nao adiantou nada. Entao ele nasce no meio do campo de batalha, que e'
 * onde os olhos ja' estao.
 *
 * ---- E por que ele nao aceita clique ----
 *
 * `pointer-events: none`. Ele nasce por cima do mapa sem aviso nenhum, e um
 * cartaz que engole o clique de quem estava mirando num bicho e' pior do que
 * nao avisar.
 * ------------------------------------------------------------------------- */
/*
 * ---- Centrado por LAYOUT, e nao por `transform` ----
 *
 * "o card do boss na area que informa que o boss apareceu na area ta meio
 *  borrado".
 *
 * A culpa era do `left: 50%` com `translateX(-50%)`. Numa largura impar — e a
 * do cartaz muda com o nome do boss — os -50% caem em meio pixel, e o
 * navegador desenha o cartaz inteiro fora da grade de pixels: a fonte serifada
 * do nome e as bordas de 1px saem lavadas.
 *
 * `inset-inline: 0` mais `margin-inline: auto` centra pelo mesmo caminho de uma
 * margem automatica qualquer, sem transform nenhum no estado final — e o texto
 * volta a cair em cima do pixel.
 */
#cartaz-boss {
  position: fixed; z-index: 45; pointer-events: none;
  top: calc(var(--altura-da-topbar) + var(--altura-do-aviso, 0px) + 8px);
  inset-inline: 0; margin-inline: auto; width: max-content;
  display: flex; align-items: center; gap: 10px;
  max-width: min(400px, 92vw); padding: 8px 30px 8px 9px;
  background: linear-gradient(160deg, #3a1410 0%, #24100c 55%, #140807 100%);
  border: 1px solid #a33228; border-radius: 11px;
  box-shadow: 0 12px 32px #000000b3, inset 0 1px 0 #ff9a9126, 0 0 26px #a3322833;
  animation: cartaz-boss-entra .55s cubic-bezier(.2, .9, .25, 1) both;
}
#cartaz-boss[hidden] { display: none; }

/* A moldura do desenho: o bicho precisa de um fundo proprio, ou ele se perde
   no gradiente vermelho do cartaz. */
#cartaz-boss .arte {
  flex: none; width: 50px; height: 50px; display: grid; place-items: center;
  overflow: hidden;
  background: #0a0605b8; border: 1px solid #a3322866; border-radius: 9px;
}
#cartaz-boss .arte canvas { image-rendering: pixelated; max-width: 100%; max-height: 100%; }

#cartaz-boss .dizeres { display: grid; gap: 1px; min-width: 0; }
#cartaz-boss .selo {
  justify-self: start; padding: 1px 8px; border-radius: 999px;
  background: #ff6a4d1f; border: 1px solid #ff8a6d;
  font-family: var(--font-heading); font-size: 8.5px; letter-spacing: .13em;
  text-transform: uppercase; color: #ffb9a6;
}
/* O NOME e' o que a pessoa tem de levar da tela; o resto e' moldura. */
#cartaz-boss b {
  font-family: var(--font-title); font-size: 15px; line-height: 1.2;
  color: #ffe0b0; text-shadow: 0 2px 8px #00000099, 0 0 14px #c8823c40;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/*
 * A frase quebra em DUAS linhas em vez de ser cortada no meio.
 *
 * Com o cartaz encolhido e os dois botoes ocupando a direita, uma linha so'
 * terminava em "apareceu na area de Bo...". O nome do boss ja' esta' logo
 * acima, entao o que se perdia era o fim da frase — e um aviso que termina em
 * reticencias parece um aviso que quebrou.
 */
#cartaz-boss .resumo {
  font-size: 11px; line-height: 1.3; color: #f0c2b6;
  font-family: "Segoe UI", system-ui, sans-serif;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}

/*
 * ---- Os dois botoes ----
 *
 * O cartaz inteiro e' `pointer-events: none` para nao engolir o clique de quem
 * estava mirando num bicho. Sao ESTES dois — e a caixa do loot — que voltam a
 * aceitar o dedo, e so' eles: e' a area minima que o pedido precisa.
 */
#cartaz-boss .loot-botao, #cartaz-boss .fecha, #cartaz-boss .loot-caixa { pointer-events: auto; }

#cartaz-boss .loot-botao {
  flex: none; align-self: center; cursor: pointer;
  padding: 5px 11px; border-radius: 8px;
  background: #ffffff0d; border: 1px solid #a3322899; color: #ffc9a8;
  font-family: var(--font-heading); font-size: 10px; letter-spacing: .1em;
  text-transform: uppercase;
  transition: border-color .15s ease, color .15s ease, background .15s ease;
}
#cartaz-boss .loot-botao:hover, #cartaz-boss .loot-botao.aberto {
  background: #ff6a4d26; border-color: #ff8a6d; color: #fff0e6;
}
#cartaz-boss .loot-botao[hidden] { display: none; }

/* No canto, pequeno e apagado: ele e' a saida, e nao o assunto. */
#cartaz-boss .fecha {
  position: absolute; top: 5px; right: 6px; cursor: pointer;
  width: 18px; height: 18px; padding: 0; line-height: 1;
  display: grid; place-items: center; border-radius: 6px;
  background: none; border: 1px solid transparent; color: #b98a7e; font-size: 11px;
}
#cartaz-boss .fecha:hover { border-color: #a33228; color: #ffd0c6; background: #ffffff0d; }

/*
 * ---- A caixa do loot ----
 *
 * Pendurada EMBAIXO do cartaz, e nao dentro dele: o cartaz e' pequeno de
 * proposito agora, e uma tabela de quarenta itens dentro dele desfaria isso.
 * Assim ele continua do tamanho que e' e a lista aparece so' quando se pede.
 */
#cartaz-boss .loot-caixa {
  position: absolute; top: calc(100% + 7px); right: 0;
  width: min(330px, 86vw); max-height: 46vh; overflow-y: auto;
  padding: 9px 10px; border-radius: 10px;
  background: #100a09f7; border: 1px solid #7a2f36;
  box-shadow: 0 14px 34px #000000c4;
  animation: cartaz-boss-loot .18s ease both;
}
#cartaz-boss .loot-caixa[hidden] { display: none; }
#cartaz-boss .loot-caixa b {
  display: block; margin-bottom: 7px;
  font-family: var(--font-heading); font-size: 10.5px; letter-spacing: .07em;
  text-transform: uppercase; color: #ffb9a6; text-shadow: none; white-space: normal;
}
#cartaz-boss .loot-caixa .bag { gap: 4px; }
#cartaz-boss .loot-caixa .empty { margin: 0; font-size: 11.5px; }
@keyframes cartaz-boss-loot {
  from { opacity: 0; transform: translateY(-5px); }
  to { opacity: 1; transform: translateY(0); }
}

/*
 * Entra SUBINDO, e nao descendo como o `cartaz-entra`: aquele vem da barra de
 * cima, que e' de onde vem o assunto dele. Este vem do campo de batalha.
 *
 * So' no eixo Y, e terminando em `none`: um `transform` que sobra no estado
 * final — mesmo um `scale(1)` — mantem o cartaz numa camada propria e desfaz o
 * conserto do borrado logo acima.
 */
@keyframes cartaz-boss-entra {
  from { opacity: 0; transform: translateY(16px) scale(.96); }
  to { opacity: 1; transform: none; }
}
/* Os dez segundos acabaram: some devagar, e so' entao o `hidden` volta. */
#cartaz-boss.saindo {
  opacity: 0; transform: translateY(-10px);
  transition: opacity .6s ease, transform .6s ease;
  animation: none;
}
@media (prefers-reduced-motion: reduce) {
  #cartaz-boss { animation: none; }
  #cartaz-boss.saindo { transition: opacity .3s linear; transform: none; }
}

/* Com a faixa de novidades na tela, esta desce para nao cobri-la. */
body.com-novidades #faixa-serversave { top: calc(var(--altura-da-topbar) + var(--altura-do-aviso, 0px) + 30px); }
/* E a do Auto Boss desce mais um degrau quando as duas aparecem juntas. */
body.com-serversave #faixa-autoboss { top: calc(var(--altura-da-topbar) + var(--altura-do-aviso, 0px) + 30px); }
body.com-serversave.com-novidades #faixa-autoboss { top: calc(var(--altura-da-topbar) + var(--altura-do-aviso, 0px) + 60px); }

/* O cartaz de beta desce para nao nascer debaixo da placa; o HUD fica onde
   estava, porque a placa e' centrada e nao passa por cima dele. */
body.com-novidades #cartaz-beta { top: calc(var(--altura-da-topbar) + var(--altura-do-aviso, 0px) + 14px + 30px); }

/* ---------- a lista dentro do modal ---------- */

.novidades-lista { margin: 0; padding-left: 20px; display: grid; gap: 9px; }
.novidades-lista li { font-size: 13px; line-height: 1.55; color: var(--text); }
.novidades-quando { margin: 0 0 12px; font-size: 12px; color: var(--muted); }

/*
 * As publicações anteriores, dobradas embaixo da lista nova.
 *
 * Fechadas por padrão: a pergunta que traz a pessoa a esta caixa é "o que mudou
 * agora", e o histórico não pode empurrar a resposta para fora da tela.
 */
.novidades-antigas { margin-top: 14px; border-top: 1px solid var(--line); padding-top: 10px; }
.novidades-antigas > summary {
  cursor: pointer; font-family: var(--font-heading); font-size: 12px;
  letter-spacing: .05em; color: var(--muted); list-style: none;
}
.novidades-antigas > summary::-webkit-details-marker { display: none; }
/* O triângulo é nosso, para virar junto com o estado sem depender do padrão. */
.novidades-antigas > summary::before { content: '▸ '; display: inline-block; transition: transform .15s ease; }
.novidades-antigas[open] > summary::before { content: '▾ '; }
.novidades-antigas > summary:hover { color: var(--text); }
.novidades-antigas .novidades-lista { margin-top: 10px; }
.novidades-antigas .novidades-lista li { color: var(--muted); font-size: 12px; }
/*
 * ---- As ações da janela de novidades, no TOPO e coladas lá ----
 *
 * Elas eram um rodapé, e o rodapé desta janela fica depois da lista nova e de
 * trinta e cinco publicações anteriores: dizer "já li" custava rolar tudo o que
 * a pessoa acabou de decidir não ler. Ver o report em `abrirNovidades`.
 *
 * O fundo é opaco de propósito — o texto passa POR BAIXO dela ao rolar, e sem
 * ele as duas camadas se misturariam. E a linha embaixo separa a barra do
 * conteúdo que desliza sob ela.
 */
.novidades-acoes {
  position: sticky; top: 0; z-index: 2;
  display: flex; align-items: center; justify-content: flex-end; gap: 10px;
  margin: -4px 0 12px; padding: 8px 0 10px;
  background: var(--panel); border-bottom: 1px solid var(--line);
}

/*
 * ---- A altura da barra de cima, como variavel ----
 *
 * Ela era 62 escrito a mao em quatro lugares: a faixa de obra, o cartaz de
 * beta e o HUD se penduravam nesse numero. Com a barra podendo RECOLHER, o
 * numero passou a ter dois valores, e quatro copias de um numero que muda e'
 * o comeco de tres deles ficarem para tras.
 */
:root { --altura-da-topbar: 62px; }
body.topbar-recolhida { --altura-da-topbar: 26px; }

#hud { top: calc(var(--altura-da-topbar) + 10px + var(--altura-do-aviso, 0px)); }

/*
 * ---- Recolher a barra de cima ----
 *
 * A de baixo ja' recolhia; esta nao tinha como sair da frente. Numa tela
 * baixa sao 62px de cromo permanente por cima do mapa.
 *
 * Some tudo menos a seta, e a barra vira uma fita de 26px encostada no alto —
 * do mesmo jeito que a de baixo vira uma fita quando recolhida. A seta e' o
 * unico pedaco que fica: recolher sem deixar como voltar seria trancar a loja,
 * o banco e o "sair da conta" atras de um clique sem volta.
 */
#topbar-min {
  margin-left: auto; flex: none;
  width: 26px; height: 20px; padding: 0;
  background: #0000004d; border: 1px solid var(--line); border-radius: 5px;
  color: var(--muted); font-size: 10px; line-height: 1; cursor: pointer;
}
#topbar-min:hover { color: #fff; border-color: var(--line-strong, var(--line)); }
body.topbar-recolhida #topbar > *:not(#topbar-min) { display: none; }
body.topbar-recolhida #topbar { padding: 0 8px; justify-content: flex-end; }
body.topbar-recolhida #topbar-min { transform: rotate(180deg); }

#topbar {
  position: fixed; top: 0; left: 0; right: 0; height: var(--altura-da-topbar); z-index: 30;
  /* 16px de respiro entre cinco blocos são 80px que a fileira de ícones não
     tem para dar numa tela de 1920 — era parte do que empurrava "Sair" para
     fora. O espaço voltou para os botões, que é onde ele conta. */
  display: flex; align-items: center; gap: 6px; padding: 0 8px;
  background: linear-gradient(180deg, #0d1214f7, #0d1214d9);
  border-bottom: 1px solid var(--line);
}
/* A marca da topbar é a mesma logo, só que na altura da barra. */
.brand { height: 34px; width: auto; display: block; flex: none; user-select: none; -webkit-user-drag: none; }
@media (max-width: 600px) { .brand { height: 22px; } }
.identity { display: flex; align-items: center; gap: 9px; }
.identity #portrait { display: block; width: 34px; height: 34px; }
.identity #portrait canvas { width: 34px; height: 34px; }
.identity strong { display: block; font-size: 13px; letter-spacing: .05em; }
.identity span { color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: .05em; }
.identity em {
  font-style: normal; font-size: 11px; color: var(--accent);
  border: 1px solid var(--accent-dim); border-radius: 999px; padding: 1px 8px;
}
.wallets { display: flex; gap: 10px; margin-left: 4px; flex: none; }
.wallet { display: flex; align-items: center; gap: 6px; font-size: 15px; }
.wallet .coin-icon { width: 22px; height: 22px; image-rendering: pixelated; display: inline-flex; }
.wallet .coin-icon canvas { width: 22px; height: 22px; }
.online { color: var(--muted); font-size: 14px; display: flex; align-items: center; gap: 5px; margin-left: 8px; flex: none; }
.online i { width: 7px; height: 7px; border-radius: 50%; background: var(--hp); }
.online b { color: var(--text); }

/* Folga maior desde que a caixa saiu: sem a moldura para separá-los, 4px
   deixavam os halos se encostando e os ícones viravam uma mancha só. */
/* Sem `margin-left: auto`: as ferramentas correm logo depois do mercado, e o
   banco fecha o grupo do dinheiro encostado nele. Empurradas para a direita da
   tela, sobrava um vão de duzentos pixels entre um e outro. */
/* `flex: 1` para o grupo poder empurrar sair/trocar até a borda: sem largura
   para dar, o `margin-left: auto` do último respiro não teria o que ocupar. */
/* 2px encostavam a legenda de um na do vizinho — "Profic." e "Imbuem." viravam
   uma linha de texto só. O respiro é o que separa as colunas. */
/*
 * ---- O ritmo da fileira ----
 *
 * O espaço que sobrava ia todo para um lugar só: o último separador tinha
 * `margin-left: auto` e engolia a folga inteira, abrindo um vão de duzentos
 * pixels entre a última ferramenta e o Sair enquanto os outros ícones ficavam
 * espremidos a 3px um do outro. Dava uma fileira com dois ritmos.
 *
 * Com `space-between` a folga se reparte igualmente entre TODOS os botões, da
 * primeira ferramenta até o Sair encostado na direita. O `gap` vira o piso —
 * o mínimo que dois ícones podem ficar um do outro quando a tela aperta — e os
 * separadores de grupo continuam existindo, só que agora como um respiro a
 * mais, e não como o único respiro.
 *
 * A placa da Mineiroidle Store fica fora disto: ela é do bloco da esquerda.
 */
.tools {
  margin-left: 4px; display: flex; gap: 3px; align-items: flex-start;
  flex: 1; min-width: 0; justify-content: space-between;
  /*
   * ---- A fileira ROLA em vez de cortar ----
   *
   * São vinte e um botões. Medindo (`tools/test-resolucao.mjs`), em 1366x768 —
   * o notebook mais comum do mundo — cinco deles ficavam do lado de fora da
   * tela: Loot, Chat, Análise, Opções e Sair. Não sumiam do DOM nem davam erro;
   * simplesmente estavam além da borda direita, e de dentro de um monitor
   * grande não havia como ver isso. Em 1024x640 eram doze.
   *
   * Com `overflow-x: auto` o que não cabe continua ALCANÇÁVEL: rola com a roda
   * do mouse, com o dedo no celular, com Tab no teclado. É a diferença entre
   * "não cabe" e "não existe".
   *
   * A barra de rolagem é fina e escura de propósito — ela precisa aparecer (é o
   * que diz que há mais coisa ali) sem virar um traço branco atravessando a
   * barra de cima.
   */
  overflow-x: auto; overflow-y: hidden;
  scrollbar-width: thin; scrollbar-color: var(--line-strong, var(--line)) transparent;
  /* Rolar com o dedo sem que o navegador ache que é gesto de página. */
  touch-action: pan-x;
  overscroll-behavior-x: contain;
}
.tools::-webkit-scrollbar { height: 4px; }
.tools::-webkit-scrollbar-track { background: transparent; }
.tools::-webkit-scrollbar-thumb { background: var(--line); border-radius: 999px; }
.tools::-webkit-scrollbar-thumb:hover { background: var(--accent-dim, var(--accent)); }
/* Os separadores encolhem junto: eles marcam grupos, não ocupam espaço. */
.tools .divider { align-self: center; }
/*
 * Sem caixa: só a arte e um halo.
 *
 * A moldura escura em volta de cada um brigava com a própria arte, que já vem
 * com contorno e volume — eram dois quadrados, o do desenho e o do botão, em
 * tons diferentes. O halo verde faz o mesmo trabalho de dizer "isto é um
 * botão" sem desenhar nada por cima.
 *
 * Ele é `drop-shadow` e não `box-shadow` porque segue os pixels pintados: o
 * brilho contorna o elmo, o pergaminho, o troféu — e não um retângulo.
 */
.tools button {
  background: none; border: none; border-radius: 7px;
  padding: 2px; cursor: pointer; font-size: 13px; display: grid; place-items: center;
  width: 46px; height: 46px;
  /*
   * Parado o halo é curto e discreto — um contorno, não uma luz. A 3px e 33%
   * ele vazava para fora do desenho, os halos vizinhos se encontravam no meio
   * do caminho e a barra inteira ficava embaçada de verde. O brilho de verdade
   * é do hover; aqui embaixo ele só destaca a silhueta do fundo escuro.
   */
  filter: drop-shadow(0 0 1px #0a0d0f) drop-shadow(0 0 4px #3fbfa877);
  transition: filter .16s ease, transform .16s ease;
}
.tools button:hover {
  color: #fff;
  filter: drop-shadow(0 0 4px #3fbfa8) drop-shadow(0 0 11px #3fbfa877);
  transform: scale(1.14);
}
.tools button:active { transform: scale(1.05); }
/* Ícone de arte é reduzido, não ampliado: nearest-neighbour aqui serrilha. */
.tools button .icon { width: 30px; height: 30px; display: block; image-rendering: auto; object-fit: contain; }
.tools button.fallback .icon { width: 22px; height: 22px; image-rendering: pixelated; }

/*
 * O nome embaixo do ícone.
 *
 * Sem ele a barra era uma fileira de doze desenhos que só se explicavam no
 * hover — e quem está aprendendo o jogo não passa o mouse por doze coisas para
 * achar o banco. Cada botão ganha largura fixa: com largura automática, os
 * nomes compridos empurravam os vizinhos e a fileira ficava desalinhada.
 *
 * O zoom do hover sai daqui e vira só o halo: uma coluna com texto crescendo
 * 14% embaralha as legendas das vizinhas.
 */
/*
 * 56px, e não 62.
 *
 * São dezoito colunas agora (as dezessete de antes mais Opções), e a 62 elas
 * somavam mais do que a barra tem para dar numa tela de 1920: "Análise" e
 * "Sair" ficavam para fora da borda direita, e o jogo perdia o botão de sair.
 * A conta que sobra: 18×56 mais os respiros cabem com folga, e a legenda de
 * duas sílabas ainda entra sem reticências.
 */
.tools button {
  display: flex; flex-direction: column; align-items: center; justify-content: flex-start;
  /*
   * 52px, e não 56.
   *
   * Medido em 1920x1080: com 56 a fileira pedia 1325px e tinha 1283 — os
   * quatro últimos botões (entre eles o de sair) ficavam do lado de fora por
   * 42px. Quatro pixels a menos em cada um resolvem a conta com folga, e a
   * diferença não se vê.
   */
  /*
   * ---- E agora a largura ENCOLHE até tudo caber ----
   *
   * 52 era o número fixo que fechava a conta de 1920 com dezoito colunas. Toda
   * coluna nova (a Forja é a dezenove) refazia essa conta à mão, e a resposta
   * dependia do monitor de quem estava medindo — em 1366 nunca coube.
   *
   * Agora o número é medido no navegador de quem joga: `caberNaBarra`, em
   * main.mjs, divide a largura que sobrou pelo número de botões e escreve o
   * resultado aqui. Fica em 52 quando cabe, e desce até 34 quando não cabe.
   * Abaixo disso a legenda deixa de ser legível e a rolagem continua sendo a
   * saída — mas é preciso um monitor muito estreito para chegar lá.
   */
  gap: 3px; width: var(--largura-do-botao, 52px); height: auto; padding: 3px 0 2px; flex: none;
}
/* O desenho encolhe junto: um ícone de 30 num botão de 34 não teria margem. */
.tools button .icon { width: var(--tamanho-do-icone, 30px); height: var(--tamanho-do-icone, 30px); }
/*
 * Fileira apertada: fica só o desenho.
 *
 * Vale mais um botão inteiro sem nome do que meio botão com nome — e o balão do
 * hover continua dizendo o que cada um faz. Ver `LARGURA_COM_LEGENDA`, em
 * main.mjs, que é quem liga esta classe.
 */
.tools.sem-legenda button .label { display: none; }
.tools.sem-legenda button { padding: 4px 0; }
/* O mercado acompanha, e ele mora fora da fileira. Ver `barra-enxuta`. */
body.barra-enxuta #market-button .label { display: none; }
.tools button .label {
  display: block; width: 100%; text-align: center;
  font-size: 9px; line-height: 1.15; letter-spacing: 0.01em; color: #6d7f86;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tools button:hover { transform: none; }
.tools button:active { transform: none; }
.tools button:hover .label { color: var(--accent); }
.tools [data-tool][aria-selected='true'] .label { color: var(--accent); }
.tools button:disabled .label { color: #2f3a3e; }
/*
 * Janela aberta: o halo fica aceso o tempo todo, sem o zoom do hover.
 *
 * Vale para os dois tipos — a aba, que abre janela flutuante, e o botão que
 * abre modal. Antes só as abas acendiam, e com o bestiary aberto o ícone dele
 * ficava igual ao dos fechados.
 */
.tools .toggle[aria-selected="true"],
.tools [data-tool][aria-selected="true"] {
  filter: drop-shadow(0 0 1px #0a0d0f) drop-shadow(0 0 4px #3fbfa8cc);
}
/*
 * Ponto para gastar: o facho dourado dá voltas em torno do ícone.
 *
 * É o mesmo anel da placa da Mineiroidle Store, e pela mesma razão: um halo que pulsa
 * some contra um fundo qualquer, enquanto uma luz que anda o olho pega mesmo de
 * canto. Aqui ele contorna o quadrado do botão — o gradiente cônico é recortado
 * em anel pela máscara, e o ângulo é animado por `@property`, sem o qual o
 * navegador não interpola gradiente cônico.
 */
.tools button { position: relative; }
.tools button.alerta::after {
  content: ""; position: absolute; inset: -2px; border-radius: 9px; padding: 2px; pointer-events: none;
  background: conic-gradient(from var(--store-angle), transparent 0%, #ffd980 8%, #fff6d0 12%, #ffd980 16%, transparent 26%, transparent 100%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  animation: store-orbit 3s linear infinite;
}
/* E um dourado fraco por baixo, para o ícone não ficar frio dentro do anel. */
.tools button.alerta { filter: drop-shadow(0 0 1px #0a0d0f) drop-shadow(0 0 5px #d9ae4a66); }
.tools button.alerta:hover {
  filter: drop-shadow(0 0 4px #ffd980) drop-shadow(0 0 11px #d9ae4a99);
}

/* Ação que não cabe agora — voltar para a cidade estando nela. */
.tools button:disabled { cursor: default; opacity: .35; filter: grayscale(.6); }
.tools button:disabled:hover { transform: none; filter: grayscale(.6); }
/*
 * Quem pede menos movimento perde a transição, não o zoom.
 *
 * Tirar o `transform` aqui matava o aumento no hover para todo mundo com
 * "animações" desligado no Windows — e um estado que muda na hora não é
 * animação, é o botão respondendo.
 */
@media (prefers-reduced-motion: reduce) {
  .tools button { transition: none; }
}
/*
 * Tela estreita: primeiro encolhem os respiros, depois os ícones.
 *
 * São dezessete botões mais a placa da loja e as carteiras; abaixo de 1800 isso
 * não cabe em 46px cada. Encolher é melhor que deixar o "sair da conta"
 * escapar pela borda direita, que foi o que aconteceu ao medir em 1656.
 */
/*
 * Encolher é só a LARGURA e o desenho — nunca a altura.
 *
 * Estes dois blocos vinham de antes de o nome existir embaixo do ícone e ainda
 * mandavam `height: 38px`. Como a altura da coluna é o ícone mais a legenda, o
 * valor fixo cortava a legenda fora: numa tela de 1656px de largura — que é a
 * mais comum aqui — a barra inteira ficava sem nome nenhum, e o nome estava lá,
 * escondido atrás da borda do botão.
 *
 * Agora a altura continua `auto` nos dois degraus e quem cede espaço é a
 * largura da coluna. O respiro entre ícones cresce em vez de encolher: a
 * legenda precisa de um vão para não encostar na do vizinho, e é ela que
 * separa um botão do outro agora que a moldura saiu.
 */
/*
 * ---- Os degraus fixos de largura saíram ----
 *
 * Eram quatro: 48px abaixo de 1800, 36 abaixo de 1500, 30 abaixo de 1400 e 30
 * de novo abaixo de 1300. Cada um veio de uma medição feita à mão num monitor
 * só, e cada botão novo na fileira invalidava os quatro ao mesmo tempo — o
 * comentário de um deles ainda fala em "21 botões", de quando eram 21.
 *
 * Quem decide a largura agora é `caberNaBarra`, em main.mjs: ele mede o quanto
 * a fileira está passando do lugar (`scrollWidth - clientWidth`) e encolhe até
 * caber, no monitor de quem está jogando. Um degrau fixo aqui embaixo brigaria
 * com ele — foi o que aconteceu enquanto os dois existiam: a variável dizia 36
 * e o botão saía com 30, porque a regra de `@media` vinha depois na folha.
 *
 * O que continua aqui é o que é DE VIEWPORT de verdade: o respiro entre os
 * botões e a largura dos separadores, que não dependem de quantos botões há.
 */
@media (max-width: 1800px) {
  .tools { gap: 2px; }
  .tools .divider { width: 8px; }
  .tools .divider:last-of-type { width: 14px; }
  .tools button .label { font-size: 8px; }
}
@media (max-width: 1500px) {
  .tools { gap: 1px; }
  .tools .divider { width: 5px; }
  .tools .divider:last-of-type { width: 10px; }
  .tools button .label { font-size: 7px; }
}
/*
 * ---- Abaixo de 1200: primeiro o texto, depois a companhia ----
 *
 * Os dois degraus acima param em 1500 e o mundo não. Medido, um notebook de
 * 1366 já perdia cinco botões pela borda; um de 1024, doze. A rolagem lateral
 * acima resolve o "não dá para alcançar", mas rolar para achar o botão de sair
 * é pior do que ele estar à vista — então antes de rolar vale espremer.
 *
 * A ordem do que cede é deliberada, do menos útil para o mais:
 *
 *   1200 .. a LEGENDA sai. O ícone é o que a mão procura; o nome embaixo é
 *           ajuda de quem está aprendendo, e cabe no balão do hover.
 *   1000 .. o NOME e a VOCAÇÃO do personagem saem da barra. Eles estão no card
 *           do personagem, a um clique — repetidos aqui só por conforto.
 *    820 .. a MARCA sai. Ninguém precisa da logo para jogar, e ela é 34px de
 *           largura que valem quase um botão.
 *
 * O que nunca sai: os botões, o retrato (é o alvo de clique do personagem) e as
 * carteiras. Esconder dinheiro de alguém é diferente de esconder enfeite.
 */
@media (max-width: 1400px) {
  /*
   * A LEGENDA sai antes dos ícones.
   *
   * O ícone é o que a mão procura; o nome embaixo é ajuda de quem está
   * aprendendo, e continua no balão do hover. Medido: com legenda, 21 botões
   * pedem 981px, e um notebook de 1366 só tem 743 para dar.
   */
  /*
   * A largura e o ícone saíram daqui: ver a nota dos degraus, acima. A legenda
   * também — quem a esconde é a classe `sem-legenda`, ligada quando o botão
   * fica estreito de verdade, e não quando a JANELA fica estreita. Um monitor
   * de 1380 com sete botões tem espaço de sobra para as legendas.
   */
  .tools .divider { width: 4px; }
  #market-button { width: 30px; }
  #market-button .label { display: none; }
}
/*
 * ---- Abaixo de 1300 a companhia da barra também cede ----
 *
 * Medido, os vizinhos da fileira de botões comem 545px fixos: a marca (85), as
 * carteiras (190), o "online" (20), a placa da loja (182), o mercado (42) e a
 * seta de recolher (26). Com 21 botões de 30px pedindo 720px, é isso que
 * decide se cabe — e não o tamanho dos ícones, que já estão no mínimo.
 *
 * A placa da loja é a maior peça e a primeira a encolher: ela é um cartaz, e um
 * cartaz menor continua sendo um cartaz. Depois saem a marca e o "online", que
 * são enfeite. O retrato e as carteiras ficam: esconder o dinheiro de alguém é
 * diferente de esconder enfeite.
 */
@media (max-width: 1300px) {
  #store-button img { height: 30px; }
  .brand { display: none; }
  .online { display: none; }
  .identity strong, .identity span, .identity em { display: none; }
  .identity { gap: 0; }
  .wallets { gap: 6px; margin-left: 0; }
  .wallet { font-size: 13px; }
  .wallet .coin-icon, .wallet .coin-icon canvas { width: 18px; height: 18px; }
  #topbar { gap: 4px; padding: 0 4px; }
  .tools { margin-left: 0; }
}
/*
 * ---- Abaixo de 1050 a barra vira DUAS linhas ----
 *
 * Aqui acaba o que dá para espremer: em 360px de largura os vizinhos sozinhos
 * (362px) já não cabem, e a fileira de botões ficava com largura ZERO — os
 * vinte e um botões existiam e nenhum aparecia. Foi o que a medição mostrou.
 *
 * Com a quebra, a primeira linha leva o personagem, o dinheiro e a loja; a
 * segunda é a fileira inteira, rolando de lado com o dedo. A barra fica mais
 * alta, e `--altura-da-topbar` é quem avisa o HUD disso — o resto do layout se
 * penduro nela justamente para casos assim.
 */
@media (max-width: 1050px) and (min-height: 520px) {
  :root { --altura-da-topbar: 92px; }
  #topbar { flex-wrap: wrap; height: var(--altura-da-topbar); align-content: center; row-gap: 2px; }
  .tools { order: 9; flex: 1 0 100%; width: 100%; justify-content: flex-start; }
  /* Recolhida, a barra volta a ser uma fita: a fileira some junto com o resto. */
  body.topbar-recolhida { --altura-da-topbar: 26px; }
}
/*
 * ---- Tela BAIXA: a barra não pode virar duas linhas ----
 *
 * Um celular deitado tem 360px de altura. Trinta deles a mais de barra fixa é
 * quase um décimo da tela, e a tela é onde o jogo acontece. Aqui a fileira fica
 * numa linha só e rola de lado — o dedo já sabe fazer isso, e a altura é o
 * recurso escasso, não a largura.
 */
@media (max-height: 520px) {
  :root { --altura-da-topbar: 54px; }
  #topbar { flex-wrap: nowrap; }
  /*
   * Aqui a largura CONTINUA fixa, e é o único lugar em que ela deve continuar.
   *
   * Nos outros degraus quem manda é a medição (`caberNaBarra`); neste, o que
   * está apertado é a ALTURA — 360px de tela deitada —, e o botão precisa ficar
   * baixo, não estreito. A medição só sabe encolher pela largura, então a
   * altura pede uma regra própria.
   */
  .tools button { padding: 2px 0; }
  .tools button .label { display: none; }
  #store-button img { height: 26px; }
  .brand, .online { display: none; }
  .identity strong, .identity span, .identity em { display: none; }
}

/*
 * ---- Celular e tablet: a janela ocupa a tela ----
 *
 * Os painéis do jogo são janelas flutuantes com moldura, e a moldura sozinha
 * come 50px em cima e 30 de cada lado. Num aparelho de 360px de largura sobram
 * 300 para o conteúdo, e a moldura passa a ser a maior parte do que se vê.
 *
 * Abaixo de 900px a janela encosta nas bordas e a moldura afina. O respiro de
 * baixo é `safe-area-inset-bottom`: é a faixa da barra de gestos do Android, e
 * sem ela o último botão da janela fica embaixo dela.
 */
@media (max-width: 900px), (max-height: 540px) and (pointer: coarse) {
  .modal-box {
    width: 100vw; max-width: 100vw; max-height: 100dvh;
    border-width: 34px 12px 16px 12px;
  }
  #modal { padding: 0; place-items: stretch; }
  #modal-body { padding: 4px 4px calc(4px + env(safe-area-inset-bottom, 0px)); }
  .modal-box.store, .modal-box.imbue { width: 100vw; }
  /* A grade de quatro colunas não cabe: duas, e os cards continuam legíveis. */
  .store-grid, .train-grid { grid-template-columns: repeat(2, 1fr) !important; }
  .store-layout { grid-template-columns: 1fr !important; display: block !important; }
  .store-sections { display: flex; overflow-x: auto; gap: 4px; margin-bottom: 8px; }
  .store-sections button { flex: none; white-space: nowrap; }
}
/*
 * O respiro entre grupos é espaço, e um pontinho.
 *
 * Era um traço (`height: 1px` com fundo), e com quinze ícones desenhados ele
 * virava mais uma linha para o olho tropeçar — por isso tinha sido apagado. Um
 * ponto de três pixels no meio do vão faz o mesmo trabalho de dizer "aqui
 * começa outro grupo" sem cortar a fileira: ele se lê como pausa, não como
 * divisória.
 */
.tools .divider {
  width: 14px; height: 34px; background: none; margin: 0; flex: none;
  display: flex; align-items: center; justify-content: center;
}
.tools .divider::before {
  content: ''; width: 3px; height: 3px; border-radius: 50%;
  background: var(--accent); opacity: .45;
  box-shadow: 0 0 4px #3fbfa866;
}
/*
 * Trocar de personagem e sair encostam na direita da tela: eles não abrem nada
 * do jogo, saem dele, e ficam longe do resto de propósito. O vão extra à
 * esquerda deles é o lugar do botão de opções.
 */
/* Sem `margin-left: auto`: quem espalha a fileira agora é o `space-between` do
   `.tools`, e o último separador é só o respiro do grupo de sair. */
.tools .divider:last-of-type { width: 18px; }

/* ---------- HUD superior esquerdo ---------- */

/*
 * ---- O topo do card, como variavel ----
 *
 * Era `72px` escrito a mao aqui, e passou a ter tres leitores: o card, o
 * contador de FPS (que nasce exatamente onde o card comeca) e o calculo que
 * empurra o card para baixo quando o contador aparece. Tres copias de um
 * numero e' o comeco de duas ficarem para tras.
 *
 * ---- E por que ele deixou de ser um numero cravado ----
 *
 * "coloca o ping e fps um pouco pra baixo, porque ta atras do aviso de Mineiroidle
 *  Idle."
 *
 * A faixa de obra ocupa de 62 a 86, e o contador nascia em 72 — no meio dela.
 * Somar `--altura-do-aviso` resolve, e nao e' uma conta nova: e' a MESMA que o
 * cartaz de beta, a faixa de novidades e os recados ja fazem, e a mesma que a
 * regra do `#hud` la em cima (a de `@media`) sempre quis fazer.
 *
 * Sem aviso na tela a variavel vale zero e a conta da 72 — exatamente o numero
 * que estava cravado aqui. Ou seja: para quem nao ve a faixa, nada se move.
 *
 * De quebra, a barra de cima RECOLHE, e com o numero cravado o card ficava
 * parado num lugar que a barra tinha acabado de deixar.
 */
/*
 * No `body`, e nao no `:root`.
 *
 * Um `var()` dentro de outra variavel e' resolvido no elemento onde ela e'
 * DECLARADA — e `--altura-do-aviso` mora no `body` (`body.com-aviso`). Posta no
 * `:root`, esta conta lia o valor de fabrica da faixa (zero) e devolvia 72
 * mesmo com a faixa na tela: exatamente o defeito que ela veio consertar.
 * Aconteceu, e o contador continuou atras do aviso.
 */
body {
  --topo-do-hud: calc(var(--altura-da-topbar) + var(--altura-do-aviso, 0px) + 10px);
  --altura-do-medidor: 25px;
}

#hud {
  position: fixed; top: var(--topo-do-hud); left: 12px; z-index: 24; width: 340px;
  /* `minmax(0, 1fr)` prende a coluna na largura do card: sem isso o conteúdo
     mais largo esticava a grade e as barras passavam da borda. */
  padding: 10px 12px 8px; display: grid; grid-template-columns: minmax(0, 1fr); gap: 7px;
  border-style: solid;
  border-width: 12px 14px 14px 14px;
  border-image-source: url(/client/assets/ui/padrao.png);
  border-image-slice: 150 110 130 110 fill;
  border-image-repeat: stretch;
}
.hud-top { display: flex; align-items: center; gap: 10px; }
/*
 * Card da promoção: dourado, brilhando, logo abaixo da ficha. Some para sempre
 * assim que o personagem se promove.
 */
#hud-promotion {
  position: fixed; left: 12px; z-index: 24; width: 300px; padding: 9px 14px;
  display: grid; gap: 2px; justify-items: center; cursor: pointer; text-align: center;
  background: linear-gradient(180deg, #6b4f16, #3a2a0b);
  border: 1px solid #d9ae4a; border-radius: 8px; color: #ffe9b0;
  box-shadow: 0 0 12px #d9ae4a55, inset 0 0 12px #ffd98033;
  animation: promotion-glow 1.8s ease-in-out infinite;
}
#hud-promotion:hover { background: linear-gradient(180deg, #7d5c1a, #46330d); border-color: #ffe08a; }
#hud-promotion b { font-family: var(--font-title); font-size: 15px; letter-spacing: .08em; color: #ffe9b0; }
#hud-promotion em { font-style: normal; font-size: 10px; color: #e6cf9a; }
@keyframes promotion-glow {
  0%, 100% { box-shadow: 0 0 8px #d9ae4a44, inset 0 0 10px #ffd98022; border-color: #c79a3c; }
  50% { box-shadow: 0 0 22px #ffd98099, inset 0 0 16px #ffd98055; border-color: #ffe6a3; }
}

/* O botão de confirmar a promoção usa o mesmo dourado do card. */
.promotion-confirm {
  justify-self: start; margin-top: 6px; padding: 9px 22px; cursor: pointer;
  font-family: var(--font-title); font-size: 14px; letter-spacing: .06em; color: #2a1d05;
  background: linear-gradient(180deg, #f0cf7a, #c79a3c); border: 1px solid #ffe6a3; border-radius: 7px;
  box-shadow: 0 0 12px #d9ae4a66, inset 0 1px 0 #fff6d0;
  animation: promotion-glow 1.8s ease-in-out infinite;
}
.promotion-confirm:hover:not(:disabled) { background: linear-gradient(180deg, #ffe4a0, #d9ae4a); }
.promotion-confirm:disabled { opacity: .5; cursor: not-allowed; animation: none; filter: grayscale(.5); }

#hud-portrait {
  position: relative; width: 46px; height: 46px; flex: none;
  border-radius: 50%; background: #0b1416;
  box-shadow: 0 0 0 2px var(--copper), inset 0 0 12px #000;
  display: grid; place-items: center; overflow: visible;
}
#hud-portrait canvas { width: 46px; height: 46px; border-radius: 50%; }
.hud-level {
  position: absolute; left: -4px; bottom: -3px; min-width: 20px; text-align: center;
  font-family: var(--font-heading); font-size: 11px; font-weight: 700; color: #f2dfae;
  background: #14100a; border: 1px solid var(--copper); border-radius: 999px; padding: 0 4px;
}
.hud-id { flex: 1; min-width: 0; }
.hud-id strong {
  display: block; font-family: var(--font-heading); font-size: 15px; letter-spacing: .06em;
  text-transform: uppercase; color: #f2e6cd; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.hud-id span { font-size: 12px; color: var(--muted); }
#hud-sheet, #hud-min {
  width: 24px; height: 24px; flex: none; padding: 0; cursor: pointer; font-size: 12px;
  background: #1b2327cc; border: 1px solid var(--line); border-radius: 5px; color: var(--muted);
}
#hud-sheet:hover, #hud-min:hover { border-color: var(--accent); color: #fff; }
/*
 * O card encolhe, mas não fecha: ele é a ficha viva do personagem.
 *
 * Estas três linhas estavam embaralhadas — o `display: none` tinha escapado
 * para um seletor solto (`#hud-body`), escondendo o corpo sempre, e uma regra
 * mais abaixo o trazia de volta com `display: grid`. Resultado: o botão
 * alternava a classe e nada acontecia. É o mesmo estrago que atingiu o
 * `.window.minimized`.
 */
#hud-body { display: grid; gap: 7px; min-width: 0; }
#hud.minimized #hud-body { display: none; }
#hud.minimized { padding-bottom: 2px; }

/* ---------- sistemas dentro do card ---------- */

/* Os três sistemas: só os ícones do client, um do lado do outro. */
.hud-systems { display: flex; gap: 6px; margin-top: 4px; justify-content: flex-start; }
.hud-system {
  position: relative; display: grid; place-items: center; cursor: pointer;
  width: 30px; height: 30px; padding: 0;
  background: #10171899; border: 1px solid #ffffff14; border-radius: 6px; color: inherit;
}
.hud-system:hover { border-color: var(--accent-dim); background: #16201f; }
/*
 * O botão é o mesmo do topo do client (20x20 recortado do par apagado/aceso).
 * Ele é cinza por natureza, então o tema entra por sepia + hue-rotate; quando
 * há ponto para gastar ele acende em dourado e pulsa, como no client.
 */
/* 20px de arte em 20px de caixa: escalar pixel art por 1,15 (era 23) deixava
   as bordas do glifo com meio pixel de cada lado. */
.hud-system-icon {
  width: 20px; height: 20px; flex: none; background-size: 20px 20px; background-repeat: no-repeat;
  background-position: center; image-rendering: pixelated;
  filter: sepia(1) hue-rotate(115deg) saturate(2.2) brightness(1.05);
}
.hud-system.alert .hud-system-icon { animation: hud-system-glow 1.4s ease-in-out infinite; }
@keyframes hud-system-glow {
  0%, 100% { filter: sepia(1) hue-rotate(-8deg) saturate(3) brightness(1.1) drop-shadow(0 0 2px var(--copper)); }
  50% { filter: sepia(1) hue-rotate(-8deg) saturate(3) brightness(1.45) drop-shadow(0 0 8px var(--copper)); }
}
/* Perk esperando escolha ou ponto de charm sobrando. */
.hud-system.alert { border-color: var(--copper); }

.hud-bars { display: grid; gap: 4px; }
/* No card a barra é larga e traz o número dentro: o ícone não acrescenta nada
   e ainda roubaria largura dela. Ele só aparece em pé, na barra de baixo. */
.bar-icon { display: none; image-rendering: pixelated; }
.hud-bar {
  position: relative; height: 15px; background: #0a0e10;
  border: 1px solid #000; border-radius: 3px; overflow: hidden;
  box-shadow: inset 0 1px 0 #ffffff0f;
}
/*
 * O preenchimento é líquido, não uma barra chapada.
 *
 * Três camadas empilhadas na mesma caixa: um verniz de cima para baixo que dá
 * volume, uma trama diagonal que escorre para o lado, e a cor. Só a trama anda
 * — é o deslocamento dela que faz parecer que há algo correndo lá dentro, sem
 * repintar nada e sem custar quadro.
 *
 * A cor vem de duas variáveis por classe, e não de um `background` inteiro:
 * assim as três camadas ficam escritas uma vez só aqui, e cada barra só diz de
 * que cor ela é.
 */
.hud-bar i {
  display: block; height: 100%; width: var(--fill, 0%); transition: width .25s linear;
  background-image:
    linear-gradient(180deg, #ffffff40, #ffffff00 42%, #00000038),
    repeating-linear-gradient(115deg, #ffffff12 0 7px, #ffffff00 7px 20px),
    linear-gradient(180deg, var(--liq-a, #888), var(--liq-b, #444));
  background-size: 100% 100%, 40px 100%, 100% 100%;
  animation: liquido 2.4s linear infinite;
}
@keyframes liquido {
  from { background-position: 0 0, 0 0, 0 0; }
  to { background-position: 0 0, 40px 0, 0 0; }
}
/* Um lampejo lento atravessando: o brilho sutil que falta numa cor parada. */
.hud-bar::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 1;
  background: linear-gradient(100deg, #ffffff00 42%, #ffffff26 50%, #ffffff00 58%);
  background-size: 260% 100%;
  animation: lampejo 5.5s ease-in-out infinite;
}
@keyframes lampejo {
  0%, 62% { background-position: 130% 0; }
  100% { background-position: -30% 0; }
}
@media (prefers-reduced-motion: reduce) {
  .hud-bar i { animation: none; }
  .hud-bar::after { animation: none; opacity: 0; }
}

/* O número é do jogo, não do navegador: mesma serifa dos títulos, com sombra
   dos dois lados para se ler tanto sobre a cor cheia quanto sobre o vazio. */
.hud-bar span {
  position: absolute; inset: 0; z-index: 2; text-align: center;
  font-family: var(--font-heading); font-size: 10px; line-height: 13px;
  font-weight: 700; letter-spacing: .04em; color: #fff8ec;
  text-shadow: 0 1px 2px #000, 0 0 4px #000c, 0 -1px 0 #0008;
}
/* Vermelho e azul, como as barras do client. */
.hud-bar.hp i { --liq-a: #ef6a52; --liq-b: #a81f14; }
.hud-bar.mana i { --liq-a: #5fadee; --liq-b: #1d4d99; }
.hud-bar.exp i { --liq-a: #f0cf7a; --liq-b: #a8781f; }
.hud-bar.exp { height: 14px; }
/*
 * Stamina fecha a fileira, e a cor é o aviso: verde acima de 14h (experiência
 * cheia), amarelo abaixo disso (metade) e vermelho no zero (nenhuma). A régua e
 * o quadradinho ao lado dela usam o mesmo `data-grau`, senão um diria uma coisa
 * e o outro, outra.
 */
.hud-bar.stamina { height: 14px; }
.hud-bar.stamina i { --liq-a: #6ddb96; --liq-b: #25794a; }
.hud-bar.stamina[data-grau="media"] i { --liq-a: #f0cf7a; --liq-b: #a8781f; }
.hud-bar.stamina[data-grau="zerada"] i { --liq-a: #ef6a52; --liq-b: #a81f14; }
/*
 * ---- Enchendo: a régua ganha um brilho que CORRE, e um "+" ----
 *
 * A stamina sobe na cidade e no pátio de treino, e desce caçando. Nada na tela
 * dizia qual dos dois estava acontecendo: o número anda devagar demais para se
 * ver mexer — três minutos de descanso valem um minuto de stamina.
 *
 * A primeira tentativa foi clarear o líquido em pulso. Num líquido que já é
 * verde-claro, clarear mais quase não muda nada — foi o que o dono viu. Agora
 * são duas coisas que não dependem de contraste de cor: uma FAIXA de luz que
 * atravessa a régua da esquerda para a direita (o sentido em que ela enche) e o
 * sinal de mais no canto, que se lê de relance mesmo sem olhar para a cor.
 */
/* `position: relative` no líquido para o brilho ficar DENTRO do que já encheu:
   sem isso o `inset: 0` mede a régua inteira e a faixa atravessa o vazio. */
.hud-bar.stamina.enchendo i { position: relative; }
.hud-bar.stamina.enchendo i::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background: linear-gradient(100deg, #fff0 20%, #ffffffcc 45%, #ffffffee 50%, #ffffffcc 55%, #fff0 80%);
  background-size: 220% 100%;
  animation: stamina-correndo 2.2s linear infinite;
  mix-blend-mode: screen;
}
@keyframes stamina-correndo {
  from { background-position: 160% 0; }
  to { background-position: -60% 0; }
}
/*
 * ---- O "+" de "está enchendo" ----
 *
 * Ele já morou DENTRO da régua, encostado na borda direita, e ali ninguém o via:
 * quinze pixels de altura, 'overflow: hidden', e o número das horas passando por
 * cima. O dono pediu duas vezes.
 *
 * Agora ele é solto na CAIXA da régua, mordendo a borda de cima pelo canto
 * direito — fora do recorte, com espaço para ser grande e para brilhar.
 */
.bar-slot { position: relative; }
.bar-slot .bar-mais {
  position: absolute; right: -1px; top: -9px; z-index: 6;
  padding: 0 3px;
  font-style: normal; font-weight: 700; font-size: 15px; line-height: 1;
  color: #d7fff0; text-shadow: 0 0 6px #35d17a, 0 0 12px #35d17a, 0 1px 2px #000;
  pointer-events: none;
  animation: stamina-mais 1.6s ease-in-out infinite;
}
.bar-slot .bar-mais[hidden] { display: none; }
@keyframes stamina-mais {
  0%, 100% { opacity: .72; transform: translateY(0); }
  50% { opacity: 1; transform: translateY(-1px); }
}
/*
 * Na fita do rodapé as quatro réguas ficam num estojo recortado ('overflow:
 * hidden' em '.bars-dock .hud-bars'), e o sinal solto seria cortado fora. Lá
 * quem avisa é o mesmo "+" na frente do próprio número — dentro da régua, que é
 * a outra metade do que o dono pediu.
 */
.bars-dock .bar-slot .bar-mais { display: none; }
.bars-dock .hud-bar.stamina.enchendo span::before {
  content: "+"; margin-right: 5px;
  color: #d7fff0; text-shadow: 0 0 6px #35d17a, 0 0 10px #35d17a, 0 1px 2px #000;
}
@media (prefers-reduced-motion: reduce) { .bar-slot .bar-mais { animation: none; opacity: 1; } }

/*
 * ---- O VAZIO da régua também pisca, e em azul ----
 *
 * A faixa de luz corre pelo líquido, que é o pedaço já cheio — e numa stamina de
 * duas horas o líquido é um traço no canto esquerdo: o aviso ficava do tamanho
 * do que já existe, quando o que se quer avisar é justamente sobre o que ainda
 * falta. O azul é o que está por vir, e ele pulsa no fundo da régua inteira; o
 * líquido verde fica por cima e esconde a parte já conquistada.
 */
.hud-bar.stamina.enchendo { animation: stamina-vazio 2.2s ease-in-out infinite; }
@keyframes stamina-vazio {
  0%, 100% { background: #0a0e10; }
  50% { background: #16344d; box-shadow: inset 0 1px 0 #ffffff0f, inset 0 0 8px #2f7fd688; }
}
@media (prefers-reduced-motion: reduce) { .hud-bar.stamina.enchendo { animation: none; } }

/*
 * ---- A confirmação da entrega ----
 *
 * O que sai à esquerda, o que entra à direita, e a seta entre os dois. É a mesma
 * leitura de uma troca — que é o que uma entrega é.
 */
.entrega-confirma {
  display: grid; grid-template-columns: 1fr auto 1fr; gap: 14px; align-items: center;
  padding: 14px 10px;
}
.entrega-confirma-lado { display: grid; gap: 4px; justify-items: center; text-align: center; }
.entrega-confirma-lado canvas { image-rendering: pixelated; }
.entrega-confirma-lado b { font-size: 13px; color: var(--text); }
.entrega-confirma-lado em {
  font-style: normal; font-size: 10px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--muted);
}
.entrega-confirma-seta { font-size: 22px; color: var(--accent); }
.entrega-confirma-acoes {
  display: flex; align-items: center; gap: 10px; margin-top: 12px;
  padding-top: 12px; border-top: 1px solid var(--line);
}
/* O "não perguntar" empurra os botões para a direita: ele é a nota de rodapé da
   decisão, e eles são a decisão. */
.entrega-confirma-acoes .hunt-filtro-check { margin-right: auto; }
/* O quadradinho ao lado acompanha, pelo mesmo motivo de sempre: os dois contam
   a mesma história, e um parado ao lado de um piscando é uma contradição. */
.bar-dot.enchendo { animation: dot-enchendo 2s ease-in-out infinite; }
@keyframes dot-enchendo {
  0%, 100% { box-shadow: inset 0 1px 0 #ffffff40, 0 0 0 #6ddb9600; }
  50% { box-shadow: inset 0 1px 0 #ffffff40, 0 0 7px #6ddb96cc; }
}
@media (prefers-reduced-motion: reduce) {
  .hud-bar.stamina.enchendo i::after, .bar-dot.enchendo { animation: none; }
}

/*
 * ---- A pílula do pergaminho, dentro da faixa do treino ----
 *
 * Ela fica embaixo do botão de parar, e só existe enquanto uma exercise weapon
 * está batendo — que é o único momento em que o saldo do Scroll Speed desce.
 * Fora daí não há nada acontecendo para ela contar.
 */
#efeitos-faixa {
  display: flex; gap: 8px; justify-content: center; margin-top: 2px;
}
#efeitos-faixa[hidden] { display: none; }
.efeito-pill {
  display: flex; align-items: center; gap: 9px;
  padding: 5px 12px 5px 7px; border-radius: 999px;
  background: linear-gradient(180deg, #14202bee, #0d1214dd);
  border: 1px solid var(--line); box-shadow: 0 4px 14px #0009;
}
.efeito-pill .sprite { image-rendering: pixelated; flex: none; }
.efeito-pill-texto { display: grid; gap: 1px; }
.efeito-pill-nome {
  font-family: var(--font-title); font-size: 10px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--accent);
}
.efeito-pill-linha { display: flex; align-items: baseline; gap: 7px; }
.efeito-pill-tempo { font-size: 12px; color: #ffe9c2; font-variant-numeric: tabular-nums; }
.efeito-pill-estado {
  font-style: normal; font-size: 9px; letter-spacing: .07em; text-transform: uppercase;
  color: var(--muted);
}
/* Gastando agora: a pílula respira, como a régua da stamina que enche. Ela só
   aparece gastando, então este é o único estado que existe. */
.efeito-pill.gastando { border-color: #c98a3a; }
.efeito-pill.gastando .efeito-pill-estado { color: #f0b155; }
.efeito-pill.gastando .sprite { animation: efeito-pulso 1.6s ease-in-out infinite; }
@keyframes efeito-pulso {
  0%, 100% { filter: brightness(1); }
  50% { filter: brightness(1.5); }
}
@media (prefers-reduced-motion: reduce) { .efeito-pill.gastando .sprite { animation: none; } }

/*
 * ---- A faixa do treino, no alto e no meio ----
 *
 * As réguas são as MESMAS `.hud-bar` do card do personagem — mesma altura,
 * mesmo líquido correndo, mesmo lampejo. Escrever um segundo tipo de barra
 * daria duas barras parecidas que um dia divergem; aqui só muda a cor e a
 * largura.
 *
 * `pointer-events: none` porque ela fica por cima do mapa: uma faixa que
 * engolisse o clique faria o personagem parar de andar bem no meio da tela.
 */
#treino-faixa {
  position: fixed; z-index: 12; pointer-events: none;
  top: calc(var(--altura-da-topbar) + 8px + var(--altura-do-aviso, 0px));
  left: 50%; transform: translateX(-50%);
  display: grid; gap: 5px; justify-items: center;
  padding: 8px 14px 9px;
  background: linear-gradient(180deg, #0d1214ee, #0d1214cc);
  border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 6px 18px #0009;
}
#treino-faixa[hidden] { display: none; }
.treino-faixa-titulo {
  display: flex; align-items: baseline; gap: 10px;
  font-family: var(--font-title); font-size: 11px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--accent);
}
/* O relógio, em dígitos de largura fixa: sem isso a faixa treme a cada segundo
   porque o "1" é mais estreito que o "8". */
#treino-faixa-tempo { color: var(--copper); font-variant-numeric: tabular-nums; }
.treino-faixa-barras { display: flex; gap: 10px; align-items: flex-start; }
.treino-faixa-item { display: grid; gap: 3px; justify-items: center; }
/* Larga o bastante para o número caber com quatro casas depois da vírgula. */
.treino-faixa-item .hud-bar { width: 210px; height: 17px; }
.treino-faixa-item .hud-bar span { line-height: 15px; font-size: 10px; }
.treino-faixa-item em {
  font-style: normal; font-size: 10px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--muted);
}
.hud-bar.treino i { --liq-a: #6fe0c2; --liq-b: #1f7a66; }
.hud-bar.treino.escudo i { --liq-a: #9fb6d8; --liq-b: #3a5378; }
/*
 * A régua do escudo apaga quando ele não está subindo.
 *
 * No pátio o escudo sobe junto; com arma de exercise, não — cada arma treina a
 * sua perícia e nada mais, e é por isso que existe uma `exercise shield`. Uma
 * régua parada sem explicação faria o jogador achar que o treino está quebrado;
 * apagada, ela diz que está ali e não está valendo agora.
 */
/*
 * A faixa inteira ignora o clique (ela fica por cima do mapa), mas o BOTÃO não
 * pode: `pointer-events: auto` devolve o clique só a ele. Sem isso o botão
 * apareceria e não funcionaria — o pior dos dois mundos.
 */
#treino-faixa-parar {
  pointer-events: auto; cursor: pointer; margin-top: 2px;
  padding: 5px 22px; border-radius: 999px;
  background: linear-gradient(180deg, #8f2f26, #591a15);
  border: 1px solid #c0533f; color: #ffe3e0;
  font-family: var(--font-heading); font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  box-shadow: 0 2px 6px #0007, inset 0 1px 0 #ffffff26;
  transition: filter .15s ease, transform .12s ease;
}
#treino-faixa-parar:hover { filter: brightness(1.18); border-color: #ff9a91; }
#treino-faixa-parar:active { transform: translateY(1px); }
@media (prefers-reduced-motion: reduce) { #treino-faixa-parar { transition: none; } }
@media (max-width: 900px), (max-height: 540px) and (pointer: coarse) {
  .treino-faixa-item .hud-bar { width: 140px; }
  #treino-faixa { padding: 5px 8px 6px; }
}

/* O quadrado no lugar do sprite. */
.bar-dot {
  width: 11px; height: 11px; flex: none; border-radius: 2px;
  background: #5fd08a; border: 1px solid #0a0d0f; box-shadow: inset 0 1px 0 #ffffff40;
}
.bar-dot[data-grau="media"] { background: #e8c46a; }
/* Zerada pulsa: parado, vermelho vira só mais uma cor no rodapé. */
.bar-dot[data-grau="zerada"] { background: #e8563f; animation: dot-vazio 1.4s ease-in-out infinite; }
@keyframes dot-vazio {
  0%, 100% { box-shadow: inset 0 1px 0 #ffffff40, 0 0 0 #e8563f00; }
  50% { box-shadow: inset 0 1px 0 #ffffff40, 0 0 7px #e8563fcc; }
}

/*
 * Premium e blessings viraram dois selos dentro da grade do inventário, nos
 * dois cantos vazios da última fileira. Eram chips com o número ao lado numa
 * faixa própria embaixo da grade — a faixa custava altura de janela e o número
 * mudava de largura conforme o texto, empurrando o vizinho.
 *
 * Sem moldura de encaixe e sem fundo de slot: eles não são um lugar onde se
 * larga item. Só o desenho, com um halo que acende quando o estado está ativo,
 * do mesmo verde do resto da interface.
 */
.inv-badge {
  width: 44px; height: 44px; display: grid; place-items: center; cursor: help;
  /* A arte apagada já diz que está desligada — a coroa vem com o X vermelho.
     Um cinza forte por cima só apagava o vermelho, que é justamente o aviso. */
  filter: grayscale(.2) brightness(.9) drop-shadow(0 0 1px #0a0d0f);
  transition: filter .16s ease, transform .16s ease;
}
/*
 * Escala inteira, ou nada.
 *
 * Os dois ícones do client são minúsculos e de tamanhos diferentes: a coroa é
 * 22x19 e o símbolo das blessings 12x12. Numa caixa de 26 com `contain`, a
 * coroa ia a 1,18x e o símbolo a 2,17x — e `pixelated` numa escala fracionária
 * duplica algumas fileiras de pixel e não outras. É exatamente isso que se vê
 * como serrilhado: uma borda em degraus irregulares.
 *
 * Então cada um vai numa escala inteira — a coroa em 1x, as blessings em 2x —
 * e as duas dão quase o mesmo tamanho na tela, sem um pixel torto. Enquanto a
 * arte for essa, este é o teto: para um ícone maior e liso, a arte tem que
 * nascer maior.
 */
.inv-badge img { image-rendering: pixelated; object-fit: contain; }
.inv-badge.premium img { width: 22px; height: auto; }
/* Este não é mais o símbolo de 12px do client: é o ícone de 128px que estava na
   barra de cima. Reduzir de 128 para 30 o navegador faz liso sozinho — e aí
   `pixelated` só atrapalha, porque ele manda ignorar essa suavização. */
.inv-badge.blessings img { width: 30px; height: 30px; image-rendering: auto; }
.inv-badge.blessings { cursor: pointer; }
.inv-badge.on { filter: drop-shadow(0 0 2px #0a0d0f) drop-shadow(0 0 6px #3fbfa866); }
.inv-badge:hover { transform: scale(1.12); filter: drop-shadow(0 0 3px #3fbfa8) drop-shadow(0 0 9px #3fbfa877); }
@media (prefers-reduced-motion: reduce) {
  .inv-badge { transition: none; }
}

/* ---------- janelas flutuantes ---------- */

/*
 * A moldura vem do padrao.png em nine-slice: os cantos ornamentados ficam
 * intactos e só as bordas retas esticam. A barra de título do desenho é a
 * borda de cima, então o cabeçalho é posicionado por cima dela.
 */
/* z-index 10: o piso da faixa das janelas (10 a 29). Acima dela ficam a topbar
   (30), o modal (50) e a confirmação (55) — ver `Z_TETO` em windows.mjs. */
.window {
  position: fixed; z-index: 10; display: flex; flex-direction: column; min-width: 200px;
  border-style: solid;
  border-width: 36px 22px 24px 22px;
  border-image-source: url(/client/assets/ui/padrao.png);
  border-image-slice: 150 110 130 110 fill;
  border-image-repeat: stretch;
  background: none;
}
.window.dragging { opacity: .92; }
.window > header {
  /* Título colado na borda esquerda, minimizar e fechar colados na direita:
     a moldura tem ornamento nos cantos, e o texto cabe entre eles. */
  position: absolute; top: -25px; left: 4px; right: 4px; height: 28px; overflow: hidden;
  display: flex; align-items: center; gap: 6px; padding: 0 2px; cursor: grab;
  background: none; border: none; user-select: none; flex: none;
}
.window.dragging > header { cursor: grabbing; }
.window > header h2 {
  margin: 0; font-size: 10px; letter-spacing: .04em; text-transform: uppercase;
  color: #e8d9b4; font-weight: 700; flex: 1;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/*
 * ---- Os botões do cabeçalho, e por que eles sumiam ----
 *
 * Eles usavam `--muted` (#7a8a90, um cinza azulado) por cima da moldura de
 * madeira escura da janela, que é quente e tem ornamento no fundo. Cinza frio
 * sobre marrom com textura é quase o mesmo tom de claridade, e o olho não
 * separa os dois: a engrenagem e o relógio ficavam invisíveis do lado do X.
 *
 * O título ao lado deles já resolvia isso há muito tempo, com #e8d9b4 — um
 * pergaminho claro que a moldura não engole. Os ícones passam a ser da mesma
 * família, um degrau abaixo do título para continuarem sendo botão e não
 * manchete.
 *
 * O TAMANHO não muda — 11px e 12px, como antes. O que mudou foi contraste,
 * que é o que estava faltando: não adianta aumentar uma letra que está na cor
 * do fundo.
 */
.window-close, .window-min, .window-reset, .window-organizar {
  background: none; border: none; cursor: pointer; font-size: 11px; padding: 0 3px; line-height: 1;
  color: #cbbc9a; text-shadow: 0 1px 2px #000c; transition: color .15s, opacity .15s;
}
.window-close:hover, .window-min:hover, .window-reset:hover, .window-organizar:hover { color: #fff3d6; }
/*
 * ---- O "Organizar" da janela, colado na engrenagem ----
 *
 * "ao lado da engrenagem um botão de reorganizar." Mesma família dos três
 * botões do canto — mesmo tamanho, mesma cor, mesma transição —, porque ele
 * mora na mesma fileira e destoar ali chamaria mais atenção do que ele merece.
 *
 * Apagado quando não há dois itens para trocar de lugar: um botão que não pode
 * fazer nada não deve parecer que pode.
 */
.window-organizar { font-size: 12px; opacity: .8; }
.window-organizar:hover:not(:disabled) { opacity: 1; color: var(--accent); }
.window-organizar:disabled { opacity: .3; cursor: default; }

/*
 * O mesmo botão dentro do depósito, que é um modal e não uma janela: ali ele
 * entra na fileira do "Voltar / Renomear / Mover tudo" e usa o visual `ghost`
 * dela. O que esta regra faz é só encolhê-lo — ele é uma seta, e não uma
 * palavra, e com a largura dos outros pareceria um botão sem rótulo.
 */
.deposito-organizar { flex: none; padding: 0 9px; font-size: 13px; line-height: 26px; }
/* A engrenagem do arranjo. Acende quando a janela saiu do tamanho de fábrica,
   porque aí ela tem uma opção a mais lá dentro. */
.window-reset { font-size: 12px; opacity: .8; }
.window-reset:hover { opacity: 1; }
.window.resized .window-reset { opacity: 1; color: var(--accent); }

/* A contagem de tipos, ao lado do título da janela da bolsa. Discreta: ela é a
   legenda do nome, não uma segunda manchete.

   `flex: none` é o ponto: ela nunca encolhe, e o `margin-right: auto` empurra
   os botões de volta para a borda direita. Quem cede espaço é o nome da janela
   (a regra logo abaixo), porque "BOLSA DE LOOT…" ainda se lê e "5 / 10…" não. */
/* A Boss Pouch tem a mesma contagem no mesmo lugar, e pelo mesmo motivo. */
.window[data-window-id="loot"] > header h2,
.window[data-window-id="bossPouch"] > header h2 { flex: 0 1 auto; }
.bag-count {
  flex: none; margin-right: auto; font-size: 10px; font-weight: 400;
  color: var(--muted); letter-spacing: 0;
}
.bag-count.full { color: var(--danger, #d8564c); font-weight: 600; }

/* O relógio da venda e o "+" que encurta o tempo dela. */
.bag-timer { display: inline-flex; align-items: center; gap: 5px; }
.bag-timer i { font-style: normal; opacity: .7; }
.bag-timer b.agora { color: var(--accent); }
.bag-timer-buy {
  margin-left: auto; min-width: 20px; height: 18px; padding: 0 6px; line-height: 1;
  border: 1px solid var(--line); border-radius: 5px; background: none;
  color: var(--accent-dim); cursor: pointer; font-size: 12px; font-weight: 700;
}
.bag-timer-buy:hover:not(:disabled) { color: var(--accent); border-color: var(--accent-dim); }
.bag-timer-buy:disabled { opacity: .4; cursor: default; }

/*
 * ---- O "+" pulsa em dourado enquanto houver melhoria para comprar ----
 *
 * Ele é o único botão da bolsa que leva a uma compra, e vivia apagado no
 * verde-água do resto da interface — do lado de um relógio que anda, um
 * botão parado e da cor do fundo não é lido como botão.
 *
 * O dourado é o `--exp` que o jogo já usa para o que vale dinheiro, e o pulso
 * é lento (2,4s) de propósito: é um chamariz que fica na tela a caçada
 * inteira, e uma pulsação rápida vira cintilação em segundos.
 *
 * Quando as cinco compras acabam o botão vira "✓" e fica `disabled` — e aí a
 * animação para sozinha, porque a regra abaixo exige `:not(:disabled)`.
 * Anunciar uma compra que não existe mais é pior do que não anunciar nada.
 */
@keyframes pulso-dourado {
  0%, 100% { color: var(--exp); border-color: #6a5420; box-shadow: 0 0 0 0 #c8a13c00; }
  50%      { color: #ffdf8a; border-color: var(--exp); box-shadow: 0 0 7px 1px #c8a13c55; }
}
.bag-timer-buy:not(:disabled) {
  color: var(--exp); border-color: #6a5420;
  animation: pulso-dourado 2.4s ease-in-out infinite;
}
.bag-timer-buy:not(:disabled):hover { color: #ffdf8a; border-color: var(--exp); animation-play-state: paused; }

/* Quem pediu menos movimento ao sistema fica com o dourado parado: a cor
   sozinha já destaca o botão, e o pulso é o enfeite. */
@media (prefers-reduced-motion: reduce) {
  .bag-timer-buy:not(:disabled) { animation: none; }
}

/* A barra de páginas da bolsa, quando ela passa de cem tipos. */
.bag-pages { display: flex; align-items: center; justify-content: center; gap: 8px; padding: 5px 0 2px; }
.bag-pages span { font-size: 11px; color: var(--muted); }
.bag-pages button {
  min-width: 22px; height: 20px; border: 1px solid var(--line); border-radius: 5px;
  background: none; color: var(--text); cursor: pointer; line-height: 1;
}
.bag-pages button:disabled { opacity: .35; cursor: default; }

/* O atalho da bolsa para a loja: mesma família dos botões do cabeçalho, com a
   cor do acento para se distinguir da engrenagem que fica ao lado dele. */
.bag-store {
  background: none; border: none; cursor: pointer; color: var(--exp);
  font-size: 12px; padding: 0 3px; line-height: 1; opacity: .9;
  text-shadow: 0 1px 2px #000c; transition: opacity .15s, color .15s;
}
.bag-store:hover { opacity: 1; color: #ffdf8a; }

/* ---------- menu da engrenagem ---------- */

/* Ancorado no botão que o abriu, não no canto da janela: ele fala das janelas
   todas, mas quem o chamou foi uma. */
.window-menu {
  position: fixed; z-index: 90; min-width: 218px; padding: 4px;
  display: flex; flex-direction: column;
  background: var(--panel-solid); border: 1px solid var(--line); border-radius: 7px;
  box-shadow: 0 12px 30px #000a;
}
.window-menu button {
  text-align: left; background: none; border: none; padding: 7px 10px; cursor: pointer;
  border-radius: 5px; font-size: 12px; color: var(--text);
}
.window-menu button:hover:not(:disabled) { background: var(--panel-2); color: #fff; }
.window-menu button:disabled { color: #4a585c; cursor: default; }
.window-body {
  flex: 1; overflow-y: auto; overflow-x: hidden; padding: 4px 6px 6px; min-height: 0; min-width: 0;
  /* Nada de palavra comprida furando a moldura nine-slice. */
  overflow-wrap: anywhere;
}
.window-body > *, #modal-body > * { min-width: 0; max-width: 100%; }
.window.minimized .window-body, .window.minimized .window-grip { display: none; }
/*
 * ---- O corpo do chat, e o que sobra dele MINIMIZADO ----
 *
 * O `display: flex` morava inline no `render()` do chat, e estilo inline vence
 * qualquer seletor: minimizar escondia o corpo de todas as janelas menos a do
 * chat. Aqui ele vale pela folha, e a regra de minimizado volta a mandar.
 *
 * E, minimizado, o chat é a única janela que NÃO esconde o corpo inteiro: as
 * abas continuam à vista com os numerinhos de não lidas, que é o que o dono
 * pediu ("clicar numa aba restaura a janela já nessa aba"). O que some é a
 * conversa e a caixa de escrever — `.chat-corpo`.
 */
.window[data-window-id='chat'] .window-body { display: flex; flex-direction: column; }
.window.minimized[data-window-id='chat'] .window-body { display: flex; }
.window.minimized .chat-corpo { display: none; }

/* =========================================================================
 * O CHAT REORGANIZADO — conversa de um lado, log do outro
 *
 * As cores saem das mesmas variáveis das outras janelas: o contorno e a aba
 * ativa em verde/teal, e nada de dourado, que neste jogo é da Store. O dono foi
 * explícito quanto a isso.
 * ========================================================================= */

/* O corpo que some ao minimizar, e que é quem rola. */
.chat-corpo { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }

/*
 * ---- O miolo dividido: Privados (conversas | conversa) e Logs (categorias | log) ----
 *
 * O desenho do dono. A lateral é estreita de propósito — só nomes, sem ícone
 * nem level — e o resto é da lista de linhas. Tudo flex, com `min-height: 0`
 * para a rolagem ficar dentro e nunca estourar a janela.
 */
.chat-miolo { display: flex; flex: 1 1 auto; min-height: 0; }
.chat-miolo.chat-dividido { gap: 4px; }
.chat-lateral {
  flex: 0 0 auto; width: 92px; max-width: 38%; min-height: 0; overflow-y: auto; overflow-x: hidden;
  display: flex; flex-direction: column; gap: 1px;
  border-right: 1px solid var(--line-soft); padding-right: 3px; scrollbar-width: thin;
}
.chat-lateral-titulo { margin: 0 0 2px; font-size: 9px; color: var(--muted); text-transform: uppercase; letter-spacing: .06em; flex: none; }
.chat-lateral button {
  display: flex; align-items: center; gap: 3px; flex: none;
  background: none; border: 1px solid transparent; border-radius: 4px; padding: 2px 4px;
  font: inherit; font-size: 11px; line-height: 15px; color: var(--text); cursor: pointer;
  text-align: left; white-space: nowrap; overflow: hidden; min-width: 0;
}
.chat-lateral button:hover { background: var(--panel-2); }
.chat-lateral button[aria-selected="true"] { border-color: var(--accent); color: var(--accent); background: var(--panel-2); }
.chat-lateral .chat-lateral-acao { color: #7fd8c9; }
.chat-lista-de-conversas { display: flex; flex-direction: column; gap: 1px; }
.chat-conversa-nome { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; }
.chat-lateral button i.chat-citou {
  font-style: normal; font-size: 9px; border-radius: 999px; padding: 0 4px; flex: none;
  background: #7a4a1e; color: #ffd9a8; border: 1px solid #b4854a;
}
.chat-lateral button i.chat-fecha { font-style: normal; color: var(--muted); flex: none; padding: 0 2px; }
.chat-lateral button i.chat-fecha:hover { color: #ff8a7a; }
.chat-direita { flex: 1 1 auto; min-width: 0; min-height: 0; display: flex; flex-direction: column; }
.chat-conversa-cabecalho {
  display: flex; align-items: center; gap: 4px; flex: none;
  font-size: 11px; padding: 0 0 2px; margin-bottom: 2px; border-bottom: 1px solid var(--line-soft);
}
.chat-conversa-cabecalho .who { color: var(--accent); }
.chat-vazio { margin: 4px 2px; font-size: 11px; color: var(--muted); font-style: italic; }
.chat-dois-pontos { color: var(--muted); }
/* O rótulo na frente de cada linha dos Logs: [DANO], [XP], [LOOT]... */
.chat-rotulo { font-weight: 700; font-size: 10px; letter-spacing: .02em; }
.rotulo-dano { color: #e08a84; }
.rotulo-xp { color: var(--accent); }
.rotulo-loot { color: var(--copper); }
.rotulo-cura { color: var(--hp); }
.rotulo-magia { color: #f36500; }
.rotulo-morte { color: #ff5a4a; }
.rotulo-sistema { color: var(--muted); }

/* O numerinho de quem te chamou pelo nome: ele fura a regra do ponto. */
.chat-tabs i.chat-citou {
  background: #7a4a1e; color: #ffd9a8; border-color: #b4854a;
}

/* A linha que cita o seu nome, em qualquer canal. */
.chat-log .chat-mencao {
  background: #1d2b1f; border-left: 2px solid #5f9a52; padding-left: 3px;
}

/* A resposta da equipe no Help: fácil de achar no meio da conversa. */
.chat-log .chat-staff { background: #12262a; border-left: 2px solid #3f9aa8; padding-left: 3px; }
.chat-tag-staff { color: #6fd3e0; font-weight: 700; }
.chat-nome-staff { color: #6fd3e0; cursor: pointer; }

/* A citação de "Responder", acima da fala. */
.chat-citada {
  border-left: 2px solid #3a4a4f; margin: 1px 0 1px 6px; padding-left: 4px;
  color: #8fa3a8; font-size: 10px; font-style: italic;
}
.chat-citada b { color: #b6c7cc; font-style: normal; }

/* O "Responder" que aparece ao passar o mouse numa linha do Help. */
.chat-responder {
  float: right; border: 0; background: none; cursor: pointer;
  color: #6fd3e0; font-size: 10px; padding: 0 2px; visibility: hidden;
}
.chat-log[data-canal='help'] div:hover .chat-responder { visibility: visible; }
/* E a barra de "respondendo a", em cima da caixa de escrever. */
.chat-respondendo {
  display: flex; align-items: center; gap: 4px; flex: none; margin-top: 3px;
  font-size: 10px; color: #8fa3a8; padding: 1px 4px;
  border-left: 2px solid #3f9aa8;
}
.chat-respondendo span { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-respondendo button { border: 0; background: none; color: #8fa3a8; cursor: pointer; }

/* A linha de onde começam as não lidas. */
.chat-separador {
  display: flex; align-items: center; gap: 6px;
  color: #b4553f; font-size: 9px; text-transform: uppercase; letter-spacing: .06em;
  margin: 2px 0;
}
.chat-separador::before, .chat-separador::after {
  content: ''; flex: 1; height: 1px; background: #4a2a24;
}
/* O histórico entra apagado: ele é o que já passou. */
.chat-do-historico { opacity: 0.86; }

/* Os menus (Privados, Log) e o popover do "+", no contorno das janelas. */
.chat-menu {
  position: fixed; z-index: 60; min-width: 190px; max-width: 280px;
  max-height: 260px; overflow-y: auto;
  background: #0d1417f2; border: 1px solid #3a4a4f; border-radius: 4px;
  box-shadow: 0 6px 18px #000a; padding: 3px;
}
.chat-menu-titulo { margin: 2px 4px 4px; font-size: 10px; color: #8fa3a8; text-transform: uppercase; letter-spacing: .06em; }
.chat-menu-vazio { margin: 4px; font-size: 11px; color: #8fa3a8; }
.chat-menu-secao, .chat-popover-secao { margin: 4px 4px 2px; font-size: 9px; color: #6f8288; text-transform: uppercase; }
.chat-menu-item {
  display: flex; align-items: center; gap: 4px; width: 100%;
  padding: 3px 4px; border: 0; border-radius: 3px;
  background: none; color: #d9e6e8; font: inherit; font-size: 11px;
  text-align: left; cursor: pointer;
}
.chat-menu-item:hover, .chat-menu-item:focus-visible { background: #1b2a2e; outline: none; }
.chat-menu-item:focus-visible { box-shadow: inset 0 0 0 1px #4e8c86; }
.chat-menu-acao { color: #7fd8c9; }
.chat-menu-marca { cursor: pointer; }
.chat-menu-trecho { color: #8fa3a8; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-popover-campo {
  width: 100%; box-sizing: border-box; margin: 0 0 4px;
  padding: 4px 6px; border: 1px solid #3a4a4f; border-radius: 3px;
  background: #0b1113; color: #e7f0f1; font: inherit; font-size: 12px;
}
.chat-popover-campo:focus { outline: none; border-color: #4e8c86; }
.chat-popover-campo::placeholder { color: #6f8288; text-transform: none; font-variant: normal; }
.chat-popover-erro { margin: 0 0 4px; font-size: 11px; color: #ff9b8a; }

/*
 * As categorias dos Logs e o escopo (todos / party / meus): quem esconde é o
 * CSS, lendo o atributo do log e a marca de cada linha. Trocar não remonta nada.
 */
.chat-log[data-categoria="recebido"] > :not([data-tipo~="recebido"]),
.chat-log[data-categoria="causado"] > :not([data-tipo~="aplicado"]),
.chat-log[data-categoria="exp"] > :not([data-fonte="exp"]),
.chat-log[data-categoria="loot"] > :not([data-fonte="loot"]),
.chat-log[data-categoria="sistema"] > :not([data-fonte="servidor"]):not([data-tipo~="sistema"]),
.chat-log[data-categoria="magia"] > :not([data-tipo~="magia"]),
.chat-log[data-categoria="cura"] > :not([data-tipo~="cura"]),
.chat-log[data-categoria="morte"] > :not([data-tipo~="morte"]) { display: none; }
.chat-log[data-escopo="meus"] > [data-de]:not([data-de="meu"]),
.chat-log[data-escopo="party"] > [data-de="outro"] { display: none; }
.window.minimized[data-window-id='chat'] .chat-tabs { margin-bottom: 0; }
.rule-hint { margin: 4px 0 2px; font-size: 10px; color: var(--muted); }
.cap-warning {
  display: grid; gap: 1px; margin: 6px 0 0; padding: 6px 8px; border-radius: 6px;
  background: #2a11119c; border: 1px solid #a3333366;
}
.cap-warning b { font-size: 11px; color: #ff8a7a; }
.cap-warning em { font-style: normal; font-size: 10px; color: var(--muted); }

.window.minimized { height: auto !important; border-bottom-width: 12px; }
/*
 * Bolsa sem capacidade: a moldura pulsa em vermelho até o jogador vender.
 *
 * `box-shadow` desenhava o brilho na caixa do elemento, e a caixa é bem maior
 * que a moldura em nove fatias que se vê — por isso o vermelho aparecia solto,
 * longe da janela. `drop-shadow` segue os pixels que foram realmente pintados,
 * então o brilho contorna a moldura ornamentada certinho.
 */
.window.nocap { animation: nocap-pulse 1.5s ease-in-out infinite; }
@keyframes nocap-pulse {
  0%, 100% { filter: drop-shadow(0 0 2px #a3333388) drop-shadow(0 0 7px #a3333355); }
  50% { filter: drop-shadow(0 0 5px #ff6a55dd) drop-shadow(0 0 16px #e04a3aaa); }
}
/* E um vermelho leve por dentro, subindo das bordas do miolo: de fora o
   brilho some contra um fundo claro, e o aviso passava batido. */
.window.nocap .window-body {
  animation: nocap-inside 1.5s ease-in-out infinite;
  border-radius: 4px;
}
@keyframes nocap-inside {
  0%, 100% { box-shadow: inset 0 0 12px #a3333322; }
  50% { box-shadow: inset 0 0 22px #e04a3a55; }
}
.rule-hint { margin: 4px 0 2px; font-size: 10px; color: var(--muted); }
.cap-warning {
  display: grid; gap: 1px; margin: 6px 0 0; padding: 6px 8px; border-radius: 6px;
  background: #2a11119c; border: 1px solid #a3333366;
}
.cap-warning b { font-size: 11px; color: #ff8a7a; }
.cap-warning em { font-style: normal; font-size: 10px; color: var(--muted); }

/*
 * Alça de redimensionar, no canto de baixo à direita.
 *
 * Ela mora dentro da borda ornamentada — daí os deslocamentos negativos: o
 * bloco posicionado se mede pela caixa de conteúdo, e a moldura tem 22px de
 * cada lado. Puxa nos dois sentidos, largura e altura.
 */
/*
 * As três listras na quina da moldura.
 *
 * Os números negativos não jogam a alça para fora da janela: um filho
 * `absolute` se posiciona pela CAIXA DE CONTEÚDO do pai, e a moldura desta
 * janela é `border-width: 36px 22px 24px 22px`. Então `right: -17px` é 17px
 * para fora do conteúdo e ainda 5px para DENTRO da beirada — em cima da quina
 * desenhada, que é onde ela tem de estar.
 */
.window-grip {
  position: absolute; right: -17px; bottom: -19px; width: 15px; height: 15px; cursor: nwse-resize;
  background: linear-gradient(135deg, transparent 50%, var(--copper) 50%, var(--copper) 60%, transparent 60%, transparent 74%, var(--copper) 74%, var(--copper) 84%, transparent 84%);
  opacity: .55;
}
.window-grip:hover { opacity: 1; }
/*
 * As outras sete alças: as quatro bordas e os três cantos restantes.
 *
 * Faixas invisíveis de 8px sobre a moldura. Elas não desenham nada parado —
 * seis janelas abertas com oito marcas cada viraria uma cerca de enfeites — e
 * se anunciam de dois jeitos: o cursor vira seta dupla ao encostar, e a faixa
 * acende de leve por baixo do ponteiro.
 *
 * A geometria evita o cabeçalho de propósito. A moldura tem 36px em cima e
 * 22px nos lados, e o cabeçalho fica a 11px do topo e a 26px de cada lateral —
 * então faixas de 8px nas bordas e cantos de 10px passam por FORA dele, e nem o
 * arrasto pelo título nem os botões de minimizar e fechar perdem um pixel.
 */
/*
 * Sem pintura nenhuma: só cursor.
 *
 * A primeira versão acendia a faixa em cobre sob o ponteiro e ficou ruim —
 * uma tarja marrom aparecendo na moldura desenhada, que já tem cor e ornamento
 * próprios. O cursor virando seta dupla é aviso suficiente, e é o que toda
 * janela de sistema faz.
 */
.window-lado { position: absolute; z-index: 4; }
/*
 * ---- Por que os números são negativos ----
 *
 * Este era o erro da primeira versão: `right: 0` NÃO é a beirada da janela.
 *
 * Um filho `absolute` se posiciona pela caixa de CONTEÚDO do pai, e o conteúdo
 * desta janela termina 22px antes da beirada — a moldura inteira é
 * `border-width: 36px 22px 24px 22px`. Com `right: 0` as faixas ficavam em cima
 * do miolo, dentro da janela, e o cursor virava seta no lugar errado: um pouco
 * ANTES do fim, que foi exatamente o que se viu na tela.
 *
 * Os negativos põem cada faixa sobre a espessura da moldura, do conteúdo até a
 * beirada: 22px nas laterais, 24px embaixo. A alça de três listras sempre
 * esteve certa, e sempre pelo mesmo motivo.
 */
.window-lado[data-lado="s"] { bottom: -24px; left: 0; right: 0; height: 24px; cursor: ns-resize; }
.window-lado[data-lado="w"] { left: -22px; top: -25px; bottom: -24px; width: 22px; cursor: ew-resize; }
.window-lado[data-lado="e"] { right: -22px; top: -25px; bottom: -24px; width: 22px; cursor: ew-resize; }
.window-lado[data-lado="sw"] { bottom: -24px; left: -22px; width: 22px; height: 24px; cursor: nesw-resize; }
/*
 * Em cima a faixa para nos 11px, e não nos 36 da moldura: o cabeçalho começa
 * ali e é ele que arrasta a janela. Descer mais comeria o alto do título e dos
 * botões de minimizar e fechar — clicar na quina do X viraria redimensionar.
 *
 * As laterais também começam nos 11px (`top: -25px`) pelo mesmo motivo, e por
 * isso não encostam no cabeçalho: ele fica a 26px de cada lado, e elas ocupam
 * só os 22px da moldura.
 */
.window-lado[data-lado="n"] { top: -36px; left: 0; right: 0; height: 11px; cursor: ns-resize; }
.window-lado[data-lado="nw"] { top: -36px; left: -22px; width: 22px; height: 22px; cursor: nwse-resize; }
.window-lado[data-lado="ne"] { top: -36px; right: -22px; width: 22px; height: 22px; cursor: nesw-resize; }
.window.sizing { user-select: none; }

/* ---------- action bar ---------- */

/* A barra é o painel liso de sempre. A moldura de pedra foi testada aqui e não
   ficou: ela pede altura, e esta barra é justamente a peça que não pode crescer. */
/*
 * Coluna: a fita das réguas atravessa por cima, os slots e os controles vêm
 * embaixo numa fileira só.
 *
 * A caixa lisa ficou. A moldura de pedra foi testada em volta da barra inteira
 * e não ficou: ela é uma peça grande e ornamentada emoldurando outra peça
 * grande e ornamentada — os sulcos das réguas —, e as duas competiam. O sulco
 * ficou porque ele é o que a régua precisava; a moldura em volta era enfeite
 * sobre enfeite.
 */
/*
 * `width: max-content`, e não a largura que sobrar.
 *
 * A barra é `position: fixed` com `left: 50%`, e para um elemento assim o
 * navegador calcula a largura contra o espaço que vai do `left` até a borda
 * direita — metade da tela, não a tela inteira. Ele parava em 1201px quando o
 * conteúdo precisava de 1238. Os três blocos da fileira são `flex: none` de
 * propósito (os doze slots têm tamanho fixo), então em vez de encolherem eles
 * transbordavam — e quem estava na ponta direita, o botão de hunt, saía para
 * fora da moldura. Medido: 24px de fora, igual em 1920, 1656, 1500 e 1366.
 *
 * Com `max-content` a caixa nasce do tamanho do que há dentro, e o `max-width`
 * continua sendo o teto. Abaixo de ~1262px de tela o conteúdo não cabe mesmo,
 * e aí a barra rola na horizontal em vez de vazar.
 */
/*
 * A barra encosta no fim da tela.
 *
 * Havia 10px de folga embaixo: uma faixa de mapa aparecia por baixo dela, e a
 * fita ficava boiando em vez de assentada. Encostada, o canto de baixo perde o
 * arredondamento — uma borda arredondada contra a beirada da janela fica com
 * cara de erro de desenho, não de moldura.
 */
/*
 * ---- A moldura da barra ----
 *
 * `actionbar-frame.png` já estava na pasta, na mesma arte das janelas do jogo —
 * ferro escuro, dois trilhos de ouro e o floreio nos cantos. Ela nunca chegou a
 * ser ligada; a barra era um retângulo chapado com borda de 1px.
 *
 * ---- Por que ela não faz a barra crescer ----
 *
 * A espessura da moldura SUBSTITUI a margem interna que já existia, em vez de
 * somar por fora. Era `1px de borda + 7/8/12 de padding`; agora é uma borda de
 * 6/7/11 mais 2px de padding, que dá exatamente os mesmos 8, 9 e 13 de antes. A
 * barra ocupa o mesmo lugar na tela, pixel por pixel — só que agora a beirada
 * dela é desenhada.
 *
 * ---- Fina, e por quê ----
 *
 * A borda é de 5 a 7 pixels: o dono pediu um fio, não uma cerca. Numa fita que
 * tem doze slots de 52px, uma moldura grossa rouba a atenção de tudo que está
 * dentro — e o que precisa saltar aos olhos é o sprite da magia.
 *
 * A moldura é um FIO: 3px em cima, 4 nos lados e embaixo. O dono foi afinando
 * até aqui, e este é o degrau em que ela ainda se lê como moldura —
 * na horizontal a barra é longa e a moldura corre por mil pixels — grossa ali,
 * ela vira duas cercas em volta dos slots.
 *
 * ---- A fatia tem de crescer quando a borda encolhe ----
 *
 * É o contrário do que parece. A fatia (26) precisa pegar o TRILHO INTEIRO —
 * a linha escura de fora, o brilho do meio e a linha escura de dentro. Cortando
 * antes disso, sobra só a metade clara do trilho, e ela é desenhada como uma
 * BARRA VERTICAL ACESA junto da beirada; foi o que apareceu nas tentativas com
 * fatia 10 e 16, e está na comparação guardada no scratchpad.
 *
 * Com o trilho inteiro dentro da fatia, encolher a borda só borra os detalhes —
 * que é o que se quer: de longe vira um fio.
 *
 * `fill` pinta o miolo escuro da arte, que passa a ser o fundo da barra — por
 * isso o `background` chapado saiu daqui.
 */
#actionbar {
  /* O `--desloca-barra` (medido no actionbar.mjs) é o que põe a FILEIRA DE
     SLOTS no meio da tela, e não a barra: ela não é simétrica, e centrá-la
     deixava os slots à esquerda do personagem. Ver a nota longa lá. */
  position: fixed; bottom: 0; left: 50%;
  transform: translateX(calc(-50% + var(--desloca-barra, 0px)));
  z-index: 25;
  display: flex; flex-direction: column; gap: 3px; align-items: stretch;
  width: max-content;
  max-width: 100vw;
  overflow-x: auto;
  border-style: solid;
  /*
   * A moldura e o enchimento são mais finos EMBAIXO.
   *
   * A borda de baixo não é uma borda: é o pedaço da arte que encosta na beira
   * da tela, e ninguém a vê inteira — o monitor acaba ali. Os 4px dela mais os
   * 5px de enchimento eram 9px de faixa escura entre o último slot e o fim do
   * mundo, e é isso que fazia a barra parecer descolada da beirada.
   *
   * Em cima os 3px continuam, porque ali a moldura tem o mapa atrás e o friso
   * dela é o que separa uma coisa da outra.
   */
  border-width: 3px 4px 3px;
  border-image-source: url('/client/assets/ui/actionbar-frame.png');
  border-image-slice: 26 fill;
  border-image-repeat: stretch;
  border-radius: 0;
  padding: 5px 9px 2px;
}
/*
 * ---- A grade: duas fileiras, e quem decide a quebra é o servidor ----
 *
 * `--slots-por-fileira` chega do `montarHotbar`, que o lê de
 * `catalog.slotsPorFileira`. Escrever o 12 aqui seria ter o mesmo número em
 * dois lugares: no dia em que o `PAPEL_DO_SLOT` mudasse, a linha quebraria no
 * meio de um ofício — quatro slots de vida em cima e o quinto sozinho embaixo.
 * O 11 do fallback só vale enquanto o catálogo não chegou.
 *
 * O resto dos slots desce sozinho: são 22 numa grade de 11 colunas, então a
 * primeira fileira leva 11 e a segunda os 11 de ataque.
 *
 * ---- O tamanho: 52px, e ele já foi a 42 ----
 *
 * Ao virar duas fileiras o slot encolheu para 42 (sprite 34) para poupar
 * altura: duas fileiras de 52 custam 109px de tela, e o que está debaixo da
 * barra é o mapa. O dono pediu o tamanho de sempre de volta — o sprite grande
 * é o ponto da barra, e vinte e dois quadrados menores se leem pior do que
 * vinte e dois normais ocupando mais altura.
 *
 * Fica em 42, com o sprite em 34 (`SLOT_ICON`, no actionbar.mjs). Os dois
 * números andam juntos: mexer aqui pede mexer lá, e há uma nota de cada lado
 * dizendo isso.
 *
 * As molduras de bronze foram testadas e não ficaram: numa grade de vinte e
 * dois quadros ornamentados a barra vira uma cerca, e o que precisa saltar aos
 * olhos é o sprite da magia, não o encaixe.
 */
.hotbar {
  display: grid;
  grid-template-columns: repeat(var(--slots-por-fileira, 11), 42px);
  grid-auto-rows: 42px;
  /*
   * 5px, e não os 3px do primeiro aperto.
   *
   * O vão real entre dois quadros era 13px (5px de `gap` mais os 8px mortos que
   * a célula tinha a mais que o slot). Corrigido o slot para preencher a
   * célula, 3px de `gap` viraram 3px de verdade — e aí a fileira ficou apertada
   * demais, com os quadros quase se tocando. Cinco é o vão que se vê.
   */
  gap: 5px;
  flex: none;
}
/*
 * ---- O slot PREENCHE a célula ----
 *
 * Ele não preenchia, e isso passou muito tempo escondido: a célula media 52px e
 * o `.slot` (a regra genérica, dividida com o inventário) media 44. Sobravam
 * OITO pixels mortos em cada célula, que somados ao vão de 5px davam 13px entre
 * um slot e o vizinho — o dobro do que parecia estar escrito no CSS.
 *
 * Com o slot preenchendo, o tamanho dele passa a ser o da célula e há um número
 * só mandando nas duas coisas. Foi o que permitiu apertar a fileira sem os
 * quadros ficarem pequenos: os 52/44 viraram 42/42, e o slot encolheu 2px
 * enquanto a fileira encolheu mais de 130. E o `gap` voltou a significar o que
 * diz — antes ele mentia por 8px.
 */
.hotbar .slot { width: 100%; height: 100%; }
/*
 * ---- O contorno dos slots ----
 *
 * A borda de 1px chapada os deixava boiando dentro da barra; moldura desenhada,
 * já testada aqui, vira cerca (a nota lá em cima conta essa história).
 *
 * O meio-termo é este: um fio escuro POR DENTRO, que dá fundura ao quadro, e um
 * fio da cor do tema por fora. Custa dois `box-shadow` e nenhum arquivo, e
 * acompanha a moldura da barra sem competir com o sprite da magia.
 */
.hotbar .slot {
  background: #161d20; border: 1px solid #46656d; border-radius: 5px;
  /* Fio escuro por dentro, brilho de fora: o glow é fraco de propósito — doze
     deles em fila, num brilho forte, viram um letreiro. */
  box-shadow: inset 0 0 0 1px #0b0f10d9, 0 0 7px -1px #3fbfa866, 0 1px 2px #0006;
  display: grid; place-items: center; position: relative; cursor: pointer; color: #33403f;
}
.hotbar .slot:hover {
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px #0b0f10d9, 0 0 11px -1px #3fbfa8e6;
}
/* Slot com algo dentro puxa o verde do tema: dá para varrer a fila e ver o que
   está posto sem olhar sprite por sprite. */
.hotbar .slot.filled {
  border-color: #3fbfa899; background: #1c2529;
  box-shadow: inset 0 0 0 1px #0b0f10ff, 0 0 9px -1px #3fbfa88c, 0 1px 2px #0006;
}
/*
 * ---- Apagar a AÇÃO, e não o quadro ----
 *
 * `.off` é a magia que não pode sair agora — sem mana, em cooldown de grupo,
 * ainda não aprendida. A opacidade caía no slot INTEIRO, e junto com o sprite
 * iam embora a borda, o fio de dentro e o brilho: numa fila de doze, os slots
 * apagados pareciam estar sem contorno nenhum. Era o que o dono viu.
 *
 * Agora o desbotado é só do desenho. O quadro continua desenhado com a mesma
 * força — ele é o que diz "aqui tem alguma coisa posta", e isso não deixa de
 * ser verdade porque a magia está sem mana.
 */
.hotbar .slot.off > canvas,
.hotbar .slot.off > .spell-icon,
.hotbar .slot.off > .rune-mark { opacity: .45; }
/* Casa com o `SLOT_ICON` do actionbar.mjs — ver a nota lá sobre a folga. */
.hotbar .slot canvas { width: 34px; height: 34px; image-rendering: pixelated; }
.hotbar .slot .plus { font-size: 17px; color: #33403f; }
.hotbar .slot .rune-mark { font-family: var(--font-heading); font-size: 14px; color: var(--accent); }
/* Os crachás ficam DENTRO do slot. Pendurados para fora (top/right negativos)
   o vizinho da direita passava por cima deles, porque irmão que vem depois
   pinta em cima — era o meio-círculo laranja escondido atrás do ícone. */
.hotbar .slot .cond {
  position: absolute; top: 2px; right: 2px; font-style: normal; font-size: 10px; z-index: 2;
  border-radius: 999px; padding: 0 5px; line-height: 14px; pointer-events: none;
  background: var(--copper); color: #1a1208;
}
/* O número fica por cima do sprite, com fundo próprio: escondido atrás dele
   ninguém enxergava qual tecla era. */
.hotbar .slot .key {
  position: absolute; bottom: 0; left: 1px; font-size: 10px; line-height: 12px; padding: 0 4px;
  color: #d8cfb8; text-decoration: none; background: #0b0f10cc; border-radius: 3px; pointer-events: none;
}
.hotbar .slot canvas, .hotbar .slot .spell-icon { pointer-events: none; }
/*
 * ---- O leque do cooldown ----
 *
 * A sombra varre em círculo a partir das doze horas e some no sentido do
 * relógio: `--cd` é quanto FALTA, em porcentagem, e o `conic-gradient` pinta de
 * escuro do começo até ali. Uma barra de altura, que era o desenho antigo, não
 * diz de que lado do relógio a ação está — o ponteiro diz.
 *
 * O `from -90deg` é o que põe o zero em cima; sem ele o leque começaria às três
 * horas. E o `inset: 1px` continua: colada na beirada, a sombra pintava por
 * cima do fio de dentro e apagava o contorno justamente enquanto recarregava.
 */
.hotbar .slot .cooldown {
  position: absolute; inset: 1px; border-radius: 4px; pointer-events: none;
  background: conic-gradient(from -90deg, #000000b8 0%, #000000b8 var(--cd, 0%), transparent var(--cd, 0%));
}
.hotbar .slot .cooldown-text {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-size: 13px; font-weight: 700; color: #fff; text-shadow: 0 1px 3px #000; pointer-events: none;
}
.spell-icon { display: block; background-repeat: no-repeat; image-rendering: pixelated; }
.imbue-icon { image-rendering: pixelated; flex: none; }
.imbue-row .name { display: flex; align-items: center; gap: 10px; }

/* Coluna: os quatro sistemas em cima, alvo/distância/sair embaixo. O vão de
   cima já existia — a fileira é alta como a pilha dos slots e os selects são
   baixos —, então preenchê-lo não custa altura nenhuma à barra. */
/*
 * ---- Duas fileiras, cada controle do tamanho do que ele tem dentro ----
 *
 * Os quatro controles moravam numa tira horizontal só, com o rótulo EM CIMA do
 * seu controle. Com a barra de slots em duas fileiras a coluna da direita
 * ganhou altura de sobra e passou a faltar LARGURA, então eles se dobraram em
 * duas linhas e o rótulo deitou ao lado do controle.
 *
 * ---- A grade alinhada que NÃO ficou ----
 *
 * A primeira tentativa foi uma grade de quatro colunas com `display: contents`
 * nos `<label>`, para as bordas dos selects formarem duas linhas verticais. O
 * alinhamento saiu, e com ele um defeito que o dono viu na hora: a coluna do
 * controle tem a largura do MAIOR item dela, e o maior é o par do lure (dois
 * selects lado a lado). "Mais próximo", que é curto, era esticado até aquela
 * largura e ficava com um rombo vazio à direita.
 *
 * Alinhar exige que todo mundo tenha a largura do mais gordo. Numa barra que
 * disputa espaço com o mapa isso é caro demais para o que entrega — e o pedido
 * era o oposto: encolher. Então cada controle voltou a ter a largura do que
 * tem dentro, e o que alinha as duas fileiras é a borda DIREITA, que é a da
 * barra.
 */
/*
 * As duas fileiras de controle se espalham na altura da barra, em vez de se
 * amontoarem embaixo.
 *
 * Com `flex-end` elas ficavam coladas na base e deixavam 36px de vazio em cima
 * — e, pior, não tinham relação nenhuma com as fileiras de slots ao lado.
 * `space-around` põe cada uma no meio da sua metade, que é onde as duas
 * fileiras de slots já estão: "Alvo" fica na altura da fileira de cima e
 * "Lurar até" na da de baixo. O olho passa a ler a barra em duas faixas
 * horizontais inteiras, e não em três colunas soltas.
 */
/*
 * As duas fileiras JUNTAS, centradas na altura da coluna.
 *
 * Era `space-around`, e o motivo era bom: com o rótulo deitado ao lado, cada
 * fileira tinha 32px e o `space-around` as punha na altura das duas fileiras de
 * slots. Com o rótulo em cima elas passaram a 38px, e espalhar 76px de conteúdo
 * em 109px deixou um vão entre as duas grande o bastante para elas pararem de
 * se ler como um grupo — foi o "muita separação" que o dono viu.
 *
 * Centradas e com 6px entre si, as quatro caixas voltam a ser um bloco.
 */
/*
 * ---- Uma grade 2x2 de verdade, para as quatro caixas ficarem iguais ----
 *
 * Eram duas fileiras `flex`, e cada caixa tinha a largura do texto da opção
 * mais comprida dela: "Corpo a corpo" é maior que "Menos vida", "Voltar: auto"
 * é maior que "4 monstros". Quatro larguras diferentes em duas linhas, e
 * nenhuma borda alinhada com a de cima — foi o que o dono viu.
 *
 * Numa grade de duas colunas `1fr`, as duas ficam do tamanho da maior caixa
 * delas, e com `width: 100%` nos controles as quatro passam a medir o mesmo. O
 * alinhamento vertical vem junto, de graça.
 *
 * `display: contents` nas fileiras: elas somem como caixa e as `<label>` caem
 * direto nas células. Sem isso, cada fileira seria UMA célula e as caixas
 * dentro dela continuariam soltas.
 */
.controls {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 6px 5px;
  align-content: center;
  flex: none;
}
.controls-row { display: contents; }
/*
 * A fileira do lure ocupa as DUAS colunas e repete a mesma grade por dentro.
 *
 * Ela tem um `<label>` só, com os dois seletores num `.lure-dupla` — o "lurar
 * até" e o "voltar em N" são um controle de duas partes, e separá-los em duas
 * `<label>` pediria um rótulo para o segundo que não existe. Espalhando o label
 * pelas duas colunas e repetindo a grade lá dentro (mesmo número de colunas,
 * mesmo vão), o "voltar" cai exatamente sob a caixa da direita de cima.
 */
.controls-row:last-child > label { grid-column: 1 / -1; }
/*
 * As duas fileiras OCUPAM a mesma largura, em vez de se encostarem à direita.
 *
 * A largura da coluna é a da fileira mais larga — a de cima, com alvo e
 * distância. Encostada à direita, a de baixo (lurar + hunts, mais curta)
 * deixava uma faixa vazia à esquerda dela, entre ela e os slots: o mesmo tipo
 * de buraco que o `stretch` do `.bar-row` acabou de resolver na vertical.
 *
 * `space-between` empurra o primeiro item para o começo e o último para o fim,
 * e o vão vai para o MEIO da fileira, onde ele separa dois controles diferentes
 * em vez de ficar sobrando na beirada. Na fileira de cima, que já é do tamanho
 * da coluna, não sobra nada para distribuir e nada muda.
 */
/*
 * ---- `flex-end`, e a volta do `space-between` ----
 *
 * Houve um `space-between` aqui, e a razão era boa: a fileira de baixo era mais
 * curta que a de cima e, encostada à direita, deixava uma faixa vazia entre ela
 * e os slots. Espalhar resolveu aquilo.
 *
 * E criou o contrário assim que o "voltar: auto" apareceu — com dois selects, a
 * de BAIXO passou a ser a mais larga, e a sobra que o `space-between` distribuía
 * caiu no meio da fileira de CIMA, abrindo um rombo entre "Mais perto" e
 * "Distância". Era o mesmo vazio, do outro lado.
 *
 * `space-between` só serve quando se sabe qual fileira é a maior, e aqui isso
 * MUDA durante o jogo. Com o Hunts fora daqui (ver o HTML) as duas ficaram
 * parecidas, e basta encostá-las na borda de fora da barra: a sobra da mais
 * curta cai do lado dos SLOTS, onde ela se lê como o respiro que já existe
 * entre as colunas, e não como buraco.
 *
 * A borda de fora era a direita, e virou a esquerda quando as duas colunas
 * trocaram de lado — por isso `flex-start` e não `flex-end`.
 */

/*
 * Aqui eles são o que o jogador clica o tempo todo — proficiência, charms,
 * imbuements, prey — e não um enfeite espremido numa tira. Maiores que no card,
 * centrados sobre os dois seletores.
 */
.systems-dock { display: flex; justify-content: center; }
.systems-dock .hud-systems { display: flex; gap: 7px; margin-top: 0; }
.systems-dock .hud-system { width: 30px; height: 30px; border-radius: 6px; }
/*
 * ---- O rótulo ao LADO do controle, e não em cima ----
 *
 * Era um grid de duas linhas: rótulo em cima, select embaixo. Isso resolvia o
 * caso antigo, em que os quatro controles moravam numa tira horizontal só — em
 * pé eles ficariam altos demais para uma barra de uma fileira de slots.
 *
 * Com a barra em duas fileiras a conta inverteu: sobra ALTURA e falta LARGURA.
 * Deitado, cada controle perde a linha do rótulo e ganha a largura dela de
 * volta; empilhados em duas fileiras, os quatro cabem numa coluna bem mais
 * estreita e a barra inteira encurta junto.
 *
 * O rótulo alinha à direita para que o texto encoste no controle: com fileiras
 * de rótulos de tamanhos diferentes ("ALVO" e "DISTÂNCIA DO ALVO"), alinhar à
 * esquerda deixaria um vão irregular entre a palavra e a caixa.
 */
/*
 * ---- O rótulo volta para CIMA do controle ----
 *
 * Ele já foi assim, deitou ao lado, e volta. Não é indecisão: o que manda é o
 * que está apertado, e isso mudou duas vezes.
 *
 * Deitado, o rótulo custa LARGURA — "Lurar até" mais a caixa dele, na mesma
 * linha. Isso valeu a pena enquanto a barra tinha uma fileira de slots e altura
 * nenhuma para gastar. Com duas fileiras a coluna dos controles ganhou 109px de
 * altura e passou a usar 32 deles: sobra altura de novo, e a largura voltou a
 * ser o que falta.
 *
 * Em cima, cada controle fica com a largura da sua CAIXA e mais nada. A coluna
 * inteira encolhe pela largura de "alvo", "distância" e "lurar até" somadas.
 */
.controls label {
  font-family: var(--font-heading); font-weight: 600;
  display: flex; flex-direction: column; align-items: stretch; gap: 2px;
  font-size: 9px; color: var(--muted); text-transform: uppercase; letter-spacing: .08em;
}
/* `nowrap` porque o rótulo agora divide a linha com o controle: sem ele,
   "Lurar até" quebraria em duas e a fileira inteira cresceria de altura. */
/* `nowrap` para "Lurar até" não quebrar em duas e crescer a fileira; o rótulo
   fica encostado à esquerda da caixa que ele nomeia. */
.controls .rotulo { white-space: nowrap; line-height: 1.15; padding-left: 2px; }
/*
 * `.controls-row`, e não `.controls`: os quatro botões de sistema também são
 * `<button>` e moram dentro de `.controls`, então esta regra os pegava junto.
 * Ela dava a eles `padding: 6px 9px`, o que espremia a caixa de conteúdo para
 * 10x16 — o glifo de 20x20 transbordava e a grade o empurrava para um canto.
 * Era o quadrado de trás que não encaixava.
 */
/* O respiro lateral era 9px, de quando estes controles moravam sozinhos numa
   tira larga. Em duas fileiras eles disputam a largura da barra com os slots,
   e 6px de cada lado continuam confortáveis para clicar — o que aperta o dedo
   é a ALTURA, e ela não mudou. */
/*
 * ---- O fundo das caixas encolheu ----
 *
 * Eram `padding: 6px` com canto de 6px e texto de 12px. Numa tira horizontal
 * isso é o tamanho certo; em duas fileiras, cada pixel de enchimento vale
 * dobrado, e o retângulo arredondado passou a pesar mais na tela do que o texto
 * que ele contém — foi o que o dono viu ("o fundo arredondado ocupa muito
 * espaço").
 *
 * 3px em cima e embaixo tiram 6px de cada fileira sem encostar na área de
 * clique útil, que é a caixa inteira e não o enchimento. O canto vai a 4px:
 * arredondar 6px numa caixa de 24px de altura come a metade da borda reta.
 */
/*
 * ---- O mesmo quadro dos slots, nos controles ----
 *
 * Eles tinham `border: 1px solid var(--line)` e mais nada: um retângulo chapado
 * ao lado de vinte e dois slots com fio escuro por dentro e brilho por fora. Do
 * lado deles, os controles pareciam de outra tela.
 *
 * As três sombras são copiadas do `.hotbar .slot`, e a razão de cada uma é a
 * mesma de lá: o `inset` escuro dá fundura ao quadro, o brilho verde de fora o
 * amarra ao tema, e a sombra de 1px o descola do fundo. O brilho é fraco de
 * propósito — em fila, num brilho forte, viram um letreiro.
 */
.controls-row select, .controls-row button {
  background: #161d20; border: 1px solid #46656d; border-radius: 4px;
  box-shadow: inset 0 0 0 1px #0b0f10d9, 0 0 7px -1px #3fbfa866, 0 1px 2px #0006;
  padding: 3px 6px; font-size: 11px; cursor: pointer; white-space: nowrap;
}
.controls-row select:hover, .controls-row button:hover {
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px #0b0f10d9, 0 0 11px -1px #3fbfa8e6;
}
/* As quatro caixas preenchem a célula da grade: é o que as deixa do mesmo
   tamanho e alinha as bordas de cima com as de baixo. */
.controls-row select, .controls-row button { width: 100%; }

/*
 * ---- O ALVO no braço: ícone, palavra curta e setinha em pé (15/09) ----
 *
 * O dono: "é só a função de alvo, mas o ícone do alvo e a setinha na mesma
 * linha vertical, colado na barra pra economizar espaço", e depois "entre o
 * ícone e a setinha tipo prox, -vida, +vida". Na Caça Online e na Boss Diários
 * (`body.manual`) o Alvo é o único controle que sobra. A escolha em palavra
 * curta vem de `CONTROLES_DA_BARRA`, em main.mjs; o clique abre o menu do jogo
 * (`.alvo-menu`). Só no computador: no celular a barra tem a arrumação dela.
 */
@media (min-width: 901px) {
  body.manual .bar-row .controls { display: flex; align-items: center; gap: 0; }
  body.manual .bar-row .controls-row { display: contents; }
  body.manual .controls-row > label:has(#strategy) {
    flex-direction: column; align-items: center; gap: 4px;
    padding: 5px 3px; border-radius: 6px; cursor: pointer;
  }
  body.manual .controls-row > label:has(#strategy):hover { background: #ffffff08; }
  body.manual .controls-row > label:has(#strategy) > .rotulo {
    width: 16px; height: 16px; flex: none; padding: 0; overflow: hidden;
    font-size: 0; color: transparent; background: #7fd9c6;
    -webkit-mask: var(--icone) center / contain no-repeat; mask: var(--icone) center / contain no-repeat;
  }
  body.manual .controls-row #strategy {
    -webkit-appearance: none; appearance: none;
    width: 26px; min-width: 0; height: 16px; padding: 0;
    color: transparent; font-size: 11px; text-indent: -999px;
    background: #161d20 url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%237fd9c6' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E") center / 9px 6px no-repeat;
  }
  body.manual .controls-row .ctl-curto[data-para='strategy'] {
    display: block; font-family: var(--font-numero, inherit); font-size: 10px; font-weight: 500;
    line-height: 1; letter-spacing: .02em; text-transform: none; color: #cfeee6; white-space: nowrap;
  }

  /*
   * ---- Fora do braço: a arrumação de sempre, mais caprichada (15/09) ----
   *
   * O dono experimentou ícones e 2x2 na caçada automática e preferiu "deixa
   * como era antes, só deixa mais bonito". Então os mesmos quatro controles, no
   * mesmo lugar e do mesmo tamanho (Alvo e Distância em cima, Lurar e Voltar
   * embaixo, rótulo por cima da caixa), com: um ícone pequeno antes de cada
   * rótulo, a caixa com seta desenhada e cantos macios, e o menu do jogo no
   * lugar da lista branca do navegador.
   */
  body:not(.manual) .controls-row > label > .rotulo {
    display: inline-flex; align-items: center; gap: 4px; color: #8fb5ad;
  }
  body:not(.manual) .controls-row > label > .rotulo::before {
    content: ''; width: 10px; height: 10px; flex: none; background: #5fc4ae;
    -webkit-mask: var(--icone) center / contain no-repeat; mask: var(--icone) center / contain no-repeat;
  }
  body:not(.manual) .controls-row > label.lurando > .rotulo { color: var(--accent); }
  body:not(.manual) .controls-row > label.lurando > .rotulo::before { background: var(--accent); }
  body:not(.manual) .controls-row select {
    -webkit-appearance: none; appearance: none; cursor: pointer;
    padding: 4px 22px 4px 8px; border-radius: 6px;
    font-family: var(--font-heading); font-size: 10.5px; font-weight: 600; letter-spacing: .05em;
    color: #dcebe7; border: 1px solid #34494f;
    background:
      url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%237fd9c6' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E") right 8px center / 9px 6px no-repeat,
      linear-gradient(180deg, #1a2427, #121a1c);
    box-shadow: inset 0 1px 0 #ffffff0a, inset 0 0 0 1px #0b0f10d9, 0 1px 2px #0006;
    transition: border-color .15s, box-shadow .15s;
  }
  body:not(.manual) .controls-row select:hover {
    border-color: #4fd1b5;
    box-shadow: inset 0 1px 0 #ffffff0a, inset 0 0 0 1px #0b0f10d9, 0 0 10px -2px #4fd1b5aa;
  }
  body:not(.manual) .controls-row select option { color: #e7efef; background: #161d20; }

  /* Os ícones: mira (Alvo), setas (Distância), bichos puxados (Lurar), seta dando a volta (Voltar). */
  .controls-row > label:has(#strategy) > .rotulo {
    --icone: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='1.6'%3E%3Ccircle cx='8' cy='8' r='5'/%3E%3Ccircle cx='8' cy='8' r='1.4' fill='%23000'/%3E%3Cpath d='M8 0.5v3M8 12.5v3M0.5 8h3M12.5 8h3'/%3E%3C/svg%3E");
  }
  .controls-row > label:has(#distance) > .rotulo {
    --icone: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2 8h12M5 5L2 8l3 3M11 5l3 3-3 3'/%3E%3C/svg%3E");
  }
  .controls-row > label:has(#lure) > .rotulo {
    --icone: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3E%3Ccircle cx='3' cy='4' r='2'/%3E%3Ccircle cx='3' cy='12' r='2'/%3E%3Ccircle cx='8' cy='8' r='2'/%3E%3Cpath d='M11 5l4 3-4 3z'/%3E%3C/svg%3E");
  }
}
/* A palavra curta só existe no Alvo em pé do braço. */
.ctl-curto { display: none; }

/*
 * O menu dos seletores da barra (15/09): o lugar da lista branca do navegador,
 * quase igual a ela — um nome por linha, o escolhido aceso —, com o fundo
 * escuro e o verde da barra, colado na caixa clicada. Ver `abrirMenuDoSeletor`.
 */
.alvo-menu {
  position: fixed; z-index: 80;
  display: grid; gap: 1px; padding: 3px;
  max-height: min(60vh, 360px); overflow-y: auto;
  background: #111819; border: 1px solid #3a5a58; border-radius: 6px;
  box-shadow: 0 8px 20px #000b, 0 0 0 1px #0b0f10;
  animation: alvoMenuAbre .08s ease-out;
}
.alvo-menu button {
  display: block; width: 100%; text-align: left; white-space: nowrap; cursor: pointer;
  padding: 4px 10px; border: 0; border-radius: 4px; background: transparent;
  font-family: var(--font-heading); font-size: 10.5px; font-weight: 600; letter-spacing: .05em;
  text-transform: uppercase; color: #cfe1dd;
}
.alvo-menu button:hover:not(:disabled) { background: #1d2c2f; color: #eafffb; }
.alvo-menu button.ativo { background: #1f6f62; color: #eafffb; }
.alvo-menu button.ativo:hover { background: #24806f; }
.alvo-menu button:disabled { opacity: .35; cursor: not-allowed; }
@keyframes alvoMenuAbre { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .alvo-menu { animation: none; } }
/*
 * A nota abaixo é de quando os controles eram uma fileira flex.
 *
 * Houve um `width: 100%` para as bordas dos selects se alinharem em coluna. Ele
 * esticava os curtos até a largura do mais largo da coluna — "Mais próximo"
 * ficava com um rombo vazio à direita por causa do par do lure, que é o item
 * mais gordo. Ver a nota em `.controls`.
 *
 * Sem ele, o `<select>` faz o que o navegador já faz bem: fica da largura da
 * MAIOR opção da lista. Isso é mais apertado que a coluna alinhada e, o que
 * importa mais, é estável — a caixa não muda de tamanho quando o jogador troca
 * a opção, que é o que aconteceria se a largura seguisse o texto escolhido.
 */
.controls-row button.danger:hover { border-color: var(--danger); color: #ffd9d6; }

/* ---------- menu de contexto ---------- */

/*
 * ---- O menu do botão direito ----
 *
 * Ele era uma caixa cinza com texto cinza: nada dizia de QUEM era o menu, a
 * opção apagada tinha a mesma forma da ligada, e o passar do mouse mudava só o
 * fundo. Numa lista de seis linhas parecidas, cada clique pedia uma leitura
 * inteira.
 *
 * Três coisas mudam isso, e nenhuma delas é enfeite:
 *
 *   - a CABEÇA (`.menu-cabeca`) com o desenho e o nome, para o menu se
 *     apresentar antes de a pessoa ler a primeira opção;
 *   - uma barra de acento que cresce à esquerda da linha sob o mouse — o olho
 *     acha a linha ativa sem procurar;
 *   - a linha apagada com metade do peso, e o porquê no balão.
 */
#context-menu {
  position: fixed; z-index: 80; min-width: 226px; max-width: 300px; padding: 5px;
  background: linear-gradient(180deg, #16232a, var(--panel-solid));
  border: 1px solid var(--line); border-radius: 9px;
  box-shadow: 0 16px 40px #000c, 0 0 0 1px #00000060;
  display: flex; flex-direction: column;
  animation: menu-abre .11s ease-out;
}
@keyframes menu-abre {
  from { opacity: 0; transform: translateY(-4px) scale(.985); }
  to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) { #context-menu { animation: none; } }

/* A cabeça: o desenho à esquerda, o nome e o contexto à direita. */
.menu-cabeca {
  display: flex; align-items: center; gap: 9px;
  padding: 7px 9px 8px; margin-bottom: 3px;
  border-bottom: 1px solid var(--line-soft);
}
.menu-cabeca canvas { image-rendering: pixelated; flex: none; }
.menu-cabeca-texto { display: grid; gap: 1px; min-width: 0; }
/* A cor é a da raridade (`--tier`, posta pela classe na cabeça), a mesma do
   balão. O verde do tema é o padrão de quem não tem raridade — gente. */
.menu-cabeca-texto b {
  font-family: var(--font-heading); font-size: 13px; color: var(--tier, var(--accent));
  text-transform: capitalize; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.menu-cabeca-texto em {
  font-style: normal; font-size: 10px; letter-spacing: .05em;
  text-transform: uppercase; color: var(--muted);
}

/* =========================================================================
 * O BLOCO DA GUILDA NO MENU
 *
 * "abaixo do cabeçalho, com um divisor fino, uma linha: Guilda: (rótulo pequeno,
 *  cor discreta) à esquerda e o nome da guilda na fonte da guilda, com › no fim.
 *  Logo abaixo, o brasão (~28px) e ao lado dele o cargo em texto pequeno."
 *
 * ---- O QUE ESTAVA AQUI ANTES ----
 *
 * Duas peças dentro do cabeçalho: uma LINHA com o nome, na terceira altura do
 * texto, e um SELO com o escudo de 30px na ponta direita. As duas saíram, e o
 * motivo está na nota do `blocoDaGuilda` (em `social.mjs`): eram as duas metades da
 * mesma informação em lados opostos, e nenhuma delas dizia "guilda". A linha, logo
 * abaixo de "level 300" e com a mesma cara, lia-se como um segundo subtítulo do
 * personagem; o escudo, sem legenda, como enfeite.
 *
 * ---- POR QUE UM BOTAO, E NAO UMA CAIXA COM UM LINK DENTRO ----
 *
 * "o bloco inteiro é clicável, com hover."
 *
 * O alvo de clique passa de um nome de oito letras para uma caixa de duas linhas.
 * Num menu que abre com o botão direito num personagem que anda, essa diferença é a
 * diferença entre abrir a guilda e fechar o menu sem querer.
 *
 * `all: unset` e não `background: none`: é um `<button>`, e o navegador lhe dá
 * borda, enchimento, fonte própria e alinhamento de formulário. Sem zerar tudo, ele
 * se levanta uma linha acima do resto do menu.
 * ========================================================================= */
.menu-guilda-bloco {
  all: unset;
  box-sizing: border-box;
  display: grid; gap: 3px;
  width: 100%;
  /*
   * O mesmo enchimento das opções do menu (`7px 10px 7px 13px`), para o bloco ficar
   * na mesma coluna do texto delas — ele fica logo abaixo do divisor, e duas
   * margens esquerdas diferentes a três pixels de distância se veem.
   */
  padding: 6px 10px 7px 13px;
  border-radius: 6px;
  cursor: pointer;
  transition: background .12s;
}
.menu-guilda-bloco:hover { background: #ffffff0f; }
.menu-guilda-bloco:focus-visible { outline: 1px solid #e0a84a99; outline-offset: -2px; }

/* ---- A primeira linha: o rótulo, o ESCUDO, o nome e a seta ---- */
/*
 * `align-items: center` e não `baseline`: o escudo é uma caixa de 24px sem linha de
 * base, e com `baseline` o navegador alinha o pé dele com a base do texto — o escudo
 * sobe meia altura e o rótulo desce.
 */
.menu-guilda-topo { display: flex; align-items: center; gap: 6px; min-width: 0; }
.menu-guilda-topo .guilda-brasao { flex: none; }
/*
 * O rótulo é a palavra que faltava: é ela que faz o resto do bloco ser lido como
 * guilda, e não como personagem. Apagado e em versalete, do mesmo jeito que o
 * subtítulo do cabeçalho — ele nomeia o campo, não é o campo.
 */
.menu-guilda-rotulo {
  flex: none;
  font-style: normal; font-size: 9.5px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--muted);
}
/*
 * A FAMÍLIA vem do `style` do nó (a fonte que a guilda escolheu) e o corte com
 * reticências vem da `.guilda-nome-fonte`, injetada pelo desenhista do brasão. Aqui
 * ficam só o tamanho e a cor: "onde o espaço é pequeno, manter o tamanho de letra
 * atual; só a família muda".
 */
.menu-guilda-nome {
  min-width: 0;
  font-size: 12px; font-weight: 600; color: #ffd98a;
}
/* A seta promete que o bloco abre alguma coisa. Ela anda um pixel no hover. */
.menu-guilda-seta {
  flex: none; margin-left: auto;
  font-size: 13px; line-height: 1; color: #8a6f42;
  transition: transform .12s, color .12s;
}
.menu-guilda-bloco:hover .menu-guilda-seta { color: #e0a84a; transform: translateX(2px); }

/* ---- A segunda linha: o escudo e o cargo ---- */
/*
 * A segunda linha é só o cargo, e ela é recuada até debaixo do nome: o escudo subiu
 * para a linha de cima (ver a nota no `blocoDaGuilda`), e um "Líder" começando na
 * margem esquerda pareceria uma linha nova em vez do complemento do nome.
 */
.menu-guilda-baixo { display: flex; align-items: center; gap: 7px; min-width: 0; padding-left: 31px; }
/*
 * As cores do posto são as MESMAS do site (`.guilda-posto`, em `site.css`): ouro
 * para o líder, bronze para o vice, apagado para o membro. Uma pessoa que é vice
 * tem de ser vice da mesma cor nas duas telas.
 */
.menu-guilda-cargo {
  font-style: normal; font-size: 10px; letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.menu-guilda-cargo.cargo-3 { color: #ffd98a; }
.menu-guilda-cargo.cargo-2 { color: #cbb388; }

#context-menu button {
  position: relative;
  text-align: left; background: none; border: none; padding: 7px 10px 7px 13px; cursor: pointer;
  border-radius: 6px; font-size: 12px; color: var(--text);
  transition: background .1s ease, color .1s ease;
}
/* A barra de acento cresce de cima para baixo na linha sob o mouse. */
#context-menu button::before {
  content: ''; position: absolute; left: 4px; top: 50%; transform: translateY(-50%);
  width: 2px; height: 0; border-radius: 2px; background: var(--accent);
  transition: height .12s ease;
}
#context-menu button:hover:not(:disabled) { background: #1d3038; color: #fff; }
#context-menu button:hover:not(:disabled)::before { height: 60%; }
#context-menu button:disabled { color: #4a585c; cursor: default; }
#context-menu button.danger { color: #f0a89f; }
#context-menu button.danger:hover:not(:disabled) { background: #3a1d1a; color: #ffd9d6; }
#context-menu button.danger::before { background: #c0533f; }
#context-menu hr { border: none; border-top: 1px solid var(--line-soft); margin: 4px 8px; }
@media (prefers-reduced-motion: reduce) { #context-menu button, #context-menu button::before { transition: none; } }

/* ---------- conteúdo das janelas ---------- */

.empty { color: var(--muted); font-size: 12px; margin: 4px 0; font-style: italic; }
.wide {
  width: 100%; background: var(--panel-2); border: 1px solid var(--line); border-radius: 6px;
  padding: 7px; cursor: pointer; font-size: 12px; margin-top: 8px;
}
.wide:hover:not(:disabled) { border-color: var(--accent-dim); color: #fff; }
.wide:disabled { opacity: .5; cursor: not-allowed; }
.wide em { font-style: normal; color: var(--copper); }

/* Sete abas numa linha só: gaps e paddings curtos, e sem quebrar. */
.chat-tabs { display: flex; gap: 2px; margin-bottom: 4px; flex: none; overflow-x: auto; scrollbar-width: none; }
.chat-tabs button {
  background: var(--panel-2); border: 1px solid var(--line-soft); border-radius: 5px;
  padding: 2px 5px; cursor: pointer; font-size: 10.5px; position: relative; white-space: nowrap; flex: none;
}
.chat-tabs button[aria-selected="true"] { border-color: var(--accent); color: var(--accent); }
/*
 * A marca de mensagem nova é VERDE, a cor do tema.
 *
 * Era cobre (`--copper`), que é a cor do ouro e do loot no resto do jogo — num
 * canto onde tudo mais é verde-água ela puxava o olho para o lugar errado e
 * ficava, nas palavras do dono, feia.
 */
.chat-tabs button i {
  font-style: normal; font-size: 9px; background: var(--accent); color: #08110f;
  border-radius: 999px; padding: 0 4px; margin-left: 4px;
}
/*
 * A marca das abas que o jogo escreve sozinho (Combate, Loot) e' um PONTO, e
 * nao um numero — o porque esta' em `chat.mjs`, em `TETO_DO_NUMERO`. Aqui ele
 * so' vira uma bolinha de verdade: sem o texto deslocando a linha de base, e
 * com largura fixa, para a aba nao mudar de tamanho quando o ponto acende.
 */
.chat-tabs button i.chat-ponto {
  font-size: 0; line-height: 0; width: 6px; height: 6px; padding: 0;
  display: inline-block; vertical-align: middle;
}
.chat-log {
  flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 2px; font-size: 12px; min-height: 0;
  user-select: text; -webkit-user-select: text;
}
/*
 * ---- O chat FLUTUANTE (◐ no cabeçalho do chat, ou Ajustes → Interface) ----
 *
 * Sem moldura e sem fundo, como o chat de jogo de tiro: as falas soltas por
 * cima do mapa, com sombra forte para ler em qualquer chão. Título, abas e
 * caixa de texto só aparecem com o mouse em cima ou escrevendo; as falas
 * velhas (`chat-velha`, ver `apagarFalasVelhas`) somem até lá.
 */
.window.chat-flutuante {
  border-image: none; border-color: transparent;
  border-width: 26px 4px 4px 4px;
  transition: background .2s ease;
}
.window.chat-flutuante:hover,
.window.chat-flutuante:focus-within { background: #05080980; border-radius: 6px; }
/*
 * O que some no flutuante: tudo que é moldura — o cabeçalho, as abas, a caixa,
 * e também as partes novas do miolo dividido (a lista de conversas, as
 * categorias dos Logs, o cabeçalho da conversa, a barra de "respondendo").
 * Só as falas ficam por cima do mapa; o mouse em cima traz o resto de volta.
 */
.window.chat-flutuante > header,
.window.chat-flutuante .chat-tabs,
.window.chat-flutuante .chat-lateral,
.window.chat-flutuante .chat-conversa-cabecalho,
.window.chat-flutuante .chat-respondendo,
.window.chat-flutuante .chat-vazio,
.window.chat-flutuante .chat-form { opacity: 0; transition: opacity .2s ease; }
.window.chat-flutuante:hover > header,
.window.chat-flutuante:hover .chat-tabs,
.window.chat-flutuante:hover .chat-lateral,
.window.chat-flutuante:hover .chat-conversa-cabecalho,
.window.chat-flutuante:hover .chat-respondendo,
.window.chat-flutuante:hover .chat-form,
.window.chat-flutuante:focus-within > header,
.window.chat-flutuante:focus-within .chat-tabs,
.window.chat-flutuante:focus-within .chat-lateral,
.window.chat-flutuante:focus-within .chat-conversa-cabecalho,
.window.chat-flutuante:focus-within .chat-respondendo,
.window.chat-flutuante:hover .chat-vazio,
.window.chat-flutuante:focus-within .chat-vazio,
.window.chat-flutuante:focus-within .chat-form { opacity: 1; }
/* E os botões da lateral sem fundo próprio: no flutuante o fundo é o mapa. */
.window.chat-flutuante .chat-lateral { border-right-color: transparent; }
.window.chat-flutuante .chat-lateral button { background: none; text-shadow: 0 1px 2px #000, 0 0 4px #000; }
.window.chat-flutuante .chat-lateral button[aria-selected="true"] { background: #05080980; }
/*
 * A barra de rolagem some junto com a moldura.
 *
 * A regra escondia a barra do `.window-body`, mas quem rola é o `.chat-log`
 * (é ele que tem `overflow-y: auto`): a trilha cinza de 8px continuava em pé
 * ao lado das falas, a única peça de moldura que sobrava sobre o mapa ("a
 * barra de scroll no modo transparente do chat tem que sumir também"). Vale
 * para a lista de conversas também. A rolagem continua (roda do mouse, dedo);
 * o mouse em cima traz a barra de volta com o resto da moldura. O
 * `::-webkit-scrollbar` é para o Safari velho, que não conhece `scrollbar-width`.
 */
.window.chat-flutuante .window-body,
.window.chat-flutuante .chat-log,
.window.chat-flutuante .chat-lateral { scrollbar-width: none; }
.window.chat-flutuante .window-body::-webkit-scrollbar,
.window.chat-flutuante .chat-log::-webkit-scrollbar,
.window.chat-flutuante .chat-lateral::-webkit-scrollbar { display: none; width: 0; height: 0; }
.window.chat-flutuante:hover .window-body,
.window.chat-flutuante:hover .chat-log,
.window.chat-flutuante:hover .chat-lateral { scrollbar-width: thin; }
.window.chat-flutuante:hover .window-body::-webkit-scrollbar,
.window.chat-flutuante:hover .chat-log::-webkit-scrollbar,
.window.chat-flutuante:hover .chat-lateral::-webkit-scrollbar { display: block; width: 8px; }
.window.chat-flutuante .chat-log {
  font-size: 12.5px; color: #f2f6f5;
  text-shadow: 0 1px 1px #000, 0 0 3px #000, 0 0 6px #000c;
}
.window.chat-flutuante .chat-log > div { transition: opacity .8s ease; }
.window.chat-flutuante .chat-log > div.chat-velha { opacity: 0; }
.window.chat-flutuante:hover .chat-log > div.chat-velha,
.window.chat-flutuante:focus-within .chat-log > div.chat-velha { opacity: 1; transition-duration: .15s; }
.window.chat-flutuante .chat-form input { background: #000a; }
.window > header .chat-flutuar[aria-pressed="true"] { color: var(--accent); }
.chat-log .who { color: var(--accent); }
.chat-log .lvl { color: var(--muted); font-size: 11px; }
/* O ícone da vocação, na frente do nome. Ver `seloDaVocacao` em chat.mjs. */
.chat-log .vocacao-no-chat {
  width: 15px; height: 15px; vertical-align: -3px;
  margin-right: 4px; opacity: .9;
}
.chat-log .sys { color: var(--copper); font-style: italic; }
.chat-log .hit { color: #cfe3e0; }
.chat-log .hurt { color: #e08a84; }
.chat-log .kill { color: var(--accent); }
.chat-log .heal { color: var(--hp); }
.chat-log .loot-line { color: var(--copper); }

/*
 * ---- [FATAL] e [CRÍTICO] no combate ----
 *
 * As cores dos dois efeitos que sobem no mapa: o roxo do FATAL! e o vermelho do
 * CRIT!. Quem vê um na tela reconhece o outro no chat.
 */
.chat-log .marca-do-golpe { font-weight: 700; letter-spacing: .03em; }
.chat-log .marca-fatal { color: #c77dff; text-shadow: 0 0 6px #9d4edd99; }
.chat-log .marca-critico { color: #ff5a4a; text-shadow: 0 0 6px #ff3b2e80; }

.chat-log .say { color: #f36500; }
.chat-log .loot-line.empty { color: var(--muted); }
.chat-log .loot-line.nocap { color: #ff8a7a; }
.chat-log .loot-line.charm { color: var(--accent); }
/*
 * A fileira de cada pessoa na linha de loot em grupo. Ver `loot-pessoa`, no
 * chat.mjs: o nome primeiro, numa coluna, e o que foi dela ao lado — a
 * segunda linha de uma fileira longa recua até a mesma coluna, e o nome nunca
 * se mistura com as peças.
 */
.chat-log .loot-pessoa {
  display: grid; grid-template-columns: minmax(52px, auto) 1fr; column-gap: 6px;
  margin: 2px 0 0 10px; padding-left: 6px;
  border-left: 1px solid #c8874a40;
}
.chat-log .loot-quem { color: var(--muted); font-weight: 600; }
/* "ver loot de um jogador": discreto, da cor apagada do texto, e só acende no dedo. */
.chat-log .loot-nada { color: var(--muted); }
.chat-log .loot-ver { display: inline-flex; flex-wrap: wrap; gap: 4px; vertical-align: baseline; }
.chat-log .loot-ver-botao {
  background: none; border: 1px solid #c8874a40; border-radius: 4px;
  padding: 0 5px; font: inherit; font-size: 11px; line-height: 16px;
  color: var(--muted); cursor: pointer;
}
.chat-log .loot-ver-botao:hover { color: var(--copper); border-color: #c8874a99; }
.chat-log .loot-ver-botao.aberto { color: var(--copper); border-color: var(--copper); }
/*
 * O balão do "ver loot de um jogador" ao passar o mouse. Mora no `body`, fora do
 * chat (que corta o que passa da borda), então repete as cores da linha de loot
 * que o `.chat-log` daria.
 */
.loot-balao {
  position: fixed; z-index: 9000; pointer-events: none;
  max-width: min(360px, calc(100vw - 12px));
  padding: 6px 9px;
  background: #0d1214f5; border: 1px solid #c8874a80; border-radius: 6px;
  box-shadow: 0 6px 18px #000a;
  color: var(--copper); font-size: 12px; line-height: 1.4;
}
.loot-balao .loot-pessoa { display: grid; grid-template-columns: auto 1fr; column-gap: 8px; }
.loot-balao .loot-quem { color: var(--muted); font-weight: 600; }
.loot-balao [class^="tier-"] { color: var(--tier) !important; font-weight: 600; }

/*
 * ---- A RARIDADE dentro da linha de loot ----
 *
 * "o chat de loot poderia indicar as raridades no texto. no fluxo normal fica
 * só um bloco de texto a ser acompanhado."
 *
 * Duas marcas, e elas servem a duas leituras diferentes:
 *
 *   - o NOME de cada peça sai na cor da raridade dela (as mesmas `--tier` do
 *     balão e do mercado). É para quem está lendo a linha.
 *   - e a LINHA ganha uma barrinha na margem, da melhor raridade que caiu ali.
 *     É para quem NÃO está lendo: correndo o canal para baixo, o olho pega a
 *     cor na margem e sabe onde parar. Só a partir de "raro" — ver
 *     `MARCA_A_PARTIR_DE`, no chat.mjs.
 *
 * O `!important` na cor do nome é porque `.chat-log .loot-line` pinta a linha
 * inteira de cobre, e ela é mais específica que a classe de uma palavra dentro.
 */
.chat-log .loot-line [class^="tier-"] { color: var(--tier) !important; font-weight: 600; }
.chat-log .loot-line[class*="tem-tier-"] {
  position: relative;
  padding-left: 7px;
}
.chat-log .loot-line[class*="tem-tier-"]::before {
  content: ''; position: absolute; left: 0; top: 1px; bottom: 1px;
  width: 3px; border-radius: 2px; background: var(--marca-do-loot);
}
.chat-log .loot-line.tem-tier-raro { --marca-do-loot: #57a6e8; }
.chat-log .loot-line.tem-tier-epico { --marca-do-loot: #b184e8; }
.chat-log .loot-line.tem-tier-lendario { --marca-do-loot: #e0a84a; }
.chat-log .loot-line.tem-tier-mitico { --marca-do-loot: #f2503f; }
.chat-readonly { color: var(--muted); font-size: 11px; font-style: italic; margin: 6px 0 0; flex: none; }
/* `relative` é o que ancora a gaveta de emotes, que sobe por cima da conversa. */
.chat-form { display: flex; gap: 4px; margin-top: 4px; flex: none; position: relative; }
.chat-form input { flex: 1; min-width: 0; background: #080b0c; border: 1px solid var(--line); border-radius: 6px; padding: 5px 8px; }
.chat-form input:disabled { opacity: .5; }
.chat-form input:focus { outline: none; border-color: var(--accent-dim); }
.chat-form button { background: var(--panel-2); border: 1px solid var(--line); border-radius: 6px; padding: 6px 11px; cursor: pointer; }
/*
 * O áudio do chat. O 🎤 é do tamanho do ☺; gravando, ele vira um botão vermelho
 * com o relógio, para ninguém esquecer o microfone aberto.
 */
.chat-form .chat-mic { padding: 6px 8px; font-variant-numeric: tabular-nums; }
.chat-form .chat-mic:disabled { opacity: .45; cursor: not-allowed; }
.chat-form .chat-mic.gravando {
  background: #5a1d1a; border-color: #e0564a; color: #ffe1dc; min-width: 64px;
  animation: chat-mic-pulso 1.2s ease-in-out infinite;
}
.chat-form .chat-mic-cancelar { padding: 6px 8px; color: var(--muted); }
@keyframes chat-mic-pulso { 50% { box-shadow: 0 0 10px #e0564a99; } }
.chat-log .chat-audio {
  display: inline-flex; align-items: center; gap: 4px; vertical-align: middle;
  background: #10231f; border: 1px solid var(--accent-dim); color: var(--accent); border-radius: 999px;
  padding: 1px 10px; font-size: 11px; cursor: pointer; font-variant-numeric: tabular-nums;
}
.chat-log .chat-audio:hover { border-color: var(--accent); }
.chat-log .chat-audio.expirado { background: none; border-color: var(--line); color: var(--muted); cursor: default; font-style: italic; }
/*
 * O áudio que o navegador RECUSOU tocar. Ver `naoDeuParaTocar`, no chat.mjs:
 * antes ele falhava calado e o botão só piscava, que é o que fez o report
 * chegar como "o áudio dos outros não toca" em vez de "o navegador bloqueou".
 * Vermelho e com o motivo no title, para a próxima vez ter o que contar.
 */
.chat-log .chat-audio.mudo { border-color: #a33; color: #ff8a7a; }

.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 10px; }
.grid2 div { display: grid; }
.grid2 b { font-family: var(--font-heading); font-weight: 600; font-size: 9px; color: var(--muted); text-transform: uppercase; letter-spacing: .08em; }
.grid2 span { font-size: 13px; color: #e4ecec; }
.tally { margin-top: 10px; display: grid; gap: 3px; font-size: 12px; color: var(--muted); }
.tally b { color: var(--text); font-weight: 500; }

/* ---------- inventário ---------- */

/* 4px, e nao 10: a capacidade fica logo abaixo das botas e os dez pixels
   viravam um degrau no meio de tres pecas que sao a mesma coisa. */
.equipment { display: grid; grid-template-columns: repeat(3, 44px); gap: 4px; justify-content: center; margin-bottom: 4px; }
.slot {
  width: 44px; height: 44px; background: #161d20; border: 1px solid var(--line-soft);
  border-radius: 5px; display: grid; place-items: center; cursor: pointer; position: relative;
}
.slot:hover { border-color: var(--accent-dim); }
.slot.drop-target { border-color: var(--accent); background: #1a2c29; }
.slot small { position: absolute; inset: 0; display: grid; place-items: center; font-size: 8px; color: #40504f; }
.slot-art { width: 32px; height: 32px; image-rendering: pixelated; opacity: .5; }
.slot:hover .slot-art { opacity: .8; }
.slot canvas { width: 32px; height: 32px; }
.slot .imbued {
  position: absolute; bottom: 1px; left: 2px; font-style: normal; font-size: 9px;
  color: #9fe6ff; text-shadow: 0 0 4px #2b6d8a;
}
/*
 * A capacidade fecha o inventário, centrada e colada no rodapé da janela.
 *
 * `margin-top: auto` só empurra dentro de um flex, então o corpo do inventário
 * vira coluna: o grid do equipamento em cima, a linha de peso lá embaixo,
 * qualquer altura que a janela tenha.
 */
/* Sem barra de rolagem: a janela tem a altura exata do que está dentro dela, e
   uma barra de 2px de sobra só sujava a moldura. */
.window[data-window-id="inventory"] .window-body {
  display: flex; flex-direction: column; overflow: hidden;
  /* 2px em vez dos 6 de todas as outras: esta janela nao estica e nao rola,
     entao o recheio do rodape virava sobra de moldura embaixo da lixeira. */
  padding-bottom: 2px;
}
/* Miúda e no rodapé, ao lado da capacidade: ela é um destino de arrasto, não um
   botão — ninguém precisa vê-la até estar carregando um item. */
/*
 * Sem `margin-top: auto`.
 *
 * Ele empurrava a lixeira para o rodapé da janela, e o que ficava entre a
 * última fileira do equipamento e ela era um buraco do tamanho da sobra —
 * quanto mais alta a janela, maior o vazio. Agora as três peças (grade,
 * capacidade, lixeira) vêm coladas, uma atrás da outra, logo abaixo das botas.
 */
.inv-trash {
  margin-top: 4px; display: flex; align-items: center; justify-content: center; gap: 6px;
  padding: 4px; border: 1px dashed var(--line); border-radius: 6px;
  font-size: 10px; color: #55646a; transition: all .15s ease;
}
.inv-trash b { font-family: var(--font-heading); font-weight: 600; letter-spacing: .06em; }
.inv-trash-can { font-size: 13px; line-height: 1; }
/* Com o item por cima ela acende em vermelho: é a última parada dele. */
.inv-trash.over {
  border-style: solid; border-color: var(--danger); color: #ff8a7a;
  background: #2a11119c; box-shadow: inset 0 0 12px #a3333344;
}
/*
 * A capacidade: só a barra, colada na grade do equipamento.
 *
 * O rótulo "Capacidade" saiu de cima e virou o "Cap" de dentro da barra — a
 * barra já tem um texto centrado, e uma linha inteira para repetir o nome do
 * que está logo abaixo era altura gasta à toa numa janela que não estica.
 */
.inv-cap {
  margin-top: 0; padding-top: 4px;
  border-top: 1px solid var(--line-soft);
}
.inv-cap b { font-size: 12px; color: #e4ecec; }
/*
 * As três cores da carga, nos mesmos tons da stamina — verde é "pode pegar",
 * amarelo é "está enchendo", vermelho é "o próximo pode não caber". Repetir a
 * paleta é de propósito: o jogador só precisa aprender o código uma vez.
 */
/* As duas abas opcionais do chat, dentro da caixinha do `+`. */
.chat-abas-opcionais { display: flex; gap: 14px; justify-content: center; margin: 4px 0 2px; }
.chat-aba-opcao {
  display: flex; align-items: center; gap: 5px; cursor: pointer;
  font-size: 12px; color: var(--muted);
}
.chat-aba-opcao:hover { color: #e4ecec; }
.chat-aba-opcao input { cursor: pointer; accent-color: var(--accent); }

.hud-bar.cap { height: 14px; }
.hud-bar.cap i { --liq-a: #6ddb96; --liq-b: #25794a; }
.hud-bar.cap[data-grau="enchendo"] i { --liq-a: #f0cf7a; --liq-b: #a8781f; }
.hud-bar.cap[data-grau="cheia"] i { --liq-a: #ef6a52; --liq-b: #a81f14; }

/* Cabeçalho da bolsa: contagem à esquerda, interruptor da venda à direita, tudo
   numa linha só — a janela é estreita e o texto quebrava no meio. */
/*
 * ---- A linha de cima da bolsa e da mochila ----
 *
 * Ela tinha `nowrap` e nada que pudesse encolher: numa janela estreita o
 * conteúdo transbordava para fora do painel (report de um jogador, "os textos e
 * ícones dos botões vazam pra fora"). Ligar só a quebra piorava de outro jeito
 * — o último botão caía sozinho numa segunda linha e o `space-between` o
 * empurrava para a esquerda, que é a "inversão do Vender com o Limpar" que o
 * dono viu.
 *
 * Agora: os botões moram num bloco (`.bag-botoes`) que nunca encolhe e nunca se
 * separa, e quem cede espaço é o texto da esquerda, com reticências. Quando nem
 * assim cabe, a linha quebra com os dois botões JUNTOS e ainda à direita.
 */
.bagline {
  display: flex; align-items: center; justify-content: space-between; gap: 6px 8px;
  flex-wrap: wrap;
  font-size: 11px; color: var(--muted); margin-bottom: 6px;
}
/* O que pode encolher: o nome da mochila e o relógio da venda. */
.bagline > .bag-titulo, .bagline > .bag-timer {
  flex: 1 1 auto; min-width: 0; display: inline-flex; align-items: center; gap: 5px;
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}
.bagline > .bag-titulo > span { overflow: hidden; text-overflow: ellipsis; }
/* O que não encolhe nem se separa: os botões, sempre nesta ordem e à direita. */
.bagline .bag-botoes {
  display: flex; align-items: center; gap: 6px; flex: none; margin-left: auto;
}
/* Dentro do bloco o "+" perde o empurrão que ele dava sozinho na linha. */
.bagline .bag-botoes .bag-timer-buy { margin-left: 0; }
/* Sem isto o rótulo de nove pixels ainda espremia numa janela bem estreita. */
.bagline .bag-clear { min-width: max-content; }
.bag { display: grid; grid-template-columns: repeat(auto-fill, 44px); gap: 5px; align-content: start; min-height: 48px; }
/* aviso de vazio ocupa a linha toda, senão o texto quebra letra a letra */
.bag .empty, .depot-grid .empty { grid-column: 1 / -1; }
.cell {
  width: 44px; height: 44px; background: #161d20; border: 1px solid var(--line-soft);
  border-radius: 5px; display: grid; place-items: center; position: relative; cursor: pointer;
}
.cell:hover { border-color: var(--accent-dim); }
/*
 * ---- O quadradinho fixo da Boss Pouch, no começo da mochila ----
 *
 * Ele tem de se ler como LUGAR e não como item: a borda de cobre é a mesma que
 * o jogo já usa para "esta peça é especial" (`.cell.protected`), e o fundo mais
 * quente o separa das peças soltas ao redor sem inventar uma cor nova. Quem
 * olha a mochila vê onde clicar sem precisar ler nada.
 */
.cell.boss-pouch-cell {
  border-color: var(--copper);
  background: linear-gradient(180deg, #241d15, #161d20);
}
.cell.boss-pouch-cell:hover { border-color: var(--accent); }
/*
 * A faixa dela, entre o cabeçalho da mochila e a grade.
 *
 * Ela é uma linha e não um quadradinho solto porque precisa dizer o que é: um
 * saco dourado sem legenda, no meio de uma mochila cheia de sacos, seria só
 * mais um item. O nome e a contagem ficam ao lado, no tamanho do resto da
 * janela.
 */
.bag-boss-pouch {
  display: flex; align-items: center; gap: 8px; margin: 2px 0 6px;
  padding-bottom: 6px; border-bottom: 1px solid var(--line-soft);
}
.bag-boss-pouch-texto { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }
/*
 * A Store Inbox (15/09) mora na mesma faixa, ao lado da Boss Pouch, e desce
 * para a linha de baixo quando a mochila é estreita. Azul, para não se
 * confundir com o cobre da Boss Pouch: é o que veio da loja.
 */
.bag-boss-pouch { flex-wrap: wrap; row-gap: 6px; }
.bag-store-inbox { display: flex; align-items: center; gap: 8px; }
.cell.store-inbox-cell {
  border-color: #4f86c6;
  background: linear-gradient(180deg, #15202d, #161d20);
}
.cell.store-inbox-cell:hover { border-color: var(--accent); }
.cell.store-inbox-cell .store-inbox-icone { width: 32px; height: 32px; image-rendering: pixelated; object-fit: contain; }
.bag-store-inbox-texto b { color: #8fbfff !important; }
/* O botão da Store Inbox no rodapé da loja, com a contagem num selo. */
.store-inbox-botao { display: inline-flex; align-items: center; gap: 6px; }
.store-inbox-conta {
  min-width: 16px; padding: 0 5px; border-radius: 999px; font-size: 10px; line-height: 16px; text-align: center;
  background: #4f86c6; color: #fff;
}
/* As duas coladas, só o desenho com uma etiqueta pequena dentro. */
.bag-boss-pouch { gap: 4px; }
.cell.boss-pouch-cell, .cell.store-inbox-cell { position: relative; }
.cell .cell-etiqueta {
  position: absolute; left: 1px; top: 1px; z-index: 2; pointer-events: none;
  padding: 0 2px; border-radius: 2px; font-size: 7px; line-height: 9px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .2px; color: #fff; background: rgba(0, 0, 0, .65);
}
.bag-bolsas-divisao {
  flex-basis: 100%; display: flex; align-items: center; gap: 5px;
  font-size: 8px; line-height: 10px; text-transform: uppercase; letter-spacing: .6px; color: var(--muted);
}
.bag-bolsas-divisao::before, .bag-bolsas-divisao::after { content: ''; flex: 1; height: 1px; background: var(--line-soft); }
.bag-bolsas-divisao i { font-style: normal; opacity: .6; }
/* Duas colunas iguais, bem separadas, com a divisão (linha + nome) em cima de cada quadrado largo. */
.bag-boss-pouch:has(.bag-bolsa-coluna) { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.bag-bolsa-coluna { display: flex; flex-direction: column; align-items: stretch; gap: 4px; min-width: 0; }
.bag-bolsa-nome {
  display: flex; align-items: center; gap: 5px;
  font-family: var(--font-heading); font-weight: 700;
  font-size: 8px; line-height: 11px; text-transform: uppercase; letter-spacing: 0; white-space: nowrap; justify-content: center;
}
.bag-bolsa-nome::before, .bag-bolsa-nome::after { content: ''; flex: 1; min-width: 0; height: 1px; background: currentColor; opacity: .35; }
.bag-bolsa-coluna > .cell { width: 100%; display: flex; justify-content: center; align-items: center; overflow: hidden; }
/* Borda vermelha na Boss Pouch, dourada na Store Inbox, e um brilho passando de tempos em tempos. */
.bag-bolsa-coluna > .cell.boss-pouch-cell {
  border-color: #d9463a; background: linear-gradient(180deg, #2a1616, #161d20);
  box-shadow: 0 0 6px rgba(217, 70, 58, .35), inset 0 0 8px rgba(217, 70, 58, .15);
}
.bag-bolsa-coluna > .cell.store-inbox-cell {
  border-color: #d9a441; background: linear-gradient(180deg, #2a2114, #161d20);
  box-shadow: 0 0 6px rgba(217, 164, 65, .35), inset 0 0 8px rgba(217, 164, 65, .15);
}
.bag-bolsa-coluna > .cell.boss-pouch-cell:hover { border-color: #ff6b5b; }
.bag-bolsa-coluna > .cell.store-inbox-cell:hover { border-color: #f0c27a; }
/*
 * ---- Este brilho andava no `left`, e isso custava um LAYOUT POR QUADRO ----
 *
 * Medido num telefone com o jogo PARADO: 75 layouts por segundo numa tela onde
 * nada acontece. Eram estes dois brilhos — `left` é propriedade de LAYOUT, e
 * animá-la obriga o navegador a recalcular a posição de tudo a cada quadro,
 * para sempre, enquanto a mochila estiver aberta.
 *
 * `transform` faz o mesmo caminho na placa de vídeo, sem tocar no layout. O
 * desenho é idêntico — o que muda é quem faz a conta.
 *
 * ---- Por que 475%, e não 190% ----
 *
 * A viagem era de `left: -60%` até `130%`: 190% da largura do PAI. Em
 * `translateX` a porcentagem é da largura DO PRÓPRIO ELEMENTO, que é 40% do
 * pai — então os mesmos 190% do pai são 190/40 = 475% dele. O `left: -60%`
 * fica parado, como ponto de partida.
 */
.bag-bolsa-coluna > .cell::after {
  content: ''; position: absolute; top: 0; bottom: 0; left: -60%; width: 40%; pointer-events: none;
  background: linear-gradient(100deg, transparent, rgba(255, 255, 255, .28), transparent);
  transform: skewX(-20deg); animation: bolsa-glow 3.2s ease-in-out infinite;
  will-change: transform;
}
.bag-bolsa-coluna:nth-child(2) > .cell::after { animation-delay: 1.6s; }
@keyframes bolsa-glow {
  0% { transform: translateX(0) skewX(-20deg); }
  45%, 100% { transform: translateX(475%) skewX(-20deg); }
}
@media (prefers-reduced-motion: reduce) { .bag-bolsa-coluna > .cell::after { animation: none; display: none; } }
.bag-bolsas-boss { color: #ff6b5b; }
.bag-bolsas-store { color: #f0c27a; }
.cell.boss-pouch-cell .cell-etiqueta { color: #ff6b5b; }
.cell.store-inbox-cell .cell-etiqueta { color: #f0c27a; }
.bag-boss-pouch-texto b { font-size: 11px; color: var(--copper); }
.bag-boss-pouch-texto em { font-size: 9px; color: var(--muted); font-style: normal; }
.cell.dragging { opacity: .4; }
.cell.protected { border-color: var(--copper); }
.cell.ignored { opacity: .45; }
/*
 * O número da pilha, no canto de baixo à direita.
 *
 * FILHO DIRETO de propósito. Como `.cell b` isto pegava qualquer `<b>` dentro
 * da célula, e no dia em que as estrelas do afixo viraram um `<b>` por afixo
 * elas foram capturadas por esta regra: as três empilhadas uma sobre a outra no
 * canto de baixo, a 10px, parecendo uma só. O número da pilha é sempre
 * pendurado direto na célula (ver `itemCell`), então o `>` não tira nada dele e
 * fecha a porta para o próximo `<b>` que alguém puser aqui dentro.
 */
.cell > b {
  position: absolute; bottom: 0; right: 2px; font-size: 10px; color: #fff; text-shadow: 0 1px 2px #000;
  /*
   * O `z-index` existe por causa da raridade "quina": la o canvas do item
   * sobe para `z-index: 1` para ficar acima do degrade de fundo, e sem um
   * numero AINDA MAIS alto a pilha ia parar atras do proprio item — o topo
   * dos digitos sumia debaixo do sprite. O selo do tier e os afixos ja
   * andavam em 3 e 4 pelo mesmo motivo; a contagem faltava.
   */
  z-index: 2;
}
.cell canvas { width: 34px; height: 34px; }

/*
 * ---- A RARIDADE, num SOPRO de luz na borda ----
 *
 * Ela só existia no balão: para saber o que era o quê era preciso passar o
 * mouse peça por peça, e uma mochila cheia são quarenta passadas. Foi o que o
 * jogador pediu — "normalmente nao da pra saber qual é a raridade".
 *
 * ---- Por que a luz VAZA, em vez de contornar ----
 *
 * Contorno duro em quarenta quadradinhos vira grade, e grade colorida cansa a
 * vista antes de informar. E a borda da célula já tem três donos — o `:hover`, o
 * `protected` (não vender) e o `drop-target` do arrasto —, que dizem o que a
 * pessoa está FAZENDO agora e não podem perder a linha para uma cor do item.
 *
 * Aqui a caixa não muda: a luz sai dela para o fundo. A peça boa parece ACESA,
 * a moldura continua respondendo ao mouse, e nada é desenhado por cima do
 * desenho — um halo por baixo do item lavava a arte de cor, que foi a primeira
 * tentativa e o dono recusou.
 *
 * ---- Por que num `::before`, e não no `box-shadow` da própria célula ----
 *
 * Porque a célula já usa `box-shadow` noutros lugares, com seletor mais forte:
 * `.filter-grid .cell.barred`, `.filter-grid .cell.protected` e
 * `.equipment .slot.loaded`. Posta na célula, esta regra seria apagada por eles
 * sem aviso — e só nas telas onde eles valem, que é o pior tipo de defeito de
 * CSS. Num pseudo-elemento só dela, a luz não disputa propriedade com ninguém.
 *
 * ---- Por que o comum não acende ----
 *
 * Ele é a esmagadora maioria de qualquer mochila. Acender tudo não distingue
 * nada — a pessoa volta a ter de passar o mouse, que é justamente o que ela
 * reclamou. A luz começa onde ela significa alguma coisa: do incomum para cima.
 */
.cell.raridade::before, .slot.raridade::before {
  content: ""; position: absolute; inset: -1px; border-radius: 5px;
  box-shadow: 0 0 7px -1px var(--tier); pointer-events: none;
}
/*
 * ---- E a silhueta da essência NÃO é pintada ----
 *
 * Ela chegou a ser, e o dono cortou: "a qualidade das essências não era pra
 * ter um fundo extra de cor, um quadrado; era pra ser igual dos itens normais.
 * Por exemplo, a essência do amuleto mítico tem que ter o mesmo fundo de um
 * amuleto mítico."
 *
 * Ele está certo, e o erro era de excesso: a célula JÁ acende na cor da
 * raridade, como acende em qualquer peça. Pintar também o desenho era um
 * segundo sinal para a mesma coisa, e ele fazia a essência parecer de outra
 * espécie — dois itens míticos lado a lado ficavam diferentes um do outro.
 *
 * A silhueta fica cinza, como o PNG é. Quem diz a qualidade é a luz da célula,
 * a mesma de todo mundo. (A ESSÊNCIA VERMELHA é a única exceção, e ela é uma
 * exceção declarada: ver `.cell.essencia-vermelha`, mais abaixo.)
 */
/*
 * Do épico para cima a luz acende de verdade: duas camadas, uma larga e uma
 * curta, para o brilho ter miolo em vez de virar uma nuvem. São as peças que se
 * procura de longe, e uma mochila inteira passa por baixo do olho num rolar só
 * — é o brilho que faz a pessoa PARAR de rolar.
 */
.cell.raridade.tier-epico::before, .slot.raridade.tier-epico::before,
.cell.raridade.tier-lendario::before, .slot.raridade.tier-lendario::before,
.cell.raridade.tier-mitico::before, .slot.raridade.tier-mitico::before {
  box-shadow: 0 0 11px -1px var(--tier), 0 0 3px -1px var(--tier);
}

/*
 * ---- E as outras duas leituras da mesma coisa ----
 *
 * Marcar raridade é gosto, e gosto não se resolve escolhendo por todo mundo: o
 * mesmo brilho que faz uma pessoa achar a peça na hora faz outra achar a
 * mochila poluída. Então o sopro acima é o PADRÃO — quem não mexer em nada vê
 * ele —, e Opções → Ajustes da tela troca por uma destas.
 *
 * Quem troca é um atributo no `<html>` (`data-raridade`), e não uma classe em cada
 * célula: são quarenta e quatro quadradinhos entre mochila, bolsa, depósito e
 * corpo, e todos eles já leem o `--tier`. Com o atributo lá em cima o CSS resolve
 * sozinho, sem redesenhar lista nenhuma — trocar é instantâneo. Ver
 * `aplicarEstiloDaRaridade` no `panels.mjs`.
 *
 * O comum continua sem marca em todos os três. Ele é a maioria da mochila, e
 * acender tudo não distingue nada em estilo nenhum.
 */

/*
 * ---- "anel": o contorno aceso POR DENTRO da moldura ----
 *
 * O mais marcado dos três: a peça boa recorta na hora numa mochila cheia. Em
 * troca, é o único que desenha uma linha em volta — quem achar que vira grade
 * colorida tem os outros dois.
 */
[data-raridade="anel"] .cell.raridade::before,
[data-raridade="anel"] .slot.raridade::before {
  box-shadow: inset 0 0 7px -1px var(--tier), inset 0 0 0 1px var(--tier);
}
[data-raridade="anel"] .cell.raridade.tier-epico::before, [data-raridade="anel"] .slot.raridade.tier-epico::before,
[data-raridade="anel"] .cell.raridade.tier-lendario::before, [data-raridade="anel"] .slot.raridade.tier-lendario::before,
[data-raridade="anel"] .cell.raridade.tier-mitico::before, [data-raridade="anel"] .slot.raridade.tier-mitico::before {
  box-shadow: inset 0 0 9px -1px var(--tier), inset 0 0 0 1px var(--tier), 0 0 7px -2px var(--tier);
}

/*
 * ---- "quina": a luz entra por UM canto ----
 *
 * Um degradê na diagonal, aceso na quina de cima à esquerda e apagando antes de
 * chegar ao meio. Não é anel nem sopro: é como se algo iluminasse a peça de
 * lado, e o quadrado inteiro ganha um ar de relevo sem que nenhuma linha seja
 * desenhada.
 *
 * ---- Duas coisas que ele PRECISA fazer, e nenhuma é o degradê ----
 *
 * A primeira regra apaga o sopro do padrão. Sem ela os dois somariam — a quina
 * acesa E a caixa vazando luz —, e ninguém pediu os dois.
 *
 * A última põe o desenho ACIMA da luz. Este é o único dos três que pinta FUNDO,
 * e `::before` é posicionado: sem o `z-index` ele cobriria o sprite e lavaria a
 * arte de cor, que foi a primeira tentativa de tudo isto e foi recusada. O anel
 * e o sopro não precisam disso porque desenham só sombra, nunca preenchimento.
 */
[data-raridade="quina"] .cell.raridade::before,
[data-raridade="quina"] .slot.raridade::before,
[data-raridade="quina"] .cell.raridade.tier-epico::before, [data-raridade="quina"] .slot.raridade.tier-epico::before,
[data-raridade="quina"] .cell.raridade.tier-lendario::before, [data-raridade="quina"] .slot.raridade.tier-lendario::before,
[data-raridade="quina"] .cell.raridade.tier-mitico::before, [data-raridade="quina"] .slot.raridade.tier-mitico::before {
  box-shadow: none;
}
[data-raridade="quina"] .cell.raridade::before,
[data-raridade="quina"] .slot.raridade::before {
  background: linear-gradient(135deg, var(--tier) -30%, transparent 55%);
  opacity: .45;
}
[data-raridade="quina"] .cell.raridade.tier-epico::before, [data-raridade="quina"] .slot.raridade.tier-epico::before,
[data-raridade="quina"] .cell.raridade.tier-lendario::before, [data-raridade="quina"] .slot.raridade.tier-lendario::before,
[data-raridade="quina"] .cell.raridade.tier-mitico::before, [data-raridade="quina"] .slot.raridade.tier-mitico::before {
  background: linear-gradient(135deg, var(--tier) -15%, transparent 62%);
  opacity: .68;
}
[data-raridade="quina"] .cell.raridade canvas,
[data-raridade="quina"] .slot.raridade canvas {
  position: relative;
  z-index: 1;
}

/*
 * ---- "nenhum": a mochila como ela era antes de tudo isto ----
 *
 * Marcar raridade é gosto, e há quem ache poluição. Sem esta saída a pessoa não
 * tem o que fazer além de reclamar — e a reclamação legítima ("não quero nada
 * disso") viraria um pedido para tirar o recurso de todo mundo.
 *
 * `display: none` e não `box-shadow: none`: aqui a intenção é APAGAR, e apagar
 * tem de valer para o que existe hoje e para o que alguém desenhar amanhã. Um
 * estilo novo que use fundo, borda ou conteúdo continuaria aparecendo se esta
 * regra zerasse só a sombra — e o botão "desligado" passaria a mentir.
 */
[data-raridade="nenhum"] .cell.raridade::before,
[data-raridade="nenhum"] .slot.raridade::before,
[data-raridade="nenhum"] .cell.raridade.tier-epico::before, [data-raridade="nenhum"] .slot.raridade.tier-epico::before,
[data-raridade="nenhum"] .cell.raridade.tier-lendario::before, [data-raridade="nenhum"] .slot.raridade.tier-lendario::before,
[data-raridade="nenhum"] .cell.raridade.tier-mitico::before, [data-raridade="nenhum"] .slot.raridade.tier-mitico::before {
  display: none;
}

/*
 * ---- AFIXOS: as estrelas da instância ----
 *
 * UMA ESTRELA POR AFIXO, e cada uma com a cor DELA: o quanto aquele afixo
 * chegou perto do máximo que ele pode dar. Terço de baixo azul, do meio roxo,
 * de cima dourado. Quem faz a conta é `estrelasDosAfixos`, e é lá que está o
 * porquê.
 *
 * Por isso o degrau mora no `<b>` de cada estrela, e não no selo inteiro: um
 * ★★★ pode sair azul, roxo e dourado ao mesmo tempo. O selo ainda carrega a
 * classe do MELHOR afixo, que é o que a célula usa quando precisa de uma cor
 * só para a peça toda.
 *
 * A contagem não entra na cor — ela já está desenhada nas próprias estrelas.
 * Assim ★ dourado e ★★★ azul são duas peças visivelmente diferentes, que é como
 * elas de fato são.
 *
 * Elas NÃO são as cores da raridade — raridade é do item base e tem a paleta
 * dela (`--tier`); estrela é da cópia. Duas escalas de cor diferentes de
 * propósito, porque são duas perguntas diferentes.
 */
.com-afixo { --estrela: #57a6e8; }
.selo-afixo .q1, .item-estrelas .q1, .tip-afixo-tier.q1 { --estrela: #57a6e8; }
.selo-afixo .q2, .item-estrelas .q2, .tip-afixo-tier.q2 { --estrela: #b184e8; }
.selo-afixo .q3, .item-estrelas .q3, .tip-afixo-tier.q3 { --estrela: #e0a84a; }
/*
 * A QUARTA, que só a fusão fabrica.
 *
 * "faz a essência vermelha, por exemplo, que seria a essência mítica." O
 * vermelho é o mesmo das peças Mineiroidle (a variável --tier do mítico), e é de propósito: é a
 * cor que este jogo já usa para dizer "acima do topo". As outras três descrevem
 * onde o afixo caiu na régua; esta descreve um afixo que passou dela.
 */
.selo-afixo .q4, .item-estrelas .q4, .tip-afixo-tier.q4 { --estrela: #ff5a52; }
.selo-afixo b.estrela.q4 { text-shadow: 0 0 6px var(--estrela), 0 0 3px #000, 0 1px 2px #000; }
.tip-afixo-tier.q4 b.estrela { text-shadow: 0 0 6px var(--estrela); }

/*
 * O selo no canto de cima à direita do quadradinho.
 *
 * `pointer-events: none` para ele não roubar o clique nem o arrasto da peça, e
 * `text-shadow` preto porque a estrela cai sobre o desenho do item, que pode ser
 * claro — sem a sombra ela some numa armadura branca.
 */
.selo-afixo {
  position: absolute; top: 0; right: 2px; z-index: 3;
  font-style: normal; font-size: 9px; letter-spacing: -1px; line-height: 1;
  text-shadow: 0 0 3px #000, 0 1px 2px #000;
  pointer-events: none;
}
/*
 * Layout, `position`, `display` e `font-size` explícitos, e não só a cor.
 *
 * Estas estrelas são um `<b>` por afixo, e `<b>` é um elemento que meia dúzia
 * de telas já estilizam por descendência. Elas moram dentro de `.cell`, que
 * posiciona `<b>` no canto (o número da pilha), e dentro do cabeçalho do menu,
 * que empilha os `<b>` em coluna — e quebraram nos DOIS: primeiro as três se
 * sobrepondo num canto, depois uma embaixo da outra no balão.
 *
 * Duas vezes o mesmo defeito é o suficiente: em vez de caçar cada regra que as
 * atropela, o selo declara o que ele é. `inline-flex` fixa a fileira sem
 * depender do que o pai resolveu ser.
 */
.selo-afixo, .item-estrelas { display: inline-flex; align-items: baseline; }
/*
 * DUAS classes de propósito (`.item-estrelas b.estrela`), e não `.item-estrelas b`.
 *
 * Com uma classe só isto empatava com qualquer `.x b` da folha, e em empate
 * ganha quem vem por último no arquivo — a cor da estrela passava a depender da
 * ORDEM das regras. Foi assim que `.tip-id b` (que pinta o nome do item na cor
 * da RARIDADE) pintou as três estrelas de uma cor só. Ver `seloDeEstrelas`.
 */
.selo-afixo b.estrela, .item-estrelas b.estrela, .tip-afixo-tier b.estrela {
  display: inline; position: static; font-size: inherit; font-weight: inherit;
  color: var(--estrela, #57a6e8);
}
/*
 * A estrela do terço de cima ganha luz própria além da cor.
 *
 * Cor sozinha é um sinal fraco num quadradinho de 30px cheio de selo, e some de
 * vez para quem não distingue bem roxo de dourado. O brilho é um segundo canal
 * que não depende de enxergar matiz: a dourada ACENDE, as outras duas não —
 * então dá para achar a peça boa numa mochila cheia sem ler cor nenhuma.
 */
.selo-afixo b.estrela.q3 { text-shadow: 0 0 5px var(--estrela), 0 0 3px #000, 0 1px 2px #000; }

/* As mesmas estrelas, ao lado do nome no balão. */
.item-estrelas {
  font-style: normal; margin-left: 5px; letter-spacing: -1px;
}
.item-estrelas b.estrela { text-shadow: 0 0 4px currentColor; }

/*
 * O bloco "Atributos extras" do balão.
 *
 * Cor própria e uma linha acima separando: ele fala da CÓPIA, e os atributos de
 * cima falam do item. A borda é o que impede a leitura de emendar os dois numa
 * lista só.
 */
.tip-afixos {
  margin-top: 6px; padding-top: 6px; border-top: 1px solid #23343a;
  display: grid; gap: 2px;
}
.tip-afixos-titulo {
  font-family: var(--font-heading); font-size: 11px; letter-spacing: .06em;
  text-transform: uppercase; color: #7fb8d8; margin-bottom: 2px;
}
.tip-afixo {
  display: flex; justify-content: space-between; gap: 10px;
  font-size: 12px; color: #a9d6ee;
}
/*
 * O selo da linha: a estrela na cor do afixo, e ao lado dela o tier e o quanto
 * ele rolou da faixa. A estrela é o que amarra a linha à do canto do ícone; o
 * texto fica apagado de propósito, para a linha continuar sendo lida pelo nome
 * do atributo e não pelo número do lado.
 */
.tip-afixo-tier {
  font-style: normal; font-size: 10px; color: #5d7f92;
  display: inline-flex; align-items: baseline; gap: 3px; white-space: nowrap;
}
.tip-afixo-tier b.estrela { font-weight: inherit; color: var(--estrela, #5d7f92); }
.tip-afixo-tier.q3 b.estrela { text-shadow: 0 0 5px var(--estrela); }

/*
 * ---- A essência de afixo, no balão ----
 *
 * O desenho dela é a silhueta cinza do slot de onde o afixo saiu — a mesma
 * figura da casa vazia da ficha. Ela vem com a opacidade baixa de propósito:
 * aquilo NÃO é uma bota, é o lugar de onde o afixo veio, e um desenho cheio
 * seria lido como a peça.
 */
/*
 * A mesma silhueta no balão, e na mesma cor: o balão é o lugar em que se
 * confere o que a essência é, e sair cinza ali seria justamente esconder a
 * qualidade na tela feita para mostrá-la.
 */
/*
 * A mesma coisa no balão: a silhueta é a silhueta, e a luz é a de sempre. O
 * balão já diz a qualidade por escrito e na cor do nome, então aqui a luz é um
 * reforço — não a única leitura.
 */
.tip-essencia-arte {
  display: grid; place-items: center; width: 44px; height: 44px;
  position: relative; border-radius: 5px;
}
.tip-essencia-arte img { opacity: .8; image-rendering: pixelated; }
.tip-essencia-arte:not(.tier-comum)::before {
  content: ""; position: absolute; inset: 2px; border-radius: 5px;
  box-shadow: 0 0 9px -1px var(--tier); pointer-events: none;
}
.tip-afixo-origem {
  margin-top: 4px; font-size: 10px; color: var(--muted); font-style: italic;
}

/* ---------- modal ---------- */

#modal { position: fixed; inset: 0; background: #04060799; display: grid; place-items: center; z-index: 50; }
.modal-box {
  width: min(980px, 94vw); max-height: 90vh; display: flex; flex-direction: column;
  position: relative; background: none;
  border-style: solid;
  border-width: 50px 30px 32px 30px;
  border-image-source: url(/client/assets/ui/padrao.png);
  border-image-slice: 150 110 130 110 fill;
  border-image-repeat: stretch;
}
/*
 * ---- O painel de imbuir ENCOLHEU ----
 *
 * "a tela de imbuements tem botoes muito espaçados sem necessidade sabe."
 *
 * Os 1120px foram medidos para um desenho que nao existe mais: tres cartoes de
 * grau emoldurados lado a lado, cada um com nome, efeito e receita. Eles viraram
 * dois menus suspensos ("seleciona o item, escolhe o imbue pela setinha"), e a
 * largura ficou para tras — o conteudo mais largo da tela passou a ser a linha
 * da peca, com 500px, dentro de uma janela de 1120.
 *
 * O que sobra nao fica vazio: fica ESPALHADO. Dois menus de 500px cada para uma
 * frase de tres palavras, e o "Aplicar" a meia tela de distancia do que ele
 * aplica. Encolhendo, o olho percorre a tela inteira sem sair do lugar.
 */
.modal-box.imbue { width: min(780px, 96vw); }
/*
 * A forja, pelo mesmo motivo: a aba de craft põe os dois sets lado a lado, cada
 * um com a boneca e a coluna das armas extras, e embaixo a lista de materiais em
 * colunas. Com 980px os dois corpos ficavam espremidos contra a seta.
 *
 * Não quebra no celular: a regra de `@media (max-width: 900px)` lá embaixo manda
 * o `.modal-box` para 100vw, e ela vem DEPOIS nesta folha.
 */
.modal-box.forja { width: min(1180px, 96vw); }

/* A loja usa a moldura dourada — é a vitrine do jogo. */
.modal-box.store {
  border-width: 54px 34px 36px 34px;
  border-image-source: url(/client/assets/ui/prastore.png);
  border-image-slice: 150 105 135 105 fill;
}
.modal-box > header {
  position: absolute; top: -34px; left: 14px; right: 20px; height: 38px;
  display: flex; align-items: center; padding: 0; border: none; overflow: hidden;
  /* A faixa é a alça: o modal se arrasta por ela, como as janelas flutuantes. */
  cursor: move; touch-action: none;
}
.modal-box > header button, .modal-box > header input,
.modal-box > header select, .modal-box > header label { cursor: pointer; }
/*
 * O cabeçalho CONTINUA recortando o que passa dele.
 *
 * Aqui morava uma exceção (`overflow: visible`) para a lista de sugestões da
 * busca poder cair por cima do modal. Ela resolvia a lista e criava um
 * problema maior: a fila de filtros inteira passou a vazar para fora da
 * moldura quando não cabia.
 *
 * O recorte volta, e quem escapa é só a lista — ela virou camada FIXA,
 * posicionada pelo retângulo do próprio campo. Ver `posicionarSugestoes`.
 */
.modal-box.store > header { top: -38px; left: 22px; right: 28px; }
/*
 * O título ESTICA, e é ele que empurra o resto para a direita.
 *
 * O X era empurrado por um `margin-left: auto` dele mesmo. Quando o canto de
 * ações entrou no meio, a margem passou para lá — e como o canto some quando
 * está vazio (`:empty`), o X ficou sem ninguém para empurrá-lo: em toda janela
 * sem botão de ação ele colava no título, no canto esquerdo.
 *
 * Com o título esticando, o X fica no canto direito sempre, tenha ou não ação
 * no meio. `min-width: 0` é o que deixa o `text-overflow` continuar valendo
 * num item de flex que cresce.
 */
.modal-box h2 { flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#modal-body { padding: 6px 10px 10px; }
.modal-box h2 { font-family: var(--font-title); margin: 0; font-size: 17px; letter-spacing: .05em; font-weight: 700; color: var(--accent); }
/* As ações do cabeçalho, entre o título e o X. Quem empurra os dois para a
   direita é o título, que estica — ver `.modal-box h2`. */
/*
 * `flex: 0 1 auto` com `min-width: 0`: o canto de ações ENCOLHE antes de
 * empurrar o X. Sem isso, uma fila comprida (a peneira do mercado) esticava a
 * faixa e o botão de fechar saía por baixo da borda.
 */
#modal-acoes { display: flex; align-items: center; gap: 8px; flex: 0 1 auto; min-width: 0; margin-right: 10px; }
#modal-acoes:empty { display: none; }

/*
 * ---- O SELO: o canto ESQUERDO do cabecalho ----
 *
 * "coloca la encima na esquerda ao lado de arena x1 pra mostrar a quantidade de
 *  tickets."
 *
 * `#modal-acoes` e o canto DIREITO, e ele ja existia. Este e o irmao dele do
 * outro lado, e nasce pela mesma razao: o numero de tickets nao e uma acao —
 * ninguem clica nele — e por isso nao cabe na fileira de botoes, que fica
 * encostada no X.
 *
 * `:empty { display: none }` e o que faz ele nao existir para as outras trinta
 * janelas: elas nao preenchem nada, e o cabecalho delas continua exatamente
 * como estava. Ele e' esvaziado a cada `openModal`, como o canto de acoes —
 * senao o selo da arena apareceria na janela seguinte.
 */
#modal-selo { display: flex; align-items: center; gap: 6px; flex: none; margin-right: 10px; }
#modal-selo:empty { display: none; }

/*
 * ---- A peneira do mercado, morando no cabeçalho ----
 *
 * A faixa do cabeçalho tem 38px e `overflow: hidden`; os controles descem para
 * 26px para caber sem encostar nas bordas. A busca é a única que estica, e o
 * título encolhe antes dela (ele já tem `text-overflow`), então o X nunca é
 * empurrado para fora.
 *
 * Abaixo de 1100px os seletores saem e fica só a busca: cinco controles numa
 * faixa dessa largura viram cinco lascas ilegíveis, e a busca é a que resolve
 * a maior parte das procuras.
 */
.balcao-peneira.no-topo {
  padding: 0;
  border: none;
  background: none;
  /*
   * Descolada do topo da faixa.
   *
   * O cabeçalho é uma tira de 38px acima da moldura, e os controles centrados
   * nela encostavam na borda de cima — pareciam nascer meio para fora da
   * janela. Quatro pixels resolvem, e o X ao lado continua no lugar dele.
   */
  margin: 4px 0 0;
  flex-wrap: nowrap;
  min-width: 0;
  gap: 5px;
}
.balcao-peneira.no-topo .search,
.balcao-peneira.no-topo select,
.balcao-peneira.no-topo .balcao-limpar {
  padding: 0 8px;
  font-size: 11px;
  height: 26px;
  line-height: 24px;
  border-radius: 4px;
}
/*
 * Todo controle pode encolher, e nenhum some por conta própria.
 *
 * Sem `min-width: 0` um `select` recusa encolher abaixo do texto da opção mais
 * comprida — e é ele que empurrava a fila para fora da moldura em vez de ceder.
 */
.balcao-peneira.no-topo .balcao-busca { flex: 1 1 150px; min-width: 80px; }
.balcao-peneira.no-topo select { flex: 0 1 auto; min-width: 0; max-width: 118px; }
.balcao-peneira.no-topo .balcao-limpar { flex: none; }
/* A busca com fundo, para não parecer um buraco na faixa do cabeçalho. */
.balcao-peneira.no-topo .search { background: #0b1012; }

@media (max-width: 1100px) {
  .balcao-peneira.no-topo select,
  .balcao-peneira.no-topo .balcao-limpar { display: none; }
}
.modal-acao {
  display: inline-flex; align-items: center; gap: 6px;
  background: linear-gradient(180deg, #16222b, #0d1417);
  border: 1px solid var(--line); border-radius: 6px;
  padding: 4px 12px; cursor: pointer;
  font-family: var(--font-heading); font-size: 11px; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase; color: var(--accent);
}
.modal-acao:hover { border-color: var(--accent); }
/* Aberto: o botão fica aceso, para o painel que caiu não parecer avulso. */
.modal-acao[aria-expanded="true"] { border-color: var(--accent); background: linear-gradient(180deg, #1c2f38, #101a1f); }
/* Com filtro valendo, um ponto no canto — a janela pode estar escondendo cards
   e o botão fechado não teria como avisar. */
.modal-acao .modal-acao-ponto {
  width: 6px; height: 6px; border-radius: 50%; background: var(--copper);
}

/*
 * ---- A gaveta do filtro ----
 *
 * Ela nasce fechada e cai do botão de Filtro. Fechada, a janela é só as abas e
 * os cards — que é o que o dono pediu ao mandar tirar o filtro da fileira: ele
 * ocupava uma faixa inteira para uma coisa que quase nunca se mexe.
 */
.filtro-gaveta {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin: 0 0 10px; padding: 9px 11px;
  background: linear-gradient(180deg, #101a1f, #0b1114);
  border: 1px solid var(--accent-dim); border-radius: 7px;
}
.filtro-gaveta[hidden] { display: none; }

#modal-close { flex: none; margin-left: 12px; background: none; border: none; cursor: pointer; color: var(--muted); font-size: 15px; }
#modal-close:hover { color: var(--text); }
#modal-body { padding: 18px; overflow-y: auto; overflow-x: hidden; min-width: 0; overflow-wrap: anywhere; }
#modal-body h3, .sheet h3 {
  font-weight: 700; font-size: 12px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--accent); margin: 18px 0 9px;
}
#modal-body h3:first-child, .sheet h3:first-child { margin-top: 0; }

/*
 * ---- A fileira de abas: barras largas que DIVIDEM o painel ----
 *
 * Ela era uma fila de botõezinhos encostada à esquerda, com um ícone de 16px
 * espremido antes do texto. Agora é o que o dono pediu e desenhou:
 *
 *     ------- hunts ------|------ bosses ------|------ arena ------
 *
 * Cada aba ocupa a MESMA fatia da largura (o 'flex: 1'), o ícone fica em cima
 * do nome, e a régua embaixo fecha o cabeçalho. Sendo o primeiro gesto de toda
 * janela, a fileira merece ser a primeira coisa que o olho encontra.
 *
 * ---- Por que o nome já vem aceso ----
 *
 * O dono pediu o texto "naquela cor como se o mouse estivesse em cima". E ele
 * está certo: apagado, o nome de uma aba parece desativado, e a pessoa fica
 * procurando por que não pode clicar. Quem diz qual está ABERTA é a moldura e o
 * fundo, que é uma diferença que ninguém confunde com "desligado".
 */
.tabs {
  position: relative;
  display: flex; gap: 0; margin-bottom: 10px;
  border-bottom: 1px solid var(--line);
}
.tabs button {
  flex: 1 1 0; min-width: 0;
  display: inline-flex; flex-direction: column; align-items: center; justify-content: flex-end; gap: 5px;
  background: linear-gradient(180deg, #101a1f, #0b1114);
  border: 1px solid var(--line); border-bottom: none;
  border-radius: 7px 7px 0 0;
  margin-right: -1px;
  padding: 9px 8px 8px; cursor: pointer;
  font-size: 12px; font-family: var(--font-heading); font-weight: 600;
  letter-spacing: .07em; text-transform: uppercase;
  color: var(--accent);
  transition: background .12s ease, border-color .12s ease, color .12s ease;
}
.tabs button:last-child { margin-right: 0; }
.tabs button:hover { background: linear-gradient(180deg, #17252c, #0d1417); }
/*
 * A aba aberta é a que SOBE: fundo mais claro, moldura acesa e uma linha grossa
 * embaixo, encostada na régua. É a metáfora da pasta de arquivo, e ela dispensa
 * qualquer diferença de cor no texto.
 */
.tabs button[aria-selected="true"] {
  background: linear-gradient(180deg, #1c2f38, #101a1f);
  border-color: var(--accent); color: var(--accent);
  box-shadow: inset 0 -3px 0 var(--accent);
}
/*
 * O ícone da aba, quando existe ('client/assets/icons/aba-<id>.png'). Sem ele o
 * botão continua sendo só o texto: 'artOrUiIcon' tira a si mesmo do documento
 * quando não acha arte nenhuma, e a barra encolhe sozinha.
 */
.tabs button > img { width: 40px; height: 40px; flex: none; }
/* Sem arte nenhuma: o <img> fica no lugar, mas nao ocupa espaco. Ver
   'artOrUiIcon' e o conjunto 'semDesenhoNenhum'. */
.ui-icon.vazio { display: none; }
.tabs button[aria-selected="true"] > img { filter: none; }
.tabs button:not([aria-selected="true"]) > img { opacity: .62; filter: grayscale(.4); }

/* ---- A aba que TEM alguma coisa esperando ----

   "quando eu tiver recompensas disponíveis e estiver na aba de quests, tem que
    ficar meio que chamativo as abas ali pra clicar."

   Ela acende em OURO, e não na cor do jogo: o turquesa já é a cor da aba aberta
   (ver `aria-selected`), e duas coisas na mesma cor não se distinguem — a
   pessoa olharia a barra e veria duas abas "ligadas" sem saber a diferença. O
   ouro é a mesma cor do presente da faixa de baixo, que é exatamente a mesma
   promessa: tem prêmio aqui.

   O ícone perde o cinza junto: metade do que apaga uma aba fechada é o
   `grayscale`, e deixá-lo aceso é metade do chamado. */
.tabs button.aba-chama {
  border-color: #e0b45a;
  color: #ffe9b0;
  background: linear-gradient(180deg, #24201a, #14100c);
  animation: aba-chama 1.8s ease-in-out infinite;
}
.tabs button.aba-chama > img { opacity: 1; filter: none; }
@keyframes aba-chama {
  0%, 100% { box-shadow: inset 0 -3px 0 #e0b45a88, 0 0 0 0 #e0b45a00; }
  50%      { box-shadow: inset 0 -3px 0 #ffd76a, 0 0 14px -2px #ffb32e99; }
}
/* O ponto no canto: o pulso sozinho some numa tela cheia de movimento, e o
   ponto é o que resolve num relance — é o mesmo sinal do botão da barra. */
.tabs button.aba-chama::after {
  content: ''; position: absolute; top: 6px; right: 8px;
  width: 7px; height: 7px; border-radius: 50%;
  background: #ffd76a; box-shadow: 0 0 6px #ffb32e;
}
.tabs button { position: relative; }
/* Quem pediu menos movimento fica com o ouro parado: o chamado continua, o
   pisca-pisca sai. */
@media (prefers-reduced-motion: reduce) {
  .tabs button.aba-chama { animation: none; box-shadow: inset 0 -3px 0 #ffd76a; }
}
.tabs button:hover:not([aria-selected="true"]) > img { opacity: .9; filter: none; }
/*
 * ---- Uma fileira com DEZ abas ----
 *
 * O Highscores tem experiência, level, magic e sete perícias. Com a arte de
 * 40px que as outras barras usam, cada botão fica com trinta pixels de largura
 * e SHIELDING quebra em três linhas — foi o que aconteceu quando os ícones
 * entraram. Aqui a figura encolhe e o texto aperta, e os dez cabem numa linha.
 */
.tabs.tabs-miudas button { padding: 6px 3px 5px; gap: 3px; font-size: 9px; letter-spacing: .03em; }
.tabs.tabs-miudas button > img { width: 24px; height: 24px; }

/*
 * ---- A aba Especial Hunts, em ouro ----
 *
 * "onde esta escrito Especial Hunts coloca as letras em dourado e com efeito."
 *
 * E a aba onde moram as duas portas pagas do servidor — a Instance e a Divine —,
 * e ela estava com a mesma cor das outras quatro. O ouro e o que diz, antes de
 * qualquer clique, que ali dentro tem coisa que as normais nao tem.
 *
 * O brilho e um degrade DESLIZANDO por dentro da letra, e nao um pisca-pisca:
 * a barra de abas fica aberta o tempo todo que a janela de Aventuras esta
 * aberta, e um brilho que apaga e acende puxa o olho para longe do que a pessoa
 * foi ler. Este passa uma vez a cada cinco segundos e sai.
 *
 * A cor sozinha vem primeiro, fora do @supports: se o recorte na letra faltar,
 * o texto fica dourado chapado em vez de ficar INVISIVEL, que e no que da um
 * `color: transparent` sem o degrade por tras.
 */
.tabs button.aba-especiais .aba-rotulo {
  color: #ffd97a;
  /* Mais encorpado que as outras quatro: letra fina em ouro sobre painel escuro
     perde contra o mesmo tamanho em verde-agua. */
  font-weight: 700;
  text-shadow: 0 0 7px rgba(242, 197, 106, .30), 0 1px 0 rgba(0, 0, 0, .55);
}
@supports (background-clip: text) or (-webkit-background-clip: text) {
  .tabs button.aba-especiais .aba-rotulo {
    /*
     * O degrade ficou TODO na faixa clara do ouro.
     *
     * "quase nao da pra ler, como se estivesse um pouco apagado."
     *
     * Duas coisas apagavam: o tom mais escuro do degrade era um bronze
     * (#bf8b2c) que, sobre o painel quase preto da aba, some; e a `text-shadow`
     * preta da regra de cima continuava valendo aqui dentro. Numa letra de
     * preenchimento transparente a sombra aparece ATRAVES do vao — em vez de
     * contornar, ela suja o miolo. Por isso `text-shadow: none` e o contorno
     * feito com `drop-shadow`, que se aplica ao resultado ja' pintado.
     */
    background-image: linear-gradient(
      100deg,
      #e8b855 0%, #ffe6a4 24%, #fffdf2 38%, #ffe6a4 52%, #e8b855 76%, #ffe6a4 100%
    );
    background-size: 300% 100%;
    background-position: 0% 50%;
    -webkit-background-clip: text; background-clip: text;
    color: transparent; -webkit-text-fill-color: transparent;
    text-shadow: none;
    filter: drop-shadow(0 1px 1px rgba(0, 0, 0, .75)) drop-shadow(0 0 6px rgba(255, 210, 110, .30));
    animation: aba-ouro 5s linear infinite;
  }
}
@keyframes aba-ouro {
  from { background-position: 0% 50%; }
  to { background-position: -300% 50%; }
}
/* Aberta ou com o mouse em cima, o ouro acende um pouco mais — a mesma
   diferenca de brilho que o resto da barra faz, so que em ouro. */
.tabs button.aba-especiais:hover .aba-rotulo,
.tabs button.aba-especiais[aria-selected="true"] .aba-rotulo {
  /* O contorno preto continua na frente — sem ele, acender o halo faria a letra
     PERDER contraste em vez de ganhar. */
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, .75)) drop-shadow(0 0 8px rgba(255, 214, 120, .55));
}
/* Quem pediu menos movimento fica com o ouro parado, no ponto mais claro. */
@media (prefers-reduced-motion: reduce) {
  .tabs button.aba-especiais .aba-rotulo { animation: none; background-position: 40% 50%; }
}

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

input.search {
  width: 100%; padding: 8px 11px; margin-bottom: 10px;
  background: #080b0c; border: 1px solid var(--line); border-radius: 6px; color: var(--text);
}
input.search:focus { outline: none; border-color: var(--accent-dim); }

/* ---------- hunts ---------- */

.hunt-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(232px, 1fr)); gap: 9px; }

/*
 * ---- O filtro, numa LINHA PRÓPRIA embaixo das abas ----
 *
 * Ele morava dentro da fileira de abas, encostado à direita. Com as abas
 * viradas barras que dividem a largura inteira, não sobra canto: ele ficaria em
 * cima da última aba. Aqui ele é a linha seguinte, e a lista começa logo abaixo
 * — foi o que o dono pediu ao mandar "leva o filtro pra baixo do modal" e
 * "sobe as hunts pra perto das abas".
 */
/*
 * O filtro mora dentro da gaveta (`.filtro-gaveta`), que o botão de Filtro do
 * cabeçalho abre e fecha. Aqui sobra só o arranjo dos controles.
 */
.hunt-filtros { display: contents; }
.hunt-filtros input.search { margin: 0; width: 148px; }
.hunt-filtros select {
  background: var(--panel-2); color: var(--text);
  border: 1px solid var(--line); border-radius: 6px;
  padding: 4px 6px; font-size: 11px; font-family: inherit;
}
.hunt-filtros select:focus { outline: none; border-color: var(--accent-dim); }
/* O rotulo inteiro clica, e nao so a caixinha de 13px. */
.hunt-filtro-check {
  display: flex; align-items: center; gap: 5px; cursor: pointer;
  font-size: 10px; letter-spacing: .04em; text-transform: uppercase; color: var(--muted);
  white-space: nowrap;
}
.hunt-filtro-check:hover { color: var(--text); }
.hunt-filtro-check input { accent-color: var(--accent); cursor: pointer; margin: 0; }
/* A conta do filtro: presente quando peneira, invisivel quando nao. */
.hunt-filtro-vazio { margin: 0 0 8px; font-size: 11px; color: var(--muted); min-height: 14px; }
/*
 * Na tela estreita as barras encolhem: o ícone diminui e o nome quebra em duas
 * linhas em vez de espremer a última aba até virar um traço.
 */
@media (max-width: 720px) {
  .tabs button { font-size: 10px; letter-spacing: .04em; padding: 7px 4px 6px; }
  .tabs button > img { width: 28px; height: 28px; }
}
/*
 * O card da hunt, limpo e centrado.
 *
 * Ele carregava um botão "Detalhes" no canto e três números de rodapé — xp, hp
 * e drops — que ninguém compara entre vinte cards; era ruído em volta da única
 * coisa que a lista precisa responder, que é o que mora ali e se dá para
 * entrar. Sobraram o bicho, o nome, a descrição, o level e as estrelas.
 *
 * Tudo centrado: o card é estreito e cada linha tem um comprimento diferente,
 * então alinhado à esquerda ele ficava com a borda direita toda recortada.
 */
.hunt-card {
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px;
  padding: 12px 13px 11px; cursor: pointer; color: inherit;
  display: grid; gap: 6px; justify-items: center; text-align: center;
  grid-template-rows: auto 1fr auto auto;
}
.hunt-card:hover:not(.locked) { border-color: var(--accent-dim); }
.hunt-card.locked { opacity: .45; cursor: not-allowed; }
.hunt-card[data-active="true"] { border-color: var(--accent); background: #16241f; }
.hunt-card h3 { font-weight: 700; margin: 0; font-size: 15px; color: #e7efef; }
.hunt-card .lv { font-size: 11px; color: var(--copper); }
.hunt-card p { margin: 0; font-size: 11px; color: var(--muted); line-height: 1.4; }
/* Os bichos numa fileira, cada um com as estrelas embaixo. */
.hunt-card-bichos { display: flex; gap: 10px; align-items: flex-end; justify-content: center; min-height: 52px; }
/* Bicho e estrelas empilhados — a peça que se repete na lista e na ficha. */
.hunt-bixo { display: grid; justify-items: center; gap: 2px; }
.hunt-bixo canvas { image-rendering: pixelated; }
.hunt-bixo .bestiary-stars { line-height: 1; }
.boss-locked { color: var(--copper); font-size: 11px; }

/*
 * ---- A faixa do Auto Boss, no alto da aba de Bosses ----
 *
 * Moldura própria e não um card de boss: ela fala DA LISTA, e um retângulo do
 * mesmo tamanho e da mesma cor dos cards seria lido como mais um boss na grade.
 * Rodando, a borda vira verde — é o mesmo verde que o jogo usa para "isto está
 * acontecendo agora", e é a única pintura que muda de estado aqui.
 */
.auto-boss {
  display: grid; gap: 8px; margin: 0 0 12px;
  padding: 10px 12px; border: 1px solid var(--line);
  border-radius: 8px; background: var(--panel-2);
}
.auto-boss.rodando { border-color: var(--accent); }
.auto-boss-topo { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.auto-boss-topo b { font-family: var(--font-heading); font-size: 14px; }
.auto-boss-topo span { font-size: 11px; color: var(--muted); }
.auto-boss-espera { color: var(--copper); }
.auto-boss-passe { color: var(--accent); }
.auto-boss p { margin: 0; font-size: 11px; color: var(--muted); line-height: 1.45; }
.auto-boss .confirm-actions { margin: 0; }

/*
 * ---- A faixa mais bonita (15/09) ----
 *
 * O dono: "dá pra deixar isso mais bonito? e com o botão ali brilhando?". Uma
 * luz verde vinda do canto, o selo dourado do passe e o botão de começar com um
 * reflexo que atravessa de tempos em tempos. Animação só em transform/opacity e
 * box-shadow, duas camadas: não pesa. Quem pede menos movimento não vê nenhuma.
 */
.auto-boss {
  position: relative; overflow: hidden;
  padding: 12px 14px; border-radius: 10px;
  border-color: #2c4a45;
  background:
    radial-gradient(120% 140% at 0% 0%, rgba(47, 160, 138, .16), transparent 55%),
    linear-gradient(180deg, #1c2a2a, #161f20);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .04), 0 4px 14px rgba(0, 0, 0, .25);
}
.auto-boss::before {
  content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: linear-gradient(180deg, #4fd1b5, #2a7f70);
}
.auto-boss.com-passe { border-color: #6d5a2a; }
.auto-boss.com-passe::before { background: linear-gradient(180deg, #ffe08a, #b8862b); }
.auto-boss.com-passe {
  background:
    radial-gradient(120% 140% at 0% 0%, rgba(255, 200, 90, .12), transparent 55%),
    radial-gradient(90% 120% at 100% 100%, rgba(47, 160, 138, .12), transparent 60%),
    linear-gradient(180deg, #1f2624, #161d1e);
}
.auto-boss-topo { align-items: center; }
.auto-boss-topo b { font-size: 16px; letter-spacing: .04em; color: #e9f3ef; text-shadow: 0 0 10px rgba(79, 209, 181, .25); }
.auto-boss.com-passe .auto-boss-topo b { text-shadow: 0 0 10px rgba(255, 214, 120, .25); }
.auto-boss p { font-size: 12px; color: #a9b8b4; max-width: 70ch; }

.auto-boss-selo {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 2px 9px; border-radius: 999px;
  font-family: var(--font-heading); font-size: 11px !important; letter-spacing: .05em;
  color: #2a1d05 !important; font-weight: 700;
  background: linear-gradient(180deg, #ffe7a1, #d9a441);
  box-shadow: 0 0 0 1px rgba(255, 224, 138, .5), 0 0 12px rgba(255, 200, 90, .35);
}
.auto-boss-selo i {
  font-style: normal; font-family: inherit; font-weight: 600;
  padding-left: 6px; border-left: 1px solid rgba(42, 29, 5, .35); color: #4a3510;
}
.auto-boss-passe { color: #d8c48a !important; }

.auto-boss-acoes { align-items: center; flex-wrap: wrap; gap: 8px; }

/* O botão de começar: brilho que respira e um reflexo que passa. */
.auto-boss-brilho {
  position: relative; overflow: hidden;
  box-shadow: 0 0 0 1px rgba(120, 240, 210, .35), 0 0 14px rgba(79, 209, 181, .35);
  animation: autoBossRespira 2.6s ease-in-out infinite;
}
.auto-boss-brilho::after {
  content: ''; position: absolute; top: -20%; bottom: -20%; left: -40%; width: 30%;
  background: linear-gradient(100deg, transparent, rgba(255, 255, 255, .45), transparent);
  transform: translateX(-120%) skewX(-18deg);
  animation: autoBossReflexo 3.4s ease-in-out infinite;
  pointer-events: none;
}
.auto-boss-brilho:hover { box-shadow: 0 0 0 1px rgba(150, 255, 225, .6), 0 0 22px rgba(79, 209, 181, .6); }
.auto-boss-brilho:disabled { animation: none; box-shadow: none; }
.auto-boss-brilho:disabled::after { display: none; }
@keyframes autoBossRespira {
  0%, 100% { box-shadow: 0 0 0 1px rgba(120, 240, 210, .3), 0 0 10px rgba(79, 209, 181, .25); }
  50% { box-shadow: 0 0 0 1px rgba(150, 255, 225, .55), 0 0 22px rgba(79, 209, 181, .55); }
}
@keyframes autoBossReflexo {
  0%, 55% { transform: translateX(-120%) skewX(-18deg); }
  100% { transform: translateX(520%) skewX(-18deg); }
}

/* O atalho pequeno para a store: dourado como tudo que se compra com coins. */
/* `#modal .auto-boss` na frente: o `.confirm-actions button` da tela de confirmar vem depois e é mais forte. */
#modal .auto-boss .auto-boss-atalho,
.auto-boss .confirm-actions .auto-boss-atalho {
  margin-right: auto; cursor: pointer;
  padding: 4px 11px; border-radius: 999px;
  font-family: inherit; font-weight: 500; text-transform: none;
  font-size: 11px; letter-spacing: .02em;
  color: #ffe3a0; background: rgba(120, 88, 26, .22);
  border: 1px solid rgba(255, 214, 120, .45);
  transition: background .15s, box-shadow .15s;
}
#modal .auto-boss .auto-boss-atalho:hover,
.auto-boss .confirm-actions .auto-boss-atalho:hover { background: rgba(160, 118, 36, .38); box-shadow: 0 0 12px rgba(255, 200, 90, .35); }

@media (prefers-reduced-motion: reduce) {
  .auto-boss-brilho, .auto-boss-brilho::after { animation: none; }
}

/*
 * A oferta do passe, so durante a espera. Dourada como o resto do que se compra
 * com Mineiroidle Coins — a caixa em volta e' verde, e a diferenca de cor e' o que
 * diz "isto aqui custa dinheiro" antes de alguem ler.
 */
.auto-boss-oferta {
  display: grid; gap: 6px; justify-items: start;
  padding: 10px 12px; border: 1px solid #6d5420; border-radius: 8px;
  background: linear-gradient(180deg, #241a08, #16110a);
}
.auto-boss-oferta b { font-family: var(--font-heading); font-size: 12px; color: #ffe08a; }
.auto-boss-oferta em { font-style: normal; font-size: 11px; color: #c9b183; line-height: 1.45; }
.auto-boss-oferta button {
  margin-top: 2px; cursor: pointer; border-radius: 6px; padding: 6px 16px;
  background: linear-gradient(180deg, #7d5c1a, #46330d); border: 1px solid #ffe08a;
  color: #ffe9b0; font-family: var(--font-heading); font-size: 11px; letter-spacing: .06em;
}
.auto-boss-oferta button:hover { background: linear-gradient(180deg, #9a7222, #5c4211); }

/* ---------- as sequencias guardadas, dentro do modal de montar a lista ---------- */

.auto-boss-listas {
  display: grid; gap: 8px; margin-bottom: 12px;
  padding: 10px 12px; border: 1px solid var(--line); border-radius: 8px; background: var(--panel-2);
}
.auto-boss-listas-linha { display: flex; flex-wrap: wrap; align-items: center; gap: 7px; }
.auto-boss-listas-linha > b { font-family: var(--font-heading); font-size: 12px; }
.auto-boss-listas-linha > em { font-style: normal; font-size: 11px; color: var(--muted); }
.auto-boss-listas-linha input { flex: 1 1 200px; margin: 0; }
/* Cada sequencia e' um par: o nome (carrega) e o x (apaga), colados. */
.auto-boss-lista { display: inline-flex; }
.auto-boss-lista button { font-size: 11px; padding: 4px 10px; }
.auto-boss-lista button:first-child { border-radius: 6px 0 0 6px; }
.auto-boss-lista-x { border-radius: 0 6px 6px 0; border-left: none; padding: 4px 8px; color: var(--muted); }
.auto-boss-lista-x:hover { color: #ff8f8f; }

/*
 * Boss em cooldown na tela de montar: apagado, e no fim da grade. Ele nao se
 * marca (ver `escolherAutoBoss`); marcado, veio de uma sequencia guardada e
 * ainda da' para tirar — por isso a opacidade cai so' quando ele NAO esta
 * escolhido.
 */
.ciclo-card.em-cooldown:not(.escolhido) { opacity: .42; }
.ciclo-card.em-cooldown span { color: var(--copper); }
.boss-feito { color: var(--muted); }

/*
 * ---- A aba de Bosses vem em duas seções ----
 *
 * Boss task e boss diário sao coisas diferentes com o mesmo card. `hunt-secoes`
 * empilha as duas (titulo + grade), no lugar da grade unica das hunts.
 */
.hunt-secoes { display: flex; flex-direction: column; gap: 4px; }
.hunt-secoes > .empty { margin: 0 0 10px; }

/* A conta de mortes no card do boss de task. */
.boss-task { display: grid; gap: 4px; font-size: 11px; color: var(--muted); margin-top: 4px; }
.boss-task-barra { height: 4px; background: #0d1113; border-radius: 999px; overflow: hidden; }
.boss-task-barra i { display: block; height: 100%; background: var(--accent); }
.boss-task-aberta { color: var(--accent); font-weight: 600; }

.arena-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 8px; }
.arena-card {
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px;
  padding: 10px 8px; cursor: pointer; display: grid; justify-items: center; gap: 3px; color: inherit;
}
.arena-card:hover:not(:disabled) { border-color: var(--accent); }
.arena-card:disabled { opacity: .4; cursor: not-allowed; }
.arena-card.cleared { border-color: var(--accent-dim); background: #16241f; }
.arena-card b { font-family: var(--font-heading); font-size: 12px; }
.arena-card span { font-size: 11px; color: var(--text); text-align: center; }
.arena-card em { font-style: normal; font-size: 10px; color: var(--muted); }

.train-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 9px; }
.train-grid button { background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px; padding: 14px 10px; cursor: pointer; display: grid; justify-items: center; gap: 3px; }
.train-grid button:hover:not(:disabled) { border-color: var(--accent); }
.train-grid button[aria-selected="true"] { border-color: var(--accent); background: #16241f; }
.train-grid b { font-family: var(--font-heading); font-size: 13px; text-transform: capitalize; }
.train-grid em { font-style: normal; color: var(--muted); font-size: 11px; }

/* ---------- prey ---------- */

/*
 * Prey em três cartas.
 *
 * A ideia é a mesma da vitrine de um jogo: cada slot é um quadro. Travado
 * mostra o cadeado e o convite; escolhido vira retrato do bicho com estandarte
 * de raridade e barra de tempo; livre mostra a grade de candidatos. As cores
 * são as nossas — grafite, teal e cobre — e não o azul da referência.
 */
.prey-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 14px; }
.prey-head p { margin: 0; font-size: 12px; color: var(--muted); max-width: 62ch; line-height: 1.5; }
.prey-wallet {
  display: flex; align-items: center; gap: 7px; flex: none; padding: 7px 13px;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 999px;
}
.prey-wallet img { width: 20px; height: 20px; }
.prey-wallet b { font-family: var(--font-heading); font-size: 15px; color: var(--copper); }
.prey-wallet span { font-size: 10px; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); }

.prey-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; align-items: start; }
.prey-slot {
  display: flex; flex-direction: column; min-height: 430px;
  background: linear-gradient(180deg, #182226, var(--panel-2));
  border: 1px solid var(--line); border-radius: 10px; padding: 0 0 12px;
}
.prey-slot.locked { background: linear-gradient(180deg, #151b1e, #11171a); }

.prey-slot-head {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 10px 13px; border-bottom: 1px solid var(--line);
}
.prey-slot h4 { margin: 0; font-family: var(--font-heading); font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: var(--text); }
.prey-lock {
  font-size: 9px; text-transform: uppercase; letter-spacing: .08em; color: var(--muted);
  border: 1px solid var(--line); border-radius: 999px; padding: 2px 8px;
}

/* Slot travado: cadeado, o porquê e o convite, centrados no quadro. */
.prey-empty { flex: 1; display: grid; align-content: center; justify-items: center; gap: 8px; padding: 20px 16px; text-align: center; }
.prey-empty img { width: 54px; height: 54px; opacity: .5; }
.prey-empty b { font-family: var(--font-heading); font-size: 13px; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.prey-empty em { font-style: normal; font-size: 11px; color: var(--muted); max-width: 26ch; line-height: 1.5; }
.prey-unlock {
  margin-top: 8px; padding: 9px 20px; cursor: pointer; font-family: var(--font-heading); font-size: 12px;
  color: #2a1d05; background: linear-gradient(180deg, #f0cf7a, #c79a3c);
  border: 1px solid #ffe6a3; border-radius: 7px; box-shadow: inset 0 1px 0 #fff6d0;
}
.prey-unlock:hover { background: linear-gradient(180deg, #ffe4a0, #d9ae4a); }

/* Presa escolhida: o retrato. */
.prey-portrait { padding: 13px; display: grid; gap: 9px; }
.prey-name { text-align: center; font-family: var(--font-heading); font-size: 15px; color: var(--text); }
.prey-stage {
  position: relative; display: grid; place-items: center; min-height: 118px; padding: 10px;
  background: radial-gradient(ellipse at center, #1d2c2a 0%, #131a1d 72%);
  border: 1px solid var(--line-soft); border-radius: 8px;
}
.prey-stage canvas { image-rendering: pixelated; }
/* O estandarte é uma flâmula estreita pendurada no canto — as dez estrelas
   entram em duas fileiras de cinco, senão ela atravessa o quadro e cobre o
   bicho. */
.prey-banner {
  position: absolute; top: 0; right: 8px; width: 56px; display: grid; justify-items: center; gap: 4px;
  padding: 7px 5px 9px; background: linear-gradient(180deg, #23343a, #16232a);
  border: 1px solid var(--line); border-top: none; border-radius: 0 0 5px 5px;
}
.prey-banner > img { width: 24px; height: 24px; }
.prey-banner .prey-stars { display: grid; grid-template-columns: repeat(5, 8px); gap: 1px; justify-content: center; }
.prey-banner .prey-stars img { width: 8px; height: 9px; }
.prey-gain { text-align: center; font-family: var(--font-heading); font-size: 14px; color: var(--accent); }

.prey-time {
  position: relative; height: 22px; border-radius: 5px; overflow: hidden;
  background: var(--panel-solid); border: 1px solid var(--line);
}
.prey-time i { position: absolute; inset: 0 auto 0 0; background: linear-gradient(180deg, #2f7f6d, #1f5f54); }
.prey-time b {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-size: 10px; font-weight: 600; letter-spacing: .04em; color: #eafffb; text-shadow: 0 1px 2px #0009;
}
.prey-note { display: block; text-align: center; font-style: normal; font-size: 10px; color: var(--muted); }

.prey-bonus { display: grid; justify-items: center; gap: 4px; padding: 12px 12px 10px; }
.prey-bonus img { width: 26px; height: 26px; }
.prey-bonus b { font-size: 12px; color: var(--accent); }
.prey-stars { display: flex; gap: 1px; }
.prey-stars img { width: 10px; height: 11px; }

.prey-options { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; padding: 0 12px; }
.prey-options button {
  background: var(--panel-solid); border: 1px solid var(--line-soft); border-radius: 7px;
  padding: 8px 3px 6px; cursor: pointer; display: grid; justify-items: center; gap: 3px;
  font-size: 9px; line-height: 1.2; color: var(--muted); min-height: 78px; align-content: center;
}
.prey-options button canvas { image-rendering: pixelated; }
.prey-options button:hover { border-color: var(--accent); color: var(--text); background: #16241f; }

/* Rodapé: três fichas de ação com o preço embaixo do ícone. */
.prey-buttons { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; margin: auto 12px 0; padding-top: 12px; }
.prey-action {
  display: grid; justify-items: center; gap: 4px; padding: 8px 4px; cursor: pointer;
  background: var(--panel-solid); border: 1px solid var(--line); border-radius: 7px; color: var(--muted);
}
.prey-action img { width: 30px; height: 30px; }
.prey-action .price { display: flex; align-items: center; gap: 3px; font-size: 10px; }
.prey-action .price img { width: 13px; height: 13px; }
.prey-action:hover:not(:disabled) { border-color: var(--copper); color: var(--copper); background: #221d12; }
.prey-action:disabled { opacity: .4; cursor: not-allowed; }

.prey-toggles { display: grid; gap: 4px; margin: 8px 12px 0; font-size: 11px; color: var(--muted); }
.prey-toggles label {
  display: flex; align-items: center; gap: 8px; cursor: pointer; padding: 5px 9px;
  background: var(--panel-solid); border: 1px solid var(--line-soft); border-radius: 6px;
}
.prey-toggles label span:first-of-type { flex: 1; }
.prey-toggles .price { display: flex; align-items: center; gap: 3px; color: var(--copper); }
.prey-toggles .price img { width: 13px; height: 13px; }

@media (max-width: 900px), (max-height: 540px) and (pointer: coarse) {
  .prey-grid { grid-template-columns: 1fr; }
  .prey-slot { min-height: 0; }
}

.prey-all { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 6px; }
.prey-all button {
  display: flex; align-items: center; gap: 8px; text-align: left; cursor: pointer;
  background: var(--panel-2); border: 1px solid var(--line-soft); border-radius: 6px; padding: 6px 8px; color: inherit;
}
.prey-all button:hover { border-color: var(--accent); }
.prey-all b { font-size: 12px; font-weight: 500; flex: 1; }
.prey-all em { font-style: normal; font-size: 10px; color: var(--muted); }

/* ---------- imbuements ---------- */

/*
 * Painel de imbuir.
 *
 * O bloco de cima responde três perguntas de uma olhada: qual peça está sendo
 * encantada, quantos encaixes dela já foram usados, e o que já está ativo nela.
 * A lista de baixo é a vitrine — ícone, efeito, reagentes e preço.
 */
.imbue-piece { display: grid; grid-template-columns: 190px minmax(0, 1fr); gap: 14px; margin-bottom: 18px; align-items: start; }
.imbue-focus {
  display: grid; justify-items: center; gap: 7px; padding: 14px 12px; text-align: center;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 9px;
}
.imbue-focus h3 { margin: 0; font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
.imbue-frame {
  display: grid; place-items: center; width: 76px; height: 76px;
  background: radial-gradient(ellipse at center, #1d2c2a 0%, #131a1d 75%);
  border: 1px solid var(--line-soft); border-radius: 8px;
}
.imbue-frame canvas { image-rendering: pixelated; }
.imbue-frame .empty { font-size: 10px; color: #33403f; }
.imbue-focus b { font-family: var(--font-heading); font-size: 13px; line-height: 1.3; }
.imbue-focus em { font-style: normal; font-size: 10px; color: var(--muted); }
/* Encaixes como contas: cheia é encaixe usado. */
.imbue-dots { display: flex; gap: 5px; }
.imbue-dots i { width: 9px; height: 9px; border-radius: 999px; border: 1px solid var(--accent-dim); }
.imbue-dots i.on { background: var(--accent); }
.imbue-dots i.off { border-color: var(--line); }

.imbue-side { display: grid; gap: 10px; }
.imbue-slots { display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: 6px; }
.imbue-slots button {
  display: grid; justify-items: center; gap: 3px; padding: 8px 5px; cursor: pointer;
  background: var(--panel-solid); border: 1px solid var(--line); border-radius: 7px; color: inherit;
}
.imbue-slots button canvas { image-rendering: pixelated; }
.imbue-slots button .hole { display: block; width: 32px; height: 32px; border: 1px dashed var(--line); border-radius: 5px; }
.imbue-slots button[aria-selected="true"] { border-color: var(--accent); background: #16241f; }
.imbue-slots button:hover:not(:disabled) { border-color: var(--accent-dim); }
.imbue-slots button:disabled { opacity: .35; cursor: not-allowed; }
.imbue-slots span { font-size: 10px; text-align: center; line-height: 1.25; }
.imbue-slots em { font-style: normal; font-size: 9px; color: var(--muted); }

.imbue-active { display: grid; gap: 5px; }
/*
 * `> div`, e nao `div`: a regra tambem pegava o `.grow` la' dentro, e a linha
 * saia com uma caixa com fundo e borda propria dentro de outra. Passava
 * despercebido enquanto as duas eram um retangulo de 1px; com a moldura do grau
 * por fora, a caixa interna vira um segundo quadro encaixado.
 */
.imbue-active > div {
  display: flex; align-items: center; gap: 11px; padding: 8px 11px;
  background: var(--panel-2); border: 1px solid var(--line-soft); border-radius: 7px;
}
.imbue-active .grow { flex: 1; display: grid; gap: 1px; }
.imbue-active b { font-weight: 600; font-size: 12px; }
.imbue-active span { font-size: 11px; color: var(--muted); }
.imbue-active .empty { margin: 0; padding: 14px; text-align: center; font-size: 11px; color: var(--muted); background: var(--panel-2); border: 1px dashed var(--line); border-radius: 7px; }

.imbue-listhead { display: flex; align-items: center; gap: 14px; margin-bottom: 9px; }
.imbue-listhead h3 { margin: 0; flex: none; font-size: 12px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.imbue-listhead .search { flex: 1; margin: 0; }

.imbue-list { display: grid; gap: 6px; }
.imbue-row {
  display: grid; grid-template-columns: minmax(0, 1fr) auto auto; gap: 14px; align-items: center;
  background: var(--panel-2); border: 1px solid var(--line-soft); border-radius: 8px; padding: 10px 13px;
}
.imbue-row:hover { border-color: var(--accent-dim); background: #17211f; }
.imbue-row .name b { display: block; font-size: 12px; font-weight: 600; }
.imbue-row .name em { font-style: normal; font-size: 11px; color: var(--muted); line-height: 1.4; }
.imbue-row .cost { display: flex; align-items: center; gap: 8px; font-size: 11px; }
.imbue-row .cost b { color: var(--copper); font-family: var(--font-heading); font-size: 13px; }
/* Reagente como ficha, para o custo se ler de relance. */
.reagent {
  display: flex; align-items: center; gap: 3px; color: var(--muted); font-size: 10px;
  padding: 3px 7px 3px 3px; background: var(--panel-solid); border: 1px solid var(--line); border-radius: 999px;
}
.reagent canvas { width: 20px; height: 20px; image-rendering: pixelated; }

@media (max-width: 900px), (max-height: 540px) and (pointer: coarse) {
  .imbue-piece { grid-template-columns: 1fr; }
  .imbue-row { grid-template-columns: 1fr; gap: 8px; }
}

.imbue-row button, .quest-row button, .market-row button, .bless-card button, .store-card button {
  background: var(--accent-dim); border: 1px solid var(--accent-dim); color: #eafffb;
  border-radius: 6px; padding: 6px 13px; cursor: pointer; font-size: 12px; white-space: nowrap;
}
.imbue-row button:hover:not(:disabled), .quest-row button:hover:not(:disabled),
.market-row button:hover:not(:disabled), .store-card button:hover:not(:disabled) { filter: brightness(1.2); }
.imbue-row button:disabled, .quest-row button:disabled, .market-row button:disabled,
.store-card button:disabled {
  background: var(--panel); border-color: var(--line); color: var(--muted); cursor: not-allowed;
}
button.ghost { background: var(--panel-2); border: 1px solid var(--line); color: var(--text); border-radius: 6px; padding: 6px 13px; cursor: pointer; }
button.ghost:hover { border-color: var(--accent-dim); }

/* blessings: o desenho novo mora no fim do arquivo, junto com o do balcao. */

/* ---------- quests ---------- */

.quest-list { display: grid; gap: 6px; }
.quest-row {
  display: grid; grid-template-columns: auto 1fr auto auto; gap: 12px; align-items: center;
  background: var(--panel-2); border: 1px solid var(--line-soft); border-radius: 7px; padding: 9px 12px;
}
.quest-row .name { display: grid; gap: 4px; }
.quest-row .name b { font-size: 13px; font-weight: 600; }
.quest-row .name em { font-style: normal; font-size: 11px; color: var(--muted); }
.quest-row .cost { display: grid; gap: 2px; text-align: right; font-size: 11px; color: var(--muted); }
.quest-row .cost b { color: var(--copper); font-size: 12px; }
/*
 * A que FECHOU se destaca na aba de Entrega: e' o que a pessoa veio buscar, e
 * ela pode ter tres linhas iguais na frente.
 */
.quest-row.quest-pronta { border-color: var(--accent-dim); background: #101a17; }
/* A boss task ja' derrotada fica apagada — nao ha' mais nada a fazer com ela. */
.quest-row.quest-feita { opacity: .55; }

/*
 * ---- As abas de colecao (Outfits e Mounts) ----
 *
 * Uma grade de figuras com o nome embaixo; o que falta sai apagado e sem cor,
 * de modo que a lista se leia de relance como "isto eu tenho, isto nao".
 */
.colecao-track { margin: 8px 0 12px; }
.colecao-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); gap: 8px; }
.colecao-item {
  display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 8px 4px;
  background: var(--panel-2); border: 1px solid var(--line-soft); border-radius: 7px;
  font-size: 10px; text-align: center; color: var(--text);
}
.colecao-item.falta { opacity: .38; filter: grayscale(1); }
.colecao-item span { line-height: 1.2; }

/*
 * O tanque da stamina de treino, no pe' da aba de Treino. Aparece sempre — um
 * recurso que so' se mostra quando acaba e' um recurso que a pessoa descobre
 * sendo punida por ele.
 */
.treino-tanque {
  display: grid; gap: 5px; margin-top: 14px; padding: 10px 12px;
  background: var(--panel-2); border: 1px solid var(--line-soft); border-radius: 7px;
}
.treino-tanque b { font-size: 12px; font-weight: 600; }
.treino-tanque em { font-style: normal; font-size: 11px; color: var(--muted); }

/* ---------- montarias ---------- */

/*
 * A grade da vitrine de outfits e montarias, do mesmo tamanho da dos servicos.
 *
 * Eram cartoes de 140px ao lado da aba de premium, cujos cartoes tem 210 — duas
 * grades de tamanhos diferentes na mesma loja, e a dos bonecos era justamente a
 * que precisava de espaco: e' onde se olha o desenho antes de comprar. O dono
 * pediu "deixa no mesmo tamanho da grade de premium 30 dias".
 */
.mount-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 8px; }
.mount-card {
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px;
  padding: 10px; cursor: pointer; display: grid; justify-items: center; gap: 3px; color: inherit;
}
.mount-card:hover { border-color: var(--accent); }
.mount-card[aria-selected="true"] { border-color: var(--accent); background: #16241f; }
.mount-card b { font-family: var(--font-heading); font-size: 12px; text-align: center; }
.mount-card em { font-style: normal; font-size: 10px; color: var(--muted); }
.mount-card .owned { font-size: 10px; color: var(--accent); }
.mount-card .price, .outfit-list .price { display: flex; align-items: center; gap: 4px; font-size: 11px; color: var(--copper); }

/* ---------- loja de coins ---------- */

.store-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 8px; }
/*
 * ---- O card estica, e o BOTAO desce com ele ----
 *
 * A grade iguala a altura de todo card da linha pelo mais alto — o que sempre
 * foi assim e nunca incomodou, porque os cards eram parecidos. O card do Auto
 * Boss, com dois prazos dentro, ficou bem mais alto e os vizinhos viraram
 * retangulos com tres linhas de texto no topo e um vao morto embaixo.
 *
 * A saida NAO e' deixar cada um com a altura dele (`align-items: start`):
 * tentei, e a grade passa a ter buracos entre as linhas, que e' pior de olhar.
 *
 * O que arruma e' o preco DESCER ate' o rodape. O vao deixa de ser sobra e vira
 * alinhamento: os botoes de uma fileira ficam na mesma linha, que e' como toda
 * vitrine de produto se parece.
 */
.store-card {
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px;
  padding: 12px; display: flex; flex-direction: column; gap: 6px;
}
/* O ultimo filho e' o preco (ou a faixa de precos): ele vai para o fim. */
.store-card > button:last-child,
.store-card > .store-opcoes:last-child { margin-top: auto; }
.store-card b { font-family: var(--font-heading); font-size: 13px; }
.store-card em { font-style: normal; font-size: 11px; color: var(--muted); }
/* A caixa de destaque de um produto: o que o jogador precisa ler antes do resto. */
.store-card .store-destaque {
  font-size: 12px; font-weight: 600; line-height: 1.35; color: #f3d9a4;
  background: rgba(200, 130, 60, 0.16); border: 1px solid var(--copper);
  border-left-width: 4px; border-radius: 4px; padding: 7px 9px;
}
/* O aviso de contas diferentes: vermelho, para não ser lido como o mesmo recado. */
.store-card .store-destaque-alerta {
  color: #f6c1b8; background: rgba(200, 70, 55, 0.16); border-color: #c8503c;
}
/* Azul: vale para a conta inteira (o passe do Auto Boss). Pedido do dono, 15/09. */
.store-card .store-destaque-azul {
  color: #cfe6ff; background: rgba(70, 140, 230, 0.18); border-color: #4f9cff;
}
.store-card button { display: flex; align-items: center; gap: 6px; justify-content: center; }

/*
 * ---- O card de equipamento ----
 *
 * Ele carrega mais coisa que os outros: o nome, a linha de números, a regra de
 * quem pode usar e o preço. A ordem é a da decisão — o que é, o que dá, se
 * serve para mim, quanto custa.
 *
 * 'capitalize' porque o nome vem do items.xml em minúsculas ('falcon
 * longsword'), como em todo lugar que mostra item; quem o veste é a folha de
 * estilo, e não uma cópia do nome escrita à mão no servidor.
 */
/*
 * ---- Os filtros da prateleira de Itens ----
 *
 * Duas fileiras de fichas, uma por pergunta: "que tipo de peça?" e "o que serve
 * para o meu personagem?". Fichas e não uma caixa de seleção porque as duas
 * respostas cabem na tela inteiras — abrir uma lista para escolher entre seis
 * coisas visíveis é um clique cobrado à toa.
 *
 * O número dentro de cada ficha é quantas peças ela mostra AGORA, com o outro
 * filtro já aplicado. É ele que evita o clique que leva a lugar nenhum.
 */
.item-filtros { display: grid; gap: 6px; margin: 2px 0 12px; }
.item-filtro-linha { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.item-filtro-rotulo {
  flex: none; width: 58px;
  font-size: 10px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted);
}
.item-filtro-fichas { display: flex; gap: 5px; flex-wrap: wrap; }
.item-filtro-ficha {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 9px 4px 6px; cursor: pointer;
  background: linear-gradient(180deg, #101a1f, #0b1114);
  border: 1px solid var(--line); border-radius: 999px;
  font-family: inherit; font-size: 10px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--muted);
  transition: border-color .12s ease, color .12s ease, background .12s ease;
}
.item-filtro-ficha:hover { border-color: var(--accent-dim); color: var(--text); }
/*
 * A escolhida ACENDE — moldura, texto e um brilho de fora. É a mesma linguagem
 * do coração de favorita e das abas: verde é "isto está ligado".
 */
.item-filtro-ficha[aria-selected="true"] {
  background: linear-gradient(180deg, #1c2f38, #101a1f);
  border-color: var(--accent); color: var(--accent);
  box-shadow: 0 0 7px #6fe0c233;
}
/* A contagem, na bolinha do fim. */
.item-filtro-ficha i {
  font-style: normal; font-size: 9px; font-weight: 700;
  min-width: 15px; padding: 1px 4px; border-radius: 999px;
  background: #0b1114cc; color: #8fb8ae;
}
.item-filtro-ficha[aria-selected="true"] i { color: #b6ffcf; }
.item-filtro-ficha .filtro-arte,
.item-filtro-ficha .ui-icon {
  width: 18px; height: 18px; flex: none;
  image-rendering: pixelated; opacity: .7;
}
.item-filtro-ficha[aria-selected="true"] .filtro-arte,
.item-filtro-ficha[aria-selected="true"] .ui-icon,
.item-filtro-ficha:hover .filtro-arte,
.item-filtro-ficha:hover .ui-icon { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .item-filtro-ficha { transition: none; } }

/*
 * A marca de tier, ao lado do nome no balao do item.
 *
 * Dourada e pequena, como no client dele: ela nao e um atributo da peca, e uma
 * conquista feita nela — e por isso nao entra na fileira cinzenta dos numeros.
 */
/* A escolha de em qual peca usar a pedra do Tier Up. Uma linha por peca
   vestida que aceita tier, com o preco do proximo degrau a vista. */
.tier-escolha { display: grid; gap: 6px; margin-top: 8px; }
.tier-peca {
  display: flex; align-items: center; gap: 10px; text-align: left;
  padding: 8px 10px; cursor: pointer;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px;
  font-family: inherit; color: var(--text);
}
.tier-peca:hover:not(:disabled) { border-color: var(--accent); }
.tier-peca canvas { image-rendering: pixelated; flex: none; }
.tier-peca-texto { display: grid; gap: 2px; min-width: 0; }
.tier-peca-texto b { font-family: var(--font-heading); font-size: 13px; text-transform: capitalize; }
.tier-peca-texto em { font-style: normal; font-size: 11px; color: var(--muted); }
/* Sem os cores ou sem o ouro: apagada, mas com o preco a vista — ela responde
   quanto falta sem obrigar a fechar a janela e ir contar na mochila. */
.tier-peca.nao-da { opacity: .55; cursor: not-allowed; }

/*
 * ---- A mira da pedra do Tier Up ----
 *
 * Enquanto ela está ligada o cursor é uma cruz em TODA a página, e não só em
 * cima dos itens: a pergunta que ela faz é "onde?", e um cursor que volta ao
 * normal fora dos quadros diria que a pergunta acabou.
 *
 * Os quadros que podem receber acendem de leve — é o que separa "clique aqui"
 * de "aqui não adianta" antes do clique.
 */
body.mirando-tier, body.mirando-tier * { cursor: crosshair !important; }
body.mirando-tier .cell[data-item], body.mirando-tier .slot[data-item] {
  outline: 1px solid var(--accent-dim); outline-offset: -1px;
}
body.mirando-tier .cell[data-item]:hover, body.mirando-tier .slot[data-item]:hover {
  outline-color: var(--accent); box-shadow: 0 0 9px #6fe0c255;
}

/*
 * ---- O selo de tier em cima do item ----
 *
 * Canto de cima a esquerda (o de baixo a direita e da quantidade da pilha), e
 * ele BRILHA: numa grade de trinta quadrados iguais, a unica coisa que se
 * conquistou tem de se ver de relance. O pulso e lento — 2,4s — porque trinta
 * selos piscando rapido viram uma arvore de natal e ninguem olha para nenhum.
 *
 * A moldura dourada e a mesma do balao do item, para os dois falarem a mesma
 * lingua: dourado e tier, aqui e la.
 */
.cell.com-tier, .slot.com-tier { position: relative; }
/*
 * A arte de tier do client dele, no canto de cima à esquerda da peça.
 *
 * `image-rendering: pixelated` porque o desenho é de 9x8: qualquer suavização o
 * transforma num borrão. `pointer-events: none` para o selo não roubar o
 * clique da própria peça.
 */
.selo-tier-arte {
  position: absolute; top: -1px; left: -1px; z-index: 4;
  width: 9px; height: 8px; pointer-events: none;
  image-rendering: pixelated;
}

.selo-tier {
  position: absolute; top: -2px; left: -2px; z-index: 4;
  min-width: 11px; height: 11px; padding: 0 2px;
  display: grid; place-items: center;
  font-style: normal; font-size: 8px; font-weight: 700; line-height: 1;
  color: #ffe9b0; background: linear-gradient(180deg, #6b4f22, #2a1e0e);
  border: 1px solid #d8a657; border-radius: 4px;
  text-shadow: 0 1px 1px #000; pointer-events: none;
  animation: selo-tier-brilho 2.4s ease-in-out infinite;
}
@keyframes selo-tier-brilho {
  0%, 100% { box-shadow: 0 0 3px #d8a65755; }
  50% { box-shadow: 0 0 9px #ffd98acc, 0 0 16px #d8a65766; }
}
@media (prefers-reduced-motion: reduce) { .selo-tier { animation: none; box-shadow: 0 0 5px #d8a65788; } }

/*
 * O selo do IMBUEMENT, EMBAIXO do de tier.
 *
 * Os dois na mesma coluna da esquerda, empilhados: o canto direito é onde a
 * contagem da pilha já mora, e o azul ali brigava com ela. Empilhados, a peça
 * lê de cima para baixo — tier, depois imbuement.
 *
 * O número é quantos imbuements estão ativos; o tempo de cada um fica no balão,
 * que é onde cabe.
 *
 * Vale em qualquer lugar onde a peça apareça (mochila, bolsa, depósito, corpo),
 * porque quem desenha lê a própria peça. Ver `selarTier`.
 */
.cell.com-imbu, .slot.com-imbu { position: relative; }
/*
 * A arte do selo de imbuement: o MESMO desenho do tier, virado para o azul.
 *
 * Sai do `tools/gerar-selo-imbu.mjs`, que gira a matiz dos `tier-N.png` da
 * base. Mesma forma, mesma borda, mesmo brilho — só a cor muda, e é a cor que
 * diz qual dos dois selos é qual. Fica logo abaixo do de tier, na mesma coluna.
 */
.selo-imbu-arte {
  position: absolute; top: 8px; left: -1px; z-index: 4;
  width: 9px; height: 8px; pointer-events: none;
  image-rendering: pixelated;
}

.selo-imbu {
  position: absolute; top: 11px; left: -2px; z-index: 4;
  min-width: 11px; height: 11px; padding: 0 2px;
  display: grid; place-items: center;
  font-style: normal; font-size: 8px; font-weight: 700; line-height: 1;
  color: #cdf3ff; background: linear-gradient(180deg, #1d4a5c, #0d2029);
  border: 1px solid #57b6c8; border-radius: 4px;
  text-shadow: 0 1px 1px #000; pointer-events: none;
  box-shadow: 0 0 5px #57b6c855;
}

.tip-id .item-tier {
  font-style: normal; font-size: 9px; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--copper, #d8a657);
  margin-left: 6px; padding: 1px 5px; border-radius: 999px;
  background: #2a1e0e; border: 1px solid #6b4f22;
}

.store-card.item-card .item-card-nome { text-transform: capitalize; }
.store-card.item-card .item-card-resumo { color: var(--text); font-size: 11px; line-height: 1.35; }

/*
 * A regra de uso: vocação, level e as duas mãos, em fichinhas.
 *
 * Cinza quando serve, vermelha quando não — e não impede a compra. Dá para
 * comprar hoje a arma do level 300 e guardá-la; o que não pode acontecer é a
 * compra ENGANADA, que é a única que dá arrependimento.
 */
.item-card-regra { display: flex; flex-wrap: wrap; gap: 4px; }
.item-card-regra i {
  font-style: normal; font-size: 9px; letter-spacing: .06em; text-transform: uppercase;
  padding: 2px 6px; border-radius: 999px;
  background: #0b1114; border: 1px solid var(--line); color: var(--muted);
}
.item-card-regra .item-card-voc { text-transform: capitalize; letter-spacing: .04em; }
.item-card-regra.nao-serve i { border-color: #7d3a34; color: #e9a79c; }
/* Quantas já estão na mochila: a pergunta de quem volta à loja e não lembra. */
.store-card .store-tem { text-align: center; font-size: 10px; color: var(--accent-dim); }

/* ---------- armas de treino ---------- */

/* O titulo de cada degrau da prateleira (boosted, durable, lasting...). */
.store-degrau {
  font-family: var(--font-heading); font-size: 12px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted); margin: 14px 0 8px; padding-bottom: 6px; border-bottom: 1px solid var(--line-soft);
}
.store-degrau:first-child { margin-top: 0; }
/* Cargas e duracao: o par que o jogador compara entre duas ofertas. */
.exercise-cargas { color: var(--copper) !important; }
/* Quantas ele ja tem — some quando e' zero, entao nunca diz "voce tem 0". */
.exercise-tem { color: var(--accent) !important; }

/*
 * ---- Os cards de pacote ----
 *
 * Mais largos que os outros porque mostram o CONTEUDO item por item, e uma
 * lista de tres linhas espremida em 150px vira duas colunas de nada. A conta
 * (preco avulso riscado + desconto) fica logo acima do botao, que e' onde o
 * olho ja' esta' quando decide.
 */
.pacote-grid { grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); }
.pacote-card { align-items: stretch; text-align: left; }
.pacote-card > b, .pacote-card > em { text-align: center; }
.pacote-conteudo {
  list-style: none; margin: 8px 0 4px; padding: 8px; display: flex; flex-direction: column; gap: 6px;
  background: #0d1113; border: 1px solid var(--line-soft); border-radius: 6px;
}
.pacote-conteudo li { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--text); }
.pacote-conteudo li canvas { flex: none; }
.pacote-conta { display: flex; align-items: center; justify-content: center; gap: 8px; margin: 6px 0; }
.pacote-conta s { color: var(--muted); font-size: 12px; }
.pacote-conta i {
  font-style: normal; font-size: 11px; font-weight: 700; color: #0d1113; background: var(--accent);
  border-radius: 999px; padding: 1px 7px;
}

/* A arma que esta na mao, no card do treino Exercise. */
.exercise-mao {
  display: flex; align-items: center; gap: 12px; margin: 10px 0;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px; padding: 12px;
}
.exercise-mao-texto { display: grid; gap: 3px; }
.exercise-mao-texto b { font-family: var(--font-heading); font-size: 14px; }
.exercise-mao-texto em { font-style: normal; font-size: 11px; color: var(--muted); }
/*
 * A estimativa do tipo inteiro, logo abaixo da arma da mão.
 *
 * Ela acende quando a troca automática está ligada — porque aí o número é uma
 * promessa que o jogo vai cumprir — e fica apagada quando não está, onde ela é
 * só o que a marca daria.
 */
.exercise-falta {
  display: grid; gap: 2px; margin: -4px 0 10px; padding: 8px 12px;
  border-left: 2px solid var(--accent-dim); background: #ffffff05; border-radius: 0 6px 6px 0;
}
.exercise-falta b { font-family: var(--font-heading); font-size: 12px; color: var(--accent); }
.exercise-falta em { font-style: normal; font-size: 10px; color: var(--muted); line-height: 1.45; }
.exercise-falta.apagada { border-left-color: var(--line); }
.exercise-falta.apagada b { color: var(--muted); }

/*
 * A marca de "continuar com a próxima arma".
 *
 * Ela tem moldura, e as outras marcas do jogo não têm. O motivo é o que ela
 * faz: é a única caixinha que autoriza o servidor a GASTAR o que foi comprado
 * com Mineiroidle Coins sem perguntar mais nada. Uma linha de rodapé cinza, do
 * tamanho de "ver as habilidades do grupo", seria fácil demais de marcar sem
 * ler — e não há como devolver uma carga.
 */
.exercise-auto {
  display: flex; align-items: flex-start; gap: 8px; margin: 10px 0;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px;
  padding: 10px 12px; cursor: pointer;
}
.exercise-auto input { accent-color: var(--accent); cursor: pointer; margin-top: 2px; }
.exercise-auto span { display: grid; gap: 3px; }
.exercise-auto b { font-size: 12px; }
.exercise-auto em { font-style: normal; font-size: 11px; color: var(--muted); line-height: 1.4; }

/*
 * O atalho para a loja, no pé da tela do Exercise.
 *
 * Moldura dourada e não verde: ele não é uma ação do treino, é uma saída para
 * outro lugar. A diferença de cor é o que impede alguém de clicar nele achando
 * que está começando a treinar.
 */
/*
 * Dois cartazes lado a lado e UM botao no meio embaixo. Ver `escolherExercise`:
 * as armas de treino e o pergaminho levam a mesma loja, entao dois botoes so
 * dariam uma escolha que nao existe.
 */
.exercise-loja {
  display: grid; gap: 10px; justify-items: center; margin-top: 14px; padding: 12px 14px;
  background: linear-gradient(180deg, #241a08, #16110a);
  border: 1px solid #6d5420; border-radius: 10px;
}
.exercise-loja-cartazes {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 10px 18px;
  width: 100%;
}
.exercise-loja-cartaz { display: grid; gap: 4px; align-content: start; }
/* O desenho do pergaminho encostado no titulo dele. */
.exercise-loja-cartaz b { display: flex; align-items: center; gap: 7px; }
.exercise-loja-cartaz b canvas { image-rendering: pixelated; flex: none; }
/* Quanto ele ja tem guardado: informacao, e nao anuncio — por isso na cor do jogo. */
.exercise-loja-saldo { font-size: 11px; color: var(--accent); }
/* O desconto do lote: o preço cheio some, o que se paga fica. */
/* ---------- o presente de nível ----------

   A faixa do meio de baixo foi embora e levou este bloco junto: `#presente`,
   `#presente-fila`, os dois baús de 84px, o "—" de minimizar e as duas
   animações que os faziam pulsar. Os avisos agora são dois botões da barra de
   cima, à direita de Social, e usam a pintura da própria fileira (ver
   `.aviso-da-barra`, no fim desta folha).

   O que sobrou aqui embaixo é a JANELA do presente, que não mudou. */

/* A grade de escolha do presente: as mesmas caixas do treino. */
.presente-escolha { display: grid; grid-template-columns: repeat(4, 1fr); gap: 9px; }
.presente-escolha button {
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px; padding: 12px 8px;
  cursor: pointer; display: grid; justify-items: center; gap: 4px;
}
.presente-escolha button:hover { border-color: var(--accent); background: #16241f; }
/* A escolha do elemento do Boost Dano 1 hora: ícone do elemento em cima do nome. */
.escolha-de-elemento button img { width: 34px; height: 34px; }
/* As Chegadas em 5 páginas de 100 (o dono, 01/10). */
.chegadas-paginas { display: inline-flex; gap: 4px; flex-wrap: wrap; margin: 0 0 0 6px; }
.chegadas-paginas button { display: inline-flex; flex-direction: column; align-items: center; gap: 0; min-width: 40px; padding: 2px 6px; line-height: 1.1; }
.chegadas-paginas button em { font-size: 10px; opacity: 0.7; font-style: normal; }
.chegadas-paginas button.ativa { border-color: var(--accent); background: #16241f; }
/* A escolhida fica marcada até o Confirmar: o mesmo par de estados do treino. */
.presente-escolha button[aria-selected="true"] {
  border-color: var(--accent); background: #16241f; box-shadow: 0 0 0 1px var(--accent-dim) inset;
}
.presente-escolha b { font-family: var(--font-heading); font-size: 12px; text-align: center; }
.presente-escolha em { font-style: normal; font-size: 11px; color: var(--muted); }
.presente-passos { display: flex; gap: 5px; justify-content: center; margin: 10px 0 4px; }
.presente-passos i {
  width: 26px; height: 5px; border-radius: 999px; background: var(--line);
}
.presente-passos i.pego { background: var(--copper); }
.presente-passos i.agora { background: var(--accent); }

/* ---------- o que o treino custou ---------- */

.treino-gastos-titulo {
  font-family: var(--font-heading); font-size: 12px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted); margin: 14px 0 6px; padding-bottom: 5px; border-bottom: 1px solid var(--line-soft);
}
.treino-gastos { display: grid; gap: 5px; }
.treino-gasto {
  display: flex; align-items: center; gap: 9px;
  background: var(--panel-2); border: 1px solid var(--line-soft); border-radius: 6px; padding: 5px 9px;
}
.treino-gasto b { font-family: var(--font-heading); font-size: 12px; }
/* O número encostado na direita: é o que se compara entre duas linhas. */
.treino-gasto em { font-style: normal; font-size: 11px; color: var(--copper); margin-left: auto; }

.lote-desconto { display: block; font-style: normal; font-size: 11px; color: var(--accent); margin-top: 3px; }

.exercise-loja b { font-family: var(--font-heading); font-size: 13px; color: #ffe08a; }
.exercise-loja em { font-style: normal; font-size: 11px; color: #c9b183; line-height: 1.5; }
.exercise-loja button {
  margin-top: 4px; cursor: pointer; border-radius: 6px; padding: 8px 20px;
  background: linear-gradient(180deg, #7d5c1a, #46330d); border: 1px solid #ffe08a;
  color: #ffe9b0; font-family: var(--font-heading); font-weight: 600; letter-spacing: .06em;
}
.exercise-loja button:hover { background: linear-gradient(180deg, #9a7222, #5c4211); }

/* ---------- mercado ---------- */

.market-bar { display: flex; gap: 8px; align-items: center; margin-bottom: 12px; }
.market-bar .search { margin: 0; flex: 1; }
.market-bar select { background: var(--panel-2); border: 1px solid var(--line); border-radius: 6px; padding: 8px 10px; cursor: pointer; }
.market-bar b { color: var(--copper); white-space: nowrap; }
.market-list { display: grid; gap: 4px; }
.market-row {
  display: grid; grid-template-columns: auto 1fr auto auto auto; gap: 10px; align-items: center;
  background: var(--panel-2); border: 1px solid var(--line-soft); border-radius: 6px; padding: 6px 10px;
}
.market-row .name { font-size: 12px; }
.market-row .name b { display: block; font-weight: 500; }
.market-row .name em { font-style: normal; font-size: 10px; color: var(--muted); }
.market-row .price { color: var(--copper); font-size: 12px; text-align: right; white-space: nowrap; }
.market-row .kind { font-size: 10px; color: var(--muted); white-space: nowrap; }
.market-head { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.market-head b { display: block; font-family: var(--font-heading); font-size: 15px; }
.market-head em { font-style: normal; font-size: 11px; color: var(--muted); }
.market-columns { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
.market-form { display: grid; grid-template-columns: 90px 1fr auto auto; gap: 8px; }
.market-form input { background: #080b0c; border: 1px solid var(--line); border-radius: 6px; padding: 8px 10px; }
.market-form button { background: var(--accent-dim); border: 1px solid var(--accent-dim); color: #eafffb; border-radius: 6px; padding: 8px 14px; cursor: pointer; }

/* ---------- loja de gold ---------- */

.shop-list { display: grid; gap: 6px; }
.shop-row {
  display: grid; grid-template-columns: 36px 1fr auto auto; gap: 12px; align-items: center;
  background: var(--panel-2); border: 1px solid var(--line-soft); border-radius: 6px; padding: 7px 11px;
}
.shop-row.upgrade { border-color: var(--accent-dim); }
.shop-row .name { font-size: 13px; }
.shop-row .name em { font-style: normal; display: block; color: var(--muted); font-size: 11px; }
.shop-row .price { font-size: 13px; color: var(--copper); text-align: right; }
.shop-row button {
  background: var(--accent-dim); border: 1px solid var(--accent-dim); color: #eafffb;
  border-radius: 6px; padding: 6px 14px; cursor: pointer; font-size: 12px;
}
.shop-row button:hover:not(:disabled) { filter: brightness(1.2); }
.shop-row button:disabled { background: var(--panel); border-color: var(--line); color: var(--muted); cursor: not-allowed; }
.shop-note { color: var(--muted); font-size: 11px; margin: 0 0 14px; }
.shop-note img { vertical-align: -3px; }
/*
 * ---- O ícone que acompanha um rótulo ----
 *
 * Mesmo tamanho da linha de texto e alinhado pela base dela, para o rótulo
 * continuar sendo uma linha só. `flex: none` porque ele nunca encolhe: um
 * ícone amassado é pior do que um rótulo cortado.
 *
 * Os desenhos novos são de 128px descendo para 16 — precisam ser suavizados, e
 * é o contrário do `pixelated` que os recortes antigos do client pedem.
 */
.icone-do-campo {
  width: 16px; height: 16px; flex: none; vertical-align: -3px; margin-right: 5px;
  image-rendering: auto; opacity: .9;
}
.number-label { display: flex; align-items: center; gap: 0; }
/*
 * O parágrafo de EXEMPLO.
 *
 * Ele não é mais uma nota entre notas: é o "faça assim" que faz a condição de
 * criatura ser entendida de primeira. Um friso na margem e um fundo de meio
 * tom bastam para o olho pousar nele sem que a caixa vire um cartaz.
 */
.shop-note.dica {
  border-left: 2px solid var(--accent-dim, var(--line));
  background: #ffffff08; padding: 6px 9px; border-radius: 0 5px 5px 0;
  color: var(--text); line-height: 1.45;
}

/* ---------- editor de ação ---------- */

/*
 * ---- O editor cabe na tela ----
 *
 * O botão que SALVA a ação ficava no fim de uma coluna que cresce: cada
 * condição nova empurrava o "Aplicar" para baixo, e numa tela de 900px de
 * altura, com três condições, era preciso rolar a janela para conseguir
 * clicar nele. Salvar é a última coisa que alguém faz aqui e era a mais longe.
 *
 * Três medidas, e nenhuma delas é encolher a fonte:
 *
 *   - a lista da esquerda vira uma fração da tela (`vh`) em vez de 420px fixos,
 *     então ela encolhe junto com a janela em vez de esticá-la;
 *   - a coluna da direita ganha rolagem PRÓPRIA, e não empurra mais o rodapé;
 *   - o rodapé gruda no pé da janela (`sticky`), com um degradê por baixo para
 *     o conteúdo passar atrás dele sem virar sopa.
 *
 * Resultado: o Aplicar está sempre no mesmo lugar, e a rolagem — quando existe —
 * é só da lista de condições.
 */
.action-editor { display: grid; grid-template-columns: 264px 1fr; gap: 14px; align-items: start; }
.action-list { display: grid; gap: 3px; max-height: min(46vh, 420px); overflow-y: auto; padding-right: 4px; }
.action-item {
  display: flex; align-items: center; gap: 8px; text-align: left; cursor: pointer;
  background: var(--panel-2); border: 1px solid var(--line-soft); border-radius: 6px; padding: 6px 9px; color: inherit;
}
.action-item:hover { border-color: var(--accent-dim); }
.action-item[aria-selected="true"] { border-color: var(--accent); background: #16241f; }
.action-item.blocked { opacity: .5; }
.action-side { display: grid; gap: 8px; align-content: start; }
.action-filters { display: grid; gap: 6px; }
.action-filters input, .action-filters select {
  background: #080b0c; border: 1px solid var(--line); border-radius: 5px; padding: 6px 8px; font-size: 12px; width: 100%;
}
.filter-row { display: grid; grid-template-columns: 96px 1fr; gap: 6px; }
.action-text { flex: 1; display: grid; gap: 1px; min-width: 0; }
.action-item b { font-weight: 500; font-size: 12px; }
/* As palavras da magia em dourado, como no client. */
.action-text em.words { font-style: normal; font-size: 10px; color: var(--exp); letter-spacing: .2px; }
.action-cost { font-size: 10px; color: var(--muted); flex: none; }
.action-item em { font-style: normal; font-size: 10px; color: var(--muted); }
.number-row { justify-content: flex-start; }
.number-label { flex: 1; font-size: 12px; color: var(--muted); }
.action-head .action-text b { font-family: var(--font-heading); font-size: 15px; }
.action-head .action-text em.words { font-size: 11px; }
.action-item .rune-mark, .hotbar .rune-mark { font-family: var(--font-heading); }
.action-detail {
  display: grid; gap: 5px; align-content: start;
  max-height: min(60vh, 560px); overflow-y: auto; padding-right: 4px;
}
/* Os títulos do detalhe eram tão altos quanto os do modal e comiam três linhas
   de altura útil cada um. */
.action-detail h3 { margin: 6px 0 0; font-size: 12px; }
.action-detail .shop-note { margin: 0 0 4px; }
.action-head { display: flex; align-items: center; gap: 10px; }
.action-head b { font-family: var(--font-heading); font-size: 15px; }
.action-detail p { margin: 0; font-size: 12px; color: var(--text); }
.action-detail p.words { color: var(--accent); font-style: italic; }
.action-detail p.blocked-note { color: var(--danger); }
.condition {
  display: flex; gap: 6px; align-items: center; flex-wrap: wrap;
  background: var(--panel-2); border: 1px solid var(--line-soft); border-radius: 6px; padding: 6px 8px;
}
/*
 * ---- Os dois campos do "Quem curar" ----
 *
 * `.field` nunca teve regra nenhuma nesta folha: a lista e a caixa de nome
 * saiam com a pintura de fabrica do navegador — fundo branco, borda cinza —
 * dentro de um painel escuro. Era o que o dono viu.
 *
 * A pintura e' a mesma da linha de condicao, logo abaixo delas na mesma tela.
 * Ficar igual e' o ponto: sao dois controles do mesmo painel.
 */
.field { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--muted); }
.field > span { flex: none; }
.condition select, .condition input,
.field select, .field input {
  background: #080b0c; border: 1px solid var(--line); border-radius: 5px; padding: 5px 7px; font-size: 12px;
  color: var(--text);
}
.field select, .field input { flex: 1 1 auto; min-width: 0; }
.field select:focus, .field input:focus { outline: none; border-color: var(--accent-dim); }
.condition input[type="number"] { width: 64px; }
.condition .step { width: 26px; height: 26px; padding: 0; background: var(--panel-solid); border: 1px solid var(--line); border-radius: 5px; cursor: pointer; }
.condition .step.danger:hover { border-color: var(--danger); color: #ffd9d6; }
/*
 * ---- A condição por criatura ----
 *
 * A lista de nomes escolhidos quebra para a linha de baixo (o `.fichas` ocupa
 * a largura toda), e não fica espremida ao lado dos controles: são nomes de
 * tamanho livre — "grim reaper", "hellspawn" — e quatro deles numa linha só
 * empurrariam o botão de apagar para fora da caixa.
 */
.condition .rotulo { font-size: 12px; color: var(--muted); }
.condition.nome input[type="text"] { flex: 1 1 120px; min-width: 90px; }
.condition .fichas { flex: 1 1 100%; display: flex; flex-wrap: wrap; gap: 4px; }
.condition .fichas .vazio { font-size: 11px; color: var(--muted); font-style: italic; }
.condition .fichas .ficha {
  display: inline-flex; align-items: center; gap: 4px;
  background: var(--panel-solid); border: 1px solid var(--line); border-radius: 999px;
  padding: 2px 4px 2px 9px; font-size: 11px; color: var(--text);
}
.condition .fichas .ficha .step {
  width: 16px; height: 16px; line-height: 1; font-size: 10px;
  border-radius: 999px; border-color: transparent; background: transparent; color: var(--muted);
}
.condition .fichas .ficha .step:hover { color: #ffd9d6; border-color: var(--danger); }
.switch { display: flex; align-items: center; gap: 5px; font-size: 12px; color: var(--muted); cursor: pointer; }
.action-footer {
  display: flex; align-items: center; gap: 12px;
  position: sticky; bottom: 0; z-index: 4; margin-top: 8px; padding: 9px 0 3px;
  background: linear-gradient(to top, var(--panel-solid) 72%, transparent);
}
.action-footer button { border-radius: 6px; padding: 7px 16px; cursor: pointer; border: 1px solid var(--accent-dim); background: var(--accent-dim); color: #eafffb; }
.action-footer button.danger { background: var(--panel-2); border-color: var(--line); color: var(--danger); }
.action-footer .switch { margin-left: auto; }
.action-footer button:disabled { background: var(--panel); border-color: var(--line); color: var(--muted); cursor: not-allowed; }

/* ---------- blacklist da bolsa ---------- */

.add-cell {
  display: flex; align-items: center; justify-content: center; cursor: pointer;
  font-size: 20px; line-height: 1; color: var(--accent);
  background: transparent; border: 1px dashed var(--accent-dim); border-radius: 6px;
}
.add-cell:hover { background: #16241f; border-style: solid; }
.picker-search {
  width: 100%; background: #080b0c; border: 1px solid var(--line); border-radius: 6px;
  padding: 8px 10px; margin-bottom: 10px;
}
.picker-results { max-height: 320px; overflow-y: auto; }

/* ---------- confirmação de compra ---------- */

/*
 * A confirmacao fica acima de TUDO, inclusive das janelas do saldo (z-index 56).
 *
 * Ela era 55, e passou a nascer de dentro da janela de transferir — que abre por
 * cima da loja. O pedido de confirmacao aparecia ATRAS dela: o jogador clicava
 * em "Transferir" e nada acontecia na tela, com a pergunta escondida no fundo.
 */
.confirm-back {
  position: fixed; inset: 0; z-index: 58; display: grid; place-items: center;
  background: #04070880; backdrop-filter: blur(2px);
}
/*
 * ---- E ela NÃO passa da tela ----
 *
 * A caixa nasceu para uma compra: título, preço, dois botões. A confirmação de
 * entrega pôs uma grade de itens dentro dela, e o addon 1 do Mage pede treze —
 * a caixa passava de alto a baixo do monitor, e as pontas (o título em cima,
 * os botões embaixo) ficavam fora da tela, sem rolagem que as alcançasse.
 * Era o "alguns modal estão fora de tela".
 *
 * O teto é da JANELA, e não um número de pixels: quem decide é a tela de quem
 * está olhando.
 */
.confirm-box {
  width: min(360px, 90vw); display: grid; gap: 12px; padding: 20px 22px;
  max-height: 88vh; overflow-y: auto; overscroll-behavior: contain;
  background: var(--panel-solid); border: 1px solid var(--accent-dim); border-radius: 10px;
  box-shadow: 0 18px 48px #000a;
}
/* A confirmação de entrega é mais larga: ela mostra os dois lados da troca. */
.confirm-box.confirm-largo { width: min(460px, 94vw); }
.confirm-box h3 { margin: 0; font-size: 15px; color: var(--accent); }
.confirm-box canvas { justify-self: center; }
.confirm-item { margin: 0; font-family: var(--font-heading); font-size: 16px; text-align: center; }
.confirm-rows { display: grid; gap: 5px; font-size: 12px; }
.confirm-rows div { display: flex; justify-content: space-between; gap: 12px; color: var(--muted); }
.confirm-rows div b { color: var(--text); font-weight: 500; }
.confirm-rows .cost b { color: var(--copper); }
.confirm-rows .after { border-top: 1px solid var(--line-soft); padding-top: 6px; }
.confirm-rows .after b { color: var(--accent); }
.confirm-short { margin: 0; font-size: 12px; color: var(--danger); text-align: center; }
/*
 * O aviso da confirmação — "esta arma é de paladino", "pede level 300".
 *
 * Cor de alerta e não de erro: ele não barra a compra, avisa. Quem quiser
 * comprar a arma do level 300 no level 80 e guardá-la continua podendo.
 */
.confirm-aviso {
  margin: 0; font-size: 12px; line-height: 1.4; text-align: center;
  color: var(--copper, #d8a657);
}
/*
 * ---- A exigencia do produto, em destaque ----
 *
 * "SO ENTRA LEVEL X+ E COM PREMIUM, e isso bem destacado, porque tao comprando
 *  sem ter level e premy."
 *
 * Mais forte que o `.confirm-aviso` de proposito: maiuscula, negrito e uma
 * moldura. O aviso explica a SITUACAO de quem esta comprando; esta linha e' a
 * REGRA do produto, e e' a que a pessoa precisa ler antes de gastar 50 coins.
 */
/*
 * ---- Os prazos do Auto Boss, dentro do card ----
 *
 * "no mesmo card, só que meio que separado bonito."
 *
 * Uma faixa com fundo próprio e um traço em cima: separada do texto sem virar
 * outro card. Cada prazo numa linha, com o nome à esquerda e o preço à direita —
 * é a leitura de uma tabela de preços, que é o que a pessoa está fazendo ali.
 */
.store-opcoes {
  display: flex; flex-direction: column; gap: 6px;
  margin-top: 10px; padding-top: 10px;
  border-top: 1px solid var(--linha, rgba(216, 166, 87, .25));
}
.store-opcao {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 6px 8px; border-radius: 6px;
  background: rgba(255, 255, 255, .03);
}
.store-opcao-prazo {
  display: flex; flex-direction: column; gap: 2px;
  font-weight: 700; font-size: 13px;
}
.store-opcao-desconto {
  font-style: normal; font-weight: 600; font-size: 11px;
  color: var(--verde, #7fd18b);
}
.store-opcao button { margin: 0; white-space: nowrap; }
.auto-boss-ativo { color: var(--copper, #d8a657); }

/*
 * ---- As duas tentativas da forja ----
 *
 * O botao normal e o reforcado lado a lado: a escolha e' entre dois precos com
 * duas chances, e ver os dois juntos e' o que permite comparar. Cada um mostra
 * a chance e o preco embaixo do nome, porque e' isso que difere entre eles.
 */
/*
 * ---- A palavra da forja, por cima da peça ----
 *
 * FAILED / SUCCESS / UPGRADE saem do próprio client (ver `efeitos-da-forja.mjs`)
 * e são desenhadas num canvas. Ficam CENTRADAS sobre a moldura, sem empurrar
 * nada: `position: absolute` para o cartaz continuar do mesmo tamanho com ou
 * sem elas.
 */
/*
 * A palavra do resultado em cima do quadro da peça: centrada, por cima de tudo,
 * e sem ocupar espaço — o quadro tem o mesmo tamanho com ela e sem ela.
 */
/*
 * A coluna do meio: as setas, e a palavra do resultado logo acima delas.
 *
 * A palavra é `absolute` para não empurrar as setas para baixo — a bancada fica
 * com a mesma altura antes e depois da forja, e nada pula de lugar quando o
 * resultado chega.
 */
.forja-meio { position: relative; display: grid; place-items: center; }
.forja-palavra {
  /*
   * Encostada nas setas: `bottom: 100%` a deixava flutuando bem acima, porque a
   * palavra ocupa só a parte de baixo da célula de 64px do sprite e o resto é o
   * rastro. Descendo, ela fica junto do que está explicando.
   */
  position: absolute; bottom: 25%; left: 50%;
  transform: translateX(-50%);
  image-rendering: pixelated; pointer-events: none;
  z-index: 4;
}
.forja-quadro { position: relative; }
/*
 * A seta do meio conta o resultado: verde quando subiu, vermelha quando caiu.
 * A transição é o que faz a cor ser notada — ela ACENDE, não aparece pronta.
 */
/*
 * ---- O cartão da bancada se pinta pelo resultado ----
 *
 * "o card tem que ficar vermelho ou verde de acordo com sucesso ou falha."
 *
 * A cor entra na MOLDURA dos dois quadros e no fundo da bancada, de leve: forte
 * o bastante para ser lida de relance, fraca o bastante para não competir com a
 * peça desenhada dentro dela.
 */
/*
 * ---- Só o quadro da PEÇA se pinta ----
 *
 * O da direita é o "Fica": ele mostra a promessa do PRÓXIMO degrau, e não o que
 * acabou de acontecer. Pintado, ele dizia que o próximo já tinha dado certo.
 * Fica com a cor de sempre — pedido do dono, e é o certo.
 */
.forja-bancada.deu-certo .forja-quadro:not(.resultado) {
  border-color: var(--verde, #7fd18b);
  background: linear-gradient(180deg, rgba(127, 209, 139, .10), transparent 70%);
}
.forja-bancada.falhou .forja-quadro:not(.resultado) {
  border-color: var(--perigo, #d4574a);
  background: linear-gradient(180deg, rgba(212, 87, 74, .10), transparent 70%);
}
.forja-bancada .forja-quadro { transition: border-color .25s ease, background .25s ease; }

.forja-setas { transition: color .25s ease, text-shadow .25s ease; }
.forja-setas.deu-certo {
  color: var(--verde, #7fd18b);
  text-shadow: 0 0 10px rgba(127, 209, 139, .55);
}
.forja-setas.falhou {
  color: var(--perigo, #d4574a);
  text-shadow: 0 0 10px rgba(212, 87, 74, .45);
}
/* Uma falha não brilha: a moldura fica fria e o texto, cor de aviso. */
.forja-resultado.falhou .forja-moldura {
  border-color: var(--perigo, #d4574a);
  box-shadow: none;
}
.forja-resultado.falhou .forja-resultado-texto b { color: var(--perigo, #d4574a); }

.forja-tentativas { display: flex; gap: 8px; align-items: stretch; }
.forja-tentativas .forja-botao {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  line-height: 1.2; padding: 8px 14px;
}
.forja-tentativas .forja-botao em { font-style: normal; font-size: 11px; opacity: .85; }
.forja-aviso {
  margin: 8px 0 0; font-size: 12px; line-height: 1.4;
  color: var(--copper, #d8a657);
}

.confirm-exigencia {
  margin: 0; padding: 8px 10px; border-radius: 6px;
  text-align: center; font-weight: 700; letter-spacing: .04em;
  font-size: 12px; line-height: 1.35;
  color: var(--gold, #e8c06a);
  background: rgba(216, 166, 87, .12);
  border: 1px solid var(--copper, #d8a657);
}
/*
 * A caixinha de "quero comprar mesmo assim".
 *
 * Ela só aparece quando o item não vai FUNCIONAR — hoje, o Instance Hunts sem
 * premium. É um label inteiro clicável, e não um quadradinho de 13px ao lado de
 * um texto solto: o alvo de clique é a frase toda.
 */
.confirm-marcar {
  display: flex; align-items: center; gap: 8px; cursor: pointer;
  padding: 8px 10px; border-radius: 6px;
  background: var(--panel-2); border: 1px solid var(--copper, #d8a657);
  font-size: 12px; color: var(--copper, #d8a657);
}
.confirm-marcar input { width: 16px; height: 16px; cursor: pointer; flex: none; }

.confirm-actions { display: flex; gap: 10px; justify-content: flex-end; }
.confirm-actions button {
  border-radius: 6px; padding: 8px 18px; cursor: pointer;
  border: 1px solid var(--accent-dim); background: var(--accent-dim); color: #eafffb;
}
.confirm-actions button.ghost { background: var(--panel-2); border-color: var(--line); color: var(--muted); }
.confirm-actions button:disabled { background: var(--panel); border-color: var(--line); color: var(--muted); cursor: not-allowed; }

/* Já comprado: fica no fim da lista e apagado. */
.mount-card.owned, .store-card.owned { opacity: .42; filter: saturate(.4); }
.owned-tag { color: var(--muted); font-style: italic; }

/* ---------- proficiência e charms ---------- */

.prof-head { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; }
.prof-head .action-text b { font-family: var(--font-heading); font-size: 15px; }
.prof-stars { margin-left: auto; display: flex; gap: 2px; }
.prof-star { font-style: normal; color: var(--line); font-size: 15px; }
/* 9x10 na arte: numa caixa quadrada a estrela ficava achatada. */
.prof-star-art { width: 14px; height: 15px; object-fit: contain; image-rendering: pixelated; }
.prof-star.on { color: var(--exp); text-shadow: 0 0 6px #c8a13c88; }
.prof-bar {
  position: relative; height: 16px; background: #0a0e10; border: 1px solid #000; border-radius: 3px;
  overflow: hidden; margin-bottom: 12px;
}
.prof-bar i { display: block; height: 100%; background: linear-gradient(180deg, #e8c46a, #b8862c); }
.prof-bar span { position: absolute; inset: 0; text-align: center; font-size: 10px; line-height: 14px; text-shadow: 0 1px 2px #000; }
.prof-level { display: grid; grid-template-columns: 78px 1fr; gap: 10px; align-items: center; padding: 6px 0; border-top: 1px solid var(--line-soft); }
.prof-level.locked { opacity: .45; }
.prof-level-label { font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.prof-perks { display: flex; gap: 6px; flex-wrap: wrap; }
.prof-perk {
  cursor: pointer; font-size: 11px; padding: 6px 10px; border-radius: 6px; color: inherit;
  background: var(--panel-2); border: 1px solid var(--line);
}
.prof-perk[aria-selected="true"] { border-color: var(--accent); background: #16241f; color: #eafffb; }
.prof-perk:disabled { cursor: not-allowed; }

/*
 * Proficiência de arma.
 *
 * Vitrine à esquerda, ficha à direita. A grade de armas é alta e rola sozinha:
 * são mais de seiscentas, e dá para folhear a árvore de uma arma antes de sair
 * atrás dela. O que o personagem tem na mão ou na mochila fica marcado em cobre
 * e aparece primeiro.
 */
.prof-layout { display: grid; grid-template-columns: 268px minmax(0, 1fr); gap: 18px; align-items: start; }
.prof-side { display: grid; gap: 9px; align-content: start; }
.prof-side .search { margin: 0; }
.prof-filters { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.prof-filters select {
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 6px;
  padding: 6px 8px; cursor: pointer; font-size: 11px; color: inherit; min-width: 0;
}
.prof-filters select:last-child { grid-column: 1 / -1; }

.prof-weapons {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(46px, 1fr)); gap: 5px;
  max-height: 396px; overflow-y: auto; padding: 8px; align-content: start;
  background: #0f1517; border: 1px solid var(--line); border-radius: 8px;
}
.prof-weapon {
  position: relative; aspect-ratio: 1; display: grid; place-items: center; cursor: pointer;
  background: #161d20; border: 1px solid var(--line-soft); border-radius: 6px; opacity: .58;
}
.prof-weapon canvas { image-rendering: pixelated; }
/* Arma que o personagem tem fica inteira; o resto do catálogo fica apagado. */
.prof-weapon.owned { opacity: 1; }
.prof-weapon:hover { border-color: var(--accent-dim); opacity: 1; }
.prof-weapon[aria-selected="true"] { border-color: var(--accent); background: #16241f; opacity: 1; }
.prof-weapon.equipped { box-shadow: inset 0 0 0 1px var(--copper); }
.prof-weapon-level {
  position: absolute; right: -2px; bottom: -2px; font-style: normal; font-size: 9px; line-height: 12px;
  padding: 0 3px; background: var(--exp); color: #1a1208; border-radius: 999px;
}
.prof-count { font-style: normal; font-size: 10px; color: var(--muted); text-align: right; }

.prof-tree { display: grid; gap: 9px; align-content: start; }
.prof-head {
  display: flex; align-items: center; gap: 13px; padding: 11px 13px;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 9px;
}
/*
 * O retrato da arma leva a MESMA moldura dos perks — o aro por fora, o item
 * dentro da abertura. Era a mesma caixinha de borda fina de antes, e duas
 * maneiras diferentes de emoldurar um item na mesma tela nao se explicam.
 * 64px de aro dao 54 de abertura, que e' o tamanho que a caixa tinha.
 */
.prof-art {
  display: grid; place-items: center; width: 64px; height: 64px; flex: none;
  background: url(/client/assets/proficiency/border-weaponmasterytreeicons-active.png) center / 100% 100% no-repeat;
  border: 0; border-radius: 0;
}
.prof-art canvas { image-rendering: pixelated; }
.prof-id { flex: 1; min-width: 0; display: grid; gap: 3px; }
.prof-id b { font-family: var(--font-heading); font-size: 15px; }
.prof-id em { font-style: normal; font-size: 10px; letter-spacing: .06em; text-transform: uppercase; color: var(--copper); }
.prof-stars { display: flex; gap: 2px; }
/* 9x10 na arte: numa caixa quadrada a estrela ficava achatada. */
.prof-star-art { width: 14px; height: 15px; object-fit: contain; image-rendering: pixelated; }
.prof-xp {
  display: grid; justify-items: end; gap: 2px; flex: none; padding: 7px 12px;
  background: var(--panel-solid); border: 1px solid var(--line); border-radius: 7px;
}
.prof-xp span { font-size: 9px; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
.prof-xp b { font-family: var(--font-heading); font-size: 13px; color: var(--exp); }

.prof-progress-label { display: flex; justify-content: space-between; gap: 12px; font-size: 11px; color: var(--muted); }
.prof-progress-label b { color: var(--accent); font-family: var(--font-heading); font-size: 12px; }
.prof-progress {
  position: relative; height: 10px; border-radius: 999px; overflow: hidden;
  background: var(--panel-solid); border: 1px solid var(--line);
}
.prof-progress i { position: absolute; inset: 0 auto 0 0; background: linear-gradient(90deg, #1f5f54, #3fb193); }
.prof-inactive { font-style: normal; font-size: 11px; color: var(--danger); }

.prof-columns { display: flex; gap: 8px; overflow-x: auto; padding-bottom: 6px; }
.prof-column {
  display: grid; gap: 8px; justify-items: center; align-content: start; min-width: 108px; padding: 10px 8px 9px;
  background: #10171899; border: 1px solid var(--line-soft); border-radius: 9px;
}
/* Coluna conquistada fica com o fundo do tema, como o teal do client. */
.prof-column.unlocked { background: linear-gradient(180deg, #14352f, #10231f); border-color: var(--accent-dim); }
.prof-column-head { display: grid; justify-items: center; gap: 2px; }
.prof-column-head b { font-family: var(--font-heading); font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.prof-column.unlocked .prof-column-head b { color: #cdf3ea; }
.prof-perks { display: grid; gap: 6px; justify-items: center; }
.prof-column-foot {
  font-style: normal; font-size: 10px; line-height: 1.35; color: var(--muted); text-align: center;
  min-height: 26px; max-width: 96px;
}
.prof-column.unlocked .prof-column-foot { color: #cdf3ea; }
/*
 * ---- A moldura fica EM VOLTA do perk, e nao por dentro dele ----
 *
 * Era uma caixa: fundo escuro, borda de 1px, cantos arredondados, e o icone
 * plantado no meio dela. O desenho da moldura terminava onde o icone comecava —
 * a moldura estava DENTRO do quadro, disputando espaco com a arte. Foi o que o
 * dono apontou.
 *
 * A arte certa ja' estava na pasta e e' feita justamente para isso: a
 * `border-weaponmasterytreeicons` tem 76x76 com o miolo VAZIO — 64x64 de
 * transparencia no centro e um anel de 6px de ornamento em volta. Ela nao e' um
 * fundo, e' um aro: o icone entra pela abertura e a moldura o cerca por fora.
 *
 * Por isso o slot cresceu de 48 para 57 (76 x 0,75) e o icone de 34 para 48
 * (64 x 0,75, a medida exata da abertura, ver a chamada de `perkIcon`): a
 * proporcao entre aro e miolo e' a do arquivo, senao o ornamento fica gordo de
 * um lado e fino do outro.
 */
.prof-perk-slot {
  width: 57px; height: 57px; display: grid; place-items: center; cursor: pointer; padding: 0;
  background: url(/client/assets/proficiency/border-weaponmasterytreeicons-inactive.png) center / 100% 100% no-repeat;
  border: 0; border-radius: 0;
}
/* Nivel conquistado usa o aro aceso; o trancado fica com o apagado. */
.prof-column.unlocked .prof-perk-slot {
  background-image: url(/client/assets/proficiency/border-weaponmasterytreeicons-active.png);
}
.prof-perk-slot:hover:not(:disabled) { filter: brightness(1.25); }
/*
 * O perk escolhido ganha o `backdrop` do proprio client ATRAS do aro — 80x80
 * para um aro de 76, entao ele aparece como um halo de dois pixels em volta.
 * Duas camadas na mesma propriedade: o aro na frente, o halo atras.
 */
.prof-perk-slot[aria-selected="true"] {
  background-image:
    url(/client/assets/proficiency/border-weaponmasterytreeicons-active.png),
    url(/client/assets/proficiency/backdrop_weaponmastery_highlight.png);
  background-size: 100% 100%, 105% 105%;
  background-position: center, center;
  background-repeat: no-repeat, no-repeat;
}
.prof-perk-slot:disabled { opacity: .4; cursor: not-allowed; }

/*
 * ---- E o escolhido tem de SALTAR, não brilhar dois pixels ----
 *
 * "o perk escolhido em proficiência não dá pra saber exatamente qual escolheu,
 * não fica marcado nem nada". O halo do `backdrop` acima é arte do client dele e
 * fica; o que faltava era contraste que se lê sem procurar.
 *
 * Três camadas, e a do meio é a que mais trabalha: apagar os irmãos. Num trio de
 * ícones igualmente acesos não há "o escolhido", só três opções.
 */
.prof-perk-slot.escolhido {
  position: relative;
  filter: drop-shadow(0 0 6px rgba(185, 151, 91, 0.85));
}
.prof-perk-slot.preterido { opacity: .38; filter: grayscale(0.7); }
.prof-perk-slot.preterido:hover:not(:disabled) { opacity: .7; filter: none; }

/* O selo de confirmação, no canto de baixo à direita do aro. */
.prof-perk-selo {
  position: absolute; right: -2px; bottom: -2px;
  width: 18px; height: 18px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--copper, #b9975b); color: #10161a;
  font-size: 11px; font-style: normal; font-weight: 700; line-height: 1;
  box-shadow: 0 0 0 2px #10161a;
}

/* O rodapé com a escolha feita pesa mais que o "escolha um perk". */
.prof-column-foot.tem { color: var(--text, #d8d2c4); font-style: normal; }
.prof-column-foot.tem b { color: var(--copper, #b9975b); font-weight: 700; }
.perk-icon { display: block; background-repeat: no-repeat; image-rendering: auto; }

@media (max-width: 900px), (max-height: 540px) and (pointer: coarse) {
  .prof-layout { grid-template-columns: 1fr; }
  .prof-head { flex-wrap: wrap; }
}

.charm-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 10px; }
.charm-card {
  display: grid; gap: 6px; align-content: start; padding: 10px 12px;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px;
}
.charm-card.owned { border-color: var(--accent-dim); }
.charm-head { display: flex; align-items: center; gap: 8px; }
.charm-head b { font-family: var(--font-heading); font-size: 13px; }
.charm-icon { width: 20px; height: 20px; object-fit: contain; flex: none; image-rendering: auto; }
.charm-tiers { margin-left: auto; display: flex; gap: 2px; }
.charm-tier { font-style: normal; font-size: 10px; color: var(--line); }
.charm-tier.on { color: var(--accent); }
.charm-text { margin: 0; font-size: 11px; color: var(--muted); }
.charm-chance { font-style: normal; font-size: 11px; color: var(--copper); }
.charm-foot { display: flex; gap: 8px; align-items: center; margin-top: 2px; }
.charm-foot button {
  cursor: pointer; font-size: 11px; padding: 6px 10px; border-radius: 6px;
  border: 1px solid var(--accent-dim); background: var(--accent-dim); color: #eafffb;
}
.charm-foot button.ghost { background: var(--panel); color: var(--muted); border-color: var(--line); }
.charm-foot button:disabled { background: var(--panel); border-color: var(--line); color: var(--muted); cursor: not-allowed; }
.charm-foot select { flex: 1; min-width: 0; background: #080b0c; border: 1px solid var(--line); border-radius: 5px; padding: 5px 6px; font-size: 11px; }
.charm-max { font-size: 11px; color: var(--accent); }

/* ---------- bestiary ---------- */

.bestiary-layout { display: grid; grid-template-columns: 300px 1fr; gap: 18px; align-items: start; }
.bestiary-list { display: grid; gap: 4px; max-height: 460px; overflow-y: auto; padding-right: 4px; }
.bestiary-card {
  position: relative; display: flex; align-items: center; gap: 9px; cursor: pointer; overflow: hidden;
  background: var(--panel-2); border: 1px solid var(--line-soft); border-radius: 6px; padding: 6px 9px;
  color: inherit; text-align: left;
}
.bestiary-card:hover { border-color: var(--accent-dim); }
.bestiary-card[aria-selected="true"] { border-color: var(--accent); background: #16241f; }
.bestiary-card.locked { opacity: .5; }
.bestiary-card b { font-size: 12px; font-weight: 500; }
.bestiary-stars { font-style: normal; font-size: 10px; color: var(--exp); letter-spacing: 1px; }
.bestiary-progress { position: absolute; left: 0; bottom: 0; height: 2px; background: var(--accent); }
.bestiary-unknown {
  width: 40px; height: 40px; flex: none; display: grid; place-items: center;
  font-style: normal; font-size: 18px; color: var(--line); border: 1px dashed var(--line); border-radius: 6px;
}
.bestiary-detail { display: grid; gap: 8px; align-content: start; }
.bestiary-head { display: flex; align-items: center; gap: 12px; }
.bestiary-head .action-text b { font-family: var(--font-heading); font-size: 16px; }
/* O desenho novo vem de 128px e desce: suavizado, e um pouco maior porque agora
   há o que ver nele. O recorte antigo do client sobe de 9px, e aí `pixelated`
   é o certo — sem ele a ampliação vira uma papa cinzenta. */
.bestiary-art { width: 22px; height: 22px; object-fit: contain; image-rendering: auto; }
.bestiary-art.antiga { width: 18px; height: 18px; image-rendering: pixelated; }
/*
 * O quadradinho: desenho à esquerda, número e rótulo empilhados e centrados.
 *
 * O ícone foi de 18 para 28px — a arte nasce em 1024 e a 18 ela virava mancha.
 * E o texto passou a ser centrado no bloco em vez de encostado no topo: com o
 * ícone maior, a coluna da direita sobrava altura e o número ficava boiando
 * acima do centro do card.
 */
.bestiary-stats { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 8px; }
.bestiary-stat {
  display: grid; grid-template-columns: 28px 1fr; gap: 0 9px; align-items: center;
  background: var(--panel-2); border: 1px solid var(--line-soft); border-radius: 6px; padding: 8px 10px;
  cursor: help;
}
.bestiary-stat .bestiary-art { grid-row: span 2; align-self: center; width: 28px; height: 28px; }
.bestiary-stat .bestiary-art.antiga { width: 22px; height: 22px; justify-self: center; }
.bestiary-stat b { font-size: 14px; line-height: 1.15; align-self: end; }
.bestiary-stat em { font-style: normal; font-size: 10px; color: var(--muted); line-height: 1.15; align-self: start; }
.bestiary-stat:hover { border-color: var(--accent-dim); }
.bestiary-elements { display: flex; gap: 6px; flex-wrap: wrap; }
.bestiary-element {
  display: flex; align-items: center; gap: 6px; font-size: 12px; padding: 6px 9px; border-radius: 6px;
  background: var(--panel-2); border: 1px solid var(--line-soft); cursor: help;
}
.bestiary-element .bestiary-art { width: 24px; height: 24px; }
.bestiary-element .bestiary-art.antiga { width: 18px; height: 18px; }
.bestiary-element:hover { border-color: var(--accent-dim); }
.bestiary-element.resist b { color: var(--hp); }
.bestiary-element.weak b { color: var(--danger); }

/* ---------- listas e tabelas ---------- */

table.list { width: 100%; border-collapse: collapse; font-size: 12px; }
table.list th { text-align: left; color: var(--muted); font-weight: 600; font-size: 10px; text-transform: uppercase; letter-spacing: .08em; padding-bottom: 6px; font-family: var(--font-heading); }
table.list td { padding: 5px 8px 5px 0; border-top: 1px solid var(--line-soft); }
table.list td.num { text-align: right; color: var(--muted); }
table.list .me { color: var(--accent); }
table.list em { font-style: normal; font-size: 10px; color: var(--muted); }

.rows { display: grid; gap: 5px; }
.rows > div { display: flex; justify-content: space-between; font-size: 12px; border-bottom: 1px solid var(--line-soft); padding-bottom: 4px; }
.rows span { color: var(--muted); }
/* A linha com ORIGEM (o dono, 01/10: como o balão da barra de exp): rótulo esticado, número, e a origem miúda no fim. */
.rows > div.com-dono { justify-content: flex-start; gap: 8px; align-items: baseline; }
.rows > div.com-dono .stat-rotulo { flex: 1; }
.rows > div.com-dono em.sheet-dono { font-size: 9px; color: #55646a; font-style: normal; white-space: nowrap; }
.rows b { font-weight: 500; }
.rows .total { border-top: 1px solid var(--line); border-bottom: none; margin-top: 4px; padding-top: 7px; }
.rows .total b { color: var(--accent); font-size: 14px; }

/* ---------- banco e depot ---------- */

/*
 * ---- O banco, numa coluna só ----
 *
 * Eram duas colunas — saldos à esquerda, formulário à direita — e isso punha o
 * campo de depositar longe do número que ele mexe. Empilhado, a leitura é a da
 * ação: quanto eu tenho de cada lado, e o que eu faço com isso.
 */
.bank { display: grid; gap: 16px; align-items: start; }
.bank-saldos { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.bank-figure {
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px;
  padding: 13px; text-align: center; display: grid; gap: 3px;
}
/* Verde no que está protegido, cobre no que a morte pode levar. */
.bank-figure.seguro { border-color: var(--accent-dim); }
.bank-figure.risco { border-color: #6b4a2a; }
.bank-figure-topo { display: flex; align-items: center; justify-content: center; gap: 7px; }
.bank-figure-topo canvas { width: 20px; height: 20px; image-rendering: pixelated; }
.bank-figure b { font-family: var(--font-numero); font-size: 22px; color: var(--copper); letter-spacing: .01em; }
.bank-figure span { color: var(--muted); font-size: 10px; text-transform: uppercase; letter-spacing: .08em; }
.bank-figure em { font-style: normal; font-size: 10px; color: #6d7b80; }
.bank-figure.seguro em { color: var(--hp); }
.bank-figure.risco em { color: #c08a52; }

.bank-form { display: grid; gap: 8px; }
.bank-linha { display: flex; align-items: stretch; gap: 6px; }
/* O rótulo com a seta: é ele que diz para que lado o ouro vai. */
.bank-rotulo {
  display: flex; align-items: center; gap: 6px; flex: none; width: 108px;
  padding: 0 4px;
}
.bank-rotulo b { font-family: var(--font-heading); font-size: 12px; }
.bank-seta {
  font-style: normal; font-size: 14px; line-height: 1;
  width: 20px; height: 20px; display: grid; place-items: center; flex: none;
  border-radius: 50%; background: #10161980; border: 1px solid var(--line); color: var(--accent);
}
.bank-linha .num-campo { flex: 1 1 auto; min-width: 0; }
.bank-form input { flex: 1; min-width: 0; background: #080b0c; border: 1px solid var(--line); border-radius: 6px; padding: 8px 10px; color: var(--text); }
.bank-form button { background: var(--accent-dim); border: 1px solid var(--accent-dim); color: #eafffb; border-radius: 6px; padding: 8px 14px; cursor: pointer; white-space: nowrap; }
.bank-form button.ghost { background: var(--panel-2); border-color: var(--line); color: var(--text); }
.bank-form button:disabled { opacity: .35; cursor: not-allowed; }

.bank-cabeca { display: flex; align-items: center; gap: 8px; margin-top: 6px; }
.bank-cabeca img { width: 20px; height: 20px; image-rendering: pixelated; }
.bank-cabeca h3 { margin: 0; font-size: 13px; }
.bank-transfer { display: flex; align-items: stretch; gap: 6px; }
.bank-transfer .bank-nome { flex: 1 1 auto; min-width: 0; }
.bank-transfer .num-campo { flex: 0 1 190px; }
.depot-grid { display: grid; grid-template-columns: repeat(auto-fill, 44px); gap: 5px; }
.depot-grid .cell { width: 44px; height: 44px; }
.depot-grid .cell canvas { width: 32px; height: 32px; }

/* ---------- outfit ---------- */

.outfit-picker { display: grid; grid-template-columns: 250px 1fr; gap: 20px; align-items: start; }
.outfit-side { display: grid; gap: 10px; align-content: start; }
/* "CABEÇA · CORPO · PERNAS · PÉS" na coluna de 250px: letra menor e sem quebrar a palavra (etapa 1.2). */
.outfit-side .tabs button { font-size: 10px; letter-spacing: .02em; padding: 7px 3px 6px; white-space: nowrap; word-break: keep-all; overflow-wrap: normal; }
.outfit-choices { display: grid; gap: 10px; align-content: start; }
/* A caixinha "mostrar os bloqueados", logo abaixo das abas Outfits/Montarias. */
.outfit-filtro { justify-self: end; font-size: 11px; color: var(--muted); margin-top: -4px; }
/*
 * O quadradinho de "Addon 1" e "Addon 2" era um checkbox cru do navegador: um
 * quadrado branco no meio do tema escuro — o "pontinho branco" que aparecia ao
 * lado dos addons. Agora ele veste o tema, aqui e em toda a interface.
 */
input[type='checkbox'] {
  appearance: none; -webkit-appearance: none;
  width: 14px; height: 14px; margin: 0; flex: none; cursor: pointer;
  display: inline-grid; place-items: center; vertical-align: middle;
  background: #0b1112; border: 1px solid var(--line); border-radius: 4px;
}
input[type='checkbox']:hover:not(:disabled) { border-color: var(--accent-dim); }
input[type='checkbox']:checked { background: var(--accent-dim); border-color: var(--accent); }
input[type='checkbox']:checked::after {
  content: '✓'; font-size: 10px; line-height: 1; font-weight: 700; color: #05100d;
}
input[type='checkbox']:disabled { opacity: .35; cursor: not-allowed; }

.outfit-marks { display: grid; gap: 4px; }
.outfit-mark {
  display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: 12px;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 6px; padding: 7px 10px;
}
.outfit-mark.disabled { opacity: .45; cursor: not-allowed; }
.outfit-turn { position: absolute; right: 8px; bottom: 8px; width: 26px; height: 26px; padding: 0; cursor: pointer;
  background: var(--panel-solid); border: 1px solid var(--line); border-radius: 5px; color: var(--muted); }
.outfit-turn:hover { border-color: var(--accent); color: var(--accent); }
.outfit-preview { position: relative; background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px; padding: 18px; display: grid; justify-items: center; gap: 8px; align-content: start; }
.outfit-preview canvas { width: 108px; height: 108px; }
.outfit-dirs, .outfit-addons { display: flex; gap: 5px; align-items: center; }
.outfit-dirs .step, .outfit-addons .step {
  width: 26px; height: 26px; padding: 0; cursor: pointer; font-size: 12px;
  background: var(--panel-solid); border: 1px solid var(--line); border-radius: 5px; color: var(--muted);
}
.outfit-dirs .step[aria-selected="true"], .outfit-addons .step[aria-selected="true"] {
  border-color: var(--accent); color: var(--accent); background: #16241f;
}
.outfit-addons .number-label { flex: none; }
.outfit-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(82px, 1fr)); gap: 8px; }
.outfit-list button { background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px; padding: 8px; cursor: pointer; display: grid; justify-items: center; gap: 4px; font-size: 11px; color: inherit; }
.outfit-list button[aria-selected="true"] { border-color: var(--accent); }
/* O que o jogador NÃO tem: cinza, cadeado, sem clique. O que está vestido agora: moldura acesa + "em uso" (etapa 4.2). */
.outfit-list button { position: relative; }
.outfit-list button.trancado { opacity: .45; filter: grayscale(1); cursor: not-allowed; }
.outfit-list button .cadeado { position: absolute; top: 4px; right: 6px; font-style: normal; font-size: 12px; filter: none; }
.outfit-list button em { font-style: normal; font-size: 10px; color: var(--muted); }
.outfit-list button.em-uso { box-shadow: inset 0 0 0 1px var(--accent), 0 0 8px rgba(79, 201, 174, .25); }
.outfit-list button em.uso { color: var(--accent); font-weight: 600; letter-spacing: .04em; text-transform: uppercase; font-size: 9px; }
.color-grid { display: grid; grid-template-columns: repeat(19, 1fr); gap: 2px; margin-top: 10px; }
.color-grid button { aspect-ratio: 1; border: 1px solid #0006; border-radius: 2px; cursor: pointer; padding: 0; }
.color-grid button[aria-selected="true"] { outline: 2px solid var(--accent); z-index: 1; }

/* ---------- ficha de personagem ---------- */

.sheet { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; }
.sheet-header { display: grid; grid-template-columns: 190px 1fr; gap: 20px; align-items: center; margin-bottom: 14px; }
.sheet-portrait { background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px; padding: 14px; display: grid; justify-items: center; gap: 4px; }
.sheet-portrait canvas { width: 84px; height: 84px; }
.sheet-portrait b { font-family: var(--font-heading); font-size: 15px; letter-spacing: .04em; }
.sheet-portrait span { color: var(--muted); font-size: 11px; }
.sheet-bars { display: grid; gap: 8px; }
.sheet-bar { display: grid; grid-template-columns: 92px 1fr 110px; gap: 10px; align-items: center; font-size: 12px; }
.sheet-bar > span { color: var(--muted); }
.sheet-bar > b { text-align: right; font-weight: 500; }
.sheet-bar > b em { display: block; font-style: normal; font-weight: 400; font-size: 9px; color: var(--muted); white-space: nowrap; }
.track { height: 12px; background: #080b0c; border: 1px solid var(--line-soft); border-radius: 3px; overflow: hidden; }
.track i { display: block; height: 100%; }
.track.hp i { background: linear-gradient(180deg, #66d6a0, var(--hp)); }
.track.mana i { background: linear-gradient(180deg, #6ba6e0, var(--mana)); }

/* ---------- A barra de mana com escudo de mana de pe' ----------
 *
 * "quando eu tiver com o utamo vita ou o energy ring usando, a barra de mana
 *  tem que brilhar mais forte".
 *
 * O brilho PULSA em vez de ficar aceso, e isso e' de proposito: uma barra mais
 * clara e parada se le' como uma cor diferente — a pessoa acha que trocou de
 * tema e nao que ganhou uma condicao. O que se move a gente ve.
 *
 * Devagar (2,4s) porque ela pode ficar dez minutos assim com o anel no dedo, e
 * um pisca-pisca rapido ao lado da barra de vida cansa e depois some da
 * atencao — que e' o contrario do que este aviso existe para fazer.
 */
.hud-bar.mana.com-escudo {
  box-shadow: 0 0 10px #6699ffaa, inset 0 0 6px #6699ff55;
  border-color: #6699ff88;
  animation: escudo-de-mana 2.4s ease-in-out infinite;
}
.hud-bar.mana.com-escudo > i {
  filter: brightness(1.45) saturate(1.2);
}
@keyframes escudo-de-mana {
  0%, 100% { box-shadow: 0 0 6px #6699ff88, inset 0 0 4px #6699ff44; }
  50% { box-shadow: 0 0 16px #9dc4ffdd, inset 0 0 9px #6699ff77; }
}
/* Quem pediu menos movimento fica com o brilho aceso, e sem pulso. */
@media (prefers-reduced-motion: reduce) {
  .hud-bar.mana.com-escudo { animation: none; box-shadow: 0 0 12px #6699ffbb, inset 0 0 7px #6699ff66; }
}
.track.exp i { background: linear-gradient(180deg, #dfb44f, var(--exp)); }
.track.stamina i { background: linear-gradient(180deg, #9184d6, var(--stamina)); }
.track.accent i { background: linear-gradient(180deg, #57d6bd, var(--accent-dim)); }
/* Cobre: o aviso de "esta acabando", usado pelo tanque do treino offline. */
.track.copper i { background: linear-gradient(180deg, #e0b464, var(--copper)); }

/*
 * O card virou duas colunas: o desenho de um lado, os números do outro.
 *
 * O ícone entrou espremido na linha do rótulo, a 15px. A arte nasce em 1024 e
 * a 15 pixels ela vira uma mancha — não dava para ver o que era. E não era
 * falta de espaço: o card tem 170x85, e a metade de baixo estava vazia.
 *
 * Agora ele ocupa 34px numa coluna própria, centrado na altura do card, com o
 * rótulo, o número e a explicação empilhados ao lado. Mesmo card, mesma grade,
 * mesmo número de colunas — só o de dentro reorganizado. Tirar o ícone
 * resolveria a mancha, mas devolveria a parede de números que ele veio quebrar.
 */
.stat-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(148px, 1fr)); gap: 8px; }
.stat-card { background: var(--panel-2); border: 1px solid var(--line-soft); border-radius: 7px; padding: 9px 11px; }
/* Com desenho o card vira duas colunas: a arte à esquerda, do topo à base, e o
   rótulo, o número e a explicação empilhados à direita. */
.stat-card.com-arte {
  display: grid; grid-template-columns: 34px 1fr; column-gap: 10px; align-items: center;
}
.stat-card.com-arte > img {
  grid-row: 1 / -1; grid-column: 1;
  width: 34px; height: 34px; object-fit: contain; align-self: center;
}
.stat-card.com-arte > span,
.stat-card.com-arte > b,
.stat-card.com-arte > em { grid-column: 2; }
.stat-card span { display: block; font-family: var(--font-heading); font-size: 9px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
/* Rótulo com ícone: a linha vira flex para o desenho e o texto ficarem no mesmo
   eixo. `display: block` do rótulo acima continua valendo para quem não tem
   arte — esta regra só ganha dele por vir depois. */
.stat-rotulo { display: flex; align-items: center; gap: 6px; }
.stat-rotulo img { width: 15px; height: 15px; object-fit: contain; flex: none; }
/* Nas linhas de bônus o ícone é menor: elas são baixas e uma de 15px empurrava
   a altura da fileira inteira. */
.rows .stat-rotulo img { width: 14px; height: 14px; }
/* A sprite do item ou o boneco do addon na linha de bônus (o dono, 01/10): do tamanho do ícone, sem empurrar a fileira. */
.rows .stat-rotulo canvas { width: 18px; height: 18px; flex: none; image-rendering: pixelated; margin: -2px 0; }
.stat-card b { display: block; font-size: 17px; font-weight: 600; color: #e8f0f0; margin-top: 2px; }
/* Valor ESCRITO ("corpo a corpo", "2.114 livre / 7.770 total"): menor e sem quebrar (etapas 1.3 e 3.1). */
.stat-card.valor-texto b { font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* A capacidade ("2.114 livre / 7.770 total") não cabe em 148px numa linha: quebra no "/" em vez de cortar. */
.stat-card.valor-texto.duas-linhas b { white-space: normal; line-height: 1.25; }
.stat-card em { font-style: normal; font-size: 10px; color: var(--muted); }

.skill-table { display: grid; gap: 6px; }
.skill-row { display: grid; grid-template-columns: 20px 84px minmax(46px, auto) 1fr 38px; gap: 8px; align-items: center; font-size: 12px; }
.skill-row > span { color: var(--muted); text-transform: capitalize; }
/* "150+60" numa linha só: a coluna cresce com o número em vez de quebrá-lo (etapa 1.1). */
.skill-row > b { font-weight: 600; color: #e8f0f0; text-align: right; white-space: nowrap; }
.skill-row em { font-style: normal; color: var(--muted); font-size: 11px; text-align: right; }
.pips { display: grid; grid-template-columns: repeat(10, 1fr); gap: 2px; }
.pips i { height: 9px; background: #101819; border: 1px solid var(--line-soft); border-radius: 2px; }
.pips i.on { background: linear-gradient(180deg, #57d6bd, var(--accent-dim)); border-color: var(--accent-dim); }

.progress-block { display: grid; gap: 6px; margin-bottom: 6px; }
.progress-block b { font-weight: 500; font-size: 12px; }

.element-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); gap: 7px; }
.element { display: flex; align-items: center; gap: 8px; background: var(--panel-2); border: 1px solid var(--line-soft); border-radius: 7px; padding: 8px 11px; font-size: 12px; }
.element img { width: 14px; height: 14px; }
/*
 * O rótulo não quebra, e o número não empurra.
 *
 * O `flex: 1` sozinho deixava o rótulo encolher até zero quando o valor ao lado
 * ficava comprido — foi assim que "Fogo" virou uma letra por linha no dia em
 * que a proteção veio com dezoito casas decimais. O número já foi arredondado
 * na origem (ver `porcento`, em sheet.mjs); estas duas linhas são a segunda
 * tranca, para nenhum valor inesperado poder desmontar o cartão de novo.
 */
.element span { flex: 1; color: var(--muted); white-space: nowrap; }
.element b { font-weight: 600; margin-left: auto; white-space: nowrap; }

.vocation-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin-top: 12px; }
.vocation-grid button { padding: 12px; border-radius: 8px; background: var(--panel-2); border: 1px solid var(--line); cursor: pointer; }
.vocation-grid button:hover:not(:disabled) { border-color: var(--accent); }

/* ---------- tooltip de item ---------- */

/*
 * Tooltip de item.
 *
 * A cor manda no que se lê primeiro: o nome pega a cor da faixa de raridade, os
 * ganhos saem em teal, as proteções em azul, os encaixes de imbuement em roxo e
 * o preço de NPC em cobre. É a nossa paleta, só que usada para separar
 * assunto — nada de um bloco cinza onde tudo tem o mesmo peso.
 */
.tooltip {
  position: fixed; z-index: 90; width: max-content; max-width: 320px; pointer-events: none;
  background: linear-gradient(180deg, #121b1ff2, #0b1113f7);
  border: 1px solid var(--tier, var(--copper)); border-radius: 8px;
  padding: 0; box-shadow: 0 12px 34px #000c, 0 0 0 1px #0008; font-size: 12px;
  overflow: hidden;
}
/* A faixa colorida no alto repete a raridade, para ela se ver de canto de olho. */
.tooltip::before { content: ""; display: block; height: 2px; background: var(--tier, var(--copper)); }

/* A cor da raridade não é do balão: é da FICHA. O mesmo miolo é desenhado no
   balão da mochila e na Cyclopedia (`.ciclo-balao`), e ali dentro tudo lê
   `--tier` — nome, faixa, moldura. Preso a `.tooltip`, o da enciclopédia caía
   no cobre padrão e todos os itens ficavam da mesma cor. */
/*
 * O item escrito dentro de uma frase — no chat e no aviso do saco de prêmio.
 *
 * A cor é a da raridade, como no balão e no menu do botão direito, e o
 * pontilhado embaixo é o convite: aqui tem mais coisa se o mouse parar. Ver
 * `textoComItens` em tooltip.mjs.
 */
/*
 * A cor da raridade já diz que ali tem uma peça, e o balão aparece ao parar o
 * mouse. O pontilhado embaixo era um terceiro aviso da mesma coisa, e numa
 * linha de conversa ele lia como link quebrado.
 */
.item-no-chat {
  color: var(--tier, var(--copper));
  cursor: help;
}

/*
 * O selo do IMBUEMENT ao lado do nome, no azul dos imbuements — a mesma família
 * de cor do `.selo-imbu` da mochila, para os dois lerem como a mesma coisa.
 */
.item-no-chat .item-imbu {
  font-style: normal; font-size: 9px; font-weight: 700;
  color: #cdf3ff; margin-left: 3px; padding: 0 4px; border-radius: 999px;
  background: #0d2029; border: 1px solid #1d4a5c;
  vertical-align: 1px;
}

/* O selo de tier ao lado do nome, igual ao do balão. Ver `.tip-id .item-tier`. */
.item-no-chat .item-tier {
  font-style: normal; font-size: 9px; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--copper, #d8a657);
  margin-left: 4px; padding: 0 4px; border-radius: 999px;
  background: #2a1e0e; border: 1px solid #6b4f22;
  vertical-align: 1px;
}

.tier-comum { --tier: #8fa3a1; }
.tier-incomum { --tier: #37c2a0; }
.tier-raro { --tier: #57a6e8; }
.tier-epico { --tier: #b184e8; }
.tier-lendario { --tier: #e0a84a; }
/*
 * Mítico: as peças Mineiroidle, o degrau acima de lendário.
 *
 * Vermelho a pedido do dono, e um vermelho MAIS QUENTE que o `--danger`
 * (#d0574f) de propósito: aquele é a cor de "deu errado", e aparece em aviso
 * de compra e de morte. Um item que a pessoa quer não pode ter a mesma cor do
 * erro que ela quer evitar.
 */
.tier-mitico { --tier: #f2503f; }

.tip-head { display: flex; align-items: flex-start; gap: 12px; padding: 10px 12px 9px; }
.tip-id { flex: 1; min-width: 0; }
.tip-id b {
  display: block; font-family: var(--font-heading); font-size: 14px; line-height: 1.25;
  color: var(--tier, var(--copper));
}
.tip-id em { display: block; margin-top: 2px; font-style: normal; font-size: 10px; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); }
.tip-art {
  display: grid; place-items: center; width: 54px; height: 54px; flex: none;
  background: radial-gradient(ellipse at center, #1c2a28 0%, #10171a 76%);
  border: 1px solid var(--line-soft); border-radius: 7px;
}
.tip-art canvas { image-rendering: pixelated; }

.tip-stats { display: grid; gap: 2px; padding: 9px 12px; border-top: 1px solid var(--line-soft); }
/*
 * Cada linha na cor do que ela diz.
 *
 * As cores elementais são as mesmas que o jogo já usa nos números de dano —
 * saem do `combatGetTypeInfo` do servidor, pela paleta de 216 cores do Tibia —,
 * só que puxadas para o claro: a original do gelo é quase branca e a da morte é
 * quase preta, e nenhuma das duas se lê em cima de um fundo escuro.
 */
.tip-stats div { color: var(--accent); font-weight: 500; }
.tip-stats div.atk { color: #ff5a4a; }
.tip-stats div.def { color: #9fc2d4; }
.tip-stats div.speed { color: #7fd8c4; }
.tip-stats div.skill { color: #d8c98a; }
.tip-stats div.crit { color: #e0a84a; }
.tip-stats div.leech { color: #ff8a7a; }
.tip-stats div.mana { color: #6fa8ff; }
.tip-stats div.heal { color: #57e0a8; }
.tip-stats div.area { color: #b184e8; }
.tip-stats div.plain { color: var(--muted); font-weight: 400; }

.tip-stats div.el-physical { color: #ff5a4a; }
.tip-stats div.el-fire { color: #ff9a3c; }
.tip-stats div.el-ice { color: #7fd4ff; }
.tip-stats div.el-earth { color: #5ad86a; }
.tip-stats div.el-energy { color: #c98aff; }
.tip-stats div.el-holy { color: #ffe066; }
.tip-stats div.el-death { color: #d05a6a; }
.tip-stats div.el-drown { color: #5ad8d8; }
.tip-stats div.el-poison { color: #9ad84a; }
.tip-stats div.el-lifedrain { color: #ff7a8a; }
.tip-stats div.el-manadrain { color: #6fa8ff; }
.tip-stats div.el-healing { color: #57e0a8; }

.tip-rules { display: grid; gap: 2px; padding: 9px 12px; border-top: 1px solid var(--line-soft); font-size: 11px; }
.tip-rules div { display: flex; justify-content: space-between; gap: 16px; }
/* A linha do preso salta das outras regras: as demais são requisitos ("o que
   você precisa ter"), e esta é uma limitação da peça ("o que você não vai
   poder fazer"). Mesma família de cor do "Coletado" da Recompensa Diária, que
   é de onde a maioria destas peças vem. */
.tip-rules div.tip-fixo { color: var(--hp); }
.tip-rules div.tip-fixo b { color: var(--hp); font-weight: 600; }
.tip-rules div.tip-fixo span::before { content: '🔒'; margin-right: .4em; font-size: 10px; }

/* ---- As cores dos imbuements, no balão do item ----
   As mesmas do bloco de cima (`.tip-stats`), e de propósito: um imbuement de
   fogo tem de ser do mesmo laranja da linha de dano de fogo três dedos acima.
   Cor nova aqui faria a peça parecer outra coisa. */
.tip-rules div.el-physical b { color: #ff5a4a; }
.tip-rules div.el-fire b { color: #ff9a3c; }
.tip-rules div.el-ice b { color: #7fd4ff; }
.tip-rules div.el-earth b { color: #5ad86a; }
.tip-rules div.el-energy b { color: #c98aff; }
.tip-rules div.el-holy b { color: #ffe066; }
.tip-rules div.el-death b { color: #d05a6a; }
.tip-rules div.el-poison b { color: #9ad84a; }
.tip-rules div.crit b { color: #ff7a4a; }
.tip-rules div.leech b { color: #ff7a8a; }
.tip-rules div.mana b { color: #6fa8ff; }
.tip-rules div.skill b { color: #ffd479; }
.tip-rules div.speed b { color: #7fe0c0; }
.tip-rules div.el-physical span, .tip-rules div.el-fire span, .tip-rules div.el-ice span,
.tip-rules div.el-earth span, .tip-rules div.el-energy span, .tip-rules div.el-holy span,
.tip-rules div.el-death span, .tip-rules div.el-poison span, .tip-rules div.crit span,
.tip-rules div.leech span, .tip-rules div.mana span, .tip-rules div.skill span,
.tip-rules div.speed span { color: inherit; opacity: .85; }
.tip-rules div.el-physical, .tip-rules div.el-fire, .tip-rules div.el-ice,
.tip-rules div.el-earth, .tip-rules div.el-energy, .tip-rules div.el-holy,
.tip-rules div.el-death, .tip-rules div.el-poison, .tip-rules div.crit,
.tip-rules div.leech, .tip-rules div.mana, .tip-rules div.skill,
.tip-rules div.speed { color: inherit; }
.tip-rules span { color: var(--muted); }
.tip-rules b { font-weight: 500; color: #dfe8e8; text-align: right; }
.tip-rules .imbue b { color: #b184e8; }

.tip-prices { display: grid; gap: 1px; padding: 8px 12px; border-top: 1px solid var(--line-soft); color: var(--copper); font-size: 11px; }
.tip-extra { padding: 8px 12px; border-top: 1px solid var(--line-soft); color: var(--accent); font-size: 11px; }

/* ---------- munição ---------- */

/* Pisca até o jogador escolher qual flecha quer usar. */
.equipment .slot.pending { animation: ammo-blink 1s ease-in-out infinite; }
@keyframes ammo-blink {
  0%, 100% { box-shadow: inset 0 0 0 1px var(--line); }
  50% { box-shadow: inset 0 0 0 2px var(--exp), 0 0 12px #c8a13c88; }
}

/*
 * ---- Munição escolhida: uma moldura dourada, e mais nada girando ----
 *
 * Era um gradiente cônico rodando em volta do slot, recortado por máscara para
 * virar um anel de 2px. Num quadradinho de 44px o trecho aceso do cone ocupa
 * quase metade da volta: o que se via não era um anel girando, era um risco
 * amarelo grosso atravessando o canto — e, agora que ele mora na ALJAVA, ainda
 * disputa espaço com a flecha desenhada em cima e com o "∞".
 *
 * Uma moldura acesa com um brilho que respira devagar diz a mesma coisa ("está
 * carregada") sem nada em movimento por cima do desenho. E não depende de
 * `mask-composite`, que é a parte que sai diferente em cada navegador.
 */
.equipment .slot.loaded {
  border-color: #f0c95f;
  animation: ammo-carregada 2.6s ease-in-out infinite;
}
@keyframes ammo-carregada {
  0%, 100% { box-shadow: inset 0 0 0 1px #f0c95f55, 0 0 4px #f0c95f44; }
  50% { box-shadow: inset 0 0 0 1px #f0c95f99, 0 0 9px #f0c95f88; }
}
@media (prefers-reduced-motion: reduce) {
  .equipment .slot.loaded { animation: none; box-shadow: inset 0 0 0 1px #f0c95f88; }
}
.slot .endless {
  position: absolute; right: 2px; bottom: 1px; font-size: 11px; font-style: normal;
  color: var(--exp); text-shadow: 0 1px 2px #000;
}
.ammo-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px; }
.ammo-card {
  display: grid; justify-items: center; gap: 3px; cursor: pointer; padding: 10px 8px;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px; color: inherit;
}
.ammo-card[aria-selected="true"] { border-color: var(--accent); background: #16241f; }
/*
 * ---- A letra dos cartoes e' a do resto do jogo ----
 *
 * O nome da flecha e a linha de baixo saiam na fonte do corpo, do tamanho de um
 * paragrafo qualquer. Ao lado dos outros cartoes da mesma tela — personagem,
 * vocacao, charm, todos com o nome em Cinzel e o detalhe em versalete —
 * pareciam texto colado de outro lugar, que e' o que o dono descreveu.
 *
 * O molde e' o do `.character-card`: nome na fonte de titulo, detalhe pequeno,
 * apagado e espacado. Nada de novo — so' parar de ser a excecao.
 */
.ammo-card b { font-family: var(--font-heading); font-size: 12px; font-weight: 600; letter-spacing: .02em; }
.ammo-card em {
  font-style: normal; font-size: 10px; color: var(--muted); text-align: center;
  letter-spacing: .04em;
}
.ammo-card.blocked { opacity: .45; cursor: not-allowed; }
.ammo-card:disabled { cursor: default; }
/*
 * O quadro do desenho na lista de aljavas.
 *
 * Os selos de tier e de afixo se penduram nos cantos de quem os recebe
 * (`position: absolute`), então precisam de um retângulo do tamanho da peça
 * para se pendurar. Sem ele iriam para os cantos do cartão inteiro, longe do
 * desenho a que se referem.
 */
.aljava-arte { position: relative; display: inline-block; line-height: 0; }
.ammo-card .aljava-ganho { color: var(--accent); }
.ammo-card .ammo-area { color: var(--copper); }
.ammo-card .ammo-block { color: var(--danger); }

/*
 * ---- O BOLSO DA ALJAVA ----
 *
 * A munição Mineiroidle posta a salvo da venda e da limpeza. Fica embaixo da grade
 * porque responde a outra pergunta: a grade é "qual flecha eu uso", esta é
 * "onde as minhas flechas moram".
 *
 * A borda é a de aviso e não a de perigo: guardar não destrói nada.
 */
.aljava-bolso {
  margin-top: 12px; padding: 10px; border-radius: 8px;
  background: var(--panel-2); border: 1px solid var(--line);
  display: grid; gap: 6px;
}
.aljava-bolso > b { font-family: var(--font-heading); font-size: 12px; letter-spacing: .06em; }
.aljava-bolso > em { font-style: normal; font-size: 11px; color: var(--muted); }
.aljava-linhas { display: grid; gap: 6px; }
.aljava-linha {
  display: grid; grid-template-columns: auto 1fr auto; gap: 8px; align-items: center;
  padding: 6px; border-radius: 6px; background: var(--panel);
}
.aljava-linha b { font-size: 12px; }
.aljava-linha em { display: block; font-style: normal; font-size: 10px; color: var(--muted); }
.aljava-botoes { display: flex; gap: 6px; }
.aljava-botoes button { padding: 4px 10px; font-size: 11px; }

/* ---------- auto venda e blacklist ---------- */

/* Venda manual: botão branco, sóbrio — a decisão é do jogador. */
.sell-button {
  width: 100%; margin-top: 8px; padding: 8px; cursor: pointer; border-radius: 7px;
  display: grid; gap: 1px; text-align: center;
  background: linear-gradient(180deg, #f2efe6, #cfc9b8);
  border: 1px solid #8d8672; color: #1a1f21;
}
.sell-button b { font-family: var(--font-heading); font-size: 13px; letter-spacing: .07em; }
.sell-button em { font-style: normal; font-size: 11px; color: #4b514f; }
.sell-button:hover:not(:disabled) { filter: brightness(1.06); }
.sell-button:disabled {
  background: var(--panel-2); border-color: var(--line); color: var(--muted); cursor: not-allowed;
}

/* Auto venda: dourada quando ligada, vermelha quando desligada. */
.autosell {
  width: 100%; margin-top: 8px; padding: 9px; cursor: pointer; border-radius: 7px;
  display: grid; gap: 1px; text-align: center;
  border: 1px solid; color: #fff8e6;
}
.autosell b { font-family: var(--font-heading); font-size: 13px; letter-spacing: .06em; }
.autosell em { font-style: normal; font-size: 11px; opacity: .82; }
.autosell:hover { filter: brightness(1.12); }
.autosell.on {
  background: linear-gradient(180deg, #d3a038, #8c6415);
  border-color: #f0c95f; color: #fff6dd;
  animation: autosell-gold 2.2s ease-in-out infinite;
}
.autosell.off {
  background: linear-gradient(180deg, #a83c34, #6d211b);
  border-color: #e0655b; color: #ffe4e0;
  animation: autosell-red 2.2s ease-in-out infinite;
}
@keyframes autosell-gold {
  0%, 100% { box-shadow: 0 0 10px #d3a03844, inset 0 1px 0 #ffffff2e; }
  50% { box-shadow: 0 0 22px #f0c95faa, inset 0 1px 0 #ffffff2e; }
}
@keyframes autosell-red {
  0%, 100% { box-shadow: 0 0 10px #a83c3444, inset 0 1px 0 #ffffff2e; }
  50% { box-shadow: 0 0 22px #e0655baa, inset 0 1px 0 #ffffff2e; }
}

/* Lista da venda manual. */
.sell-list tr { cursor: pointer; }
.sell-list tr:hover td { background: #16241f; }
.sell-list td.gold { color: var(--exp); text-align: right; }
.sell-total { margin: 14px 0 0; text-align: right; font-size: 13px; }
.sell-total b { color: var(--exp); font-size: 15px; }

.blacklist { margin-top: 10px; }
.blacklist summary {
  cursor: pointer; font-size: 11px; color: var(--copper); letter-spacing: .04em;
  padding: 4px 0; list-style: none;
}
.blacklist summary::marker { content: ''; }
.blacklist summary::before { content: '▸ '; }
.blacklist[open] summary::before { content: '▾ '; }

/* ---------- caçada: hunt única ou ciclo ---------- */

/*
 * O botão do rodapé conta em que modo a caçada está. Parado numa hunt só ele é
 * o "sair" vermelho de sempre; num ciclo vira dourado e pulsa, com o tooltip
 * listando as hunts da roda e quanto falta para a próxima troca.
 */
/*
 * A placa dourada é a mesma do "auto venda on" — a arte, a fatia e a fonte.
 *
 * Ele era um botão de sistema cinza no meio de dois seletores, e não parecia a
 * ação principal do rodapé. `border-image` no lugar de `border` e de `padding`:
 * a moldura é a borda, então `padding` aqui empurraria o texto para longe dela.
 * A fatia 44/48 é onde o ornamento da arte acaba; a `border-width` menor faz o
 * ornamento encolher junto e sobrar como friso, que é o que cabe nesta altura.
 */
/* Na coluna das réguas ele toma a largura dela: é o botão mais clicado da
   barra, e alinhado com as réguas a coluna vira um bloco só em vez de três
   coisas soltas. */
#leave-hunt { width: 100%; }
#leave-hunt {
  font-family: var(--font-heading); font-weight: 600; font-size: 11px;
  letter-spacing: .05em; text-transform: uppercase; white-space: nowrap;
  color: #2a1d05; text-shadow: 0 1px 0 #ffe6a366;
  min-height: 30px; padding: 0 4px;
  border-style: solid; border-width: 10px 9px;
  border-image-source: url(/client/assets/ui/auto-venda-on.png);
  border-image-slice: 44 48 fill;
  border-image-repeat: stretch;
  border-radius: 0; background: none;
  filter: drop-shadow(0 0 3px #d3a03866);
}
/* `drop-shadow` segue os pixels pintados, e a placa tem canto arredondado —
   `box-shadow` desenharia um retângulo em volta do nada. */
#leave-hunt:hover { filter: brightness(1.1) drop-shadow(0 0 6px #f0c95faa); }
/* Ele não desliga mais: fora da caçada vira o "Hunts", que abre a escolha. A
   regra fica para o caso de algum estado futuro precisar dela. */
#leave-hunt:disabled { filter: grayscale(.7) brightness(.7); cursor: default; }
/* Em ciclo a placa é a mesma, mas pulsando: o que muda é o modo, não o botão. */
#leave-hunt.cycle { animation: sair-ciclo 1.8s ease-in-out infinite; }
@keyframes sair-ciclo {
  0%, 100% { filter: drop-shadow(0 0 3px #d3a03866); }
  50% { filter: brightness(1.08) drop-shadow(0 0 10px #ffd980cc); }
}

/* Dois modos: Caça Automática e Caça Online. */
.run-modes { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; margin: 4px 0 14px; }
.run-mode {
  display: grid; gap: 5px; padding: 14px 12px; cursor: pointer; text-align: left;
  font-family: var(--font-heading); font-size: 14px; color: var(--text);
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 9px;
}
.run-mode:hover:not(:disabled) { border-color: var(--accent); background: #16241f; }
.run-mode em { font-style: normal; font-size: 11px; color: var(--muted); line-height: 1.4; }
.run-mode.cycle:hover:not(:disabled) { border-color: #ffe6a3; background: #241d0d; }
.run-mode:disabled { opacity: .45; cursor: not-allowed; }

.run-size { display: flex; align-items: center; gap: 7px; font-size: 11px; color: var(--muted); }
.run-size button {
  width: 30px; height: 30px; cursor: pointer; font-family: var(--font-heading);
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 6px; color: var(--muted);
}
.run-size button[aria-selected="true"] { border-color: #ffe6a3; color: #ffe9b0; background: #241d0d; }

/* A roda que vai rodar, na ordem: a primeira é a que o jogador escolheu. */
.run-preview { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.run-preview span {
  font-size: 11px; padding: 4px 9px; border-radius: 999px;
  background: var(--panel-2); border: 1px solid var(--line-soft); color: var(--muted);
}
.run-preview span.first { border-color: #c79a3c; color: #ffe9b0; }
.run-preview span + span::before { content: "→"; margin-right: 7px; color: #3d4a49; }

.rows b.good { color: var(--accent); }
.rows b.bad { color: var(--danger); }

/* ---------- prêmio de colecionar ---------- */

/* A mesma faixa na aparência e nas duas abas da loja: quem vê um outfit à
   venda precisa saber que ele vale mais do que o desenho. */
.collection-note {
  display: flex; align-items: center; gap: 12px; margin-bottom: 14px; padding: 10px 13px;
  background: linear-gradient(90deg, #241d0d, var(--panel-2));
  border: 1px solid var(--line); border-left: 3px solid var(--copper); border-radius: 9px;
}
.collection-note img { width: 30px; height: 30px; flex: none; image-rendering: pixelated; }
.collection-note b { display: block; font-family: var(--font-heading); font-size: 13px; color: var(--copper); }
.collection-note em { font-style: normal; font-size: 11px; color: var(--muted); line-height: 1.5; }

.outfit-bonus {
  grid-column: 1 / -1; font-style: normal; font-size: 10px; line-height: 1.4;
  color: var(--copper); border-top: 1px solid var(--line-soft); padding-top: 6px; margin-top: 2px;
}
.mount-card .card-crit { font-style: normal; font-size: 10px; color: var(--copper); }
.modal-back { justify-self: start; margin-bottom: 10px; font-size: 12px; }

/* ---------- tooltip de magia, runa e poção ---------- */

/* Mesmo desenho do tooltip de item; o que muda é a cor da faixa, que conta o
   que a ação faz: cura em teal, ataque em cobre, suporte em violeta. */
.acao-cura { --tier: #37c2a0; }
.acao-ataque { --tier: #e0a84a; }
.acao-suporte { --tier: #b184e8; }
.acao-item { --tier: #57a6e8; }
.acao-bloqueada { --tier: #a35a52; }

.tip-words {
  display: block; margin-top: 3px; font-style: italic; font-size: 11px; color: var(--accent);
}
.tip-blocked {
  padding: 8px 12px; border-top: 1px solid var(--line-soft);
  background: #2a11119c; color: #ff8a7a; font-size: 11px;
}

/* ---------- Mineiroidle Store em seções ---------- */

/* A loja virou prateleira: seções à esquerda, produtos à direita. Antes
   montarias e outfits eram abas irmãs da loja, o que dava a entender que eram
   outra coisa — são prateleiras da mesma loja. */
/* A loja abre sempre do mesmo tamanho: com altura livre ela crescia na aba de
   montarias e encolhia na de serviços, e o modal pulava a cada troca. */
.modal-box.store { width: min(1180px, 96vw); height: min(760px, 86vh); }
/*
 * O corpo da loja ocupa a altura inteira da moldura.
 *
 * Sem o `flex: 1`, ele encolhia ate' o tamanho do conteudo: na aba de
 * Utilitarios, que tem um produto so', o rodape com o saldo subia para o meio
 * da janela e mudava de lugar a cada troca de secao. O saldo e' a unica coisa
 * que vale em todas as abas — ele tem de ficar parado.
 */
.modal-box.store #modal-body { display: flex; flex-direction: column; flex: 1; min-height: 0; }
/*
 * ---- Quem rola e' a PRATELEIRA, nao o modal inteiro ----
 *
 * `.store-layout` tem `align-items: start`, e com ele as duas colunas nascem do
 * tamanho do conteudo em vez de esticarem ate a altura da caixa. Enquanto a
 * prateleira era a coluna direta isso passava; com a coluna `.store-direita` no
 * meio (a busca em cima, a prateleira embaixo), a faixa `1fr` dela ficou sem
 * altura definida para medir, a prateleira nunca chegou a rolar por dentro e
 * quem rolou foi o `#modal-body`. O resultado e' o que o dono viu: a coluna das
 * secoes indo embora para cima e o rodape do saldo — que fica DEPOIS da grade —
 * subindo por cima dos cartoes.
 *
 * `align-items: stretch` devolve a altura para a coluna, e a partir dela para a
 * faixa `1fr` e para o `max-height: 100%` da prateleira. Os `min-height: 0` sao
 * o de sempre: sem eles um item de grade ou de flex se recusa a ficar menor que
 * o conteudo, e nada rola em lugar nenhum.
 */
.modal-box.store .store-layout { flex: 1; min-height: 0; align-items: stretch; }
.modal-box.store .store-direita { min-height: 0; }
.modal-box.store .store-shelf { overflow-y: auto; max-height: 100%; min-height: 0; padding-right: 6px; }
/*
 * A coluna da direita: a busca em cima, presa, e a prateleira rolando embaixo.
 *
 * `minmax(0, 1fr)` na segunda faixa, e nao `1fr` puro: sem o minimo zero a
 * faixa nasce do tamanho do conteudo, a prateleira nunca fica menor do que a
 * lista inteira e o `overflow-y` dela nunca chega a rolar — a loja empurrava o
 * rodape do saldo para fora do modal.
 */
.store-direita {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  gap: 10px;
  min-width: 0;
  min-height: 0;
}
.store-busca { margin: 0; }
/* O nome da prateleira em cima de cada bloco de resultados. */
.store-grupo {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  padding-bottom: 5px; border-bottom: 1px solid var(--line-soft);
}
.store-grupo b {
  font-family: var(--font-heading); font-size: 12px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--accent);
}
.store-grupo span { font-size: 10px; color: var(--muted); }
.store-layout { display: grid; grid-template-columns: 190px minmax(0, 1fr); gap: 18px; align-items: start; }
.store-sections { display: grid; gap: 5px; align-content: start; }
.store-sections button {
  display: flex; align-items: center; gap: 9px;
  text-align: left; padding: 8px 12px; cursor: pointer; font-family: var(--font-heading); font-size: 12px;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 7px; color: var(--muted);
}
/* O desenho da prateleira, ao lado do nome — e nao em cima dele como nas abas
   de cima: esta lista e' vertical e estreita, e um icone empilhado sobre o
   texto dobraria a altura da coluna inteira. Ver `ARTE_DA_PRATELEIRA`. */
.store-sections button > img {
  width: 26px; height: 26px; flex: none; object-fit: contain;
  opacity: .72; transition: opacity .12s ease, filter .12s ease;
  filter: grayscale(.35);
}
.store-sections button:hover > img { opacity: .95; filter: none; }
.store-sections button[aria-selected="true"] > img { opacity: 1; filter: none; }
.store-sections button:hover { border-color: var(--accent-dim); color: var(--text); }
.store-sections button[aria-selected="true"] { border-color: var(--accent); background: #16241f; color: var(--accent); }

.store-shelf { display: grid; gap: 10px; align-content: start; min-width: 0; }
.store-art {
  display: grid; place-items: center; width: 70px; height: 70px; margin: 0 auto 3px;
  overflow: hidden;
  background: radial-gradient(ellipse at center, #1d2c2a 0%, #131a1d 76%);
  border: 1px solid var(--line-soft); border-radius: 7px;
}
.store-art canvas { image-rendering: pixelated; }

/* Trilho das melhorias repetíveis: uma conta por compra, cheia é comprada. */
.upgrade-track { display: flex; gap: 4px; justify-content: center; margin: 2px 0; }
.upgrade-track i { width: 12px; height: 6px; border-radius: 2px; border: 1px solid var(--accent-dim); }
.upgrade-track i.on { background: var(--accent); }
.upgrade-state { font-style: normal; font-size: 10px; color: var(--copper); text-align: center; }

.bagline span.full { color: var(--danger); }


/* ---------- placa da Mineiroidle Store na topbar ---------- */

/* A loja vende: ela ganha placa, não um ícone perdido no meio das
   ferramentas. Fica depois de quem está online, com folga à esquerda. */
#store-button {
  position: relative; margin-left: 4px; padding: 0; flex: none; cursor: pointer; line-height: 0;
  background: none; border: none;
  animation: store-glow 2.4s ease-in-out infinite;
  transition: transform .12s ease;
}
#store-button img { height: 44px; width: auto; display: block; user-select: none; -webkit-user-drag: none; }
/* O brilho dourado dá uma volta na placa: é a vitrine da loja. */
@keyframes store-glow {
  0%, 100% { filter: drop-shadow(0 0 3px #d9ae4a3a) drop-shadow(0 2px 6px #0009); }
  50% { filter: drop-shadow(0 0 8px #ffd98066) drop-shadow(0 0 16px #d9ae4a33) drop-shadow(0 2px 6px #0009); }
}
/*
 * O facho corre pela borda da placa, e não num círculo.
 *
 * A versão anterior girava um leque cônico dentro de um retângulo largo e
 * baixo: virava uma elipse, e o brilho passava por dentro do desenho em vez de
 * contorná-lo. Agora o gradiente é recortado em anel pela máscara, então o
 * facho segue exatamente o contorno arredondado. O ângulo é animado por
 * `@property` — sem isso o navegador não interpola gradiente cônico.
 */
@property --store-angle {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}
/* Colado na placa: a arte tinha 25px de margem transparente em cima e 41 em
   baixo, então o anel contornava a caixa e não o desenho. Aparada a margem
   (tools/crop.mjs auto), 3px de folga bastam. */
#store-button::after {
  content: ""; position: absolute; inset: -3px; border-radius: 12px; padding: 2px; pointer-events: none;
  background: conic-gradient(from var(--store-angle), transparent 0%, #ffd980 8%, #fff6d0 12%, #ffd980 16%, transparent 26%, transparent 100%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  animation: store-orbit 3s linear infinite;
}
@keyframes store-orbit { to { --store-angle: 360deg; } }
/*
 * O mercado não é placa: é um ícone, como os da direita.
 *
 * A placa e o anel de luz são da loja — ela vende, e a vitrine se anuncia. O
 * mercado é entre jogadores e é uma ferramenta como as outras; duas placas
 * brilhando lado a lado brigavam entre si. Mesmo halo verde e mesmo zoom dos
 * botões da barra de ferramentas, só que aqui na esquerda.
 */
#market-button {
  margin-left: 6px; padding: 3px 0 2px; flex: none; cursor: pointer;
  width: 56px; height: auto; display: flex; flex-direction: column; align-items: center; gap: 3px;
  background: none; border: none;
  filter: drop-shadow(0 0 1px #0a0d0f) drop-shadow(0 0 2px #3fbfa844);
  transition: filter .16s ease, transform .16s ease;
}
#market-button img { width: 30px; height: 30px; display: block; object-fit: contain; }
/* A legenda do mercado é a mesma dos ícones da barra, e por isso reaproveita a
   regra deles em vez de inventar um segundo estilo de nome. */
#market-button .label {
  display: block; width: 100%; text-align: center;
  font-size: 9px; line-height: 1.15; letter-spacing: 0.01em; color: #6d7f86;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
#market-button:hover .label { color: var(--accent); }
#market-button[aria-selected="true"] .label { color: var(--accent); }
@media (max-width: 1800px) {
  #market-button { width: 48px; }
  #market-button img { width: 27px; height: 27px; }
  #market-button .label { font-size: 8px; }
}
@media (max-width: 1500px) {
  #market-button { width: 42px; }
  #market-button img { width: 23px; height: 23px; }
  #market-button .label { font-size: 7px; }
}
#market-button:hover { filter: drop-shadow(0 0 4px #3fbfa8) drop-shadow(0 0 11px #3fbfa877); }
#market-button[aria-selected="true"] {
  filter: drop-shadow(0 0 1px #0a0d0f) drop-shadow(0 0 4px #3fbfa8cc);
}
@media (prefers-reduced-motion: reduce) { #market-button { transition: none; } }
#store-button:hover { transform: translateY(-2px) scale(1.03); }
#store-button:active { transform: translateY(0) scale(1); }
@media (max-width: 900px), (max-height: 540px) and (pointer: coarse) { #store-button img { height: 30px; } }

/* Ouro entrando: o número dá um pulo dourado. */
.wallet b.gained { animation: gold-pop .5s ease-out; }
@keyframes gold-pop {
  0% { transform: scale(1); color: inherit; }
  35% { transform: scale(1.32); color: #ffd980; text-shadow: 0 0 10px #ffd98099; }
  100% { transform: scale(1); color: inherit; text-shadow: none; }
}
.wallet b { display: inline-block; transition: color .2s ease; }

/* ---------- arranjos da barra de ações ---------- */

/* Uma barra de caçar não serve para o boss. Os arranjos ficam numa fileira
   discreta logo acima da barra, sem roubar espaço dos slots. */
.hotbar-stack { display: grid; gap: 6px; flex: none; position: relative; }
/* Arranjos de teclas e o botão de devolver a ficha, à esquerda do primeiro
   slot. Eles ocupavam uma fileira própria em cima dos slots — uma faixa inteira
   gasta com dois controles miúdos. */
/* Ela não pode passar da altura dos slots: como a fileira alinha por baixo, o
   que sobra em cima vai justamente para o vão entre as réguas e a barra — e é
   esse vão que precisa sumir. Os arranjos ficam em duas colunas. */
/*
 * O `max-height` fixo saiu: era 52px (a barra de uma fileira), virou 109px (a
 * de duas) e seria mais um número para lembrar de mexer no dia em que a barra
 * mudar de novo. Com `.bar-row` em `align-items: stretch` a coluna já tem
 * exatamente a altura da fileira, e o `align-items: center` daqui centra os
 * dois botões nela — que é o que tira o buraco de 87px que ficava por cima
 * deles quando a coluna se colava na base.
 */
/*
 * A coluna da esquerda é uma PILHA: réguas em cima, arranjos embaixo.
 *
 * Era uma fileira deitada com dois botões dentro — 67px de conteúdo numa coluna
 * tão alta quanto os slots, e o resto vazio. As réguas de vida/mana/exp moraram
 * numa faixa horizontal por cima de tudo, gastando uma linha inteira de altura.
 * Juntar as duas coisas resolve as duas: a coluna passa a ter conteúdo do topo
 * à base, e a faixa devolve a altura que ocupava.
 *
 * `justify-content: flex-end` empurra tudo para baixo, então quando a ficha não
 * está recolhida (réguas escondidas) o "+ salvar" fica onde sempre esteve: no
 * canto de baixo, e não boiando no meio da coluna.
 */
/*
 * A coluna da direita: o Hunts em cima e o "Salvar hk" embaixo.
 *
 * O Hunts fica no TOPO, alinhado com a primeira fileira de slots — daí o
 * `flex-start`. Quem se vira com a sobra é o "Salvar hk", com margens
 * automáticas (ver a regra dele): elas o põem no meio do que restou, entre o
 * Hunts e a base.
 *
 * As outras duas distribuições já estiveram aqui e cada uma errava de um jeito:
 * `flex-end` prendia o botão mais clicado da barra no canto mais baixo dela, e
 * `space-between` colava o "Salvar hk" na beirada de baixo.
 */
.bar-side {
  display: flex; flex-direction: column; justify-content: flex-start;
  /* `gap: 0` de propósito: quem separa os dois é a margem automática do
     "Salvar hk". Com gap, os 5px dele entravam só do lado de CIMA e o botão
     parava 5px abaixo do meio — 28px acima contra 23 embaixo. */
  align-items: stretch; gap: 0; flex: none; width: 132px;
}
/* A coluna nunca fica vazia agora: o Hunts e os arranjos moram nela e não
   mudam de casa. A regra que a escondia quando ficava sem filho visível saiu
   junto com o motivo dela. */
/*
 * Dois botões e só: guardar, e a setinha que abre os guardados.
 *
 * Cada arranjo salvo era um chip aqui dentro, e a coluna crescia junto — três
 * conjuntos já empurravam a barra de baixo para cima e comiam a tela do jogo.
 * A lista mudou de casa, e a altura daqui parou de depender de quantos são.
 */
/*
 * Os arranjos de hotkeys, logo abaixo do Hunts.
 *
 * Eles já flutuaram acima da barra, presos a duas variáveis medidas, para não
 * custarem altura ao rodapé. Na coluna da direita esse custo não existe: ela
 * tem a altura das duas fileiras de slots e o Hunts sozinho não a preenche —
 * eles cabem na sobra que já estava lá.
 *
 * `center` porque o botão é bem mais estreito que a coluna: encostado à
 * esquerda ele ficaria pendurado fora do eixo do Hunts, que é largo.
 */
/*
 * ---- `margin: auto 0` é o que o centra no que sobrou ----
 *
 * Ele já encostou na base (`space-between`) e já ficou 5px acima dela; o dono
 * quer no MEIO entre o Hunts e o fim da coluna.
 *
 * Margem automática num item flex come todo o espaço livre daquele lado. Com
 * `auto` em cima E embaixo, o que sobra se reparte igual entre os dois, e o
 * botão para no meio — sem número nenhum escrito à mão. É por isso que serve
 * melhor que um `margin-top` calculado: a sobra muda quando o Hunts troca de
 * rótulo ou a barra muda de altura, e a conta se refaz sozinha.
 */
#hotbar-presets {
  display: flex; align-items: center; justify-content: center; gap: 4px;
  margin: auto 0;
}
#hotbar-presets button { font-size: 10px; padding: 3px 7px; }

/*
 * Os dois automáticos ao lado do "Salvar hk" (15/09). Tamanho fixo: acender
 * não muda a largura, e a coluna de 132px continua cabendo inteira.
 */
#hotbar-presets .auto-toggle {
  width: 22px; height: 21px; padding: 0; flex: none;
  display: grid; place-items: center; cursor: pointer;
  font-size: 11px; line-height: 1; color: #6f8a8e;
  background: #161d20; border: 1px solid #34494f; border-radius: 6px;
  box-shadow: inset 0 0 0 1px #0b0f10d9, 0 1px 2px #0006;
  transition: color .15s, border-color .15s, box-shadow .15s, background .15s;
}
#hotbar-presets .auto-toggle:hover:not(:disabled) { color: var(--accent); border-color: var(--accent); }
#hotbar-presets .auto-toggle.ligado {
  color: #eafffb; border-color: #4fd1b5;
  background: linear-gradient(180deg, #1f6f62, #154a42);
  box-shadow: inset 0 0 0 1px #0b0f10d9, 0 0 9px -1px #4fd1b5cc;
}
#hotbar-presets .auto-toggle:disabled { opacity: .35; cursor: default; }
/* A mão conjurando: 5º quadro (20px) da folha de grupos de magia, em 15px. */
#hotbar-presets .auto-toggle-magia::before {
  content: ''; width: 15px; height: 15px; border-radius: 3px;
  background: url('/client/assets/ui/spellgroup-icons.png') no-repeat;
  background-size: 165px 15px; background-position: -60px 0;
  image-rendering: pixelated;
  filter: grayscale(1) brightness(.75); transition: filter .15s;
}
#hotbar-presets .auto-toggle-magia:hover:not(:disabled)::before { filter: grayscale(.4) brightness(.95); }
#hotbar-presets .auto-toggle-magia.ligado::before { filter: none; box-shadow: 0 0 6px #b48cff99; }
.preset-open {
  padding: 3px 6px; cursor: pointer; font-size: 10px; line-height: 1;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 6px; color: var(--muted);
}
.preset-open:hover { border-color: var(--accent); color: var(--accent); }

/* Ela abre para cima: a barra mora no rodapé, e para baixo não há tela. */
.preset-menu {
  position: fixed; z-index: 80; min-width: 170px; max-height: 44vh; overflow: auto;
  display: grid; gap: 3px; padding: 5px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 8px;
  box-shadow: 0 10px 26px #000a;
}
.preset-menu header {
  font-family: var(--font-heading); font-size: 9px; letter-spacing: .09em; text-transform: uppercase;
  color: var(--muted); padding: 2px 4px 4px;
}
.preset-menu .preset-chip {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  width: 100%; text-align: left; border-radius: 6px; padding: 5px 8px; font-size: 11px;
}
.preset-menu .preset-chip i { font-style: normal; font-size: 9px; color: var(--muted); }
/*
 * A fileira dos slots: teclas à esquerda, alvo/distância/sair à direita, e as
 * barras em pé no fim quando a ficha está recolhida.
 *
 * ---- `stretch`, e não `flex-end` ----
 *
 * As três colunas se alinhavam por BAIXO. Enquanto a barra teve uma fileira de
 * slots isso não se via: as três tinham mais ou menos a mesma altura. Com duas
 * fileiras a coluna dos slots foi para 109px e as outras duas ficaram do
 * tamanho do que têm dentro — 23px os arranjos, 73px os controles —, e o que
 * sobrava virava buraco EM CIMA: 87px de vazio sobre o "+ salvar" e 36px sobre
 * o "Alvo". Foi o que o dono viu.
 *
 * Esticadas, as duas passam a ter a altura da fileira e distribuem o que têm
 * dentro nela (ver `.bar-side` e `.controls`). O vazio não foi "preenchido com
 * coisa": ele foi repartido, e é isso que faz o vão parecer respiro em vez de
 * falha.
 */
.bar-row { display: flex; gap: 9px; align-items: stretch; }
/*
 * ---- Os slots CENTRALIZADOS, e o que isso custa ----
 *
 * A fileira era `flex`, e as três colunas ficavam do tamanho do que tinham
 * dentro: 67px os arranjos, 622px os slots, 343px os controles. Somando, os
 * slots caíam à ESQUERDA do meio da barra — e o meio da barra é onde está o
 * personagem, porque a barra é centrada na tela.
 *
 * Numa grade `1fr auto 1fr` as duas colunas de fora são forçadas ao MESMO
 * tamanho (o do maior conteúdo entre as duas, aqui os 343px dos controles), e a
 * do meio fica exatamente no centro. É a única forma de centrar o miolo: as
 * bordas precisam pesar igual.
 *
 * O preço é largura — a barra vai de 1086 para ~1336px, e a diferença vira
 * folga à esquerda, embaixo dos arranjos. Não dá para ter as duas coisas: slot
 * centrado E sem sobra nas pontas só aconteceria se os dois lados tivessem, por
 * acaso, o mesmo conteúdo.
 *
 * `justify-self` nas duas pontas é o que impede a folga de virar buraco no meio:
 * sem ele os controles esticariam pelos 343px da célula e o `space-between`
 * deles abriria de novo o vão entre "Lurar até" e o botão.
 */
/*
 * ---- Os arranjos saem do fluxo, e por isso os slots ficam no meio ----
 *
 * A coluna da esquerda existia só para segurar o "+ salvar" e a setinha dos
 * arranjos: 67px de conteúdo numa coluna que a grade forçava a ter os mesmos
 * 341px dos controles, para o miolo cair no centro. O resultado eram 276px de
 * vazio com dois botões perdidos no canto.
 *
 * Agora eles são POSTOS (ver `.bar-side` mais abaixo, com `position: absolute`)
 * no canto de baixo da barra, e a coluna da esquerda fica vazia de conteúdo —
 * mas continua existindo e continua medindo o mesmo que a direita, que é o que
 * mantém os slots centrados no personagem.
 *
 * Com dois filhos só no fluxo, a colocação automática os jogaria nas colunas 1
 * e 2 — os slots iriam para a ponta esquerda. Por isso as duas dizem em que
 * coluna moram.
 */


.preset-chip, .preset-save {
  padding: 3px 10px; cursor: pointer; font-size: 10px; letter-spacing: .03em;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 999px; color: var(--muted);
}
/* O "Salvar hk" mora na barra, ao lado dos slots, e ganha o quadro deles — o
   mesmo trio de sombras dos controles logo acima. O `.preset-chip` fica de
   fora: ele vive dentro do balão da lista, longe dos slots, e ali o brilho não
   amarraria nada. */
#hotbar-presets .preset-save {
  background: #161d20; border-color: #46656d;
  box-shadow: inset 0 0 0 1px #0b0f10d9, 0 0 7px -1px #3fbfa866, 0 1px 2px #0006;
}
#hotbar-presets .preset-save:hover {
  border-color: var(--accent); color: var(--accent);
  box-shadow: inset 0 0 0 1px #0b0f10d9, 0 0 11px -1px #3fbfa8e6;
}
/* Fonte de título: ele é vizinho do "Sair da hunt", e em Segoe ao lado da placa
   dourada parecia texto de sistema que sobrou ali. */
.preset-save {
  font-family: var(--font-heading); font-weight: 600;
  letter-spacing: .07em; text-transform: uppercase; font-size: 9px;
}
.preset-chip:hover { border-color: var(--accent); color: var(--accent); }
.preset-save { border-style: dashed; }
.preset-save:hover { border-color: var(--copper); color: var(--copper); }

/* ---------- transferir coins ---------- */

.transfer-card { width: 100%; display: grid; gap: 10px; }
.transfer-head { display: flex; align-items: center; gap: 9px; }
.transfer-head img { width: 22px; height: 22px; }
.transfer-head h3 { margin: 0; font-size: 15px; color: var(--accent); }
.transfer-lead { margin: 0; font-size: 11px; color: var(--muted); line-height: 1.55; }

.transfer-saldo {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 10px 13px; border-radius: 8px;
  background: linear-gradient(90deg, #241d0d, #171f22);
  border: 1px solid var(--line); border-left: 3px solid var(--copper);
}
.transfer-saldo-nome { display: flex; align-items: center; gap: 7px; font-size: 10px; text-transform: uppercase; letter-spacing: .07em; color: var(--muted); }
.transfer-saldo-nome img { width: 22px; height: 22px; }
.transfer-saldo b { font-family: var(--font-heading); font-size: 17px; color: var(--copper); }

.transfer-campo { display: grid; gap: 5px; }
.transfer-rotulo { font-size: 10px; text-transform: uppercase; letter-spacing: .07em; color: var(--muted); }
.transfer-input {
  width: 100%; background: #080b0c; border: 1px solid var(--line); border-radius: 7px;
  padding: 9px 11px; color: var(--text); font-size: 13px;
}
.transfer-input:focus { outline: none; border-color: var(--accent-dim); }

/* A barra e a caixa mostram o mesmo numero: ver o comentario em panels.mjs. */
.transfer-barra { width: 100%; accent-color: var(--accent); cursor: pointer; margin: 0; }
.transfer-escala { display: flex; justify-content: space-between; font-size: 10px; color: var(--muted); margin-top: -4px; }
.transfer-dica { font-size: 10px; color: var(--muted); margin-top: -4px; }

.transfer-resumo { display: grid; gap: 4px; font-size: 12px; padding-top: 8px; border-top: 1px solid var(--line-soft); }
.transfer-resumo div { display: flex; justify-content: space-between; gap: 12px; color: var(--muted); }
.transfer-resumo .envia b { color: var(--copper); }
.transfer-resumo .fica b { color: var(--accent); }

.transfer-enviar {
  padding: 11px 22px; cursor: pointer; font-family: var(--font-heading); font-size: 13px; letter-spacing: .04em;
  background: linear-gradient(180deg, var(--accent-dim), #1f5f54);
  border: 1px solid var(--accent-dim); border-radius: 8px; color: #eafffb;
}
.transfer-enviar:hover:not(:disabled) { filter: brightness(1.15); }
.transfer-enviar:disabled { background: var(--panel); border-color: var(--line); color: var(--muted); cursor: not-allowed; }
.transfer-aviso { margin: 0; font-size: 10px; color: var(--danger); text-align: center; }

/* ---------- o rodape da loja e a tela de obter coins ---------- */

.store-footer {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line-soft);
}
.store-footer-esq { display: flex; align-items: center; gap: 12px; }
.store-footer-saldo { display: flex; align-items: center; gap: 7px; }
.store-footer-saldo img { width: 24px; height: 24px; }

/* Mandar coins embora fica colado no numero de quantos existem. */
.store-transferir {
  padding: 9px 18px; cursor: pointer; border-radius: 7px;
  font-family: var(--font-heading); font-size: 12px; letter-spacing: .03em;
  background: var(--panel-2); border: 1px solid var(--line); color: var(--text);
}
.store-transferir:hover { border-color: var(--accent); color: var(--accent); }
/*
 * Os três botões do rodapé (Transferir, Histórico, Store Inbox), mais bonitos:
 * vidro escuro com filete dourado, ícone num medalhão à esquerda, e a Store
 * Inbox com o brilho passando, como na mochila.
 */
.store-footer-esq .store-transferir {
  position: relative; overflow: hidden;
  display: inline-flex; align-items: center; gap: 8px; padding: 6px 14px 6px 6px;
  border-radius: 9px; color: #f3e2c0;
  background: linear-gradient(180deg, #2a2418, #171a1c 60%, #121517);
  border: 1px solid #6b5530;
  box-shadow: inset 0 1px 0 #ffffff14, 0 2px 6px #0006;
  transition: border-color .15s, box-shadow .15s, transform .15s, color .15s;
}
.store-footer-esq .store-transferir:hover {
  color: #ffe2a8; border-color: #d9a441; transform: translateY(-1px);
  box-shadow: inset 0 1px 0 #ffffff1f, 0 0 12px #d9a44155, 0 3px 8px #0007;
}
.store-footer-esq .store-transferir:active { transform: translateY(0); }
.store-botao-icone {
  width: 26px; height: 26px; flex: 0 0 26px; border-radius: 7px;
  display: grid; place-items: center; color: #f0c27a;
  background: radial-gradient(circle at 50% 35%, #4a3a1e, #1b1712 75%);
  border: 1px solid #8a6a35; box-shadow: inset 0 0 6px #0008;
}
.store-botao-icone img, .store-botao-icone canvas { width: 20px !important; height: 20px !important; image-rendering: auto; }
/* O desenho da Store Inbox é de 32px: reduzido demais vira borrão, então ganha mais espaço. */
.store-inbox-botao .store-botao-icone canvas { width: 28px !important; height: 28px !important; margin: -2px; }
.store-botao-icone svg { width: 15px; height: 15px; }
.store-botao-icone svg.store-icone-setas { width: 17px; height: 17px; color: #5fdc7a; filter: drop-shadow(0 0 3px #5fdc7a88); }
.store-botao-texto { font-family: var(--font-heading); font-size: 12px; letter-spacing: .04em; }
.store-footer-esq .store-inbox-botao { border-color: #a07a38; }
.store-footer-esq .store-inbox-botao::after {
  content: ''; position: absolute; top: 0; bottom: 0; left: -60%; width: 35%; pointer-events: none;
  background: linear-gradient(100deg, transparent, #ffffff30, transparent);
  transform: skewX(-20deg); animation: bolsa-glow 3.6s ease-in-out infinite;
}
.store-footer-esq .store-inbox-conta {
  background: linear-gradient(180deg, #f0bd76, #c8823c); color: #2a1a06; font-weight: 700;
  box-shadow: 0 0 6px #d9a44188;
}
@media (prefers-reduced-motion: reduce) { .store-footer-esq .store-inbox-botao::after { display: none; } }
.store-footer-saldo b { font-family: var(--font-heading); font-size: 15px; color: var(--copper); }
.store-footer-saldo span { font-size: 9px; text-transform: uppercase; letter-spacing: .07em; color: var(--muted); }

/*
 * O botao de comprar coins, com um brilho que atravessa.
 *
 * O reflexo e' uma faixa clara inclinada que corre por cima do dourado a cada
 * poucos segundos — o mesmo truque de vitrine de loja de jogo. Ele mora num
 * `::after` com `overflow: hidden` no botao, entao nao vaza para os lados, e
 * some junto com o botao quando o donate esta desligado.
 */
.store-obter {
  position: relative; overflow: hidden;
  display: flex; align-items: center; gap: 8px; padding: 10px 22px; cursor: pointer;
  font-family: var(--font-heading); font-size: 13px; letter-spacing: .04em; color: #2a1a06;
  background: linear-gradient(180deg, #f0bd76, var(--copper));
  border: 1px solid #f7d9a8; border-radius: 8px;
  box-shadow: 0 0 16px #c8823c4d, inset 0 1px 0 #fff6;
  animation: obter-pulso 3.2s ease-in-out infinite;
}
.store-obter img { width: 20px; height: 20px; position: relative; z-index: 1; }
.store-obter span { position: relative; z-index: 1; }
.store-obter::after {
  content: ''; position: absolute; top: -60%; bottom: -60%; width: 45%; left: -70%;
  background: linear-gradient(90deg, #fff0 0%, #ffffffa6 50%, #fff0 100%);
  transform: rotate(18deg); pointer-events: none;
  animation: obter-reflexo 3.2s ease-in-out infinite;
}
.store-obter:hover:not(:disabled) { filter: brightness(1.1); }
.store-obter:disabled {
  background: var(--panel); border-color: var(--line); color: var(--muted);
  box-shadow: none; cursor: not-allowed; animation: none;
}
.store-obter:disabled::after { display: none; }

@keyframes obter-reflexo {
  0%   { left: -70%; }
  55%  { left: 130%; }
  100% { left: 130%; }
}
@keyframes obter-pulso {
  0%, 100% { box-shadow: 0 0 14px #c8823c40, inset 0 1px 0 #fff6; }
  50%      { box-shadow: 0 0 24px #e0a45a80, inset 0 1px 0 #fff8; }
}

/* Quem prefere a tela quieta nao ganha um botao piscando na cara. */
@media (prefers-reduced-motion: reduce) {
  .store-obter, .store-obter::after, .coins-card { animation: none; }
}

/* A janela abre POR CIMA da loja, que continua atras — ver `abrirObterCoins`. */
.coins-back {
  position: fixed; inset: 0; z-index: 56; display: grid; place-items: center;
  background: #0407089e; backdrop-filter: blur(3px); padding: 20px;
}
.coins-box {
  width: min(760px, 96vw); max-height: 88vh; overflow-y: auto;
  background: var(--panel-solid); border: 1px solid var(--copper); border-radius: 12px;
  box-shadow: 0 22px 60px #000b;
}
.coins-box.pagamento { width: min(420px, 96vw); border-color: var(--accent-dim); }
.coins-box.transferencia { width: min(480px, 96vw); border-color: var(--accent-dim); }
.coins-box.transferencia .coins-title h3 { color: var(--accent); }

.coins-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 16px 20px; border-bottom: 1px solid var(--line-soft);
  background: linear-gradient(90deg, #241d0d, transparent);
}
.coins-title { display: flex; align-items: center; gap: 10px; }
.coins-title img { width: 28px; height: 28px; }
.coins-title h3 { margin: 0; font-size: 17px; color: var(--copper); }
.coins-box.pagamento .coins-title h3 { color: var(--accent); }
.coins-x {
  background: none; border: none; color: var(--muted); font-size: 22px; line-height: 1;
  cursor: pointer; padding: 0 4px;
}
.coins-x:hover { color: var(--text); }

.coins-body { padding: 18px 20px 22px; display: grid; gap: 14px; }
.coins-lead { margin: 0; font-size: 12px; color: var(--muted); line-height: 1.55; }

.coins-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); gap: 10px; }
/*
 * Os cartoes dos pacotes, acesos por dentro.
 *
 * O brilho e' um halo cobre atras do numero (`radial-gradient` no `::before`),
 * respirando devagar e fora de fase entre os cartoes — sem o atraso, os sete
 * pulsariam juntos e a tela viraria um letreiro. Passar o mouse acende o cartao
 * de vez e o levanta um pouco.
 */
.coins-card {
  position: relative; overflow: hidden; display: grid; gap: 4px; justify-items: center; text-align: center;
  padding: 18px 12px 14px; border-radius: 10px;
  background: linear-gradient(180deg, #232b31, #151b1e);
  border: 1px solid var(--line);
  box-shadow: inset 0 1px 0 #ffffff0f;
  transition: transform .16s ease, border-color .16s ease, box-shadow .16s ease;
}
.coins-card::before {
  content: ''; position: absolute; top: -40%; left: 50%; width: 150%; height: 120%;
  transform: translateX(-50%); pointer-events: none;
  background: radial-gradient(ellipse at 50% 30%, #c8823c40 0%, #c8823c00 62%);
  animation: coins-respira 4.6s ease-in-out infinite;
}
.coins-card:nth-child(2n)::before { animation-delay: -1.1s; }
.coins-card:nth-child(3n)::before { animation-delay: -2.3s; }
.coins-card:nth-child(5n)::before { animation-delay: -3.4s; }
.coins-card:hover {
  transform: translateY(-2px);
  border-color: var(--copper);
  box-shadow: 0 8px 22px #0008, 0 0 20px #c8823c33, inset 0 1px 0 #ffffff1a;
}
.coins-card > * { position: relative; z-index: 1; }

@keyframes coins-respira {
  0%, 100% { opacity: .45; }
  50%      { opacity: 1; }
}

.coins-card-topo { display: flex; align-items: center; gap: 7px; }
.coins-card-topo img { width: 28px; height: 28px; }
.coins-card-topo b { font-family: var(--font-heading); font-size: 24px; color: var(--text); }
.coins-card-rotulo { font-size: 9px; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); }
.coins-bonus { font-size: 11px; color: var(--accent); }
.coins-recebe { font-size: 10px; color: var(--muted); }
.coins-preco { font-family: var(--font-heading); font-size: 17px; color: var(--copper); margin-top: 6px; }
.coins-comprar {
  width: 100%; margin-top: 8px; padding: 9px 0; cursor: pointer; border-radius: 7px;
  font-family: var(--font-heading); font-size: 12px; color: #eafffb;
  background: var(--accent-dim); border: 1px solid var(--accent-dim);
}
.coins-comprar:hover:not(:disabled) { filter: brightness(1.2); }
.coins-comprar:disabled { background: var(--panel); border-color: var(--line); color: var(--muted); cursor: not-allowed; }

.coins-metodo {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  width: 100%; padding: 14px 18px; cursor: pointer; text-align: left; border-radius: 9px;
  background: var(--panel-2); border: 1px solid var(--line); color: var(--text);
}
.coins-metodo:hover { border-color: var(--accent); }
.coins-metodo.pix:hover { box-shadow: 0 0 14px #3fbfa826; }
/* O roxo da marca do Stripe, só no filete e no brilho: o resto segue a loja. */
.coins-metodo.stripe { box-shadow: inset 3px 0 0 #635bff; }
.coins-metodo.stripe:hover { border-color: #635bff; box-shadow: inset 3px 0 0 #635bff, 0 0 14px #635bff33; }
.coins-metodo.stripe .coins-metodo-nome b { color: #a7a2ff; }
.coins-metodo-nome { display: grid; gap: 2px; }
.coins-metodo-nome b { font-family: var(--font-heading); font-size: 14px; }
.coins-metodo-nome em { font-style: normal; font-size: 10px; color: var(--muted); }
.coins-metodo-valor { font-family: var(--font-heading); font-size: 16px; color: var(--copper); }
.coins-voltar { justify-self: center; padding: 8px 26px; }

/* ---------- troca manual de Tibia Coins / Rubini Coins (ver passoTroca) ---------- */
.troca-tc-entrada {
  display: flex; align-items: center; gap: 12px; width: 100%; margin-top: 4px; padding: 12px 16px;
  cursor: pointer; text-align: left; border-radius: 10px; color: var(--text);
  background: linear-gradient(180deg, #2a2418, #171a1c); border: 1px solid #8a6a35;
}
.troca-tc-entrada:hover { border-color: #d9a441; box-shadow: 0 0 14px #d9a44133; }
.troca-tc-entrada img { width: 28px; height: 28px; }
.troca-tc-entrada-texto { display: grid; gap: 2px; flex: 1; min-width: 0; }
.troca-tc-entrada-texto b { font-family: var(--font-heading); font-size: 14px; color: #f0c27a; }
.troca-tc-entrada-texto em { font-style: normal; font-size: 10px; color: var(--muted); }
.troca-tc-entrada-seta { font-size: 22px; color: #f0c27a; }
.troca-tc-grupo { display: grid; gap: 5px; }
.troca-tc-final { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.troca-tc-final .troca-tc-confirmo { flex: 1 1 280px; }
.troca-tc-passo {
  display: block; margin-top: 0; font-family: var(--font-heading); font-size: 11px;
  letter-spacing: .05em; text-transform: uppercase; color: var(--copper);
}
.troca-tc-servidores { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 8px; }
.troca-tc-servidor {
  display: grid; gap: 2px; padding: 10px 14px; cursor: pointer; text-align: left; border-radius: 9px;
  background: var(--panel-2); border: 1px solid var(--line); color: var(--text);
}
.troca-tc-servidor b { font-family: var(--font-heading); font-size: 14px; }
.troca-tc-servidor em { font-style: normal; font-size: 10px; color: var(--muted); }
.troca-tc-servidor:hover { border-color: #8a6a35; }
.troca-tc-servidor.escolhido { border-color: #d9a441; background: linear-gradient(180deg, #2a2418, #1b1e20); box-shadow: 0 0 12px #d9a44133; }
.troca-tc-servidor.escolhido b { color: #f0c27a; }
.troca-tc-quanto { display: grid; gap: 8px; padding: 12px 14px; border-radius: 9px; background: var(--panel-2); border: 1px solid var(--line); }
/*
 * O resumo em dois cartões: o que SAI (vermelho suave) e o que ENTRA (verde),
 * com a seta num círculo entre eles. Só a cor muda — sem enfeite a mais.
 */
.troca-tc-resumo { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: center; gap: 10px; }
.troca-tc-lado {
  display: grid; gap: 2px; padding: 8px 12px; border-radius: 8px; min-width: 0;
  background: linear-gradient(180deg, #2a1614, #1c1716); border: 1px solid #6e2e28;
}
.troca-tc-lado span { font-size: 9px; text-transform: uppercase; letter-spacing: .08em; color: #ff9b8a; }
.troca-tc-lado b { font-family: var(--font-heading); font-size: 18px; color: #ffd0c7; }
.troca-tc-lado-recebe {
  text-align: right; justify-items: end;
  background: linear-gradient(180deg, #13261b, #151c18); border-color: #2f6e45;
}
.troca-tc-lado-recebe span { color: #7fe0a0; }
.troca-tc-lado-recebe b { color: #b9f5cc; }
.troca-tc-igual {
  width: 30px; height: 30px; display: grid; place-items: center; border-radius: 50%;
  font-size: 16px; color: #5fdc7a; background: none; border: none;
}
@media (max-width: 520px) {
  .troca-tc-resumo { grid-template-columns: 1fr; }
  .troca-tc-lado-recebe { text-align: left; justify-items: start; }
  .troca-tc-igual { justify-self: center; transform: rotate(90deg); }
}
.troca-tc-linha-barra { display: flex; align-items: center; gap: 8px; }
.troca-tc-passo-botao {
  width: 28px; height: 28px; flex: none; cursor: pointer; border-radius: 6px; font-size: 16px; line-height: 1;
  background: var(--panel); border: 1px solid var(--line); color: var(--text);
}
.troca-tc-passo-botao:hover { border-color: #d9a441; color: #f0c27a; }
.troca-tc-barra {
  flex: 1; min-width: 0; height: 8px; cursor: pointer; appearance: none; -webkit-appearance: none; border-radius: 999px;
  outline: none; caret-color: transparent;
  /*
   * O dourado termina no CENTRO da bolinha (18px): o trilho útil é a largura
   * menos a bolinha, e a ponta do gradiente solta aparecia como um tracinho
   * ao lado dela.
   */
  background:
    linear-gradient(#d9a441, #d9a441) 0 0 / calc(9px + (100% - 18px) * var(--p, 0)) 100% no-repeat,
    #2b3a3f;
}
.troca-tc-barra:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 3px #d9a44155, 0 0 8px #d9a44188; }
.troca-tc-barra::-webkit-slider-thumb {
  -webkit-appearance: none; width: 18px; height: 18px; border-radius: 50%;
  background: #f0c27a; border: 2px solid #6b5530; box-shadow: 0 0 8px #d9a44188;
}
.troca-tc-barra::-moz-range-thumb { width: 16px; height: 16px; border-radius: 50%; background: #f0c27a; border: 2px solid #6b5530; }
/* As moedas desenhadas no texto da troca (comMoedas / moedasTrocando). */
/* Em linha com o texto (inline-flex subia ou descia a palavra): só a moeda desce até o meio da letra. */
.troca-tc-com-moeda { white-space: nowrap; }
.troca-tc-com-moeda .troca-tc-moeda { display: inline-block; vertical-align: middle; margin: -3px 3px 0 0; }
/*
 * Só tamanhos exatos, senão borra: a do Tibia e a do Mineiroidle nascem com 32px e
 * vão a 16 ou 24 (redução lisa); a do Rubini nasce com 12px e fica em 12
 * (centrada numa caixa de 16) ou dobra para 24 com pixel duro.
 */
.troca-tc-moeda { width: 16px; height: 16px; object-fit: contain; image-rendering: auto; flex: none; }
.troca-tc-moeda.moeda-rubini { object-fit: none; image-rendering: pixelated; }
.troca-tc-trocando { display: inline-flex; align-items: center; gap: 3px; flex: none; }
.troca-tc-trocando .troca-tc-moeda { width: 24px; height: 24px; }
.troca-tc-setas { width: 16px; height: 16px; color: #5fdc7a; filter: drop-shadow(0 0 3px #5fdc7a88); }
.troca-tc-servidor-nome { display: flex; align-items: center; gap: 8px; }
.troca-tc-servidor-nome .troca-tc-trocando .troca-tc-moeda { width: 16px; height: 16px; }
.troca-tc-servidor-nome .troca-tc-setas { width: 13px; height: 13px; }
.troca-tc-entrada .troca-tc-trocando .troca-tc-moeda { width: 24px; height: 24px; }
/* Dentro do texto a moeda acompanha a letra, mesmo onde a regra da caixa pinta todo <img>/<span>. */
.troca-tc-entrada .troca-tc-com-moeda .troca-tc-moeda { width: 16px; height: 16px; }
/* Grandes (24px): o Rubini dobra certinho e o desenho enche a caixa. */
.troca-tc-trocando .troca-tc-moeda.moeda-rubini,
.troca-tc-lado b .troca-tc-moeda.moeda-rubini { object-fit: contain; }
.troca-tc-servidor-nome .troca-tc-trocando .troca-tc-moeda.moeda-rubini { object-fit: none; }
.troca-tc-lado b .troca-tc-moeda { width: 24px; height: 24px; margin-top: -5px; }
.troca-tc-lado b .troca-tc-com-moeda { font-size: inherit; text-transform: inherit; letter-spacing: inherit; color: inherit; }
.troca-tc-aviso {
  display: grid; gap: 4px; justify-items: center; text-align: center; padding: 12px 14px; border-radius: 9px;
  background: #2a1d0e; border: 1px solid #d9a441; box-shadow: inset 0 0 18px #d9a44122;
}
.troca-tc-aviso span { font-size: 12px; color: var(--text); }
.troca-tc-aviso em { font-style: normal; font-size: 10px; color: #e8c79a; }
.troca-tc-char-do-dono { font-family: var(--font-heading); font-size: 22px; color: #ffd27a; letter-spacing: .03em; user-select: all; }
.troca-tc-atencao {
  /* Numa linha só, como era o texto, só que chamativa. */
  display: inline-flex; align-items: center; gap: 7px; margin-top: 4px; padding: 4px 12px; border-radius: 999px;
  text-align: left; background: linear-gradient(180deg, #4a1512, #2e0e0c); border: 1px solid #e0564a;
  box-shadow: 0 0 12px #e0564a44; animation: troca-tc-atencao 2.4s ease-in-out infinite;
}
.troca-tc-atencao svg { width: 17px; height: 17px; flex: none; filter: drop-shadow(0 0 4px #ffcf4a88); }
.troca-tc-atencao-texto { display: flex; align-items: baseline; gap: 5px; flex-wrap: wrap; }
.troca-tc-aviso .troca-tc-atencao-texto b { font-size: 11px; font-weight: 700; color: #ffe1a8; letter-spacing: .01em; }
.troca-tc-aviso .troca-tc-atencao-texto span { font-size: 10px; color: #ffb8ad; }
@keyframes troca-tc-atencao { 50% { box-shadow: 0 0 18px #e0564a88; border-color: #ff7a6b; } }
@media (prefers-reduced-motion: reduce) { .troca-tc-atencao { animation: none; } }
.troca-tc-char-linha { display: flex; align-items: center; justify-content: center; gap: 10px; flex-wrap: wrap; }
.troca-tc-copiar {
  padding: 5px 12px; cursor: pointer; border-radius: 6px; font-family: var(--font-heading); font-size: 11px;
  color: #2a1a06; background: linear-gradient(180deg, #f0bd76, #c8823c); border: 1px solid #f7d9a8;
}
.troca-tc-copiar:hover { filter: brightness(1.1); }
.troca-tc-copiar.copiado { color: #eafffb; background: var(--accent-dim); border-color: var(--accent); }
.troca-tc-confirmar:disabled { opacity: .55; }
.troca-tc-nomes { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 8px; }
.troca-tc-campo { display: grid; gap: 4px; }
.troca-tc-campo span { font-size: 10px; color: var(--muted); }
.troca-tc-campo input {
  padding: 8px 10px; border-radius: 7px; font-size: 13px; color: var(--text);
  background: var(--panel); border: 1px solid var(--line);
}
.troca-tc-campo input:focus { outline: none; border-color: #d9a441; }
.troca-tc-avisos { margin: 0; padding-left: 18px; display: grid; gap: 4px; font-size: 11px; color: var(--text); line-height: 1.5; }
.troca-tc-confirmo { display: flex; align-items: flex-start; gap: 8px; font-size: 12px; color: var(--text); cursor: pointer; }
.troca-tc-confirmo input { margin-top: 2px; accent-color: #d9a441; }
.troca-tc-erro { margin: 0; font-size: 12px; color: var(--danger); text-align: center; }
.troca-tc-botoes { display: flex; justify-content: center; align-items: center; gap: 10px; flex-wrap: wrap; }
.troca-tc-botoes .coins-voltar { justify-self: auto; }
.troca-tc-confirmar { width: auto; margin-top: 0; padding: 9px 28px; }
.troca-tc-feita { display: grid; gap: 4px; text-align: center; }
.troca-tc-feita b { font-family: var(--font-heading); font-size: 18px; color: var(--accent); }
.troca-tc-feita span { font-size: 12px; color: var(--text); }
.troca-tc-whatsapp {
  display: inline-flex; align-items: center; gap: 8px; padding: 10px 26px; border-radius: 8px; text-decoration: none;
  font-family: var(--font-heading); font-size: 13px; color: #fff; background: linear-gradient(180deg, #2fd46a, #1b9e4b);
  border: 1px solid #5ff09a; box-shadow: 0 0 14px #25d36655;
}
.troca-tc-whatsapp:hover { filter: brightness(1.1); }

.donate-passos { margin: 0; font-size: 12px; color: var(--text); line-height: 1.6; text-align: center; }


/* ---------- filtro de loot ---------- */

.filter-layout { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); gap: 14px; align-items: start; }
.filter-side { display: grid; gap: 12px; }
.filter-box { background: var(--panel-2); border: 1px solid var(--line); border-radius: 9px; padding: 11px 12px; }
.filter-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 7px; }
.filter-head b { font-family: var(--font-heading); font-size: 12px; letter-spacing: .06em; text-transform: uppercase; }
.filter-head span {
  font-size: 11px; color: var(--muted); background: var(--panel-solid);
  border: 1px solid var(--line); border-radius: 999px; padding: 1px 9px;
}
/* Coluna do tamanho da célula: com `minmax(40px, 1fr)` e célula de 44px fixos a
   grade estourava a largura e nascia uma barra horizontal. */
.filter-grid {
  display: grid; grid-template-columns: repeat(auto-fill, 44px); gap: 5px; justify-content: start;
  max-height: 340px; overflow-y: auto; overflow-x: hidden;
}
/* O aviso de lista vazia ocupa a FILEIRA inteira.
   Numa grade de colunas de 44px o paragrafo cai dentro de uma celula, e
   "Nenhum drop conhecido por aqui" sai quebrado em uma silaba por linha. E o
   mesmo defeito que a caixa vazia do deposito tinha. */
.filter-grid > .empty { grid-column: 1 / -1; margin: 6px 2px; }
.filter-legend { display: block; margin-top: 7px; font-style: normal; font-size: 10px; color: var(--muted); line-height: 1.4; }
/* Contorno vermelho para o que nem é recolhido; teal para o que fica na bolsa. */
/*
 * Uma cor por estado, e uma só.
 *
 * `.cell.protected` já pinta a borda de cobre lá em cima, para o item marcado
 * se destacar dentro da mochila. Aqui na grade do filtro ela somava com o anel
 * verde e a célula ficava com duas cores ao mesmo tempo — parecia dois estados
 * empilhados em vez de um. A borda passa a acompanhar o anel.
 */
/* As duas cores são as MESMAS da legenda logo acima da grade: vermelho é "não
   coleta", verde é "não vende". Com o teal do tema no lugar do verde, a célula
   marcada para não vender e o contorno de foco do jogo ficavam do mesmo tom. */
.filter-grid .cell.barred { border-color: #d8564c; box-shadow: inset 0 0 0 2px #d8564c; }
.filter-grid .cell.protected { border-color: #35d17a; box-shadow: inset 0 0 0 2px #35d17a; }
.filter-foot { display: flex; justify-content: flex-end; margin-top: 14px; }

/* ---------- bolsa de loot enxuta ---------- */

.autosell.mini {
  flex: none; padding: 2px 8px; cursor: pointer; font-size: 8px; letter-spacing: .03em; text-transform: uppercase;
  line-height: 15px; white-space: nowrap;
  border-radius: 999px; border: 1px solid var(--line); background: var(--panel-solid); color: var(--muted);
}
.autosell.mini.on { border-color: var(--copper); color: var(--copper); }
.autosell.mini.off { border-color: #a33; color: #ff8a7a; }

.loot-filter-button {
  display: flex; align-items: center; justify-content: center; gap: 7px; width: 100%; margin-top: 8px;
  cursor: pointer; font-size: 11px; color: #cfe0dd;
  min-height: 40px; padding: 0 4px;
  border-style: solid; border-width: 9px 11px;
  border-image-source: url(/client/assets/ui/loot-filter.png);
  /* A moldura desta é fina — um friso de bronze com o fio de verdete —, então a
     fatia é bem menor que a das placas de venda. */
  border-image-slice: 16 18 fill;
  border-image-repeat: stretch;
  border-radius: 0; background: none;
  transition: filter .15s ease;
}
.loot-filter-button:hover { color: var(--accent); filter: brightness(1.15) drop-shadow(0 0 6px #3fbfa877); }
.loot-filter-button img { width: 18px; height: 18px; image-rendering: pixelated; }
.loot-filter-button .count {
  font-size: 10px; padding: 0 6px; border-radius: 999px;
  background: var(--copper); color: #1a1208;
}

/* ---------- bolsa de loot: interruptores e avisos ---------- */

/* Os dois interruptores ficam entre o cabeçalho e o loot, centrados e miúdos —
   nenhum dos dois é ação do dia a dia. */
/* Lado a lado: empilhados eles comiam duas fileiras de loot numa janela que já
   é baixa. Cada um fica com metade da largura e a altura de uma linha só. */
.bag-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 5px; margin-bottom: 7px; align-items: stretch; }
.bag-actions .autosell, .bag-actions .loot-filter-button { width: 100%; min-width: 0; }

/*
 * ---- A placa tem um TAMANHO, e a janela pode ser qualquer um ----
 *
 * O relato: "a imagem de fundo dos botões estica conforme a largura da janela.
 * Se deixar muito largo a imagem fica distorcida. Os textos e ícones dos botões
 * vazam pra fora se a janela fica muito pequena".
 *
 * São os dois extremos do mesmo descuido: o botão seguia a janela sem piso nem
 * teto.
 *
 * ---- O teto ----
 *
 * A arte é 2:1 e a moldura é `border-image` de nove fatias, então os cantos
 * ficam inteiros por construção — o que deforma é a FATIA DO MEIO, esticada
 * sozinha à medida que a janela cresce. Um teto de largura resolve isso sem
 * mexer na arte: passado ele a placa para de crescer e fica centrada, e a
 * janela larga ganha margem em vez de uma placa borrada.
 *
 * A bolsa nasce com 246px, o que dá ~118 por placa. 200 é bastante folga para
 * quem gosta da janela grande e ainda assim longe do ponto em que o friso
 * começa a se abrir.
 *
 * ---- O piso ----
 *
 * Vazar é outra coisa: `white-space: nowrap` no rótulo mais o ícone e a bolinha
 * da contagem somam mais do que a placa estreita tem. Nada aqui pode transbordar
 * a placa, então o rótulo passa a caber por reticências e os dois enfeites
 * param de encolher — um ícone amassado é pior do que um rótulo cortado.
 */
.bag-actions .autosell, .bag-actions .loot-filter-button { max-width: 200px; justify-self: center; overflow: hidden; }
.bag-actions .autosell b, .bag-actions .loot-filter-button b {
  min-width: 0; overflow: hidden; text-overflow: ellipsis;
}
.bag-actions .loot-filter-button canvas, .bag-actions .loot-filter-button img, .bag-actions .loot-filter-button .count {
  flex: none;
}

/*
 * As duas placas.
 *
 * A moldura ornamentada é `border-image`, e não uma imagem esticada: o botão é
 * quase cinco vezes mais largo do que alto, e a arte é 2:1 — esticada, os
 * rebites dos cantos virariam elipses. Em nove fatias os cantos ficam intactos
 * e só as bordas retas crescem.
 *
 * A fatia 44/48 é onde o ornamento acaba e o campo liso começa, medido na arte
 * de 512px. `border-width` é bem menor que isso de propósito: o ornamento
 * encolhe junto e sobra como um friso, que é o que cabe num botão desta altura.
 */
.bag-actions .autosell {
  display: grid; gap: 0; cursor: pointer; text-align: center; align-content: center;
  min-height: 40px; padding: 0 4px;
  border-style: solid; border-width: 11px 13px;
  border-image-slice: 44 48 fill;
  border-image-repeat: stretch;
  border-radius: 0; background: none;
}
.bag-actions .autosell.on { border-image-source: url(/client/assets/ui/auto-venda-on.png); }
.bag-actions .autosell.off { border-image-source: url(/client/assets/ui/auto-venda-off.png); }
/* O pulsar continua, agora contornando a placa em vez da caixa: `drop-shadow`
   segue os pixels pintados, e a placa tem canto arredondado. */
.bag-actions .autosell.on, .bag-actions .autosell.off { animation: none; }
.bag-actions .autosell.on { filter: drop-shadow(0 0 3px #d3a03866); }
.bag-actions .autosell.off { filter: drop-shadow(0 0 3px #a83c3466); }
.bag-actions .autosell:hover { filter: brightness(1.1) drop-shadow(0 0 6px #f0c95faa); }
.bag-actions .autosell.off:hover { filter: brightness(1.1) drop-shadow(0 0 6px #e0655baa); }
.bag-actions .autosell b {
  font-family: var(--font-heading); font-size: 10px; letter-spacing: .04em; white-space: nowrap;
  /* Texto escuro sobre o dourado, claro sobre o vermelho: cada placa pede a sua. */
  text-shadow: 0 1px 0 #00000055;
}
.bag-actions .autosell.on b { color: #2a1d05; text-shadow: 0 1px 0 #ffe6a366; }
.bag-actions .autosell.off b { color: #ffe4e0; }
/* A explicação vira tooltip: na metade da largura ela não cabe. */
.bag-actions .autosell em { display: none; }


/* O aviso flutua no rodapé da janela: empilhado no fluxo ele empurrava o loot
   para baixo e comia metade da bolsa justamente quando ela precisava ser vista. */
.bag-alert {
  position: absolute; left: 6px; right: 6px; bottom: -14px; z-index: 3; pointer-events: none;
  display: grid; gap: 1px; padding: 5px 10px; text-align: center;
  background: #2a1111f2; border: 1px solid #a3333388; border-radius: 6px;
  box-shadow: 0 6px 18px #000a;
}
.bag-alert b { font-size: 11px; color: #ff8a7a; }
.bag-alert em { font-style: normal; font-size: 9px; color: #d8b0a8; }

/* Alvo de soltura no filtro de loot. */
.filter-box.drop-target { transition: border-color .12s ease, background .12s ease; }
.filter-box.drop-target.over { border-color: var(--accent); background: #16241f; }
.filter-grid .cell[draggable="true"] { cursor: grab; }
.filter-grid .cell.dragging { opacity: .4; }

/* ---------- botões da bolsa: brilho por dentro ---------- */

/* Ligado, o interruptor respira dourado por dentro; desligado, vermelho. É o
   mesmo pulso do card de promotion — o jogador reconhece o sinal. */
.bag-actions .autosell.on {
  background: linear-gradient(180deg, #2a2210, var(--panel-solid));
  animation: autosell-on 2.4s ease-in-out infinite;
}
@keyframes autosell-on {
  0%, 100% { box-shadow: inset 0 0 8px #d9ae4a22, 0 0 0 1px #c79a3c33; }
  50% { box-shadow: inset 0 0 16px #ffd98055, 0 0 8px #d9ae4a44; }
}
.bag-actions .autosell.off {
  background: linear-gradient(180deg, #2a1414, var(--panel-solid));
  animation: autosell-off 1.4s ease-in-out infinite;
}
@keyframes autosell-off {
  0%, 100% { box-shadow: inset 0 0 8px #a3333333; }
  50% { box-shadow: inset 0 0 18px #e04a3a66, 0 0 8px #a3333355; }
}


/* Arte da loja: as imagens da gamestore são 64px, então não pixelam. */
.store-art img { display: block; object-fit: contain; }


/* ---------- ficha recolhida para a barra de baixo ---------- */

/*
 * Quando o card desce, os mesmos elementos mudam de casa: `hud-body` inteiro
 * vem para cá. Nada é duplicado, então nada precisa ser mantido em dois
 * lugares — mas aqui ele se deita, porque o rodapé é largo e baixo.
 */
/*
 * Linha própria, acima dos slots: encaixada ao lado dos doze slots ela empurrava
 * o "Sair da hunt" para fora da tela. Ela é só uma faixa fina — em cima o card
 * empilha as três barras porque é estreito e alto; aqui elas se deitam lado a
 * lado, com os chips e os ícones dos sistemas no mesmo alinhamento.
 */
/*
 * Recolhida, a ficha se parte em dois — o rodapé não é um card.
 *
 * Chips e ícones de sistema formam uma tira centrada em cima dos slots; as três
 * barras ficam em pé, à direita do "Sair da hunt". Empilhadas como no card elas
 * teriam que dobrar a altura da barra inteira.
 */
.hud-dock { display: flex; align-items: center; gap: 8px; }

/*
 * Uma régua só, dividida em quatro.
 *
 * Em pé, à direita do "Sair da hunt", elas eram tirinhas de 14px onde o número
 * não cabia. Deitadas e dividindo a largura toda, cada uma fica com uns 246px:
 * o número volta para dentro dela e dá para ler de relance quanta vida falta,
 * que é para isso que a régua existe. `flex: 1` reparte o espaço em partes
 * iguais, então a fita acompanha a largura da barra sem número mágico nenhum.
 *
 * `gap: 0` entre elas e o arredondado só nas duas pontas: no meio, o que separa
 * é a própria borda preta de cada barra, que encostada na vizinha vira um traço
 * de dois pixels. É uma régua repartida, não quatro peças soltas.
 */
/*
 * ---- As réguas voltaram a ser uma FITA deitada, em cima dos slots ----
 *
 * Elas já foram assim, ficaram em pé na coluna de fora, e voltam. O que muda a
 * resposta é onde está o aperto, e ele mudou de lugar duas vezes.
 *
 * Em pé elas resolviam uma coluna vazia e devolviam altura; deitadas elas
 * custam ~22px de altura, e é o que o dono escolheu — quatro medidores lado a
 * lado se leem de uma varrida só, e é a leitura que importa numa barra que se
 * olha de canto de olho.
 *
 * E ela atravessa a BARRA inteira, não só os slots: mora como irmã da fileira,
 * então `width: 100%` já é a largura toda. Chegou a morar dentro da
 * `.hotbar-stack` para ter o tamanho exato da fileira de slots — o dono
 * preferiu a fita larga.
 */
.bars-dock { display: flex; align-items: center; gap: 10px; width: 100%; }
.bars-dock .hud-bars {
  display: flex; flex-direction: row; gap: 0; width: auto; flex: 1;
  border-radius: 4px; overflow: hidden; margin-top: 0;
}
.bars-dock .bar-slot { display: flex; flex: 1; min-width: 0; }
/*
 * O sulco de pedra em volta de cada régua.
 *
 * `border-image` com `fill`: o friso de bronze e verdete fica nas bordas, o
 * canal escuro preenche o meio, e o `<i>` do preenchimento corre por dentro
 * dele. A borda de 5px é fina de propósito — quatro sulcos lado a lado com
 * moldura grossa viram a mesma cerca que estragou a barra de habilidade.
 */
/*
 * 18px de altura, com a moldura de 3px em cima e embaixo em vez de 5.
 *
 * Deitadas eram 22px com moldura de 5px — 12px de miolo, exatamente a
 * entrelinha do número. Em pé são QUATRO empilhadas, e cada pixel de altura
 * vale quatro: em 22px a coluna ficava mais alta que a fileira de slots e
 * passava a mandar na altura da barra inteira.
 *
 * A moldura é que cedeu, e não o miolo: 18px de caixa com 3px de borda dão os
 * mesmos 12px de dentro, então o número continua cabendo do jeito que cabia. O
 * friso de bronze fica dois pixels mais fino, que a essa escala não se vê.
 *
 * Foi a 20/4 primeiro, e depois a 18/3 quando o Hunts veio morar nesta coluna:
 * são mais 34px aqui dentro, e sem isso a coluna passava dos 109px dos slots e
 * voltava a ser ela quem manda na altura da barra.
 */
.bars-dock .hud-bar {
  flex: 1; min-width: 0; height: 18px; border-radius: 0;
  border-style: solid; border-width: 3px 6px;
  border-image-source: url(/client/assets/ui/bar-track.png);
  border-image-slice: 22 fill;
  border-image-repeat: stretch;
  background: none; box-shadow: none;
}
/* Ícone dentro da régua, sobre o preenchimento: fora dela ele abriria fresta. */
.bars-dock .bar-icon {
  display: block; position: absolute; left: 4px; top: 50%; transform: translateY(-50%);
  height: 11px; width: auto; z-index: 2; pointer-events: none;
}
/* O quadrado não é sprite: `width: auto` num `<span>` vazio o achatava para
   dois pixels de borda. */
.bars-dock .bar-dot { width: 11px; }
/* O número se centra no que sobra à direita do ícone, senão encosta nele. */
.bars-dock .hud-bar span { font-size: 10px; line-height: 12px; padding-left: 15px; }

#hud-undock {
  width: 20px; height: 20px; flex: none; padding: 0; cursor: pointer; font-size: 10px;
  background: #1b2327cc; border: 1px solid var(--line); border-radius: 4px; color: var(--muted);
}
#hud-undock:hover { border-color: var(--accent); color: #fff; }
/*
 * Descido, o card some inteiro.
 *
 * Antes ficava lá em cima o casco vazio — retrato, nome, vocação — e o jogador
 * via duas fichas ao mesmo tempo. O corpo está no rodapé; o resto vai junto, e
 * o ▴ de baixo é quem traz tudo de volta.
 */
#hud.docked { display: none; }

#hud-dock-btn {
  width: 24px; height: 24px; flex: none; padding: 0; cursor: pointer; font-size: 12px;
  background: #1b2327cc; border: 1px solid var(--line); border-radius: 5px; color: var(--muted);
}
#hud-dock-btn:hover { border-color: var(--accent); color: #fff; }

/* ---------- analisador de loot ---------- */

/* Ícones pequenos com a quantidade no canto: em texto a lista viraria uma
   coluna de vinte linhas e a janela dobraria de altura. */
.loot-tally { margin-top: 8px; }
.loot-tally > summary {
  cursor: pointer; font-size: 10px; letter-spacing: .07em; text-transform: uppercase;
  color: var(--muted); padding: 4px 0; list-style: none;
}
.loot-tally > summary::-webkit-details-marker { display: none; }
.loot-tally > summary::before { content: "▸ "; color: var(--accent-dim); }
.loot-tally[open] > summary::before { content: "▾ "; }
.loot-tally .empty { margin: 4px 0; font-size: 10px; color: var(--muted); }
.loot-tally-grid { display: grid; grid-template-columns: repeat(auto-fill, 30px); gap: 4px; }
.loot-chip {
  position: relative; width: 30px; height: 30px; display: grid; place-items: center;
  background: #161d20; border: 1px solid var(--line-soft); border-radius: 5px;
}
.loot-chip canvas { width: 24px; height: 24px; image-rendering: pixelated; }
.loot-chip i {
  position: absolute; right: -2px; bottom: -3px; font-style: normal; font-size: 9px; line-height: 11px;
  padding: 0 3px; background: #0b0f10e6; border-radius: 999px; color: #d8cfb8;
}

/*
 * ---- A peça gasta: quantidade em cima, ouro embaixo ----
 *
 * A quantidade fica no mesmo canto do loot (é a mesma leitura: "quantos"), e o
 * ouro sai por baixo em cobre, alinhado ao centro. A peça ganha 12px de altura
 * para caber a segunda linha — só nesta grade, para não mexer no loot.
 */
.loot-chip.gasto { width: 36px; height: 50px; align-content: start; padding-top: 3px; }
.loot-chip.gasto canvas { width: 30px; height: 30px; }
.loot-chip.gasto i { bottom: 13px; right: -1px; }
.loot-chip.gasto u {
  position: absolute; left: 0; right: 0; bottom: 1px;
  text-decoration: none; text-align: center;
  font-family: var(--font-numero); font-size: 9px; line-height: 10px; color: var(--copper);
}

/* O total ao lado do título da seção, com a moeda antes do número. */
.gasto-total { display: inline-flex; align-items: center; gap: 4px; margin-left: 6px; }
.gasto-total canvas { width: 13px; height: 13px; image-rendering: pixelated; }
.gasto-total b { font-family: var(--font-numero); font-size: 12px; color: var(--copper); }


/* ---------- tooltip de conteúdo livre ---------- */

/* ---------- tooltip dos botões da barra ---------- */

/* Sprite grande, nome e a frase do que o clique faz. O `title` do navegador
   dava só o nome, na fonte do sistema e meio segundo atrasado. */
.tip-tool { display: grid; gap: 0; max-width: 260px; }
.tip-tool-head {
  display: flex; align-items: center; gap: 10px; padding: 9px 12px 8px;
  border-bottom: 1px solid var(--line);
}
.tip-tool-head img { width: 34px; height: 34px; flex: none; object-fit: contain; }
.tip-tool-glyph {
  width: 34px; height: 34px; flex: none; display: grid; place-items: center;
  font-size: 19px; color: var(--accent);
}
.tip-tool-head b {
  font-family: var(--font-heading); font-size: 13px; letter-spacing: .05em;
  color: #f2e6cd; font-weight: 700;
}
.tip-tool p { margin: 0; padding: 8px 12px 10px; font-size: 11px; line-height: 1.45; color: var(--muted); }

/* Sem faixa de raridade e sem cabeçalho de item: a moldura é a mesma, o miolo
   é de quem chamou. */
/* Opaco, ao contrário do tooltip de item: são sete linhas de texto miúdo, e o
   que passa por trás delas atravessava a leitura. */
.tooltip.painel { padding: 0; min-width: 232px; background: var(--panel-solid); }
.tip-bless { display: grid; gap: 0; }
.tip-bless-head {
  padding: 8px 11px 7px; font-family: var(--font-heading); font-size: 11px;
  letter-spacing: .08em; text-transform: uppercase; color: var(--accent);
  border-bottom: 1px solid var(--line);
}
.tip-bless-list { display: grid; gap: 1px; padding: 7px 9px; }
.tip-bless-row {
  display: flex; align-items: center; gap: 8px; padding: 3px 4px; border-radius: 4px;
  font-size: 11px; color: #55646a;
}
/* A que está ativa acende; a que falta fica apagada, mas continua na lista —
   é assim que dá para ver o que ainda dá para comprar. */
.tip-bless-row.on { color: #e4ecec; background: #16201f; }
.tip-bless-row canvas { width: 20px; height: 20px; image-rendering: pixelated; opacity: .35; }
.tip-bless-row.on canvas { opacity: 1; }
.tip-bless-gap { width: 20px; height: 20px; flex: none; }
.tip-bless-row b { flex: 1; font-weight: 500; }
.tip-bless-tag {
  font-style: normal; font-size: 9px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--copper); border: 1px solid #ffffff14; border-radius: 999px; padding: 0 5px;
}
.tip-bless-row.on .tip-bless-tag { border-color: var(--copper); }
.tip-bless-mark { font-style: normal; font-size: 11px; width: 12px; text-align: center; color: #3d4a4a; }
.tip-bless-row.on .tip-bless-mark { color: var(--accent); }
.tip-bless-foot {
  margin: 0; padding: 7px 11px 9px; font-size: 10px; color: var(--muted);
  border-top: 1px solid var(--line);
}

/* As skills no hover da régua de experiência: ícone, nome, nível e a fração.
   Grade de quatro colunas para os números ficarem alinhados um debaixo do
   outro — em flex cada linha achava a sua própria posição e virava escada. */
.tip-skills {
  display: grid; grid-template-columns: auto 1fr auto auto;
  gap: 2px 8px; padding: 7px 11px; align-items: center;
}
.tip-skill { display: contents; }
.tip-skill img { width: 14px; height: 14px; object-fit: contain; image-rendering: pixelated; }
.tip-skill span { font-size: 11px; color: var(--muted); }
.tip-skill b { font-size: 11px; color: var(--text); font-weight: 600; text-align: right; }
.tip-skill em { font-style: normal; font-size: 10px; color: #55646a; text-align: right; min-width: 30px; }
.tip-exp-foot { padding: 7px 11px 9px; border-top: 1px solid var(--line); display: grid; gap: 2px; }
.tip-exp-foot p { margin: 0; font-size: 10px; color: var(--muted); }
.tip-exp-foot p.fraco { color: #55646a; }
.tip-bless-empty { margin: 0; padding: 9px 11px; font-size: 10px; color: var(--muted); }


/* ---------- as três placas da bolsa ---------- */

/*
 * Última palavra sobre os dois botões da bolsa.
 *
 * Eles tinham três blocos espalhados pela folha, escritos em batidas
 * diferentes, e os de baixo desfaziam a moldura dos de cima — `border-image`
 * ficava `none` porque um `border: 1px solid` mais adiante o apagava. Os três
 * viraram este.
 *
 * A moldura ornamentada é `border-image` e não uma imagem esticada: o botão é
 * quase quatro vezes mais largo do que alto e a arte é 2:1; esticada, os
 * rebites dos cantos virariam elipses. Em nove fatias os cantos ficam intactos
 * e só as bordas retas crescem.
 */
/*
 * `height` e não `min-height`: o filtro tem um sprite de 22px dentro e crescia
 * sozinho, ficando um degrau mais alto que a placa de venda ao lado.
 *
 * `margin: 0` nos DOIS. A venda herdava um `margin-top: 8px` de quando ela era
 * um botão largo sozinho no rodapé da bolsa, e o filtro não — com a mesma
 * altura, um começava oito pixels abaixo do outro.
 */
.bag-actions .autosell,
.bag-actions .loot-filter-button {
  height: 42px; margin: 0; padding: 0 6px; cursor: pointer;
  border-style: solid; border-radius: 0; background: none; box-shadow: none;
  border-image-repeat: stretch;
  transition: filter .15s ease;
}
.bag-actions .autosell {
  display: grid; align-content: center; text-align: center;
  /* 44/48 é onde o ornamento acaba na arte de 512px. A borda desenhada é bem
     menor: o ornamento encolhe junto e sobra como friso, que é o que cabe. */
  border-width: 11px 13px;
  border-image-slice: 44 48 fill;
}
.bag-actions .autosell.on { border-image-source: url(/client/assets/ui/auto-venda-on.png); }
.bag-actions .autosell.off { border-image-source: url(/client/assets/ui/auto-venda-off.png); }
.bag-actions .autosell b {
  font-family: var(--font-heading); font-size: 10px; letter-spacing: .04em; white-space: nowrap;
}
/* Escuro sobre o dourado, claro sobre o vermelho: cada placa pede o seu. */
.bag-actions .autosell.on b { color: #2a1d05; text-shadow: 0 1px 0 #ffe6a366; }
.bag-actions .autosell.off b { color: #ffe4e0; text-shadow: 0 1px 2px #00000088; }
.bag-actions .autosell em { display: none; }

/* O pulsar segue os pixels pintados, então contorna a placa e não a caixa. */
.bag-actions .autosell.on { animation: placa-ouro 2.2s ease-in-out infinite; }
.bag-actions .autosell.off { animation: placa-vermelha 2.2s ease-in-out infinite; }
@keyframes placa-ouro {
  0%, 100% { filter: drop-shadow(0 0 2px #d3a03855); }
  50% { filter: drop-shadow(0 0 7px #f0c95faa); }
}
@keyframes placa-vermelha {
  0%, 100% { filter: drop-shadow(0 0 2px #a83c3455); }
  50% { filter: drop-shadow(0 0 7px #e0655baa); }
}
.bag-actions .autosell:hover { animation: none; filter: brightness(1.12) drop-shadow(0 0 8px #f0c95fcc); }
.bag-actions .autosell.off:hover { filter: brightness(1.12) drop-shadow(0 0 8px #e0655bcc); }

.bag-actions .loot-filter-button {
  display: flex; align-items: center; justify-content: center; gap: 7px;
  font-size: 11px; color: #cfe0dd; margin: 0;
  /* A moldura desta é um friso fino de bronze com o fio de verdete, então a
     fatia é bem menor que a das placas de venda. */
  border-width: 9px 11px;
  border-image-slice: 16 18 fill;
  border-image-source: url(/client/assets/ui/loot-filter.png);
}
.bag-actions .loot-filter-button b {
  font-family: var(--font-heading); font-size: 10px; letter-spacing: .03em; color: #e4ecec; white-space: nowrap;
}
.bag-actions .loot-filter-button canvas { image-rendering: pixelated; }
.bag-actions .loot-filter-button:hover { filter: brightness(1.15) drop-shadow(0 0 7px #3fbfa899); }
.bag-actions .loot-filter-button:hover b { color: var(--accent); }
/* Com filtro montado ele fica aceso: é um estado, não um botão parado. */
.bag-actions .loot-filter-button:has(.count) { animation: placa-armada 2.6s ease-in-out infinite; }
@keyframes placa-armada {
  0%, 100% { filter: drop-shadow(0 0 2px #d9ae4a44); }
  50% { filter: drop-shadow(0 0 7px #d9ae4a99); }
}


/* ---------- prévia da hunt e cortina de viagem ---------- */

/*
 * A prévia em cima da escolha de modo: a cara do lugar e o que cai dele.
 * A arte é uma faixa baixa e larga, cortada com `cover` — ela ilustra, não é o
 * assunto, e alta demais empurraria os dois botões para fora da dobra.
 */
.hunt-previa { margin-bottom: 12px; }
/* 150 e não 120: a arte deixou de ser um enfeite de fundo e passou a mostrar a
   linha do percurso e as criaturas em cima dela — coisas que precisam de altura
   para dar para ver. */
.hunt-previa-arte {
  display: block; width: 100%; height: 190px; object-fit: cover;
  border: 1px solid var(--line); border-radius: 8px; margin-bottom: 9px;
}
/* Quantas voltas o personagem já fechou neste percurso. */
.hunt-previa-voltas {
  margin: 0 0 9px; font-size: 11px; color: var(--copper);
  font-family: var(--font-heading); letter-spacing: .04em;
}

/* Duas colunas: o que cai de um lado, quem mora lá do outro. Em tela estreita
   elas viram uma só — a coluna dos bichos tem texto e não sobrevive a 160px. */
.hunt-previa-colunas { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; align-items: start; }
@media (max-width: 900px), (max-height: 540px) and (pointer: coarse) {
  .hunt-previa-colunas { grid-template-columns: 1fr; }
}
.hunt-previa-bloco { display: grid; gap: 6px; align-content: start; min-width: 0; }
.hunt-previa-bloco > b {
  font-family: var(--font-heading); font-size: 10px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--muted);
}
.hunt-previa-bloco > em.words { font-size: 10px; color: #55646a; }

/* A lista de criaturas rola dentro de si: uma hunt de seis bichos com
   resistência em todos passava de trezentos pixels e empurrava os dois botões
   de modo para fora da dobra. */
.hunt-previa-bichos { display: grid; gap: 5px; max-height: 230px; overflow-y: auto; padding-right: 4px; }
.hunt-bicho {
  display: grid; grid-template-columns: 46px 1fr; gap: 8px; align-items: center;
  background: var(--panel-2); border: 1px solid var(--line-soft); border-radius: 6px; padding: 6px 8px;
}
.hunt-bicho canvas { image-rendering: pixelated; justify-self: center; }
.hunt-bicho-vazio { display: block; width: 40px; height: 40px; }
.hunt-bicho-texto { display: grid; gap: 2px; min-width: 0; }
.hunt-bicho-texto > b { font-size: 12px; color: #e7efef; }
.hunt-bicho-texto > em { font-style: normal; font-size: 10px; color: var(--muted); }
.hunt-bicho-el { display: flex; flex-wrap: wrap; gap: 3px; margin-top: 1px; }
.hunt-bicho-el span {
  font-size: 9px; padding: 1px 5px; border-radius: 999px; white-space: nowrap;
  background: #10171899; border: 1px solid #ffffff14;
}
/* Positivo é resistência (leva menos), negativo é fraqueza (leva mais). Sem a
   cor os dois números pareciam a mesma coisa. */
.hunt-bicho-el .resiste { color: #7fd8c4; border-color: #3fbfa844; }
.hunt-bicho-el .fraco { color: #e8a08a; border-color: #c0603a55; }

/*
 * A cortina de viagem cobre a tela inteira enquanto o mapa troca.
 *
 * `z-index` acima do modal (50) e da confirmação (55): ela sobe justamente
 * quando o modal de escolha ainda está fechando, e por baixo dele apareceria
 * cortada pela metade.
 */
#viagem {
  position: fixed; inset: 0; z-index: 70; display: grid; place-items: center;
  background: #040607f2;
  animation: viagem-entra .18s ease-out;
}
@keyframes viagem-entra { from { opacity: 0; } to { opacity: 1; } }
.viagem-caixa {
  width: min(520px, 84vw); display: grid; gap: 10px; justify-items: center; text-align: center;
  padding: 26px 30px 30px;
  border-style: solid; border-width: 36px 22px 24px 22px;
  border-image-source: url(/client/assets/ui/padrao.png);
  border-image-slice: 150 110 130 110 fill;
  border-image-repeat: stretch;
}
#viagem-arte {
  width: 100%; height: 168px; object-fit: cover;
  border: 1px solid var(--line); border-radius: 6px;
}
.viagem-caixa h2 {
  margin: 0; font-family: var(--font-title); font-size: 13px; font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase; color: var(--muted);
}
#viagem-hunt { font-family: var(--font-title); font-size: 24px; color: var(--accent); line-height: 1.1; }
.viagem-caixa em { font-style: normal; font-size: 11px; color: var(--muted); }

/* O trilho não mede nada: não há progresso para medir, o servidor responde de
   uma vez. Ele só diz que a coisa está andando — por isso uma faixa que
   atravessa, e não uma barra que enche até 100%, que seria mentira. */
.viagem-trilho {
  width: 100%; height: 4px; overflow: hidden; border-radius: 999px;
  background: #0d1214; border: 1px solid var(--line);
}
.viagem-trilho i {
  display: block; width: 38%; height: 100%; border-radius: 999px;
  background: linear-gradient(90deg, #3fbfa800, var(--accent), #3fbfa800);
  animation: viagem-corre 1.15s ease-in-out infinite;
}
@keyframes viagem-corre {
  0% { transform: translateX(-100%); }
  100% { transform: translateX(300%); }
}
@media (prefers-reduced-motion: reduce) {
  #viagem { animation: none; }
  .viagem-trilho i { animation: none; width: 100%; }
}


/* Título de seção da ficha com ícone à esquerda. O ícone é de 128px reduzido
   para 22 — sem `pixelated`, porque reduzir é onde o navegador acerta sozinho. */
.sheet-titulo { display: flex; align-items: center; gap: 8px; }
.sheet-titulo img { width: 26px; height: 26px; object-fit: contain; flex: none; }


/* Onde se digita, a seleção continua valendo — sem ela não dá nem para apagar
   uma palavra do meio do que foi escrito. */
input, textarea {
  user-select: text; -webkit-user-select: text;
}


/* Balão de texto puro: o que antes era `title` do navegador. Largura contida —
   o tooltip do ciclo tem cinco linhas e sem limite ele virava uma faixa. */
.tip-texto { max-width: 280px; }
.tip-texto-linhas { padding: 7px 11px 9px; display: grid; gap: 3px; }
.tip-texto-linhas p { margin: 0; font-size: 11px; color: #cfd8d8; }
.tip-texto-solo { margin: 0; padding: 8px 11px; font-size: 11px; color: #cfd8d8; }


/* O contador de voltas dentro do chip da roda do ciclo. */
.run-preview span i {
  font-style: normal; margin-left: 6px; font-size: 9px; color: var(--copper);
}


/* A barra de ferramentas do "o que cai aqui": escolhe o modo e sai clicando. */
.previa-pinceis { display: flex; gap: 4px; flex-wrap: wrap; }
.previa-pincel {
  padding: 3px 9px; cursor: pointer; font-size: 10px; border-radius: 999px;
  background: var(--panel-2); border: 1px solid var(--line); color: var(--muted);
}
.previa-pincel:hover { border-color: var(--accent-dim); color: var(--text); }
.previa-pincel[aria-selected="true"] { border-color: var(--accent); color: var(--accent); background: #16241f; }
.previa-pincel.sell[aria-selected="true"] { border-color: var(--copper); color: var(--copper); background: #241d12; }
.previa-pincel.loot[aria-selected="true"] { border-color: #a33; color: #ff8a7a; background: #2a1111; }
/* Com pincel na mão o cursor conta o que vai acontecer no clique. */
.filter-grid.pintando .cell { cursor: crosshair; }

.previa-pincel.zerar { margin-left: auto; }
.previa-pincel:disabled { opacity: .4; cursor: default; }
.previa-pincel.zerar:not(:disabled):hover { border-color: var(--danger); color: #ff8a7a; }


/*
 * Ícone desenhado por nós, dentro de um lugar feito para o recorte do client.
 *
 * Os `ui-icon` são de 9x9 e 12x12 e sobem para 18 — por isso a folha inteira
 * usa `pixelated`. Estes nascem em 128 e descem: com `pixelated` a redução
 * escolhe um pixel a cada sete e o desenho vira sujeira. E ganham dois pixels a
 * mais de caixa, porque agora há o que ver neles.
 */
.ui-icon.arte { image-rendering: auto; }
.skill-row .ui-icon.arte { width: 20px; height: 20px; }
/* No treino a arte e' o rosto do cartao, e nao um marcador de linha. */
.train-grid .ui-icon.arte { width: 26px; height: 26px; }
.element .ui-icon.arte { width: 20px; height: 20px; }
.tip-skill .ui-icon.arte { width: 16px; height: 16px; }


/* A ressalva embaixo do bônus total da ficha. */
.sheet-nota { margin: 6px 0 0; font-size: 10px; color: #55646a; line-height: 1.35; }

/* Cabecalho do bloco da prey dentro dos bonus de experiencia: ela fica FORA do
   total, porque so' vale contra a criatura dela. */
.rows .sheet-sub {
  margin: 10px 0 2px; padding-top: 8px;
  border-top: 1px solid rgba(255, 255, 255, 0.07);
  font-size: 10px; letter-spacing: 0.04em; text-transform: uppercase; color: #55646a;
}


/* A faixa de level do ciclo: dois campos e a ressalva. */
.run-faixa { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 4px 0 12px; }
.run-faixa label {
  display: flex; align-items: center; gap: 6px;
  font-family: var(--font-heading); font-size: 10px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--muted);
}
.run-faixa input {
  width: 64px; padding: 6px 8px; text-align: center;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 6px; color: var(--text);
}
.run-faixa input:focus { outline: none; border-color: var(--accent); }
.run-faixa em.words { font-size: 10px; color: #55646a; }
/* O modo escolhido acende, como qualquer par de opções do jogo. */
.run-mode.escolhido { border-color: var(--accent); background: #16241f; }


/* ---------- a ficha da criatura dentro da prévia da hunt ---------- */

/* Com mais de um bicho, uma fileira de retratos escolhe de quem é a ficha. */
.hunt-previa-abas { display: flex; gap: 5px; flex-wrap: wrap; }
.hunt-aba {
  display: grid; justify-items: center; gap: 2px; cursor: pointer; padding: 5px 7px;
  background: var(--panel-2); border: 1px solid var(--line-soft); border-radius: 7px;
}
.hunt-aba span { font-size: 9px; color: var(--muted); max-width: 74px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hunt-aba:hover { border-color: var(--accent-dim); }
.hunt-aba[aria-selected="true"] { border-color: var(--accent); background: #16241f; }
.hunt-aba[aria-selected="true"] span { color: var(--accent); }

/* A ficha rola dentro de si: seis estatísticas mais as resistências passam da
   altura da coluna, e sem isto empurravam os dois botões de modo para fora. */
.hunt-previa-ficha {
  display: grid; gap: 8px; max-height: 320px; overflow-y: auto; padding-right: 4px;
  background: var(--panel-2); border: 1px solid var(--line-soft); border-radius: 7px; padding: 9px 10px;
}
.hunt-previa-cabeca { display: flex; align-items: center; gap: 10px; }
.hunt-previa-cabeca .action-text { display: grid; gap: 1px; }
.hunt-previa-cabeca b { font-size: 13px; color: #e7efef; }
.hunt-previa-ficha h3 {
  margin: 2px 0 0; font-size: 10px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted);
}


/* ---------- os botões das telas de hunt e boss ---------- */

/*
 * Fonte de título nos dois. Eles são as duas saídas da tela — voltar ou entrar
 * — e em Segoe pareciam controles de formulário no meio de uma tela que é toda
 * do jogo.
 */
.confirm-actions button {
  font-family: var(--font-heading); font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase;
}

/*
 * "Enfrentar o boss" é o botão mais importante do jogo inteiro: dele sai uma
 * luta com cooldown de horas. Ele ganha a placa dourada com o facho correndo
 * pela borda — o mesmo `@property --store-angle` da Mineiroidle Store, porque uma luz
 * que ANDA o olho pega mesmo de canto, e um brilho parado sumia contra a
 * moldura da janela.
 */
.confirm-actions .enfrentar {
  position: relative; overflow: hidden;
  padding: 11px 26px; font-size: 13px; letter-spacing: .09em;
  color: #2a1d05; text-shadow: 0 1px 0 #ffe6a366;
  background: linear-gradient(180deg, #ffe4a0 0%, #f0cf7a 38%, #c79a3c 100%);
  border: 1px solid #ffe6a3; border-radius: 8px;
  box-shadow: 0 0 14px #d9ae4a55, inset 0 1px 0 #fff6d0, inset 0 -2px 6px #8a6a2144;
}
.confirm-actions .enfrentar:hover {
  background: linear-gradient(180deg, #fff2c8 0%, #ffe4a0 38%, #d9ae4a 100%);
  box-shadow: 0 0 22px #ffd980aa, inset 0 1px 0 #fff6d0, inset 0 -2px 6px #8a6a2144;
}
.confirm-actions .enfrentar:active { transform: translateY(1px); }

/* O anel de luz correndo pela borda. */
/* `inset: 0` e não `-2px`: o botão tem `overflow: hidden` por causa do lustro,
   e o anel para fora da caixa era cortado justamente nos cantos. */
.confirm-actions .enfrentar::before {
  content: ""; position: absolute; inset: 0; border-radius: 8px; padding: 2px; pointer-events: none;
  background: conic-gradient(from var(--store-angle), transparent 0%, #fff6d0 7%, #ffffff 11%, #fff6d0 15%, transparent 24%, transparent 100%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  animation: store-orbit 2.6s linear infinite;
}

/* E um lustro que atravessa a placa de tempos em tempos, como metal polido. */
.confirm-actions .enfrentar::after {
  content: ""; position: absolute; top: 0; bottom: 0; width: 40%; left: -60%; pointer-events: none;
  background: linear-gradient(105deg, #ffffff00, #ffffff66, #ffffff00);
  animation: enfrentar-lustro 3.4s ease-in-out infinite;
}
@keyframes enfrentar-lustro {
  0%, 62% { left: -60%; }
  86%, 100% { left: 120%; }
}
@media (prefers-reduced-motion: reduce) {
  .confirm-actions .enfrentar::before,
  .confirm-actions .enfrentar::after { animation: none; }
  .confirm-actions .enfrentar::after { opacity: 0; }
}

/* ---------- limpar a bolsa ---------- */

/*
 * O botão mora na linha da contagem de tipos, à direita do "20 / 20".
 *
 * Ele é destrutivo, então não pode parecer um dos interruptores dourados logo
 * abaixo: fica em tom de brasa apagada e só acende no hover, quando a intenção
 * já é dele. O tamanho é o do texto da linha — é um atalho, não uma decisão.
 */
/*
 * ---- E ele vale onde quer que o botão esteja ----
 *
 * O dono: "arrume esse botão Limpar que está branco, deixa vermelho".
 *
 * Era o `Limpar` de cada sacola do baú de boss. A regra pedia `.bagline`
 * ANTES, e a sacola não tem bagline nenhuma — a linha dela é o cabeçalho com o
 * nome do boss e o prazo. Sem a regra o navegador pintou o botão dele: branco,
 * de sistema, ao lado do "Levar tudo" verde. O estilo passou a ser da CLASSE,
 * que é o que ela sempre quis dizer: um "Limpar" é um "Limpar" onde estiver.
 */
.bag-clear {
  flex: none; padding: 2px 9px; cursor: pointer;
  font-family: var(--font-heading); font-size: 9px; font-weight: 600;
  letter-spacing: .07em; text-transform: uppercase;
  color: #c98a80; background: #2a141433; border: 1px solid #7a3a3466; border-radius: 5px;
  transition: color .12s ease, border-color .12s ease, background .12s ease;
}
/*
 * ---- O botão de vender, ao lado do de limpar ----
 *
 * Mesma forma do `bag-clear` — eles vivem lado a lado e disputariam a atenção
 * se fossem diferentes —, com a cor do ouro em vez da do descarte. É o que
 * separa os dois de relance: um tira da mochila para o lixo, o outro para o
 * bolso.
 */
.bag-sell { border-color: #6b5a2e88; color: #d8b45a; }
.bag-sell:hover:not(:disabled) { border-color: #c8a24a; color: #f0d488; }

/*
 * A peça que a venda em lote NÃO leva: tier, imbuement, estrela ou "não
 * vender". Ela continua na grade, apagada — some daí e o jogador iria procurá-la
 * sem achar. O balão diz o motivo.
 */
.filter-grid .venda-travada {
  opacity: .38;
  filter: grayscale(.7);
  cursor: not-allowed;
  border-style: dashed;
}

/*
 * ---- A grade da venda: o preço embaixo de cada quadradinho ----
 *
 * A coluna deixa de ser os 44px da célula porque agora ela carrega duas coisas
 * empilhadas. 52px é a célula mais a folga de que o número precisa para caber
 * sem reticências até "1.5kk" — acima disso o `money` já abrevia.
 */
.venda-grade { grid-template-columns: repeat(auto-fill, 52px); gap: 6px 4px; }
.venda-item {
  display: grid; justify-items: center; gap: 2px; cursor: pointer;
}
.venda-item.travada { cursor: not-allowed; }
.venda-preco {
  font-size: 9px; line-height: 1; letter-spacing: .02em; color: var(--muted);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
/* Marcada = vai virar ouro, e o número acende junto com a célula. */
.venda-item.marcada .venda-preco { color: var(--exp); font-weight: 700; }
.venda-item.travada .venda-preco { opacity: .4; }

.bag-clear:hover:not(:disabled) {
  color: #ffd9d6; border-color: var(--danger); background: #3a1a1a88;
}
.bag-clear:disabled { opacity: .35; cursor: default; }

/* Na confirmação, o que fica é verde e o que vai fora é vermelho — as mesmas
   duas cores que o filtro de loot já usa para "protegido" e "barrado". */
.confirm-actions button.danger {
  background: linear-gradient(180deg, #5a2420, #3a1614);
  border-color: #a3453c; color: #ffd9d6;
}
.confirm-actions button.danger:hover:not(:disabled) { filter: brightness(1.15); }
.confirm-actions button.danger:disabled { opacity: .4; cursor: default; filter: none; }
/* "Deixar caçando offline": laranja, entre o Cancelar e o Sair. */
.confirm-actions button.laranja {
  background: linear-gradient(180deg, #8a4a14, #5e300b);
  border-color: #d07a2a; color: #ffe6cc;
}
.confirm-actions button.laranja:hover:not(:disabled) { filter: brightness(1.15); }
.confirm-actions button.laranja:disabled { opacity: .35; cursor: default; filter: grayscale(.6); }

/*
 * A grade de drops rola em vez de crescer.
 *
 * Num ciclo de quinze hunts a lista somada passa de duzentos itens; sem teto
 * ela empurrava os botões de confirmar para fora da janela. Cinco fileiras é o
 * que cabe deixando a roda e as ações à vista ao mesmo tempo.
 */
.filter-grid.rolagem { max-height: 232px; overflow-y: auto; padding-right: 4px; }

/* Na tela do ciclo o bloco vem logo abaixo da fileira de hunts da roda, e
   coladinho nela o título parecia legenda da fileira. */
.run-preview + .hunt-previa-bloco { margin-top: 12px; }

/*
 * ---- Sem rolagem aninhada na prévia da hunt e na Caça Automática (02/10) ----
 *
 * A coluna "O que cai aqui" rolava dentro do modal e a grade ficava escondida
 * lá embaixo; a ficha do bicho e a grade de cards também tinham rolagem
 * própria. Agora só o modal rola. O bloco da venda automática nasce recolhido
 * (`<details>`), com a frase-resumo das regras; a grade vem logo abaixo.
 */
.hunt-previa .filter-grid.rolagem, .ciclo-modal .filter-grid.rolagem { max-height: none; overflow: visible; padding-right: 0; }
.hunt-previa .hunt-previa-ficha { max-height: none; overflow: visible; }
.ciclo-modal .ciclo-grade { max-height: none; overflow: visible; }
.hunt-bixo-espera { display: inline-block; }
.hunt-aba.filtrando { outline: 1px solid var(--accent); outline-offset: 1px; }
.previa-pincel.bicho-todos { justify-self: start; }
/* O card trancado: cadeado, level em vermelho, e o balão diz quanto falta. */
.ciclo-card.locked { opacity: .55; cursor: not-allowed; }
.ciclo-card.locked:hover { border-color: var(--line); }
.ciclo-cadeado { position: absolute; top: 4px; right: 6px; font-style: normal; font-size: 12px; }
.ciclo-level.trancado { color: var(--danger); }
.ciclo-card .ciclo-ganho { font-size: 9.5px; color: #b9c6ca; }
.ciclo-card .ciclo-ganho i { font-style: normal; color: var(--copper); }
/* Legibilidade: os cinzas pequenos destas telas sobem para AA (contraste ≥ 4,5:1 no painel escuro). */
.ciclo-card span { color: #a9b8bd; }
.hunt-previa-bloco > b, .hunt-previa-ficha h3 { color: #a9b8bd; }
.hunt-previa-bloco > em.words { color: #9fb0b5; }
.hunt-previa .bestiary-stat em, .hunt-previa .bestiary-element em { color: #b3c1c6; }
.hunt-previa .filtro-afixo-gaveta > summary { color: #d6dfe2; }

/* ---------- rodapé preso das telas de hunt, ciclo e boss ---------- */

/*
 * Os botões de decisão não podem depender de rolagem.
 *
 * A prévia da hunt tem foto, todo o loot e a ficha do bicho: medida numa tela
 * de 848px de altura, ela passava 133px do fundo e "Só esta hunt", "Ciclo de
 * hunts" e "Voltar" ficavam abaixo da dobra. Preso no pé do corpo do modal, o
 * rodapé fica sempre à vista e quem rola é a prévia acima dele.
 *
 * O fundo é sólido e a sombra sobe: sem isso o loot passa por baixo dos botões
 * enquanto rola e vira uma sopa de ícones atrás do texto.
 */
.modal-rodape {
  position: sticky; bottom: -14px; z-index: 4;
  display: grid; gap: 8px;
  margin: 4px -14px -14px; padding: 10px 14px 14px;
  background: var(--panel-solid, #10171a);
  box-shadow: 0 -10px 16px -6px #000a;
}
.modal-rodape > .gate-note { margin: 0; }
.modal-rodape > .confirm-actions { margin: 0; }

/* ---------- prévia da hunt mais compacta ---------- */

/*
 * A foto perde 50px e a ficha do bicho encolhe junto.
 *
 * Tudo aqui é para caber sem rolagem numa tela de notebook: a foto continua
 * mostrando o percurso, os quadradinhos de vida/exp/armadura passam a caber
 * quatro por linha em vez de três, e as resistências viram fichas miúdas — são
 * doze delas em algumas criaturas, e a 24px de ícone tomavam duas fileiras
 * inteiras.
 */
.hunt-previa-arte { height: 96px; margin-bottom: 6px; }

/*
 * Cinco colunas fixas, e não `auto-fill`.
 *
 * O `auto-fill` media a largura disponível e escolhia quatro, jogando o quinto
 * quadradinho — pontos de charm — para uma segunda fileira de 46px que só
 * existia para ele. Cinco de propósito cabem na coluna da ficha e economizam
 * essa fileira inteira, que é o que faltava para a tela fechar sem rolagem.
 */
.hunt-previa .bestiary-stats { grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 4px; }
/*
 * Aqui o quadradinho é de pé: desenho em cima, número e rótulo embaixo.
 *
 * Deitado, o rótulo dividia a largura com o ícone e sobravam uns quarenta
 * pixels — "experiência" quebrava em "experiên / cia" e "armadura" em
 * "armadur / a". De pé, o rótulo tem a coluna inteira e cabe numa linha só, e
 * os cinco continuam numa fileira.
 */
.hunt-previa .bestiary-stat {
  grid-template-columns: 1fr; gap: 1px; padding: 6px 4px;
  justify-items: center; text-align: center;
}
.hunt-previa .bestiary-stat .bestiary-art { grid-row: auto; width: 20px; height: 20px; }
.hunt-previa .bestiary-stat .bestiary-art.antiga { width: 16px; height: 16px; }
.hunt-previa .bestiary-stat b { font-size: 12px; align-self: auto; }
.hunt-previa .bestiary-stat em { font-size: 9px; align-self: auto; line-height: 1.1; }

.hunt-previa .bestiary-elements { gap: 4px; }
.hunt-previa .bestiary-element { gap: 4px; padding: 3px 6px; font-size: 11px; }
.hunt-previa .bestiary-element .bestiary-art { width: 18px; height: 18px; }
.hunt-previa .bestiary-element .bestiary-art.antiga { width: 14px; height: 14px; }

/*
 * ---- A grade de drops toma a folga da janela ----
 *
 * Ela tinha 150px cravados — tres fileiras — e rolava dentro disso mesmo quando
 * sobrava meia janela vazia embaixo. Numa hunt de setenta drops isso e' rolar
 * vinte fileiras dentro de um postigo de tres, com o vazio logo abaixo olhando.
 *
 * O encadeamento e' o mesmo que a Mineiroidle Store ja' usa (`.modal-box.store`): o
 * corpo do modal vira coluna flexivel, a previa toma a sobra dele, as duas
 * colunas tomam a sobra da previa, e a grade toma a sobra da coluna dela. O
 * rodape com os dois modos continua colado no pe, porque e' irmao da previa e
 * nao cresce.
 *
 * E ela so' rola quando acaba o espaco, que era o pedido: sem folga na janela
 * (hunt pequena, tela baixa), `flex` nao tem o que distribuir e a grade fica do
 * tamanho do que tem dentro. As 132 casas de piso sao para a grade nao sumir
 * numa tela muito baixa — abaixo disso o modal inteiro ja' esta' rolando.
 */
.modal-box:has(.hunt-previa) #modal-body { display: flex; flex-direction: column; flex: 1; min-height: 0; }
.modal-box:has(.hunt-previa) .hunt-previa { display: flex; flex-direction: column; flex: 1; min-height: 0; }
.modal-box:has(.hunt-previa) .hunt-previa-colunas { flex: 1; min-height: 0; align-items: stretch; }
.modal-box:has(.hunt-previa) .hunt-previa-colunas > .hunt-previa-bloco {
  display: flex; flex-direction: column; min-height: 0;
}
/*
 * Quem rola e' a GRADE, e nao a janela.
 *
 * A primeira tentativa deixou a grade crescer sem limite e mandou a rolagem
 * para o modal inteiro. Duas coisas quebraram: a fileira de baixo do loot ficou
 * atras do rodape de "parar em" (ele e' `sticky`, entao ele passa por cima), e a
 * unica pista de que havia mais loot passou a ser a barra do modal la' na borda
 * — longe demais da grade para alguem ligar uma coisa a' outra.
 *
 * Agora a grade cresce ate' onde o espaco deixa e rola dentro de si a partir
 * dali, que e' o que ela sempre fez: o que mudou e' que ela deixou de ter tres
 * fileiras cravadas e passou a usar a folga da janela. A barra de rolagem fica
 * encostada nela, e nada dela passa por baixo do rodape.
 */
.modal-box:has(.hunt-previa) .hunt-previa .filter-grid.rolagem {
  flex: 1 1 auto; max-height: none; min-height: 96px;
}
/*
 * A ficha do bicho rola dentro da coluna dela pelo mesmo motivo: sem isto, a
 * coluna da direita e' que estourava a janela, e a fileira de resistencias
 * saia cortada pelo rodape.
 */
.modal-box:has(.hunt-previa) .hunt-previa-ficha { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding-right: 4px; }

/* Sem o `:has` (navegador antigo), continua valendo o postigo de antes. */
@supports not selector(:has(*)) {
  .hunt-previa .filter-grid.rolagem { max-height: 150px; }
}
/*
 * ---- 02/10: só o MODAL rola ----
 *
 * O arranjo flex acima fazia a grade de loot e a ficha do bicho rolarem cada
 * uma dentro da própria coluna, para os botões de modo ficarem sempre à vista.
 * O preço era a grade escondida lá embaixo de um postigo de 150px. Agora o
 * corpo volta a ser um bloco comum: a página do modal rola inteira, a grade
 * e a ficha crescem até o fim, e os botões de modo ficam no pé do conteúdo.
 */
.modal-box:has(.hunt-previa) #modal-body { display: block; overflow-y: auto; }
.modal-box:has(.hunt-previa) .hunt-previa { display: block; }
.modal-box:has(.hunt-previa) .hunt-previa-colunas { display: grid; align-items: start; }
.modal-box:has(.hunt-previa) .hunt-previa-colunas > .hunt-previa-bloco { display: grid; }
.modal-box:has(.hunt-previa) .hunt-previa .filter-grid.rolagem { flex: none; max-height: none; min-height: 0; overflow: visible; padding-right: 0; }
.modal-box:has(.hunt-previa) .hunt-previa-ficha { flex: none; max-height: none; overflow: visible; padding-right: 10px; }
@supports not selector(:has(*)) {
  .hunt-previa .filter-grid.rolagem { max-height: none; overflow: visible; }
}
/* E o rodapé com os dois modos deixa de ser grudado: ele vem depois do conteúdo, sem cobrir a última fileira do loot. */
.modal-box:has(.hunt-previa) .modal-rodape { position: static; margin: 12px 0 0; box-shadow: none; border-top: 1px solid var(--line-soft); }

/* Os retratos que escolhem de quem é a ficha: 6px a menos cada, e com duas ou
   três criaturas isso já é a diferença entre caber e rolar. */
.hunt-previa .hunt-previa-abas .hunt-bixo { transform: scale(.88); transform-origin: center bottom; }
.hunt-previa .hunt-aba { padding-top: 2px; padding-bottom: 2px; }
.hunt-previa-colunas { gap: 10px; }
.hunt-previa-voltas { margin: 0 0 6px; }

/* ---------- controles da barra de ações ---------- */

/*
 * No canto de cima à direita, e fora do fluxo.
 *
 * `absolute` de propósito: entrando na fileira, os dois botões empurrariam os
 * slots e a barra ficaria mais larga — e o pedido era justamente não mexer no
 * tamanho. Sobrepostos ali, eles caem no cantinho vazio acima do "distância do
 * alvo", que não tem nada.
 */
.bar-controls {
  position: absolute; top: 4px; right: 6px; z-index: 3;
  display: flex; gap: 3px;
}
.bar-controls button {
  width: 18px; height: 18px; padding: 0; line-height: 1; cursor: pointer;
  font-size: 10px; color: var(--muted);
  background: #0d1214cc; border: 1px solid var(--line); border-radius: 4px;
}
.bar-controls button:hover { color: var(--accent); border-color: var(--accent-dim); }

/* O menu da engrenagem abre para cima: a barra mora no rodapé. */
.bar-menu {
  position: absolute; bottom: calc(100% + 8px); right: 0; z-index: 40;
  min-width: 250px; display: grid; gap: 4px; padding: 6px;
  background: #10171af5; border: 1px solid var(--line); border-radius: 8px;
  box-shadow: 0 12px 30px #000a;
}
.bar-menu button {
  width: 100%; text-align: left; cursor: pointer; font-size: 11px; padding: 7px 9px;
  color: #cfe0dd; background: none; border: 1px solid transparent; border-radius: 6px;
}
.bar-menu button:hover { border-color: var(--accent-dim); background: #16241f; color: var(--accent); }

/* A âncora dos dois é a barra inteira, não a coluna da esquerda. */
#actionbar { position: fixed; }
/*
 * Sem `align-self`: a coluna estica com a fileira e o `justify-content:
 * flex-start` dela põe o Hunts no TOPO, na altura da primeira fileira de slots.
 *
 * Havia um `align-self: flex-end` aqui, de quando esta coluna era só o "+
 * salvar" e o certo era ele ficar na quina de baixo. Com o Hunts dentro, ele
 * prendia o botão mais clicado da barra no canto mais baixo dela.
 */
.bar-side { position: relative; }

/*
 * Minimizada: some tudo menos os dois controles.
 *
 * `display: none` e não `visibility`, porque a barra tem largura `max-content`
 * — escondendo sem tirar do fluxo, a fita continuaria com a largura dos doze
 * slots e o "minimizar" não teria minimizado nada.
 */
#actionbar.minimizada .hotbar-stack,
#actionbar.minimizada .controls label,
#actionbar.minimizada #hud-bars-dock { display: none; }
/* O Hunts saiu de `.controls` e foi para a coluna das réguas, então a regra que
   o escondia junto com elas deixou de alcançá-lo. A nota logo abaixo explica
   por que ele some ao recolher; ela continua valendo. */
#actionbar.minimizada #leave-hunt { display: none; }
/* Voltaram a ser filhos do rodapé, então o seletor de descendente os alcança
   de novo — o `:has` que precisou existir enquanto eles flutuavam saiu. */
#actionbar.minimizada #hotbar-presets { display: none; }
/* Recolhida, a barra é uma fita curta: os controles voltam para o fluxo, senão
   ficariam sobrepostos ao próprio Hunts. */
/* Recolhida ela é uma fita deitada: os dois controles e o Stop lado a lado. O
   rodapé é uma coluna quando aberto, e mantê-lo assim empilhava os controles
   ACIMA do Stop — a fita ficava mais alta recolhida do que aberta. */
#actionbar.minimizada {
  flex-direction: row; align-items: center; gap: 8px; padding: 4px 8px;
  /*
   * Recolhida, a fita volta ao MEIO da tela.
   *
   * O `--desloca-barra` existe para pôr a FILEIRA DE SLOTS no meio, e não a
   * barra — ela é assimétrica, e centrá-la deixava os slots à esquerda do
   * personagem. Recolhida não há fileira nenhuma: os slots estão em
   * `display: none`, e o deslocamento medido para eles empurrava a fitinha
   * para o canto, sem nada que o justificasse.
   *
   * Sem o deslocamento ela é só uma caixa pequena centrada, que é o que se
   * espera de algo minimizado no rodapé.
   */
  transform: translateX(-50%);
}
/*
 * Recolhida sobra a seta, e ela fica DEPOIS do Stop.
 *
 * A engrenagem some: o que ela abre são ajustes da barra, e com a barra
 * escondida não há barra para ajustar. E a seta vai para a direita do Stop
 * porque é assim que a fita fica menor — dois botões antes do Stop empurravam
 * a placa para o meio e a fita ficava com cara de barra pequena em vez de
 * botão solto.
 */
#actionbar.minimizada .bar-controls { position: static; order: 2; }
#actionbar.minimizada #bar-gear { display: none; }
#actionbar.minimizada .bar-row { align-items: center; }
/*
 * ---- O Hunts/Stop recolhe junto ----
 *
 * Ele ficava, e a razão era boa: escondendo a fileira de controles inteira, o
 * botão que começa e para a caçada sumia com ela, e com ele o único caminho
 * para escolher hunt. Recolher a barra não podia trancar o jogo.
 *
 * Só que a seta continua ali — recolher tem volta, e um clique devolve o botão.
 * Com a placa ficando, "minimizar" deixava na tela a coisa MAIS alta da barra:
 * a fita recolhida tinha quase a altura da barra aberta, e o gesto não
 * entregava o que promete.
 *
 * Então some também. O que sobra encostado no rodapé é a seta, e nada mais.
 */
#actionbar.minimizada .controls,
#actionbar.minimizada .controls-row { display: none; }
/*
 * 15/09: recolhida sobra SÓ a setinha, no centro — sem a fita escura em volta
 * (pedido do dono: "ao invés de ter essa barra toda, teria só uma setinha no
 * centro").
 */
#actionbar.minimizada {
  background: none !important; border-color: transparent !important; box-shadow: none !important;
  padding: 0 !important; gap: 0; overflow: visible;
}
#actionbar.minimizada::before, #actionbar.minimizada::after { display: none !important; }
#actionbar.minimizada > :not(.bar-controls) { display: none !important; }
#actionbar.minimizada #bar-min {
  width: 34px; height: 16px; margin-bottom: 2px; font-size: 9px; color: #f0c27a;
  background: linear-gradient(180deg, #2a2418, #121517); border: 1px solid #8a6a35;
  border-bottom: none; border-radius: 8px 8px 0 0; box-shadow: 0 -2px 8px #0008;
}
#actionbar.minimizada #bar-min:hover { color: #ffe2a8; border-color: #d9a441; }
/* O botão da ficha: o desenho novo, e a seta virada quando a ficha já está no canto. */
#bar-gear svg { width: 12px; height: 12px; }
#bar-gear.ficha-no-canto svg { transform: rotate(180deg); }

/* A hora de cada linha do chat: presente, e fora do caminho da leitura. */
.chat-log .hora {
  margin-right: 5px; font-variant-numeric: tabular-nums;
  font-size: 10px; color: #5f7076;
}

/* ---------- conexão perdida ---------- */

#reconectando {
  position: fixed; top: 70px; left: 50%; transform: translateX(-50%); z-index: 90;
  width: max-content; max-width: calc(100vw - 32px);
  display: grid; gap: 4px; justify-items: center; padding: 9px 18px 11px;
  background: #2a1414f2; border: 1px solid #a3453c; border-radius: 9px;
  box-shadow: 0 10px 28px #000a;
}
#reconectando b {
  font-family: var(--font-heading); font-size: 12px; letter-spacing: .06em;
  text-transform: uppercase; color: #ff9a8e;
}
#reconectando span { font-size: 11px; color: #d8b0a8; }

/* Barra indeterminada: um facho que atravessa. Ninguém sabe quanto falta, e uma
   barra que enchesse até 100% prometeria uma previsão que não existe. */
.reconectando-barra {
  width: 220px; height: 4px; margin-top: 3px; overflow: hidden;
  background: #00000055; border-radius: 3px;
}
.reconectando-barra i {
  display: block; width: 40%; height: 100%; border-radius: 3px;
  background: linear-gradient(90deg, #a3453c00, #ff9a8e, #a3453c00);
  animation: reconectando-vai 1.1s ease-in-out infinite;
}
@keyframes reconectando-vai {
  0% { transform: translateX(-110%); }
  100% { transform: translateX(260%); }
}
@media (prefers-reduced-motion: reduce) {
  .reconectando-barra i { animation: none; width: 100%; opacity: .6; }
}

/* ---------- extrato de itens no relatório da caçada ---------- */

.relatorio-itens { display: grid; gap: 10px; margin-top: 12px; }
.relatorio-grupo { display: grid; gap: 5px; }
.relatorio-cabeca { display: flex; align-items: baseline; gap: 8px; cursor: help; }
.relatorio-cabeca b {
  font-family: var(--font-heading); font-size: 11px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--accent);
}
.relatorio-cabeca span { font-size: 10px; color: var(--muted); }
/* Três fileiras e rola: uma caçada longa junta quarenta tipos, e a lista
   inteira empurraria o OK para fora da janela. */
.relatorio-itens .filter-grid.rolagem { max-height: 118px; }

/* O OK no meio do pé: é a única saída da tela, e fica onde o olho já está. */
.relatorio-ok { display: flex; justify-content: center; margin-top: 14px; }
.relatorio-ok button {
  min-width: 130px; padding: 9px 26px; cursor: pointer;
  font-family: var(--font-heading); font-weight: 600; font-size: 12px;
  letter-spacing: .1em; text-transform: uppercase;
  /* A classe `primary` só tem cor dentro do portão e do formulário de
     transferência; solto aqui, o botão saía branco do navegador. */
  background: linear-gradient(180deg, var(--accent-dim), #1f5f54);
  border: 1px solid var(--accent-dim); border-radius: 6px; color: #eafffb;
}
.relatorio-ok button:hover { filter: brightness(1.15); }

/* ---------- montar o ciclo: um card por hunt ---------- */

.ciclo-grade {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(126px, 1fr)); gap: 7px;
  max-height: 264px; overflow-y: auto; padding: 2px 4px 2px 2px; margin-bottom: 10px;
}
.ciclo-card {
  position: relative; display: grid; gap: 2px; justify-items: center; text-align: center;
  padding: 8px 6px 7px; cursor: pointer;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px;
  transition: border-color .12s ease, background .12s ease;
}
.ciclo-card:hover:not(:disabled) { border-color: var(--accent-dim); }
.ciclo-card:disabled { opacity: .35; cursor: default; }
.ciclo-card.escolhido { border-color: var(--accent); background: #16241f; }
.ciclo-card b { font-size: 11px; color: #e7efef; line-height: 1.2; }
.ciclo-card span { font-size: 9px; color: var(--muted); }
.ciclo-bichos { display: flex; gap: 2px; align-items: flex-end; min-height: 32px; }

/* O número da ordem no canto: a roda é percorrida nessa sequência, e sem ele
   dois cards marcados seriam indistinguíveis. */
.ciclo-ordem {
  position: absolute; top: -6px; left: -6px; z-index: 2;
  display: grid; place-items: center; width: 19px; height: 19px;
  font-style: normal; font-size: 10px; font-weight: 700; color: #10171a;
  background: var(--accent); border-radius: 50%;
  box-shadow: 0 2px 6px #000a;
}

/* ---------- comprar a coleção inteira ---------- */

.store-lote {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  width: 100%; margin-bottom: 8px; padding: 9px 13px; cursor: pointer; text-align: left;
  background: linear-gradient(180deg, #2a2210, var(--panel-solid));
  border: 1px solid var(--gold-dim); border-radius: 8px;
}
.store-lote b {
  font-family: var(--font-heading); font-size: 12px; letter-spacing: .04em; color: #ffe4a0;
}
.store-lote span { font-size: 11px; color: var(--copper); white-space: nowrap; }
.store-lote:hover { filter: brightness(1.12); }
/* Sem coins para o lote inteiro: continua clicável — o servidor responde
   dizendo quanto falta, que é a informação que o jogador quer. */
.store-lote.curto { opacity: .6; border-color: var(--line); }
.store-lote.curto b { color: var(--muted); }

/* ---------- o ofício de cada slot da barra ---------- */

/*
 * O desenho fica no canto de cima do slot, do lado oposto ao número da tecla.
 * Pequeno e um pouco apagado: ele é a legenda do lugar, não o conteúdo dele —
 * quem tem de saltar aos olhos é o sprite da magia.
 */
.hotbar .slot .papel {
  position: absolute; top: 2px; left: 2px; z-index: 2;
  width: 13px; height: 13px; image-rendering: pixelated;
  opacity: .75; pointer-events: none;
  filter: drop-shadow(0 1px 1px #000c);
}
.hotbar .slot:hover .papel { opacity: 1; }
/* Slot vazio: o desenho do ofício é a única coisa ali, então cresce. */
.hotbar .slot:not(.filled) .papel { width: 16px; height: 16px; opacity: .55; }

/* ---- Condições de parada, na tela de antes de entrar na hunt ---- */
.run-paradas {
  margin: 0 0 10px; padding: 8px 10px;
  border: 1px solid rgba(255, 255, 255, 0.08); border-radius: 8px;
  background: rgba(0, 0, 0, 0.18);
}
.run-paradas-titulo {
  font-size: 10px; letter-spacing: 0.04em; text-transform: uppercase;
  color: #55646a; margin-bottom: 6px;
}
/* As quatro condicoes numa fileira; duas colunas em tela apertada. */
/* O layout desta fileira está mais abaixo, em "as condições de parada". */
.run-parada {
  display: flex; align-items: center; gap: 6px;
  padding: 3px 0; font-size: 12px; color: var(--muted); cursor: pointer; min-width: 0;
}
.run-parada.on { color: var(--text); }
.run-parada input[type='checkbox'] { accent-color: var(--accent); cursor: pointer; }
.run-parada-nome { flex: 1; }
.run-parada input[type='number'] {
  width: 100%; min-width: 46px; max-width: 88px; padding: 3px 6px; text-align: right;
  border: 1px solid rgba(255, 255, 255, 0.12); border-radius: 5px;
  background: rgba(0, 0, 0, 0.35); color: var(--text); font: inherit;
}
.run-parada input[type='number']:disabled { opacity: 0.35; }
.run-parada-unidade { width: 30px; font-size: 10px; color: #55646a; font-style: normal; }
.run-paradas-resumo { margin: 6px 0 0; font-size: 10px; color: #55646a; }
.run-paradas-nota { margin: 3px 0 0; font-size: 10px; color: var(--accent); line-height: 1.35; }

/* O seletor de lure conta a leva em voz alta enquanto ele junta. */
.controls label.lurando { color: var(--accent); }
/*
 * Os dois seletores do lure, lado a lado dentro da mesma célula do rótulo.
 * O segundo é menor de propósito: ele é a nota de rodapé do primeiro, e dar o
 * mesmo peso aos dois faria a fileira parecer ter ganhado um controle novo.
 */
/* A mesma grade da `.controls`, com o mesmo vão: é isso que faz as caixas de
   baixo caírem sob as de cima. */
.lure-dupla { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 5px; }
/* O ponto que separava os dois seletores não faz mais falta: quem os separa
   agora é a coluna da grade. Some sempre — o JS ainda o esconde e o mostra
   junto com o "voltar", e isso continua sem efeito nenhum. */
.lure-dupla .lure-sep { display: none; }
/* Sem estilo próprio: ele é uma das quatro caixas e usa o tamanho das outras.
   Tinha enchimento e opacidade só dele, de quando vivia espremido ao lado do
   irmão. */
.lure-dupla #lure-volta { opacity: .85; }
.lure-dupla #lure-volta:hover { opacity: 1; }

/* A faixa verde da stamina: acima de 39h com premium, 1,5x de experiência. */
.hud-bar.stamina[data-grau="verde"] i { --liq-a: #9df5b8; --liq-b: #1c9c52; }
#dot-stamina[data-grau="verde"] { background: #35d17a; }

/* ---- Lista de amigos (a VIP list) ---- */
.amigos-topo { display: flex; gap: 8px; margin-bottom: 10px; }
.amigos-topo .search { flex: 1; margin: 0; }
.amigos-lista { display: flex; flex-direction: column; gap: 2px; }
.amigo {
  display: flex; align-items: center; gap: 10px;
  padding: 6px 8px; border-radius: 6px; background: rgba(0, 0, 0, 0.18);
}
.amigo:hover { background: rgba(255, 255, 255, 0.05); }
.amigo-ponto {
  width: 8px; height: 8px; border-radius: 50%; flex: none;
  background: #55646a; box-shadow: none;
}
.amigo.on .amigo-ponto { background: #35d17a; box-shadow: 0 0 6px #35d17a88; }
.amigo-meio { flex: 1; display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.amigo-meio b { font-size: 13px; color: var(--muted); }
.amigo.on .amigo-meio b { color: var(--text); }
.amigo-meio span { font-size: 10px; color: #55646a; }
.amigo-tirar { padding: 2px 8px; font-size: 12px; opacity: 0.5; }
.amigo:hover .amigo-tirar { opacity: 1; }

/* A Caça Online se distingue: é o modo em que o teclado manda. */
.run-mode.manual { border-color: rgba(63, 191, 168, 0.35); }
.run-mode.manual:hover:not(:disabled) { border-color: var(--accent); }

/* A faixa de ajuda do modo manual: uma linha da própria pilha da barra, e não
   uma etiqueta flutuando por cima — solta, ela era cortada pelo rodapé. */
.manual-dica {
  justify-self: center; padding: 3px 12px;
  border: 1px solid rgba(63, 191, 168, 0.3); border-radius: 6px;
  background: rgba(8, 14, 16, 0.92); color: var(--accent);
  font-size: 10px; letter-spacing: 0.03em; white-space: nowrap; pointer-events: none;
}

/* ---- Convite para caçar junto ---- */
/*
 * ---- O convite fica no MEIO, logo acima da barra ----
 *
 * Ele morava no canto direito, na altura da bolsa de loot e do analisador — e
 * ali ele era só mais uma caixa entre as caixas. Um convite tem prazo: quem não
 * o vê nos primeiros segundos responde tarde ou não responde.
 *
 * No centro, acima da barra de habilidade, ele cai onde os olhos já estão
 * durante uma caçada. E continua sem escurecer a tela nem prender o teclado:
 * quem está no meio de uma luta continua jogando com ele aberto — um convite
 * que impede de jogar mata o personagem de quem recebeu.
 *
 * A altura é 176 e não 118 porque o presente de nível (`#presente`) já ocupa o
 * 118 centralizado: subir para 118 faria os dois se sobreporem justamente
 * quando os dois importam — subir de level no meio de uma caçada em grupo.
 */
.convite {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: calc(var(--barra-altura, 69px) + 107px); z-index: 60;
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 10px 16px; min-width: 260px;
  border: 1px solid var(--accent); border-radius: 10px;
  background: rgba(8, 14, 16, 0.96);
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.55);
  text-align: center;
}
.convite b { font-size: 13px; color: var(--text); }
.convite span { font-size: 12px; color: var(--accent); }
.convite em { font-size: 10px; color: #55646a; font-style: normal; }
.convite-acoes { display: flex; gap: 8px; margin-top: 8px; align-self: stretch; }
.convite-acoes button { flex: 1; }

/* A lista de quem vai junto, na tela de antes de entrar. */
.run-amigos .run-parada-unidade { width: auto; }

/* O quadro do grupo, acima da barra de ações. */
.grupo-caixa {
  justify-self: center; display: flex; align-items: center; gap: 10px;
  padding: 3px 12px; border: 1px solid rgba(63, 191, 168, 0.3); border-radius: 6px;
  background: rgba(8, 14, 16, 0.92); font-size: 10px;
}
.grupo-caixa b { color: var(--text); font-size: 11px; }
.grupo-caixa span { color: var(--accent); }
.grupo-caixa.off { border-color: rgba(200, 80, 60, 0.4); }
.grupo-caixa.off span { color: #d97a63; }
.grupo-caixa em { color: #55646a; font-style: normal; }
.grupo-caixa button { padding: 1px 8px; font-size: 10px; }

/*
 * ---- O escudo da party ----
 *
 * Amarelo é líder, azul é membro, e a marca no meio diz se a Shared Experience
 * está valendo — as mesmas quatro figuras do cliente do Tibia. Ele é pequeno de
 * propósito: fica ao lado do nome sem empurrar nada, e é a cor que se reconhece
 * de relance, não o desenho.
 */
/*
 * O sprite tem 11x11 e é pixel art: `pixelated` mantém a borda dura em telas
 * com escala, que é o que faz ele parecer o do cliente e não uma figura borrada.
 */
.party-escudo { width: 11px; height: 11px; flex: 0 0 auto; display: block; image-rendering: pixelated; }
/*
 * O escudo de quem derrubou a partilha pisca — o `_NOSHAREDEXP_BLINK` da base.
 * Meio segundo aceso, meio apagado, o mesmo ritmo do cliente do Tibia.
 */
.party-escudo.piscando { animation: escudo-pisca 1s steps(1, end) infinite; }
@keyframes escudo-pisca { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0.12; } }
.grupo-estado { display: inline-flex; align-items: center; gap: 5px; }
.grupo-estado i { font-style: normal; }

/* O seletor de distância do líder, ao lado de "Sair do grupo". */
.grupo-coleira { display: inline-flex; align-items: center; gap: 4px; color: #55646a; }
.grupo-coleira select {
  padding: 1px 4px; font-size: 10px; font-family: inherit;
  color: var(--text); background: var(--panel-2);
  border: 1px solid var(--line-soft); border-radius: 4px;
}

/* ---- Legenda dos dois botões do mouse no filtro de loot ---- */
/*
 * A legenda não pode parecer uma caixa de seleção.
 *
 * O quadrado era só contorno, do tamanho de um checkbox e ao lado de um texto —
 * lia-se como "marque aqui", e não como "é assim que o item fica". Agora ele é
 * um quadradinho preenchido de escuro com o contorno colorido: a mesma cara que
 * a célula do item ganha quando é marcada.
 */
/*
 * ---- Até onde a estrela salva a peça da venda automática ----
 *
 * Quatro botões numa fileira, com a estrela de cada degrau na cor dele. A cor
 * é o rótulo de verdade: quem já viu uma estrela roxa numa peça não precisa de
 * legenda para saber o que "roxa para cima" guarda. Ver `escolhaDeAfixo`.
 */
/* O selo do afixo na linha do balcão, no mesmo tom das outras marcas. */
.balcao-afixo { display: inline-flex; align-items: center; gap: 5px; }
/* `:not(.estrela)` porque o selo do afixo mora aqui dentro e tem cor própria. */
.balcao-afixo b:not(.estrela) { font-weight: 500; font-size: 10px; color: var(--muted); }

.filtro-afixo { margin: 8px 0 10px; }
/* O "Apenas o que NPC compra" no cabeçalho da grade de loot, entre o título e a
   contagem: empurra a contagem para a ponta e fica do tamanho de uma etiqueta. */
.filter-head .filter-head-npc { margin-left: auto; margin-right: 8px; padding: 1px 9px; font-size: 11px; }
/*
 * Afixo e raridade lado a lado, separados por um fio — o espaço vazio à direita
 * da regra do afixo era onde o dono pediu a raridade. Abaixo de 760px as duas
 * empilham: lado a lado, cada coluna ficaria estreita demais para os botões.
 */
.filtro-venda-regras {
  /* O afixo leva mais: os quatro botões da cor precisam caber numa fileira. */
  display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); gap: 0 18px;
  align-items: start;
}
.filtro-venda-regras > .filtro-raridade { border-left: 1px solid var(--line); padding-left: 16px; }
@media (max-width: 760px) {
  .filtro-venda-regras { grid-template-columns: minmax(0, 1fr); }
  .filtro-venda-regras > .filtro-raridade { border-left: 0; padding-left: 0; }
}
/* O rótulo do botão sai na cor da raridade dele, e o aceso ganha a borda dela. */
.filtro-afixo-opcao.com-raridade > span { color: var(--tier); }
.filtro-afixo-opcao.com-raridade.ativo { border-color: var(--tier); box-shadow: inset 0 0 0 1px var(--tier); }
.filtro-afixo > b {
  font-family: var(--font-heading); font-size: 11px; letter-spacing: .06em;
  text-transform: uppercase; color: #7fb8d8;
}
.filtro-afixo-opcoes { display: flex; gap: 5px; flex-wrap: wrap; margin: 6px 0 4px; }
.filtro-afixo-opcao {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px; cursor: pointer; font-size: 11px; border-radius: 999px;
  background: var(--panel-2); border: 1px solid var(--line); color: var(--muted);
}
.filtro-afixo-opcao:hover { border-color: var(--accent-dim); color: var(--text); }
.filtro-afixo-opcao.ativo { border-color: var(--accent); color: var(--text); background: #16241f; }
/* A estrela aqui é rótulo, e não selo de canto: sem sombra e sem posição. */
.filtro-afixo-opcao .item-estrelas { margin: 0; font-size: 12px; }

/*
 * ---- A segunda fileira: QUANTAS estrelas ----
 *
 * Recuada e com um filete à esquerda, para se ler como uma condição a mais
 * dentro da regra de cima e não como uma segunda regra independente — que é
 * exatamente o que ela é: "roxa para cima E pelo menos duas".
 *
 * As estrelas daqui não têm cor. Coloridas, as duas fileiras ficariam idênticas
 * e a de baixo pareceria repetir a de cima; cinzas, elas leem como contagem.
 */
.filtro-afixo-quantas {
  margin: 8px 0 2px 10px; padding-left: 10px;
  border-left: 1px solid var(--line);
}
.filtro-afixo-quantas > b {
  font-family: var(--font-heading); font-size: 10px; letter-spacing: .06em;
  text-transform: uppercase; color: #6d8b9c;
}
.item-estrelas.contagem b.estrela { color: #9fb3bd; text-shadow: none; }
.filtro-afixo-opcao.ativo .item-estrelas.contagem b.estrela { color: #d6e4ea; }

.filtro-legenda { display: flex; gap: 16px; margin: 6px 0 8px; font-size: 10px; }
.filtro-legenda span { display: flex; align-items: center; gap: 6px; color: #55646a; }
.filtro-legenda span::before {
  content: ''; width: 14px; height: 14px; border-radius: 3px; flex: none;
  background: #161d20; box-shadow: inset 0 0 0 2px currentColor;
}
.filtro-legenda-loot { color: #c0504a; }
.filtro-legenda-sell { color: #3fbfa8; }

/* O preset do NPC, ao lado dos outros botões da barra do loot. */
/*
 * ---- "Apenas o que NPC compra" tem cara de BOTÃO ----
 *
 * "dá um efeito no 'apenas o que o NPC compra' pra pessoa saber que pode ser
 * clicado."
 *
 * Ele era um contorno fino dourado com texto dourado — a mesma cara das
 * etiquetas e contagens ao redor, que não se clicam. Agora tem o que um botão
 * tem: um fundo, uma seta de ação na frente, e uma resposta ao mouse (acende,
 * sobe um pixel e passa um brilho). O brilho corre UMA vez por passada, e não em
 * laço: animação infinita num canto da tela é ruído, e no telefone come bateria.
 */
.previa-pincel.npc {
  position: relative; overflow: hidden;
  display: inline-flex; align-items: center; gap: 5px;
  border-color: rgba(240, 207, 122, 0.55); color: #f5d98c;
  background: linear-gradient(180deg, #3a2e12, #221a0a);
  box-shadow: inset 0 1px 0 #ffe7a526, 0 0 0 0 #f0cf7a00, 0 1px 2px #0008;
  cursor: pointer;
  transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease, color .15s ease;
}
.previa-pincel.npc::before { content: '▸'; font-size: 10px; opacity: .85; }
.previa-pincel.npc::after {
  content: ''; position: absolute; top: 0; bottom: 0; left: -60%; width: 40%;
  background: linear-gradient(100deg, transparent, #fff3c466, transparent);
  transform: skewX(-20deg); pointer-events: none;
}
.previa-pincel.npc:hover:not(:disabled) {
  border-color: #f0cf7a; color: #fff1c2;
  background: linear-gradient(180deg, #5a4718, #33280e);
  box-shadow: inset 0 1px 0 #ffe7a540, 0 0 10px -1px #f0cf7a99, 0 2px 4px #0009;
  transform: translateY(-1px);
}
.previa-pincel.npc:hover:not(:disabled)::after { left: 130%; transition: left .6s ease; }
.previa-pincel.npc:active:not(:disabled) { transform: translateY(0); box-shadow: inset 0 1px 3px #0009; }
.previa-pincel.npc:disabled { background: none; box-shadow: none; }
.previa-pincel.npc:disabled::before { opacity: .4; }

/* As quatro combinações precisam se distinguir: só coleta, só venda, e ambas. */
.filter-grid .cell.barred.protected { box-shadow: inset 0 0 0 2px #d8564c, 0 0 0 2px #35d17a; }

/* ---- Arrastar entre slots da barra: troca os dois ---- */
.hotbar .slot[draggable='true'] { cursor: grab; }
.hotbar .slot.dragging { opacity: 0.35; cursor: grabbing; }
.hotbar .slot.alvo { outline: 2px solid var(--accent); outline-offset: -2px; }
.hotbar .slot.recusa { outline: 2px solid #c0504a; outline-offset: -2px; cursor: not-allowed; }

/* ---- Modal de ajustes da tela ---- */
/*
 * ---- Por que a caixa das abas tem altura mínima ----
 *
 * "faz por abas igual config de jogo mesmo" — e as quatro abas têm tamanhos bem
 * diferentes: Interface tem quatro seções, Janelas tem uma. Sem um piso, a
 * janela encolhia e crescia a cada clique, e o botão da aba seguinte fugia de
 * baixo do ponteiro no meio do caminho. É o mesmo motivo pelo qual um cliente
 * de jogo nunca redimensiona a tela de opções entre as abas dela.
 */
.ajustes-painel { min-height: 320px; padding-top: 12px; }
.ajustes-secao {
  margin-bottom: 14px; padding: 10px 12px;
  border: 1px solid rgba(255, 255, 255, 0.07); border-radius: 8px;
  background: rgba(0, 0, 0, 0.18);
}
.ajustes-titulo {
  font-size: 10px; letter-spacing: 0.05em; text-transform: uppercase;
  color: #55646a; margin-bottom: 8px;
}
.ajustes-linha { display: flex; align-items: center; gap: 14px; }
.ajustes-texto { flex: 1; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ajustes-texto b { font-size: 13px; color: var(--text); }
.ajustes-texto span { font-size: 10px; color: #55646a; line-height: 1.35; }
.ajustes-botoes { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 8px; }

/* ---- Cyclopedia ---- */
.ciclo-layout { display: grid; grid-template-columns: 300px 1fr; gap: 12px; align-items: start; }
@media (max-width: 860px) { .ciclo-layout { grid-template-columns: 1fr; } }
.ciclo-lista {
  display: flex; flex-direction: column; gap: 2px;
  max-height: 52vh; overflow-y: auto; padding-right: 4px;
}
.ciclo-item {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 4px 6px; border: 1px solid transparent; border-radius: 6px;
  background: rgba(0, 0, 0, 0.18); cursor: pointer; text-align: left;
}
.ciclo-item:hover { border-color: var(--accent-dim); }
.ciclo-item.escolhido { border-color: var(--accent); background: rgba(63, 191, 168, 0.08); }
.ciclo-item-texto { flex: 1; display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.ciclo-item-texto b { font-size: 12px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ciclo-item-texto span { font-size: 9px; color: #55646a; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ciclo-item-preco { font-size: 10px; color: #f0cf7a; font-style: normal; flex: none; }

.ciclo-ficha {
  padding: 12px; border: 1px solid rgba(255, 255, 255, 0.07); border-radius: 8px;
  background: rgba(0, 0, 0, 0.18); min-height: 200px;
}
.ciclo-ficha-topo { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; }
.ciclo-ficha-topo b { display: block; font-size: 15px; color: var(--text); }
.ciclo-ficha-topo span { font-size: 10px; color: #55646a; }
.ciclo-drops { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 6px; }
.ciclo-drop {
  display: flex; align-items: baseline; gap: 5px;
  padding: 2px 7px; border-radius: 5px; background: rgba(255, 255, 255, 0.05);
}
.ciclo-drop b { font-size: 10px; color: var(--muted); }
.ciclo-drop span { font-size: 9px; color: #55646a; }

.ciclo-magias {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 8px;
  max-height: 56vh; overflow-y: auto; padding-right: 4px;
}
.ciclo-magia {
  padding: 8px 10px; border: 1px solid rgba(255, 255, 255, 0.07); border-radius: 7px;
  background: rgba(0, 0, 0, 0.18); display: flex; flex-direction: column; gap: 3px;
}
.ciclo-magia.bloqueada { opacity: 0.55; }
.ciclo-magia-topo { display: flex; align-items: baseline; gap: 8px; justify-content: space-between; }
.ciclo-magia-topo b { font-size: 12px; color: var(--text); }
.ciclo-magia-topo em { font-size: 9px; color: var(--accent); font-style: normal; }
.ciclo-magia-dados { font-size: 10px; color: #55646a; line-height: 1.4; }
.ciclo-magia-trava { font-size: 9px; color: #c0504a; font-style: normal; }

/* ---- Painel do grupo da caçada ---- */
.grupo-pessoas { display: flex; gap: 6px; }
.grupo-pessoa {
  display: flex; align-items: baseline; gap: 4px;
  padding: 1px 7px; border-radius: 5px; background: rgba(255, 255, 255, 0.05);
}
.grupo-pessoa.eu { background: rgba(63, 191, 168, 0.14); }
.grupo-pessoa.morto { opacity: 0.45; text-decoration: line-through; }
.grupo-pessoa b { font-size: 11px; color: var(--text); }
.grupo-pessoa span { font-size: 9px; color: #55646a; }
.grupo-lider { font-size: 9px; color: #f0cf7a; font-style: normal; }
.grupo-estado { color: var(--accent); }
.grupo-caixa.off .grupo-estado { color: #d97a63; }

/* O relógio do convite: ele expira, e o cartão diz quando. */
.convite-relogio { font-size: 9px; color: #55646a; font-style: normal; margin-top: 4px; }

/* ---- Bônus de experiência no tooltip da régua ---- */
.tip-exp-bonus { margin-top: 10px; padding-top: 8px; border-top: 1px solid rgba(255, 255, 255, 0.08); }
.tip-exp-linha { display: flex; align-items: baseline; gap: 8px; font-size: 11px; padding: 1px 0; }
.tip-exp-linha span { flex: 1; color: var(--muted); }
.tip-exp-linha b { color: var(--accent); }
.tip-exp-linha em { font-size: 9px; color: #55646a; font-style: normal; }
.tip-exp-total {
  margin-top: 6px; padding-top: 6px; border-top: 1px solid rgba(255, 255, 255, 0.06);
  font-size: 11px; color: var(--text);
}

/* ==================================================================
   Correções de leitura da barra de cima, dos botões e do filtro
   ================================================================== */

/*
 * O "+1" de pedidos de amizade.
 *
 * Ele era criado em `marcarPedidosDeAmizade()` e nunca teve regra nenhuma: um
 * `<i>` solto dentro de um botão em coluna virava uma terceira linha de texto
 * miúdo embaixo da legenda — e nas telas em que a coluna tinha altura fixa ele
 * ficava simplesmente fora da vista. Era por isso que "não chegava o +1".
 *
 * Agora é um selo ancorado no canto do ícone, como o de qualquer caixa de
 * entrada, e o botão inteiro ganha o mesmo anel dourado que já marca "tem coisa
 * para fazer aqui" nos outros ícones.
 */
.tools button .badge-pedidos {
  position: absolute; top: -1px; right: 6px; z-index: 2;
  min-width: 15px; height: 15px; padding: 0 3px;
  display: grid; place-items: center;
  font-family: var(--font-heading); font-size: 9px; font-style: normal; font-weight: 700;
  color: #1a0f04; background: linear-gradient(#ffe6a3, #d9ae4a);
  border: 1px solid #7a5a1c; border-radius: 8px;
  box-shadow: 0 0 6px #ffd98088;
  animation: pedido-pulsa 1.6s ease-in-out infinite;
}
@keyframes pedido-pulsa {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.12); }
}
@media (prefers-reduced-motion: reduce) { .tools button .badge-pedidos { animation: none; } }

/* A engrenagem da barra virou desenho: a caixinha de 18px acomoda o PNG. */
.bar-controls button { display: grid; place-items: center; }
#bar-gear { width: 20px; height: 20px; }
#bar-gear img { width: 16px; height: 16px; display: block; object-fit: contain; }
#bar-gear:hover img { filter: drop-shadow(0 0 4px var(--accent)); }

/*
 * `.primary` fora da porta de entrada não tinha regra nenhuma.
 *
 * `.gate-box button.primary` cobria só a tela de login. Dentro de um painel o
 * botão caía no desenho padrão do navegador — cinza-branco, fonte de sistema —
 * e era isso que aparecia em "Enviar pedido", em "Aceitar" e em "Sair". Aqui
 * ele passa a ser o mesmo botão de confirmar que o resto do jogo usa.
 */
/* O modal é `#modal`, e não `.modal`: a regra não pegava nada. */
/*
 * ---- E os cartoes que flutuam soltos no `body` ----
 *
 * O convite para caçar (`.convite`) e as caixas de confirmar (`.confirm-back`)
 * nao moram dentro de `#modal` nem de `.window`: sao anexados direto no corpo
 * da pagina, de proposito, para nao travarem o jogo por tras. Com isso ficavam
 * fora desta regra, e o "Aceitar" saia branco, com a fonte do sistema, ao lado
 * de um "Recusar" desenhado — foi o que o dono viu.
 */
#modal button.primary,
.window button.primary,
.convite button.primary,
.confirm-back button.primary {
  border-radius: 6px; padding: 8px 18px; cursor: pointer;
  font-family: var(--font-heading); font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase; font-size: 12px;
  border: 1px solid var(--accent-dim); background: var(--accent-dim); color: #eafffb;
}
#modal button.primary:hover:not(:disabled),
.window button.primary:hover:not(:disabled),
.convite button.primary:hover:not(:disabled),
.confirm-back button.primary:hover:not(:disabled) { filter: brightness(1.18); }
#modal button.primary:disabled,
.convite button.primary:disabled,
.confirm-back button.primary:disabled { background: var(--panel); border-color: var(--line); color: var(--muted); cursor: not-allowed; }
/* Botões pequenos dentro de uma linha de lista não usam o tamanho de confirmar. */
#modal button.primary.amigo-acao { padding: 4px 12px; font-size: 10px; letter-spacing: .04em; }

/*
 * Os quadradinhos da legenda ganham a cor cheia.
 *
 * Vazados eles ainda liam-se como caixa de marcar: um contorno fino e um miolo
 * escuro é o desenho de um checkbox, não de "isto fica vermelho". Preenchidos,
 * a legenda diz a cor da regra antes de o olho chegar ao texto — vermelho é o
 * que não se coleta, verde é o que não se vende.
 */
.filtro-legenda span::before {
  background: currentColor;
  box-shadow: inset 0 0 0 1px #0006, 0 0 5px currentColor;
}
.filtro-legenda-loot { color: #d8564c; }
.filtro-legenda-sell { color: #35d17a; }

/* ==================================================================
   A tela de antes de entrar na hunt, encolhida para caber sem rolagem
   ================================================================== */

/* "Voltar" mudou para o topo: fica antes da foto, encostado à esquerda. */
/*
 * O topo da prévia: Voltar à esquerda, "Parar em" à direita.
 *
 * Os dois são do mesmo tamanho e da mesma família — um sai da tela, o outro
 * abre uma gaveta — e ficam nas pontas porque não têm nada a ver um com o
 * outro. Numa janela estreita eles quebram, e aí o "Parar em" fica embaixo.
 */
.previa-topo { display: flex; align-items: stretch; justify-content: space-between; gap: 8px; flex-wrap: wrap; margin: 0 0 8px; }
.previa-topo .modal-back {
  padding: 4px 10px; font-size: 11px; cursor: pointer;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 6px; color: var(--muted);
}
.previa-topo .modal-back:hover { border-color: var(--accent-dim); color: var(--text); }

/*
 * Convite e condições de parada dividem a mesma linha do rodapé.
 *
 * ---- Por que isto deixou de ser `grid` ----
 *
 * Era `grid-template-columns: auto 1fr`, e o `auto` da primeira coluna crescia
 * com o conteúdo: bastava marcar um amigo para a ficha com o nome dele ("Teste
 * Sorcerer 300 ✕") empurrar o convite até os 320px do `max-width` e roubar a
 * largura do `1fr` do lado. As quatro condições não têm para onde encolher —
 * nome com `nowrap`, campo com `min-width` — então quem cedia era o `<em>` da
 * unidade, que ia a um caractere de largura: era daí que vinham as letras
 * empilhadas "o/z/g/o/l/d" da foto, e o "50" do gold cortado.
 *
 * Como flex, os dois blocos têm uma largura mínima declarada (`flex-basis`) e
 * QUEBRAM a linha quando ela não cabe, em vez de se espremerem. O rodapé pode
 * ficar com duas linhas num modal estreito — o que ele não pode é ficar ilegível.
 */
.previa-ajustes {
  display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-start;
  margin-bottom: 8px;
}
.previa-ajustes .run-convidar { flex: 0 1 auto; }
.previa-ajustes .run-paradas { flex: 1 1 480px; min-width: 0; margin: 0; }

/* ---- o convite virou um botão ---- */
.run-convidar {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 6px 8px; max-width: 320px;
  border: 1px solid rgba(255, 255, 255, 0.08); border-radius: 8px;
  background: rgba(0, 0, 0, 0.18);
}
.convidar-botao {
  position: relative; flex: none; width: 34px; height: 34px; padding: 0; cursor: pointer;
  display: grid; place-items: center;
  background: none; border: none;
  filter: drop-shadow(0 0 1px #0a0d0f) drop-shadow(0 0 4px #3fbfa877);
  transition: filter .16s ease;
}
.convidar-botao img { width: 30px; height: 30px; display: block; object-fit: contain; }
.convidar-botao:hover:not(:disabled) { filter: drop-shadow(0 0 4px #3fbfa8) drop-shadow(0 0 10px #3fbfa877); }
.convidar-botao:disabled { opacity: .35; cursor: default; filter: grayscale(.6); }
/* O "+" é o que diz que o desenho é uma AÇÃO, e não a lista de amigos. */
.convidar-mais {
  position: absolute; right: -3px; bottom: -3px;
  width: 15px; height: 15px; display: grid; place-items: center;
  font-family: var(--font-heading); font-size: 12px; font-style: normal; font-weight: 700; line-height: 1;
  color: #06110e; background: var(--accent); border-radius: 50%;
  box-shadow: 0 0 5px #3fbfa899;
}
.convidar-botao:disabled .convidar-mais { background: var(--muted); box-shadow: none; }

.convidar-fichas { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; min-width: 0; }
.convidar-vazio { font-style: normal; font-size: 10px; color: #55646a; }
/*
 * A ficha de cada companheiro virou um BOTAO de marcar: marcada, ela vai; sem
 * marca, a pessoa fica de fora desta cacada (e continua na party). Por isso o
 * estado apagado precisa ser lido de longe — e nao so' pela ausencia do "v".
 */
.convidar-ficha {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 8px 2px 6px; font-size: 11px; cursor: pointer;
  border: 1px solid var(--line-soft); border-radius: 20px; background: #12191c; color: var(--muted);
}
.convidar-ficha.marcada { border-color: var(--accent-dim); background: #16241f; color: var(--text); }
.convidar-ficha:hover { border-color: var(--accent); }
.convidar-marca {
  display: inline-flex; align-items: center; justify-content: center;
  width: 13px; height: 13px; font-size: 9px; font-style: normal; line-height: 1;
  border: 1px solid var(--line-soft); border-radius: 4px; color: var(--bg, #0d1215);
}
.convidar-ficha.marcada .convidar-marca { background: var(--accent); border-color: var(--accent); }
/*
 * O "Entrar sozinho" ao lado das fichas. Mesma forma delas — e' a mesma
 * pergunta ("quem vai?") — com a cor do cobre para nao se confundir com um
 * companheiro marcado: ele nao e' gente, e' a ausencia dela.
 */
.convidar-sozinho {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 8px 2px 6px; font-size: 11px; cursor: pointer; white-space: nowrap;
  border: 1px solid var(--line-soft); border-radius: 20px; background: #12191c; color: var(--muted);
}
.convidar-sozinho:hover { border-color: var(--copper); }
.convidar-sozinho.marcada { border-color: var(--copper); background: #241d15; color: var(--text); }
.convidar-sozinho.marcada .convidar-marca { background: var(--copper); border-color: var(--copper); }
.convidar-ficha button {
  width: 15px; height: 15px; padding: 0; line-height: 1; cursor: pointer;
  font-size: 9px; color: var(--muted);
  background: none; border: none; border-radius: 50%;
}
.convidar-ficha button:hover { color: var(--danger); }
/* A lista só existe enquanto está aberta, e ocupa a linha inteira do quadro. */
.convidar-lista { flex-basis: 100%; display: grid; gap: 2px; margin-top: 4px; }

/*
 * ---- as condições de parada numa fileira só ----
 *
 * Flex com quebra, e não grid de colunas fixas: quatro colunas `1fr` num espaço
 * curto viram quatro colunas curtas demais, e o conteúdo transborda. Aqui cada
 * condição pede 118px e, se não couberem as quatro, elas passam para a linha de
 * baixo inteiras.
 */
.run-paradas-fila {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px;
}
.run-paradas-fila .run-parada { flex: 1 1 118px; min-width: 0; }
.run-paradas-rotulo {
  font-size: 10px; letter-spacing: 0.04em; text-transform: uppercase;
  color: #55646a; white-space: nowrap;
}
/* Numa tela estreita o rótulo fica sozinho na primeira linha da fileira. */
@media (max-width: 900px), (max-height: 540px) and (pointer: coarse) { .run-paradas-rotulo { flex-basis: 100%; } }

/*
 * ---- A cor dos dois modos ----
 *
 * Eram dois retângulos de borda cinzenta que só se distinguiam pelo texto. A
 * cor faz o trabalho antes da leitura: laranja para o modo que joga sozinho,
 * verde para o modo em que quem joga é você. O brilho é o mesmo `drop-shadow`
 * dos ícones da barra, para não inventar um terceiro jeito de acender algo.
 */
.run-modes { margin: 0; }
.run-mode { border-width: 2px; transition: border-color .16s ease, background .16s ease, box-shadow .16s ease; }

.run-mode.cycle {
  border-color: #ff9a3c; color: #ffd6a8; background: linear-gradient(#241a0d, #17120b);
  box-shadow: inset 0 0 18px #ff9a3c1f, 0 0 8px #ff9a3c33;
}
.run-mode.cycle em { color: #c79a67; }
.run-mode.cycle:hover:not(:disabled) {
  border-color: #ffb765; background: linear-gradient(#33240f, #1d160c);
  box-shadow: inset 0 0 22px #ff9a3c33, 0 0 16px #ff9a3c66;
}

.run-mode.manual {
  border-color: #35d17a; color: #c6f5da; background: linear-gradient(#0d2418, #0b1712);
  box-shadow: inset 0 0 18px #35d17a1f, 0 0 8px #35d17a33;
}
.run-mode.manual em { color: #6fae8a; }
.run-mode.manual:hover:not(:disabled) {
  border-color: #5ef0a0; background: linear-gradient(#113222, #0d1f16);
  box-shadow: inset 0 0 22px #35d17a33, 0 0 16px #35d17a66;
}

/*
 * O nome da condição não quebra linha.
 *
 * Com "Parar em" ocupando a primeira coluna, as outras quatro ficaram estreitas
 * e "Stamina" virou três linhas empilhadas. Quem cede largura é o campo do
 * número, que já tem `min-width`, e não a palavra.
 */
.run-parada-nome { white-space: nowrap; flex: none; }
.run-parada input[type='number'] { flex: 1 1 44px; min-width: 40px; max-width: 70px; }
/* A unidade nunca encolhe: era ela que virava uma letra por linha. */
.run-paradas-fila .run-parada-unidade { flex: none; width: auto; white-space: nowrap; }

/*
 * A cor da legenda perdia para o cinza por especificidade.
 *
 * `.filtro-legenda span` (classe + tipo) vence `.filtro-legenda-loot` (classe
 * só), e as duas pintam a mesma `color` — então o vermelho e o verde nunca
 * apareciam, nem no texto nem no quadradinho, que herda a cor por
 * `currentColor`. Qualificar pelo mesmo tipo empata o peso e a ordem decide.
 */
.filtro-legenda span.filtro-legenda-loot { color: #d8564c; }
.filtro-legenda span.filtro-legenda-sell { color: #35d17a; }

/* ==================================================================
   Cyclopedia
   ================================================================== */

/*
 * A ficha do item, na enciclopédia, é o balão da mochila numa moldura.
 *
 * O miolo vem inteiro do `tooltip.mjs` (`fichaDeItem`) e traz consigo as
 * classes `.tip-head`, `.tip-stats`, `.tip-rules` e `.tip-prices`, que já têm
 * regra própria. O que falta aqui é só o que o balão ganhava por ser um balão:
 * a moldura na cor da raridade e a faixa no alto. Nada de fonte, cor ou
 * espaçamento se repete — se o balão mudar, esta tela muda junto.
 */
.ciclo-balao {
  border: 1px solid var(--tier, var(--copper)); border-radius: 8px; overflow: hidden;
  background: linear-gradient(180deg, #121b1fcc, #0b1113e0);
  margin-bottom: 12px;
}
.ciclo-balao::before { content: ""; display: block; height: 2px; background: var(--tier, var(--copper)); }
/* Solto numa coluna larga, o balão espalhava as linhas por 700px. */
.ciclo-balao .tip-head { padding: 12px 14px 10px; }
.ciclo-balao .tip-id b { font-size: 16px; }

/* ---- magias, runas e poções com o desenho de cada uma ---- */
.ciclo-magia { flex-direction: row; align-items: flex-start; gap: 9px; cursor: help; }
.ciclo-magia:hover { border-color: var(--accent-dim); }
.ciclo-magia-arte {
  flex: none; width: 40px; height: 40px; display: grid; place-items: center;
  border: 1px solid rgba(255, 255, 255, 0.08); border-radius: 6px; background: rgba(0, 0, 0, 0.3);
}
/* O recorte da folha de magias é um `<i>` com `background-position`; o sprite
   de runa e poção é um canvas. Os dois cabem no mesmo quadrado. */
.ciclo-magia-arte .spell-icon { display: block; }
.ciclo-magia-arte canvas { display: block; image-rendering: pixelated; }
.ciclo-magia-arte .rune-mark {
  font-family: var(--font-heading); font-size: 13px; color: var(--muted);
}
.ciclo-magia-texto { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.ciclo-magia-topo { flex-wrap: wrap; }

/* ==================================================================
   A tecla de cada slot da barra
   ================================================================== */

/*
 * A grade de teclas, no editor do slot.
 *
 * Três estados e nada mais: livre, ocupada por outro slot, e a deste slot. O
 * dourado é o "é seu"; o apagado com contorno é "está com outro" — clicar nele
 * é o roubo, e o `title` diz de quem. É a mesma leitura das hotkeys do client,
 * onde uma tecla nunca está em dois lugares.
 */
.tecla-grade {
  display: flex; flex-wrap: wrap; gap: 4px; margin: 6px 0 12px;
}
.tecla-op {
  min-width: 30px; height: 26px; padding: 0 7px; cursor: pointer;
  font-family: var(--font-heading); font-size: 11px; letter-spacing: .04em;
  color: var(--muted); background: var(--panel-2);
  border: 1px solid var(--line); border-radius: 5px;
  transition: border-color .12s ease, color .12s ease, background .12s ease;
}
.tecla-op:hover { border-color: var(--accent-dim); color: var(--text); }
.tecla-op.ocupada { color: #55646a; border-style: dashed; }
.tecla-op.ocupada:hover { border-color: var(--copper); color: var(--copper); border-style: solid; }
.tecla-op.minha {
  color: #1a0f04; background: linear-gradient(#ffe6a3, #d9ae4a);
  border-color: #7a5a1c; box-shadow: 0 0 6px #ffd98055;
}

/* Slot sem tecla: o canto mostra um ponto em vez de um número que mentia. */
.hotbar .slot .key.sem { opacity: .35; }

/* ==================================================================
   "Você morreu"
   ================================================================== */

/*
 * A morte toma a tela.
 *
 * Ela era um aviso de canto do mesmo tamanho de "venda automática: +120 gold",
 * e some em três segundos — para o acontecimento que custa um level e meio e
 * manda o personagem de volta para a cidade. Aqui ela para o jogo por um
 * instante, como para no Tibia: o fundo escurece em vermelho, o número da perda
 * é o maior da tela, e embaixo está para onde ele foi.
 *
 * Ela NÃO bloqueia o jogo de verdade (`pointer-events` só no painel): o
 * personagem já está no templo e não há nada acontecendo por baixo.
 */
.morte {
  position: fixed; inset: 0; z-index: 80;
  display: grid; place-items: center; pointer-events: none;
  background: radial-gradient(ellipse at center, #2a0a0acc 0%, #060809ee 70%);
  animation: morte-entra .35s ease;
}
@keyframes morte-entra { from { opacity: 0; } to { opacity: 1; } }

.morte-painel {
  pointer-events: auto;
  min-width: 340px; max-width: 460px; padding: 26px 30px 20px;
  display: grid; gap: 12px; text-align: center;
  background: linear-gradient(180deg, #17100ff2, #0b0d0ef7);
  border: 1px solid #7a2c26; border-radius: 12px;
  box-shadow: 0 20px 60px #000c, inset 0 0 40px #7a2c2622;
}
.morte-painel h2 {
  margin: 0; font-family: var(--font-display, var(--font-heading));
  font-size: 30px; letter-spacing: .12em; text-transform: uppercase;
  color: #e0564c; text-shadow: 0 0 18px #7a2c2699;
}

/* As perdas em coluna: o número grande, o rótulo miúdo embaixo. */
.morte-perdas { display: flex; justify-content: center; gap: 26px; margin: 2px 0 4px; }
.morte-perdas div { display: grid; gap: 1px; }
.morte-perdas b { font-family: var(--font-heading); font-size: 20px; line-height: 1; }
.morte-perdas span { font-size: 10px; color: #55646a; letter-spacing: .04em; }
.morte-perdas .exp b { color: #e0564c; }
.morte-perdas .ouro b { color: var(--copper); }
.morte-perdas .level b { color: #e08a4c; }

.morte-bencao { margin: 0; font-size: 11px; line-height: 1.5; color: var(--accent); }
.morte-sem-bencao { margin: 0; font-size: 11px; line-height: 1.5; color: #c79a67; }
.morte-nota { margin: 0; font-size: 10px; color: #55646a; }
.morte-destino { margin: 4px 0 0; font-size: 12px; color: var(--text); line-height: 1.5; }
.morte .confirm-actions { justify-content: center; margin-top: 4px; }

/*
 * O cantinho da tecla, no slot da barra, é um BOTÃO.
 *
 * Clicar nele arma a escuta e a próxima tecla apertada passa a ser daquele
 * slot — o "assign hotkey" do client. Enquanto ele espera, pisca em dourado
 * para não haver dúvida de quem vai receber a tecla. O direito tira a tecla.
 */
.hotbar .slot .key { cursor: pointer; pointer-events: auto; }
.hotbar .slot .key:hover { color: var(--accent); }
.hotbar .slot .key.ouvindo {
  color: #1a0f04; background: linear-gradient(#ffe6a3, #d9ae4a);
  border-radius: 3px; padding: 0 3px;
  animation: tecla-espera .8s ease-in-out infinite;
}
@keyframes tecla-espera {
  0%, 100% { box-shadow: 0 0 0 #ffd98000; }
  50% { box-shadow: 0 0 7px #ffd980cc; }
}
@media (prefers-reduced-motion: reduce) { .hotbar .slot .key.ouvindo { animation: none; } }

/*
 * O aviso de "outra janela assumiu" não é um erro de digitação.
 *
 * O `<small>` da tela de personagens é vermelho porque quase tudo que aparece
 * ali é recusa — senha errada, nome em uso. Isto é informação: o personagem
 * está bem, a caçada continua, e entrar de novo resolve.
 */
.gate-box small.aviso {
  display: block; margin-top: 10px; padding: 9px 11px; text-align: left;
  color: var(--accent); line-height: 1.5;
  border: 1px solid var(--accent-dim); border-radius: 7px; background: rgba(63, 191, 168, 0.06);
}
/*
 * ---- A caixa de "faltam slots de Party e Mc" (tela de personagens) ----
 *
 * Aparece quando o servidor recusa a entrada por falta de slot
 * (`precisaDeSlots`) e vende o slot ali mesmo. Moldura verde-água como o resto
 * da porta; os botões de comprar em dourado, que é a cor das coins no jogo.
 */
.gate-slots {
  margin: 10px auto 12px; max-width: 476px; padding: 12px 14px; text-align: left;
  border: 1px solid var(--accent-dim); border-radius: 9px;
  background: linear-gradient(180deg, rgba(63, 191, 168, 0.08), rgba(63, 191, 168, 0.03));
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.25) inset;
}
.gate-slots[hidden] { display: none; }
.gate-slots-cabeca { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.gate-slots-cabeca b { font-size: 14px; color: var(--accent); letter-spacing: .02em; }
.gate-slots-icone { width: 22px; height: 22px; image-rendering: pixelated; }
.gate-slots-texto { margin: 4px 0; font-size: 12px; line-height: 1.5; color: #cfe3de; }
.gate-slots-texto b { color: #fff; }
.gate-slots-fraco { color: var(--muted); }
.gate-slots-fichas { display: flex; flex-wrap: wrap; gap: 6px; margin: 4px 0 8px; }
.gate-slots-ficha {
  display: inline-flex; align-items: center; gap: 6px; padding: 3px 9px; font-size: 11px;
  color: #cfe3de; border: 1px solid var(--line); border-radius: 999px; background: rgba(0, 0, 0, 0.25);
}
.gate-slots-ficha .character-ponto { width: 6px; height: 6px; border-radius: 50%; background: var(--muted); }
.gate-slots-ficha.cacando .character-ponto { background: var(--accent); box-shadow: 0 0 6px var(--accent); }
.gate-slots-opcoes { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 8px; margin: 8px 0 6px; }
.gate-slots-opcao {
  position: relative; overflow: hidden;
  display: flex; flex-direction: column; align-items: center; gap: 3px; padding: 0 8px 9px; cursor: pointer;
  font: inherit; color: #f3e6c8; border-radius: 9px;
  background:
    radial-gradient(120% 70% at 50% 0%, rgba(233, 195, 116, 0.22), transparent 62%),
    linear-gradient(180deg, #1d2b2d, #0e1618);
  border: 1px solid #c9973f;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.45) inset, 0 0 14px rgba(233, 195, 116, 0.12), 0 2px 8px rgba(0, 0, 0, 0.4);
  transition: transform .12s ease, box-shadow .12s ease, border-color .12s ease;
}
.gate-slots-opcao:hover {
  border-color: #f3d894; transform: translateY(-1px);
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.45) inset, 0 0 18px rgba(233, 195, 116, 0.28), 0 4px 10px rgba(0, 0, 0, 0.45);
}
.gate-slots-opcao:disabled { cursor: default; filter: grayscale(.4) brightness(.8); transform: none; }
.gate-slots-opcao b { font-size: 14px; color: #ffe9b0; text-shadow: 0 1px 0 #000; letter-spacing: .02em; }
.gate-slots-opcao small { font-size: 10px; color: #b9c9c4; }
.gate-slots-preco { display: inline-flex; align-items: center; gap: 4px; font-weight: 700; font-size: 13px; color: #ffd979; }
.gate-slots-moeda { width: 14px; height: 14px; image-rendering: pixelated; vertical-align: -2px; }
.gate-slots-desconto { font-style: normal; font-size: 10px; padding: 0 6px; border-radius: 999px; background: #c9973f; color: #1a1208; font-weight: 700; }
.gate-slots-opcao.sem-saldo { filter: saturate(.25) brightness(.85); border-color: #5a5a5a; }
.gate-slots-opcao.sem-saldo:hover { transform: none; border-color: #777; }
.gate-slots-falta { font-size: 10px; color: #f0b7b3; }
.gate-slots-bonecos {
  display: flex; justify-content: center; align-items: flex-end; width: calc(100% + 16px); margin: 0 -8px 4px;
  padding: 6px 6px 3px; background: linear-gradient(180deg, rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.42));
  border-bottom: 1px solid rgba(201, 151, 63, 0.35);
}
.gate-slots-bonecos canvas { width: 30px; height: 30px; image-rendering: pixelated; margin-left: -7px; filter: drop-shadow(0 2px 1px rgba(0, 0, 0, 0.6)); }
.gate-slots-bonecos canvas:first-child { margin-left: 0; }
.gate-slots-boneco-vazio { display: inline-block; width: 22px; height: 30px; border-radius: 6px 6px 2px 2px; background: rgba(0, 0, 0, 0.3); }
.gate-slots-opcao.comprando { opacity: .7; }
.gate-slots-saldo { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 6px; font-size: 12px; color: #cfe3de; }
.gate-slots-saldo b { color: #ffe9b0; }
.gate-slots-coins {
  margin-left: auto; padding: 5px 12px; font: inherit; font-size: 11px; font-weight: 700; cursor: pointer;
  color: #1a1208; border-radius: 6px; background: linear-gradient(180deg, #e9c374, #b8832f); border: 1px solid #f3d894;
}
.gate-slots-coins:hover { filter: brightness(1.08); }
.gate-slots-coins { display: inline-flex; align-items: center; gap: 5px; }
.gate-slots-confirma {
  margin: 8px 0 4px; padding: 0 12px 12px; border-radius: 9px; overflow: hidden;
  border: 1px solid #c9973f; background: linear-gradient(180deg, #1d2b2d, #0e1618);
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.45) inset, 0 0 16px rgba(233, 195, 116, 0.14);
}
.gate-slots-confirma .gate-slots-bonecos { width: calc(100% + 24px); margin: 0 -12px 8px; }
.gate-slots-confirma-titulo { margin: 0 0 8px; font-size: 13px; text-align: center; color: #f3e6c8; }
.gate-slots-confirma-titulo b { color: #ffe9b0; }
.gate-slots-conta { display: flex; flex-direction: column; gap: 4px; padding: 8px 10px; border-radius: 7px; background: rgba(0, 0, 0, 0.3); border: 1px solid rgba(201, 151, 63, 0.25); }
.gate-slots-conta-linha { display: flex; justify-content: space-between; align-items: center; font-size: 12px; color: #b9c9c4; }
.gate-slots-conta-valor { display: inline-flex; align-items: center; gap: 5px; }
.gate-slots-conta-valor b { color: #ffe9b0; font-variant-numeric: tabular-nums; }
.gate-slots-conta-linha.custo .gate-slots-conta-valor b { color: #f0b7b3; }
.gate-slots-conta-linha.depois { padding-top: 5px; border-top: 1px dashed rgba(201, 151, 63, 0.35); font-weight: 600; color: #e8f1ee; }
.gate-slots-conta-linha.depois .gate-slots-conta-valor b { color: #ffd979; font-size: 13px; }
.gate-slots-confirma .gate-slots-fraco { display: block; margin-top: 8px; text-align: center; font-size: 11px; }
.gate-slots-botoes { display: flex; gap: 8px; margin-top: 10px; }
.gate-slots-botoes button { flex: 1; padding: 8px 10px; font: inherit; font-size: 12px; font-weight: 700; cursor: pointer; border-radius: 7px; }
.gate-slots-botoes button:disabled { cursor: default; opacity: .6; }
.gate-slots-cancelar { background: transparent; border: 1px solid var(--line); color: var(--muted); }
.gate-slots-cancelar:hover { border-color: var(--muted); color: #cfe3de; }
.gate-slots-confirmar {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px; color: #1a1208;
  background: linear-gradient(180deg, #e9c374, #b8832f); border: 1px solid #f3d894;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.3) inset, 0 2px 6px rgba(0, 0, 0, 0.35);
}
.gate-slots-confirmar:hover { filter: brightness(1.08); }
.gate-slots-rodape { min-height: 14px; margin-top: 4px; font-size: 11px; color: var(--accent); }
.gate-slots-rodape.erro { color: var(--danger); }
.gate-slots-ok { margin: 2px 0; font-size: 13px; color: var(--accent); }
.gate-slots-nota { margin: 6px 0 0; font-size: 11px; color: var(--muted); }

/* A prioridade de disparo, no editor do slot: subir, a posição, descer. */
.prioridade { display: flex; align-items: center; gap: 10px; margin: 4px 0 6px; }
.prioridade button {
  padding: 5px 12px; font-size: 11px; cursor: pointer;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 6px; color: var(--muted);
}
.prioridade button:hover:not(:disabled) { border-color: var(--accent-dim); color: var(--text); }
.prioridade button:disabled { opacity: .35; cursor: default; }
.prioridade-pos { font-family: var(--font-heading); font-size: 12px; color: var(--accent); }
/* O campo em que a prioridade se digita: largo o bastante para dois dígitos. */
.prioridade-campo {
  width: 52px; padding: 5px 6px; text-align: center;
  font-family: var(--font-heading); font-size: 13px; color: var(--accent);
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 6px;
}
.prioridade-campo:focus { outline: none; border-color: var(--accent-dim); }
.prioridade-de { font-style: normal; font-size: 11px; color: var(--muted); }

/* ==================================================================
   Elementos da criatura: dois grupos com nome
   ================================================================== */

/*
 * A cor conta a história antes do número.
 *
 * Vermelho é o que a protege (o seu dano cai) e verde é o ponto fraco (o seu
 * dano sobe) — a mesma leitura de qualquer barra do jogo. Antes as duas cores
 * estavam TROCADAS: `resist` usava o verde da vida e `weak` o vermelho do
 * perigo, porque a regra fora escrita do ponto de vista do bicho.
 */
.bestiary-elgrupo { display: grid; gap: 4px; margin-bottom: 8px; }
/* Sem o "Contra que dano ela se defende" em cima, o primeiro grupo precisa do
   respiro que o h3 dava — senão ele encosta na grade de atributos. */
.bestiary-elgrupo:first-of-type { margin-top: 10px; }
.bestiary-elgrupo-titulo {
  font-size: 10px; letter-spacing: .04em; text-transform: uppercase; color: #55646a;
}
.bestiary-elgrupo.resist .bestiary-elgrupo-titulo { color: #c07a72; }
.bestiary-elgrupo.weak .bestiary-elgrupo-titulo { color: #6fae8a; }

.bestiary-element em { font-style: normal; font-size: 10px; color: #55646a; }
.bestiary-element.resist { border-color: rgba(216, 86, 76, 0.35); }
.bestiary-element.weak { border-color: rgba(53, 209, 122, 0.35); }
.bestiary-element.resist b { color: #d8564c; }
.bestiary-element.weak b { color: #35d17a; }

/* Os filtros da Cyclopedia: três marcas numa linha, acima da lista. */
.ciclo-filtros { display: flex; flex-wrap: wrap; gap: 12px; margin: 0 0 10px; }
.ciclo-filtro {
  display: flex; align-items: center; gap: 6px; cursor: pointer;
  font-size: 11px; color: var(--muted);
}
.ciclo-filtro.on { color: var(--text); }
.ciclo-filtro input { accent-color: var(--accent); cursor: pointer; }

/* ==================================================================
   Imbuements: um por linha, com os três graus lado a lado
   ================================================================== */

/*
 * A linha é o imbuement; as colunas são os graus.
 *
 * Antes cada GRAU era uma linha, e as 72 entradas viravam 72 linhas de rolagem
 * para 24 encantamentos — com os três graus do mesmo imbuement separados por
 * duas linhas de outros. A decisão que se toma aqui é entre os três (preço
 * contra bônus), e para tomá-la eles precisam estar do lado um do outro.
 */
.imbue-familia {
  display: grid; grid-template-columns: 190px minmax(0, 1fr); gap: 12px; align-items: start;
  background: var(--panel-2); border: 1px solid var(--line-soft); border-radius: 8px; padding: 9px 12px;
}
.imbue-familia:hover { border-color: var(--accent-dim); }
.imbue-familia-cabeca { display: flex; align-items: center; gap: 9px; min-width: 0; }
.imbue-familia-cabeca b { display: block; font-size: 13px; font-weight: 600; }
.imbue-familia-cabeca em {
  font-style: normal; font-size: 10px; color: #55646a;
  text-transform: uppercase; letter-spacing: .04em;
}

.imbue-graus { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.imbue-grau {
  display: grid; gap: 5px; align-content: start;
  padding: 8px 9px; border-radius: 7px;
  background: rgba(0, 0, 0, 0.22); border: 1px solid var(--line);
}
/* O grau sobe de cor com o preço: cinza, teal, dourado. É a mesma escada de
   raridade do resto do jogo, e diz "este é o caro" antes de o olho ler o
   número. */
.imbue-grau.grau-1 { border-color: rgba(143, 163, 161, 0.3); }
.imbue-grau.grau-2 { border-color: rgba(55, 194, 160, 0.3); }
.imbue-grau.grau-3 { border-color: rgba(224, 168, 74, 0.32); }
.imbue-grau-nome {
  font-family: var(--font-heading); font-size: 10px; letter-spacing: .08em; text-transform: uppercase;
}
.imbue-grau.grau-1 .imbue-grau-nome { color: #8fa3a1; }
.imbue-grau.grau-2 .imbue-grau-nome { color: #37c2a0; }
.imbue-grau.grau-3 .imbue-grau-nome { color: #e0a84a; }
.imbue-grau-efeito { font-size: 10px; line-height: 1.35; color: var(--muted); }
.imbue-grau-custo { display: flex; flex-wrap: wrap; align-items: center; gap: 5px; }
.imbue-grau-custo b { color: var(--copper); font-family: var(--font-heading); font-size: 12px; }
.imbue-grau .reagent { font-size: 9px; padding: 2px 6px 2px 2px; }
.imbue-grau .reagent canvas { width: 18px; height: 18px; }
.imbue-grau button {
  padding: 5px 0; width: 100%; cursor: pointer; font-size: 11px;
  background: var(--accent-dim); border: 1px solid var(--accent-dim); color: #eafffb; border-radius: 6px;
}
.imbue-grau button:hover:not(:disabled) { filter: brightness(1.18); }
.imbue-grau button:disabled {
  background: var(--panel); border-color: var(--line); color: var(--muted); cursor: not-allowed;
}

@media (max-width: 1100px) {
  .imbue-familia { grid-template-columns: 1fr; }
  .imbue-graus { grid-template-columns: 1fr; }
}

/* O porquê do fim da caçada, no topo do extrato — só aparece quando quem
   encerrou foi outra pessoa do grupo. */
.relatorio-motivo {
  margin: 0 0 10px; padding: 8px 10px; font-size: 12px; color: var(--text);
  background: rgba(255, 154, 60, 0.10); border: 1px solid rgba(255, 154, 60, 0.35);
  border-left-width: 3px; border-radius: 6px;
}

/* ---------- "quantos?" ---------- */

/*
 * A caixa de quantidade: régua, campo e três atalhos.
 *
 * Arrastar uma pilha movia tudo, e não havia como separar. É a caixa do client
 * dele — arrastar a régua e digitar o número são o MESMO valor visto de dois
 * jeitos, e o Enter confirma sem tirar a mão do teclado.
 */
.quantia-box { width: min(340px, 92vw); }
.quantia-topo { display: flex; align-items: center; gap: 10px; justify-self: center; }
.quantia-topo b { font-family: var(--font-heading); font-size: 14px; }
.quantia-linha { display: flex; align-items: center; gap: 10px; }
.quantia-regua { flex: 1; accent-color: var(--accent); cursor: pointer; }
.quantia-campo {
  width: 78px; padding: 6px 8px; text-align: center;
  font-family: var(--font-heading); font-size: 14px; color: var(--accent);
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 6px;
}
.quantia-campo:focus { outline: none; border-color: var(--accent-dim); }
.quantia-teto { font-style: normal; font-size: 11px; color: var(--muted); white-space: nowrap; }
.quantia-atalhos { display: flex; gap: 6px; justify-content: center; }
.quantia-atalhos button { padding: 5px 14px; font-size: 12px; border-radius: 6px; cursor: pointer; }
/*
 * A regua e os atalhos viajam juntos.
 *
 * `controleDeQuantidade` devolve os dois dentro deste embrulho para poder entrar
 * em qualquer caixa — a de "quantos?" e a de destruir. O `gap` aqui repoe o da
 * `.confirm-box`, que so' alcanca os filhos diretos dela.
 */
.quantia-controle { display: grid; gap: 10px; }

/* ---------- troca de itens ---------- */

.troca-colunas { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.troca-lado {
  display: grid; gap: 8px; padding: 10px;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px;
}
/* O verde diz "este lado está pronto" sem precisar ler o texto. */
.troca-lado.pronto { border-color: var(--accent); box-shadow: inset 0 0 18px #3fbfa81f; }
.troca-cabeca { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.troca-cabeca b { font-family: var(--font-heading); font-size: 13px; }
.troca-cabeca em { font-style: normal; font-size: 10px; color: var(--muted); }
.troca-lado.pronto .troca-cabeca em { color: var(--accent); }
/*
 * Cinco colunas, porque a mesa passou a caber VINTE tipos (ver `ITENS_POR_OFERTA`).
 * Em quatro colunas seriam cinco fileiras altas; em cinco, quatro — e a mesa
 * inteira continua cabendo na janela sem rolagem.
 */
.troca-grade { display: grid; grid-template-columns: repeat(5, 1fr); gap: 5px; }
.troca-item {
  position: relative; display: grid; place-items: center; aspect-ratio: 1;
  background: #0b1112; border: 1px solid var(--line-soft); border-radius: 6px;
}
.troca-lado.meu .troca-item:not(.vazio) { cursor: pointer; }
.troca-lado.meu .troca-item:not(.vazio):hover { border-color: var(--danger); }
.troca-item.vazio { opacity: .35; }
.troca-item u {
  position: absolute; right: 2px; bottom: 1px; text-decoration: none;
  font-size: 10px; color: var(--text); text-shadow: 0 1px 2px #000;
}
/*
 * ---- A linha do ouro é UM bloco, e não duas pontas ----
 *
 * O dono, com o print: "o ouro ficou meio separado". Era o
 * `justify-content: space-between`: com a moeda e a palavra "Ouro" de um lado e
 * os botões do outro, a linha inteira virava um vão. Com três filhos em vez de
 * dois, o vão ficou no meio da coisa que devia ser lida junta.
 *
 * Agora a moeda e o rótulo ficam colados, e o controle é empurrado para a
 * direita por uma margem automática — o vão continua existindo, mas ele fica
 * FORA do bloco, que é onde vão serve para alguma coisa.
 */
.troca-ouro { display: flex; align-items: center; gap: 6px; font-size: 12px; }
.troca-ouro .troca-ouro-caixa { margin-left: auto; }
.troca-ouro span { color: var(--muted); }
.troca-ouro b { color: var(--copper); }
.troca-ouro input {
  width: 110px; padding: 5px 8px; text-align: right; color: var(--copper);
  background: #0b1112; border: 1px solid var(--line); border-radius: 6px;
}
.troca-aviso {
  margin: 10px 0 0; padding: 7px 10px; font-size: 11px; color: var(--muted);
  background: rgba(255, 154, 60, .08); border: 1px solid rgba(255, 154, 60, .28);
  border-left-width: 3px; border-radius: 6px;
}

/* As duas pontas da conversa privada, separadas pela direção. */
.privado-veio .who { color: var(--accent); }
.privado-saiu .who { color: var(--muted); }
/*
 * A seta diz a direção e mais nada, então ela não disputa atenção com o nome:
 * apagada e um ponto menor. Ver a montagem da linha em `chat.mjs`.
 */
.privado-seta { color: var(--muted); font-size: 11px; }

/* ---------- casa de leilões ---------- */

/*
 * Duas colunas: a lista sempre visível à esquerda, o item escolhido à direita.
 *
 * Eram dois modais empilhados, e comparar dois itens custava quatro cliques e
 * voltar ao topo da lista. Com a lista fixa, trocar de item é um clique.
 */
.leilao { display: grid; grid-template-columns: 288px 1fr; gap: 14px; align-items: start; }
@media (max-width: 900px), (max-height: 540px) and (pointer: coarse) { .leilao { grid-template-columns: 1fr; } }

.leilao-lista { display: grid; gap: 7px; align-content: start; }
.leilao-saldo {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 7px 10px; font-size: 12px; color: var(--muted);
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 7px;
}
.leilao-saldo b { color: var(--copper); font-family: var(--font-heading); font-size: 14px; }
.leilao-lista .search, .leilao-lista select {
  width: 100%; padding: 7px 9px; font-size: 12px;
  background: #080b0c; border: 1px solid var(--line); border-radius: 6px; color: inherit;
}
.leilao-filtros { display: flex; flex-wrap: wrap; gap: 4px; }
.leilao-chip {
  padding: 4px 10px; font-size: 11px; cursor: pointer; color: var(--muted);
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 999px;
}
.leilao-chip:hover { border-color: var(--accent-dim); color: var(--text); }
.leilao-chip.on { border-color: var(--accent); background: #16241f; color: var(--text); }

.leilao-rolagem { display: grid; gap: 3px; max-height: min(52vh, 460px); overflow-y: auto; padding-right: 4px; }
.leilao-item {
  display: flex; align-items: center; gap: 9px; text-align: left; cursor: pointer; color: inherit;
  padding: 5px 8px; background: var(--panel-2); border: 1px solid var(--line-soft); border-radius: 6px;
}
.leilao-item:hover { border-color: var(--accent-dim); }
.leilao-item.on { border-color: var(--accent); background: #16241f; }
.leilao-item-texto { flex: 1; display: grid; gap: 1px; min-width: 0; }
.leilao-item-texto b { font-weight: 500; font-size: 12px; }
.leilao-item-texto em { font-style: normal; font-size: 10px; color: var(--muted); }
.leilao-preco { font-size: 12px; color: var(--copper); white-space: nowrap; }

.leilao-detalhe { display: grid; gap: 10px; align-content: start; min-width: 0; }
.leilao-cabeca { display: flex; align-items: center; gap: 12px; }
.leilao-cabeca b { display: block; font-family: var(--font-heading); font-size: 16px; }
.leilao-cabeca em { font-style: normal; font-size: 11px; color: var(--muted); }

/* As duas pontas do balcão, lado a lado: quem compra e quem vende. */
.leilao-colunas { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 1100px) { .leilao-colunas { grid-template-columns: 1fr; } }
.leilao-coluna {
  display: grid; gap: 7px; padding: 9px;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px;
}
/* A cor separa as duas de longe: verde é quem compra de você, âmbar é quem vende. */
.leilao-coluna.compra { border-left: 3px solid var(--accent); }
.leilao-coluna.venda { border-left: 3px solid var(--copper); }
.leilao-coluna-topo { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.leilao-coluna-topo b { font-family: var(--font-heading); font-size: 12px; letter-spacing: .03em; }
.leilao-criar {
  padding: 4px 10px; font-size: 11px; cursor: pointer; color: var(--text);
  background: var(--panel-solid); border: 1px solid var(--accent-dim); border-radius: 999px;
}
.leilao-criar:hover { background: #16241f; }

.leilao-ofertas { display: grid; gap: 2px; max-height: min(34vh, 300px); overflow-y: auto; }
.leilao-oferta {
  display: grid; grid-template-columns: 1fr 46px 62px 72px auto; gap: 6px; align-items: center;
  padding: 4px 6px; font-size: 11px; border-radius: 5px;
}
.leilao-oferta:not(.cabeca):hover { background: #0f1618; }
.leilao-oferta.cabeca { font-size: 10px; color: #55646a; text-transform: uppercase; letter-spacing: .04em; }
.leilao-oferta .quem { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.leilao-oferta .qtd, .leilao-oferta .preco, .leilao-oferta .total { text-align: right; }
.leilao-oferta .preco { color: var(--copper); }
.leilao-oferta .total { color: var(--muted); }
.leilao-oferta button {
  padding: 3px 10px; font-size: 11px; cursor: pointer; border-radius: 5px;
  background: var(--accent-dim); border: 1px solid var(--accent-dim); color: #eafffb;
}
.leilao-oferta button:disabled { background: var(--panel); border-color: var(--line); color: var(--muted); cursor: not-allowed; }
.leilao-minhas { display: grid; gap: 3px; }
.leilao-oferta.minha { grid-template-columns: 30px 1fr 60px 74px 84px auto; background: var(--panel-2); }

.leilao-campo { display: flex; align-items: center; justify-content: space-between; gap: 10px; font-size: 12px; }
.leilao-campo span { color: var(--muted); }
.leilao-campo input {
  width: 120px; padding: 6px 8px; text-align: right;
  background: #0b1112; border: 1px solid var(--line); border-radius: 6px; color: inherit;
}

/* ==================================================================
   O convite de troca, e a mesa que recebe item arrastado
   ================================================================== */

/*
 * O cartão de convite embaixo, no meio.
 *
 * Mesma peça do convite de caçada (`.convite`), só que ancorada no centro da
 * borda de baixo em vez do canto direito — é onde o jogador está olhando
 * quando o convite chega, sem ficar por cima do personagem nem da barra de
 * ações. Sem fundo escurecido e sem prender o teclado: ele não impede nada.
 *
 * A folga de 79px sobre a barra (`--barra-altura`) deixa a barra de ações e a
 * régua de vida inteiras à mostra. O número era um `bottom: 148px` cravado,
 * medido numa barra de uma fileira só — ver a nota em actionbar.mjs.
 */
.convite-baixo {
  right: auto; left: 50%; transform: translateX(-50%);
  bottom: calc(var(--barra-altura, 69px) + 79px); min-width: 226px; max-width: 300px;
  padding: 9px 12px;
}
.convite-baixo b { font-size: 12px; }
.convite-baixo span { font-size: 11px; }
.convite-baixo .convite-acoes { margin-top: 6px; }
.convite-baixo .convite-acoes button { padding: 3px 10px; font-size: 11px; }

/* O meu lado da mesa aceita item arrastado da mochila. */
.troca-lado.meu { transition: border-color 0.12s, background 0.12s; }
.troca-lado.meu.soltar-aqui {
  border-color: var(--accent);
  background: rgba(63, 191, 168, 0.09);
}

/*
 * O selo do bônus na placa da Caça Online.
 *
 * Verde e em cima da linha de instrução: é a razão para escolher esse modo, e
 * ela precisa ser lida antes da explicação de como se joga.
 */
.run-mode-bonus {
  display: block; margin-top: 4px;
  font-size: 11px; font-weight: 700; letter-spacing: 0.02em;
  color: var(--accent);
}

/*
 * O resumo da morte no painel de bênçãos.
 *
 * Três números lado a lado — o que se perde agora, o que se perderia sem
 * nenhuma, e quanto isso é em levels. É a única razão de comprar uma bênção, e
 * antes o painel não mostrava nenhum deles.
 */
.bless-resumo {
  display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 10px;
  padding: 9px 12px; border: 1px solid rgba(255, 255, 255, 0.07); border-radius: 8px;
  background: rgba(255, 255, 255, 0.02);
}
.bless-resumo > div { display: flex; flex-direction: column; gap: 1px; flex: 1 1 132px; }
.bless-resumo b { font-size: 13px; color: var(--text); }
.bless-resumo span { font-size: 10px; color: #55646a; }
.bless-resumo .agora b { color: var(--danger); }
.bless-resumo .sem b { color: var(--muted); }
.bless-resumo .levels b { color: var(--accent); }

/* ---- Caça Online: a cruz do arremesso e o interruptor da assistência ---- */

/*
 * Runa armada: o cursor vira cruz sobre o mapa inteiro.
 *
 * É o sinal de que o próximo clique não anda — lança. Sem ele o jogador aperta
 * a tecla, clica para andar e a runa sai no lugar errado, gastando o ouro dela.
 */
body.mirando #map { cursor: crosshair; }

.assist-btn {
  /* Do tamanho do texto: esticado na largura da barra ele virava uma faixa, e
     faixa é o que a Caça Online já tinha e foi tirado de propósito. */
  width: max-content; align-self: center; margin: 0 0 6px; padding: 6px 12px; cursor: pointer;
  font-family: var(--font-heading); font-size: 11px; letter-spacing: .03em; white-space: nowrap;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px; color: var(--muted);
}
.assist-btn:hover { border-color: var(--accent); color: var(--accent); }
/* Ligada ela fica acesa: é um estado que muda o jogo inteiro, não um botão. */
.assist-btn.on { border-color: var(--accent); color: #0d1416; background: var(--accent); }


/* ---------- A tela de carregamento ---------- */

/*
 * Ela cobre tudo (z-index acima do portão e do jogo) e sai com uma dissolvida.
 * O fundo é o mesmo do portão para a troca não piscar: quem está olhando vê a
 * barra encher e a porta de entrada aparecer por baixo, no mesmo cenário.
 */
#boot {
  position: fixed; inset: 0; z-index: 200;
  display: grid; place-items: center;
  background: #06080a url(/client/assets/ui/gate-bg.webp) center/cover no-repeat;
  transition: opacity .35s ease-out;
}
#boot.saindo { opacity: 0; pointer-events: none; }

.boot-caixa { display: grid; justify-items: center; gap: 12px; width: min(420px, 84vw); text-align: center; }
.boot-logo { width: min(300px, 70vw); image-rendering: auto; filter: drop-shadow(0 6px 18px #000a); }

.boot-barra {
  width: 100%; height: 10px; border-radius: 999px; overflow: hidden;
  background: #0d1519; border: 1px solid var(--line);
}
/* A largura é escrita pelo JavaScript a cada passo; a transição é o que faz o
   avanço parecer movimento em vez de salto. */
.boot-barra i {
  display: block; height: 100%; width: 0%;
  background: linear-gradient(90deg, var(--accent-dim), var(--accent));
  transition: width .3s ease-out;
}

#boot-passo { font-family: var(--font-heading); font-size: 13px; letter-spacing: .04em; color: var(--accent); }
#boot-detalhe { font-size: 11px; color: var(--muted); min-height: 14px; }


/*
 * A tela de entrada no personagem usa a mesma caixa da abertura — é o mesmo
 * momento visto duas vezes, e duas caras diferentes para a mesma espera só
 * fariam o jogo parecer remendado.
 */
#entrada {
  position: fixed; inset: 0; z-index: 190;
  display: grid; place-items: center;
  background: #06080a url(/client/assets/ui/gate-bg.webp) center/cover no-repeat;
  transition: opacity .35s ease-out;
}
#entrada.saindo { opacity: 0; pointer-events: none; }
#entrada[hidden] { display: none; }
#entrada-nome { font-family: var(--font-heading); font-size: 18px; color: var(--accent); letter-spacing: .05em; }
#entrada-passo { font-family: var(--font-heading); font-size: 13px; letter-spacing: .04em; color: var(--accent); }
#entrada-detalhe { font-size: 11px; color: var(--muted); min-height: 14px; }


/* ---------- A tela do pagamento (QR do donate) ---------- */

.donate-intro { margin: 0; text-align: center; font-family: var(--font-heading); font-size: 20px; color: var(--accent); }
.donate-nota { display: block; text-align: center; color: var(--muted); font-size: 12px; margin-bottom: 10px; }

/*
 * O fundo do QR é branco e com folga por baixo do desenho: leitor de celular
 * precisa de contraste alto e de borda clara. Um QR bonito no tema escuro do
 * jogo seria um QR que ninguém lê.
 */
.donate-qr { display: grid; place-items: center; padding: 12px; background: #fff; border-radius: 10px; margin: 0 auto; width: max-content; }
.donate-qr canvas { display: block; image-rendering: pixelated; }

.donate-botoes { display: flex; gap: 8px; justify-content: center; margin-top: 14px; }
.donate-botoes button { padding: 10px 18px; cursor: pointer; border-radius: 8px; font-family: var(--font-heading); font-size: 12px; }
/* O verde da casa, o mesmo dos botoes de compra da loja. */
.donate-botoes button.primary {
  background: linear-gradient(180deg, var(--accent-dim), #1f5f54);
  border: 1px solid var(--accent-dim); color: #eafffb;
}
.donate-botoes button.primary:hover { filter: brightness(1.18); }
.donate-rodape { display: block; text-align: center; color: var(--muted); font-size: 11px; margin-top: 10px; line-height: 1.5; }

/* ---- "vale trocar?": o item sob o mouse contra o que está vestido ----
   Verde a favor da peça nova, vermelho contra. O bloco fica DEPOIS das regras
   e antes do preço de NPC, que é a ordem em que a pergunta aparece: o que ela
   faz, quem pode usar, o que muda para mim, quanto vale. */
.tip-vs {
  display: grid;
  gap: 2px;
  padding: 9px 12px;
  border-top: 1px solid var(--line-soft);
  font-size: 11px;
}
.tip-vs .vs-titulo { color: var(--muted); font-weight: 500; margin-bottom: 2px; }
.tip-vs .vs-igual { color: var(--muted); }
.tip-vs .vs-aviso { color: #e0a84a; margin-top: 3px; }
.tip-vs div.vs-melhor,
.tip-vs div.vs-pior { display: flex; justify-content: space-between; gap: 16px; }
.tip-vs div.vs-melhor span,
.tip-vs div.vs-pior span { color: var(--muted); }
.tip-vs div.vs-melhor b { color: #57e0a8; }
.tip-vs div.vs-pior b { color: #ff6a5a; }

/* ---- O desenho de onde uma magia pega ----
   Uma grade com o personagem no meio (a casa clara) e as casas atingidas na
   cor do elemento. As formas são escritas viradas para o norte, que é como o
   servidor as guarda; no jogo elas giram para o lado que o personagem encara,
   e a legenda diz isso. */
.magia-previa {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 12px;
  border-top: 1px solid var(--line-soft);
  --cor-da-area: #c98aff;
}
.magia-grade {
  display: grid;
  grid-template-columns: repeat(var(--colunas), 9px);
  gap: 1px;
  flex: none;
}
.magia-casa {
  width: 9px;
  height: 9px;
  border-radius: 1px;
  background: rgba(255, 255, 255, 0.05);
}
.magia-casa.area { background: var(--cor-da-area); }
.magia-casa.alcance { background: var(--cor-da-area); opacity: 0.55; }
.magia-casa.eu { box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.85); }
.magia-legenda { color: var(--muted); font-size: 11px; line-height: 1.35; }

.magia-previa.el-fire { --cor-da-area: #ff9a3c; }
.magia-previa.el-ice { --cor-da-area: #7fd4ff; }
.magia-previa.el-earth { --cor-da-area: #5ad86a; }
.magia-previa.el-energy { --cor-da-area: #c98aff; }
.magia-previa.el-holy { --cor-da-area: #ffe066; }
.magia-previa.el-death { --cor-da-area: #d05a6a; }
.magia-previa.el-physical { --cor-da-area: #ff5a4a; }
.magia-previa.el-poison { --cor-da-area: #9ad84a; }
.magia-previa.el-healing { --cor-da-area: #57e0a8; }

/* No painel de escolha da magia a grade fica maior: ali há espaço, e é onde a
   decisão é tomada. */
.action-detail .magia-previa { border-top: 0; padding: 4px 0 8px; }
.action-detail .magia-grade { grid-template-columns: repeat(var(--colunas), 12px); }
.action-detail .magia-casa { width: 12px; height: 12px; }

/*
 * Distancia do alvo alem do que o personagem alcanca: continua escolhivel
 * (equipar outra arma muda o numero na hora), mas nao se oferece em silencio.
 */
#distance option.fora-do-alcance { color: #8a8378; }

/*
 * ---- A faixa de "voce derrotou o boss" ----
 *
 * Sem botao de fechar de proposito: ela sai sozinha depois de alguns segundos,
 * e antes disso se o jogador clicar. `pointer-events` fica em `none` no fundo
 * para o clique atravessar e continuar valendo no jogo — a faixa avisa, nao
 * interrompe. So o painel escuta clique, para poder ser dispensado.
 */
.vitoria {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  z-index: 60;
}

.vitoria-painel {
  pointer-events: auto;
  cursor: pointer;
  min-width: 320px;
  padding: 26px 42px 24px;
  text-align: center;
  border: 1px solid #b9975b;
  border-radius: 10px;
  background: linear-gradient(180deg, rgba(38, 32, 22, 0.97), rgba(22, 19, 14, 0.97));
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.6), 0 18px 48px rgba(0, 0, 0, 0.75), 0 0 60px rgba(185, 151, 91, 0.18);
  animation: vitoria-entra 420ms cubic-bezier(0.2, 1.1, 0.35, 1) both;
}

.vitoria.saindo .vitoria-painel { animation: vitoria-sai 380ms ease-in both; }

.vitoria-selo {
  font-size: 34px;
  line-height: 1;
  color: #e8c87a;
  text-shadow: 0 0 18px rgba(232, 200, 122, 0.55);
}

.vitoria-painel h2 {
  margin: 10px 0 2px;
  font-size: 26px;
  letter-spacing: 0.06em;
  color: #f0dda8;
  text-shadow: 0 2px 0 rgba(0, 0, 0, 0.6);
}

.vitoria-quem {
  margin: 0;
  font-size: 15px;
  color: #d8cdb4;
}

/* "Este boss sai uma vez so', e essa foi a sua." Ver `mostrarVitoria`. */
.vitoria-task {
  margin: 4px 0 0; font-size: 12px; line-height: 1.4; color: var(--copper);
  border-top: 1px solid var(--line-soft); padding-top: 8px;
}

.vitoria-ganhos {
  display: flex;
  gap: 22px;
  justify-content: center;
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid rgba(185, 151, 91, 0.28);
}

.vitoria-ganhos div { display: flex; flex-direction: column; gap: 2px; }
.vitoria-ganhos b { font-size: 17px; color: #9fd68a; }
.vitoria-ganhos span { font-size: 11px; color: #9b927f; }

/* ---------------------------------------------------------------------------
 * A CONTAGEM REGRESSIVA DA ARENA — so o numero
 *
 * "a contagem regressiva na tela nao precisa ter o fundo retangular sabe? deixa
 *  so o numero na tela bem bonito em vermelho com efeito."
 *
 * A caixa entrou na rodada passada para consertar um numero que nascia torto —
 * ele, o anel e a legenda se centravam cada um por conta propria. O alinhamento
 * continua resolvido sem ela: o painel virou uma COLUNA (`grid` com
 * `justify-items: center`), e quem segura tudo e o conteiner.
 *
 * ---- O efeito, e por que ele nao e so uma cor ----
 *
 * Um numero vermelho chapado em cima de um mapa escuro some. O que o faz existir
 * sao quatro camadas de sombra: um contorno preto que o descola do chao, dois
 * halos vermelhos de raios diferentes (o de perto da a brasa, o de longe da o
 * clarao) e um miolo quase branco no proprio texto, que e o que da a impressao
 * de metal em brasa em vez de tinta.
 *
 * A trava de andar e bater e do SERVIDOR (ver `naLargada`, no hunt.mjs). Esta
 * folha nao segura ninguem: ela so avisa.
 * ------------------------------------------------------------------------- */
.arena-largada {
  position: fixed; inset: 0; z-index: 70;
  display: flex; align-items: center; justify-content: center;
  /*
   * Centrado na horizontal, ACIMA do centro na vertical: o mapa centra a camera
   * no jogador, e um numero no meio exato tapa os dois bonecos e os primeiros
   * bichos em volta — que e o que se quer olhar nos cinco segundos em que nao
   * da para andar.
   */
  padding-bottom: 20vh;
  pointer-events: none;
}
/* Debaixo da cortina de viagem ainda: nada aparece. */
.arena-largada.esperando { opacity: 0; }

/* Sem caixa: a coluna e' o que alinha o numero e a legenda. */
.arena-largada-painel { display: grid; justify-items: center; gap: 4px; }

.arena-largada-numero {
  font-family: var(--font-title);
  font-size: 118px; line-height: 1;
  /*
   * ---- O miolo e VERMELHO, e nao branco-rosado ----
   *
   * A primeira versao usou `#ffd9cd` — quase branco, com o vermelho so nos
   * halos. Lido na tela ele dava rosa, e o pedido era "bem bonito em vermelho".
   *
   * Agora a LETRA e vermelha e quem faz o contraste e o contorno preto: um
   * vermelho chapado sobre pedra escura sumiria sem ele, e e por isso que os
   * dois primeiros `text-shadow` sao sombras duras e nao brilho.
   */
  color: #ff4f2e;
  text-shadow:
    0 0 3px #1a0402,
    0 0 6px #1a0402,
    0 3px 0 #150301,
    0 0 20px #ff3b1e,
    0 0 50px #ff2a0fcc,
    0 0 96px #c41507aa;
}
/*
 * O "Derrote-o!" nao e um numero: e uma FRASE, e uma frase de 118px nao cabe em
 * tela nenhuma. A fonte cai e o clarao aumenta — e a troca de tamanho que diz
 * "mudou", junto com o brilho.
 */
.arena-largada.vai .arena-largada-numero {
  font-size: 52px;
  /* Na frase o vermelho clareia um degrau: e a unica vez que a cor muda, e e
     assim que a tela diz que a contagem acabou. */
  color: #ff7354;
  text-shadow:
    0 0 2px #2a0603,
    0 3px 0 #1a0402,
    0 0 22px #ff5a3a,
    0 0 60px #ff2a0f,
    0 0 110px #c41507;
}

/*
 * Cada numero BATE uma vez: entra grande e claro e assenta. E o pulso que
 * transforma cinco numeros trocando num relogio correndo — sem ele a tela so
 * pisca, e o jogador nao sente o tempo passar.
 */
.arena-largada-numero.bate { animation: arena-largada-bate .46s cubic-bezier(.2, .9, .3, 1); }
@keyframes arena-largada-bate {
  0% { transform: scale(1.65); opacity: 0; filter: brightness(2.2); }
  35% { opacity: 1; }
  100% { transform: scale(1); opacity: 1; filter: none; }
}

/*
 * ---- A legenda, e por que ela precisou de contorno ----
 *
 * "o contador ficou perfeito, mas o ''contra fulano'' quase nao da pra ver."
 *
 * Ela nasceu cinza-fraca de propósito, para não disputar com o número. O erro
 * não foi o tamanho: foi o FUNDO. Atrás dela não há tela escura, há o mapa —
 * chão claro, bichos e dois bonecos passando por baixo. Um cinza de pouco
 * contraste sobre isso não é discreto, é invisível.
 *
 * O conserto é o mesmo do número: contorno escuro em volta, que descola o texto
 * de qualquer coisa que passe atrás. Com ele dá para clarear a letra sem ela
 * virar um segundo título.
 *
 * E a linha se parte em duas vozes: "contra" é cola e fica apagada; o NOME é a
 * informação e fica claro, maior e com um resto do vermelho da arena.
 */
.arena-largada-nota {
  margin: 0;
  display: flex; align-items: baseline; gap: 7px;
  font-family: var(--font-title);
  text-transform: uppercase;
}
.arena-largada-contra {
  font-size: 12px; letter-spacing: .22em;
  color: #c9b3a6;
  text-shadow: 0 0 2px #1a0402, 0 2px 0 #1a0402, 0 0 10px #000;
}
.arena-largada-quem {
  font-size: 19px; letter-spacing: .1em;
  color: #ffe8dc;
  text-shadow:
    0 0 2px #1a0402,
    0 2px 0 #1a0402,
    0 0 14px #ff4f2e,
    0 0 36px #c41507aa;
}

@media (max-width: 560px) {
  .arena-largada-numero { font-size: 84px; }
  .arena-largada.vai .arena-largada-numero { font-size: 36px; }
}

/* ---------------------------------------------------------------------------
 * O CARTAO DE DESAFIO, em cima do mapa
 *
 * "o desafio, e quem desafiou e o elo da pessoa, tinha que aparecer na tela da
 *  pessoa (desde que ela esteja na cidade)."
 *
 * ---- CENTRADO, e EMBAIXO ----
 *
 * "o convite de desafio ... nao e pra ficar la encima, e pra ficar no centro
 *  embaixo perto da barra de xp, acima da barra de habilidade."
 *
 * Ele já morou em dois lugares errados. No canto de baixo à direita, com o
 * argumento de que chega sem ser chamado e não deve interromper — mas o
 * argumento vale para um aviso, e este é uma PERGUNTA com prazo: do outro lado
 * há alguém parado esperando, e o convite vence em um minuto. No meio da tela,
 * onde tapava o próprio boneco de quem estava decidindo.
 *
 * O rodapé central resolve os dois: é onde o olho já está (vida, mana, atalhos),
 * e nada de útil fica embaixo do cartão. O `bottom` é posto pelo JS, que MEDE a
 * barra de ações — ela muda de altura com as fileiras de atalhos.
 *
 * ---- E por que ele estava BORRADO ----
 *
 * "e o conviet pra arena ta borrado."
 *
 * Era o `transform: translate(-50%, -50%)` que o centrava. Metade de uma altura
 * ímpar dá meio pixel, e um `transform` com meio pixel não desloca o texto: ele
 * RASTERIZA a camada inteira nessa fração. A letra sai interpolada — borrada,
 * exatamente como ele viu.
 *
 * Agora quem centra é uma régua de largura total com `justify-content: center`.
 * Sem transform nenhum na caixa, o texto volta a ser desenhado direto na grade
 * de pixels. `pointer-events: none` na régua é obrigatório junto: ela atravessa
 * a tela inteira e engoliria todo clique no mapa. O painel retoma.
 * ------------------------------------------------------------------------- */
.arena-desafio {
  position: fixed; z-index: 69;
  left: 0; right: 0; bottom: 150px;
  display: flex; justify-content: center;
  pointer-events: none;
}
.arena-desafio > * { pointer-events: auto; }
.arena-desafio-painel {
  display: grid;
  grid-template-columns: 58px minmax(0, 1fr);
  grid-template-areas: 'boneco texto' 'botoes botoes';
  align-items: center; gap: 8px 10px;
  padding: 11px 13px;
  border: 1px solid #b9975b; border-radius: 10px;
  background: linear-gradient(180deg, rgba(38, 32, 22, .97), rgba(20, 17, 13, .97));
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .6), 0 14px 38px rgba(0, 0, 0, .75), 0 0 44px rgba(185, 151, 91, .16);
  animation: arena-desafio-entra 300ms cubic-bezier(.2, 1.1, .35, 1) both;
}
/*
 * A animação mora no PAINEL e não no cartão: o cartão já usa `transform` para
 * se centrar, e uma animação de `transform` nele apagaria a centragem no
 * primeiro quadro — o cartão nasceria no canto e pularia para o meio.
 */
@keyframes arena-desafio-entra {
  from { opacity: 0; transform: scale(.92); }
  to { opacity: 1; transform: none; }
}

/* Sem boneco, a grade perde a coluna dele — senão sobra um rombo de 58px. */
.arena-desafio-painel.sem-boneco {
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas: 'texto' 'botoes';
}

.arena-desafio-boneco {
  grid-area: boneco;
  display: flex; align-items: flex-end; justify-content: center;
  width: 58px; height: 64px;
  border-radius: 8px; border: 1px solid var(--line-soft);
  background: radial-gradient(ellipse at 50% 95%, #241f14 0%, #0f0d08 74%);
  overflow: hidden;
}
.arena-desafio-boneco canvas { image-rendering: pixelated; }

.arena-desafio-texto { grid-area: texto; display: grid; gap: 1px; min-width: 0; }
.arena-desafio-rotulo {
  font-size: 9.5px; letter-spacing: .16em; text-transform: uppercase; color: #9b927f;
}
.arena-desafio-quem { display: flex; align-items: center; gap: 5px; min-width: 0; }
.arena-desafio-quem b {
  font-size: 13.5px; color: #f0dda8;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.arena-desafio-selo { display: block; flex: none; }
.arena-desafio-elo { font-size: 10px; letter-spacing: .06em; text-transform: uppercase; color: var(--accent); }
.arena-desafio-onde { font-size: 10.5px; color: #9b927f; }

.arena-desafio-botoes { grid-area: botoes; display: flex; gap: 8px; margin-top: 2px; }
.arena-desafio-botoes button { flex: 1 1 auto; }
/* O "Aceitar" reusa o verde do PRONTO da sala, menor: e o mesmo gesto. */
.arena-desafio-botoes button.arena-pronto { padding: 7px 14px; font-size: 12px; letter-spacing: .1em; }

@media (max-width: 560px) {
  /* A régua já tem a largura da tela; o painel é que precisa de teto para não
     encostar nas beiradas. */
  .arena-desafio-painel { max-width: calc(100vw - 20px); }
}

/* ---------------------------------------------------------------------------
 * O DEGRAU DA ARENA: "os bichos ficaram mais fortes"
 *
 * "conforme os bixo fica mais forte tem que aparecer uma msg na tela que ficou
 *  mais forte x%."
 *
 * ---- Em CIMA, e nao no meio ----
 *
 * A contagem de largada mora no meio da tela porque naquele instante nao ha
 * luta para tapar. Esta chega no meio da briga: um painel no centro cobriria
 * justamente os dois bonecos e os bichos que o aviso esta anunciando.
 *
 * O `top` desvia das TRES faixas que ja moram no alto: a barra de cima, o aviso
 * de beta e a tira de novidades. Medido na tela, a ultima delas acaba em 112px
 * — 124 poe o aviso logo abaixo, sem buraco e sem sobreposicao.
 *
 * `pointer-events: none` porque ela passa por cima do mapa e ninguem deve
 * perder um clique por causa de um aviso que vai sumir em quatro segundos.
 * ------------------------------------------------------------------------- */
.arena-onda {
  position: fixed; top: 124px; left: 0; right: 0; z-index: 68;
  display: flex; justify-content: center;
  pointer-events: none;
}
.arena-onda-painel {
  display: flex; align-items: center; gap: 12px;
  padding: 9px 18px 9px 14px;
  border: 1px solid #c0705a; border-radius: 999px;
  background: linear-gradient(180deg, rgba(44, 26, 22, .96), rgba(24, 16, 14, .96));
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .6), 0 10px 30px rgba(0, 0, 0, .7), 0 0 44px rgba(255, 107, 74, .18);
  animation: arena-onda-entra 360ms cubic-bezier(.2, 1.1, .35, 1) both;
}
.arena-onda.saindo .arena-onda-painel { animation: arena-onda-sai 380ms ease-in both; }

/*
 * O passo em numero grande a esquerda: e o unico pedaco que se le de relance, e
 * de relance e como este aviso vai ser lido — quem esta apanhando nao para para
 * ler uma frase.
 */
.arena-onda-passo {
  font-family: var(--font-title); font-size: 24px; line-height: 1;
  color: #ffb08f; text-shadow: 0 2px 0 #0009, 0 0 20px #ff6b4a66;
}
.arena-onda-texto { display: grid; gap: 1px; text-align: left; }
.arena-onda-texto strong { font-size: 12.5px; color: #ffd9c9; letter-spacing: .02em; }
.arena-onda-texto span { font-size: 10.5px; color: #b79a8d; }

@keyframes arena-onda-entra {
  from { opacity: 0; transform: translateY(-14px) scale(.96); }
  to { opacity: 1; transform: none; }
}
@keyframes arena-onda-sai {
  from { opacity: 1; transform: none; }
  to { opacity: 0; transform: translateY(-10px); }
}

@media (max-width: 560px) {
  .arena-onda { top: 96px; }
  .arena-onda-passo { font-size: 19px; }
  .arena-onda-texto strong { font-size: 11px; }
}

/* ---------------------------------------------------------------------------
 * A TELA DE FIM DE LUTA DA ARENA
 *
 * Ela reaproveita o esqueleto da faixa de vitoria de boss (`.vitoria`) porque e
 * a mesma peca: um painel no meio da tela, que entra, espera e sai. O que muda
 * e a COR — e a cor aqui nao e enfeite, e a leitura: quem chega correndo da
 * luta precisa saber se ganhou antes de ler qualquer palavra.
 *
 * Ouro para a vitoria (a mesma paleta da faixa de boss, e de proposito: as duas
 * dizem "voce conseguiu"), e um vermelho fosco para a derrota — fosco, e nao
 * berrante, porque perder aqui nao custa nada e a tela nao deve parecer um
 * castigo.
 * ------------------------------------------------------------------------- */
.arena-fim .arena-fim-painel { min-width: 360px; max-width: min(460px, 92vw); }

.arena-fim.perdeu .arena-fim-painel {
  border-color: #8c5a52;
  background: linear-gradient(180deg, rgba(40, 24, 22, .97), rgba(22, 15, 14, .97));
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .6), 0 18px 48px rgba(0, 0, 0, .75), 0 0 60px rgba(140, 90, 82, .18);
}
.arena-fim.perdeu h2 { color: #e8b2a6; }

/*
 * O selo da patente: grande, com o halo na cor do degrau.
 *
 * `drop-shadow` e nao `box-shadow`: a patente e um PNG recortado, e o box segue
 * o retangulo da imagem — o brilho sairia num quadrado em volta de um brasao.
 */
.arena-fim-selo {
  display: block;
  width: 84px; height: 84px;
  margin: 0 auto 2px;
  filter: drop-shadow(0 0 14px color-mix(in srgb, var(--patente-cor, #e0a84a) 55%, transparent));
}

/*
 * As linhas do que mudou, empilhadas e nao lado a lado.
 *
 * A faixa de boss poe os ganhos em colunas porque sao dois numeros curtos
 * ("+90.750 de experiencia"). Aqui cada linha carrega tres coisas — o sinal, o
 * rotulo e o "de -> para" — e em coluna elas ficariam espremidas uma ao lado da
 * outra, com o texto quebrando no meio.
 */
.arena-fim-conta { flex-direction: column; gap: 8px; align-items: stretch; }
.arena-fim-conta div {
  flex-direction: row; align-items: center; justify-content: center; gap: 8px;
}
.arena-fim-conta b { font-size: 19px; min-width: 38px; text-align: right; }
.arena-fim-conta .subiu b { color: #9fd68a; }
.arena-fim-conta .baixou b { color: #e08a7a; }
.arena-fim-conta span { font-size: 12px; }
.arena-fim-moeda { display: block; flex: none; }

/* "Voce subiu de Bronze para Prata" — a unica linha que a patente merece. */
.arena-fim-patente {
  margin: 12px 0 0; padding-top: 10px;
  border-top: 1px solid rgba(185, 151, 91, .28);
  font-size: 14px; letter-spacing: .02em;
  color: var(--patente-cor, #e0a84a);
  text-shadow: 0 0 12px color-mix(in srgb, var(--patente-cor, #e0a84a) 40%, transparent);
}
.arena-fim-falta { margin: 12px 0 0; font-size: 11.5px; color: #9b927f; }
.arena-fim-placar { margin: 6px 0 0; font-size: 11.5px; color: #9b927f; letter-spacing: .04em; }

/*
 * A frase que fecha. Ela e' para quem perdeu, e por isso nao e cinza-claro de
 * rodape: quem acabou de morrer com o corpo de outra pessoa precisa LER que
 * nada foi perdido, e nao quase ver.
 */
.arena-fim-nota {
  margin: 12px 0 0; padding-top: 10px;
  border-top: 1px solid rgba(185, 151, 91, .18);
  font-size: 12px; line-height: 1.45; color: #cdc3ae;
}

@keyframes vitoria-entra {
  from { opacity: 0; transform: translateY(18px) scale(0.94); }
  to   { opacity: 1; transform: none; }
}

@keyframes vitoria-sai {
  from { opacity: 1; transform: none; }
  to   { opacity: 0; transform: translateY(-14px) scale(0.97); }
}

/* O locker: bau de recompensa em cima, depot embaixo. */
.locker-topo { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.locker-topo h3 { margin: 0; }
/*
 * A grade do bau e do depot.
 *
 * `.grid` sozinha nao existe na folha — o inventario desenha as celulas com
 * regras proprias, e aqui elas cairam empilhadas numa coluna so. Esta grade e'
 * dela mesma: quantas celulas de 34px couberem na largura do modal.
 */
.locker-grade {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(38px, 38px));
  gap: 5px;
  margin-bottom: 14px;
}

/*
 * ---- A caixa do depósito é um QUADRADO, e não uma fileira ----
 *
 * O dono: "os slots não fossem linha única na horizontal, fosse um quadrado com
 * os slots mesmo".
 *
 * `auto-fill` acima enche a largura disponível — numa janela larga, as vinte e
 * cinco vagas viravam uma fileira só. Aqui a contagem de colunas é FIXA (cinco,
 * como o `COLUNAS_DA_CAIXA` do panels.mjs), então a caixa tem o mesmo formato em
 * qualquer largura de tela: cinco por cinco.
 */
/*
 * Classe própria, e não `#modal .locker-grade`: o baú de recompensa de boss usa
 * a MESMA `.locker-grade` nesta mesma janela, e ele tem cem vagas — enquadrá-lo
 * em cinco colunas seria mexer numa tela que ninguém pediu para mexer.
 */
/*
 * Centralizada: a grade tem largura fixa (dez colunas de 44) e a janela e' bem
 * mais larga que ela. Encostada a esquerda, ela ficava com um vazio enorme de um
 * lado so' — e o dono pediu no meio.
 */
.locker-grade.caixa-quadrada {
  grid-template-columns: repeat(10, 44px);
  justify-content: center;
}

/* A vaga vazia: é ela que diz quanto ainda cabe. Sem cursor — não há o que clicar. */
.locker-grade .cell.vaga {
  background: #12181a;
  border-style: dashed;
  border-color: var(--line-soft);
  cursor: default;
}
.locker-grade .cell.vaga:hover { border-color: var(--line-soft); }

/*
 * O balao da peca VESTIDA, ao lado do que o mouse esta olhando.
 *
 * Herda `.tooltip` inteiro — largura, faixa de raridade, cores das linhas — e
 * so acrescenta o selo e um leve apagamento: quem decide e a ficha da direita,
 * a da esquerda esta ali como referencia.
 */
.tooltip.vs { opacity: 0.92; }

.tooltip.vs .vs-selo {
  align-self: flex-start;
  margin-bottom: 6px;
  padding: 2px 7px;
  border-radius: 3px;
  font-size: 10px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: #d9cfb6;
  background: rgba(185, 151, 91, 0.22);
  border: 1px solid rgba(185, 151, 91, 0.4);
}

/*
 * ---- O painel de escolha da magia: texto a esquerda, desenho a direita ----
 *
 * O desenho ficava embaixo das linhas e empurrava o resto do painel para fora
 * da tela. Lado a lado os dois cabem, e a lista de magias ao lado continua
 * visivel enquanto se compara uma com a outra.
 */
.action-resumo {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 18px;
}
.action-resumo-texto { flex: 1 1 auto; min-width: 0; }
/*
 * A moldura da previa, na cor do modal.
 *
 * O desenho flutuava solto ao lado do texto e nao se lia como uma coisa so'.
 * Com a mesma borda e o mesmo fundo dos outros cartoes do painel, ele vira o
 * quadro da magia — que e' o que o dono pediu ao falar em "borda da cor do
 * modal".
 */
.action-resumo .magia-previa,
.ammo-previa .magia-previa {
  flex: 0 0 auto;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  /*
   * ---- Largura para a magia que vai LONGE ----
   *
   * Eram 232px, e uma magia de alvo unico a 7 sqm nao cabe deitada em 232: ela
   * era espremida ate o conjurador e o bicho sairem do quadro. O teto agora e' o
   * do desenho (320px de miolo) mais os 52 de moldura, e a coluna de texto ao
   * lado encolhe sozinha — as linhas dela sao curtas ("25 de mana · 2s de
   * cooldown") e o modal tem 920px de miolo para dividir.
   */
  max-width: 348px;
  text-align: center;
  padding: 0;
}
/*
 * A altura de um quadro cheio mais a legenda. Como o quadro agora encolhe em
 * altura quando a magia e' comprida, sem esta reserva o painel inteiro subia e
 * descia a cada magia clicada na lista.
 *
 * So' no painel de escolha: na tela de municao a previa e' a coluna inteira e
 * nao ha vizinho para ela empurrar.
 */
.action-resumo .magia-previa { min-height: 172px; }
/* A coluna da municao e' estreita, e o teto dela sai da largura da coluna. */
.ammo-previa .magia-previa { max-width: 256px; }
.action-resumo .magia-legenda { font-size: 10px; }

/*
 * O palco desenhado: 32px por casa no canvas, encolhido pelo CSS ate caber.
 * `pixelated` porque o sprite e' arte de pixel — suavizar borra o efeito.
 */
/*
 * ---- O quadro da previa ----
 *
 * A moldura de nove fatias do resto do jogo, VESTINDO o desenho: quem manda no
 * tamanho do miolo e' `palcoDaMagia`, que escreve `width`/`height` em linha
 * (ver `LARGURA_MAXIMA_DO_QUADRO`). Magia comprida estica o quadro para o lado,
 * magia redonda o deixa quadrado, e em nenhum dos dois casos sobra faixa preta
 * — a moldura tem exatamente a medida da arte.
 *
 * As medidas de reserva aqui embaixo valem so' para o instante antes de o
 * script medir, e para o teto: a altura nunca passa de 120px, e e' isso que
 * segura o painel quieto quando se pula de uma magia para outra.
 */
.magia-quadro {
  /*
   * `content-box`, contra o `border-box` que esta folha da a todo mundo.
   *
   * Com `border-box` a medida INCLUIRIA os 52px de moldura, e sobraria miolo de
   * menos para o desenho: ele transbordava e pintava por cima da propria
   * moldura, que sumia da tela. As medidas aqui sao as do MIOLO, e sao as
   * mesmas que `palcoDaMagia` usa para escalar o desenho — as duas pontas
   * precisam falar do mesmo retangulo.
   */
  box-sizing: content-box;
  width: 176px;
  height: 120px;
  max-height: 120px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  /* Nada a cortar — mas se a arte errar por um pixel de arredondamento, ela
     nao vaza por cima do ornamento. */
  overflow: hidden;
}
.magia-palco-arte {
  display: block;
  image-rendering: pixelated;
}

/*
 * O palco: a grade com o boneco por cima, no centro exato.
 *
 * `position` no palco e nao na grade porque a grade e um `grid` e mexer no
 * posicionamento dela desalinharia as casas.
 */
.magia-palco { position: relative; display: inline-block; }
.magia-boneco {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}
/*
 * Semitransparente para as casas atras dele continuarem legiveis: o boneco diz
 * "voce esta aqui", nao esconde a forma da magia.
 */
.magia-boneco canvas {
  image-rendering: pixelated;
  opacity: 0.88;
  filter: drop-shadow(0 0 3px rgba(0, 0, 0, 0.85));
}

/*
 * A magia saindo do centro para as bordas.
 *
 * Cada casa tem o proprio `--atraso`, proporcional a distancia do conjurador —
 * quem monta e o `previaDaMagia`. O laco de 1,8s deixa a forma acesa a maior
 * parte do tempo e reinicia devagar: e uma demonstracao, nao um pisca-pisca.
 */
.action-detail .magia-casa.area,
.action-detail .magia-casa.alcance {
  animation: magia-sai 1800ms var(--atraso, 0ms) infinite;
}

@keyframes magia-sai {
  0%   { opacity: 0.12; transform: scale(0.72); }
  12%  { opacity: 1;    transform: scale(1.12); }
  26%  { opacity: 0.9;  transform: scale(1); }
  82%  { opacity: 0.9;  transform: scale(1); }
  100% { opacity: 0.12; transform: scale(0.72); }
}

/* Quem pediu menos movimento no sistema recebe o desenho parado. */
@media (prefers-reduced-motion: reduce) {
  .action-detail .magia-casa.area,
  .action-detail .magia-casa.alcance { animation: none; }
}

/*
 * ---- A parede de caixas do deposito ----
 *
 * O desenho e o do Depot Chest do client: uma grade de armarios numerados. O
 * contorno aceso marca a caixa que TEM coisa dentro — e a pergunta que se faz
 * ao abrir o deposito ("onde e' que eu guardei aquilo?") se responde de relance.
 */
/* Quatro fileiras de quatro, como o Depot Chest do client dele. */
.deposito-parede {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  margin-bottom: 12px;
  max-width: 520px;
  /* No meio da janela: ela e' bem mais larga que os 520 da parede. */
  margin-inline: auto;
}

.deposito-parede .deposito-caixa {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  padding: 10px 8px;
  text-align: center;
  cursor: pointer;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--panel-2);
  color: var(--text);
}

.deposito-parede .deposito-caixa canvas { image-rendering: pixelated; }

.deposito-parede .deposito-caixa:hover { border-color: var(--accent-dim); }
.deposito-parede .deposito-caixa.cheia { border-color: rgba(185, 151, 91, 0.55); }
.deposito-parede .deposito-caixa b { font-size: 12px; }
.deposito-parede .deposito-caixa span { font-size: 10px; color: var(--muted); }

.deposito-titulo { margin-bottom: 6px; }

.deposito-paginas {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  margin-top: 6px;
}
.deposito-paginas span { font-size: 11px; color: var(--muted); }
.deposito-paginas button { min-width: 34px; }

/* O "+" do chat, ao lado da engrenagem: mesmo botao, outro glifo. */
.window-header .chat-mais { font-size: 15px; line-height: 1; }

/*
 * A tela de munição: a grade de flechas à esquerda, a prévia do que ela faz à
 * direita. Mesma ideia do painel de magias — o desenho fica ao lado da escolha,
 * e não embaixo, para os dois caberem sem rolagem.
 */
.ammo-lado { display: flex; align-items: flex-start; gap: 16px; }
.ammo-lado .ammo-grid { flex: 1 1 auto; min-width: 0; }
.ammo-previa {
  flex: 0 0 auto;
  /*
   * 300 e nao 236: o quadro da previa passou a acompanhar o feitio do desenho,
   * e uma flecha de alcance 6 e' uma tira deitada. Nos 236 antigos ela nao
   * cabia — e nao caber, agora que nada mais e' cortado, seria o desenho
   * passando por fora da coluna.
   */
  width: 300px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  text-align: center;
  padding: 10px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--panel-2);
}
.ammo-previa b { font-family: var(--font-heading); font-size: 13px; font-weight: 600; }
.ammo-previa em { font-size: 10px; color: var(--muted); font-style: normal; letter-spacing: .04em; }
/* `border-top` e' da versao do balao, em que a previa fica embaixo do texto. */
.ammo-previa .magia-previa { border-top: 0; }

/*
 * ---- O modal "solto": avisa sem trancar o jogo ----
 *
 * `#modal` cobre a tela e engole todo o ponteiro — e' o certo para uma compra
 * ou uma confirmacao. Para o deposito e' o contrario do que se quer: guardar um
 * item e' arrastar da MOCHILA para a caixa, e a mochila estava atras do fundo.
 *
 * Aqui o fundo fica transparente e deixa o ponteiro passar; so a caixa escuta.
 */
#modal.solto { background: none; pointer-events: none; }
#modal.solto .modal-box { pointer-events: auto; }

/* A grade da caixa aceita item arrastado; acende inteira ao passar por cima. */
/*
 * As duas caixas que recebem peça arrastada: a do depósito e o baú da guilda. Duas
 * classes e uma regra — a moldura do arrasto é a mesma, mas o NOME não pode ser, que
 * é por ele que `caixaDoDepositoAberta` descobre se há caixa do depósito na tela.
 */
.deposito-alvo, .guilda-bau-alvo { min-height: 46px; border: 1px dashed transparent; border-radius: 6px; padding: 4px; }
.deposito-alvo.drop-target, .guilda-bau-alvo.drop-target { border-color: var(--accent-dim); background: rgba(63, 191, 168, 0.08); }

/* A sacola do boss no baú: o número é quantos tipos de item ela guarda. */
.locker-grade .cell.sacola { cursor: pointer; }
.locker-grade .cell.sacola:hover { border-color: var(--accent-dim); }
/*
 * A sacola que esta aberta para olhar (botao direito). O contorno e' o unico
 * jeito de ligar a lista que aparece embaixo a' sacola de que ela veio.
 */
.locker-grade .cell.sacola.aberta { border-color: var(--accent); background: #16241f; }
.sacola-aberta {
  margin: -6px 0 14px;
  padding: 9px 10px 2px;
  border: 1px solid var(--line); border-radius: 8px; background: var(--panel-2);
}
.sacola-aberta .locker-topo { margin-bottom: 8px; }
.sacola-aberta h4 { margin: 0; font-size: 12px; }
.sacola-aberta .sacola-prazo { margin-right: auto; font-size: 11px; color: var(--muted); }
.sacola-aberta .locker-grade { margin-bottom: 8px; }

/* O balao da sacola: o que tem dentro, com desenho e quantidade. */
.tip-sacola { display: grid; gap: 6px; min-width: 190px; max-width: 260px; }
.tip-sacola-prazo { font-size: 11px; color: var(--muted); }
.tip-sacola-itens { display: grid; gap: 3px; max-height: 220px; overflow: hidden; }
.tip-sacola-item { display: flex; align-items: center; gap: 7px; font-size: 12px; }
.tip-sacola-item canvas { flex: none; image-rendering: pixelated; }
.tip-sacola-item span { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tip-sacola-item b { flex: none; color: var(--accent); font-size: 11px; }
.tip-sacola-dica { font-size: 10px; color: var(--muted); border-top: 1px solid var(--line-soft); padding-top: 5px; }

/* O que caiu, dentro da faixa de vitória. */
.vitoria-caiu { margin: 14px 0 6px; font-size: 11px; color: #9b927f; }
/*
 * Sai o loot INTEIRO (ver `mostrarVitoria`), entao o teto passou a ser de
 * altura: seis fileiras cabem sem empurrar a faixa para fora da tela, e o resto
 * rola por dentro. Um "+6" no lugar da rolagem escondia justamente o que a
 * faixa existe para mostrar.
 */
.vitoria-loot {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  justify-content: center;
  max-width: 340px;
  max-height: 210px;
  overflow-y: auto;
  padding-right: 2px;
}

/* Aba que existe mas ainda nao tem conteudo — ver `renderArena`. */
.em-obras { text-align: center; padding: 28px 18px; color: var(--muted); }
.em-obras h3 { margin: 0 0 8px; color: var(--copper); font-size: 15px; }
.em-obras .shop-note { max-width: 460px; margin: 0 auto; }

/*
 * ---- Os tres encaixes numa linha so ----
 *
 * `Imbuements   strike 19h, vazio, vazio` — o formato do servidor dele. Cada
 * encaixe cheio leva a cor do que ele faz (as mesmas classes do resto do balao),
 * o relogio sai menor logo ao lado, e o vazio fica apagado.
 */
.tip-rules div.imbue { align-items: flex-start; }
.tip-imbuements { display: inline; text-align: right; font-weight: 400; }
.tip-imbue-vazio { font-style: normal; color: #46565a; }
.tip-imbue-virgula { font-style: normal; color: #46565a; }
.tip-imbue-cheio { font-style: normal; white-space: nowrap; }
.tip-imbue-cheio em { font-style: normal; color: var(--muted); font-size: 10px; margin-left: 4px; }
.tip-imbue-cheio.el-physical span { color: #ff5a4a; }
.tip-imbue-cheio.el-fire span { color: #ff9a3c; }
.tip-imbue-cheio.el-ice span { color: #7fd4ff; }
.tip-imbue-cheio.el-earth span { color: #5ad86a; }
.tip-imbue-cheio.el-energy span { color: #c98aff; }
.tip-imbue-cheio.el-holy span { color: #ffe066; }
.tip-imbue-cheio.el-death span { color: #d05a6a; }
.tip-imbue-cheio.speed span { color: #7fd4ff; }
.tip-imbue-cheio.crit span { color: #ff9a3c; }
.tip-imbue-cheio.leech span { color: #4fbf8b; }
.tip-imbue-cheio.mana span { color: #4f8fd0; }
.tip-imbue-cheio.skill span { color: var(--accent); }
.tip-imbue-cheio.plain span { color: var(--text); }

/*
 * ---- O painel de configurar acao usa as cores do balao da barra ----
 *
 * As classes sao as mesmas que `fichaDeAcao` ja usava dentro do balao
 * (`acao-*` no bloco, `el-*`/`heal`/`atk`/`area` em cada linha). Aqui elas
 * ganham efeito tambem no painel de escolha, que saia todo cinza — duas telas
 * falando da mesma magia com aparencias diferentes.
 *
 * A `--tier` vem da familia `.acao-*` logo acima e e' a mesma cor da faixa do
 * balao: dourada para ataque, teal para cura, violeta para suporte.
 */
.action-resumo .action-head b { color: var(--tier, var(--text)); }
.action-resumo-texto p.atk { color: #ff5a4a; }
.action-resumo-texto p.heal { color: #57e0a8; }
.action-resumo-texto p.mana { color: #6fa8ff; }
.action-resumo-texto p.area { color: #b184e8; }
.action-resumo-texto p.ouro { color: var(--exp); }
.action-resumo-texto p.plain { color: var(--muted); }
.action-resumo-texto p.el-physical { color: #ff5a4a; }
.action-resumo-texto p.el-fire { color: #ff9a3c; }
.action-resumo-texto p.el-ice { color: #7fd4ff; }
.action-resumo-texto p.el-earth { color: #5ad86a; }
.action-resumo-texto p.el-energy { color: #c98aff; }
.action-resumo-texto p.el-holy { color: #ffe066; }
.action-resumo-texto p.el-death { color: #d05a6a; }
.action-resumo-texto p.el-drown { color: #5ad8d8; }
.action-resumo-texto p.el-poison { color: #9ad84a; }
.action-resumo-texto p.el-lifedrain { color: #ff7a8a; }
.action-resumo-texto p.el-manadrain { color: #6fa8ff; }
/*
 * A lista da esquerda tambem: o nome de cada magia na cor da funcao dela, para
 * a escolha ja comecar colorida em vez de virar cor so' depois de clicada.
 */
.action-item.acao-cura b, .action-item.acao-ataque b,
.action-item.acao-suporte b, .action-item.acao-item b { color: var(--tier); }
.action-item.acao-bloqueada b { color: var(--tier); opacity: .8; }

/*
 * ---- A aba de uma conversa privada ----
 *
 * Ela nasce e morre com a conversa, entao leva o X que a fecha. O nome fica em
 * italico para se distinguir de relance dos canais fixos, que sao do servidor e
 * nao vao a lugar nenhum.
 */
.chat-tabs .chat-conversa { font-style: italic; padding-right: 4px; }
/*
 * ---- O × de fechar NÃO é uma marca de mensagem ----
 *
 * Ele é um `<i>` dentro do botão da aba, e por isso herdava a pílula da regra
 * de cima: um quadrado laranja de fundo atrás do ×, do lado do nome da pessoa.
 * O `color` daqui trocava a cor da letra e deixava o fundo intacto — e o
 * defeito só aparecia nas abas de conversa, as únicas que fecham.
 *
 * Fundo nenhum no descanso; o vermelho aparece no hover, que é quando o ×
 * anuncia o que faz.
 */
.chat-tabs .chat-fecha {
  font-style: normal; margin-left: 5px; padding: 0 3px; border-radius: 3px;
  color: var(--muted); font-size: 12px; line-height: 1;
  background: transparent;
}
.chat-tabs .chat-fecha:hover { color: var(--danger); background: #2a1a1a; }
/*
 * A bolinha de online da conversa, antes do nome: verde com o jogo aberto,
 * vermelha offline ou com a aba fechada. Pequena como o ponto do contador de
 * online, e sem a pílula laranja que o `<i>` da aba herdaria.
 */
.chat-tabs button i.chat-presenca {
  display: inline-block; vertical-align: middle; width: 6px; height: 6px; padding: 0;
  margin: -1px 5px 0 0; border-radius: 50%; font-size: 0; line-height: 0;
  background: #56666c; box-shadow: none;
}
.chat-tabs button i.chat-presenca.on { background: #3fd07a; box-shadow: 0 0 5px #3fd07aaa; }
.chat-tabs button i.chat-presenca.off,
.chat-tabs button i.chat-presenca.fechada { background: #e0463c; box-shadow: 0 0 5px #e0463c99; }
/* O aviso "fulano está offline" dentro da conversa. */
.chat-log .privado-aviso { color: #e88a7f; font-style: italic; }

/*
 * ================= A MOLDURA DE LOGIN, ONDE ELA CABE =================
 *
 * Primeiro ela foi para TODO cartao — hunt, arena, treino, banco, prey, charm,
 * caixa do deposito, criatura. O dono olhou e mandou desfazer quase tudo: a
 * moldura em volta do cartao MAIS a moldura em volta da criatura dentro dele
 * viravam dois quadros encaixados, e o cartao sumia no meio deles.
 *
 * O que ficou e' o que ele escolheu ver emoldurado:
 *
 *   · a sala de BOSS — o cartao de uma luta que so' acontece de doze em doze
 *     horas nao e' um item de lista;
 *   · os botoes que COMECAM a cacada — "Caca Automatica", "Caca Online" e
 *     "Enfrentar", que sao o ultimo clique antes de o personagem sair.
 *
 * Todo o resto voltou ao retangulo de 1px de antes: as regras originais nunca
 * foram editadas, so' sobrescritas por este bloco. Encolher o bloco desfaz.
 *
 * `border-image` ignora `border-radius` e ignora `border-color`, entao hover e
 * selecionado nao sao borda aqui: sao brilho e contorno interno.
 */
.hunt-card.boss,
.run-mode,
.enfrentar {
  border-style: solid;
  /*
   * 30px porque o canto ornamentado da arte tem ~104px de 1212: abaixo de uns
   * 26 ele vira um risco escuro e a moldura some. Foi medido na previa de
   * magia, que passou pelo mesmo problema com 14px.
   */
  border-width: 30px;
  border-image-source: url('/client/assets/ui/panel-frame.webp');
  border-image-slice: 110 fill;
  border-image-repeat: stretch;
  border-radius: 0;
  background: none;
  box-shadow: none;
  padding: 0;
  image-rendering: auto; /* arte em alta, nao pixel art */
}
/* O botao de comecar e' largo e baixo: moldura mais fina em cima e embaixo. */
.run-mode,
.enfrentar { border-width: 20px 30px; color: var(--text); }
.enfrentar { font-family: var(--font-heading); letter-spacing: .06em; }
.hunt-card.boss { gap: 5px; }

.hunt-card.boss:hover:not(.locked),
.run-mode:hover:not(:disabled),
.enfrentar:hover:not(:disabled) { filter: brightness(1.18); }
.hunt-card.boss[data-active="true"],
.run-mode.escolhido {
  outline: 1px solid var(--accent);
  outline-offset: -7px;
  filter: brightness(1.12);
}
.hunt-card.boss.locked,
.run-mode:disabled { filter: grayscale(.5) brightness(.7); }

/*
 * ---- E a moldura de JANELA nos cartoes de hunt, treino e arena ----
 *
 * A de login ficou para o que e' decisao grande (a sala de boss, o botao que
 * comeca a cacada). Estes tres sao lista — o jogador passa os olhos por seis
 * hunts —, e a moldura de janela e' a certa para isso: e' a mesma do inventario
 * e da mochila, que e' onde ele ja esta acostumado a olhar item atras de item.
 *
 * A criatura dentro do cartao continua SEM moldura: cartao emoldurado com
 * bicho emoldurado dentro viravam dois quadros encaixados, e foi o que ele
 * mandou desfazer.
 */
.hunt-card:not(.boss),
.arena-card,
.train-grid button {
  border-style: solid;
  border-width: 26px 18px 20px 18px;
  border-image-source: url(/client/assets/ui/padrao.png);
  border-image-slice: 150 110 130 110 fill;
  border-image-repeat: stretch;
  border-radius: 0;
  background: none;
  box-shadow: none;
  padding: 0;
}
.hunt-card:not(.boss) { gap: 5px; }
.train-grid button { gap: 2px; }

.hunt-card:not(.boss):hover:not(.locked),
.arena-card:hover:not(:disabled),
.train-grid button:hover:not(:disabled) { filter: brightness(1.18); }
.hunt-card:not(.boss)[data-active="true"],
.arena-card.cleared,
.train-grid button[aria-selected="true"] {
  outline: 1px solid var(--accent);
  outline-offset: -6px;
  filter: brightness(1.12);
}
.hunt-card:not(.boss).locked,
.arena-card:disabled,
.train-grid button:disabled { filter: grayscale(.5) brightness(.7); }

/*
 * ---- E a moldura de LOGIN em cada item da loja ----
 *
 * A vitrine ja tem a moldura dourada propria em volta do modal inteiro
 * (`.modal-box.store`), e o dono pediu a mesma ideia item a item: cada coisa a
 * venda dentro do proprio quadro, como um produto exposto.
 *
 * O botao de comprar continua sendo botao — ele nao ganha moldura nenhuma, ou o
 * cartao viraria dois quadros encaixados, que foi o que ele mandou desfazer nos
 * cartoes de hunt.
 */
.store-card {
  border-style: solid;
  border-width: 26px;
  border-image-source: url('/client/assets/ui/panel-frame.webp');
  border-image-slice: 110 fill;
  border-image-repeat: stretch;
  border-radius: 0;
  background: none;
  box-shadow: none;
  padding: 0;
  gap: 5px;
  image-rendering: auto;
}
.store-card:hover { filter: brightness(1.12); }
.store-card.owned { filter: grayscale(.55) brightness(.8); }

/*
 * ---- E a mesma moldura nos outfits e nas montarias da loja ----
 *
 * A vitrine de servicos (premium, blessings, prey slot) ja' vendia cada coisa
 * dentro do proprio quadro; as abas de outfit e montaria — que sao a parte da
 * loja em que o desenho E' o produto — continuavam com o retangulo de 1px. Duas
 * metades da mesma loja com aparencias diferentes, e a metade sem moldura era a
 * mais visual das duas.
 *
 * `border-image` ignora `border-color` e `border-radius`, entao o selecionado e
 * o ja-adquirido nao podem ser cor de borda: viram contorno por dentro e
 * filtro, como nos cartoes de hunt.
 */
.mount-card {
  border-style: solid;
  border-width: 26px;
  border-image-source: url('/client/assets/ui/panel-frame.webp');
  border-image-slice: 110 fill;
  border-image-repeat: stretch;
  border-radius: 0;
  background: none;
  box-shadow: none;
  padding: 0;
  gap: 4px;
  image-rendering: auto; /* arte em alta, nao pixel art */
}
.mount-card:hover:not(:disabled) { filter: brightness(1.14); }
.mount-card[aria-selected="true"] {
  outline: 1px solid var(--accent);
  outline-offset: -8px;
  filter: brightness(1.1);
}

/*
 * ---- E a moldura de JANELA nos painies de coleção ----
 *
 * Charms, proficiência, imbuements e prey: as quatro telas em que o jogador
 * fica escolhendo entre muitos quadradinhos, um de cada vez. E' a mesma leitura
 * do inventario, e por isso leva a mesma moldura dele — a sobria, de regua
 * fina, e nao a dourada de login (essa ficou para a sala de boss, para os
 * botoes que comecam a cacada e para a vitrine da loja).
 *
 * As linhas de imbuement (`.imbue-row`) sao LINHA e nao cartao: emoldurar cada
 * uma daria trinta quadros empilhados. Quem ganha moldura ali e' a peca em
 * foco, que e' o cartao da tela.
 */
/*
 * `.prof-art` saiu desta lista.
 *
 * Ele e' o retrato da ARMA, e emoldurar um item com a moldura de janela punha o
 * ornamento POR DENTRO do quadro do item — o desenho da borda comendo o sprite
 * pela beirada, que foi o que o dono viu e apontou. Agora ele usa o aro do
 * weapon mastery (`border-weaponmasterytreeicons`), que tem o miolo vazado e
 * cerca o item por fora. Ver `.prof-art` la' em cima.
 */
.charm-card,
.prey-slot,
.prof-column,
.imbue-focus {
  border-style: solid;
  border-width: 24px 16px 18px 16px;
  border-image-source: url(/client/assets/ui/padrao.png);
  border-image-slice: 150 110 130 110 fill;
  border-image-repeat: stretch;
  border-radius: 0;
  background: none;
  box-shadow: none;
  padding: 0;
}
/*
 * ---- Uma moldura POR GRAU do imbuement ----
 *
 * Os tres graus eram tres caixas iguais com a borda tingida de cinza, teal e
 * dourado — um fio de 1px dizendo que um custa 7.500 e o outro 250.000. O dono
 * escolheu, um por um, com qual moldura do jogo cada grau devia se parecer, e a
 * escolha tem logica: cada moldura ja' carrega um peso que o jogador aprendeu
 * em outro lugar da tela.
 *
 *   BASIC     a moldura do INVENTARIO (`padrao.png`, a mesma de `.window`) —
 *             a de janela, sobria, a que ele ve o tempo todo. E' o grau comum.
 *   INTRICATE a moldura da MINEIROIDLE STORE (`prastore.png`, a de `.modal-box.store`)
 *             — a da vitrine, um degrau acima da de janela.
 *   POWERFUL  a moldura dos BOSSES (`panel-frame.webp`, a de `.hunt-card.boss`
 *             e a da tela de login) — a dourada, reservada para o que e' raro.
 *
 * ---- E as fatias sao as DE CADA ARQUIVO ----
 *
 * Houve uma tentativa de igualar a espessura dos tres em 24px, com artes
 * recortadas para isso. Nao ficou: numa moldura de nove fatias, mexer no
 * numero muda ONDE a imagem e' cortada, e as duas de janela nao aguentam ser
 * cortadas como a dourada — o ornamento se desmontava. O dono mandou voltar
 * para esta versao, e ela e' a que respeita a proporcao de cada arte: as fatias
 * sao as do arquivo, e a espessura acompanha a fatia.
 *
 * O `fill` faz a fatia central pintar o fundo, e por isso o `background` e a
 * borda de 1px de antes saem: dois fundos empilhados deixariam o miolo mais
 * escuro do que o resto da moldura.
 *
 * `border-image` ignora `border-color`, entao as regras `.grau-1/2/3` la' de
 * cima continuam escritas mas nao pintam mais nada — quem diz o grau agora e' a
 * propria moldura, e a cor ficou so' no nome.
 */
.imbue-grau,
.imbue-ativo.grau-1,
.imbue-ativo.grau-2,
.imbue-ativo.grau-3 {
  border-style: solid;
  border-radius: 0;
  background: none;
  box-shadow: none;
  padding: 0;
  border-image-repeat: stretch;
}
/* Basic: a moldura de janela, a mesma do inventario e da mochila. */
.imbue-grau.grau-1,
.imbue-ativo.grau-1 {
  border-width: 24px 16px 18px 16px;
  border-image-source: url(/client/assets/ui/padrao.png);
  border-image-slice: 150 110 130 110 fill;
}
/* Intricate: a moldura da vitrine, a que se ve ao abrir a Mineiroidle Store. */
.imbue-grau.grau-2,
.imbue-ativo.grau-2 {
  border-width: 26px 17px 19px 17px;
  border-image-source: url(/client/assets/ui/prastore.png);
  border-image-slice: 150 105 135 105 fill;
}
/*
 * Powerful: a dourada dos bosses. As quatro fatias sao iguais (110 de 1212),
 * entao a espessura tambem e' — encolher so' um lado deforma o ornamento.
 */
.imbue-grau.grau-3,
.imbue-ativo.grau-3 {
  border-width: 24px;
  border-image-source: url('/client/assets/ui/panel-frame.webp');
  border-image-slice: 110 fill;
  image-rendering: auto; /* arte em alta, nao pixel art */
}
.imbue-grau { gap: 5px; }
/*
 * O respiro voltou para DENTRO, no conteudo.
 *
 * O `padding: 0` ali em cima e' obrigatorio — com `border-image` o padding
 * empurraria o texto para longe da moldura e o cartao ficaria oco no meio —,
 * mas sem folga nenhuma o texto encosta na beirada interna do ornamento.
 */
.imbue-grau > * { margin-inline: 2px; }
.imbue-grau:hover { filter: brightness(1.1); }

/*
 * ---- E a moldura do grau tambem no imbuement JA' APLICADO ----
 *
 * A lista de "o que esta ativo nesta peca" mostrava toda linha igual, com a
 * borda de 1px de sempre. Quem gastou 250.000 num powerful via o mesmo
 * retangulo cinza de quem gastou 7.500 num basic — e a linha e' justamente onde
 * o jogador confere o que comprou. Cada linha leva a moldura do grau DELA, a
 * mesma da vitrine logo abaixo.
 *
 * As espessuras sao as do cartao encolhidas na mesma proporcao: a linha e' baixa
 * e a moldura cheia dobraria a altura dela.
 */
.imbue-active > .imbue-ativo { gap: 11px; }
.imbue-active > .imbue-ativo.grau-1 { border-width: 18px 12px 14px 12px; }
.imbue-active > .imbue-ativo.grau-2 { border-width: 20px 13px 14px 13px; }
.imbue-active > .imbue-ativo.grau-3 { border-width: 18px; }

.charm-card:hover,
.prof-column:hover { filter: brightness(1.15); }
.charm-card.owned { outline: 1px solid var(--accent-dim); outline-offset: -6px; }
.prey-slot.locked { background: none; filter: grayscale(.5) brightness(.8); }

/* ---------- árvore de habilidades ---------- */

/*
 * A arte manda no tamanho.
 *
 * Ela tem proporção fixa (4:5) e é ela que carrega a moldura; o canvas do
 * caminho e a dica são posicionados EM CIMA dela, em fração. Por isso o quadro
 * é `position: relative` e a imagem entra como bloco, não como background:
 * background não tem `onload`, e sem o `onload` não há quando medir.
 */
.arvore { display: grid; grid-template-columns: 196px minmax(0, 1fr) 260px; gap: 14px; align-items: start; }
.arvore-quadro { position: relative; line-height: 0; }
.arvore-arte { width: 100%; height: auto; display: block; border-radius: 6px; }
/* Sem a imagem da vocação, sobra a ardósia — o painel continua utilizável. */
.arvore-quadro.sem-arte {
  aspect-ratio: 1024 / 1536; background: #141813;
  border: 1px solid var(--line); border-radius: 6px;
}
.arvore-quadro.sem-arte .arvore-arte { display: none; }
.arvore-tela { position: absolute; inset: 0; }

.arvore-dica {
  position: absolute; z-index: 3; pointer-events: none;
  display: grid; gap: 2px; padding: 8px 10px; min-width: 170px;
  background: var(--panel-solid); border: 1px solid var(--accent-dim); border-radius: 6px;
  line-height: 1.4; box-shadow: 0 10px 26px #000a;
}
.arvore-dica b { font-family: var(--font-heading); font-size: 13px; color: var(--accent); }
.arvore-dica span { font-size: 12px; color: var(--text); }
.arvore-dica em { font-style: normal; font-size: 12px; color: var(--muted); }
.arvore-dica small { font-size: 11px; color: var(--copper); }

.arvore-lado { display: grid; gap: 10px; align-content: start; }
.arvore-placar {
  display: grid; justify-items: center; gap: 1px; padding: 12px;
  background: var(--panel-2); border: 1px solid var(--accent-dim); border-radius: 6px;
}
.arvore-placar b { font-family: var(--font-heading); font-size: 30px; color: var(--accent); }
.arvore-placar span { font-size: 12px; color: var(--text); }
.arvore-placar em { font-style: normal; font-size: 11px; color: var(--muted); }

.arvore-ramo {
  display: grid; gap: 3px; padding: 8px 10px;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 6px;
}
.arvore-ramo-topo { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.arvore-ramo-topo b { font-family: var(--font-heading); font-size: 13px; color: var(--text); }
.arvore-ramo-topo span { font-size: 12px; color: var(--accent); }
.arvore-ramo small { font-size: 11px; color: var(--muted); }
.arvore-preco { color: var(--danger) !important; }
.arvore-barra { height: 3px; background: var(--line); border-radius: 2px; overflow: hidden; }
.arvore-barra i { display: block; height: 100%; background: var(--accent); }

.arvore-resumo {
  display: grid; gap: 3px; padding: 10px;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 6px;
}
.arvore-resumo h4 {
  margin: 0 0 3px; font-size: 11px; color: var(--muted);
  text-transform: uppercase; letter-spacing: .06em; font-weight: 600;
}
.arvore-resumo div { display: flex; justify-content: space-between; gap: 10px; font-size: 12px; color: var(--muted); }
.arvore-resumo div b { color: var(--accent); font-weight: 500; }
/* O que o ramo COBRA aparece junto, e em vermelho. Preço escondido é propaganda. */
.arvore-resumo div.custa b { color: var(--danger); }

/* ---- o que a árvore dá: ícone, rótulo, número ---- */
/* A linha virou três colunas: o ícone deixa reconhecer a linha sem ler, e o
   número fica encostado à direita para as casas alinharem entre si. */
.arvore-resumo div { align-items: center; }
.arvore-ico {
  width: 16px; height: 16px; flex: 0 0 16px; object-fit: contain;
  image-rendering: pixelated; opacity: .85;
}
.arvore-resumo div span { flex: 1; }
.arvore-resumo div b { font-variant-numeric: tabular-nums; }
/* Quem tem procedência ganha tracinho: avisa que passar o mouse diz de onde veio. */
.arvore-resumo div.tem-fonte { cursor: help; }
.arvore-resumo div.tem-fonte span { border-bottom: 1px dotted var(--line); }

/* ---- a previsão por level, embaixo do placar ---- */
.arvore-placar .arvore-previsao { font-size: 11px; color: var(--muted); text-align: center; margin-top: 3px; }

/* ---- as habilidades dos medalhões: apagadas até o medalhão completar ---- */
.arvore-especiais small { font-size: 11px; color: var(--muted); line-height: 1.35; margin: -1px 0 5px; }
.arvore-especiais div.apagada span { color: var(--muted); }
.arvore-especiais div.apagada b { color: var(--muted); }
.arvore-especiais div.ativa span { color: var(--text); }
.arvore-dica .arvore-dica-especial { margin-top: 4px; }
.arvore-especiais .arvore-hab-botao { padding: 1px 8px; font-size: 11px; flex: 0 0 auto; }
.arvore-especiais .arvore-vagas-dica { margin: -2px 0 6px; }
.arvore-montagens div { gap: 6px; }
.arvore-montagens div.vazia span { color: var(--muted); font-style: italic; }
.arvore-montagens div.cheia span { color: var(--text); }
/* ---- cada habilidade é um grupo: a linha, o texto e, se travada, o que falta ---- */
.arvore-especiais .arvore-hab { display: grid; gap: 1px; margin-bottom: 6px; }
.arvore-especiais .arvore-hab > small { margin: 0; }
.arvore-especiais .arvore-hab.bloqueada { opacity: .5; }
.arvore-especiais .arvore-hab.bloqueada span { color: var(--muted); }
.arvore-especiais .arvore-hab.disponivel span { color: var(--text); }
.arvore-especiais .arvore-hab-falta { color: var(--danger) !important; font-style: italic; }
.arvore-montagens div { flex-wrap: wrap; }
.arvore-montagens div span { flex: 1 1 100%; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.arvore-montagens .arvore-hab-botao { white-space: nowrap; }

/* ---- o rumo sem ação continua recebendo o mouse, para o quadro abrir ---- */
.arvore-rumo.desligado { opacity: .55; cursor: default; }
.arvore-rumos .arvore-zerar { margin-top: 6px; }

/* ---- "como ficaria": o quadro que abre ao parar o mouse num rumo ---- */
.arvore-quadro-rumo {
  position: fixed; z-index: 60; width: 290px; max-height: 80vh; overflow-y: auto;
  display: grid; gap: 4px; padding: 10px 12px;
  background: var(--panel); border: 1px solid var(--accent-dim); border-radius: 8px;
  box-shadow: 0 10px 28px rgba(0, 0, 0, .55); pointer-events: none;
}
.arvore-quadro-rumo-titulo { font-family: var(--font-heading); font-size: 13px; color: var(--accent); }
.arvore-quadro-rumo > small { font-size: 11px; color: var(--muted); margin-bottom: 4px; }
.arvore-quadro-rumo-lista { display: grid; gap: 2px; }
.arvore-quadro-rumo-lista div { display: grid; grid-template-columns: 16px 1fr auto 52px; align-items: center; gap: 6px; font-size: 12px; color: var(--muted); }
.arvore-quadro-rumo-lista b { color: var(--text); font-weight: 500; font-variant-numeric: tabular-nums; }
.arvore-quadro-rumo-lista i { font-style: normal; font-size: 11px; text-align: right; font-variant-numeric: tabular-nums; }
.arvore-quadro-rumo-lista i.ganha { color: var(--accent); }
.arvore-quadro-rumo-lista i.custa { color: var(--danger); }
.arvore-quadro-rumo-hab { display: grid; gap: 1px; margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--line); }
.arvore-quadro-rumo-hab b { font-size: 12px; color: var(--accent); }
.arvore-quadro-rumo-hab small { font-size: 11px; color: var(--muted); line-height: 1.35; }

/* ---- aplicar e cancelar ---- */
.arvore-acoes { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.arvore-acoes button { padding: 7px 0; font-size: 12px; }
.arvore-acoes button:disabled { opacity: .4; cursor: default; }

/* O placar acende quando há rascunho por aplicar — é o aviso de que a tela
   mostra uma PROPOSTA, e não o que o personagem tem. */
.arvore-placar.mexido { border-color: #8fbcd8; background: rgba(143, 188, 216, .08); }
.arvore-mexido {
  font-style: normal; font-size: 11px; color: #8fbcd8; margin-top: 2px;
}

/* ---- predefinições ---- */
.arvore-pre { display: grid; grid-template-columns: 1fr auto auto auto; gap: 5px; }
.arvore-pre select {
  min-width: 0; font-size: 11.5px; padding: 5px 6px;
  background: var(--panel-2); color: var(--text);
  border: 1px solid var(--line); border-radius: 5px;
}
.arvore-pre button { padding: 5px 9px; font-size: 11.5px; }
.arvore-pre button:disabled { opacity: .4; cursor: default; }
.arvore-pre-nome {
  width: 100%; margin: 8px 0 4px; padding: 8px 10px; font-size: 13px;
  background: var(--panel-2); color: var(--text);
  border: 1px solid var(--accent-dim); border-radius: 5px;
}
.arvore-zerar { margin-top: 2px; }
.arvore-zerar:disabled { opacity: .4; cursor: default; }

/*
 * ---- A moldura dos bosses nos quadros da coluna da direita ----
 *
 * É a mesma `panel-frame.webp` de `.hunt-card.boss`, e ela entra por
 * `border-image` — o que significa que a borda VIRA o desenho, e a largura dela
 * é quanto de moldura aparece.
 *
 * 30px, que é o valor da sala de boss, comeria estes quadros inteiros: eles são
 * curtos, e sobrariam trinta de moldura em cima e embaixo de duas linhas de
 * texto. 22 na horizontal e 18 na vertical é o menor par em que o canto
 * ornamentado ainda se lê como canto, e não como um risco escuro.
 *
 * `border-image` ignora `border-radius` e `border-color`, então o realce de
 * rascunho no placar deixou de ser borda e passou a ser contorno interno.
 */
.arvore-placar,
.arvore-ramo,
.arvore-resumo {
  border-style: solid;
  border-width: 18px 22px;
  border-image-source: url('/client/assets/ui/panel-frame.webp');
  border-image-slice: 110 fill;
  border-image-repeat: stretch;
  border-radius: 0;
  background: none;
  box-shadow: none;
  padding: 0;
  image-rendering: auto; /* arte em alta, não pixel art */
}
.arvore-placar { padding: 2px 0 6px; }
.arvore-ramo { gap: 3px; }
.arvore-resumo h4 { margin-top: 0; }
/* Sem borda para pintar, o aviso de rascunho vira contorno por dentro. */
.arvore-placar.mexido {
  background: none;
  outline: 1px solid #8fbcd8;
  outline-offset: -6px;
}

/* ---- o balão do ícone da barra ---- */
.tip-arvore { display: grid; gap: 3px; margin-top: 6px; min-width: 172px; }
.tip-arvore > b { color: var(--accent); font-size: 12px; }
.tip-arvore > em { font-style: normal; font-size: 11px; color: var(--muted); }
.tip-arvore div {
  display: flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--muted);
}
.tip-arvore div span { flex: 1; }
.tip-arvore div b { color: var(--text); font-variant-numeric: tabular-nums; }
.tip-arvore div.custa b { color: var(--danger); }
.tip-arvore .arvore-ico { width: 14px; height: 14px; flex: 0 0 14px; }

/*
 * ---- As três vias, no alto da coluna ----
 *
 * Numa treliça a decisão é POR ONDE ir, e essa é a única maneira de ver isso
 * sem contar bolinha na arte. Fica antes das listas de bônus de propósito: o
 * rumo explica os números que vêm abaixo dele.
 */
.arvore-vias {
  display: grid; gap: 2px; padding: 8px 10px;
  border: 1px solid var(--accent-dim); border-radius: 6px; background: var(--panel-2);
}
.arvore-vias div { display: flex; justify-content: space-between; gap: 8px; font-size: 11.5px; }
.arvore-vias div span { color: var(--muted); }
.arvore-vias div b { color: var(--accent); font-variant-numeric: tabular-nums; }

/*
 * ---- A coluna "traçar sozinho" ----
 *
 * Ela mora no VÃO que já existia: a arte da treliça é alta e estreita e fica
 * centrada numa coluna larga, então sobravam uns 200px de nada de cada lado.
 * O ajudante ocupa o da esquerda, e a arte continua no meio.
 *
 * Cada rumo é um botão-cartão, e não um item de lista, porque ele FAZ alguma
 * coisa ao ser clicado — e o que ele faz é grande (gasta todos os pontos à
 * espera). Um alvo pequeno para uma ação grande é o que produz clique sem
 * querer; daí a altura, e daí a nota embaixo dizendo que nada é aplicado antes
 * do Aplicar.
 */
.arvore-rumos { display: grid; gap: 7px; align-content: start; }
.arvore-rumos h4 {
  margin: 0; font-family: var(--font-heading); font-size: 11px; font-weight: 500;
  letter-spacing: .09em; text-transform: uppercase; color: var(--muted);
}
.arvore-rumo {
  display: grid; gap: 2px; justify-items: start; text-align: left;
  padding: 8px 10px; cursor: pointer;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 6px;
  transition: border-color .15s ease, background .15s ease;
}
.arvore-rumo { width: 100%; }
.arvore-rumo b { font-family: var(--font-heading); font-size: 12.5px; color: var(--text); font-weight: 500; }
.arvore-rumo small { font-size: 10.5px; line-height: 1.3; color: var(--muted); }
.arvore-rumo em { font-style: normal; font-size: 10.5px; color: var(--accent); }

/*
 * ---- A barra de duas cores ----
 *
 * O pedaço cheio é o que a via já tem; o claro em cima é o que o rumo
 * acrescentaria se você clicasse. São duas informações no mesmo traço de 3px, e
 * é a comparação entre elas que responde "vale a pena clicar aqui?".
 */
.arvore-rumo-barra {
  display: flex; width: 100%; height: 3px; margin: 3px 0 1px;
  background: var(--line); border-radius: 2px; overflow: hidden;
}
.arvore-rumo-barra i { display: block; height: 100%; background: var(--accent); }
.arvore-rumo-barra u { display: block; height: 100%; background: rgba(143, 188, 216, .75); }
.arvore-rumo-linha { display: flex; justify-content: space-between; width: 100%; gap: 6px; align-items: baseline; }
.arvore-rumo-linha span { font-size: 10.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.arvore-rumo .arvore-preco {
  display: flex; align-items: center; gap: 4px; width: 100%;
  color: var(--danger); font-variant-numeric: tabular-nums;
}
.arvore-rumo .arvore-preco .arvore-ico { width: 12px; height: 12px; flex: 0 0 12px; }
/* O ` · ` que o `.arvore-preco` da coluna da direita usa como separador não
   vale aqui: neste cartão o preço é uma linha inteira, e não um apêndice. */
.arvore-rumo .arvore-preco::before { content: none; }

/* Os três maiores ganhos, em fila. Ícone e número; o nome vive no `title`. */
.arvore-rumo-ganho { display: flex; flex-wrap: wrap; gap: 4px 8px; width: 100%; margin-top: 1px; }
.arvore-rumo-ganho span { display: flex; align-items: center; gap: 3px; cursor: help; }
.arvore-rumo-ganho .arvore-ico { width: 12px; height: 12px; flex: 0 0 12px; }
.arvore-rumo-ganho b { font-size: 10.5px; font-weight: 500; color: var(--accent); font-variant-numeric: tabular-nums; }
/* A segunda fileira é o que o rumo TIRA — mesma conta líquida do painel da
   direita, e por isso o mesmo vermelho que ele usa. */
.arvore-rumo-ganho.perde b { color: var(--danger); }
.arvore-rumo:hover:not(:disabled) { border-color: var(--accent-dim); background: rgba(63, 191, 168, .07); }
.arvore-rumo:disabled { opacity: .42; cursor: default; }
.arvore-rumo--misto b { color: var(--muted); }
.arvore-rumo-nota { margin: 2px 0 0; font-size: 10.5px; line-height: 1.35; color: var(--muted); }

/*
 * ---- A treliça inteira TEM de caber na tela ----
 *
 * Ela é alta (2:3) e tem setenta nós ligados entre si. Rolar para ver metade
 * dela destrói o painel: a graça de uma treliça é enxergar os caminhos
 * possíveis de uma vez, e quem só vê meia treliça não escolhe caminho — clica
 * no que está à vista.
 *
 * Então a ALTURA é quem manda, e a largura acompanha. A conta desconta o que a
 * moldura do modal come (50px em cima, 32 embaixo) mais o cabeçalho e o
 * respiro do corpo — por isso 170px, e não um número redondo.
 *
 * A coluna da direita rola sozinha se precisar; a arte, nunca.
 */
/*
 * ---- A largura sai da ARTE, e não de um número ----
 *
 * Era `min(1240px, 96vw)`, e 1240 é um chute: a arte é alta e a altura dela
 * manda na largura, então a largura certa do modal muda com a altura da JANELA
 * de quem está jogando. Num monitor baixo sobrava vão dos dois lados da tábua;
 * num alto ela encostava nas colunas.
 *
 * E não há uma proporção só para cravar: a treliça do knight é 1086x1448 e as
 * outras 1024x1536. Qualquer número escolhido à mão sobra para quatro vocações
 * ou aperta a quinta.
 *
 * Então ninguém escolhe. O quadro é `fit-content` com altura definida, o que
 * faz a largura dele sair da proporção da imagem que ele contém — seja ela
 * qual for. A coluna do meio da grade vira `auto`, e o modal vira `fit-content`
 * também: a medida sobe da arte até a moldura, e não desce de um chute.
 *
 * O `max-width` do quadro é o freio para a janela larga e baixa: sem ele, uma
 * arte alta demais empurraria a grade para fora do modal, que só pode ter 96vw.
 * 460px é o que as duas colunas laterais e os vãos ocupam.
 */
.modal-box:has(.arvore) { width: fit-content; max-width: 96vw; }
.modal-box:has(.arvore) #modal-body { overflow: hidden; }
.arvore { grid-template-columns: 196px auto 250px; align-items: start; }
.arvore-quadro {
  height: calc(92vh - 170px);
  width: fit-content;
  max-width: calc(96vw - 460px);
  display: flex; justify-content: center;
}
.arvore-arte { height: 100%; width: auto; max-width: 100%; border-radius: 6px; }
.arvore-lado,
.arvore-rumos { max-height: calc(92vh - 170px); overflow-y: auto; padding-right: 2px; }

/*
 * ---- A coluna da direita COMPACTA ----
 *
 * Ela não cabia: os quatro cartões de ramo empurravam "o que a árvore dá" para
 * baixo da dobra, e o preço de cada ramo — que é metade da decisão — só
 * aparecia depois de rolar. Um preço que exige rolagem é um preço escondido.
 *
 * O que encolheu: a moldura passou de 18/22 para 12/16, o resumo do ramo virou
 * uma linha só com o preço ao lado, e o vão entre cartões caiu pela metade.
 * A barra de proporção continua, porque ela é lida de relance e não custa
 * altura nenhuma.
 */
.arvore-lado { gap: 6px; }
.arvore-placar,
.arvore-ramo,
.arvore-resumo { border-width: 12px 16px; }
.arvore-placar { padding: 0 0 4px; }
.arvore-placar b { font-size: 26px; }
.arvore-ramo { gap: 2px; }
.arvore-ramo-topo b { font-size: 12px; }
.arvore-ramo small { font-size: 10.5px; line-height: 1.25; }
/* Resumo e preço na mesma linha: dois textos curtos não precisam de duas. */
.arvore-ramo small:not(.arvore-preco) { display: inline; }
.arvore-preco { display: inline; }
.arvore-preco::before { content: ' · '; color: var(--muted); }
.arvore-acoes button { padding: 5px 0; }
.arvore-resumos { display: grid; gap: 6px; }
.arvore-resumo div { font-size: 11.5px; }
.arvore-resumo h4 { font-size: 10.5px; margin-bottom: 2px; }
/* O bloco do que ela TIRA é o mesmo cartão, só que os números vêm em vermelho. */
.arvore-resumo.custa div b { color: var(--danger); }

/* ---------- treino: os três modos ---------- */
/*
 * O tamanho, a moldura e o hover vêm de `.hunt-card.boss` — os cards do treino
 * usam as MESMAS classes dos cards de boss, e não uma cópia. O que sobra aqui é
 * só o que é diferente: no boss aquela faixa do meio são as figuras dos bichos,
 * e no treino é uma ilustração só.
 */
.treino-arte {
  width: 100%;
  display: block;
  overflow: hidden;
}
/*
 * A arte é vertical (4:5) e preenche a largura do card. `aspect-ratio` em vez de
 * altura fixa faz os três acompanharem a largura da coluna sem esmagar a figura,
 * e `cover` corta pelas bordas em vez de deformar.
 */
.treino-arte img,
.treino-arte .ui-icon {
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  display: block;
  image-rendering: auto;
}
/* Sem arte ainda: a faixa não colapsa e o card não muda de altura quando ela chegar. */
.hunt-card.boss.treino .treino-arte:empty { min-height: 52px; }
.hunt-card.boss.treino.locked img { filter: grayscale(.7); }

/* ---------- treino: o que subiu ---------- */
.treino-ganho { display: flex; flex-direction: column; gap: 8px; margin: 12px 0; }
.treino-linha {
  display: grid;
  grid-template-columns: 24px 1fr auto auto;
  align-items: center;
  gap: 10px;
}
.treino-linha img { width: 24px; height: 24px; image-rendering: pixelated; }
/*
 * Os números em tabular: "10 → 32" e "12 → 14" alinham a seta na mesma coluna,
 * e uma lista de perícias se lê de cima a baixo em vez de dente de serra.
 */
.treino-linha .de-para { font-variant-numeric: tabular-nums; opacity: .8; }
.treino-linha em { font-style: normal; color: var(--bom, #7fd18a); font-weight: 600; }

/* ---------- analisador: dano por elemento ---------- */
.dano-lado { margin: 8px 0 4px; }
.dano-lado h5 {
  margin: 0 0 6px; font-family: var(--font-heading); font-size: 11px;
  letter-spacing: .08em; text-transform: uppercase; color: var(--muted);
}
.dano-linha {
  display: grid; grid-template-columns: 18px 62px 1fr 34px;
  align-items: center; gap: 7px; margin-bottom: 4px;
}
.dano-linha img { width: 18px; height: 18px; image-rendering: pixelated; }
.dano-linha b { font-size: 11px; font-weight: 500; }
/*
 * A barra é o que se lê. Sete linhas de porcentagem obrigam a comparar de
 * cabeça; sete barras dizem de uma vez de onde vem o grosso do dano — que é a
 * única pergunta que alguém abre isto para responder.
 */
.dano-barra { height: 7px; background: #ffffff12; border-radius: 4px; overflow: hidden; }
.dano-barra i { display: block; height: 100%; border-radius: 4px; }
.dano-linha span { font-size: 10px; color: var(--muted); text-align: right; font-variant-numeric: tabular-nums; }

/* ---------- analisador: cooldown de boss ---------- */
.boss-cd > div {
  display: flex; justify-content: space-between; gap: 10px;
  padding: 4px 0; font-size: 11px; border-bottom: 1px solid #ffffff0d;
}
.boss-cd > div:last-child { border-bottom: none; }
.boss-cd b { font-weight: 500; }
.boss-cd span { color: var(--accent); font-variant-numeric: tabular-nums; }
/* Quem ainda não voltou fica apagado: o que se procura aqui é o que está pronto. */
.boss-cd .esperando { opacity: .5; }
.boss-cd .esperando span { color: var(--muted); }

/* ---------- quem é da equipe fala marcado ---------- */
/*
 * O nome dourado com a tag antes dele. A cor sozinha não bastaria — daltônico
 * não a distingue do resto, e a conversa é onde alguém se passa por GM. A TAG
 * escrita é o que identifica; o brilho é o que faz olhar.
 */
.who-equipe {
  color: #ffd76a;
  text-shadow: 0 0 6px #ffb32e88, 0 0 2px #ffd76a;
}
.tag-cargo {
  font-family: var(--font-heading);
  font-style: normal;
  font-size: 9px;
  letter-spacing: .1em;
  vertical-align: 1px;
  margin-right: 5px;
  padding: 1px 5px;
  border-radius: 3px;
  color: #1a1206;
  background: linear-gradient(180deg, #ffe9a8, #d9a53a);
  box-shadow: 0 0 8px #ffb32e66;
}
/* Tutor é do mesmo time e não é a mesma coisa: prata em vez de ouro. */
.who-tutor { color: #cfe3ef; text-shadow: 0 0 6px #9fc4d888; }
.who-tutor .tag-cargo { background: linear-gradient(180deg, #eaf4fa, #9fb8c6); box-shadow: 0 0 8px #9fc4d855; }

/* ---------- tarefas: boss tasks e entregas ---------- */

/*
 * ---- O card de boss task ----
 *
 * Três colunas, e a ordem é a da pergunta: O QUE matar (com a cara do bicho),
 * QUANTO falta, e O QUE se ganha. O card antigo era texto em três linhas — o
 * nome do bicho e o nome do boss são palavras em inglês, e uma palavra não é
 * uma cara.
 *
 * A moldura é a nine-slice da casa (.ui-frame), na medida de card.
 */
.bosstask-lista { display: grid; gap: 14px; }
/*
 * O título que separa as boss tasks das tasks de montaria, dentro da mesma aba.
 * A margem de cima é o que faz as duas listas lerem como duas — sem ela os
 * cards de baixo pareceriam continuação dos de cima.
 */
.bosstask-secao { margin: 22px 0 6px; font-size: 15px; letter-spacing: .04em; text-transform: uppercase; opacity: .85; }
/*
 * A régua entre a lista de tasks e a de entregas, na aba das montarias. Ela é o
 * que diz "aqui começa outra coisa" — as duas dão montaria, e só o corte separa
 * a que conta sozinha da que pede um clique no balcão.
 */
.secao-corte { border: 0; border-top: 1px solid rgba(255, 255, 255, .12); margin: 26px 0 0; }
.bosstask-dentro {
  display: grid; grid-template-columns: auto 1fr auto; gap: 16px; align-items: center;
  background: linear-gradient(180deg, #131c22, #0c1215);
  padding: 12px 14px; border-radius: 6px;
}
.bosstask-alvos { display: flex; gap: 8px; }
/*
 * A cela do alvo tem 62px e "NECROMANCER" tem doze letras: ela quebrava no meio
 * da palavra ("NECROMANC ER"), que e o unico corte que se le como erro de
 * digitacao. Um pouco mais larga e sem quebrar palavra, os nomes de duas
 * palavras ("MINOTAUR GUARD") continuam quebrando no ESPACO, que e onde deve.
 */
.bosstask-alvo {
  display: grid; gap: 3px; justify-items: center; width: 74px; text-align: center;
  word-break: keep-all; overflow-wrap: normal;
}
.bosstask-alvo canvas { image-rendering: pixelated; }
.bosstask-alvo span {
  font-size: 9px; line-height: 1.15; color: var(--muted);
  letter-spacing: .03em; text-transform: uppercase;
}
.bosstask-meio { display: grid; gap: 5px; min-width: 0; }
.bosstask-titulo { font-family: var(--font-heading); font-size: 14px; color: var(--text); }
.bosstask-blurb { font-style: normal; font-size: 11px; color: var(--muted); }
.bosstask-conta { font-style: normal; font-size: 11px; color: var(--copper); font-variant-numeric: tabular-nums; }

/*
 * A recompensa fica encostada à direita, atrás de uma divisa.
 *
 * Ela é o único pedaço do card que não fala do trabalho, e sim do prêmio — a
 * linha vertical é o que separa "o que você faz" de "o que você ganha" sem
 * precisar de um rótulo dizendo isso.
 */
.bosstask-premio {
  display: flex; align-items: center; gap: 10px;
  padding-left: 16px; border-left: 1px solid var(--line); max-width: 260px;
}
.bosstask-premio canvas { image-rendering: pixelated; flex: none; }
.bosstask-premio-texto { display: grid; gap: 2px; }
.bosstask-premio-rotulo {
  font-family: var(--font-title); font-size: 9px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--accent);
}
.bosstask-premio-texto b { font-size: 12px; color: var(--text); }
/*
 * A linha do Task Token, na coluna do prêmio.
 *
 * Dez pixels e cor de cobre — a MESMA do contador de mortes do card, e é de
 * propósito: as duas linhas falam de número, e a cor as liga sem precisar de
 * rótulo. `nowrap` porque "+24 Task Token" quebrando em duas linhas é o único
 * jeito de esta linha crescer o card.
 */
.bosstask-token {
  font-style: normal; font-size: 10px; letter-spacing: .03em;
  color: var(--copper); white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.bosstask-estado {
  font-style: normal; font-size: 10px; letter-spacing: .04em;
  text-transform: uppercase; color: var(--muted);
}
.bosstask-estado.aberto { color: #6ddb96; }
.bosstask-estado.feito { color: var(--copper); }
/* Fechada por cima: o card fica apagado, mas legível — ele ainda conta o que
   aconteceu, e apagá-lo de vez esconderia a própria conquista. */
.bosstask-card.bosstask-feita { opacity: .62; }
.bosstask-card.bosstask-aberta .bosstask-dentro {
  background: linear-gradient(180deg, #16261d, #0c1215);
}

/*
 * ---- Os cards de entrega ----
 *
 * Dois lados: o que se leva (com o boneco já vestindo o addon) e o que se traz
 * (o item, quantos você tem, e de qual bicho ele cai). O botão fica do lado do
 * PEDIDO, e não do prêmio: ele é o fim daquela coluna — "tenho 15 de 15,
 * entregar".
 */
/*
 * Um card por PEÇA, com os passos empilhados dentro. Mais largo que a versão
 * anterior (que era um card por entrega) porque cada linha agora carrega uma
 * sprite, o item, de quem cai e o botão.
 */
/*
 * ---- DOIS por linha ----
 *
 * O mínimo era 430px, e no painel de 980px isso dava dois só quando sobrava
 * folga — na prática, um. 300px garante os dois; o que evita o "Entre gar"
 * quebrado é o botão não encolher (`flex: none` e `white-space: nowrap` no
 * passo), e não a largura da coluna.
 */
/*
 * ---- E os cards NÃO se esticam até a altura do vizinho ----
 *
 * O `align-items` padrão de uma grade é `stretch`: os dois cards de uma linha
 * nascem com a altura do mais alto. Enquanto cada entrega pedia UM item isso
 * não aparecia — os cards tinham quase a mesma altura. Com os dados do Addoner
 * um addon pede treze itens e outro pede zero, e o Nobleman (dois passos de
 * ouro) virava uma moldura de 456px com 306 deles vazios do lado do Assassin.
 *
 * Medido antes do conserto, nos 15 cards: 306, 148, 472 pixels de vazio dentro
 * da moldura. É o "modal de outfits ta todo quebrado" — não era o card, era a
 * linha da grade puxando um pelo outro.
 */
.entrega-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 14px; align-items: start;
}
.entrega-dentro {
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 11px; align-items: start;
  background: linear-gradient(180deg, #131c22, #0c1215);
  padding: 12px 12px; border-radius: 6px;
}
.entrega-premio {
  display: grid; gap: 3px; justify-items: center; width: 84px; text-align: center;
  position: sticky; top: 0;
}
.entrega-premio b { overflow-wrap: break-word; }
.entrega-premio canvas { image-rendering: pixelated; }
.entrega-premio b { font-size: 13px; font-family: var(--font-heading); color: var(--text); }
.entrega-premio-tipo {
  font-style: normal; font-size: 10px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--accent); font-variant-numeric: tabular-nums;
}

/*
 * ---- Os passos ----
 *
 * A roupa, o addon 1 e o addon 2, um embaixo do outro, na ordem em que se
 * conquistam. Cada um com a sprite do que ELE acrescenta — é o que responde "o
 * que este addon muda?" antes de a pessoa gastar a caçada descobrindo.
 */
.entrega-passos {
  display: grid; gap: 6px; min-width: 0;
  padding-left: 11px; border-left: 1px solid var(--line);
}
/*
 * ---- DUAS fileiras, e a de itens ocupa a largura toda ----
 *
 * Em uma fileira só (boneco | meio | botão) sobravam 111px para os itens dentro
 * de um passo de 259px — o boneco come 44, o botão "Entregar" come 84, e os dois
 * não encolhem. Numa cela de 75px isso dá UM item por linha: o addon 1 do
 * Assassin virava sete linhas empilhadas, e o do Mage, treze.
 *
 * O botão sobe para o lado do título (que é curto e sobrava espaço) e a grade
 * desce para uma fileira própria, larga. Os mesmos 259px passam a dar 205 para
 * os itens, e a cela encolheu junto: três por fileira em vez de um.
 */
.entrega-passo {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-rows: auto auto; gap: 5px 9px; align-items: center;
  padding: 7px 9px; border-radius: 6px;
  background: #0e161a; border: 1px solid var(--line-soft);
}
.entrega-passo > canvas { image-rendering: pixelated; flex: none; grid-row: 1 / -1; align-self: center; }
.entrega-passo > .entrega-passo-meio { grid-column: 2; grid-row: 1; }
.entrega-passo > button { grid-column: 3; grid-row: 1; }
.entrega-passo > .entrega-itens { grid-column: 2 / -1; grid-row: 2; }
/* Passo sem item nenhum (a montaria) não deixa uma fileira vazia com gap. */
.entrega-passo > .entrega-itens:empty { display: none; }
.entrega-passo-meio { display: grid; gap: 3px; min-width: 0; }
.entrega-passo-meio > b {
  font-family: var(--font-heading); font-size: 11px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--accent);
}
/*
 * ---- O botão do passo é PEQUENO, mesmo quando está aceso ----
 *
 * '#modal button.primary' fixa 'padding: 8px 18px' e 12px de fonte — o tamanho
 * de um "Confirmar" de caixa de diálogo. Com o id na frente, essa regra vencia
 * a daqui, e o botão do passo pronto inchava até passar por cima do nome do
 * item: era o "ENTREGAR" gigante que o dono viu em cima do "nose ring".
 *
 * O id vem para cá pelo mesmo motivo: é o que faz esta regra ganhar.
 */
#modal .entrega-passo button,
.entrega-passo button {
  flex: none; white-space: nowrap;
  padding: 4px 11px; font-size: 10px; letter-spacing: .04em;
}

/*
 * ---- Pronto: o botão CHAMA ----
 *
 * Ter o item e não perceber é o desperdício que esta tela existe para evitar —
 * a pessoa sai para caçar de novo o que já está na mochila. O pulso é lento
 * (1,8s) e só na moldura: um botão piscando forte no meio de uma grade de dez
 * cards vira ruído, e aí ninguém olha para nenhum.
 */
#modal .entrega-passo.passo-pronto button {
  animation: entrega-pronta 1.8s ease-in-out infinite;
}
@keyframes entrega-pronta {
  0%, 100% { box-shadow: 0 0 0 #0000; }
  50% { box-shadow: 0 0 9px #6fe0c2aa, inset 0 0 6px #ffffff26; }
}
@media (prefers-reduced-motion: reduce) {
  #modal .entrega-passo.passo-pronto button { animation: none; }
}
/* Pronto acende; conquistado apaga e o botão vira um ✓. */
.entrega-passo.passo-pronto { border-color: var(--accent); background: #12211a; }
.entrega-passo.passo-feito { opacity: .5; }

.entrega-item { display: flex; align-items: center; gap: 7px; }
.entrega-item canvas { image-rendering: pixelated; flex: none; }
.entrega-item b { font-variant-numeric: tabular-nums; color: var(--copper); font-size: 12px; }
/* `break-word` e nao `anywhere`: o nome so quebra ENTRE palavras enquanto
   couber, senao "maxilla maximus" saia partido no meio da segunda. */
.entrega-item span { font-size: 11px; color: var(--text); overflow-wrap: break-word; }
.entrega-item b { white-space: nowrap; }
/*
 * ---- A GRADE de itens da entrega ----
 *
 * O balcão pedia UM item e a linha era "ícone 3 / 10 nome". Com os dados do NPC
 * Addoner são até treze por addon, e treze linhas dessas fariam um card de meia
 * tela — numa lista de 31.
 *
 * Então eles se enfileiram numa grade que quebra sozinha. O nome sai da cela e
 * vai para o balão: com treze itens, o que o olho procura é "quanto falta", e o
 * nome de cada um só interessa ao parar em cima.
 */
/*
 * ---- De volta ao `flex-wrap`, e por um motivo medido ----
 *
 * As colunas iguais de 58px foram escolhidas para a fileira não ficar com um
 * dente a cada quebra. Só que a cela mais larga não cabe em 58: "100/100" tem
 * quase o dobro dos caracteres de "0/1", e numa coluna fixa ela era cortada —
 * "o retângulo dos itens está ficando pequeno", e estava mesmo.
 *
 * Numa lista em que o conteúdo varia de "0/1" a "150.000", quem manda é o
 * conteúdo. A fileira fica irregular; um número cortado seria pior, porque o
 * número é a única coisa que a cela existe para dizer.
 */
.entrega-itens { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; }
.entrega-itens .entrega-item {
  flex: 0 0 auto; gap: 4px; padding: 2px 6px; border-radius: 4px;
  background: #0d1315; border: 1px solid #ffffff12;
}
/* O número nunca quebra no meio: é ele que se lê de relance. */
.entrega-itens .entrega-item b { white-space: nowrap; }
.entrega-itens .entrega-item canvas { width: 22px; height: 22px; }
.entrega-itens .entrega-item b { font-size: 11px; }
/* Já tem o bastante: verde discreto, para o olho pular estes e ver o que falta. */
.entrega-itens .entrega-item.item-ok { border-color: #7fc7a455; }
.entrega-itens .entrega-item.item-ok b { color: #7fc7a4; }
/*
 * Já saiu da mochila e está guardado no balcão, mas a conta ainda não fechou.
 * Cobre, e não verde: verde é "completo", e estes dois estados vizinhos não
 * podem ter a mesma cor — quem adiantou precisa saber que ainda falta.
 */
.entrega-itens .entrega-item.item-guardado { border-color: #d8a65788; background: #1a1409; }
.entrega-itens .entrega-item.item-guardado b { color: #d8a657; }

/* O botão de adiantar é discreto de propósito: ele não fecha nada. */
#modal .entrega-passo button.entrega-adiantar,
.entrega-passo button.entrega-adiantar {
  border-color: #d8a65766; color: #d8a657;
}

/*
 * Item que ainda não cai de nenhum bicho das hunts. Não é erro do jogador e não
 * some da lista: o dono vai pô-lo na loja de Task Token ou num boss. Até lá, a
 * cela diz que a culpa não é de quem procura.
 */
.entrega-itens .entrega-item.item-sem-fonte { border-style: dashed; border-color: #d9807055; opacity: .75; }
.entrega-itens .entrega-ouro b { color: #e0b45a; }

.entrega-fonte { display: flex; align-items: center; gap: 6px; }
.entrega-fonte canvas { image-rendering: pixelated; flex: none; }
.entrega-fonte span { font-size: 10px; color: var(--muted); letter-spacing: .03em; }
/* Pronta: o card acende. É o estado que a pessoa veio procurar, e a ordem da
   lista já o traz para cima — a cor termina de apontar. */
.entrega-card.entrega-pronta .entrega-dentro {
  background: linear-gradient(180deg, #16261d, #0c1215);
}
.entrega-card.entrega-feita { opacity: .58; }

@media (max-width: 720px) {
  .bosstask-dentro { grid-template-columns: 1fr; }
  .bosstask-premio { padding-left: 0; border-left: none; border-top: 1px solid var(--line); padding-top: 10px; max-width: none; }
  .entrega-grid { grid-template-columns: 1fr; }
  .entrega-dentro { grid-template-columns: 1fr; }
  .entrega-passos { padding-left: 0; border-left: none; border-top: 1px solid var(--line); padding-top: 10px; }
}

/*
 * ---- O coração de favorita ----
 *
 * Vazio quando não é, cheio quando é. Ele fica no canto de cima do card e não
 * na fileira de botões: favoritar é uma marca que se põe na COISA, e um botão
 * "favoritar" ao lado de "entrar" seriam duas ações de peso muito diferente
 * disputando o mesmo olhar.
 *
 * 'pointer-events' próprio porque o card inteiro é clicável: sem isso, marcar a
 * hunt entraria nela.
 */
.hunt-fav {
  position: absolute; top: 6px; right: 6px; z-index: 2;
  width: 24px; height: 24px; padding: 0; line-height: 1;
  display: grid; place-items: center;
  background: #0b1114cc; border: 1px solid var(--line); border-radius: 999px;
  color: #6b7b82; font-size: 13px; cursor: pointer;
  transition: color .12s ease, border-color .12s ease, transform .1s ease;
}
/*
 * ---- Verde, e não vermelho ----
 *
 * O vermelho de coração é a convenção de fora — de rede social, de curtida —, e
 * aqui ele era a única coisa dessa cor num jogo inteiro pintado de verde-água:
 * lido de relance parecia aviso de perigo, que é o oposto de "esta eu gosto".
 *
 * O verde é o mesmo `--accent` do texto do topo, e o brilho em volta é o que o
 * separa da moldura cinza sem precisar de um segundo elemento.
 */
.hunt-fav:hover { color: var(--accent); border-color: var(--accent-dim); }
.hunt-fav:active { transform: scale(.9); }
.hunt-fav[aria-pressed="true"] {
  color: var(--accent); border-color: var(--accent);
  text-shadow: 0 0 6px var(--accent), 0 0 12px #6fe0c266;
  box-shadow: 0 0 7px #6fe0c244;
}
.hunt-card { position: relative; }
@media (prefers-reduced-motion: reduce) { .hunt-fav { transition: none; } }

/*
 * ---- A munição desenhada em cima da aljava ----
 *
 * A aljava é o mesmo desenho para qualquer flecha, e a flecha carregada é a
 * única coisa que muda ali. Ela vai no canto de baixo à esquerda, que é o canto
 * livre — o "∞" já mora no de baixo à direita.
 */
.slot .aljava-municao {
  position: absolute; left: 0; bottom: 0; z-index: 2;
  width: 22px; height: 22px; line-height: 0; pointer-events: none;
  filter: drop-shadow(0 0 2px #000) drop-shadow(0 0 2px #000);
}
.slot .aljava-municao canvas {
  /* `.slot canvas` fixa 32px para o desenho da peça; a marca é menor e precisa
     dizer isso depois. */
  width: 22px; height: 22px; image-rendering: pixelated;
}

/* O balão da aljava: o mesmo arranjo dos outros painéis de balão. */
.tip-municao { display: grid; gap: 6px; min-width: 190px; }
.tip-municao-topo { display: flex; align-items: center; gap: 8px; }
.tip-municao-topo canvas { image-rendering: pixelated; flex: none; }
.tip-municao-topo b { font-size: 13px; color: var(--text); }
.tip-municao .shop-note { margin: 2px 0 0; }

/* O balão da stamina: o mesmo arranjo dos outros painéis de balão. */
.tip-stamina { display: grid; gap: 5px; min-width: 210px; }
.tip-stamina-topo { display: flex; align-items: baseline; gap: 7px; }
.tip-stamina-topo b { font-size: 15px; color: var(--text); font-variant-numeric: tabular-nums; }
.tip-stamina-topo span { font-size: 11px; color: var(--muted); }
/* A linha do estado, que é a primeira coisa que se procura ao parar o mouse. */
.tip-stamina-carregando {
  font-family: var(--font-title); font-size: 10px; letter-spacing: .1em;
  text-transform: uppercase; color: #6ddb96;
}
.tip-stamina .shop-note { margin: 3px 0 0; }

/*
 * ---- A oferta do pergaminho, logo acima do "Parar treino" ----
 *
 * Uma faixa da largura do cartaz, e não mais uma pílula espremida na linha do
 * título: lá cabia uma linha de dez pixels e um alvo de clique fino demais para
 * se acertar sem mirar. Aqui há espaço para as duas linhas e para o dedo.
 *
 * 'pointer-events: auto' porque a faixa do treino inteira ignora o clique (ela
 * fica por cima do mapa) — é o mesmo cuidado do botão de parar.
 */
#treino-faixa .efeito-oferta {
  pointer-events: auto; cursor: pointer;
  display: flex; align-items: center; justify-content: center; gap: 8px;
  width: 100%; margin: 2px 0 6px; padding: 6px 12px;
  background: linear-gradient(180deg, #0f1a1d, #0b1114);
  border: 1px solid var(--line); border-radius: 7px;
  font-family: inherit;
  transition: border-color .15s ease, background .15s ease;
}
#treino-faixa .efeito-oferta[hidden] { display: none; }
#treino-faixa .efeito-oferta:hover { border-color: var(--accent-dim); background: linear-gradient(180deg, #14242a, #0d1417); }
#treino-faixa .efeito-oferta canvas { image-rendering: pixelated; flex: none; opacity: .9; }
#treino-faixa .efeito-oferta:hover canvas { opacity: 1; }

/*
 * Duas linhas: a chamada em cima, o nome do produto embaixo.
 *
 * O brilho recorta o BLOCO das duas (ver abaixo), então nenhuma das duas pode
 * pintar a própria cor — a diferença entre elas é só de tamanho e de peso.
 */
.oferta-texto { display: grid; gap: 1px; text-align: left; line-height: 1.2; }
.oferta-chamada { font-size: 11px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; }
.oferta-item { font-style: normal; font-size: 9px; letter-spacing: .07em; text-transform: uppercase; }

/*
 * ---- O brilho que ATRAVESSA as letras ----
 *
 * Um degradê recortado pelo próprio texto (`background-clip: text`), deslizando
 * da esquerda para a direita. Não é o texto que pisca: é uma luz passando por
 * cima dele, que chama sem gritar — três segundos e meio por volta, devagar o
 * bastante para não competir com as réguas do treino logo abaixo.
 *
 * As cores são explícitas e não `currentColor`: com `text-fill-color:
 * transparent`, `currentColor` também seria transparente e a chamada sumiria.
 */
/*
 * O recorte é do BLOCO das duas linhas, e não só da chamada.
 *
 * Com o degradê preso a uma linha só, a luz varria "Treine mais rápido" e morria
 * na borda dela — o nome do produto, que é justamente o que a pessoa vai
 * procurar na loja, ficava apagado embaixo. Recortado pelo bloco, o mesmo
 * degradê atravessa as duas de uma vez, na mesma passada.
 */
.oferta-texto {
  background: linear-gradient(100deg, #7b8a90 38%, #6fe0c2 47%, #d6fff2 50%, #6fe0c2 53%, #7b8a90 62%);
  background-size: 300% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  animation: oferta-brilho 3.5s linear infinite;
}
@keyframes oferta-brilho {
  from { background-position: 200% 0; }
  to { background-position: -100% 0; }
}
/* Com o mouse em cima o degradê para e a chamada assume a cor de acento: já não
   é preciso chamar quem já está olhando. */
#treino-faixa .efeito-oferta:hover .oferta-texto {
  animation: none; background: none;
  -webkit-text-fill-color: var(--accent); color: var(--accent);
}
@media (prefers-reduced-motion: reduce) {
  .oferta-texto { animation: none; background: none; -webkit-text-fill-color: #8fb8ae; color: #8fb8ae; }
  #treino-faixa .efeito-oferta { transition: none; }
}
/*
 * ---- O card que a loja abriu para mostrar ----
 *
 * Quem chegou pelo atalho do treino veio buscar um produto, e a prateleira tem
 * cinco. A moldura acesa some sozinha depois de alguns segundos: ela é uma
 * apresentação, e uma apresentação que fica é decoração.
 */
.store-card.store-destaque {
  border-color: var(--accent);
  animation: store-destaque 2.4s ease-out 2;
}
@keyframes store-destaque {
  0%, 100% { box-shadow: 0 0 0 #0000; }
  35% { box-shadow: 0 0 14px #6fe0c288, inset 0 0 10px #6fe0c233; }
}
@media (prefers-reduced-motion: reduce) { .store-card.store-destaque { animation: none; } }

/*
 * ---- O botão de ação FORTE do cabeçalho ----
 *
 * O "Entregar tudo" fica ao lado do "Filtro" e não pode parecer igual a ele: um
 * abre uma gaveta, o outro consome itens. A cor e a conta do lado dizem isso
 * antes da leitura.
 */
.modal-acao.modal-acao-forte {
  border-color: var(--accent); color: #eafffb;
  background: linear-gradient(180deg, #1d5a52, #123c37);
}
.modal-acao.modal-acao-forte:hover { filter: brightness(1.15); }
.modal-acao .modal-acao-conta {
  display: inline-grid; place-items: center; min-width: 16px; height: 16px;
  padding: 0 4px; border-radius: 999px; background: #0b1114cc;
  font-style: normal; font-size: 10px; font-weight: 700; color: #b6ffcf;
}

/* A caixa do lote é mais larga: cada linha carrega item, seta e prêmio. */
.confirm-box.confirm-lote { width: min(520px, 92vw); }
.lote-lista {
  display: grid; gap: 5px; margin: 10px 0 4px;
  max-height: 46vh; overflow-y: auto; padding-right: 4px;
}
.lote-linha {
  display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); gap: 10px;
  align-items: center; padding: 6px 9px; border-radius: 6px;
  background: #0e161a; border: 1px solid var(--line-soft);
}
.lote-item, .lote-premio { display: flex; align-items: center; gap: 7px; min-width: 0; }
.lote-item canvas, .lote-premio canvas { image-rendering: pixelated; flex: none; }
.lote-item b { color: var(--copper); font-variant-numeric: tabular-nums; font-size: 12px; }
.lote-item span { font-size: 11px; color: var(--text); overflow-wrap: break-word; }
.lote-seta { color: var(--accent); font-size: 14px; }
.lote-premio-texto { display: grid; gap: 1px; min-width: 0; }
.lote-premio-texto b { font-size: 12px; color: var(--text); }
.lote-premio-texto em {
  font-style: normal; font-size: 9px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--accent);
}

/* A resposta do dono a um report, na janela do jogador. */
.report-resposta {
  border-left: 3px solid var(--accent, #3fbfa8);
  padding: 8px 12px;
  margin: 10px 0;
  background: rgba(63, 191, 168, .07);
  border-radius: 0 4px 4px 0;
}
.report-resposta b { display: block; font-size: 13px; }
.report-resposta em { display: block; font-size: 11px; opacity: .7; margin-bottom: 4px; font-style: normal; }
.report-resposta p { margin: 0; white-space: pre-wrap; }

/* O relato do próprio jogador, acima da resposta. Apagado de propósito: ele é
   o contexto, e a notícia é a resposta logo abaixo. */
.report-meu {
  border-left: 3px solid rgba(255, 255, 255, .18);
  padding: 8px 12px;
  margin: 10px 0 0;
  background: rgba(255, 255, 255, .03);
  border-radius: 0 4px 4px 0;
  opacity: .78;
}
.report-meu b { display: block; font-size: 13px; }
.report-meu em { display: block; font-size: 11px; opacity: .7; margin-bottom: 4px; font-style: normal; }
.report-meu p { margin: 0; white-space: pre-wrap; }
.report-meu + .report-resposta { margin-top: 6px; }

/* ---------- recompensas de nível ---------- */

/* A faixa pisca enquanto houver prêmio esperando. Devagar e no brilho, não no
   tamanho: um elemento que muda de tamanho empurra o que está em volta, e ele
   fica ancorado na barra de ações. */
@keyframes presente-pulso {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255, 200, 90, 0); }
  50%      { box-shadow: 0 0 18px 2px rgba(255, 200, 90, .55); }
}
.presente-pulsa { animation: presente-pulso 1.8s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) {
  .presente-pulsa { animation: none; box-shadow: 0 0 12px 1px rgba(255, 200, 90, .45); }
}

/* ---------- o calendário de recompensas ----------
 *
 * Grade que se ajusta sozinha: oito cartões cabem em quatro colunas numa tela
 * larga e em duas num notebook, sem quebra de linha no meio de um cartão. */
.recompensas-grade {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(148px, 1fr));
  gap: 10px;
  margin: 12px 0;
}

.recompensa-cartao {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 12px 10px;
  text-align: center;
  border: 1px solid rgba(255, 255, 255, .12);
  border-radius: 4px;
  background: rgba(255, 255, 255, .03);
}
/* Disponível ganha o ouro; já pego apaga. O estado vai na borda e na opacidade
   para não competir com a arte do prêmio, que é o que a pessoa veio ver. */
.recompensa-cartao.aberto {
  border-color: #e0b45a;
  background: rgba(224, 180, 90, .09);
  box-shadow: 0 0 12px -4px rgba(224, 180, 90, .7);
}
/* Mais apagado que antes (.45 -> .35): agora há uma faixa por cima dizendo o
   estado, e a carta pega não precisa mais competir por atenção. */
.recompensa-cartao.pego { opacity: .35; position: relative; }

/* ---- A fonte é a da casa, e não a do sistema ----
 *
 * O "Level 50" e o "Set intermediário" saíam na fonte do corpo, ao lado de
 * títulos que usam a Cinzel em toda a interface. Numa janela que é uma vitrine
 * de prêmios, o cabeçalho do cartão é metade do que a pessoa lê — ele veste a
 * mesma fonte dos outros títulos do jogo. */
.recompensa-level {
  font-family: var(--font-title); font-size: 15px; font-weight: 700;
  letter-spacing: .07em; color: #f2dfae;
}
.recompensa-titulo {
  font-family: var(--font-heading); font-size: 11px; font-weight: 600;
  letter-spacing: .07em; text-transform: uppercase; opacity: .82;
}
/* O preço, com a moeda do jogo do lado: 100k escrito é um número; 100k com a
   moeda ao lado é um preço. Vermelho quando o ouro não dá. */
.recompensa-preco {
  display: flex; align-items: center; justify-content: center; gap: 4px;
  font-family: var(--font-heading); font-size: 11.5px; letter-spacing: .04em; color: #e0b45a;
}
.recompensa-preco canvas { image-rendering: pixelated; }
.recompensa-preco.curto { color: #d8756a; }
.recompensa-preco.curto canvas { filter: grayscale(.7) brightness(.8); }
.recompensa-arte {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 4px;
  min-height: 34px;
}
.recompensa-resumo { font-size: 10.5px; opacity: .7; font-style: normal; line-height: 1.3; }
/* ---- "PEGO" é uma faixa, e não uma palavrinha ----

   Era um `em` de 11px no pé do cartão, na cor do corpo: com o cartão a 35% de
   opacidade ele sumia, e a pergunta que a aba responde é justamente essa ("já
   peguei?"). Agora é a MESMA faixa da Recompensa Diária — visto, versalete e
   tarja escura — para as duas telas lerem como a mesma coisa. Quem aprendeu
   numa não reaprende na outra.

   `position: absolute` e não `margin-top: auto`: a faixa atravessa o cartão de
   ponta a ponta, e no fluxo ela respeitaria o `padding` lateral. */
.recompensa-selo {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 3px 0;
  background: linear-gradient(180deg, #0a0d0f00, #0a0d0fe6 45%);
  border-top: 1px solid #3fbfa844;
  font-family: var(--font-heading); font-size: 10px; font-style: normal;
  letter-spacing: .2em; text-transform: uppercase;
  color: var(--hp); text-align: center; opacity: 1;
}
.recompensa-selo::before { content: '✓'; margin-right: .35em; opacity: .9; }
/* O cartão fechado explica POR QUE está fechado, e isso não é um selo: fica no
   pé do cartão, discreto, sem faixa e sem visto. */
.recompensa-espera {
  margin-top: auto; font-size: 11px; font-style: normal; opacity: .6;
}
/* O cartão pego ganha rodapé para a faixa não encostar no texto. */
.recompensa-cartao.pego { padding-bottom: 22px; }
.recompensa-cartao.aberto .recompensa-selo { color: #e0b45a; opacity: 1; }
.recompensa-cartao button { margin-top: auto; width: 100%; }

/* ---- O botão de pegar o prêmio ----
 *
 * Ele é o único clique da janela, e estava com a mesma cor do "Fechar" logo
 * abaixo. Aqui ele é dourado, com um brilho que atravessa a cada poucos
 * segundos — o mesmo ouro da borda do cartão disponível, para os dois lerem
 * como a mesma coisa. O brilho é lento de propósito: um pisca-pisca rápido
 * numa janela que se abre para escolher cansa antes de convencer. */
/*
 * O aviso de versão usa o MESMO botão dourado do calendário.
 *
 * A regra vivia presa ao `#modal`, e o aviso de versão não mora lá dentro — ele
 * é uma cortina própria, por cima de tudo. Sem o `.atualizar` aqui o botão caía
 * no padrão do navegador e saía BRANCO, com cara de alerta de sistema no meio
 * de um jogo que não tem um só botão branco.
 */
#modal button.recompensa-pegar,
.atualizar button.recompensa-pegar {
  /* A largura vem do cartão (`.recompensa-cartao button`), e não daqui: o mesmo
     botão aparece na linha do "Voltar / Confirmar", onde 100% o esticaria por
     cima do outro. */
  position: relative; overflow: hidden;
  border-radius: 6px; padding: 8px 14px; cursor: pointer;
  font-family: var(--font-heading); font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; font-size: 12px;
  color: #2a1d05; border: 1px solid #f6d999;
  background: linear-gradient(180deg, #ffe9b0 0%, #e8b955 48%, #c9922f 100%);
  box-shadow: 0 0 14px -4px rgba(236, 190, 96, .85), inset 0 1px 0 rgba(255, 255, 255, .55);
}
#modal button.recompensa-pegar::after,
.atualizar button.recompensa-pegar::after {
  content: ''; position: absolute; top: 0; bottom: 0; width: 45%;
  left: -60%; transform: skewX(-18deg); pointer-events: none;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .75), transparent);
  animation: recompensa-brilho 3.2s ease-in-out infinite;
}
#modal button.recompensa-pegar:hover:not(:disabled),
.atualizar button.recompensa-pegar:hover:not(:disabled) { filter: brightness(1.1); }
#modal button.recompensa-pegar:active:not(:disabled),
.atualizar button.recompensa-pegar:active:not(:disabled) { transform: translateY(1px); }
#modal button.recompensa-pegar:disabled,
.atualizar button.recompensa-pegar:disabled {
  background: var(--panel); border-color: var(--line); color: var(--muted);
  box-shadow: none; cursor: not-allowed;
}
/* Sem ouro não há o que celebrar: o brilho para junto com o botão. */
#modal button.recompensa-pegar:disabled::after,
.atualizar button.recompensa-pegar:disabled::after { animation: none; opacity: 0; }
@keyframes recompensa-brilho {
  0% { left: -60%; }
  55%, 100% { left: 130%; }
}
@media (prefers-reduced-motion: reduce) {
  #modal button.recompensa-pegar::after,
  .atualizar button.recompensa-pegar::after { animation: none; opacity: 0; }
}

/* A grade do "foi para o depósito": item desenhado, nome e a caixa onde está. */
/*
 * `auto-fit` e 180px, e nao `auto-fill` e 120.
 *
 * Com `auto-fill` a grade cria colunas vazias para preencher a largura, e um
 * item sozinho ficava num cartao de 120px no meio de uma janela de 900 — foi o
 * que apertou o nome ate ele quebrar letra por letra. `auto-fit` recolhe as
 * colunas vazias, entao um item sozinho ocupa a linha inteira, dois dividem ao
 * meio, e a partir de tres a grade volta a se comportar como antes.
 */
.marco-itens {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 8px; margin: 6px 0 10px;
}
.marco-item {
  display: flex; align-items: center; gap: 9px; padding: 7px 9px;
  border: 1px solid var(--line); border-radius: 4px; background: rgba(255, 255, 255, .03);
}
/* O desenho nao encolhe; quem cede espaco e o texto, que sabe quebrar. */
.marco-item > canvas, .marco-item > img { flex: none; }
/*
 * `min-width: 0` e o que permite ao bloco encolher DENTRO do flex.
 *
 * Sem ele um item de flex nunca fica menor que o conteudo dele, e o texto
 * empurra o cartao ou estoura para fora em vez de quebrar por palavra.
 */
.marco-texto { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.marco-item em { font-style: normal; font-size: 11px; line-height: 1.3; overflow-wrap: break-word; }
.marco-caixa { font-size: 10px; opacity: .6; }
.deposito-titulo { display: block; margin: 12px 0 6px; font-size: 13px; opacity: .85; }


/* ---------- a ficha de quem falou no chat ----------
 *
 * O nome vira alvo de clique: sublinhado pontilhado, que diz "dá para clicar"
 * sem transformar a conversa numa página de links azuis. O clique abre o mesmo
 * menuzinho de quando se clica em alguém na cidade — ver `mostrarPerfil`. */
/*
 * O nome é clicável, e o pontilhado embaixo dele saiu.
 *
 * Ele era a dica de "dá para clicar aqui", e numa janela em que TODO nome é
 * clicável a dica vira ruído: cada linha do Global saía sublinhada. O convite
 * continua no cursor de mão e no brilho ao passar o mouse, que aparecem
 * exatamente quando a pergunta existe.
 */
.who-clicavel { cursor: pointer; }
.who-clicavel:hover { filter: brightness(1.2); text-decoration: underline; text-decoration-color: var(--accent); }


/* ---------- a tela de morte: foto e extrato ----------
 *
 * A foto tem largura fixa e a moldura acompanha: uma imagem que estica com a
 * janela sai borrada, e o que interessa nela são os pixels do jogo. */
/* Foto e extrato dividem a largura; numa janela estreita voltam a empilhar. */
.morte-colunas {
  display: grid; grid-template-columns: minmax(0, 420px) minmax(0, 1fr);
  gap: 16px; align-items: start; text-align: left; margin: 10px 0 2px;
}
.morte-colunas:only-child { justify-content: center; }
@media (max-width: 980px) { .morte-colunas { grid-template-columns: 1fr; } }
.morte-foto { margin: 0 auto; text-align: center; max-width: 420px; }
.morte-foto img {
  display: block; width: 100%; height: auto; border: 1px solid var(--line);
  border-radius: 4px; image-rendering: pixelated;
  box-shadow: 0 6px 22px -10px #000;
}
.morte-foto em { display: block; margin-top: 4px; font-style: normal; font-size: 10.5px; color: var(--muted); }
/* O extrato é longo; ele rola dentro da caixa em vez de empurrar os botões
   para fora da tela. */
.morte-extrato {
  margin: 0; padding: 10px 12px; max-height: 46vh; overflow-y: auto;
  border: 1px solid var(--line); border-radius: 6px; background: rgba(255, 255, 255, .025);
}
.morte-ocultar { display: block; margin: 6px auto 0; font-size: 11px; opacity: .75; }
.morte-ocultar:hover { opacity: 1; }

/* A conta da compra do marco: tem / sai / sobra, em três linhas. */
.confirmar-itens { margin: 10px 0; }
.confirmar-conta { max-width: 320px; margin: 10px auto 4px; }
.confirmar-conta div { display: flex; justify-content: space-between; gap: 16px; padding: 3px 0; }
.confirmar-conta b { font-family: var(--font-heading); letter-spacing: .03em; }

/* A caixa de morte cresce quando tem as duas colunas dentro. */
.morte-painel.morte-largo { max-width: min(940px, 94vw); }
/* E nunca passa da altura da tela: o "Continuar" tem de estar sempre à vista. */
.morte-painel { max-height: 92vh; overflow-y: auto; }

/* ---------- a foto ampliada ----------
 *
 * Acima da caixa de morte (80), que é de onde ela é aberta. `contain` para a
 * imagem crescer até o limite da tela sem cortar nem esticar, e `pixelated`
 * porque o conteúdo é o mapa do jogo — suavizar transformaria os sprites em
 * borrão justamente no aumento. */
.foto-lupa {
  position: fixed; inset: 0; z-index: 90; cursor: zoom-out;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px;
  padding: 24px; background: rgba(4, 6, 7, .95);
  animation: morte-entra .18s ease;
}
.foto-lupa img {
  max-width: 100%; max-height: calc(100% - 30px); object-fit: contain;
  image-rendering: pixelated; border: 1px solid var(--line); border-radius: 6px;
  box-shadow: 0 20px 60px #000c;
}
.foto-lupa em { font-style: normal; font-size: 11px; color: var(--muted); letter-spacing: .04em; }
/* Na caixa de morte a foto passa a ser clicável, e o cursor diz isso. */
.morte-foto img { cursor: zoom-in; }
.morte-foto img:hover { border-color: var(--accent); }

/* ---------- a caixa de morte, vestida ----------
 *
 * O desenho de fundo entra como PRIMEIRA camada de `background`. Se o arquivo
 * não existir, o navegador descarta só aquela camada e o gradiente de trás
 * continua pintando: a caixa nunca fica transparente esperando arte. */
/* ---- A moldura desenhada ----
 *
 * `border-image` em vez de `background-image`: esticar o PNG inteiro deformaria
 * os cantos de ouro quando a caixa fica alta ou estreita. Aqui a arte é fatiada
 * — os quatro cantos vão inteiros para os cantos, as bordas esticam só no
 * comprimento, e o `fill` pinta o miolo escuro por dentro.
 *
 * Sem o arquivo, `border-image` é simplesmente ignorado: sobra uma borda
 * transparente de 26px com o gradiente de trás aparecendo por baixo. A caixa
 * nunca fica quebrada esperando arte. */
.morte-painel {
  background: linear-gradient(180deg, #17100ff2, #0b0d0ef7);
  border: 26px solid transparent;
  border-image: url('/client/assets/ui/morte-fundo.png') 150 fill stretch;
  border-radius: 0;
  padding: 10px 20px 16px;
}
/* O selo em cima do título — sai sozinho quando não há PNG (ver `mostrarMorte`). */
.morte-selo {
  display: block; width: 96px; height: 96px; margin: -6px auto -10px;
  object-fit: contain; filter: drop-shadow(0 6px 18px #7a2c2688);
  pointer-events: none;
}
/* Um fio de ouro separando o título da conta — o mesmo da moldura das janelas. */
.morte-painel h2 + .morte-perdas { position: relative; padding-top: 14px; }
.morte-painel h2 + .morte-perdas::before {
  content: ''; position: absolute; top: 0; left: 12%; right: 12%; height: 1px;
  background: linear-gradient(90deg, transparent, #e0b45a66 30%, #e0b45a66 70%, transparent);
}
/* A foto é o botão inteiro, e o dedo precisa saber disso. */
.morte-foto { cursor: zoom-in; pointer-events: auto; border-radius: 6px; padding: 4px; }
.morte-foto:hover { background: rgba(224, 180, 90, .07); }
.morte-foto:hover img { border-color: #e0b45a; }
.morte-foto:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.morte-foto img { border-width: 2px; }
/* O extrato ganha a mesma moldura discreta da foto, para os dois lados casarem. */
.morte-extrato { background: rgba(0, 0, 0, .25); border-color: #ffffff1f; }
.morte-extrato .rows > div { padding: 3px 0; border-bottom: 1px solid #ffffff0d; }
.morte-extrato .rows > div:last-child { border-bottom: 0; }

/* ---------- os números do dinheiro ----------
 *
 * `tabular-nums` trava a largura de cada algarismo: sem isso a coluna do preço
 * pula de lugar a cada centavo que muda, e no banco o valor "anda" enquanto se
 * digita. */
.bank-figure b,
.leilao-saldo b,
.market-bar b,
.market-row .price,
.morte-perdas b,
.confirmar-conta b,
.recompensa-preco span {
  font-family: var(--font-numero);
  font-variant-numeric: tabular-nums;
  letter-spacing: .01em;
}
/* No banco eles são a informação principal da tela: peso e tamanho acompanham. */
.bank-figure b { font-weight: 600; font-size: 27px; line-height: 1.1; }
.leilao-saldo b, .market-bar b { font-weight: 500; font-size: 15px; }
.morte-perdas b { font-weight: 600; font-size: 23px; }
.confirmar-conta b { font-weight: 500; }

/* ---------- "versão nova" ----------
 *
 * Acima de tudo (a lupa da morte é 90): enquanto esta caixa está de pé, nada
 * mais na página deve ser clicável — a aba está rodando código velho, e é isso
 * que se quer interromper. */
.atualizar {
  position: fixed; inset: 0; z-index: 120;
  display: grid; place-items: center; padding: 24px;
  /*
   * ---- O jogo continua à vista ----
   *
   * O fundo era quase opaco e apagava a tela inteira: quem estava caçando via a
   * caverna virar um retângulo preto e não tinha como saber se o personagem
   * continuava vivo lá atrás. E ele continua — a caçada roda no servidor, e
   * nada aqui a interrompe.
   *
   * Então a cortina só escurece as bordas e deixa o meio quase limpo: o mapa,
   * as barras e o boneco seguem visíveis e mexendo. O aviso continua obrigando
   * (ele toma os cliques), mas para de esconder o que estava acontecendo.
   */
  background: radial-gradient(ellipse at center, rgba(4, 6, 7, .10) 0%, rgba(4, 6, 7, .62) 100%);
  animation: morte-entra .25s ease;
}
/*
 * A moldura vem do `.ui-frame--miudo` (a mesma das janelas). Aqui fica só a
 * largura e a sombra — `filter` e não `box-shadow`, porque a sombra tem de
 * seguir o RECORTE do ornamento, e não uma caixa retangular por baixo dele.
 */
.atualizar-painel {
  max-width: 460px;
  filter: drop-shadow(0 24px 40px rgba(0, 0, 0, .85));
}
/* O miolo: `.ui-frame` zera fundo e padding, então quem os põe de volta é este.
   Opaco, porque agora tem jogo aparecendo atrás. */
.atualizar-dentro {
  display: grid; gap: 12px; text-align: center;
  padding: 18px 20px 16px;
  /*
   * Translúcido: o jogo aparece POR DENTRO da caixa também, não só em volta
   * dela. O `blur` é o que segura a leitura — sem ele, um chão claro passando
   * atrás do texto o apagaria, e o aviso precisa ser lido de primeira.
   */
  background: linear-gradient(180deg, rgba(16, 26, 24, .78), rgba(11, 13, 14, .84));
  backdrop-filter: blur(7px) saturate(1.1);
}
.atualizar-dentro h2 {
  margin: 0; font-family: var(--font-title); font-size: 22px;
  letter-spacing: .08em; color: var(--accent);
}
.atualizar-dentro p { margin: 0; font-size: 12.5px; line-height: 1.6; }
.atualizar-nota { color: var(--muted); font-size: 11px !important; }
.atualizar-dentro button { justify-self: center; min-width: 200px; margin-top: 4px; }

/* A lista de novidades dentro do aviso de versão. Ela pode crescer, então rola
   dentro da caixa em vez de empurrar o botão para fora da tela. */
.atualizar-painel { max-width: 520px; }
.atualizar-novidades {
  text-align: left; margin: 2px 0 0; padding: 10px 12px;
  max-height: 42vh; overflow-y: auto;
  background: rgba(0, 0, 0, .28); border: 1px solid var(--line); border-radius: 6px;
}
.atualizar-novidades b {
  display: block; margin-bottom: 6px; font-family: var(--font-heading);
  font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--accent);
}
.atualizar-novidades ul { margin: 0; padding-left: 16px; }
.atualizar-novidades li { font-size: 11.5px; line-height: 1.5; margin-bottom: 5px; color: var(--text); }
.atualizar-novidades li::marker { color: var(--accent-dim); }

/* ======================================================= O BALCÃO (mercado) */
/*
 * A tela é uma TABELA e não um par de colunas, então tudo aqui nasce da mesma
 * grade: o cabeçalho e cada linha compartilham `grid-template-columns`, e é só
 * isso que mantém as colunas alinhadas quando o nome do item é curto numa linha
 * e comprido na outra.
 */

.balcao-topo {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}
.balcao-saldos { display: flex; gap: 8px; }
.balcao-moeda {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--panel-2);
}
.balcao-moeda b { font-family: var(--font-numero); font-size: 15px; letter-spacing: 0.02em; }
/*
 * A figura de verdade dentro do chip: a pilha de crystal coins para o ouro
 * (item 3043, a mesma da barra do topo) e a arte da loja para a coin. Um disco
 * desenhado no CSS morava aqui e não era nenhuma das duas.
 */
.balcao-moeda canvas,
.balcao-moeda img { width: 18px; height: 18px; flex: none; image-rendering: pixelated; }
.balcao-moeda.ouro b { color: var(--copper); }
.balcao-moeda.coin b { color: var(--accent); }

/* ---------------------------------------------------------------- peneira */
.balcao-peneira {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
  padding: 10px;
  border: 1px solid var(--line-soft);
  border-radius: 6px;
  background: #10161980;
  margin-bottom: 10px;
}
.balcao-peneira .search { flex: 1 1 180px; min-width: 140px; }
.balcao-peneira .search,
.balcao-peneira select {
  padding: 7px 9px;
  border: 1px solid var(--line);
  border-radius: 5px;
  background: var(--panel-solid);
  color: var(--text);
  font: inherit;
  font-size: 12px;
}
.balcao-peneira select { flex: 0 1 auto; cursor: pointer; }
.balcao-peneira select:hover { border-color: var(--accent-dim); }
.balcao-limpar {
  padding: 7px 12px;
  border: 1px solid var(--line);
  border-radius: 5px;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}
.balcao-limpar:hover { border-color: var(--danger); color: var(--danger); }

/* ----------------------------------------------------------------- tabela */
/*
 * ---- A janela não encolhe enquanto se filtra ----
 *
 * A tabela tem sempre a altura de uma página cheia (oito linhas), mesmo com
 * uma linha só ou nenhuma. Sem isto, cada tecla digitada na busca mudava o
 * tamanho do modal — ele pulava para cima e para baixo enquanto o resultado
 * afinava, e os botões de página fugiam de baixo do cursor.
 *
 * Oito linhas de 48px mais o cabeçalho e os vãos: é o que `porPagina: 8` pede.
 */
.balcao-tabela {
  display: grid;
  gap: 4px;
  align-content: start;
  min-height: 420px;
}
/* O câmbio tem seis linhas por lado, e as linhas dele são mais baixas. */
.balcao-tabela.coins { min-height: 258px; }
.balcao-linha {
  display: grid;
  /* Item, level, slot, preço e o botão. */
  grid-template-columns: minmax(0, 1fr) 58px 92px 148px 116px;
  align-items: center;
  gap: 10px;
  padding: 7px 10px;
  border: 1px solid var(--line-soft);
  border-radius: 6px;
  background: var(--panel-2);
}
.balcao-linha:hover { border-color: var(--line); }
.balcao-linha.cabeca {
  border-color: transparent;
  background: none;
  padding-bottom: 2px;
  font-family: var(--font-heading);
  font-size: 10px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--muted);
}
.balcao-linha.cabeca:hover { border-color: transparent; }
/*
 * "Minhas ofertas" tem outra grade: no lugar do level ela mostra a QUANTIDADE
 * anunciada, e o "vendendo/comprando" precisa de mais espaço do que um número
 * de level. Sem esta linha ela herdava a grade da tabela de anúncios e o
 * "comprando" saía cortado.
 */
.balcao-linha.minha { border-left: 2px solid var(--accent-dim); grid-template-columns: minmax(0, 1fr) 92px 72px 148px 116px; }

/*
 * O cabeçalho ORDENA: cada coluna é um botão, e a que está mandando na lista
 * fica acesa com a setinha do sentido. Ver `COLUNAS_DO_BALCAO`, no panels.mjs.
 */
.balcao-ordena { cursor: pointer; display: flex; align-items: center; gap: 4px; }
.balcao-ordena:hover { color: var(--text); }
.balcao-ordena.ordenando { color: var(--accent); }
.balcao-ordena i { font-style: normal; font-size: 8px; opacity: .9; }

/*
 * O level pedido pela peça. Tabular para as unidades ficarem uma embaixo da
 * outra, e vermelho quando está acima do seu — ver a nota no `corpoDasOfertas`.
 */
.balcao-level { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
.balcao-level.alto { color: var(--danger); }

.balcao-item { display: flex; align-items: center; gap: 9px; min-width: 0; }
.balcao-item canvas { flex: none; }
.balcao-item-texto { display: grid; gap: 1px; min-width: 0; }
.balcao-item-texto b,
.balcao-item > b {
  font-weight: 500;
  font-size: 13px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.balcao-item-texto em { font-style: normal; font-size: 10px; color: var(--muted); }

.balcao-slot { font-size: 11px; color: var(--muted); text-transform: capitalize; }

.balcao-preco { display: grid; gap: 1px; justify-items: end; }
.balcao-preco-linha { display: flex; align-items: center; gap: 5px; }
.balcao-preco-linha canvas { width: 14px; height: 14px; flex: none; image-rendering: pixelated; }
.balcao-preco b { font-family: var(--font-numero); font-size: 14px; color: var(--copper); }
.balcao-preco em { font-style: normal; font-size: 10px; color: var(--muted); }

/*
 * O botão de comprar: aceso quando dá, apagado quando não dá.
 *
 * A diferença entre os dois estados é grande de propósito — numa lista de oito
 * linhas o jogador decide pelo que está ACESO, sem ler preço por preço.
 */
.balcao-comprar {
  padding: 8px 10px;
  border: 1px solid transparent;
  border-radius: 5px;
  background: linear-gradient(#d2913f, #a9662a);
  color: #1a1207;
  font-family: var(--font-heading);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  cursor: pointer;
}
.balcao-comprar:hover:not(:disabled) { filter: brightness(1.12); }
.balcao-comprar:disabled {
  background: none;
  border-color: var(--line);
  color: #556065;
  cursor: not-allowed;
}
.balcao-comprar.ghost {
  background: none;
  border-color: var(--line);
  color: var(--muted);
}
.balcao-comprar.ghost:hover:not(:disabled) { border-color: var(--danger); color: var(--danger); filter: none; }

/* -------------------------------------------------------------- paginação */
.balcao-paginas {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  margin-top: 12px;
}
.balcao-paginas button {
  padding: 7px 14px;
  border: 1px solid var(--line);
  border-radius: 5px;
  background: var(--panel-2);
  color: var(--text);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}
.balcao-paginas button:hover:not(:disabled) { border-color: var(--accent-dim); }
.balcao-paginas button:disabled { opacity: 0.35; cursor: not-allowed; }
.balcao-conta { font-family: var(--font-numero); font-size: 12px; color: var(--muted); }

/* ------------------------------------------------------------ mineiroidle coins */
.balcao-cambio-nota {
  padding: 9px 12px;
  border: 1px solid var(--line-soft);
  border-left: 2px solid var(--accent-dim);
  border-radius: 5px;
  background: #10161980;
  margin-bottom: 12px;
}
.balcao-cambio-nota p { margin: 0; font-size: 11px; line-height: 1.5; color: var(--muted); }

.balcao-cambio { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; align-items: start; }
.balcao-coluna { display: grid; gap: 8px; align-content: start; min-width: 0; }
.balcao-coluna-topo {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.balcao-coluna-topo b { font-family: var(--font-heading); font-size: 13px; }
/* A cor de cada lado do câmbio: quem paga, e quem cobra. */
.balcao-coluna.compra .balcao-coluna-topo b { color: var(--hp); }
.balcao-coluna.venda .balcao-coluna-topo b { color: var(--copper); }
.balcao-criar {
  padding: 6px 11px;
  border: 1px solid var(--accent-dim);
  border-radius: 5px;
  background: transparent;
  color: var(--accent);
  font: inherit;
  font-size: 11px;
  cursor: pointer;
}
.balcao-criar:hover { background: #16241f; }

/* No câmbio a grade é outra: não há item nem raridade, só números. */
.balcao-tabela.coins .balcao-linha {
  grid-template-columns: minmax(0, 1fr) 60px 74px 84px 92px;
  gap: 8px;
}
.balcao-quem {
  font-size: 12px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.balcao-coin-qtd,
.balcao-coin-preco,
.balcao-coin-total { font-family: var(--font-numero); font-size: 12px; text-align: right; }
.balcao-coin-qtd { color: var(--accent); }
.balcao-coin-preco { color: var(--text); }
.balcao-coin-total { color: var(--copper); }

/* -------------------------------------------------- escolher o que vender */
.confirm-box.largo { max-width: 520px; width: 92vw; }
.balcao-escolher {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 6px;
  max-height: 46vh;
  overflow-y: auto;
  padding: 2px;
  margin: 8px 0;
}
.balcao-escolha {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border: 1px solid var(--line-soft);
  border-radius: 5px;
  background: var(--panel-2);
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
  min-width: 0;
}
.balcao-escolha:hover { border-color: var(--accent); }
/*
 * A peça com tier ou imbuement ocupa DUAS linhas — nome em cima, selos embaixo
 * — e por isso a coluna mede mais e o cartão nao pode centralizar mais nada
 * pela vertical: o desenho do item alinha pelo topo do texto.
 */
.balcao-escolha .balcao-item-texto { flex: 1 1 auto; }
.balcao-escolha .balcao-marcas { gap: 4px; }
/* Peça única: o campo continua legível, mas não convida a mexer. */
.num-campo.travado { opacity: 0.6; pointer-events: none; }
.balcao-escolha b {
  font-weight: 500;
  font-size: 12px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/*
 * ---- O Mercado como o Market do Tibia: categorias à esquerda ----
 *
 * A coluna de categorias, a fita dos itens da categoria e a ficha que abre
 * embaixo de um anúncio (o "Details"). Mesmas cores do resto do balcão: o
 * painel escuro, o fio `--line`, o verde `--accent` no que está escolhido e o
 * cobre no preço.
 */
.balcao-corpo { display: flex; gap: 12px; align-items: flex-start; min-width: 0; }
.balcao-principal { flex: 1 1 auto; min-width: 0; }
.balcao-categorias {
  flex: 0 0 176px; display: grid; gap: 2px; align-content: start;
  padding: 6px; border: 1px solid var(--line-soft); border-radius: 6px; background: #10161980;
  max-height: 560px; overflow-y: auto;
}
.balcao-categoria {
  display: flex; align-items: center; justify-content: space-between; gap: 6px;
  padding: 6px 8px; border: 1px solid transparent; border-radius: 5px;
  background: none; color: var(--muted); font: inherit; font-size: 12px; text-align: left; cursor: pointer;
}
.balcao-categoria span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.balcao-categoria i { font-style: normal; font-family: var(--font-numero); font-size: 10px; color: var(--accent-dim); flex: none; }
.balcao-categoria:hover { color: var(--text); border-color: var(--line); }
.balcao-categoria.on { color: var(--accent); background: #16241f; border-color: var(--accent-dim); }
.balcao-categoria.on i { color: var(--accent); }
.balcao-categoria.filha { padding-left: 20px; font-size: 11px; }
.balcao-categoria.filha::before { content: '·'; margin-right: -2px; color: var(--muted); }

.balcao-itens { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 8px; }
.balcao-item-chip {
  display: flex; align-items: center; gap: 6px; max-width: 240px; min-width: 0;
  padding: 3px 8px 3px 4px; border: 1px solid var(--line-soft); border-radius: 999px;
  background: var(--panel-2); color: var(--text); font: inherit; text-align: left; cursor: pointer;
}
.balcao-item-chip canvas { flex: none; }
.balcao-item-chip:hover { border-color: var(--line); }
.balcao-item-chip.on { border-color: var(--accent); background: #16241f; }
.balcao-item-chip-texto { display: grid; gap: 0; min-width: 0; }
.balcao-item-chip b { font-weight: 500; font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.balcao-item-chip em { font-style: normal; font-size: 9.5px; color: var(--muted); white-space: nowrap; }

.balcao-detalhar {
  flex: none; width: 22px; height: 22px; padding: 0; margin-left: 2px;
  border: 1px solid var(--line); border-radius: 50%; background: none;
  color: var(--muted); font-size: 13px; line-height: 1; cursor: pointer;
}
.balcao-detalhar:hover, .balcao-detalhar[aria-expanded="true"] { color: var(--accent); border-color: var(--accent-dim); }
.balcao-detalhe {
  margin: -2px 0 2px 18px; padding: 0;
  border-left: 2px solid var(--accent-dim);
}
/* A ficha é a do balão, sem o balão: mesma faixa de raridade, sem flutuar. */
.balcao-detalhe-ficha {
  max-width: 560px; border: 1px solid var(--tier, var(--copper)); border-radius: 8px;
  background: linear-gradient(180deg, #121b1ff2, #0b1113f7); font-size: 12px; overflow: hidden;
}
.balcao-detalhe-ficha::before { content: ""; display: block; height: 2px; background: var(--tier, var(--copper)); }

/* No telefone a coluna vira uma fita que rola de lado, acima de tudo. */
@media (max-width: 820px) {
  .balcao-corpo { flex-direction: column; gap: 8px; }
  .balcao-categorias {
    flex: none; width: 100%; display: flex; flex-wrap: nowrap; overflow-x: auto; overflow-y: hidden;
    max-height: none; scrollbar-width: none; -webkit-overflow-scrolling: touch;
  }
  .balcao-categorias::-webkit-scrollbar { display: none; }
  .balcao-categoria { flex: none; white-space: nowrap; }
  .balcao-categoria.filha { padding-left: 8px; }
  .balcao-detalhe { margin-left: 0; }
  /*
   * A linha do anúncio deixa de ser a grade de cinco colunas de mesa (58, 92,
   * 148 e 116px fixos numa tela de 360 espremiam o nome letra a letra) e vira
   * duas fileiras: o item em cima, preço e botão embaixo. Level e slot saem —
   * os dois estão na ficha do ⓘ.
   */
  .balcao-linha, .balcao-linha.minha { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; }
  .balcao-linha.cabeca { display: none; }
  .balcao-linha .balcao-item { flex: 1 1 100%; }
  .balcao-linha .balcao-level, .balcao-linha .balcao-slot { display: none; }
  .balcao-linha .balcao-preco { flex: 1 1 auto; justify-items: start; }
  .balcao-linha .balcao-comprar { flex: none; }
  .balcao-item-texto b { white-space: normal; }
  .balcao-moeda b { white-space: nowrap; font-size: 13px; }
  .balcao-detalhe-ficha { max-width: none; }
}

@media (max-width: 780px) {
  .balcao-cambio { grid-template-columns: 1fr; }
  /*
   * Sem espaço para cinco colunas: o SLOT sai, o level fica. Dos dois, o level
   * é o que decide se a peça serve — o slot a pessoa lê no nome do item.
   */
  .balcao-linha,
  .balcao-linha.minha { grid-template-columns: minmax(0, 1fr) 38px 82px 86px; gap: 6px; }
  .balcao-linha > .balcao-slot,
  .balcao-linha.cabeca > .balcao-ordena:nth-child(3) { display: none; }
  .balcao-peneira .search { flex-basis: 100%; }
}

/* ==================================================== AS BÊNÇÃOS (blessings) */

/* Centralizado: os números do topo são o resumo da tela, não uma barra lateral. */
.bless-chips { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-bottom: 10px; }
.bless-chip {
  display: grid;
  gap: 1px;
  padding: 8px 14px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--panel-2);
  min-width: 96px;
}
.bless-chip b { font-family: var(--font-numero); font-size: 17px; color: var(--text); line-height: 1.1; }
.bless-chip span {
  font-size: 9px;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--muted);
}
.bless-chip.cheio { border-color: var(--accent); background: #16241f; }
.bless-chip.cheio b { color: var(--accent); }
.bless-chip.bom b { color: var(--hp); }
.bless-chip.perda b { color: var(--danger); }

.bless-poupanca {
  margin: 0 0 12px;
  font-size: 11px;
  line-height: 1.5;
  color: var(--muted);
  text-align: center;
}
/* O parágrafo da regra, no pé, pela mesma razão do resto. */
.bless-rodape ~ .shop-note { text-align: center; }

/*
 * `auto-fit` com `justify-content: center`, e não `auto-fill`.
 *
 * São sete bênçãos: numa fileira de cinco, as duas que sobram ficavam
 * encostadas na esquerda com um vão do tamanho de três cards à direita. Com o
 * centro, a fileira órfã fica no meio — que é como o olho espera ver o resto de
 * uma grade.
 */
.bless-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(148px, 168px));
  justify-content: center;
  gap: 9px;
}
.bless-card {
  display: grid;
  gap: 5px;
  justify-items: center;
  padding: 13px 10px 11px;
  border: 1px solid var(--line-soft);
  border-radius: 7px;
  /*
   * O pergaminho: um brilho quente no alto do card, que some quando a bênção
   * já está ativa (aí o card inteiro vira verde). É o que dá relevo à fileira
   * sem precisar de arte nova para cada uma.
   */
  background: radial-gradient(120% 70% at 50% 0%, #23292c, var(--panel-2) 70%);
  text-align: center;
}
.bless-card:hover { border-color: var(--line); }
.bless-card.owned {
  border-color: var(--accent-dim);
  background: radial-gradient(120% 70% at 50% 0%, #1b2f29, #16241f 70%);
}
.bless-arte {
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: #0f1417a0;
  border: 1px solid var(--line-soft);
}
.bless-card.owned .bless-arte { border-color: var(--accent-dim); }
.bless-arte canvas { width: 40px; height: 40px; }
.bless-nome {
  font-family: var(--font-heading);
  font-size: 12px;
  line-height: 1.25;
  min-height: 30px;
  display: flex;
  align-items: center;
}
.bless-tipo { font-style: normal; font-size: 9px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); }
.bless-preco { display: flex; align-items: baseline; gap: 4px; }
.bless-preco b { font-family: var(--font-numero); font-size: 15px; color: var(--copper); }
.bless-preco span { font-size: 9px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); }

.bless-comprar {
  width: 100%;
  margin-top: 2px;
  padding: 7px;
  border: 1px solid transparent;
  border-radius: 5px;
  background: linear-gradient(#d2913f, #a9662a);
  color: #1a1207;
  font-family: var(--font-heading);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  cursor: pointer;
}
.bless-comprar:hover:not(:disabled) { filter: brightness(1.12); }
.bless-comprar:disabled { background: none; border-color: var(--line); color: #556065; cursor: not-allowed; }

.bless-ativa {
  width: 100%;
  margin-top: 2px;
  padding: 7px;
  border: 1px solid var(--accent-dim);
  border-radius: 5px;
  color: var(--accent);
  font-family: var(--font-heading);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.bless-rodape { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-top: 14px; }
.bless-todas {
  flex: 1 1 240px;
  padding: 11px;
  border: 1px solid transparent;
  border-radius: 6px;
  background: linear-gradient(#d2913f, #a9662a);
  color: #1a1207;
  font-family: var(--font-heading);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  cursor: pointer;
}
.bless-todas:hover:not(:disabled) { filter: brightness(1.12); }
.bless-todas:disabled { background: none; border-color: var(--line); color: #556065; cursor: not-allowed; }

.bless-loja {
  flex: 0 1 240px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 11px 14px;
  border: 1px solid var(--accent-dim);
  border-radius: 6px;
  background: transparent;
  color: var(--accent);
  font-family: var(--font-heading);
  font-size: 12px;
  cursor: pointer;
}
.bless-loja:hover { background: #16241f; }
/* O preço em coins vem com a MOEDA, para não se confundir com o preço em ouro. */
.bless-loja-moeda {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 9px 2px 5px;
  border-radius: 10px;
  background: #16241f;
  border: 1px solid var(--accent-dim);
}
.bless-loja-moeda img { width: 14px; height: 14px; image-rendering: pixelated; }
.bless-loja-moeda b { font-family: var(--font-numero); font-size: 12px; color: var(--accent); }

/* ================================================ O CAMPO DE NÚMERO DO JOGO */
/*
 * As setinhas do `<input type=number>` são desenho do navegador — fundo branco
 * no meio de um painel escuro, e sem CSS que as pinte de verdade. Aqui elas são
 * dois botões nossos, e o campo é de texto para caber o ponto de milhar.
 *
 * A regra abaixo apaga as nativas onde ainda houver um `type=number` vivo, para
 * o branco não voltar por uma porta esquecida.
 */
input[type='number']::-webkit-outer-spin-button,
input[type='number']::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
input[type='number'] { -moz-appearance: textfield; appearance: textfield; }

.num-campo { display: grid; gap: 4px; }
.num-rotulo { font-size: 11px; color: var(--muted); }
.num-linha { display: flex; align-items: stretch; gap: 5px; }

.num-entrada {
  flex: 1 1 auto;
  min-width: 0;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 5px;
  background: var(--panel-solid);
  color: var(--text);
  font-family: var(--font-numero);
  font-size: 15px;
  letter-spacing: 0.02em;
  text-align: right;
}
.num-entrada:focus { outline: none; border-color: var(--accent); }

.num-passo {
  flex: none;
  width: 34px;
  border: 1px solid var(--line);
  border-radius: 5px;
  background: var(--panel-2);
  color: var(--text);
  font-family: var(--font-numero);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  user-select: none;
}
.num-passo:hover { border-color: var(--accent-dim); color: var(--accent); }
.num-passo:active { background: #16241f; }

.num-max {
  flex: none;
  padding: 0 12px;
  border: 1px solid var(--accent-dim);
  border-radius: 5px;
  background: transparent;
  color: var(--accent);
  font-family: var(--font-heading);
  font-size: 11px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  cursor: pointer;
}
.num-max:hover { background: #16241f; }

/* ------------------------------------------------ a caixa de fechar negócio */
.confirm-box.negocio { display: grid; gap: 11px; }

.negocio-alvo {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 10px 12px;
  border: 1px solid var(--line-soft);
  border-radius: 6px;
  background: var(--panel-2);
}
.negocio-alvo img { width: 34px; height: 34px; }
.negocio-alvo-texto { display: grid; gap: 2px; min-width: 0; }
.negocio-alvo-texto b { font-family: var(--font-heading); font-size: 13px; }
.negocio-alvo-texto em { font-style: normal; font-size: 11px; color: var(--muted); }

.negocio-total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--line-soft);
  border-left: 2px solid var(--copper);
  border-radius: 6px;
  background: #10161980;
}
.negocio-total span { font-size: 11px; letter-spacing: 0.07em; text-transform: uppercase; color: var(--muted); }
.negocio-total b { font-family: var(--font-numero); font-size: 19px; color: var(--copper); }


/* A linha do banco: campo largo, e os dois botões do tamanho do texto. */
.bank-linha { display: flex; align-items: stretch; gap: 6px; }
.bank-linha .num-campo { flex: 1 1 auto; min-width: 0; }

/* ------------------------------------------ o lado do balcão e a busca com arte */

/*
 * ---- O par de decisão ----
 *
 * Centralizado e largo porque não é filtro: é a pergunta que define o que a
 * lista inteira quer dizer. Cada botão tem título e legenda — sem a legenda,
 * "Procurados" não se explica sozinho para quem abre a tela pela primeira vez.
 */
.balcao-par {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  max-width: 560px;
  margin: 0 auto 14px;
}
.balcao-lado-grande {
  display: grid;
  gap: 3px;
  padding: 13px 16px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: linear-gradient(180deg, #1d262a, var(--panel-2));
  color: var(--muted);
  font: inherit;
  text-align: center;
  cursor: pointer;
  transition: border-color .12s, color .12s;
}
.balcao-lado-grande b {
  font-family: var(--font-heading);
  font-size: 15px;
  letter-spacing: 0.03em;
  color: var(--text);
}
.balcao-lado-grande span { font-size: 10px; color: var(--muted); }
.balcao-lado-grande:hover { border-color: var(--accent-dim); }
/* O lado escolhido acende na cor do que ele faz: comprar em cobre, vender em verde. */
.balcao-lado-grande.on.sell {
  border-color: var(--copper);
  background: linear-gradient(180deg, #2a1f14, #1d1710);
}
.balcao-lado-grande.on.sell b { color: var(--copper); }
.balcao-lado-grande.on.buy {
  border-color: var(--accent);
  background: linear-gradient(180deg, #16281f, #101d18);
}
.balcao-lado-grande.on.buy b { color: var(--accent); }

/* ---- as marcas da peça: tier e imbuement, na segunda linha do nome ---- */
.balcao-marcas { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; min-width: 0; }
.balcao-marcas em { font-style: normal; font-size: 10px; color: var(--muted); }
.balcao-tier,
.balcao-imbu {
  padding: 1px 6px;
  border-radius: 3px;
  font-family: var(--font-numero);
  font-size: 10px;
  letter-spacing: 0.02em;
  white-space: nowrap;
}
.balcao-tier { background: #3a2a12; color: #e0a94a; border: 1px solid #5c4319; }
.balcao-tier.vazio { background: none; color: var(--muted); border-color: var(--line); }
/* Slot vazio é discreto; imbuement ATIVO acende — é ele que vale dinheiro. */
.balcao-imbu { background: none; color: var(--muted); border: 1px solid var(--line); }
.balcao-imbu.cheio { background: #17282c; color: #57b6c8; border-color: #26454c; }

/* A raridade agora é a COR DO NOME, e não uma coluna. */
.rar-comum { color: #b3bec2; }
.rar-incomum { color: #5fbf7f; }
.rar-raro { color: #4f9fd8; }
.rar-epico { color: #a877dd; }
.rar-lendario { color: #d9a13c; }
.rar-mitico { color: #f2503f; }

/*
 * A busca precisa de `position: relative` para a lista de sugestões cair
 * ancorada NELA, e não no canto do painel.
 */
.balcao-busca { position: relative; flex: 1 1 190px; min-width: 150px; }
.balcao-busca .search { width: 100%; }

/*
 * Camada FIXA, e não `absolute` dentro da busca.
 *
 * Dentro da barra de filtros ela era recortada pelo cabeçalho do modal, que
 * tem `overflow: hidden` — e tirar o recorte de lá soltava a fila inteira para
 * fora da moldura. Fixa, ela é posicionada pelo retângulo do campo (ver
 * `posicionarSugestoes`) e não depende de quem está por perto.
 */
.balcao-sugestoes {
  position: fixed;
  z-index: 62;
  display: grid;
  gap: 2px;
  max-height: 300px;
  overflow-y: auto;
  padding: 4px;
  border: 1px solid var(--accent-dim);
  border-radius: 6px;
  background: var(--panel-solid);
  box-shadow: 0 14px 34px #000b;
}
.balcao-sugestao {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 5px 7px;
  border: 1px solid transparent;
  border-radius: 4px;
  background: none;
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
  min-width: 0;
}
.balcao-sugestao:hover { border-color: var(--accent-dim); background: var(--panel-2); }
.balcao-sugestao canvas { width: 28px; height: 28px; flex: none; image-rendering: pixelated; }
.balcao-sugestao-texto { display: grid; gap: 1px; min-width: 0; }
.balcao-sugestao-texto b {
  font-weight: 500;
  font-size: 12px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.balcao-sugestao-texto em { font-style: normal; font-size: 10px; color: var(--muted); text-transform: capitalize; }

/* ------------------------------------------------- anunciar, junto do saldo */
.balcao-anunciar {
  display: flex;
  align-items: center;
  padding: 6px 14px;
  border: 1px solid var(--accent-dim);
  border-radius: 6px;
  background: transparent;
  color: var(--accent);
  font-family: var(--font-heading);
  font-size: 12px;
  white-space: nowrap;
  cursor: pointer;
}
.balcao-anunciar:hover { background: #16241f; border-color: var(--accent); }

/* ------------------------------------------------- o extrato do balcão */

.hist-resumo { justify-content: center; margin-bottom: 12px; }
.balcao-moeda span { font-size: 10px; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.balcao-moeda.hist-ganho b { color: var(--hp); }
.balcao-moeda.hist-gasto b { color: var(--copper); }

/*
 * A linha do extrato tem outra grade: não há slot nem botão, e "com quem"
 * ocupa o lugar deles. A borda da esquerda diz o lado antes da leitura.
 */
.balcao-linha.hist { grid-template-columns: 92px minmax(0, 1fr) 130px 150px; }
.balcao-linha.hist.compra { border-left: 2px solid var(--copper); }
.balcao-linha.hist.venda { border-left: 2px solid var(--hp); }
.balcao-linha.hist.compra .balcao-preco b { color: var(--copper); }
.balcao-linha.hist.venda .balcao-preco b { color: var(--hp); }
.hist-quando { font-size: 11px; color: var(--muted); white-space: nowrap; }
.hist-quem {
  font-size: 12px; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.balcao-linha.hist .balcao-item img { width: 26px; height: 26px; image-rendering: pixelated; }

@media (max-width: 780px) {
  /* Sem espaço para quatro: "com quem" sai, o valor fica. */
  .balcao-linha.hist { grid-template-columns: 78px minmax(0, 1fr) 120px; }
  .balcao-linha.hist > .hist-quem,
  .balcao-linha.hist.cabeca > span:nth-child(3) { display: none; }
}


/* ============================== A PARTY ============================== */

/* A setinha no ícone de Amigos: um segundo destino no mesmo botão. */
.ferramenta-com-menu { position: relative; display: inline-flex; align-items: stretch; }
.ferramenta-seta {
  padding: 0 3px; font-size: 9px; line-height: 1; color: var(--muted);
  background: none; border: none; cursor: pointer; align-self: center;
}
.ferramenta-seta:hover { color: var(--accent); }
.ferramenta-menu {
  position: absolute; top: 100%; right: 0; z-index: 60; min-width: 130px;
  display: flex; flex-direction: column; padding: 3px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 6px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.5);
}
.ferramenta-menu-item {
  padding: 5px 10px; font: inherit; font-size: 12px; text-align: left;
  color: var(--text); background: none; border: none; border-radius: 4px; cursor: pointer;
}
.ferramenta-menu-item:hover { background: var(--panel-2); color: var(--accent); }

/*
 * Os cards, lado a lado. `auto-fill` com um mínimo é o que faz cinco pessoas
 * caberem em duas linhas na janela estreita e numa só na larga, sem media query.
 */
.party-grade {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 6px; margin: 8px 0;
}
.party-card {
  display: flex; flex-direction: column; gap: 3px; padding: 5px 6px;
  border: 1px solid var(--line-soft); border-radius: 5px; background: var(--panel-2);
}
.party-card.eu { border-color: rgba(63, 191, 168, 0.45); }
.party-card.offline { opacity: 0.5; }
.party-card-topo { display: flex; align-items: center; gap: 6px; }
.party-retrato { width: 32px; height: 32px; flex: 0 0 auto; }
.party-nomes { display: grid; gap: 0; min-width: 0; flex: 1 1 auto; }
.party-linha-nome { display: flex; align-items: center; gap: 4px; min-width: 0; }
.party-linha-nome b { font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* A vocação com o ícone dela, e o level ao lado. */
.party-sub { display: flex; align-items: center; gap: 4px; font-size: 9px; color: var(--muted); }
.party-voc-icone { width: 12px; height: 12px; object-fit: contain; flex: 0 0 auto; }
.party-sub i { font-style: normal; }
.party-dentro { color: var(--accent); }
.party-fora { color: #d97a63; }

/*
 * As barras: finas, com o ícone do que medem à esquerda. O número mora no
 * balão — cinco cards com três números cada seria uma parede de dígitos.
 */
.party-linha-barra { display: flex; align-items: center; gap: 4px; }
.party-linha-barra img { width: 10px; height: 10px; object-fit: contain; flex: 0 0 auto; opacity: 0.85; }
.party-barra {
  flex: 1 1 auto; height: 6px; border-radius: 3px; overflow: hidden;
  background: rgba(0, 0, 0, 0.5);
}
.party-barra i { display: block; height: 100%; }
/*
 * As MESMAS cores da barra de habilidade (`.hud-bar.hp` e irmãs). Um segundo
 * vocabulário de cores para vida e mana seria uma coisa a mais para aprender
 * sem motivo — e num card de 6px de barra a cor é tudo o que se lê.
 */
.party-linha-barra.hp .party-barra i { background: linear-gradient(#ef6a52, #a81f14); }
.party-linha-barra.mana .party-barra i { background: linear-gradient(#5fadee, #1d4d99); }
.party-linha-barra.exp .party-barra i { background: linear-gradient(#f0cf7a, #a8781f); }

/*
 * ---- Botões com o NOME do que fazem ----
 *
 * Eram um caractere cada num quadrado de 20px: não dava para ler nem para
 * acertar com o mouse. Um ícone só é atalho quando já se sabe o que ele faz —
 * num botão que se usa uma vez por caçada, a palavra chega antes.
 */
.party-card-acoes { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 3px; }
.party-acao {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 3px 8px; font: inherit; font-size: 10px; line-height: 1.4;
  color: var(--text); background: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--line-soft); border-radius: 5px; cursor: pointer;
}
.party-acao img { width: 12px; height: 12px; object-fit: contain; }
.party-acao i { font-style: normal; font-size: 11px; line-height: 1; }
.party-acao:hover { color: var(--accent); border-color: var(--accent); background: rgba(63, 191, 168, 0.1); }
/* Chamar para a caçada é a ação que se procura: ela puxa a cor do jogo. */
.party-acao.chamar { color: #0b1113; background: var(--accent); border-color: var(--accent); }
.party-acao.chamar:hover { background: #6fe0c8; color: #0b1113; }
.party-acao.perigo:hover { color: #d97a63; border-color: #d97a63; background: rgba(217, 122, 99, 0.12); }
/*
 * "Entrar na hunt" é o pedido, e não o TP: ele fica com a borda da cor do jogo
 * e o fundo apagado. Pintá-lo cheio como o "Chamar" poria dois botões
 * disputando o olho no mesmo card — e quem manda, ali, é o que já existia.
 */
.party-acao.entrar { color: var(--accent); border-color: var(--accent); background: rgba(63, 191, 168, 0.1); }
.party-acao.entrar:hover { background: rgba(63, 191, 168, 0.2); }

/*
 * O pedido de entrada em pé, no alto da janela da party.
 *
 * O cartão flutuante some sozinho; este fica até alguém responder. Ver
 * `corpoDaJanelaDaParty`.
 */
.party-pedido {
  display: flex; flex-direction: column; gap: 5px;
  margin: 4px 0; padding: 6px 8px; border-radius: 6px;
  background: rgba(63, 191, 168, 0.1); border: 1px solid var(--accent);
}
.party-pedido b { font-size: 11px; line-height: 1.3; }
.party-pedido-acoes { display: flex; gap: 4px; }
.party-pedido-acoes button { flex: 1; padding: 3px 6px; font-size: 10px; }

/*
 * Como cada um está configurado — visível para os OUTROS.
 *
 * A escolha é pessoal, mas o efeito é do grupo: sem esta linha, o líder não
 * tinha como saber que o paladino anda a 9 casas, e o comportamento dele virava
 * mistério.
 */
.party-config-selo {
  display: flex; align-items: center; gap: 4px;
  font-size: 9px; color: var(--muted);
}
.party-config-selo img { width: 11px; height: 11px; object-fit: contain; opacity: 0.8; }
.party-config-selo.frente { color: var(--accent); }

/*
 * Onde o companheiro está caçando, embaixo da barra de experiência.
 *
 * O mesmo desenho do selo de configuração acima — é a mesma classe de
 * informação (uma linha discreta sobre o estado dele) e não havia por que
 * inventar um segundo vocabulário para ela. O nome da hunt pode ser longo:
 * `min-width: 0` e o corte com reticências impedem que ele estique o card.
 */
.party-onde {
  display: flex; align-items: center; gap: 4px; min-width: 0; margin-top: 2px;
  font-size: 9px; color: var(--muted);
}
.party-onde img { width: 11px; height: 11px; object-fit: contain; opacity: 0.8; flex: none; }
.party-onde span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.party-selo {
  padding: 1px 6px; font-size: 9px; border-radius: 4px;
  color: #0b1113; background: var(--accent);
}
.party-selo.fraco { color: var(--muted); background: rgba(255, 255, 255, 0.06); }

.party-amigos { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin: 6px 0; }
.party-amigos button { padding: 2px 7px; font-size: 10px; }
.party-titulo { font-size: 10px; color: var(--muted); margin-right: 4px; }

/* O bloco da caçada: partilha, faixa de level e as duas escolhas de posição. */
.party-cacada {
  display: grid; gap: 8px; padding: 8px; margin-top: 8px;
  border: 1px solid var(--line-soft); border-radius: 6px; background: rgba(8, 14, 16, 0.6);
}
.party-estado { display: flex; align-items: center; gap: 6px; font-size: 11px; }
.party-estado em { font-style: normal; color: var(--muted); }
/* O bônus de vocações diferentes: na cor da experiência, porque é disso que
   ele fala, e não na cor de legenda do resto da linha. */
.party-estado .party-bonus { color: var(--exp); font-weight: 600; cursor: help; }
.party-config { display: grid; gap: 2px; font-size: 11px; }
/*
 * O seletor precisa de área para o clique: com 2px de padding a lista abria e
 * fechava no mesmo gesto em telas com escala, e escolher virava sorte.
 */
.party-config select {
  justify-self: stretch; width: 100%; padding: 5px 8px; font: inherit; font-size: 11px;
  color: var(--text); background: var(--panel-2);
  border: 1px solid var(--line-soft); border-radius: 5px; cursor: pointer;
}
.party-config select:hover { border-color: var(--accent); }
.party-config { gap: 3px; margin-top: 2px; }
.party-config > span { font-size: 10px; color: var(--muted); }
.party-config em { font-style: normal; font-size: 10px; color: var(--muted); }

/* Na janela estreita os cards ficam em coluna, um por linha. */
.party-grade.estreita { grid-template-columns: 1fr; gap: 6px; margin: 6px 0; }
.party-faixa { margin: 2px 0 0; font-size: 10px; color: var(--muted); }

/*
 * ---- A barra de habilidade de um companheiro ----
 *
 * Doze slots numa linha que precisa caber num card de 180px: por isso 18px cada
 * e quebra de linha. Em cooldown o ícone escurece e o tempo aparece por cima —
 * a mesma leitura da barra de baixo, que é onde o jogador aprendeu isso.
 */
.party-spells { display: flex; flex-wrap: wrap; gap: 3px; margin-top: 3px; }
/*
 * 26px, e não 20: a 20 o sprite de uma magia virava um borrão colorido — a arte
 * da folha é de 32px e não sobrevive a essa redução, que é justamente o que faz
 * uma faixa de ícones deixar de ser reconhecível de relance. A 26 ela volta a
 * ser lida, e doze deles ainda cabem em duas linhas no card estreito.
 */
.party-spell {
  position: relative; width: 26px; height: 26px; display: grid; place-items: center;
  border: 1px solid var(--line-soft); border-radius: 4px; background: rgba(0, 0, 0, 0.35);
}
.party-spell canvas, .party-spell img, .party-spell .spell-icon { width: 22px; height: 22px; object-fit: contain; }
/* Frio = em cooldown: a arte apaga e o leque manda. */
.party-spell.frio canvas, .party-spell.frio img, .party-spell.frio .spell-icon { opacity: 0.35; }
/*
 * ---- O MESMO leque da barra de habilidade ----
 *
 * O tempo era um algarismo por cima do ícone apagado — outro vocabulário para a
 * mesma coisa. Aqui é o desenho de baixo, reduzido: a sombra varre a partir das
 * doze horas no sentido do relógio, e `--cd` é quanto FALTA.
 */
.party-spell .cooldown {
  position: absolute; inset: 1px; border-radius: 3px; pointer-events: none;
  background: conic-gradient(from -90deg, #000000c4 0%, #000000c4 var(--cd, 0%), transparent var(--cd, 0%));
}
.party-spell .cooldown-text {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-size: 10px; font-weight: 700; color: #fff;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.95); pointer-events: none;
}

/* O interruptor de ver as habilidades do grupo. */
.party-opcao {
  display: flex; align-items: center; gap: 6px; margin-top: 8px;
  font-size: 10px; color: var(--muted); cursor: pointer;
}
.party-opcao input { accent-color: var(--accent); cursor: pointer; }

/* ---------- o cabeçalho da aba Especial Hunts ----------
 *
 * Duas portas e um relógio, acima da grade de hunts. Ele responde antes do
 * clique o que o servidor só responderia depois dele: precisa de premium, e
 * precisa do passe de 24 horas.
 */
.especial-aviso {
  display: grid; gap: 8px; margin: 0 0 12px;
  padding: 10px 12px; border: 1px solid var(--line);
  border-radius: 8px; background: var(--panel-2);
}
.especial-porta { display: flex; align-items: center; gap: 8px; font-size: 13px; }
.especial-porta .ui-icon { flex: none; }
.especial-porta.ok { color: var(--text); }
/* O vermelho do aviso é o `--danger`: aqui ele É um impedimento, e não um item. */
.especial-porta.falta { color: var(--danger); }

/* ---- O bloco de cada porta da aba Especial ----
   Titulo, legenda e a barra do relogio. A borda mais viva que a do aviso de
   premium: sao dois blocos empilhados, e sem ela a aba vira uma lista de
   paragrafos sem dono. */
/* ---- A lista de premios de uma bag, dentro do balao ----
   Duas colunas de 18px + nome. O balao tem 300px de largura util, entao cada
   coluna fica com ~140 — o suficiente para "Mineiroidle Sorcerer Backpack" caber em
   duas linhas sem estourar. */
.tip-saco { margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--line); }
.tip-saco-titulo { display: block; font-size: 11px; color: var(--muted); margin-bottom: 4px; }
.tip-saco-grade { display: grid; grid-template-columns: 1fr 1fr; gap: 2px 8px; }
.tip-saco-item { display: flex; align-items: center; gap: 5px; min-width: 0; }
.tip-saco-item canvas { flex: none; image-rendering: pixelated; }
.tip-saco-item span {
  font-size: 10px; line-height: 1.2; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ---- O aviso de "comprar nao e' usar", no alto da prateleira ----
   Caixa acesa e nao nota cinza: e' a unica coisa desta loja em que comprar nao
   entrega o beneficio, e quem descobre isso depois de pagar tem razao em
   reclamar. */
.buff-aviso {
  display: grid; gap: 5px; margin-bottom: 12px; padding: 10px 12px;
  border: 1px solid var(--copper, #a8842f); border-radius: 8px;
  background: linear-gradient(180deg, #241c0d, #14100a);
}
.buff-aviso b { font-size: 13px; color: #f0cf6a; }
.buff-aviso span { font-size: 11px; color: var(--text); line-height: 1.4; }
.buff-aviso em { font-style: normal; font-size: 10px; color: var(--muted); }
/* O preco da hora, no card. Cor de moeda para nao ler como nota de rodape. */
.buff-custo { color: var(--copper) !important; }

/* ---- A janela Buffs e Boosts ----
   Linha por linha, como o Analisador: desenho a esquerda, nome e efeito no
   meio, relogio a direita, alinhado. A cor da borda esquerda e' a do grupo — e'
   o que deixa distinguir experiencia de buff de passe sem ler. */
.buffs-lista { display: grid; gap: 6px; }
.buffs-linha {
  display: grid; grid-template-columns: 26px 1fr auto; align-items: center; gap: 9px;
  padding: 6px 9px; border: 1px solid var(--line); border-left-width: 3px; border-radius: 7px;
  background: linear-gradient(180deg, #14202b88, #0d121466);
}
.buffs-linha canvas, .buffs-linha img { image-rendering: pixelated; width: 26px; height: 26px; }
.buffs-texto { display: grid; gap: 1px; min-width: 0; }
.buffs-texto b {
  font-family: var(--font-title); font-size: 10px; letter-spacing: .07em;
  text-transform: uppercase; color: var(--accent);
}
.buffs-texto em {
  font-style: normal; font-size: 10px; color: var(--muted); line-height: 1.3;
  overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.buffs-relogio { display: grid; justify-items: end; gap: 1px; }
.buffs-relogio b { font-size: 13px; color: #ffe9c2; font-variant-numeric: tabular-nums; }
.buffs-relogio span { font-size: 9px; color: var(--muted); }

/* ---- A janela Boss Cooldown ----
   Ela toma emprestada a grade dos Buffs (mesmo desenho, mesmo alinhamento, a
   pedido do dono) e muda so' a cor da borda esquerda: aqui nao ha' grupos, e
   uma cor de perigo diz de relance que aquilo esta' FECHADO. */
.buffs-linha.bosscd { border-left-color: var(--danger, #b4453c); }
.buffs-linha.bosscd .hunt-bicho-vazio { width: 26px; height: 26px; display: block; }
/* A conta de quantas salas sobraram abertas, no alto da janela. */
.bosscd-conta {
  margin: 0 0 7px; font-size: 10px; letter-spacing: .04em; color: var(--muted);
}

/* ---- As fichas de ajuste ----
   Uma fileira de botoes pequenos que MOSTRAM o estado em vez de o descrever:
   acesa e' ligada, apagada e' desligada. Foi o que tirou seis linhas de titulo
   e frase da secao dos relogios. */
.ajustes-fichas { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 8px; }
.ajustes-ficha {
  padding: 4px 9px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--line); background: #0c1215; color: var(--muted);
  font-size: 10px; letter-spacing: .04em;
  transition: color .12s ease, border-color .12s ease, background .12s ease;
}
.ajustes-ficha:hover { color: var(--text); border-color: var(--accent-dim); }
.ajustes-ficha.acesa {
  color: #06100f; background: var(--accent); border-color: var(--accent); font-weight: 600;
}
/* A barrinha que separa "como aparece" de "o que aparece". */
.ajustes-fichas-corte {
  width: 1px; align-self: stretch; margin: 2px 4px; background: var(--line);
}

/* Os tres botoes de tamanho, juntos na mesma linha de ajuste. */
.ajustes-tamanhos { display: flex; gap: 4px; flex: none; }
.ajustes-tamanhos button { min-width: 32px; padding: 5px 8px; }

/* ---- Os relogios do que esta ligado ----
   Mesma posicao da faixa de treino: alto e meio, o pedaco livre da tela. Sem
   fundo proprio — cada pilula ja' tem o seu, e uma caixa em volta de uma pilula
   so' engrossaria a moldura. */
#pilulas-de-efeito {
  position: fixed; z-index: 12;
  top: calc(var(--altura-da-topbar) + 8px + var(--altura-do-aviso, 0px));
  left: 50%; transform: translateX(-50%);
  display: flex; gap: 8px; justify-content: center;
  /* Ela e' arrastavel, entao a faixa inteira recebe eventos — o `pointerdown`
     mora nela, e nao em cada pilula (as pilulas sao refeitas a cada quadro). */
  cursor: grab;
}
#pilulas-de-efeito.arrastando { cursor: grabbing; }
/* Arrastada, `left/top` viram pixels e a centralizacao do CSS sai do caminho. */
#pilulas-de-efeito.arrastada { transform: none; }
/* Em pe: uma pilula embaixo da outra, alinhadas pela esquerda para os relogios
   ficarem numa coluna so'. */
#pilulas-de-efeito.em-pe { flex-direction: column; align-items: flex-start; }
/* Os tres tamanhos. `P` e' o de fabrica — o dono pediu um pouco menor que o
   original, que virou o `M`. */
#pilulas-de-efeito.tamanho-P .efeito-pill { gap: 6px; padding: 3px 9px 3px 5px; }
#pilulas-de-efeito.tamanho-P .efeito-pill-nome { font-size: 8px; letter-spacing: .07em; }
#pilulas-de-efeito.tamanho-P .efeito-pill-tempo { font-size: 10px; }
#pilulas-de-efeito.tamanho-P .efeito-pill-estado { font-size: 8px; }
#pilulas-de-efeito.tamanho-P .sprite,
#pilulas-de-efeito.tamanho-P img { width: 16px !important; height: 16px !important; }
#pilulas-de-efeito.tamanho-G .efeito-pill { gap: 11px; padding: 7px 15px 7px 9px; }
#pilulas-de-efeito.tamanho-G .efeito-pill-nome { font-size: 12px; }
#pilulas-de-efeito.tamanho-G .efeito-pill-tempo { font-size: 15px; }
#pilulas-de-efeito.tamanho-G .sprite,
#pilulas-de-efeito.tamanho-G img { width: 28px !important; height: 28px !important; }
#pilulas-de-efeito[hidden] { display: none; }
#pilulas-de-efeito .efeito-pill { pointer-events: auto; }
/* A cor e' so' a borda: tres pilulas de fundo colorido lado a lado viram
   semaforo. */
.efeito-pill.buff-vermelho { border-color: #8d3b3b; }
.efeito-pill.buff-verde { border-color: #3b8d5a; }
.efeito-pill.buff-dourado { border-color: #a8842f; }
/* O x de esconder: apagado ate' o mouse chegar na pilula. Ele nao pode competir
   com o relogio, que e' o que a pilula existe para mostrar. */
.efeito-pill-fechar {
  margin-left: 2px; padding: 0 2px; border: none; background: none;
  color: var(--muted); font-size: 14px; line-height: 1; cursor: pointer; opacity: .35;
  transition: opacity .12s ease, color .12s ease;
}
.efeito-pill:hover .efeito-pill-fechar { opacity: .8; }
.efeito-pill-fechar:hover { color: var(--text); opacity: 1; }

/* O card do Buff Power na ficha: a sprite do item ocupa a coluna da arte, como
   o icone dos outros cards. `image-rendering` porque e' pixel art de 32. */
.ficha-buff-card canvas {
  image-rendering: pixelated; width: 32px; height: 32px; align-self: center;
}

/* ---- O que o Buff Power faz, no balao do item ----
   Bloco proprio e nao mais uma linha de "regra": ele e' a unica coisa que o
   balao desses tres tem para dizer, e uma linha solta no meio do peso e da
   capacidade se perde. */
.tip-buff {
  display: grid; gap: 4px; margin-top: 8px; padding: 8px 10px;
  border: 1px solid var(--line); border-radius: 8px; background: #0b1114;
}
.tip-buff-titulo {
  font-family: var(--font-title); font-size: 10px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--accent);
}
.tip-buff-bonus { font-size: 12px; color: var(--text); }
/* O custo em destaque: e' o que separa comprar de usar, e e' a pergunta que o
   jogador so' faz depois de ja' ter gasto. */
.tip-buff-custo {
  display: flex; align-items: baseline; gap: 6px;
  padding-top: 4px; border-top: 1px solid var(--line);
}
.tip-buff-custo em { font-style: normal; font-size: 10px; color: var(--muted); }
.tip-buff-custo b { font-size: 12px; color: var(--copper); }
.tip-buff-regra { font-size: 10px; color: var(--muted); line-height: 1.35; }
.tip-buff-relogio { font-size: 11px; color: var(--gold, var(--accent)); font-variant-numeric: tabular-nums; }

/* ---- O trio de Buff Power, na loja ----
   Um card largo embaixo dos tres: ele nao e' um produto a mais na fileira, e'
   a conta de levar os tres. */
.store-card.buff-trio { grid-column: 1 / -1; align-items: center; text-align: center; }
.buff-trio-arte { display: flex; gap: 10px; justify-content: center; margin: 6px 0 2px; }
.buff-trio-peca {
  width: 40px; height: 40px; display: grid; place-items: center; font-style: normal;
  border: 1px solid var(--line); border-radius: 6px; background: #0b1114; cursor: help;
}
.buff-trio-peca canvas { image-rendering: pixelated; }

/* ---- Os dois botoes da aba Especial ----
   Herdam o desenho de aba de `.tabs button` e trocam o miolo: a chave a
   esquerda, o nome e o relogio no meio, a bag a direita. */
.especial-portas button {
  flex-direction: row; align-items: center; justify-content: flex-start; gap: 9px;
  padding: 8px 10px; text-transform: none; letter-spacing: .02em;
}
.especial-portas .porta-chave,
.especial-portas .porta-bag {
  flex: none; width: 28px; height: 28px; display: grid; place-items: center; font-style: normal;
}
.especial-portas .porta-bag { margin-left: auto; cursor: help; }
.especial-portas .porta-chave canvas,
.especial-portas .porta-bag canvas { image-rendering: pixelated; }
.especial-portas .porta-texto { display: grid; gap: 1px; min-width: 0; text-align: left; }
.especial-portas .porta-texto b {
  font-size: 12px; letter-spacing: .05em; text-transform: uppercase;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* O relogio: apagado sem acesso, dourado com ele — a mesma cor da barra. */
.especial-portas .porta-texto em {
  font-style: normal; font-size: 10px; color: var(--muted); font-variant-numeric: tabular-nums;
}
.especial-portas .porta-texto em.ligado { color: var(--gold, var(--accent)); }

/* ---- A bag no card da LOJA ----
   Mesma ideia do cartao do acesso, em tamanho de card: figura pequena e uma
   linha dizendo que o balao dela lista os premios. */
.item-card-bag {
  display: flex; align-items: center; gap: 8px; margin-top: 6px;
  padding: 5px 7px; border: 1px solid var(--gold-line, var(--line));
  border-radius: 5px; background: #1a140a55;
}
.item-card-bag-arte { flex: none; width: 30px; height: 30px; display: grid; place-items: center; font-style: normal; cursor: help; }
.item-card-bag-arte canvas { image-rendering: pixelated; }
.item-card-bag span { font-size: 10px; line-height: 1.25; color: var(--muted); }

/* ---- A bag que se vai buscar, no cartao do acesso ----
   Figura a esquerda, frase a direita. A moldura acesa marca que ali tem uma
   figura clicavel (o balao dela lista os premios). */
.especial-premio {
  display: flex; align-items: center; gap: 10px; margin-top: 8px;
  padding: 8px 10px; border: 1px solid var(--gold-line, var(--line));
  border-radius: 6px; background: #1a140a55;
}
.especial-premio-arte {
  flex: none; width: 34px; height: 34px; display: grid; place-items: center;
  font-style: normal; cursor: help;
}
.especial-premio-arte canvas { image-rendering: pixelated; }
.especial-premio span { font-size: 12px; line-height: 1.3; color: var(--gold, var(--text)); }

.especial-porta-bloco { margin-top: 4px; border-color: var(--line-2, var(--line)); }
.especial-porta-cabeca { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.especial-porta-cabeca h4 { margin: 0; font-size: 14px; letter-spacing: .02em; }
.especial-porta-cabeca span { font-size: 11px; color: var(--muted); }
.especial-porta-bloco .shop-note { margin: 0; }

.especial-acesso { display: grid; gap: 6px; }
.especial-acesso-topo { display: flex; align-items: center; gap: 8px; }
.especial-acesso-topo .sprite { image-rendering: pixelated; flex: none; }
.especial-acesso-topo b { font-family: var(--font-heading); font-size: 13px; color: var(--muted); }
.especial-acesso.ligado .especial-acesso-topo b { color: var(--copper); }
.especial-acesso-tempo {
  margin-left: auto; font-family: var(--font-numero); font-size: 12px;
  color: var(--muted); font-variant-numeric: tabular-nums;
}
.especial-acesso.ligado .especial-acesso-tempo { color: #ffe9c2; }

.especial-acesso-trilho {
  height: 6px; border-radius: 3px; overflow: hidden;
  background: #0a0d0f; border: 1px solid var(--line-soft);
}
.especial-acesso-trilho i {
  display: block; height: 100%; width: 0;
  background: linear-gradient(90deg, #c8823c, #f0b155);
  transition: width 1s linear;
}

/* A munição Mineiroidle: posse, e não gasto. A cor é a do mítico — ela é uma peça
   Mineiroidle como as armas, e a mesma cor no card e no balão diz isso sem palavra. */
.ammo-mineiroidle { color: #f2503f; font-size: 11px; }

/* O reagente que falta: a mesma cor do impedimento, para o olho achar a linha
   travada sem ler os três chips. */
.reagent.falta { color: var(--danger); border-color: var(--danger); opacity: 1; }

/* ---------- forja ---------- */
/*
 * ---- A BANCADA ----
 *
 * O desenho é o da Exaltation Forge do client dele: as peças lado a lado com as
 * setas no meio, e a faixa de requisitos embaixo. Ver a nota em `openForja`,
 * que explica por que essa ordem e não uma lista.
 */
/*
 * A bancada de UM quadro só (a aba de Afixos) fica CENTRADA.
 *
 * Com `1fr auto 1fr` e um filho só, o quadro era esticado até a metade do painel
 * e o resto ficava vazio — o retrato mais feio das duas abas. Uma bancada de um
 * filho não precisa de colunas; ela precisa de centro.
 */
.forja-bancada:has(> .forja-quadro:only-child) {
  grid-template-columns: minmax(220px, 420px);
  justify-content: center;
}
.forja-bancada {
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 10px;
  padding: 14px 12px; margin-bottom: 12px;
  background: linear-gradient(180deg, #0d1214, #101719);
  border: 1px solid var(--line); border-radius: 9px;
}
.forja-setas { color: var(--line-strong, var(--line)); font-size: 15px; letter-spacing: 2px; text-align: center; }

/*
 * O quadro é um BOTÃO, e não uma caixa com um botão dentro: o alvo de clique é
 * o quadro inteiro, que é o que a mão mira.
 */
.forja-quadro {
  display: grid; justify-items: center; gap: 3px; width: 100%;
  padding: 9px 8px; cursor: pointer; text-align: center;
  background: var(--panel-2); border: 1px dashed var(--line); border-radius: 8px;
  color: var(--muted);
}
.forja-quadro.cheio { border-style: solid; color: var(--text); }
.forja-quadro:hover { border-color: var(--accent-dim, var(--accent)); }
.forja-quadro b { font-size: 12px; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.forja-quadro .forja-rotulo {
  font-style: normal; font-size: 9px; text-transform: uppercase; letter-spacing: .08em; color: var(--muted);
}
.forja-quadro .forja-onde { font-size: 10px; color: var(--muted); }
/* A peça que vai SUMIR ganha o fio vermelho; a que vai melhorar, o dourado. */
.forja-quadro.consome.cheio { border-color: #a3333388; }
.forja-quadro.resultado.cheio { border-color: #b8893f88; }

/* A moldura do sprite: o quadrado escuro em que a peça pousa. */
.forja-moldura {
  position: relative; width: 52px; height: 52px; display: grid; place-items: center;
  background: #080b0c; border: 1px solid var(--line-soft); border-radius: 6px;
}
.forja-moldura canvas { image-rendering: pixelated; }
.forja-vazio { font-size: 20px; color: var(--line-strong, var(--line)); line-height: 1; }
/* O selo do tier, no canto — o mesmo lugar em que a mochila o desenha. */
.forja-selo {
  position: absolute; top: -5px; right: -5px; font-style: normal; font-size: 10px;
  min-width: 17px; padding: 0 4px; line-height: 16px; text-align: center;
  background: #b8893f; color: #1a1208; border-radius: 999px;
}

/* ---- a tira de escolha ---- */
/*
 * ---- A lista de peças vira GRADE ----
 *
 * Era uma coluna: cada peça numa linha da largura inteira do painel, com um
 * sprite de 24px à esquerda e um oceano de vazio à direita. Cabiam cinco peças
 * na tela e o resto ficava atrás da rolagem.
 *
 * Em grade, a mesma altura mostra três vezes mais, e cada cartão fica do
 * tamanho do que tem dentro. `auto-fill` com mínimo de 190px se ajeita sozinho
 * quando a janela muda — inclusive no telefone, onde vira uma coluna de novo.
 */
.forja-escolha {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 6px; margin-bottom: 12px; max-height: 300px; overflow-y: auto;
  padding-right: 4px;
}
.forja-opcao {
  display: flex; align-items: center; gap: 9px; width: 100%; padding: 6px 9px; cursor: pointer; text-align: left;
  background: var(--panel-2); border: 1px solid var(--line-soft); border-radius: 7px; color: var(--text);
}
.forja-opcao:hover { border-color: var(--accent-dim, var(--accent)); }
.forja-opcao.tem-tier { border-color: #b8893f55; }
.forja-opcao canvas { flex: none; image-rendering: pixelated; }
.forja-opcao-texto { display: grid; gap: 1px; min-width: 0; }
.forja-opcao-texto b { font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.forja-opcao-texto em { font-style: normal; font-size: 10px; color: var(--muted); }

/* ---- a faixa de requisitos ---- */
.forja-requisitos {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap;
  padding: 10px 12px; margin-top: 4px;
  background: var(--panel-2); border: 1px solid var(--line-soft); border-radius: 8px;
}
.forja-custo { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.forja-chip { display: flex; align-items: center; gap: 6px; font-size: 12px; }
.forja-chip canvas { image-rendering: pixelated; }
.forja-chip b { color: var(--text); }
.forja-chip em { font-style: normal; font-size: 10px; color: var(--muted); }
/* Requisito que não está cumprido — ou aviso do que vai ser perdido. */
.forja-chip.falta b { color: #ff8a7a; }
.forja-botao { padding: 8px 22px; border-radius: 7px; cursor: pointer; font-size: 13px; }
.forja-botao:disabled { cursor: not-allowed; opacity: .45; }

/* ---- o rodapé com a bolsa ---- */
.forja-bolsa {
  display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
  margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--line-soft);
  font-size: 12px; color: var(--muted);
}
.forja-bolsa canvas { image-rendering: pixelated; }
.forja-bolsa b { color: #f0c95f; }
.forja-bolsa em { font-style: normal; }
.forja-bolsa .forja-dica-rodape { margin-left: auto; font-size: 11px; text-align: right; }

/* ---------- loja de NPC ---------- */
/*
 * O balcão da Zuma: uma lista, e não uma grade de cartões.
 *
 * O que se compara aqui é NOME e PREÇO, duas informações em texto lidas de cima
 * para baixo. Numa grade quadrada elas ficariam empilhadas dentro de cada
 * célula e o olho teria de entrar em cada uma para comparar — é a mesma escolha
 * da lista da forja.
 */
/*
 * ---- DUAS por linha ----
 *
 * "organiza os itens dela pra mostrar 2 por linha."
 *
 * A lista da Zuma passa de quarenta linhas, e numa coluna só ela era uma
 * rolagem de parede: o que está embaixo custa dez arrastadas para ser visto, e
 * quem não sabia que existia nunca descobria. Em duas colunas a mesma lista
 * cabe em metade da altura.
 *
 * DUAS, e não "quantas couberem": `auto-fit` enchia a janela larga com três
 * e quatro colunas, que é uma lista diferente da que foi pedida. O telefone
 * é o único lugar onde duas não cabem, e lá a regra estreita logo abaixo as
 * desfaz em uma só.
 */
.loja-npc { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 5px; }
/*
 * A linha virou BOTÃO: ela é a escolha, e não mais um cartaz com um botão
 * dentro. Por isso os `reset` de botão aqui — texto à esquerda, fonte herdada,
 * largura inteira —, senão o navegador a centraliza e a desenha com a fonte
 * dele.
 */
.loja-linha {
  display: flex; align-items: center; gap: 10px; padding: 6px 10px;
  background: var(--panel-2); border: 1px solid var(--line-soft); border-radius: 7px;
  width: 100%; text-align: left; font: inherit; color: inherit; cursor: pointer;
}
.loja-linha:hover { border-color: var(--line); background: var(--panel-3, var(--panel-2)); }
/* A escolhida fica acesa: é ela que o balcão lá embaixo está mostrando. */
.loja-linha.escolhida {
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent), 0 0 10px #3fbfa833;
}

/*
 * ---- O balcão, embaixo da lista ----
 *
 * O item escolhido, a régua da quantidade, a conta e UM botão. Ver a nota em
 * `balcaoDaLoja`.
 *
 * Ele gruda no rodapé do modal (`position: sticky`) porque a lista rola e a
 * pergunta não pode rolar junto: escolher um item lá em cima e ter de rolar
 * até o fim para apertar Comprar seria trocar a caixa que saiu por uma
 * rolagem.
 */
.loja-balcao {
  position: sticky; bottom: 0; z-index: 2;
  display: grid; gap: 8px; margin-top: 10px; padding: 10px 12px;
  /* OPACO: a lista rola por baixo dele, e o `--panel` translúcido deixava
     os anéis passarem por cima da conta e do botão. */
  background: var(--panel-solid); border: 1px solid var(--line); border-radius: 9px;
  box-shadow: 0 -8px 18px #000a;
}
.loja-balcao-alvo { display: flex; align-items: center; gap: 10px; min-width: 0; }
.loja-balcao-alvo canvas { flex: none; image-rendering: pixelated; }
.loja-balcao-texto { display: grid; gap: 1px; min-width: 0; }
.loja-balcao-texto b { font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.loja-balcao-texto em { font-style: normal; font-size: 11px; color: var(--muted); }
.loja-balcao-conta { display: flex; gap: 18px; flex-wrap: wrap; font-size: 12px; }
.loja-balcao-conta .balcao-conta-item { display: flex; gap: 6px; align-items: baseline; }
.loja-balcao-conta span { color: var(--muted); }
/* A conta à esquerda, o botão à direita, na mesma linha. */
.loja-balcao-rodape { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; }
.loja-balcao-acoes { display: flex; justify-content: flex-end; margin-left: auto; }
/* Os atalhos 1/Metade/Tudo alinham com a régua, e não no meio do balcão. */
.loja-balcao .quantia-atalhos { justify-content: flex-start; }
.loja-balcao-acoes button { padding: 7px 22px; border-radius: 7px; cursor: pointer; font-size: 13px; }
.loja-balcao-acoes button:disabled { cursor: not-allowed; opacity: .45; }
.loja-balcao-nao { margin: 0; font-size: 12px; color: #ff8a7a; }
/* No telefone duas colunas cortariam o nome de todo item. */
@media (max-width: 620px) {
  .loja-npc { grid-template-columns: minmax(0, 1fr); }
}
.loja-linha canvas { flex: none; image-rendering: pixelated; }
.loja-texto { display: grid; gap: 1px; min-width: 0; flex: 1; }
.loja-texto b { font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.loja-sub { display: flex; align-items: center; gap: 8px; font-size: 11px; color: var(--muted); flex-wrap: wrap; }
/* O que ela PAGA sai em dourado: é dinheiro entrando, e não saindo. */
.loja-sub .loja-paga { font-style: normal; color: #f0c95f; }
.loja-sub .loja-tenho { font-style: normal; color: var(--accent); }
.loja-acoes { flex: none; display: flex; gap: 4px; }
.loja-acoes button { padding: 5px 12px; border-radius: 6px; cursor: pointer; font-size: 12px; }
.loja-acoes button:disabled { cursor: not-allowed; opacity: .45; }

/* ---- as duas abas do balcão ---- */
/*
 * O que ela VENDE e o que ela COMPRA são dois negócios, e agora são duas ABAS.
 * Ver a nota em `renderLojaNpc`: empilhar as duas listas na mesma rolagem não
 * separava nada — as três linhas de venda continuavam a quatro rolagens de
 * distância, embaixo de quarenta de compra.
 *
 * A cabeça é só a linha fina embaixo da aba: quantos são e quem paga a quem. O
 * nome do lado já está aceso na aba, e repeti-lo aqui seria dizer duas vezes a
 * mesma coisa em dois centímetros.
 */
.loja-fileira-cabeca {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  margin: 2px 0 8px;
}
.loja-fileira-cabeca em { font-style: normal; font-size: 11px; color: var(--muted); }

/* ---- a caixa de confirmar um negócio no balcão ---- */
.balcao-box { min-width: 290px; }
.balcao-alvo {
  display: flex; align-items: center; gap: 10px; padding: 8px 10px;
  background: var(--panel-2); border: 1px solid var(--line-soft); border-radius: 7px;
}
.balcao-alvo canvas { flex: none; image-rendering: pixelated; }
.balcao-alvo-texto { display: grid; gap: 2px; min-width: 0; }
.balcao-alvo-texto b { font-size: 13px; }
.balcao-alvo-texto em { font-style: normal; font-size: 11px; color: var(--muted); }

/*
 * A conta, em três linhas alinhadas à direita.
 *
 * "Fica com" é a linha que o pedido pediu, e ela é a última de propósito: é a
 * resposta, e as duas de cima são as parcelas dela.
 */
.balcao-conta {
  display: grid; gap: 3px; padding: 8px 10px;
  background: var(--panel-2); border: 1px solid var(--line-soft); border-radius: 7px;
  font-size: 12px;
}
.balcao-conta-item { display: flex; justify-content: space-between; gap: 12px; }
.balcao-conta-item span { color: var(--muted); }
.balcao-conta-item b { color: #f0c95f; }
.balcao-conta-item .balcao-depois { color: var(--accent); }
/* Sair da loja sem nenhum ouro é legítimo, mas merece ser visto antes. */
.balcao-conta-item .balcao-depois.vazia { color: #ff8a7a; }

/* ---- a confirmação da forja ---- */
.forja-confirma { min-width: 290px; justify-items: center; }
.forja-confirma .forja-moldura { justify-self: center; }
.forja-confirma-frases { display: grid; gap: 5px; width: 100%; }
.forja-confirma-frases p { margin: 0; font-size: 12px; color: var(--muted); text-align: center; }
.forja-confirma-frases p.perigo { color: #ff8a7a; }
.forja-confirma .balcao-conta { width: 100%; }

/* ---- a moldura em três tamanhos ---- */
.forja-moldura.mini { width: 38px; height: 38px; flex: none; border-radius: 5px; }
.forja-moldura.mini .forja-selo { top: -4px; right: -4px; font-size: 9px; min-width: 15px; line-height: 14px; }
.forja-moldura.grande { width: 66px; height: 66px; }

/* ---- o efeito de quando a peça sai do fogo ---- */
/*
 * Ver `efeitoDaForja`: subir tier troca um dígito num selo de dezesseis pixels,
 * e sem isto um clique de 75 milhões parece um clique que não funcionou.
 *
 * São três coisas ao mesmo tempo, e cada uma responde a uma pergunta: o ANEL
 * que se abre diz "aconteceu agora", o BRILHO da moldura diz "foi aqui", e as
 * FAGULHAS dão o peso do martelo. Nenhuma delas se repete: o efeito toca uma
 * vez e a tela fica parada, porque uma forja é um acontecimento e não um estado.
 */
.forja-resultado {
  display: flex; align-items: center; gap: 14px;
  padding: 12px 14px; margin-bottom: 12px;
  background: linear-gradient(180deg, #1a1408, #12100a);
  border: 1px solid #b8893f66; border-radius: 9px;
  animation: forja-entra 380ms ease-out;
}
.forja-resultado-texto { display: grid; gap: 3px; min-width: 0; }
.forja-resultado-texto b { font-size: 13px; color: #f0c95f; }
.forja-resultado-texto em { font-style: normal; font-size: 11px; color: var(--muted); }

.forja-moldura.forjando {
  border-color: #b8893f;
  animation: forja-brilho 900ms ease-out;
}
/* O anel que se abre a partir da peça. */
.forja-moldura.forjando::after {
  content: ''; position: absolute; inset: 0; border-radius: 6px;
  border: 2px solid #f0c95f; pointer-events: none;
  animation: forja-anel 700ms ease-out forwards;
}

/*
 * As fagulhas saem do CENTRO e voam para fora.
 *
 * O ângulo de cada uma vem da classe (`f0`…`f5`), e não de um número sorteado:
 * seis direções fixas e espalhadas parecem uma explosão; seis sorteadas caem
 * juntas com frequência e parecem um borrão de um lado só.
 */
.forja-faisca {
  position: absolute; left: 50%; top: 50%; width: 3px; height: 3px; margin: -1.5px 0 0 -1.5px;
  background: #ffd97a; border-radius: 50%; pointer-events: none;
  animation: forja-faisca 620ms ease-out forwards;
}
.forja-faisca.f0 { --giro: 0deg; }
.forja-faisca.f1 { --giro: 60deg; animation-delay: 40ms; }
.forja-faisca.f2 { --giro: 120deg; animation-delay: 15ms; }
.forja-faisca.f3 { --giro: 180deg; animation-delay: 55ms; }
.forja-faisca.f4 { --giro: 240deg; animation-delay: 25ms; }
.forja-faisca.f5 { --giro: 300deg; animation-delay: 70ms; }

@keyframes forja-entra {
  from { opacity: 0; transform: translateY(-6px); }
  to { opacity: 1; transform: none; }
}
@keyframes forja-brilho {
  0% { box-shadow: 0 0 0 0 #f0c95f00; }
  25% { box-shadow: 0 0 18px 4px #f0c95faa; }
  100% { box-shadow: 0 0 0 0 #f0c95f00; }
}
@keyframes forja-anel {
  from { transform: scale(1); opacity: .9; }
  to { transform: scale(1.9); opacity: 0; }
}
@keyframes forja-faisca {
  from { transform: rotate(var(--giro)) translateX(0); opacity: 1; }
  to { transform: rotate(var(--giro)) translateX(38px); opacity: 0; }
}

/*
 * Quem pediu menos movimento não recebe o efeito.
 *
 * O cartaz continua aparecendo — ele é a informação, e a informação não é
 * opcional. O que sai é o que se move: o anel, as fagulhas e o pulso.
 */
@media (prefers-reduced-motion: reduce) {
  .forja-resultado { animation: none; }
  .forja-moldura.forjando { animation: none; }
  .forja-moldura.forjando::after { display: none; }
  .forja-faisca { display: none; }
}

/* ---------- a aba de craft da forja ---------- */
/*
 * ---- A tira das vocações ----
 *
 * "deixe o nome das vocação escrito com uma fonte bonita medieval e um pouquinho
 * maior e com o ícone das vocação sabe? igual o ícone do chat."
 *
 * Três coisas na mesma tarja, e cada uma vem de um lugar que já existe:
 *
 *   o FUNDO   as cinco artes de `client/assets/ui/vocacao-*.webp`, as mesmas da
 *             criação de personagem;
 *   o ÍCONE   o mesmo do chat e da party (`PERICIA_DA_VOCACAO`) — espada, arco,
 *             as duas magias, o punho;
 *   a LETRA   a Cinzel de `--font-heading`, que é a capitular romana usada em
 *             todo título deste jogo.
 *
 * Nada aqui é desenho novo, e é de propósito: cada elemento repetido é uma coisa
 * que a pessoa já sabe ler.
 */
.craft-vocs {
  display: grid; grid-template-columns: repeat(5, 1fr); gap: 6px;
  margin-bottom: 10px;
}
.craft-voc {
  position: relative; height: 70px; padding: 0 4px 7px;
  display: flex; flex-direction: column; align-items: center; justify-content: flex-end;
  cursor: pointer;
  border: 1px solid var(--line); border-radius: 8px; overflow: hidden;
  background-size: cover; background-position: top center; background-repeat: no-repeat;
  color: var(--muted);
}
.craft-voc-nome { display: flex; align-items: center; gap: 5px; }
.craft-voc-icone {
  width: 17px; height: 17px; object-fit: contain; flex: 0 0 auto;
  filter: drop-shadow(0 1px 2px #000);
}
/*
 * A Cinzel em 13px com versalete: ela foi desenhada para NOME gravado em pedra, e
 * é o que ela faz melhor. O espaçamento entre letras é o que a impede de virar um
 * borrão nesse tamanho.
 */
.craft-voc b {
  font-family: var(--font-heading); font-size: 13px; letter-spacing: .06em;
  text-shadow: 0 1px 3px #000, 0 0 10px #000;
}
.craft-voc:hover { border-color: var(--accent-dim, var(--accent)); }
.craft-voc.escolhida { border-color: #b8893f; color: var(--text); filter: brightness(1.12) saturate(1.05); }
.craft-voc.escolhida b { color: #f0c95f; }
/* A marca de "esta é a sua" fica no topo, longe do nome. */
.craft-voc-minha {
  position: absolute; top: 4px; right: 4px;
  font-style: normal; font-size: 9px; letter-spacing: .4px;
  padding: 1px 5px; border-radius: 999px;
  background: #0d1618cc; border: 1px solid #b8893f88; color: #f0c95f;
}
.craft-voc[data-vocation="knight"] { background-image: linear-gradient(180deg, #0d161866 26%, #0d1618d9 74%, #0d1618f2), url('/client/assets/ui/vocacao-knight.webp'); }
.craft-voc[data-vocation="paladin"] { background-image: linear-gradient(180deg, #0d161866 26%, #0d1618d9 74%, #0d1618f2), url('/client/assets/ui/vocacao-paladin.webp'); }
.craft-voc[data-vocation="druid"] { background-image: linear-gradient(180deg, #0d161866 26%, #0d1618d9 74%, #0d1618f2), url('/client/assets/ui/vocacao-druid.webp'); }
.craft-voc[data-vocation="sorcerer"] { background-image: linear-gradient(180deg, #0d161866 26%, #0d1618d9 74%, #0d1618f2), url('/client/assets/ui/vocacao-sorcerer.webp'); }
.craft-voc[data-vocation="monk"] { background-image: linear-gradient(180deg, #0d161866 26%, #0d1618d9 74%, #0d1618f2), url('/client/assets/ui/vocacao-monk.webp'); }

/*
 * ---- OS DOIS SETS, lado a lado ----
 *
 * "faz mostrar os 2 sets, tanto o craftado quanto o craftado v2, na mesma aba."
 *
 * Duas colunas de largura igual, cada uma com o nome do set em cima e a boneca
 * embaixo. Cada boneca são três colunas de 44px mais os vãos — 140px —, então as
 * duas com 18px de respiro cabem em 300px, que é menos do que a janela da forja já
 * tinha de largura por causa da lista de materiais.
 *
 * `align-items: start` para a coluna com menos peças não esticar a boneca dela.
 */
.craft-sets {
  display: flex; gap: 14px; justify-content: center; align-items: start;
  flex-wrap: wrap; margin-bottom: 12px;
}
.craft-set { display: grid; gap: 6px; justify-items: center; }

/*
 * ---- A seta entre os dois sets ----
 *
 * "entre o set craftado e o craftado v2 coloca uma setinha verde no meio."
 *
 * `align-self: center` para ela ficar na altura do meio dos dois corpos, e não
 * grudada no topo. É a única coisa verde da tela — o resto do craft é dourado —,
 * e é isso que a faz ser lida como direção e não como enfeite.
 */
.craft-seta {
  align-self: center; color: #6fbf73; font-size: 17px; letter-spacing: -2px;
  text-shadow: 0 0 10px #6fbf7355; flex: none; user-select: none;
}
/*
 * ---- As peças que não cabem na boneca ----
 *
 * Uma fila na linha a que elas pertencem, separada por um traço fino para não
 * serem lidas como mais casas do corpo.
 *
 * ---- Do MESMO tamanho das casas do set ----
 *
 * "deixa no mesmo tamanho do set que está lá."
 *
 * Elas foram 38px por um tempo, com a ideia de que "transbordo" devia parecer
 * menor que o corpo. Ficou errado por um motivo simples: são as MESMAS peças, e um
 * machado craftado não é menos peça do que a espada que está na casa. Duas
 * medidas para a mesma coisa fazem a fila parecer um resumo do que está ao lado, e
 * ela não é — é a continuação.
 *
 * O traço separador basta para dizer o que é corpo e o que é fila.
 */
.craft-extras {
  display: flex; gap: 4px; align-items: center; flex: none;
  margin-left: 4px; padding-left: 7px;
  border-left: 1px solid var(--line);
}
/* Do lado esquerdo o traço separador troca de borda junto com a tira. */
.lado-esquerda .craft-extras {
  margin-left: 0; margin-right: 4px;
  padding-left: 0; padding-right: 7px;
  border-left: none; border-right: 1px solid var(--line);
}
.craft-extra {
  position: relative; width: 54px; height: 54px; padding: 0; cursor: pointer;
  display: grid; place-items: center;
  background: #161d20; border: 1px solid var(--line-soft); border-radius: 5px;
}
.craft-extra canvas { width: 40px; height: 40px; image-rendering: pixelated; }
.craft-extra:hover { border-color: var(--accent-dim); }
.craft-extra.pronta { border-color: #6fbf7377; }
.craft-extra.aberta { border-color: #f0c95f; box-shadow: 0 0 0 1px #f0c95f55; }

.craft-set-nome { display: flex; align-items: baseline; gap: 7px; }
.craft-set-nome b {
  font-family: var(--font-heading); font-size: 12px; letter-spacing: .06em; color: #f0c95f;
}
.craft-set-nome em { font-style: normal; font-size: 10px; color: var(--muted); }

/*
 * ---- A BONECA ----
 *
 * "a aba de craft tinha que mostrar exatamente desse jeito os sets lá, sem espaço
 * sabe, pra meio que a pessoa ver como ficaria."
 *
 * Então é a MESMA medida de `.equipment`: três colunas de 44px, 4px de vão,
 * centralizada. E a casa é a mesma `.slot` — 44x44, o mesmo fundo, a mesma borda,
 * a mesma arte cinza no vazio. Copiar as medidas em vez de reaproveitar a classe é
 * deliberado: `.slot` tem comportamento de arrastar e soltar que aqui não existe,
 * e herdar isso traria eventos que ninguém quer. O que precisa ser igual é o que
 * se VÊ.
 *
 * Se um dia `.equipment` mudar de 44px, este bloco muda junto — são os dois
 * lugares, e é o preço de não misturar os comportamentos.
 */
/*
 * ---- 54px, e não os 44px do inventário ----
 *
 * "deixa os sets um pouco maior na página do craft."
 *
 * A boneca do inventário é 44px porque ela divide a janela lateral com a mochila
 * inteira. Aqui ela é o conteúdo principal de uma janela de 1180px, e 44px era
 * pequeno para o que se está olhando — que é a peça, e não a casa.
 *
 * A proporção do inventário é mantida: o sprite ocupa 32 de 44, aqui 40 de 54. É
 * ela que faz a peça parecer "encaixada" e não flutuando dentro da casa.
 *
 * Três colunas de 54 mais dois vãos de 4 dão 170px; com a coluna das armas extras
 * (38px) e os vãos, cada set ocupa ~214px, e os dois com a seta cabem em 470px —
 * folgado dentro dos 1180px, e no celular o `.craft-sets` quebra a linha.
 */
/*
 * O corpo encosta na seta do meio: o set da esquerda alinha as casas à DIREITA, o
 * da direita à ESQUERDA. É isso que mantém as duas bonecas juntas enquanto as
 * peças que sobram abrem para as bordas da janela.
 */
.craft-boneca { display: grid; gap: 4px; }
.craft-boneca.lado-esquerda { justify-content: end; }
.craft-boneca.lado-direita { justify-content: start; }
.craft-boneca.lado-esquerda .craft-linha { justify-content: flex-end; }
/*
 * Cada linha da boneca: as três casas do corpo e, à direita, as peças que
 * sobraram dos slots DAQUELA linha. É o que põe as seis armas do knight na mesma
 * altura da casa da arma.
 */
.craft-linha { display: flex; gap: 4px; align-items: center; }
.craft-casa {
  width: 54px; height: 54px; padding: 0; position: relative;
  background: #161d20; border: 1px solid var(--line-soft);
  border-radius: 5px; display: grid; place-items: center; cursor: pointer;
}
.craft-casa canvas { width: 40px; height: 40px; image-rendering: pixelated; }
.craft-casa .slot-art { width: 40px; height: 40px; image-rendering: pixelated; opacity: .5; }
.craft-casa:hover { border-color: var(--accent-dim); }
/* Sem receita: a casa fica, com a arte apagada. Ela é o que segura a forma. */
.craft-casa.sem-receita { cursor: default; opacity: .45; }
.craft-casa.sem-receita:hover { border-color: var(--line-soft); }
/* As duas casas de premium e bênçãos do inventário, aqui sem nada dentro. */
.craft-casa.vazia { background: none; border-style: dashed; opacity: .16; cursor: default; }
.craft-casa.pronta { border-color: #6fbf7377; box-shadow: inset 0 0 8px #6fbf7322; }
.craft-casa.aberta { border-color: #f0c95f; box-shadow: 0 0 0 1px #f0c95f55; }
.craft-casa-nome {
  font-style: normal; font-size: 8px; letter-spacing: .04em; text-align: center;
  color: #40504f;
}
/* Quantos materiais faltam. Mesmo canto do selo de tier da forja. */
.craft-peca-falta {
  position: absolute; top: -5px; right: -5px;
  min-width: 15px; line-height: 15px; padding: 0 3px;
  font-style: normal; font-size: 9px; text-align: center;
  border-radius: 999px; background: #2a1414; border: 1px solid #ff8a7a66; color: #ff8a7a;
}
/*
 * Quantas peças existem para aquele slot. Vai no canto de BAIXO, do outro lado do
 * que falta: são duas contagens diferentes e o olho não pode confundi-las.
 */
.craft-peca-variantes {
  position: absolute; bottom: -4px; left: -4px;
  min-width: 14px; line-height: 14px; padding: 0 3px;
  font-style: normal; font-size: 9px; text-align: center;
  border-radius: 999px; background: #0d1618; border: 1px solid #b8893f77; color: #d9c79a;
}

/* ---- as outras peças do mesmo slot, dentro da ficha ---- */
.craft-irmas { display: flex; flex-wrap: wrap; gap: 4px; padding: 0 11px 6px; }
.craft-irma {
  width: 34px; height: 34px; padding: 0; cursor: pointer;
  display: grid; place-items: center;
  border: 1px solid var(--line); border-radius: 5px; background: #00000033;
}
.craft-irma canvas { image-rendering: pixelated; }
.craft-irma:hover { border-color: var(--accent-dim, var(--accent)); }
.craft-irma.pronta { border-color: #6fbf7355; }
.craft-irma.escolhida { border-color: #f0c95f; background: #b8893f1f; }
/* ---- a ficha da receita escolhida ---- */
.craft-ficha {
  border: 1px solid #b8893f55; border-radius: 8px; background: #0000002e;
  margin-bottom: 10px;
}
.craft-ficha.pronta { border-color: #6fbf7366; }
.craft-ficha-topo { display: flex; align-items: center; gap: 10px; padding: 9px 11px 6px; }
.craft-ficha-topo canvas { flex: none; image-rendering: pixelated; }
.craft-ficha-texto { display: grid; gap: 2px; min-width: 0; flex: 1; }
.craft-ficha-texto b { font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.craft-ficha-texto em { font-style: normal; font-size: 10px; color: var(--muted); }
.craft-falta {
  flex: none; font-size: 10px; padding: 2px 9px; border-radius: 999px;
  border: 1px solid #ff8a7a55; color: #ff8a7a;
}
.craft-falta.tem { border-color: #6fbf7355; color: #8fd694; }

.craft-herda { margin: 0; padding: 0 11px 4px; font-size: 11px; color: #d9c79a; }

/*
 * Os materiais em colunas: são até dezoito por receita, e uma coluna só faria a
 * lista mais alta que a janela para quase todas elas.
 */
.craft-mats {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(195px, 1fr));
  gap: 3px 12px; padding: 6px 11px 8px;
}
.craft-mat { display: flex; align-items: center; gap: 7px; font-size: 11px; min-width: 0; }
.craft-mat canvas { flex: none; image-rendering: pixelated; }
.craft-mat b { font-weight: 400; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.craft-mat em { margin-left: auto; font-style: normal; flex: none; }
.craft-mat.ok em { color: #8fd694; }
.craft-mat.falta em { color: #ff8a7a; }
/*
 * Os oito materiais que a receita pede e este jogo não tem. Ficam na lista
 * riscados: tirá-los faria a receita parecer mais barata do que é.
 */
.craft-mat.de-fora { opacity: .55; }
.craft-mat.de-fora b { text-decoration: line-through; }

.craft-ficha-rodape {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 0 11px 10px;
}
.craft-impossivel { font-style: normal; font-size: 10px; color: #ff8a7a; flex: 1; }
.craft-ficha-rodape .forja-botao { margin-left: auto; }

/* ---- a aba que ainda não existe ---- */
.craft-emobra {
  display: grid; gap: 7px; justify-items: center; text-align: center;
  padding: 26px 22px; margin-top: 10px;
  border: 1px dashed var(--line); border-radius: 9px;
}
.craft-emobra b { font-family: var(--font-heading); font-size: 15px; color: #f0c95f; letter-spacing: .06em; }
.craft-emobra p { margin: 0; font-size: 12px; color: var(--muted); max-width: 46ch; }
.craft-emobra-nota { font-size: 11px !important; opacity: .8; }
/* ---------- promoção de coins na loja do jogo ---------- */
/*
 * O cartao precisa de `position: relative` para a faixa colar na borda de cima
 * dele; sem isso ela sobe ate o primeiro pai posicionado e sai do lugar.
 */
.coins-card.coins-card-destaque {
  position: relative;
  padding-top: 26px;
  border-color: #F0C040;
  box-shadow: 0 0 0 1px rgba(240, 192, 64, .35), 0 6px 20px rgba(0, 0, 0, .45);
}
.coins-card-destaque .coins-selo {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  background: linear-gradient(180deg, #F0C040, #B8860B);
  color: #201804;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: .12em;
  padding: 3px 12px;
  border-radius: 0 0 6px 6px;
  white-space: nowrap;
}
.coins-card .coins-riscado {
  display: block;
  font-size: 12px;
  color: #8b949e;
  text-decoration: line-through;
}
.coins-card .coins-promo {
  display: block;
  font-size: 13.5px;
  font-weight: 700;
  color: #F0C040;
}

.promo-faixa {
  margin: 4px 0 16px;
  padding: 14px 18px;
  border-radius: 10px;
  text-align: center;
  border: 1px solid rgba(240, 192, 64, .45);
  background: linear-gradient(180deg, rgba(240,192,64,.16), rgba(240,192,64,.05));
  animation: promo-pulsa 2.6s ease-in-out infinite;
}
.promo-faixa b {
  display: block;
  font-size: 19px;
  letter-spacing: .06em;
  color: #F0C040;
  text-shadow: 0 0 18px rgba(240, 192, 64, .45);
}
.promo-faixa span { display: block; font-size: 13px; margin-top: 3px; opacity: .85; }
.promo-faixa .promo-relogio {
  display: block;
  margin-top: 8px;
  font-size: 12.5px;
  font-style: normal;
  letter-spacing: .04em;
  color: #FFD960;
}
@keyframes promo-pulsa {
  0%, 100% { border-color: rgba(240, 192, 64, .45); }
  50%      { border-color: rgba(240, 192, 64, .85); }
}
@media (prefers-reduced-motion: reduce) {
  .promo-faixa { animation: none; }
}

/* ---------- o recado grande da loja ---------- */
.loja-aviso {
  margin: 6px 0 14px;
  padding: 18px 20px;
  border-radius: 12px;
  text-align: center;
  border: 2px solid #F0C040;
  background: linear-gradient(180deg, rgba(240,192,64,.22), rgba(240,192,64,.06));
  box-shadow: 0 0 26px rgba(240, 192, 64, .28), inset 0 0 24px rgba(240, 192, 64, .07);
  animation: aviso-brilha 2.2s ease-in-out infinite;
}
.loja-aviso b {
  display: block;
  font-size: 22px;
  letter-spacing: .07em;
  color: #FFD960;
  text-shadow: 0 0 20px rgba(255, 217, 96, .6);
}
.loja-aviso span {
  display: block;
  margin-top: 7px;
  font-size: 14px;
  line-height: 1.5;
  color: #F5E6C0;
}
@keyframes aviso-brilha {
  0%, 100% { box-shadow: 0 0 26px rgba(240,192,64,.28), inset 0 0 24px rgba(240,192,64,.07); }
  50%      { box-shadow: 0 0 40px rgba(240,192,64,.5),  inset 0 0 30px rgba(240,192,64,.14); }
}
@media (prefers-reduced-motion: reduce) { .loja-aviso { animation: none; } }

/* ---------- a barrinha de carga da peça ---------- */
/*
 * Anel e amuleto que se gastam (o might ring com 20 cargas, o sword ring com
 * meia hora de uso) mostram quanto resta numa barra colada na borda de baixo do
 * quadro, com o número no canto ao lado. Ver `selarDesgaste`, em
 * `inventory.mjs`, para o porquê do lugar, dos quatro estágios e do número.
 *
 * `.slot` é o quadro do corpo e `.cell` o da mochila: a barra vale nos dois
 * desde que a peça guardada também a mostra.
 */
.slot.com-desgaste, .cell.com-desgaste { position: relative; }
/*
 * Dois pixels — foi cinco, depois tres, e agora dois.
 *
 * "pode afinar mais a carga dos itens que tem carga". Ela e um traco de
 * informacao em cima de um quadro de 32px que ja carrega o sprite, o selo do
 * tier, as estrelas do afixo e a contagem da pilha: cada pixel que ela ocupa e
 * um pixel de desenho coberto. Dois e o piso — um pixel unico, com a sombra de
 * fora, nao teria onde por o brilho que da volume a barra, e ela viraria de
 * novo o risco cinzento que era antes.
 *
 * A precisao nunca foi dela: quem da o numero exato e a contagem ao lado.
 */
.desgaste {
  position: absolute; left: 2px; right: 2px; bottom: 1px; height: 2px;
  background: linear-gradient(180deg, #000a, #000d);
  border-radius: 2px; overflow: hidden;
  box-shadow: 0 0 0 1px #000a, inset 0 1px 1px #0009;
  pointer-events: none; z-index: 3;
}
/*
 * O preenchimento tem um brilho no topo e escurece para baixo — é o mesmo
 * volume das barras de vida e mana do jogo, e é o que separa a barra do
 * desenho colorido que ela cobre. Três pixels chapados eram um risco cinzento.
 */
.desgaste-cheio {
  display: block; height: 100%; border-radius: 2px;
  background:
    linear-gradient(180deg, #ffffff5c, #ffffff00 55%),
    var(--desgaste-cor, #4cd07a);
  box-shadow: 0 0 5px var(--desgaste-cor, #4cd07a);
  /* A largura muda a cada retrato do servidor; sem a transição ela salta. */
  transition: width .25s linear;
}
/*
 * Quatro estágios: verde inteiro, amarelo na metade, âmbar no último terço,
 * vermelho no último décimo. O amarelo é o que faltava — de verde a âmbar em
 * 34% é, num anel de 20 cargas, o aviso chegando com seis de sobra.
 */
.desgaste.cheio { --desgaste-cor: #4cd07a; }
.desgaste.meio { --desgaste-cor: #d8d24a; }
.desgaste.baixo { --desgaste-cor: #e0a84a; }
.desgaste.critico { --desgaste-cor: #ff6b5a; }
/*
 * O número, no canto de baixo à esquerda — o único dos quatro ainda livre: o
 * tier ocupa o de cima à esquerda, as estrelas do afixo o de cima à direita e a
 * contagem da pilha o de baixo à direita.
 *
 * Ele sai na cor do estágio, então a barra e o número dizem a mesma coisa por
 * dois caminhos: a cor de relance e o número quando se olha.
 */
.desgaste-conta {
  position: absolute; left: 1px; bottom: 3px; z-index: 4;
  font-style: normal; font-size: 9px; font-weight: 700; line-height: 1;
  letter-spacing: -.02em;
  color: var(--desgaste-cor, #4cd07a);
  text-shadow: 0 0 3px #000, 0 1px 2px #000, 0 0 6px #000;
  pointer-events: none;
}
.desgaste-conta.cheio { --desgaste-cor: #7fe0a2; }
.desgaste-conta.meio { --desgaste-cor: #e8e27a; }
.desgaste-conta.baixo { --desgaste-cor: #f0c078; }
.desgaste-conta.critico { --desgaste-cor: #ff8f82; }
/*
 * E ela PISCA no fim. É o único aviso que chega a quem está caçando de olho no
 * mapa e não no inventário — e perder um anel sem ter visto que ele ia acabar é
 * a diferença entre um sistema e um sumiço.
 */
.desgaste.critico .desgaste-cheio,
.desgaste-conta.critico { animation: desgaste-pisca 900ms ease-in-out infinite; }
@keyframes desgaste-pisca {
  0%, 100% { opacity: 1; }
  50% { opacity: .35; }
}
@media (prefers-reduced-motion: reduce) {
  .desgaste.critico .desgaste-cheio, .desgaste-conta.critico { animation: none; }
  .desgaste-cheio { transition: none; }
}
/* ---- a terceira lista do filtro: em que itens a estrela vale ---- */
/*
 * Nem barrada (vermelha) nem protegida (verde): dourada, que é a cor da
 * estrela. As três marcas têm de ser distinguíveis de relance, porque o mesmo
 * item pode estar em duas listas ao mesmo tempo.
 */
.filter-grid .cell.so-afixo { border-color: #e0a84a; box-shadow: inset 0 0 0 2px #e0a84a; }
.filter-grid .cell.so-afixo.protected { box-shadow: inset 0 0 0 2px #e0a84a, 0 0 0 2px #35d17a; }
.filtro-afixo-onde { display: grid; gap: 6px; margin-top: 4px; }
.filtro-afixo-escolher { justify-self: start; padding: 4px 10px; border-radius: 6px; cursor: pointer; font-size: 11px; }
.filtro-afixo-onde .filter-grid { max-height: 96px; overflow-y: auto; }

/* ---------- os emotes do chat ---------- */
/*
 * O botão fica entre a caixa de texto e o "Enviar", e a gaveta sobe por cima da
 * conversa — a janela do chat tem 300px de altura e não sobra linha para uma
 * barra fixa de emotes. Ver `gavetaDeEmotes`, em chat.mjs.
 */
.chat-emotes-botao {
  flex: none; width: 26px; padding: 0; cursor: pointer;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 6px;
  color: var(--muted); font-size: 14px; line-height: 1;
}
.chat-emotes-botao:hover { color: var(--text); border-color: var(--accent-dim); }
/*
 * ---- A gaveta de emotes ----
 *
 * `fixed`, e não `absolute`: dentro da janela do chat ela era cortada pela
 * borda quando não havia altura acima do rodapé, e as primeiras fileiras
 * sumiam — o report "dependendo do chat os emotes nao mostram todos". As
 * coordenadas são postas na abertura, em `posicionarGaveta`.
 *
 * O teto de altura é o que faz a promessa: se não couber, ela ROLA. Nenhuma
 * fileira fica escondida sem um jeito de chegar nela.
 */
.chat-emotes {
  position: fixed; z-index: 60;
  display: grid; grid-template-columns: repeat(8, 1fr); gap: 2px;
  padding: 6px;
  max-height: min(52vh, 340px); overflow-y: auto; overscroll-behavior: contain;
  background: #0d1518; border: 1px solid var(--line); border-radius: 8px;
  box-shadow: 0 6px 18px #0009;
}
.chat-emote {
  padding: 3px 0; cursor: pointer; font-size: 16px; line-height: 1.1;
  background: none; border: 1px solid transparent; border-radius: 5px;
}
.chat-emote:hover { background: #16241f; border-color: var(--accent-dim); }

/* ---------- os balões do alto ---------- */

/*
 * O aviso de que chegou resposta a um report.
 *
 * Ele mora na mesma coluna de `#faixa-novidades` e do cartaz de beta: centrado,
 * logo abaixo da barra de cima (por isso a soma com `--altura-do-aviso`, que
 * vale zero quando não há faixa de obra). É o corredor do jogo para avisos que
 * ficam — e ficar é o ponto: quem está caçando lê quando puder.
 *
 * `z-index: 29` é o mesmo da faixa de novidades, um a menos que a barra de
 * cima: o balão passa por cima das janelas e por baixo da barra, que é onde
 * estão os botões.
 *
 * A PILHA não recebe ponteiro; cada balão recebe. Assim a faixa vazia — que
 * ocupa a largura toda — não engole o clique no mapa atrás dela.
 */
#recados {
  position: fixed; z-index: 29;
  top: calc(var(--altura-da-topbar) + var(--altura-do-aviso, 0px) + 6px);
  left: 50%; transform: translateX(-50%);
  display: flex; flex-direction: column; gap: 6px;
  width: min(620px, 92vw);
  pointer-events: none;
}
/* Com a placa de novidades na tela, os balões descem uma faixa — o mesmo
   deslocamento que o cartaz de beta faz. */
body.com-novidades #recados { top: calc(var(--altura-da-topbar) + var(--altura-do-aviso, 0px) + 6px + 30px); }

.recado {
  display: flex; align-items: stretch; pointer-events: auto;
  background: linear-gradient(180deg, #123a33, #0b201d);
  border: 1px solid #2f7d6c; border-radius: 8px;
  box-shadow: 0 8px 22px #000a;
  animation: recado-entra .35s cubic-bezier(.2, .9, .25, 1) both;
}

/*
 * O corpo é um BOTÃO, e não uma div com `onclick`: ele é a área de "ler", e o
 * jogo se joga com o teclado — um alvo que o Tab não alcança é um alvo que
 * metade das pessoas não tem.
 */
.recado-corpo {
  flex: 1 1 auto; min-width: 0;
  display: flex; align-items: center; gap: 9px;
  padding: 8px 12px; cursor: pointer; text-align: left;
  background: none; border: none; color: inherit; font: inherit;
}
.recado-corpo:hover { background: #ffffff0d; }

.recado-selo {
  flex: none; padding: 2px 9px; border-radius: 999px;
  background: #ffffff14; border: 1px solid #52c9ad;
  font-family: var(--font-heading); font-size: 10px; letter-spacing: .09em;
  text-transform: uppercase; color: #8ff0d6;
}

/* O único pedaço que pode encolher: o selo diz o que é e o "ler" diz o que
   fazer — cortar qualquer um dos dois deixaria o balão mudo. */
.recado-texto {
  flex: 1 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 12px; color: #d6efe8;
}

.recado-ler { flex: none; font-style: normal; font-size: 11px; color: #8ff0d6; text-decoration: underline; }

.recado-fecha {
  flex: none; width: 30px; padding: 0; cursor: pointer;
  background: none; border: none; border-left: 1px solid #2f7d6c59;
  color: #7fb8ab; font-size: 16px; line-height: 1;
}
.recado-fecha:hover { background: #ffffff12; color: #fff; }

@keyframes recado-entra {
  from { opacity: 0; transform: translateY(-10px); }
  to { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .recado { animation: none; }
}

/* ---------- a prévia da hunt, mais compacta ---------- */

/*
 * ---- A gaveta da venda automática ----
 *
 * O dono: "a página de filtro de loot na hora de escolher a caçada ficou
 * bugado; vê uma forma de otimizar ou compactar, porque tá ruim. Se quiser
 * diminuir um pouco o tamanho dos botões de caça automática e caça online,
 * pode."
 *
 * Na coluna da esquerda da prévia moram, de cima para baixo: o título, os dois
 * botões de preset, a legenda dos cliques, o bloco da estrela e a grade de
 * loot. O bloco da estrela sozinho tem oito fileiras quando está ligado, e é o
 * único deles que não é sobre ESTA hunt — é um ajuste geral que por acaso
 * também aparece aqui.
 *
 * Recolhido, ele vira uma linha que diz a regra de agora, e as sete fileiras
 * que ele devolve vão para a grade — que é o que a pessoa veio marcar. Ver
 * `escolhaDeAfixo` no panels.mjs.
 */
.filtro-afixo-gaveta {
  margin: 6px 0 8px; border: 1px solid var(--line); border-radius: 7px;
  background: #0e1518;
}
.filtro-afixo-gaveta > summary {
  cursor: pointer; padding: 6px 9px; font-size: 11px; color: var(--muted);
  /* O triângulo é desenhado abaixo: o nativo muda de forma entre navegadores. */
  list-style: none;
}
.filtro-afixo-gaveta > summary::-webkit-details-marker { display: none; }
.filtro-afixo-gaveta > summary::before { content: '\25B8'; margin-right: 6px; color: var(--accent-dim); }
.filtro-afixo-gaveta[open] > summary::before { content: '\25BE'; }
.filtro-afixo-gaveta > summary:hover { color: var(--text); }
.filtro-afixo-gaveta[open] > summary { border-bottom: 1px solid var(--line); }
.filtro-afixo-gaveta > .filtro-afixo { margin: 0; padding: 8px 9px 10px; }
/* O título já está no resumo — dentro ele seria a mesma frase duas vezes. */
.filtro-afixo-gaveta > .filtro-afixo > b { display: none; }
/* A da raridade FICA: o resumo fala das duas, mas dentro da gaveta ela é a
   segunda regra, e sem título pareceria continuação da primeira. */
.filtro-afixo-gaveta > .filtro-raridade > b { display: block; }

/*
 * ---- E os dois botões de modo encolhem ----
 *
 * Foi ele quem ofereceu, e eles são o item mais alto do rodapé grudado no pé:
 * cada pixel que saem daqui é um pixel que a grade de loot ganha. Só dentro da
 * prévia — noutras telas os mesmos botões não disputam altura com nada.
 *
 * ---- E o que encolhe é a MOLDURA, não o padding ----
 *
 * A primeira tentativa pôs `padding: 9px 11px` aqui e deixou os botões MAIS
 * altos. É que eles não têm padding: têm `padding: 0` e uma moldura ornamentada
 * de `border-image` com 20px em cima e embaixo (ver o bloco `.run-mode,
 * .enfrentar` mais acima). Somar padding só empurra o conteúdo para dentro de
 * uma caixa que continua do mesmo tamanho, e ainda soma os 18px.
 *
 * Quem cede altura é a faixa de cima e a de baixo da moldura, de 20 para 13. Os
 * 30px dos LADOS ficam: é onde moram os cantos ornamentados, e a nota daquele
 * bloco mediu que abaixo de ~26px eles viram um risco escuro. Em cima e embaixo
 * a arte é uma faixa lisa, que é justamente por que ela já estava em 20 e não
 * em 30.
 */
.modal-box:has(.hunt-previa) .run-mode { border-width: 13px 30px; gap: 2px; font-size: 13px; }
.modal-box:has(.hunt-previa) .run-mode em { font-size: 10px; line-height: 1.25; }
.modal-box:has(.hunt-previa) .run-mode .run-mode-bonus { font-size: 10px; }
.modal-box:has(.hunt-previa) .run-modes { gap: 8px; }
/* O rodapé aperta junto: são mais 8px para a grade, sem mexer em nada dentro. */
.modal-box:has(.hunt-previa) .modal-rodape { gap: 6px; padding-top: 8px; padding-bottom: 10px; }

/*
 * ---- E, se ainda assim não couber, quem rola é a coluna ----
 *
 * A rolagem da grade resolve o caso em que quem sobra é a grade. Não resolve o
 * contrário: numa janela muito baixa, o que está ACIMA dela já não cabe, e o
 * excedente ia parar atrás do rodapé — que é `sticky` e passa por cima. Era o
 * "ficou bugado" do print: a fileira "Só a dourada" cortada ao meio pela barra
 * do "Parar em".
 *
 * Com a coluna rolando, o pior caso passa a ser uma barra de rolagem a mais.
 * Nada fica escondido, que era o problema.
 */
.modal-box:has(.hunt-previa) .hunt-previa-colunas > .hunt-previa-bloco { overflow-y: auto; }

/*
 * ---- A regra combinada, no pé do bloco da estrela ----
 *
 * As duas fileiras respondem a duas perguntas; esta linha é a conta entre elas.
 * Ela tem peso de conclusão — texto claro, fundo próprio — porque é a única
 * frase do bloco que diz o que vai acontecer com a peça. Ver
 * `fraseDaRegraDoAfixo`.
 */
.filtro-afixo-regra {
  display: grid; gap: 3px; margin: 8px 0 2px; padding: 7px 9px;
  border-left: 2px solid var(--accent-dim); border-radius: 0 5px 5px 0;
  background: #101a1d;
}
.filtro-afixo-regra > b { font-size: 12px; color: var(--text); font-weight: 600; }
.filtro-afixo-regra > em { font-style: normal; font-size: 10px; color: var(--muted); line-height: 1.4; }

/*
 * Dentro da gaveta, a frase da regra já é o RESUMO dela — repeti-la no pé seria
 * a mesma linha duas vezes na mesma caixa. O que fica é só a explicação de que
 * as duas fileiras valem juntas, que o resumo não tem espaço para dizer.
 */
.filtro-afixo-gaveta .filtro-afixo-regra > b { display: none; }
.filtro-afixo-gaveta .filtro-afixo-regra { margin-top: 6px; }

/*
 * ---- As regras da sala de boss, escritas na tela de entrar ----
 *
 * Três coisas que custam caro e que nenhuma dá para descobrir de dentro: a
 * espera é cobrada na ENTRADA, o relógio é de 25 minutos e a saída é um
 * teleporte no chão. Ficam entre a prévia e os dois botões, que é o último
 * lugar por onde o olho passa antes do clique.
 */
.boss-regras {
  list-style: none;
  margin: 6px 0 2px;
  padding: 8px 10px;
  display: grid;
  gap: 4px;
  border: 1px solid #6b5a2e66;
  border-radius: 6px;
  background: #1a150b66;
  color: var(--muted);
  font-size: 11px;
  line-height: 1.35;
}
.boss-regras li { position: relative; padding-left: 12px; }
.boss-regras li::before { content: '·'; position: absolute; left: 3px; color: #c8a24a; font-weight: 700; }

/*
 * O aviso que substitui o filtro de loot na sala de boss: lá tudo vai para o
 * baú de recompensa, e não há nada que uma marca pudesse mudar.
 */
.previa-recompensa {
  margin: 4px 0 8px;
  padding: 6px 8px;
  border-left: 3px solid #c8a24a;
  background: #1a150b66;
  color: var(--muted);
  font-size: 11px;
  line-height: 1.35;
}


/* =========================================================================
   A LOJA DE BOSS TOKEN
   =========================================================================

   Mesma linguagem da Mineiroidle Store — cards em grade, arte em cima, preço no
   botão — com a moeda trocada.

   ---- O DOURADO SAIU ----

   "contornos: usar o MESMO contorno padrão das outras janelas do jogo (o
    verde/teal que já usamos), não dourado."

   O saldo tinha uma barra `--exp` (o dourado da experiência) e era a única coisa
   dourada da janela; as molduras agora são `--line` e a seleção é `--accent`, as
   mesmas de vinte outras telas. O âmbar ficou só para AVISO — o selo de premium
   de quem não tem premium.

   ---- AS VARIÁVEIS TÊM ESCOPO NA JANELA ----

   Elas moram em `.modal-box.bt`, que é a variante desta loja (e da irmã dela, a
   de Task Token): mexer numa delas não alcança nenhuma outra tela.
   ========================================================================= */
.modal-box.bt {
  --bt-corpo: #141a1c;
  --bt-sec: #1b2426;
  --bt-caixa: #24312f;
  --bt-linha: var(--line);
  --bt-forte: var(--accent);
  --bt-hover: var(--accent-dim);
  --bt-ok: #6fd48a;
  --bt-falta: #e2574c;
  --bt-aviso: #e0b464;
}
/* O ícone do cabeçalho: o mesmo do botão que abre a loja. */
.bt-selo-arte { width: 26px; height: 26px; image-rendering: pixelated; }
/*
 * ---- O VOLTAR, À ESQUERDA DO TÍTULO ----
 *
 * Ele fica no canto esquerdo do cabeçalho (`#modal-selo`), antes do ícone —
 * onde a seta de voltar está em toda tela que tem uma. Só aparece quando há
 * origem: aberta pelo atalho direto, não há para onde voltar.
 */
.bt-voltar {
  padding: 3px 9px; cursor: pointer;
  background: var(--bt-caixa, #24312f); border: 1px solid var(--line); border-radius: 5px;
  font: inherit; font-size: 11px; color: var(--text);
}
.bt-voltar:hover { border-color: var(--accent); color: var(--accent); }

/* =========================================================================
 * ---- O SALDO E AS ABAS FICAM PARADOS ----
 *
 * "o bloco do saldo fica FIXO no topo da janela (sticky), junto com as abas. Só
 *  a lista de itens rola."
 *
 * Quem rola é o `#modal-body`, então o `sticky` cola no topo dele. O fundo é
 * opaco de propósito: sem ele os cards passariam por baixo do saldo, visíveis
 * através dele.
 * ========================================================================= */
.bt-topo {
  position: sticky; top: -18px; z-index: 3;
  margin: -18px -18px 10px; padding: 18px 18px 0;
  background: var(--panel-solid, #141a1d);
}
.bt-saldo {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin: 0; padding: 9px 12px;
  background: var(--bt-sec, #1b2426);
  border: 1px solid var(--bt-linha, var(--line)); border-radius: 6px;
}
.bt-saldo canvas { image-rendering: pixelated; flex: none; }
.bt-saldo b {
  font-family: var(--font-numero); font-size: 21px; line-height: 1; color: #eef3f2;
  font-variant-numeric: tabular-nums;
}
.bt-saldo-moeda { font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--accent); }
.bt-saldo em { font-style: normal; font-size: 11px; color: var(--muted); }
/* As abas encostam no saldo, e a faixa do sticky cobre as duas. */
.bt-topo .tabs { margin: 8px 0 0; }

/* =========================================================================
 * ---- A GRADE UNIFORME ----
 *
 * "todos os cards com a mesma largura e altura dentro da aba, colunas que se
 *  ajustam à largura."
 *
 * `grid-auto-rows: 1fr` é o que iguala a ALTURA entre fileiras diferentes — sem
 * ele cada fileira tem a altura do maior card dela, e a grade fica em degraus.
 * ========================================================================= */
.bt-grade {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  grid-auto-rows: 1fr; gap: 10px;
}
/* Uma coluna só: é o caso do card único das Lasting Exercise. */
.bt-grade-um { grid-template-columns: minmax(0, 1fr); }
.bt-card {
  position: relative;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 12px 10px 10px;
  background: var(--bt-sec, #1b2426);
  border: 1px solid var(--bt-linha, var(--line)); border-radius: 8px;
  text-align: center;
}
.bt-card:hover { border-color: var(--bt-hover, var(--accent-dim)); }
.bt-card b { font-family: var(--font-heading); font-size: 12.5px; line-height: 1.25; }
/*
 * A descrição para em TRÊS linhas, e o resto fica no balão. Era o texto inteiro,
 * e com ele o card do passe de Divine (que explica dois levels) ficava duas vezes
 * mais alto que o da wildcard — numa grade que promete cards iguais.
 */
.bt-card em {
  font-style: normal; font-size: 10.5px; color: var(--muted); line-height: 1.4;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden;
}
.bt-card canvas { image-rendering: pixelated; }
/* O ícone grande, centrado, num quadro de altura fixa para os nomes se alinharem. */
.bt-arte-caixa { display: grid; place-items: center; min-height: 80px; flex: none; }
.bt-arte { width: 56px; height: 56px; object-fit: contain; image-rendering: pixelated; }
/* O rodapé do card cola embaixo: é ele que faz o preço ficar na mesma linha em
   todos os cards da fileira, mesmo com nomes de tamanhos diferentes. */
.bt-pe { margin-top: auto; padding-top: 6px; display: grid; justify-items: center; gap: 4px; }
.bt-card button { min-width: 86px; }
/* O preço é o desenho da moeda mais o número: dizer "500 Boss Token" em cada
   card repetiria o nome doze vezes na mesma tela. */
.bt-preco { display: inline-flex; align-items: center; gap: 5px; font-variant-numeric: tabular-nums; }
.bt-preco canvas { width: 16px; height: 16px; }
/* O que falta, embaixo do botão apagado — e não num balão, que é onde ninguém
   procura por que um botão não responde. */
.bt-falta { font-size: 10.5px; font-weight: 700; color: var(--bt-falta, #e2574c); }
.bt-ja-tem {
  font-size: 11.5px; font-weight: 700; letter-spacing: .04em;
  color: var(--bt-ok, #6fd48a);
}
/* E o que ele já tem de um conjunto incompleto: ter o outfit sem os addons é
   diferente de ter tudo, e a diferença decide se vale pagar. */
.bt-parcial { font-size: 10px; color: var(--muted); }
/* Já comprado: o card apaga em vez de sumir — some daqui e o jogador procura
   o que ele já tem. */
.bt-card.bt-tem { opacity: .62; }

/* ---- Os selos do canto ---- */
.bt-selos { position: absolute; right: 6px; top: 6px; display: flex; flex-direction: column; align-items: flex-end; gap: 3px; }
.bt-selo {
  padding: 1px 6px; border-radius: 3px;
  background: #ffffff10; border: 1px solid var(--line);
  font-size: 9px; letter-spacing: .04em; text-transform: uppercase; color: var(--muted);
}
/* O único âmbar da janela: premium que a pessoa NÃO tem. */
.bt-selo.bt-selo-aviso {
  background: rgba(224, 180, 100, .12); border-color: rgba(224, 180, 100, .55);
  color: var(--bt-aviso, #e0b464);
}
/* O botãozinho de ver a prévia no outro sexo. */
.bt-sexo {
  position: absolute; left: 6px; top: 6px;
  padding: 1px 6px; cursor: pointer;
  background: #ffffff10; border: 1px solid var(--line); border-radius: 3px;
  font: inherit; font-size: 10px; color: var(--muted);
}
.bt-sexo:hover { border-color: var(--accent); color: var(--accent); }

/* =========================================================================
 * ---- OS CHIPS DAS LASTING EXERCISE ----
 *
 * Oito cards iguais em tudo menos numa palavra viraram um card e oito chips. O
 * escolhido tem a borda de seleção da janela, a mesma das abas.
 * ========================================================================= */
.bt-chips { display: flex; flex-wrap: wrap; justify-content: center; gap: 5px; }
.bt-chip {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 3px 8px; cursor: pointer;
  background: var(--bt-caixa, #24312f); border: 1px solid var(--line); border-radius: 12px;
  font: inherit; font-size: 10.5px; color: var(--muted);
}
.bt-chip canvas { width: 20px; height: 20px; image-rendering: pixelated; }
.bt-chip:hover { border-color: var(--accent-dim); color: var(--text); }
.bt-chip.escolhido { border-color: var(--accent); color: #eafffb; background: #3fbfa81c; }
/* O card único fica largo, com os chips em linha — ver `cartaoDasLasting`. */
.bt-card.bt-largo { max-width: none; }

/* ---- A caixa de confirmar a compra ---- */
.confirm-box.bt-confirma { display: grid; gap: 10px; width: min(400px, 94vw); }
.bt-confirma-resumo { display: grid; justify-items: center; gap: 7px; }
.bt-confirma-resumo canvas { image-rendering: pixelated; }
.bt-confirma-texto { margin: 0; font-size: 11.5px; line-height: 1.4; color: var(--muted); text-align: center; }
.bt-confirma-conta {
  margin: 0; padding: 8px; display: grid; justify-items: center; gap: 2px;
  background: var(--bt-caixa, #24312f); border: 1px solid var(--line); border-radius: 5px;
}
.bt-confirma-conta b { font-family: var(--font-numero); font-size: 17px; color: #eef3f2; }
.bt-confirma-conta span { font-size: 11px; color: var(--muted); }

/* O foco por teclado, em tudo o que se clica nesta loja. */
.modal-box.bt .bt-chip:focus-visible,
.modal-box.bt .bt-card button:focus-visible,
.modal-box.bt .bt-sexo:focus-visible,
.modal-box.bt .tabs button:focus-visible,
.bt-voltar:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}

/*
 * ---- A JANELA ESTREITA ----
 *
 * "em tela estreita a grade cai para 2 colunas e depois 1; abas continuam
 *  visíveis."
 *
 * As abas continuam no `sticky` — elas não têm o que ceder, e são a única
 * navegação da tela.
 */
@media (max-width: 620px) {
  .bt-grade { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
}
@media (max-width: 420px) {
  .bt-grade { grid-template-columns: minmax(0, 1fr); }
  .bt-saldo b { font-size: 18px; }
}

/* O atalho no canto de ações da aba de Bosses. */
.bt-atalho { display: inline-flex; align-items: center; gap: 6px; }
.bt-atalho canvas { width: 16px; height: 16px; image-rendering: pixelated; }

/* ---------- a peça cara na tela de vender ----------
 *
 * Apagada enquanto está fora da seleção — o mesmo desenho de quando ela era
 * intocável, porque o recado é o mesmo: "esta aqui não é sucata". Marcada, ela
 * acende em vermelho, que é a única cor da tela que quer dizer "não volta".
 */
.venda-item.com-aviso .venda-preco { color: #c98a80; }
.venda-item.com-aviso.marcada .venda-preco { color: var(--danger); font-weight: 700; }
.venda-item.com-aviso.marcada .cell { border-color: var(--danger); box-shadow: 0 0 0 1px #7a3a3455; }
/* A lista da segunda confirmação: uma linha por peça, com o desenho e o motivo. */
.venda-valiosas { display: grid; gap: 6px; margin: 10px 0; max-height: 210px; overflow-y: auto; }
.venda-valiosa {
  display: flex; align-items: center; gap: 9px; text-align: left;
  padding: 5px 7px; background: #ffffff05; border: 1px solid var(--line-soft); border-radius: 6px;
}
.venda-valiosa b { font-family: var(--font-heading); font-size: 12px; display: block; }
.venda-valiosa em { font-style: normal; font-size: 10px; color: var(--muted); }

/* ---------- o botão "Parar em", no topo da prévia ----------
 *
 * Fechado ele é do tom do Voltar do lado; com alguma condição ligada acende no
 * dourado do jogo — a mesma cor do que vale dinheiro, porque uma caçada que
 * encerra sozinha é uma decisão com preço.
 */
.paradas-botao {
  display: inline-flex; align-items: baseline; gap: 7px; max-width: 100%;
  text-align: left; overflow: hidden;
}
.paradas-botao b { font-family: var(--font-heading); font-size: 11px; letter-spacing: .04em; }
.paradas-botao em {
  font-style: normal; font-size: 10px; opacity: .8;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.paradas-botao .paradas-seta { font-style: normal; font-size: 11px; opacity: .7; margin-left: 2px; }
.previa-topo .paradas-botao.on { border-color: #6a5420; color: var(--exp); }
.previa-topo .paradas-botao.on em { color: #d9c48a; opacity: 1; }
.previa-topo .paradas-botao[aria-expanded="true"] { border-color: var(--accent-dim); color: var(--text); }

/* ---------- o lobby da party ----------
 *
 * Um card por pessoa, e o estado dela na própria linha. As três cores dizem as
 * três respostas sem precisar ler: cinza é esperando, verde é pronto, vermelho
 * é quem não pode entrar — e aí o motivo está escrito no lugar de "pronto".
 */
.lobby-cabeca {
  display: grid; gap: 3px; margin: 0 0 12px; padding: 10px 12px;
  background: #ffffff05; border-left: 2px solid var(--accent-dim); border-radius: 0 6px 6px 0;
}
.lobby-cabeca b { font-family: var(--font-heading); font-size: 15px; color: var(--accent); }
.lobby-cabeca em { font-style: normal; font-size: 11px; color: var(--muted); }
.lobby-conta { font-size: 10px; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.lobby-gente { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 7px; }
.lobby-membro {
  display: grid; gap: 3px; padding: 9px 10px;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px;
}
.lobby-membro em { font-style: normal; font-size: 10px; color: var(--muted); }
/*
 * O card ganhou o boneco, a vocacao e o level — o mesmo trio do card da party,
 * e com o mesmo desenho. O retrato fica a' esquerda e o resto numa coluna, que
 * e' como a party ja' o mostra: duas telas que mostram a mesma pessoa nao podem
 * mostra-la de jeitos diferentes.
 */
.lobby-topo { display: flex; align-items: center; gap: 7px; min-width: 0; }
.lobby-retrato {
  flex: none; width: 34px; height: 34px; display: grid; place-items: center;
  background: #00000033; border: 1px solid var(--line-soft); border-radius: 6px; overflow: hidden;
}
.lobby-coluna { display: grid; gap: 1px; min-width: 0; }
.lobby-sub { display: flex; align-items: center; gap: 4px; font-size: 10px; color: var(--muted); }
.lobby-nome { display: flex; align-items: center; gap: 5px; min-width: 0; }
.lobby-nome b {
  font-family: var(--font-heading); font-size: 12px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.lobby-coroa { font-style: normal; font-size: 10px; color: var(--exp); }
/* Quem puxa a fila, dito no card de quem puxa — a mesma cor do selo da party. */
.lobby-ponta {
  flex: none; font-style: normal; font-size: 9px; color: var(--copper);
  border: 1px solid var(--copper); border-radius: 20px; padding: 0 5px; line-height: 14px;
}
/*
 * As caixas de formacao, no pe' da janela. Elas sao as MESMAS do painel de
 * Amigos (`escolhasDaPosicao`), entao o que esta regra faz e' so' dar a elas um
 * lugar separado da lista de gente — nao um segundo visual.
 */
.lobby-config {
  display: grid; gap: 6px; margin-top: 12px; padding-top: 10px;
  border-top: 1px solid var(--line-soft);
}
.lobby-membro.pronto { border-color: var(--accent-dim); }
.lobby-membro.pronto em { color: var(--accent); }
.lobby-membro.impedido { border-color: #7a3a3466; }
.lobby-membro.impedido em { color: #c98a80; }
/* Quem o lider nao chamou desta vez: fica a' vista, apagado. */
.lobby-membro.fora { opacity: .45; border-style: dashed; }

/*
 * ---- O "Parar em" dentro do lobby ----
 *
 * O mesmo botao da previa da hunt, no mesmo formato fechadinho ("igual a foto
 * 2, igual como e' la em hunts"). O que muda e' so' onde ele mora: no pe' da
 * janela, separado da lista de gente pela mesma linha que separa as caixas de
 * formacao.
 *
 * As cores do aceso estavam presas a `.previa-topo`; aqui elas se repetem com o
 * mesmo valor em vez de a regra de la ser afrouxada — afrouxa-la pintaria de
 * dourado qualquer `.paradas-botao` que venha a existir noutra tela.
 */
.lobby-paradas {
  display: grid; gap: 8px; justify-items: start;
  margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--line-soft);
}
/*
 * ---- E ele usa a MOLDURA que o jogo já usa ----
 *
 * Report do dono: "esse botão do parar em tá com fundo branco, deixa no mesmo
 * estilo q a gente já usa."
 *
 * O visual dele não morava na classe `.paradas-botao`: morava em
 * `.previa-topo .modal-back`, a fileira do "Voltar para as hunts". Fora dali o
 * `.modal-back` não pinta nada, e um `<button>` sem pintura é o botão CINZENTO
 * do navegador — que é o branco que ele viu.
 *
 * Repetido aqui em vez de afrouxar a regra de lá: afrouxá-la mudaria o
 * "Voltar" de toda tela que usa `modal-back`, e o pedido era o contrário
 * disso.
 */
.lobby-paradas .paradas-botao {
  padding: 4px 10px; font-size: 11px; cursor: pointer;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 6px; color: var(--muted);
  margin-bottom: 0;
}
.lobby-paradas .paradas-botao:hover { border-color: var(--accent-dim); color: var(--text); }
.lobby-paradas .run-paradas { width: 100%; }
.lobby-paradas .paradas-botao.on { border-color: #6a5420; color: var(--exp); }
.lobby-paradas .paradas-botao.on em { color: #d9c48a; opacity: 1; }
.lobby-paradas .paradas-botao[aria-expanded="true"] { border-color: var(--accent-dim); color: var(--text); }

/*
 * A caixinha do "aceitar automaticamente", colada nos botoes do lobby.
 *
 * Ela fica na largura toda e alinhada a esquerda porque nao e uma acao: e uma
 * preferencia que a pessoa marca de passagem, e por na fileira dos botoes a
 * faria competir com o "Pronto", que e o clique da vez.
 */
.lobby-auto {
  display: flex; align-items: center; gap: 6px;
  margin-top: 8px; font-size: 11px; color: var(--muted); cursor: pointer;
}
.lobby-auto:hover { color: var(--text); }

/* Um botão por amigo na lista de convite da prévia: clicou, o convite saiu. */
.convidar-amigo {
  display: flex; align-items: center; gap: 6px; width: 100%;
  padding: 4px 8px; cursor: pointer; text-align: left;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 6px;
  color: var(--text); font-size: 11px;
}
.convidar-amigo:hover:not(:disabled) { border-color: var(--accent-dim); }
.convidar-amigo:disabled { opacity: .45; cursor: default; }
.convidar-amigo i { font-style: normal; font-size: 10px; color: var(--accent-dim); margin-left: auto; }

/*
 * A moeda ao lado do rótulo "Coins" no câmbio.
 *
 * A coluna é alinhada à direita como os números que ela encima, então a figura
 * entra antes do texto e o conjunto continua encostado na borda direita.
 */
.balcao-linha.cabeca > .balcao-coluna-coin {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 4px;
}
.balcao-linha.cabeca > .balcao-coluna-coin canvas,
.balcao-linha.cabeca > .balcao-coluna-coin img {
  width: 13px;
  height: 13px;
  flex: none;
  image-rendering: pixelated;
  opacity: .9;
}

/*
 * A caixa das Chegadas, no depósito.
 *
 * Ela não é uma das dezesseis do jogador: é onde o jogo põe o que chegou de
 * compra, de mercado, de correio ou de saco quando não coube na mochila. A cor
 * do acento e o pacote no lugar da depot box são o que a separam da parede de
 * caixas sem ninguém precisar ler o nome. Ver `CAIXA_DE_CHEGADAS`, no servidor.
 */
.deposito-parede .deposito-caixa.chegadas {
  border-color: var(--accent-dim);
  background: linear-gradient(180deg, rgba(88, 160, 130, 0.10), transparent 70%);
}
.deposito-parede .deposito-caixa.chegadas b { color: var(--accent); }
.deposito-parede .deposito-caixa.chegadas:hover { border-color: var(--accent); }

/*
 * A caixa COMPARTILHADA da conta, em roxo.
 *
 * Ela precisa se distinguir das dezesseis do personagem E da de Chegadas, que
 * ja e verde: sao tres coisas diferentes na mesma parede, e a unica que muda o
 * que acontece com a peca — o que entra aqui sai nos outros personagens — e
 * justamente esta.
 */
.deposito-parede .deposito-caixa.compartilhada {
  border-color: rgba(158, 128, 214, 0.55);
  background: linear-gradient(180deg, rgba(158, 128, 214, 0.12), transparent 70%);
}
.deposito-parede .deposito-caixa.compartilhada b { color: #b9a1e8; }
.deposito-parede .deposito-caixa.compartilhada:hover { border-color: #b9a1e8; }

/*
 * O baú de boss, primeiro da parede: âmbar, porque ele é o único cujo conteúdo
 * VENCE. As sacolas têm prazo, e a cor é o que faz a pessoa olhar para ele antes
 * de olhar para as caixas que esperam para sempre.
 */
.deposito-parede .deposito-caixa.recompensa {
  border-color: rgba(199, 149, 74, 0.55);
  background: linear-gradient(180deg, rgba(199, 149, 74, 0.12), transparent 70%);
}
.deposito-parede .deposito-caixa.recompensa b { color: #e0b878; }
.deposito-parede .deposito-caixa.recompensa:hover { border-color: #e0b878; }

/* A arte de interface numa caixa da parede (a Compartilhada usa o ícone da party). */
.deposito-parede .deposito-caixa-arte { image-rendering: pixelated; }

/*
 * A fileira das TRES especiais: centralizada e separada das dezesseis por uma
 * linha. Sao coisas de natureza diferente — uma vence, uma e' da conta toda, uma
 * e' preenchida pelo jogo — e a separacao e' o que diz isso sem escrever nada.
 */
.deposito-parede.especiais {
  /*
   * `flex` e nao a grade de quatro colunas: sao TRES caixas, e numa grade de
   * quatro elas ficariam encostadas a esquerda com uma coluna vazia sobrando —
   * `justify-content` nao centraliza itens em colunas `1fr`, que ja ocupam tudo.
   */
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  padding-bottom: 12px;
  margin-bottom: 12px;
  border-bottom: 1px solid var(--line-soft);
}
/* Na fileira flex a caixa nao tem coluna que lhe de largura: ela vem daqui. */
.deposito-parede.especiais .deposito-caixa { width: 118px; }

/* O rodapé de comprar vagas, embaixo da grade da caixa compartilhada. */
.deposito-vagas {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: 4px;
}
.deposito-vagas em { color: var(--muted); font-size: 12px; font-style: normal; }

/*
 * ---- A prateleira do balcão: ouro ou Mineiroidle Coins ----
 *
 * Fica logo abaixo dos dois lados ("À venda" / "Procurados") e é menor que
 * eles de propósito: o lado muda o que a lista significa, a moeda muda só em
 * que os preços estão escritos. Ver `MOEDAS_DO_BALCAO`, no panels.mjs.
 */
.balcao-lados { display: grid; gap: 0; }
.balcao-lados .balcao-par { margin-bottom: 8px; }
.balcao-moedas {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  margin: 0 auto 14px;
  flex-wrap: wrap;
}
.balcao-moedas-rotulo {
  font-family: var(--font-heading);
  font-size: 10px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--muted);
  margin-right: 2px;
}
.balcao-moeda-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 11px;
  border: 1px solid var(--line-soft);
  border-radius: 999px;
  background: var(--panel-2);
  color: var(--muted);
  cursor: pointer;
}
.balcao-moeda-chip canvas,
.balcao-moeda-chip img { width: 16px; height: 16px; flex: none; image-rendering: pixelated; opacity: .75; }
.balcao-moeda-chip b { font-size: 11.5px; font-weight: 600; }
.balcao-moeda-chip:hover { border-color: var(--line); color: var(--text); }
.balcao-moeda-chip.on { border-color: var(--accent-dim); color: var(--text); background: rgba(88, 160, 130, 0.10); }
.balcao-moeda-chip.on canvas,
.balcao-moeda-chip.on img { opacity: 1; }
.balcao-moeda-chip.on.gold { border-color: rgba(185, 151, 91, 0.55); background: rgba(185, 151, 91, 0.10); }

/* Dentro da caixa de anunciar ela é uma linha do formulário, e não um filtro. */
.balcao-moedas.na-caixa { justify-content: flex-start; margin: 2px 0 10px; }

/*
 * O aviso de caixa vazia ocupa a LARGURA TODA do armário.
 *
 * A grade do locker tem colunas fixas de 38px — o tamanho de um quadradinho de
 * item —, e um parágrafo caía dentro de uma dessas colunas: a frase saía uma
 * sílaba por linha, numa tira de 38px de largura. Vale para toda caixa vazia, e
 * não só para a de Chegadas.
 */
.locker-grade > .vazio {
  grid-column: 1 / -1;
  font-size: 12px;
  color: var(--muted);
  font-style: italic;
  margin: 2px 0;
}

/* ---------- O card de quantidade da loja ----------
 *
 * "o de 25 ficou um pouco fora do card, se vc quizer aumentar mais o card
 *  pode."
 *
 * Em vez de alargar o card, os botoes QUEBRAM linha. Alargar resolveria os
 * quatro tamanhos de hoje e voltaria a estourar no dia em que houvesse um 50x
 * — e um card mais largo que os vizinhos desalinha a grade inteira da
 * prateleira. Com `wrap`, cabe o que couber e o resto desce.
 */
.store-qtd { display: flex; flex-wrap: wrap; gap: 4px; justify-content: center; margin: 6px 0 4px; }
.store-qtd-botao {
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  min-width: 46px; padding: 4px 6px; line-height: 1.1;
  border: 1px solid #3a4a4f; border-radius: 4px;
  background: #10181acc; color: #d8cfb8; cursor: pointer;
}
.store-qtd-botao:hover { border-color: #6a8a92; }
/* O escolhido fica aceso — e' o unico estado que muda o preco logo abaixo. */
.store-qtd-botao.escolhido { border-color: #3fbfa8; background: #12282acc; color: #eafff8; }
.store-qtd-botao b { font-size: 12px; }
/* O desconto e' verde porque e' ganho, e pequeno porque nao e' o titulo. */
.store-qtd-off { font-size: 9px; color: #4ade80; }

/* ---------- A troca automatica do amuleto e do anel ----------
 *
 * A engrenagem mora na quina de CIMA, a direita do slot, e ela levou duas
 * correcoes em sentidos opostos — o meio entre as duas e' o que esta aqui.
 *
 * Nasceu discreta demais: um simbolo cinza de 11px solto sobre a arte da peca,
 * que o dono nao achava. Virou um disco de 16px com borda clara, sombra e,
 * quando ligada, verde com halo — e ai era o contrario: "nao precisava destacar
 * tanto". Um botao de configuracao gritando mais que a peca equipada inverte a
 * ordem do que importa naquele quadro.
 *
 * O acordo: disco pequeno, escuro e de borda discreta, que se le' como
 * "ha algo aqui" sem disputar com o item. Ligada ela so' TROCA DE COR — verde
 * fosco, sem halo e sem preenchimento —, o bastante para se achar correndo o
 * olho pela mochila. O destaque forte fica para o hover, que e' quando a pessoa
 * ja esta procurando por ela.
 */
.slot-regra {
  /*
   * A quina de fora, mordendo a folga da grade — que e' de 4px entre slots.
   * Sao 14px encostados a 2px para fora: sobra folga para o vizinho, e quase
   * nada do desenho da peca fica por baixo.
   *
   * ---- Ela saiu do canto de cima a DIREITA ----
   *
   * Report de um jogador: "as estrelas dos afixos deveriam mudar de lugar na
   * posicao dos itens, ou entao os botoes de configuracao do ring e do amuleto,
   * pois estao ficando um sobre o outro".
   *
   * Ele estava certo e a colisao era exata: `.selo-afixo` fica em `top: 0;
   * right: 2px` e a engrenagem estava em `top: -2px; right: -2px`. Um anel com
   * afixo tinha as estrelas por baixo do botao.
   *
   * Das duas saidas que ele ofereceu, mexer na ENGRENAGEM e' a barata: as
   * estrelas sao as mesmas em toda celula do jogo — mochila, deposito, mercado,
   * balao — e a engrenagem so' existe em dois slots.
   *
   * ---- E por que o meio da esquerda ----
   *
   * "vc coloca no meio no canto esquerdo". A borda esquerda tem o selo de tier
   * no alto (`.selo-tier`, -2px a 9px) e o de imbuement logo abaixo
   * (`.selo-imbu`, 11px a 22px) — mas nenhum dos dois aparece AQUI: medido no
   * catalogo, nenhum dos 96 aneis nem dos 120 amuletos aceita imbuement, e a
   * engrenagem so' existe nesses dois slots (`SLOTS_COM_REGRA`). Centrada numa
   * celula de 44px ela ocupa de 15px a 29px, abaixo de onde o selo de tier
   * termina.
   */
  position: absolute; left: -2px; right: auto; top: 50%;
  transform: translateY(-50%);
  width: 14px; height: 14px; box-sizing: border-box;
  display: grid; place-items: center;
  font-size: 10px; line-height: 1; font-style: normal;
  color: #8a9aa1; cursor: pointer;
  background: #101619; border: 1px solid #33434a; border-radius: 50%;
  transition: color .1s, border-color .1s;
  z-index: 2;
}
.slot-regra:hover { color: #f0e6cc; border-color: var(--accent-dim); }
/* Ligada: so' a cor muda. Sem halo, sem fundo — ela continua sendo um cantinho
   do slot, e nao o assunto dele. */
.slot-regra.ligada { color: #6fbf95; border-color: #3f6b57; }
.slot-regra.ligada:hover { color: #9fe6c2; border-color: var(--accent-dim); }

/* ---- a tela das regras ---- */
/* O "+ e mana": discreto, porque ele e' uma opcao e nao o assunto da linha. */
/*
 * ---- Os dois ✕ da linha nao podem ser iguais ----
 *
 * Um tira a FAIXA DE SAIDA, o outro apaga a REGRA INTEIRA, e eles ficam a
 * quatro pixels um do outro. Iguais, o clique errado custa a regra toda —
 * e quem escreveu oito nao vai perceber qual sumiu.
 *
 * O da faixa e' cinza e discreto (ele desfaz um detalhe); o da regra e'
 * vermelho (ele desfaz a linha). A cor faz o trabalho que a posicao nao faz.
 */
.joia-botoes button.danger { color: #d08072; border-color: #4a2b26; }
.joia-botoes button.danger:hover { color: #ffd9d6; border-color: var(--danger); background: #2a1512; }
/* E um respiro antes das setas, para o olho separar os dois grupos. */
.joia-botoes { display: flex; gap: 3px; margin-left: 6px; flex: none; }
.joia-mais {
  font-size: 11px; padding: 2px 7px; white-space: nowrap;
  color: #8fa0a8; border-color: #2b3940;
}
.joia-mais:hover { color: #eafff8; border-color: var(--accent-dim); }
/* O "E a" separa as duas faixas: um pouco de ar antes dele e' o que faz a
   linha continuar legivel com o dobro de campos. */
.joia-e { margin-left: 6px; font-weight: 700; color: #8fa0a8; }
/* A segunda medida nao e' escolhivel (e' sempre a outra), entao ela e' texto e
   nao um <select> — um campo que so' tem um valor possivel so' atrapalha. */
.joia-medida-fixa { font-style: normal; font-weight: 700; }
.joia-medida-fixa.vida { color: #e0938c; }
.joia-medida-fixa.mana { color: #8db4e8; }
.joia-ajuda { margin: 0 0 10px; }
.joia-ajuda p { margin: 0 0 5px; font-size: 12px; color: var(--muted); line-height: 1.45; }
.joia-ajuda .joia-exemplo { color: #8fa0a8; font-style: italic; }

.joia-regras { display: flex; flex-direction: column; gap: 6px; margin: 0 0 10px; }
/*
 * `nowrap`: a regra e' uma frase, e uma frase partida no meio deixa de ser
 * legivel de relance — que e' a unica coisa que uma lista de oito precisa ser.
 * O que encolhe quando falta espaco e' o nome da peca (`.joia-peca`), porque
 * ele e' o unico campo que continua se lendo pela metade.
 */
.joia-regra {
  display: flex; align-items: center; gap: 5px; flex-wrap: nowrap;
  padding: 6px 8px; border: 1px solid #2c3a3f; border-radius: 5px; background: #0e1518;
}
/*
 * O campo e a etiqueta dele, numa coluna so'. A etiqueta e' de nove pixels e
 * fica ACIMA porque ao lado ela viraria mais uma palavra na frase — e palavra
 * na frase foi justamente o que tirou a linha do lugar.
 */
.joia-campo { display: grid; gap: 1px; justify-items: center; flex: none; }
.joia-campo em {
  font-style: normal; font-size: 9px; line-height: 1;
  color: #6f8189; letter-spacing: .04em; text-transform: uppercase;
}
.joia-ordem { font-size: 11px; color: #6f8189; min-width: 18px; }
.joia-arte { width: 30px; height: 30px; display: flex; align-items: center; justify-content: center; flex: none; }
.joia-tirar { color: #b4553f; font-size: 15px; }
/* As palavras que costuram a frase: "enquanto a ... estiver entre ... e ... %" */
.joia-liga { font-size: 11px; color: #8fa0a8; flex: none; white-space: nowrap; }

/*
 * Os campos com a mesma pintura das linhas de condicao da barra de acoes (ver
 * `.condition select, .condition input`). Sem isto o navegador desenha o campo
 * BRANCO, que foi o que o dono viu — uma caixa de formulario de site no meio de
 * uma tela de pedra.
 */
.joia-regra select, .joia-regra input {
  background: #080b0c; border: 1px solid var(--line); border-radius: 5px;
  padding: 4px 5px; font-size: 12px; color: var(--text);
}
.joia-regra select:focus, .joia-regra input:focus { outline: none; border-color: var(--accent-dim); }
.joia-peca { flex: 1 1 130px; min-width: 90px; }
.joia-num { width: 46px; text-align: center; flex: none; padding: 4px 2px; }
/* A seta de girar do campo numerico rouba largura e nao acrescenta nada: o
   numero se digita. */
.joia-num::-webkit-inner-spin-button, .joia-num::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
.joia-num { -moz-appearance: textfield; }
/* A medida escolhida se le' pela cor, como as reguas de vida e mana. */
.joia-medida { flex: none; font-weight: 600; padding-right: 2px; }
.joia-medida.vida { color: #e0938c; }
.joia-medida.mana { color: #8db4e8; }

.joia-botoes { display: flex; gap: 3px; margin-left: auto; flex: none; }
.joia-botoes button { padding: 3px 7px; font-size: 11px; }
.joia-botoes button:disabled { opacity: .35; cursor: default; }
.joia-botoes .danger:hover { border-color: var(--danger); color: #ffd9d6; }
.joia-rodape { display: flex; justify-content: space-between; gap: 8px; }

/* ---------- Os relogios das magias ligadas ----------
 *
 * Uma fileira de cards FLUTUANDO logo acima da barra de acoes: a sprite da
 * magia ocupa o card e o tempo mora dentro, no pe dela.
 *
 * `position: fixed` e nao um filho do rodape: la dentro ele ficava preso ao
 * recorte da barra (`overflow-x: auto`), e dentro do card da ficha ele sumia
 * junto com o card quando a ficha se encaixava embaixo. O `bottom` e escrito
 * pelo JS, medido na propria barra — ver `renderBuffsDaMagia`.
 *
 * Vazia ela some inteira (o `hidden` vem do JS).
 */
.hud-buffs {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: 96px; /* so' ate' o JS medir a barra de verdade */
  z-index: 26;
  display: flex; flex-wrap: wrap-reverse; gap: 4px; justify-content: center;
  max-width: 96vw; pointer-events: none;
}
.hud-buffs[hidden] { display: none; }
.hud-buff {
  position: relative; pointer-events: auto;
  display: flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; padding: 1px;
  border: 1px solid #3a4a4f; border-radius: 4px;
  background: #0b1113ee; line-height: 1;
  box-shadow: 0 1px 3px #000a;
}
/*
 * O tempo por CIMA da figura, encostado no pe do card.
 *
 * O contorno preto de quatro lados e o que o deixa legivel em cima de qualquer
 * sprite — as de fogo sao claras, as de morte sao escuras, e uma sombra so nao
 * cobre as duas.
 */
.hud-buff b {
  position: absolute; left: 0; right: 0; bottom: 0;
  text-align: center; font-size: 9px; line-height: 9px;
  color: #f2e9d2; font-variant-numeric: tabular-nums;
  text-shadow: 0 1px 0 #000, 0 -1px 0 #000, 1px 0 0 #000, -1px 0 0 #000;
}
/* Os ultimos cinco segundos: e' quando renovar ainda vale a pena. */
.hud-buff.acabando { border-color: #b4553f; }
.hud-buff.acabando b { color: #ffb4a2; }
/*
 * ---- O card de ESPERA ----
 *
 * "tem que ficar um cronometro la embaixo apos uma transcedencia mostrando o
 * tempo restante pra proxima chance."
 *
 * Ele mora na mesma fileira dos efeitos ligados, e por isso precisa dizer, de
 * relance, que NAO e' um: figura sem cor e card apagado. Um card igual aos
 * outros diria o contrario do que ele e — que a transcendencia esta valendo.
 */
.hud-buff.espera { border-color: #2c363a; background: #0b1113cc; }
.hud-buff.espera .spell-icon { filter: grayscale(1); opacity: 0.45; }
.hud-buff.espera b { color: #9fb0b6; }


/* ---------- a ficha do familiar, na caixa de configurar ação ---------- */

/* Ela mora na mesma coluna estreita das condições da magia, então tudo aqui é
   de largura cheia e empilhado — nada de duas colunas num espaço de 260px. */
.familiar-nivel {
  display: flex; align-items: baseline; gap: 6px; margin-top: 2px;
}
.familiar-nivel b {
  font-family: var(--font-heading); font-size: 18px; line-height: 1; color: #ffe4a0;
}
.familiar-nivel span { font-size: 11px; color: var(--muted); }

/* O trilho é o mesmo desenho do `.upgrade-track` da loja, mas contínuo: ali são
   cinco compras contáveis, aqui são cem níveis — cem tracinhos não se leem. */
.familiar-trilho {
  height: 6px; margin: 4px 0 6px; overflow: hidden;
  background: #14100a; border: 1px solid var(--accent-dim); border-radius: 3px;
}
.familiar-trilho i {
  display: block; height: 100%;
  background: linear-gradient(90deg, var(--accent-dim), var(--accent));
}

/* O botão que leva à loja: discreto, porque ele não é a ação principal desta
   caixa — o que se veio fazer aqui é configurar a magia. */
.familiar-loja {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  width: 100%; margin: 2px 0 8px; padding: 6px 10px; cursor: pointer;
  font-size: 11px; color: #ffe4a0;
  background: linear-gradient(180deg, #2a2210, var(--panel-solid));
  border: 1px solid var(--gold-dim); border-radius: 7px;
}
.familiar-loja:hover { filter: brightness(1.15); }
.familiar-loja img, .familiar-loja canvas { width: 14px; height: 14px; }

/* O boneco do familiar ao lado do nível, e a grade das nove skins. */
.familiar-cabeca { display: flex; align-items: center; gap: 10px; margin: 4px 0 2px; }
.familiar-cabeca > div { flex: 1; min-width: 0; }
.familiar-cabeca b {
  display: block; font-family: var(--font-heading); font-size: 12px; color: #ffe4a0;
}
.familiar-cabeca canvas { flex: none; image-rendering: pixelated; }

/* Três por linha: com 40px de boneco mais o nome embaixo, quatro apertariam o
   nome a ponto de cortar "Elemental de Sangue" no meio. */
.familiar-skins {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 5px; margin: 6px 0 8px;
}
.familiar-skin {
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  padding: 5px 3px; text-align: center;
  background: var(--panel-solid); border: 1px solid var(--line); border-radius: 6px;
  /* O que ele não tem fica apagado, e não escondido: metade da razão de olhar a
     grade é ver o que falta. */
  opacity: .42; filter: grayscale(.7);
}
.familiar-skin.tem { opacity: 1; filter: none; }
.familiar-skin.vestida { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent-dim) inset; }
.familiar-skin canvas { image-rendering: pixelated; }
.familiar-skin b { font-size: 9px; line-height: 1.15; color: var(--text); }
.familiar-skin em { font-size: 9px; font-style: normal; color: var(--copper); }
.familiar-skin-tag {
  font-size: 8px; letter-spacing: .06em; text-transform: uppercase; color: var(--muted);
}
.familiar-skin.vestida .familiar-skin-tag { color: var(--accent); }

/* A ficha do familiar é o primeiro bloco da coluna quando a magia é a de
   summon; a linha embaixo a separa do resumo da magia, que vem depois. */
.familiar-ficha { padding-bottom: 6px; border-bottom: 1px solid var(--line); margin-bottom: 8px; }
.familiar-ficha h3:first-child { margin-top: 0; }

/*
 * ---- O alvo do charm, escolhido DENTRO da janela ----
 *
 * Era um `<select>`, e a lista aberta dele é uma janela do sistema: com a caçada
 * rodando atrás ela fechava antes de o dedo chegar no nome (report de um jogador,
 * diagnóstico do dono). Aqui é DOM comum — nada o fecha além do clique.
 */
.charm-alvo { position: relative; display: grid; gap: 3px; min-width: 0; }
.charm-alvo-botao {
  display: flex; align-items: center; gap: 6px; width: 100%;
  padding: 3px 6px; text-align: left; min-width: 0;
}
.charm-alvo-botao span { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.charm-alvo-botao i { font-style: normal; opacity: 0.6; }
.charm-alvo-botao.tem { border-color: var(--accent, #6fc); }
.charm-alvo-botao canvas, .charm-alvo-item canvas { flex: none; }
.charm-alvo-vazio { font-size: 10px; color: var(--muted); padding: 2px 4px; }
/* A lista fica no fluxo, e não flutuando: dentro de um card estreito um painel
   absoluto sairia por baixo do card vizinho. */
.charm-alvo-lista {
  display: grid; gap: 4px; padding: 5px;
  border: 1px solid var(--line); border-radius: 6px;
  background: #0f1218cc;
}
.charm-alvo-lista input { width: 100%; box-sizing: border-box; }
.charm-alvo-itens { display: grid; gap: 2px; max-height: 190px; overflow-y: auto; }
.charm-alvo-item {
  display: flex; align-items: center; gap: 6px;
  padding: 2px 5px; text-align: left; background: none; border: 1px solid transparent;
}
.charm-alvo-item:hover { background: #ffffff14; }
.charm-alvo-item.escolhido { border-color: var(--accent, #6fc); }
.charm-alvo-item span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/*
 * ---- O ouro da troca: moeda, passo e separador ----
 *
 * O dono: "não mostra automaticamente com as vírgulas, e tem que ter o ícone do
 * gold". O campo era um `input[type=number]` cru — sem moeda, sem separador, e
 * com as setinhas do navegador, que num número de oito dígitos não servem para
 * nada.
 */
.troca-ouro-caixa { display: flex; flex-direction: column; gap: 3px; align-items: flex-end; }
.troca-ouro-controle { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; justify-content: flex-end; }
/*
 * `.troca-ouro input` la em cima e mais especifico que uma classe sozinha, entao
 * este seletor repete o elemento — senao o campo velho continuaria mandando.
 */
.troca-ouro input.troca-ouro-campo {
  width: 108px; text-align: right; font-variant-numeric: tabular-nums;
  background: #10161a; color: var(--text); border: 1px solid var(--line);
  border-radius: 4px; padding: 3px 6px; font-size: 12px;
}
.troca-ouro input.troca-ouro-campo:focus { border-color: var(--accent-dim); outline: none; }
.troca-ouro-passo {
  min-width: 24px; padding: 2px 6px; font-size: 14px; line-height: 1;
}
.troca-ouro-acao { padding: 2px 8px; font-size: 11px; }
.troca-ouro-passo:disabled, .troca-ouro-acao:disabled { opacity: .4; cursor: not-allowed; }
.troca-ouro-resto { color: var(--muted); font-size: 11px; font-style: normal; }
.troca-ouro canvas { image-rendering: pixelated; vertical-align: middle; }

/* ---------- a bancada de AFIXOS da forja ---------- */
/*
 * Ela empresta a bancada, a moldura, a tira de escolha e a faixa de requisitos
 * da forja de tier — é a MESMA mesa, com outro material em cima, e inventar um
 * segundo desenho para o mesmo gesto seria ensinar duas coisas onde há uma.
 *
 * O que é novo aqui é o que não existe lá: a régua de porcentagem, a escolha da
 * moeda e a silhueta da essência.
 */
.forja-bancada.dupla { grid-template-columns: 1fr auto 1fr; }
.forja-seta { color: var(--line-strong, var(--line)); font-size: 18px; text-align: center; }

/*
 * ---- As estrelas da bancada são as MESMAS da mochila ----
 *
 * Elas passaram um tempo dentro do selo redondo do tier — a pastilha laranja
 * de .forja-selo —, e o dono cortou: "as estrelas não precisam estar
 * circuladas, deixa elas como elas são, senão mal dá pra ver".
 *
 * Ele está certo, e o erro era mais fundo que o desenho: dentro da pastilha as
 * três estrelas ficavam da mesma cor (a do fundo), e a COR é o que elas
 * contam — azul, roxa, dourada e vermelha dizem quão bom é cada afixo.
 * Circuladas, três afixos diferentes viravam três pontinhos iguais.
 *
 * Agora usam .selo-afixo, que é a classe da mochila: sem fundo, com sombra
 * preta para não sumirem sobre uma peça clara, e cada uma na cor dela. Uma
 * peça é a mesma peça nas duas telas — não havia razão para dois desenhos.
 *
 * .forja-selo continua existindo: ele é o selo do TIER, um número dentro de
 * uma pastilha, e ali a pastilha é o desenho certo.
 */

/* ---- a lista de afixos ---- */
.afixo-lista { display: grid; gap: 5px; margin-bottom: 12px; }
.afixo-lista.previa { opacity: .92; border-left: 2px solid #b8893f66; padding-left: 8px; }

/*
 * Cada linha é uma grade de quatro colunas fixas: nome, valor, régua e
 * porcentagem. Fixas para as réguas ficarem ALINHADAS de uma linha para a
 * outra — é a comparação entre elas que se está fazendo aqui, e réguas que
 * começam em pontos diferentes não se comparam de relance.
 */
.afixo-linha {
  display: grid; grid-template-columns: 1fr 90px 44px; align-items: center; gap: 10px;
  width: 100%; padding: 7px 10px; text-align: left;
  background: var(--panel-2); border: 1px solid var(--line-soft); border-radius: 7px;
  color: var(--text); font-size: 12px;
  /*
   * A borda ESQUERDA é a cor do degrau daquele afixo — o mesmo azul/roxo/dourado
   * das estrelas, e o vermelho da vermelha. É o que faz a lista ser lida de
   * relance: quem procura o afixo bom procura a faixa dourada, não o número.
   */
  border-left: 3px solid var(--estrela, var(--line-soft));
}
.afixo-linha.q1 { --estrela: #57a6e8; }
.afixo-linha.q2 { --estrela: #b184e8; }
.afixo-linha.q3 { --estrela: #e0a84a; }
.afixo-linha.q4 { --estrela: #ff5a52; }
button.afixo-linha { cursor: pointer; }
button.afixo-linha:hover { border-color: var(--accent-dim, var(--accent)); border-left-color: var(--estrela); }
.afixo-linha.on { border-color: #b8893f; background: #1a150c; border-left-color: var(--estrela); }
/* O bônus é a manchete: "+2,2% Resistência física", e não os 24% da régua. */
.afixo-linha > b { font-weight: 600; color: var(--text); }
.afixo-linha .afixo-valor { color: #f0c95f; font-weight: 600; }
.afixo-linha .afixo-pct { font-style: normal; font-size: 11px; color: var(--muted); text-align: right; }
/*
 * Quantas vezes o posto já foi rerrolado. Ela só aparece quando já houve algum,
 * e existe para explicar o preço: um rerroll que custa 172kk sem dizer por quê
 * parece defeito.
 */
.afixo-rr { grid-column: 1 / -1; font-style: normal; font-size: 10px; color: #b8893f; }
.afixo-ordem {
  font-style: normal; font-size: 10px; color: var(--muted); margin-right: 6px;
}

/* A régua: a porcentagem desenhada, para não ter de ler quarenta números. */
.afixo-regua {
  height: 5px; border-radius: 999px; background: #0b0f10; border: 1px solid var(--line-soft); overflow: hidden;
}
.afixo-regua i { display: block; height: 100%; background: linear-gradient(90deg, #6a8f3f, var(--estrela, #b8893f)); }

/* O afixo que não é daquela peça — a mesma marca do balão do item. */
.afixo-linha.torto { opacity: .78; }
.afixo-linha.torto b { color: #9aa3a6; }
.afixo-torto { grid-column: 1 / -1; font-style: normal; font-size: 10px; color: #c98b6a; }

/* ---- a escolha da moeda ---- */
.afixo-moedas { display: flex; gap: 8px; margin-bottom: 10px; }
.afixo-moeda {
  flex: 1; display: flex; align-items: center; gap: 8px; padding: 8px 10px; cursor: pointer;
  background: var(--panel-2); border: 1px solid var(--line-soft); border-radius: 7px; color: var(--muted);
}
.afixo-moeda.on { border-color: #b8893f; color: var(--text); background: #1a150c; }
.afixo-moeda-text, .afixo-moeda-texto { display: grid; gap: 1px; text-align: left; min-width: 0; }
.afixo-moeda b { font-size: 13px; color: #f0c95f; }
.afixo-moeda em { font-style: normal; font-size: 10px; }
.afixo-moeda img, .afixo-moeda canvas { flex: none; }
/*
 * A moeda sem saldo fica APAGADA e continua clicável de propósito: ela mostra
 * quanto falta. Escondê-la esconderia a existência do caminho, e quem não sabe
 * que dava para pagar em coin não vai atrás de coin.
 */
.afixo-moeda.falta { opacity: .55; }
.afixo-moeda.falta b { color: #c98b6a; }
.afixo-moeda.falta em { color: #c98b6a; }

/*
 * ---- A essência: a silhueta do slot, NA COR da peça de origem ----
 *
 * "a essência do afixo tem que ficar com a cor da raridade do item que foi
 * retirado."
 *
 * A cor não é decoração: a qualidade é METADE da regra de onde a essência pode
 * entrar (a outra metade é o slot, que a silhueta já conta). Ela era a metade
 * invisível — todas saíam cinza —, e com a cor a mochila de essências se lê de
 * relance, do mesmo jeito que a ficha se lê pela borda das peças.
 *
 * A tinta vem da variável `--tier`, que as classes `tier-*` definem: é a MESMA
 * paleta do resto do jogo, e não uma segunda inventada aqui.
 *
 * O `drop-shadow` é o que pinta o PNG, que é cinza e não tem cor própria; o
 * `brightness` primeiro clareia a silhueta para a sombra ter o que contornar.
 */
.afixo-essencia-arte { display: grid; place-items: center; opacity: .8; }
.afixo-essencia-arte img { image-rendering: pixelated; }
/*
 * ---- A MESMA luz da célula, onde não há célula ----
 *
 * "era pra ser igual dos itens normais: a essência do amuleto mítico tem que
 * ter o mesmo fundo de um amuleto mítico."
 *
 * Na mochila quem dá esse fundo é `.cell.raridade::before` — um sopro de luz
 * para FORA da caixa, sem preenchimento nenhum. Na bancada da forja e na linha
 * do mercado não há célula, e a primeira tentativa aqui inventou outra coisa:
 * um disco de cor por baixo da silhueta. Era um segundo desenho para a mesma
 * ideia, e o dono o recusou pelo nome certo — "fundo extra".
 *
 * Então esta regra é uma CÓPIA daquela, com o mesmo `box-shadow` e o mesmo
 * degrau (do épico para cima a luz ganha miolo). O que muda é só a moldura em
 * que ela mora. Uma essência mítica acende igual a um amuleto mítico, em
 * qualquer das quatro telas.
 */
.afixo-essencia-arte[class*='tier-'] { position: relative; }
.afixo-essencia-arte[class*='tier-']:not(.tier-comum)::before {
  content: ""; position: absolute; inset: -1px; border-radius: 5px;
  box-shadow: 0 0 7px -1px var(--tier); pointer-events: none;
}
.afixo-essencia-arte.tier-epico::before,
.afixo-essencia-arte.tier-lendario::before,
.afixo-essencia-arte.tier-mitico::before {
  box-shadow: 0 0 11px -1px var(--tier), 0 0 3px -1px var(--tier);
}
/* O comum não acende: ele é a maioria, e acender tudo não distingue nada. */

/*
 * ---- A ESSÊNCIA VERMELHA: o vermelho do mítico, e um efeito a mais ----
 *
 * "quando a essência for a que tem estrela vermelha, o fundo do item tem que
 *  ser vermelho igual de mítico, só que tem que ter um efeito a mais."
 *
 * O vermelho é o mesmo — ela recebe a classe tier-mitico venha de onde vier,
 * inclusive de peças comuns. O QUE MUDA é a batida: a luz do mítico é fixa, e
 * a dela pulsa.
 *
 * ---- Por que pulso, e não uma cor nova ----
 *
 * Uma sétima cor seria uma sétima coisa para aprender, e ela não é uma sétima
 * qualidade: ela é uma essência da qualidade que for, com um afixo que passou
 * do topo da régua. O movimento diz isso sem inventar vocabulário — o olho
 * acha o que se mexe numa grade parada, e é a única peça da mochila que se
 * mexe. É o mesmo recurso do selo de tier, que já pisca por ali.
 *
 * Duas camadas: o pulso do halo (::before, que é a luz da raridade que toda
 * peça tem) e um segundo anel por dentro (::after), que dá miolo ao brilho em
 * vez de o deixar virar uma nuvem vermelha.
 */
/*
 * ---- O efeito mora num pseudo-elemento PRÓPRIO ----
 *
 * A primeira tentativa animava o `::before`, que é onde a luz da raridade de
 * toda peça vive. Era o caminho errado, e por uma razão que só aparece em duas
 * das quatro telas: Opções → Ajustes da tela troca o estilo da raridade, e o
 * "quina" e o "nenhum" mandam justamente naquele `::before` (um o pinta de
 * degradê, o outro o esconde). Propriedade animada ganha do cascata inteira —
 * o pulso teria reacendido a luz que essas duas escolhas apagam de propósito.
 *
 * No `::after`, que é só dela, o efeito soma em vez de disputar: seja qual for
 * a marca de raridade escolhida, a vermelha ganha a batida por cima.
 */
.cell.essencia-vermelha::after {
  content: ""; position: absolute; inset: -1px; border-radius: 5px;
  border: 1px solid #ff5a5288; pointer-events: none; z-index: 2;
  animation: essencia-vermelha 1.9s ease-in-out infinite;
}
@keyframes essencia-vermelha {
  0%, 100% { border-color: #ff5a5240; box-shadow: 0 0 5px -1px #ff5a5288; }
  50% { border-color: #ffb0aadd; box-shadow: 0 0 13px 0 #ff5a52, 0 0 4px 0 #ff8078; }
}
/*
 * E quem escolheu "nenhum" não vê marca nenhuma, nem esta: a escolha é "não
 * quero marca na mochila", e abrir uma exceção para a peça mais chamativa do
 * jogo seria justamente desrespeitar o que ela pediu.
 */
[data-raridade="nenhum"] .cell.essencia-vermelha::after { display: none; }

/*
 * A MESMA batida fora da mochila: na bancada da forja, na linha do mercado e
 * no balão. Ela pulsa a MESMA luz que as outras qualidades acendem parada —
 * não uma segunda marca por cima, que foi o "fundo extra" que o dono cortou.
 */
.afixo-essencia-arte.mitica::before,
.tip-essencia-arte.vermelha::before {
  content: ""; position: absolute; inset: -1px; border-radius: 5px; pointer-events: none;
  animation: essencia-vermelha-halo 1.9s ease-in-out infinite;
}
.afixo-essencia-arte.mitica { position: relative; }
@keyframes essencia-vermelha-halo {
  0%, 100% { box-shadow: 0 0 7px -1px #ff5a52, 0 0 2px -1px #ff5a52; }
  50% { box-shadow: 0 0 15px 0 #ff5a52, 0 0 5px 0 #ffb0aa; }
}

/*
 * Quem pediu para o sistema parar de animar não perde o sinal: a luz fica
 * ACESA no ponto alto do pulso, em vez de sumir junto com a animação. É a
 * mesma saída do selo de tier.
 */
@media (prefers-reduced-motion: reduce) {
  .cell.essencia-vermelha::after {
    animation: none;
    border-color: #ffb0aa99; box-shadow: 0 0 11px 0 #ff5a52, 0 0 4px 0 #ff8078;
  }
  .afixo-essencia-arte.mitica::before,
  .tip-essencia-arte.vermelha::before {
    animation: none; box-shadow: 0 0 13px 0 #ff5a52, 0 0 4px 0 #ffb0aa;
  }
}

/*
 * ---- As casas da bancada de inserir ----
 *
 * "quando eu for aplicar 3 essências tem que mostrar lado a lado as essências
 * ali, e não '3 essências' e mostrando apenas 1."
 *
 * Três casas fixas, e não uma por essência escolhida: as vazias são o que diz
 * que ainda cabe mais. São as mesmas três da fusão, e é de propósito — o mesmo
 * desenho para a mesma ideia ("até três, e o que já está posto").
 */
.afixo-casas { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.forja-quadro.casa { min-height: 104px; padding: 8px 6px; }
.forja-quadro.casa b { font-size: 11px; line-height: 1.25; }
.forja-quadro.casa .forja-onde { font-size: 9px; }
.forja-quadro.casa .forja-rotulo { font-size: 9px; }

/* O aviso do que não dá para desfazer. Ele é vermelho porque a perda é real. */
.forja-aviso {
  margin: 8px 0 0; padding: 8px 10px; font-size: 11px; line-height: 1.45;
  background: #1a0f0e; border: 1px solid #a3333355; border-radius: 7px; color: #ffb3a7;
}
.forja-bolsa .forja-bolsa-coin { color: #7fd4e0; }

/*
 * ---- A BOLSA da página de afixos ----
 *
 * "onde está ouro tem que ter o ícone do ouro, e onde está Mineiroidle Coins tem que
 * ter o Mineiroidle Coins."
 *
 * Duas caixas lado a lado, no topo, cada uma com o ícone de sempre. Ela subiu do
 * rodapé porque nesta tela o saldo é a primeira pergunta, e não a última.
 */
.afixo-bolsa {
  display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin: 0 0 12px;
}
.afixo-bolsa-item {
  display: flex; align-items: center; gap: 8px; padding: 8px 10px;
  background: var(--panel-2); border: 1px solid var(--line-soft); border-radius: 7px;
}
.afixo-bolsa-item b { font-size: 14px; }
.afixo-bolsa-item em { font-style: normal; font-size: 10px; color: var(--muted); margin-left: auto; }
.afixo-bolsa-item.ouro b { color: #f0c95f; }
.afixo-bolsa-item.coin b { color: #7fd4e0; }
.afixo-bolsa-item img, .afixo-bolsa-item canvas { flex: none; }

/*
 * ---- O botão de SENTIDO da bancada de essências ----
 *
 * As abas "Retirar" e "Inserir" viraram uma só, a pedido do dono, e o que as
 * separa agora é este par. As setas nos rótulos ("Tirar da peça →", "← Pôr na
 * peça") dizem para onde o afixo vai — é a única diferença entre os dois lados,
 * e é a que precisa ficar óbvia sem ler.
 */
.afixo-sentido {
  display: grid; grid-template-columns: 1fr 1fr; gap: 6px; margin-bottom: 12px;
  padding: 4px; background: var(--panel-2); border: 1px solid var(--line-soft); border-radius: 8px;
}
.afixo-sentido-botao {
  padding: 7px 10px; cursor: pointer; font-size: 12px; border-radius: 6px;
  background: transparent; border: 1px solid transparent; color: var(--muted);
}
.afixo-sentido-botao:hover { color: var(--text); }
.afixo-sentido-botao.on { background: #1a150c; border-color: #b8893f; color: var(--text); }

/*
 * ---- As três casas da fusão ----
 *
 * "teria 3 slots vazios." Três buracos iguais, lado a lado, e é o desenho que
 * conta a regra: três, do mesmo tipo. Nenhum texto faz isso tão rápido.
 */
.afixo-fusao { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-bottom: 12px; }
.forja-quadro.fusao { min-height: 118px; }
.forja-quadro.fusao.cheio { border-color: #b8893f; }
/* A vermelha, onde quer que ela apareça: casa, opção da lista ou moldura. */
.forja-quadro.vermelha, .forja-opcao.vermelha { border-color: #ff5a5266; box-shadow: inset 0 0 0 1px #ff5a5222; }
/*
 * A vermelha não tinge o desenho: ela acende, como as outras. O que a separa
 * é a BATIDA — ver `essencia-vermelha-halo`, lá em cima.
 */
.afixo-essencia-arte.mitica { opacity: 1; }
.afixo-lista.previa.vermelha { border-left-color: #ff5a5288; }
.afixo-vermelha { color: #ff8078; }

/* A opção já escolhida na tira — a mesma marca das linhas de afixo. */
.forja-opcao.on { border-color: #b8893f; background: #1a150c; }

/* O título de "como a peça fica": é uma prévia, e não um fato. */
.afixo-previa-titulo::after {
  content: ' (prévia)'; font-size: 10px; font-weight: 400; color: var(--muted);
}

/*
 * O preço no rodapé leva o ícone da moeda ESCOLHIDA, e não os dois: a essa
 * altura a escolha já foi feita logo acima, e repetir as duas moedas aqui faria
 * parecer que ainda há uma decisão pendente.
 */
.forja-chip.preco { border-color: #b8893f66; }
.forja-chip.preco img, .forja-chip.preco canvas { flex: none; }
.forja-chip.preco.falta { border-color: #a3333366; }
.forja-chip.preco.falta b { color: #ffb3a7; }

/* ================================================================
 * AS CHAVES DE GRÁFICOS
 *
 * "o modo lite não era pro jogo ficar sem fps, era pra tirar os efeitos das
 *  magias, efeitos dos ícones e etc, sabe, pra ficar liso pra quem tem pc ruim"
 *
 * Os "efeitos dos ícones" são estes: dezenas de animações em `@keyframes` e
 * centenas de sombras espalhadas por esta folha. Elas ficam aqui, no fim de
 * tudo, e não perto de cada regra que apagam — assim uma tela NOVA nasce
 * obedecendo às chaves sem que ninguém precise se lembrar delas.
 *
 * O `!important` é necessário e não é preguiça: a regra apagada quase sempre
 * mora num seletor mais específico que `body.sem-brilho *`, e sem ele a
 * chave simplesmente não faria nada. Ver `client/src/graficos.mjs`.
 * ================================================================ */

/*
 * ---- Animações da interface ----
 *
 * `animation` e `transition` juntas: uma transição é uma animação disparada
 * pelo hover, e quem apaga o ícone que pulsa não quer o painel que desliza.
 *
 * `animation: none` para uma animação de `opacity: 0` até `1` deixaria o
 * elemento parado no estilo BASE dele — que é o do quadro zero, invisível. Por
 * isso a segunda regra: quem entra na tela por animação entra visível e
 * inteiro, na hora.
 */
body.sem-animacao *,
body.sem-animacao *::before,
body.sem-animacao *::after {
  animation: none !important;
  transition: none !important;
}
body.sem-animacao [class*='entra'],
body.sem-animacao [class*='abre'],
body.sem-animacao [class*='pulso'],
body.sem-animacao [class*='pulsa'] {
  opacity: 1 !important;
  transform: none !important;
}

/*
 * ---- Brilhos e halos ----
 *
 * `backdrop-filter` primeiro, porque é o caro de verdade: desfocar o que está
 * ATRÁS de uma janela obriga a placa a reler a tela inteira por baixo dela, a
 * cada quadro, enquanto a janela estiver aberta.
 *
 * `box-shadow` e `text-shadow` saem juntos. O que NÃO sai é o `filter`: ele
 * carrega o `grayscale` do que está indisponível e o `brightness` do que está
 * aceso — apagá-lo faria botão desligado parecer ligado, e isso é perder
 * informação, não perder enfeite.
 */
body.sem-brilho * {
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  box-shadow: none !important;
  text-shadow: none !important;
}
/*
 * ---- E o traço de um pixel SAIU, porque ele apagava a janela ----
 *
 * Aqui havia `border: 1px solid #1d2a30 !important` para modal, janela e balão.
 * A ideia era boa — sem a sombra, duas caixas escuras encostadas não se
 * separam — e a execução apagava a tela: o atalho `border` RESETA o
 * `border-image`, e é o `border-image` que desenha a moldura E O FUNDO da
 * janela e do modal (os dois têm `background: none` e `border-image-slice ...
 * fill`, ver `.window` e `.modal-box`).
 *
 * O resultado era uma gaveta de vidro: a moldura sumia, o fundo sumia junto, e
 * os itens da mochila ficavam soltos por cima do mapa. Quem apertasse "Deixar
 * leve" no computador já via isso; no dia em que o telefone passou a nascer
 * leve, passou a ser o normal do celular.
 *
 * Não entra nada no lugar porque não falta nada: a moldura desenhada É o
 * limite dessas duas caixas, e ela nunca foi brilho. O balão (`.tooltip`) tem
 * fundo próprio e borda própria na cor da raridade — o `!important` também a
 * apagava, e ela volta sozinha.
 *
 * O que o `sem-brilho` continua tirando é o que ele existe para tirar, na
 * regra logo acima: `backdrop-filter`, `box-shadow` e `text-shadow`.
 */

/* ================================================================
 * O CONTADOR DE FPS E PING, no canto superior esquerdo
 *
 * "faz uma opção pra ativar de mostrar o fps e ping no cantinho superior
 *  esquerdo ao ser ativado"
 *
 * Ele nasce só quando alguém acende uma das duas fichas (ver `medidor.mjs`), e
 * por isso não existe estado "escondido" aqui: se o elemento está no documento,
 * é para aparecer.
 * ================================================================ */
#medidor {
  position: fixed;
  /*
   * ---- Onde ele fica, e por que o card sai da frente ----
   *
   * "no cantinho superior esquerdo" — que é exatamente onde mora o card do
   * personagem. A primeira versão ficava POR CIMA dele: o contador começava
   * 18px dentro do card, em cima da moldura e colado no nome.
   *
   * Então ele toma o lugar do card, e o card desce a altura dele. É a mesma
   * ideia da barra de aviso lá em cima — quem chega empurra, em vez de tapar.
   * Ver `com-medidor`, logo abaixo, e `--topo-do-hud`.
   *
   * Com a ficha mandada para a barra de baixo, não há card nenhum aqui e o
   * contador fica sozinho sobre o mapa, sem nenhuma conta a mais.
   */
  top: var(--topo-do-hud);
  left: 12px;
  z-index: 26; /* acima do #hud (24): é uma régua, e régua tapada não serve */
  display: flex; gap: 8px; align-items: center;
  padding: 2px 7px; border-radius: 5px;
  background: #04070899;
  border: 1px solid #ffffff14;
  font-family: Consolas, "Courier New", monospace;
  font-size: 10px; line-height: 1.5;
  /*
   * ---- Por que ele não recebe clique ----
   *
   * Ele flutua por cima do canto do card do personagem, e o card tem botões ali
   * (a ficha, o minimizar). Um retângulo transparente por cima deles engoliria
   * o clique e o jogador não faria ideia do porquê — o contador é uma régua, e
   * régua não é para clicar.
   */
  pointer-events: none;
  /* O jogo inteiro fica atrás; ele não pode competir com o mapa. */
  opacity: .85;
}
/*
 * O card desce a altura do contador. `body.com-medidor #hud` ganha do `#hud`
 * por especificidade, então vale mesmo com o `top` do card escrito depois.
 */
body.com-medidor #hud { top: calc(var(--topo-do-hud) + var(--altura-do-medidor)); }

.medidor-valor { font-weight: 700; letter-spacing: .02em; color: #9fb2b8; }
.medidor-valor.bom { color: #7fc7a4; }
.medidor-valor.medio { color: #d8bd72; }
.medidor-valor.ruim { color: #d98070; }

/*
 * ================= O JOGO NUM CELULAR =================
 *
 * Tudo aqui dentro vale SÓ até 820px de largura. Nenhum monitor de mesa chega
 * perto disso — o menor que se usa hoje tem 1280 —, então o layout de mesa não
 * é tocado por uma linha sequer. Quem quiser ver de perto é só estreitar a
 * janela do navegador.
 *
 * ---- O que a medição apontou ----
 *
 * `tools/analise-mobile.mjs` abre o jogo num telefone de verdade (360, 390 e
 * 414 px, com toque emulado) e mede. Num iPhone de 390:
 *
 *   - as JANELAS abriam nas coordenadas de mesa: mochila em cima do
 *     personagem, bolsa de loot e chat empilhados um sobre o outro, cada um
 *     mais largo do que a tela;
 *   - 91 ALVOS DE TOQUE abaixo de 44px, o mínimo que Apple e Google publicam
 *     para um dedo — o × e o — das janelas mediam ONZE pixels;
 *   - TEXTO de 9px, que a essa largura ninguém lê;
 *   - o cartaz do beta cobria um quarto da tela.
 *
 * ---- O que muda, e por quê ----
 *
 * As janelas param de flutuar e viram UMA GAVETA no rodapé, todas no mesmo
 * retângulo. Empilhadas assim, aparece a de cima — que é a que a pessoa
 * acabou de abrir —, e as pílulas da barra trocam entre elas. É o padrão de
 * todo aplicativo de telefone, e resolve de uma vez o amontoado.
 *
 * O `--barra-altura` é medido pelo `actionbar.mjs` a cada mudança da barra de
 * ações. A gaveta se apoia nele em vez de num número escrito à mão: quando a
 * barra recolhe ou ganha uma fileira, a gaveta acompanha.
 */
/*
 * ---- E o telefone DEITADO ----
 *
 * A regra era só `max-width: 820px`, e um iPhone na horizontal tem 844 de
 * largura: ele passava do corte e não recebia NADA — nem a gaveta, nem os
 * botões de dedo, nem o analógico. O jogo virava a versão de mesa espremida
 * numa tela de 390px de altura.
 *
 * A segunda condição pega esse caso pela ALTURA, que é o que sobra pouco na
 * horizontal. E ela exige `pointer: coarse` — dedo — de propósito: sem isso,
 * quem no computador deixasse a janela baixa (uma segunda janela dividindo a
 * tela, o console do navegador aberto) receberia o layout de celular com o
 * mouse na mão.
 *
 * ---- E o JS pergunta ao CSS, em vez de repetir o número ----
 *
 * `--e-celular` é lido pelo `mobile.mjs` para decidir se monta o analógico.
 * Antes ele tinha a própria cópia do `(max-width: 820px)` num `matchMedia`, e
 * duas cópias da mesma regra em arquivos diferentes é a definição de uma
 * divergir calada — foi exatamente o que aconteceu com a horizontal: o CSS
 * mudaria aqui e o analógico continuaria com o corte velho.
 */
:root { --e-celular: 0; }

@media (max-width: 820px), (max-height: 540px) and (pointer: coarse) {
  :root {
    --e-celular: 1;
    /*
     * A altura da gaveta vira MEDIDA, e não um número repetido.
     *
     * Quem flutua no rodapé (o aviso de presente, os ícones de buff) precisa
     * saber subir acima dela quando ela abre — e a conta de "acima da gaveta" é
     * esta altura mais a distância do chão. Escrita duas vezes, um dia uma
     * mudaria e a outra não, e o aviso voltaria a ficar por baixo.
     */
    --gaveta-altura: min(46dvh, 430px);
    --gaveta-chao: calc(var(--barra-altura, 110px) + 8px);
  }

  /* ---- 1. As janelas viram uma gaveta ---- */
  /* `:not(.solta)`: a janela que a pessoa arrastou sai da gaveta (ver o item 18). */
  .window:not(.solta) {
    left: var(--morta-lado) !important;
    right: var(--morta-direita) !important;
    width: auto !important;
    top: auto !important;
    bottom: var(--gaveta-chao) !important;
    height: var(--gaveta-altura) !important;
    max-height: 46dvh !important;
    /*
     * A moldura desenhada continua — ela é a cara do jogo, e o pedido foi
     * deixar liso sem mudar a aparência. Só afina: 22px de borda de cada lado
     * numa tela de 360 comem um oitavo da largura útil.
     */
    border-width: 32px 14px 16px 14px;
  }
  /* Arrastar e redimensionar não existem numa gaveta que ocupa a largura toda. */
  .window-reset { display: none; }
  /* Menos o ◐ do chat ("chat com moldura ou transparente"): ele não é de
     arranjo, é de estilo, e no telefone vale igual. Também em Opções → Chat. */
  .window-reset.chat-flutuar { display: revert; }
  /* Sem mouse não há hover, mas tocar no chat (foco) traz cabeçalho, abas e
     caixa de volta; até lá some tudo, como no PC. */

  /*
   * ---- E o que flutua no rodapé SOBE quando a gaveta abre ----
   *
   * O aviso de presente e os ícones de buff moram colados na barra de baixo, no
   * meio da tela — o mesmo retângulo que a gaveta ocupa, e com z-index maior.
   * Com a gaveta aberta eles apareciam POR CIMA dela, cortados pela borda: no
   * telefone via-se "10 RECOMPENSA PARA PEG" e um botão STOP flutuando em cima
   * da mochila.
   *
   * A classe `com-gaveta` é posta pelo `windows.mjs` quando alguma janela está
   * aberta. Sem gaveta nenhuma, nada disto vale e eles voltam ao lugar de
   * sempre — no caso dos buffs, o lugar que o próprio JS mede.
   */
  /*
   * `!important` nos dois: o `bottom` deles é escrito pelo JS em estilo INLINE
   * (o presente mede a barra de baixo, ver `pintarPresente`), e estilo inline
   * ganha de folha de estilo. Sem ele, a regra existe e não vale nada.
   */
  /*
   * DUAS fileiras, e não uma. O presente é uma placa larga e CENTRADA; o Stop
   * mora à direita e os ajustes à esquerda, na mesma altura. Com todos no mesmo
   * degrau a placa passava por baixo do Stop e saía cortada no meio da palavra.
   * O presente e os buffs sobem um degrau a mais e cada coisa fica inteira.
   */
  /*
   * ---- E só EM PÉ ----
   *
   * Deitado a janela não mora mais no rodapé: ela é uma coluna encostada na
   * borda (ver o item 15, no fim deste bloco), e o rodapé inteiro fica livre.
   * Subir o presente e os buffs meia tela para fugir de uma gaveta que não está
   * ali os jogaria para o meio do mapa — que é de onde o dono os tirou.
   */
  /*
   * `com-gaveta` (windows.mjs) acende com QUALQUER janela aberta, mas só quem
   * está na gaveta empurra o rodapé: a janela solta pelo dedo e o inventário
   * (um quadro no canto, em pé) deixam o chão livre — e subir os relógios das
   * magias meia tela por causa deles os jogava para o meio do mapa.
   */
  @media (orientation: portrait) {
  body.com-gaveta:has(.window:not([hidden]):not(.solta):not([data-window-id="inventory"])) #presente,
  body.com-gaveta:has(.window:not([hidden]):not(.solta):not([data-window-id="inventory"])) .hud-buffs {
    bottom: calc(var(--gaveta-chao) + var(--gaveta-altura) + 54px) !important;
  }
  /*
   * O "Stop" e os ajustes da caçada moram na mesma faixa, colados na barra —
   * um à direita, outro à esquerda. Eles sobem junto e formam uma fileira em
   * cima da gaveta, cada um no seu canto: são os dois controles que a pessoa
   * pode querer no meio de uma caçada com a mochila aberta, e enterrá-los sob
   * a gaveta seria obrigar a fechá-la para parar de caçar.
   */
  body.com-gaveta:has(.window:not([hidden]):not(.solta):not([data-window-id="inventory"])) #leave-hunt,
  body.com-gaveta:has(.window:not([hidden]):not(.solta):not([data-window-id="inventory"])) #ajustes-da-caca {
    bottom: calc(var(--gaveta-chao) + var(--gaveta-altura) + 8px) !important;
  }
  }

  /* ---- 2. O que se toca tem tamanho de dedo ---- */
  /*
   * 34px e não 44: a moldura da janela tem 32px de altura de cabeçalho, e um
   * botão maior do que ela estouraria o ornamento do canto. 34 é o maior que
   * cabe ali dentro, e é três vezes o que havia.
   */
  .window-close, .window-min {
    min-width: 34px; min-height: 34px;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 17px;
  }
  .toggle { min-width: 38px; min-height: 38px; }
  .bag-clear, .alerta, #aviso-dev-report, #faixa-novidades { min-height: 32px; }

  /* ---- 3. Um piso para o texto ---- */
  /*
   * Só onde a medição achou 9 e 10px. Um piso geral (`* { font-size }`)
   * empurraria a tabela de atributos e a fileira de slots para fora do lugar —
   * o alvo aqui é a legibilidade do que se LÊ, não de tudo que tem letra.
   */
  .rotulo, .bag-clear, .oferta-item, .chat-readonly, .gate-note, .campo-aviso { font-size: 11px; }
  .chat-log { font-size: 13px; }
  .chat-tabs button { font-size: 12px; padding: 5px 9px; }

  /* ---- 4. O cartaz do beta encolhe ---- */
  /*
   * Ele cobria do topo do personagem até o meio do mapa. Aqui vira um recado
   * de duas linhas: o texto continua inteiro, e o botão de reportar continua
   * do tamanho de um dedo.
   */
  #cartaz-beta { padding: 10px 40px 10px 14px; width: calc(100vw - 16px); }
  #cartaz-beta h2, #cartaz-beta .cartaz-titulo { font-size: 15px; }
  #cartaz-beta p { font-size: 12px; margin: 4px 0; }

  /* ---- 5. A rolagem lateral da barra de ações fica com jeito de dedo ---- */
  /*
   * A barra é mais larga do que a tela e já rolava de lado (`overflow-x: auto`),
   * mas com a barra de rolagem de mesa — uma tira cinza de 15px que come altura
   * e que ninguém arrasta com o dedo. Some a tira; o gesto continua.
   *
   * `text-align: left` porque a barra é centrada no personagem
   * (`--desloca-barra`): numa tela estreita esse deslocamento joga o começo da
   * fileira para fora à esquerda, e a pessoa nem descobre que há o que rolar.
   */
  #actionbar {
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    left: 0 !important;
    transform: none !important;
    width: 100vw;
    max-width: 100vw;
  }
  #actionbar::-webkit-scrollbar { display: none; }

  /* ---- 6. O aviso de beta cabe em duas linhas em vez de ser cortado ---- */
  /*
   * Ele era uma fita de 24px com `white-space: nowrap` e reticências: numa tela
   * de 390 a frase virava "MINEIRO IDLE EM DESENVOLVIMENTO — PODE HAVER BUC". O
   * recado é curto e importa inteiro, então aqui ele quebra.
   *
   * A altura passa a ser automática, e o `--altura-do-aviso` (que empurra o HUD
   * e o cartaz para baixo) é acertado junto — sem isso, a segunda linha ficaria
   * por baixo do card do personagem.
   */
  body.com-aviso { --altura-do-aviso: 38px; }
  /*
   * "afina bem a linha de Mineiro Idle em desenvolvimento."
   *
   * Ela quebra em duas linhas para o texto não ser cortado, e duas linhas de
   * 10px com folga custavam 38px de altura — perto de um vigésimo da tela para
   * um aviso que se lê uma vez. A letra desce para 9px, a entrelinha aperta e a
   * faixa fica com 28px.
   */
  /*
   * ---- E ela afina de novo: uma LINHA só ----
   *
   * "afina isso bem pra celular pra não ficar poluído."
   *
   * Deixá-la quebrar em duas linhas custava 28px — e o aviso é o primeiro que
   * se lê e o último que interessa depois da primeira vez. Numa linha com
   * reticências ele fica em 20: a frase inteira cabe em 8px numa tela de 360, e
   * o que não couber é aparado no fim em vez de virar um parágrafo.
   */
  body.com-aviso { --altura-do-aviso: 20px; }
  #aviso-dev {
    height: 20px; min-height: 0; padding: 0 6px; gap: 5px;
    white-space: nowrap; line-height: 1; font-size: 8px;
    letter-spacing: .04em;
    align-items: center;
    overflow: hidden; text-overflow: ellipsis;
  }
  #aviso-dev::before { font-size: 9px; }
  #aviso-dev-report { min-height: 0; font-size: 8px; padding: 1px 7px; letter-spacing: .04em; }

  /*
   * ---- E os ícones da barra de cima afinam ----
   *
   * Vinte e um botões de 46px numa fileira que rola: quanto menor cada um,
   * menos rolagem e menos altura de barra. 36px continua acima do que um dedo
   * erra, e a fileira ganha quase metade da largura de volta.
   */
  .tools button { width: 36px; height: 36px; padding: 1px; }
  .tools button img { width: 24px; height: 24px; }
  #store-button img { height: 22px; }
  #aviso-dev::before { line-height: 1; }

  /* ---- 7. A fileira de habilidades CABE, em vez de rolar ---- */
  /*
   * "barra de habilidade sem precisar scrolar."
   *
   * A grade tinha um número fixo de colunas (`--slots-por-fileira`, posto pelo
   * `actionbar.mjs` a partir do catálogo): onze slots de 42px são 517px, e numa
   * tela de 360 sobravam sete escondidos atrás de uma rolagem que ninguém
   * descobre. `auto-fill` troca o número fixo pelo que cabe — a fileira vira
   * duas ou três, e todo slot fica na tela.
   *
   * O `1fr` no lugar do 42px fixo faz os quadros dividirem a sobra em vez de
   * deixá-la na ponta direita, e é o que centra a fileira sem conta nenhuma.
   */
  .hotbar {
    grid-template-columns: repeat(auto-fill, minmax(38px, 1fr));
    grid-auto-rows: 38px;
    gap: 4px;
    width: 100%;
  }
  .hotbar-stack { width: 100%; min-width: 0; }
  /*
   * 38px e nao os 42 da mesa: sao vinte e dois slots, e a diferenca de quatro
   * pixels e' uma FILEIRA inteira a menos numa tela de 360 — a barra passou de
   * um terco da tela para um quinto, e o que ela devolveu foi mapa.
   */

  /*
   * E a barra inteira empilha em vez de deitar. Os três blocos — os seletores
   * de alvo, a fileira de slots e a coluna do "Sair da hunt" — somavam quase
   * mil pixels de largura numa tela de 360.
   */
  .bar-row { flex-wrap: wrap; justify-content: center; width: 100%; gap: 4px; }
  /*
   * ---- Cada polegar com o seu canto ----
   *
   * "dava pra tu colocar as habilidades tudo no canto da direita pra facilitar
   * a pessoa apertar com a outra mão, e a esquerda embaixo fica livre só pra
   * pessoa com o analógico."
   *
   * É o desenho de todo jogo de telefone, e o motivo é físico: quem segura o
   * aparelho com as duas mãos alcança os dois cantos de baixo e MAIS NADA sem
   * mudar a pegada. Uma barra de largura cheia obriga a mão a atravessar a
   * tela — e, de quebra, tapava o jogo de ponta a ponta.
   *
   * Agora a barra encolhe para o tamanho do que tem dentro e vai para o canto
   * direito, flutuando sobre o mapa. O `left: auto` e o `transform: none`
   * desfazem a centralização no personagem (`--desloca-barra`), que só faz
   * sentido numa barra que atravessa a tela.
   */
  #actionbar {
    /*
     * No RODAPÉ inteiro outra vez, e não no canto direito: a fileira única
     * atravessa a tela, e uma caixa de 62vw a cortaria no meio.
     *
     * `overflow-x: auto` é o que salva a tela em pé — ver a nota da `.hotbar`.
     */
    left: 0 !important;
    right: 0;
    /* "grude os slots de habilidade e as coisas no rodapé": encostada mesmo. */
    bottom: 0;
    transform: none !important;
    width: 100% !important;
    max-width: none;
    max-height: none;
    display: flex;
    /*
     * `align-items` e não `justify-content`: o `#actionbar` é uma coluna
     * (`flex-direction: column`, lá em cima), e numa coluna quem alinha na
     * horizontal é o `align-items`. Com `justify-content` a fileira ficava
     * colada na esquerda e o centro não acontecia.
     */
    align-items: center;
    overflow-x: auto !important;
    overflow-y: hidden !important;
    /*
     * A faixa da direita é do cadeado ("à direita dos slots de action bar o
     * cadeado"). Reservada como padding, ela sai da conta da centralização — a
     * fileira fica no meio do que SOBRA, e não por baixo do botão.
     */
    /* (o enchimento fica na declaração de baixo, que é a que vence) */
    /*
     * ---- Sem moldura: no celular são ÍCONES SOLTOS ----
     *
     * A moldura de nove fatias tem 22px de borda de cada lado e um fundo opaco.
     * Numa tela de mesa ela emoldura uma barra larga e faz sentido; num
     * telefone ela é um retângulo escuro tapando o mapa para enquadrar três
     * colunas de ícones que já têm moldura própria — cada slot tem a sua.
     *
     * Tirada a moldura, o que fica é o que importa: os ícones, flutuando sobre
     * o jogo.
     */
    border-style: none !important;
    border-image: none !important;
    border-width: 0 !important;
    background: none !important;
    /*
     * Sem enchimento, MENOS as duas faixas laterais.
     *
     * A da direita é do cadeado e do "Stop"; a da esquerda existe só para a
     * fileira ficar no MEIO DA TELA. Reservando um lado só, ela era empurrada
     * para a esquerda e parecia torta — centrada no espaço que sobra não é a
     * mesma coisa que centrada na tela, e o olho vê a diferença.
     */
    padding: 0 34px !important;
  }
  /*
   * ---- Deitado, o "Stop" fica ENTRE o último slot e o cadeado ----
   *
   * "o botão hunts e stop, vc coloca entre o último slot de habilidade e entre
   * o cadeado."
   *
   * Os dois na mesma linha da fileira pedem uma faixa maior à direita — e a
   * mesma faixa à esquerda, senão a fileira sai do meio da tela.
   */
  @media (orientation: landscape) {
    /*
     * A faixa da ESQUERDA é maior: é onde o analógico mora, e ele desceu para o
     * chão. Sem reservá-la, o controle ficava por cima dos primeiros slots em
     * qualquer tela deitada mais estreita que 914px.
     */
    #actionbar { padding: 0 78px 0 104px !important; }
    /* O `overflow` de cima (`x: auto`, `y: hidden`) é o que vale: um atalho
       `visible` aqui embaixo o desfazia, e a fileira comprida vazava em vez de
       rolar. */
  }
  .controls { grid-template-columns: repeat(2, minmax(0, 1fr)); flex: 1 1 100%; gap: 4px; }
  /*
   * A coluna da direita vira FILEIRA: em pé ela empilhava "Sair da hunt", o
   * "Hunts" e o "Salvar HK" um sobre o outro, três faixas de tela para três
   * botões que cabem lado a lado.
   */
  .bar-side {
    flex: 1 1 100%; width: 100%;
    display: flex; flex-direction: row; align-items: center; gap: 5px;
  }
  .bar-side > * { flex: 1 1 0; min-width: 0; }
  #actionbar .bars-dock { width: 100%; }
  /*
   * E um TETO para a barra inteira. Ela é o rodapé, não a tela: passando de um
   * terço da altura ela deixa de ser controle e vira o jogo.
   */
  #actionbar { max-height: 40vh; }
  /* A fileira é uma só: o teto de 40vh é do tempo do teclado em coluna. */
  #actionbar { max-height: none; }

  /* ---- 8. O ANALÓGICO ---- */
  /*
   * Canto inferior esquerdo, flutuando SOBRE o mapa e acima da barra de ações
   * (`--barra-altura`, medido pelo actionbar.mjs). É onde o polegar esquerdo
   * cai sem a mão sair da posição de segurar o telefone.
   *
   * Ele fica ABAIXO da gaveta no empilhamento de propósito: com a mochila
   * aberta ninguém está andando, e um controle por cima da janela roubaria o
   * toque de quem quer arrastar um item.
   */
  #analogico {
    position: fixed;
    /*
     * ---- Acima das janelas, e não abaixo ----
     *
     * Ele nasceu no z-index 9, por baixo da gaveta (10): a ideia era que, com a
     * mochila aberta, o toque fosse todo dela. Medido, isso o tornava
     * INALCANÇÁVEL — a gaveta ocupa a metade de baixo da tela, é justamente
     * onde o polegar cai, e as janelas abrem sozinhas ao entrar. O jogador
     * chegava na cidade sem nenhum jeito de andar.
     *
     * Um controle de movimento não disputa espaço com uma janela: ele fica por
     * cima, como a barra de ações (25) já fica. 26 o põe acima dela também e
     * abaixo dos modais, que são os únicos que devem cobrir tudo.
     */
    z-index: 26;
    /*
     * Menor, e recuado da quina.
     *
     * 112px colados no canto punham metade do controle debaixo da palma de quem
     * segura o aparelho, e o polegar chegava nele torto. 88px afastados 24 da
     * borda e 46 do chão é a posição de descanso do polegar — e os 24px que ele
     * perde de diâmetro voltam como mapa.
     */
    /*
     * Encostado na borda esquerda: com a mão segurando o aparelho pela quina,
     * o polegar cai NA quina, não a um centímetro dela. Ele já esteve a 24px, e
     * o desenho que o dono mandou o trouxe para cá.
     */
    left: 8px;
    /*
     * Preso ao teto da barra, e não só à altura dela.
     *
     * `--barra-altura` é medida de verdade, e com a barra cheia de slots ela
     * passou de um terço da tela — o analógico saía pela borda de cima e sumia.
     * O `min` prende o controle no mesmo teto de 40vh que a barra tem: aconteça
     * o que acontecer com a barra, ele continua na tela.
     */
    /*
     * Colado no chão, e não mais apoiado na altura da barra: ela saiu do
     * caminho e foi para o canto direito. Os dois polegares agora têm cada um
     * o seu canto, e nenhum dos dois empurra o outro.
     */
    /*
     * APOIADO na fileira, não colado no chão.
     *
     * Ele chegou a ir para a quina, quando a barra era um teclado no canto
     * direito e o rodapé estava vazio. Com a fileira única atravessando o
     * rodapé de novo, o chão é dela: o controle sobe para cima dela, e a altura
     * é a MEDIDA (`--barra-altura`, publicada pelo `actionbar.mjs`) e não um
     * número — a fileira encolhe quando o personagem tem poucas magias.
     */
    /* "o analógico tem que ser perto da action bar": encostado nela. */
    bottom: calc(var(--barra-altura, 40px) + 4px);
    width: 88px; height: 88px;
    border-radius: 50%;
    /*
     * ---- No verde do jogo ----
     *
     * Cinza sobre pedra cinza, o controle sumia no mapa. O verde é o mesmo
     * `--accent` do resto da interface: em vez de inventar uma cor para o
     * telefone, o controle passa a pertencer ao tema — e quem já sabe que o
     * verde é "coisa do jogo, não do cenário" reconhece o disco de relance.
     *
     * Translúcido do mesmo jeito: ele fica POR CIMA do mapa, e um disco opaco
     * no canto seria um buraco na tela.
     */
    background: radial-gradient(circle at 50% 45%, #1a4f4699, #10312c85 70%, #0a10124d);
    border: 1px solid #2a7d6e8c;
    box-shadow: 0 6px 18px #0009, inset 0 1px 0 #3fbfa81f;
    /*
     * `touch-action: none` é o que faz o controle FUNCIONAR: sem ele o
     * navegador entende o arrasto como rolagem da página e para de mandar
     * `pointermove` no meio do gesto — o boneco andaria um passo e travaria.
     */
    touch-action: none;
    user-select: none; -webkit-user-select: none;
    opacity: .78;
    transition: opacity .18s ease;
  }
  #analogico.ativo { opacity: 1; }
  .analogico-bola {
    position: absolute; left: 50%; top: 50%;
    width: 38px; height: 38px; margin: -19px 0 0 -19px;
    border-radius: 50%;
    /* A bola é a peça OPACA: é ela que o dedo empurra, e é pelo contraste dela
       com o disco que se enxerga para onde o controle está apontando. */
    background: radial-gradient(circle at 40% 35%, #4fa895, #2a7d6e 55%, #143f38);
    border: 1px solid #0c1214;
    box-shadow: 0 3px 10px #000c;
    pointer-events: none;
  }
  /*
   * A cruz apagada no fundo: ela diz para que serve o círculo antes de a pessoa
   * encostar nele. Sem nenhuma marca, um disco no canto da tela é um enfeite.
   */
  #analogico::before,
  #analogico::after {
    content: ''; position: absolute; left: 50%; top: 50%; background: #3fbfa829;
  }
  #analogico::before { width: 2px; height: 48px; margin: -24px 0 0 -1px; }
  #analogico::after { width: 48px; height: 2px; margin: -1px 0 0 -24px; }
  /*
   * A margem de toque do iPhone (ver `EH_IOS` em mobile.mjs): 24px invisíveis
   * em volta do disco, com `touch-action: none`, para o dedo que encosta um
   * pouco fora não virar rolagem da página. `-webkit-touch-callout` só existe
   * no Safari do iOS, então o bloco não vale em Android nem em PC — e o
   * elemento só é criado lá.
   */
  @supports (-webkit-touch-callout: none) {
    #analogico .analogico-margem {
      position: absolute; inset: -24px;
      border-radius: 50%;
      touch-action: none;
    }
  }

  /* ---- 9. Os modais NASCEM do tamanho do telefone ---- */
  /*
   * "se eu abro um modal no celular tem que scrollar, se tu vê no OTClient ao
   * abrir já abre a telinha pequena."
   *
   * O modal era `width: min(980px, 94vw)` — a largura já cabia. O que não cabia
   * era a ALTURA e a moldura: 50px de borda em cima e 30 de cada lado numa tela
   * de 360 comem um sexto da largura útil antes de o conteúdo começar, e o
   * `max-height: 90vh` medido em `vh` ignora a barra do navegador, que no
   * celular aparece e some — o rodapé do modal ficava por baixo dela.
   *
   * `100dvh` é a altura VIVA da janela, a que encolhe junto com a barra. O `vh`
   * fica de reserva para navegador que ainda não a conhece.
   */
  .modal-box,
  .modal-box.imbue {
    width: calc(100vw - 10px) !important;
    max-width: calc(100vw - 10px) !important;
    max-height: 92vh;
    max-height: calc(100dvh - 14px);
    border-width: 40px 14px 18px 14px;
  }
  #modal { padding: 6px; }
  /*
   * A rolagem mora no CORPO do modal, e não na página.
   *
   * Sem isto o conteúdo alto empurrava a moldura para fora da tela e a pessoa
   * rolava a PÁGINA para achar o botão de fechar — que é o defeito descrito. Com
   * o corpo rolando por dentro, a moldura e o × ficam sempre onde estão.
   */
  #modal-body {
    padding: 4px 2px 8px;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
  }
  .modal-box h2 { font-size: 15px; }

  /* ---- 10. E o conteúdo de dentro deixa de ser desenhado para 980px ---- */
  /*
   * Quase toda tela do jogo foi montada com grades de largura fixa — a loja, o
   * mercado, o depósito, a forja. Numa tela de 360 elas estouram a moldura e
   * levam junto o resto do layout. Aqui as grades passam a se contar pelo que
   * cabe, uma vez só, em vez de uma regra por tela.
   */
  #modal-body [style*="grid-template-columns"],
  #modal-body .grade,
  #modal-body .cards,
  #modal-body .lista-de-cards {
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)) !important;
  }
  /*
   * E nada lá dentro pode ser mais largo do que a moldura. É a trava final: o
   * que escapar das regras acima encolhe em vez de furar a borda.
   */
  #modal-body * { max-width: 100%; }
  /* Menos as tabelas, que encolhidas viram uma coluna de letra torta: elas
     rolam de lado dentro da própria caixa, que é o certo para tabela. */
  #modal-body table { display: block; overflow-x: auto; max-width: 100%; }

  /* ---- O que estava plantado no MEIO da tela sai do meio ---- */
  /*
   * "essas coisas da foto ainda tá no meio da tela."
   *
   * A faixa de recompensas (`#presente`) é `left: 50%` apoiada na altura da
   * barra de ações — um desenho que fazia sentido quando a barra atravessava o
   * rodapé. Agora o rodapé é do analógico e do teclado, e o meio da tela é o
   * mapa: é lá que o personagem fica, e é o que a faixa tapava.
   *
   * Ela sobe para debaixo da barra de cima, onde já moram os outros avisos, e
   * encolhe: é um lembrete, não um cartaz.
   */
  /*
   * "o recompensas pra pegar configure ele pra ficar pequeno no celular e deixa
   * ali no rodapé central de baixo."
   *
   * Ele já tinha saído do meio da tela para o topo; agora desce para a faixa do
   * rodapé que ficou entre o analógico (à esquerda) e o teclado (à direita) —
   * a única parte do rodapé que nenhum dos dois polegares usa.
   */
  /*
   * "esse 'recompensas pra pegar' tira do meio da tela pelo amor de deus, faz
   * aparecer pequeno embaixo."
   *
   * Ele era uma faixa de 134px de altura no meio do rodapé — um cartaz. Vira um
   * selo miúdo encostado na direita, acima do "Stop": lembrete, não anúncio.
   */
  #presente {
    left: auto !important;
    right: 70px;
    transform: none !important;
    top: auto !important;
    /*
     * Uma faixa ACIMA da fileira de ajustes, e nao no chao junto com ela: as
     * duas coisas sao centradas no rodape, e no chao os icones de alvo e
     * distancia caiam por cima da faixa de recompensas.
     */
    /*
     * Na mesma faixa do rodapé, no vão entre os ajustes (à esquerda) e o
     * "Stop" (à direita). Empilhado ACIMA do Stop ele subia para o meio do
     * mapa, que é de onde o dono queria tirá-lo; aqui ele está tão embaixo
     * quanto a fileira permite.
     */
    bottom: calc(var(--barra-altura, 40px) + 6px) !important;
    /*
     * Em FILEIRA, e não empilhado: o "—" de minimizar em cima da placa fazia o
     * selo ter duas alturas. Lado a lado ele tem uma só.
     */
    display: flex !important;
    flex-direction: row;
    align-items: center;
    gap: 4px;
    justify-items: end;
    z-index: 13;
    /* Estreito o bastante para não encostar nos três ajustes, que ocupam de
       102 a 184 numa tela de 390. */
    max-width: 32vw;
  }
  /*
   * "o ícone do recompensas pra pegar pode aumentar, mas o texto pode ser um
   * pouco menor."
   *
   * O baú é o que se reconhece de relance; a frase é só a legenda dele. Em
   * fileira, com a figura à esquerda e o texto à direita, o selo fica mais
   * baixo do que era empilhado.
   */
  #presente-abrir {
    font-size: 7px; padding: 2px 5px; line-height: 1.1;
    white-space: normal; text-align: left;
    display: flex; flex-direction: row; align-items: center; gap: 4px;
  }
  #presente-abrir img { width: 30px !important; height: 30px !important; }
  #presente-min { transform: scale(.8); }

  /* ---- A porta de entrada cabe na tela, sem rolar ---- */
  /*
   * "faz a tela do character list e do login ser na tela sem precisar
   * scrollar."
   *
   * O `#gate` centraliza a caixa e rola a PÁGINA inteira quando ela não cabe.
   * Num telefone deitado (412px de altura) a lista de personagens passa da
   * tela na quarta linha, e o "Criar personagem" some lá embaixo — quem entra
   * pela primeira vez não vê o botão que precisa apertar.
   *
   * A caixa passa a caber por definição (`100dvh`, a altura viva, que desconta
   * a barra do navegador) e quem rola é a LISTA, por dentro. Assim o logo, o
   * título e os botões do rodapé ficam sempre visíveis, e o que rola é o que
   * pode rolar.
   */
  #gate { padding: 10px; align-items: stretch; }
  .gate-box,
  .gate-box.escolhendo,
  .gate-box.creating {
    width: 100% !important;
    max-height: calc(100dvh - 20px);
    display: flex;
    flex-direction: column;
  }
  .gate-inner {
    display: flex;
    flex-direction: column;
    min-height: 0;
    max-height: 100%;
  }
  .gate-box .logo { max-width: 190px; }
  /* Uma coluna só: dois cartões lado a lado em 360px viram dois cartões ilegíveis. */
  .character-list {
    grid-template-columns: minmax(0, 1fr);
    overflow-y: auto;
    min-height: 0;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
  }
  /*
   * ---- E a corrente do "pode encolher" tem de chegar até a lista ----
   *
   * Pôr `max-height` na caixa e `overflow-y` na lista não basta: entre as duas
   * há a `.gate-inner` e a `<section>` do painel, e um filho de flex nasce com
   * `min-height: auto` — ele se recusa a ficar menor do que o conteúdo. Basta
   * UM elo sem `min-height: 0` para o pedido de encolher morrer no caminho, e
   * foi o que aconteceu: com cinco personagens, deitado, a lista empurrava o
   * "Criar personagem" para fora da tela.
   *
   * A lista é a única peça que cresce (`flex: 1`); o logo, o título e os botões
   * ficam do tamanho que são.
   */
  #gate .gate-inner > section {
    display: flex; flex-direction: column;
    min-height: 0; max-height: 100%;
  }
  #gate .character-list { flex: 1 1 auto; min-height: 0; }
  #gate .gate-inner > section > *:not(.character-list) { flex: none; }

  /* Deitado sobra pouca altura: o logo encolhe e a lista ganha duas colunas. */
  @media (max-height: 540px) {
    .gate-box .logo { max-width: 110px; margin-bottom: 2px; }
    .gate-box h2 { margin-bottom: 4px; font-size: 11px; }
    .character-card { padding: 5px 9px; gap: 8px; }
    .character-card img, .character-card canvas { width: 34px; height: 34px; }
    /*
     * Duas colunas: deitado sobra LARGURA e falta altura, que é o contrário do
     * telefone em pé. Cada cartão fica com 400px, de sobra para nome, vocação e
     * o que ele está fazendo.
     */
    #gate .character-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  }
  /* O aviso de palco vazio também: ele fica no lugar do boneco. */
  #stage-empty { bottom: auto !important; top: 40%; padding: 10px 16px; }

  /* ---- 11. As telas de DUAS COLUNAS viram uma ---- */
  /*
   * Medido com `tools/test-telas-celular.mjs`: de treze telas, quatro furavam a
   * moldura — e todas pelo mesmo motivo. Elas são grades de largura fixa,
   * desenhadas para os 980px do computador:
   *
   *   .arvore   196px + 1fr + 260px   → o lado direito saía 110px fora
   *   .sheet    1fr 1fr               → as réguas saíam 70px fora
   *   .bank     1fr 1fr               → os saldos saíam 135px fora
   *   .craft    duas bonecas lado a lado → 108px fora
   *
   * Numa tela de 360, duas colunas não são duas colunas: são uma coluna e um
   * pedaço escondido. Empilhar é o único desenho que cabe, e é o que todo
   * aplicativo de telefone faz com a mesma tela.
   *
   * O `!important` é porque várias delas já têm um `@media` de mesa mais
   * específico mais abaixo na folha (ver `.arvore` em 10386, por exemplo).
   */
  #modal-body .arvore,
  #modal-body .sheet,
  #modal-body .sheet-header,
  #modal-body .bank-saldos,
  #modal-body .craft-mesa,
  #modal-body .arvore-acoes {
    grid-template-columns: minmax(0, 1fr) !important;
    gap: 10px !important;
  }

  /*
   * ---- A ARVORE no telefone: o "Aplicar" estava FORA da tela ----
   *
   * Do report: "Na versao mobile nao ta aparecendo a opcao de aplicar arvore
   * de habilidade". Nao estava mesmo — e nao adiantava rolar.
   *
   * Tres regras de mesa se somavam. `.modal-box:has(.arvore) #modal-body` corta
   * o que passa (`overflow: hidden`), `.arvore-quadro` tem altura travada em
   * `92vh - 170px`, e a regra logo acima transforma a grade de tres colunas em
   * UMA. Resultado: a arte ocupava a altura inteira do corpo e a coluna da
   * direita — o placar, o Aplicar e o Cancelar — ia empilhada logo abaixo,
   * fora da moldura, num corpo que nao rola.
   *
   * O `overflow` do corpo precisa de `!important` porque aquela regra e' mais
   * ESPECIFICA que o `#modal-body` do bloco de celular: `:has(.arvore)` soma a
   * classe de dentro, entao ela vence por especificidade mesmo vindo antes.
   *
   * A arte passa a ter a altura do proprio desenho (o canvas se remede sozinho
   * — ver `medir`, que le `quadro.clientWidth` e o `offsetWidth` da imagem), e
   * as colunas laterais largam o `max-height` de mesa, que aqui so' criaria uma
   * rolagem dentro de outra.
   */
  .modal-box:has(.arvore) #modal-body {
    overflow-y: auto !important;
    overflow-x: hidden !important;
  }
  #modal-body .arvore-quadro {
    height: auto !important;
    width: 100% !important;
    max-width: 100% !important;
  }
  #modal-body .arvore-arte { height: auto !important; width: 100%; }
  #modal-body .arvore-lado,
  #modal-body .arvore-rumos {
    max-height: none !important;
    overflow-y: visible !important;
  }
  /*
   * E o placar com os botoes sobe para o TOPO.
   *
   * So' devolver a rolagem nao resolve o report: "Aplicar" atras de uma arvore
   * de tela inteira continua sendo um botao que se acha por acaso, e ele e' o
   * fim do que a pessoa veio fazer aqui. Em cima, ele e' a primeira coisa
   * depois do titulo — junto com os pontos a espera, que sao o que ele gasta.
   */
  #modal-body .arvore-lado { order: -1; }
  /*
   * As duas bonecas do craft ficam lado a lado por serem irmãs num flex; aqui
   * elas empilham e cada uma ocupa a linha inteira.
   */
  #modal-body .craft-boneca { justify-content: center !important; width: 100%; }
  /*
   * A régua da ficha tem três colunas fixas (92 + 110 + a barra). Os rótulos
   * encolhem e a barra fica com o que sobrar — ela é a única das três que
   * aguenta ser espremida sem virar texto cortado.
   */
  #modal-body .sheet-bar { grid-template-columns: minmax(64px, auto) minmax(0, 1fr) minmax(58px, auto); gap: 6px; }
  /* O rótulo do banco tinha 108px fixos ao lado de um campo de texto. */
  #modal-body .bank-rotulo { width: auto; min-width: 0; }

  /* ---- O rodapé da loja EMPILHA ---- */
  /*
   * "a store ficou quebrada: o saldo, transferir e comprar coins ficou no meio
   * da tela."
   *
   * Foi o `min-width: 0` do item 12 que cobrou o preço aqui. Ele é o que faz as
   * telas de 980px caberem em 360 — mas numa fileira `flex` com
   * `space-between`, autorizar todo mundo a encolher abaixo do conteúdo faz o
   * texto de cada um transbordar da própria caixa e cair POR CIMA do vizinho.
   * O saldo, o "Transferir" e o "Obter Mineiroidle Coins" viraram três textos no
   * mesmo lugar.
   *
   * A regra não pode sair (sem ela, quatro telas voltam a furar a moldura), e o
   * conserto é o certo de qualquer jeito: numa tela estreita, três blocos que
   * disputam uma linha viram três linhas.
   */
  #modal-body .store-footer {
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
  }
  #modal-body .store-footer-esq { justify-content: space-between; flex-wrap: wrap; gap: 8px; }
  #modal-body .store-obter,
  #modal-body .store-transferir { justify-content: center; text-align: center; }
  /*
   * E a mesma cautela para QUALQUER fileira de `space-between` dentro de um
   * modal: é o arranjo que mais aparece nestas telas (um dado à esquerda, uma
   * ação à direita) e o que pior reage a encolher. Deixá-las quebrar linha
   * custa uma linha a mais; não deixar custa dois textos sobrepostos.
   */
  #modal-body [style*="space-between"],
  #modal-body .linha-de-acao,
  #modal-body .topo-com-acao { flex-wrap: wrap; }
  /*
   * E texto que não cabe QUEBRA a linha em vez de transbordar.
   *
   * É a outra metade do preço do `min-width: 0`: autorizada a encolher, a caixa
   * fica menor que a frase — e uma frase com `white-space: nowrap` sai por fora
   * e pousa no vizinho. Deixá-la quebrar custa uma linha; não deixar custa dois
   * textos no mesmo lugar. Medido pelo `test-telas-celular`, que reprova
   * qualquer elemento cujo texto passe da própria caixa.
   */
  #modal-body button,
  #modal-body label,
  #modal-body .rotulo,
  #modal-body b,
  #modal-body span { white-space: normal; overflow-wrap: anywhere; }

  /* ---- 12. E a trava que faz TUDO caber: `min-width: 0` ---- */
  /*
   * O Banco e a Forja continuavam furando 131px e 108px mesmo com as colunas já
   * empilhadas, e o motivo é uma regra do CSS que pega quase todo mundo uma vez:
   * item de grade e de flex nasce com `min-width: auto`, e `auto` quer dizer
   * "não encolho abaixo do meu conteúdo". Um texto largo, uma figura, uma linha
   * de botões — qualquer coisa lá dentro empurra a trilha inteira para fora da
   * moldura, e nem `max-width: 100%` nem `overflow` seguram, porque a caixa já
   * nasceu grande.
   *
   * `min-width: 0` é o que autoriza encolher. Junto com o `max-width: 100%` de
   * cima, é o par que faz uma tela desenhada para 980px caber em 360.
   */
  #modal-body, #modal-body * { min-width: 0; }

  /* ---- 13. A barra de ações para de tapar o jogo ---- */
  /*
   * "quase não dá pra ver a tela pq a barra de habilidade tampa tudo."
   *
   * Ela estava em 31% da altura, e com a gaveta aberta sobrava uma faixa de
   * mapa. Três cortes, do mais caro para o mais barato:
   *
   *   1. Os seletores (Alvo, Distância, Lurar até) eram duas colunas em duas
   *      fileiras, com rótulo por cima de cada um: 110px. São ajustes que se
   *      mexem uma vez por caçada, não a cada segundo. Viram três colunas numa
   *      fileira só, com o rótulo miúdo — 55px.
   *   2. O slot cai de 38 para 34px.
   *   3. A gaveta cai de 46vh para 38vh.
   *
   * Somados, a barra sai de 31% para perto de 20% e o mapa dobra de área útil.
   */
  /*
   * ---- O que fica À MÃO e o que fica guardado ----
   *
   * No canto só cabe o que se usa a cada segundo: os slots. Os seletores (Alvo,
   * Distância, Lurar até) e os botões da coluna (Sair da hunt, Hunts, Salvar
   * HK) são ajustes de uma vez por caçada — eles somavam 150px de altura para
   * ficarem parados na tela a caçada inteira.
   *
   * Eles não sumiram: a seta que já existia na barra (`#bar-min`) passa a
   * abri-los e fechá-los no celular. Ver `mobile.mjs`.
   */
  .controls, .bar-side, #actionbar .bars-dock { display: none; }
  /*
   * ---- A ⚙ e a ▼ somem do teclado ----
   *
   * "no modo de celular tu pode tirar esse minimizar a barra e a engrenagem da
   * barra de habilidade."
   *
   * As duas eram `position: absolute` no canto de cima do `#actionbar`, o que
   * numa tela de mesa as põe num pedaço vazio da moldura. Sem moldura, no
   * telefone, esse canto é o PRIMEIRO SLOT — e elas ficavam deitadas em cima
   * dele: foi o único que ele não conseguiu arrastar ao desenhar o arranjo.
   */
  .bar-controls { display: none !important; }

  /*
   * ---- E o "Stop" sai da gaveta para o rodapé ----
   *
   * A gaveta abria pela ▼, que acabou de sumir. O que só existia lá dentro era
   * este botão, e ele é o único jeito de voltar da caçada para a cidade —
   * escondê-lo atrás de um botão que não existe mais o tornaria inalcançável.
   *
   * `fixed` no meio do rodapé, acima da fileira de ajustes: os dois L moram nas
   * quinas, e o meio é a faixa que nenhum dos dois polegares usa.
   */
  body.em-caca .bar-side { display: block; }
  /*
   * "o botão de hunts ou quando é stop deixa pequeno ao lado direito da última
   * action bar."
   *
   * Na mesma faixa da direita que o cadeado usa, logo acima dele: é o pedaço
   * que a fileira já não ocupa, e o polegar direito passa por ali de qualquer
   * jeito. Pequeno porque é um botão de uma vez por caçada.
   */
  body.em-caca #leave-hunt {
    position: fixed;
    left: auto; right: 3px; transform: none;
    /* Em pé não há faixa para os dois lado a lado: ele sobe para cima do
       cadeado, que é o único lugar livre numa tela de 390. */
    bottom: calc(var(--barra-altura, 40px) + 6px);
    width: auto; min-width: 0;
    padding: 3px 8px;
    font-size: 10px;
    z-index: 27;
  }
  /* Deitado ele desce para a linha da fileira, à esquerda do cadeado. */
  @media (orientation: landscape) {
    body.em-caca #leave-hunt { right: 32px; bottom: 2px; }
    /*
     * ---- E o analógico desce até o chão ----
     *
     * "no modo horizontal pode descer o analógico mais pra baixo também."
     *
     * Deitado sobram 412px de altura e o controle come 88 deles: cada pixel que
     * ele desce é mapa. Ele não bate na fileira porque a fileira é centrada e
     * a faixa da esquerda (78px) fica livre — o controle mora dentro dela.
     */
    #analogico { bottom: 2px; }
    /* Os ajustes acompanham, logo acima do controle: 2 do chão + 90 do círculo
       + 6 de respiro. */
    #ajustes-da-caca { bottom: 98px; }
    /* E o selo das recompensas recua: deitado o "Stop" desceu para a linha da
       fileira, e os dois se encontravam por três pixels. */
    #presente { right: 100px; }
  }
  /* Destrancado ele sai da frente: a coluna do cadeado cresce para cima quando
     vira três botões, e passaria por cima dele. Quem está arrumando a barra não
     está saindo da caçada no mesmo segundo. */
  body.slots-livres #leave-hunt { display: none !important; }

  /* ---- O "Hunts" e o "Salvar hk" NAO entram na gaveta ---- */
  /*
   * "o botao hunts e o de salvar hk nem precisa estar ali no celular."
   *
   * Eram os dois que saiam pela borda: a coluna da direita foi desenhada para
   * um rodape de 1100px de largura, e em 390 os dois botoes de texto nao cabem
   * lado a lado — o "Salvar hk" ficava cortado no meio da palavra e o "Hunts"
   * pousava em cima da faixa de recompensas.
   *
   * Guardar arranjos de hotkey e' trabalho de teclado: quem monta doze slots
   * com nome esta' no computador. No telefone o botao so' ocupava espaco.
   */
  #hotbar-presets { display: none !important; }
  /*
   * O mesmo botao tem duas caras (ver `renderRunControls`): fora da cacada ele
   * e' "Hunts" e abre a escolha — que ja' esta' no menu de cima; dentro dela ele
   * e' "Stop", e e' o unico jeito de voltar para a cidade. So' a segunda fica.
   */
  body:not(.em-caca) #leave-hunt { display: none !important; }

  /* ---- Os três ajustes da caçada viram ÍCONES ---- */
  /*
   * "perto disso deixa um ícone de alvo, de distância, de lurar até, que aí
   * abre e configura e não ocupa tanto a tela."
   *
   * Eram três seletores com rótulo, parados na tela a caçada inteira para
   * ajustes que se mexem uma vez por hunt. Viram três botões de 34px ao lado do
   * teclado de habilidades; tocar num deles abre AQUELE, e só aquele.
   *
   * ---- E o que abre é o seletor DE VERDADE ----
   *
   * O painel não tem cópia nenhuma: ele mostra o mesmo `<label>` que já estava
   * no `#actionbar`, escondido. Uma cópia precisaria repetir as opções, os
   * valores e os ouvintes — e no dia em que uma opção nova entrasse no jogo, a
   * cópia continuaria com a lista velha, calada.
   *
   * O `:has()` é o que permite separá-los sem tocar no HTML: cada `<label>` é
   * reconhecido pelo `<select>` que carrega dentro.
   */
  body[data-ajuste] .controls {
    display: grid !important;
    position: fixed;
    left: 8px;
    right: auto;
    bottom: 42px;
    z-index: 27;
    width: min(260px, 64vw);
    padding: 10px 12px;
    gap: 6px;
    grid-template-columns: minmax(0, 1fr) !important;
    background: var(--panel-solid);
    border: 1px solid var(--line);
    border-radius: 8px;
    box-shadow: 0 10px 28px #000b;
  }
  body[data-ajuste] .controls label { display: none; }
  body[data-ajuste] .controls .controls-row { display: contents; }
  /* Com `#actionbar`: a barra recolhida (`#actionbar.minimizada .controls label`,
     de mesa) pesa mais que `body[data-ajuste=...]` e deixava o painel vazio. */
  body[data-ajuste="alvo"] #actionbar .controls label:has(#strategy),
  body[data-ajuste="distancia"] #actionbar .controls label:has(#distance),
  body[data-ajuste="lurar"] #actionbar .controls label:has(#lure) { display: grid; gap: 4px; }
  body[data-ajuste] .controls .rotulo { font-size: 11px; letter-spacing: .05em; }
  body[data-ajuste] .controls select { padding: 8px 10px; font-size: 13px; }

  /*
   * ---- Os ajustes viram ÍCONES SOLTOS, ao lado do analógico ----
   *
   * "deixa os ícones de alvo, distância, lurar, cadeado etc sem o fundo, só os
   * ícones pequenininhos, e coloca elas no rodapé perto do analógico."
   *
   * Eram seis plaquinhas escuras de 34px empilhadas em cima do teclado da
   * direita — seis retângulos opacos tapando mapa para carregar seis glifos.
   * Sem fundo, sem borda e sem sombra de caixa, o que sobra é o glifo.
   *
   * ---- E a sombra do TEXTO fica ----
   *
   * Ela é o que faz um ícone sem plaqueta continuar legível: o mapa embaixo
   * muda de cor a cada passo — grama clara, pedra escura, água —, e um glifo
   * cinza sem contorno some em metade dos cenários. Duas sombras pretas
   * coladas fazem o papel do fundo sem ocupar o lugar dele.
   *
   * ---- Por que uma COLUNA na borda esquerda ----
   *
   * O pedido é "perto do analógico". Em fileira horizontal eles cairiam no arco
   * onde o `⌒` põe as habilidades (raio de 87px em volta do controle) e os dois
   * se cobririam. Em coluna, colados na borda, ficam ao lado do polegar e fora
   * do caminho do arco.
   */
  /*
   * No RODAPÉ, em fileira: é onde o dono os pediu, e é a faixa que sobrou livre
   * depois de o analógico subir 46px. Eles ficam por baixo do braço horizontal
   * do L (ver `emVoltaDoAnalogico`), que corre na altura do meio do controle.
   */
  /*
   * Puxados para a direita, para saírem de baixo do braço horizontal do L e da
   * quina onde o polegar esquerdo trabalha. Eles são ajustes, não ação: ficam
   * no caminho de ninguém.
   */
  /*
   * No MEIO do rodape, e nao mais empurrados para a direita.
   *
   * Eles foram para a direita quando o L saia da cintura do analogico e passava
   * por cima deles. Agora os dois L moram nas QUINAS e crescem das bordas para
   * dentro (ver `emVoltaDoAnalogico`): o meio do rodape e' justamente o pedaco
   * que sobrou entre os dois, e e' onde nenhum dos dois polegares trabalha.
   */
  #ajustes-da-caca {
    display: flex; flex-direction: row; gap: 2px;
    position: fixed; z-index: 27;
    /*
     * ---- Ao lado do ANALÓGICO ----
     *
     * "perto do analógico os botão de alvo, distância do alvo e lurar."
     *
     * Eles ajustam a caçada, e quem ajusta a caçada é a mão que já está no
     * controle. Encostados na direita dele, na mesma altura, ficam a um
     * centímetro do polegar e fora do caminho da fileira.
     */
    /*
     * ---- Acima do analógico, na quina esquerda ----
     *
     * "o botão alvo, distância e lurar pode ir mais pra esquerda pra não ficar
     * em cima do cronômetro das spells de tempo."
     *
     * Ao lado do controle eles ficavam bem em cima dos primeiros slots — e é
     * ali que o relógio de recarga de uma magia aparece, POR CIMA do quadrado.
     * Subindo para além do controle, a coluna da esquerda inteira é deles e não
     * há mais nada por baixo.
     */
    left: 6px; right: auto;
    transform: none;
    /*
     * ---- E ACIMA do analógico, com folga medida ----
     *
     * "os botão de alvo, distância e lurar não pode ficar por cima do
     * analógico." Estavam por cima por quatro pixels, e a conta era minha: o
     * controle começa a 4px do chão da barra e tem 88 de diâmetro mais 1 de
     * borda de cada lado — 94 no total. 100 não bastava; 106 deixa 6 de
     * respiro.
     */
    bottom: calc(var(--barra-altura, 40px) + 106px);
  }

  /*
   * ---- E o cadeado na PONTA da fileira ----
   *
   * "à direita dos slots de action bar o cadeado."
   *
   * Em coluna, e não em fileira: destrancado ele vira três botões (cadeado,
   * desfazer, copiar), e três em fileira comeriam a faixa que o `#actionbar`
   * reserva à direita — a fileira de slots voltaria a passar por baixo deles.
   * Em coluna eles sobem, que é para onde há espaço.
   */
  #travas-da-caca {
    position: fixed; z-index: 27;
    right: 3px; bottom: 2px;
    display: flex; flex-direction: column-reverse; gap: 2px;
  }
  #travas-da-caca button {
    width: 26px; height: 26px; padding: 0;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 16px; line-height: 1;
    color: #cbd8dbcc;
    background: none; border: 0; border-radius: 0; box-shadow: none;
    text-shadow: 0 1px 2px #000, 0 0 6px #000c;
  }
  /* 26 e nao 30: os quatro pixels de cada um sao 24 de rodape livre, e e' o que
     abre espaco para mais um icone em cada braco do chao. */
  #ajustes-da-caca button {
    width: 26px; height: 26px; padding: 0;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 17px; line-height: 1;
    color: #cbd8dbcc;
    background: none;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    text-shadow: 0 1px 2px #000, 0 0 6px #000c;
  }
  #ajustes-da-caca button[aria-pressed="true"] { color: var(--accent); }

  /* ---- 14. Cada ícone pode ir para onde a pessoa quiser ---- */
  /*
   * "a princípio vinha trancado e a pessoa poderia mover pra qualquer lugar os
   * action bar individualmente."
   *
   * TRANCADO é o padrão de propósito: no celular o toque é o mesmo gesto que
   * usa a habilidade, e um slot que sai do lugar quando se tenta lançar uma
   * magia é pior do que um slot que não se move. Quem quiser arrumar destranca,
   * arruma, e tranca de novo.
   *
   * Solto, o slot vira `fixed` e sai da grade — os outros fecham a fila
   * sozinhos, porque é uma grade. A posição é guardada em FRAÇÃO da tela (ver
   * `mobile.mjs`), e não em pixels: quem arrumou em pé continua achando tudo
   * no lugar depois de girar o telefone.
   */
  /*
   * ---- Trancado, o quadrado VAZIO some ----
   *
   * Com o arranjo pronto, o teclado da direita fica com o que sobrou — e a
   * maior parte dos vinte e dois slots é quadrado vazio. Eles ocupam o mesmo
   * espaço de um cheio e não fazem nada.
   *
   * Voltam assim que se destranca, que é quando eles servem para alguma coisa:
   * é ali que se arrasta uma magia para dentro de um slot livre.
   */
  /*
   * ---- Os 22 aparecem SEMPRE, trancado ou não ----
   *
   * "trancado/destrancado tá mudando de onde os slots ficam" — e mudava mesmo:
   * enquanto trancado, o quadrado vazio sumia, e os cheios corriam para
   * preencher a lacuna. Destrancar para arrumar mostrava uma barra e trancar de
   * volta mostrava outra.
   *
   * Um quadrado vazio ocupa lugar sem fazer nada, e foi por isso que ele sumia.
   * Mas uma barra que muda de forma sozinha custa mais do que os pixels que
   * economiza: a memória da mão é POSIÇÃO, e ela é o que faz apertar sem olhar.
   */

  .slot.solto {
    position: fixed;
    z-index: 24;
    margin: 0;
    /*
     * O tamanho tem de ser DITO aqui.
     *
     * Dentro da grade quem dava largura ao slot era a trilha (34px). Solto, ele
     * sai da grade e passa a se medir pelo conteúdo — e um ícone sem tamanho
     * definido esticava até a largura da tela, o que fazia a trava de "não
     * deixar sair da tela" grampeá-lo no canto esquerdo. O sintoma era o ícone
     * voltar para x=0 sozinho a cada remontagem da fileira.
     */
    /* Do tamanho da casa da barra: com 29px o ícone de 32 tapava a própria
       borda, e "os slots ficam sem borda e a sprite muda de tamanho". */
    width: var(--casa, 29px);
    height: var(--casa, 29px);
  }
  /* Destrancado, todo slot mostra que pode ser pego. */
  body.slots-livres .slot {
    outline: 1px dashed var(--accent);
    outline-offset: 1px;
    /* O navegador não pode entender o arrasto como rolagem da página. */
    touch-action: none;
  }
  body.slots-livres #travas-da-caca button[data-travar] { color: var(--accent); }
  /*
   * O painel abre AO LADO da coluna de ícones, e não mais no canto direito:
   * ele pertence ao botão que o abriu, e um painel que nasce do outro lado da
   * tela obriga o olho a procurar o que acabou de ser tocado.
   */

  /*
   * ---- As habilidades em COLUNAS, e não num bloco ----
   *
   * "deixa em linhas completas na vertical."
   *
   * O bloco de cinco por cinco era um quadrado de 190px de lado no canto: largo
   * o bastante para comer metade da largura da tela justo na altura em que o
   * personagem costuma estar.
   *
   * Em pé ele vira uma faixa estreita colada na borda direita. `grid-auto-flow:
   * column` é o que faz o slot 2 cair EMBAIXO do 1 (e não ao lado): a fileira
   * corre para baixo, e só quando a coluna acaba é que começa a próxima, à
   * esquerda dela.
   *
   * E quantos cabem por coluna não é um número escrito à mão: `auto-fill` sobre
   * uma altura definida conta sozinho. Num telefone pequeno saem menos por
   * coluna e mais colunas; num grande, o contrário. Nenhum slot sai da tela em
   * nenhum dos dois.
   */
  /*
   * `max-content` e não `auto`: o item 7 deste mesmo bloco põe `width: 100%` na
   * fileira (ela era o rodapé de largura cheia), e `auto` não desfaz uma
   * porcentagem — a grade continuava com 811px de caixa mesmo tendo só duas
   * colunas de 34px dentro, e os vinte e dois slots ficavam fora da tela.
   *
   * `max-content` diz o óbvio: a caixa tem a largura do que há nela.
   */
  /*
   * `max-content` e não `auto`: o item 7 deste mesmo bloco põe `width: 100%` na
   * fileira (ela era o rodapé de largura cheia), e `auto` não desfaz uma
   * porcentagem.
   *
   * ---- E o número de fileiras é ESCRITO, não contado ----
   *
   * A primeira versão usava `repeat(auto-fill, 34px)` nas linhas, para a coluna
   * se medir sozinha pela altura da tela. Não funciona, e o motivo é uma
   * armadilha conhecida do grid: para saber a LARGURA que a caixa pede, o
   * navegador calcula antes de ter uma altura definida — e sem altura,
   * `auto-fill` resolve como UMA fileira. Vinte e dois slots viravam vinte e
   * duas colunas, 811px de caixa, e tudo fora da tela.
   *
   * Nove por coluna, então: 9 × 37 = 333px, que cabe com folga num telefone em
   * pé e deixa os vinte e dois slots em três colunas de 111px no total.
   */
  /*
   * ---- UMA fileira só, no rodapé, como no site ----
   *
   * "deixa mais ou menos como é no site: uma linha completa lá embaixo na
   * horizontal, linha única."
   *
   * Ela já foi um teclado de três colunas no canto direito, para caber em pé
   * sem rolagem. O dono jogou nas duas formas e preferiu a do site: uma fileira
   * atravessando o rodapé, que é onde a mão espera encontrá-la.
   *
   * `max-content` e não `auto`: o item 7 deste mesmo bloco põe `width: 100%` na
   * fileira, e `auto` não desfaz uma porcentagem — a grade ficava com 811px de
   * caixa e os slots saíam da tela. `max-content` diz o óbvio: a caixa tem a
   * largura do que há dentro.
   *
   * ---- E deitado ela CABE; em pé ela corre ----
   *
   * Vinte e dois slots de 29px com 3 de folga são 700px: sobra folga numa tela
   * deitada de 914, e não há como caber nos 390 de uma em pé. Em vez de quebrar
   * a fileira em duas (que é o que ele acabou de pedir para não fazer), ela
   * ROLA de lado nas telas estreitas — e quem não quiser rolar arrasta para
   * fora os que usa, que é justamente o que o cadeado serve para fazer.
   */
  /*
   * O desenho dentro do slot também encolhe. Quem escolhe o tamanho é o
   * `actionbar.mjs` (ver `SLOT_ICON_CELULAR`), porque o ícone de magia é um
   * recorte de folha de sprites e o CSS só saberia cortá-lo; isto aqui é para
   * o `canvas` dos itens, que o CSS prendia em 34px.
   */
  .hotbar .slot canvas { width: 24px !important; height: 24px !important; }
  /*
   * E o crachá da tecla some.
   *
   * Ele diz qual tecla dispara o slot — num telefone não há tecla nenhuma, e o
   * cantinho ainda roubava o toque para "escolher a tecla deste slot": era o
   * que impedia de usar a habilidade tocando nela.
   */
  .hotbar .slot .key { display: none; }

  .bar-row { width: 100% !important; }
  .hotbar-stack { width: 100%; height: auto; }
  .hotbar {
    grid-auto-flow: column;
    grid-template-columns: none;
    /* 29px: os 34 menos 15%, como ele pediu quando a barra ainda era coluna.
       Cada pixel a menos aqui é mapa a mais. */
    grid-template-rows: 29px;
    grid-auto-rows: 29px;
    /*
     * ---- 29px é TETO, não obrigação ----
     *
     * Vinte e dois quadrados de 29 com 2 de folga são 680px, e o rodapé ainda
     * reserva as duas faixas laterais (o analógico de um lado, o "Stop" e o
     * cadeado do outro). Num telefone deitado de 844 sobram 666 — treze a
     * menos. Com a largura fixa a fileira vazava; com `minmax` os quadrados
     * encolhem um pixel cada e ninguém percebe.
     */
    grid-auto-columns: minmax(0, 29px);
    gap: 2px;
    width: 100%;
    justify-content: center;
    align-content: end;
    height: auto;
  }
  /*
   * ---- Em pé, DUAS fileiras de onze ----
   *
   * "verticalmente seriam 2 fileiras de 11 cada, pra caber."
   *
   * Vinte e dois quadrados de 29px são 700px: cabem folgados numa tela deitada
   * e em nenhuma tela em pé. Onze por fileira é a metade exata, e o `minmax`
   * deixa os quadrados encolherem nos telefones mais estreitos em vez de
   * empurrar a fileira para fora — 29px é o teto, não a obrigação.
   *
   * `grid-auto-flow: row` e não `column`: as duas fileiras se leem da esquerda
   * para a direita, como no site. Em coluna, o slot 2 ficaria embaixo do 1.
   */
  @media (orientation: portrait) {
    .hotbar {
      grid-auto-flow: row;
      grid-template-columns: repeat(11, minmax(0, 29px));
      /*
       * DUAS fileiras escritas, e não deixadas ao acaso: com as linhas em
       * `auto` o navegador cria quantas precisar, e um slot a mais (ou um
       * arrastado para fora, que sai da grade) refazia a conta e deixava a
       * fileira de cima com um número diferente da de baixo — era o que ele
       * viu como "quebrado".
       */
      grid-template-rows: repeat(2, 29px);
      grid-auto-rows: 29px;
      /* As duas fileiras centradas UMA SOBRE A OUTRA: sem isto, a de cima
         alinha à esquerda e a de baixo também, mas com contagens diferentes o
         olho vê um degrau. */
      justify-content: center;
      align-content: end;
      gap: 2px;
      width: 100%;
      max-width: 341px;
    }
    .hotbar-stack, .bar-row { width: 100% !important; }
  }

  /*
   * ---- Em pé a gaveta encolhe, mas continua APOIADA na barra ----
   *
   * Ela encolhe de 46vh para 38vh, que é o corte descrito acima e deixa mais
   * mapa à vista. O que mudou aqui foi o `bottom`.
   *
   * Havia `bottom: 8px`, com a explicação de que "com a barra no canto ela não
   * precisa mais se apoiar na altura dela". A barra não está no canto em pé:
   * logo acima, nesta mesma regra, ela é uma fileira dupla de onze slots
   * ocupando a largura toda, 64 pixels colados no rodapé. A gaveta descia para
   * debaixo dela, e os 56 pixels de baixo da mochila ficavam tapados — dava
   * para ver o item e não dava para tocar nele.
   *
   * Voltando ao `--gaveta-chao`, ela para em cima da barra. E a altura sai de
   * `--gaveta-altura` em vez de um número escrito aqui: quem flutua no rodapé
   * (o presente, os buffs) calcula a posição a partir dessas duas medidas, e
   * com um número solto aqui eles subiriam a altura errada.
   */
  :root { --gaveta-altura: min(38dvh, 380px); }
  .window:not(.solta) {
    max-height: 38dvh !important;
  }

  /* ---- 15. DEITADO, as janelas encostam nas BORDAS e o mapa fica no meio ---- */
  /*
   * "se possível deixa o celular pra ficar igual as foto aí."
   *
   * Nas fotos (a base de referência, a base de OTClient do dono) o telefone deitado tem
   * duas colunas de painel encostadas nas bordas e o mapa inteiro entre elas. O
   * jogo fazia o contrário: as janelas eram uma gaveta de meia tela no rodapé,
   * e com a mochila aberta o personagem ficava atrás dela.
   *
   * Deitado sobra LARGURA e falta ALTURA — o contrário do telefone em pé, e por
   * isso o desenho também é o contrário. A janela passa a ocupar a altura
   * inteira entre a barra de cima e a de ações, com a largura de uma coluna, e
   * nada dela cai no meio da tela.
   *
   * ---- Uma de cada lado, e não uma só ----
   *
   * `--gaveta-em-coluna` é lida pelo `windows.mjs` (o mesmo trato do
   * `--e-celular`: a decisão mora na folha de estilo, e o JS pergunta). Com ela
   * acesa, "uma gaveta por vez" vira "uma por LADO" — que é o arranjo da foto,
   * chat de um lado e bolsa do outro.
   *
   * 31vw é o teto: em 844px de largura a coluna fica com 261, e sobram 320 de
   * mapa entre as duas mesmo com as duas abertas.
   */
  @media (orientation: landscape) {
    :root {
      --gaveta-em-coluna: 1;
      --coluna-largura: min(268px, 31vw);
    }

    .window:not(.solta) {
      /*
       * Do rodapé da barra de cima até o teto da barra de ações. As duas são
       * MEDIDAS (`--altura-da-topbar` e `--barra-altura`, publicadas pelo JS) e
       * não números: a barra de ações encolhe quando o personagem tem poucas
       * magias, e a coluna acompanha em vez de descolar.
       */
      top: calc(var(--altura-da-topbar, 46px) + var(--altura-do-aviso, 0px) + 4px) !important;
      bottom: calc(var(--barra-altura, 40px) + 4px) !important;
      height: auto !important;
      max-height: none !important;
      width: var(--coluna-largura) !important;
      /* As âncoras de mesa são inline (`applyLayout`): as duas precisam ser
         desfeitas, senão a janela fica presa no `left` que o arranjo gravou. */
      left: auto !important;
      right: auto !important;
      /* A moldura afina mais um pouco: numa coluna de 261px, 14 de cada lado
         já são um décimo da largura útil. */
      border-width: 30px 12px 14px 12px;
    }
    /*
     * ---- E cada coluna PARA antes do canto do polegar ----
     *
     * As duas quinas de baixo já são de outra coisa, e uma coluna que desce até
     * a barra passaria por cima das duas — com z-index maior, porque a janela
     * sobe ao ser tocada.
     *
     * ESQUERDA: o analógico (2px do chão, 88 de diâmetro → topo em 90) e, logo
     * acima dele, a fileira de alvo/distância/lurar (98 do chão, 26 de altura →
     * topo em 124). 128 deixa quatro de respiro sobre os dois.
     *
     * DIREITA: o selo de recompensas, que mora a `--barra-altura + 6` e tem uns
     * 34 de altura. 44 acima da barra o libera.
     *
     * Os dois são somas de medidas escritas aqui mesmo neste bloco — se um dia
     * o analógico mudar de tamanho, é aqui que a conta desencontra, e é por isso
     * que ela está escrita por extenso em vez de ser um número solto.
     */
    .window:not(.solta)[data-lado="esq"] { left: 4px !important; bottom: 128px !important; }
    .window:not(.solta)[data-lado="dir"] {
      right: 4px !important;
      bottom: calc(var(--barra-altura, 40px) + 44px) !important;
    }
    /*
     * Minimizada ela vira só o cabeçalho, colada no TOPO da coluna — sem isto
     * o `height: auto` a esticaria de ponta a ponta com o corpo escondido, e um
     * retângulo vazio de tela inteira tapava o mapa.
     */
    .window.minimized { bottom: auto !important; height: auto !important; }
    /* O corpo é quem rola: a moldura fica parada, como no modal. */
    .window > .window-body {
      overflow-y: auto;
      -webkit-overflow-scrolling: touch;
      overscroll-behavior: contain;
    }
  }

  /* ---- 16. O DESENHO DO REFERÊNCIA: painéis flutuando sobre o mapa ---- */
  /*
   * "quero que fique mais ou menos assim, igual da foto."
   *
   * A foto é a base de referência no telefone: o mapa ocupa a tela INTEIRA e tudo o mais
   * flutua por cima dele em painéis escuros e arredondados. No canto de cima à
   * esquerda, a ficha (vida, mana, um fio de experiência, o level e a stamina)
   * e uma coluna de três botões redondos ao lado dela; no canto de cima à
   * direita, a carteira, a placa da loja e o MENU; embaixo à esquerda o
   * analógico; embaixo à direita dois botões redondos; e no rodapé a barra de
   * habilidades com setas nas pontas e o STOP no fim.
   *
   * Tudo abaixo vem DEPOIS dos itens 1 a 15 de propósito: mesma especificidade,
   * quem vem depois manda. Onde o item antigo usou `!important`, aqui também.
   *
   * O que o JS cria (ver `ornamentosDoCelular`, no mobile.mjs): o botão MENU, a
   * coluna de atalhos da ficha, os dois botões da direita, as setas da barra e
   * a linha do level. O resto é o que já existia, só posto no lugar da foto.
   */
  :root {
    /* Não há mais barra de cima: o que morava nela virou painéis soltos. */
    --altura-da-topbar: 0px;
    --ficha-largura: min(236px, calc(100vw - 232px));
    /*
     * ---- A CASA: o tamanho de um slot ----
     *
     * Em pé cabem SETE por fileira: a tela menos as duas setas (30px cada) e
     * os seis vãos de 4px, dividida por sete, com teto de 46px. Numa tela de
     * 360 dá 40; numa de 430, os 46 inteiros. Tudo o que se alinha com a
     * fileira (o STOP, a altura das setas) se mede por esta variável.
     */
    --casa: min(36px, calc((100vw - 150px) / 7));
  }

  /* ---- A barra de cima some; o que era dela vira painel ---- */
  #topbar {
    height: 0 !important; padding: 0 !important; border: 0 !important;
    background: none !important; overflow: visible; pointer-events: none;
  }
  #topbar > * { pointer-events: auto; }
  #topbar .brand, #topbar .online, #topbar-min, #topbar .identity { display: none !important; }
  /*
   * ---- A barra recolhida do PC não pode esconder o MENU do celular ----
   *
   * "no S24+ ao clicar não abre as coisas" (02/10): o rastro mostrava o menu e
   * as gavetas ABERTOS no DOM e nada na tela. O ▼ da barra de cima (do layout
   * de mesa) fica guardado no navegador (`mineiroidle:topbar-min`), e a regra dele,
   * `body.topbar-recolhida #topbar > *:not(#topbar-min) { display: none }`,
   * tem um id no `:not()` e por isso vencia a grade do MENU; a gaveta tem a
   * dela própria. Quem recolheu a barra uma vez no telefone (ou no deitado)
   * ficava sem menu para sempre. O `display: revert` que havia aqui perdia
   * por especificidade e, se vencesse, mostraria a grade o tempo todo.
   */
  body.topbar-recolhida.menu-aberto #topbar .tools:not(#topbar-min) { display: grid; }
  body.topbar-recolhida .gaveta-da-barra:not([hidden]) { display: flex; }

  /*
   * A carteira mora na FICHA, em cima do retrato e das réguas.
   *
   * "o dinheiro e as mineiroidle coins no mobile, pode colocar junto no card do
   * boneco, de preferência em cima." O `mobile.mjs` move o `.wallets` da barra
   * de cima para dentro do `#hud` (e devolve quando a tela deixa de ser de
   * celular); aqui ela vira a primeira linha da grade, atravessando as duas
   * colunas, com o ouro à esquerda e as coins à direita.
   */
  /*
   * "a quantidade de dinheiro e mineiroidle coins tem que ser embaixo da ficha e sem
   * fundo, só flutuante." A carteira é a ÚLTIMA linha da grade da ficha (assim
   * o `placePromotion` do hud.mjs, que pendura o card da promoção no
   * `getBoundingClientRect` da ficha, já a pula), mas o cartão desenhado pelo
   * `::before` acaba antes dela: os números ficam soltos sobre o mapa.
   */
  #hud > .wallets {
    grid-column: 1 / -1; position: static; order: 99;
    display: flex; flex-direction: row; justify-content: space-between; align-items: center; gap: 8px;
    margin: 0; padding: 0 4px; min-width: 0; height: 16px;
  }
  .wallet { font-size: 11px; gap: 4px; min-width: 0; text-shadow: 0 1px 2px #000, 0 0 4px #000; }
  .wallet b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .wallet .coin-icon { width: 15px; height: 15px; filter: drop-shadow(0 1px 1px #000c); }
  .wallet .coin-icon canvas { width: 15px; height: 15px; }
  /* Com o medidor ligado a ficha reserva a linha dele embaixo da carteira. */
  body.com-medidor #hud > .wallets { margin-bottom: 24px; }
  body.com-medidor #hud::before { bottom: 40px; }
  /*
   * A loja: o emblema redondo ("esse seria o ícone clicável da mineiroidle store"),
   * ao lado do MENU. O `mobile.mjs` troca a imagem da placa pelo emblema. Sem
   * o anel que orbita a placa de mesa: ele contornava um quadrado.
   */
  #store-button { display: none; }
  #store-button::after { display: none; }
  #market-button { display: none; }

  /* O MENU: um botão de canto que abre a fileira de ferramentas. */
  #menu-do-celular {
    position: fixed; z-index: 31;
    top: var(--morta-topo); right: var(--morta-direita);
    width: 54px; height: 50px; padding: 0;
    display: grid; place-items: center; align-content: center; gap: 1px;
    background: #0b0f11e0; border: 1px solid #ffffff22; border-radius: 10px;
    box-shadow: 0 3px 10px #0009;
    color: #ece4cf; font-family: var(--font-heading); font-size: 8px; font-weight: 700; letter-spacing: .1em;
  }
  #menu-do-celular::before { content: '☰'; font-size: 20px; line-height: 1; }
  body.menu-aberto #menu-do-celular { border-color: var(--accent); color: var(--accent); }

  /*
   * A fileira de ferramentas vira uma GRADE pendurada no MENU. Os botões
   * continuam sendo os mesmos (com as gavetas de cada grupo e tudo): só o
   * lugar mudou. O mercado, que era um botão à parte na barra, entra aqui
   * (o JS o move para dentro do `#tools`).
   */
  #topbar .tools { display: none; }
  body.menu-aberto #topbar .tools {
    display: grid; position: fixed; z-index: 31;
    top: calc(var(--morta-topo) + 56px); right: var(--morta-direita); left: auto;
    /* `max-content`: a fileira de mesa é `flex: 1` e esticava o quadro até a
       borda esquerda, com as quatro colunas encostadas lá ("o menu em pé abre
       mais pra esquerda"). Do tamanho das colunas, ele fica pendurado no MENU. */
    width: max-content; min-width: 0; flex: none;
    grid-template-columns: repeat(4, 60px); gap: 6px;
    padding: 8px; margin: 0;
    background: #0b0f11f2; border: 1px solid #ffffff22; border-radius: 12px;
    box-shadow: 0 8px 24px #000c;
    max-height: calc(100dvh - 80px); overflow-y: auto;
    justify-content: start;
  }
  .tools .divider { display: none; }
  /*
   * "o menu não aparece Opções no mobile": Cidade, Opções e Sair vivem num
   * `<span class="canto-da-barra">` que na barra de mesa vai para a ponta
   * direita. Na grade ele era UMA célula de 60px com três botões espremidos
   * dentro, fora da vista. `display: contents` dissolve o span e os três viram
   * células como as outras.
   */
  .tools .canto-da-barra { display: contents; }
  .tools button, .tools #market-button {
    width: 60px; height: 60px; padding: 3px; margin: 0; position: static;
    display: grid; grid-template-rows: 1fr auto; place-items: center;
    background: #121a1e; border: 1px solid #ffffff14; border-radius: 9px;
  }
  .tools #market-button { display: grid; }
  .tools button img, .tools #market-button img { width: 30px; height: 30px; }
  .tools button .label, .tools #market-button .label { display: block; font-size: 8px; color: #b9c6cb; }
  /* A loja é uma célula como as outras (o JS a move para cá), sem o brilho da placa. */
  .tools #store-button {
    display: grid; position: static; width: 60px; height: 60px; padding: 3px; margin: 0;
    grid-template-rows: 1fr auto; place-items: center; line-height: normal;
    background: #121a1e; border: 1px solid #ffffff14; border-radius: 9px;
    animation: none; filter: none; transform: none;
  }
  .tools #store-button img { width: 36px; height: 36px; }
  .tools #store-button .label { display: block; font-size: 8px; color: #b9c6cb; }

  /* ---- A FICHA: o retrato com o balão do level e as QUATRO réguas ---- */
  /*
   * "faltou as barras de nível, xp, stamina, mana lá em cima e o balãozinho do
   * level atual, e nas barras faltou o iconezinho igual do normal."
   *
   * O retrato fica à esquerda só pelo balão do level que mora nele; nome,
   * vocação e os três botões do card somem. As réguas são as mesmas quatro do
   * card, com o ícone dentro como na fita do rodapé (`.bars-dock`).
   */
  #hud {
    left: var(--morta-lado); width: var(--ficha-largura);
    padding: 6px 8px 0 6px; gap: 6px;
    grid-template-columns: auto minmax(0, 1fr); align-items: center;
    border: 0 !important; border-image: none !important;
    background: none; box-shadow: none;
  }
  /* O cartão: cobre o retrato e as réguas, e para antes da carteira (16px). */
  #hud::before {
    content: ''; position: absolute; inset: 0 0 16px 0; z-index: -1;
    border: 1px solid #ffffff22; border-radius: 12px;
    background: #0b0f11d9; box-shadow: 0 4px 14px #0008;
  }
  #hud .hud-top { display: block; }
  #hud .hud-id, #hud-sheet, #hud-min, #hud-dock-btn { display: none !important; }
  #hud-portrait { display: block; position: relative; width: 40px; height: 40px; }
  #hud-portrait canvas { width: 40px; height: 40px; }
  #hud .hud-level { left: -5px; bottom: -4px; font-size: 10px; }
  #hud.minimized #hud-body, #hud #hud-body { display: block !important; }
  #hud .hud-bars { gap: 3px; }
  #hud .hud-bar { height: 15px; border-radius: 4px; border-color: #000c; }
  #hud .hud-bar.exp, #hud .hud-bar.stamina { height: 13px; }
  #hud .hud-bar span { font-size: 10px; line-height: 13px; padding-left: 14px; }
  #hud .bar-icon {
    display: block; position: absolute; left: 3px; top: 50%; transform: translateY(-50%);
    height: 10px; width: auto; z-index: 2; pointer-events: none;
  }
  #hud .bar-dot { width: 10px; }
  /* O card da promoção, compacto, embaixo da ficha. */
  #hud-promotion {
    left: var(--morta-lado); width: var(--ficha-largura); top: calc(var(--topo-do-hud) + 98px);
    padding: 5px 8px; gap: 0; border-radius: 8px;
  }
  #hud-promotion b { font-size: 11px; }
  #hud-promotion em { font-size: 9px; }
  /*
   * ---- O aviso de desenvolvimento some, e as novidades viram um BALÃO ----
   *
   * "já pode tirar a faixa e o aviso que aparece quando loga, e a faixa de
   * novidades será só um balãozinho que clica e abre."
   *
   * A faixa continua sendo o mesmo elemento (com o mesmo clique que abre as
   * novidades): só o desenho muda — um círculo dourado com um ponto de
   * exclamação, embaixo dos três atalhos.
   */
  #aviso-dev, #cartaz-beta { display: none !important; }
  body.com-aviso { --altura-do-aviso: 0px; }
  body { --topo-do-hud: var(--morta-topo); }
  /*
   * A pilha da esquerda: ficha, depois o card da promoção. `--altura-da-ficha`
   * (medida pelo hud.mjs) soma os dois, e é dela que as janelas deitadas se
   * penduram. No BODY, e não no :root: `--topo-do-hud` mora no body, e uma
   * variável do :root não enxerga o body — a conta dava inválida e as janelas
   * nasciam no topo da tela, por baixo da carteira.
   */
  body { --pilha-da-esquerda: calc(var(--topo-do-hud) + var(--altura-da-ficha, 96px) + 6px); }
  body.com-medidor { --pilha-da-esquerda: calc(var(--topo-do-hud) + var(--altura-da-ficha, 96px) + 28px); }
  /* "tira o ping/fps dali, pode colocar embaixo da stamina": a ficha não desce
     mais para dar lugar ao medidor; ele fica colado embaixo dela. */
  body.com-medidor #hud { top: var(--topo-do-hud); }
  #medidor {
    top: calc(var(--topo-do-hud) + 103px); left: var(--morta-lado); width: var(--ficha-largura);
    justify-content: center; padding: 1px 6px; font-size: 9px; border-radius: 6px;
  }
  body.com-medidor #hud-promotion { top: calc(var(--topo-do-hud) + 120px); }
  #faixa-novidades {
    top: calc(var(--topo-do-hud) + 3 * 37px + 14px); left: calc(var(--morta-lado) + var(--ficha-largura) + 6px);
    transform: none; width: 32px; height: 32px; min-height: 0; max-width: none; padding: 0;
    border: 1px solid #d9ae4a; border-radius: 50%; box-shadow: 0 2px 6px #0009, 0 0 8px #d9ae4a44;
    display: grid; place-items: center; overflow: visible;
  }
  #faixa-novidades > * { display: none; }
  #faixa-novidades::before { content: '!'; font-family: var(--font-heading); font-size: 17px; font-weight: 700; color: #ffe6a3; line-height: 1; }
  /* Os cards de vocação da forja em pé: cinco numa fileira de 360px quebravam
     "KNI GHT" letra a letra; em três colunas cada nome cabe inteiro. */
  @media (orientation: portrait) { #modal-body .craft-vocs, #modal-body .craft-sets { grid-template-columns: repeat(3, minmax(0, 1fr)) !important; } }
  /* O aviso passageiro sai do topo, que agora é dos painéis, e fica sobre o mapa. */
  #notice { top: 42%; max-width: 80vw; text-align: center; }

  /* Os três atalhos ao lado da ficha: personagem, inventário e chat. */
  #atalhos-da-ficha {
    position: fixed; z-index: 24;
    top: var(--topo-do-hud); left: calc(var(--morta-lado) + var(--ficha-largura) + 6px);
    display: flex; flex-direction: column; gap: 5px;
  }
  .atalho-redondo {
    width: 32px; height: 32px; padding: 4px; margin: 0;
    border-radius: 50%; background: #0b0f11e0; border: 1px solid #ffffff2a;
    box-shadow: 0 2px 6px #0009; display: grid; place-items: center;
  }
  .atalho-redondo img { width: 100%; height: 100%; object-fit: contain; display: block; }
  .atalho-redondo[aria-pressed="true"] { border-color: var(--accent); box-shadow: 0 0 8px #3fbfa877; }

  /* ---- O ANALÓGICO: o disco da foto, com as quatro setas ---- */
  #analogico {
    left: var(--morta-lado); bottom: calc(var(--barra-altura, 60px) + 22px);
    width: 118px; height: 118px;
    background:
      url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cg fill='%23b8c7d6' fill-opacity='.85'%3E%3Cpath d='M50 7l6 9H44z'/%3E%3Cpath d='M50 93l-6-9h12z'/%3E%3Cpath d='M7 50l9-6v12z'/%3E%3Cpath d='M93 50l-9 6V44z'/%3E%3C/g%3E%3C/svg%3E") center / 100% 100% no-repeat,
      radial-gradient(circle at 50% 45%, #1b2429e8, #0b1013e6 68%, #05080ab0);
    border: 2px solid #ffffff2e;
    box-shadow: 0 8px 20px #000a, inset 0 0 0 5px #ffffff0a;
    opacity: .94;
  }
  #analogico::before, #analogico::after { display: none; }
  .analogico-bola {
    width: 54px; height: 54px; margin: -27px 0 0 -27px;
    background: radial-gradient(circle at 40% 35%, #92b3d2, #4b6f95 58%, #22384e);
    border: 1px solid #0c1214;
    box-shadow: 0 3px 10px #000c, inset 0 1px 0 #ffffff33;
  }

  /* ---- O alvo: um botão pequeno à esquerda do cadeado, na linha de baixo ---- */
  /* "o ícone da crosshair coloca próximo ao analógico, ao lado do cadeado, e
     pode ser menor." Em pé: [alvo][cadeado] embaixo da seta ‹; deitado: [alvo][🔒][‹]. */
  /* "coloca perto do botão de ataque automático": o alvo mora na coluna da
     direita, em cima dos dois automáticos (que só existem na caçada). */
  #botoes-da-direita {
    position: fixed; z-index: 27;
    right: var(--morta-direita); left: auto;
    bottom: calc(var(--barra-altura, 60px) + 8px);
    display: flex;
  }
  body.em-caca.manual #botoes-da-direita { bottom: calc(var(--barra-altura, 60px) + 8px + 2 * 48px); }
  .botao-redondo {
    width: 40px; height: 40px; padding: 7px; margin: 0;
    border-radius: 50%; border: 1px solid #d9c07a;
    background: radial-gradient(circle at 50% 40%, #171f24, #06090b);
    box-shadow: 0 0 6px #d9ae4a44, 0 2px 6px #000a;
    display: grid; place-items: center; color: #efe3b8;
  }
  .botao-redondo img, .botao-redondo svg { width: 100%; height: 100%; display: block; }
  .botao-redondo[aria-pressed="true"] { border-color: var(--accent); color: var(--accent); }

  /*
   * Os ajustes da caçada (alvo, distância, lurar) e o cadeado ficam GUARDADOS
   * atrás do botão de alvo: tocar nele abre a coluna ao lado, tocar de novo
   * fecha. Destrancado, o cadeado continua à vista para poder trancar.
   */
  #ajustes-da-caca, #travas-da-caca { display: none; }
  body.ajustes-abertos #ajustes-da-caca,
  body.ajustes-abertos #travas-da-caca,
  body.slots-livres #travas-da-caca { display: flex; }
  /* A fileira de ajustes abre CENTRADA em cima da barra: o alvo agora mora na
     esquerda, junto do analógico, e uma coluna ali cairia em cima dele. */
  /* "tem que abrir perto do analógico": à direita dele, em cima da barra. Em pé
     o analógico (118px) acaba em x=138; deitado (104px), em x=116. */
  #ajustes-da-caca {
    flex-direction: row-reverse; gap: 6px;
    right: 56px; left: auto; transform: none;
    bottom: calc(var(--barra-altura, 60px) + 8px);
  }
  body.em-caca.manual #ajustes-da-caca { bottom: calc(var(--barra-altura, 60px) + 8px + 2 * 48px); }
  #travas-da-caca {
    flex-direction: column-reverse; gap: 6px;
    right: 118px; bottom: calc(var(--barra-altura, 60px) + 82px);
  }
  #ajustes-da-caca button, #travas-da-caca button {
    width: 40px; height: 40px; border-radius: 50%;
    background: #0b0f11e0; border: 1px solid #ffffff2a; box-shadow: 0 2px 6px #0009;
    font-size: 18px; color: #e8e0cc;
  }
  body[data-ajuste] .controls {
    right: 8px; left: auto; transform: none; bottom: calc(var(--barra-altura, 60px) + 56px);
    max-width: calc(100vw - 16px);
  }
  body.em-caca.manual[data-ajuste] .controls { bottom: calc(var(--barra-altura, 60px) + 56px + 2 * 48px); }
  /* Sem o rótulo dentro do painel: o ícone da fileira já diz qual é ("ficou
     duplicado"). Sobra o seletor. */
  body[data-ajuste] .controls .rotulo { display: none; }
  /*
   * ---- A Caça Online no telefone DEITADO ----
   *
   * O braço de mesa da caça online (`@media (min-width: 901px) body.manual`, lá
   * em cima) vale a partir de 901px — e o telefone deitado tem 914. Ele punha o
   * chip "prox ▾" do Alvo dentro da barra (o "alvo duplicado") e vestia o
   * seletor do painel com a roupa do chip (26px, texto transparente): o painel
   * "quebrava". Aqui o braço some e o seletor volta a ser um seletor.
   */
  body.manual .bar-row .controls { display: none; }
  body[data-ajuste] .controls .ctl-curto { display: none !important; }
  body[data-ajuste] .controls-row > label:has(#strategy) { flex-direction: column; padding: 0; }
  body[data-ajuste] .controls-row #strategy {
    -webkit-appearance: auto; appearance: auto;
    width: 100%; height: auto; padding: 8px 10px;
    color: var(--text); font-size: 13px; text-indent: 0;
    background: #161d20;
  }
  /* Os botões de ajuste que a caça online não usa (o main.mjs esconde o
     seletor deles) não aparecem: tocar abriria um painel vazio. */
  /* Na caçada manual a fileira não existe: o alvo abre o painel direto
     (`data-ajuste="tudo"`, posto pelo mobile.mjs) com o que sobra — só o
     seletor do Alvo, já que o main.mjs esconde distância e lurar lá. */
  body.manual #ajustes-da-caca { display: none !important; }
  body.manual[data-ajuste="tudo"] #actionbar .controls label:not([hidden]) { display: grid; gap: 4px; }

  /* ---- A BARRA: um painel no rodapé, setas nas pontas, STOP no fim ---- */
  /*
   * A barra tem 26 slots em duas fileiras, e a foto tem onze quadrados
   * grandes. A saída é uma PÁGINA por fileira: a seta troca entre a fileira de
   * cima (curas, mana, velocidade, suporte) e a de baixo (ataque e
   * ferramentas). Quem esconde é o `data-fileira` do `body`, posto pelo JS. Em
   * pé a fileira da vez quebra em 7 + 6; deitada cabe inteira.
   */
  body[data-fileira="1"] #hotbar .slot:nth-child(n + 14) { display: none; }
  body[data-fileira="2"] #hotbar .slot:nth-child(-n + 13) { display: none; }
  /* Um slot SOLTO não é de página nenhuma: "coloco uns slots pra lá e tranco;
     quando volto na setinha eles não aparecem". Ele fica, seja qual for a fileira. */
  body[data-fileira] #hotbar .slot.solto { display: grid !important; }
  /* "tira as bordas da barra, deixa só os slots e as setinhas perto do
     primeiro e do último slot": a barra não tem fundo nem risco em cima. */
  #actionbar {
    padding: 6px 30px var(--chao) 30px !important;
    background: none !important;
    border: 0 !important;
    box-shadow: none;
    overflow: visible !important;
  }
  .hotbar {
    grid-auto-flow: row;
    grid-template-columns: repeat(7, var(--casa));
    grid-template-rows: repeat(2, var(--casa));
    grid-auto-rows: var(--casa);
    gap: 4px; max-width: none; justify-content: center;
    counter-reset: casa;
  }
  .hotbar .slot {
    border-radius: 7px; border: 1px solid #5a6a72; background: #0f1416;
    box-shadow: inset 0 0 0 1px #000c, 0 1px 2px #0008;
  }
  .hotbar .slot.filled { border-color: #8496a0; background: #141b1f; box-shadow: inset 0 0 0 1px #000c, 0 0 6px #ffffff10; }
  /* O ícone cresce junto com o quadrado: o JS o recorta em 24px. */
  /* Escala pelo tamanho do RECORTE (`--recorte`, posto pelo `spellIcon`): a barra
     montada no tamanho de mesa (34px) e a de celular (24px) ficam as duas com 36px
     dentro do slot, em vez de a primeira estourar a moldura. */
  .hotbar .slot .spell-icon { transform: scale(calc(32 / var(--recorte, 24))); }
  .hotbar .slot .rune-mark { transform: scale(1.33); }
  .hotbar .slot canvas { width: 32px !important; height: 32px !important; }
  /* O número do quadrado, como na foto: é a POSIÇÃO na fileira, não a tecla. */
  .hotbar .slot::before {
    counter-increment: casa; content: counter(casa);
    position: absolute; left: 3px; bottom: 1px; z-index: 3; pointer-events: none;
    font-family: var(--font-heading); font-size: 9px; font-weight: 700; line-height: 1;
    color: #efe8d2; text-shadow: 0 1px 2px #000, 0 0 3px #000;
  }
  .hotbar .slot .papel { display: block; width: 12px; height: 12px; top: 2px; left: 2px; }
  #seta-esq, #seta-dir {
    position: fixed; z-index: 27;
    bottom: calc(var(--barra-altura, 60px) / 2 - 17px);
    width: 28px; height: 34px; padding: 0; margin: 0;
    background: none; border: 0; box-shadow: none;
    color: #efe3b8; font-size: 22px; line-height: 1; text-shadow: 0 1px 2px #000, 0 0 4px #000;
  }
  /* Coladas na fileira (7 casas + 6 vãos de 4px, centrada), não na borda da tela.
     Em pé as setas ficam na altura da fileira de CIMA, e o cadeado embaixo da
     seta da esquerda, na altura da fileira de baixo: não sobra largura para os
     dois lado a lado numa tela de 412. */
  #seta-esq, #seta-dir { bottom: calc(var(--chao) + 1.5 * var(--casa) + 4px - 17px); }
  #seta-esq { left: calc(50% - 3.5 * var(--casa) - 12px - 30px); }
  #seta-dir { right: calc(50% - 3.5 * var(--casa) - 12px - 30px); }
  #cadeado-da-barra {
    position: fixed; z-index: 27;
    left: calc(50% - 3.5 * var(--casa) - 12px - 30px); bottom: calc(var(--chao) + 0.5 * var(--casa) - 13px);
    width: 28px; height: 26px; padding: 0; margin: 0;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 15px; line-height: 1; color: #cbd8dbcc;
    background: none; border: 0; border-radius: 0; box-shadow: none;
    text-shadow: 0 1px 2px #000, 0 0 6px #000c;
  }
  body.slots-livres #cadeado-da-barra { color: var(--accent); }
  /* O STOP: um quadrado dourado, do tamanho de um slot, na casa que sobra. */
  body.em-caca #leave-hunt {
    width: var(--casa); height: var(--casa); min-height: 0; min-width: 0; padding: 0;
    left: calc(50% + 2.5 * var(--casa) + 12px); right: auto; bottom: var(--chao);
    border: 2px solid #d9ae4a; border-image: none; border-radius: 8px;
    background: linear-gradient(180deg, #4a3510, #1c1306);
    color: #ffe3a0; font-size: 9px; letter-spacing: .06em; text-shadow: 0 1px 1px #000;
    filter: none; box-shadow: 0 0 8px #d9ae4a55, inset 0 1px 0 #ffffff1a;
  }
  /* O STOP é parte da barra: não sobe com a gaveta como subia solto. */
  @media (orientation: portrait) {
    body.com-gaveta #leave-hunt { bottom: var(--chao) !important; }
    /*
     * Com uma janela aberta, a gaveta toma o rodapé inteiro: o analógico, os
     * botões redondos e os ajustes sobem para cima dela, como o presente e os
     * buffs já sobem (item 1). Por baixo dela eles ficariam inalcançáveis.
     */
    /* 44px e não 10: o cabeçalho da janela (a alça do arrasto) fica 25px ACIMA
       do corpo dela, e com 10 o analógico pousava em cima da alça. */
    body.com-gaveta:has(.window:not([hidden]):not(.solta):not([data-window-id="inventory"])) #analogico {
      bottom: calc(var(--gaveta-chao) + var(--gaveta-altura) + 44px) !important;
    }
    body.com-gaveta:has(.window:not([hidden]):not(.solta):not([data-window-id="inventory"])) #ajustes-da-caca,
    body.com-gaveta:has(.window:not([hidden]):not(.solta):not([data-window-id="inventory"])) #travas-da-caca {
      bottom: calc(var(--gaveta-chao) + var(--gaveta-altura) + 104px) !important;
    }
    body.com-gaveta:has(.window:not([hidden]):not(.solta):not([data-window-id="inventory"]))[data-ajuste] .controls { bottom: calc(var(--gaveta-chao) + var(--gaveta-altura) + 104px) !important; }
  }
  /* O selo de recompensas vai para o meio, entre o analógico e os botões. */
  #presente {
    left: 50% !important; right: auto !important; transform: translateX(-50%) !important;
    bottom: calc(var(--barra-altura, 60px) + 8px) !important;
    max-width: 40vw;
  }

  /* ---- 17. As telas que vinham MAIORES que o telefone ---- */
  /*
   * "qualquer aba que eu abro tipo store, x1, mercado, praticamente todas vem
   * maior que o celular aceita."
   *
   * Medido com `.scratch/foto-modais.mjs`, tela por tela. Três causas, e
   * nenhuma delas era a moldura do modal (que já cabia):
   *
   *   1. O CABEÇALHO do modal tem 38px de altura e `overflow: hidden`, e é lá
   *      que várias telas penduram os seus controles (`#modal-acoes`): os
   *      filtros do Mercado, as abas da Arena, o Voltar/Confirmar. Numa tela
   *      de 390px eles não cabem ao lado do título e somem cortados. Aqui o
   *      título encolhe e a fila de controles ROLA DE LADO.
   *   2. A LOJA tem altura fixa de 86vh e uma coluna de seções que não rola:
   *      em pé, a lista de seções empurrava a prateleira e o rodapé para
   *      fora. As seções viram uma fita que rola de lado, e a prateleira fica
   *      com a altura que sobra.
   *   3. O DEPÓSITO desenha a caixa como um quadrado de 10 colunas de 44px
   *      (480px): a grade vazava 55px pela direita. Aqui ela quebra em quantas
   *      colunas couberem.
   */
  .modal-box > header { overflow: visible; }
  .modal-box > header h2 { flex: 0 1 auto; max-width: 44%; font-size: 14px; }
  .modal-box > header #modal-acoes {
    flex: 1 1 auto; min-width: 0; margin-right: 4px;
    overflow-x: auto; overflow-y: hidden; scrollbar-width: none; -webkit-overflow-scrolling: touch;
    flex-wrap: nowrap;
  }
  .modal-box > header #modal-acoes::-webkit-scrollbar { display: none; }
  .modal-box > header #modal-acoes > *, .modal-box > header .tabs, .modal-box > header .balcao-peneira { flex: none; flex-wrap: nowrap; }
  .modal-box > header .tabs button, .modal-box > header select, .modal-box > header button { white-space: nowrap; }
  /* O × fica na ponta direita (sem isto ele colava no título encurtado) e ganha
     tamanho de dedo. */
  .modal-box > header #modal-close { margin-left: auto; min-width: 38px; min-height: 34px; flex: none; }
  /* A Arena pendura as abas em posição absoluta: a fila começa na esquerda e rola. */
  .modal-box.arena > header #modal-acoes { left: 6px; right: 48px; justify-content: flex-start; }

  /* A loja: moldura comum, altura pelo que couber, seções em fita. */
  .modal-box.store {
    height: auto; max-height: calc(100dvh - 14px);
    border-width: 40px 14px 18px 14px;
    border-image-source: url(/client/assets/ui/padrao.png);
    border-image-slice: 150 110 130 110 fill;
  }
  .modal-box.store > header { top: -34px; left: 14px; right: 20px; }
  .modal-box.store .store-layout { display: flex !important; flex-direction: column; gap: 8px; }
  .modal-box.store .store-sections {
    display: flex; flex-wrap: nowrap; gap: 5px; flex: none;
    overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; padding-bottom: 2px;
  }
  .modal-box.store .store-sections::-webkit-scrollbar { display: none; }
  .modal-box.store .store-sections button { flex: none; padding: 6px 10px; font-size: 11px; white-space: nowrap; }
  .modal-box.store .store-sections button > img { width: 22px; height: 22px; }
  .modal-box.store .store-direita { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
  .modal-box.store .store-shelf { flex: 1 1 auto; max-height: none; }
  .modal-box.store .store-footer { flex: none; margin-top: 8px; padding-top: 8px; }

  /* O depósito: as caixas quebram em quantas colunas couberem. */
  #modal-body .locker-grade, #modal-body .depot-grid, #modal-body .bag {
    grid-template-columns: repeat(auto-fill, 44px) !important;
    width: 100%; max-width: 100%; justify-content: start;
  }

  /* ---- 18. Arrastar janelas, o inventário fino e a mochila ao lado dos baús ---- */
  /*
   * "algumas janelas eu tenho que poder arrastar; a janela de inventário eu não
   * consigo arrastar no mobile, e pode afinar ela na horizontal; e quando eu
   * abrir os baús tem que ter espaço pra eu abrir minha mochila do lado."
   *
   * ARRASTAR: o arrasto do `windows.mjs` escreve `left`/`top` em linha, e as
   * regras da gaveta (itens 1 e 15) os venciam com `!important`. Agora essas
   * regras valem só para `.window:not(.solta)`: no primeiro arrasto de dedo o
   * `mobile.mjs` marca a janela como `solta`, e a posição em linha passa a
   * mandar. O tamanho continua o da gaveta/coluna, e a janela nunca sai da
   * tela (`clampToViewport`). `touch-action: none` no cabeçalho é o que faz o
   * dedo arrastar em vez de rolar a página.
   */
  .window > header { touch-action: none; }
  .window.solta {
    max-width: calc(100vw - 12px) !important;
    max-height: calc(100dvh - 20px) !important;
    right: auto !important; bottom: auto !important;
  }
  .window.solta > .window-body { overflow-y: auto; -webkit-overflow-scrolling: touch; }
  /*
   * A MOCHILA AO LADO DOS BAÚS: com um modal aberto (o depósito, a forja, o
   * mercado), a janela da mochila fica POR CIMA dele e o modal abre espaço
   * para ela — deitado, encolhendo pela direita; em pé, encolhendo por baixo.
   * O botão da mochila no cabeçalho do modal é do `mobile.mjs`.
   */
  body:has(#modal:not([hidden])) .window[data-window-id="container"]:not([hidden]) { z-index: 52 !important; }
  .mochila-no-modal {
    flex: none; width: 34px; height: 30px; padding: 3px; margin: 0;
    border: 1px solid var(--line); border-radius: 6px; background: #0b1113cc;
    display: grid; place-items: center;
  }
  .mochila-no-modal img { width: 100%; height: 100%; object-fit: contain; }
  .mochila-no-modal[aria-pressed="true"] { border-color: var(--accent); }
  @media (orientation: portrait) {
    body:has(#modal:not([hidden])):has(.window[data-window-id="container"]:not([hidden]):not(.solta)) #modal { align-items: start; }
    body:has(#modal:not([hidden])):has(.window[data-window-id="container"]:not([hidden]):not(.solta)) .modal-box {
      max-height: calc(100dvh - var(--gaveta-altura) - var(--gaveta-chao) - 16px) !important;
    }
  }
  /*
   * A RECOMPENSA DIÁRIA: o quadro pintado tem proporção fixa (1586:992) e o
   * corpo do modal não rolava — deitado, o pé do quadro ficava fora da tela
   * sem jeito de descer. O quadro encolhe até caber na ALTURA, e o corpo
   * passa a rolar se ainda assim faltar.
   */
  .modal-box.diario { width: min(96vw, calc((100dvh - 24px) * 1.598)) !important; max-width: none !important; }
  .modal-box.diario #modal-body { overflow-y: auto; max-height: calc(100dvh - 14px); }

  /* ---- DEITADO: uma fileira só, a barra à direita do analógico ---- */
  @media (orientation: landscape) {
    :root {
      /* Treze por fileira no que sobra à direita do analógico. */
      --casa: min(38px, calc((100vw - 320px) / 13));
    }
    #analogico { left: var(--morta-lado); bottom: var(--chao); width: 104px; height: 104px; }
    .analogico-bola { width: 48px; height: 48px; margin: -24px 0 0 -24px; }
    #actionbar {
      left: auto !important; right: 0; width: calc(100vw - 122px) !important;
      padding: 6px calc(var(--morta-direita) + var(--casa) + 40px) var(--chao) 30px !important;
      border-radius: 12px 0 0 0;
    }
    .hotbar {
      grid-template-columns: repeat(13, var(--casa));
      grid-template-rows: var(--casa);
      justify-content: end;
    }
    /* Deitado: [🔒][‹][13 casas][›][STOP], da direita para a esquerda. */
    #seta-esq, #seta-dir { bottom: calc(var(--chao) + var(--casa) / 2 - 17px); }
    #seta-dir { right: calc(var(--morta-direita) + var(--casa) + 4px); }
    #seta-esq { left: auto; right: calc(var(--morta-direita) + 14 * var(--casa) + 86px); }
    #cadeado-da-barra { left: auto; right: calc(var(--morta-direita) + 14 * var(--casa) + 116px); bottom: calc(var(--chao) + var(--casa) / 2 - 13px); }
    body.em-caca #leave-hunt { left: auto; right: var(--morta-direita); bottom: var(--chao); }
    #travas-da-caca { bottom: calc(var(--barra-altura, 60px) + 68px); }
    #presente { bottom: calc(var(--barra-altura, 60px) + 6px) !important; }
    /* As colunas de janela começam abaixo da ficha e param antes dos botões. */
    /*
     * Deitado sobram 390px de altura. A coluna da ESQUERDA nasce abaixo da
     * ficha e da promoção e para em cima do analógico. A da DIREITA tem mais
     * folga: começa logo abaixo da ficha (a promoção mora à esquerda) e desce
     * até a barra, deslocada para a esquerda dos dois botões redondos.
     */
    .window:not(.solta)[data-lado="esq"] { top: var(--pilha-da-esquerda) !important; bottom: 120px !important; }
    .window:not(.solta)[data-lado="dir"] {
      top: calc(var(--topo-do-hud) + 86px) !important;
      right: 70px !important;
      bottom: calc(var(--barra-altura, 60px) + 8px) !important;
    }
    /* "pode afinar ela na horizontal": o inventário é a boneca de três colunas. */
    .window:not(.solta)[data-window-id="inventory"] { width: 172px !important; }
    /* Com um modal aberto, a mochila cola na direita e o modal encolhe. */
    body:has(#modal:not([hidden])) .window[data-window-id="container"]:not([hidden]):not(.solta) {
      top: 8px !important; right: 4px !important; bottom: calc(var(--barra-altura, 60px) + 8px) !important;
      width: 200px !important;
    }
    body:has(#modal:not([hidden])):has(.window[data-window-id="container"]:not([hidden]):not(.solta)) #modal { justify-items: start; }
    body:has(#modal:not([hidden])):has(.window[data-window-id="container"]:not([hidden]):not(.solta)) .modal-box {
      width: calc(100vw - 216px) !important; max-width: none !important;
    }
  }

  /* ---- 20. Inventário miúdo, aviso de server save no rodapé ---- */
  /*
   * "o inventário no mobile tem que ser menor": as casas da boneca (`.slot`, 44px)
   * viram 36, e a janela larga o `min-width: 200px` de mesa — deitado ela pedia
   * 172 e a mesa segurava em 200. Em pé ela deixa de ser a gaveta de tela
   * inteira: vira um quadro de 172px no canto direito, da altura da boneca.
   */
  .window[data-window-id="inventory"] { min-width: 0 !important; }
  .window[data-window-id="inventory"] .equipment { grid-template-columns: repeat(3, 36px); gap: 3px; }
  .window[data-window-id="inventory"] .equipment .slot { width: 36px; height: 36px; }
  .window[data-window-id="inventory"] .equipment .slot canvas { width: 28px; height: 28px; }
  .window[data-window-id="inventory"] .inv-cap, .window[data-window-id="inventory"] .inv-trash { font-size: 10px; }
  @media (orientation: portrait) {
    .window:not(.solta)[data-window-id="inventory"] {
      left: auto !important; right: var(--morta-direita) !important; width: 172px !important;
      height: auto !important; max-height: var(--gaveta-altura) !important;
    }
  }
  /*
   * "o aviso de server save no mobile tem que ser menor e em outro lugar": o
   * topo agora é da ficha, da loja e do MENU. Ele vai para cima da barra de
   * ações, centrado, numa fita de 20px.
   */
  #faixa-serversave {
    /* `!important`: `body.com-novidades #faixa-serversave` de mesa ganha no peso. */
    top: auto !important; bottom: calc(var(--barra-altura, 60px) + 4px) !important;
    height: 20px; padding: 0 8px; gap: 6px; max-width: 78vw;
    border-top: 1px solid #8c3b2f; border-radius: 8px;
    font-size: 9px; letter-spacing: .05em;
  }
  #faixa-serversave .selo { padding: 1px 6px; font-size: 8px; }
  #faixa-serversave .resumo { font-size: 10px; }
  body.com-serversave #faixa-autoboss, body.com-serversave.com-novidades #faixa-autoboss { top: calc(var(--topo-do-hud) + 3 * 37px + 52px); }

  /* ---- 21. Os atalhos redondos: mover, tirar, pôr ---- */
  /* Ver `montarAtalhos` no mobile.mjs. Solto = tem posição guardada. */
  .atalho-redondo { position: relative; }
  .atalho-redondo.solto { position: fixed; z-index: 24; }
  body.editando-atalhos .atalho-redondo { outline: 2px dashed var(--accent); outline-offset: 2px; touch-action: none; }
  .atalho-tirar {
    display: none; position: absolute; top: -7px; right: -7px; width: 17px; height: 17px;
    border-radius: 50%; background: #b23b2f; color: #fff; font-size: 12px; line-height: 17px; text-align: center;
    box-shadow: 0 1px 3px #000;
  }
  body.editando-atalhos .atalho-tirar { display: block; }
  #atalhos-mais, #atalhos-padrao, #atalhos-pronto {
    display: none; position: fixed; z-index: 40; bottom: calc(var(--barra-altura, 60px) + 30px);
    padding: 8px 14px; border-radius: 999px;
    font-family: var(--font-heading); font-size: 12px; letter-spacing: .06em; color: #ece4cf;
    background: #0b0f11f2; border: 1px solid #ffffff33; box-shadow: 0 4px 12px #000a;
  }
  body.editando-atalhos #atalhos-mais, body.editando-atalhos #atalhos-padrao, body.editando-atalhos #atalhos-pronto { display: inline-flex; }
  /* [+ Ícone] [Padrão] [Pronto], centrados. */
  #atalhos-mais { right: calc(50% + 52px); }
  #atalhos-padrao { left: 50%; transform: translateX(-50%); }
  #atalhos-pronto { left: calc(50% + 52px); border-color: var(--accent); color: var(--accent); }
  /* Em pé o analógico ocupa o canto de baixo: a fileira de botões sobe acima dele. */
  @media (orientation: portrait) { #atalhos-mais, #atalhos-padrao, #atalhos-pronto { bottom: calc(var(--barra-altura, 60px) + 146px); } }
  /* Arrumando, a fileira de ajustes e o menu saem da frente. */
  body.editando-atalhos #ajustes-da-caca, body.editando-atalhos #topbar .tools { display: none !important; }
  #escolha-de-atalhos {
    position: fixed; z-index: 41; left: 12px; right: 12px; top: 60px;
    max-height: calc(100dvh - var(--barra-altura, 60px) - 110px); overflow-y: auto;
    display: grid; grid-template-columns: repeat(auto-fill, 60px); justify-content: center; gap: 6px; padding: 8px;
    background: #0b0f11f2; border: 1px solid #ffffff22; border-radius: 12px; box-shadow: 0 8px 24px #000c;
  }
  #escolha-de-atalhos[hidden] { display: none; }
  #escolha-de-atalhos p { grid-column: 1 / -1; margin: 6px; color: #b9c6cb; font-size: 12px; text-align: center; }
  .escolha-atalho {
    width: 60px; height: 60px; padding: 3px; margin: 0;
    display: grid; grid-template-rows: 1fr auto; place-items: center;
    background: #121a1e; border: 1px solid #ffffff14; border-radius: 9px;
  }
  .escolha-atalho img { width: 28px; height: 28px; object-fit: contain; }
  .escolha-atalho .label { font-size: 8px; color: #b9c6cb; max-width: 54px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

  /* ---- 22. Ataque automático e barra automática, na caçada ---- */
  /*
   * "no caça online / sala de boss / arena x1 tem que ter aqueles botõezinhos
   * que ativam magia automática e atacar automático, igual no PC." São os
   * mesmos dois interruptores do `renderPresets` (⚔ e a mão conjurando), que
   * moravam no `#hotbar-presets` escondido: a coluna some (`contents`), o
   * "Salvar hk" e os arranjos continuam escondidos, e os dois ficam redondos
   * no canto direito, em cima da barra.
   */
  /* Só na caçada MANUAL (online, boss, arena): "a caça automática já tem o
     auto target e a auto magia", lá os dois só ocupariam lugar. */
  body.em-caca.manual .bar-side { display: contents; }
  body.em-caca.manual #hotbar-presets {
    display: flex !important; flex-direction: column-reverse; gap: 8px;
    position: fixed; z-index: 27;
    right: var(--morta-direita); bottom: calc(var(--barra-altura, 60px) + 8px);
  }
  #hotbar-presets > :not(.auto-toggle) { display: none !important; }
  #hotbar-presets .auto-toggle {
    width: 40px; height: 40px; font-size: 19px; border-radius: 50%;
    border: 2px solid #d9c07a; color: #efe3b8;
    background: radial-gradient(circle at 50% 40%, #171f24, #06090b);
    box-shadow: 0 0 6px #d9ae4a44, 0 2px 6px #000a;
  }
  #hotbar-presets .auto-toggle.ligado {
    color: #eafffb; border-color: var(--accent);
    background: linear-gradient(180deg, #1f6f62, #154a42);
    box-shadow: 0 0 10px #4fd1b5aa, 0 2px 6px #000a;
  }
  #hotbar-presets .auto-toggle-magia::before { width: 20px; height: 20px; background-size: 220px 20px; background-position: -80px 0; }
  /* Deitado o STOP está dentro da barra: os dois ficam logo acima dele. */
  @media (orientation: landscape) { body.em-caca.manual #hotbar-presets { bottom: calc(var(--barra-altura, 60px) + 6px); } }

  /* A gaveta de um grupo, aberta por um atalho no meio da tela: quebra em
     fileiras e cabe na largura do telefone (7 ícones davam 480px). */
  .gaveta-da-barra { flex-wrap: wrap; justify-content: center; max-width: calc(100vw - 12px); }

  /* ---- 23. A faixa morta das bordas ---- */
  /*
   * Do Garibaldi, no telefone de verdade: "achei muito colado nas bordas ainda.
   * Em celular tem uma faixa morta de todos os 4 lados, ainda mais nos cantos."
   * As posições deste bloco usam estas quatro medidas em vez de 4-8px soltos:
   * o mínimo é a faixa morta, e o entalhe/barra de gestos entra quando é maior.
   */
  :root {
    --morta-topo: max(12px, env(safe-area-inset-top));
    --morta-lado: max(18px, env(safe-area-inset-left));
    --morta-direita: max(18px, env(safe-area-inset-right));
    --chao: max(16px, env(safe-area-inset-bottom));
  }

  /*
   * iOS: o Safari só entrega `click` a quem "parece clicável" quando o ouvinte
   * está delegado no documento — e um `<div>` sem `cursor: pointer` não parece.
   * Tudo que se toca neste layout ganha o cursor, e some o flash cinza do toque.
   */
  #faixa-novidades, .atalho-redondo, .botao-redondo, #menu-do-celular, #hotbar .slot,
  #seta-esq, #seta-dir, #cadeado-da-barra, .tools button, .gaveta-da-barra button,
  #ajustes-da-caca button, .mochila-no-modal, .escolha-atalho, #atalhos-mais, #atalhos-padrao, #atalhos-pronto,
  #hotbar-presets .auto-toggle, .window > header, .character-card, .vocation-picker button {
    cursor: pointer; -webkit-tap-highlight-color: transparent;
  }

  /* ---- 19. O PORTAL cabe no telefone ---- */
  /*
   * "o botão entrar tá ficando um pouco pra fora, a de login também, criar
   * conta também, character list dá pra melhorar, a de criar personagem
   * também."
   *
   * Deitado, a tela tem 412px de altura e a moldura de mesa come 96 deles
   * (48px de borda em cima e embaixo). O que sobrava não cabia o logo, as duas
   * abas, dois campos, o botão e a linha da Google — e nada rolava, porque o
   * item 10 só ensinou a LISTA de personagens a rolar. O "Entrar" ficava
   * cortado na borda de baixo.
   *
   * Três coisas: a moldura afina (26px, e 20px deitado), tudo perde um pouco
   * de respiro (o logo, as abas, os campos, os botões), e o miolo inteiro rola
   * quando ainda assim não couber — o rodapé deixa de ser um lugar inalcançável.
   */
  /*
   * `center`, e não o `stretch` do item 10: a caixa tem a altura do que ela
   * carrega (até o teto do `max-height`). Esticada, a tela de login em pé era
   * um quadro de 900px com 400px de nada embaixo do botão da Google. A lista
   * de personagens continua rolando por dentro: o teto é o mesmo.
   */
  #gate { padding: 8px; align-items: center; }
  #gate .gate-box.ui-frame { border-width: 30px 26px 26px; }
  .gate-box, .gate-box.escolhendo, .gate-box.creating { max-height: calc(100dvh - 16px); }
  .gate-inner { padding: 6px 10px 8px; overflow-y: auto; overflow-x: hidden; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; }
  #gate-voltar { top: 8px; left: 8px; padding: 5px 9px; font-size: 10px; }
  /* O da criação tinha 340px (regra própria, mais específica): era metade da tela. */
  .gate-box .logo, .gate-box.creating .logo { max-width: 150px; margin-bottom: 10px; }
  .gate-box h2 { margin-bottom: 8px; }
  .gate-tabs { margin-bottom: 10px; }
  .gate-tabs button { padding: 7px; font-size: 12px; }
  .gate-box form { gap: 7px; }
  .gate-box input { padding: 7px 10px; }
  .gate-box button.primary { padding: 8px; margin-top: 2px; }
  .gate-box button.ghost { padding: 7px; margin-top: 6px; }
  .gate-or { margin: 10px 0 8px; }
  .gate-box small { margin-top: 6px; min-height: 0; }
  .gate-note { margin-top: 6px; }
  .gate-box.escolhendo #character-slots { margin-bottom: 8px; }
  .create-top { gap: 10px; }
  .create-top label { min-width: 150px; }
  .vocation-picker { gap: 8px; }
  .vocation-picker button { padding: 10px 8px 10px; gap: 5px; }
  .vocation-picker em { font-size: 10px; }
  .create-actions { margin-top: 4px; }
  /* Deitado: cada pixel de altura conta. */
  @media (max-height: 540px) {
    #gate .gate-box.ui-frame { border-width: 22px 20px 20px; }
    .gate-inner { padding: 2px 10px 4px; }
    .gate-box .logo, .gate-box.creating .logo { max-width: 96px; margin-bottom: 4px; }
    .gate-tabs { margin-bottom: 6px; }
    .gate-tabs button { padding: 5px; }
    .gate-box form { gap: 5px; }
    .gate-box input { padding: 5px 9px; }
    .gate-box button.primary { padding: 6px; margin-top: 0; }
    .gate-box button.ghost { padding: 5px; margin-top: 4px; }
    .gate-or { margin: 6px 0 4px; }
    .gate-box small { margin-top: 3px; }
    .gate-note { margin-top: 3px; }
    .gate-box.escolhendo #character-slots { margin: 0 0 6px; }
    #gate .gate-inner > section > h2 { margin-bottom: 4px; }
    /* As cinco vocações numa fileira: deitado sobra largura. */
    .vocation-picker { grid-template-columns: repeat(5, minmax(0, 1fr)) !important; gap: 6px; }
    .vocation-picker button { padding: 8px 6px; gap: 4px; }
    .vocation-picker b { font-size: 12px; }
    .vocation-picker em { font-size: 9px; }
    .vocation-skills img { width: 16px; height: 16px; }
    .create-top label { min-width: 120px; }
  }

  /* ---- 21. Lançamento (30/09): toque, teclado e o que estourava a tela ----
   *
   * a) Campo com fonte menor que 16px faz o iOS AMPLIAR a página ao focar, e
   *    ela fica ampliada depois. Todo campo de texto/seleção sobe para 16px.
   * b) Toque longo em imagem abria "Salvar imagem" no iOS e brigava com o
   *    botão direito do dedo (`ligarToqueLongo`); arrastar imagem idem.
   * c) Área de toque de 44px nos controles miúdos SEM mudar o desenho: a área
   *    extra é um ::before invisível de 6px em volta (34 + 12 = 46).
   * d) O balão de item cabe em 320px; o par de comparação é decidido no JS.
   * e) Mercado e balcão: as grades têm colunas em px (450 a 750px) e ficavam
   *    CORTADAS por `overflow: hidden`. Agora rolam de lado dentro da caixa.
   */
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]), select, textarea { font-size: 16px !important; }
  html { -webkit-text-size-adjust: 100%; }
  img, canvas, button, .slot, .bar-slot, .atalho-redondo, .window > header { -webkit-touch-callout: none; -webkit-user-drag: none; }
  .window-close, .window-min, #modal-close, .mochila-no-modal { position: relative; }
  #seta-esq::before, #seta-dir::before, #cadeado-da-barra::before, .window-close::before, .window-min::before,
  #modal-close::before, .mochila-no-modal::before, .atalho-tirar::before { content: ''; position: absolute; inset: -6px; }
  .tooltip { max-width: min(320px, calc(100vw - 16px)); }
  .tooltip.painel { min-width: min(232px, calc(100vw - 16px)); }
  .mercado-grade, .balcao-tabela { overflow: auto; -webkit-overflow-scrolling: touch; }
  .mercado-corpo { overflow: auto; }
  .mercado-tr { width: max-content; min-width: 100%; box-sizing: border-box; }
  .mercado-grade .mercado-corpo { min-width: max-content; }
  .balcao-linha { min-width: 480px; }
  .balcao-tabela.coins .balcao-linha { min-width: 0; }
}

/* ---- o histórico da loja: uma lista só ---- */
.historico-loja .coins-body { display: grid; gap: 8px; }
.historico-lista { display: grid; gap: 2px; max-height: 60vh; overflow-y: auto; }
.historico-linha {
  display: grid; grid-template-columns: 36px 1fr auto auto; gap: 10px; align-items: center;
  padding: 6px 8px; border-bottom: 1px solid var(--line); font-size: 12.5px;
}
.historico-imagem { width: 36px; height: 36px; display: grid; place-items: center; }
.historico-imagem img, .historico-imagem canvas { max-width: 36px; max-height: 36px; image-rendering: pixelated; }
.historico-meio { display: grid; min-width: 0; }
.historico-oque { color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.historico-tipo { color: var(--muted); font-size: 11px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.historico-quando { color: var(--muted); font-size: 11.5px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.historico-linha b { font-variant-numeric: tabular-nums; font-weight: 600; white-space: nowrap; }
.historico-linha.entrou b { color: var(--accent); }
.historico-linha.saiu b { color: var(--danger); }
.historico-valor { display: inline-flex; align-items: center; gap: 4px; }
.historico-valor img, .historico-valor canvas, .historico-valor svg { width: 14px; height: 14px; }
.historico-nota { color: var(--muted); font-size: 11px; }
@media (max-width: 480px) {
  .historico-linha { grid-template-columns: 36px 1fr auto; }
  .historico-quando { grid-column: 2 / -1; }
}

/*
 * O arrasto com o mouse é do jogo (`arrasto-do-mouse.mjs`): o cursor de mão
 * fechada em qualquer lugar, e nenhum balão de item abrindo por baixo do
 * fantasma — o arrasto do navegador também não os abria.
 */
html.arrastando-item,
/*
 * ---- E durante o gesto o ponteiro é o de MOVER ----
 *
 * "ao arrastar um item não tá aparecendo o crosshair de como se fosse arrastar
 * pra algum lugar, tá com a mãozinha de click."
 *
 * Era a mão fechada (`grabbing`), e ela diz a coisa errada: mão fechada é
 * "segurando", e o que a pessoa está fazendo é LEVANDO a peça para outro lugar.
 * `move` é a cruz de quatro setas — o mesmo ponteiro que o client do dono usa
 * enquanto o item está no ar, e o que já diz sozinho que existe um destino.
 *
 * A mão ABERTA continua valendo antes do gesto, em cima do que se pode pegar
 * (ver a regra logo abaixo): as duas contam metades diferentes da mesma
 * história.
 */
html.arrastando-item * { cursor: move !important; }

/*
 * ---- E o ponteiro de PEGAR em tudo que se arrasta ----
 *
 * "quando arrastar o mouse o ponteiro tem que ser de arraste."
 *
 * A mão fechada durante o gesto já existia (a regra acima). O que faltava era a
 * mão ABERTA antes dele: passar o mouse por cima de uma peça não dizia que ela
 * podia ser arrastada, e a barra de habilidades e a grade do filtro eram as
 * únicas duas telas em que isso aparecia — cada uma com a sua regra.
 *
 * Aqui é o seletor que responde pelo fato: `draggable="true"` é posto pelo
 * `makeDraggable` em toda peça que o jogo deixa arrastar (mochila, equipamento,
 * bolsa de loot, depósito, aljava). Uma regra só, e a próxima tela que usar
 * peças nasce com o ponteiro certo.
 */
[draggable="true"].cell,
[draggable="true"].slot,
.cell[draggable="true"],
.slot[draggable="true"] { cursor: grab; }
html.arrastando-item .tooltip { display: none !important; }
.fantasma-do-arrasto { box-shadow: none; }

/*
 * ---- O BROWSE FIELD: a casa do chão aberta como uma sacola ----
 *
 * Uma linha por peça, do topo para o fundo. A figura à esquerda porque é por
 * ela que se reconhece o item de relance; o botão à direita, na mesma coluna em
 * todas as linhas, porque é o que o dedo procura sem ler.
 */
/*
 * ---- O BROWSE FIELD é uma SACOLA, e não uma lista ----
 *
 * "o browse field tinha que ser mais parecido com a base sabe? abriria tipo
 * slot de bolsa, e eu poderia arrastar pra onde eu quisesse — tipo arrastar pra
 * outro sqm ou pra mochila."
 *
 * Ele nasceu como uma lista de linhas com um botão "Pegar" em cada. Funcionava
 * e era a coisa errada: no client do dono a casa do chão abre como um container
 * qualquer, com os mesmos quadradinhos da mochila — e é por serem os mesmos que
 * o gesto de arrastar já vale ali sem ninguém aprender nada.
 *
 * Então a grade é a `.bag-grid` de sempre, e cada quadrado é o `itemCell` de
 * sempre. O que muda é só de onde a peça vem.
 */
/*
 * ---- E ela e QUADRADA, numa janela, e nao numa cortina ----
 *
 * "o browse field nao seria em linha reta horizontal sabe? seria quadrado, e
 * nao seria um modal assim, senao eu nao consigo arrastar pra outros lado do
 * mapa."
 *
 * As duas metades do recado. A PRIMEIRA e a grade: quatro colunas, como uma
 * bolsa — em linha, dez pecas viravam uma fita atravessando a tela. A SEGUNDA
 * esta no JS: ela deixou de ser `openModal` e virou `createWindow` (ver
 * `abrirBrowseField`), porque o `#modal` e uma cortina por cima da tela inteira
 * e com ela aberta o mapa nao recebe o `drop` — a metade do pedido que era
 * "arrastar pra outro sqm" nao tinha como funcionar.
 *
 * Quatro colunas de 34 com 3 de folga sao 145px, que e o miolo de uma janela de
 * 178 — a mesma largura da Mochila, que fica logo acima dela no arranjo.
 */
.browse-field { display: grid; gap: 6px; }
.browse-grade {
  display: grid;
  grid-template-columns: repeat(4, 34px);
  gap: 3px;
  justify-content: center;
}
.browse-nota { color: var(--muted); font-size: 10px; line-height: 1.3; text-align: center; }


/*
 * ---- A tira de PREDEFINIÇÕES do filtro de loot ----
 *
 * Uma linha por predefinição: nome, tamanho, os dois botões e a marcação de
 * "vale para a conta toda". A marcação é a última porque é a frase mais longa
 * das quatro — no fim da linha ela quebra sozinha numa tela estreita sem
 * empurrar os botões, que são o que o dedo procura.
 */
/*
 * ---- As duas marcacoes do filtro de loot, ao lado do X ----
 *
 * "pode colocar resumido la encima mesmo ao lado do x."
 *
 * `#modal-acoes` e a faixa entre o titulo e o X, e ela e estreita de proposito:
 * o que entra ali cabe em duas palavras. Por isso o rotulo e curto e a frase
 * inteira mora no `title` — ver `marcacoesDoFiltro`, no panels.mjs.
 *
 * Aqui esteve um bloco inteiro de predefinicoes com nome, lista e botoes. O
 * dono cancelou ("cancela o negocio de predefinicoes, deixa o modal do loot
 * filter como era"), e o modal voltou a ser o que era.
 */
.filtro-marca {
  display: inline-flex; align-items: center; gap: 4px;
  color: var(--muted); font-size: 11px; line-height: 1;
  white-space: nowrap; cursor: pointer;
}
.filtro-marca:hover { color: var(--text); }
.filtro-marca input { margin: 0; flex: none; }
/* Marcada, ela acende: sao duas escolhas que mudam o que o jogo guarda, e o
   olho tem de achar o estado delas sem abrir a caixinha. */
.filtro-marca:has(input:checked) { color: var(--accent); }

/* ---------------------------------------------------------------------------
 * ---- Gem Atelier e Fragment Workshop ----
 *
 * As artes são as do client oficial (`client/assets/ui/gemas`, tiradas do
 * `graphics_resources.rcc`): a gema no formato da vocação, o símbolo do
 * domínio, a cruz do atelier, as molduras de grau e os ícones dos
 * modificadores. Todas são pixel art, e por isso ampliadas sem suavização.
 * Ver `client/src/gemas.mjs`.
 * ------------------------------------------------------------------------ */
.modal-box.gemas { width: min(1140px, 96vw); }
.gemas-sprite, .gemas-img { display: inline-block; image-rendering: pixelated; background-repeat: no-repeat; flex: none; vertical-align: middle; }
.dominio-verde { --dominio: #8fbf3a; --dominio-fundo: #1d2a14; }
.dominio-vermelho { --dominio: #d8404f; --dominio-fundo: #2c1418; }
.dominio-azul { --dominio: #2fbf96; --dominio-fundo: #10271f; }
.dominio-roxo { --dominio: #c14fd0; --dominio-fundo: #26142b; }

.gemas-topo { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 12px; }
.gemas-saldo { display: flex; gap: 16px; flex-wrap: wrap; }
.gemas-fragmento { display: inline-flex; align-items: center; gap: 6px; background: var(--panel-2); border: 1px solid var(--line); border-radius: 20px; padding: 3px 12px 3px 6px; }
.gemas-fragmento b { font-family: var(--font-numero); font-size: 16px; color: var(--exp); }
.gemas-fragmento em { color: var(--muted); font-style: normal; font-size: 12px; }
.gemas-abas { display: flex; gap: 4px; flex-wrap: wrap; }
.gemas-aba { display: inline-flex; align-items: center; gap: 6px; background: var(--panel-2); border: 1px solid var(--line); color: var(--text); border-radius: 6px; padding: 4px 12px 4px 6px; cursor: pointer; font-family: var(--font-heading); font-size: 13px; }
.gemas-aba:hover { border-color: var(--accent-dim); }
.gemas-aba.ativa { border-color: var(--copper); color: var(--copper); box-shadow: 0 0 10px #c8823c33 inset; }
.gemas-aviso { color: var(--danger); margin: 0 0 10px; }
.gemas-legenda { color: var(--muted); font-size: 12px; margin: 0 0 10px; }
.gemas-bloco { margin-bottom: 18px; }
.gemas-bloco h4 { font-family: var(--font-heading); margin: 0 0 8px; color: var(--copper); letter-spacing: .03em; }
.gemas-alternar { margin: 0 0 10px; }

/* As gemas fechadas: as quatro cores da gema de cada tamanho, e o botão de revelar. */
.gemas-fechadas { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 10px; }
.gemas-fechada { display: grid; justify-items: center; gap: 6px; background: radial-gradient(circle at 50% 30%, #2a2418 0, var(--panel-2) 70%); border: 1px solid var(--line); border-radius: 10px; padding: 12px; text-align: center; }
.gemas-vitrine { display: flex; gap: 2px; align-items: flex-end; min-height: 48px; }
.gemas-fechada-nome { display: inline-flex; align-items: center; gap: 4px; font-family: var(--font-heading); }
.gemas-fechada em { color: var(--muted); font-style: normal; font-size: 12px; }
.gemas-fechada button { width: 100%; }
.gemas-triturar { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 10px; }
.gemas-triturar em { color: var(--muted); font-style: normal; font-size: 12px; }
.gemas-triturar-item { padding: 2px 4px; line-height: 0; }
.gemas-lista { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 10px; }

/* O cartão da gema. */
.gemas-cartao { --dominio: var(--muted); --dominio-fundo: var(--panel-2); background: linear-gradient(135deg, var(--dominio-fundo) 0, var(--panel-2) 55%); border: 1px solid var(--line); border-radius: 10px; padding: 10px; display: grid; gap: 8px; }
.gemas-cartao.ativa { border-color: var(--dominio); box-shadow: 0 0 12px color-mix(in srgb, var(--dominio) 35%, transparent); }
.gemas-cartao-cabeca { display: flex; align-items: center; gap: 10px; }
.gemas-pedra { display: grid; place-items: center; width: 70px; height: 70px; flex: none; border-radius: 50%; background: radial-gradient(circle, color-mix(in srgb, var(--dominio) 30%, transparent) 0, transparent 70%); }
.gemas-cartao-titulo { display: grid; gap: 2px; min-width: 0; }
.gemas-cartao-nome { display: flex; align-items: center; gap: 6px; }
.gemas-cartao-nome b { font-family: var(--font-heading); font-size: 15px; }
.gemas-cartao-titulo em { color: var(--dominio); font-style: normal; font-size: 12px; }
.gemas-selos { display: flex; gap: 4px; flex-wrap: wrap; }
.gemas-selo { font-size: 11px; border: 1px solid var(--line); border-radius: 10px; padding: 0 7px; color: var(--muted); }
.gemas-selo.ativa { border-color: var(--dominio); color: var(--dominio); }
.gemas-mods { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
.gemas-mods li { display: flex; gap: 8px; align-items: center; }
.gemas-mods li.apagado { opacity: 0.45; filter: grayscale(0.7); }
.gemas-mod-texto { display: grid; gap: 1px; font-size: 12px; line-height: 1.25; min-width: 0; }
.gemas-mod-texto b { font-size: 12px; color: var(--text); }
.gemas-mod-texto span { color: var(--muted); }
.gemas-mods li.supremo .gemas-mod-texto span { color: var(--exp); }
.gemas-mods li.aceso .gemas-mod-texto span { color: #9fe0a0; }
.gemas-mods li.supremo.aceso .gemas-mod-texto span { color: #ffd76a; }
.gemas-moldura { position: relative; display: inline-grid; place-items: center; }
.gemas-icone-do-mod { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); }
.gemas-acoes { display: flex; flex-wrap: wrap; gap: 4px; }
.gemas-acoes button { padding: 4px 9px; font-size: 12px; }
.gemas-acoes button.perigo { color: var(--danger); }
.gemas-acoes button:disabled, .gemas-fechada button:disabled, .gemas-oficina-linha button:disabled { opacity: 0.45; cursor: not-allowed; }

/* Os encaixes: a cruz no meio, dois domínios de cada lado. */
.gemas-palco { display: grid; grid-template-columns: 1fr auto 1fr; gap: 12px; align-items: start; }
.gemas-lado { display: grid; gap: 10px; }
.gemas-cruz { position: relative; width: 228px; height: 228px; margin-top: 30px; }
.gemas-cruz-arte { width: 228px; height: 228px; filter: drop-shadow(0 0 14px #0009); }
.gemas-cruz-vaga { position: absolute; width: 64px; height: 64px; display: grid; place-items: center; border-radius: 50%; }
.gemas-cruz-vaga.cheia { background: radial-gradient(circle, #000a 0, transparent 70%); }
.gemas-cruz-vaga.cheia .gemas-desenho { filter: drop-shadow(0 0 6px #fff6); }
.gemas-cruz-vaga.pos-verde { left: 30px; top: 30px; }
.gemas-cruz-vaga.pos-vermelho { right: 30px; top: 30px; }
.gemas-cruz-vaga.pos-azul { left: 30px; bottom: 30px; }
.gemas-cruz-vaga.pos-roxo { right: 30px; bottom: 30px; }
.gemas-dominio { --dominio: var(--muted); --dominio-fundo: var(--panel-2); border: 1px solid var(--line); border-top: 3px solid var(--dominio); border-radius: 10px; padding: 10px; display: grid; gap: 8px; align-content: start; background: linear-gradient(180deg, var(--dominio-fundo) 0, var(--panel-2) 60%); }
.gemas-dominio-cabeca { display: flex; justify-content: space-between; align-items: center; gap: 6px; }
.gemas-dominio-nome { display: flex; align-items: center; gap: 6px; }
.gemas-dominio-nome b { color: var(--dominio); font-family: var(--font-heading); }
.gemas-dominio-cabeca em { color: var(--muted); font-style: normal; font-size: 12px; }
.gemas-vessels { display: flex; align-items: center; gap: 4px; }
.gemas-vessel { opacity: 0.35; filter: grayscale(1); }
.gemas-vessel.cheio { opacity: 1; filter: drop-shadow(0 0 4px var(--dominio)); }
.gemas-barra { position: relative; flex: 1; height: 6px; margin: 0 4px; background: #0008; border: 1px solid var(--line); border-radius: 4px; overflow: hidden; }
.gemas-barra i { position: absolute; inset: 0 auto 0 0; background: var(--dominio); }
.gemas-barra b { position: absolute; top: 0; bottom: 0; width: 1px; background: #fff8; }
.gemas-vessel-texto { color: var(--muted); font-size: 11px; min-width: 32px; text-align: right; }
.gemas-dominio .gemas-cartao { border-left-width: 1px; padding: 8px; }
.gemas-dominio .gemas-pedra { width: 56px; height: 56px; }
.gemas-escolha { width: 100%; background: var(--panel-solid); color: var(--text); border: 1px solid var(--line); border-radius: 6px; padding: 5px; }

/* A oficina. */
.gemas-oficina { display: grid; gap: 4px; }
.gemas-oficina-linha { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 10px; padding: 4px 8px; border: 1px solid var(--line-soft); border-radius: 8px; background: var(--panel-2); }
.gemas-oficina-linha.em-uso { border-color: var(--accent-dim); }
.gemas-oficina-nome { display: grid; gap: 1px; }
.gemas-oficina-nome em { color: var(--text); font-style: normal; font-size: 12px; }
.gemas-oficina-nome small { color: var(--muted); font-size: 11px; }
.gemas-oficina-linha button { padding: 4px 9px; font-size: 12px; white-space: nowrap; }
.gemas-maximo { color: var(--exp); font-size: 12px; font-family: var(--font-heading); }

@media (max-width: 900px), (max-height: 540px) and (pointer: coarse) {
  .gemas-palco { grid-template-columns: 1fr; }
  .gemas-cruz { margin: 0 auto; order: -1; }
}
@media (max-width: 640px) {
  .gemas-oficina-linha { grid-template-columns: auto 1fr; }
  .gemas-oficina-linha button, .gemas-maximo { grid-column: 1 / -1; }
  .gemas-lista { grid-template-columns: 1fr; }
}

/* ---- As peças novas do Gem Atelier: ícones no texto, filtro, lote e a oficina ---- */
.gemas-partes { display: flex; flex-wrap: wrap; gap: 2px 8px; }
.gemas-parte { display: inline-flex; align-items: center; gap: 3px; }
.gemas-parte .ui-icon, .gemas-parte-icone { width: 16px; height: 16px; object-fit: contain; flex: none; }
.gemas-parte .spell-icon { border-radius: 3px; flex: none; }
.gemas-pilula { display: inline-flex; align-items: center; gap: 6px; padding: 4px 12px; border: 1px solid var(--copper); border-radius: 20px; color: var(--copper); cursor: help; font-size: 12px; background: #c8823c14; }
.tip-gemas { display: grid; gap: 4px; min-width: 260px; max-width: 360px; }
.tip-gemas-titulo { color: var(--copper); font-family: var(--font-heading); margin-bottom: 2px; }
.tip-gemas-linha { display: grid; grid-template-columns: auto 1fr auto; gap: 8px; align-items: center; font-size: 12px; }
.tip-gemas-linha b { color: #9fe0a0; font-family: var(--font-numero); }
.tip-gemas-icones { display: inline-flex; gap: 2px; align-items: center; }
.tip-gemas-icones .ui-icon { width: 16px; height: 16px; object-fit: contain; }
.tip-gemas-total { border-top: 1px solid var(--line); padding-top: 4px; margin-top: 2px; color: var(--muted); font-style: normal; font-size: 11px; }
.gemas-confirmar { display: grid; gap: 10px; justify-items: center; width: min(460px, 92vw); }
.gemas-confirmar .gemas-mods { justify-self: stretch; }
.gemas-confirmar .confirm-short { display: inline-flex; align-items: center; gap: 4px; }
.gemas-confirmar-vitrine { display: flex; flex-wrap: wrap; gap: 2px; justify-content: center; max-height: 140px; overflow: auto; }
#modal button.gemas-perigo, .confirm-back button.gemas-perigo { background: #7a2530; border-color: var(--danger); color: #ffd9dc; }
.gemas-filtro { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-bottom: 10px; }
.gemas-filtro-campo, .gemas-filtro-busca { background: var(--panel-solid); color: var(--text); border: 1px solid var(--line); border-radius: 6px; padding: 5px 7px; font-size: 12px; }
.gemas-filtro-busca { flex: 1; min-width: 190px; }
.gemas-lote { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; width: 100%; }
.gemas-lote button { padding: 4px 10px; font-size: 12px; }
.gemas-lote-conta { font-family: var(--font-numero); color: var(--copper); }
.gemas-lote-dica { color: var(--muted); font-style: normal; font-size: 11px; width: 100%; }
.gemas-lista.escolhendo .gemas-cartao { cursor: pointer; position: relative; }
.gemas-cartao.marcada { outline: 2px solid var(--danger); outline-offset: -2px; }
.gemas-marca { position: absolute; top: 8px; right: 8px; width: 18px; height: 18px; accent-color: var(--danger); }

.gemas-oficina-cabeca { display: flex; gap: 12px; align-items: center; margin-bottom: 8px; }
.gemas-oficina-cabeca b { font-family: var(--font-heading); color: var(--copper); font-size: 17px; }
.gemas-oficina-cabeca .gemas-legenda { margin: 2px 0 0; }
.gemas-oficina-arte { filter: drop-shadow(0 0 8px #c8823c55); }
.gemas-oficina-titulo { display: flex; align-items: center; gap: 6px; }
.gemas-oficina-linha { grid-template-columns: auto 1fr auto; padding: 6px 10px; background: linear-gradient(90deg, #1f1a12 0, var(--panel-2) 40%); }
.gemas-oficina-linha.no-maximo { background: linear-gradient(90deg, #2c2410 0, var(--panel-2) 45%); }
.gemas-bancada { display: flex; align-items: center; gap: 4px; }
.gemas-atual, .gemas-potencial { position: relative; display: inline-grid; place-items: center; }
.gemas-potencial { opacity: 0.8; }
.gemas-selo-potencial { position: absolute; left: 0; top: 0; pointer-events: none; }
.gemas-seta { color: var(--muted); font-size: 16px; }
.gemas-brilho { position: absolute; left: 50%; top: 50%; width: 54px; height: 54px; transform: translate(-50%, -50%); background-size: 1458px 54px; image-rendering: pixelated; mix-blend-mode: screen; pointer-events: none; animation: gemas-brilho 1.1s steps(27) 2 forwards; }
@keyframes gemas-brilho { from { background-position: 0 0; opacity: 1; } to { background-position: -1458px 0; opacity: 0.2; } }
.gemas-oficina-nome-linha { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.gemas-trilha { display: inline-flex; gap: 2px; align-items: center; }
.gemas-pip { opacity: 0.25; filter: grayscale(1); }
.gemas-pip.aceso { opacity: 1; filter: none; }
.gemas-grau-nome { color: var(--muted); font-size: 11px; }
.gemas-proximo { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; color: var(--muted); }
.gemas-proximo .gemas-partes { opacity: 0.85; }
.gemas-subir { display: grid; gap: 2px; justify-items: center; min-width: 150px; }
.gemas-subir-rotulo { font-size: 12px; }
.gemas-preco { display: inline-flex; align-items: center; gap: 4px; font-size: 11px; }
.gemas-preco b { font-family: var(--font-numero); }
.gemas-maximo { display: inline-flex; align-items: center; gap: 4px; }
@media (max-width: 640px) {
  .gemas-oficina-linha { grid-template-columns: 1fr; }
  .gemas-subir { width: 100%; }
}

/* ---- Gem Atelier no desenho do client: painéis, grade de gemas, cadeado e escada de graus ---- */
.modal-box.gemas { width: min(1180px, 97vw); }
.gemas-abas { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; margin-bottom: 10px; }
.gemas-aba { justify-content: center; padding: 6px 10px; font-size: 14px; }
.gemas-painel { background: #15191b; border: 1px solid var(--line); border-radius: 6px; padding: 8px; box-shadow: inset 0 0 0 1px #0006; }
.gemas-painel-titulo { margin: -8px -8px 8px; padding: 4px 8px; background: #1e2427; border-bottom: 1px solid var(--line); color: var(--muted); font-family: var(--font-heading); font-size: 12px; text-align: center; letter-spacing: .04em; font-weight: normal; }

.gemas-atelier { display: grid; grid-template-columns: 210px 1fr; gap: 8px; align-items: start; }
.gemas-atelier-esquerda { display: grid; gap: 8px; }
.gemas-atelier-direita { display: grid; gap: 8px; min-width: 0; }
.gemas-cruz.pequena { width: 120px; height: 120px; margin: 4px auto; }
.gemas-cruz.pequena .gemas-cruz-arte { width: 120px; height: 120px; }
.gemas-cruz.pequena .gemas-cruz-vaga { width: 36px; height: 36px; cursor: pointer; }
.gemas-cruz.pequena .gemas-cruz-vaga.pos-verde { left: 14px; top: 14px; }
.gemas-cruz.pequena .gemas-cruz-vaga.pos-vermelho { right: 14px; top: 14px; }
.gemas-cruz.pequena .gemas-cruz-vaga.pos-azul { left: 14px; bottom: 14px; }
.gemas-cruz.pequena .gemas-cruz-vaga.pos-roxo { right: 14px; bottom: 14px; }
.gemas-revelar { display: grid; gap: 10px; }
.gemas-revelar-item { display: grid; justify-items: center; gap: 4px; text-align: center; }
.gemas-revelar-item b { font-size: 12px; font-weight: normal; color: var(--text); }
.gemas-revelar-item.vazio b { color: var(--muted); }
.gemas-revelar-moldura { display: grid; place-items: center; width: 40px; height: 40px; border: 1px solid #3c6b3a; background: #0f1a10; box-shadow: inset 0 0 6px #3c6b3a88; }
.gemas-revelar-acao, .gemas-com-preco { display: inline-flex; gap: 3px; align-items: stretch; }
.gemas-revelar-acao button, .gemas-com-preco button { padding: 3px 12px; font-size: 12px; }
.gemas-preco-caixa { display: inline-flex; align-items: center; gap: 3px; padding: 2px 7px; background: #0c0f10; border: 1px solid var(--line); border-radius: 4px; font-family: var(--font-numero); font-size: 12px; color: var(--text); }
.gemas-preco-caixa.falta { color: #ff6b6b; }

.gemas-detalhe { min-height: 150px; }
.gemas-detalhe-corpo { display: flex; gap: 14px; align-items: flex-start; }
.gemas-detalhe-pedra { display: grid; justify-items: center; gap: 6px; flex: none; }
.gemas-detalhe-dominio { display: flex; align-items: center; gap: 6px; color: var(--muted); font-size: 12px; }
.gemas-detalhe-mods { display: flex; flex-wrap: wrap; gap: 10px 18px; flex: 1; }
.gemas-detalhe-mod { display: flex; gap: 8px; align-items: center; min-width: 220px; max-width: 320px; }
.gemas-detalhe-mod.apagado { opacity: .5; filter: grayscale(.7); }
.gemas-detalhe-texto { display: grid; gap: 2px; font-size: 12px; }
.gemas-detalhe-texto em { color: var(--muted); font-style: normal; font-size: 11px; }
.gemas-detalhe-mod.supremo .gemas-parte { color: var(--exp); }
.gemas-detalhe-acoes { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--line-soft); }
.gemas-detalhe-acoes button { padding: 4px 12px; font-size: 12px; }
.gemas-detalhe-acoes-direita { margin-left: auto; display: flex; gap: 6px; align-items: center; }

.gemas-cadeado { display: inline-flex; align-items: center; gap: 4px; background: transparent; border: 1px solid transparent; border-radius: 4px; padding: 2px 4px; cursor: pointer; color: var(--muted); image-rendering: pixelated; }
.gemas-cadeado:hover { border-color: var(--line); }
.gemas-cadeado.trancada { color: #ffd76a; }
.gemas-cadeado.trancada img { filter: drop-shadow(0 0 3px #ffd76a88); }
.gemas-cadeado.com-texto { border-color: var(--line); background: var(--panel-2); padding: 3px 10px; font-size: 12px; }

.gemas-filtro { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin: 0; }
.gemas-filtro-check { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; color: var(--text); cursor: pointer; }
.gemas-filtro-check img { image-rendering: pixelated; }
.gemas-filtro-conta { color: var(--muted); font-size: 12px; margin-left: auto; }
.gemas-lote { width: auto; }

.gemas-grade { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 4px; max-height: 360px; overflow-y: auto; padding: 4px; background: #101315; border: 1px solid var(--line); border-radius: 6px; align-content: start; }
.gemas-celula { position: relative; display: grid; justify-items: center; gap: 4px; padding: 16px 6px 8px; background: linear-gradient(180deg, color-mix(in srgb, var(--dominio) 12%, #1d2225) 0, #1a1e20 55%); border: 1px solid #2f3538; cursor: pointer; min-height: 96px; }
.gemas-celula:hover { border-color: #5a6368; }
.gemas-celula.escolhida { border: 2px solid #e8e8e8; padding: 15px 5px 7px; }
.gemas-celula.ativa { box-shadow: inset 0 0 12px color-mix(in srgb, var(--dominio) 35%, transparent); }
.gemas-celula.marcada { border: 2px solid var(--danger); padding: 15px 5px 7px; }
.gemas-celula .gemas-cadeado { position: absolute; left: 3px; top: 3px; padding: 1px 3px; }
.gemas-celula-encaixada { position: absolute; right: 5px; top: 5px; image-rendering: pixelated; }
.gemas-celula-mods { display: flex; gap: 4px; justify-content: center; flex-wrap: wrap; }
.gemas-celula-mods .apagado { opacity: .45; filter: grayscale(.8); }
.gemas-grade.escolhendo .gemas-celula { cursor: copy; }
.gemas-marca { position: absolute; right: 4px; bottom: 4px; width: 16px; height: 16px; display: grid; place-items: center; border: 1px solid var(--line); border-radius: 3px; background: #0008; color: #ff8a8a; font-style: normal; font-size: 12px; }

.tip-gema { display: grid; gap: 6px; min-width: 260px; max-width: 360px; }
.tip-gema-cabeca { display: flex; gap: 8px; align-items: center; }
.tip-gema-cabeca b { display: block; font-family: var(--font-heading); color: var(--text); }
.tip-gema-dominio { display: inline-flex; align-items: center; gap: 4px; color: var(--dominio, var(--muted)); font-size: 12px; }
.tip-gema-mod { display: flex; gap: 8px; align-items: center; font-size: 12px; }
.tip-gema-mod b { display: block; font-size: 12px; margin-bottom: 1px; }
.tip-gema-mod.apagado { opacity: .5; }
.tip-gema-mod.supremo .gemas-parte { color: var(--exp); }
.tip-gema-estado { color: var(--muted); font-style: normal; font-size: 11px; border-top: 1px solid var(--line); padding-top: 4px; }

.gemas-rodape { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-top: 10px; padding-top: 8px; border-top: 1px solid var(--line); }
.gemas-rodape-caixa { display: inline-flex; align-items: center; gap: 5px; min-width: 120px; justify-content: flex-end; padding: 3px 8px; background: #0c0f10; border: 1px solid var(--line); border-radius: 4px; }
.gemas-rodape-caixa b { font-family: var(--font-numero); }
.gemas-rodape .gemas-pilula { margin-left: auto; }

.gemas-dominio-gema { display: flex; gap: 8px; align-items: center; padding: 6px; border: 1px solid var(--line-soft); border-radius: 6px; background: #0006; cursor: help; }
.gemas-dominio-mods { display: grid; gap: 3px; font-size: 12px; }
.gemas-dominio-mod { display: flex; gap: 6px; align-items: center; }
.gemas-dominio-mod.apagado { opacity: .45; }

.gemas-oficina-layout { display: grid; grid-template-columns: 320px 1fr; gap: 8px; align-items: stretch; }
.gemas-escada { display: grid; align-content: start; gap: 6px; }
.gemas-escada-nome { text-align: center; font-family: var(--font-heading); }
.gemas-escada-degraus { display: grid; justify-items: start; padding: 4px 6px; }
.gemas-degrau { display: flex; gap: 12px; align-items: center; opacity: .5; }
.gemas-degrau.alcancado, .gemas-degrau.proximo { opacity: 1; }
.gemas-degrau.proximo .gemas-degrau-texto { color: var(--muted); }
.gemas-degrau-circulo { position: relative; display: grid; place-items: center; width: 58px; height: 58px; flex: none; }
.gemas-degrau-anel { position: absolute; inset: 0; width: 58px; height: 58px; image-rendering: pixelated; filter: drop-shadow(0 0 5px #3fbf6f88); }
.gemas-degrau-circulo .gemas-moldura { position: relative; }
.gemas-degrau-circulo .gemas-selo-potencial { position: absolute; left: 4px; top: 4px; }
.gemas-degrau-texto { display: grid; gap: 2px; font-size: 12px; }
.gemas-degrau.atual .gemas-degrau-texto b { color: #9fe0a0; }
.gemas-degrau-haste { display: block; width: 4px; height: 22px; margin-left: 27px; background: #2b3134; border-radius: 2px; }
.gemas-degrau-haste.alcancada { background: linear-gradient(180deg, #3fbf6f, #2a8a4f); box-shadow: 0 0 5px #3fbf6f88; }
.gemas-escada-rodape { display: flex; gap: 4px; align-items: stretch; flex-wrap: wrap; padding-top: 8px; border-top: 1px solid var(--line-soft); }
.gemas-escada-rodape button { padding: 4px 12px; font-size: 12px; }
.gemas-oficina-lista { display: grid; gap: 8px; align-content: start; min-width: 0; }
.gemas-oficina-grade { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 4px; max-height: 470px; overflow-y: auto; padding: 4px; background: #101315; border: 1px solid var(--line); border-radius: 6px; align-content: start; }
.gemas-oficina-celula { position: relative; display: grid; place-items: center; height: 78px; background: #1a1e20; border: 1px solid #2f3538; cursor: pointer; }
.gemas-oficina-celula:hover { border-color: #5a6368; }
.gemas-oficina-celula.escolhida { border: 2px solid #e8e8e8; }
.gemas-oficina-celula.no-maximo { background: linear-gradient(180deg, #2c2410, #1a1e20); }
.gemas-oficina-conta { position: absolute; right: 6px; top: 4px; font-size: 11px; color: var(--text); }
.gemas-oficina-grau { position: absolute; left: 6px; bottom: 3px; font-size: 10px; color: var(--muted); font-family: var(--font-numero); }
@media (max-width: 900px), (max-height: 540px) and (pointer: coarse) {
  .gemas-atelier, .gemas-oficina-layout { grid-template-columns: 1fr; }
  .gemas-detalhe-mod { min-width: 0; }
}
.tip-gema, .tip-gemas { white-space: normal; }
.tip-gema .gemas-parte span { overflow-wrap: anywhere; }

/* ---- A caixa do modal sai do caminho ----

   O `.modal-box` normal desenha a propria moldura (`padrao.png`) e um
   cabecalho com titulo. A Recompensa Diaria JA' e' uma moldura pintada, com o
   nome dela dentro: as duas juntas viram duas bordas e dois titulos na mesma
   tela. Aqui a caixa vira so' um lugar onde a arte se apoia.

   O X de fechar fica — e' a unica coisa da caixa que faz falta —, e ele sobe
   para o canto da propria arte. */
.modal-box.diario {
  width: min(1240px, 96vw);
  border: none; border-image: none; padding: 0; background: none;
}
/* `z-index: 6` e nao 2: `.diario-moldura` nao abre contexto de empilhamento
   proprio, entao as camadas dela (a moldura por cima em 2, o selo em 3, os
   olhos em 4) disputam o mesmo nivel que este header — e a moldura, que vem
   DEPOIS no documento, ganhava o empate e enterrava o X. */
.modal-box.diario > header {
  position: absolute; z-index: 6; top: 0; right: 0; left: auto;
  padding: 0; margin: 0; border: none; background: none; min-height: 0;
}
.modal-box.diario > header #modal-title { display: none; }
/* ---- O X de fechar ----

   O X comum do modal e' um glifo cinza de 15px sem fundo. Em cima de qualquer
   painel ele se ve'; em cima da cripta, que e' escura e cheia de detalhe, ele
   some — o dono abriu a aba e nao achou por onde sair.

   Aqui ele vira botao de verdade: disco escuro, aro de ouro velho e o glifo
   claro por cima. O disco e' o que resolve, e nao a cor da letra: o que
   escondia o X era o RUIDO do desenho atras dele, e nenhuma cor de letra
   vence fundo movimentado. `position: absolute` no proprio X (e nao so' no
   header) e' o que o tira de cima do titulo da arte. */
.modal-box.diario > header #modal-close {
  margin: 10px;
  width: 30px; height: 30px; padding: 0;
  display: grid; place-content: center;
  border: 1px solid #8a6f42; border-radius: 50%;
  background: #0b0f11e6;
  box-shadow: 0 0 0 1px #0a0d0f99, 0 2px 10px #000a;
  color: #e8d9b4; font-size: 17px; line-height: 1;
  transition: background .12s ease, color .12s ease, border-color .12s ease;
}
.modal-box.diario > header #modal-close:hover {
  background: #17262a; color: #fff3d6; border-color: #d8b471;
}
.modal-box.diario #modal-body { padding: 0; overflow: visible; }

/* ---------- A Recompensa Diária ----------

   ---- A moldura manda, e a tela obedece ----

   `diario-fundo.webp` nao e' enfeite atras da tela: ela tem LUGARES marcados —
   o medalhao vazio no alto a esquerda, o painel escuro no meio, o vao entre os
   arabescos embaixo. Cada peca e' posta em cima do lugar dela, em PORCENTAGEM,
   porque a moldura tem proporcao fixa e encolhe junto com a janela.

   Os numeros sairam de MEDIR a imagem de 1586x992, e estao escritos em cada
   regra. Se a arte mudar, e' aqui que se mexe:

     medalhao       centro em 8,3% x 10%,  raio ~4,5% da largura
     painel escuro  4,3% de cada lado, 21% do topo, 6,5% do rodape
     arabescos      faixa de baixo, vao central em 96,8%

   ---- Por que `cqw` e nao `px` ----

   A moldura encolhe com a janela, e o texto tem de encolher junto: com `px` as
   letras ficariam do mesmo tamanho numa carta que virou metade. `cqw` e' um
   centesimo da largura DELA — entao tudo escala de uma vez. */
/* ---- A bordinha em volta ----

   A arte chega ate' a borda da imagem, entao sem nada em volta o painel se
   dissolve no jogo atras dele — principalmente na cidade, que tambem e' escura.
   Um fio de ouro velho (a mesma cor dos ferros da propria arte) fecha o
   contorno, e a sombra funda descola o painel do fundo. */
.diario-moldura {
  position: relative;
  container-type: inline-size;
  aspect-ratio: 1586 / 992;
  width: 100%;
  background: url('/client/assets/ui/diario-fundo.webp') center/100% 100% no-repeat, var(--bg);
  border: 1px solid #6b5636;
  border-radius: 10px;
  box-shadow: 0 0 0 1px #0a0d0f, 0 18px 54px #000d, 0 0 60px #0a0d0fcc;
  overflow: hidden;
}
/* ---- A moldura, de novo, POR CIMA das cartas ----

   A mesma arte com o miolo do painel recortado (`diario-frente.webp`): so' a
   borda, a cripta do alto e os dois gargoyles. Ela fica acima da grade, entao a
   carta que chega no canto passa POR BAIXO do gargoyle em vez de cobri-lo.

   `pointer-events: none` e' obrigatorio: sem isso a camada engoliria o mouse e
   as cartas de baixo perderiam o balao e o clique. */
.diario-moldura::after {
  content: ''; position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background: url('/client/assets/ui/diario-frente.webp') center/100% 100% no-repeat;
}
/* O que fica ACIMA da camada: o medalhao, o titulo e o botao. Eles moram nos
   lugares desenhados da moldura, entao precisam estar na frente dela. */
.diario-selo, .diario-titulo, .diario-pegar { z-index: 3; }

/* ---- Os olhos dos gargoyles acendem ----

   Quatro brasas vermelhas em cima dos olhos que a arte ja' desenhou — e nao
   olhos novos: o desenho tem duas orbitas escuras em cada cara, e o brilho so'
   mora dentro delas.

   Os lugares foram MEDIDOS na arte de 1586x992 e estao em porcentagem, como
   todo o resto desta tela:

     esquerdo   x 92,5 e 98    y 855   ->  5,83% e 6,18%  /  86,2%
     direito    x 1488 e 1493  y 855   -> 93,82% e 94,17% /  86,2%

   Se a arte mudar, e' aqui que se mexe — e do jeito mais simples possivel: os
   quatro sao um `background` so', com quatro gradientes, num unico elemento.
   Quatro elementos separados dariam quatro coisas para manter alinhadas.

   `z-index: 4` poe as brasas acima da camada da moldura (2) e do que esta' nela
   (3), senao o proprio gargoyle da `diario-frente` as taparia. */
.diario-olhos {
  position: absolute; inset: 0; z-index: 4; pointer-events: none;
  background:
    radial-gradient(circle .3cqw at 5.85% 86.05%,  #ffcfc0 0%, #ff2a10 38%, #c4150766 62%, #a8120600 100%),
    radial-gradient(circle .3cqw at 6.22% 86.2%,   #ffcfc0 0%, #ff2a10 38%, #c4150766 62%, #a8120600 100%),
    radial-gradient(circle .3cqw at 93.78% 86.05%, #ffcfc0 0%, #ff2a10 38%, #c4150766 62%, #a8120600 100%),
    radial-gradient(circle .3cqw at 94.15% 86.2%,  #ffcfc0 0%, #ff2a10 38%, #c4150766 62%, #a8120600 100%);
  mix-blend-mode: screen;
  animation: diario-olhos 5.2s ease-in-out infinite;
}
/* A piscada nao e' um liga-desliga: a brasa fica SEMPRE acesa no minimo e o que
   varia e' a forca. Apagar de vez faria dois buracos pretos aparecerem no meio
   da cara a cada volta — chama mais atencao do que o brilho. */
@keyframes diario-olhos {
  0%, 44%  { opacity: .78; }
  50%      { opacity: .22; }
  56%      { opacity: 1; }
  62%      { opacity: .3; }
  70%, 100% { opacity: .78; }
}
/* ---- E a brasa SOBE ----

   So' piscar deixava os olhos parecendo duas luzinhas de aparelho. O que o
   desenho pede e' fogo: fagulhas saindo da orbita e subindo ate' apagar.

   Seis fagulhas, tres por cara, cada uma com atraso proprio — e' o atraso que
   faz um fio continuo em vez de seis pontos piscando juntos. Cada uma sobe
   3,4cqw (pouco mais que a altura da cabeca) e some no caminho, entao nunca
   encosta nas cartas.

   So' `transform` e `opacity` animam, que sao as duas coisas que o navegador
   resolve na placa de video: a aba fica aberta muito tempo e isto nao pode
   custar quadro. */
.diario-brasa {
  position: absolute; width: var(--tam, .42cqw); aspect-ratio: 1; border-radius: 50%;
  background: radial-gradient(circle, #fff1e6 0%, #ff8a3c 30%, #ff3a10 58%, #ff3a1000 100%);
  opacity: 0;
  animation: diario-sobe 4.4s linear infinite;
}
/* Ela nasce um pouco ABAIXO do centro do olho (.2cqw) e cresce no comeco: sair
   ja' do tamanho final fazia a fagulha "aparecer", e nao "sair de dentro". */
@keyframes diario-sobe {
  0%   { transform: translate(-50%, .2cqw) scale(.45); opacity: 0; }
  12%  { opacity: 1; }
  60%  { opacity: .85; }
  100% { transform: translate(calc(-50% + var(--lado, 0cqw)), -7cqw) scale(.25); opacity: 0; }
}
/* Os lugares: as mesmas orbitas de cima, com os x espalhados em volta delas.
   Cada fagulha tem tres coisas proprias, e cada uma conserta um defeito:

     --lado   a inclinacao da subida — sem ela todas sobem na mesma reta e o
              efeito le como um RISCO, e nao como fogo;
     --tam    o tamanho — todas iguais viram uma fileira de bolinhas;
     delay    o atraso, espalhado pelo ciclo INTEIRO (4,4s / 6) — e' o que faz
              um fio continuo em vez de seis pontos piscando juntos.

   Sao seis, tres por cara. Catorze foi testado e o dono cortou: com mais
   fagulhas o canto virava fogueira, e o que a cara do gargoyle pede e' brasa. */
.diario-brasa.b1 { left: 5.85%;  top: 86.05%; --lado: -.6cqw; --tam: .46cqw; animation-delay: 0s; }
.diario-brasa.b2 { left: 94.15%; top: 86.2%;  --lado:  .6cqw; --tam: .46cqw; animation-delay: .73s; }
.diario-brasa.b3 { left: 6.22%;  top: 86.2%;  --lado:  .5cqw; --tam: .38cqw; animation-delay: 1.46s; }
.diario-brasa.b4 { left: 93.78%; top: 86.05%; --lado: -.5cqw; --tam: .38cqw; animation-delay: 2.2s; }
.diario-brasa.b5 { left: 6.02%;  top: 86.1%;  --lado: -.12cqw; --tam: .42cqw; animation-delay: 2.93s; }
.diario-brasa.b6 { left: 93.98%; top: 86.1%;  --lado:  .12cqw; --tam: .42cqw; animation-delay: 3.66s; }

/* ---- A fagulha que voa do olho até a carta ----

   Ela nasce e morre em 720ms (ver `acenderDoGargoyle`), então não tem estado
   guardado: se algo der errado no meio, o pior que acontece é uma bolinha
   sumir. `z-index: 4` a põe no mesmo nível das brasas, acima da moldura da
   frente e da grade; `pointer-events: none` porque ela passa POR CIMA das
   cartas e não pode roubar o clique de nenhuma. */
/* A camada do efeito: presa à JANELA, e não ao painel. O painel se redesenha a
   cada quadro do jogo e levaria o efeito junto — ver `acenderDoGargoyle`. */
.diario-brilho { position: fixed; inset: 0; z-index: 9999; pointer-events: none; }
.diario-raio {
  position: fixed; aspect-ratio: 1; border-radius: 50%;
  background: radial-gradient(circle, #fff6ee 0%, #ffb15c 28%, #ff3a10 55%, #ff3a1000 100%);
  box-shadow: 0 0 10px #ff5a2aaa, 0 0 24px #ff3a1055;
}
/* O anel que acende na carta quando a fagulha chega. Ele é um elemento à
   parte, e não uma classe na carta, pelo mesmo motivo. */
.diario-anel {
  position: fixed; opacity: 0;
  border: 1px solid #ffd9a0;
  box-shadow: 0 0 0 2px #ffb15c77, 0 0 26px #ff8a3ccc, inset 0 0 22px #ffb15c55;
}

/* Quem pediu menos movimento fica com a brasa parada e fraca: o enfeite
   continua, o pisca-pisca e as fagulhas somem. */
@media (prefers-reduced-motion: reduce) {
  .diario-olhos { animation: none; opacity: .7; }
  .diario-brasa { display: none; }
}

/* O medalhao. `display: grid` centra os dois filhos sem conta nenhuma. */
.diario-selo {
  position: absolute; left: 8.3%; top: 10%;
  transform: translate(-50%, -50%);
  width: 9%; aspect-ratio: 1;
  display: grid; place-content: center; text-align: center; line-height: 1;
}
.diario-selo strong {
  display: block;
  font-family: var(--font-title); font-weight: 900;
  font-size: 5.4cqw; line-height: 1; color: var(--accent);
  text-shadow: 0 0 1cqw #3fbfa866;
}
/* Quem nunca pegou nao tem numero. O ponto sozinho fica perdido no medalhao,
   entao ele cresce — o medalhao e' grande e nao pode ficar vazio. */
.diario-selo.vazio strong { font-size: 3.4cqw; color: #7fb8ab; }
.diario-selo span {
  display: block; margin-top: .4cqw;
  font-family: var(--font-heading); font-size: 1.25cqw;
  letter-spacing: .22em; text-transform: uppercase; color: #9fb8b0;
}

/* O titulo, na faixa da cripta. A sombra existe porque o fundo ali e' a cena
   pintada, e sem ela a letra some em cima da chama. */
.diario-titulo {
  position: absolute; left: 15%; right: 6%; top: 3%;
  text-shadow: 0 2px 10px #000c, 0 0 22px #000a;
}
/* O `#modal-body h3` tem ID e ganharia deste por especificidade — ele fixa 12px
   e a cor do accent em TODO h3 de modal. O `#modal-body` aqui na frente nao e'
   enfeite: e' o que empata a conta e deixa a regra de baixo valer. */
#modal-body .diario-titulo h3 {
  margin: 0; font-family: var(--font-title); font-weight: 700;
  font-size: 2.6cqw; line-height: 1.1; letter-spacing: .16em; text-transform: uppercase;
  color: #eef6f3;
}
.diario-titulo p {
  margin: .8cqw 0 0; font-family: var(--font-heading);
  font-size: 1.15cqw; letter-spacing: .06em; color: #a9c3bb;
}

/* A grade, dentro do painel escuro. Seis por cinco, preenchendo a area. */
/* ---- A ultima fileira passa POR BAIXO dos gargoyles ----

   Os dois gargoyles dos cantos de baixo avancam para dentro do painel (medido
   na arte: ate' 7,9% da largura, a partir de 84% da altura), e as cartas 25 e
   30 batiam neles.

   A primeira tentativa foi subir o piso da grade para 84%. Funcionava, mas
   encolhia as TRINTA cartas por causa de dois cantos — e o dono cortou: "nao,
   deixa como estava, so' coloca o quadrado pra mostrar atras do gargoyle".

   Entao a grade fica onde estava e o gargoyle vem para CIMA dela, pela camada
   `.diario-moldura::after` (ver logo abaixo). A carta continua inteira; o que
   muda e' quem tapa quem. */
.diario-grade {
  position: absolute; left: 5.4%; right: 5.4%; top: 23%; bottom: 10.5%;
  z-index: 1;
  display: grid; gap: .8cqw;
  grid-template-columns: repeat(6, 1fr);
  grid-template-rows: repeat(5, 1fr);
}
.diario-dia {
  position: relative; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: .3cqw;
  /* Folga de cima curta de proposito: o numero do dia fica ENCOSTADO no canto
     esquerdo e o icone no centro, entao eles nunca se cruzam — e o que sobrar
     de altura vai todo para o desenho. */
  padding: 1.1cqw .4cqw .5cqw;
  border: 1px solid #2c373c99; border-radius: .6cqw;
  background: linear-gradient(180deg, #161d2199, #10161999);
  text-align: center; overflow: hidden;
}
.diario-dia .numero {
  position: absolute; top: .5cqw; left: .7cqw;
  font-family: var(--font-heading); font-size: 1.1cqw;
  color: #8fa3a9; letter-spacing: .04em;
}
.diario-dia .simbolo { font-size: 2.4cqw; line-height: 1; color: var(--copper); }
.diario-dia .premio {
  font-family: var(--font-heading); font-size: .92cqw; line-height: 1.3;
  letter-spacing: .05em; text-transform: uppercase; color: #c8d6d8;
  padding: 0 .2cqw;
}
/* ---- O tamanho do icone solto ----

   Eram 2,6cqw: a carta ficava com um selo pequeno no meio de muito vazio, e a
   peca — que e' o que a pessoa quer reconhecer — nao se lia. 3,5cqw e' o maior
   que cabe sem empurrar o nome para fora: a carta tem ~7,7cqw de altura util e
   o nome ocupa duas linhas. O `desenhoDoDiario` desenha o canvas com 44px de
   lado justamente para bater com isto e nao subir borrado. */
.diario-dia canvas, .diario-dia .diario-arte { width: 3.5cqw; height: 3.5cqw; }
/* A fila de icones do dia de escolha. `gap` pequeno e `nowrap`: eles tem de
   ler como UM grupo, e nao como uma lista que quebrou de linha. */
.diario-varios {
  display: flex; align-items: center; justify-content: center;
  gap: .35cqw; flex-wrap: nowrap;
  /* A carta nao pode ser empurrada pelos icones: se um dia forem mais do que
     cabem, eles encolhem juntos em vez de estourar a grade. */
  max-width: 100%; overflow: hidden;
}
/* A regra acima vale para o icone SOLTO; aqui a fila manda no tamanho dela.
   Precisa de `.diario-dia` na frente: sem isso `.diario-dia canvas` tem
   especificidade maior e vence, e a fila inteira era esticada para 3,5cqw. */
.diario-dia .diario-varios canvas { width: auto; height: auto; }
.diario-dia canvas { image-rendering: pixelated; }

/* ---- Ja' pego ----

   Apagado, mas nao some: a sequencia inteira e' o produto, e o que ja' saiu e'
   metade dela. O que muda e' a FAIXA — "Coletado" atravessando a carta, que
   responde de longe a unica pergunta de quem abre a aba.

   Menos apagado que antes (.5 no lugar de .38) porque agora ha' texto por cima,
   e texto em cima de 38% de opacidade nao se le. */
.diario-dia.pego { opacity: .4; }
/* A faixa atravessava a carta no meio — bem em cima do icone, que e' a unica
   coisa que diz QUAL premio era aquele. Trocada por uma tarja no pe' da carta:
   responde a mesma pergunta de longe e nao tapa nada, porque o rodape' da
   carta e' vazio. O icone continua inteiro; so' fica mais apagado. */
.diario-dia .coletado {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: .22cqw 0;
  background: linear-gradient(180deg, #0a0d0f00, #0a0d0fe6 45%);
  border-top: 1px solid #3fbfa844;
  font-family: var(--font-heading); font-size: .82cqw;
  letter-spacing: .2em; text-transform: uppercase;
  color: var(--hp); text-align: center;
}
/* O certinho ANTES da palavra. Ele responde de longe, sem ler: numa grade de
   trinta cartas o olho conta vistos, e não palavras. A palavra fica porque o
   visto sozinho é ambíguo — visto de quê? */
.diario-dia .coletado::before {
  content: '✓';
  margin-right: .35em;
  font-family: inherit;
  opacity: .9;
}
/* O rodape' da carta passa a ser da tarja, entao o nome do premio sobe um
   pouco para nao encostar nela. */
.diario-dia.pego .premio { margin-bottom: 1.8cqw; }
/* ---- O da vez PISCA ----

   Ele ja' era o unico aceso, mas aceso parado se perde no meio de trinta
   cartas — a pessoa abre a aba e procura. A pulsacao resolve em meio segundo,
   e e' lenta (2,4s) de proposito: pisca-pisca rapido em cima de uma tela que
   fica aberta vira incomodo.

   `prefers-reduced-motion` desliga a animacao e deixa o brilho parado: quem
   pediu menos movimento no sistema pediu por um motivo. */
.diario-dia.a-vez {
  border-color: var(--accent);
  background: linear-gradient(180deg, #16302bee, #0f1f1cee);
  animation: diario-pulsa 2.4s ease-in-out infinite;
}
@keyframes diario-pulsa {
  0%, 100% {
    box-shadow: 0 0 0 1px #3fbfa833, 0 0 1cqw #3fbfa826;
    border-color: #2f8c7b;
  }
  50% {
    box-shadow: 0 0 0 1px #3fbfa8aa, 0 0 2.6cqw #3fbfa866;
    border-color: #6fe0c8;
  }
}
@media (prefers-reduced-motion: reduce) {
  .diario-dia.a-vez {
    animation: none;
    box-shadow: 0 0 0 1px #3fbfa866, 0 0 1.6cqw #3fbfa844;
  }
}
/* A carta responde ao mouse: ela tem balao, entao precisa parecer tocavel. */
.diario-dia { transition: transform .12s ease, border-color .12s ease; }
.diario-dia:hover { transform: translateY(-2px); border-color: #55707a; }
.diario-dia.a-vez:hover { border-color: #6fe0c8; }
.diario-dia.a-vez .numero { color: var(--accent); }
/* Os dias de escolha valem mais, e a borda de cobre diz isso antes de a pessoa
   chegar neles. */
/* O dia de escolha NAO tem contorno proprio: "nao precisa o contorno dos itens
   que sao escolhiveis ser diferentes". Os dois (ou quatro) icones lado a lado
   ja' dizem que aquele dia e' uma escolha — a borda de cobre so' competia com a
   borda do dia da vez, que e' a unica que precisa saltar. */
.diario-dia.de-escolha .simbolo { color: var(--exp); }

/* O botao, no vao dos arabescos de baixo. */
.diario-pegar {
  position: absolute; left: 50%; top: 96.4%;
  transform: translate(-50%, -50%);
  padding: .9cqw 4cqw; cursor: pointer; border-radius: 999px;
  font-family: var(--font-title); font-weight: 700;
  font-size: 1.5cqw; letter-spacing: .18em; text-transform: uppercase;
  background: linear-gradient(180deg, #1f5a4eee, #0f2c27ee);
  border: 1px solid var(--accent-dim); color: #d8f2ea;
  text-shadow: 0 1px 6px #000a;
  box-shadow: 0 0 1.4cqw #000a;
}
.diario-pegar:hover:not(:disabled) {
  border-color: var(--accent); color: #fff; box-shadow: 0 0 2cqw #3fbfa844;
}
.diario-pegar:disabled { opacity: .5; cursor: default; }

/* A escolha, FORA da moldura: dentro ela cobriria as cartas, e e' justamente a
   hora de ver as duas coisas. */
/* ---- A escolha, por cima da moldura ----

   Ela e' uma camada que cobre a arte inteira e escurece a grade: na hora de
   escolher so' existe uma decisao na tela. `z-index: 5` a poe acima da moldura
   da frente (2), do selo (3) e das brasas (4), e abaixo so' do X (6) — de
   proposito, para nunca prender ninguem numa escolha sem saida.

   Tudo em `cqw` porque ela mora DENTRO da moldura: encolhe junto com a janela,
   como as cartas. */
.diario-escolha {
  position: absolute; inset: 0; z-index: 5;
  display: grid; place-content: center;
  padding: 3cqw;
  background: #05090bdd;
}
.diario-escolha-caixa {
  max-width: 52cqw;
  padding: 1.8cqw 2cqw;
  border: 1px solid #6b5636; border-radius: .8cqw;
  background: linear-gradient(180deg, #111a1ef2, #0b1114f2);
  box-shadow: 0 1.2cqw 3.5cqw #000c;
}
#modal-body .diario-escolha h4 {
  margin: 0 0 1.2cqw; font-family: var(--font-title); font-weight: 700; font-size: 1.5cqw;
  letter-spacing: .08em; text-transform: uppercase; color: var(--exp); text-align: center;
}
/* `flex` e nao `grid`: a lista vai de DUAS opcoes (Instance ou Divine) a OITO
   (as Durable). Com colunas fixas, duas opcoes ficariam espremidas num canto;
   assim elas se centram sozinhas e as oito quebram em duas fileiras. */
.diario-opcoes {
  display: flex; flex-wrap: wrap; justify-content: center; gap: .8cqw;
}
.diario-opcao {
  display: flex; flex-direction: column; align-items: center; gap: .35cqw;
  width: 11cqw;
  padding: .9cqw .6cqw; cursor: pointer; text-align: center;
  border: 1px solid var(--line); border-radius: .6cqw;
  background: var(--panel-2); color: var(--text);
}
.diario-opcao:hover { border-color: var(--accent); background: #16302b; }
/* A marcada, ANTES de confirmar. Ela precisa se ver de longe no meio de oito
   desenhos parecidos, entao muda as tres coisas de uma vez: aro, fundo e um
   anel por fora. So' a cor da borda nao bastava — as oito ja' tem borda. */
.diario-opcao.marcada {
  border-color: var(--accent); background: #16302b;
  box-shadow: 0 0 0 .18cqw #3fbfa866, 0 0 1.4cqw #3fbfa833;
}
/* ---- Confirmar e Cancelar ----

   O clique no icone entregava na hora, sem volta. Agora ele so' MARCA, e a
   entrega passa por aqui. `Confirmar` nasce apagado: sem nada marcado nao ha'
   o que confirmar, e um botao que aceita clique sem efeito ensina errado. */
.diario-escolha-acoes {
  display: flex; align-items: center; justify-content: flex-end;
  gap: .7cqw; margin-top: 1.4cqw;
}
.diario-escolha-acoes .aviso {
  margin-right: auto; font-size: .85cqw; color: var(--muted);
}
.diario-escolha-acao {
  padding: .6cqw 1.4cqw; cursor: pointer;
  font-family: var(--font-heading); font-size: 1cqw;
  letter-spacing: .1em; text-transform: uppercase;
  border: 1px solid var(--line); border-radius: .5cqw;
  background: var(--panel-2); color: var(--text);
}
.diario-escolha-acao:hover:not(:disabled) { border-color: #8fa3a9; background: #1b2429; }
.diario-escolha-acao.confirma {
  border-color: #3fbfa8; color: #eafaf6;
  background: linear-gradient(180deg, #1d4a42, #13332e);
}
.diario-escolha-acao.confirma:hover:not(:disabled) {
  border-color: #6fe0c8; background: linear-gradient(180deg, #246055, #17413a);
}
.diario-escolha-acao:disabled { opacity: .45; cursor: default; }
.diario-opcao .nome { font-family: var(--font-heading); font-size: 1cqw; line-height: 1.3; }
.diario-opcao .detalhe { font-size: .85cqw; color: var(--muted); }
.diario-opcao canvas, .diario-opcao .diario-arte { width: 3.2cqw; height: 3.2cqw; }
.diario-opcao canvas { image-rendering: pixelated; }

.diario-dia .diario-arte,
.diario-opcao .diario-arte { object-fit: contain; image-rendering: auto; }

/* O balao de uma carta do diario. */
.tip-diario { max-width: 300px; }
.tip-diario-dia {
  font-family: var(--font-heading); font-size: 10px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--muted);
}
.tip-diario-nome {
  margin-top: 2px; font-family: var(--font-title); font-weight: 700;
  font-size: 13px; letter-spacing: .04em; color: var(--accent);
}
.tip-diario-texto { margin: 7px 0 0; font-size: 12px; line-height: 1.45; color: var(--text); }
.tip-diario-estado {
  margin-top: 8px; padding-top: 7px; border-top: 1px solid var(--line-soft);
  font-size: 11px; color: var(--muted);
}
.tip-diario-estado.aceso { color: var(--accent); }


/*
 * ================= AS TASKS DE CRIATURA =================
 *
 * A aba Tasks tem duas listas: as boss tasks (três) e as criaturas (309). Os
 * CARDS são os mesmos — `.bosstask-card` e as três colunas dele —, porque o
 * dono pediu assim: "era pra ter os cards bonito igual tem a da task de
 * minotaur". Aqui mora só o que é próprio desta seção: a divisa, a barra de
 * filtro, o realce de quem tem prêmio esperando e o botão de pegar.
 *
 * (A primeira versão tinha uma lista de linhas baixas, com estilo próprio para
 * nome, level, régua e canto. Tudo aquilo saiu: o card das boss tasks já
 * resolve os três, e duas maneiras de desenhar a mesma coisa na mesma janela
 * eram duas coisas para manter.)
 */

.tbicho-filtro { display: flex; flex-direction: column; gap: 6px; margin: 8px 0 10px; }
#tbicho-busca {
  width: 100%; box-sizing: border-box;
  padding: 6px 9px; border-radius: 6px;
  background: #0d1315; border: 1px solid #ffffff1f; color: var(--text);
  font-size: 12px;
}
#tbicho-busca:focus { outline: none; border-color: var(--accent-dim); }

.tbicho-faixas { display: flex; flex-wrap: wrap; gap: 5px; }
.tbicho-faixa {
  padding: 3px 9px; border-radius: 999px;
  background: #0d1315; border: 1px solid #ffffff1a; color: var(--muted);
  font-size: 11px; cursor: pointer;
}
.tbicho-faixa:hover { border-color: var(--accent-dim); color: var(--text); }
.tbicho-faixa.ativa { background: var(--accent-dim); border-color: var(--accent); color: #eafffb; }
/*
 * ---- A fileira de ESTADO é dourada, a de level é turquesa ----
 *
 * As duas fileiras peneiram coisas diferentes — onde o bicho vive, e onde eu
 * estou na task — e uma cor só faria a barra inteira parecer um bloco de oito
 * fichas iguais. O dourado é a cor do prêmio no resto do jogo (o baú da faixa
 * de baixo, o selo do Level Reward), e é para ele que o olho vai.
 */
/*
 * As fichas de estado entram na MESMA fileira das de level, atrás de uma divisa
 * fina. A fileira quebra sozinha quando a janela é estreita (`flex-wrap` no
 * `.tbicho-faixas`), e aí as duas famílias caem em linhas separadas sem
 * ninguém pedir — que é o arranjo certo quando há espaço para isso.
 */
.tbicho-estados {
  display: inline-flex; flex-wrap: wrap; gap: 5px;
  margin-left: 5px; padding-left: 10px;
  border-left: 1px solid #ffffff1f;
}
.tbicho-estado.ativa { background: #4a3a14; border-color: #e0b45a; color: #ffe9b8; }
.tbicho-estado:hover { border-color: #e0b45a88; }

.tbicho-resumo {
  font-size: 11px; color: var(--muted); margin: 2px 0 8px;
  font-variant-numeric: tabular-nums;
}

/* O card com prêmio esperando ganha a borda dourada do resto do jogo. */
.bosstask-card.tbicho-pronta .bosstask-dentro {
  background: linear-gradient(180deg, #1d1809, #0c1215);
  box-shadow: inset 0 0 0 1px #e0b45a44;
}

/*
 * As marcas de etapa. Pequenas e na mesma linha da conta: elas são um resumo,
 * não um segundo widget — e o card não pode crescer (ele se repete 24 vezes).
 */
/* `wrap` porque a escada de boss tem DEZ degraus, e nem todo card é largo. */
.tbicho-etapas { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; line-height: 1; }
/*
 * `.tbicho-marca`, e não `.tbicho-etapa`: a primeira versão chamou os estados
 * de `tbicho-feita/pegar/aberta`, e `tbicho-pegar` já era o BOTÃO dourado de
 * pegar o prêmio. A marca herdava o padding, o fundo e a borda do botão e
 * virava um retângulo no meio da fileira.
 */
.tbicho-marca {
  font-style: normal; font-size: 11px; width: 11px; text-align: center;
  font-variant-numeric: tabular-nums;
}
.tbicho-marca-feita { color: #7fc7a4; }
.tbicho-marca-pegar { color: #e0b45a; text-shadow: 0 0 6px #e0b45a66; }
.tbicho-marca-aberta { color: #ffffff33; }

.tbicho-pegar {
  display: inline-flex; align-items: center; gap: 4px; margin-top: 4px;
  padding: 4px 10px; border-radius: 5px;
  background: #4a3a14; border: 1px solid #e0b45a; color: #ffe9b8;
  font-size: 11px; font-weight: 700; cursor: pointer; white-space: nowrap;
}
.tbicho-pegar:hover { background: #5c4819; box-shadow: 0 0 10px -3px #e0b45a; }

/*
 * ---- A task PARADA ----
 *
 * Ela fechou uma etapa, o prêmio foi pago, e nada mais conta até alguém clicar
 * em Aceitar. O card precisa mostrar isso de longe: sem cor própria ele fica
 * igual a uma task normal com a barra em zero, e quem caça uma hora sem ver
 * o número andar acha que o contador quebrou.
 *
 * Azul, e não o dourado do "tem prêmio": são dois estados diferentes que pedem
 * o mesmo gesto, e o dourado já quer dizer "tem coisa para receber".
 */
.bosstask-card.tbicho-pausada .bosstask-dentro {
  background: linear-gradient(180deg, #0d1a22, #0c1215);
  box-shadow: inset 0 0 0 1px #5aa8e044;
}
/* A régua parada não finge que anda. */
.bosstask-card.tbicho-pausada .track i { background: #5aa8e0; opacity: .5; }
.bosstask-card.tbicho-pausada .bosstask-conta { color: #7fb4d8; }
.tbicho-aceitar {
  background: #133046; border-color: #5aa8e0; color: #cfe8fb;
}
.tbicho-aceitar:hover { background: #1a4262; box-shadow: 0 0 10px -3px #5aa8e0; }

/* A nota do topo quando o passe está valendo: o aviso vira confirmação. */
.shop-note.tbicho-passe { color: #7fc7a4; }

/*
 * ---- O "?" do filtro ----
 *
 * Redondo e dourado, encostado em "Quase finalizadas". Ele é o único botão da
 * fileira que não peneira nada, e é a FORMA que diz isso: as fichas são
 * retângulos, ele é um círculo. Com a mesma forma, seria lido como mais um
 * filtro e clicado por engano.
 */
.tbicho-ajuda {
  flex: none; width: 22px; height: 22px; margin-left: 4px; padding: 0;
  border-radius: 50%; cursor: pointer; line-height: 1;
  background: #3a2f12; border: 1px solid #e0b45a88; color: #ffe9b8;
  font-size: 12px; font-weight: 700; font-family: var(--font-heading);
}
.tbicho-ajuda:hover { background: #5c4819; box-shadow: 0 0 10px -3px #e0b45a; }
.tbicho-ajuda.ativa { background: #e0b45a; border-color: #e0b45a; color: #1a1408; }

/*
 * A faixa do Auto Task usa o desenho da do Auto Boss (`.auto-boss`), com a cor
 * trocada: a do boss é vermelha porque fala de luta, e esta fala de contagem.
 * Ver `faixaDoAutoTask`.
 */
.auto-boss.auto-task { border-color: #5aa8e055; }
.auto-boss.auto-task .auto-boss-topo b { color: #9ecbe8; }
#modal .auto-boss.auto-task .confirm-actions .auto-task-comprar {
  background: linear-gradient(180deg, #2a5f8a, #17405f); border-color: #5aa8e0; color: #eaf6ff;
  font-weight: 700; letter-spacing: .02em;
}
#modal .auto-boss.auto-task .confirm-actions .auto-task-comprar:hover {
  box-shadow: 0 0 14px -3px #5aa8e0;
}

.tbicho-mais {
  display: block; width: 100%; margin: 12px 0 2px;
  padding: 7px; border-radius: 6px;
  background: #0d1315; border: 1px dashed #ffffff26; color: var(--muted);
  font-size: 11px; cursor: pointer;
}
.tbicho-mais:hover { border-color: var(--accent-dim); color: var(--text); }


/* ---- A aba do Desmanche, na forja ----
 *
 * Ela reaproveita o que já existe onde dá: a grade de itens é a `.filter-grid`
 * do filtro de loot (mesmo quadradinho, mesmo tamanho) e os degraus de
 * quantidade são os botões `.filtro-afixo-opcao` da regra do afixo. O que é
 * próprio daqui são as três caixas: o cabeçalho do token, o grupo e a ficha.
 */
.desmanche-topo {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px; margin-bottom: 12px; border-radius: 8px;
  background: linear-gradient(180deg, #121a1e, #0e1417);
  border: 1px solid #ffffff1f;
}
.desmanche-topo-texto { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.desmanche-topo b { color: var(--tier); font-size: 15px; letter-spacing: 0.2px; }
.desmanche-topo em { color: var(--muted); font-style: normal; font-size: 11px; }

/*
 * ---- Cada grupo é uma LINHA ----
 *
 * Duas tentativas antes desta, e as duas tortas pelo mesmo motivo: os sete
 * grupos têm tamanhos muito diferentes (o Umbral tem trinta peças, o Lions
 * tem onze).
 *
 *   colunas iguais   a caixa de um item ficava do tamanho da de trinta, com o
 *                    vazio no meio — "tá sobrando pros lado";
 *   flex embrulhando as alturas ficavam desencontradas e o último caía sozinho
 *                    numa fileira com meia tela vazia ao lado — "ta meio
 *                    quebrado o modal".
 *
 * Em LINHA o problema não existe: o nome e o pagamento numa coluna fixa à
 * esquerda, as peças correndo para a direita, e cada linha com a altura das
 * peças dela. Sete linhas empilhadas, sem buraco nenhum e sem a largura de uma
 * mandar na da outra.
 */
.desmanche-grupos { display: flex; flex-direction: column; gap: 8px; }
.desmanche-grupo {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 8px 10px; border-radius: 8px;
  background: #0d1315; border: 1px solid #ffffff14;
}
.desmanche-grupo.vazio { opacity: 0.6; }
.desmanche-grupo-lado { flex: 0 0 150px; min-width: 150px; }
.desmanche-grupo .filter-grid { flex: 1 1 auto; justify-content: flex-start; }

/*
 * O nome e o pagamento em DOIS andares.
 *
 * "quando tiver ali escrito embaixo tá feio": eles dividiam a mesma linha, em
 * corrido, e o nome do conjunto encostava no número. São coisas de pesos
 * diferentes, e agora uma fica em cima da outra — com a sprite do token
 * ancorando a de baixo.
 */
.desmanche-grupo-nome {
  display: flex; align-items: center; gap: 4px;
  padding-bottom: 5px; margin-bottom: 5px; border-bottom: 1px solid #ffffff12;
}
.desmanche-grupo-nome b {
  font-family: var(--font-heading, inherit);
  font-size: 13px; letter-spacing: 0.3px; color: var(--text);
}
.desmanche-grupo.vazio .desmanche-grupo-nome { border-bottom-color: transparent; padding-bottom: 0; }
.desmanche-grupo-quantas {
  min-width: 18px; padding: 1px 5px; border-radius: 999px; text-align: center;
  background: #ffffff12; color: var(--muted); font-size: 10px;
}
.desmanche-grupo-paga { display: flex; align-items: center; gap: 5px; margin-bottom: 7px; }
.desmanche-grupo-paga b { color: var(--tier); font-size: 12px; }
.desmanche-grupo-paga span { color: var(--muted); font-size: 11px; }
.desmanche-grupo.vazio .desmanche-grupo-paga { margin-bottom: 0; }

.desmanche-ficha {
  margin-top: 12px; padding: 10px; border-radius: 8px;
  background: #0f1518; border: 1px solid var(--accent-dim);
}
.desmanche-ficha-nome { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.desmanche-ficha-nome b { font-size: 14px; }
.desmanche-ficha-nome em { color: var(--muted); font-style: normal; font-size: 11px; }
.desmanche-quantos { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.desmanche-conta {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  margin: 0 0 8px; font-size: 13px;
}
.desmanche-conta b:last-of-type { color: var(--tier); }

/*
 * ---- A setinha que abre a lista inteira do grupo ----
 *
 * "a setinha pra eu ver o que pode ser desmanchado quase não dá pra ver."
 *
 * Era um triângulo cinza do tamanho do texto, sem moldura. Agora é um botão com
 * fundo, borda e a contagem do grupo dentro — o número é o convite, e ele se lê
 * de longe. Acende no hover como os outros botões da forja.
 */
.desmanche-seta {
  display: inline-flex; align-items: center; gap: 3px;
  margin-left: 6px; padding: 2px 6px; border-radius: 999px; cursor: pointer;
  background: #16242a; border: 1px solid var(--accent-dim); color: var(--accent);
  font-size: 11px; line-height: 1;
}
.desmanche-seta:hover { background: #1c3138; border-color: var(--accent); color: var(--text); }
.desmanche-seta-conta { font-weight: 700; }
.desmanche-seta-bico { font-size: 9px; opacity: 0.85; }
.desmanche-grupo-direita { margin-left: auto; display: flex; align-items: center; gap: 6px; }

/*
 * ---- A sprite maior, SÓ aqui ----
 *
 * "a sprite dos itens ali do desmanche pode aumentar."
 *
 * O quadradinho de 44px é o do filtro de loot, onde a grade tem oitenta itens.
 * Aqui são três ou quatro, e o desenho é o que diferencia uma soulcrusher de
 * uma soulmaimer. A regra é escopada ao desmanche para não mexer nas outras
 * dezenas de grades do jogo que usam a mesma classe.
 */
.desmanche-grupo .filter-grid { grid-template-columns: repeat(auto-fill, 56px); gap: 6px; max-height: none; }
.desmanche-grupo .filter-grid .cell { width: 56px; height: 56px; }

/* A caixinha da lista do grupo. */
.desmanche-lista-resumo { display: flex; align-items: center; gap: 6px; margin: 0 0 10px; font-size: 12px; }
.desmanche-lista-resumo b { color: var(--tier); }
.desmanche-lista-resumo span { color: var(--muted); }
.desmanche-lista { display: grid; gap: 4px; max-height: 52vh; overflow-y: auto; }
.desmanche-lista-linha {
  display: flex; align-items: center; gap: 8px;
  padding: 5px 8px; border-radius: 6px;
  background: #0d1315; border: 1px solid #ffffff0f;
}
.desmanche-lista-linha.tem { border-color: var(--accent-dim); background: #101a1c; }
.desmanche-lista-texto { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1; }
.desmanche-lista-texto b { font-size: 12px; }
.desmanche-lista-texto span { color: var(--muted); font-size: 10px; }
.desmanche-lista-linha.tem .desmanche-lista-texto span { color: var(--accent); }
.desmanche-lista-paga { display: flex; align-items: center; gap: 3px; }
.desmanche-lista-paga b { color: var(--tier); font-size: 12px; }

/*
 * ---- Uma linha por peça marcada, dentro da ficha ----
 *
 * "diminuir um pouco o preview debaixo."
 *
 * A linha encolheu: o nome, o contador e a conta cabem em duas fileiras em vez
 * de quatro, e o texto desceu um ponto. O andar de baixo é conferência — quem
 * está escolhendo olha para a grade lá em cima, e cada pixel que esta parte
 * devolve é um item a mais visível lá.
 */
.desmanche-linha {
  padding: 5px 8px; border-radius: 6px; margin-bottom: 4px;
  background: #0d1315; border: 1px solid #ffffff12;
}
.desmanche-linha:last-of-type { margin-bottom: 8px; }
.desmanche-linha .desmanche-ficha-nome { margin-bottom: 3px; gap: 6px; }
/* A conta vem no fim da fileira do deslizante, e é o que ela responde. */
.desmanche-passo .desmanche-conta { margin: 0 0 0 auto; padding-left: 8px; }
/* Quem tem uma cópia só não tem deslizante: a conta sobe para a do nome. */
.desmanche-ficha-nome .desmanche-conta { margin: 0 0 0 auto; }
.desmanche-linha-texto { display: flex; align-items: baseline; gap: 6px; min-width: 0; flex: 1; }
.desmanche-linha-texto b { font-size: 12px; }
.desmanche-linha-texto em { color: var(--muted); font-style: normal; font-size: 10px; }
.desmanche-linha .desmanche-conta { margin: 4px 0 0; font-size: 12px; }
.desmanche-linha .filter-legend { display: block; margin-top: 3px; font-size: 10px; }
.desmanche-tirar {
  margin-left: auto; padding: 1px 6px; border-radius: 6px; cursor: pointer;
  background: #0d1315; border: 1px solid #ffffff1f; color: var(--muted); font-size: 11px;
}
.desmanche-tirar:hover { border-color: var(--danger, #b5483f); color: var(--text); }
.desmanche-total { border-top: 1px solid #ffffff14; padding-top: 8px; }
.desmanche-total .desmanche-conta { font-size: 13px; margin-bottom: 6px; }

/*
 * ---- O contador de quantas ----
 *
 * "cada item no desmanche eu só consigo desmanchar 1 ou tudo — tem que ter a
 *  opção de eu ir clicando pra selecionar quantos eu quero."
 *
 * Menos, o número, mais — e os degraus do lua ao lado, como atalho. O número
 * tem largura fixa para a linha não pular de tamanho ao passar de 9 para 10.
 */
.desmanche-passo { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/*
 * O deslizante: "em vez de + e - pra adicionar quantidade, teria que ser um
 * scrollzinho horizontal". Pintado a mao porque o `range` de fabrica nao segue
 * a cor de nada — ele sairia cinza de sistema no meio de uma tela escura.
 */
.desmanche-trilho {
  -webkit-appearance: none; appearance: none;
  flex: 1 1 150px; min-width: 110px; max-width: 260px; height: 18px;
  background: none; cursor: pointer;
}
.desmanche-trilho:disabled { opacity: 0.4; cursor: default; }
.desmanche-trilho::-webkit-slider-runnable-track {
  height: 5px; border-radius: 999px; background: #1b262b; border: 1px solid #ffffff14;
}
.desmanche-trilho::-moz-range-track {
  height: 5px; border-radius: 999px; background: #1b262b; border: 1px solid #ffffff14;
}
.desmanche-trilho::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none; margin-top: -6px;
  width: 16px; height: 16px; border-radius: 50%;
  background: var(--accent); border: 2px solid #0d1315;
}
.desmanche-trilho::-moz-range-thumb {
  width: 16px; height: 16px; border-radius: 50%;
  background: var(--accent); border: 2px solid #0d1315;
}
.desmanche-trilho:hover::-webkit-slider-thumb { background: var(--text); }
.desmanche-trilho:hover::-moz-range-thumb { background: var(--text); }
.desmanche-passo-numero {
  min-width: 34px; text-align: center; font-size: 14px; color: var(--accent);
}
.desmanche-passo-de { color: var(--muted); font-size: 10px; margin-right: 2px; }
.desmanche-passo .desmanche-quantos { margin: 0; gap: 4px; }
.desmanche-passo .filtro-afixo-opcao { padding: 2px 7px; font-size: 10px; }

/* A coluna da esquerda de cada linha de grupo. */
.desmanche-grupo-paga { flex-wrap: wrap; }
.desmanche-grupo-por { color: var(--muted); font-size: 11px; }

/*
 * ---- A escolha fica GRUDADA no pé ----
 *
 * Sete linhas de grupo enchem a janela, e a ficha da escolha nascia embaixo
 * delas: marcar uma peça e não ver nada acontecer — porque a conta e o botão
 * estavam fora da tela — é o mesmo que a tela não ter respondido.
 *
 * Grudada no pé do corpo do modal, ela responde na hora, e os grupos continuam
 * rolando atrás. O teto de 42vh existe para o caso de muitas peças marcadas:
 * ela rola por dentro em vez de comer a tela inteira.
 */
.desmanche-ficha {
  position: sticky; bottom: -10px; z-index: 2;
  box-shadow: 0 -10px 18px #06080ab3;
}
/*
 * Só a LISTA rola. O rodapé com a soma e os dois botões fica fora dela, no pé
 * da ficha, e por isso não some quando há quatro peças marcadas — era o "o
 * botão de desmanchar e cancelar tem que scrolar pra ver ele".
 *
 * 30vh é onde cabem umas quatro linhas: o bastante para a lista parecer uma
 * lista, e pouco o bastante para a grade de cima continuar visível.
 */
.desmanche-linhas { max-height: 30vh; overflow-y: auto; overflow-x: hidden; }

/* ---------------------------------------------------------------------------
 * O atalho para a área de Boss Diários, no topo da aba de Bosses
 *
 * "faz meio que chamativo, e quando tiver algum boss lá ativo informar boss
 *  ativo".
 *
 * Chamativo é a palavra, e ela tem limite: a faixa fica em cima de 87 cards de
 * sala, e se gritar mais alto que eles a aba deixa de ser a aba de bosses.
 * Então ela é larga e tem cor própria — o vermelho de boss —, mas só ACENDE
 * (borda quente, selo pulsando) quando há alguém lá dentro. Vazia ela é só a
 * porta, e uma porta não pisca.
 * ------------------------------------------------------------------------- */
.arena-atalho {
  display: flex; align-items: center; gap: 12px; width: 100%;
  margin: 0 0 12px; padding: 10px 14px 10px 10px; cursor: pointer;
  text-align: left; border-radius: 12px;
  background: linear-gradient(115deg, #24100c 0%, #1a0d10 55%, #141a1d 100%);
  border: 1px solid #5c2a2a;
  box-shadow: inset 0 1px 0 #ffffff0f;
  transition: border-color .18s ease, box-shadow .18s ease, background .18s ease;
}
.arena-atalho:hover { border-color: #a33228; box-shadow: inset 0 1px 0 #ffffff14, 0 0 18px #a3322840; }
.arena-atalho.ativo {
  border-color: #a33228;
  box-shadow: inset 0 1px 0 #ff9a9126, 0 0 22px #a3322859;
}

.arena-atalho-arte {
  flex: none; width: 52px; height: 52px; overflow: hidden;
  display: grid; place-items: center; border-radius: 10px;
  background: radial-gradient(circle at 50% 35%, #5a1c22, #180a0d 70%);
  border: 1px solid #8c3a42;
}
.arena-atalho-arte canvas { image-rendering: pixelated; max-width: 100%; max-height: 100%; }
/* Sem ninguém lá dentro, a caveira: a faixa continua sendo a porta. */
.arena-atalho-vazio { font-size: 22px; color: #8c6a62; line-height: 1; }

.arena-atalho-dizeres { display: grid; gap: 2px; min-width: 0; flex: 1; }
.arena-atalho-dizeres b {
  font-family: var(--font-title); font-size: 15px; letter-spacing: .02em; color: #ffd9c2;
}
.arena-atalho-dizeres span { font-size: 12px; color: var(--muted); }
.arena-atalho.ativo .arena-atalho-dizeres span { color: #f0c2b6; }

/*
 * ---- A vida do boss, dentro da faixa ----
 *
 * Fina e sem retrato: a faixa é um ATALHO, e a barra grande dele já existe
 * dentro da arena. Aqui ela responde uma coisa só — "ainda dá tempo?".
 *
 * O número vem do servidor em por cento inteiro e só chega quando muda de
 * ponto; não há relógio nenhum desenhando isto de segundo em segundo.
 */
.arena-atalho-vidas { display: grid; gap: 3px; margin-top: 5px; }
.arena-atalho-vida em {
  display: block; font-style: normal; font-size: 10px; color: var(--muted); margin-bottom: 1px;
}
.arena-atalho-trilho {
  position: relative; height: 12px; border-radius: 6px; overflow: hidden;
  background: #2a0e12; border: 1px solid #00000080; box-shadow: inset 0 2px 4px #0009;
}
.arena-atalho-trilho i {
  display: block; height: 100%;
  background: linear-gradient(180deg, #ff6b5e, #b81f2c 60%, #7d101c);
  box-shadow: inset 0 1px 0 #ffffff40;
  transition: width .25s linear;
}
.arena-atalho-trilho span {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-size: 9px; font-weight: 700; color: #fff; letter-spacing: .04em;
  text-shadow: 0 1px 2px #000; font-variant-numeric: tabular-nums;
}
/* Abaixo de um terço ela esquenta, como as outras duas barras de boss. */
.arena-atalho-vida.aperto .arena-atalho-trilho i {
  background: linear-gradient(180deg, #ffb057, #d9631a 60%, #8a3a08);
}

/*
 * ---- O botão de loot ----
 *
 * A faixa inteira é um botão que ENTRA na arena; este é um botão dentro dele.
 * É por isso que o clique dele para de subir no JS — sem isso, olhar o loot
 * mandaria a pessoa para dentro da sala.
 */
.arena-atalho-loot {
  flex: none; align-self: center; cursor: pointer;
  padding: 4px 11px; border-radius: 8px;
  background: #ffffff0d; border: 1px solid #8c3a4299; color: #ffc9a8;
  font-family: var(--font-heading); font-size: 9.5px; letter-spacing: .1em;
  text-transform: uppercase;
  transition: border-color .15s ease, color .15s ease, background .15s ease;
}
.arena-atalho-loot:hover, .arena-atalho-loot.aberto {
  background: #ff6a4d26; border-color: #ff8a6d; color: #fff0e6;
}
/* Pendurada FORA da faixa: ela tem de continuar do tamanho de um atalho. */
.arena-atalho { position: relative; }
.arena-atalho-loot-caixa {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 3;
  width: min(340px, 86vw); max-height: 46vh; overflow-y: auto;
  padding: 9px 10px; border-radius: 10px; cursor: default;
  background: #100a09f7; border: 1px solid #7a2f36;
  box-shadow: 0 14px 34px #000000c4;
}
.arena-atalho-loot-caixa[hidden] { display: none; }
.arena-atalho-loot-caixa b {
  display: block; margin: 8px 0 6px;
  font-family: var(--font-heading); font-size: 10.5px; letter-spacing: .07em;
  text-transform: uppercase; color: #ffb9a6;
}
.arena-atalho-loot-caixa b:first-child { margin-top: 0; }
.arena-atalho-loot-caixa .bag { gap: 4px; }
.arena-atalho-loot-caixa .empty { margin: 0; font-size: 11.5px; }

/* O selo só existe quando há boss: ver a nota acima. */
.arena-atalho-selo {
  flex: none; padding: 3px 11px; border-radius: 999px;
  background: #ff6a4d1f; border: 1px solid #ff8a6d; color: #ffb9a6;
  font-family: var(--font-heading); font-size: 9.5px; letter-spacing: .13em;
  text-transform: uppercase;
  animation: arena-selo-pulsa 1.6s ease-in-out infinite;
}
@keyframes arena-selo-pulsa {
  0%, 100% { box-shadow: 0 0 0 #ff6a4d00; }
  50% { box-shadow: 0 0 12px #ff6a4d80; }
}
@media (prefers-reduced-motion: reduce) {
  .arena-atalho-selo { animation: none; }
}

/* ==========================================================================
   AS GAVETAS DA BARRA DE CIMA
   ==========================================================================

   Quatro botões da fileira não abrem janela: abrem uma fileira menor logo
   abaixo deles — Sistemas, Personagem, Tarefas e Social. Ver `BARRA` e
   `alternarGaveta`, em main.mjs.

   A gaveta é filha do `body`, e não da fileira: `.tools` tem
   `overflow-y: hidden` e cortaria qualquer coisa que descesse abaixo da barra.
   Por isso ela é `position: fixed` e a esquerda dela é calculada no JS.
   ========================================================================== */

.gaveta-da-barra {
  position: fixed; z-index: 31;
  display: flex; align-items: flex-start; gap: 2px;
  padding: 7px 9px;
  background: linear-gradient(180deg, #131b1ef7, #0c1113fa);
  border: 1px solid var(--line-strong, var(--line));
  border-radius: 11px;
  /* A sombra é o que a descola da barra: sem ela a gaveta parece um pedaço
     da topbar que desalinhou, e não uma coisa que abriu por cima do jogo. */
  box-shadow: 0 12px 26px #000b, inset 0 1px 0 #ffffff0a;
  animation: gaveta-abre .13s ease-out;
}
/* `display: flex` vence o `display: none` que o atributo `hidden` traz de
   fábrica — sem esta linha a gaveta nasceria aberta. */
.gaveta-da-barra[hidden] { display: none; }
@keyframes gaveta-abre {
  from { opacity: 0; transform: translateY(-5px); }
  /* Termina em `none`, e não em `translateY(0)`: uma transformação parada
     mantém a camada composta e deixa o texto meio pixel fora da grade. */
  to { opacity: 1; transform: none; }
}

/*
 * Os botões de dentro são os mesmos da fileira, só que com folga.
 *
 * Aqui não há briga por largura — a gaveta cresce com o que tem dentro —,
 * então a legenda cabe inteira e o desenho pode ser maior do que o de cima.
 * É a diferença que faz a gaveta parecer um menu, e não a barra repetida.
 */
.gaveta-da-barra button {
  position: relative;
  background: none; border: none; border-radius: 7px;
  padding: 3px 2px 2px; cursor: pointer; font-size: 13px;
  display: flex; flex-direction: column; align-items: center; justify-content: flex-start;
  /*
   * A largura é do CONTEÚDO, com um piso.
   *
   * Era 64px fixos, e "Recompensa de Boss" saía cortado — o nome por extenso
   * foi justamente o que o dono pediu ("onde está escrito só Conta, escreva
   * Baú da Conta"), então cortá-lo aqui desfazia o pedido em silêncio.
   *
   * A gaveta não tem a briga de espaço da fileira: ela cresce com o que tem
   * dentro. O piso de 64px é só para os nomes curtos não virarem botões
   * estreitos ao lado dos compridos.
   */
  gap: 4px; min-width: 64px; max-width: 132px; flex: none;
  filter: drop-shadow(0 0 1px #0a0d0f) drop-shadow(0 0 4px #3fbfa877);
  transition: filter .16s ease;
}
.gaveta-da-barra button .icon {
  width: 32px; height: 32px; display: block; object-fit: contain; image-rendering: auto;
}
.gaveta-da-barra button.fallback .icon { width: 24px; height: 24px; image-rendering: pixelated; }
.gaveta-da-barra button .label {
  display: block; width: 100%; text-align: center;
  font-size: 9.5px; line-height: 1.15; letter-spacing: .01em; color: #6d7f86;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.gaveta-da-barra button:hover {
  filter: drop-shadow(0 0 4px #3fbfa8) drop-shadow(0 0 11px #3fbfa877);
}
.gaveta-da-barra button:hover .label { color: var(--accent); }
.gaveta-da-barra [data-tool][aria-selected="true"] {
  filter: drop-shadow(0 0 1px #0a0d0f) drop-shadow(0 0 4px #3fbfa8cc);
}
.gaveta-da-barra [data-tool][aria-selected="true"] .label { color: var(--accent); }
.gaveta-da-barra button:disabled { cursor: default; opacity: .35; filter: grayscale(.6); }

/* O mesmo facho dourado da fileira, para o item com ponto a gastar. */
.gaveta-da-barra button.alerta::after {
  content: ""; position: absolute; inset: -2px; border-radius: 9px; padding: 2px; pointer-events: none;
  background: conic-gradient(from var(--store-angle), transparent 0%, #ffd980 8%, #fff6d0 12%, #ffd980 16%, transparent 26%, transparent 100%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  animation: store-orbit 3s linear infinite;
}
.gaveta-da-barra button.alerta { filter: drop-shadow(0 0 1px #0a0d0f) drop-shadow(0 0 5px #d9ae4a66); }

/*
 * ---- O botão que ABRE uma gaveta ----
 *
 * Ele precisa dizer, parado, que não é uma ferramenta: o seta embaixo do nome
 * é a única diferença visível entre "isto abre a mochila" e "isto abre mais
 * cinco botões". Com a fileira apertada a legenda some e a seta vai junto —
 * aí o balão do hover é quem conta, e ele já lista o que há dentro.
 */
.tools button.grupo .label::after { content: " ⌄"; opacity: .5; }
.tools button.com-gaveta-aberta {
  filter: drop-shadow(0 0 4px #3fbfa8) drop-shadow(0 0 11px #3fbfa877);
}
.tools button.com-gaveta-aberta .label { color: var(--accent); }
.tools button.com-gaveta-aberta .label::after { opacity: 1; }

/* Barra recolhida: a gaveta não pode ficar pendurada no ar sem a barra. */
body.topbar-recolhida .gaveta-da-barra { display: none; }

/* O balão do botão de grupo lista o que há dentro, em duas colunas. */
.tip-gaveta {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 2px 12px; margin-top: 6px;
  font-size: 11.5px; color: var(--muted);
}
.tip-gaveta span::before { content: "• "; color: var(--accent-dim, var(--accent)); }

@media (prefers-reduced-motion: reduce) {
  .gaveta-da-barra { animation: none; }
  .gaveta-da-barra button.alerta::after { animation: none; }
}

/* ==========================================================================
   A FILEIRA JUNTA, E O CANTO DA DIREITA
   ==========================================================================

   "junta eles meio que no meio sem aquele pontinho que separa eles, só o Sair
    e Opções que você deixa lá no canto direito."

   Era `space-between`, que repartia toda a sobra entre os botões — com vinte e
   um deles isso era o que fazia a fileira ocupar a barra inteira. Com seis, a
   mesma regra os espalhava de uma ponta à outra com buracos no meio.
   ========================================================================== */

/*
 * ---- Mais três pixels entre os ícones da fileira ----
 *
 * "dá um espaço de uns 3 pixels a mais entre os ícones da topbar (só espaça
 *  mais os da topbar, os que ficam no subícone não)."
 *
 * Eram 5px, herdados de quando a fileira tinha vinte e um botões e cada pixel
 * contava. Com sete, o aperto virou o problema: sete desenhos coloridos colados
 * leem como uma faixa só. A gaveta não muda — lá os botões já respiram, e o
 * pedido diz isso com todas as letras.
 */
.tools { justify-content: center; gap: 8px; }
/*
 * O canto come a sobra da esquerda e encosta na borda.
 *
 * `margin-left: auto` num item flex é o que empurra ele e tudo o que vem
 * depois; como só há ele depois do meio, o efeito é exatamente "o resto fica
 * centrado, estes dois ficam na direita".
 */
.canto-da-barra { display: flex; gap: 5px; margin-left: auto; flex: none; }

/*
 * ---- O dinheiro é clicável, e precisa parecer ----
 *
 * Sem marca nenhuma ninguém descobre que o número abre o banco: o balão só
 * conta depois que a pessoa já parou o mouse ali, e ela só para o mouse ali se
 * algo disser que há o que ver. A moldura fraca e o cursor de mão são esse
 * algo.
 */
.wallet.abre-banco {
  cursor: pointer; border-radius: 8px; padding: 2px 7px; margin: 0 -3px;
  border: 1px solid transparent;
  transition: background-color .16s ease, border-color .16s ease;
}
.wallet.abre-banco:hover {
  background: #d9ae4a14; border-color: var(--accent-dim, var(--accent));
}

/* ==========================================================================
   CHARMS: A GRADE COMPACTA E A FICHA AO LADO
   ==========================================================================

   "a tela de charms eu queria deixar mais bonita e mais compacta... olha bem
    como está essa tela e tenta fazer parecido na nossa."

   Eram vinte e cinco cartões de 230px com o parágrafo do efeito dentro de cada
   um. Aqui a lista guarda só o que serve para ESCOLHER, e o texto longo mora
   uma vez só, na ficha da direita. Ver `renderCharms`, em panels.mjs.

   As cores são as de sempre: nada aqui inventa paleta.
   ========================================================================== */

.charm-tela {
  display: grid; grid-template-columns: minmax(0, 1fr) 286px; gap: 12px;
  align-items: start; margin-top: 10px;
}
/* Estreitou: a ficha desce para baixo da grade em vez de espremer as duas. */
@media (max-width: 820px) {
  .charm-tela { grid-template-columns: minmax(0, 1fr); }
}

/* ---- A grade ---- */

.charm-grade {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 6px;
  align-content: start;
}
.charm-tile {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 9px 5px 7px; min-width: 0; cursor: pointer;
  background: #0b0f1099; border: 1px solid var(--line); border-radius: 8px;
  color: inherit; font: inherit; text-align: center;
  transition: border-color .14s ease, background-color .14s ease;
}
.charm-tile:hover { background: #ffffff0e; border-color: var(--line-strong, var(--line)); }
/* Já comprado: a moldura acende, como o `.owned` do cartão antigo fazia. */
.charm-tile.tem { border-color: var(--accent-dim); background: #3fbfa80d; }
/*
 * O selecionado é o que a ficha ao lado está descrevendo, e precisa ser
 * inconfundível: a moldura inteira em accent mais um degrau de fundo. Sem isso
 * a pessoa clica, a direita troca, e ela não sabe de onde veio.
 */
.charm-tile.sel {
  border-color: var(--accent); background: #3fbfa81c;
  box-shadow: inset 0 0 0 1px #3fbfa844;
}
.charm-tile b {
  font-family: var(--font-heading); font-size: 10.5px; line-height: 1.15;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.charm-tile .charm-icon { width: 26px; height: 26px; }
.charm-tile .charm-tiers { margin: 0; }
.charm-tile em {
  font-style: normal; font-size: 10px; color: var(--muted); letter-spacing: .02em;
}
/* Dá para comprar agora: é a única pergunta que se faz olhando a grade. */
.charm-tile em.pode { color: var(--accent); }
.charm-tile em.charm-max { color: var(--copper); }

/* ---- A ficha da direita ---- */

.charm-ficha {
  display: grid; gap: 9px; align-content: start; min-width: 0;
  padding: 11px; border: 1px solid var(--line); border-radius: 9px;
  background: linear-gradient(180deg, #0e1416cc, #0a0e0fcc);
}
.charm-ficha-topo { display: flex; align-items: center; gap: 9px; min-width: 0; }
.charm-ficha-topo .grow { min-width: 0; display: grid; gap: 1px; }
.charm-ficha-topo b { font-family: var(--font-heading); font-size: 14px; letter-spacing: .03em; }
.charm-ficha-topo .grow span {
  font-size: 9.5px; letter-spacing: .12em; text-transform: uppercase; color: var(--muted);
}
.charm-icon.grande { width: 40px; height: 40px; }
.charm-selo {
  flex: none; align-self: flex-start;
  font-size: 9px; letter-spacing: .1em; text-transform: uppercase;
  padding: 3px 7px; border-radius: 999px;
  border: 1px solid var(--line); color: var(--muted);
}
.charm-selo.tem { border-color: var(--accent-dim); color: var(--accent); }

.charm-ficha .charm-text { font-size: 11.5px; line-height: 1.45; }

/* ---- As linhas de número ---- */

.charm-linhas { display: grid; gap: 1px; }
.charm-linha {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  padding: 5px 0; border-top: 1px solid #ffffff0d;
}
.charm-linha:first-child { border-top: none; }
.charm-linha dt {
  margin: 0; font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--muted);
}
.charm-linha dd {
  margin: 0; font-size: 12px; text-align: right; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* O valor que responde "dá para agora?" — chance ativa, preço alcançável. */
.charm-linha dd.forte { color: var(--accent); }

.charm-acoes { display: grid; gap: 6px; }
.charm-acoes button {
  width: 100%; padding: 8px 10px; cursor: pointer;
  background: var(--accent-dim); border: 1px solid var(--accent); border-radius: 6px;
  color: #04100d; font: inherit; font-size: 12px; font-weight: 700; letter-spacing: .02em;
}
.charm-acoes button:hover:not(:disabled) { background: var(--accent); }
.charm-acoes button:disabled {
  background: var(--panel); border-color: var(--line); color: var(--muted); cursor: not-allowed;
}
.charm-acoes .charm-max { text-align: center; font-size: 11px; }

/* ---- O saldo, no rodapé ---- */

.charm-rodape {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: 12px; padding: 9px 11px;
  border: 1px solid var(--line); border-radius: 9px; background: #0b0f1099;
}
.charm-saldo {
  display: grid; gap: 1px; padding: 2px 12px 2px 0; border-right: 1px solid #ffffff0f;
}
.charm-saldo:last-of-type { border-right: none; }
.charm-saldo span {
  font-size: 9px; letter-spacing: .11em; text-transform: uppercase; color: var(--muted);
}
.charm-saldo b { font-family: var(--font-heading); font-size: 15px; color: var(--accent); }
.charm-rodape p { margin: 0; flex: 1; min-width: 180px; font-size: 10.5px; color: var(--muted); }

/*
 * A busca de criatura dentro da ficha.
 *
 * Ela é a mesma de antes (`escolhaDaCriatura`), e só precisa de um respiro do
 * bloco de botões — o resto das regras dela continua valendo como está.
 */
.charm-ficha .charm-alvo { margin-top: 2px; }

/* ==========================================================================
   A OFICINA DE IMBUIR — o desenho do Imbuing Shrine
   ==========================================================================

   O dono mandou a foto do santuário e o protótipo em HTML: faixas com título
   centralizado, os itens em quadrados de 64, três encaixes de 70 lado a lado,
   dois menus, a caixa do efeito e uma fileira de "precisa de" que termina num
   botão grande com o ícone de encaixe.

   ---- AS CORES SÃO VARIÁVEIS DAQUI, E NÃO DO JOGO INTEIRO ----

   "usar variáveis CSS com escopo na janela de imbuements, para não vazar estilo
   para o resto do jogo."

   Elas moram em `.modal-box.imbue`, então valem só enquanto esta janela está na
   tela. Mexer numa delas não tem como mudar a cor de nenhuma outra tela.

   ---- O CONTORNO É O DO JOGO, E NÃO UM DOURADO DAQUI ----

   "a janela está usando contornos dourados (moldura, seções, dropdowns, caixas,
    slot/item selecionado, caixa de gold). Trocar TODOS pelo contorno padrão."

   Havia dois hex de moldura só desta tela — `#8a6d3b` e `#e0b464` — e eles
   faziam a janela parecer de outro jogo, ao lado de vinte janelas com moldura
   `--line` e seleção `--accent`. As três variáveis de contorno abaixo agora
   APONTAM para as do jogo: mudar o teal do jogo muda esta tela junto, que é o
   contrário do que acontecia.

   O âmbar ficou, e só para AVISO — o tempo acabando e o risco na caixa de
   confirmar. Ele quer dizer "olhe aqui", e não "esta é a cor da janela".
   ========================================================================== */
.modal-box.imbue {
  --imb-corpo: #141a1c;
  --imb-sec: #1b2426;
  --imb-caixa: #24312f;
  /* Os três contornos, emprestados do jogo: moldura, seleção e hover. */
  --imb-linha: var(--line);
  --imb-forte: var(--accent);
  --imb-hover: var(--accent-dim);
  --imb-teal: var(--accent);
  --imb-ok: #6fd48a;
  --imb-falta: #e2574c;
  --imb-aviso: #e0b464;
  --imb-txt: #d8d2c2;
  --imb-apagado: #8d9691;
}

/*
 * ---- O ÍCONE NO CANTO, MEIO PARA FORA DA MOLDURA ----
 *
 * É o mesmo desenho do botão da barra de cima (ver `renderImbuements`). O
 * `margin` negativo é o que o põe montado na borda, como na foto: ele pertence
 * ao cabeçalho, mas transborda dele de propósito.
 */
.imbue-selo-arte {
  display: block; width: 46px; height: 46px; object-fit: contain;
  margin: -10px 2px -10px -6px;
  image-rendering: pixelated;
  filter: drop-shadow(0 2px 6px #000a);
}

/*
 * A linha embaixo do título, dizendo para que a janela serve.
 *
 * ---- ELA PERDEU A CAIXA ----
 *
 * "faixa do subtítulo mais compacta, ou o texto direto abaixo do título sem
 *  caixa."
 *
 * Era uma caixa com fundo e moldura, e ela virava um terceiro retângulo
 * empilhado em cima das duas seções de verdade — o primeiro deles com uma linha
 * de texto dentro. Sem a caixa ela ocupa o que ocupa: uma linha.
 */
.imbue-faixa {
  margin: -2px 0 10px;
  font-size: 12px; line-height: 1.35; color: var(--imb-apagado);
}

/* ---- As seções, com a barra de título centralizada ---- */
.imbue-sec {
  margin-bottom: 12px;
  background: var(--imb-sec);
  border: 1px solid var(--imb-linha); border-radius: 4px;
}
/* A última seção não empurra rodapé: era 14px de vão embaixo da tela. */
.imbue-sec:last-child { margin-bottom: 0; }
.imbue-sec-barra {
  padding: 6px 7px;
  background: linear-gradient(#1f2a2b, #172022);
  border-bottom: 1px solid var(--imb-linha);
  text-align: center;
  font-family: var(--font-heading); font-size: 11.5px; font-weight: 700;
  letter-spacing: .1em; color: var(--imb-apagado);
}
.imbue-sec-corpo { padding: 12px; display: grid; gap: 10px; }

/* ==========================================================================
   1. INFORMAÇÕES DA PEÇA
   ========================================================================== */
/*
 * As peças à esquerda, o divisor, e os encaixes à direita — a linha da foto.
 * `auto` na segunda coluna: os três encaixes têm largura fixa, e deixá-los em
 * `1fr` faria o divisor dançar conforme o número de peças vestidas.
 */
.imbue-peca {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 14px; align-items: center;
}
.imbue-pecas {
  display: flex; flex-wrap: wrap; gap: 8px;
  padding-right: 14px; border-right: 1px solid var(--imb-linha);
}
/*
 * O quadrado de 64 da foto. A peça escolhida ganha a borda dourada e um brilho
 * por dentro — é a única marca de seleção, e por isso ela tem de se ver de
 * relance numa fileira de oito.
 */
.imbue-peca-quadro {
  position: relative; width: 64px; height: 64px; padding: 0; cursor: pointer;
  display: grid; place-items: center;
  background: var(--imb-caixa); border: 2px solid var(--imb-linha); border-radius: 2px;
  color: inherit; font: inherit;
}
.imbue-peca-quadro:hover { border-color: var(--imb-hover); }
.imbue-peca-quadro.escolhido {
  border-color: var(--imb-forte);
  box-shadow: inset 0 0 12px rgba(63, 191, 168, .22);
}
.imbue-peca-quadro canvas { image-rendering: pixelated; }
/* O contador "usados/total" no canto, como no protótipo. */
.imbue-peca-conta {
  position: absolute; right: 4px; bottom: 1px;
  font-size: 11px; color: var(--imb-apagado); text-shadow: 0 1px 2px #000;
}

.imbue-encaixes-lado { display: flex; align-items: center; gap: 12px; }
.imbue-encaixes-lado > b { font-size: 14px; color: var(--imb-txt); }
.imbue-encaixes { display: flex; gap: 10px; }
/*
 * ---- OS ENCAIXES ----
 *
 * 70px, com a arte de encaixe do próprio cliente por fundo — a mesma que esta
 * janela já usava, e que quem jogou reconhece antes de ler qualquer rótulo. O
 * cheio troca para `encaixe-cheio.png` e recebe o ícone do encantamento por
 * cima; o que a peça não tem sai apagado e sem clique, para a fileira ter
 * sempre três e não encolher de peça para peça.
 */
.imbue-encaixe {
  position: relative; width: 70px; height: 70px; padding: 0; cursor: pointer;
  display: grid; place-items: center;
  background: var(--imb-caixa) url(/client/assets/imbuing/encaixe-vazio.png) center/54px no-repeat;
  border: 2px solid var(--imb-linha); border-radius: 2px;
  color: inherit; font: inherit;
  image-rendering: pixelated;
}
.imbue-encaixe:hover:not(:disabled) { border-color: var(--imb-hover); }
.imbue-encaixe.escolhido { border-color: var(--imb-forte); }
/*
 * ---- O ENCAIXE CHEIO É SÓ A SPRITE ----
 *
 * "encaixe PREENCHIDO: não desenhar o fundo de encaixe vazio (o 'Y') por baixo.
 *  Mostrar SÓ a sprite do imbue ocupando o quadrado inteiro, como um ícone de
 *  item no inventário."
 *
 * O `background-image: none` é o conserto: a arte do encaixe vazio continuava
 * pintada atrás do ícone de 40px, e o quadrado cheio ficava parecendo meio
 * vazio — o contrário do que ele é. Agora a sprite tem 62 dos 70px do quadrado,
 * como uma célula da mochila.
 */
.imbue-encaixe.cheio { background-image: none; }
.imbue-encaixe img { image-rendering: pixelated; }
.imbue-encaixe.cheio img { width: 62px; height: 62px; object-fit: contain; }
.imbue-encaixe.travado { opacity: .4; cursor: not-allowed; }
/* O cadeado do encaixe que a peça não tem: o `icon-locked` da janela de gemas. */
.imbue-encaixe-cadeado { width: 24px; height: 24px; object-fit: contain; opacity: .8; }
/*
 * ---- O TEMPO NUMA FAIXA, e com cor de urgência ----
 *
 * "tempo restante numa faixa escura semitransparente na base do quadrado. Menos
 *  de 1h: âmbar; menos de 10min: vermelho."
 *
 * A faixa existe porque o texto passou a ficar em cima da SPRITE, e não de um
 * fundo escuro: sem ela, "1h00" some dentro de um ícone claro. As duas cores são
 * o único âmbar e o único vermelho desta fileira, e é por isso que elas se leem
 * de longe.
 */
.imbue-encaixe-tempo {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 2px 0;
  background: rgba(6, 10, 11, .72);
  text-align: center; font-size: 10px; font-weight: 700;
  color: var(--imb-teal); text-shadow: 0 1px 2px #000;
}
.imbue-encaixe-tempo.curto { color: var(--imb-aviso); }
.imbue-encaixe-tempo.urgente { color: var(--imb-falta); }

/*
 * A barra do encaixe escolhido, com o "Remover" na ponta. Ela só aparece quando
 * o encaixe escolhido está cheio. Ver a nota em `renderImbuements` — o botão não
 * cabe dentro do quadrado de 70px, e tirar um imbuement não podia sumir daqui.
 *
 * A segunda linha é o EFEITO: a barra dizia o nome e o tempo, e o que aquele
 * encantamento faz ficava só no balão, que exige descobrir que há um balão.
 */
.imbue-barra {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin: 0; padding: 6px 10px;
  background: var(--imb-corpo); border: 1px solid var(--imb-linha); border-radius: 3px;
}
.imbue-barra-texto { min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.imbue-barra-titulo { font-size: 11.5px; color: var(--imb-txt); }
.imbue-barra-tempo { font-weight: 700; color: var(--imb-teal); }
.imbue-barra-tempo.curto { color: var(--imb-aviso); }
.imbue-barra-tempo.urgente { color: var(--imb-falta); }
.imbue-barra-efeito { font-size: 10.5px; line-height: 1.3; color: var(--imb-apagado); }
.imbue-barra button { flex: none; padding: 4px 12px; font-size: 11px; }

/*
 * ---- E QUANDO O ENCAIXE ESCOLHIDO ESTÁ CHEIO, NÃO HÁ RECEITA ----
 *
 * A seção de baixo mostrava a receita inteira e um botão apagado para uma casa
 * que não podia receber nada. Agora mostra a frase e, quando há para onde ir, o
 * atalho para o encaixe vazio.
 */
.imbue-ocupado {
  display: grid; gap: 8px; justify-items: center; text-align: center;
  padding: 14px 10px;
}
.imbue-ocupado p { margin: 0; font-size: 12.5px; color: var(--imb-apagado); }
.imbue-ir-vazio {
  padding: 5px 14px; cursor: pointer;
  background: var(--imb-caixa); border: 1px solid var(--imb-linha); border-radius: 4px;
  font: inherit; font-size: 11.5px; color: var(--imb-forte);
}
.imbue-ir-vazio:hover { border-color: var(--imb-forte); }

/* ==========================================================================
   2. IMBUIR ENCAIXE VAZIO
   ========================================================================== */
.imbue-oficina { display: grid; gap: 12px; }
.imbue-menus { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }

/*
 * ---- A CAIXA DA DESCRIÇÃO ----
 *
 * Ícone do encantamento à esquerda, o efeito em dourado e negrito à direita —
 * é a linha `.desc` do protótipo. A moldura muda com o grau, que é o que
 * continua dizendo "isto aqui é o caro".
 */
.imbue-desc {
  display: flex; align-items: center; gap: 14px; padding: 8px;
  background: var(--imb-corpo); border: 1px solid var(--imb-linha); border-radius: 3px;
}
.imbue-desc-icone {
  width: 56px; height: 56px; flex: none;
  display: grid; place-items: center;
  background: var(--imb-caixa); border: 1px solid var(--imb-linha);
}
.imbue-desc-icone img { image-rendering: pixelated; }
.imbue-desc-lado { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.imbue-desc-txt { font-weight: 700; font-size: 12.5px; line-height: 1.4; color: #e9efee; }
/* A duração, que sai do `durationMs` do catálogo — ver a nota em panels.mjs. */
.imbue-desc-dura { font-size: 11px; color: var(--imb-apagado); }
/* O grau ainda se lê na moldura, agora sem dourado: o mais forte é o mais teal. */
.imbue-desc.grau-1 { border-color: var(--imb-linha); }
.imbue-desc.grau-2 { border-color: rgba(63, 191, 168, .45); }
.imbue-desc.grau-3 { border-color: var(--imb-forte); }

/* =========================================================================
 * ---- PRECISA DE: uma linha só, e ela não quebra ----
 *
 * "a linha de requisitos quebrou: a caixa de gold caiu para a linha de baixo, as
 *  setas se separaram em duas linhas, o texto '1.000.000 g tem 0' quebrou em
 *  pedaços e sobrou uma caixa de material vazia."
 *
 * Era um flex com `flex-wrap: wrap` dentro de outro flex: quando a soma das
 * caixas passava da largura, ele fazia o que um wrap faz — dobrava onde deu, e o
 * que sobrou (o ouro, e depois as setas) desceu. Com quatro caixas em vez de
 * três, isso passou a acontecer na largura normal da janela.
 *
 * Agora são COLUNAS FIXAS, e por isso não há o que dobrar:
 *
 *     [80px]  [80px]  [120px]   [auto]    [1fr]
 *     token   token    ouro     setas     botão
 *
 * ---- E O BOTÃO É UMA COLUNA, não uma pilha ao lado ----
 *
 * "o topo do botão alinhado ao topo das caixas; a base do botão alinhada à base
 *  das legendas. Altura do botão = caixa de ícone + espaço + legenda."
 *
 * `align-items: stretch` (o padrão, escrito aqui porque é ele que faz o
 * trabalho) estica o botão até a altura da fileira, e a fileira tem a altura da
 * coluna mais alta — que é uma coluna de requisito: quadro de 80 mais o espaço
 * mais a legenda. Por isso não há altura escrita em lugar nenhum: mudar o quadro
 * de 80 para 96 muda o botão junto, sem ninguém tocar nesta regra.
 *
 * Nada fica ABAIXO da fileira. O status ("Pronto para aplicar") mora dentro do
 * botão, como terceira linha — ver `.imbue-motivo`.
 * ========================================================================= */
.imbue-req { display: grid; gap: 7px; }
/* "Precisa de:" à esquerda, a chance à direita, na mesma linha e mesma base. */
.imbue-req-titulos { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.imbue-req-rotulo { font-weight: 700; font-size: 12.5px; color: var(--imb-txt); }
.imbue-req-grade {
  display: grid;
  grid-template-columns: 80px 80px 120px auto minmax(180px, 1fr);
  align-items: stretch;
  gap: 10px;
}
/*
 * Cada material é uma coluna: o quadrado de 80 com o sprite e, embaixo, a
 * caixinha "tem/precisa". As vazias completam até três para a fileira não mudar
 * de largura de um encantamento para outro.
 */
.imbue-custo { position: relative; display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.imbue-custo-quadro {
  height: 80px; display: grid; place-items: center;
  background: var(--imb-caixa); border: 2px solid var(--imb-linha);
}
.imbue-custo-quadro canvas, .imbue-custo-quadro img { image-rendering: pixelated; }
.imbue-moeda { width: 40px; height: 40px; object-fit: contain; }
/*
 * ---- "1 · tem 477", e não "477/1" ----
 *
 * "trocar '477/1' (parece fração) por: necessário em destaque e o que tem menor
 *  ao lado."
 *
 * A barra fazia o número virar fração, e punha o grande — o que você tem — onde
 * ele não é o que se pergunta. O que se pergunta é quanto a receita pede; ter
 * 477 é a resposta tranquilizadora, e ela pode ser miúda.
 */
.imbue-custo-qtd {
  /*
   * ALTURA FIXA, e não mínima.
   *
   * A do ouro tem duas linhas (o preço e o saldo) e ficava 2px mais alta que as
   * dos materiais. Dois pixels são invisíveis na legenda — e visíveis na
   * FILEIRA: a coluna do ouro passava a ser a mais alta, a fileira crescia com
   * ela, e o botão, que estica até a altura da fileira, terminava dois pixels
   * abaixo da base das outras duas legendas. Iguais, todas as colunas têm a
   * mesma altura e a base é uma só.
   */
  height: 36px; padding: 2px 4px;
  display: flex; align-items: baseline; justify-content: center; gap: 4px;
  background: var(--imb-corpo); border: 1px solid var(--imb-linha);
  color: var(--imb-apagado);
  /* A legenda do material é UMA linha: "1 · tem 0" não pode partir no ponto. */
  white-space: nowrap;
}
.imbue-custo-qtd b { font-weight: 700; font-size: 14px; }
.imbue-custo-qtd span { font-size: 10px; }
/*
 * A do ouro é a única em duas linhas: o preço em cima e o saldo embaixo. Um
 * milhão ao lado de "tem 172.213.541" não cabe em 120px, e era essa soma que
 * partia o texto em pedaços.
 */
.imbue-custo.ouro .imbue-custo-qtd {
  flex-direction: column; align-items: center; justify-content: center; gap: 0;
  line-height: 1.25;
}
.imbue-custo-qtd.ok b { color: var(--imb-ok); }
.imbue-custo-qtd.ok span { color: #6fd48a99; }
.imbue-custo-qtd.falta b { color: var(--imb-falta); }
.imbue-custo-qtd.falta span { color: #e2574c99; }
/*
 * ---- CLICAR NO MATERIAL ABRE O MERCADO ----
 *
 * O botão cobre a coluna inteira e é transparente: o desenho da caixa é o
 * sprite e a contagem, e uma moldura de botão em cima de cada material
 * transformaria a fileira em três botões concorrendo com o de aplicar.
 *
 * É um `<button>` de verdade, e não um clique no `div`, porque ele precisa
 * receber o Tab e o Enter como qualquer outro caminho para o Mercado.
 */
.imbue-custo-clique {
  position: absolute; inset: 0; cursor: pointer;
  background: none; border: 0; padding: 0;
}
.imbue-custo:hover .imbue-custo-quadro { border-color: var(--imb-hover); }
/*
 * As setas são UM elemento, e ele não parte: `nowrap` porque "▶▶▶" com
 * `letter-spacing` negativo era o que se dividia em duas linhas quando a coluna
 * apertava.
 *
 * ---- E ELAS SE ALINHAM COM O QUADRO, e não com a coluna inteira ----
 *
 * "setas centralizadas verticalmente com as CAIXAS DE ÍCONE (não com a coluna
 *  inteira)."
 *
 * A coluna tem o quadro de 80 MAIS a legenda; centrado nela, o traço caía na
 * altura da legenda, abaixo do meio dos quadrados que ele liga. Uma caixa de
 * 80px de altura no topo da coluna é o que o põe na linha dos ícones.
 */
.imbue-setas {
  align-self: start; height: 80px; padding: 0 2px;
  display: grid; place-items: center;
  white-space: nowrap;
  color: var(--imb-apagado); font-size: 30px; letter-spacing: -6px;
}

/* =========================================================================
 * ---- O BOTÃO DE APLICAR ----
 *
 * "o quadrado à direita das setas hoje só parece clicável no hover. Transformar
 *  em um BOTÃO de verdade: ícone do imbue selecionado em cima e o texto
 *  'Aplicar imbuement' embaixo."
 *
 * Era um quadrado com o ícone de encaixe e nada escrito — e o `encaixe-vazio`
 * dentro dele dizia "encaixe", não "aplicar". Agora ele é o `button.primary` do
 * jogo (o mesmo de "Aceitar", "Confirmar" e "Enviar pedido"), e é de lá que vêm
 * o fundo, a moldura, o hover e o estado apagado. O que sobra aqui é o ARRANJO:
 * o ícone do encantamento escolhido em cima, o texto embaixo.
 * ========================================================================= */
.imbue-chance { text-align: right; font-weight: 700; font-size: 12px; color: var(--imb-apagado); }
.imbue-chance .cheia { color: var(--imb-ok); }
.imbue-chance .parcial { color: var(--imb-aviso); }
#modal .imbue-botao {
  /*
   * Sem altura: quem a dá é a fileira (ver `.imbue-req-grade`). Escrever 80px
   * aqui deixaria o botão mais curto que a coluna de requisito, que tem o quadro
   * mais a legenda — e era isso que o fazia terminar acima das legendas.
   */
  width: 100%; padding: 8px 6px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  line-height: 1.1; text-align: center;
}
.imbue-botao-nome { font: inherit; }
/*
 * ---- O ÍCONE DENTRO DO BOTÃO ----
 *
 * "o ícone do imbue dentro do botão está quase invisível."
 *
 * Ele estava apagado porque o BOTÃO estava apagado — e o botão estava apagado
 * por causa do ouro, que a tela contava errado (ver `ouroTotal`, em panels.mjs).
 * Com o `opacity: 1` escrito, o estado aceso não depende de nenhuma herança; e o
 * apagado vai a .5 em vez de .45, para o desenho continuar legível dizendo
 * "agora não".
 */
.imbue-botao img {
  width: 34px; height: 34px; object-fit: contain; image-rendering: pixelated;
  opacity: 1; filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .55));
}
.imbue-botao:disabled img { filter: grayscale(1); opacity: .5; }
/*
 * ---- O MOTIVO, DENTRO DO BOTÃO ----
 *
 * "tirar o 'Pronto para aplicar' de baixo do botão e colocar DENTRO dele, como
 *  terceira linha menor."
 *
 * Ele já morou num balão (o lugar onde ninguém procura por que um botão não
 * responde) e depois embaixo do botão — onde era a única coisa da seção a passar
 * da linha das legendas, e por isso a que desalinhava a fileira inteira.
 *
 * Dentro do botão ele é a legenda do próprio botão, e some junto com ele quando
 * o encaixe escolhido está cheio. As duas cores são explícitas porque o botão
 * apagado pinta o texto de `--muted`, e a herança apagaria o vermelho justamente
 * no caso em que ele precisa ser lido.
 */
.imbue-motivo {
  font-size: 10.5px; font-weight: 700; letter-spacing: 0;
  text-transform: none; line-height: 1.2;
}
.imbue-motivo.falta { color: var(--imb-falta); }
.imbue-motivo.ok { color: #bff3e4; }
#modal .imbue-botao:disabled .imbue-motivo.falta { color: var(--imb-falta); }

/* O foco por teclado, visível em tudo o que se clica nesta janela. */
.imbue-peca-quadro:focus-visible,
.imbue-encaixe:focus-visible,
.imbue-custo-clique:focus-visible,
.imbue-ir-vazio:focus-visible,
.imbue-barra button:focus-visible,
#modal .imbue-botao:focus-visible,
.modal-box.imbue .suspenso-botao:focus-visible,
.modal-box.imbue .suspenso-item:focus-visible {
  outline: 2px solid var(--imb-forte); outline-offset: 2px;
}

/* =========================================================================
 * ---- OS BALÕES DESTA JANELA ----
 *
 * O balão do encaixe cheio e o da peça. Eles usam o balão de painel que o jogo
 * já tem (`tipPanel`); o que está aqui é só o miolo — e todo o conteúdo sai do
 * catálogo que já está na memória, sem nenhuma viagem nova ao servidor.
 * ========================================================================= */
.imbue-tip { display: grid; gap: 5px; max-width: 250px; padding: 9px 11px; }
.imbue-tip-topo { display: flex; align-items: center; gap: 7px; }
.imbue-tip-topo img { image-rendering: pixelated; flex: none; }
.imbue-tip-nome { font-size: 12.5px; color: #e9efee; }
.imbue-tip-sub { font-size: 10.5px; color: var(--muted); }
.imbue-tip-efeito { font-size: 11.5px; line-height: 1.35; color: var(--accent); }
.imbue-tip-tempo { font-style: normal; font-size: 11px; font-weight: 700; color: var(--accent); }
.imbue-tip-tempo.curto { color: #e0b464; }
.imbue-tip-tempo.urgente { color: #e2574c; }
.imbue-tip-linha { display: flex; gap: 7px; padding-top: 5px; border-top: 1px solid #ffffff12; }
.imbue-tip-linha img { image-rendering: pixelated; flex: none; }
.imbue-tip-texto { min-width: 0; display: grid; gap: 1px; }
.imbue-tip-texto b { font-size: 11.5px; color: #e9efee; }
.imbue-tip-texto span { font-size: 10.5px; line-height: 1.3; color: var(--muted); }
.imbue-tip-vazio { font-size: 11px; color: var(--muted); }

/* =========================================================================
 * ---- A CAIXA DE CONFIRMAR ----
 *
 * A `.confirm-box` de sempre; o que ela tem de próprio é o resumo do que vai
 * acontecer. Um imbuement custa um milhão e dois tokens, e o clique fica ao lado
 * de uma lista em que se troca de grau com a setinha.
 * ========================================================================= */
.confirm-box.imbue-confirma { display: grid; gap: 9px; width: min(420px, 94vw); }
.imbue-confirma-resumo {
  display: flex; align-items: center; gap: 10px;
  padding: 8px; background: #24312f; border: 1px solid var(--line); border-radius: 4px;
}
.imbue-confirma-resumo img { image-rendering: pixelated; flex: none; }
.imbue-confirma-quem { min-width: 0; display: grid; gap: 2px; }
.imbue-confirma-quem b { font-size: 13px; color: #e9efee; }
.imbue-confirma-quem span { font-size: 11px; color: var(--muted); }
.imbue-confirma-efeito { margin: 0; font-size: 12px; line-height: 1.4; color: var(--accent); }
.imbue-confirma-linha { margin: 0; font-size: 11.5px; color: var(--text); }
/* O único âmbar da caixa, e ele é o aviso de risco. */
.imbue-confirma-aviso {
  margin: 0; padding: 7px 9px;
  background: rgba(224, 180, 100, .1); border: 1px solid rgba(224, 180, 100, .5); border-radius: 4px;
  font-size: 11.5px; line-height: 1.35; color: #e0b464;
}
.imbue-confirma-denovo {
  display: flex; align-items: center; gap: 7px;
  font-size: 11.5px; color: var(--muted); cursor: pointer;
}
.imbue-confirma-denovo input { width: auto; margin: 0; accent-color: var(--accent); }

/*
 * ---- A JANELA ESTREITA ----
 *
 * Abaixo de 640px as colunas empilham e as setas somem: elas apontam da fileira
 * para o botão, e numa coluna só não há de onde para onde apontar.
 */
@media (max-width: 660px) {
  .imbue-peca { grid-template-columns: minmax(0, 1fr); }
  .imbue-pecas { border-right: 0; border-bottom: 1px solid var(--imb-linha); padding: 0 0 12px; }
  .imbue-menus { grid-template-columns: minmax(0, 1fr); }
  /*
   * ---- APERTADO, O BOTÃO DESCE INTEIRO ----
   *
   * "as três caixas ficam numa linha e as setas somem; o botão vai para baixo
   *  com largura total e altura fixa (~64px), com o status dentro."
   *
   * As duas primeiras colunas continuam FIXAS — é o que garante que as caixas
   * nunca quebrem uma por linha — e a do ouro absorve a sobra, para a fileira
   * chegar até a borda. Quem cede é o botão, que passa a ocupar a fileira
   * inteira; as setas somem, porque numa coluna só não há de onde para onde
   * apontar.
   *
   * E aqui a altura é ESCRITA: sozinho na fileira, ele não tem coluna de
   * requisito de quem copiar a altura, e um botão de uma linha de texto ficaria
   * com 30px de altura no meio da tela.
   */
  .imbue-req-grade { grid-template-columns: 80px 80px minmax(120px, 1fr); }
  .imbue-req-grade > .imbue-botao { grid-column: 1 / -1; }
  #modal .imbue-botao { height: 64px; }
  .imbue-setas { display: none; }
}

/* ==========================================================================
   OS ÍCONES CENTRADOS, A SETA VISÍVEL E OS DOIS BOTÕES DA CARTEIRA
   ========================================================================== */

/*
 * ---- A fileira centrada entre a loja e o Opções ----
 *
 * "esses ícones têm que centralizar no meio entre opções e mineiroidle store."
 *
 * `justify-content: center` não bastava: o canto da direita usa
 * `margin-left: auto`, e uma margem automática ENGOLE toda a sobra antes de o
 * `justify-content` ter o que repartir. O resultado era a fileira empurrada
 * para a esquerda, colada na loja.
 *
 * Duas margens automáticas resolvem sozinhas: a do primeiro botão e a do canto
 * dividem a sobra em partes iguais, e o bloco do meio fica exatamente no centro
 * do vão entre os dois vizinhos. É a mesma conta que centraliza um elemento
 * entre dois irmãos em qualquer flexbox — e ela continua certa quando a barra
 * encolhe, porque margem automática vira zero quando não há sobra.
 */
/*
 * A margem do primeiro botao e' escrita pelo JS agora, e nao mais `auto`.
 *
 * `auto` centralizava no VAO entre a loja e o Opcoes; o dono quer centrado no
 * BONECO, que e' outro ponto — e que so' se sabe medindo o `#map`. Ver
 * `centrarNoBoneco`, em main.mjs.
 */
.tools > button:first-of-type { margin-left: 0; }

/*
 * ---- A seta do grupo, visível ----
 *
 * "a setinha quase não dá pra ver." Ela era um `⌄` no tamanho da legenda (9px)
 * com 50% de opacidade, dentro de um texto cinza: somava uns três pixels
 * acesos. Agora é um triângulo desenhado em borda — tamanho e cor próprios,
 * independentes da fonte — logo abaixo do desenho, que é onde o olho procura
 * "isto abre mais coisa".
 */
.tools button.grupo .label::after { content: none; }
.tools button.grupo {
  /* Espaço para a seta morar sem empurrar a legenda. */
  padding-bottom: 8px;
}
.tools button.grupo::before {
  content: ""; position: absolute; bottom: 2px; left: 50%; margin-left: -4px;
  width: 0; height: 0; pointer-events: none;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 4px solid var(--accent-dim, var(--accent));
  opacity: .85;
  transition: transform .14s ease, opacity .14s ease, border-top-color .14s ease;
}
.tools button.grupo:hover::before { border-top-color: var(--accent); opacity: 1; }
/* Gaveta aberta: a seta vira para cima, como a de qualquer menu. */
.tools button.com-gaveta-aberta::before {
  border-top-color: var(--accent); opacity: 1; transform: rotate(180deg);
}

/*
 * ---- Os dois botões da carteira ----
 *
 * O do banco é um desenho ao lado do ouro: um número clicável não avisa
 * ninguém de que é clicável. O `+` das coins é botão de verdade, porque ele
 * faz OUTRA coisa que não é abrir o banco — e por isso ele segura o próprio
 * clique (ver `stopPropagation`, em main.mjs).
 */
/*
 * O desenho do banco ao lado do ouro saiu a pedido do dono ("pode retirar o
 * icone do banco ao lado do gold"). O clique continua: quem diz que ele existe
 * e' a moldura que acende no hover, mais o balao.
 */

/*
 * ---- O `+` das coins: dourado, sem caixa, em cima do ultimo digito ----
 *
 * "coloca ele meio dourado e sem o fundo, e meio que em cima do valor, tipo na
 *  borda de cima do ultimo digito."
 *
 * Fora do fluxo: a carteira e' `relative` e ele e' `absolute` na borda direita
 * dela, que e' onde o numero acaba. Assim ele nao empurra o resto da barra e
 * acompanha o numero quando ele cresce de cinco para seis digitos.
 */
.wallet { position: relative; }
.carteira-mais {
  position: absolute; right: -9px; top: -7px;
  width: 14px; height: 14px; padding: 0; cursor: pointer;
  display: grid; place-items: center; line-height: 1;
  font-family: var(--font-heading); font-size: 14px; font-weight: 700;
  background: none; border: none; color: var(--copper, #d9ae4a);
  text-shadow: 0 0 4px #0009, 0 1px 0 #0009;
  transition: color .14s ease, transform .14s ease, text-shadow .14s ease;
}
.carteira-mais:hover {
  color: #ffe9a8; transform: scale(1.25);
  text-shadow: 0 0 8px #d9ae4acc, 0 1px 0 #0009;
}

/* ==========================================================================
   A OFICINA DE IMBUIR: OS DOIS MENUS SUSPENSOS
   ==========================================================================

   "seleciona o item, escolhe o imbue pela setinha e etc."

   O menu é NOSSO e não um `<select>`: a lista aberta de um `<select>` é uma
   janela do sistema e fecha sozinha a cada redesenho da página, que é o que
   acontece o tempo todo com uma caçada rodando atrás. Ver `menuSuspenso`, em
   panels.mjs.
   ========================================================================== */

.imbue-oficina { display: grid; gap: 8px; }
.imbue-menus { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
@media (max-width: 700px) {
  .imbue-menus { grid-template-columns: minmax(0, 1fr); }
}

/* O painel é absoluto para não empurrar o resto da tela ao abrir. */
.suspenso { position: relative; min-width: 0; }
/*
 * ---- O MENU COM A CARA DO `<select>` DA FOTO ----
 *
 * Dentro da janela de imbuir, o botão do menu veste o desenho do protótipo:
 * fundo escuro, moldura dourada, texto centralizado em negrito. Ele CONTINUA
 * sendo o menu de sempre — um `<select>` de verdade fecha sozinho a cada
 * redesenho da página, e é por isso que ele não existe neste jogo.
 */
.modal-box.imbue .suspenso-botao {
  justify-content: center; text-align: center;
  padding: 9px 34px 9px 12px;
  background: var(--imb-corpo); border: 2px solid var(--imb-linha); border-radius: 0;
  color: #e9efee;
}
.modal-box.imbue .suspenso-botao b { font-size: 15px; font-weight: 700; }
.modal-box.imbue .suspenso-botao:hover, .modal-box.imbue .suspenso-botao.aberto {
  border-color: var(--imb-forte);
}
.modal-box.imbue .suspenso-botao .grow { text-align: center; }
.modal-box.imbue .suspenso-seta { border-top-color: var(--imb-forte); }

/*
 * ---- OS GRUPOS DA LISTA, e o que está fora de alcance ----
 *
 * "agrupar pela categoria que o jogo já tem" e "tipos já aplicados em outro
 *  encaixe do mesmo item: desabilitados com o motivo".
 *
 * O título do grupo é uma linha, e não uma caixa: ele separa sem virar um
 * segundo nível de moldura dentro de um painel que já é uma.
 */
.suspenso-grupo {
  padding: 7px 8px 3px;
  font-family: var(--font-heading); font-size: 10px; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase; color: var(--accent);
}
.suspenso-grupo:first-child { padding-top: 2px; }
.suspenso-item.travado { cursor: not-allowed; opacity: .55; }
.suspenso-item.travado:hover { background: none; }
.suspenso-motivo { color: #e2574cc4; }

.suspenso-botao {
  display: flex; align-items: center; gap: 9px; width: 100%; min-width: 0;
  padding: 7px 10px; cursor: pointer; text-align: left;
  background: linear-gradient(180deg, #121a1c, #0c1113);
  border: 1px solid var(--line-strong, var(--line)); border-radius: 7px;
  color: inherit; font: inherit;
  transition: border-color .14s ease, background-color .14s ease;
}
.suspenso-botao:hover { border-color: var(--accent-dim); }
.suspenso-botao.aberto { border-color: var(--accent); background: #101a1a; }
/* `flex: 1` para a setinha ir para a DIREITA do botao, e nao colar no texto. */
.suspenso-botao .grow { flex: 1; min-width: 0; display: grid; gap: 1px; }
.suspenso-botao b {
  font-size: 13px; font-weight: 600; line-height: 1.2;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.suspenso-botao em {
  font-style: normal; font-size: 9.5px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.suspenso-botao canvas, .suspenso-botao img { flex: none; image-rendering: pixelated; }
/* A setinha do pedido: triângulo desenhado, e não um caractere de fonte. */
.suspenso-seta {
  flex: none; width: 0; height: 0; margin-left: 4px;
  border-left: 5px solid transparent; border-right: 5px solid transparent;
  border-top: 6px solid var(--accent-dim, var(--accent));
  transition: transform .14s ease, border-top-color .14s ease;
}
.suspenso-botao:hover .suspenso-seta { border-top-color: var(--accent); }
.suspenso-botao.aberto .suspenso-seta { transform: rotate(180deg); border-top-color: var(--accent); }

.suspenso-painel {
  position: absolute; z-index: 5; top: calc(100% + 4px); left: 0; right: 0;
  display: grid; gap: 4px; padding: 7px;
  background: linear-gradient(180deg, #131b1ef7, #0c1113fa);
  border: 1px solid var(--accent-dim); border-radius: 8px;
  box-shadow: 0 12px 26px #000b;
}
.suspenso-painel input { width: 100%; box-sizing: border-box; }
.suspenso-itens { display: grid; gap: 2px; max-height: 260px; overflow-y: auto; }
.suspenso-item {
  display: flex; align-items: center; gap: 8px; width: 100%; min-width: 0;
  padding: 5px 7px; cursor: pointer; text-align: left;
  background: none; border: 1px solid transparent; border-radius: 6px;
  color: inherit; font: inherit;
}
.suspenso-item:hover { background: #ffffff12; }
.suspenso-item.escolhido { border-color: var(--accent); background: #3fbfa81c; }
.suspenso-item .grow { min-width: 0; display: grid; gap: 1px; }
.suspenso-item b {
  font-size: 11.5px; font-weight: 600; line-height: 1.2;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.suspenso-item em {
  font-style: normal; font-size: 9px; letter-spacing: .07em; text-transform: uppercase; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.suspenso-item canvas, .suspenso-item img { flex: none; image-rendering: pixelated; }
.suspenso-vazio { font-size: 10.5px; color: var(--muted); padding: 6px 7px; }

/*
 * ---- O que sobrou aqui ----
 *
 * `.imbue-efeito`, `.imbue-conta`, `.imbue-receita`, `.imbue-fichas` e
 * `.imbue-aplicar` eram a versão anterior desta tela — a caixa do efeito, a
 * linha de reagentes em fichas pequenas e o botão escrito "APLICAR". As três
 * viraram, no desenho do Imbuing Shrine, a caixa de descrição, as caixas de 80
 * com "tem/precisa" e o botão grande com o ícone de encaixe. Ver o bloco "A
 * OFICINA DE IMBUIR", lá em cima, que é onde elas moram agora.
 */

/* O ícone do banco na carteira precisa aparecer: .72 sumia no fundo escuro. */
.carteira-acao { opacity: .9; }

/* O apelido em português do charm, na grade e na ficha. Ver `traduz.mjs`. */
.charm-apelido {
  display: block; max-width: 100%; font-style: normal;
  font-size: 8.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.charm-tile.sel .charm-apelido, .charm-tile:hover .charm-apelido { color: var(--accent-dim); }
.charm-ficha-apelido {
  font-style: normal; font-size: 11px; color: var(--copper);
}

/*
 * A ponte invisível entre o botão e a gaveta.
 *
 * São 5px de vão, e atravessá-los dispara `pointerleave` no botão antes de o
 * `pointerenter` da gaveta chegar. Sem esta faixa a gaveta fecharia na cara de
 * quem está indo até ela. Ver `fecharSeOMouseSaiu`, em main.mjs.
 */
.gaveta-da-barra::before {
  content: ""; position: absolute; left: 0; right: 0; top: -9px; height: 9px;
}

/* ---- Os balões de "o que eu tenho ativo" ---- */

.tip-resumo { display: grid; gap: 3px; margin-top: 7px; }
.tip-resumo > div {
  display: flex; align-items: center; gap: 7px; min-width: 0;
  font-size: 11.5px; line-height: 1.25;
}
.tip-resumo > div > span {
  flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tip-resumo > div > b { flex: none; color: var(--accent); font-weight: 600; }
.tip-resumo > div > em {
  flex: none; font-style: normal; font-size: 10px; color: var(--muted);
  max-width: 150px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tip-resumo img, .tip-resumo canvas, .tip-resumo .perk-icon {
  flex: none; width: 20px; height: 20px; object-fit: contain;
}
.tip-resumo canvas { image-rendering: pixelated; }
/* O que está parado esperando uma decisão sua acende; o que está travado apaga. */
.tip-resumo .chama, .tip-resumo em.chama { color: var(--copper); }
.tip-resumo .apagado, .tip-resumo em.apagado { color: #3d4a4d; }
.tip-resumo > em {
  font-style: normal; font-size: 11px; color: var(--muted); line-height: 1.4;
}
.tip-resumo-pe { margin-top: 3px; padding-top: 5px; border-top: 1px solid #ffffff12; }

/*
 * ---- O botão de escolher a criatura do charm, pintado ----
 *
 * "arruma o escolher criatura do charm pq o botão tá branco."
 *
 * Ele nunca teve pintura própria: herdava a de `.charm-foot button`, do cartão
 * antigo. Quando o cartão virou a ficha da direita (ver `renderCharms`), o
 * seletor deixou de alcançá-lo e ele caiu no botão de fábrica do navegador —
 * branco, no meio de uma tela preta.
 *
 * Agora ele tem a pintura escrita aqui, e não emprestada: é a mesma dos menus
 * suspensos da oficina de imbuir, que é o outro botão do jogo que abre uma
 * lista por dentro.
 */
.charm-alvo-botao {
  cursor: pointer; font: inherit; font-size: 12px; color: var(--text);
  background: linear-gradient(180deg, #121a1c, #0c1113);
  border: 1px solid var(--line-strong, var(--line)); border-radius: 7px;
  padding: 7px 9px;
  transition: border-color .14s ease, background-color .14s ease;
}
.charm-alvo-botao:hover:not(:disabled) { border-color: var(--accent-dim); background: #101a1a; }
.charm-alvo-botao:disabled { opacity: .45; cursor: not-allowed; }
/* Com criatura apontada a moldura acende: é o que diz que o charm está armado. */
.charm-alvo-botao.tem { border-color: var(--accent); background: #3fbfa814; }
.charm-alvo-botao i { color: var(--accent-dim, var(--accent)); opacity: 1; font-size: 10px; }

/* A lista e a busca dela, no mesmo tom. */
.charm-alvo-lista input {
  background: #080b0c; border: 1px solid var(--line); border-radius: 6px;
  padding: 6px 8px; color: var(--text); font: inherit; font-size: 12px;
}
.charm-alvo-lista input:focus { outline: none; border-color: var(--accent-dim); }
.charm-alvo-item {
  cursor: pointer; font: inherit; font-size: 11.5px; color: var(--text);
  border-radius: 6px; padding: 4px 6px;
}

/*
 * ---- O Mercado agora é FILHO da fileira ----
 *
 * Ele era vizinho dela, com placa própria colada na Mineiroidle Store; com a fileira
 * centrada no boneco isso deixava um vão de meia tela entre ele e o Depósito.
 * Dentro dela, ele passa a obedecer a largura medida como qualquer outro botão
 * — sem isto ele ficaria 56px fixos no meio de vizinhos de 52 ou menos, e a
 * conta de `caberNaBarra` erraria por ele.
 */
.tools #market-button {
  width: var(--largura-do-botao, 52px); margin-left: 0;
  padding: 3px 0 2px;
}
.tools #market-button img {
  width: var(--tamanho-do-icone, 30px); height: var(--tamanho-do-icone, 30px);
}
.tools.sem-legenda #market-button .label { display: none; }

/*
 * ---- As legendas da barra, legíveis ----
 *
 * "as letras que informam o que os ícones são, tipo Sistemas, elas estão ok,
 *  mas elas têm que ser mais visíveis — não sei, uma cor mais forte na letra ou
 *  grossura melhor da letra."
 *
 * Eram 9px em #6d7f86, que é um cinza-azulado a meio caminho do fundo. Três
 * coisas mudam juntas, porque nenhuma sozinha resolve:
 *
 *   COR     de #6d7f86 para #b3c6cb — quase o dobro de contraste contra o
 *           #0d1214 da barra;
 *   PESO    de 400 para 600. Numa fonte de 9px, meio passo de peso vale mais
 *           do que um pixel de tamanho: engrossa o traço sem alargar a palavra,
 *           e a largura é o que não tem para dar num botão de 52px;
 *   SOMBRA  um contorno escuro de 2px. A barra é translúcida (#0d1214f7) e o
 *           mapa passa por baixo dela: sobre um chão claro, a legenda clara
 *           sumia justamente onde ela ficou mais clara. A sombra é o que a
 *           segura nos dois fundos.
 *
 * Meio pixel a mais no tamanho (9 -> 9.5) porque sobrou espaço depois que os
 * separadores saíram — e é o máximo que "Personagem" aceita sem reticências.
 */
.tools button .label,
.gaveta-da-barra button .label,
.tools #market-button .label {
  /*
   * O TAMANHO fica em 9px, e quem engrossa é o peso.
   *
   * Subir para 9.5 cortou "Personagem" com reticências — a palavra mais longa
   * da fileira já vivia no limite dos 52px. O peso 600 dá quase todo o ganho de
   * leitura sem alargar a palavra, que é exatamente a moeda que falta aqui.
   */
  font-size: 9px; font-weight: 600; color: #b3c6cb; letter-spacing: 0;
  text-shadow: 0 1px 2px #05080ae0, 0 0 3px #05080a99;
}
/* O aceso continua sendo o accent — só que agora ele brilha mais que o normal. */
.tools button:hover .label,
.tools [data-tool][aria-selected='true'] .label,
.tools button.com-gaveta-aberta .label,
.gaveta-da-barra button:hover .label,
.gaveta-da-barra [data-tool][aria-selected='true'] .label {
  color: #6fe3c6;
}
/* E o desligado continua apagado, senão "Cidade" gritaria tanto quanto o resto. */
.tools button:disabled .label { color: #45555a; text-shadow: 0 1px 2px #05080ac0; }
.gaveta-da-barra button:disabled .label { color: #45555a; }

/* ==========================================================================
   O BAÚ EM DUAS COLUNAS
   ==========================================================================

   "o Baú e o Baú de Boss eu gostaria de fazer algo parecido com isso da foto."

   A foto é o depósito do client: a parede de baús à esquerda, o conteúdo do
   escolhido à direita, e um rodapé de ação embaixo. Era "parede OU caixa" —
   clicar numa trocava a tela inteira por ela. Ver `renderLocker`.
   ========================================================================== */

.deposito-dois {
  display: grid; grid-template-columns: minmax(0, 280px) minmax(0, 1fr); gap: 12px;
  align-items: start;
}
@media (max-width: 820px) {
  .deposito-dois { grid-template-columns: minmax(0, 1fr); }
}
.deposito-lado {
  display: grid; gap: 9px; align-content: start; min-width: 0;
  padding: 11px; border: 1px solid var(--line); border-radius: 9px;
  background: linear-gradient(180deg, #0e1416cc, #0a0e0fcc);
}
/* O título de cada lado, com a mesma barra dos blocos da oficina de imbuir. */
.deposito-lado > h4 {
  margin: 0 0 1px; padding: 0 0 6px;
  display: flex; align-items: center; gap: 8px;
  font-family: var(--font-heading); font-size: 11px; font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase; color: var(--muted);
  border-bottom: 1px solid var(--line);
}
.deposito-lado > h4::before {
  content: ""; width: 3px; height: 13px; border-radius: 2px;
  background: var(--accent-dim); flex: none;
}
/* A parede encolheu para caber na coluna: quatro por fileira, como na foto. */
.deposito-dois .deposito-parede {
  grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 5px;
}
/*
 * A caixa que está sendo mostrada à direita fica marcada.
 *
 * Sem isto, trocar de baú muda só a metade direita e nada na esquerda diz de
 * onde aquilo veio — e com dezesseis quadrados iguais a pessoa perde o fio.
 */
.deposito-caixa.aberta {
  border-color: var(--accent); background: #3fbfa81c;
  box-shadow: inset 0 0 0 1px #3fbfa844;
}
.deposito-limite {
  margin: 0; font-size: 10px; line-height: 1.4; color: var(--muted);
  padding-top: 7px; border-top: 1px solid #ffffff0d;
}
/* A coluna da direita não tem o respiro extra do `locker-topo` solto. */
.deposito-conteudo .locker-topo { margin: 0; }
.deposito-conteudo .deposito-titulo { margin: 0; }

/* O nome da caixa é o cabeçalho da coluna da direita, igual ao da esquerda. */
.deposito-conteudo .deposito-titulo {
  margin: 0 0 1px; padding: 0 0 6px;
  display: flex; align-items: center; gap: 8px;
  font-family: var(--font-heading); font-size: 11px; font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase; color: var(--muted);
  border-bottom: 1px solid var(--line);
}
.deposito-conteudo .deposito-titulo::before {
  content: ""; width: 3px; height: 13px; border-radius: 2px;
  background: var(--accent-dim); flex: none;
}

/* ==========================================================================
   O "?" do cabeçalho, e a largura de cada seção do Depósito
   --------------------------------------------------------------------------
   "ao lado do x você coloca uma interrogação que aí teria essas informações
    sabe... o Baú da Conta também dava pra otimizar o tamanho horizontal?"

   O parágrafo de explicação era quem mandava na largura da janela: trinta
   palavras não quebram antes de uns 900px, e a grade de itens embaixo tem 485.
   No "?" a frase continua inteira — a um passar de mouse — e a janela volta a
   ter a largura do que ela guarda. Ver `ajudaNoCabecalho`, no panels.mjs.
   ========================================================================== */
.ajuda-do-modal {
  flex: none;
  width: 20px; height: 20px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--line); border-radius: 50%;
  background: #0f1618; color: var(--muted);
  font-family: var(--font-heading); font-size: 12px; font-weight: 700; line-height: 1;
  cursor: help;
}
.ajuda-do-modal:hover { color: var(--accent); border-color: var(--accent-dim); background: #14201f; }

/*
 * Três larguras, uma por formato — ver o comentário de `openLocker`.
 *
 * Vêm DEPOIS de `.modal-box` na folha, que é o que as faz valer sem `!important`.
 * O celular não é afetado: a regra de `@media (max-width: 900px)` manda a caixa
 * para 100vw e vem depois destas.
 */
.modal-box.deposito-estreito { width: min(620px, 94vw); }
.modal-box.deposito-boss { width: min(700px, 94vw); }

/*
 * O Baú de Boss em pé.
 *
 * "a página Baú de Boss deixa mais vertical, mais ou menos igual da Baú do char."
 *
 * A coluna das sacolas encolhe para 210px — quatro por fileira, como a parede de
 * baús do irmão — e a janela inteira para 700. Antes, numa janela de 980, o que
 * havia dentro de uma sacola virava UMA fileira de quinze quadradinhos e a tela
 * ficava deitada: larga, baixa e com metade dela vazia embaixo.
 */
.modal-box.deposito-boss .deposito-dois {
  grid-template-columns: minmax(0, 210px) minmax(0, 1fr);
}
/* A grade de sacolas cabe na coluna estreita sem escorrer para fora dela. */
.modal-box.deposito-boss .deposito-lado .locker-grade {
  grid-template-columns: repeat(auto-fill, 38px);
  justify-content: start;
  margin-bottom: 0;
}

/* ==========================================================================
   O aviso da recompensa diária, à direita de Social
   --------------------------------------------------------------------------
   "faz aparecer o ícone de recompensa diária... lá do lado de Social, à
    direita, chamativo — mas só quando tiver pra pegar."

   É um botão da fileira como os outros, e a diferença é que ele só existe
   enquanto há o que pegar. O facho dourado que dá voltas (`.alerta`) já é o
   "chamativo", e é o MESMO da árvore com ponto para gastar e do baú de boss
   cheio: um aviso novo com uma luz nova seria uma segunda gramática para a
   mesma coisa. O que se soma aqui é a legenda dourada — nos outros o facho é
   um detalhe do ícone, e neste ele é a razão de o botão estar na tela.
   ========================================================================== */

/*
 * `hidden` precisa vencer o `display: flex` da fileira.
 *
 * Um `<button hidden>` desaparece sozinho em qualquer lugar da página, MENOS
 * onde alguém lhe deu um `display` — e `.tools button` dá. Sem esta linha o
 * aviso ficaria na barra o tempo todo, vazio de motivo.
 */
.tools button[hidden] { display: none; }

/* Um respiro à esquerda: ele não é da fileira fixa, e o olho tem de ver isso
   sem ninguém explicar. */
.tools button.aviso-da-barra { margin-left: 6px; }
.tools button.aviso-da-barra .label {
  color: #ffd76a;
  text-shadow: 0 1px 2px #000;
}
.tools button.aviso-da-barra:hover .label { color: #fff6d8; }
/* O desenho já vem aceso, e não só no hover: é um aviso, não uma ferramenta. */
.tools button.aviso-da-barra .icon {
  animation: aviso-da-barra-pulso 1.8s ease-in-out infinite;
}
@keyframes aviso-da-barra-pulso {
  0%, 100% { filter: drop-shadow(0 0 2px #ffd76a77); transform: scale(1); }
  50% { filter: drop-shadow(0 0 7px #ffe9b0) drop-shadow(0 0 14px #ffb32e99); transform: scale(1.06); }
}
/* Quem pediu menos movimento fica com o brilho parado — ele é o que faz notar. */
@media (prefers-reduced-motion: reduce) {
  .tools button.aviso-da-barra .icon {
    animation: none; filter: drop-shadow(0 0 5px #ffe9b0);
  }
}
/* A frase do balão que conta o que está esperando. */
.tip-aviso { margin: 4px 0 0; font-size: 11px; color: #ffd76a; }

/* ==========================================================================
   O lobby da Arena
   --------------------------------------------------------------------------
   "ao clicar aparece tipo um lobby que eu consigo desafiar alguém pra um x1."

   Uma coluna de blocos, cada um com o mesmo cabeçalho de barrinha do resto do
   jogo: onde se luta, como estou eu, quem está livre, e o ranking. Ver
   `renderArena`, no panels.mjs.
   ========================================================================== */
#modal-body > .arena-lobby-ficha,
#modal-body > .arena-lobby-eu,
#modal-body > .arena-lobby-convites,
#modal-body > .arena-lobby-gente,
#modal-body > .arena-lobby-ranking {
  display: grid; gap: 8px; align-content: start; margin-bottom: 10px;
  padding: 11px; border: 1px solid var(--line); border-radius: 9px;
  background: linear-gradient(180deg, #0e1416cc, #0a0e0fcc);
}
/*
 * Uma linha de gente: nome à esquerda, o que ela é no meio, o botão à direita.
 *
 * `margin-left: auto` no botão e não `space-between`: o nome e a descrição são
 * um bloco só, e com `space-between` eles se afastariam um do outro conforme a
 * janela crescesse, deixando um vão no meio do nome da pessoa.
 */
.arena-lobby-linha {
  display: flex; align-items: center; gap: 10px; padding: 7px 9px;
  border: 1px solid var(--line); border-radius: 7px; background: var(--panel-2);
}
.arena-lobby-linha b { font-size: 12.5px; }
.arena-lobby-linha span { font-size: 11px; color: var(--muted); }
.arena-lobby-linha button { margin-left: auto; flex: none; }
/* O desafio que chegou acende: ele tem prazo, e quem não reparar perde a vez. */
.arena-lobby-convites { border-color: rgba(224, 168, 74, .5); }
.arena-lobby-convites .arena-lobby-linha { border-color: rgba(224, 168, 74, .35); }

/* ---- Os bichos da arena e os dois lutadores ---- */

/* =========================================================================
 * A JANELA DA ARENA — a moldura pintada, como BORDA
 *
 * "a moldura da arena coloca como moldura mesmo, essa ficou muitooo grossa."
 *
 * ---- Por que ela estava grossa, e o que mudou ----
 *
 * A primeira versão punha a arte inteira como fundo da caixa, esticada para o
 * tamanho dela (`background-size: 100% 100%`). Nesse arranjo a espessura da
 * pedra é uma PROPORÇÃO da arte — 9,2% de cada lado e 15% em cima —, e ela
 * continua sendo 9,2% numa janela de 600px ou de 1600: o desenho engorda junto
 * com a janela e o vão nunca ganha espaço.
 *
 * Agora a arte é FATIADA e usada como borda (`border-image`). A diferença é que
 * a espessura passa a ser um número nosso, em pixels, e o miolo fica com todo o
 * resto — cresce com a janela enquanto a moldura não muda. É isso que faz dela
 * uma moldura em vez de um quadro com uma fresta no meio.
 *
 * ---- OS CORTES SAÍRAM DE MEDIR ----
 *
 * `node tools/medir-moldura.mjs client/assets/ui/arena-moldura.png`
 *
 *   imagem  1578 x 961   (JÁ APARADA — ver abaixo)
 *   vão     x 43..1535   y 52..917     (94,6% da largura, 90,1% da altura)
 *   fatias  topo 52   direita 42   rodapé 43   esquerda 43
 *
 * ---- A margem preta foi APARADA antes de medir ----
 *
 * A arte veio com uma borda preta em volta: 6px em cima, 4 de cada lado e 25
 * embaixo. Ela não é desenho — é sobra do gerador —, e numa borda fatiada isso
 * não some: os 25px de preto entram na fatia de baixo e são pintados como se
 * fossem moldura. Na tela virava uma tarja preta sob o ornamento, mais grossa
 * que a própria pedra.
 *
 * `node .tmp/aparar.mjs <arquivo.png>` corta a margem. A tolerância importa:
 * "preto" numa imagem gerada não é 0,0,0 em todo pixel, e os cantos de filigrana
 * chegam mais perto da beirada que as faixas retas — cortar pelo perfil do meio
 * comeria os cantos.
 *
 * ---- E desta vez a borda é usada no TAMANHO NATURAL ----
 *
 * A primeira arte tinha a pedra em 9% de cada lado e 15% em cima. Para caber,
 * eu encolhia a borda a um terço da fatia — e encolher a fatia ACHATA o
 * desenho: as espadas e o louro saíam espremidos. Era um custo que estava
 * escrito aqui como inevitável.
 *
 * Não era: era a ARTE que estava grossa. Esta nasceu fina (a segunda passada do
 * prompt, em `tools/prompt-tela-da-arena.txt`), e por isso `border-width` é
 * igual a `border-image-slice`. A escala é 1:1 — nada é esmagado.
 *
 * O que continua sendo esticado é a horizontal das faixas retas, e é de graça
 * porque o motivo delas é REPETITIVO: um trilho de tachas iguais estica sem
 * ninguém ver. Foi por isso que o prompt pediu motivo repetido em vez de uma
 * peça grande no meio.
 * ========================================================================= */
.modal-box.arena {
  width: min(1180px, 96vw);
  max-height: 90vh;
  display: flex;
  flex-direction: column;
  position: relative;
  /* =======================================================================
   * O ENCHIMENTO QUE TIRA O CONTEÚDO DE CIMA DOS CRISTAIS
   *
   * "faz o css da aba arena nao ficar por cima da moldura nos cantos, ou
   *  realinhe certinho igual a gente fez com a gargoyle da recompensa diaria."
   *
   * Os cristais dos quatro cantos NÃO param na borda: eles avançam para dentro
   * da janela. Medido na tela, o do canto inferior direito entra 36px na
   * horizontal e 62px na vertical da caixa de conteúdo.
   *
   * As seções do corpo têm fundo próprio e são filhas posicionadas — elas pintam
   * DEPOIS da borda, por regra de CSS. Então a ponta do cristal ficava por
   * baixo de um vidro escuro, que é o "por cima da moldura" que ele viu.
   *
   * Enchimento na CAIXA e não na borda: `border-width` maior esticaria as
   * fatias e achataria o trilho. `padding` não toca no `border-image` — ele só
   * empurra o conteúdo para dentro, que é exatamente o que falta.
   *
   * O `::before` continua cobrindo tudo: `inset: 0` num filho absoluto resolve
   * contra a caixa de PREENCHIMENTO, que inclui este enchimento. O fundo da
   * arena não ganha buraco nas beiradas.
   * ======================================================================= */
  /*
   * ---- E o de cima ENCOLHEU ----
   *
   * "tem que aumentar um pouco do css pra cima pq ta ficando um buraco, e
   *  obviamente nao pode sobrepor ali onde ta escrito ARENA X1."
   *
   * Os 26px de cima eram a mesma folga dos lados, copiada sem medir. Só que em
   * cima não há cristal para desviar no meio da faixa — ele está nos cantos, e
   * quem já empurra o conteúdo para longe deles é a folga LATERAL. O que sobrava
   * virava uma faixa vazia entre o trilho e a primeira seção.
   *
   * 8px é o que fecha o buraco sem encostar: a placa do título termina em y=65
   * da arte e a borda de cima tem 66, então o conteúdo começa abaixo dela de
   * qualquer jeito. O "ARENA X1" não é alcançado — ele mora no cabeçalho, que
   * é outra camada.
   */
  padding: 8px 30px 30px 30px;
  background: none;
  border-style: solid;
  /* As fatias medidas, em tamanho natural. Ver acima. */
  border-width: 66px 41px 60px 42px;
  border-image-source: url('/client/assets/ui/arena-moldura.webp');
  /*
   * ---- SEM `fill`, e o preto da arte foi VAZADO ----
   *
   * "a moldura da arena ainda esta com as borda preta, e as diagonais tem que
   *  ficar atras do cristal — o css das bordas da diagonal tem que ficar pra
   *  tras, senão fica feio por cima da moldura."
   *
   * A arte vem como um retângulo OPACO: o trilho de metal no meio e preto puro
   * em volta dele. Numa borda fatiada esse preto não é descartado — ele entra
   * nas fatias e é pintado. Por fora do trilho virava uma tarja preta; nos
   * cantos, uma cunha diagonal por cima do cristal.
   *
   * Aparar a margem não resolvia, e foi o que eu tentei duas vezes: o preto não
   * está só na beirada, está ENTRE o cristal e o trilho. O que resolve é apagar
   * o preto por VALOR — `node tools/vazar-preto.mjs`, com uma rampa para a
   * beirada do desenho não serrilhar.
   *
   * Sem o preto, `fill` perde o sentido: o que ele pintava no corpo era esse
   * mesmo preto. Quem dá fundo ao corpo agora é o `::before` logo abaixo, que
   * cobre a caixa de preenchimento — e por fora do trilho a janela fica
   * transparente, com os cristais flutuando sobre o mapa.
   */
  border-image-slice: 66 41 60 42;
  border-image-repeat: stretch;
}

/*
 * ---- O FUNDO DA ARENA, no corpo da janela ----
 *
 * `inset: 0` sobre a caixa posicionada chega até a borda de dentro — a área de
 * conteúdo —, que é exatamente onde ele deve ficar. Sem `z-index` negativo:
 * ele é o primeiro filho pintado e o conteúdo vem depois, com `position:
 * relative`.
 */
.modal-box.arena::before {
  content: '';
  position: absolute;
  /*
   * ---- E ele SOBE 14px, para fechar o buraco ----
   *
   * "onde ta circulado azul vc tem que esticar o css pra cima pra nao fica com
   *  buraco."
   *
   * A borda de cima tem 66px, mas o trilho desenhado acaba em y=57 da arte — os
   * 9px seguintes são transparentes desde que o preto foi vazado. `inset: 0`
   * começa na caixa de preenchimento, ou seja em 66: aquela faixa de 9px ficava
   * sem fundo nenhum, e o mapa aparecia por ela. É o buraco que ele circulou.
   *
   * Subir 14 cobre a faixa com folga. O que ele tinge do trilho não importa: a
   * moldura é repintada por cima logo abaixo (`::after`).
   */
  top: -14px; left: 0; right: 0; bottom: 0;
  z-index: 0;
  background:
    linear-gradient(180deg, #060a0b8c 0%, #060a0bc9 46%, #060a0bef 82%, #060a0bf7 100%),
    url('/client/assets/ui/arena-fundo.webp') center/cover no-repeat;
  pointer-events: none;
}

/* =========================================================================
 * A MOLDURA, DE NOVO, POR CIMA DE TUDO
 *
 * "as borda diagonais a moldura tem que ficar por cima, pra nao fica feio
 *  bugado (apenas onde eu circulei em vermelho)."
 *
 * ---- Por que ela ficava por baixo ----
 *
 * Não é escolha minha: é a ordem de pintura do CSS. O fundo e as BORDAS de um
 * elemento são pintados antes de qualquer descendente — sempre, sem `z-index`
 * que resolva. Como a moldura é `border-image` da própria janela, as seções do
 * corpo pintam depois dela, e as quinas dos cristais ficavam por baixo de um
 * vidro escuro.
 *
 * Eu tinha atacado isso com ENCHIMENTO: empurrar o conteúdo para longe dos
 * cantos. Funciona até a próxima seção larga, e custa espaço dos quatro lados
 * por causa de quatro quinas.
 *
 * A moldura desenhada UMA SEGUNDA VEZ resolve de vez: mesma arte, mesmas
 * fatias, mesma caixa, `z-index` acima do corpo. O que aparecer por baixo dela
 * fica por baixo, e nenhuma medida precisa ser adivinhada.
 *
 * ---- A caixa dele é a da JANELA, e por isso os deslocamentos são negativos ----
 *
 * Um filho absoluto se posiciona contra a caixa de PREENCHIMENTO do pai, que
 * começa onde a borda acaba. Recuando cada lado pela largura da borda daquele
 * lado, a caixa de borda deste pseudo-elemento cai exatamente sobre a da
 * janela — e aí as fatias caem no mesmo lugar, pixel por pixel.
 *
 * `z-index: 4` é entre o corpo (1) e o cabeçalho (6): ele cobre o conteúdo e
 * NÃO cobre o título nem os botões do canto — que são a única coisa que precisa
 * ficar por cima da moldura, porque se clica neles.
 *
 * `pointer-events: none` é obrigatório: ele cobre a janela inteira e engoliria
 * todo clique do corpo.
 * ========================================================================= */
.modal-box.arena::after {
  content: '';
  position: absolute;
  top: -66px; left: -42px; right: -41px; bottom: -60px;
  z-index: 4;
  pointer-events: none;
  border-style: solid;
  border-width: 66px 41px 60px 42px;
  border-image-source: url('/client/assets/ui/arena-moldura.webp');
  border-image-slice: 66 41 60 42;
  border-image-repeat: stretch;
}

/*
 * ---- O título vai na PLACA que a arte desenhou ----
 *
 * O cabeçalho sai do fluxo e vira uma régua sobre a janela inteira, para o
 * título poder subir até a borda de cima. `pointer-events: none` é obrigatório
 * junto: sem ele esta camada cobriria o corpo e engoliria todo clique. Os
 * filhos o retomam.
 *
 * A placa é centrada na arte (x 617..966 de 1586, meio em 49,9%), então centrar
 * o título já o põe nela — e centrar é mais robusto que repetir a medida, que
 * dependeria de quanto a fatia de cima esticou.
 */
.modal-box.arena > header {
  position: absolute; z-index: 6;
  top: -66px; left: 0; right: 0; height: 66px;
  display: block; padding: 0; margin: 0; border: none; background: none;
  min-height: 0;
  pointer-events: none;
}
.modal-box.arena > header #modal-title,
.modal-box.arena > header #modal-selo,
.modal-box.arena > header #modal-acoes,
.modal-box.arena > header #modal-close { pointer-events: auto; }

/* =========================================================================
 * O TÍTULO ESTAVA POR CIMA DO SELO, e engolia o balão dele
 *
 * "quando eu deixo o mouse em cima dos tickets não dá informações dele, apenas
 *  aparece o símbolo de arrastar a página."
 *
 * O `#modal-title` é absoluto com `left: 0; right: 0` — ele atravessa o
 * cabeçalho inteiro, de ponta a ponta, e no HTML ele vem DEPOIS do
 * `#modal-selo`. Dois irmãos posicionados sem `z-index` empilham por ordem de
 * documento, então a placa do título ficava por cima do selo e do X: o mouse
 * nunca chegava no ticket, chegava no título — que é a alça de arrastar a
 * janela. Daí o cursor de arrastar, e daí o balão que não aparecia.
 *
 * O texto do título é centrado e nunca chega perto dos cantos, então por cima
 * ou por baixo não muda nada do que se vê. O que muda é quem recebe o mouse.
 *
 * Vale para as DUAS janelas de moldura (a arena e as guildas): o desenho é o
 * mesmo e o defeito era o mesmo — na das guildas quem estava debaixo da placa
 * era o brasão com o nome da guilda.
 * ========================================================================= */
.modal-box.arena > header #modal-title { z-index: 1; }
.modal-box.arena > header #modal-selo,
.modal-box.arena > header #modal-acoes,
.modal-box.arena > header #modal-close { z-index: 2; }

/* =========================================================================
 * O TÍTULO NA PLACA, COM BRASAS
 *
 * "onde esta escrito arena x1 coloque particulas de fogo, e pode aumentar a
 *  fonte."
 *
 * ---- A fonte ----
 *
 * 12,5px era o tamanho de quando o título dividia uma faixa de 52px com os
 * botões do canto. Agora ele mora sozinho numa placa desenhada no meio da
 * moldura, com 52px de altura só para ele — e um título de 12px numa placa de
 * 52 parece uma etiqueta esquecida ali.
 *
 * ---- As brasas ----
 *
 * São CSS e não canvas: uma partícula de verdade custaria um quadro de
 * JavaScript por brasa enquanto a janela estiver aberta, e esta janela fica
 * aberta enquanto alguém procura adversário. Duas camadas de `radial-gradient`
 * (`::before` e `::after`), cada uma com quatro pontos, subindo em tempos
 * diferentes: oito brasas de graça, compostas pela GPU.
 *
 * Os dois tempos são primos entre si de propósito (3,1s e 4,3s). Com tempos
 * iguais as oito brasas subiriam em formação, e o olho pega isso na hora — vira
 * uma fileira piscando, e não fogo.
 *
 * `pointer-events: none` nas duas: elas cobrem a placa inteira, e sem isso
 * engoliriam o clique de quem tentasse arrastar a janela pelo título.
 *
 * `mask-image` afunila as brasas para as pontas: elas nascem largas embaixo e
 * somem em cima, que é o que faz uma brasa parecer brasa em vez de bolinha
 * subindo.
 * ========================================================================= */
.modal-box.arena > header #modal-title {
  position: absolute;
  /* A placa medida na arte: y 14..65 dos 66px da faixa de cima. */
  left: 0; right: 0; top: 14px; height: 52px;
  margin: 0; padding: 0;
  display: grid; place-content: center;
  font-family: var(--font-title);
  font-size: 18px; letter-spacing: .2em; text-transform: uppercase;
  white-space: nowrap;
  color: #ffdfae;
  /*
   * O contorno escuro primeiro, e só depois os halos quentes: a placa da arte é
   * escura mas tem relevo e um fio de ouro atravessando, e uma letra clara sem
   * contorno se perde exatamente em cima dele.
   */
  text-shadow:
    0 0 2px #1c0a02,
    0 2px 0 #1c0a02,
    0 0 14px #ff7a2e66,
    0 0 34px #ff4f1e4d;
  animation: arena-titulo-brilha 3.7s ease-in-out infinite;
}

/*
 * A pulsação é do BRILHO e nunca da cor da letra: piscar a cor faria o texto
 * mudar de peso, e um título que muda de peso sozinho parece defeito de fonte.
 */
@keyframes arena-titulo-brilha {
  0%, 100% { text-shadow: 0 0 2px #1c0a02, 0 2px 0 #1c0a02, 0 0 12px #ff7a2e4d, 0 0 28px #ff4f1e33; }
  50% { text-shadow: 0 0 2px #1c0a02, 0 2px 0 #1c0a02, 0 0 18px #ff9a4e80, 0 0 44px #ff4f1e66; }
}

.modal-box.arena > header #modal-title::before,
.modal-box.arena > header #modal-title::after {
  content: '';
  position: absolute; inset: 0;
  pointer-events: none;
  background-repeat: no-repeat;
  /*
   * ---- A máscara é ESTREITA, e esse foi o conserto ----
   *
   * A primeira passada espalhou as brasas entre 36% e 71% da largura. Só que
   * este elemento é a faixa INTEIRA da janela (`left: 0; right: 0`) — são 1097px,
   * e a placa onde o título mora tem 200. As brasas subiam ao longo do trilho,
   * bem longe das letras, que era o oposto do pedido.
   *
   * Agora tanto as posições quanto a máscara ficam entre 45% e 55%: uma faixa de
   * ~110px em volta do centro, que é onde a placa está.
   */
  -webkit-mask-image: radial-gradient(ellipse 7% 80% at 50% 76%, #000 30%, transparent 100%);
  mask-image: radial-gradient(ellipse 7% 80% at 50% 76%, #000 30%, transparent 100%);
}

/* Quatro brasas pequenas, subindo depressa. */
.modal-box.arena > header #modal-title::before {
  background-image:
    radial-gradient(circle, #ffb066 0%, #ff6a2299 45%, transparent 70%),
    radial-gradient(circle, #ffd9a0 0%, #ff8a3a99 45%, transparent 70%),
    radial-gradient(circle, #ff9a4e 0%, #e0431299 45%, transparent 70%),
    radial-gradient(circle, #ffc98a 0%, #ff7a2e99 45%, transparent 70%);
  background-size: 5px 5px, 3px 3px, 4px 4px, 3px 3px;
  background-position: 45.5% 100%, 48% 100%, 51.5% 100%, 54% 100%;
  animation: arena-brasas-sobem 3.1s linear infinite;
}

/* Quatro maiores e mais lentas, deslocadas: o fogo não sobe em formação. */
.modal-box.arena > header #modal-title::after {
  background-image:
    radial-gradient(circle, #ffd9a0 0%, #ff7a2e99 45%, transparent 70%),
    radial-gradient(circle, #ff8a3a 0%, #c9350f99 45%, transparent 70%),
    radial-gradient(circle, #ffb066 0%, #ff5a1e99 45%, transparent 70%),
    radial-gradient(circle, #ffe0b8 0%, #ff9a4e99 45%, transparent 70%);
  background-size: 6px 6px, 4px 4px, 5px 5px, 3px 3px;
  background-position: 46.5% 100%, 49.5% 100%, 52.5% 100%, 55% 100%;
  animation: arena-brasas-sobem 4.3s linear infinite;
  animation-delay: -1.6s;
}

/*
 * Um `@keyframes` só para as duas camadas: o que as diferencia é a DURAÇÃO e o
 * atraso negativo, não o caminho. Dois conjuntos de quadros que dizem a mesma
 * coisa seriam dois lugares para consertar quando a placa mudar de altura.
 *
 * `background-position` e não `transform`: as quatro brasas de uma camada
 * precisam subir cada uma no seu ponto, e `transform` moveria a camada inteira.
 */
@keyframes arena-brasas-sobem {
  0% { background-position-y: 100%, 100%, 100%, 100%; opacity: 0; }
  14% { opacity: .95; }
  70% { opacity: .7; }
  100% { background-position-y: -10%, -20%, -14%, -26%; opacity: 0; }
}

/*
 * Quem pediu menos animação no sistema não recebe brasas. Elas são enfeite puro:
 * nada do que a janela informa depende delas.
 */
@media (prefers-reduced-motion: reduce) {
  .modal-box.arena > header #modal-title { animation: none; }
  .modal-box.arena > header #modal-title::before,
  .modal-box.arena > header #modal-title::after { display: none; }
}

/*
 * ---- O canto: Loja, "?" e fechar ----
 *
 * Sobre a pedra do alto, à direita. Ali a arte é escura e cheia de detalhe,
 * então o X é um DISCO opaco com aro de ouro — a mesma lição que o X da
 * Recompensa Diária deixou escrita: o que esconde um botão é o RUÍDO do desenho
 * atrás dele, e nenhuma cor de letra vence fundo movimentado.
 */
/*
 * ---- Encostados no canto ----
 *
 * "coloca o x, o interrogaçao e o botao da loja mais pro canto, ta quase no
 *  meio da tela kkk."
 *
 * Eles estavam a 74px e 26px da direita, medidos quando a borda tinha 82px: os
 * 74px caíam DENTRO da pedra, e com três botões a fileira avançava para o meio
 * do topo. Agora o X encosta na quina e o resto se alinha à esquerda dele.
 *
 * `right` no X e `left: auto` na fileira: assim ela cresce para a esquerda
 * quando um botão novo entrar, em vez de empurrar o X para fora da janela.
 */
/*
 * ---- Encostados na QUINA ----
 *
 * "vc tem que arrastar o xis de fechar da tela de arena mais perto do canto, e
 *  o interrogaçao tambem."
 *
 * O `right` é NEGATIVO, e precisa ser. O cabeçalho é filho posicionado da
 * caixa, e para um filho absoluto o contêiner é a caixa de PREENCHIMENTO — que
 * começa 41px para dentro, onde a borda acaba. `right: 0` já deixava os botões
 * 41px longe da quina, e era esse o "quase no meio da tela" que ele via.
 *
 * -22px põe o X sobre o trilho, perto do cristal sem encostar nele: o cristal
 * ocupa os últimos ~40px da faixa, e um botão por cima dele tapava justamente a
 * parte da moldura que ele mandou não tapar.
 */
/*
 * ---- E o limite da direita é o CRISTAL ----
 *
 * "vc tem que arrastar o xis de fechar mais perto do canto, e o interrogaçao
 *  tambem" — e, no mesmo fôlego, "o cristal da moldura está sendo tampado".
 *
 * Os dois pedidos se encontram num número. O cristal do canto começa 27px antes
 * da caixa de preenchimento (medido na tela: ele vai de 1470 a 1537 numa janela
 * que acaba em 1538), e a partir dali qualquer botão o tapa. Então o X para
 * exatamente ali: 30px é o mais perto da quina que dá para chegar SEM cobrir a
 * moldura.
 *
 * O que fez a fileira andar de verdade para a direita não foi este número: foi a
 * Loja e o Ranking virarem discos (ver `renderArena`). Eles devolveram 130px.
 */
.modal-box.arena > header #modal-acoes {
  position: absolute; right: 64px; top: 20px;
  display: flex; align-items: center; gap: 6px;
}

/* =========================================================================
 * O SELO DE TICKETS, no canto de cima a ESQUERDA
 *
 * "coloca la encima na esquerda ao lado de arena x1 na aba de arena x1 pra
 *  mostrar a quantidade de tickets."
 *
 * ---- Por que 27px, o mesmo numero do X ----
 *
 * A moldura tem um cristal em cada canto de cima, e eles sao simetricos. O X ja
 * tinha sido encostado no limite do cristal da direita — 27px e' o mais perto
 * da quina que da' para chegar sem tapa-lo. O da esquerda comeca no espelho
 * dessa medida, entao repetir o numero e' o que faz os dois cantos ficarem
 * iguais de verdade, e nao por acaso.
 *
 * ---- Ele nao e' um botao ----
 *
 * E' um numero. Nao tem `:hover`, nao tem cursor de mao e nao responde a
 * clique: se respondesse, a primeira coisa que todo mundo faria era clicar
 * esperando comprar mais — e nao ha o que comprar.
 *
 * A cor MUDA com o que sobra, e isso e a unica informacao que ele da alem do
 * numero: quem tem tickets ve dourado, quem esta no ultimo ve ambar, e quem
 * zerou ve vermelho apagado. E' a leitura de relance, antes de ler "0/10".
 * ========================================================================= */
.modal-box.arena > header #modal-selo {
  /* "onde ficam os tickets, arraste 5 pixels pra direita" — 27 + 5. */
  position: absolute; left: 32px; top: 20px;
  display: flex; align-items: center; gap: 0;
  margin: 0;
}
.arena-ticket {
  display: flex; align-items: center; gap: 6px;
  height: 28px; padding: 0 11px 0 9px;
  border: 1px solid #8a6f42; border-radius: 14px;
  background: #0b0f11e6;
  box-shadow: 0 0 0 1px #0a0d0f99, 0 2px 10px #000a;
  color: #e8d9b4;
  font-family: var(--font-title);
  font-size: 12px; letter-spacing: .06em; line-height: 1;
  white-space: nowrap;
  /* O balao explica a reposicao; o selo so' mostra o numero. */
  cursor: default;
}
/*
 * O bilhete e' desenhado no CSS, e nao um arquivo.
 *
 * Um icone de 16px a mais para baixar por causa de dois retangulos e um talho
 * seria uma ida ao servidor para o que a borda resolve. O talho e' um `::after`
 * com a mesma cor do fundo do selo: e' o que faz o retangulo parecer um bilhete
 * picotado em vez de uma etiqueta.
 */
.arena-ticket-icone {
  position: relative; flex: none;
  width: 15px; height: 11px;
  border: 1.5px solid currentColor; border-radius: 2px;
  opacity: .92;
}
.arena-ticket-icone::before,
.arena-ticket-icone::after {
  content: ''; position: absolute; top: 50%;
  width: 3px; height: 5px; margin-top: -2.5px;
  background: #0b0f11;
  border: 1.5px solid currentColor;
}
.arena-ticket-icone::before { left: -1.5px; border-left: none; border-radius: 0 3px 3px 0; }
.arena-ticket-icone::after { right: -1.5px; border-right: none; border-radius: 3px 0 0 3px; }

.arena-ticket b { font-size: 13px; font-weight: 700; color: #ffdfae; }
.arena-ticket span { opacity: .6; font-size: 11px; }

/* As tres leituras de relance. */
.arena-ticket.ultimo { border-color: #c58a3a; color: #f3c98a; }
.arena-ticket.ultimo b { color: #ffcf8a; }
.arena-ticket.vazio { border-color: #7d3a3a; color: #d79b9b; }
.arena-ticket.vazio b { color: #ff9e9e; }
/* Cheio: o dourado acende de leve, para o acumulo ser visivel sem gritar. */
.arena-ticket.cheio { border-color: #d8b471; box-shadow: 0 0 0 1px #0a0d0f99, 0 0 12px #e0a84a33, 0 2px 10px #000a; }
.modal-box.arena > header #modal-close {
  position: absolute; right: 27px; top: 20px;
  margin: 0;
  width: 28px; height: 28px; padding: 0;
  display: grid; place-content: center;
  border: 1px solid #8a6f42; border-radius: 50%;
  background: #0b0f11e6;
  box-shadow: 0 0 0 1px #0a0d0f99, 0 2px 10px #000a;
  color: #e8d9b4; font-size: 16px; line-height: 1;
  transition: background .12s ease, color .12s ease, border-color .12s ease;
}
.modal-box.arena > header #modal-close:hover {
  background: #17262a; color: #fff3d6; border-color: #d8b471;
}

/*
 * ---- O corpo, e a promessa de não rolar ----
 *
 * "faz nao precisar escrollar a pagina."
 *
 * A rolagem não sumiu por decreto: ela sumiu porque o conteúdo encolheu. O
 * ranking virou página (atrás do troféu), a seção "Você" subiu para dentro do
 * preview, e a lista de gente virou grade de três colunas em vez de uma pilha
 * de linhas. O que sobrou cabe.
 *
 * `overflow-y: auto` FICA, e não é contradição: ele é a rede para o dia em que
 * houver quarenta pessoas na cidade ou oito arenas. Sem ele, o excesso não
 * rolaria — sumiria por baixo da pedra, que é pior do que uma barra.
 */
.modal-box.arena #modal-body {
  position: relative; z-index: 1;
  /* O recuo agora é da caixa (ver `padding` lá em cima); aqui sobra a folga. */
  padding: 2px 2px 4px;
  overflow-y: auto; overflow-x: hidden;
}

/*
 * As seções viram vidro. `backdrop-filter` não: ele custa uma composição por
 * painel e por quadro, e o fundo aqui já está escurecido — o borrão do
 * navegador não teria o que acrescentar.
 */
.modal-box.arena #modal-body > section {
  border-color: #ffffff24;
  background: linear-gradient(180deg, #0b1214bf, #070d0ed6);
  box-shadow: inset 0 1px 0 #ffffff14, 0 8px 22px #0007;
  /*
   * O canto arredondado é a segunda metade do conserto. O cristal entra na
   * diagonal; o enchimento resolve o avanço reto, e o raio tira a QUINA — que
   * é a parte da seção que chega mais perto da ponta dele.
   */
  border-radius: 14px;
}
/*
 * ---- A ficha é só a moldura do preview ----
 *
 * Ela não tem fundo próprio nem borda: quem carrega a imagem é o
 * `.arena-lobby-preview` lá dentro, que sangra até a beirada. Uma caixa de
 * vidro em volta de uma caixa com imagem seriam duas molduras encaixadas, e a
 * de fora não teria função nenhuma.
 */
.modal-box.arena #modal-body > .arena-lobby-ficha {
  border-color: transparent;
  background: none;
  box-shadow: none;
  padding: 0;
  overflow: visible;
}

/* As linhas de dentro acompanham, senão elas viram a parede que a seção deixou de ser. */
.modal-box.arena .arena-lobby-linha { background: #0a10119e; border-color: #ffffff1a; }
.modal-box.arena .arena-lobby-bicho { background: #0a1011a8; }

/*
 * ---- No telefone a moldura AFINA ----
 *
 * 83px de pedra em cima e 80 de cada lado, numa tela de 400px, sobram 240px de
 * conteúdo. A borda cai para um terço: o desenho fica pequeno demais para ser
 * lido, mas continua dando a cor e o contorno da arena — e o espaço volta para
 * quem precisa dele.
 */
@media (max-width: 760px) {
  .modal-box.arena {
    width: 100%;
    border-width: 28px 20px 28px 20px;
  }
  /* A cópia de cima acompanha a borda fina, senão ela desenha uma moldura de
     tamanho de computador por cima da encolhida. */
  .modal-box.arena::after {
    top: -28px; left: -20px; right: -20px; bottom: -28px;
    border-width: 28px 20px 28px 20px;
  }
  .modal-box.arena > header {
    top: -28px; height: 28px;
  }
  .modal-box.arena > header #modal-title { top: 1px; height: 24px; font-size: 10px; letter-spacing: .1em; }
  .modal-box.arena > header #modal-selo { left: 4px; top: 2px; }
  .arena-ticket { height: 22px; padding: 0 8px 0 6px; font-size: 10px; gap: 4px; }
  .arena-ticket b { font-size: 11px; }
  .arena-ticket span { font-size: 9px; }
  .arena-ticket-icone { width: 12px; height: 9px; }
  .modal-box.arena > header #modal-acoes { right: 38px; top: 2px; }
  .modal-box.arena > header #modal-close { right: 4px; top: 1px; width: 24px; height: 24px; font-size: 14px; }
}

/* ---- Os convites, em pilulas ----
 *
 * "deixa mais otimizado, ta ocupando uma linha inteira dentro do modal."
 *
 * Duas secoes com titulo e linhas de largura cheia viraram uma faixa so. O que
 * diz qual e' qual e' a COR: verde no que espera a SUA resposta, apagado no que
 * espera a do outro.
 */
.arena-convites {
  display: flex; flex-wrap: wrap; gap: 8px;
  padding: 9px 11px;
}
.arena-convite {
  display: flex; align-items: center; gap: 8px;
  padding: 5px 9px 5px 12px;
  border: 1px solid var(--line); border-radius: 999px;
  background: #0a1011b3;
}
.arena-convite b { font-size: 12px; color: var(--text); }
.arena-convite > span { font-size: 10.5px; color: var(--muted); }
/* Quem esta chamando VOCE: verde, e e o unico aceso da faixa. */
.arena-convite.chamando { border-color: #4f9d6a; background: #12241acc; }
.arena-convite.chamando b { color: #d9f5e4; }
.arena-convite.esperando { opacity: .72; }
.arena-convite button { padding: 4px 12px; font-size: 10.5px; }

/* =========================================================================
 * A SALA DE DUELO — os dois lados, e o PRONTO
 *
 * "embaixo apareceria a esquerda e a direita quem esta no duelo, e ambos tem
 *  que da pronto antes de começar."
 *
 * Os dois bonecos grandes, o "×" no meio e o estado de cada um embaixo. É a
 * única coisa na tela enquanto a sala existe (ver `renderArena`), então ela
 * pode ser grande: não há nada disputando espaço com ela.
 * ========================================================================= */
.arena-sala {
  display: grid; gap: 9px; justify-items: center;
  padding: 12px 14px 12px;
}
.arena-sala-titulo {
  margin: 0;
  font-family: var(--font-title); font-size: 13px;
  letter-spacing: .16em; text-transform: uppercase; color: var(--muted);
}

.arena-sala-ringue {
  display: flex; align-items: center; justify-content: center;
  gap: 18px; flex-wrap: wrap;
}
.arena-sala-versus {
  font-family: var(--font-title); font-size: 26px; color: #7d6a45;
  text-shadow: 0 2px 0 #0009;
}

.arena-sala-lado {
  display: grid; justify-items: center; gap: 3px;
  min-width: 150px; padding: 10px 16px 10px;
  border: 1px solid var(--line); border-radius: 11px;
  background: linear-gradient(180deg, #0b1214cc, #070d0edd);
  transition: border-color .18s ease, box-shadow .18s ease;
}
/* O SEU lado, com um fio de ouro: numa tela com dois bonecos iguais de costas,
   saber qual é o seu não devia depender de ler o nome. */
.arena-sala-lado.eu { border-color: rgba(224, 168, 74, .45); }
/* Pronto: verde, e o brilho de fora. A cor muda os dois cards ao mesmo tempo
   quando o segundo confirma, e é esse o instante que a arena abre. */
.arena-sala-lado.pronto {
  border-color: #4f9d6a;
  box-shadow: 0 0 26px #4f9d6a2e, inset 0 1px 0 #9fd68a24;
}

.arena-sala-boneco {
  display: flex; align-items: flex-end; justify-content: center;
  width: 78px; height: 84px;
  border-radius: 9px; border: 1px solid var(--line-soft);
  background: radial-gradient(ellipse at 50% 95%, #1a2a2c 0%, #0a1011 74%);
  overflow: hidden;
}
.arena-sala-boneco canvas { image-rendering: pixelated; }

.arena-sala-nome { display: flex; align-items: center; gap: 5px; }
.arena-sala-nome b { font-size: 13px; color: var(--text); }
.arena-sala-level { font-size: 10.5px; color: var(--muted); }

.arena-sala-estado {
  margin-top: 3px; padding: 2px 9px;
  border-radius: 999px; border: 1px solid var(--line);
  font-size: 10px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted); background: #0a1011a8;
}
.arena-sala-lado.pronto .arena-sala-estado {
  border-color: #4f9d6a; color: #9fd68a; background: #12241a;
}
.arena-sala-estado.caiu { border-color: #8c5a52; color: #e08a7a; background: #2a1512; }

.arena-sala-botoes { display: flex; align-items: center; gap: 10px; margin-top: 2px; }

/* ---- O botão PRONTO ----
 *
 * Grande, verde e sozinho no meio: é a única coisa que a sala pede. Depois de
 * clicado ele não some — vira "Aguardando o outro...", apagado. Sumir deixaria
 * a pessoa sem saber se o clique pegou.
 */
button.arena-pronto {
  padding: 10px 30px;
  border: 1px solid #4f9d6a; border-radius: 8px;
  background: linear-gradient(180deg, #1c3a29 0%, #12241a 60%, #0d1a13 100%);
  color: #d9f5e4;
  font-family: var(--font-title); font-size: 14px;
  letter-spacing: .14em; text-transform: uppercase;
  cursor: pointer;
  box-shadow: inset 0 1px 0 #9fd68a26, 0 3px 12px #0008;
  transition: border-color .14s ease, color .14s ease, box-shadow .14s ease, transform .1s ease;
}
button.arena-pronto:hover:not(:disabled) {
  border-color: #7fd6a0; color: #f0fff6;
  box-shadow: inset 0 1px 0 #9fd68a45, 0 0 22px #4f9d6a45, 0 4px 14px #0009;
  transform: translateY(-1px);
}
button.arena-pronto:disabled,
button.arena-pronto.esperando {
  opacity: .55; cursor: default; transform: none;
  border-color: var(--line); color: var(--muted);
  background: linear-gradient(180deg, #0f1618, #0a1011);
  box-shadow: none;
}

/* ---- O botão COMEÇAR, e por que ele não é verde ----
 *
 * "quando as duas pessoas derem pronto nao tem que começar automaticamente, o
 *  lider tem que clicar em começar."
 *
 * Ele OCUPA O LUGAR do PRONTO quando a sala enche, e não aparece ao lado dele.
 * Dois botões grandes e parecidos, um deles morto, é a receita para clicar no
 * errado — e este clique não tem volta: do outro lado ele abre uma arena.
 *
 * A cor é a da arena (fogo) e não o verde do pronto, de propósito: "estou
 * pronto" e "vai agora" são gestos de peso diferente, e a mão precisa perceber
 * que o segundo não é mais um passo do primeiro. O pulso lento diz que a tela
 * está esperando por ele.
 */
button.arena-comecar {
  padding: 11px 34px;
  border: 1px solid #c06a3a; border-radius: 8px;
  background: linear-gradient(180deg, #47200f 0%, #2c1409 60%, #1d0d06 100%);
  color: #ffe2cf;
  font-family: var(--font-title); font-size: 15px;
  letter-spacing: .16em; text-transform: uppercase;
  cursor: pointer;
  box-shadow: inset 0 1px 0 #ffb98a33, 0 3px 14px #0009, 0 0 22px #ff4f2e22;
  animation: arena-comecar-pulsa 1.9s ease-in-out infinite;
  transition: border-color .14s ease, color .14s ease, box-shadow .14s ease, transform .1s ease;
}
button.arena-comecar:hover {
  border-color: #ff9a5e; color: #fff4ec;
  box-shadow: inset 0 1px 0 #ffb98a4d, 0 0 30px #ff4f2e55, 0 4px 16px #000a;
  transform: translateY(-1px);
  animation: none;
}
@keyframes arena-comecar-pulsa {
  0%, 100% { box-shadow: inset 0 1px 0 #ffb98a33, 0 3px 14px #0009, 0 0 18px #ff4f2e1f; }
  50% { box-shadow: inset 0 1px 0 #ffb98a33, 0 3px 14px #0009, 0 0 34px #ff4f2e55; }
}

/*
 * Quem NÃO é líder vê uma frase, e não um botão apagado: um botão que nunca vai
 * acender é um convite a clicar nele repetidamente até concluir que a tela
 * travou.
 */
.arena-sala-espera-lider {
  display: flex; align-items: baseline; gap: 6px;
  padding: 10px 16px;
  font-size: 12px; color: var(--muted);
}
.arena-sala-espera-lider b { color: #f0dda8; font-size: 13px; }

/* O crachá de líder no card: o botão de começar tem dono, e ele diz quem é. */
.arena-sala-lider {
  padding: 1px 7px;
  border: 1px solid #8a6f42; border-radius: 999px;
  background: #1a140a;
  font-size: 9px; letter-spacing: .16em; text-transform: uppercase;
  color: #e0c88a;
}

/* =========================================================================
 * OS CARDS DE QUEM DÁ PARA DESAFIAR
 *
 * "quando eu for desafiar alguem, que aparece ali o nome da pessoa tem que
 *  aparecer o nome e o addon outfit que ela esta usando. Bem bonito, quero tipo
 *  um lobby de jogo mesmo."
 *
 * O boneco à esquerda, o nome e o placar no meio, o botão embaixo. Em grade de
 * três: era uma pilha de linhas de largura inteira, e dez pessoas na cidade
 * davam dez linhas e uma barra de rolagem.
 * ========================================================================= */
/* =========================================================================
 * O CABECALHO DA FILA: o titulo a esquerda, o botao de alistar-se a direita
 *
 * O botao mora na MESMA linha do titulo, e nao acima da grade, porque ele fala
 * da lista inteira e nao de nenhum card: posto embaixo, ele pareceria o botao
 * do ultimo card; posto acima, ganharia uma faixa so' para ele numa janela que
 * a tela inteira tenta manter sem rolagem.
 *
 * O `margin-left: auto` empurra o botao para a direita sem precisar de largura
 * fixa nem de um segundo elemento vazio para ocupar o meio.
 * ========================================================================= */
.arena-fila-cabeca {
  display: flex; align-items: center; gap: 10px;
  /* O h4 de dentro ja traz a margem de baixo da secao; aqui ela zera para os
     dois nao somarem e afastarem o botao do titulo. */
  margin-bottom: 8px;
}
.arena-fila-cabeca > .deposito-titulo { margin: 0; }
.arena-fila-cabeca > button { margin-left: auto; flex: 0 0 auto; }

.arena-lobby-grade {
  display: grid; gap: 8px;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
}
.arena-lobby-card {
  display: grid;
  grid-template-columns: 52px minmax(0, 1fr);
  grid-template-areas: 'boneco texto' 'boneco botao';
  align-items: center; gap: 2px 10px;
  padding: 9px 11px;
  border: 1px solid var(--line); border-radius: 9px;
  background: linear-gradient(180deg, #0b1214cc, #070d0edd);
  transition: border-color .12s ease, transform .12s ease;
}
.arena-lobby-card:hover { border-color: rgba(224, 168, 74, .45); transform: translateY(-1px); }

/*
 * O palco do boneco: altura fixa e o desenho ancorado embaixo. Sem a altura
 * fixa, um outfit com montaria (mais alto) empurraria o card inteiro e a grade
 * ficaria com linhas de alturas diferentes.
 */
.arena-lobby-card-boneco {
  grid-area: boneco;
  display: flex; align-items: flex-end; justify-content: center;
  width: 52px; height: 58px;
  border-radius: 7px;
  border: 1px solid var(--line-soft);
  background: radial-gradient(ellipse at 50% 95%, #1a2a2c 0%, #0a1011 72%);
  overflow: hidden;
}
.arena-lobby-card-boneco canvas { image-rendering: pixelated; }

.arena-lobby-card-texto { grid-area: texto; display: grid; gap: 1px; min-width: 0; }
.arena-lobby-card-nome { display: flex; align-items: center; gap: 5px; min-width: 0; }
.arena-lobby-card-nome b {
  font-size: 12.5px; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.arena-lobby-card-texto > span { font-size: 10.5px; color: var(--muted); }

/* ---- O botão de desafiar ----
 *
 * "deixa o botao desafiar bem bonito."
 *
 * Ele era o verde chapado de todo botão primário do jogo. Aqui ele é o único
 * botão do card e a única coisa que se clica nesta tela: ganhou o ouro velho da
 * arena, um degradê de metal e um brilho que acende no hover. Desabilitado, ele
 * apaga em vez de sumir — quem não alcança o level precisa ver por quê.
 */
.arena-lobby-card button.arena-desafiar { grid-area: botao; }
button.arena-desafiar {
  margin-top: 4px;
  padding: 6px 14px;
  border: 1px solid #a5813f; border-radius: 7px;
  background: linear-gradient(180deg, #3a2f18 0%, #241c0e 58%, #1a140a 100%);
  color: #f0dda8;
  font-family: var(--font-title); font-size: 11.5px;
  letter-spacing: .12em; text-transform: uppercase;
  cursor: pointer;
  box-shadow: inset 0 1px 0 #ffd98a2e, 0 2px 8px #0007;
  transition: border-color .14s ease, color .14s ease, box-shadow .14s ease, transform .1s ease;
}
button.arena-desafiar:hover:not(:disabled) {
  border-color: #e0c07a; color: #fff6dc;
  box-shadow: inset 0 1px 0 #ffd98a4d, 0 0 18px #e0a84a3d, 0 3px 10px #0008;
  transform: translateY(-1px);
}
button.arena-desafiar:active:not(:disabled) { transform: none; }
button.arena-desafiar:disabled {
  opacity: .42; cursor: not-allowed;
  border-color: var(--line); color: var(--muted);
  box-shadow: none;
}

/* =========================================================================
 * O PÓDIO DO RANKING
 *
 * Os três primeiros em cards e o resto em linhas. Numa lista corrida de vinte,
 * o primeiro lugar tem o mesmo peso visual do décimo sétimo — e o primeiro
 * lugar é a única parte que alguém quer alcançar.
 * ========================================================================= */
/* ---- E os TRÊS são destacados de verdade ----
 *
 * "faz um efeito melhor na aba de ranking pros 3 tops, destaque eles."
 *
 * Antes o que separava o primeiro do terceiro era a COR DA BORDA — um fio de
 * 1px em três tons parecidos de dourado. Num pódio, o primeiro lugar tem de ser
 * a primeira coisa que se vê, e não a que se descobre comparando molduras.
 *
 * São quatro coisas juntas, e nenhuma delas sozinha bastava:
 *
 *   TAMANHO   a coluna do meio é mais larga e o card sobe 10px. É o pódio de
 *             verdade: ouro no centro e mais alto, prata e bronze nos lados.
 *   LUZ       um halo da cor do metal, por trás do card inteiro.
 *   COROA     só o primeiro, e é o único elemento que nenhum outro tem.
 *   BRILHO    uma faixa clara que atravessa o card do ouro, devagar.
 *
 * A ordem no HTML continua 1º, 2º, 3º — quem troca de lugar é o `order`, e só
 * na tela larga. Numa tela estreita eles voltam a empilhar na ordem lida, que é
 * a ordem certa quando não há pódio para desenhar.
 */
.arena-podio {
  display: grid; gap: 10px; margin-bottom: 12px;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  align-items: end;
}
@media (min-width: 620px) {
  /* Prata à esquerda, OURO no meio, bronze à direita. */
  .arena-podio { grid-template-columns: 1fr 1.18fr 1fr; }
  .arena-podio-card.lugar-1 { order: 2; }
  .arena-podio-card.lugar-2 { order: 1; }
  .arena-podio-card.lugar-3 { order: 3; }
}

.arena-podio-card {
  position: relative;
  display: grid; justify-items: center; gap: 4px;
  padding: 12px 10px;
  border: 1px solid var(--line); border-radius: 12px;
  background: linear-gradient(180deg, #0b1214cc, #070d0edd);
  overflow: hidden;
}

/*
 * O halo do metal, atrás de tudo. `inset: -1px` para ele cobrir a borda
 * também: um degradê que para 1px antes deixa um fio escuro em volta.
 */
.arena-podio-card::before {
  content: '';
  position: absolute; inset: -1px; z-index: 0;
  border-radius: inherit;
  background: radial-gradient(ellipse 120% 90% at 50% 0%, var(--halo, transparent) 0%, transparent 70%);
  pointer-events: none;
}
.arena-podio-card > * { position: relative; z-index: 1; }

.arena-podio-card.lugar-1 {
  --halo: #e0a84a3d;
  border-color: #d8b45e;
  padding: 18px 12px 14px;
  box-shadow: 0 0 34px #e0a84a33, inset 0 1px 0 #ffd98a45, 0 10px 26px #0008;
}
.arena-podio-card.lugar-2 {
  --halo: #b8c4cc2e;
  border-color: #aab3ba;
  box-shadow: 0 0 20px #aab3ba1f, inset 0 1px 0 #dfe8ee2e;
}
.arena-podio-card.lugar-3 {
  --halo: #c07f4a2e;
  border-color: #bd854f;
  box-shadow: 0 0 20px #bd854f1f, inset 0 1px 0 #e8b98a2e;
}

/*
 * ---- A COROA, e só no primeiro ----
 *
 * Um elemento que os outros dois não têm vale mais do que qualquer diferença de
 * grau: tamanho e cor se comparam, presença não. `::after` porque o `::before`
 * já é o halo, e os dois cabem no mesmo card.
 */
.arena-podio-card.lugar-1::after {
  content: '\265B';
  position: absolute; top: 2px; left: 50%; transform: translateX(-50%);
  z-index: 2;
  font-size: 15px; line-height: 1;
  color: #ffd98a;
  text-shadow: 0 0 10px #e0a84a99, 0 1px 0 #2a1c06;
  pointer-events: none;
}

/*
 * O brilho que atravessa o card do ouro. Lento (5,5s) e fraco de propósito:
 * rápido vira pisca-pisca, e a página fica aberta enquanto alguém lê a tabela.
 */
.arena-podio-card.lugar-1 {
  background:
    linear-gradient(115deg, transparent 38%, #ffe7b012 47%, transparent 56%) 0 0 / 260% 100% no-repeat,
    linear-gradient(180deg, #14181acc, #0a0f10dd);
  animation: arena-podio-lustra 5.5s ease-in-out infinite;
}
@keyframes arena-podio-lustra {
  0%, 100% { background-position: 150% 0, 0 0; }
  50% { background-position: -50% 0, 0 0; }
}

.arena-podio-lugar {
  font-family: var(--font-title); font-size: 19px; line-height: 1;
  color: var(--muted);
}
.arena-podio-card.lugar-1 .arena-podio-lugar {
  font-size: 27px; color: #ffe0a0;
  text-shadow: 0 0 20px #e0a84a80, 0 2px 0 #2a1c06;
}
.arena-podio-card.lugar-2 .arena-podio-lugar { color: #dfe8ee; text-shadow: 0 0 14px #aab3ba55; }
.arena-podio-card.lugar-3 .arena-podio-lugar { color: #f0b98a; text-shadow: 0 0 14px #bd854f55; }

/* O boneco do primeiro é maior, e ganha o chão dourado. */
.arena-podio-card.lugar-1 .arena-podio-boneco {
  width: 72px; height: 72px;
  border-color: #8a6f42;
  background: radial-gradient(ellipse at 50% 95%, #3a2d14 0%, #120e06 74%);
}
.arena-podio-nome {
  font-size: 12.5px; color: var(--text); text-align: center;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%;
}
.arena-podio-pontos { font-size: 10.5px; color: var(--accent); }

/* ---- O boneco de cada um ----
 *
 * "tem que mostra o addon atual da pessoa tambem."
 *
 * `align-items: flex-end` porque o desenho de um outfit não preenche a caixa:
 * montaria e capacete deixam folga em cima e o boneco flutuaria no meio. Com os
 * pés no chão, dez linhas ficam alinhadas entre si mesmo com roupas de alturas
 * diferentes.
 */
.arena-podio-boneco {
  display: flex; align-items: flex-end; justify-content: center;
  width: 62px; height: 62px;
  border-radius: 8px; border: 1px solid var(--line-soft);
  background: radial-gradient(ellipse at 50% 95%, #241f14 0%, #0f0d08 74%);
  overflow: hidden;
}
.arena-podio-boneco canvas { image-rendering: pixelated; }

.arena-rank-boneco {
  flex: none;
  display: flex; align-items: flex-end; justify-content: center;
  width: 32px; height: 32px;
  overflow: hidden;
}
.arena-rank-boneco canvas { image-rendering: pixelated; }

/*
 * O placar empurrado para a direita, colado no total de pontos: "7 pontos" diz
 * a posição, "4V · 2D" diz como ela foi feita. Sem o segundo, dois jogadores
 * com sete pontos parecem iguais, e um deles perdeu doze vezes.
 */
.arena-rank-placar {
  margin-left: auto;
  font-size: 10.5px; color: var(--muted); font-variant-numeric: tabular-nums;
}

/* =========================================================================
 * AS ÚLTIMAS BATALHAS
 *
 * "tem que ter um historico das ultimas batalhas e quanto tempo durou etc."
 *
 * Cada luta é uma linha com quatro partes: quem ganhou, a palavra "venceu",
 * quem perdeu, e a conta (tempo, arena, degrau dos bichos, há quanto tempo).
 *
 * ---- Por que os dois lados têm o mesmo tamanho ----
 *
 * `1fr auto 1fr` e não `auto auto auto`: com colunas automáticas, a linha
 * inteira se desloca conforme o comprimento dos nomes, e vinte linhas empilhadas
 * viram uma serra. Com frações iguais, o "venceu" fica na mesma coluna em todas
 * — e é ele que se lê para saber a direção de cada linha.
 *
 * A conta desce para a linha de baixo em vez de virar uma quinta coluna: ela
 * tem quatro números curtos, e espremidos numa coluna estreita nenhum deles
 * seria legível.
 * ========================================================================= */
.arena-batalhas { display: grid; gap: 6px; }

.arena-batalha {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  grid-template-areas: 'venceu versus perdeu' 'conta conta conta';
  align-items: center; gap: 4px 10px;
  padding: 8px 12px;
  border: 1px solid #ffffff1a; border-radius: 9px;
  background: #0a10119e;
}

.arena-batalha-lado { display: flex; align-items: center; gap: 8px; min-width: 0; }
.arena-batalha-lado.venceu { grid-area: venceu; }
/*
 * O perdedor espelhado (`row-reverse`): assim os dois bonecos ficam nas pontas
 * da linha e os dois nomes se encontram no meio, em volta do "venceu". É a
 * mesma anatomia do ringue da sala de duelo, e de propósito — duas telas que
 * mostram um duelo não devem mostrá-lo de jeitos diferentes.
 */
.arena-batalha-lado.perdeu { grid-area: perdeu; flex-direction: row-reverse; }

.arena-batalha-boneco {
  flex: none;
  display: flex; align-items: flex-end; justify-content: center;
  width: 36px; height: 36px;
  overflow: hidden;
}
.arena-batalha-boneco canvas { image-rendering: pixelated; }
/* O derrotado esmaecido: a linha diz quem ganhou antes de ser lida. */
.arena-batalha-lado.perdeu .arena-batalha-boneco { opacity: .5; filter: grayscale(.6); }

.arena-batalha-quem { display: flex; align-items: center; gap: 5px; min-width: 0; }
.arena-batalha-quem b {
  font-size: 12.5px; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.arena-batalha-lado.venceu .arena-batalha-quem b { color: #f0dda8; }
.arena-batalha-lado.perdeu .arena-batalha-quem b { color: #9b927f; }

.arena-batalha-versus {
  grid-area: versus;
  font-size: 9.5px; letter-spacing: .16em; text-transform: uppercase;
  color: #6f8a72;
}

.arena-batalha-conta {
  grid-area: conta;
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px;
  padding-top: 3px;
  border-top: 1px solid #ffffff10;
  font-size: 10px; color: var(--muted);
}
.arena-batalha-tempo { color: #cbb894; font-variant-numeric: tabular-nums; }
.arena-batalha-onde { color: var(--accent); }
/*
 * O degrau em vermelho: ele conta quanto os bichos tinham subido quando a luta
 * acabou, e é a única parte da conta que fala de perigo.
 */
.arena-batalha-degrau { color: #e08a6a; }
.arena-batalha-quando { margin-left: auto; }

@media (max-width: 560px) {
  /*
   * Numa tela estreita as três colunas viram três linhas: `1fr auto 1fr` com
   * 340px de largura daria dois nomes cortados na terceira letra.
   */
  .arena-batalha {
    grid-template-columns: 1fr;
    grid-template-areas: 'venceu' 'versus' 'perdeu' 'conta';
    justify-items: start;
  }
  .arena-batalha-lado.perdeu { flex-direction: row; }
}

/* A posição, na tabela de baixo. */
.arena-lobby-pos {
  flex: none; min-width: 28px;
  font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums;
}
/* A sua linha, destacada: numa tabela de vinte, achar-se é o primeiro gesto. */
.arena-lobby-linha.eu { border-color: rgba(224, 168, 74, .5); background: #1a140a80; }

/* ---- A tira de arenas ----
 *
 * Só aparece com mais de uma (ver `renderArena`). Ela é uma fileira de abas
 * pequenas acima do preview: o nome e o level, que é o par que decide se vale
 * clicar.
 *
 * `overflow-x: auto` porque a lista cresce e a janela não: com seis arenas a
 * tira rola, em vez de quebrar em duas linhas e empurrar o preview para baixo
 * da dobra.
 */
.arena-lobby-tira {
  display: flex; gap: 6px; margin-bottom: 8px;
  overflow-x: auto; scrollbar-width: thin;
  padding-bottom: 2px;
}
.arena-lobby-aba {
  flex: none;
  display: flex; align-items: baseline; gap: 6px;
  padding: 5px 11px;
  border: 1px solid var(--line); border-radius: 999px;
  background: #0a1011b3; color: var(--muted);
  cursor: pointer;
  transition: border-color .12s ease, background .12s ease, color .12s ease;
}
.arena-lobby-aba b { font-size: 12px; color: var(--text); }
.arena-lobby-aba span { font-size: 10px; letter-spacing: .06em; text-transform: uppercase; }
.arena-lobby-aba:hover { border-color: rgba(224, 168, 74, .5); background: #14201fb3; }
.arena-lobby-aba.ligada { border-color: var(--accent); background: #1d3a37cc; }
.arena-lobby-aba.ligada b { color: #d8f5ec; }
.arena-lobby-aba.ligada span { color: var(--accent); }

/* =========================================================================
 * O PREVIEW DA ARENA — o mapa dela, desfocado, atrás do nome e dos bichos
 *
 * "o fundo com a area a ser desafiado vai ficar atras apenas de onde sera o
 *  preview da arena, pq eu terei varias arenas."
 *
 * A imagem é DESENHADA do mapa da hunt (`tools/fundo-da-arena.mjs`), já borrada
 * e escurecida no arquivo — 16 KB a da Livraria, 23 KB a do Skeletinho. Borrar
 * no CSS custaria um filtro por quadro e obrigaria a escurecer com mais uma
 * camada por cima; pronto no arquivo, custa uma imagem.
 *
 * `--arena-fundo` é posta pelo JS neste elemento, e não na janela: é o que faz
 * a arena seguinte nascer com o fundo dela sem uma linha a mais de código. A
 * janela tem o fundo FIXO da arena (ver `.modal-box.arena::before`), que diz
 * "isto é uma arena"; este diz QUAL.
 * ========================================================================= */
.arena-lobby-preview {
  position: relative; isolation: isolate;
  display: grid; gap: 6px;
  /*
   * O acolchoado e pequeno de proposito: "faz nao precisar escrollar a pagina".
   * Com 14px em volta, o preview sozinho levava 270px de altura e empurrava a
   * sala de duelo (ou a lista de gente) para fora da janela.
   */
  padding: 10px 12px 10px;
  border: 1px solid #ffffff24; border-radius: 10px;
  overflow: hidden;
  box-shadow: inset 0 1px 0 #ffffff14, 0 10px 26px #0008;
}
/* ---- As duas colunas do preview ----
 *
 * A arena a esquerda e o retrospecto a direita. A direita tem largura FIXA
 * (170px) e a esquerda leva o resto: o retrospecto tem sempre o mesmo conteudo
 * (tres numeros e um selo), entao deixa-lo elastico so faria a fila de bichos
 * encolher a toa quando a coluna nao precisava de espaco.
 *
 * `align-items: start` para a coluna da direita nao esticar ate o pe do card
 * quando a esquerda for alta — ela ficaria com um vazio embaixo, que e
 * exatamente o defeito que esta mudanca veio corrigir.
 */
.arena-lobby-preview-corpo {
  display: grid; grid-template-columns: minmax(0, 1fr) 170px; gap: 14px;
  align-items: start;
}
.arena-lobby-preview-esq { display: grid; gap: 8px; align-content: start; min-width: 0; }

.arena-lobby-preview-eu {
  display: grid; justify-items: center; gap: 6px;
  padding: 10px 12px 12px;
  border: 1px solid #ffffff1f; border-radius: 9px;
  background: linear-gradient(180deg, #0b1214a8, #070d0ecc);
  box-shadow: inset 0 1px 0 #ffffff10;
}
.arena-lobby-eu-titulo {
  margin: 0;
  font-size: 10px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--muted);
}
.arena-lobby-eu-falta { font-size: 10px; text-align: center; color: var(--muted); line-height: 1.35; }

/* Os tres numeros, um por linha: rotulo a esquerda, numero a direita. */
.arena-lobby-eu-placar { display: grid; gap: 3px; width: 100%; margin-top: 2px; }
.arena-lobby-eu-placar div {
  display: flex; align-items: baseline; justify-content: space-between; gap: 8px;
  padding: 3px 7px; border-radius: 6px; background: #0a10119e;
}
.arena-lobby-eu-placar b { order: 2; font-size: 15px; color: var(--accent); }
.arena-lobby-eu-placar span { order: 1; font-size: 10px; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }

.arena-lobby-eu-moeda { display: flex; align-items: center; gap: 5px; margin-top: 2px; }
.arena-lobby-eu-moeda > span { font-size: 10px; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }

/* A trava de level: vermelha fosca, porque nao e castigo — e um requisito. */
.arena-lobby-eu-trava {
  margin: 4px 0 0; padding: 5px 8px;
  font-size: 10px; line-height: 1.35; text-align: center;
  border: 1px solid #8c5a52; border-radius: 6px;
  background: #2a15124d; color: #e08a7a;
}

/* Numa janela estreita as duas colunas viram uma. */
@media (max-width: 760px) {
  .arena-lobby-preview-corpo { grid-template-columns: minmax(0, 1fr); }
}

.arena-lobby-preview::before {
  content: '';
  position: absolute; inset: 0; z-index: -1;
  /*
   * O degradê escurece PARA BAIXO: em cima, onde mora o nome da arena, a
   * paisagem aparece; embaixo, onde ficam a descrição e a fila de bichos, ele
   * fecha para o texto ter contraste. É a mesma ideia do cartaz de hunt.
   *
   * O véu é leve porque a imagem já sai do gerador escurecida (ver `VEU`, em
   * `tools/fundo-da-arena.mjs`). A primeira versão empilhava mais 85% de preto
   * por cima e o resultado foi um painel liso: o fundo estava lá e não se via
   * nenhum.
   */
  background:
    linear-gradient(180deg, #060a0b33 0%, #060a0b96 46%, #060a0bd9 82%, #060a0bec 100%),
    var(--arena-fundo, none) center/cover no-repeat;
  /* Sem imagem nenhuma o bloco não fica vazio: fica o degradê, que já é fundo. */
  background-color: #0a1011;
}

/* ---- Os dois botões do canto, ao lado do X ---- */
/*
 * "a loja vai ser um botao clicavel ao lado do botao de fechar."
 *
 * Eles são pequenos e discretos de propósito: moram na mesma faixa do X, que é
 * a régua de altura do cabeçalho. Um botão grande ali empurraria o título.
 */
/*
 * ---- E eles CRESCERAM ----
 *
 * "coloque o icone pra abrir a loja maior, ranking maior, e o interrogaçao
 *  mesmo tamanho do x de fechar."
 *
 * Eles nasceram pequenos com um argumento que era bom para a moldura ANTIGA: um
 * botão grande empurraria o título. A moldura nova tem 66px de faixa em cima,
 * contra 52 — e o título mora numa placa desenhada no meio, que os botões do
 * canto não encostam. O aperto não existe mais, e o que sobrou foi um ícone de
 * 16px numa faixa de 66: pequeno demais para ser lido de relance.
 *
 * 28px é a altura do X, e não um número escolhido: os três botões do canto são
 * uma fileira só, e uma fileira com alturas diferentes fica torta.
 */
.arena-acao {
  display: inline-flex; align-items: center; gap: 6px;
  height: 28px; padding: 0 11px;
  border: 1px solid #8a6f42; border-radius: 999px;
  background: #0b0f11e6; color: #e8d9b4;
  font-size: 11.5px; letter-spacing: .06em; text-transform: uppercase;
  cursor: pointer;
  box-shadow: 0 0 0 1px #0a0d0f99, 0 2px 10px #000a;
  transition: background .12s ease, color .12s ease, border-color .12s ease;
}
.arena-acao:hover { background: #17262a; color: #fff3d6; border-color: #d8b471; }
.arena-acao.ligado { background: #1d3a37; border-color: var(--accent); color: #d8f5ec; }
.arena-acao img { display: block; width: 22px; height: 22px; }

/*
 * O `?` nao tem palavra ao lado — entao ele e redondo, e nao uma pilula com um
 * caractere perdido no meio.
 *
 * "o interrogaçao mesmo tamanho do x de fechar": 28x28 e a mesma borda
 * arredondada do X. Os dois são os únicos botões sem palavra da fileira, e
 * eles são vizinhos — um disco de 24 ao lado de um de 28 lê-se como defeito.
 */
.arena-acao.so-icone {
  width: 28px; height: 28px; padding: 0; justify-content: center;
  font-size: 16px; font-weight: 700; line-height: 1;
}
/* No disco o desenho ocupa quase tudo: e' ele que carrega o botão sozinho. */
.arena-acao.so-icone img { width: 20px; height: 20px; }

/* ---- O cabeçalho da arena: o nome grande e a porta ---- */
.arena-lobby-cabeca-arena {
  display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
}
.arena-lobby-nome {
  margin: 0; flex: 1 1 auto;
  font-family: var(--font-title); font-size: 21px; letter-spacing: .03em;
  color: #f0dda8; text-shadow: 0 2px 0 #0009, 0 0 24px #e0a84a33;
}
.arena-lobby-porta {
  display: inline-flex; align-items: baseline; gap: 5px; flex: none;
  padding: 3px 10px; border-radius: 999px;
  border: 1px solid rgba(224, 168, 74, .45); background: #1a140a4d;
}
.arena-lobby-porta b { font-size: 12.5px; color: var(--accent); }
.arena-lobby-porta span { font-size: 10px; color: var(--muted); }
/* Sem level para entrar, a etiqueta avisa em vez de só informar. */
.arena-lobby-porta.falta { border-color: #8c5a52; background: #2a15124d; }
.arena-lobby-porta.falta b { color: #e08a7a; }

/* ---- A prateleira da loja ---- */
.arena-loja-cabeca {
  position: relative;
  display: grid; gap: 6px; margin-bottom: 10px;
  padding: 12px 14px; border: 1px solid var(--line); border-radius: 9px;
  background: linear-gradient(180deg, #0b1214bf, #070d0ecc);
  overflow: hidden;
}

/*
 * ---- O balcão ----
 *
 * `object-fit: cover` e uma altura fixa: a arte veio 1024x427 e o que se quer é
 * uma FAIXA. Recortar no arquivo teria travado a altura para sempre; assim a
 * mesma imagem serve se a faixa crescer amanhã, e o navegador é quem corta.
 *
 * `object-position` no meio, que é onde o gerador põe o assunto — e foi o que
 * o prompt pediu ("subject centred with breathing room top and bottom").
 *
 * A máscara apaga o pé da imagem para o texto do cabeçalho nascer de dentro
 * dela, em vez de começar depois de uma borda dura.
 */
.arena-loja-balcao {
  width: calc(100% + 28px);
  height: 110px;
  margin: -12px -14px 2px;
  object-fit: cover; object-position: center 45%;
  -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 62%, #0000 100%);
  mask-image: linear-gradient(180deg, #000 0%, #000 62%, #0000 100%);
}
.arena-loja-bolso { display: flex; align-items: center; gap: 8px; }
.arena-loja-bolso .arena-moeda b { font-size: 22px; }
.arena-loja-bolso > span { font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.arena-loja-cabeca .shop-note { margin: 0; }

.arena-loja-prateleira {
  display: grid; gap: 10px;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
}
.arena-loja-card {
  display: grid; justify-items: center; gap: 7px; padding: 12px 10px;
  border: 1px solid var(--line); border-radius: 9px;
  background: linear-gradient(180deg, #0b1214d9, #070d0ee6);
  transition: border-color .12s ease, transform .12s ease;
}
.arena-loja-card:hover { border-color: rgba(224, 168, 74, .5); transform: translateY(-1px); }
/* Sem moeda o card não some: ele apaga. Quem não pode comprar precisa ver o preço. */
.arena-loja-card.sem-moeda { opacity: .55; }
.arena-loja-card.sem-moeda:hover { transform: none; }
.arena-loja-arte {
  position: relative; display: grid; place-items: center;
  width: 56px; height: 56px; border-radius: 8px;
  border: 1px solid var(--line-soft); background: #0006;
}
.arena-loja-arte canvas { image-rendering: pixelated; }
.arena-loja-quantos {
  position: absolute; right: 2px; bottom: 1px;
  font-size: 10px; color: var(--accent); text-shadow: 0 1px 2px #000;
}
.arena-loja-nome {
  font-size: 11.5px; line-height: 1.3; text-align: center; color: var(--text);
  min-height: 30px;
}
.arena-loja-preco .arena-moeda b { font-size: 15px; }
.arena-loja-card button { width: 100%; }

/*
 * ---- A ficha de cada bicho da arena ----
 *
 * Nome em cima, desenho no meio com as estrelas de dificuldade embaixo dele
 * (quem as desenha e o `figuraDaCriatura`, o mesmo do card de Aventuras), e a
 * contagem no rodape. Tres informacoes empilhadas, e nao um quadradinho com
 * numero no canto: numa fileira de sete, o quadradinho obriga a passar o mouse
 * um por um para descobrir quem e quem.
 *
 * A largura e' FIXA e o nome quebra em duas linhas quando precisa. Deixar a
 * caixa crescer com o nome faria "Guardian of Tales" ter o dobro da largura de
 * "Ink Blob", e a fila viraria uma escada.
 */
.arena-lobby-bichos { display: flex; flex-wrap: wrap; gap: 6px; }
.arena-lobby-bicho {
  display: grid; justify-items: center; align-content: start; gap: 2px;
  width: 76px; padding: 5px 4px 4px;
  border: 1px solid var(--line); border-radius: 7px; background: #0b0f1099;
  cursor: help;
}
.arena-lobby-bicho canvas { image-rendering: pixelated; }
.arena-lobby-bicho-nome {
  font-size: 9px; line-height: 1.2; text-align: center; color: var(--muted);
  /* Duas linhas no maximo: o terceiro pedaco de um nome comprido nao informa. */
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  min-height: 22px;
}
.arena-lobby-bicho .bestiary-stars { line-height: 1; }
.arena-lobby-bicho > b { font-size: 10px; color: var(--accent); }

/*
 * ---- O selo da patente ----
 *
 * A cor vem do servidor, numa variavel: os sete degraus tem cor propria e ela
 * mora junto do corte de pontos (ver `patentes-de-arena.mjs`). Sete regras de
 * CSS aqui seriam a segunda copia da escada.
 */
.arena-patente {
  display: inline-flex; align-items: center; gap: 4px; flex: none;
  padding: 2px 7px 2px 3px; border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--patente-cor, #b87333) 45%, transparent);
  background: color-mix(in srgb, var(--patente-cor, #b87333) 12%, transparent);
}
.arena-patente img { display: block; image-rendering: auto; }
.arena-patente b {
  font-size: 10px; letter-spacing: .04em; text-transform: uppercase;
  color: var(--patente-cor, #b87333);
}
.arena-patente-grande b { font-size: 12.5px; }

/* A moeda da arena. Ela nao e item: nao ha inventario onde ela apareca. */
.arena-moeda { display: inline-flex; align-items: center; gap: 4px; flex: none; }
.arena-moeda img { display: block; }
.arena-moeda b { font-family: var(--font-heading); font-size: 13px; color: var(--accent); }

/* Titulo a esquerda, selo e moeda a direita, na mesma linha. */
.arena-lobby-cabeca { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.arena-lobby-cabeca .deposito-titulo { margin-right: auto; }
.arena-lobby-cabeca .shop-note { margin: 0; font-size: 10.5px; }

/* Os dois que estão lá dentro, com o "×" entre eles. */
.arena-lobby-dois { display: flex; align-items: center; justify-content: center; gap: 14px; flex-wrap: wrap; }
.arena-lobby-lutador {
  display: grid; justify-items: center; gap: 2px; min-width: 96px; padding: 8px 10px;
  border: 1px solid rgba(224, 168, 74, .45); border-radius: 9px; background: #1a140a4d;
}
.arena-lobby-lutador canvas { image-rendering: pixelated; }
.arena-lobby-lutador b { font-size: 12.5px; }
.arena-lobby-lutador span { font-size: 10px; color: var(--muted); }
.arena-lobby-versus {
  font-family: var(--font-title); font-size: 20px; color: #e0a84a; line-height: 1;
}
#modal-body > .arena-lobby-briga {
  display: grid; gap: 8px; align-content: start; margin-bottom: 10px;
  padding: 11px; border: 1px solid rgba(224, 168, 74, .5); border-radius: 9px;
  background: linear-gradient(180deg, #14100acc, #0a0e0fcc);
}

/*
 * ---- O bloco antigo das guildas saiu daqui ----
 *
 * Ele desenhava a primeira versao da janela: caixas de cantinho arredondado,
 * uma coluna de listas e nenhuma moldura. O dono pediu outra coisa — "bem
 * bonita bem feita igual de jogo profissional, sem 9slice, igual a aba da
 * arena" — e a janela foi refeita com a receita da arena.
 *
 * As classes novas ficam no fim deste arquivo, em "A JANELA DAS GUILDAS".
 * Deixar as antigas aqui nao seria inofensivo: metade dos nomes e o mesmo
 * (.guilda-membro, .guilda-campo, .guilda-linha), e as regras de la vazariam
 * o que as novas nao redefinem.
 */

/* =========================================================================
 * =========================================================================
 * A JANELA DAS GUILDAS
 *
 * "a aba de guildas do servidor tem que ser bem bonita bem feita igual de jogo
 *  profissional, sem 9slice, igual a aba da arena."
 *
 * ---- "sem 9slice" e "igual a aba da arena" ----
 *
 * As duas frases parecem se contradizer, porque a arena USA uma borda fatiada em
 * nove. Elas não se contradizem: o que ele está recusando é o 9slice de painel
 * genérico — aquela caixa de cantinho arredondado esticada, que se reconhece de
 * longe como "UI de kit". O que a arena faz é outra coisa: a janela É uma
 * ilustração, e o `border-image` é só o jeito de fazer uma ilustração caber em
 * qualquer altura sem esticar o ornamento.
 *
 * Então esta janela usa a mesma receita da arena, que tem três partes e nenhuma
 * delas é opcional:
 *
 *   1. a moldura em `border-image` com a fatia IGUAL à espessura (escala 1:1);
 *   2. o preto da arte VAZADO, para os cristais dos cantos flutuarem sobre o
 *      jogo em vez de virarem tarja preta;
 *   3. uma SEGUNDA cópia da moldura, repintada num `::after`, porque em CSS a
 *      borda de um elemento é pintada antes de qualquer filho — sem a segunda
 *      cópia, a primeira seção do corpo tapa os cantos e nenhum `z-index`
 *      conserta.
 *
 * ---- A arte é a própria, e as fatias são medidas nela ----
 *
 * Por um tempo esta janela tomou emprestada a moldura da arena, porque a dela
 * ainda não existia. Agora existe (`guilda-moldura.webp`), e as fatias abaixo
 * são as DELA — cada moldura traz as suas, e por isso elas moram em variáveis
 * no topo do bloco em vez de espalhadas por três regras.
 *
 * ---- O que diferencia esta janela da arena, então ----
 *
 * O ouro. A arena é teal e brasa (é uma arena de luta); a guilda é ouro velho e
 * pedra (é um salão). A diferença mora em três lugares: o fundo do `::before`, a
 * cor do título e o `--guilda-ouro` que atravessa os painéis.
 * ========================================================================= */
/* =========================================================================
 * AS FATIAS TÊM DE CONTER O ORNAMENTO INTEIRO, e não só o vão
 *
 * Esta é a medida que decide se a moldura fica certa ou fica costurada, e ela
 * não é o que `medir-moldura` devolve.
 *
 * `medir-moldura` responde onde começa o VÃO — nesta arte, x 62 e y 69. Fatiar
 * ali seria o natural, e está errado: o escudo de cada canto é MAIOR que a
 * faixa reta. Medido pixel a pixel, o ornamento do canto vai até x 137 e desce
 * até y 118; a faixa reta tem 61 de lado e 67 em cima.
 *
 * Num `border-image`, o canto é a única parte que NÃO estica. Com fatia 62, os
 * 75px de escudo que sobram cairiam na faixa de cima — que é esticada — e
 * sairiam espremidos a 68% ao lado da metade que ficou em tamanho natural. Uma
 * costura no meio do escudo, nos quatro cantos.
 *
 * Então a fatia é o ORNAMENTO (137/118), e não o vão (62/69). O que entra a
 * mais é vazio transparente, e vazio não aparece: ele só empurra o conteúdo
 * para dentro, que é o que o `padding` faria de qualquer jeito.
 *
 * ---- E a que ficou é a FINA ----
 *
 * A `guilda-moldura.webp` (escudos e estandartes) chegou a entrar, e por pouco
 * tempo: ela é grossa, e o ornamento do canto dela mede 137x118 — quer dizer,
 * 274px de borda horizontal só para os quatro cantos saírem sem costura. Numa
 * janela que mostra uma lista de trinta membros, isso é um quarto da largura.
 *
 * A `moldura-fina.webp` faz o mesmo trabalho com 81px: a filigrana dela é menor
 * e a faixa reta tem 47px em cima contra 67. Sobra tela, e a janela continua
 * sendo uma ilustração.
 *
 * As fatias continuam sendo o ORNAMENTO e não o vão — 86/81/108/81, medidos
 * pixel a pixel nesta arte. A `guilda-moldura.webp` fica no disco para o dia em
 * que houver uma janela de guilda mais curta (a ficha de UMA guilda, por
 * exemplo), onde a borda grossa não custa lista nenhuma.
 * ========================================================================= */
.modal-box.guilda {
  --guilda-moldura: url('/client/assets/ui/moldura-fina.webp');
  --guilda-fundo: url('/client/assets/ui/guilda-fundo.webp');
  --guilda-ouro: #e0a84a;
  --guilda-ouro-fraco: #8a6f42;

  /* =======================================================================
   * A MESMA ARTE, DESENHADA MENOR
   *
   * "não troque por borda fina; mantenha a mesma arte, mas desenhada menor:
   *  mantenha o slice 86/81/108/81 e reduza a largura para 36–44px."
   *
   * A FATIA e a LARGURA são duas coisas diferentes, e é essa distinção que
   * deixa isto funcionar sem tocar na arte:
   *
   *   `border-image-slice`  onde o corte é feito NA IMAGEM. Continua 86/81/
   *                         108/81, que é o ornamento inteiro medido pixel a
   *                         pixel nesta moldura (ver a nota acima). Mudar isto
   *                         cortaria o escudo do canto ao meio.
   *
   *   `border-width`        o espaço que a borda ocupa NA TELA. É ele que
   *                         comia 81px de cada lado numa janela que mostra uma
   *                         lista de trinta membros.
   *
   * A 46% do original, os 81px de filigrana viram 37 e o ornamento do canto é
   * desenhado em escala — a mesma ilustração, menor. Sobram 88px de largura
   * útil de cada lado, que é o pedido inteiro.
   *
   * A proporção é mantida (86:81:108:81 × 0,46): a faixa de baixo é mais alta
   * que a de cima NA ARTE, e igualá-las esmagaria o ornamento de um dos dois
   * lados.
   * ======================================================================= */
  --moldura-t: 40px;
  --moldura-r: 37px;
  --moldura-b: 50px;
  --moldura-l: 37px;
  /* A fatia é a ARTE e não muda com a largura. Ver a nota logo acima. */
  --moldura-fatia: 86 81 108 81;

  width: min(900px, 96vw);
  /* =======================================================================
   * A ALTURA RESPEITA AS DUAS BARRAS DO JOGO
   *
   * "a janela está mais alta que a tela e sobe por cima do menu superior."
   *
   * `92vh` não bastava, e por dois motivos somados. O primeiro é aritmético: o
   * modal é CENTRADO na tela (`#modal` é `place-items: center`), então a folga
   * que sobra se divide igualmente em cima e embaixo — 8vh viram 4vh de cada
   * lado, uns 43px numa tela de 1080, e a barra de cima tem mais que isso.
   *
   * `100vh - 200px` deixa 100px de cada lado: passa por baixo do menu de cima e
   * por cima da hotbar, nas duas pontas.
   *
   * O segundo motivo era pior e está logo abaixo, no `#modal-body`.
   * ======================================================================= */
  max-height: min(92vh, calc(100vh - 200px));
  display: flex;
  flex-direction: column;
  position: relative;
  /*
   * Sem enchimento lateral: a folga já está DENTRO da borda — a arte tem um
   * vazio transparente entre a faixa pintada e o vão, e ele encolheu junto.
   */
  padding: 0 2px 2px;
  /* =======================================================================
   * O FUNDO É DO PRÓPRIO ELEMENTO, e não de um `::before`
   *
   * Era um pseudo-elemento com `inset` negativo — ele precisava se esticar para
   * DEBAIXO da moldura, senão aparecia o mapa do jogo numa fresta entre os
   * dois. E era exatamente isso que obrigava a segunda cópia da moldura: um
   * descendente posicionado por cima da borda a tapa, porque em CSS a borda de
   * um elemento é pintada ANTES de qualquer descendente.
   *
   * O fundo do próprio elemento não tem esse problema — ele é pintado na ordem
   * certa, ANTES da borda, e por baixo dela até a beirada da caixa de borda.
   * Sem fresta, sem pseudo-elemento, e sem precisar da segunda cópia.
   *
   * E ele é discreto de propósito: a arte por baixo de um véu quase opaco. O
   * salão pintado competia com a lista de membros, que é o que a janela existe
   * para mostrar.
   * ======================================================================= */
  background-color: #090d0f;
  background-image:
    linear-gradient(#070b0ce6, #070b0cf2),
    var(--guilda-fundo);
  background-size: cover, cover;
  background-position: center, center;
  background-repeat: no-repeat, no-repeat;
  box-shadow: inset 0 0 0 1px #8a6f4222;
  border-style: solid;
  border-width: var(--moldura-t) var(--moldura-r) var(--moldura-b) var(--moldura-l);
  border-image-source: var(--guilda-moldura);
  border-image-slice: var(--moldura-fatia);
  border-image-repeat: stretch;
}

/* =========================================================================
 * O SALÃO PINTADO E A SEGUNDA CÓPIA DA MOLDURA SAÍRAM DAQUI
 *
 * Eram duas regras que só existiam uma por causa da outra:
 *
 *   `::before`  o salão — luz de cima, dois estandartes e a pedra, em degradês.
 *               Ele tinha `inset` NEGATIVO, para se esticar por debaixo da
 *               moldura; sem isso aparecia o mapa do jogo numa fresta entre o
 *               fundo e o trilho.
 *
 *   `::after`   a moldura desenhada uma segunda vez, por cima de tudo. Ela era
 *               obrigatória enquanto o `::before` existisse: em CSS a borda de
 *               um elemento é pintada ANTES de qualquer descendente, e o
 *               `::before`, estando por cima da borda, tapava os ornamentos
 *               dos cantos. Nenhum `z-index` conserta isso.
 *
 * Tirando o salão, a razão da segunda cópia foi junto. O fundo passou a ser o
 * do próprio elemento (ver `.modal-box.guilda`), que é pintado na ordem certa —
 * antes da borda — e chega até a beirada da caixa de borda sem fresta nenhuma.
 *
 * O cabeçalho continua por cima da moldura, e continua certo: ele é
 * transparente (`background: none`), e o que ele tem de opaco são as pastilhas
 * dos botões, que ficam SOBRE a faixa de pedra de propósito.
 * ========================================================================= */

/* =========================================================================
 * O CABEÇALHO: A PLACA DO TÍTULO
 *
 * Mesma geometria da arena (a placa da arte vai de y 14 a 65 da faixa de 66px),
 * cor diferente: ouro velho em vez de brasa. Sem partículas — as da arena são a
 * assinatura DELA, e repeti-las aqui faria as duas janelas virarem a mesma.
 *
 * O brilho é um só `text-shadow` respirando devagar (5,5s). Devagar de
 * propósito: um salão não pulsa.
 * ========================================================================= */
/* =========================================================================
 * O CABEÇALHO COBRE A JANELA INTEIRA, e não só o miolo
 *
 * "os botões minha guilda, servidor, pedidos, interrogação e x têm que ser mais
 *  pra baixo e bem mais pra direita, e o botão da esquerda que tem o nome da
 *  guilda também tem que ser mais pra baixo."
 *
 * Ele tem razão, e a causa era esta linha. `left: 0` de um filho absoluto é a
 * caixa de PREENCHIMENTO — ou seja, já 81px para dentro, do outro lado da
 * filigrana do canto. Os botões nasciam presos a essa borda invisível e
 * sobrava um palmo de trilho vazio à direita deles, que é o que ele viu.
 *
 * Com os `-1 *` abaixo o cabeçalho passa a cobrir a caixa de BORDA — a janela
 * inteira, moldura incluída. Aí `right: 92px` é uma medida da ARTE (a filigrana
 * do canto tem 81px, mais uma folga de 11), e não um resto de outra conta.
 * ========================================================================= */
/* =========================================================================
 * O CABEÇALHO: UMA LINHA, DENTRO DA ÁREA ÚTIL
 *
 * "as abas estão sobrepondo o título e o pill + botões estão em cima da
 *  filigrana da moldura. Deixe abas à esquerda e ? + X à direita, numa linha
 *  só, dentro da área útil, sem encostar na filigrana."
 *
 * ---- POR QUE ELE SOBREPUNHA ----
 *
 * Ele era ABSOLUTO e cobria a caixa de BORDA — a janela inteira, moldura
 * incluída —, e dentro dele cada peça era absoluta também, presa a uma
 * distância em pixels medida na filigrana antiga de 81px. O título ficava
 * centrado na janela toda e as abas, vindas da direita, passavam por cima dele:
 * na "Minha guilda" sobrava "GUI". Com a moldura a 37px, as mesmas distâncias
 * jogaram tudo em cima do ornamento.
 *
 * ---- O QUE ELE E' AGORA ----
 *
 * Um `flex` no FLUXO, dentro da caixa de preenchimento. Nada é absoluto, então
 * nada pode se sobrepor: as abas empurram, o `?` e o X são empurrados para a
 * direita por uma margem automática, e o que não couber quebra em vez de
 * montar por cima. Fica dentro da área útil por construção, e não por um
 * número que alguém acertou no olho.
 *
 * O título e o pill saíram (ver `desenharPaginas` e a nota em `renderGuildas`).
 * Eles continuam no DOM — quem os monta é o `openModal`, que serve a trinta
 * janelas — e são escondidos aqui.
 * ========================================================================= */
/* =========================================================================
 * ---- ELE VOLTOU PARA A FAIXA DE PEDRA ----
 *
 * "as abas + ? + X ficam numa linha DENTRO do conteúdo, e sobra uma faixa vazia
 *  na parte de cima da moldura. Suba essa linha para a faixa superior da
 *  moldura, centralizada na vertical, sem encostar nos ornamentos dos cantos."
 *
 * Ele chegou a ser absoluto, e virou estático para parar de se sobrepor ao
 * título. O título saiu; o problema de sobreposição foi com ele. O que sobrou
 * de ruim foi o custo: a faixa de pedra do topo — que é ilustração — ficava
 * vazia, e a linha de abas comia 38px do conteúdo logo abaixo dela.
 *
 * Agora ele é absoluto DE NOVO, mas sem o que o quebrava antes: nada aqui
 * dentro é posicionado por pixel. É um `flex` com `align-items: center`, então
 * a linha se centra sozinha na faixa, seja ela de 40px ou de 26 no celular.
 *
 * O enchimento lateral é a MEDIDA DO ORNAMENTO mais uma folga: `--moldura-l` é
 * exatamente a largura da filigrana do canto, e somar 7px é o que garante que
 * nenhum botão encoste nela. Escrito assim, ele acompanha a moldura sozinho
 * quando ela encolhe.
 * ========================================================================= */
.modal-box.guilda > header {
  position: absolute; z-index: 6;
  top: calc(var(--moldura-t) * -1);
  left: calc(var(--moldura-l) * -1);
  right: calc(var(--moldura-r) * -1);
  height: var(--moldura-t);
  display: flex; align-items: center; gap: 6px;
  min-height: 0; margin: 0; border: none; background: none;
  padding: 0 calc(var(--moldura-r) + 7px) 0 calc(var(--moldura-l) + 7px);
  /*
   * A faixa inteira deixa o clique passar; só os botões o recebem. Sem isto, um
   * retângulo invisível do tamanho da janela ficaria por cima da moldura.
   */
  pointer-events: none;
}
.modal-box.guilda > header > * { pointer-events: auto; }
.modal-box.guilda > header #modal-title,
.modal-box.guilda > header #modal-selo { display: none; }

/*
 * As abas ocupam a linha e empurram o resto. `flex-wrap` é o que garante o
 * "sem encostar na filigrana" numa janela estreita: as abas descem para uma
 * segunda linha em vez de espremerem o `?` e o X contra a borda.
 */
.modal-box.guilda > header #modal-acoes {
  position: static;
  flex: 1 1 auto; min-width: 0;
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px;
}
/*
 * ---- O GRUPO DE ÍCONES VAI PARA A DIREITA, COLADO NO X ----
 *
 * A regra era `.guilda-acao.so-icone { margin-left: auto }`, em cada ícone. Com
 * UM ícone ela fazia o certo; com dois, não: num flex, cada margem automática
 * fica com uma parte da sobra, então o primeiro ícone parava no MEIO da barra e
 * o segundo na ponta. Era isso que deixava o histórico solto no meio.
 *
 * Agora quem tem a margem é a caixa que embrulha os dois (`.guilda-acoes-canto`,
 * ver `cabecaDaJanela`): uma margem, uma sobra, e o grupo inteiro encosta no X —
 * na ordem [histórico] [?] [X], com o mesmo tamanho e o mesmo alinhamento.
 */
.modal-box.guilda > header #modal-acoes > .guilda-acoes-canto {
  margin-left: auto;
  display: inline-flex; align-items: center; gap: 6px; flex: none;
}

.modal-box.guilda > header #modal-close {
  position: static; flex: none;
  margin: 0;
  width: 28px; height: 28px; padding: 0;
  display: grid; place-content: center;
  border: 1px solid var(--guilda-ouro-fraco); border-radius: 50%;
  background: #0b0f11e6;
  box-shadow: 0 0 0 1px #0a0d0f99, 0 2px 10px #000a;
  color: #e8d9b4; font-size: 16px; line-height: 1;
  transition: background .12s ease, color .12s ease, border-color .12s ease;
}
.modal-box.guilda > header #modal-close:hover {
  background: #2a2013; color: #fff3d6; border-color: #d8b471;
}

/* ---- Os botões de página, irmãos dos da arena ---- */
.guilda-acao {
  position: relative;
  display: inline-flex; align-items: center; gap: 6px;
  height: 28px; padding: 0 11px;
  border: 1px solid var(--guilda-ouro-fraco); border-radius: 14px;
  background: #0b0f11e6;
  box-shadow: 0 0 0 1px #0a0d0f99, 0 2px 10px #000a;
  color: #e8d9b4;
  font-family: var(--font-title); font-size: 11px; letter-spacing: .05em;
  cursor: pointer;
  transition: background .12s ease, color .12s ease, border-color .12s ease;
}
.guilda-acao:hover { background: #2a2013; color: #fff3d6; border-color: #d8b471; }
.guilda-acao.ligado { background: #3a2c14; border-color: var(--guilda-ouro); color: #ffe9bd; }
.guilda-acao.so-icone { width: 28px; padding: 0; justify-content: center; font-size: 15px; }
/*
 * O "Voltar" e' irmao das abas e mora na mesma fileira, mas nao e' uma delas:
 * ele SAI da tela em vez de trocar de pagina. A cor mais apagada e a margem
 * separam os dois gestos sem precisar de um risco no meio.
 */
.guilda-acao.voltar { color: #9aa7ae; margin-right: 8px; }
.guilda-acao.voltar:hover { color: #ffd98a; }
/*
 * A bolha do contador fica FORA da borda, no canto de cima.
 *
 * Dentro do botão ela empurraria a palavra e o botão mudaria de largura quando
 * chegasse um pedido — a fileira inteira andaria de lugar sozinha, e o jogador
 * erraria o clique.
 */
.guilda-conta-bolha {
  position: absolute; top: -5px; right: -5px;
  min-width: 16px; height: 16px; padding: 0 4px;
  display: grid; place-content: center;
  border-radius: 8px;
  background: #b4442f; border: 1px solid #0a0d0f;
  color: #fff; font-size: 10px; font-style: normal; font-weight: 700;
  box-shadow: 0 1px 4px #000b;
}

/* =========================================================================
 * O CORPO — e o `min-height: 0` que fazia a janela estourar
 *
 * Ele tinha `overflow-y: auto` e mesmo assim não rolava: a janela inteira é que
 * crescia, passando do `max-height` e subindo por cima do menu do jogo.
 *
 * A causa é uma regra do flexbox que quase sempre pega: num container flex, o
 * `min-height` de um item vale `auto`, e `auto` quer dizer "não encolha abaixo
 * do meu conteúdo". Um item que não encolhe nunca fica menor que o conteúdo, e
 * um item que nunca fica menor que o conteúdo NUNCA ROLA — ele empurra o
 * container, e é o container que estoura.
 *
 * `min-height: 0` desfaz isso. Aí o corpo aceita ser menor que o conteúdo, o
 * `overflow-y: auto` finalmente tem o que rolar, e a rolagem fica no CONTEÚDO —
 * que é onde ela devia estar — em vez de a janela crescer.
 * ========================================================================= */
.modal-box.guilda #modal-body {
  position: relative; z-index: 1;
  flex: 1 1 auto; min-height: 0;
  padding: 2px 2px 4px;
  overflow-y: auto; overflow-x: hidden;
  display: flex; flex-direction: column; gap: 10px;
}

/* =========================================================================
 * O DESENHO DO BRASÃO SAIU DESTE ARQUIVO
 *
 * As regras do escudo (`.guilda-brasao`, `.gb-escudo`, `.gb-simbolo`,
 * `.gb-letras`) foram para `packages/shared/src/desenhar-brasao.mjs`, que as
 * injeta num `<style>` na primeira vez que alguém desenha um brasão.
 *
 * ---- POR QUE SAIU ----
 *
 * O SITE desenha o mesmo escudo — na tabela do ranking, na lista de quem está
 * online e na página do personagem. E o site carrega `site.css`, não este
 * arquivo: manter as regras aqui obrigaria a uma segunda cópia lá, e duas
 * cópias de um desenho são duas cópias que um dia discordam. O brasão no jogo e
 * o brasão no site passariam a ser desenhos diferentes da mesma guilda.
 *
 * ---- POR QUE NUM MÓDULO E NÃO NUM .css NOVO ----
 *
 * Um arquivo novo teria de entrar na lista do `publicar.sh` e ser ligado por
 * `index.html` e por cada página do site — quatro lugares para esquecer um.
 * `packages/` já vai inteiro no deploy, e quem importa o desenho leva o estilo
 * junto, por construção.
 *
 * O CRIADOR (as prateleiras, as rodas, as réguas) continua aqui embaixo: ele é
 * do jogo, e o site não tem tela de criar guilda.
 * ========================================================================= */

/* =========================================================================
 * O CRIADOR DE BRASÃO
 *
 * Ele não mora na aba de Guildas: a aba mostra a tabela do servidor, e deixar
 * as grades de forma e símbolo abertas ali enchia a tela de botões para quem
 * só queria ver quais guildas existem. Ele mora na página de criar e na caixa
 * de trocar, que é a mesma peça nas duas.
 *
 * Quatro colunas lado a lado, e NADA rola: a prévia, a forma com as camadas,
 * os símbolos e as duas rodas de cor, todos à vista ao mesmo tempo.
 * ========================================================================= */
/*
 * Mais larga do que era: dentro dela mora o MESMO criador de quatro colunas da
 * página de criar, e numa caixa de 680px as colunas quebravam duas a duas e a
 * caixa voltava a rolar — que é justamente o que se tirou.
 */
.brasao-caixa {
  width: min(96vw, 880px);
  max-width: none;
  max-height: min(88vh, 720px);
  display: flex; flex-direction: column;
  gap: 10px;
}
/*
 * Aqui a rolagem PODE existir, e a da página de criar não: lá a janela do jogo
 * dá a altura toda, e aqui a caixa vive dentro dela. Numa tela baixa as quatro
 * colunas não cabem de jeito nenhum — e rolar é melhor do que cortar o botão
 * de confirmar para fora da caixa.
 */
.brasao-caixa > .brasao-criador { overflow: auto; min-height: 0; }
.brasao-caixa > .confirm-actions { flex: none; }

/* A coluna da esquerda e a prévia moram na seção da PÁGINA, mais abaixo. */

.brasao-conta { display: grid; gap: 3px; }
/* =========================================================================
 * O CUSTO TOTAL, A DUPLA DE BOTÕES E OS DOIS AVISOS DO PALCO
 * ========================================================================= */
/*
 * O total é sempre a última linha, e por isso ele se separa das parcelas por um
 * risco: sem ele, "Efeito Ouro 50" e "Custo 50" seriam duas linhas iguais, e a
 * segunda pareceria uma repetição em vez de uma soma.
 */
.brasao-conta-total.sem-custo { color: #8f9aa0; border-top-color: #ffffff0f; }
.brasao-conta-total.sem-custo span { font-family: inherit; font-size: 11px; letter-spacing: 0; }

/*
 * O aviso de contraste fica colado no escudo de 28 pixels: é ali que o problema
 * existe. Âmbar e não vermelho — um escudo de uma cor só é uma escolha legítima,
 * e isto é um aviso, não uma recusa.
 */
.brasao-aviso {
  margin: -4px 0 0;
  font-size: 10px; line-height: 1.3; color: #ffd98a;
}
.brasao-aviso.escondido { display: none; }

/* ---- o veredito do nome ---- */
/*
 * Ele mora entre o campo e a linha de ajuda, e muda de cor com a resposta: o
 * texto diz o quê, a cor diz se é bom ou ruim sem precisar ser lido.
 */
.brasao-veredito {
  font-style: normal; font-size: 10.5px; line-height: 1.3;
}
.brasao-veredito.escondido { display: none; }
.brasao-veredito.bom { color: #7ee0a0; }
.brasao-veredito.ruim { color: #e4867f; }

/*
 * Os dois botões discretos, lado a lado. Eles fazem coisas opostas (um sorteia,
 * o outro apaga) e por isso dividem a linha em partes iguais, sem um parecer o
 * principal.
 */
.brasao-dupla { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.brasao-conta-linha {
  display: flex; align-items: center; gap: 6px; justify-content: space-between;
  font-size: 11px; color: var(--muted);
}
.brasao-conta-total {
  display: flex; align-items: center; justify-content: space-between;
  padding-top: 5px; border-top: 1px solid #ffffff14;
  font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: #cbb98f;
}
.brasao-coin {
  display: inline-flex; align-items: center; gap: 3px;
  color: #ffd98a; font-weight: 700; font-size: 11px; white-space: nowrap;
}
.brasao-coin img { display: block; }

/* ---- a coluna da direita: as prateleiras ---- */
.brasao-titulo {
  display: flex; align-items: center; gap: 5px;
  margin: 0; font-size: 10px; letter-spacing: .13em; text-transform: uppercase;
  color: #8f9aa0; font-weight: 700;
}
/*
 * O alvo do balão da seção. Pequeno DE PROPÓSITO: no título, que ocupa a
 * largura inteira e encosta na grade, o balão nascia por cima das opções e o
 * mouse quase nunca saía do dono — parecia travado. Ver `marcaDeDica`.
 */
.brasao-dica-marca {
  flex: none;
  display: grid; place-items: center;
  width: 13px; height: 13px;
  border: 1px solid #ffffff2b; border-radius: 50%;
  background: #0d1416;
  color: #8f9aa0; font-size: 9px; font-style: normal; font-weight: 700;
  letter-spacing: 0; line-height: 1; cursor: help;
  transition: color .12s, border-color .12s;
}
.brasao-dica-marca:hover { color: #e8dcbe; border-color: #e0a84a66; }

/* O bloco de Camadas/Iniciais quando ele mora no palco, e não numa coluna. */
/* No palco a coluna e' estreita: a roda encolhe junto para caber sem rolagem. */

/* =========================================================================
 * AS GRADES
 *
 * "aba Forma: grade de 6 colunas. Aba Símbolo: grade de 8 colunas com rótulos
 *  pequenos separando."
 *
 * Grade de verdade (`grid-template-columns`) e não uma fileira que quebra
 * sozinha, e a razão é o gesto: com quarenta amostras iguais, o que se faz aqui
 * é VARRER. Varrer exige colunas alinhadas — numa fileira que quebra, o número
 * de colunas muda com a largura da janela e a mesma forma nunca está no mesmo
 * lugar duas vezes.
 *
 * `1fr` e não a largura do botão: as colunas dividem a linha inteira e a grade
 * fica encostada nas duas beiradas, em vez de deixar uma sobra à direita que
 * parece erro. O botão continua com o tamanho dele, centrado na célula.
 *
 * A grade dos EFEITOS (`.cores`) continua flex: são oito, todos diferentes, e
 * eles se leem um por um e não em varredura.
 * ========================================================================= */
.brasao-grade { display: flex; flex-wrap: wrap; gap: 6px; align-content: flex-start; }
.brasao-grade.seis,
.brasao-grade.oito {
  display: grid; gap: 6px; justify-items: center;
}
.brasao-grade.seis { grid-template-columns: repeat(6, 1fr); }
.brasao-grade.oito { grid-template-columns: repeat(8, 1fr); }

/*
 * O botão é um QUADRO com a arte dentro, e não a arte solta: sem a moldura, as
 * silhuetas brancas sobre o fundo escuro da janela pareciam recortes soltos, e
 * não dava para ver qual estava escolhida.
 */
/* 40x44 e não 46x50: numa coluna estreita a diferença é caber três por fila. */
.brasao-opcao {
  flex: none; width: 40px; height: 44px; padding: 0;
  display: grid; place-items: center;
  border: 1px solid #ffffff1a; border-radius: 6px;
  background: linear-gradient(180deg, #16201f, #0c1213);
  cursor: pointer; color: #7f8c92; font-size: 16px; line-height: 1;
  transition: border-color .12s, background .12s, transform .12s;
}
.brasao-opcao:hover {
  border-color: #e0a84a66; background: linear-gradient(180deg, #1e2b2a, #101819);
  transform: translateY(-1px);
}
.brasao-opcao.ligado {
  border-color: #e0a84a;
  background: linear-gradient(180deg, #27352f, #131c1b);
  box-shadow: 0 0 0 1px #e0a84a4d inset, 0 0 10px #e0a84a26;
}
.brasao-opcao.ligado .brasao-amostra { background: #ffeec2; }

/*
 * A amostra é a PRÓPRIA arte, em máscara, pintada de creme. Em máscara ela usa
 * exatamente o mesmo caminho de desenho do escudo de verdade — um arquivo que
 * falhar falha nos dois lugares, e não só num.
 */
.brasao-amostra {
  display: block; width: 26px; height: 30px;
  background: #cfc4a8;
  -webkit-mask-image: var(--amostra); mask-image: var(--amostra);
  -webkit-mask-size: contain; mask-size: contain;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center; mask-position: center;
  transition: background .12s;
}
.brasao-amostra.simbolo { width: 28px; height: 28px; }

/* O separador de grupo: linha inteira, para quebrar a grade em três blocos. */
/*
 * `flex: 1 0 100%` servia à fileira; `grid-column: 1 / -1` serve à grade. As
 * duas declarações ficam, e cada arranjo ignora a do outro — sem isto o rótulo
 * "Animais" viraria uma célula de oito, no meio dos bichos.
 */
.brasao-grupo {
  flex: 1 0 100%; grid-column: 1 / -1; justify-self: stretch;
  padding: 6px 2px 1px;
  font-size: 9px; letter-spacing: .13em; text-transform: uppercase; color: #6d7a80;
}
.brasao-grupo:first-child { padding-top: 0; }

/* =========================================================================
 * A RODA DE COR
 *
 * "faça ele negócio RGB, que a pessoa anda com o mouse e escolhe qualquer cor
 *  (...) seria uma bola com as cores RGB e aí a pessoa vai mexendo."
 *
 * O desenho tem de dar A MESMA cor que a conta do `guildas.mjs` dá, senão o que
 * se aponta não é o que se leva. E dá, exatamente:
 *
 *   o `conic-gradient` põe o matiz no ângulo, começando no topo e andando no
 *   sentido do relógio — o mesmo referencial do `atan2(dx, -dy)` de lá;
 *
 *   o branco radial por cima vai de alfa 1 no centro a alfa 0 na beirada, e a
 *   mistura de branco com a cor pura por alfa É a definição de saturação em
 *   HSV com valor 1. Não é uma aproximação: é a fórmula.
 *
 * O `--escuro` é `1 - v`: uma camada preta por cima, que é o valor de HSV.
 * ========================================================================= */
/* =========================================================================
 * O PRATO: a roda e os controles dela, LADO A LADO
 *
 * Eram empilhados (roda, barra de brilho, leitura), e empilhados três vezes —
 * uma por peça pintada. Com uma roda só, a altura que sobrou serve melhor
 * deitada: a barra e o nome da cor ficam à direita da roda, na altura dos olhos
 * de quem está arrastando, em vez de embaixo, onde a mão os cobre.
 * ========================================================================= */
.brasao-prato {
  display: flex; align-items: center; gap: 14px;
  min-width: 0;
}
.brasao-roda-lado { flex: 1 1 0; min-width: 0; display: grid; gap: 0; }

.brasao-roda {
  position: relative;
  flex: none;
  width: 112px; height: 112px;
  border-radius: 50%;
  cursor: crosshair;
  /* Sem isto o navegador rola a página em vez de deixar o dedo escolher a cor. */
  touch-action: none;
  background:
    radial-gradient(circle closest-side, #ffffff 0%, #ffffff00 100%),
    conic-gradient(
      #ff0000 0deg, #ffff00 60deg, #00ff00 120deg,
      #00ffff 180deg, #0000ff 240deg, #ff00ff 300deg, #ff0000 360deg
    );
  box-shadow: 0 0 0 1px #ffffff2b, 0 3px 10px #00000073;
  transition: opacity .15s;
}
.brasao-roda::after {
  content: ''; position: absolute; inset: 0; border-radius: 50%;
  background: #000; opacity: var(--escuro, 0);
  pointer-events: none;
}
/* Com um efeito escolhido a roda não é o que está valendo, e ela diz isso. */
.brasao-roda.dormindo { opacity: .42; }

.brasao-roda-marca {
  position: absolute; width: 12px; height: 12px; border-radius: 50%;
  transform: translate(-50%, -50%);
  border: 2px solid #fff;
  box-shadow: 0 0 0 1px #000000a6, 0 1px 4px #000000a6;
  pointer-events: none;
  z-index: 1;
}

/* ---- a barra do brilho ---- */
.brasao-brilho {
  -webkit-appearance: none; appearance: none;
  display: block; width: 100%; height: 13px;
  margin: 9px 0 0; padding: 0;
  border: 1px solid #ffffff24; border-radius: 7px;
  background: linear-gradient(90deg, #000, var(--ponta, #fff));
  cursor: pointer;
}
.brasao-brilho::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 11px; height: 17px; border-radius: 3px;
  background: #fff3d6; border: 1px solid #000000a6;
  box-shadow: 0 1px 3px #000000a6;
}
.brasao-brilho::-moz-range-thumb {
  width: 11px; height: 17px; border-radius: 3px;
  background: #fff3d6; border: 1px solid #000000a6;
}

/*
 * Os ajustes e a roda das iniciais somem quando não há iniciais. Não é uma
 * opção escondida — é uma pergunta que deixou de existir, e deixá-la na tela
 * seria oferecer o tamanho de uma letra que ninguém vai ver.
 */
.brasao-sub.escondido { display: none; }

/* =========================================================================
 * OS AJUSTES DAS LETRAS
 *
 * "a pessoa pode escolher até 3 letras (...) e pode reposicionar essas letras
 *  e aumentar ou diminuir a fonte (sem quebrar, com limite)."
 *
 * Três réguas e um campo de três caracteres. A régua é o controle certo para o
 * "com limite": ela não tem como devolver um valor fora da faixa, e a faixa
 * está escrita no `min`/`max` que vêm do catálogo — um lugar só para o limite,
 * e não um aqui e outro lá.
 * ========================================================================= */
/* =========================================================================
 * AS LINHAS DE RÉGUA — e o rótulo que quebrava em duas
 *
 * "labels das réguas com largura fixa suficiente: nenhuma quebra em duas linhas
 *  (vale para todas as abas)."
 *
 * Quebravam: "TAMANH O", "HORIZON TAL". A coluna do rótulo tinha 62px e a
 * palavra mais longa, em caixa alta com `letter-spacing: .08em`, mede 78 — então
 * ela partia no meio, e a régua da linha seguinte subia junto.
 *
 * Duas mudanças, e as duas são necessárias: a coluna passou a 86px (a medida da
 * palavra mais longa mais folga) e o rótulo ganhou `white-space: nowrap`. A
 * largura sozinha resolveria hoje e voltaria a quebrar no dia em que alguém
 * escrevesse um rótulo mais comprido; o `nowrap` garante que, nesse dia, a
 * régua encolhe em vez de a palavra partir.
 * ========================================================================= */
.brasao-sub { display: grid; gap: 7px; min-width: 0; }
.brasao-linha {
  display: grid; grid-template-columns: 86px minmax(0, 1fr);
  align-items: center; gap: 8px;
}
.brasao-linha > span {
  font-size: 10px; letter-spacing: .08em; text-transform: uppercase;
  color: #8f9aa0; font-weight: 700;
  white-space: nowrap;
}
.guilda-campo.brasao-letras-campo {
  width: 100%; padding: 5px 7px;
  font-family: var(--font-title); font-size: 13px;
  letter-spacing: .12em; text-align: center; text-transform: uppercase;
}
/*
 * A régua é a mesma peça da barra de brilho, sem o degradê de cor: ali a barra
 * MOSTRA o que se escolhe, aqui ela só mede. Um trilho neutro para não sugerir
 * que a posição da letra tem cor.
 */
.brasao-regua {
  -webkit-appearance: none; appearance: none;
  display: block; width: 100%; height: 11px; margin: 0; padding: 0;
  border: 1px solid #ffffff1f; border-radius: 6px;
  background: linear-gradient(90deg, #131c1e, #2c3c40);
  cursor: pointer;
}
.brasao-regua::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 10px; height: 15px; border-radius: 3px;
  background: #e0c88a; border: 1px solid #000000a6;
  box-shadow: 0 1px 3px #000000a6;
}
.brasao-regua::-moz-range-thumb {
  width: 10px; height: 15px; border-radius: 3px;
  background: #e0c88a; border: 1px solid #000000a6;
}
.brasao-sub .brasao-chave { flex: none; justify-self: start; padding: 5px 10px; }
.brasao-sub .brasao-par .brasao-chave { flex: 1 1 0; justify-self: auto; }

/* ---- o que a roda deu, escrito ---- */
.brasao-hex {
  display: flex; align-items: center; gap: 6px;
  margin-top: 9px; font-size: 10.5px; color: var(--muted);
}
.brasao-hex-cor {
  flex: none; width: 15px; height: 15px; border-radius: 4px;
  border: 1px solid #ffffff2e;
}
.brasao-hex b {
  font-family: ui-monospace, Consolas, monospace;
  font-size: 10.5px; letter-spacing: .04em; color: #e8dcbe;
}

/* ---- os efeitos, embaixo da roda ---- */
.brasao-cor {
  position: relative; flex: none;
  width: 32px; height: 32px; padding: 0;
  border: 1px solid #ffffff26; border-radius: 6px;
  background: var(--amostra-cor); cursor: pointer;
  transition: transform .12s, border-color .12s, box-shadow .12s;
}
.brasao-cor.paga { box-shadow: 0 0 7px var(--brasao-brilho, transparent); }
.brasao-cor:hover { transform: translateY(-2px); border-color: #ffffff66; }
.brasao-cor.ligado {
  border-color: #fff3d6;
  box-shadow: 0 0 0 2px #e0a84a, 0 0 12px #e0a84a4d;
}
.brasao-cor.anima { background-size: 300% 100%; animation: brasao-fogo-liso 5s linear infinite; }
.brasao-grade.cores { margin-top: 9px; gap: 7px; }
.brasao-cor .brasao-coin {
  position: absolute; right: -4px; bottom: -6px;
  padding: 0 3px; border-radius: 6px;
  background: #0b1012f0; border: 1px solid #ffffff24;
  font-size: 9px;
}
.brasao-cor .brasao-coin img { width: 9px; height: 9px; }
/* O efeito já pago perde o selo e ganha um ponto — ele não custa mais nada. */
.brasao-cor.tenho::after {
  content: ''; position: absolute; right: 3px; top: 3px;
  width: 5px; height: 5px; border-radius: 50%;
  background: #7ee0a0; box-shadow: 0 0 4px #7ee0a0cc;
}

/* =========================================================================
 * OS PARES DE ESCOLHA (a ordem das camadas, as iniciais)
 *
 * "organiza pra nao ter toda essa escrita, pq ta poluindo a aba."
 *
 * Eram quatro botões de três linhas cada — um título em negrito e duas linhas
 * explicando —, doze linhas de prosa numa tela cujo assunto é um desenho. A
 * explicação foi inteira para o balão; o botão ficou com o nome.
 *
 * `1 1 0` e não `1 1 140px`: com base zero os dois botões do par dividem a
 * coluna ao meio e ficam do mesmo tamanho, em vez de o mais comprido empurrar
 * o outro para a linha de baixo.
 * ========================================================================= */
.brasao-par { display: flex; gap: 6px; flex-wrap: wrap; }
.brasao-chave {
  flex: 1 1 0; min-width: 58px;
  padding: 7px 8px;
  border: 1px solid #ffffff17; border-radius: 6px;
  background: #0d1416a8; color: var(--muted); cursor: pointer;
  font-size: 11px; text-align: center; line-height: 1.25;
  transition: border-color .12s, background .12s, color .12s;
}
.brasao-chave:hover { border-color: #e0a84a4d; color: #e8dcbe; }
.brasao-chave.ligado {
  border-color: #e0a84a99; background: #1b2729; color: #ffeec2;
}

/* =========================================================================
 * A PÁGINA DE CRIAR GUILDA
 *
 * O criador vive em dois lugares — nesta página e na caixa de trocar —, e é a
 * MESMA peça. O que muda é só a largura: aqui ele tem a janela inteira, ali
 * tem a caixa.
 * ========================================================================= */
.brasao-criador { display: grid; gap: 12px; min-width: 0; }

/* =========================================================================
 * DUAS COLUNAS: O PALCO E AS ABAS
 *
 * "layout em duas colunas. Esquerda (~260px, fixa) (...) SÓ ISSO nessa coluna.
 *  Direita: abas internas separadas. Tem que caber inteiro sem scroll em
 *  1920x1080."
 *
 * ---- O QUE ESTAVA ERRADO COM AS QUATRO COLUNAS ----
 *
 * Elas cumpriam o "não rola" — enquanto as escolhas eram poucas. Depois entraram
 * as réguas do símbolo, as das letras e a terceira roda de cor, e não há arranjo
 * lado a lado que caiba: quatro colunas parelhas são quatro colunas que crescem
 * todas juntas, e a mais alta define a altura da página.
 *
 * Com abas, a altura da direita é a da aba MAIS ALTA e não a soma delas — e é
 * isso que faz a conta fechar em 1080 mesmo com o contorno virando o quarto alvo
 * de pintura.
 *
 * ---- A ESQUERDA NÃO ENCOLHE, E A DIREITA NÃO VAZA ----
 *
 * `grid-template-columns: 260px minmax(0, 1fr)`. Os 260 são fixos porque a prévia
 * é a resposta à pergunta que a pessoa está fazendo — espremê-la para caber mais
 * prateleira seria espremer justamente a resposta.
 *
 * O `minmax(0, 1fr)` é o que impede a direita de estourar: o mínimo automático de
 * uma coluna de grade é o CONTEÚDO dela, e a grade de oito símbolos seria esse
 * piso. Com o zero explícito, ela encolhe e a grade se aperta dentro.
 * ========================================================================= */
.brasao-corpo {
  display: grid;
  grid-template-columns: 260px minmax(0, 1fr);
  gap: 16px;
  align-items: start;
  min-width: 0;
}
.brasao-lado { display: grid; gap: 12px; align-content: start; min-width: 0; }

.brasao-palco {
  display: grid; gap: 10px; align-content: start;
  padding: 14px 13px;
  border: 1px solid #8a6f4233;
  border-radius: 6px;
  background:
    radial-gradient(120% 90% at 50% 0%, #e0a84a14, transparent 60%),
    linear-gradient(180deg, #131a1cf0, #0b1012f7);
  box-shadow: inset 0 1px 0 #ffffff0d;
}
/* =========================================================================
 * A PRÉVIA GRANDE
 *
 * "prévia grande (~180px) sobre fundo escuro com brilho sutil."
 *
 * O fundo próprio, mais escuro que o palco, existe por uma razão de desenho e
 * não de enfeite: um escudo pintado de preto (o Vazio, a Ardósia) desaparecia
 * contra o palco, e um pintado de creme sumia contra o brilho. Um poço escuro
 * com um halo frio no meio dá contraste para os dois extremos.
 *
 * `cursor: grab` porque ela É um controle: o símbolo se arrasta aqui dentro.
 * ========================================================================= */
.brasao-previa {
  position: relative;
  display: grid; place-items: center;
  min-height: 186px;
  border-radius: 6px;
  border: 1px solid #ffffff10;
  background:
    radial-gradient(80% 70% at 50% 42%, #1a2b33, #0a0e10 70%),
    #080b0c;
  box-shadow: inset 0 0 26px #000000a6;
  /* Sem isto o navegador rola a página em vez de deixar o dedo mover o símbolo. */
  touch-action: none;
}
.brasao-previa:active { cursor: grabbing; }

/* =========================================================================
 * A LEGENDA DA PRÉVIA
 *
 * "e como faz pra aumentar o tamanho dos negócio pelo preview?"
 *
 * A pergunta É o defeito: arrastar já funcionava e não havia como saber. Um
 * controle que só existe no gesto é um controle que não existe para quem não
 * adivinha o gesto.
 *
 * Ela fica DENTRO da prévia, no pé, colada na coisa que descreve — e apagada, em
 * 9px: ela tem de ser encontrada por quem procura, e não competir com o escudo,
 * que é o assunto. Some sozinha quando não há peça para mover.
 *
 * `pointer-events: none` é o que impede a própria legenda de engolir o arrasto
 * que ela está ensinando — o ponteiro atravessa e chega na prévia.
 * ========================================================================= */
/*
 * ---- ELA SAIU DE DENTRO DO QUADRO ----
 *
 * "o texto 'arraste para mover...' está por cima da ponta do escudo."
 *
 * Estava: o quadro é um poço escuro com o escudo centralizado, e a ponta de baixo
 * do escudo desce justamente até onde a legenda estava. Duas coisas no mesmo
 * lugar, e a que importa é a de baixo.
 *
 * Fora do quadro ela não cobre nada, e continua colada na coisa que descreve.
 */
.brasao-previa-dica {
  margin: -3px 0 0;
  font-style: normal; font-size: 9px; letter-spacing: .04em;
  color: #7c888e; text-align: center; line-height: 1.3;
}
.brasao-previa-dica.escondido { display: none; }

/* =========================================================================
 * O MESMO BRASÃO A 28 PIXELS
 *
 * "o mesmo brasão em 28px embaixo (como aparece no chat)."
 *
 * É a única prévia que diz a verdade sobre o que quase todo mundo vai ver: o
 * escudo aparece grande nesta tela e em nenhum outro lugar do jogo. Um efeito
 * escolhido a 180px pode ser uma mancha a 28, e é melhor descobrir isso aqui do
 * que depois de pagar.
 * ========================================================================= */
.brasao-previa-mini {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 8px;
  border-radius: 5px;
  background: #0a0f10a8;
  border: 1px solid #ffffff0d;
}
.brasao-mini-escudo { flex: none; display: grid; place-items: center; width: 28px; }
.brasao-previa-mini > i {
  font-style: normal; font-size: 9.5px; letter-spacing: .06em;
  text-transform: uppercase; color: #6d7a80;
}

/* =========================================================================
 * AS ABAS INTERNAS
 *
 * Elas são as abas da JANELA vistas de perto: o mesmo ouro, a mesma pedra, e a
 * ativa com o fundo aceso. Inventar um segundo desenho de aba dentro de uma
 * janela que já tem abas faria a pessoa perguntar qual manda em qual.
 *
 * `flex: 1 1 0` nas quatro: elas dividem a largura em partes iguais, e "Símbolo"
 * (a mais comprida) não empurra as outras. Quatro caixas do mesmo tamanho também
 * dizem, sem texto, que são quatro passos do mesmo peso.
 * ========================================================================= */
.brasao-abas {
  display: flex; gap: 4px;
  padding-bottom: 8px;
  border-bottom: 1px solid #ffffff12;
}
.brasao-aba {
  flex: 1 1 0;
  padding: 7px 6px;
  border: 1px solid #ffffff14; border-radius: 6px 6px 0 0;
  border-bottom: none;
  background: #0d1416a8; color: var(--muted);
  font-family: var(--font-title); font-size: 11.5px; letter-spacing: .06em;
  cursor: pointer;
  transition: color .12s, background .12s, border-color .12s;
}
.brasao-aba:hover { color: #e8dcbe; border-color: #e0a84a4d; }
.brasao-aba.ligado {
  border-color: #e0a84a99; color: #ffeec2;
  background: linear-gradient(180deg, #23302d, #131c1b);
  box-shadow: inset 0 1px 0 #ffffff14;
}

/*
 * A página da aba, e o `min-height`: as quatro têm alturas diferentes, e sem um
 * piso a janela SALTA de tamanho a cada troca de aba — com o botão de fundar
 * subindo e descendo debaixo do mouse. Com o piso na mais alta, nada se move.
 */
.brasao-pagina {
  display: grid; gap: 11px; align-content: start;
  min-height: 322px; min-width: 0;
}
.brasao-pagina.escondido { display: none; }

/* ---- o campo de nome ---- */
.brasao-campo { display: grid; gap: 4px; }
.brasao-campo > span {
  font-size: 10px; letter-spacing: .13em; text-transform: uppercase;
  color: #8f9aa0; font-weight: 700;
}
.brasao-campo > i {
  font-style: normal; font-size: 10.5px; color: #78848a; line-height: 1.3;
}
/* =========================================================================
 * O AVISO DE CAPS LOCK
 *
 * "na hora da criação da guild não dá pra distinguir se tô com caps lock ligado
 *  ou não."
 *
 * Âmbar e não vermelho: não é um erro, é um estado — quem quer o nome em caixa
 * alta está fazendo o certo. O que ele impede é a pessoa descobrir depois, e o
 * nome de uma guilda não se troca.
 *
 * Ele fica ENTRE o campo e a linha de ajuda, colado no campo, porque é sobre o
 * que está sendo digitado agora.
 * ========================================================================= */
.brasao-campo > i.brasao-caps {
  display: flex; align-items: center; gap: 5px;
  padding: 3px 7px;
  border: 1px solid #e0a84a4d; border-radius: 4px;
  background: #2a210f80;
  color: #ffd98a; font-size: 10px; letter-spacing: .04em;
}
.brasao-campo > i.brasao-caps.escondido { display: none; }
/* =========================================================================
 * O CAMPO DO NOME — e por que ele NAO usa a fonte de titulo
 *
 * "ali onde aparece pra digitar o nome da guild não mostra a letra em maiúsculo
 *  ou minúsculo."
 *
 * Não mostrava mesmo, e a causa não era o Caps Lock: era a FONTE. `--font-title`
 * é a Cinzel Decorative, que não tem minúsculas de verdade — os códigos
 * minúsculos são desenhados como capitulares menores. Então "Guilda dos Reis" e
 * "GUILDA DOS REIS" apareciam iguais no campo e diferentes em todo o resto do
 * jogo, onde o nome é gravado exatamente como se digita e NÃO se troca depois.
 *
 * Um campo de digitação tem uma obrigação que um título não tem: mostrar o que
 * foi digitado. A fonte do corpo cumpre isso; a decorativa, não.
 *
 * O escudo continua com a decorativa — lá ela está certa, é desenho. A diferença
 * entre o campo e a prévia é a mesma diferença entre escrever e ver o resultado.
 * ========================================================================= */
.guilda-campo.brasao-campo-nome {
  width: 100%;
  font-family: inherit; font-size: 15px; letter-spacing: .02em;
  text-align: center;
  padding: 8px 10px;
}

.brasao-nome-previa {
  text-align: center; font-family: var(--font-title);
  font-size: 13px; color: #e8dcbe; letter-spacing: .04em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* =========================================================================
 * O SELETOR DE ALVO — o que a roda está pintando
 *
 * "em cima, seletor segmentado com o que está sendo pintado: Escudo · Contorno ·
 *  Símbolo · Iniciais. Cada opção mostra uma bolinha com a cor/efeito atual."
 *
 * A bolinha é a peça que substitui as três rodas visíveis. Ver três rodas ao
 * mesmo tempo dava uma coisa só de útil: saber de uma olhada que cor cada peça
 * tem. As quatro bolinhas dão isso em quarenta pixels de altura em vez de
 * quatrocentos — e dão para QUATRO peças, o que três rodas nunca deram.
 *
 * Ela é pintada com `background` e o valor vem do catálogo (`css`), então um
 * efeito aparece como o degradê que ele é, e não como um ponto de cor média.
 * ========================================================================= */
/* =========================================================================
 * DOIS POR TRES, E OS EIXOS SE LEEM
 *
 * "poder mudar o contorno do simbolo e das letras tambem."
 *
 * Era uma fileira de quatro: Escudo · Contorno · Simbolo · Iniciais, com aquele
 * "Contorno" sendo o do escudo — o unico que havia. Com tres contornos, uma
 * fileira de seis diria "Contorno", "Contorno" e "Contorno" ao lado de tres
 * nomes de peca, e ninguem saberia qual pertence a qual sem ler duas vezes.
 *
 * Em grade, a posicao responde: a coluna diz a PECA, a fileira diz se é a
 * pintura ou o contorno. O rotulo mora na primeira celula da fileira e nao num
 * titulo acima dela — assim ele fica NA linha dos tres botoes, e a leitura por
 * cruzamento funciona sem o olho subir.
 *
 * `66px` na primeira coluna e' a medida de "Contorno" mais o `ⓘ`; as outras tres
 * dividem o resto em partes iguais, e e' isso que alinha as colunas das duas
 * fileiras — sem alinhamento, a grade nao seria uma grade.
 * ========================================================================= */
.brasao-alvos {
  display: grid;
  grid-template-columns: 66px repeat(3, minmax(0, 1fr));
  gap: 5px;
  align-items: center;
}
.brasao-alvos-rotulo {
  display: flex; align-items: center; gap: 4px;
  font-size: 9px; letter-spacing: .1em; text-transform: uppercase;
  color: #6d7a80; font-weight: 700;
  white-space: nowrap;
}
.brasao-alvo {
  min-width: 0;
  display: flex; align-items: center; justify-content: center; gap: 6px;
  padding: 6px 7px;
  border: 1px solid #ffffff17; border-radius: 6px;
  background: #0d1416a8; color: var(--muted); cursor: pointer;
  transition: border-color .12s, background .12s, color .12s;
}
.brasao-alvo b {
  font-size: 10.5px; letter-spacing: .04em; font-weight: 700;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.brasao-alvo:hover:not(:disabled) { border-color: #e0a84a4d; color: #e8dcbe; }
.brasao-alvo.ligado {
  border-color: #e0a84a99; background: #1b2729; color: #ffeec2;
}
/*
 * "Símbolo = Nenhum ou Iniciais = Sem → alvo correspondente desabilitado."
 *
 * Apagado e NÃO escondido: um alvo que desaparece faz a tira mudar de largura e
 * os outros três pularem de lugar. Apagado, ele fica onde está e explica por que
 * não dá — a peça que ele pinta não existe ainda.
 */
.brasao-alvo:disabled { opacity: .38; cursor: not-allowed; }
.brasao-alvo-bolinha {
  flex: none; width: 15px; height: 15px; border-radius: 50%;
  border: 1px solid #00000080;
  box-shadow: 0 0 0 1px #ffffff2b;
}
/*
 * A bolinha VAZADA é o contorno desligado: a cor está escolhida, o brilho não
 * está aceso. Pintá-la cheia diria que o brasão tem um contorno daquela cor, o
 * que seria falso; deixá-la cinza apagaria a escolha que a pessoa fez.
 */
.brasao-alvo-bolinha.vazada {
  background-image: linear-gradient(135deg, transparent 43%, #0b1012 43% 57%, transparent 57%) !important;
  opacity: .55;
}

/* =========================================================================
 * AS FILEIRAS DE AJUSTE — grossura, "segue" e acabamento
 *
 * As três têm a MESMA grade da tira de alvos (`66px` de rótulo + o resto), e isso
 * é deliberado: elas aparecem logo abaixo dela, e a coluna do rótulo alinhada faz
 * o bloco inteiro se ler como uma tabela de propriedades em vez de três caixas
 * soltas.
 *
 * Elas SOMEM em vez de ficarem apagadas quando não servem — a grossura fora de um
 * contorno, o acabamento sobre um efeito pago. Uma fileira apagada convida a
 * procurar o que a destravaria, e não há nada.
 * ========================================================================= */
.brasao-contorno-linha,
.brasao-acabamento-linha {
  display: grid;
  grid-template-columns: 66px minmax(0, 1fr);
  gap: 6px;
  align-items: center;
  padding: 7px 9px;
  border: 1px solid #8a6f4233; border-radius: 6px;
  background: #0b1012a8;
}
.brasao-contorno-linha.escondido,
.brasao-acabamento-linha.escondido { display: none; }
.brasao-contorno-linha .brasao-par,
.brasao-acabamento-linha .brasao-par { flex: 0 0 auto; }
.brasao-contorno-linha .brasao-chave,
.brasao-acabamento-linha .brasao-chave { flex: 0 1 auto; min-width: 46px; }

/*
 * Cada tecla de acabamento mostra o MATERIAL na cor que está escolhida, numa tira
 * embaixo do nome. "Metálica" é uma palavra; a tira é a coisa — e ela muda junto
 * com a roda, então a comparação entre os três é direta, na cor certa.
 */
.brasao-acabamento-linha .brasao-chave::after {
  content: ''; display: block;
  height: 6px; margin-top: 5px;
  border-radius: 2px;
  background: var(--amostra-cor, #333);
  box-shadow: 0 0 0 1px #00000080;
}

/* =========================================================================
 * RECOMEÇAR
 *
 * "tem que ter um botão que reseta tudo com confirmação."
 *
 * Discreto de propósito — ele fica logo acima do botão de fundar, e os dois não
 * podem disputar o olho: um cria a guilda, o outro joga escolhas fora. Vermelho
 * apagado e não dourado, pela mesma razão.
 *
 * Apagado quando nada mudou, ele responde de graça a pergunta "eu mexi em algo?".
 * ========================================================================= */
/* =========================================================================
 * O "FUNDAR GUILDA" TAMBEM NAO SOBE
 *
 * Mesmo princípio da barra acima. O palco tem prévia, prévia pequena, nome, conta
 * e dois botões; numa janela baixa (ou dentro da caixa de trocar brasão, que é
 * mais curta) o botão que conclui a tela era o primeiro a sair de vista.
 *
 * `sticky` dentro da coluna: ele para no pé da área que rola enquanto o palco
 * estiver à vista, e volta ao lugar quando tudo cabe. O `padding-bottom` do palco
 * é o que impede o botão grudado de encostar na borda de baixo dele.
 * ========================================================================= */
.brasao-palco > .guilda-botao.primario {
  position: sticky; bottom: 0; z-index: 2;
}

.brasao-recomecar,
.brasao-aleatorio {
  justify-self: stretch;
  padding: 6px 8px;
  border: 1px solid #ffffff14; border-radius: 6px;
  background: #0d1416a8; color: #9aa7ae;
  font-size: 11px; letter-spacing: .04em; cursor: pointer;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  transition: color .12s, border-color .12s, background .12s;
}
/*
 * O hover os separa: o "Aleatório" acende em ouro (ele CRIA alguma coisa) e o
 * "Recomeçar" em vermelho apagado (ele apaga). Parados são iguais de propósito —
 * nenhum dos dois é o botão principal desta coluna.
 */
.brasao-aleatorio:hover:not(:disabled) {
  color: #ffd98a; border-color: #e0a84a4d; background: #17201f;
}
.brasao-recomecar:hover:not(:disabled) {
  color: #e4867f; border-color: #e4867f4d; background: #1d1516;
}
.brasao-recomecar:disabled,
.brasao-aleatorio:disabled { opacity: .4; cursor: default; }

/* =========================================================================
 * AS TECLAS DE FONTE
 *
 * "é possível ter opção pra escolher algumas fontes pro nome da guilda e nas
 *  iniciais? daria lag isso?"
 *
 * Não dá: as seis famílias ou já vêm carregadas em toda página (Cinzel e Cinzel
 * Decorative) ou são pilhas do sistema. Nenhuma baixa nada — ver `FONTES`, no
 * catálogo.
 *
 * Cada tecla escreve as INICIAIS DE VERDADE na própria fonte. O nome de uma fonte
 * não diz nada a quem não conhece fontes; a amostra responde a pergunta que a
 * pessoa está fazendo, que é "como vai ficar o meu escudo".
 * ========================================================================= */
.brasao-fonte-linha {
  display: grid;
  grid-template-columns: 66px minmax(0, 1fr);
  gap: 6px;
  align-items: center;
  padding: 7px 9px;
  border: 1px solid #8a6f4233; border-radius: 6px;
  background: #0b1012a8;
}
.brasao-fonte-linha.escondido { display: none; }
.brasao-fontes {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(58px, 1fr)); gap: 5px;
}
.brasao-fonte {
  display: grid; gap: 2px; justify-items: center;
  padding: 5px 4px;
  border: 1px solid #ffffff17; border-radius: 6px;
  background: #0d1416a8; color: var(--muted); cursor: pointer;
  transition: border-color .12s, background .12s, color .12s;
}
.brasao-fonte:hover { border-color: #e0a84a4d; color: #e8dcbe; }
.brasao-fonte.ligado { border-color: #e0a84a99; background: #1b2729; color: #ffeec2; }
.brasao-fonte-amostra {
  font-size: 16px; line-height: 1.1; color: #ffe1ad;
  /* A amostra pode vir de uma fonte larga; ela encolhe em vez de esticar a tecla. */
  max-width: 100%; overflow: hidden; white-space: nowrap;
}
.brasao-fonte > span {
  font-size: 8.5px; letter-spacing: .06em; text-transform: uppercase;
}

/* =========================================================================
 * AS DOZE CORES PRONTAS
 *
 * "~12 cores prontas."
 *
 * Uma fileira de quadrados sem rótulo: o nome de uma cor não ajuda a escolher
 * uma cor. Quem quer "aquele azul" aponta; quem quer o nome tem o balão.
 * ========================================================================= */
.brasao-prontas { display: flex; flex-wrap: wrap; gap: 5px; }
.brasao-pronta {
  flex: none; width: 26px; height: 26px; padding: 0;
  border: 1px solid #ffffff26; border-radius: 5px;
  cursor: pointer;
  transition: transform .12s, border-color .12s, box-shadow .12s;
}
.brasao-pronta:hover { transform: translateY(-2px); border-color: #ffffff66; }
.brasao-pronta.ligado {
  border-color: #fff3d6;
  box-shadow: 0 0 0 2px #e0a84a, 0 0 10px #e0a84a4d;
}

/* =========================================================================
 * A ENGRENAGEM DAS DUAS CORES
 *
 * "engrenagem dos efeitos de duas cores: fica aqui, aplicando no alvo
 *  selecionado. (Partido e companhia têm duas cores fixas.)"
 *
 * Ela não abre roda própria: clicar num dos dois lados passa a RODA DE CIMA a
 * pintar aquele lado, e o lado aceso diz qual. Uma segunda roda dentro de um
 * painel seria a quinta roda de uma tela que acabou de sair de três.
 *
 * Aparece só quando a peça selecionada está com um efeito de duas cores — uma
 * engrenagem sobre o Ouro (doze paradas de metal) seria um botão que não faz
 * nada.
 * ========================================================================= */
.brasao-engrenagem-caixa { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.brasao-engrenagem-caixa.escondido { display: none; }
/*
 * A mesma pastilha da outra engrenagem, pelo mesmo motivo: uma roda dentada de
 * treze pixels ao lado de oito amostras coloridas perde a disputa por atenção
 * todas as vezes.
 *
 * O aceno aqui cai bem por um motivo extra: ela NASCE escondida e aparece no
 * momento em que a pessoa escolhe um efeito de duas cores. O pulso acontece
 * justamente quando ela é novidade na tela.
 */
.brasao-engrenagem {
  flex: none;
  display: flex; align-items: center; gap: 5px;
  padding: 5px 11px 5px 9px;
  border: 1px solid #e0a84a99; border-radius: 13px;
  background: linear-gradient(180deg, #24312e, #131c1b);
  color: #ffd98a; cursor: pointer;
  box-shadow: 0 1px 0 #ffffff14 inset, 0 2px 8px #00000073;
  transition: color .12s, border-color .12s, background .12s, box-shadow .12s;
  animation: guilda-acena 2.2s ease-in-out 3;
}
.brasao-engrenagem b {
  font-family: var(--font-title); font-size: 10.5px; letter-spacing: .05em; line-height: 1;
}
.brasao-engrenagem-roda { font-size: 12px; line-height: 1; transition: transform .25s; }
.brasao-engrenagem:hover {
  color: #ffeec2; border-color: #ffd98a; background: linear-gradient(180deg, #2c3b37, #182220);
  box-shadow: 0 1px 0 #ffffff1f inset, 0 0 14px #e0a84a3d;
}
.brasao-engrenagem:hover .brasao-engrenagem-roda { transform: rotate(75deg); }
.brasao-engrenagem.ligado {
  color: #ffeec2; border-color: #ffd98a;
  background: linear-gradient(180deg, #32423d, #1b2624);
}
@media (prefers-reduced-motion: reduce) {
  .brasao-engrenagem { animation: none; }
}

.brasao-metades { display: flex; gap: 6px; flex-wrap: wrap; }
.brasao-metades.escondido { display: none; }
.brasao-metade {
  display: flex; align-items: center; gap: 6px;
  padding: 5px 9px;
  border: 1px solid #ffffff17; border-radius: 6px;
  background: #0d1416a8; color: var(--muted); cursor: pointer;
  transition: border-color .12s, background .12s, color .12s;
}
.brasao-metade b { font-size: 10.5px; letter-spacing: .04em; }
.brasao-metade:hover { border-color: #e0a84a4d; color: #e8dcbe; }
.brasao-metade.ligado { border-color: #e0a84a99; background: #1b2729; color: #ffeec2; }
.brasao-metade-bolinha {
  flex: none; width: 13px; height: 13px; border-radius: 3px;
  background: var(--amostra-cor, #333);
  border: 1px solid #00000080; box-shadow: 0 0 0 1px #ffffff2b;
}

/* =========================================================================
 * A CAIXA DE CONTRIBUIR COM OURO
 *
 * Ela é uma `.confirm-box` como as outras — o mesmo fundo, a mesma moldura, o
 * mesmo fechar ao clicar fora —, e o que muda é só o miolo. Os botões saem no
 * ouro e pedra da janela de guilda (`.guilda-mini`, `.guilda-botao`), e não no
 * verde-água das caixas comuns do jogo: quem está aqui veio da aba de guildas,
 * e a caixa tem de parecer que pertence a ela.
 * ========================================================================= */
.confirm-box.guilda-doar { width: min(94vw, 420px); display: grid; gap: 10px; }

/* ---- os dois números que a decisão precisa ---- */
.doar-contas {
  display: grid; gap: 5px;
  padding: 9px 11px;
  border: 1px solid #8a6f4233; border-radius: 5px;
  background: linear-gradient(180deg, #131a1cd9, #0b1012e6);
}
.doar-conta { display: flex; align-items: baseline; gap: 7px; flex-wrap: wrap; }
.doar-conta > span {
  flex: none; min-width: 52px;
  font-size: 10px; letter-spacing: .12em; text-transform: uppercase;
  color: #8f9aa0; font-weight: 700;
}
.doar-conta > b { font-family: var(--font-title); font-size: 15px; color: #e8dcbe; }
.doar-conta > b.ouro { color: #ffd98a; }
.doar-conta > i { font-style: normal; font-size: 10.5px; color: #78848a; }

/* ---- o campo ---- */
.guilda-campo.doar-campo {
  width: 100%;
  font-family: var(--font-title); font-size: 16px; letter-spacing: .04em;
  text-align: center; padding: 9px 10px;
}

/*
 * O aviso do teto. Ele OCUPA a linha mesmo vazio (`min-height`): sem isso, a
 * caixa inteira pula para baixo na primeira vez que a pessoa passa do limite —
 * e o botão de confirmar foge de debaixo do dedo.
 */
.doar-aviso {
  margin: -4px 0 0; min-height: 14px;
  font-size: 11px; color: #e4736f; text-align: center;
  opacity: 0; transition: opacity .12s;
}
.doar-aviso.ligado { opacity: 1; }

/* ---- os atalhos ---- */
.doar-atalhos { display: flex; gap: 6px; flex-wrap: wrap; }
.doar-atalhos .guilda-mini { flex: 1 1 60px; justify-content: center; }
.doar-atalhos .guilda-mini.primario { flex: 1 1 100%; }

/* =========================================================================
 * A PRÉVIA: o que a barra vira DEPOIS
 *
 * Duas fatias no mesmo trilho — a que já está guardada e a que este gesto
 * acrescenta, começando onde a primeira acaba. Uma barra só, que mudasse de
 * tamanho, mostraria o resultado e esconderia a contribuição; assim a pessoa vê
 * o TAMANHO do que ela está dando, que é a pergunta que ela está fazendo.
 * ========================================================================= */
.doar-previa { display: grid; gap: 5px; }
.doar-previa .guilda-barra { position: relative; }
.doar-previa .guilda-barra-cheia { position: absolute; top: 0; bottom: 0; }
/*
 * Escrito como descendente de propósito. `.doar-ganho` sozinho tem a mesma
 * especificidade de `.guilda-barra-cheia`, que vem DEPOIS neste arquivo e
 * ganharia o desempate por ordem — a fatia nova sairia da mesma cor da velha e
 * a prévia não mostraria nada.
 */
.doar-previa .doar-ganho {
  background: linear-gradient(180deg, #fff3d6, #ffc766);
  box-shadow: 0 0 9px #ffc76688;
}
.doar-previa-legenda {
  font-size: 10.5px; color: var(--muted); text-align: center;
  font-family: var(--font-title); letter-spacing: .04em;
}

.doar-recado { margin: 0; font-size: 10.5px; line-height: 1.35; }

/* =========================================================================
 * A FAIXA DE NÍVEL, DENTRO DO CARD
 *
 * "nível dentro do card da guilda, embaixo do nome: selo Nível X + barra fina +
 *  0 / 1kkk + botão pequeno Contribuir na mesma linha."
 *
 * Uma linha em vez de uma seção. `grid-column: 1 / -1` a põe embaixo de tudo no
 * card, atravessando as colunas do escudo e do texto — ela é sobre a guilda
 * inteira, e não sobre nenhuma das duas.
 * ========================================================================= */
.guilda-nivel-faixa {
  grid-column: 1 / -1;
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: 10px; padding-top: 10px;
  border-top: 1px solid #ffffff12;
}
.guilda-nivel-selo {
  flex: none;
  display: inline-flex; align-items: baseline; gap: 5px;
  padding: 3px 9px; border-radius: 11px;
  border: 1px solid #8a6f4255; background: #0d1416;
}
.guilda-nivel-selo i {
  font-style: normal; font-size: 9.5px; letter-spacing: .12em;
  text-transform: uppercase; color: #8f9aa0;
}
.guilda-nivel-selo b { font-family: var(--font-title); font-size: 14px; color: #ffd98a; }

/*
 * O bloco do meio é o dono do balão, e é ESTREITO de propósito: um balão nasce
 * colado no dono, e quando ele estava na barra (larga, logo abaixo do nome) ele
 * cobria o escudo e o recado. Daqui ele abre embaixo e ao lado.
 */
.guilda-nivel-meio {
  flex: 1 1 160px; min-width: 120px;
  display: grid; gap: 3px;
  cursor: help;
}
.guilda-nivel-faixa .guilda-barra { height: 7px; border-radius: 4px; }
.guilda-nivel-conta {
  font-family: var(--font-title); font-size: 10.5px;
  letter-spacing: .04em; color: #9aa7ae;
}
.guilda-nivel-faixa .guilda-mini { flex: none; }

/* =========================================================================
 * A ENGRENAGEM E O MENU DELA
 *
 * Ela fica no canto de cima do card, fora do fluxo: não é um dado da guilda, é
 * a porta dos gestos que se faz uma vez na vida dela. No fluxo, ela disputaria
 * espaço com o nome e com os números, que são o assunto.
 * ========================================================================= */
.guilda-estandarte { position: relative; }
/* =========================================================================
 * A ENGRENAGEM PRECISA SER VISTA
 *
 * "as engrenagens têm que ser mais chamativas, porque a pessoa pode não ver."
 *
 * Ela era um círculo cinza de 26px no canto do card, e é a ÚNICA porta para mudar
 * o brasão, passar a liderança, desfazer a guilda e sair dela — tudo o que morava
 * no rodapé. Quem não sabe que ela existe não procura por ela.
 *
 * Três mudanças, e cada uma resolve uma parte do problema:
 *
 *   a palavra    um ícone se decifra, um rótulo se lê. "Opções" acaba com a
 *                adivinhação, e é o que mais pesa dos três.
 *   o ouro       ela sai do cinza dos enfeites e entra na família visual dos
 *                botões que AGEM, que é o que ela é.
 *   o aceno      três pulsos ao abrir a tela e para. O olho é atraído por
 *                mudança, e uma peça parada num card cheio de números não muda
 *                nunca. Três e não infinito: um brilho perpétuo no canto da tela
 *                deixa de ser aviso e passa a ser irritação.
 *
 * O giro saiu do botão e foi para o ÍCONE: girar uma pastilha com texto dentro
 * deixaria a palavra de cabeça para baixo.
 * ========================================================================= */
.guilda-engrenagem {
  position: absolute; top: 8px; right: 8px; z-index: 2;
  display: flex; align-items: center; gap: 5px;
  padding: 5px 11px 5px 9px;
  border: 1px solid #e0a84a99; border-radius: 13px;
  background: linear-gradient(180deg, #24312e, #131c1b);
  color: #ffd98a; cursor: pointer;
  box-shadow: 0 1px 0 #ffffff14 inset, 0 2px 8px #00000073;
  transition: color .12s, border-color .12s, background .12s, box-shadow .12s;
  animation: guilda-acena 2.2s ease-in-out 3;
}
.guilda-engrenagem b {
  font-family: var(--font-title); font-size: 11px; letter-spacing: .06em;
  line-height: 1;
}
.guilda-engrenagem-roda {
  font-size: 13px; line-height: 1;
  transition: transform .25s;
}
.guilda-engrenagem:hover {
  color: #ffeec2; border-color: #ffd98a; background: linear-gradient(180deg, #2c3b37, #182220);
  box-shadow: 0 1px 0 #ffffff1f inset, 0 0 14px #e0a84a3d;
}
.guilda-engrenagem:hover .guilda-engrenagem-roda { transform: rotate(75deg); }

@keyframes guilda-acena {
  0%, 100% { box-shadow: 0 1px 0 #ffffff14 inset, 0 2px 8px #00000073; }
  50% { box-shadow: 0 1px 0 #ffffff14 inset, 0 0 16px #e0a84a80; }
}
/* Quem pediu menos movimento não leva um botão piscando no canto do card. */
@media (prefers-reduced-motion: reduce) {
  .guilda-engrenagem { animation: none; }
}

.guilda-menu {
  position: absolute; top: 38px; right: 8px; z-index: 9;
  min-width: 178px;
  display: grid; gap: 2px; padding: 4px;
  border: 1px solid #8a6f4255; border-radius: 7px;
  background: #0b1012f7;
  box-shadow: 0 10px 28px #000b, 0 0 0 1px #0008;
}
.guilda-menu-item {
  padding: 7px 10px; text-align: left;
  border: none; border-radius: 5px; background: none;
  color: #dfe5e8; font-size: 12px; cursor: pointer;
  transition: background .12s, color .12s;
}
.guilda-menu-item:hover:not(:disabled) { background: #1b2729; color: #ffeec2; }
.guilda-menu-item.perigo { color: #e4867f; }
.guilda-menu-item.perigo:hover:not(:disabled) { background: #2a1516; color: #ff9d95; }
/*
 * O item apagado FICA no menu. Um líder que procura como acabar com a guilda e
 * não acha o item conclui que o jogo não deixa; apagado, com o porquê no balão,
 * ele descobre o que falta fazer.
 */
.guilda-menu-item:disabled { color: #5c666a; cursor: not-allowed; }

/* ---- a lista de quem pode receber a liderança ---- */
.guilda-escolher { display: grid; gap: 5px; max-height: 260px; overflow-y: auto; }
.guilda-escolher-item {
  display: grid; gap: 1px; padding: 7px 10px; text-align: left;
  border: 1px solid #ffffff14; border-radius: 5px;
  background: #0d1416a8; color: var(--muted); cursor: pointer;
  transition: border-color .12s, background .12s;
}
.guilda-escolher-item:hover { border-color: #e0a84a66; background: #1b2729; }
.guilda-escolher-item b { font-size: 12.5px; color: #e8dcbe; }
.guilda-escolher-item span { font-size: 10.5px; }

/* ---- o convite da aba principal ---- */
/* =========================================================================
 * O CONVITE DE FUNDAR — UMA BARRA QUE NAO SOBE COM A ROLAGEM
 *
 * "o fundar uma guilda tem que ficar visível ali sempre que uma pessoa não tiver
 *  guilda, mesmo se a página descer."
 *
 * Ele mora no pé da tabela, e a tabela cresce: com vinte guildas, quem rolava
 * para ler a lista perdia de vista a única saída de quem não quer entrar em
 * nenhuma delas — e ela não está em mais lugar nenhum da janela.
 *
 * `sticky` e não `fixed`: ele continua no fluxo, no lugar em que sempre esteve, e
 * só PARA de subir quando encosta no pé da área que rola. Numa janela em que a
 * tabela cabe inteira nada muda, e esse é o caso comum.
 *
 * O `margin` negativo e o `bottom` negativo cancelam o enchimento do
 * `#modal-body`: sem eles a barra flutuaria com uma faixa da tabela aparecendo
 * por baixo, e a tabela pareceria continuar embaixo dela.
 *
 * O fundo é opaco de propósito — é ele que separa a barra do que passa por trás.
 * ========================================================================= */
/*
 * ---- ELA TEM O RECUO E A LARGURA DA LISTA ----
 *
 * "o bloco Não está em nenhuma guilda / Criar guilda encosta na borda esquerda e
 *  passa da largura da lista. Mesmo recuo e mesma largura da lista."
 *
 * Era `margin: 10px -10px -10px`, e as duas margens negativas eram de propósito:
 * elas cancelavam o enchimento da área que rola para a barra grudada não deixar
 * uma faixa de tabela aparecendo por baixo dela.
 *
 * O preço disso é o que ele viu — a barra ficava 10px mais larga que a tabela dos
 * dois lados e encostava na moldura, quando ela é um bloco como os outros. As
 * margens saíram, e a faixa que elas cobriam deixou de existir por outro caminho:
 * `bottom: 0` em vez de `-10px` para a barra acompanhar o pé da área que rola, e
 * borda inteira com cantos arredondados, como o `.guilda-painel`. O que aparece
 * embaixo dela agora é o fundo da janela, e não um pedaço de linha cortada.
 */
.guilda-chamada {
  position: sticky; bottom: 0; z-index: 4;
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin: 10px 0 0; padding: 9px 12px;
  border: 1px solid #8a6f4255; border-radius: 4px;
  background: linear-gradient(180deg, #121a1cfa, #0a0f11);
  box-shadow: 0 -6px 16px #00000073;
}
.guilda-chamada-texto { flex: 1 1 200px; min-width: 0; display: grid; gap: 1px; }
.guilda-chamada-texto b {
  font-family: var(--font-title); font-size: 12px; letter-spacing: .04em;
  color: #ffe1ad;
}
.guilda-chamada-texto span { font-size: 11px; color: var(--muted); line-height: 1.3; }
/*
 * Menor que um botao de acao comum, de proposito: ele nao e' o assunto da aba,
 * e' uma saida lateral para quem nao vai entrar em guilda nenhuma da tabela.
 */
.guilda-chamada .guilda-botao {
  flex: none;
  padding: 7px 16px;
  font-size: 11.5px;
  letter-spacing: .06em;
}

/* =========================================================================
 * O ESTANDARTE — o cartaz da própria guilda
 *
 * Três colunas: brasão, texto (nome, subtítulo e recado) e os números. Em
 * telas estreitas ele vira duas linhas — os números descem inteiros em vez de
 * apertarem o nome, que é o que se lê primeiro.
 * ========================================================================= */
.guilda-estandarte {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 16px;
  padding: 14px 16px;
  border: 1px solid #8a6f423d;
  border-radius: 4px;
  background:
    linear-gradient(90deg, #e0a84a14, transparent 45%),
    linear-gradient(180deg, #131a1ce6, #0b1012f2);
  box-shadow: inset 0 1px 0 #ffffff0d, 0 2px 12px #0006;
}
.guilda-estandarte-texto { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.guilda-estandarte-texto h3 {
  margin: 0;
  font-family: var(--font-title); font-size: 22px; font-weight: 700;
  letter-spacing: .04em;
  color: #ffe9bd;
  text-shadow: 0 1px 0 #000, 0 0 16px #e0a84a2e;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.guilda-estandarte-sub { font-size: 11.5px; color: #9aa3a6; }
.guilda-recado-texto {
  margin: 2px 0 0; font-size: 12.5px; font-style: italic;
  color: #cbb388;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.guilda-recado-campo { margin-top: 3px; }

/*
 * ---- A CAIXINHA DE "NAO PERGUNTAR NOVAMENTE" ----
 *
 * Ela mora na fileira dos botões e é empurrada para a ESQUERDA pelo `margin-right:
 * auto`: ali ela fica longe do "Confirmar", que é onde a mão vai. Colada nele, um
 * clique com a mira alta marcaria o acordo em vez de confirmar — e o acordo vale
 * para sempre.
 */
.confirm-nao-perguntar {
  display: flex; align-items: center; gap: 6px;
  margin-right: auto;
  font-size: 11px; color: var(--muted); cursor: pointer;
  user-select: none;
}
.confirm-nao-perguntar input { accent-color: var(--guilda-ouro, #e0a84a); cursor: pointer; }
.confirm-nao-perguntar:hover { color: #cbb388; }

/*
 * Um link de texto dentro de uma nota da janela de guildas — sem fundo e sem
 * borda, para não competir com os botões de verdade da mesma linha.
 */
.guilda-link {
  all: unset;
  cursor: pointer;
  color: #cbb388;
  border-bottom: 1px dotted #ffffff2e;
  transition: color .12s, border-color .12s;
}
.guilda-link:hover { color: #ffd98a; border-bottom-color: #e0a84a99; }
.guilda-link:focus-visible { outline: 1px solid #e0a84a99; outline-offset: 2px; }

.guilda-numeros { display: flex; gap: 8px; flex: none; }
.guilda-numero {
  min-width: 68px;
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  padding: 7px 9px;
  border: 1px solid #8a6f4233; border-radius: 3px;
  background: #0a0f1199;
  cursor: default;
}
.guilda-numero b {
  font-family: var(--font-title); font-size: 17px; color: #ffe1ad; line-height: 1;
}
.guilda-numero span { font-size: 10px; letter-spacing: .04em; color: #8e9699; text-transform: uppercase; }

/* =========================================================================
 * OS PAINÉIS — a caixa que todas as listas usam
 * ========================================================================= */
.guilda-painel {
  display: flex; flex-direction: column; gap: 8px;
  padding: 12px 14px;
  border: 1px solid #ffffff14;
  border-radius: 4px;
  background: linear-gradient(180deg, #0e1416e0, #0a0f11ee);
  box-shadow: inset 0 1px 0 #ffffff0a;
}
.guilda-painel-cabeca { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.guilda-titulo {
  margin: 0;
  font-family: var(--font-title); font-size: 13px; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--guilda-ouro);
}
.guilda-nota { margin: 0; font-size: 11.5px; color: #8e9699; }
.guilda-trava { margin: 0; font-size: 11.5px; color: #d79b9b; }

/* ---- Campos e botões ---- */
.guilda-linha-campo { display: flex; gap: 8px; align-items: center; }
.guilda-campo {
  flex: 1 1 auto; min-width: 0;
  height: 30px; padding: 0 10px;
  border: 1px solid #ffffff1f; border-radius: 3px;
  background: #060a0bcc;
  color: #e6edee; font-size: 12.5px; font-family: inherit;
}
.guilda-campo:focus { outline: none; border-color: var(--guilda-ouro-fraco); background: #0a1113; }
.guilda-campo::placeholder { color: #6e7679; }
.guilda-campo:disabled { opacity: .45; }

/* =========================================================================
 * A PLACA DE FERRO DOS BOTOES
 *
 * `guilda-botao.webp` e uma barra so' — 480x70 depois de aparada — e ela vira
 * botao de qualquer largura por `border-image`.
 *
 * ---- As fatias saem da PONTA, e a conta fecha sozinha ----
 *
 * A ponta da arte tem 35px de largura numa barra de 70px de altura: metade.
 * Entao, num botao de 30px de altura, a ponta tem de ter 15 — e a escala fica
 * IGUAL nos dois eixos (0,43), que e' o que impede o rebite de virar elipse.
 * O `.guilda-mini` tem 24px de altura e por isso ganha 12: a mesma metade.
 *
 * `fill` e' o que pinta o miolo: sem ele o centro da placa (o ferro batido)
 * ficaria vazado e o botao seria so' a moldura dele.
 *
 * ---- Um arquivo, tres estados ----
 *
 * Hover, primario e desabilitado saem de `filter`, e nao de mais arquivos. Tres
 * artes seriam tres downloads e tres chances de uma nao casar com as outras
 * duas — e a diferenca entre elas seria justamente brilho e saturacao, que e' o
 * que o filtro faz de graca.
 * ========================================================================= */
.guilda-botao, .guilda-mini {
  flex: none;
  border-style: solid;
  border-image-source: url('/client/assets/ui/guilda-botao.webp');
  border-image-slice: 8 35 8 35 fill;
  border-image-repeat: stretch;
  background: none;
  color: #e8dcc2;
  font-family: var(--font-title); letter-spacing: .04em;
  cursor: pointer;
  text-shadow: 0 1px 2px #000000cc;
  transition: filter .12s ease, color .12s ease;
}
.guilda-botao { height: 30px; border-width: 3px 15px; padding: 0 6px; font-size: 12px; }
.guilda-mini { height: 24px; border-width: 3px 12px; padding: 0 4px; font-size: 11px; }
.guilda-botao:hover, .guilda-mini:hover { filter: brightness(1.28); color: #fff6df; }
.guilda-botao:active, .guilda-mini:active { filter: brightness(.9); }
/*
 * O primario e' a MESMA placa, mais quente e com um halo. A cor sai do filtro
 * porque a placa e' cinza-ferro: um `sepia` seguido de `saturate` a puxa para o
 * ouro sem precisar de uma segunda arte.
 */
.guilda-botao.primario, .guilda-mini.primario {
  filter: sepia(.45) saturate(1.5) brightness(1.12);
  color: #fff3d6;
  box-shadow: 0 0 10px -2px #e0a84a4d;
}
.guilda-botao.primario:hover, .guilda-mini.primario:hover {
  filter: sepia(.45) saturate(1.7) brightness(1.35);
}
.guilda-botao.perigo, .guilda-mini.perigo { filter: sepia(.5) hue-rotate(-38deg) saturate(1.9); color: #ffd2d2; }
.guilda-botao.perigo:hover, .guilda-mini.perigo:hover { filter: sepia(.5) hue-rotate(-38deg) saturate(2.2) brightness(1.3); }
.guilda-botao:disabled, .guilda-mini:disabled { filter: grayscale(1) brightness(.6); opacity: .65; cursor: default; }
.guilda-botao:disabled:hover, .guilda-mini:disabled:hover { filter: grayscale(1) brightness(.6); color: #e8dcc2; }

/* =========================================================================
 * FUNDAR — a prévia do brasão ao lado do campo
 * ========================================================================= */
.guilda-fundar-corpo { display: flex; gap: 14px; align-items: center; }
.guilda-previa { flex: none; display: grid; place-content: center; }
.guilda-fundar-direita { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 6px; }

/* =========================================================================
 * OS MEMBROS
 *
 * Grade de duas colunas em tela larga e uma só em tela estreita: uma guilda de
 * trinta pessoas numa coluna é uma página de rolar, e a promessa desta janela
 * (como a da arena) é caber.
 *
 * A borda ESQUERDA de cada linha é a cor do posto. É a única marca de cargo que
 * se lê sem parar o olho — o `♛` diz quem é o líder, mas a faixa diz de relance
 * onde estão os três que mandam numa lista de trinta.
 * ========================================================================= */
/*
 * A grade dos membros mora mais abaixo, em "OS MEMBROS EM GRADE": ela deixou de
 * ser duas colunas fixas (mais uma media query para o celular) e passou a ser
 * `auto-fill`, que escolhe sozinha quantas cabem.
 */

/* =========================================================================
 * A LINHA QUE QUEBRAVA — três botões espremendo o nome até a sílaba
 *
 * "na aba de guilds tá ficando meio quebrado o 'membro', e level, e nome."
 *
 * A linha era um flex de quatro peças e os botões eram `flex: none`: eles
 * pegavam os 250px que precisavam e o que sobrava, sobrava para o nome. Numa
 * janela de duas colunas sobravam quarenta pixels, e aí "Membro" descia
 * quebrado em três andares e o nome virava reticências.
 *
 * O conserto é deixar a linha QUEBRAR de propósito: com `flex-wrap`, quando os
 * botões não couberem ao lado do nome eles descem inteiros para a segunda
 * linha, alinhados à direita. O nome ganha um piso (`flex: 1 1 150px`) que diz
 * quando isso acontece — enquanto ele tiver 150px, tudo fica numa linha só.
 *
 * E os textos de baixo (posto, level, vocação) ganham `nowrap`: eles são rótulos
 * de uma palavra, e uma palavra partida no meio lê-se como defeito. Se faltar
 * espaço eles cortam com reticências, que lê-se como "tem mais".
 * ========================================================================= */
.guilda-membro {
  display: flex; align-items: center; flex-wrap: wrap; gap: 9px 9px;
  padding: 6px 8px;
  min-height: 48px;
  border: 1px solid #ffffff12;
  border-left: 2px solid #ffffff1f;
  border-radius: 3px;
  background: #0a0f1199;
  min-width: 0;
}
.guilda-membro.cargo-3 { border-left-color: var(--guilda-ouro); background: linear-gradient(90deg, #e0a84a12, #0a0f1199 40%); }
.guilda-membro.cargo-2 { border-left-color: #8fa9b4; }
.guilda-membro:not(.online) { opacity: .62; }

.guilda-boneco {
  flex: none; display: grid; place-content: center;
  border-radius: 3px;
  background: #060a0b99;
  box-shadow: inset 0 0 0 1px #ffffff0f;
  overflow: hidden;
}
.guilda-boneco canvas { display: block; image-rendering: pixelated; }
.guilda-boneco-letra { font-family: var(--font-title); font-size: 14px; color: #6e7679; }

.guilda-membro-nome { flex: 1 1 150px; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.guilda-membro-cima { display: flex; align-items: center; gap: 5px; min-width: 0; }
.guilda-membro-cima b {
  font-size: 13px; color: #e6edee;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.guilda-membro-baixo {
  display: flex; align-items: center; gap: 7px;
  font-size: 10.5px; color: #8e9699;
  min-width: 0; white-space: nowrap;
}
.guilda-membro-baixo > * { overflow: hidden; text-overflow: ellipsis; }
.guilda-posto { color: #cbb388; opacity: .8; }
.guilda-coroa { font-style: normal; color: var(--guilda-ouro); font-size: 12px; text-shadow: 0 0 8px #e0a84a66; }
.guilda-vice { font-style: normal; color: #8fa9b4; font-size: 10px; }

/* A bolinha de online: apagada por padrão, acesa com halo. */
.guilda-ponto {
  flex: none; width: 7px; height: 7px; border-radius: 50%;
  background: #3a4245; box-shadow: inset 0 0 0 1px #00000055;
}
.guilda-ponto.aceso { background: #59c97f; box-shadow: 0 0 7px #59c97f99; }

/*
 * `margin-left: auto` é o que os empurra para a direita nos dois casos: na mesma
 * linha do nome, e sozinhos na linha de baixo quando ela quebra.
 */
.guilda-membro-acoes { flex: 0 0 auto; display: flex; gap: 4px; margin-left: auto; }

/* =========================================================================
 * O BALÃO DE UM MEMBRO — equipamento e lugar
 *
 * Duas colunas de itens porque são até dez: numa coluna o balão fica mais alto
 * que a janela, e um balão que passa da tela é um balão que se lê rolando, o que
 * não existe. Ver `balaoDoMembro` em `client/src/guildas.mjs`.
 * ========================================================================= */
/* =========================================================================
 * O ÍCONE DA VOCAÇÃO na linha do membro
 *
 * "ao lado da vocação coloca o ícone da vocação também."
 *
 * 13px é a altura da linha de baixo (10,5px de texto): o ícone alinha com a
 * letra em vez de empurrar a linha para baixo. `flex: none` porque ele é a única
 * coisa daquela linha que não pode encolher — um ícone espremido vira mancha.
 */
.guilda-voc-icone {
  flex: none; width: 13px; height: 13px;
  image-rendering: pixelated; opacity: .9;
}
.guilda-voc-sigla { color: #9aa3a6; letter-spacing: .04em; }

/* =========================================================================
 * A MELHORIA DA GUILDA — a barra do que falta
 *
 * A barra é o painel: ela responde "quanto falta" com o olho, e os números ao
 * lado são a legenda dela. Ver `painelDeMelhoria` em `client/src/guildas.mjs`.
 * ========================================================================= */
.guilda-melhoria { display: flex; flex-direction: column; gap: 8px; }
.guilda-barra {
  position: relative; height: 12px; border-radius: 6px; overflow: hidden;
  background: #060a0bcc; box-shadow: inset 0 0 0 1px #ffffff14;
}
.guilda-barra-cheia {
  display: block; height: 100%;
  background: linear-gradient(90deg, #8a6f42, var(--guilda-ouro, #e0a84a));
  box-shadow: 0 0 10px #e0a84a55;
  transition: width .25s ease;
}
.guilda-melhoria-legenda { display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap; }
.guilda-melhoria-legenda b { font-family: var(--font-title); font-size: 13px; color: #ffe1ad; }
.guilda-melhoria-legenda span { font-size: 11px; color: #8e9699; }
.guilda-melhoria .guilda-botao { align-self: flex-start; }

/* =========================================================================
 * O BAÚ COMUNITÁRIO
 *
 * Duas grades de quadradinhos, como o depósito — ver `renderBau`. O AVISO tem
 * cor própria e fica no alto: ele é a única coisa desta página que a pessoa
 * precisa ter lido antes de clicar.
 * ========================================================================= */
/*
 * ---- O AVISO E' VERMELHO ----
 *
 * "a cor vermelha do 'nao guarde o que voce nao quer contribuir'."
 *
 * Ele era âmbar, a mesma cor do ouro da janela inteira — dos títulos, das bordas,
 * dos botões. Uma frase de alerta pintada da cor do enfeite lê-se como enfeite, e
 * esta é a única linha desta página que a pessoa precisa ter lido ANTES de clicar:
 * o que entra aqui pode ser levado por qualquer um dos trinta, e não volta.
 *
 * A barra grossa na esquerda é o que o separa de um parágrafo comum sem precisar de
 * um ícone — e é o padrão dos avisos do jogo (ver `.danger`).
 */
.guilda-aviso {
  margin: 0; padding: 7px 10px 7px 11px; border-radius: 3px;
  font-size: 11.5px; line-height: 1.45; color: #ffb4ab;
  background: #b4442f1f;
  box-shadow: inset 0 0 0 1px #b4442f4d, inset 4px 0 0 #b4442f;
}
.guilda-bau-ferramentas { display: flex; gap: 6px; }
/*
 * ---- A GRADE DO BAU SAIU DAQUI ----
 *
 * `.guilda-bau-grade` e `.guilda-bau-quadro` eram um desenho proprio: quadradinhos
 * de 42px com o sprite e a contagem, e mais nada. O bau passou a usar a GRADE E A
 * CELULA do deposito (`.locker-grade.caixa-quadrada` e `.cell`), que ja' trazem a
 * raridade no fundo, o selo de tier, o de imbuement, as estrelas de afixo e o balao
 * inteiro do item — ver a nota do `renderBau`.
 *
 * Duas caixas que guardam item do mesmo jeito nao podem ter dois tamanhos de
 * quadradinho e dois espacamentos, e era isso que estas regras produziam.
 */

.guilda-tip { display: flex; flex-direction: column; gap: 8px; min-width: 240px; max-width: 320px; }

/* =========================================================================
 * O CARD DO MEMBRO — o mesmo desenho do card do personagem no site
 *
 * "o site já tem um card de personagem com o inventário organizado e bonito;
 *  esse é o visual que eu quero no card do membro da guilda."
 *
 * A GRADE vem pronta do componente compartilhado (`paperdoll.mjs`, que injeta
 * o CSS dela). O que está aqui é o resto do card: o cabeçalho, os títulos das
 * seções e o teto de altura.
 *
 * ---- O TETO DE ALTURA É O CONSERTO, e não enfeite ----
 *
 * "o card vaza para fora da parte de baixo da tela."
 *
 * Com dez peças e um set estrelado, o card passava da altura da janela. Aqui
 * ele para de crescer (`max-height`), e quem cede é a lista de afixos — o
 * cabeçalho e a grade ficam sempre à vista, que é o que se abre o card para ver.
 * A outra metade do conserto está em `place()`, no tooltip.mjs: é ela que
 * garante que o card caiba na tela depois de medido.
 * ========================================================================= */
.guilda-tip.ficha-membro {
  gap: 6px;
  max-height: calc(100vh - 24px);
}
.ficha-membro-cabeca {
  display: flex; align-items: center; gap: 8px;
  padding-bottom: 8px;
  border-bottom: 1px solid #ffffff14;
}
/* O boneco na mesma moldura redonda esverdeada do card do site. */
.ficha-membro-cabeca .guilda-boneco {
  flex: none; display: grid; place-items: center; border-radius: 6px;
  background: radial-gradient(circle at 50% 62%, #3fbfa82e, transparent 70%);
}
.ficha-membro-cabeca .guilda-boneco canvas { image-rendering: pixelated; }
.ficha-membro-quem { min-width: 0; display: flex; flex-direction: column; }
.ficha-membro-quem > b {
  display: block; font-family: var(--font-title); font-size: 14px; line-height: 1.2; color: #f0c27a;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ficha-membro-quem > span {
  display: flex; align-items: center; font-size: 11.5px; line-height: 1.5; color: #8e9699;
}
.ficha-membro-quem > span.on { color: #6fd48a; }
/* O número do level em destaque, como no card do site. */
.ficha-membro-quem em {
  font-style: normal; margin-left: 4px;
  font-family: var(--font-title); font-weight: 700; color: #eef3f2;
}
.ficha-membro-ponto {
  width: 6px; height: 6px; margin-right: 5px; flex: none;
  border-radius: 50%; background: #6fd48a; box-shadow: 0 0 5px #6fd48a99;
}
.ficha-membro-ponto.off { background: #55605f; box-shadow: none; }
/* Os títulos de seção: caps douradas e centradas, como "INVENTORY" no site. */
.ficha-membro-titulo {
  margin: 2px 0 1px; text-align: center;
  font-family: var(--font-title); font-size: 10px;
  letter-spacing: .16em; text-transform: uppercase; color: #c8823c;
}
.ficha-membro-sub { text-align: center; font-size: 10px; color: #7b8386; margin-bottom: 2px; }
/*
 * A seção dos afixos é a única que cede altura: `min-height: 0` é o que permite
 * um filho de flex encolher abaixo do próprio conteúdo — sem ele o `max-height`
 * do card não teria de onde tirar espaço, e o card voltaria a crescer.
 */
.ficha-membro-afx { display: flex; flex-direction: column; min-height: 0; }
.ficha-membro-afx .guilda-tip-afx { overflow-y: auto; min-height: 0; padding-right: 2px; }
.guilda-tip-cabeca { display: flex; align-items: center; gap: 9px; }
.guilda-tip-quem { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.guilda-tip-quem b { font-size: 13px; color: #ffe1ad; font-family: var(--font-title); letter-spacing: .04em; }
.guilda-tip-quem span { font-size: 10.5px; color: #9aa3a6; }

.guilda-tip-lugar {
  font-size: 11px; color: #9aa3a6;
  padding: 4px 8px; border-radius: 3px;
  background: #ffffff08; box-shadow: inset 0 0 0 1px #ffffff0d;
}
/* Caçando é a única que se acende: é a resposta a "dá para chamar agora?". */
.guilda-tip-lugar.cacando { color: #8fd8cf; background: #8fd8cf12; box-shadow: inset 0 0 0 1px #8fd8cf2e; }

.guilda-tip-titulo {
  font-family: var(--font-title); font-size: 10px; letter-spacing: .14em;
  text-transform: uppercase; color: #cbb388; opacity: .8;
}
.guilda-tip-vazio { font-size: 11px; color: #7b8386; font-style: italic; margin: 0; }

/*
 * ---- A GRADE, como no site ----
 *
 * "os equipamentos das pessoas da guild é pra mostrar igual da foto 2."
 *
 * ---- A FILEIRA DE CINCO SAIU ----
 *
 * `.guilda-tip-itens` era a grade do equipamento do membro: cinco quadrados por
 * linha, na ordem em que o servidor mandava. Ela virou a CRUZ do card do site
 * (`paperdoll.mjs`, que traz o CSS junto) — cada peça num lugar fixo. O
 * quadrado aqui embaixo ficou porque a PRÉVIA DO BAÚ usa o mesmo, e ele nunca
 * foi do equipamento: é o quadradinho genérico desta janela.
 */
.guilda-tip-quadro {
  position: relative; width: 40px; height: 40px;
  display: grid; place-content: center;
  border-radius: 3px; background: #060a0b99; box-shadow: inset 0 0 0 1px #ffffff12;
}
.guilda-tip-quadro canvas { display: block; image-rendering: pixelated; }

/* =========================================================================
 * A PRÉVIA DO BAÚ — o que tem lá dentro, antes de abrir
 *
 * "ao colocar o mouse em cima do baú comunitário, antes de abrir, ele já tinha que
 *  ter um preview do que tem dentro."
 *
 * Seis por linha e não cinco (como a grade de equipamento acima): o baú tem tipos
 * diferentes e não dez peças fixas, e três fileiras de seis mostram dezoito num
 * balão que ainda cabe na tela. O quadro é o mesmo `.guilda-tip-quadro` do
 * equipamento — dois desenhos de item no mesmo balão não podem ter molduras
 * diferentes.
 * ========================================================================= */
.guilda-tip-grade { display: grid; grid-template-columns: repeat(6, 40px); gap: 4px; }
/* A contagem da pilha, no canto de baixo — o mesmo canto da mochila. */
.guilda-tip-quadro > b {
  position: absolute; right: 2px; bottom: 1px;
  font-size: 9.5px; font-weight: 700;
  color: #e6edee; text-shadow: 0 1px 2px #000, 0 0 3px #000;
}
/* Sem arte empacotada, o quadro fica vazio em vez de derrubar o balão. */
.guilda-tip-quadro.sem-arte { background: #060a0b55; }
.guilda-tip-sub { font-size: 10.5px; color: #8e9699; }

/* =========================================================================
 * O QUE O CONJUNTO DÁ — os afixos somados e os bônus de tier
 *
 * "em vez de mostrar igual na foto 1, tem que mostrar igual na foto 2."
 *
 * A mesma forma da ficha do site: uma linha por afixo, com o nome à esquerda e
 * o TOTAL à direita, e embaixo um selo por peça — desenho, estrela na cor do
 * degrau e o quanto aquela peça dá.
 *
 * O total é a leitura de relance e por isso é ele que ganha cor e tamanho; os
 * selos são a resposta a "de onde vem", e ficam menores de propósito.
 * ========================================================================= */
.guilda-tip-afx { display: flex; flex-direction: column; gap: 5px; }
.guilda-tip-afx-linha {
  padding: 4px 6px;
  border-radius: 3px;
  background: #0a0f1180;
  box-shadow: inset 2px 0 0 #8a6f4255;
}
.guilda-tip-afx-topo {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  font-size: 11px; color: #c4ccce;
}
.guilda-tip-afx-topo > b { flex: none; font-size: 12px; color: #7fd3ff; font-variant-numeric: tabular-nums; }
/* O bônus de tier é dourado, como o tier é em todo o resto do jogo. */
.guilda-tip-afx-topo > b.de-tier { color: #f0c27a; }
.guilda-tip-afx-chips { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 3px; }
.guilda-tip-afx-chip {
  display: inline-flex; align-items: center; gap: 3px;
  padding: 0 4px 0 1px;
  border-radius: 3px; background: #ffffff0a;
  font-size: 9.5px; color: #96a0a3;
}
.guilda-tip-afx-chip canvas { display: block; image-rendering: pixelated; }
.guilda-tip-afx-chip em { font-style: normal; }
/*
 * As estrelas da peça saíram daqui: quem as desenha agora é a grade
 * compartilhada (`.pd-estrelas`, em `paperdoll.mjs`), com as mesmas quatro
 * cores do card do site e da mochila.
 */

/* =========================================================================
 * O HISTÓRICO DA GUILDA — um botão, três abas
 *
 * "se os historico ocupar muito espaço desnecessario, faz (...) um botao que abre
 *  todos esses historicos divididos por abas (talvez seja melhor assim)."
 *
 * ---- O QUE ESTAVA AQUI ANTES ----
 *
 * Três caixas embutidas: uma no pé do Baú, uma no pé dos Pedidos e uma dentro da
 * tela de contribuir. Cada uma custava altura numa página que já tinha o seu
 * assunto — e a de contribuir era a pior, dividindo a janela com as contas, o campo,
 * os atalhos, a prévia e dois botões.
 *
 * Numa caixa própria, o histórico custa ZERO altura enquanto ninguém o abre.
 *
 * ---- A ALTURA E' TRAVADA, E QUEM ROLA E' A LISTA ----
 *
 * `max-height: 58vh` na lista, e não na caixa: assim o título, as abas e o botão de
 * fechar ficam parados enquanto se rola. Numa caixa inteira rolável, trocar de aba
 * levaria a pessoa para o meio do nada.
 * ========================================================================= */
.confirm-box.guilda-historico {
  width: min(600px, 94vw);
  display: flex; flex-direction: column; gap: 10px;
}
/*
 * O título na fonte dos títulos e com a régua de ouro embaixo — a mesma moldura das
 * seções da janela de guildas, para a caixa não parecer uma janela de outro jogo.
 */
.confirm-box.guilda-historico > h3 {
  margin: 0 0 2px;
  padding-bottom: 8px;
  border-bottom: 1px solid #8a6f4240;
  font-family: var(--font-title); font-size: 14px; letter-spacing: .04em;
  color: var(--guilda-ouro, #e0a84a);
}
/*
 * ---- A ABA LIGADA ----
 *
 * "as abas selecionadas do historico ta preto, nao da pra ler."
 *
 * Era `color: #1a1204` — quase preto, escolhido para uma aba de FUNDO dourado, como
 * as da barra do topo. Mas o `.guilda-mini` é um botão de moldura de pedra com o
 * miolo escuro: texto quase preto sobre fundo quase preto.
 *
 * A aba ligada agora se marca do jeito que o resto da janela marca — letra clara e
 * uma linha de ouro embaixo —, sem mexer no fundo do botão.
 */
.guilda-hist-abas { display: flex; gap: 6px; flex-wrap: wrap; }
.guilda-hist-abas .guilda-mini { position: relative; }
.guilda-hist-abas .guilda-mini.ligado {
  color: #ffe7a3;
  filter: brightness(1.2);
  box-shadow: inset 0 -2px 0 #e0a84a;
}
.guilda-hist-abas .guilda-mini.ligado .guilda-conta-bolha { background: #e0a84a; color: #1a1204; }
.guilda-hist-corpo { display: flex; flex-direction: column; gap: 8px; min-height: 0; }
.guilda-hist-rolo {
  display: flex; flex-direction: column; gap: 4px;
  max-height: 58vh; min-height: 0;
  overflow-y: auto; overflow-x: hidden;
  scrollbar-gutter: stable;
}

/* ---- A linha: boneco, frase, ouro ou peça, e quando ---- */
/*
 * ---- A LINHA ----
 *
 * "deixa a pagina historico da guild mais bonita."
 *
 * Três coisas fazem o trabalho: a faixa clara na ESQUERDA (um fio de ouro que dá um
 * começo à linha, como as cartas de convite desta mesma janela), o degradê lateral —
 * que escurece para a direita e deixa a hora quase se perdendo no fundo, que é onde
 * ela deve estar — e o realce ao passar o mouse, que é o que separa uma lista de um
 * parágrafo.
 */
.guilda-hist-linha {
  display: flex; align-items: center; gap: 8px;
  padding: 5px 8px;
  border-radius: 3px;
  background: linear-gradient(90deg, #e0a84a0f, #0a0f11cc 45%);
  box-shadow: inset 2px 0 0 #8a6f4266;
  font-size: 11.5px; color: #b9bfc2;
  transition: box-shadow .12s, background .12s;
}
.guilda-hist-linha:hover {
  background: linear-gradient(90deg, #e0a84a1a, #12191bd9 45%);
  box-shadow: inset 2px 0 0 #e0a84a;
}
/*
 * ---- O QUE ENTROU E O QUE SAIU DO BAÚ ----
 *
 * "em movimentações do baú tem que ter uma diferença de cor pra facilitar a
 *  visualização e saber rapidamente o que foi guardado e o que foi pego."
 *
 * O fio da esquerda é o que muda de cor — ele é a coluna que o olho desce lendo a
 * lista, e um fio verde no meio de três vermelhos se acha sem ler nada. O degradê
 * acompanha de leve, e o verbo ("guardou" / "pegou") recebe a mesma cor, para a linha
 * não depender só de uma faixa de 2px.
 *
 * Verde da casa (`--accent-dim`) e o vermelho do aviso desta mesma janela: as duas
 * cores que o jogo já usa para ganhar e perder.
 */
.guilda-hist-linha.hist-entrou {
  background: linear-gradient(90deg, #3fbfa81c, #0a0f11cc 45%);
  box-shadow: inset 2px 0 0 #3fbfa87a;
}
.guilda-hist-linha.hist-entrou:hover {
  background: linear-gradient(90deg, #3fbfa82e, #12191bd9 45%);
  box-shadow: inset 2px 0 0 #3fbfa8;
}
.guilda-hist-linha.hist-saiu {
  background: linear-gradient(90deg, #b4442f24, #0a0f11cc 45%);
  box-shadow: inset 2px 0 0 #b4442f96;
}
.guilda-hist-linha.hist-saiu:hover {
  background: linear-gradient(90deg, #b4442f3d, #12191bd9 45%);
  box-shadow: inset 2px 0 0 #d4563d;
}
.hist-entrou .guilda-hist-verbo, .hist-entrou .guilda-hist-seta { color: #6fd3bd; }
.hist-saiu .guilda-hist-verbo, .hist-saiu .guilda-hist-seta { color: #ffa898; }
/*
 * A seta é pequena e não se mexe: ela é a mesma leitura da cor para quem não separa
 * verde de vermelho, e fica antes do nome porque é ali que o olho começa a linha.
 */
.guilda-hist-seta { flex: none; font-style: normal; font-size: 9px; line-height: 1; }
/* A legenda, uma vez em cima da lista — ver `ABAS_DO_HISTORICO`. */
.guilda-hist-legenda { display: flex; gap: 10px; flex-wrap: wrap; padding: 0 2px; }
.guilda-hist-chave {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 10px; color: #8e9699; text-transform: lowercase;
}
/*
 * O retrato tem tamanho fixo MESMO VAZIO: quem saiu ou foi expulso não está mais na
 * lista de membros e não tem boneco, e sem a caixa reservada a frase dessa linha
 * começaria 30px à esquerda das outras.
 */
.guilda-hist-retrato {
  flex: none; width: 30px; height: 30px;
  display: grid; place-items: center;
  border-radius: 3px;
  background: radial-gradient(circle at 50% 62%, #3fbfa81f, transparent 70%);
}
.guilda-hist-retrato canvas { image-rendering: pixelated; }
.guilda-hist-texto { flex: 1 1 auto; min-width: 0; }
.guilda-hist-frase { display: flex; align-items: baseline; gap: 5px; flex-wrap: wrap; min-width: 0; }
.guilda-hist-frase > b { color: #e6edee; font-weight: 600; }
.guilda-hist-frase > span { color: #8e9699; }
/* O ouro com a MOEDA do banco — o mesmo `itemCanvas(3031)` do resto do jogo. */
.guilda-hist-ouro { display: inline-flex; align-items: center; gap: 4px; flex: none; }
.guilda-hist-ouro canvas { image-rendering: pixelated; vertical-align: middle; }
.guilda-hist-ouro > b { color: #ffe1ad; }
/* A peça, na célula do inventário: ela não encolhe e não vira botão. */
.guilda-hist-linha > .cell { flex: none; cursor: default; }
.guilda-hist-quando { flex: none; font-style: normal; font-size: 10px; color: #6d757a; }

.guilda-diario-titulo {
  margin: 0;
  font-family: var(--font-title); font-size: 10px; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase;
  color: #8a6f42;
}
.guilda-diario-vazio { margin: 0; font-size: 11px; font-style: italic; color: #7b8386; }

/* ---- O placar, em cima da aba das contribuições ---- */
/*
 * O placar é o pódio da aba: moldura de ouro e um brilho baixo, o mesmo tratamento
 * que o 1º lugar recebe na tabela do servidor. Ele é a leitura rápida ("quem carrega
 * isto"), e a lista do tempo embaixo é a demorada.
 */
.guilda-placar {
  display: flex; flex-direction: column; gap: 4px;
  padding: 9px 11px;
  border: 1px solid #e0a84a3d; border-radius: 4px;
  background: linear-gradient(180deg, #e0a84a12, #0a0f1166);
  box-shadow: inset 0 1px 0 #ffffff0f, 0 0 20px -10px #e0a84a4d;
}
.guilda-placar-linha { background: none; padding: 2px 0; }
/*
 * As três primeiras na cor da medalha — as MESMAS do pódio do servidor. Quem já viu
 * o pódio reconhece o ouro e a prata sem precisar ler o número.
 */
.guilda-placar-pos {
  flex: none; width: 18px;
  font-family: var(--font-title); font-size: 10px; letter-spacing: .04em;
  color: #6d757a;
}
.guilda-placar-pos.lugar-1 { color: #ffe7a3; text-shadow: 0 0 8px #e0a84a73; }
.guilda-placar-pos.lugar-2 { color: #f4f7f8; }
.guilda-placar-pos.lugar-3 { color: #f1b98a; }

/* O link que abre o histórico de dentro da tela de contribuir. */
.doar-historico { margin: 0; }

/* =========================================================================
 * AS CARTAS — convites e pedidos
 *
 * Mesma linha do membro, com mais respiro: aqui há uma decisão a tomar, e uma
 * linha apertada com dois botões grudados é onde se clica em Recusar querendo
 * Aceitar.
 * ========================================================================= */
.guilda-carta {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px;
  border: 1px solid #8a6f4229; border-radius: 3px;
  background: linear-gradient(90deg, #e0a84a0f, #0a0f11cc 40%);
}
.guilda-carta-texto { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.guilda-carta-texto b { font-size: 13.5px; color: #ffe1ad; }
.guilda-carta-texto span { font-size: 11.5px; color: #8e9699; }
.guilda-carta-recado { font-size: 11.5px; color: #cbb388; font-style: italic; }

/* =========================================================================
 * O PÓDIO DAS TRÊS PRIMEIRAS — em pé, uma coisa por linha
 *
 * "três cards SEPARADOS, com espaço entre eles (gap ~12px), um pouco maiores que
 *  agora (~150-170px de altura). O 1º no meio, levemente maior/mais alto."
 *
 * ---- O DEFEITO QUE ELE TEVE, E QUE E' O MOTIVO DESTA FORMA ----
 *
 * Ele esteve DEITADO por uma versão: medalha, escudo e uma coluna de texto lado a
 * lado, para o card medir cem pixels de altura. O resultado foi o que ele viu —
 * "Golden eagles company0 PT1 membro". Numa coluna de 290px, o escudo de 58 mais a
 * medalha deixavam 200px para quatro informações; o nome comprido tomava a linha
 * toda com reticência e os números encostavam nele.
 *
 * Em pé, cada informação tem a LARGURA INTEIRA do card e uma linha só. Nada disputa
 * espaço horizontal, e por isso nada encosta em nada. O card volta a 150-170px, que
 * é o que seis linhas centradas pedem.
 *
 * ---- A ORDEM VISUAL E' 2º · 1º · 3º ----
 *
 * O `order` faz a troca: a lista chega ordenada do servidor, e reordená-la no
 * JavaScript só para desenhar faria a mesma lista ter duas ordens no mesmo arquivo.
 *
 * ---- AS CORES SAO AS DE POSTO DO SITE ----
 *
 * "borda e brilho sutil por posição: ouro, prata, bronze."
 *
 * São as mesmas três duplas do `.top5-item` de lá: `#e0a84a/#ffe7a3` no ouro,
 * `#b8c4c8/#f4f7f8` na prata e `#a9743d/#f1b98a` no bronze. Escritas como variáveis
 * por card, para a borda, o brilho e o número da posição saírem da mesma fonte —
 * três lugares com o mesmo hexadecimal escrito à mão é onde uma mudança futura pega
 * dois e esquece o terceiro.
 * ========================================================================= */
.guilda-podio {
  display: grid; grid-template-columns: 1fr 1.14fr 1fr;
  /* "com espaço entre eles (gap ~12px)" — eles eram 8px e pareciam colados. */
  align-items: end; gap: 12px;
}
/*
 * ---- MENOS DE TRES GUILDAS: CENTRALIZADAS ----
 *
 * "menos de 3 guildas: mostra só as que existem, centralizadas."
 *
 * `justify-content: center` sozinho não bastaria: com `1fr` as colunas comem a
 * largura toda e não há o que centralizar. As duas regras trocam as colunas por
 * larguras fixas — aí sobra espaço, e é ele que o `center` distribui.
 */
.guilda-podio:has(.lugar-1:only-child) { grid-template-columns: minmax(0, 260px); justify-content: center; }
.guilda-podio:has(.lugar-2):not(:has(.lugar-3)) {
  grid-template-columns: minmax(0, 240px) minmax(0, 270px);
  justify-content: center;
}

/*
 * ---- A ALTURA, E DE ONDE ELA VEM ----
 *
 * "~150-170px de altura."
 *
 * As seis linhas pedidas somam 146px de CONTEUDO num escudo de 56: a medalha (13),
 * o escudo (63 — 56 × 1,12), o nome (17), os números (16), o líder (13) e o pé com
 * o botão (24). Nada disso é folga; é o tamanho do que foi pedido.
 *
 * Por isso o enchimento e os vãos são pequenos (6px e 2px) e a entrelinha é 1,15:
 * eles são os únicos 25px que sobravam para cortar. O card fecha em ~171px no 2º e
 * no 3º — sete pixels acima da faixa, e o único jeito de descer mais seria encolher
 * o escudo abaixo dos 56 pedidos ou juntar duas das linhas.
 */
.guilda-podio-lugar {
  --medalha: #8e9699;
  --medalha-clara: #e6edee;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 6px 10px 7px;
  border: 1px solid #ffffff14; border-radius: 4px;
  background: linear-gradient(180deg, #0f1618e6, #0a0f11f2);
  line-height: 1.15;
  min-width: 0;
}
.guilda-podio-lugar.lugar-1 {
  order: 2;
  --medalha: #e0a84a; --medalha-clara: #ffe7a3;
  /*
   * "o 1º levemente maior/mais alto": quatro pixels de folga a mais em cima e
   * embaixo, e o escudo de 62 em vez de 56 (no JavaScript). São treze pixels de
   * diferença — o bastante para o card do meio se destacar com `align-items: end`,
   * que alinha os três pelo pé e faz a diferença toda aparecer no topo.
   */
  padding: 10px 12px 11px;
}
.guilda-podio-lugar.lugar-2 { order: 1; --medalha: #b8c4c8; --medalha-clara: #f4f7f8; }
.guilda-podio-lugar.lugar-3 { order: 3; --medalha: #a9743d; --medalha-clara: #f1b98a; }
/*
 * A borda e o brilho saem da medalha. O brilho é um `box-shadow` de raio grande com
 * espalhamento negativo (`-8px`): ele fica na vizinhança do card em vez de vazar por
 * cima do vizinho, que a doze pixels de distância é o que um halo comum faria.
 */
.guilda-podio-lugar {
  border-color: color-mix(in srgb, var(--medalha) 40%, transparent);
  box-shadow: inset 0 1px 0 #ffffff0f, 0 0 22px -8px color-mix(in srgb, var(--medalha) 34%, transparent);
}
.guilda-podio-lugar.eu { outline: 1px solid #3fbfa866; outline-offset: -1px; }

/* A medalha: o número da posição, na cor dela. */
.guilda-podio-pos {
  font-family: var(--font-title); font-size: 11.5px; letter-spacing: .08em;
  color: var(--medalha-clara);
  text-shadow: 0 0 8px color-mix(in srgb, var(--medalha) 45%, transparent);
}

/*
 * A FAMÍLIA do nome vem do `style` do nó (a fonte que a guilda escolheu) e o corte
 * com reticências vem da `.guilda-nome-fonte`, injetada pelo desenhista do brasão.
 * Aqui ficam só o tamanho, a cor e o alinhamento.
 */
.guilda-podio-nome {
  max-width: 100%; margin-top: 3px;
  font-size: 13.5px; color: #e6edee; text-align: center;
}
.guilda-podio-pontos { font-family: var(--font-title); font-size: 13px; color: #ffe1ad; }
/*
 * O líder corta com reticências: o nome dele não tem tamanho máximo pequeno, e um
 * nome comprido aqui empurraria o card — que é uma coluna de grade e não pode
 * crescer sem espremer os vizinhos.
 */
.guilda-podio-sub {
  max-width: 100%;
  font-size: 10.5px; color: #8e9699;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/*
 * O pé tem altura mesmo vazio: sem ele, o card de quem já tem guilda (rótulo em vez
 * de botão) ficaria mais baixo que os vizinhos, e três alturas diferentes não
 * parecem um pódio.
 */
.guilda-podio-pe { display: flex; align-items: center; min-height: 24px; margin-top: 3px; }
.guilda-podio-pe .guilda-mini { flex: none; }
.guilda-podio-minha {
  font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase;
  color: #6fe3c6;
}

/* =========================================================================
 * A TABELA
 * ========================================================================= */
/*
 * A linha que veio do menu do jogador nasce acesa: numa tabela de vinte guildas,
 * abrir na tabela certa ainda deixa a pessoa procurando qual era.
 */
.guilda-linha.apontada {
  border-color: #e0a84a99;
  background: #17201fcc;
  box-shadow: 0 0 0 1px #e0a84a33, 0 0 14px -4px #e0a84a4d;
}
.guilda-linha {
  display: flex; align-items: center; gap: 10px;
  padding: 5px 8px;
  border: 1px solid #ffffff0f; border-radius: 3px;
  background: #0a0f1180;
  min-width: 0;
}
.guilda-linha.eu { border-color: #3fbfa84d; background: #0d1a1a99; }
.guilda-pos { flex: none; width: 30px; font-family: var(--font-title); font-size: 11.5px; color: #8e9699; }
.guilda-linha-texto { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.guilda-linha-texto b {
  font-size: 13px; color: #e6edee;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.guilda-linha-texto span { font-size: 10.5px; color: #8e9699; }
.guilda-conta { flex: none; font-size: 11px; color: #8e9699; }
.guilda-pontos { flex: none; min-width: 52px; text-align: right; font-family: var(--font-title); font-size: 13px; color: #ffe1ad; }
/*
 * ---- O RESPIRO ENTRE OS PONTOS E O BOTAO ----
 *
 * "nas linhas, mais respiro entre 0 PT e o botão Pedir para entrar."
 *
 * O `gap` da linha é 10px e valia para todos os vizinhos, inclusive para o par
 * pontos/botão — que é o único em que os dois lados são do mesmo tamanho visual e
 * competem pelo olho. Um número grudado num botão parece um número clicável.
 *
 * A margem vale só quando o botão existe (quem tem guilda não vê nenhum), e por
 * isso ela mora no BOTAO e não nos pontos: pendurada nos pontos, ela abriria um
 * buraco no fim da linha de quem já tem guilda.
 */
.guilda-linha > .guilda-mini { flex: none; margin-left: 8px; }

/* =========================================================================
 * O ROLO DA LISTA — a rolagem sai da aba e entra na tabela
 *
 * "cabe sem scroll com até ~8 guildas visíveis em 1920x1080; mais que isso rola
 *  só a lista."
 *
 * Uma linha mede 52px (escudo de 40 mais 5px de folga em cima e embaixo, mais a
 * borda) e o `gap` da caixa é 8px: oito linhas dão 8×52 + 7×8 = 472px. É o teto de
 * cima do `clamp`.
 *
 * O `44vh` é o que evita o pior caso do número fixo: numa janela de 768px de
 * altura, 472px de lista não sobrariam para o pódio nem para a barra de fundar, e
 * a aba voltaria a rolar inteira — que é exatamente o que este bloco existe para
 * impedir. O piso de 220px garante quatro linhas mesmo numa janela baixa.
 *
 * `min-height: 0` é o de sempre: dentro de um container flex, um item com
 * `min-height: auto` não encolhe abaixo do conteúdo, e um item que não encolhe
 * nunca rola.
 * ========================================================================= */
.guilda-lista-rolo {
  display: flex; flex-direction: column; gap: 8px;
  /*
   * Duas medidas, e as duas precisam existir:
   *
   *   `max-height`  o TETO — oito linhas, e nem uma mais, mesmo numa tela alta em
   *                 que sobra espaço. Passar disso é uma lista que não acaba, e a
   *                 aba tem mais coisa embaixo dela.
   *
   *   `min-height`  o PISO — e é ele que deixa o rolo ENCOLHER. Um item flex tem
   *                 `min-height: auto`, que quer dizer "não fique menor que o meu
   *                 conteúdo": com doze guildas o rolo media os 472px do teto, a
   *                 aba estourava por três pixels e passava a rolar inteira,
   *                 levando o pódio embora — o contrário do pedido. Com um piso em
   *                 pixels ele cede os pixels que faltam, e quem rola é a lista.
   *
   * Sem `flex-grow`: o tamanho natural do rolo já é a altura das linhas, e crescer
   * além disso abriria um vão embaixo da última linha numa lista curta.
   */
  min-height: 96px;
  max-height: clamp(220px, 44vh, 472px);
  overflow-y: auto; overflow-x: hidden;
  /* O espaço da barra de rolagem, para a linha não encostar nela quando ela aparece. */
  scrollbar-gutter: stable;
}
/*
 * O painel que segura o rolo tem de poder encolher, e `min-height: auto` (o padrão
 * de um item flex) diz o contrário: "não fique menor que o meu conteúdo". Um
 * painel que não encolhe empurra a área que rola, e é a ABA que passa a rolar.
 * Ver a mesma nota em `.modal-box.guilda #modal-body`.
 */
.guilda-painel:has(> .guilda-lista-rolo) { min-height: 0; }

/* =========================================================================
 * OS MEMBROS EM GRADE
 *
 * "lista em grade de 2–3 colunas (auto-fill, minmax ~260px)."
 *
 * Era uma coluna só, e uma guilda de trinta pessoas virava uma tira de trinta
 * linhas que só se lê rolando. Em grade, as mesmas trinta cabem em dez linhas —
 * e a pergunta que se faz aqui ("quem está online?") passa a ser respondida de
 * uma olhada em vez de uma varredura.
 *
 * `auto-fill` com `minmax` e não um número fixo de colunas: a janela vai de 900
 * a 96vw, e a caixa de trocar brasão é mais estreita ainda. Com o mínimo em
 * 260px, a grade escolhe sozinha quantas cabem — três na janela larga, uma no
 * celular — sem nenhum ponto de corte inventado.
 * ========================================================================= */
.guilda-membros {
  display: grid; gap: 7px;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  align-content: start;
}

/*
 * O RODAPE MORREU. Ele tinha "Mudar o brasao", "Desfazer a guilda" ou "Sair da
 * guilda" e um paragrafo explicando por que um deles estava apagado — gestos
 * que se faz uma vez na vida da guilda, no pe de uma tela que se abre todo dia.
 * Eles moram no menu da engrenagem, no canto do card. Ver `.guilda-menu`.
 */

/* =========================================================================
 * TELA ESTREITA
 *
 * Os mesmos cortes da arena, pelo mesmo motivo: a moldura encolhe para 28/20 e
 * a cópia de cima tem de acompanhar, senão ela desenha uma moldura de tamanho
 * de computador por cima da encolhida.
 * ========================================================================= */
@media (max-width: 720px) {
  .modal-box.guilda {
    width: 96vw;
    padding: 4px 6px 6px;
    /*
     * Mais estreita ainda, e a fatia continua sendo a da ARTE: o que encolhe é
     * sempre a largura. A linha `border-image-slice` que havia aqui foi tirada
     * — ela reapontava o corte para 66/41/60/42, medidas de OUTRA moldura, e
     * cortava o ornamento desta pelo meio.
     */
    border-width: 26px 22px 32px 22px;
  }
  /*
   * O cabeçalho aqui era um retrato do antigo: `top` negativo, cada peça com um
   * `right` em pixels, e o pill. Nada disso existe mais — o cabeçalho é um
   * `flex` no fluxo, e `top`/`right` não fazem nada num elemento estático.
   *
   * O que sobra a dizer numa tela estreita é só o TAMANHO das peças. Quem
   * decide onde elas ficam é o `flex`, e ele já quebra a linha sozinho quando
   * as abas não cabem.
   */
  /*
   * Na tela estreita a moldura tem 22px de lado e a faixa 26 de altura: os
   * botões encolhem para caber nela, e o enchimento continua saindo das
   * variáveis da moldura (ver o cabeçalho lá em cima).
   */
  .modal-box.guilda > header { gap: 5px; }
  .modal-box.guilda > header #modal-close { width: 22px; height: 22px; font-size: 13px; }
  .guilda-acao { height: 22px; padding: 0 8px; font-size: 10px; }
  .guilda-acao.so-icone { width: 22px; font-size: 13px; }
  .guilda-estandarte { grid-template-columns: auto 1fr; gap: 10px; padding: 10px; }
  .guilda-numeros { grid-column: 1 / -1; }
  .guilda-estandarte-texto h3 { font-size: 17px; }
  .guilda-podio { grid-template-columns: 1fr; }
  .guilda-podio-lugar.lugar-1, .guilda-podio-lugar.lugar-2, .guilda-podio-lugar.lugar-3 { order: 0; }
}

/* =========================================================================
 * O PRÊMIO DO PÓDIO SEMANAL
 *
 * "quem esta no top 1 da arena x1 na semana ganha 8% de bonus de xp e 8% de
 *  bonus loot, top 2 5% de cada e top 3 3% de cada."
 *
 * Três pastilhas, nas cores de medalha: ouro, prata e bronze. Elas ficam no
 * cabeçalho da página de ranking e aparecem MESMO com a tabela vazia — é assim
 * que quem nunca duelou descobre que há o que ganhar.
 * ========================================================================= */
.arena-semana-relogio {
  margin: 4px 0 0;
  font-family: var(--font-title); font-size: 11.5px; letter-spacing: .04em;
  color: #e0a84a;
}
.arena-premios {
  display: flex; flex-wrap: wrap; gap: 6px;
  margin-top: 8px;
  cursor: default;
}
.arena-premio {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 10px 3px 7px;
  border: 1px solid #ffffff1f; border-radius: 999px;
  background: #0a0f1199;
  font-size: 11px; color: #9aa3a6;
  white-space: nowrap;
}
.arena-premio b {
  font-family: var(--font-title); font-size: 12px; line-height: 1;
}
/* As três cores de medalha, as mesmas do pódio logo abaixo. */
.arena-premio.lugar-1 { border-color: #e0a84a66; background: #1a140a99; }
.arena-premio.lugar-1 b { color: #ffcf8a; }
.arena-premio.lugar-2 { border-color: #b8c4c866; }
.arena-premio.lugar-2 b { color: #dfe8ee; }
.arena-premio.lugar-3 { border-color: #a9743d66; }
.arena-premio.lugar-3 b { color: #e0a06a; }

/*
 * O prêmio dentro do card do pódio, embaixo dos pontos.
 *
 * Em fonte pequena e cor apagada de propósito: o nome e os pontos são o que se
 * lê primeiro; isto é a legenda, e ela só precisa estar lá quando o olho
 * descer.
 */
.arena-podio-premio {
  margin-top: 2px;
  font-size: 10px; letter-spacing: .02em;
  color: #8fbf9f;
  white-space: nowrap;
}
.arena-podio-card.lugar-1 .arena-podio-premio { color: #a8e0b8; }


/* =========================================================================
 * O MERCADO DE 29/09 — abas na barra de título, três colunas, rodapé fixo
 *
 * O contorno é o `padrao.png` de toda janela (teal), nunca o dourado do
 * mockup. A raridade pinta a MOLDURA do ícone e o nome com a mesma variável
 * `--tier` do inventário e do balão (`.tier-*`). Texto mínimo 12px.
 * ========================================================================= */
.modal-box.mercado { width: min(1280px, 96vw); height: min(780px, 92vh); }
.modal-box.mercado #modal-body { display: flex; flex-direction: column; flex: 1; min-height: 0; padding: 8px 12px 10px; overflow: hidden; }
.modal-box.mercado #modal-acoes { flex: 1 1 auto; margin-right: 6px; }
.mercado-abas.tabs { margin: 0; border-bottom: none; gap: 4px; }
.mercado-abas.tabs button { flex: 0 0 auto; flex-direction: row; gap: 6px; padding: 4px 12px; font-size: 11px; border-radius: 6px; border-bottom: 1px solid var(--line); margin: 0; }
.mercado-abas.tabs button > img { width: 18px; height: 18px; }
.mercado-abas.tabs button[aria-selected="true"] { box-shadow: inset 0 -2px 0 var(--accent); }

.mercado { display: flex; flex-direction: column; flex: 1; min-height: 0; }
.mercado-miolo { flex: 1; min-height: 0; overflow: hidden; display: flex; flex-direction: column; }
.mercado-rodape {
  flex: none; display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 8px 4px 0; margin-top: 8px; border-top: 1px solid var(--line);
}
.mercado-saldos { display: flex; gap: 8px; flex-wrap: wrap; }
.mercado-saldo {
  display: flex; align-items: center; gap: 6px; padding: 5px 11px;
  border: 1px solid var(--line); border-radius: 6px; background: #1b2426;
}
.mercado-saldo b { font-family: var(--font-numero); font-size: 15px; }
.mercado-saldo canvas, .mercado-saldo img { width: 22px; height: 22px; flex: none; image-rendering: pixelated; }
.mercado-saldo.gold b { color: var(--copper); }
.mercado-saldo.coin b { color: var(--accent); }
.mercado-saldo span { font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.mercado-saldo.ganho b { color: var(--hp); }
.mercado-saldo.gasto b { color: var(--danger); }
.mercado-anunciar {
  padding: 8px 16px; border: 1px solid var(--accent-dim); border-radius: 6px; background: linear-gradient(180deg, #16241f, #0f1a16);
  color: var(--accent); font-family: var(--font-heading); font-size: 12px; font-weight: 700; letter-spacing: .05em; cursor: pointer; white-space: nowrap;
}
.mercado-anunciar:hover { border-color: var(--accent); background: #1a2e27; }

/* ---- a aba Itens: três colunas ---- */
.mercado-itens { display: grid; grid-template-columns: 224px 250px minmax(0, 1fr); gap: 10px; flex: 1; min-height: 0; }
.mercado-itens.arvore-recolhida { grid-template-columns: 224px 250px minmax(0, 1fr); }
.mercado-col { min-height: 0; display: flex; flex-direction: column; gap: 8px; }
.mercado-barrinha { display: none; grid-column: 1 / -1; gap: 6px; }
.mercado-gaveta-botao { padding: 6px 12px; border: 1px solid var(--line); border-radius: 6px; background: #1b2426; color: var(--accent); font: inherit; font-size: 12px; cursor: pointer; }

/* coluna 1 */
.mercado-filtros { overflow-y: auto; padding-right: 4px; }
.mercado-busca { width: 100%; box-sizing: border-box; padding: 8px 10px; font-size: 13px; }
.mercado-secao-titulo { display: flex; align-items: center; justify-content: space-between; font-family: var(--font-heading); font-size: 12px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.mercado-recolher { padding: 0 6px; border: 1px solid var(--line); border-radius: 4px; background: none; color: var(--muted); cursor: pointer; font-size: 12px; }
.mercado-arvore { display: grid; gap: 1px; padding: 4px; border: 1px solid var(--line-soft); border-radius: 6px; background: #1b2426; }
.arvore-recolhida .mercado-arvore { display: none; }
.mercado-categoria {
  display: flex; align-items: center; gap: 6px; padding: 5px 6px; border: 1px solid transparent; border-radius: 5px;
  background: none; color: var(--text); font: inherit; font-size: 13px; text-align: left; cursor: pointer; min-width: 0;
}
.mercado-categoria span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mercado-categoria canvas { flex: none; width: 20px; height: 20px; image-rendering: pixelated; }
.mercado-categoria:hover { border-color: var(--line); }
.mercado-categoria.on { color: var(--accent); background: #16241f; border-color: var(--accent-dim); }
.mercado-categoria.filha { padding-left: 26px; font-size: 12px; color: var(--muted); }
.mercado-categoria.filha.on { color: var(--accent); }
.mercado-seta { flex: none; width: 12px; font-style: normal; font-size: 11px; color: var(--muted); }
.mercado-seta.vazia { visibility: hidden; }
.mercado-rapidos { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.mercado-liga {
  padding: 6px 8px; border: 1px solid var(--line); border-radius: 5px; background: #1b2426; color: var(--muted);
  font: inherit; font-size: 12px; cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.mercado-liga:hover { border-color: var(--accent-dim); color: var(--text); }
.mercado-liga.on { border-color: var(--accent); color: var(--accent); background: #16241f; }
.mercado-par-botoes { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.mercado-seletor { display: grid; gap: 3px; font-size: 12px; }
.mercado-seletor select, .mercado-preco-campo {
  padding: 6px 8px; border: 1px solid var(--line); border-radius: 5px; background: var(--panel-solid); color: var(--text); font: inherit; font-size: 12px; width: 100%; box-sizing: border-box;
}
.mercado-rotulo { font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.mercado-caixa { display: flex; align-items: center; gap: 8px; font-size: 12px; cursor: pointer; }
.mercado-caixa input { accent-color: var(--accent); }
.mercado-moedas { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.mercado-moeda-chip {
  display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; border: 1px solid var(--line-soft); border-radius: 999px;
  background: #1b2426; color: var(--muted); cursor: pointer; font: inherit;
}
.mercado-moeda-chip canvas, .mercado-moeda-chip img { width: 16px; height: 16px; flex: none; image-rendering: pixelated; opacity: .75; }
.mercado-moeda-chip b { font-size: 12px; }
.mercado-moeda-chip.on { border-color: var(--accent-dim); color: var(--text); background: rgba(88, 160, 130, .1); }
.mercado-moeda-chip.on canvas, .mercado-moeda-chip.on img { opacity: 1; }
.mercado-limpar { padding: 7px 10px; border: 1px solid var(--line); border-radius: 5px; background: none; color: var(--muted); font: inherit; font-size: 12px; cursor: pointer; }
.mercado-limpar:hover { border-color: var(--danger); color: var(--danger); }

/* coluna 2 */
.mercado-lista-topo .mercado-seletor { grid-template-columns: auto 1fr; align-items: center; gap: 8px; }
.mercado-lista { flex: 1; min-height: 0; overflow-y: auto; display: grid; gap: 4px; align-content: start; padding-right: 3px; }
.mercado-lista-conta { font-size: 11px; color: var(--muted); text-align: right; }
.mercado-item-linha {
  display: flex; align-items: center; gap: 9px; padding: 6px 8px; border: 1px solid var(--line-soft); border-radius: 6px;
  background: #1b2426; color: var(--text); font: inherit; text-align: left; cursor: pointer; min-width: 0;
}
.mercado-item-linha:hover { border-color: var(--line); background: #22302f; }
.mercado-item-linha.on { border-color: var(--accent); background: #16241f; box-shadow: inset 2px 0 0 var(--accent); }
.mercado-item-texto { display: grid; gap: 2px; min-width: 0; flex: 1; }
.mercado-item-texto b { font-size: 13px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mercado-item-texto em { font-style: normal; font-size: 12px; color: var(--muted); }
.mercado-item-sub { display: flex; justify-content: space-between; gap: 6px; font-size: 12px; color: var(--muted); }
.mercado-preco-curto { display: inline-flex; align-items: center; gap: 4px; }
.mercado-preco-curto em { font-style: normal; color: var(--muted); }
.mercado-preco-curto canvas, .mercado-preco-curto img { width: 16px; height: 16px; image-rendering: pixelated; }
.mercado-preco-curto b { font-family: var(--font-numero); color: var(--copper); }
.mercado-vazio { padding: 24px 10px; text-align: center; color: var(--muted); display: grid; gap: 10px; justify-items: center; }

/* a moldura de raridade */
.mercado-moldura {
  --tam: 32px; position: relative; display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: var(--tam); height: var(--tam); border: 1px solid var(--tier, var(--line)); border-radius: 5px; background: #0b1113;
}
.mercado-moldura canvas { width: calc(var(--tam) - 4px); height: calc(var(--tam) - 4px); image-rendering: pixelated; }
.mercado-moldura.raridade::before { content: ""; position: absolute; inset: -1px; border-radius: 5px; box-shadow: 0 0 7px -1px var(--tier); pointer-events: none; }
.mercado-moldura.tier-epico::before, .mercado-moldura.tier-lendario::before, .mercado-moldura.tier-mitico::before { box-shadow: 0 0 11px -1px var(--tier), 0 0 3px -1px var(--tier); }
.mercado-moldura .selo-afixo { position: absolute; right: -2px; top: -6px; font-size: 10px; line-height: 1; }
b.tier-comum, b.tier-incomum, b.tier-raro, b.tier-epico, b.tier-lendario, b.tier-mitico { color: var(--tier); }

/* coluna 3 */
.mercado-detalhe { overflow-y: auto; padding-right: 4px; gap: 6px; }
.mercado-escolha-um { margin: auto; text-align: center; color: var(--muted); font-size: 13px; }
.mercado-cabeca { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; padding: 10px; border: 1px solid var(--line-soft); border-radius: 8px; background: #1b2426; }
.mercado-cabeca-item { display: flex; align-items: center; gap: 12px; min-width: 0; }
.mercado-cabeca-texto { display: grid; gap: 4px; min-width: 0; }
.mercado-cabeca-texto b { font-size: 16px; font-family: var(--font-heading); }
.mercado-cabeca-info { font-size: 12px; color: var(--muted); }
.mercado-cartoes { display: flex; gap: 8px; }
.mercado-cartao { display: grid; gap: 3px; justify-items: center; padding: 8px 12px; border: 1px solid var(--line-soft); border-radius: 6px; background: #24312f; min-width: 110px; }
.mercado-cartao span { font-size: 11px; color: var(--muted); text-align: center; }
.mercado-cartao b { font-family: var(--font-numero); font-size: 15px; color: var(--copper); }
.mercado-secao { margin: 8px 0 2px; font-family: var(--font-heading); font-size: 13px; letter-spacing: .06em; text-transform: uppercase; color: var(--accent); }

.mercado-tabela { display: grid; gap: 6px; }
.mercado-tabela-filtros { display: flex; gap: 8px; flex-wrap: wrap; }
.mercado-tabela-filtros .mercado-seletor { grid-template-columns: auto 1fr; align-items: center; gap: 6px; min-width: 150px; }
.mercado-grade { display: grid; gap: 0; border: 1px solid var(--line-soft); border-radius: 6px; overflow: hidden; background: #1b2426; min-width: 0; }
.mercado-corpo { display: grid; max-height: 320px; overflow-y: auto; }
.mercado-tr { display: grid; align-items: center; gap: 8px; padding: 6px 8px; border-top: 1px solid var(--line-soft); font-size: 12px; min-width: 0; }
.mercado-corpo .mercado-tr:nth-child(even) { background: #1f2a2c; }
.mercado-tr:hover { background: #24322f; }
.mercado-tr:focus-visible, .mercado-item-linha:focus-visible, .mercado-mini:focus-visible, .mercado-escolha:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.mercado-tr.on { background: #16241f; box-shadow: inset 2px 0 0 var(--accent); }
.mercado-tr.minha { box-shadow: inset 2px 0 0 var(--accent-dim); }
.mercado-tr.cabeca { position: sticky; top: 0; z-index: 1; background: #141a1c; border-top: none; font-family: var(--font-heading); font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.mercado-tabela.unicos.sell .mercado-tr { grid-template-columns: 22px minmax(90px, 1fr) 32px minmax(110px, 1.3fr) 56px minmax(56px, .6fr) 104px 58px 78px; gap: 6px; }
.mercado-tr.cabeca span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mercado-tabela.unicos.buy .mercado-tr { grid-template-columns: 28px minmax(120px, 1fr) 130px 90px 88px; }
.mercado-tabela.empilhavel .mercado-tr { grid-template-columns: 28px minmax(120px, 1fr) 90px 120px 130px 80px; cursor: pointer; }
.mercado-grade.minhas .mercado-tr { grid-template-columns: minmax(150px, 1.4fr) 40px minmax(140px, 1.2fr) 56px 120px 80px 74px 90px; }
.mercado-grade.coins-minhas .mercado-tr { grid-template-columns: minmax(120px, 1fr) 80px 120px 130px 80px 90px; }
.mercado-grade.hist .mercado-tr { grid-template-columns: 90px minmax(160px, 1.5fr) minmax(90px, .8fr) 130px; }
.mercado-ordena { cursor: pointer; display: flex; align-items: center; gap: 4px; }
.mercado-ordena:hover { color: var(--text); }
.mercado-ordena.ordenando { color: var(--accent); }
.mercado-ordena i { font-style: normal; font-size: 8px; }
.mercado-n { color: var(--muted); font-family: var(--font-numero); }
.mercado-td-item { display: flex; align-items: center; gap: 8px; min-width: 0; }
.mercado-td-item b { font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mercado-td-item em { font-style: normal; font-size: 12px; color: var(--muted); }
.mercado-tier { display: inline-block; padding: 1px 6px; border-radius: 3px; font-family: var(--font-numero); font-size: 12px; background: #3a2a12; color: #e0a94a; border: 1px solid #5c4319; justify-self: start; }
.mercado-tier.vazio { background: none; color: var(--muted); border-color: var(--line); }
.mercado-afixos { display: grid; gap: 1px; min-width: 0; }
.mercado-afixos .tip-afixo { display: flex; align-items: center; gap: 6px; font-size: 12px; padding: 0; }
.mercado-afixos .tip-afixo > span:first-child { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mercado-afixos em, .mercado-imbues em { font-style: normal; color: var(--muted); }
.mercado-mais { font-size: 11px; color: var(--accent); }
.mercado-imbues { display: flex; align-items: center; gap: 3px; }
.mercado-imbues img { width: 18px; height: 18px; image-rendering: pixelated; }
.mercado-imbu-vazio { display: inline-block; width: 16px; height: 16px; border: 1px dashed var(--line); border-radius: 3px; }
.mercado-imbu-ponto { font-style: normal; color: #57b6c8; }
.mercado-quem { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mercado-quem.anonimo { font-style: italic; color: var(--muted); }
.mercado-anonimo-marca { font-size: 11px; color: var(--muted); font-style: italic; }
.mercado-preco { display: inline-flex; align-items: center; gap: 5px; justify-self: end; white-space: nowrap; }
.mercado-preco canvas, .mercado-preco img { width: 18px; height: 18px; flex: none; image-rendering: pixelated; }
.mercado-preco b { font-family: var(--font-numero); font-size: 13px; color: var(--copper); }
.mercado-preco.entrada b { color: var(--hp); }
.mercado-preco.saida b { color: var(--danger); }
.mercado-expira { color: var(--muted); white-space: nowrap; font-variant-numeric: tabular-nums; }
.mercado-qtd { font-family: var(--font-numero); text-align: right; }
.mercado-botao {
  padding: 6px 10px; border: 1px solid transparent; border-radius: 5px; font-family: var(--font-heading); font-size: 11px; font-weight: 700;
  letter-spacing: .05em; text-transform: uppercase; cursor: pointer; white-space: nowrap; justify-self: end;
}
.mercado-botao.comprar { background: linear-gradient(#2f8f62, #1f6a48); color: #eafff2; }
.mercado-botao.vender { background: linear-gradient(#d2913f, #a9662a); color: #1a1207; }
.mercado-botao.confirmar { background: linear-gradient(#2f8f62, #1f6a48); color: #eafff2; padding: 10px 14px; font-size: 12px; width: 100%; justify-self: stretch; }
.mercado-botao.cancelar { background: none; border-color: var(--line); color: var(--muted); }
.mercado-botao.cancelar:hover { border-color: var(--danger); color: var(--danger); }
.mercado-botao:hover:not(:disabled) { filter: brightness(1.12); }
.mercado-botao:disabled { background: none; border-color: var(--line); color: #556065; cursor: not-allowed; filter: none; }
.mercado-minha-marca { font-size: 11px; color: var(--accent-dim); justify-self: end; }
.mercado-quantidade { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 8px 10px; border: 1px solid var(--line-soft); border-radius: 6px; background: #24312f; }
.mercado-quantidade input[type="range"] { flex: 1 1 140px; accent-color: var(--accent); }
.mercado-quantidade-total { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; }
.mercado-quantidade .num-campo { margin: 0; }

/* criar oferta */
.mercado-criar { display: grid; gap: 8px; padding: 10px; border: 1px solid var(--line-soft); border-radius: 8px; background: #1b2426; margin-top: 6px; }
.mercado-criar .mercado-secao { margin: 0; }
.mercado-criar .mercado-par-botoes { max-width: 260px; }
.mercado-criar-corpo { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(220px, .8fr); gap: 14px; }
.mercado-criar-esquerda { display: grid; gap: 8px; align-content: start; }
.mercado-criar-direita { display: grid; gap: 8px; align-content: start; padding: 10px; border: 1px solid var(--line-soft); border-radius: 6px; background: #24312f; }
.mercado-mini-grade { display: flex; flex-wrap: wrap; gap: 6px; }
.mercado-mini { position: relative; display: inline-flex; padding: 3px; border: 1px solid var(--line); border-radius: 6px; background: #0b1113; cursor: pointer; }
.mercado-mini.on { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.mercado-mini-tier { position: absolute; right: -3px; bottom: -4px; padding: 0 4px; border-radius: 3px; font-style: normal; font-family: var(--font-numero); font-size: 10px; background: #3a2a12; color: #e0a94a; border: 1px solid #5c4319; }
.mercado-resumo-da-peca { display: grid; gap: 2px; padding: 6px 8px; border: 1px solid var(--line-soft); border-radius: 6px; background: #141a1c; font-size: 12px; }
.mercado-resumo-da-peca .tip-afixo { display: flex; justify-content: space-between; gap: 8px; }
.mercado-resumo-da-peca em { font-style: normal; color: var(--muted); }
.mercado-sugestao { font-size: 12px; color: var(--muted); }
.mercado-link { background: none; border: none; padding: 0; color: var(--accent); font: inherit; font-size: 12px; cursor: pointer; text-decoration: underline dotted; }
.mercado-conta { display: grid; gap: 4px; }
.mercado-conta-linha { display: flex; justify-content: space-between; gap: 8px; font-size: 12px; color: var(--muted); }
.mercado-conta-linha.total { font-size: 13px; color: var(--text); border-top: 1px solid var(--line-soft); padding-top: 4px; }
.mercado-conta-linha .mercado-preco b { font-size: 13px; }
.mercado-erro { margin: 0; font-size: 12px; color: var(--danger); }
.mercado-erro[hidden] { display: none; }
.mercado-nota { margin: 0; font-size: 12px; color: var(--muted); line-height: 1.45; }
.mercado-aviso { margin: 0; font-size: 12px; color: #e0a84a; }

/* caixas */
.mercado-caixa-confirmar { max-width: 560px; width: 92vw; }
.mercado-caixa-miolo { display: grid; gap: 10px; margin: 8px 0 12px; }
.mercado-confirma-item { display: flex; align-items: center; gap: 10px; }
.mercado-confirma-texto { display: grid; gap: 4px; }
.mercado-confirma-texto b { font-size: 14px; }
.mercado-confirma-marcas { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; font-size: 12px; }
.mercado-confirma-marcas .tip-afixo { display: inline-flex; gap: 4px; }
.mercado-confirma-total { display: flex; justify-content: space-between; font-size: 13px; }
.mercado-escolher { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 6px; max-height: 46vh; overflow-y: auto; padding: 2px; }
.mercado-escolha { display: flex; align-items: center; gap: 8px; padding: 6px 8px; border: 1px solid var(--line-soft); border-radius: 5px; background: #1b2426; color: var(--text); font: inherit; text-align: left; cursor: pointer; min-width: 0; }
.mercado-escolha:hover { border-color: var(--accent); }

/* coins, minhas e histórico */
.mercado-coins, .mercado-minhas, .mercado-historico { overflow-y: auto; flex: 1; min-height: 0; padding-right: 4px; display: grid; gap: 8px; align-content: start; }
.balcao-cambio-nota.ambar { border-left-color: #e0a84a; background: rgba(224, 168, 74, .07); }
.balcao-cambio-nota.ambar p { color: #e0b46a; font-size: 12px; }
.mercado-coins .balcao-cambio { align-items: stretch; }
.mercado-coins .balcao-coluna { grid-template-rows: auto 1fr auto; }
.mercado-coins .balcao-tabela.coins { min-height: 0; }
.mercado-coins .balcao-coin-preco, .mercado-coins .balcao-coin-total { white-space: nowrap; }
.mercado-saldos.hist { justify-content: center; }
.hist-filtro { max-width: 420px; grid-template-columns: repeat(4, 1fr); }

/* ---- responsivo: gavetas ---- */
@media (max-width: 1200px) {
  .mercado-itens { grid-template-columns: 250px minmax(0, 1fr); }
  .mercado-barrinha { display: flex; }
  .mercado-filtros { display: none; }
  .mercado-itens.gaveta-filtros .mercado-filtros { display: flex; position: absolute; left: 8px; top: 48px; bottom: 60px; width: 240px; z-index: 5; background: #141a1c; border: 1px solid var(--accent-dim); border-radius: 8px; padding: 10px; }
  .mercado-barrinha .mercado-gaveta-botao:nth-child(2) { display: none; }
}
@media (max-width: 900px), (max-height: 540px) and (pointer: coarse) {
  .mercado-itens { grid-template-columns: minmax(0, 1fr); }
  .mercado-lista-coluna { display: none; }
  .mercado-itens.gaveta-itens .mercado-lista-coluna { display: flex; position: absolute; left: 8px; top: 48px; bottom: 60px; width: min(320px, 90vw); z-index: 5; background: #141a1c; border: 1px solid var(--accent-dim); border-radius: 8px; padding: 10px; }
  .mercado-barrinha .mercado-gaveta-botao:nth-child(2) { display: inline-flex; }
  .mercado-tabela.unicos.sell .mercado-tr { grid-template-columns: 24px minmax(120px, 1.3fr) 40px minmax(120px, 1.2fr) minmax(70px, .8fr) 110px 84px; }
  .mercado-tabela.unicos.sell .mercado-tr > .mercado-imbues, .mercado-tabela.unicos.sell .mercado-tr > .mercado-expira,
  .mercado-tabela.unicos.sell .mercado-tr.cabeca > span:nth-child(5), .mercado-tabela.unicos.sell .mercado-tr.cabeca > span:nth-child(8) { display: none; }
  .mercado-tabela.unicos.buy .mercado-tr { grid-template-columns: 24px minmax(100px, 1fr) 120px 84px; }
  .mercado-tabela.unicos.buy .mercado-tr > .mercado-expira, .mercado-tabela.unicos.buy .mercado-tr.cabeca > span:nth-child(4) { display: none; }
  .mercado-tabela.empilhavel .mercado-tr { grid-template-columns: 24px minmax(100px, 1fr) 70px 110px 110px; }
  .mercado-tabela.empilhavel .mercado-tr > .mercado-expira, .mercado-tabela.empilhavel .mercado-tr.cabeca > span:nth-child(6) { display: none; }
  .mercado-criar-corpo { grid-template-columns: 1fr; }
  .mercado-cabeca { flex-direction: column; align-items: flex-start; }
}

/* Mercado, 29/09 à noite: essência na árvore, quantidade numa linha, "você tem" */
.mercado-categoria .afixo-essencia-arte { flex: none; width: 20px; height: 20px; opacity: 1; }
.mercado-categoria .afixo-essencia-arte img { width: 18px; height: 18px; }
.mercado-quantidade { flex-wrap: nowrap; gap: 8px; }
.mercado-quantidade .mercado-rotulo { white-space: nowrap; }
.mercado-quantidade .num-entrada { width: 76px; }
.mercado-quantidade input[type="range"] { flex: 1 1 80px; min-width: 60px; }
.mercado-quantidade .mercado-quantidade-total { white-space: nowrap; }
.mercado-criar .num-campo { display: flex; align-items: center; gap: 8px; }
.mercado-criar .num-campo .num-rotulo { white-space: nowrap; }
.mercado-tenho { color: var(--accent); }
.mercado-imbues img { width: 20px; height: 20px; image-rendering: pixelated; vertical-align: middle; }
@media (max-width: 900px), (max-height: 540px) and (pointer: coarse) { .mercado-quantidade { flex-wrap: wrap; } }

/* Mercado, 29/09 à noite: "+N" no Histórico e o botão de Mineiroidle Coins */
.mercado-badge { margin-left: 4px; padding: 0 5px; border-radius: 8px; font-style: normal; font-family: var(--font-numero); font-size: 10px; line-height: 14px; background: var(--accent); color: #0b1113; }
.mercado-coins-botao { display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%; padding: 7px 10px; margin: 2px 0 6px; border-radius: 6px; border: 1px solid #c9a14a; background: linear-gradient(180deg, #4a3a14, #2a2110); color: #ffd97a; font-family: var(--font-heading); font-size: 12px; letter-spacing: .08em; text-transform: uppercase; cursor: pointer; animation: mercado-brilho 2.2s ease-in-out infinite; }
.mercado-coins-botao img { width: 20px; height: 20px; }
.mercado-coins-botao:hover { filter: brightness(1.15); }
@keyframes mercado-brilho { 0%, 100% { box-shadow: 0 0 6px rgba(255, 200, 90, .25), inset 0 0 6px rgba(255, 220, 120, .1); } 50% { box-shadow: 0 0 16px rgba(255, 210, 100, .6), inset 0 0 8px rgba(255, 220, 120, .2); } }

/* Mercado, 29/09 à noite (2): cards ao lado do nome, "Pago em" em destaque, menu de categorias, barra do câmbio */
.mercado-cabeca { flex-wrap: nowrap; }
.mercado-cabeca-item { flex: 1 1 auto; }
.mercado-cabeca-texto b { font-size: 14px; }
.mercado-cabeca-info { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mercado-cartoes { flex: none; gap: 6px; }
.mercado-cartao { padding: 4px 8px; min-width: 72px; gap: 1px; }
.mercado-cartao span { font-size: 10px; }
.mercado-cartao b { font-size: 13px; }
.mercado-moedas.destaque { justify-content: center; padding: 6px; margin: 0 0 6px; border: 1px solid var(--line-soft); border-radius: 6px; background: #1b2426; }
.mercado-moedas.destaque .mercado-rotulo { font-family: var(--font-heading); text-transform: uppercase; letter-spacing: .08em; font-size: 11px; }
.mercado-moedas.destaque .mercado-moeda-chip { padding: 5px 10px; }
.mercado-moedas.destaque .mercado-moeda-chip.on { box-shadow: 0 0 0 1px var(--accent), 0 0 8px rgba(88, 160, 130, .45); }
.mercado-categoria-menu { display: flex; align-items: center; justify-content: space-between; gap: 6px; width: 100%; padding: 7px 10px; border: 1px solid var(--line); border-radius: 6px; background: #1b2426; color: var(--text); font: inherit; font-size: 12px; cursor: pointer; text-align: left; }
.mercado-categoria-menu:hover, .mercado-categoria-menu.aberto { border-color: var(--accent-dim); }
.mercado-categoria-menu .mercado-seta { flex: none; }
.mercado-trilha { display: flex; align-items: center; gap: 4px; min-width: 0; flex-wrap: wrap; }
.mercado-trilha b { font-weight: 600; }
.mercado-trilha b:first-child { color: var(--muted); font-family: var(--font-heading); text-transform: uppercase; letter-spacing: .08em; font-size: 11px; }
.mercado-trilha-seta { font-style: normal; color: var(--muted); }
.mercado-categoria-menu + .mercado-arvore { max-height: 44vh; overflow-y: auto; }
.mercado-outra-moeda { color: var(--muted); font-style: italic; }
.negocio-barra { width: 100%; accent-color: var(--accent); margin: 2px 0 6px; }

/* Mercado, 29/09 à noite (3): o menu de categorias por cima, "Pago em" em grade, sublinha da lista */
.mercado-filtros { position: relative; }
.mercado-categoria-menu + .mercado-arvore { position: absolute; left: 0; right: 0; z-index: 5; max-height: 56vh; overflow-y: auto; box-shadow: 0 10px 24px rgba(0, 0, 0, .55); border-color: var(--accent-dim); }
.mercado-moedas.destaque { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.mercado-moedas.destaque .mercado-rotulo { grid-column: 1 / -1; text-align: center; }
.mercado-moedas.destaque .mercado-moeda-chip { justify-content: center; }
.mercado-item-sub { display: flex; flex-wrap: wrap; gap: 2px 8px; align-items: center; }
.mercado-item-sub > * { white-space: nowrap; }

.mercado-categoria-caixa { position: relative; }
.mercado-categoria-caixa .mercado-arvore { top: calc(100% + 4px); }

.mercado-moedas.destaque { grid-template-columns: auto auto; justify-content: center; }
.mercado-moedas.destaque .mercado-moeda-chip b { white-space: nowrap; font-size: 11px; }

/* Mercado, 30/09: tabela de únicos sem o nome repetido; topo do câmbio */
/* Os mínimos somam menos que a coluna 3 (~690px): a tabela ENCOLHE em vez de rolar de lado (o dono, 30/09). */
.mercado-tabela.unicos.sell:not(.com-nome) .mercado-tr { grid-template-columns: 20px 36px 30px minmax(110px, 1.6fr) 56px minmax(64px, .8fr) minmax(88px, 100px) 54px 74px; gap: 5px; }
.mercado-coins-topo { display: flex; align-items: center; gap: 12px; margin: 0 0 8px; }
.mercado-coins-titulo { margin: 0; display: flex; align-items: center; gap: 8px; }
.mercado-coins-titulo img { width: 20px; height: 20px; }
.mercado-voltar { padding: 5px 10px; border: 1px solid var(--line); border-radius: 6px; background: #1b2426; color: var(--text); font: inherit; font-size: 12px; cursor: pointer; }
.mercado-voltar:hover { border-color: var(--accent-dim); color: var(--accent); }
.mercado-tabela.unicos.sell.com-nome .mercado-tr { grid-template-columns: 20px minmax(150px, 1.8fr) 30px minmax(96px, 1fr) 56px minmax(60px, .7fr) minmax(88px, 100px) 54px 74px; gap: 5px; }

/* Mercado, 30/09: o câmbio de coins com a cara do Mercado */
.mercado-coins { display: grid; gap: 10px; align-content: start; }
.mercado-coins-topo { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin: 0; }
.mercado-cotacao { display: flex; gap: 8px; margin-left: auto; flex-wrap: wrap; }
.mercado-cotacao .mercado-cartao { min-width: 96px; }
.mercado-cotacao .mercado-cartao.saldo { background: #1b2426; }
.mercado-cotacao .mercado-cartao b { display: inline-flex; align-items: center; gap: 4px; }
.mercado-coins-nota { padding: 8px 12px; border-left: 3px solid #e0a84a; border-radius: 4px; background: rgba(224, 168, 74, .08); color: var(--text); }
.mercado-coins-nota b { color: #e0a84a; font-weight: 600; }
.mercado-cambio { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; align-items: start; }
.mercado-cambio-coluna { display: grid; gap: 8px; align-content: start; padding: 10px; border: 1px solid var(--line-soft); border-radius: 8px; background: #1b2426; min-width: 0; }
.mercado-cambio-coluna.buy { border-top: 2px solid #a9662a; }
.mercado-cambio-coluna.sell { border-top: 2px solid #1f6a48; }
.mercado-cambio-cabeca { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.mercado-cambio-titulo { display: grid; gap: 2px; min-width: 0; }
.mercado-cambio-titulo b { font-family: var(--font-heading); font-size: 13px; letter-spacing: .06em; text-transform: uppercase; color: var(--accent); }
.mercado-cambio-titulo em { font-style: normal; font-size: 11px; color: var(--muted); }
.mercado-botao.criar-ordem { white-space: nowrap; padding: 7px 12px; }
.mercado-tr.cambio { grid-template-columns: 20px minmax(80px, 1fr) minmax(84px, .9fr) minmax(90px, 1fr) minmax(96px, 1.1fr) 78px; gap: 6px; }
.mercado-cambio-coluna .mercado-tr { grid-template-columns: 20px minmax(80px, 1fr) minmax(84px, .9fr) minmax(90px, 1fr) minmax(96px, 1.1fr) 78px; gap: 6px; }
.mercado-coins-qtd { display: inline-flex; align-items: center; gap: 4px; }
.mercado-coins-qtd img { width: 16px; height: 16px; }
.mercado-coins-qtd b { font-family: var(--font-numero); color: var(--copper); }
.mercado-tr.cambio .mercado-botao { white-space: nowrap; padding: 5px 8px; }
.mercado-cambio-coluna .balcao-paginas { margin: 0; }
@media (max-width: 900px), (max-height: 540px) and (pointer: coarse) { .mercado-cambio { grid-template-columns: 1fr; } .mercado-cotacao { margin-left: 0; } }

/* Buff Power: ouro ou coins (30/09) */
.buff-como-pagar { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin: 6px 0 10px; }
.buff-opcao-de-pagar { display: grid; justify-items: center; gap: 4px; padding: 10px 8px; border: 1px solid var(--line); border-radius: 8px; background: #1b2426; color: var(--text); font: inherit; cursor: pointer; }
.buff-opcao-de-pagar img { width: 26px; height: 26px; }
.buff-opcao-de-pagar b { font-size: 13px; }
.buff-opcao-de-pagar em { font-style: normal; font-size: 11px; color: var(--muted); }
.buff-opcao-de-pagar em.falta { color: var(--danger); }
.buff-opcao-de-pagar:hover:not(:disabled) { border-color: var(--accent); }
.buff-opcao-de-pagar:disabled { opacity: .55; cursor: not-allowed; }

/* Buff Power na store: o custo com os ícones das duas moedas (30/09) */
.buff-custo .buff-moeda { display: inline-flex; align-items: center; gap: 3px; vertical-align: middle; }
.buff-custo .buff-moeda img { width: 16px; height: 16px; }
.buff-custo .buff-moeda b { font-family: var(--font-numero); font-size: 13px; }
.buff-custo .buff-moeda.ouro b { color: #ffd97a; }
.buff-custo .buff-moeda.coins b { color: #e0a84a; }
.buff-custo .buff-moeda i { font-style: normal; font-size: 10px; color: var(--muted); }

/* O balão do item: o que ele faz (30/09) */
/* A caixa é a mesma do Buff Power (.tip-buff); aqui só o que difere. */
.tip-descricao { margin: 0 12px 6px; max-width: 340px; }
.tip-descricao .tip-buff-bonus { line-height: 1.4; }
/* A linha de custo do Buff Power, com os ícones das moedas (30/09) */
.tip-buff-custo { display: grid; gap: 3px; }
.tip-buff-moedas { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.tip-buff-moedas em { font-style: normal; font-size: 10px; color: var(--muted); }
.tip-buff-custo .buff-moeda { display: inline-flex; align-items: center; gap: 3px; }
.tip-buff-custo .buff-moeda img { width: 16px; height: 16px; }
.tip-buff-custo .buff-moeda b { font-family: var(--font-numero); font-size: 13px; }
.tip-buff-custo .buff-moeda.ouro b { color: #ffd97a; }
.tip-buff-custo .buff-moeda.coins b { color: #e0a84a; }
.tip-buff-custo .buff-moeda i { font-style: normal; font-size: 10px; color: var(--muted); }

/* ==================================================================
 * A ROLETA (30/09)
 *
 * Fundo, trilho, marcador, slot e painel são as imagens de
 * client/assets/roleta. O resto é CSS: cores por raridade, glows, abas.
 * ================================================================== */
/* ---- o giro bom da roleta na aba Sistemas: um cartão dourado, e não uma frase em itálico ---- */
.chat-log .sys.destaque {
  display: block; font-style: normal; margin: 4px 0; padding: 7px 10px; border-radius: 7px;
  border: 1px solid #e0b464; color: #ffe2a3;
  background: linear-gradient(90deg, rgba(224, 180, 100, 0.30), rgba(224, 180, 100, 0.06));
}
.chat-log .sys.destaque canvas { vertical-align: middle; }
.chat-log .sys.destaque-super_raro {
  border-color: #ffd27a; color: #fff0c8; font-weight: 700;
  background: linear-gradient(90deg, rgba(255, 210, 122, 0.45), rgba(224, 180, 100, 0.12));
  box-shadow: 0 0 12px rgba(255, 210, 122, 0.45);
  animation: roleta-chat-brilho 1.2s ease-in-out 4;
}
@keyframes roleta-chat-brilho { 50% { box-shadow: 0 0 22px rgba(255, 220, 140, 0.9); filter: brightness(1.2); } }

/* ---- a tela da ROLETA ----

   A BORDA e o X de fechar são os da Recompensa Diária (o fio de ouro velho, a
   sombra funda, o X num disco escuro — ver `.modal-box.diario`); o resto é da
   roleta: o fundo próprio, a faixa do alto com título, botões e saldo, e as
   mesas uma por linha. A gaveta (prêmios, melhores, últimos) abre por cima
   das mesas, e o cartão do giro bom por cima de tudo. */
.modal-box.roleta {
  width: min(1040px, 96vw);
  height: min(920px, 94vh);
  border: none; border-image: none; padding: 0; background: none;
  display: flex; flex-direction: column;
}
.modal-box.roleta > header {
  position: absolute; z-index: 7; top: 0; right: 0; left: auto;
  padding: 0; margin: 0; border: none; background: none; min-height: 0;
}
.modal-box.roleta > header #modal-title { display: none; }
.modal-box.roleta > header #modal-close {
  margin: 10px;
  width: 30px; height: 30px; padding: 0;
  display: grid; place-content: center;
  border: 1px solid #8a6f42; border-radius: 50%;
  background: #0b0f11e6;
  box-shadow: 0 0 0 1px #0a0d0f99, 0 2px 10px #000a;
  color: #e8d9b4; font-size: 17px; line-height: 1;
}
.modal-box.roleta > header #modal-close:hover { background: #17262a; color: #fff3d6; border-color: #d8b471; }
.modal-box.roleta #modal-body.roleta { flex: 1; min-height: 0; padding: 0; overflow: visible; background: none; display: flex; }

.roleta-moldura {
  position: relative;
  flex: 1; min-height: 0; width: 100%;
  display: flex; flex-direction: column; gap: 8px;
  padding: 12px 16px 14px;
  background: #101617 url('/client/assets/roleta/fundo.jpg') center / cover no-repeat;
  border: 1px solid #6b5636;
  border-radius: 10px;
  box-shadow: 0 0 0 1px #0a0d0f, 0 18px 54px #000d, 0 0 60px #0a0d0fcc;
  overflow: hidden;
}
/* a faixa do alto: título, botões, saldo */
.roleta-cabecalho { display: flex; flex-direction: column; gap: 6px; padding-right: 84px; text-shadow: 0 2px 10px #000c; }
.roleta-cabecalho h3 { margin: 0 6px 0 0; font-family: var(--font-title); font-weight: 700; font-size: 20px; letter-spacing: 0.18em; text-transform: uppercase; color: #e8d9b4; }
.roleta-titulo { gap: 6px; }
.roleta-resumo { margin: 0 0 6px; font-size: 12px; color: #a9c9c0; }
.roleta-linha { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.roleta-botao {
  padding: 5px 12px; border-radius: 999px; border: 1px solid #6b5636;
  background: #0b0f11cc; color: #e8d9b4; font: inherit; font-size: 12px; letter-spacing: 0.06em; text-transform: uppercase; cursor: pointer;
}
.roleta-botao:hover { border-color: #d8b471; color: #fff3d6; }
.roleta-botao.ativo { border-color: #e0b464; color: #ffe2a3; background: #2a2012e6; }
.roleta-botao.inbox { border-color: #3a7a68; color: #bff0e2; }
.roleta-saldo {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 4px 10px; background: rgba(11, 15, 17, 0.85); border: 1px solid #2c3d3a; border-radius: 999px;
}
.roleta-saldo canvas { width: 26px; height: 26px; image-rendering: pixelated; }
.roleta-saldo b { font-family: var(--font-numero, inherit); font-size: 16px; color: #ffe2a3; }
.roleta-saldo span { font-size: 11px; color: #8fb3aa; }
.roleta-comprar {
  padding: 4px 10px; border-radius: 999px; border: 1px solid #e0b464;
  background: linear-gradient(#3a2f1a, #241d10); color: #ffe2a3; font: inherit; font-size: 12px; cursor: pointer;
}
.roleta-custo, .roleta-assistindo { font-size: 12px; color: #a9c9c0; }
.roleta-custo b { color: #ffe2a3; }
.roleta-lotes { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; color: #a9c9c0; }
.roleta-lotes button {
  min-width: 30px; padding: 3px 7px; border-radius: 6px; border: 1px solid #2c3d3a;
  background: #0b0f11cc; color: #cfe3dd; font: inherit; font-size: 12px; cursor: pointer;
}
.roleta-lotes button.ativo { border-color: #e0b464; color: #ffe2a3; background: #2a2012e6; }

/* o palco: as mesas rolam dentro dele; a gaveta cobre ele inteiro */
.roleta-palco { position: relative; flex: 1; min-height: 0; }
.roleta-miolo { position: absolute; inset: 0; overflow: auto; padding: 4px 6px; }
.roleta-gaveta {
  position: absolute; inset: 0; z-index: 5;
  background: rgba(6, 10, 12, 0.96); border: 1px solid #2c3d3a; border-radius: 8px;
  padding: 10px 16px 14px; overflow: hidden;
  display: flex; flex-direction: column;
  animation: roleta-surgir 0.2s ease-out;
}
.roleta-gaveta-cab { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
.roleta-gaveta-cab h3 { margin: 0; font-size: 13px; letter-spacing: 0.08em; text-transform: uppercase; color: #e0b464; }
.roleta-gaveta-cab button { border: 1px solid #2c3d3a; background: none; color: #cfe3dd; font: inherit; font-size: 12px; padding: 3px 10px; border-radius: 6px; cursor: pointer; }
.roleta-gaveta .roleta-lista { max-height: none; flex: 1; }
.roleta-historico { gap: 0; }
.roleta-historico .roleta-feed { display: flex; flex-direction: column; gap: 2px; }
.roleta-vitrine .empty { grid-column: 1 / -1; }

/* o "?" ao lado do X de fechar (no canto de ações do cabeçalho): o mesmo disco escuro do X */
.modal-box.roleta > header #modal-acoes { margin: 0; flex: none; }
.roleta-ajuda {
  margin: 10px 0;
  width: 30px; height: 30px; padding: 0;
  display: grid; place-content: center;
  border: 1px solid #8a6f42; border-radius: 50%;
  background: #0b0f11e6;
  box-shadow: 0 0 0 1px #0a0d0f99, 0 2px 10px #000a;
  color: #e8d9b4; font: 700 16px/1 var(--font-title, inherit); cursor: pointer;
}
.roleta-ajuda:hover, .roleta-ajuda.ativo { background: #17262a; color: #fff3d6; border-color: #d8b471; }
.roleta-ajuda-texto { gap: 8px; padding-right: 8px; }
.roleta-ajuda-item { margin: 0; display: grid; grid-template-columns: 130px 1fr; gap: 10px; font-size: 13px; line-height: 1.45; color: #cfe3dd; }
.roleta-ajuda-item b { color: #e0b464; }
.roleta-aviso { display: block; margin-top: 4px; color: #ff6a5a; font-size: 12px; }
.roleta-guardados { display: inline-flex; align-items: center; gap: 6px; margin-left: 10px; color: #ffcf6a; font-size: 12px; }
.roleta-receber { border: 1px solid #d8b471; background: #1a2a2d; color: #fff3d6; font: inherit; font-size: 12px; padding: 3px 10px; border-radius: 6px; cursor: pointer; }
.roleta-receber:hover { background: #26393c; }
.roleta-outfit { display: inline-grid; place-items: center; overflow: hidden; }
.roleta-outfit canvas { max-width: 100%; max-height: 100%; }
.roleta-outfit i { font-style: normal; font-size: 22px; }

/* ---- LENDÁRIO: um degrau acima do super raro (o addon Divine Majesty) ---- */
.roleta-slot.rar-lendario { filter: drop-shadow(0 0 12px rgba(190, 240, 255, 1)) drop-shadow(0 0 4px #fff); animation: roleta-pulsar 0.9s ease-in-out infinite alternate; }
.roleta-fita.parou .roleta-slot.premiado.rar-lendario { animation: roleta-explodir 0.6s ease-out 5; }
.roleta-mesa.parou-lendario { animation: roleta-brilho 0.4s ease-in-out 6; }
.roleta-destaque.lendario .roleta-destaque-cartao { border-color: #bff7ff; box-shadow: 0 0 40px rgba(191, 247, 255, 0.55), 0 0 0 1px #fff8; animation: roleta-cartao 0.32s cubic-bezier(0.2, 0.9, 0.3, 1.3); }
.roleta-destaque.lendario h4 { color: #ffffff; text-shadow: 0 0 12px #bff7ff, 0 0 24px #7fe0ff; letter-spacing: 0.2em; }
.roleta-destaque.lendario .roleta-faisca { background: #dffbff; box-shadow: 0 0 8px #bff7ff; }
.roleta-faixa.rar-lendario b { color: #dffbff; text-shadow: 0 0 10px rgba(191, 247, 255, 0.9); }
.roleta-premio.rar-lendario .roleta-nome { color: #dffbff; font-weight: 700; }
/* O selo do addon na aba Prêmios: "+5% EXP permanente", bem chamativo (o dono, 01/10). */
.roleta-selo-exp {
  margin-left: 6px; padding: 1px 7px; border-radius: 10px; font-size: 11px; font-weight: 800; letter-spacing: .3px;
  color: #1a1206; background: linear-gradient(180deg, #ffe08a, #e8b53c); border: 1px solid #fff3c4;
  box-shadow: 0 0 8px rgba(255, 215, 90, .9); white-space: nowrap;
  animation: roleta-selo-exp 1.1s ease-in-out infinite alternate;
}
@keyframes roleta-selo-exp { from { box-shadow: 0 0 4px rgba(255, 215, 90, .5); transform: scale(1); } to { box-shadow: 0 0 14px rgba(255, 230, 120, 1); transform: scale(1.06); } }
.roleta-giro-feito.rar-lendario { background: linear-gradient(90deg, rgba(191, 247, 255, 0.35), rgba(191, 247, 255, 0.08)); }
.roleta-giro-feito.rar-lendario .roleta-nome { color: #ffffff; font-weight: 700; }
.roleta-vitrine .roleta-giro-feito.rar-lendario { border-color: #bff7ff; box-shadow: 0 0 10px rgba(191, 247, 255, 0.6); }
.roleta-giro-feito.rar-lendario .roleta-etiqueta { color: #dffbff; }
.sys-icone { width: 16px; height: 16px; vertical-align: -3px; margin-right: 4px; image-rendering: auto; }

/* ---- as mesas: uma por linha ---- */
.roleta-mesas { display: flex; flex-direction: column; gap: 10px; }
.roleta-mesa {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 6px 10px 8px; border-radius: 10px;
  background: rgba(8, 12, 14, 0.5); border: 1px solid rgba(79, 201, 174, 0.14);
}
.roleta-mesa.girando { border-color: rgba(224, 180, 100, 0.45); }
.roleta-mesa-cab { width: 100%; display: flex; justify-content: space-between; align-items: center; gap: 8px; padding: 0 6px; font-size: 12px; min-height: 32px; }
.roleta-mesa-nome { color: #e0b464; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; white-space: nowrap; }
.roleta-quem-caixa { display: inline-flex; align-items: center; gap: 6px; min-width: 0; min-height: 32px; }
.roleta-quem { color: #ffe2a3; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.roleta-boneco { display: inline-flex; width: 32px; height: 32px; align-items: flex-end; justify-content: center; overflow: visible; flex: 0 0 auto; }
.roleta-boneco canvas { image-rendering: pixelated; }
.roleta-destaque-figuras { display: flex; align-items: flex-end; justify-content: center; gap: 18px; }
.roleta-destaque-figuras .roleta-boneco { width: 64px; height: 64px; }
/*
 * O trilho.png (1086 × 176, já sem o ar transparente de cima e de baixo): a
 * janela escura fica em ~88% da largura (as pontas ornamentadas ficam com 6%
 * de cada lado) e em ~70% da altura (a moldura fica com 15% em cima e
 * embaixo). A caixa é calculada a partir do slot para a fita ficar DENTRO da
 * janela, e a imagem estica até a caixa.
 */
.roleta-trilho {
  --slots: 7;
  --slot: 88px;
  position: relative;
  width: min(100%, calc(var(--slots) * var(--slot) / 0.88));
  height: calc(var(--slot) / 0.7);
  background: url('/client/assets/roleta/trilho.png') center / 100% 100% no-repeat;
  display: flex; align-items: center; justify-content: center;
}
.roleta-janela {
  width: calc(var(--slots) * var(--slot));
  height: var(--slot);
  overflow: hidden;
  position: relative;
}
.roleta-fita {
  display: flex; height: 100%;
  will-change: transform;
}
.roleta-slot {
  flex: 0 0 var(--slot); width: var(--slot); height: var(--slot);
  display: flex; align-items: center; justify-content: center;
  position: relative;
  background: url('/client/assets/roleta/slot.png') center / 100% 100% no-repeat;
  filter: drop-shadow(0 0 2px rgba(79, 201, 174, 0.35));
}
.roleta-slot canvas { image-rendering: pixelated; }
.roleta-qtd { position: absolute; right: 14px; bottom: 12px; font-style: normal; font-size: 11px; color: #fff; text-shadow: 0 0 3px #000, 0 0 3px #000; }
.roleta-slot.rar-comum { filter: drop-shadow(0 0 2px rgba(79, 201, 174, 0.4)); }
.roleta-slot.rar-medio { filter: drop-shadow(0 0 5px rgba(120, 130, 255, 0.55)) saturate(1.05); }
.roleta-slot.rar-raro { filter: drop-shadow(0 0 7px rgba(224, 180, 100, 0.85)); }
.roleta-slot.rar-super_raro { filter: drop-shadow(0 0 10px rgba(255, 200, 90, 1)); animation: roleta-pulsar 1.1s ease-in-out infinite; }
@keyframes roleta-pulsar {
  0%, 100% { filter: drop-shadow(0 0 6px rgba(255, 200, 90, 0.8)); }
  50% { filter: drop-shadow(0 0 16px rgba(255, 220, 120, 1)); }
}
.roleta-fita.parou .roleta-slot.premiado { transform: scale(1.08); z-index: 1; }
.roleta-fita.parou .roleta-slot.premiado.rar-raro { animation: roleta-explodir 0.6s ease-out 2; }
.roleta-fita.parou .roleta-slot.premiado.rar-super_raro { animation: roleta-explodir 0.6s ease-out 3; }
@keyframes roleta-explodir {
  0% { filter: drop-shadow(0 0 4px #ffd27a); }
  40% { filter: drop-shadow(0 0 28px #ffe6a8) brightness(1.4); }
  100% { filter: drop-shadow(0 0 8px #ffd27a); }
}
.roleta-mesa.parou-raro { animation: roleta-brilho 0.5s ease-in-out 2; }
.roleta-mesa.parou-super_raro { animation: roleta-brilho 0.45s ease-in-out 4; }
@keyframes roleta-brilho { 50% { filter: brightness(1.35) drop-shadow(0 0 24px rgba(255, 220, 120, 0.9)); border-color: #ffd27a; } }
.roleta-marcador {
  position: absolute; left: 50%; top: -12px; bottom: -12px; width: 36px;
  transform: translateX(-50%);
  background: url('/client/assets/roleta/marcador.png') center / 100% 100% no-repeat;
  pointer-events: none;
}

.roleta-acoes { display: flex; align-items: center; justify-content: center; gap: 12px; flex-wrap: wrap; min-height: 34px; }
.roleta-girar {
  padding: 7px 22px; border-radius: 8px; border: 1px solid #e0b464;
  background: linear-gradient(#4a3a1e, #2a2012); color: #ffe2a3; font: inherit; font-size: 14px; font-weight: 700;
  letter-spacing: 0.04em; cursor: pointer; box-shadow: 0 0 14px rgba(224, 180, 100, 0.25);
}
.roleta-girar:hover:not(:disabled) { filter: brightness(1.15); }
.roleta-girar:disabled { opacity: 0.55; cursor: default; }
.roleta-girar.sem-saldo { border-color: #4fc9ae; color: #bff0e2; background: linear-gradient(#1c3a34, #14262a); }
.roleta-posicao { font-size: 12px; color: #a9c9c0; }
.roleta-girar.parar { border-color: #c0553a; color: #ffd0c0; background: linear-gradient(#4a2418, #2a120c); }
.roleta-rodape { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 6px 4px 0; border-top: 1px solid rgba(79, 201, 174, 0.14); font-size: 12px; color: #a9c9c0; }
.roleta-ganhos { display: inline-flex; align-items: center; gap: 8px; min-width: 0; color: #cfe3dd; }
.roleta-ganhos .roleta-figura { width: 34px; height: 34px; }
.roleta-ganhos-nome { color: #ffe2a3; }
.roleta-enviado { color: #ff6a5a; font-weight: 700; }
.roleta-rodape-vao { flex: 1; }

/* ---- o cartão do giro bom, por cima de tudo ---- */
.roleta-destaque {
  position: absolute; inset: 0; z-index: 6;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0, 0, 0, 0.55);
  pointer-events: none;
  animation: roleta-surgir 0.15s ease-out;
}
.roleta-destaque.sumindo { animation: roleta-sumir 0.3s ease-in forwards; }
@keyframes roleta-surgir { from { opacity: 0; } }
@keyframes roleta-sumir { to { opacity: 0; } }
.roleta-destaque-cartao {
  position: relative; text-align: center; padding: 22px 40px 20px; min-width: 300px;
  border: 2px solid #e0b464; border-radius: 14px;
  background: radial-gradient(circle at 50% 30%, #3c2d12, #14100a 75%);
  box-shadow: 0 0 40px rgba(255, 210, 122, 0.55);
  animation: roleta-cartao 0.32s cubic-bezier(0.2, 1.5, 0.4, 1);
}
@keyframes roleta-cartao { from { transform: scale(0.4); opacity: 0; } }
.roleta-destaque-cartao h4 { margin: 0 0 8px; font-size: 14px; letter-spacing: 0.22em; text-transform: uppercase; color: #e0b464; }
.roleta-destaque-cartao canvas { width: 96px; height: 96px; image-rendering: pixelated; filter: drop-shadow(0 0 14px rgba(255, 220, 140, 0.9)); }
.roleta-destaque-cartao .roleta-boneco canvas { width: 64px; height: 64px; filter: none; }
.roleta-destaque-cartao p { margin: 8px 0 0; font-size: 15px; color: #ffe2a3; }
.roleta-destaque-cartao p b { color: #fff; }
.roleta-destaque-cartao .roleta-destaque-nome { display: block; margin-top: 4px; font-size: 18px; font-weight: 700; color: #ffd27a; }
.roleta-destaque.super_raro .roleta-destaque-cartao { border-color: #ffd27a; animation: roleta-cartao 0.32s cubic-bezier(0.2, 1.5, 0.4, 1), roleta-brilho 0.5s ease-in-out 4; }
.roleta-destaque.super_raro h4 { color: #fff0c8; text-shadow: 0 0 10px #ffd27a; }
.roleta-faisca {
  position: absolute; width: 6px; height: 6px; border-radius: 50%;
  background: #ffe6a8; box-shadow: 0 0 8px #ffd27a;
  animation: roleta-faisca 1.4s ease-out infinite;
}
@keyframes roleta-faisca {
  0% { transform: translate(0, 0) scale(0.4); opacity: 0; }
  20% { opacity: 1; }
  100% { transform: translate(var(--dx), var(--dy)) scale(1.2); opacity: 0; }
}

/* ---- as listas: prêmios, melhores drops, últimos giros ---- */
.roleta-lista { overflow: auto; display: flex; flex-direction: column; gap: 2px; padding-right: 4px; }
.roleta-premios-colunas { display: grid; grid-template-columns: 1fr 1fr; gap: 0 18px; }
.roleta-faixa { display: flex; justify-content: space-between; margin-top: 6px; padding: 2px 6px; font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; border-bottom: 1px solid #2c3d3a; }
.roleta-faixa.rar-comum b { color: #4fc9ae; }
.roleta-faixa.rar-medio b { color: #8d8dff; }
.roleta-faixa.rar-raro b { color: #e0b464; }
.roleta-faixa.rar-super_raro b { color: #ffd27a; text-shadow: 0 0 8px rgba(255, 210, 122, 0.8); }
.roleta-premio, .roleta-giro-feito { display: flex; align-items: center; gap: 8px; padding: 3px 6px; border-radius: 4px; font-size: 12px; color: #cfe3dd; }
.roleta-premio:hover, .roleta-giro-feito:hover { background: rgba(79, 201, 174, 0.08); }
.roleta-figura { width: 30px; height: 30px; display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; }
.roleta-nome { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.roleta-pct { font-family: var(--font-numero, inherit); color: #ffe2a3; }
.roleta-premio.rar-raro .roleta-nome { color: #e0b464; }
.roleta-premio.rar-super_raro .roleta-nome { color: #ffd27a; }
/* O colecionável que este personagem já tem: riscado, apagado, com o "(já obtido)" (o dono, 01/10). */
.roleta-premio.obtido { opacity: .62; }
.roleta-premio.obtido .roleta-nome { text-decoration: line-through; flex: 0 1 auto; }
.roleta-obtido { flex: 1; font-size: 11px; color: #9fd3c4; white-space: nowrap; }
.roleta-premio.obtido .roleta-selo-exp { animation: none; box-shadow: none; filter: saturate(.4); }
.roleta-conjunto summary { display: flex; align-items: center; gap: 8px; padding: 3px 6px; cursor: pointer; font-size: 12px; color: #cfe3dd; list-style: none; }
.roleta-conjunto summary::before { content: '▸'; color: #8fb3aa; font-size: 10px; }
.roleta-conjunto[open] summary::before { content: '▾'; }
.roleta-conjunto summary span { margin-left: auto; font-size: 11px; color: #8fb3aa; }
.roleta-conjunto .roleta-premio { padding-left: 24px; }
.roleta-giro-feito b { min-width: 80px; color: #bff0e2; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.roleta-giro-feito i { font-style: normal; font-size: 10px; color: #8fb3aa; white-space: nowrap; }
.roleta-giro-feito.rar-raro { background: rgba(224, 180, 100, 0.12); }
.roleta-giro-feito.rar-raro .roleta-nome { color: #e0b464; }
.roleta-giro-feito.rar-super_raro { background: linear-gradient(90deg, rgba(224, 180, 100, 0.35), rgba(224, 180, 100, 0.12)); }
.roleta-giro-feito.rar-super_raro .roleta-nome { color: #fff0c8; font-weight: 700; }
/* a vitrine dos melhores: cada linha é um cartão, com a peça maior */
.roleta-vitrine { display: grid; grid-template-columns: 1fr 1fr; gap: 4px 10px; }
.roleta-vitrine .roleta-giro-feito { padding: 5px 8px; border: 1px solid rgba(224, 180, 100, 0.35); border-radius: 6px; }
.roleta-vitrine .roleta-giro-feito.rar-super_raro { border-color: #ffd27a; box-shadow: 0 0 8px rgba(255, 210, 122, 0.3) inset; }
.roleta-vitrine .roleta-figura { width: 36px; height: 36px; }
.roleta-vitrine .roleta-giro-feito b { min-width: 0; }
.roleta-etiqueta { font-size: 9px; letter-spacing: 0.1em; text-transform: uppercase; padding: 1px 5px; border-radius: 3px; border: 1px solid currentColor; }
.roleta-giro-feito.rar-raro .roleta-etiqueta { color: #e0b464; }
.roleta-giro-feito.rar-super_raro .roleta-etiqueta { color: #ffd27a; }
.roleta-giro-feito.novo { animation: roleta-linha-nova 1s ease-out; }
@keyframes roleta-linha-nova { from { background: rgba(255, 220, 140, 0.55); } }
.roleta-lista .empty { color: #8fb3aa; font-size: 12px; padding: 8px; }
/* a essência: a casa vazia do slot com uma estrela por cima (a mesma ideia da mochila) */
.roleta-essencia { position: relative; display: inline-flex; align-items: center; justify-content: center; }
.roleta-essencia > * { max-width: 100%; max-height: 100%; }
.roleta-essencia i { position: absolute; right: -2px; bottom: -4px; font-style: normal; font-size: 13px; color: #ffd27a; text-shadow: 0 0 4px #000, 0 0 6px rgba(255, 210, 122, 0.8); }

@media (max-width: 820px), (max-height: 540px) and (pointer: coarse) {
  .modal-box.roleta { width: 100vw; height: 100dvh; }
  .roleta-moldura { border: none; border-radius: 0; box-shadow: none; padding: 8px 8px 8px; gap: 6px; }
  .roleta-cabecalho { padding-right: 76px; }
  .roleta-ajuda { width: 30px; height: 30px; }
  .roleta-ajuda-item { grid-template-columns: 1fr; gap: 2px; }
  .roleta-cabecalho h3 { font-size: 16px; }
  .roleta-miolo { padding: 0; }
  .roleta-mesa { padding: 4px 4px 6px; }
  .roleta-trilho { --slots: 5; --slot: 64px; }
  .roleta-marcador { width: 28px; }
  .roleta-qtd { right: 10px; bottom: 8px; }
  .roleta-premios-colunas, .roleta-vitrine { grid-template-columns: 1fr; }
  .roleta-destaque-cartao { min-width: 0; padding: 16px 22px; }
}

/*
 * ---- iPhone: a faixa de baixo (home indicator), 01/10 ----
 *
 * O meta tem `viewport-fit=cover`, então a página vai até a borda de baixo —
 * e a faixa do iPhone (34px em pé) cobre o que estiver lá. Já existe o
 * `--chao` (env(safe-area-inset-bottom)) e o hotbar da caçada o usa, mas fora
 * da caçada o `#actionbar` fica em `bottom: 0` sem recuo, e as caixas de modal
 * medem `100dvh - 14px` sem descontar a faixa: o rodapé delas (fechar,
 * comprar, coletar) caía debaixo do traço.
 *
 * `-webkit-touch-callout` só existe no Safari do iOS, então este bloco não
 * vale em Android nem em PC — eles recebem exatamente o CSS de cima. E o
 * `env()` é 0 fora do iPhone com recorte, então mesmo lá não muda nada.
 */
@supports (-webkit-touch-callout: none) {
  @media (max-width: 820px), (max-height: 540px) and (pointer: coarse) {
    /* O hotbar fora da caçada: a segunda fileira (slots 8-13) sai de baixo da faixa. */
    #actionbar { padding-bottom: max(2px, env(safe-area-inset-bottom, 0px)); }
    /*
     * A área dos modais termina ACIMA da faixa (o `#modal` é a grade que
     * centraliza a caixa; só encurtar a caixa a deixaria centrada e ainda com
     * a borda de baixo dentro da faixa), e as caixas descontam a faixa.
     */
    #modal { padding-bottom: env(safe-area-inset-bottom, 0px); }
    .modal-box, .modal-box.imbue, .modal-box.store { max-height: calc(100dvh - 14px - env(safe-area-inset-bottom, 0px)); }
    .modal-box.diario #modal-body { max-height: calc(100dvh - 14px - env(safe-area-inset-bottom, 0px)); }
    .gate-box, .gate-box.escolhendo, .gate-box.creating { max-height: calc(100dvh - 20px - env(safe-area-inset-bottom, 0px)); }
    .window.solta { max-height: calc(100dvh - 20px - env(safe-area-inset-bottom, 0px)) !important; }
    /* O rodapé grudado (fechar / comprar / coletar) ganha o recuo da faixa por dentro. */
    .modal-rodape { padding-bottom: calc(14px + env(safe-area-inset-bottom, 0px)); }
  }
}

/*
 * ---- Telas estreitas: os painéis que quebravam (01/10) ----
 *
 * Só até 480px de largura (telefone em pé). PC, tablet e telefone deitado não
 * entram aqui. E só nos seletores dos painéis que a sonda e as fotos mostraram
 * quebrados — os que estavam bem não são tocados.
 *
 * A causa comum (ver o bloco 12 do celular): `#modal-body * { min-width: 0 }`
 * e `overflow-wrap: anywhere` zeram toda largura mínima e quebram qualquer
 * palavra, então colunas de 108px viravam 61px e "NÍVEL 1" saía letra por letra.
 */
@media (max-width: 480px) {
  /* Proficiência: as colunas voltam aos 108px do PC e a fila ROLA de lado (3 por vez, o dedo arrasta). */
  #modal-body .prof-columns {
    overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch;
    scroll-snap-type: x proximity; padding-bottom: 8px;
  }
  #modal-body .prof-column { min-width: 108px; flex: 0 0 108px; max-width: none; scroll-snap-align: start; }
  #modal-body .prof-column b, #modal-body .prof-column span, #modal-body .prof-column em,
  #modal-body .prof-column button, #modal-body .prof-column-foot { overflow-wrap: normal; word-break: normal; white-space: nowrap; }

  /* Baú de Boss: as duas sacolas (Boss Pouch e Store Inbox) uma embaixo da outra; a sacola aberta
     com os itens em grade que preenche a largura, "expira em" numa linha só e o Coletar na horizontal. */
  .bag-boss-pouch:has(.bag-bolsa-coluna) { grid-template-columns: 1fr; gap: 10px; }
  /* O Baú de Boss (modal deposito-boss) é uma grade "sacolas | sacola aberta" de 210px + o resto:
     em 360px a sacola aberta ficava com 102px e os itens em fila única. Empilha. */
  .modal-box.deposito-boss .deposito-dois { grid-template-columns: minmax(0, 1fr); }
  .modal-box.deposito-boss .deposito-lado .locker-grade { grid-template-columns: repeat(auto-fill, 38px); }
  #modal-body .sacola-aberta .locker-grade { grid-template-columns: repeat(auto-fill, minmax(56px, 1fr)); justify-items: center; }
  #modal-body .sacola-aberta h4 { white-space: nowrap; overflow-wrap: normal; overflow: hidden; text-overflow: ellipsis; }
  #modal-body .sacola-aberta .locker-topo { flex-wrap: wrap; gap: 6px 10px; }
  #modal-body .sacola-aberta .sacola-prazo { white-space: nowrap; overflow-wrap: normal; }
  #modal-body .sacola-aberta .locker-topo button { white-space: nowrap; overflow-wrap: normal; flex: 0 0 auto; }

  /* Mineiroidle Store: os chips de prazo ("7 dias", "14 dias") e o "economize X" saíam com 21-28px de largura,
     uma letra por linha; o preço e o botão continuam na mesma linha, o chip quebra para baixo se faltar. */
  #modal-body .store-opcao { flex-wrap: wrap; row-gap: 4px; }
  #modal-body .store-opcao-prazo, #modal-body .store-opcao-prazo *, #modal-body .store-opcao-desconto { white-space: nowrap; overflow-wrap: normal; word-break: normal; }
  #modal-body .store-opcao-prazo { flex: 1 1 auto; min-width: 0; }

  /* Mercado: a barrinha "Filtros / Itens" é a primeira linha de uma grade que estica as linhas para
     preencher a altura (align-content: stretch) — os dois botões viravam torres de 15 linhas. A linha
     da barrinha fica do tamanho dela e o resto da altura vai para a coluna das ofertas. */
  .mercado-itens { align-content: start; grid-template-rows: auto minmax(0, 1fr); }
  .mercado-barrinha { align-self: start; flex-wrap: wrap; }
  .mercado-barrinha .mercado-gaveta-botao { white-space: nowrap; overflow-wrap: normal; flex: 0 0 auto; }

  /*
   * Título do modal: ocupa o que sobra do cabeçalho (reticências só no fim), e
   * as ações (abas, filtros, "Loja de Task Token") descem para uma faixa logo
   * abaixo da moldura, por cima do começo do corpo — que ganha o recuo para
   * nada nascer escondido. Esticar a moldura de cima não serve: a arte da
   * borda tem uma margem transparente e o título flutuava fora do quadro.
   */
  .modal-box > header h2, .modal-box > header #modal-title { flex: 1 1 auto; min-width: 0; max-width: none; }
  .modal-box:not(.arena) > header #modal-acoes:not(:empty) {
    position: absolute; left: 0; right: 0; top: 100%; margin: 0; height: 36px; padding: 3px 4px;
    background: var(--panel-solid, #10171a); border-bottom: 1px solid var(--line-soft, #2c373c); z-index: 3;
  }
  .modal-box:not(.arena):has(> header #modal-acoes:not(:empty)) #modal-body { padding-top: 40px; }
}

/*
 * ---- "Configurar ação" em pé no celular (02/10) ----
 *
 * O editor é duas colunas (264px + o resto): em 384px de largura sobravam 90px
 * para a coluna da direita, e "Remover"/"Salvar" saíam com uma letra por linha.
 * Em tela estreita vira uma coluna só, a lista rola menos e os botões ficam
 * lado a lado, inteiros.
 */
@media (max-width: 480px) {
  .action-editor { grid-template-columns: minmax(0, 1fr); gap: 10px; }
  .action-list { max-height: 36vh; }
  .action-side { min-width: 0; }
  .action-editor .confirm-actions { display: flex; flex-wrap: wrap; gap: 8px; }
  .action-editor .confirm-actions button { flex: 1 1 auto; white-space: nowrap; }
  .action-editor button, .action-editor .ghost, .action-editor .primary { white-space: nowrap; }
}
