/* ============================================================
   HOODMONS — base
   ------------------------------------------------------------
   Tokens, reset, layout e componentes. Uma linguagem só: "tela de jogo" — nada de
   raio de borda, nada de gradiente, sombras DESLOCADAS e chapadas em vez de difusas.

   A regra que gera todas as outras: o chrome é NEUTRO. Cada um dos 1025 Hoodmons traz
   o próprio fundo chapado e saturado dentro da imagem, e se a interface também for
   colorida os dois brigam em toda grade. A cor da UI aparece em três lugares e mais
   nenhum: a marca, o valor em $HOOD e o selo de multiplicador.
   ============================================================ */

:root {
  /* Superfícies — do fundo para a frente */
  --bg:       #0d0f12;
  --panel:    #161a20;
  --panel-2:  #1e242c;
  --line:     #39424f;
  --line-hi:  #5b6878;

  /* Texto */
  --ink:      #e6ecf2;
  --ink-2:    #8a97a6;
  --ink-3:    #5f6b7a;

  /* Acentos, tirados da PRÓPRIA arte da coleção */
  --lime:     #c8e600;   /* o fundo do #500 — é a cor do $HOOD */
  --lime-dk:  #5c6b00;
  --orange:   #f59b23;   /* o corpo do #1 — é a cor da taxa/rendimento */

  /* O dourado do logotipo, amostrado do próprio arquivo (assets/hero.webp, dentro das
     letras) em vez de escolhido no olho. É a cor da MARCA — hoje ela vive só no botão
     da landing, que fica sobre a arte e precisa pertencer a ela. */
  --gold:     #fdbd31;
  --gold-dk:  #a86f10;

  /* O oceano do próprio mapa, amostrado das bordas do arquivo. É a cor que faz a área
     em volta do mapa parecer continuação do mundo em vez de vazio preto. */
  --sea:      #0d70ba;
  --sea-dk:   #095085;
  --pink:     #f28fb4;
  --danger:   #e04a3f;
  --warn:     #f0c645;

  /* Cores de boost. NÃO são escolha de design: `utils/boost.js` no backend manda estes
     mesmos valores no campo `traitColor`/`rankColor` de cada card. Estão aqui como
     reserva para quando a regra não define cor própria. */
  --boost-trait:   #ffd34d;
  --boost-stacked: #ff8a1e;
  --boost-rank:    #34e0ff;

  --shadow: 5px 5px 0 #00000055;
  --shadow-lg: 6px 6px 0 #00000055;
}

* { box-sizing: border-box; }

html { color-scheme: dark; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: "DM Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 15px;
  line-height: 1.5;
  /* Dither sutil — a "textura de tela" sem custo de imagem nem de requisição. */
  background-image: repeating-linear-gradient(0deg, #ffffff05 0 1px, transparent 1px 3px);
  -webkit-font-smoothing: antialiased;
}

/* A REGRA MAIS IMPORTANTE DESTE ARQUIVO.
   A arte é pixel art de baixa resolução. Sem isto o navegador interpola ao ampliar e o
   sprite vira mingau — é a diferença entre a coleção parecer feita de propósito e
   parecer uma imagem estourada. Vale para TODA imagem: os 1025 GIFs são a única fonte
   de imagem do app. */
img { display: block; max-width: 100%; image-rendering: pixelated; }

/* `hidden` vence qualquer `display` de classe. Sem isto, `.grid { display: grid }` ganha
   do estilo do navegador para [hidden] (classe > atributo) e a aba "escondida" aparece. */
[hidden] { display: none !important; }

button { font: inherit; cursor: pointer; }
a { color: inherit; }

/* A fonte bitmap é de DISPLAY, nunca de leitura. Ela vai em rótulo, número e botão —
   texto corrido em Press Start 2P é ilegível a partir da segunda linha. */
.px { font-family: "Press Start 2P", monospace; letter-spacing: .02em; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ============================================================
   TELAS
   ============================================================ */
.screen { display: none; }
.screen.is-active { display: block; }

/* ---- Tela de título ---- */
#screen-landing.is-active { display: block; }

.hero {
  position: relative;
  min-height: 100vh; min-height: 100dvh;
  overflow: hidden;
  display: flex; flex-direction: column;
  background: var(--bg);
}

/* `cover` faz a arte sangrar até as bordas. O `object-position` puxa o enquadramento
   para cima do centro porque o logotipo vive no terço superior — centralizar cortaria a
   coroa em telas largas e baixas. */
.hero-art {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: center 40%;
  /* Esta arte é um render em alta que IMITA pixel art: as corridas de cor são de 1px,
     não de 4. `pixelated` não teria efeito e atrapalharia nas bordas suaves do céu. */
  image-rendering: auto;
}

/* O menu ocupa o vão de céu do centro, que é onde ele foi desenhado para caber. */
.title-menu {
  position: relative;
  margin: auto;
  padding: 0 20px;
  width: 100%;
  display: grid; place-items: center;
}
.landing-inner { width: 100%; max-width: 340px; display: grid; gap: 10px; }

/* ---- Item de menu ----
   Segue as placas da própria ilustração: borda preta grossa, sombra dura deslocada,
   zero raio. O ▶ é a convenção de menu de RPG — você não clica num item, você move o
   cursor até ele; por isso ele nasce invisível e só aparece no item apontado. */
.menu-item {
  display: flex; align-items: center; gap: 10px;
  width: 100%; padding: 15px 18px;
  font-family: "Press Start 2P", monospace; font-size: 11px; letter-spacing: .02em;
  background: #4a4f5c; color: #e9e4d4;
  border: 4px solid #000; box-shadow: 5px 5px 0 #00000099;
  text-align: left;
}
.menu-item .cursor { color: var(--gold); opacity: 0; flex-shrink: 0; font-size: 10px; }
.menu-item .menu-label { flex: 1; }
.menu-item:hover .cursor, .menu-item:focus-visible .cursor { opacity: 1; }
.menu-item:focus-visible { outline: 4px solid var(--gold); outline-offset: 3px; }
.menu-item:active:not(:disabled) { transform: translate(5px, 5px); box-shadow: 0 0 0 #00000099; }

/* O item primário é o dourado do logotipo, e nasce com o cursor já apontado: é para ele
   que a pessoa veio. */
.menu-item.is-primary { background: var(--gold); color: #2a1a05; }
.menu-item.is-primary .cursor { color: #2a1a05; opacity: 1; }
.menu-item.is-primary.is-loading { color: transparent; pointer-events: none; }
.menu-item.is-primary.is-loading .cursor { opacity: 0; }
.menu-item.is-primary.is-loading::after {
  content: ""; position: absolute; inset: 0; margin: auto; width: 10px; height: 10px;
  background: #2a1a05; animation: blink-slow .7s steps(2, start) infinite;
}
.menu-item.is-primary { position: relative; }

.landing-note {
  font-size: 12px; color: #e9e4d4; line-height: 1.6; text-align: center;
  margin: 8px auto 0; max-width: 330px;
  /* A placa de fundo é o que garante a leitura sobre o pôr do sol claro. */
  background: #0d0f12cc; border: 3px solid #000; padding: 10px 12px;
}

@keyframes blink-slow { to { opacity: 0; } }

/* ---- Não-holder ----
   A mesma arte e as mesmas placas da landing: é a tela de título dizendo "ainda não".
   Na tela larga a placa é DEITADA e desce para o chão da arte — em pé, no vão do céu, ela
   cobriria o logotipo. No celular a arte já fica em cima, e a placa volta a ser em pé. */
.nh .title-menu { margin: auto auto 7vh; }
.nh-card {
  max-width: 560px;
  grid-template-columns: auto 1fr; column-gap: 20px; align-items: center;
  background: #0d0f12e6; border: 4px solid #000; box-shadow: 5px 5px 0 #00000099;
  padding: 18px 20px;
}
/* Múltiplo de 25: cada pixel da grade do sprite vira um número inteiro de pixels. */
.nh-sprite { grid-row: span 3; width: 175px; height: 175px; animation: nh-bob 1.2s steps(2, jump-none) infinite; }
.nh-title { margin: 0 0 8px; font-size: 14px; color: var(--gold); }
.nh-text { margin: 0; font-size: 14px; color: #e9e4d4; }
.nh-card .menu-item { text-decoration: none; }
@keyframes nh-bob { to { transform: translateY(-7px); } }
@media (prefers-reduced-motion: reduce) { .nh-sprite { animation: none; } }
@media (max-width: 760px) {
  .nh .title-menu { margin: 0; }
  .nh-card { grid-template-columns: 1fr; justify-items: center; text-align: center; max-width: 340px; }
  .nh-sprite { grid-row: auto; width: 150px; height: 150px; }
  .nh-card .menu-item { justify-self: stretch; }
}

/* ---- Tela de título estreita ----
   `cover` num celular em pé come as laterais e "HoodMons" vira "oodMon". A saída mantém
   o full-bleed em vez de virar cartaz: a arte ocupa a largura inteira sem corte, presa
   no topo, e o menu desce para o chão escuro — arte e menu centralizados como um bloco. */
@media (max-width: 760px) {
  .hero { justify-content: center; }
  .hero-art {
    position: static; width: 100%; height: auto; object-fit: contain;
    border-top: 3px solid #000; border-bottom: 3px solid #000;
  }
  .title-menu { margin: 0; padding: 28px 20px 0; flex: 0 0 auto; }
  .menu-item { font-size: 10px; padding: 14px 15px; }

  /* A tela de título tem arte VERTICAL própria (assets/title-mobile.webp, via <picture>),
     então aqui ela volta a cobrir a tela inteira. O menu desce para as ruínas do rodapé:
     o logotipo mora no terço de cima e os Hoodmons no meio, e nenhum dos dois pode ficar
     atrás dos botões. A tela de não-holder segue com a regra de cima (arte larga). */
  #screen-landing .hero { justify-content: flex-end; }
  #screen-landing .hero-art {
    position: absolute; inset: 0; width: 100%; height: 100%;
    object-fit: cover; object-position: center top; border: 0;
  }
  #screen-landing .title-menu {
    margin: 0; padding: 0 20px calc(28px + env(safe-area-inset-bottom));
  }
}
/* Celular baixo (iPhone SE e afins): a nota empurraria os botões para cima dos Hoodmons.
   O que ela diz é reforçado no próprio seletor de carteira. */
@media (max-width: 760px) and (max-height: 700px) {
  #screen-landing .landing-note { display: none; }
  #screen-landing .title-menu { padding-bottom: calc(18px + env(safe-area-inset-bottom)); }
}

/* ============================================================
   APP
   ============================================================ */
/* Sem largura máxima e sem padding: o mapa precisa da tela inteira, e cada seção põe
   o próprio respiro. O menu lateral deixou de existir quando o mapa virou o hub. */
.shell { display: block; }

/* ---- HUD ----
   Flutua SOBRE o cenário, como os corações e as moedas de um overworld. Não ocupa linha
   própria e não empurra nada: o mundo é a tela inteira, e a interface mora em cima dele. */
.hud {
  position: fixed; inset: 0 0 auto; z-index: 20;
  display: flex; align-items: flex-start; justify-content: space-between; gap: 14px;
  padding: 14px 16px; pointer-events: none;
}
.hud > * { pointer-events: auto; }
.hud-right { display: flex; align-items: center; gap: 10px; }

/* As peças do HUD usam a linguagem das placas do mapa: creme, borda preta grossa,
   sombra dura. Um chip escuro de site flutuando sobre a ilustração denunciaria que a
   interface e o mundo são coisas diferentes. */
.hud .logo, .hud .chip, .hud .purse {
  background: #f8f4e4; border: 3px solid #000; box-shadow: 3px 3px 0 #00000077;
  padding: 8px 11px; color: #20201c;
}
.hud .logo { display: flex; align-items: center; gap: 9px; cursor: pointer; }
.hud .logo h1 { font-size: 12px; margin: 0; color: #20201c; }
.hud .chip { font-size: 11px; display: flex; align-items: center; gap: 8px; color: #6b6252; }
.hud .chip:hover { background: var(--gold); color: #20201c; }
.purse { display: flex; align-items: center; gap: 8px; font-family: "Press Start 2P", monospace; font-size: 13px; }

/* ---- Botão de som ----
   O mesmo chip do HUD, com um alto-falante em pixel. As duas metades do ícone (ondas e o
   x de mudo) vivem no MESMO svg e trocam por classe: nada de um segundo arquivo, e nada
   de glifo — a fonte bitmap não tem alto-falante. */
.chip.sound { padding: 9px 11px; }
.px-speaker { width: 17px; height: 14px; display: block; }
.chip.sound .mudo { display: none; }
.chip.sound.is-off { color: #a89878; }
.chip.sound.is-off .onda { display: none; }
.chip.sound.is-off .mudo { display: block; }

/* ---- Hambúrguer ----
   Só existe no celular. Lá, som, admin e carteira saem do HUD e vão para #menu-modal. */
.hud .menu-btn { display: none; padding: 9px 11px; }
.px-burger { width: 17px; height: 15px; display: block; }
@media (max-width: 760px) {
  .hud { padding: 10px 12px; gap: 8px; }
  .hud-right { gap: 8px; }
  .hud .logo { gap: 7px; padding: 7px 9px; }
  .hud .logo .mark { width: 22px; height: 22px; }
  .hud .logo .mark::before, .hud .logo .mark::after { top: 6px; width: 5px; height: 5px; }
  .hud .logo .mark::before { left: 5px; }
  .hud .logo .mark::after { right: 5px; }
  .hud .logo h1 { font-size: 10px; }
  .hud .purse { font-size: 11px; padding: 8px 9px; }
  .hud .chip.sound, .hud #admin-chip, .hud #wallet-chip { display: none !important; }
  .hud .menu-btn { display: flex; }
  .confirm-actions .btn { flex: 1 1 auto; }
}
.purse .coin {
  width: 14px; height: 14px; background: var(--gold); border: 3px solid #000; border-radius: 50%;
  flex-shrink: 0;
}
.logo { display: flex; align-items: center; gap: 11px; }
.logo .mark { width: 30px; height: 30px; background: var(--lime); position: relative; flex-shrink: 0; }
.logo .mark::before,
.logo .mark::after { content: ""; position: absolute; top: 8px; width: 7px; height: 7px; background: #20201c; }
.logo .mark::before { left: 8px; }
.logo .mark::after { right: 8px; }
.logo h1 { font-size: 15px; margin: 0; }

.topbar-right { display: flex; align-items: center; gap: 16px; }

.chip {
  border: 2px solid var(--line); padding: 9px 12px; font-size: 12px; color: var(--ink-2);
  display: flex; gap: 8px; align-items: center; background: none;
}
.chip .live { width: 7px; height: 7px; background: var(--lime); flex-shrink: 0; }
.chip:hover { color: var(--ink); border-color: var(--line-hi); }

.balance { text-align: right; }
.balance b { font-family: "Press Start 2P", monospace; font-size: 15px; color: var(--lime); display: block; }
.balance small { display: block; font-size: 8px; color: var(--ink-2); margin-top: 6px; letter-spacing: .14em;
  font-family: "Press Start 2P", monospace; }

/* ---- Menu lateral ---- */
.nav { display: flex; flex-direction: column; gap: 3px; padding-top: 22px; }
.nav a {
  font-family: "Press Start 2P", monospace; font-size: 9px; padding: 13px 12px;
  color: var(--ink-2); text-decoration: none; border-left: 4px solid transparent;
  display: flex; gap: 9px; align-items: center;
}
.nav a::before { content: "▸"; opacity: 0; }
.nav a.on { color: var(--lime); border-left-color: var(--lime); background: #c8e6000f; }
.nav a.on::before { opacity: 1; }
.nav a:hover:not(.on) { color: var(--ink); background: #ffffff08; }
/* Uma aba ainda não construída não é escondida: ela aparece desabilitada, porque o menu
   é a promessa do que o site é. Esconder faria a loja "sumir" para quem já a viu. */
.nav a.soon { opacity: .38; pointer-events: none; }
.nav a.soon::after { content: "SOON"; font-size: 7px; margin-left: auto; color: var(--ink-3); }

.main { min-width: 0; }

/* ---- Página ---- */
.page { display: none; }
.page.is-active { display: block; }

h2.sec {
  font-family: "Press Start 2P", monospace; font-size: 10px; color: var(--ink-2);
  margin: 0 0 13px; display: flex; align-items: center; gap: 11px;
}
h2.sec::after { content: ""; flex: 1; height: 3px; background: var(--line); }

/* ============================================================
   COMPONENTES
   ============================================================ */

/* ---- Painel de status ---- */
.panel {
  border: 3px solid var(--line); background: var(--panel); margin-bottom: 16px;
  box-shadow: var(--shadow-lg);
}
.panel-head {
  background: var(--panel-2); border-bottom: 3px solid var(--line); padding: 10px 14px;
  font-family: "Press Start 2P", monospace; font-size: 9px; color: var(--ink-2); letter-spacing: .1em;
}
.panel-body { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }

.cell { padding: 15px; border-right: 2px solid var(--line); }
.cell:last-child { border-right: 0; }
.cell b { display: block; font-family: "Press Start 2P", monospace; font-size: 17px; margin-bottom: 8px;
  word-break: break-all; }
.cell span { font-size: 10px; letter-spacing: .13em; color: var(--ink-2); text-transform: uppercase; }
.cell.claim b { color: var(--lime); }
.cell.rate  b { color: var(--orange); }

/* Barra segmentada até o próximo ciclo de acúmulo.
   É um bloco por segmento e não uma barra contínua: o acúmulo do backend acontece em
   CICLOS discretos (a cada `accrualIntervalHours`), e uma barra lisa sugeriria um pingo
   contínuo de $HOOD que não é o que acontece. A forma conta a verdade da mecânica. */
.cycle { padding: 13px 15px; border-top: 2px solid var(--line); display: flex; align-items: center; gap: 13px; }
.blocks { display: flex; gap: 3px; flex: 1; }
.blocks i { height: 11px; flex: 1; background: var(--panel-2); border: 1px solid var(--line); }
.blocks i.f { background: var(--lime); border-color: var(--lime); }
.cycle span { font-size: 10px; color: var(--ink-2); white-space: nowrap; letter-spacing: .08em;
  font-family: "Press Start 2P", monospace; }

/* ---- Aviso ---- */
.notice {
  border: 3px solid #7d6a1f; background: #221d0c; padding: 12px 14px; margin-bottom: 16px;
  display: flex; gap: 11px; font-size: 13px; line-height: 1.55; color: #e5d9a8;
}
.notice b { font-family: "Press Start 2P", monospace; font-size: 8px; color: var(--warn);
  flex-shrink: 0; padding-top: 3px; }
.notice.danger { border-color: #7d2b25; background: #23100e; color: #f0c4bf; }
.notice.danger b { color: var(--danger); }
.notice.info { border-color: #1f5a7d; background: #0c1a22; color: #b9dced; }
.notice.info b { color: var(--boost-rank); }

/* ---- Botões ---- */
.btn {
  font-family: "Press Start 2P", monospace; font-size: 10px; padding: 15px 20px;
  border: 3px solid var(--lime); background: var(--lime); color: #141a00;
  box-shadow: 4px 4px 0 var(--lime-dk);
}
/* O deslocamento no clique é o "afundar" de um botão físico. É a única animação do
   sistema, e ela existe porque num layout sem sombra difusa e sem transição o clique
   não teria nenhum retorno visual. */
.btn:active:not(:disabled) { transform: translate(3px, 3px); box-shadow: 1px 1px 0 var(--lime-dk); }
.btn:disabled { opacity: .4; cursor: not-allowed; }

.btn.ghost { background: none; color: var(--ink-2); border-color: var(--line); box-shadow: 4px 4px 0 #00000055; }
.btn.ghost:hover:not(:disabled) { color: var(--ink); border-color: var(--line-hi); }
.btn.ghost:active:not(:disabled) { box-shadow: 1px 1px 0 #00000055; }
.btn.sm { font-size: 8px; padding: 11px 14px; }

.btn.is-loading { position: relative; color: transparent !important; pointer-events: none; }
.btn.is-loading::after {
  content: ""; position: absolute; inset: 0; margin: auto; width: 10px; height: 10px;
  background: #141a00; animation: blink .7s steps(2, start) infinite;
}
.btn.ghost.is-loading::after { background: var(--ink-2); }
@keyframes blink { to { opacity: 0; } }

.actions { display: flex; gap: 10px; align-items: center; margin-bottom: 20px; flex-wrap: wrap; }

/* ---- Grade de Hoodmons ---- */
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(152px, 1fr)); gap: 13px; margin-bottom: 30px; }

.card {
  border: 3px solid var(--line); background: var(--panel); position: relative;
  box-shadow: var(--shadow); transition: transform .08s, box-shadow .08s, border-color .08s;
}
.card:hover { transform: translate(-2px, -2px); box-shadow: 7px 7px 0 #00000055; border-color: var(--line-hi); }
/* O fundo do sprite já vem chapado dentro do GIF — o card não desenha fundo nenhum atrás
   dele, senão apareceria uma borda de cor errada em volta da arte. */
.card .art { aspect-ratio: 1; overflow: hidden; }
.card .art img { width: 100%; height: 100%; }
.card .meta { padding: 10px 11px; border-top: 3px solid var(--line); }
.card .id { font-family: "Press Start 2P", monospace; font-size: 10px; }
.card .rank { font-size: 11px; color: var(--ink-2); margin-top: 6px; }
.card .earn { font-size: 12px; color: var(--lime); font-weight: 700; margin-top: 8px; }
.card .act {
  width: 100%; font-family: "Press Start 2P", monospace; font-size: 8px; padding: 10px;
  border: 0; border-top: 3px solid var(--line); background: var(--panel-2); color: var(--ink-2);
}
.card .act:hover:not(:disabled) { background: var(--lime); color: #141a00; }
.card .act:disabled { opacity: .45; cursor: not-allowed; }

/* Rodapé de dois botões (CLAIM | UNSTAKE). Grade de duas colunas com uma borda entre
   elas, em vez de dois botões soltos: o card é um bloco só e o rodapé tem que ler como
   uma faixa dividida, não como dois elementos empilhados por acaso. */
.card-acts { display: grid; grid-template-columns: 1fr 1fr; }
.card-acts .act + .act { border-left: 3px solid var(--line); }
.card-acts .act:last-child:hover:not(:disabled) { background: var(--danger); color: #fff; }

/* Selo de multiplicador. A cor vem do BACKEND (`traitColor`/`rankColor`), aplicada
   inline — por isso aqui só existe a forma. */
.mult {
  position: absolute; top: 8px; right: 8px; font-family: "Press Start 2P", monospace;
  font-size: 8px; padding: 5px 6px; background: var(--boost-trait); color: #2a1a05;
  box-shadow: 2px 2px 0 #00000066;
}

/* Stake encerrado nas últimas 24h. Aparece na lista de propósito: é como o usuário
   descobre POR QUE um stake sumiu, em vez de só notar que sumiu. */
.card.ended { opacity: .6; }
.card.ended:hover { transform: none; }
.card .ribbon {
  position: absolute; left: 0; right: 0; bottom: 0; background: var(--danger); color: #fff;
  font-family: "Press Start 2P", monospace; font-size: 7px; padding: 6px; text-align: center;
}

/* ---- Estado vazio ---- */
.empty {
  border: 3px dashed var(--line); padding: 44px 24px; text-align: center; margin-bottom: 30px;
  /* O estado vazio é filho direto de `.grid`, então sem isto ele vira UMA célula de
     152px e o texto quebra letra a letra. Ocupar a linha inteira é o que faz ele ler
     como um aviso da seção, e não como um card sem arte. */
  grid-column: 1 / -1;
}
.empty-icon { font-size: 26px; color: var(--ink-3); display: block; margin-bottom: 18px; }
.empty h3 { font-size: 11px; margin: 0 0 12px; color: var(--ink-2); }
.empty p { font-size: 13px; color: var(--ink-3); margin: 0 auto 20px; max-width: 400px; line-height: 1.6; }

/* ---- Esqueleto de carregamento ---- */
.skel { border: 3px solid var(--line); background: var(--panel); }
.skel .art { aspect-ratio: 1; background: var(--panel-2); animation: pulse 1.2s steps(3, end) infinite; }
.skel .meta { padding: 10px 11px; border-top: 3px solid var(--line); }
.skel .bar { height: 10px; background: var(--panel-2); margin-bottom: 7px; }
.skel .bar.short { width: 55%; }
@keyframes pulse { 50% { opacity: .45; } }

/* ---- Toast ---- */
#toast-stack {
  position: fixed; right: 18px; bottom: 18px; z-index: 90;
  display: flex; flex-direction: column-reverse; gap: 9px; max-width: min(400px, calc(100vw - 36px));
}
.toast {
  border: 3px solid var(--line); background: var(--panel); padding: 13px 15px; font-size: 13px;
  line-height: 1.5; box-shadow: var(--shadow); opacity: 0; transform: translateX(14px);
  transition: opacity .2s, transform .2s;
}
.toast.show { opacity: 1; transform: none; }
.toast-success { border-color: var(--lime); }
.toast-error { border-color: var(--danger); }
.toast-info { border-color: var(--line-hi); }

/* ---- Modal (seletor de carteira) ---- */
.modal {
  position: fixed; inset: 0; z-index: 100; display: grid; place-items: center; padding: 20px;
  background: #000000cc; opacity: 0; transition: opacity .2s;
}
.modal.is-open { opacity: 1; }
.modal.hidden { display: none; }
.modal-card {
  border: 3px solid var(--line); background: var(--panel); width: 100%; max-width: 380px;
  box-shadow: 8px 8px 0 #00000088;
}
.modal-head {
  background: var(--panel-2); border-bottom: 3px solid var(--line); padding: 13px 15px;
  display: flex; align-items: center; justify-content: space-between;
}
.modal-head h3 { font-size: 10px; margin: 0; font-family: "Press Start 2P", monospace; }
.modal-close { background: none; border: 0; color: var(--ink-2); font-size: 18px; line-height: 1; padding: 4px 6px; }
.modal-close:hover { color: var(--ink); }
.modal-body { padding: 13px; }

.wallet-item {
  display: flex; align-items: center; gap: 12px; width: 100%; padding: 12px;
  background: var(--panel-2); border: 2px solid var(--line); color: var(--ink);
  text-decoration: none; margin-bottom: 7px; text-align: left;
}
.wallet-item:hover { border-color: var(--lime); }
.wallet-item.is-missing { opacity: .55; }
.wallet-ico { width: 30px; height: 30px; flex-shrink: 0; image-rendering: auto; }
.wallet-ico-mono {
  display: grid; place-items: center; background: var(--line); color: var(--ink); font-size: 11px;
}
.wallet-name { flex: 1; font-size: 14px; }
.wallet-tag { font-size: 7px; color: var(--ink-3); }
.wallet-item:hover .wallet-tag { color: var(--lime); }
.wallet-empty { font-size: 12px; color: var(--ink-3); text-align: center; margin: 14px 0 4px; }

.modal-foot { padding: 0 13px 13px; font-size: 11px; color: var(--ink-3); line-height: 1.5; }

/* ---- Confirmação (substitui o window.confirm) ----
   Acima de qualquer outra janela: ela pode nascer de dentro do menu ou do admin. */
.modal-confirm { z-index: 110; }
.modal-confirm .modal-card { max-width: 440px; }
.confirm-text { margin: 4px 2px 18px; font-size: 14px; line-height: 1.6; color: var(--ink); white-space: pre-line; }
.confirm-actions { display: flex; gap: 12px; justify-content: flex-end; flex-wrap: wrap; }
.btn.is-danger { background: var(--danger); border-color: var(--danger); color: #fff; box-shadow: 4px 4px 0 #7d2b25; }
.btn.is-danger:active:not(:disabled) { box-shadow: 1px 1px 0 #7d2b25; }

/* ---- Menu do celular ---- */
.menu-list { display: grid; gap: 8px; }
.menu-wallet {
  display: flex; align-items: center; gap: 10px; padding: 11px 12px; margin-bottom: 2px;
  border: 2px dashed var(--line); color: var(--ink-2); font-size: 14px;
}
.menu-wallet .live { width: 8px; height: 8px; background: var(--lime); flex-shrink: 0; }
.menu-row {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; width: 100%;
  padding: 16px 13px; background: var(--panel-2); border: 2px solid var(--line); color: var(--ink);
  font-family: "Press Start 2P", monospace; font-size: 10px; text-align: left;
}
.menu-row:hover, .menu-row:focus-visible { border-color: var(--lime); outline: 0; }
.menu-row b { font-weight: normal; color: var(--lime); font-size: 9px; }
.menu-row.is-danger { color: var(--danger); border-color: #7d2b25; }
.menu-row.is-danger:hover, .menu-row.is-danger:focus-visible { background: #23100e; border-color: var(--danger); }

/* ============================================================
   RESPONSIVO
   ============================================================ */
@media (max-width: 820px) {
  .topbar { flex-wrap: wrap; gap: 12px; }
  .cell { border-right: 0; border-bottom: 2px solid var(--line); }
  .panel-body { grid-template-columns: repeat(2, 1fr); }
  .cell:nth-child(odd) { border-right: 2px solid var(--line); }
  .grid { grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); gap: 10px; }
  .actions .btn { flex: 1 1 auto; }
  #toast-stack { right: 12px; left: 12px; bottom: 12px; max-width: none; }
}

/* Quem pediu menos movimento não recebe o "afundar" do botão nem o hover dos cards. */
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .001ms !important; animation-iteration-count: 1 !important;
      transition-duration: .001ms !important; }
  .card:hover { transform: none; }
  .btn:active:not(:disabled) { transform: none; }
}

/* ============================================================
   MAPA DO MUNDO
   ============================================================ */

/* O palco é a viewport, e ele NÃO rola: quem se move é o mapa, arrastado. Daí `fixed`,
   `overflow: hidden` e `touch-action: none` — sem o último, o navegador do celular
   interpreta o arrasto como rolagem da página e rouba o gesto. */
.map-stage {
  position: fixed; inset: 0; overflow: hidden;
  background: #000;
  /* Ver `has-sea` logo abaixo. */
  cursor: grab;
  touch-action: none;
  user-select: none; -webkit-user-select: none;
}
.map-stage.is-dragging { cursor: grabbing; }

/* Controles de zoom. Fora do palco arrastável, presos à viewport. Alvos de 44px: é o
   mínimo que um dedo acerta sem mirar, e no celular eles são o principal jeito de
   enquadrar o mapa. */
.map-zoom {
  position: fixed; right: 14px; bottom: 16px; z-index: 22;
  display: flex; flex-direction: column; gap: 7px;
}
.map-zoom button {
  width: 44px; height: 44px; cursor: pointer;
  display: grid; place-items: center;
  font-family: "Press Start 2P", monospace; font-size: 14px; line-height: 1;
  background: #f8f4e4; color: #20201c; border: 3px solid #000;
  box-shadow: 3px 3px 0 #00000077;
}
.map-zoom button:hover { background: var(--gold); }
.map-zoom button:active { transform: translate(3px, 3px); box-shadow: 0 0 0; }

/* O mapa não cobriu a tela inteira (janela em retrato, onde a ampliação tem teto — ver
   `ajustar` em js/map.js). A área que sobra vira OCEANO em vez de vazio preto: `--sea` foi
   amostrada das bordas do próprio arquivo do mapa, então o que aparece em volta lê como
   continuação do mundo. O degradê escurece para baixo, como água funda. */
.map-stage.has-sea {
  background: var(--sea);
  background-image: linear-gradient(180deg, var(--sea) 0%, var(--sea-dk) 100%);
}

/* Dimensionado em JS para COBRIR a viewport. `will-change` mantém a camada promovida,
   então o arrasto não repinta o mapa inteiro a cada quadro. */
.map {
  position: absolute; top: 0; left: 0; line-height: 0;
  will-change: transform;
}
.map > img {
  width: 100%; height: 100%; display: block;
  pointer-events: none;      /* o arrasto é do palco; a imagem não intercepta */
  -webkit-user-drag: none;   /* sem o "fantasma" de arrastar imagem do navegador */
}

/* Ver o cabeçalho de js/map.js: são DUAS camadas porque no CSS o `filter` roda ANTES do
   `mask`. Com os dois juntos, o brilho seria calculado no retângulo e depois recortado
   pela máscara — sumiria. Filtro no pai, máscara no filho: o brilho nasce da silhueta. */
.spot { position: absolute; padding: 0; border: 0; background: transparent; cursor: pointer; }
.spot-art {
  display: block; width: 100%; height: 100%;
  background-repeat: no-repeat;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-size: 100% 100%; mask-size: 100% 100%;
  opacity: 0; transition: opacity .12s, transform .12s;
  image-rendering: pixelated;
}
.map-stage:not(.is-dragging) .spot:hover .spot-art,
.spot:focus-visible .spot-art { opacity: 1; transform: translateY(-3px); }
.map-stage:not(.is-dragging) .spot:hover,
.spot:focus-visible {
  filter: brightness(1.22) saturate(1.18)
          drop-shadow(0 0 7px var(--gold)) drop-shadow(0 3px 0 #00000088);
}
.spot:focus-visible { outline: none; }
.spot.round .spot-art { border-radius: 50%; }

/* Placa de madeira no hover, no idioma das que já estão pintadas na arte. */
.spot::after {
  content: attr(data-label);
  position: absolute; left: 50%; bottom: -16px; transform: translateX(-50%);
  font-family: "Press Start 2P", monospace; font-size: 9px; white-space: nowrap;
  background: #f8f4e4; color: #20201c; border: 3px solid #000; padding: 6px 9px;
  box-shadow: 3px 3px 0 #00000066; opacity: 0; transition: opacity .12s; pointer-events: none;
}
.map-stage:not(.is-dragging) .spot:hover::after,
.spot:focus-visible::after { opacity: 1; }
.spot.locked { cursor: not-allowed; }
.map-stage:not(.is-dragging) .spot.locked:hover { filter: grayscale(.7) brightness(.8); }
.spot.locked::after { content: attr(data-label) " · SOON"; background: #cfc6ac; color: #6b6252; }

/* ============================================================
   INTERIOR — o que se vê ao ENTRAR numa construção
   ------------------------------------------------------------
   O mapa é a rua; isto é o salão do castelo. Tudo aqui obedece à mesma gramática das
   placas da ilustração: creme, borda preta grossa, sombra dura deslocada, canto reto.
   Zero gradiente, zero desfoque, zero raio de borda.
   ============================================================ */

/* ---- A cortina ----
   Cobre tudo, inclusive o HUD, durante a troca de lugar. Os DEGRAUS são o ponto: cinco
   tons de preto, como o hardware de 16 bits fazia trocando a paleta. `pointer-events`
   liga junto, para ninguém clicar num prédio no meio do escuro. */
#fade {
  position: fixed; inset: 0; z-index: 200; background: #000;
  opacity: 0; pointer-events: none;
  transition: opacity .36s steps(5, end);
}
#fade.is-on { opacity: 1; pointer-events: auto; }

/* ============================================================
   O STAKING HALL — uma cena (js/hall.js)
   ============================================================ */

/* O palco é a viewport e não rola. O salão COBRE a tela (a maior das duas escalas) e
   fica centralizado, em CSS puro: largura = a maior entre a da tela e a que a altura da
   tela pede na proporção da arte. O que sobra sai pelas bordas — no celular em pé, as
   laterais; o centro (mesa e tapete) sempre aparece. */
.hall-stage {
  position: fixed; inset: 0; overflow: hidden; background: #000;
  user-select: none; -webkit-user-select: none;
}
.hall {
  position: absolute; left: 50%; top: 50%;
  width: max(100vw, calc(100vh * 1672 / 941));
  width: max(100vw, calc(100dvh * 1672 / 941));
  aspect-ratio: 1672 / 941;
  transform: translate(-50%, -50%);
}
.hall-art {
  width: 100%; height: 100%; display: block;
  pointer-events: none; -webkit-user-drag: none;
}

/* Pontos clicáveis: invisíveis até o hover, e aí brilham com a placa de madeira em cima,
   no mesmo idioma dos prédios do mapa. */
.hall-spot {
  position: absolute; padding: 0; border: 0; background: transparent; cursor: pointer;
}
.hall-spot::before {
  content: ""; position: absolute; inset: 0;
  box-shadow: inset 0 0 0 3px var(--gold), 0 0 18px #fdbd3166;
  opacity: 0; transition: opacity .12s;
}
.hall-spot::after {
  content: attr(data-label);
  position: absolute; left: 50%; top: -14px; transform: translateX(-50%);
  font-family: "Press Start 2P", monospace; font-size: 9px; white-space: nowrap;
  background: #f8f4e4; color: #20201c; border: 3px solid #000; padding: 6px 9px;
  box-shadow: 3px 3px 0 #00000066; opacity: 0; transition: opacity .12s; pointer-events: none;
}
.hall-spot:hover::before, .hall-spot:hover::after,
.hall-spot:focus-visible::before, .hall-spot:focus-visible::after { opacity: 1; }
.hall-spot:focus-visible { outline: none; }

/* O Hoodmon. Ancorado pelos PÉS: a sombra desenhada no sprite fica a ~88% da altura,
   e é ela que tem que encostar no chão. O tamanho em px vem de hall.js (múltiplo de 25). */
.hall-hero {
  position: absolute; width: 125px; height: 125px;
  transform: translate(-50%, -88%);
  pointer-events: none; z-index: 2;
  /* A caminhada: 18 degraus em vez de um deslize. É o passo de tile dos jogos da época,
     e é o que faz o salão parecer um jogo e não um site com animação. */
  transition: top 2.4s steps(18, end);
}
.hall-hero img { width: 100%; height: 100%; image-rendering: pixelated; display: block; }
/* Andando: um pulinho de dois quadros por cima da animação do próprio GIF. */
.hall-hero.is-walking img { animation: hall-hop .26s steps(2, jump-none) infinite alternate; }
@keyframes hall-hop { from { transform: translateY(0); } to { transform: translateY(-7%); } }

/* Sem sprite (sem token, ou o arquivo não carregou): entra o guia, #1, com a folha de
   8 quadros dele. */
.hall-hero.is-guide img { display: none; }
.hall-hero.is-guide {
  background: url("../assets/guide.png") 0 0 / 800% 100% no-repeat;
  animation: hall-guide .8s steps(8) infinite;
  image-rendering: pixelated;
}
@keyframes hall-guide { to { background-position: 114.2857% 0; } }

/* O "!" do banqueiro: pula duas vezes, como o de um NPC que te viu. */
.hall-bubble {
  position: absolute; transform: translate(-50%, -100%); z-index: 3;
  font-size: 16px; color: #b3341f; background: #f8f4e4;
  border: 3px solid #000; padding: 6px 9px 5px; box-shadow: 3px 3px 0 #00000088;
  animation: hall-bubble .5s steps(2, end) 2;
}
@keyframes hall-bubble { 50% { transform: translate(-50%, -125%); } }

/* EXIT: flutua sobre a escada por onde se entrou (x 50% da arte). A altura tem teto: em
   tela muito larga o salão é cortado embaixo, e a placa sobe até ficar visível — `50% +
   50dvh` é a borda de baixo da tela, medida dentro do salão centralizado. Só aparece com a
   conversa encerrada (hall.js), e surge com um "pop" de dois quadros. */
.hall-exit {
  position: absolute; left: 50%; z-index: 3;
  top: min(86%, calc(50% + 50vh - 58px));
  top: min(86%, calc(50% + 50dvh - 58px));
  transform: translate(-50%, -50%);
  display: flex; flex-direction: column; align-items: center; gap: 5px;
  font-family: "Press Start 2P", monospace; font-size: 9px; color: #20201c;
  background: #f8f4e4; border: 3px solid #000; padding: 8px 11px 6px;
  box-shadow: inset -2px -2px 0 #a89878, inset 2px 2px 0 #fff, 3px 3px 0 #000000aa;
  animation:
    hall-exit-pop .16s steps(2, end),
    hall-exit-float 1.1s steps(2, jump-none) .16s infinite alternate;
}
.hall-exit:hover, .hall-exit:focus-visible { background: var(--gold); outline: none; }
.hall-exit:active { box-shadow: 0 0 0; }
.px-arrow { width: 14px; height: 8px; color: #b3341f; }
@keyframes hall-exit-pop {
  from { transform: translate(-50%, -50%) scale(.4); }
  to { transform: translate(-50%, -50%) scale(1); }
}
@keyframes hall-exit-float {
  from { transform: translate(-50%, -50%); }
  to { transform: translate(-50%, calc(-50% + 4px)); }
}

/* Saindo: a mesma caminhada, ao contrário e mais curta — quem vai embora não passeia. */
.hall-hero.is-walking.is-leaving { transition: top 1.2s steps(9, end); }

/* LEAVE: embaixo do logo, fora do caminho da mesa. */
.hall-leave { position: fixed; top: 70px; left: 16px; z-index: 21; margin: 0; }

/* ---- O banqueiro fala ----
   A caixa é a do guia (.dialog). O retrato é um recorte da PRÓPRIA arte do salão, no rosto
   do banqueiro (782,212 · 106px), ampliado para a moldura de 84px. */
.hall-dialog { z-index: 40; }
/* Duas classes de propósito: `.dialog-portrait` (do guia) vem depois neste arquivo e o
   `background` dela apagaria o recorte. */
.dialog-portrait.banker-portrait {
  background: url("../assets/hall.webp") no-repeat;
  /* 84 / 106 da arte: tamanho e posição na mesma escala. */
  background-size: calc(1672px * 84 / 106) calc(941px * 84 / 106);
  background-position: calc(-782px * 84 / 106) calc(-212px * 84 / 106);
  image-rendering: pixelated;
}
/* O ▼ só faz sentido sem menu: com menu, a escolha já é o próximo passo. */
.hall-dialog:has(.hall-menu:not([hidden])) .dialog-inner::after { display: none; }

.hall-menu { display: grid; gap: 6px; margin-top: -4px; }
.hall-opt {
  display: flex; align-items: center; gap: 10px; text-align: left;
  font-family: "Press Start 2P", monospace; font-size: 10px; color: #20201c;
  background: transparent; border: 0; padding: 7px 4px;
}
.hall-opt .cursor { color: #b3341f; opacity: 0; font-size: 10px; }
/* `:focus` e não `:focus-visible`: o menu nasce com o foco no primeiro item (hall.js), e o
   ▶ tem que estar lá desde o começo, como em todo menu de cartucho. */
.hall-opt:hover .cursor, .hall-opt:focus .cursor { opacity: 1; animation: dialog-bob .9s steps(2, start) infinite; }
.hall-opt:hover, .hall-opt:focus { background: #e6dec4; outline: none; }

/* ---- A janela de staking ----
   Fundo escurecido por cima do salão, e a janela no centro: moldura de RPG creme com a
   faixa de título no azul dos estandartes do salão e o dourado das coroas. */
/* z-index 19: ABAIXO do HUD (20) e do LEAVE (21). O saldo continua nítido em cima do
   escurecido — é o número que muda quando se saca, e vê-lo subir é a recompensa. */
.hall-window {
  position: fixed; inset: 0; z-index: 19;
  background: #000000a6;
  display: grid; place-items: center; padding: 72px 14px 14px;
}
body.hall-window-open { overflow: hidden; }
/* Com a janela aberta, a saída é o ✕ dela. O LEAVE ficaria em cima do título no celular,
   e sair do salão com a janela aberta pula a volta ao banqueiro. */
body.hall-window-open .hall-leave { display: none; }

.rpg-window {
  width: min(1000px, 100%); max-height: calc(100dvh - 90px);
  display: flex; flex-direction: column;
  background: #f8f4e4; border: 4px solid #000;
  box-shadow: inset 0 0 0 3px #e0a93a, 8px 8px 0 #000000aa;
}
/* Abre como janela de cartucho: de uma linha para a altura inteira, em quatro quadros. */
.hall-window.is-opening .rpg-window { animation: rpg-open .2s steps(4, end); }
@keyframes rpg-open { from { transform: scaleY(.06); } to { transform: scaleY(1); } }

.rpg-title {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  background: #1d2d6b; border-bottom: 4px solid #000; padding: 12px 14px;
  box-shadow: inset 0 -3px 0 #e0a93a;
}
.rpg-title h2 {
  margin: 0; font-family: "Press Start 2P", monospace; font-size: 12px; color: #fdd66a;
  text-shadow: 2px 2px 0 #000;
  display: flex; align-items: center; gap: 10px;
}
.px-crown { width: 18px; height: 12px; filter: drop-shadow(2px 2px 0 #000); }
.rpg-close {
  font-family: "Press Start 2P", monospace; font-size: 11px; line-height: 1;
  background: #f8f4e4; color: #20201c; border: 3px solid #000; padding: 7px 8px;
  box-shadow: 2px 2px 0 #000;
}
.rpg-close:hover { background: var(--gold); }
.rpg-close:active { transform: translate(2px, 2px); box-shadow: 0 0 0; }

.rpg-body { overflow-y: auto; padding: 16px; overscroll-behavior: contain; }
/* Dentro da janela, os painéis perdem a sombra de fora: já estão sobre papel. */
.rpg-body .panel, .rpg-body .notice { box-shadow: inset -3px -3px 0 #a89878, inset 3px 3px 0 #fff; }

.rpg-bar {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 10px;
  flex-wrap: wrap-reverse; margin: 4px 0 14px; border-bottom: 4px solid #000;
}
.rpg-bar .actions { margin: 0 0 8px; }
#page-staking .rpg-bar .btn, #page-raffles .rpg-bar .btn, #page-profile .rpg-bar .btn { font-size: 9px; padding: 11px 14px; }
.rpg-tabs { display: flex; gap: 6px; }
.rpg-tabs button {
  font-family: "Press Start 2P", monospace; font-size: 9px; color: #6b6252;
  background: #e6dec4; border: 4px solid #000; border-bottom: 0;
  padding: 11px 13px; margin-bottom: -4px;
}
.rpg-tabs button.is-active { background: #1d2d6b; color: #fdd66a; padding-bottom: 15px; }
.rpg-tabs button:hover:not(.is-active) { background: var(--gold); color: #20201c; }

/* Sair: é uma porta, não um botão de navegador. */
.back {
  display: inline-flex; align-items: center; gap: 9px; margin-bottom: 18px;
  font-family: "Press Start 2P", monospace; font-size: 9px; padding: 12px 15px;
  background: #4a4f5c; color: #e9e4d4; border: 4px solid #000; box-shadow: 4px 4px 0 #00000099;
}
.back:hover { background: var(--gold); color: #20201c; }
.back:active { transform: translate(4px, 4px); box-shadow: 0 0 0; }

/* ---- A JANELA: a peça que se repete em todo interior ----
   Borda preta por fora, filete branco por dentro, linha de sombra embaixo e à direita.
   É o frame de caixa de texto de RPG. */
#page-staking .panel, #page-raffles .panel, #page-profile .panel {
  background: #f8f4e4; border: 4px solid #000; margin-bottom: 16px;
  box-shadow: inset -3px -3px 0 #a89878, inset 3px 3px 0 #fff, 5px 5px 0 #00000077;
}
#page-staking .panel-head, #page-raffles .panel-head, #page-profile .panel-head {
  background: #000; color: #f8f4e4; border-bottom: 0;
  padding: 9px 12px; font-size: 9px; letter-spacing: .12em;
}
#page-staking .panel-body, #page-raffles .panel-body, #page-profile .panel-body { padding: 2px; }
#page-staking .cell, #page-raffles .cell, #page-profile .cell { padding: 13px 14px; border-right: 3px solid #e6dec4; }
#page-staking .cell:last-child, #page-raffles .cell:last-child, #page-profile .cell:last-child { border-right: 0; }
#page-staking .cell b, #page-raffles .cell b, #page-profile .cell b { color: #20201c; font-size: 17px; }
#page-staking .cell span, #page-raffles .cell span, #page-profile .cell span { color: #6b6252; font-family: "Press Start 2P", monospace; font-size: 9px; }
#page-staking .cell.claim b, #page-raffles .cell.claim b, #page-profile .cell.claim b { color: #2f7d38; }
#page-staking .cell.rate  b, #page-raffles .cell.rate  b, #page-profile .cell.rate  b { color: var(--gold-dk); }

/* Barra de EXP, igual à de baixo da tela de batalha. */
#page-staking .cycle, #page-raffles .cycle, #page-profile .cycle { border-top: 3px solid #e6dec4; padding: 12px 14px; }
#page-staking .blocks i, #page-raffles .blocks i, #page-profile .blocks i { background: #cfc6ac; border: 2px solid #000; height: 13px; }
#page-staking .blocks i.f, #page-raffles .blocks i.f, #page-profile .blocks i.f { background: #2c6fd8; border-color: #000; }
#page-staking .cycle span, #page-raffles .cycle span, #page-profile .cycle span { color: #6b6252; }

/* ---- Avisos: fala de NPC ---- */
#page-staking .notice, #page-raffles .notice, #page-profile .notice {
  background: #f8f4e4; color: #20201c; border: 4px solid #000;
  box-shadow: inset -3px -3px 0 #a89878, inset 3px 3px 0 #fff, 5px 5px 0 #00000077;
  padding: 14px 16px; font-size: 14px;
}
#page-staking .notice b, #page-raffles .notice b, #page-profile .notice b { color: #b3341f; font-size: 8px; }
#page-staking .notice.danger, #page-raffles .notice.danger, #page-profile .notice.danger { background: #f8e4de; }
#page-staking .notice.info, #page-raffles .notice.info, #page-profile .notice.info { background: #e2ecf8; }
#page-staking .notice.info b, #page-raffles .notice.info b, #page-profile .notice.info b { color: #2c6fd8; }
/* A regra de listagem é um aviso PERMANENTE, não um evento. Lê como placa na parede do
   salão — o dourado da marca —, e não como a fala vermelha de "algo aconteceu". Só o valor
   em jogo leva vermelho, porque é o número que a pessoa perde. */
#page-staking .notice.rule, #page-raffles .notice.rule, #page-profile .notice.rule { background: #fbf0cf; }
#page-staking .notice.rule b, #page-raffles .notice.rule b, #page-profile .notice.rule b { color: var(--gold-dk); }
#page-staking .notice.rule strong, #page-raffles .notice.rule strong, #page-profile .notice.rule strong { color: #b3341f; }

/* ---- Botões grandes ---- */
#page-staking .btn, #page-raffles .btn, #page-profile .btn {
  background: var(--gold); color: #20201c; border: 4px solid #000;
  box-shadow: 4px 4px 0 var(--gold-dk); font-size: 11px; padding: 15px 20px;
}
#page-staking .btn:active:not(:disabled), #page-raffles .btn:active:not(:disabled), #page-profile .btn:active:not(:disabled) { transform: translate(4px, 4px); box-shadow: 0 0 0; }
#page-staking .btn.ghost, #page-raffles .btn.ghost, #page-profile .btn.ghost { background: #f8f4e4; color: #20201c; box-shadow: 4px 4px 0 #a89878; }
#page-staking .btn.is-loading::after, #page-raffles .btn.is-loading::after, #page-profile .btn.is-loading::after { background: #20201c; }

/* ---- Slot de equipe ---- */
#page-staking .grid, #page-raffles .grid, #page-profile .grid { grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 12px; }

.slot {
  display: flex; overflow: hidden;
  background: #f8f4e4; border: 4px solid #000;
  box-shadow: inset -3px -3px 0 #a89878, inset 3px 3px 0 #fff, 5px 5px 0 #00000077;
  transition: transform .1s;
}
.slot:hover { transform: translate(-2px, -2px); }
/* 150px = 3× exatos os 50px da arte. Ver o comentário em cardHtml(). */
.slot-art {
  width: 150px; height: 150px; flex-shrink: 0;
  border-right: 4px solid #000; background: #000; line-height: 0;
}
.slot-art img { width: 100%; height: 100%; image-rendering: pixelated; }
.slot-info { flex: 1; padding: 12px 13px; display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.slot-name { font-family: "Press Start 2P", monospace; font-size: 12px; color: #20201c; }
.slot-lv { font-family: "Press Start 2P", monospace; font-size: 9px; color: #6b6252; }
.slot-earn { font-family: "Press Start 2P", monospace; font-size: 10px; color: #2f7d38; margin-top: auto; }

/* Selo de raridade: a "tipagem" da criatura. A cor vem do backend quando há boost. */
.type {
  align-self: flex-start; font-family: "Press Start 2P", monospace; font-size: 8px;
  padding: 5px 7px; border: 3px solid #000; background: #8a8578; color: #fff;
}

.slot-acts { display: flex; gap: 6px; flex-wrap: wrap; }
.mini {
  font-family: "Press Start 2P", monospace; font-size: 8px; padding: 9px 10px;
  background: #e6dec4; color: #20201c; border: 3px solid #000; box-shadow: 2px 2px 0 #a89878;
}
.mini:hover:not(:disabled) { background: var(--gold); }
.mini.danger:hover:not(:disabled) { background: #d8402c; color: #fff; }
.mini:active:not(:disabled) { transform: translate(2px, 2px); box-shadow: 0 0 0; }
.mini:disabled { opacity: .45; cursor: not-allowed; }

/* Listado na OpenSea: o card fica — o Hoodmon é seu — e avisa, mas NÃO trava. A tarja vem
   de uma varredura que atrasa; quem decide é o clique, que confere ao vivo. Por isso a arte
   também não esmaece: o card não está indisponível, só avisado. Laranja e não vermelho:
   ainda não é perda. */
.tag-listed {
  align-self: flex-start;
  font-family: "Press Start 2P", monospace; font-size: 8px; padding: 5px 7px;
  background: var(--orange); color: #20201c; border: 3px solid #000;
}

/* ---- Estado vazio e esqueleto, no mesmo idioma ---- */
#page-staking .empty, #page-raffles .empty, #page-profile .empty {
  background: #f8f4e4; border: 4px dashed #000; color: #20201c;
}
#page-staking .empty h3, #page-raffles .empty h3, #page-profile .empty h3 { color: #20201c; }
#page-staking .empty p, #page-raffles .empty p, #page-profile .empty p { color: #6b6252; }
#page-staking .empty-icon, #page-raffles .empty-icon, #page-profile .empty-icon { color: #a89878; }

.slot.skel .slot-art { background: #cfc6ac; animation: pulse 1.2s steps(3, end) infinite; }
.slot.skel .bar { display: block; height: 11px; background: #e6dec4; }
.slot.skel .bar.short { width: 55%; }

@media (max-width: 620px) {
  #page-staking .grid, #page-raffles .grid, #page-profile .grid { grid-template-columns: 1fr; }
  .slot-art { width: 100px; height: 100px; }   /* 2× exatos */
  .hall-window { padding: 64px 6px 6px; }
  .rpg-body { padding: 10px; }
  .rpg-tabs button { font-size: 8px; padding: 10px 9px; }
  .rpg-tabs button.is-active { padding-bottom: 14px; }
}

/* ============================================================
   O GUIA — sprite no mundo + caixa de diálogo
   ============================================================ */

/* O guia é filho do MAPA e posicionado em % dele: quando a câmera anda, ele vai junto,
   porque está NO mundo. `translate(-50%,-100%)` ancora pelos pés, que é o ponto que a
   gente quer colar no chão do cenário. */
.guide {
  position: absolute;
  width: 100px; height: 100px;
  transform: translate(-50%, -100%);
  /* Folha de 8 quadros lado a lado, animada por `steps()`. Um arquivo de 1,2 KB, sem
     formato animado para dar problema de suporte, e com o timing sob controle daqui. */
  /* `../`: a URL de um CSS resolve relativa ao ARQUIVO .css, não à página. Sem isso o
     navegador pede css/assets/guide.png e leva 404 — e o guia some sem nenhum erro de JS
     para denunciar. */
  background: url("../assets/guide.png") 0 0 / 800px 100px no-repeat;
  animation: guide-idle .8s steps(8) infinite;
  image-rendering: pixelated;
  pointer-events: none;
  z-index: 5;
  /* A transição da posição é o "andar". `steps` não entra aqui: o deslocamento é suave,
     só a troca de quadro é discreta. */
  transition: left .7s ease-out, top .7s ease-out;
  filter: drop-shadow(0 3px 0 #00000055);
}
@keyframes guide-idle { to { background-position: -800px 0; } }

/* ---- Caixa de diálogo ----
   Presa embaixo, largura do texto limitada: linha comprida demais cansa e some o ritmo
   de fala. Cream, borda preta, filete branco — a mesma janela de RPG dos interiores. */
.dialog {
  position: fixed; z-index: 60;
  left: 50%; bottom: 22px; transform: translateX(-50%);
  width: min(720px, calc(100vw - 32px));
}
.dialog-inner {
  background: #f8f4e4; color: #20201c;
  border: 4px solid #000;
  box-shadow: inset -3px -3px 0 #a89878, inset 3px 3px 0 #fff, 6px 6px 0 #00000099;
  padding: 14px 16px;
  display: flex; gap: 14px; align-items: flex-start;
}

/* ---- Retrato de quem fala ----
   Moldura própria, fundo do céu da arte, e o MESMO sprite recortado que anda no mapa.
   Sem ele a caixa seria um aviso de sistema com tipografia de jogo; com ele, alguém está
   falando com você. */
.dialog-portrait {
  flex-shrink: 0; width: 84px; height: 84px;
  border: 3px solid #000; background: #6d92aa;
  display: grid; place-items: center; overflow: hidden;
  box-shadow: inset -2px -2px 0 #00000033;
}
.guide-sprite {
  display: block; width: 80px; height: 80px;
  background: url("../assets/guide.png") 0 0 / 640px 80px no-repeat;
  animation: guide-idle-sm .8s steps(8) infinite;
  image-rendering: pixelated;
}
@keyframes guide-idle-sm { to { background-position: -640px 0; } }

.dialog-body { flex: 1; min-width: 0; }
.dialog-name {
  display: block; font-family: "Press Start 2P", monospace; font-size: 9px;
  color: #b3341f; margin-bottom: 9px; letter-spacing: .08em;
}
.dialog-text {
  margin: 0 0 14px; font-size: 16px; line-height: 1.65;
  min-height: 3.3em;              /* não pula de altura ao trocar de frase */
}
.dialog-foot { display: flex; align-items: center; gap: 8px; }

.dialog-mute, .dialog-skip, .dialog-next {
  font-family: "Press Start 2P", monospace;
  border: 3px solid #000; cursor: pointer; color: #20201c;
}
.dialog-mute {
  background: #e6dec4; font-size: 11px; padding: 9px 11px; box-shadow: 2px 2px 0 #a89878;
}
.dialog-skip {
  background: #e6dec4; font-size: 8px; padding: 10px 12px; box-shadow: 2px 2px 0 #a89878;
  color: #6b6252; margin-right: auto;
}
.dialog-next {
  background: var(--gold); font-size: 10px; padding: 12px 18px; box-shadow: 3px 3px 0 var(--gold-dk);
}
.dialog-mute:active, .dialog-skip:active { transform: translate(2px, 2px); box-shadow: 0 0 0; }
.dialog-next:active { transform: translate(3px, 3px); box-shadow: 0 0 0; }

/* O ▼ só aparece quando a frase TERMINOU de ser digitada. É o sinal de "pode continuar",
   e mostrá-lo durante a digitação diria a coisa errada. */
.dialog-inner::after {
  content: "▼"; position: absolute; right: 14px; top: 14px;
  font-size: 13px; color: #6b6252; opacity: 0;
}
.dialog.is-done .dialog-inner::after { opacity: 1; animation: dialog-bob .9s steps(2, start) infinite; }
.dialog-inner { position: relative; }
@keyframes dialog-bob { to { opacity: 0; } }

@media (max-width: 620px) {
  .dialog { bottom: 12px; }
  .dialog-text { font-size: 14px; }
  .dialog-portrait { width: 62px; height: 62px; }
  .guide-sprite { width: 60px; height: 60px; background-size: 480px 60px; }
  @keyframes guide-idle-sm { to { background-position: -480px 0; } }
  .guide { width: 70px; height: 70px; background-size: 560px 70px; }
  @keyframes guide-idle { to { background-position: -560px 0; } }
}

/* ============================================================
   O RAFFLE HALL (js/raffle-hall.js, js/raffle.js)
   ------------------------------------------------------------
   A CENA reusa tudo do Staking Hall — `.hall-stage`, `.hall`, `.hall-spot`, `.hall-hero`,
   `.hall-exit`, `.dialog`, `.rpg-window`. Aquelas classes nunca souberam qual arte estão
   cobrindo: a imagem vem do `<img>` e as medidas vêm do HTML. O que existe aqui é só o
   que é próprio da rifa — o retrato do mestre e os cards.
   ============================================================ */

/* O retrato: um recorte da PRÓPRIA arte do salão, no rosto do mestre encapuzado
   (790,225 · 106px), ampliado para a moldura de 84px. Mesma técnica do banqueiro. */
.dialog-portrait.master-portrait {
  background: url("../assets/raffle.webp") no-repeat;
  background-size: calc(1672px * 84 / 106) calc(941px * 84 / 106);
  background-position: calc(-790px * 84 / 106) calc(-225px * 84 / 106);
  image-rendering: pixelated;
}

/* ---- Card de rifa ----
   Mais alto que o slot de Hoodmon porque conta uma história mais longa: o prêmio, quanto
   já foi vendido, a sua chance e o preço. Mesmo frame de RPG dos painéis. */
#page-raffles .rf-card {
  background: #f8f4e4; border: 4px solid #000; position: relative;
  box-shadow: inset -3px -3px 0 #a89878, inset 3px 3px 0 #fff, 5px 5px 0 #00000077;
  display: flex; flex-direction: column;
}

/* A arte do prêmio vem de fora (o admin cadastra a URL, e o backend só aceita host da
   allowlist). Altura fixa e `contain`: um prêmio é um objeto fotografado em proporção
   qualquer, e `cover` cortaria justamente o que a pessoa quer ver. */
.rf-art {
  position: relative; height: 150px; background: #2a2431;
  border-bottom: 4px solid #000; overflow: hidden;
}
.rf-art img { width: 100%; height: 100%; object-fit: contain; image-rendering: auto; }
/* Imagem que não carregou: a moldura fica, com a marca d'água da coroa. Um card sem topo
   pareceria quebrado; um card com a coroa parece um prêmio ainda não revelado. */
.rf-art.broken img { display: none; }
.rf-art.broken::after {
  content: "?"; position: absolute; inset: 0; display: grid; place-items: center;
  font-family: "Press Start 2P", monospace; font-size: 30px; color: #6b5b7d;
}

/* O relógio: canto da arte, como o cronômetro de uma fase. */
.rf-clock {
  position: absolute; top: 8px; right: 8px;
  font-family: "Press Start 2P", monospace; font-size: 8px; padding: 6px 7px;
  background: #f8f4e4; color: #20201c; border: 3px solid #000; box-shadow: 2px 2px 0 #00000066;
}
/* Venceu mas ainda não sorteou (o cron roda de 10 em 10 min): é uma espera legítima, e
   dizer isso é melhor que um "0M 00S" parado. */
.rf-clock.due { background: var(--gold); animation: rf-pulse 1s steps(2, end) infinite; }
.rf-clock.done { background: #cfc6ac; color: #6b6252; }
@keyframes rf-pulse { 50% { opacity: .55; } }

.rf-meta { padding: 12px 13px 0; }
.rf-name { font-family: "Press Start 2P", monospace; font-size: 11px; color: #20201c; line-height: 1.5; }
.rf-desc {
  font-size: 13px; color: #6b6252; margin: 8px 0 0; line-height: 1.5;
  /* Duas linhas e corta: a descrição é um complemento, e uma que cresce sem limite
     empurra o preço e o botão para baixo da dobra em metade dos cards. */
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

/* Barra de tickets vendidos — a mesma barra de EXP da tela de batalha, e de propósito:
   é a mesma ideia de "encheu até aqui". */
.rf-bar { padding: 12px 13px 0; }
.rf-bar-top {
  display: flex; justify-content: space-between; gap: 8px; margin-bottom: 6px;
  font-family: "Press Start 2P", monospace; font-size: 8px; color: #6b6252;
}
.rf-track { height: 13px; background: #cfc6ac; border: 2px solid #000; }
.rf-track span { display: block; height: 100%; background: #2c6fd8; transition: width .2s steps(6, end); }

.rf-stats {
  display: grid; grid-template-columns: repeat(4, 1fr);
  margin: 12px 13px 0; border: 3px solid #e6dec4;
}
.rf-stat { padding: 9px 4px; text-align: center; border-right: 3px solid #e6dec4; }
.rf-stat:last-child { border-right: 0; }
.rf-stat b { display: block; font-family: "Press Start 2P", monospace; font-size: 12px; color: #20201c; }
.rf-stat span { display: block; font-size: 10px; color: #6b6252; margin-top: 5px; line-height: 1.3; }

/* Preço e stepper na mesma linha. O total à direita é o número que a pessoa confere
   antes de clicar — por isso ele é o maior dos dois. */
.rf-buyrow {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 12px 13px; margin-top: auto;
}
.rf-step { display: flex; align-items: center; border: 3px solid #000; background: #fff; }
.rf-step button {
  width: 34px; height: 34px; border: 0; background: #e6dec4; color: #20201c;
  font-family: "Press Start 2P", monospace; font-size: 12px; line-height: 1; cursor: pointer;
}
.rf-step button:hover:not(:disabled) { background: var(--gold); }
.rf-step button:disabled { opacity: .35; cursor: not-allowed; }
.rf-qty {
  min-width: 42px; text-align: center;
  font-family: "Press Start 2P", monospace; font-size: 12px; color: #20201c;
}
.rf-total { font-family: "Press Start 2P", monospace; font-size: 11px; color: var(--gold-dk); }

/* O botão. Ocupa a largura inteira do rodapé — é a ação do card, não uma entre várias. */
.rf-buy {
  width: 100%; border: 0; border-top: 4px solid #000; cursor: pointer;
  font-family: "Press Start 2P", monospace; font-size: 9px; padding: 14px 10px;
  background: var(--gold); color: #20201c; line-height: 1.4;
}
.rf-buy:hover:not(:disabled) { background: #ffd34d; }
.rf-buy:active:not(:disabled) { background: var(--gold-dk); color: #fff; }
.rf-buy:disabled { background: #cfc6ac; color: #6b6252; cursor: not-allowed; }
.rf-buy.ghost { background: #e6dec4; }
.rf-buy.ghost:hover { background: var(--gold); }
/* Armado: o segundo clique compra. Vermelho porque é o gesto que gasta — a mesma cor que
   o resto do app usa para "isto tira alguma coisa de você". */
.rf-buy.is-armed { background: #b3341f; color: #fff; animation: rf-armed .5s steps(2, end) infinite alternate; }
@keyframes rf-armed { to { background: #d94a32; } }
.rf-buy.is-loading { color: transparent; position: relative; }
.rf-buy.is-loading::after {
  content: ""; position: absolute; left: 50%; top: 50%; width: 9px; height: 9px;
  margin: -4px 0 0 -4px; background: #20201c; animation: blink .5s steps(2, end) infinite;
}

/* Compra fechada: o motivo ocupa o lugar do stepper, em vez de deixar um vão. */
.rf-locked {
  margin: 12px 13px; padding: 11px; text-align: center; margin-top: auto;
  font-family: "Press Start 2P", monospace; font-size: 8px; color: #6b6252;
  background: #efe8d2; border: 3px solid #e6dec4; line-height: 1.5;
}

/* ---- Rifa encerrada ---- */
#page-raffles .rf-card.is-ended .rf-art { filter: saturate(.45); }
#page-raffles .rf-card.is-won { box-shadow: inset -3px -3px 0 #a89878, inset 3px 3px 0 #fff, 5px 5px 0 #00000077, 0 0 0 4px var(--gold); }
.rf-outcome {
  margin: 12px 13px; padding: 11px; text-align: center; margin-top: auto;
  font-family: "Press Start 2P", monospace; font-size: 9px; border: 3px solid #000;
}
.rf-outcome.won  { background: var(--gold); color: #20201c; box-shadow: inset -2px -2px 0 var(--gold-dk); }
.rf-outcome.lost { background: #efe8d2; color: #6b6252; }
.rf-outcome.none { background: #efe8d2; color: #a89878; }

/* ---- Esqueleto ---- */
#page-raffles .rf-card.skel { box-shadow: none; }
#page-raffles .rf-card.skel .art { height: 150px; background: #e6dec4; border-bottom: 4px solid #000;
  animation: pulse 1.2s steps(3, end) infinite; }
#page-raffles .rf-card.skel .meta { padding: 13px; }
#page-raffles .rf-card.skel .bar { display: block; height: 11px; background: #e6dec4; margin-bottom: 8px; }
#page-raffles .rf-card.skel .bar.short { width: 55%; }

/* ---- A janela de vencedores ----
   Fica no tema escuro do app (`.modal` base), e não no de pergaminho: ela é um registro
   público, não uma conversa dentro do salão. */
.win-row {
  display: grid; grid-template-columns: 42px 1fr auto; gap: 10px; align-items: center;
  padding: 11px 12px; border: 2px solid var(--line); background: var(--panel-2); margin-bottom: 7px;
}
.win-rank { font-family: "Press Start 2P", monospace; font-size: 9px; color: var(--gold); }
.win-name { font-weight: 700; word-break: break-word; }
.win-addr { font-size: 12px; color: var(--ink-3); font-variant-numeric: tabular-nums; }
/* Você entre os vencedores: o dourado da marca, para o olho achar a própria linha numa
   lista de dez sem ter que ler todas. */
.win-row.is-me { border-color: var(--gold); background: #241d0a; }
.rf-none { color: var(--ink-3); font-size: 13px; margin: 4px 0 0; line-height: 1.6; }

/* A SEMENTE. É o que torna o sorteio conferível em vez de confiável, então ela aparece
   por extenso e selecionável — um hash truncado não serve para verificar nada. */
.rf-seed { margin-top: 16px; border-top: 2px solid var(--line); padding-top: 14px; }
.rf-seed-label {
  display: block; font-family: "Press Start 2P", monospace; font-size: 8px;
  color: var(--ink-2); letter-spacing: .1em; margin-bottom: 8px;
}
.rf-seed-val {
  display: block; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11px;
  color: var(--lime); background: var(--bg); border: 2px solid var(--line); padding: 9px 10px;
  word-break: break-all; line-height: 1.6; user-select: all;
}
.rf-seed-note { font-size: 12px; color: var(--ink-3); margin: 10px 0 0; line-height: 1.6; }

@media (max-width: 620px) {
  .rf-stats { grid-template-columns: repeat(2, 1fr); }
  .rf-stat:nth-child(2) { border-right: 0; }
  .rf-stat:nth-child(-n+2) { border-bottom: 3px solid #e6dec4; }
  .rf-art { height: 120px; }
  .win-row { grid-template-columns: 34px 1fr; }
  .win-addr { grid-column: 2; }
}

/* ============================================================
   O PAINEL DE ADMIN (js/admin.js)
   ------------------------------------------------------------
   Uma FERRAMENTA, e não um lugar do mundo: nada de pergaminho, nada de cena. Fica no
   chrome escuro neutro do app, que é o mesmo motivo de o resto da interface ser neutra —
   aqui o que importa é ler um número certo, não a ambientação.
   ============================================================ */

/* O HUD flutua sobre tudo (position: fixed), então a página precisa começar abaixo dele.
   As outras páginas são cenas de tela cheia e não têm esse problema. */
.adm-wrap { max-width: 980px; margin: 0 auto; padding: 78px 16px 60px; }

.hud .chip.admin {
  font-family: "Press Start 2P", monospace; font-size: 9px; letter-spacing: .06em;
  background: var(--gold); color: #20201c; cursor: pointer;
}
.hud .chip.admin:hover { background: #ffd34d; }

.admin-warn { margin-bottom: 18px; }

.adm-tabs { display: flex; gap: 6px; margin-bottom: 18px; flex-wrap: wrap; }
.adm-tabs button {
  font-family: "Press Start 2P", monospace; font-size: 9px; padding: 13px 16px;
  background: var(--panel-2); color: var(--ink-2); border: 3px solid var(--line); cursor: pointer;
}
.adm-tabs button.is-active { background: var(--gold); color: #20201c; border-color: var(--gold-dk); }
.adm-tabs button:hover:not(.is-active) { color: var(--ink); border-color: var(--line-hi); }

.adm-body { padding: 16px; }

/* Grade de formulário: dois campos por linha no desktop, um no celular. `wide` ocupa a
   linha inteira (nome, URL), `narrow` é meia coluna (números curtos). */
.adm-form { display: grid; grid-template-columns: repeat(2, 1fr); gap: 15px; align-items: start; }
.adm-form.inline { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); align-items: end; }
.adm-field { display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.adm-field.wide { grid-column: 1 / -1; }
.adm-field > span {
  font-family: "Press Start 2P", monospace; font-size: 9px; color: var(--ink-2); letter-spacing: .05em;
}
.adm-field small, .adm-check small { font-size: 12px; color: var(--ink-3); line-height: 1.5; }
.adm-field input, .adm-field select {
  font-family: inherit; font-size: 14px; padding: 11px 12px;
  background: var(--bg); color: var(--ink); border: 3px solid var(--line); min-width: 0; width: 100%;
}
.adm-field input:focus, .adm-field select:focus { outline: none; border-color: var(--gold); }
.adm-field input:disabled { opacity: .5; cursor: not-allowed; }
.adm-field input[type="color"] { padding: 4px; height: 45px; cursor: pointer; }

.adm-check {
  grid-column: 1 / -1; display: grid; grid-template-columns: auto 1fr; gap: 6px 11px;
  align-items: center; padding: 13px; border: 3px solid var(--line); background: var(--panel-2);
}
.adm-check input { width: 19px; height: 19px; accent-color: var(--gold); cursor: pointer; }
.adm-check > span { font-family: "Press Start 2P", monospace; font-size: 9px; color: var(--ink); }
.adm-check small { grid-column: 2; }

.adm-actions { grid-column: 1 / -1; display: flex; align-items: center; gap: 13px; flex-wrap: wrap; }
.adm-hint { font-size: 12px; color: var(--ink-3); margin: 0; }
.adm-empty { font-size: 13px; color: var(--ink-3); margin: 0; line-height: 1.6; }

/* ---- Listas de regra ---- */
.adm-list { margin-top: 16px; display: grid; gap: 8px; }
.adm-row {
  display: grid; grid-template-columns: auto 1fr auto auto; gap: 12px; align-items: center;
  padding: 11px 13px; background: var(--panel-2); border: 2px solid var(--line);
}
/* A amostra de cor é a MESMA que o card do Hoodmon mostra: o admin confere aqui o que o
   usuário vai ver lá, sem abrir a outra tela. */
.adm-swatch { width: 19px; height: 19px; border: 2px solid var(--line); }
.adm-row-main { font-size: 14px; min-width: 0; word-break: break-word; }
.adm-row-mult { font-family: "Press Start 2P", monospace; font-size: 11px; color: var(--gold); }

.adm-del {
  font-family: "Press Start 2P", monospace; font-size: 8px; padding: 9px 11px; cursor: pointer;
  background: transparent; color: var(--danger); border: 2px solid var(--danger);
}
.adm-del:hover { background: var(--danger); color: #fff; }

.btn.btn-sm { font-size: 9px; padding: 10px 13px; }

/* ---- Rifa na lista do admin ---- */
.adm-raffle { padding: 14px; background: var(--panel-2); border: 2px solid var(--line); }
.adm-raffle.is-drawn { opacity: .72; }
.adm-raffle-head { display: flex; align-items: center; gap: 11px; flex-wrap: wrap; margin-bottom: 9px; }
.adm-raffle-head b { font-size: 15px; }
.adm-tag {
  font-family: "Press Start 2P", monospace; font-size: 8px; padding: 5px 7px; border: 2px solid;
}
.adm-tag.live  { color: var(--lime); border-color: var(--lime-dk); }
.adm-tag.drawn { color: var(--ink-3); border-color: var(--line); }
.adm-raffle-meta { font-size: 13px; color: var(--ink-2); line-height: 1.7; margin-bottom: 12px; }
/* A semente por extenso: ela é o registro público do sorteio, e truncar tira justamente
   o que serve para conferir. */
.adm-seed {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11px;
  color: var(--ink-3); word-break: break-all; user-select: all;
}
.adm-raffle-acts { display: flex; gap: 8px; flex-wrap: wrap; }

@media (max-width: 620px) {
  .adm-wrap { padding: 74px 12px 40px; }
  .adm-form, .adm-form.inline { grid-template-columns: 1fr; }
  .adm-row { grid-template-columns: auto 1fr; }
  .adm-row-mult, .adm-del { grid-column: 2; justify-self: start; }
}

/* ============================================================
   MY PROFILE — a praça (js/profile-hall.js, js/profile.js)
   ------------------------------------------------------------
   A cena reusa `.hall-stage`, `.hall`, `.hall-spot`, `.hall-hero`, `.hall-exit` e
   `.rpg-window`, como as outras duas. O que existe aqui é o cartão de treinador, as
   grades de escolha e o placar.
   ============================================================ */

/* ---- Cartão de treinador ---- */
#page-profile .pf-card {
  display: flex; align-items: center; gap: 14px; padding: 14px;
  border-bottom: 3px solid #e6dec4;
}
.pf-avatar {
  position: relative; width: 74px; height: 74px; flex: none;
  border: 3px solid #000; background: #e6dec4; overflow: hidden;
}
.pf-avatar img { width: 100%; height: 100%; image-rendering: pixelated; }
.pf-avatar.is-empty img { display: none; }
.pf-avatar-none {
  position: absolute; inset: 0; display: none; place-items: center;
  font-family: "Press Start 2P", monospace; font-size: 24px; color: #a89878;
}
.pf-avatar.is-empty .pf-avatar-none { display: grid; }

.pf-card-id { min-width: 0; }
.pf-card-id b {
  display: block; font-family: "Press Start 2P", monospace; font-size: 14px;
  color: #20201c; word-break: break-all; line-height: 1.5;
}
.pf-card-id span { display: block; font-size: 13px; color: #6b6252; margin-top: 6px; }
.pf-card-id small { display: block; font-size: 11px; color: #a89878; margin-top: 5px; }

/* ---- Cabeçalhos e notas dentro da janela ---- */
.pf-sub {
  font-family: "Press Start 2P", monospace; font-size: 10px; color: #20201c;
  margin: 20px 0 8px; display: flex; align-items: center; gap: 10px;
}
.pf-count {
  font-size: 9px; color: #6b6252; background: #efe8d2;
  border: 2px solid #e6dec4; padding: 5px 7px;
}
.pf-note { font-size: 13px; color: #6b6252; margin: 0 0 14px; line-height: 1.6; }
.pf-note b { color: #20201c; }

/* ---- Nome ---- */
.pf-namerow { display: flex; align-items: flex-start; gap: 12px; flex-wrap: wrap; }
.pf-field { display: flex; flex-direction: column; gap: 7px; flex: 1 1 260px; min-width: 0; }
.pf-field > span {
  font-family: "Press Start 2P", monospace; font-size: 9px; color: #6b6252; letter-spacing: .05em;
}
.pf-field input {
  font-family: inherit; font-size: 15px; padding: 12px;
  background: #fff; color: #20201c; border: 3px solid #000; width: 100%;
  box-shadow: inset 2px 2px 0 #d8d0b8;
}
.pf-field input:focus { outline: none; border-color: var(--gold-dk); }
.pf-field small { font-size: 11px; color: #a89878; }
#page-profile .pf-namerow .btn { margin-top: 22px; }

/* ---- Grade de escolha (avatar e vitrine) ----
   Compacta de propósito: um holder com 40 Hoodmons precisa ver muitos de uma vez para
   escolher, e cards grandes transformariam a escolha numa rolagem longa. */
.pf-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
  gap: 9px; margin-bottom: 18px;
}
.pf-pick {
  position: relative; padding: 0; cursor: pointer;
  border: 3px solid #000; background: #e6dec4;
  box-shadow: 3px 3px 0 #00000055; transition: transform .07s, box-shadow .07s;
}
.pf-pick img { width: 100%; aspect-ratio: 1; image-rendering: pixelated; display: block; }
.pf-pick-id {
  display: block; font-family: "Press Start 2P", monospace; font-size: 7px;
  color: #6b6252; padding: 5px 2px; background: #f8f4e4; border-top: 2px solid #000;
}
.pf-pick:hover:not(:disabled) { transform: translate(-2px, -2px); box-shadow: 5px 5px 0 #00000055; }
.pf-pick:active:not(:disabled) { transform: translate(3px, 3px); box-shadow: 0 0 0; }
/* Escolhido: moldura dourada por fora, para a seleção ser visível sem cobrir a arte —
   o Hoodmon é o que a pessoa está olhando para decidir. */
.pf-pick.is-on { box-shadow: 0 0 0 3px var(--gold), 3px 3px 0 #00000055; }
.pf-pick.is-on .pf-pick-id { background: var(--gold); color: #20201c; }
.pf-pick.is-full { opacity: .4; cursor: not-allowed; }
.pf-pick:disabled { cursor: not-allowed; }

/* A ordem na vitrine é parte da escolha, então ela aparece. */
.pf-order {
  position: absolute; top: 4px; right: 4px; width: 20px; height: 20px;
  display: grid; place-items: center;
  font-family: "Press Start 2P", monospace; font-size: 9px;
  background: var(--gold); color: #20201c; border: 2px solid #000;
}

/* ---- Listas (recompensas e placar) ---- */
.pf-list { display: grid; gap: 8px; margin-bottom: 18px; }

.pf-reward {
  display: grid; grid-template-columns: auto 1fr auto; gap: 12px; align-items: center;
  padding: 12px; background: #f8f4e4; border: 3px solid #000;
  box-shadow: inset -2px -2px 0 #a89878, inset 2px 2px 0 #fff;
}
.pf-src {
  font-family: "Press Start 2P", monospace; font-size: 7px; padding: 6px 7px;
  background: #e6dec4; color: #6b6252; border: 2px solid #000;
}
.pf-src.raffle { background: #d9c7f0; }
.pf-src.auction { background: #f0d9c7; }
.pf-src.shop { background: #c7e4f0; }
.pf-reward-main { min-width: 0; }
.pf-reward-main b { display: block; font-size: 14px; color: #20201c; word-break: break-word; }
.pf-reward-main small { display: block; font-size: 11px; color: #6b6252; margin-top: 4px; }
.pf-status {
  font-family: "Press Start 2P", monospace; font-size: 7px; color: #a89878;
  border: 2px solid #e6dec4; padding: 6px 7px;
}
/* A prova de entrega é um LINK para o explorador, não um rótulo: quem recebeu quer poder
   conferir a transação, e um "entregue" escrito por nós não prova nada. */
.pf-proof {
  font-family: "Press Start 2P", monospace; font-size: 7px; text-decoration: none;
  background: var(--gold); color: #20201c; border: 2px solid #000; padding: 7px 8px;
  box-shadow: 2px 2px 0 var(--gold-dk);
}
.pf-proof:hover { background: #ffd34d; }

/* ---- Placar ---- */
.pf-lb-row {
  display: grid; grid-template-columns: 38px 34px 1fr auto; gap: 11px; align-items: center;
  padding: 10px 12px; background: #f8f4e4; border: 3px solid #000;
  box-shadow: inset -2px -2px 0 #a89878, inset 2px 2px 0 #fff;
}
/* A minha linha em dourado: numa lista de 25, achar a própria não pode custar leitura. */
.pf-lb-row.is-me { background: #fbf0cf; box-shadow: inset -2px -2px 0 #a89878, inset 2px 2px 0 #fff, 0 0 0 3px var(--gold); }
.pf-lb-rank {
  font-family: "Press Start 2P", monospace; font-size: 11px; color: #6b6252; text-align: center;
}
.pf-lb-rank.top { color: var(--gold-dk); font-size: 13px; }
.pf-lb-face { width: 34px; height: 34px; border: 2px solid #000; background: #e6dec4; overflow: hidden; }
.pf-lb-face img { width: 100%; height: 100%; image-rendering: pixelated; }
.pf-lb-who { min-width: 0; }
.pf-lb-who b { display: block; font-size: 14px; color: #20201c; word-break: break-word; }
.pf-lb-who small { display: block; font-size: 11px; color: #6b6252; margin-top: 3px; font-variant-numeric: tabular-nums; }
.pf-lb-hood { text-align: right; }
.pf-lb-hood b { display: block; font-family: "Press Start 2P", monospace; font-size: 12px; color: #2f7d38; }
.pf-lb-hood small { display: block; font-size: 10px; color: #a89878; margin-top: 4px; }

/* O separador antes da minha linha quando estou fora do top. */
.pf-lb-sep {
  font-family: "Press Start 2P", monospace; font-size: 8px; color: #a89878;
  text-align: center; padding: 12px 6px 4px; line-height: 1.6;
}

@media (max-width: 620px) {
  #page-profile .pf-card { flex-direction: column; text-align: center; }
  .pf-grid { grid-template-columns: repeat(auto-fill, minmax(72px, 1fr)); gap: 7px; }
  .pf-lb-row { grid-template-columns: 30px 1fr auto; }
  .pf-lb-face { display: none; }
  .pf-reward { grid-template-columns: auto 1fr; }
  .pf-proof, .pf-status { grid-column: 2; justify-self: start; }
  #page-profile .pf-namerow .btn { margin-top: 0; width: 100%; }
}

/* ============================================================
   ATALHOS DAS CENAS (só em tela estreita)
   ------------------------------------------------------------
   As três cenas são artes 16:9 que COBREM a viewport. Num celular em pé isso corta ~70%
   da largura, e os pontos clicáveis desenhados nas bordas saem junto: medido em 375x812,
   o Profile ficava com quatro dos cinco pontos inteiramente fora da tela.

   A saída não é encolher a arte — ela é a cena, e encolhê-la para caber devolveria uma
   miniatura cercada de preto. É dar aos mesmos destinos uma porta que o polegar alcança.
   Em telas largas a barra não existe: lá os pontos na arte já funcionam, e são melhores.
   ============================================================ */
.scene-bar { display: none; }

@media (max-width: 820px) {
  .scene-bar {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 23;
    display: flex; gap: 6px; padding: 9px 10px calc(9px + env(safe-area-inset-bottom));
    background: #1d2d6b; border-top: 4px solid #000;
  }
  .scene-bar button {
    flex: 1; min-width: 0; min-height: 46px; cursor: pointer;
    font-family: "Press Start 2P", monospace; font-size: 8px; line-height: 1.4;
    padding: 8px 4px; background: #f8f4e4; color: #20201c; border: 3px solid #000;
    box-shadow: 2px 2px 0 #00000088;
  }
  .scene-bar button:active { transform: translate(2px, 2px); box-shadow: 0 0 0; }

  /* A janela cobre a barra quando está aberta: com as duas na tela, os atalhos ficariam
     por cima do conteúdo que eles mesmos abriram. */
  body.hall-window-open .scene-bar { display: none; }

  /* A saída da escada e o LEAVE saem do caminho da barra. */
  .hall-exit { top: min(76%, calc(50% + 50dvh - 132px)); }
  .map-zoom { bottom: 16px; }
}


@media (prefers-reduced-motion: reduce) {
  .hall-hero, .hall-hero img, .hall-bubble, .hall-opt .cursor, .hall-exit,
  .hall-window.is-opening .rpg-window, #fade,
  .rf-clock.due, .rf-buy.is-armed, .rf-track span { animation: none !important; transition: none !important; }
  .guide, .guide-sprite { animation: none; transition: none; }
  .dialog.is-done .dialog-inner::after { animation: none; opacity: 1; }
}
