/* File: pvp.css
   RANDOM PVP — the grid and the live race.

   Built on the same Amber/Asphalt tokens as the rest of the app (style.css :root), with
   ONE addition: the rival is red. Two amber cars on one track is unreadable, and the
   whole page is about telling two dots apart at a glance.

   Class names here are queried by pvp.js (.pvp-track*, .pvp-car, .pvp-tag, .pvp-hud-*,
   .pvp-ticker) — renaming one is a JS change, not just a style change. */

/* ============================================================
   O FUNDO DA PÁGINA
   ============================================================
   Pintado em `#screen-app`, e não num ::before da própria página. Isso não é preferência:
   é a mesma armadilha que a cabine do Simulador já pagou para descobrir (ver o bloco
   equivalente em simulator.css). `.app-page.is-active` entra com uma animação que mexe em
   `transform` E em `opacity` — e cada uma delas cria um contexto próprio:

     · o `transform` faz `position: fixed` resolver contra a PÁGINA em vez da viewport, e
       aí a arte fica presa dentro de `.app-content`, que tem `overflow: auto`;
     · a `opacity` cria um stacking context, e `z-index: -1` não escapa dele — durante a
       transição o fundo passaria POR CIMA do menu.

   `#screen-app` já é `position: fixed; inset: 0; cover`, vive fora de todo container
   animado, e trocar a imagem dele por página não pode ser capturado por nada. Quem liga a
   classe é o switchPage() do main.js.

   A lavagem escura é o que decide quanto da arte aparece: 0.55 no topo e 0.75 embaixo
   deixa VINEWOOD e os carros legíveis (que é o ponto de ter a arte) sem que o texto solto
   do cabeçalho brigue com a cidade. Os painéis são opacos, então dentro deles nada muda.
   Mais escuro que isso e a arte vira uma mancha; mais claro e a página perde o silêncio. */
body.is-pvp #screen-app {
  background-image:
    linear-gradient(rgba(11, 11, 14, 0.55), rgba(11, 11, 14, 0.75)),
    url("assets/bg-pvp-v2.jpg");
  background-position: center 42%;
}
/* A lavagem acima já é o escurecimento inteiro. A vinheta genérica do app somaria uma
   segunda camada não planejada por cima dela — é o mesmo motivo pelo qual a cabine do
   Simulador desliga esta. */
body.is-pvp .app-overlay { background: transparent; }

.pvp-body { padding: 0 0 40px; }

.pvp-empty {
  color: var(--text-dim);
  font-size: 13px;
  padding: 28px 4px;
  text-align: center;
}

/* O LOBBY CABE NUMA TELA.
   Antes eram duas colunas com sete blocos empilhados cada, e a pagina so existia rolando.
   Agora sao tres: ficha+loadout, as escolhas da corrida, e a grade. A altura e travada na
   viewport e QUEM ROLA E A COLUNA, nao a pagina — uma grade com trinta corridas abertas
   continua funcionando sem empurrar o botao de criar para fora da tela. */
.pvp-tabs { display: flex; gap: 8px; margin-bottom: 14px; }
.pvp-tab {
  background: none; border: 1px solid var(--border); color: var(--text-dim);
  font-family: var(--font-display); font-size: 11px; letter-spacing: 0.14em;
  padding: 9px 18px; cursor: pointer; display: inline-flex; align-items: center; gap: 8px;
  transition: color 0.2s var(--ease-smooth), border-color 0.2s var(--ease-smooth);
}
.pvp-tab:hover { color: var(--text); }
.pvp-tab.is-on { color: var(--accent); border-color: var(--accent); }

.pvp-grid {
  display: grid;
  grid-template-columns: minmax(300px, 380px) 1fr;
  gap: 18px;
  align-items: start;
}

@media (min-width: 1180px) {
  /* A altura vem do FLEX, nao de um calc(100vh - N).
     Tentei o calc primeiro e errei por 72px: `.app-content` tem 96px de padding embaixo
     para a faixa de LIVE SALES, mais o cabecalho da pagina e as abas. Qualquer numero
     cravado ali vira divida — muda a faixa, muda o cabecalho, e a conta silenciosamente
     passa a estar errada de novo. Com flex, o que sobra e o que sobra. */
  .app-page[data-page="pvp"].is-active {
    display: flex; flex-direction: column; height: 100%; min-height: 0;
  }
  .app-page[data-page="pvp"] .pvp-body { flex: 1; min-height: 0; display: flex; flex-direction: column; }
  /* GRID e GRAND PRIX dividem o mesmo layout de tres colunas.
     A aba do Grand Prix ficou de fora desta regra quando foi criada, e o efeito nao era
     "ficou diferente": ela caia na regra base de DUAS colunas, a lista OPEN GRIDS
     embrulhava para baixo da ficha do piloto e a faixa de UPDATES — que e fixa no rodape —
     cobria as ultimas linhas dela. Uma vaga aberta escondida atras da faixa e uma corrida
     que ninguem entra. */
  .pvp-grid.is-grid,
  .pvp-grid.is-gp {
    grid-template-columns: minmax(296px, 356px) minmax(270px, 320px) 1fr;
    flex: 1; min-height: 0; align-items: stretch;
  }
  /* QUEM ROLA E A COLUNA, nao a pagina: uma grade com trinta corridas abertas continua
     funcionando sem empurrar o botao de criar para fora da tela. */
  .pvp-grid.is-grid .pvp-col,
  .pvp-grid.is-gp .pvp-col { min-height: 0; overflow-y: auto; }
  .pvp-grid.is-grid .pvp-col::-webkit-scrollbar,
  .pvp-grid.is-gp .pvp-col::-webkit-scrollbar { width: 6px; }
  .pvp-grid.is-grid .pvp-col::-webkit-scrollbar-thumb,
  .pvp-grid.is-gp .pvp-col::-webkit-scrollbar-thumb {
    background: rgba(255,255,255,0.12); border-radius: 3px;
  }
  .pvp-grid.is-activity { grid-template-columns: 1fr; }

  /* O CTA e a unica coisa que NUNCA pode sair da tela.
     ANTES isto era `position: sticky` com o topo transparente, e o resultado era o bug
     visivel na tela: ao rolar a coluna, WAGER e o botao flutuavam POR CIMA do desenho do
     circuito, meio transparentes — parecia defeito, e era. Agora ele nao precisa flutuar:
     FUEL e CIRCUIT viraram gavetas fechadas por padrao, entao o bloco de aposta cabe na
     coluna sem rolagem nenhuma, empurrado para o rodape pelo `margin-top: auto`. */
  /* `height` e nao `min-height`: com altura EXATA da coluna, os filhos flex podem
     encolher — e e isso que faz a gaveta aberta usar so o espaco que sobra em vez de
     empurrar o botao para fora. Um teto fixo (max-height) nao resolveria: o numero certo
     muda com a altura da janela, e errar por 32px ja esconde metade do botao. */
  .pvp-col-setup .pvp-panel { display: flex; flex-direction: column; height: 100%; }
  .pvp-col-setup .pvp-cta { margin-top: auto; padding-top: 14px; flex: 0 0 auto; }
  /* Quem encolhe e o CORPO, nunca a secao inteira: sem `min-height: 0` aqui, a secao nao
     desce abaixo do proprio cabecalho — numa janela baixa a gaveta FUEL sumia por
     completo, titulo e tudo, e a pessoa perdia o acesso ao combustivel. */
  .pvp-col-setup .pvp-acc { flex: 0 1 auto; display: flex; flex-direction: column; }
  .pvp-col-setup .pvp-acc-head { flex: 0 0 auto; }
  .pvp-col-setup .pvp-acc-body { flex: 0 1 auto; min-height: 0; }
  /* No desktop quem limita a altura e o espaco disponivel, nao um numero fixo — mas ha um
     PISO: uma gaveta de 58px nao mostra nem uma linha inteira, e a essa altura e melhor a
     coluna rolar um pouco do que abrir uma fresta inutil. */
  .pvp-col-setup .pvp-acc.is-open .pvp-acc-inner { max-height: none; min-height: 150px; }

  /* O bloco de combustivel tinha 297px de 710 — quase metade da coluna para tres opcoes.
     Tentei tres colunas primeiro e nao coube: os filhos tem largura minima propria e
     estouraram 473px num container de 267. Empilhado e comprimido cabe em ~150 e continua
     legivel numa coluna de 305px. */
  .pvp-col-setup .pvp-fuel-rows { display: flex; flex-direction: column; gap: 5px; }
  .pvp-col-setup .pvp-fuel-row {
    gap: 8px; padding: 7px 9px; align-items: center; min-width: 0;
  }
  .pvp-col-setup .pvp-fuel-row .pvp-pump { transform: scale(0.72); flex: 0 0 auto; }
  .pvp-col-setup .pvp-fuel-info { min-width: 0; }
  .pvp-col-setup .pvp-fuel-info b { font-size: 10px; }
  /* Os modificadores viram uma linha so; "+7% SPEED, -3% CONTROL" em tres linhas empurrava
     a altura de volta ao que era. */
  .pvp-col-setup .pvp-fuel-info i {
    font-size: 8px; display: block; white-space: nowrap;
    overflow: hidden; text-overflow: ellipsis;
  }
  .pvp-col-setup .pvp-fuel-info em { font-size: 8px; }
  .pvp-col-setup .pvp-buy { flex: 0 0 auto; font-size: 8px; padding: 5px 7px; white-space: nowrap; }
}

/* A linha de rank no PvP: a mesma estrela e as mesmas cinco estrelinhas do Simulator, para
   o jogador nao ter de aprender dois vocabularios. */
.pvp-rankline { display: inline-flex; align-items: center; gap: 6px; }
.pvp-rankname {
  font-family: var(--font-display); font-size: 9px; letter-spacing: 0.08em;
  color: var(--text-dim); white-space: nowrap;
}
.pvp-pace {
  margin-left: 6px; color: var(--success); font-size: 10px; white-space: nowrap;
}
.pvp-hero-lv { display: inline-flex; align-items: center; gap: 5px; }

/* ---------- o seletor de Racerz (a garagem) ---------- */
/* Para carteiras grandes. A faixa mostra cinco; isto abre o resto com busca e ordenação. */

.pvp-swap-more {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px; cursor: pointer; padding: 6px 8px;
  background: rgba(233,161,59,0.07); border: 1px dashed var(--accent);
  color: var(--accent); border-radius: 8px; min-width: 54px;
  transition: background 0.2s var(--ease-smooth);
}
.pvp-swap-more:hover { background: rgba(233,161,59,0.16); }
.pvp-swap-more b { font-family: var(--font-display); font-size: 15px; line-height: 1; }
.pvp-swap-more span { font-size: 7.5px; letter-spacing: 0.1em; }

.pvp-racers-box { max-width: 940px; width: 95vw; }
.pvp-racers-bar { display: flex; gap: 8px; margin: 4px 0 14px; flex-wrap: wrap; }
.pvp-racers-bar input[type="search"] {
  flex: 1 1 180px; min-width: 0; padding: 9px 12px;
  background: rgba(255,255,255,0.04); border: 1px solid var(--border);
  color: var(--text); font-size: 12px; border-radius: 8px;
}
.pvp-racers-bar select {
  padding: 9px 12px; background: rgba(255,255,255,0.04);
  border: 1px solid var(--border); color: var(--text); font-size: 12px; border-radius: 8px;
}
.pvp-chip-toggle {
  padding: 9px 14px; background: none; border: 1px solid var(--border);
  color: var(--text-dim); font-family: var(--font-display); font-size: 10px;
  letter-spacing: 0.1em; cursor: pointer; border-radius: 8px;
  transition: color 0.2s var(--ease-smooth), border-color 0.2s var(--ease-smooth);
}
.pvp-chip-toggle:hover { color: var(--text); }
.pvp-chip-toggle.is-on { color: var(--accent); border-color: var(--accent); }

/* Rolagem DENTRO da grade: com 58 Racerz o modal cresceria além da tela e o topo (a busca
   e a ordenação, que é justamente o que resolve ter 58) sairia de vista ao rolar. */
.pvp-racers-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: 8px; max-height: min(58vh, 520px); overflow-y: auto; padding-right: 4px;
}
.pvp-racers-grid::-webkit-scrollbar { width: 6px; }
.pvp-racers-grid::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.12); border-radius: 3px; }

.pvp-rcard {
  position: relative; display: flex; align-items: center; gap: 10px; text-align: left;
  padding: 8px; background: rgba(255,255,255,0.03); border: 1px solid var(--border);
  border-radius: 10px; cursor: pointer; color: inherit;
  transition: border-color 0.18s var(--ease-smooth), transform 0.18s var(--ease-smooth),
              background 0.18s var(--ease-smooth);
  animation: pvpRcardIn 0.32s var(--ease-smooth) both;
  animation-delay: calc(var(--i, 0) * 18ms);
}
@keyframes pvpRcardIn {
  from { opacity: 0; transform: translateY(9px) scale(0.98); }
  to { opacity: 1; transform: none; }
}
/* Respeita quem pediu menos movimento: 58 cards entrando em cascata é exatamente o tipo de
   animação que dispara enjoo em quem tem sensibilidade vestibular. */
@media (prefers-reduced-motion: reduce) {
  .pvp-rcard { animation: none; }
}
.pvp-rcard:hover:not(:disabled) {
  border-color: var(--accent); transform: translateY(-2px);
  background: rgba(233,161,59,0.06);
}
.pvp-rcard.is-on { border-color: var(--accent); background: rgba(233,161,59,0.1); }
.pvp-rcard.is-busy { opacity: 0.42; cursor: not-allowed; }

.pvp-rcard-art { flex: 0 0 auto; width: 52px; height: 52px; border-radius: 7px; overflow: hidden; background: rgba(0,0,0,0.3); }
.pvp-rcard-art img, .pvp-rcard-img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pvp-rcard-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.pvp-rcard-top { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.pvp-rcard-top b { font-family: var(--font-display); font-size: 13px; }
.pvp-rcard-top em { font-style: normal; font-size: 10px; color: var(--accent); }
.pvp-rcard-rank {
  display: flex; align-items: center; gap: 5px;
  font-size: 8.5px; letter-spacing: 0.06em; color: var(--text-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pvp-rcard-meta { font-size: 9px; color: var(--text-dim); }
.pvp-rcard-busy {
  position: absolute; top: 6px; right: 6px;
  font-size: 7px; letter-spacing: 0.1em; color: var(--danger);
  border: 1px solid var(--danger); border-radius: 4px; padding: 2px 5px;
}

.pvp-section { margin-bottom: 22px; }
.pvp-section h3,
.pvp-entry h3,
.pvp-live-strip h3 {
  font-size: 11px;
  letter-spacing: 0.16em;
  color: var(--text-dim);
  margin: 0 0 10px;
  text-transform: uppercase;
}
.pvp-count {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--accent);
}

/* ---------- stat bars ---------- */

.pvp-sheet { margin-bottom: 14px; }
.pvp-stat {
  display: grid;
  grid-template-columns: 54px 1fr 26px;
  align-items: center;
  gap: 8px;
  margin-bottom: 5px;
}
.pvp-stat-label { font-size: 9px; letter-spacing: 0.1em; color: var(--text-dim); }
.pvp-stat-bar {
  height: 5px;
  border-radius: 3px;
  background: var(--surface-2);
  overflow: hidden;
}
.pvp-stat-bar i { display: block; height: 100%; border-radius: 3px; transition: width 0.3s; }
/* One hue per stat, matching the mockup, so a sheet is readable without the labels. */
.pvp-stat-bar i.is-speed { background: var(--accent); }
.pvp-stat-bar i.is-control { background: #5aa9e6; }
.pvp-stat-bar i.is-focus { background: #a78bfa; }
.pvp-stat-bar i.is-luck { background: var(--success); }
.pvp-stat-val { font-size: 11px; font-weight: 700; text-align: right; }

/* ---------- buttons ---------- */

.pvp-btn {
  padding: 10px 14px;
  border-radius: 8px;
  border: 1px solid transparent;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.12em;
  cursor: pointer;
  transition: filter 0.15s;
}
.pvp-btn:hover:not(:disabled) { filter: brightness(1.12); }
.pvp-btn:disabled { opacity: 0.45; cursor: not-allowed; }
.pvp-btn.is-primary { width: 100%; background: var(--accent); color: #14100a; }
.pvp-btn.is-accept { background: var(--accent-strong); color: #14100a; }
.pvp-btn.is-ghost { background: transparent; border-color: var(--border-strong); color: var(--text-dim); }

/* ---------- the race stage ---------- */

.pvp-stage {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 16px;
}
/* A short shove on an overtake or a spin. The only motion on the page that is not data —
   it exists because a lead change on a 240x120 SVG is otherwise easy to miss entirely. */
.pvp-stage.is-jolt { animation: pvp-jolt 0.7s ease-out; }
@keyframes pvp-jolt {
  0%, 100% { transform: translateX(0); }
  12% { transform: translateX(-3px); }
  28% { transform: translateX(3px); }
  46% { transform: translateX(-2px); }
  70% { transform: translateX(1px); }
}
@media (prefers-reduced-motion: reduce) {
  .pvp-stage.is-jolt { animation: none; }
  .pvp-stat-bar i { transition: none; }
  .pvp-tick { animation: none; }
}

.pvp-stage-head {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 14px;
}
.pvp-stage-head h3 { margin: 0; font-size: 15px; letter-spacing: 0.14em; color: var(--accent); }
.pvp-stage-head .pvp-hud-clock { margin-left: auto; font-size: 13px; color: var(--text-dim); }

.pvp-stage-grid {
  display: grid;
  grid-template-columns: 200px 1fr 200px;
  gap: 14px;
  align-items: start;
}

/* A FAIXA DE UPDATES, ESCONDIDA DURANTE A CORRIDA.
   Mesmo recurso do tour (`body.tour-on`): a barra é fixa no rodapé e o palco é a única
   tela que usa a altura inteira — o pote e o live feed acabam onde ela começa, e um texto
   rolando por baixo da pista briga com a corrida. `visibility` além do `opacity` para a
   barra também sair do caminho do clique, e o padding do rodapé volta ao valor de quando
   não há faixa nenhuma, como já faz `body.no-ticker`. A classe entra e sai em
   pvpWatchMode(), em pvp.js. */
body.pvp-watching #ticker-bar { opacity: 0; visibility: hidden; }
body.pvp-watching .app-content { padding-bottom: 40px; }

/* A coluna da esquerda tem duas peças empilhadas — o card do jogador e o pote — e as duas
   têm de medir exatamente a mesma largura da coluna. `min-width: 0` porque uma grid column
   de 200px não segura filho nenhum que se declare mais largo. */
.pvp-stage-side {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
}

.pvp-car-panel {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 10px;
}
.pvp-car-panel.is-b { border-color: rgba(199,68,54,0.4); }
.pvp-car-panel h4 { margin: 8px 0 2px; font-size: 12px; }
.pvp-car-panel h4 span { font-size: 9px; color: var(--text-dim); font-weight: 400; }
.pvp-panel-ovr { margin: 0 0 8px; font-size: 10px; color: var(--accent); }
.pvp-panel-fuel { margin: 8px 0 0; font-size: 9px; color: var(--text-dim); letter-spacing: 0.08em; }
.pvp-panel-odds { margin: 2px 0 0; font-size: 20px; font-weight: 700; color: var(--accent); }
.pvp-car-panel.is-b .pvp-panel-odds { color: var(--danger); }

.pvp-track-wrap { position: relative; min-width: 0; }
/* O traçado agora mora num painel, igual ao HUD e ao live feed logo abaixo. Solto sobre o
   fundo da página ele não tinha limite nenhum e a coluna do meio parecia um buraco entre
   os dois cards; com a moldura, as três peças da coluna viram uma pilha. */
/* Escopado no .pvp-track-wrap DE PROPÓSITO: `.pvp-track` também é o botão do seletor de
   circuito lá embaixo, e sem o escopo a moldura desta pista vazaria para os cinco
   botõezinhos. */
.pvp-track-wrap .pvp-track {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--border);
  border-radius: 12px;
  background:
    radial-gradient(120% 90% at 50% 45%, rgba(46,72,104,0.22) 0%, rgba(11,11,14,0) 62%),
    var(--surface-2);
}
/* CIRCUITO COM ARTE PRÓPRIA (--pvp-stage-art, posta pelo pvp.js).
   A foto entra no lugar do degradê, com um véu escuro por cima: sem ele as luzes da
   cidade competem com o neon das guias, e o traçado — que é a única coisa que precisa
   ser lida durante a corrida — deixa de ser a coisa mais clara da tela. A proporção da
   foto é a mesma do viewBox (2:1), então `cover` não corta nada de relevante. */
.pvp-track-wrap.has-art .pvp-track {
  background:
    linear-gradient(180deg, rgba(6,9,16,0.34), rgba(6,9,16,0.5)),
    var(--pvp-stage-art) var(--pvp-stage-pos, center) / var(--pvp-stage-fit, cover) no-repeat,
    var(--surface-2);
  border-color: rgba(90,169,230,0.22);
}

/* ARTE DE DIA (tone: light).
   Aqui o véu escuro do noturno seria um erro duplo: apagaria a arte e, ainda assim, não
   resolveria o contraste — sobre um campo claro o halo azul simplesmente desaparece.
   A troca é de LÓGICA, não de intensidade: quem descola a fita do chão passa a ser uma
   SOMBRA, e quem desenha a forma é o asfalto escuro, que já é a coisa mais escura da
   cena. As guias brancas continuam brancas porque estão sobre o asfalto, não sobre a
   grama. O véu vira uma vinheta: escurece só as beiradas, onde ficam os números e o HUD,
   e deixa o miolo com a cor que o artista pintou. */
.pvp-track-wrap.has-art.is-light .pvp-track {
  background:
    radial-gradient(115% 85% at 50% 48%, rgba(8,10,18,0) 38%, rgba(8,10,18,0.5) 100%),
    var(--pvp-stage-art) var(--pvp-stage-pos, center) / var(--pvp-stage-fit, cover) no-repeat,
    var(--surface-2);
  border-color: rgba(255,255,255,0.16);
}
.pvp-track-wrap.has-art.is-light .pvp-track-halo {
  stroke: rgba(6,8,14,0.5);
  stroke-width: 14;
}
/* Sobre fundo claro a guia branca sozinha some nas bordas; um fio escuro por fora dela é
   o que mantém a fita legível tanto sobre pétala rosa quanto sobre grama. */
.pvp-track-wrap.has-art.is-light .pvp-track-edge {
  stroke: rgba(255,255,255,0.92);
  stroke-width: 10.8;
}
.pvp-track-wrap.has-art.is-light .pvp-track-bed { stroke: #10141d; }

/* O TRAÇADO, EM CAMADAS.
   A fita antes era um cinza chapado sobre fundo preto: dava para ver que existia uma
   pista e nada mais. Agora o asfalto é ESCURO e quem desenha a forma é a luz nas bordas —
   é o mesmo motivo pelo qual uma foto noturna de autódromo se lê pelas guias, não pelo
   piso. As quatro camadas usam o MESMO `d`, então nenhuma pode discordar da outra. */

/* 1. halo — o borrão azul que descola a pista do fundo. Fica atrás de tudo. */
.pvp-track-halo {
  fill: none;
  /* Cor e espessura viram variáveis para que UMA arte possa pedir outro brilho sem mexer
     nas outras quatro. O padrão é o azul de sempre. */
  stroke: var(--pvp-glow, rgba(90,169,230,0.42));
  stroke-width: var(--pvp-glow-w, 12.5);
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* 2. guias — aparecem como uma linha clara de cada lado porque a camada 3, mais estreita,
      cobre o miolo. Um contorno de verdade sem precisar de dois paths deslocados. */
.pvp-track-edge {
  fill: none;
  stroke: var(--pvp-edge, rgba(205,231,255,0.72));
  stroke-width: 10.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* 3. asfalto. */
.pvp-track-bed {
  fill: none;
  stroke: #0f131c;
  stroke-width: 9;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* 4. traçado ideal: contínuo, e não mais tracejado. O tracejado dizia "faixa central de
      rodovia"; a linha contínua é a trajetória, que é o que uma corrida desenha. */
.pvp-track-line {
  fill: none;
  stroke: var(--pvp-line, rgba(126,196,255,0.55));
  stroke-width: 0.85;
}

/* Zebras — geradas por pvpDrawKerbs(). Branco por baixo, vermelho tracejado por cima. */
.pvp-kerb-base { fill: none; stroke: rgba(240,238,233,0.92); stroke-width: 1.5; }
.pvp-kerb-dash { fill: none; stroke: #c74436; stroke-width: 1.5; stroke-dasharray: 2 2; }

/* Grid quadriculado da largada — gerado por pvpDrawStartLine(). */
.pvp-grid-cell.is-light { fill: #f0eee9; }
.pvp-grid-cell.is-dark { fill: #14141a; }

.pvp-car { stroke: rgba(255,255,255,0.92); stroke-width: 1; }
.pvp-car.is-a { fill: var(--accent); }
.pvp-car.is-b { fill: var(--danger); }
.pvp-tag {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 800;
  font-size: 5.4px;
  letter-spacing: 0.02em;
  paint-order: stroke;
  stroke: rgba(11,11,14,0.9);
  stroke-width: 1.4;
  stroke-linejoin: round;
}
.pvp-tag.is-a { fill: var(--accent); }
.pvp-tag.is-b { fill: var(--danger); }

/* ============================================================
   GRAND PRIX — a corrida de campo.

   As cores dos carros num CAMPO nao seguem a regra do duelo. No duelo o ambar é sempre o
   SEU carro, seja você quem criou ou quem aceitou — o mapa é o do espectador. Com cinco
   isso não escala: cinco pessoas assistindo à mesma corrida veriam cinco pistas de cores
   diferentes, e a mesma legenda do ticker apontaria para carros diferentes em cada tela.

   Então aqui a cor é FIXA por posição na grade (igual para todo mundo) e o SEU carro ganha
   um anel branco em volta. A corrida é uma só; quem varia é onde você está nela.
   ============================================================ */
.pvp-car.is-c { fill: #4fb477; }   /* verde  */
.pvp-car.is-d { fill: #8b5cf6; }   /* roxo   */
.pvp-car.is-e { fill: #38bdf8; }   /* ciano  */
.pvp-car.is-f { fill: #f472b6; }   /* rosa   */
.pvp-car.is-g { fill: #facc15; }   /* amarelo*/
.pvp-car.is-h { fill: #fb923c; }   /* laranja*/
.pvp-tag.is-c { fill: #4fb477; }
.pvp-tag.is-d { fill: #8b5cf6; }
.pvp-tag.is-e { fill: #38bdf8; }
.pvp-tag.is-f { fill: #f472b6; }
.pvp-tag.is-g { fill: #facc15; }
.pvp-tag.is-h { fill: #fb923c; }
.pvp-car.is-me { stroke: #fff; stroke-width: 1.6; }

/* --- a classificação ao vivo, no lugar dos dois cards de carro --- */
.pvp-board { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.pvp-board-row {
  --hue: var(--text-dim);
  display: grid;
  grid-template-columns: 22px 26px 1fr auto;
  grid-template-areas: "pos art who ovr" "pos art gap gap";
  align-items: center;
  column-gap: 7px;
  padding: 6px 8px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--hue);
  border-radius: 9px;
  background: var(--surface-2);
  /* A troca de posição ANIMA porque só a propriedade `order` muda — as linhas não são
     redesenhadas (ver pvpDrawFieldHud). Sem isso a tabela pisca a cada ultrapassagem. */
  transition: border-color 0.2s var(--ease-smooth), background 0.2s var(--ease-smooth);
}
.pvp-board-row.is-a { --hue: var(--accent); }
.pvp-board-row.is-b { --hue: var(--danger); }
.pvp-board-row.is-c { --hue: #4fb477; }
.pvp-board-row.is-d { --hue: #8b5cf6; }
.pvp-board-row.is-e { --hue: #38bdf8; }
.pvp-board-row.is-f { --hue: #f472b6; }
.pvp-board-row.is-g { --hue: #facc15; }
.pvp-board-row.is-h { --hue: #fb923c; }
.pvp-board-row.is-me { background: rgba(255,255,255,0.06); border-color: rgba(255,255,255,0.28); }
.pvp-board-row.is-lead { box-shadow: 0 0 0 1px var(--accent-glow, rgba(255,138,0,0.3)); }
.pvp-board-pos {
  grid-area: pos;
  font-family: var(--font-display);
  font-size: 11px;
  color: var(--hue);
}
.pvp-board-art {
  grid-area: art;
  width: 26px; height: 26px;
  border-radius: 6px;
  object-fit: cover;
  background: var(--bg-deep);
}
.pvp-board-who { grid-area: who; min-width: 0; }
.pvp-board-who b { display: block; font-size: 11px; line-height: 1.1; }
.pvp-board-who span {
  display: block; font-size: 8px; color: var(--text-dim);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pvp-board-ovr { grid-area: ovr; font-family: var(--font-display); font-size: 11px; color: var(--text-dim); }
.pvp-board-gap { grid-area: gap; font-size: 9px; color: var(--text-dim); letter-spacing: 0.04em; }

/* --- o card de uma grade no lobby --- */
/* UM layout só, em qualquer largura.
   A primeira versão tinha três colunas no desktop e caía para duas abaixo de 900px — e a
   de três nunca chegava a acontecer, porque a coluna do lobby é estreita mesmo numa tela
   larga. Duas colunas com a ação na própria linha é o que sempre foi renderizado; manter a
   variante de três seria CSS morto esperando para se comportar diferente um dia. */
.pvp-grid-card {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas: "top stake" "body stake" "action action";
  align-items: center;
  gap: 4px 12px;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface-2);
  margin-bottom: 8px;
}
.pvp-grid-card.is-mine { border-color: var(--accent); background: rgba(255,138,0,0.06); }
.pvp-grid-top { grid-area: top; display: flex; align-items: center; gap: 8px; }
.pvp-grid-slots { display: flex; gap: 4px; }
/* A VAGA VAZIA é um buraco, e tem de PARECER um buraco: contorno tracejado e nada dentro.
   Um quadrado cinza sólido lê como "carro que não carregou a foto". */
.pvp-slot {
  width: 26px; height: 26px;
  border-radius: 7px;
  overflow: hidden;
  flex: 0 0 auto;
}
.pvp-slot.is-empty { border: 1px dashed var(--border-strong); background: transparent; }
.pvp-slot.is-taken { border: 1px solid var(--border-strong); }
.pvp-slot.is-me { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.pvp-slot-art { width: 100%; height: 100%; object-fit: cover; display: block; }
.pvp-grid-count { font-family: var(--font-display); font-size: 12px; color: var(--text-dim); }
.pvp-grid-body { grid-area: body; min-width: 0; }
.pvp-grid-owner {
  margin: 0; font-size: 10px; color: var(--text-dim);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pvp-grid-podium { margin: 3px 0 0; display: flex; gap: 8px; flex-wrap: wrap; }
.pvp-grid-podium i { font-style: normal; font-size: 9px; letter-spacing: 0.04em; color: var(--text-dim); }
.pvp-grid-podium i.is-p1 { color: var(--accent); }
.pvp-grid-stake { grid-area: stake; text-align: right; }
.pvp-grid-stake b { display: block; font-family: var(--font-display); font-size: 16px; }
.pvp-grid-stake span { font-size: 8px; color: var(--text-dim); letter-spacing: 0.1em; }
.pvp-grid-stake em { display: block; font-size: 9px; color: var(--accent); font-style: normal; }
/* TAKE A SEAT é a ação principal e ocupa a linha inteira — é o que a pessoa veio fazer.
   CANCEL, LEAVE e LOCKED IN são saídas: ficam do tamanho do texto, à direita, para não
   competirem com o botão de entrar de outra grade logo acima. */
.pvp-grid-card > .pvp-btn, .pvp-grid-locked {
  grid-area: action;
  justify-self: end;
  width: auto;
  margin-top: 6px;
  padding: 6px 16px;
}
.pvp-grid-card > .pvp-btn.is-accept { justify-self: stretch; width: 100%; padding: 9px 0; }
.pvp-grid-locked {
  font-size: 9px; letter-spacing: 0.12em; color: var(--text-dim);
  padding: 6px 10px; border: 1px dashed var(--border-strong); border-radius: 999px;
}

/* --- O CARD DE UM GRAND PRIX OFICIAL ---
   Card próprio, e não o da grade de jogador: o que se anuncia aqui é o PRÊMIO, e o card de
   grade não tem onde pôr um item. As vagas continuam sendo a segunda pergunta. */
.pvp-event-list { display: flex; flex-direction: column; gap: 12px; }
.pvp-event-card {
  padding: 14px;
  border: 1px solid var(--border-strong);
  border-radius: 14px;
  background: linear-gradient(160deg, rgba(255,138,0,0.07), transparent 55%), var(--surface-2);
}
.pvp-event-head { display: flex; align-items: flex-start; gap: 10px; margin-bottom: 10px; }
.pvp-event-head h4 {
  margin: 0; font-family: var(--font-display); font-size: 15px; letter-spacing: 0.04em;
}
.pvp-event-head p { margin: 3px 0 0; font-size: 11px; line-height: 1.5; color: var(--text-dim); }
.pvp-event-runs {
  margin-left: auto; flex: 0 0 auto;
  padding: 3px 9px; border: 1px solid var(--border); border-radius: 999px;
  font-size: 8px; letter-spacing: 0.12em; color: var(--text-dim); white-space: nowrap;
}

.pvp-eprizes {
  list-style: none; margin: 0 0 12px; padding: 10px;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 10px;
  border: 1px dashed var(--border-strong); border-radius: 11px;
}
.pvp-eprize { display: flex; align-items: center; gap: 9px; min-width: 0; }
.pvp-eprize img, .pvp-eprize-noart {
  width: 42px; height: 42px; flex: 0 0 auto;
  border-radius: 9px; object-fit: cover; background: var(--bg-deep);
  border: 1px solid var(--border);
}
.pvp-eprize > div { min-width: 0; }
.pvp-eprize-place {
  display: block; font-family: var(--font-display); font-size: 9px;
  letter-spacing: 0.12em; color: var(--accent);
}
.pvp-eprize b {
  display: block; font-size: 12px; line-height: 1.2;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pvp-eprize em {
  display: inline-block; margin-top: 2px; padding: 1px 6px;
  border-radius: 999px; background: rgba(255,255,255,0.07);
  font-style: normal; font-size: 8px; letter-spacing: 0.1em; color: var(--text-dim);
}

.pvp-event-foot { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.pvp-event-slots { display: flex; flex-direction: column; gap: 5px; }
.pvp-event-slots > span { font-size: 9px; letter-spacing: 0.08em; color: var(--text-dim); }
.pvp-event-stake { margin-left: auto; text-align: right; }
.pvp-event-stake b { display: block; font-family: var(--font-display); font-size: 17px; }
.pvp-event-stake span { font-size: 8px; letter-spacing: 0.1em; color: var(--text-dim); }
.pvp-event-stake em { display: block; margin-top: 2px; font-style: normal; font-size: 9px; color: var(--accent); }
.pvp-event-card > .pvp-event-foot > .pvp-btn { flex: 0 0 auto; padding: 9px 18px; }

.pvp-event-live { color: var(--accent); font-style: normal; display: inline-flex; align-items: center; gap: 4px; }
.pvp-gp-closed .pvp-empty { padding: 26px 4px 10px; font-size: 14px; }

@media (max-width: 620px) {
  .pvp-event-foot { align-items: stretch; }
  .pvp-event-stake { margin-left: 0; text-align: left; }
  .pvp-event-card > .pvp-event-foot > .pvp-btn { width: 100%; }
}

/* --- a tabela de prêmios do formulário --- */
.pvp-prizes {
  margin: 4px 0 14px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: rgba(255,255,255,0.02);
}
.pvp-prizes-head {
  display: flex; justify-content: space-between; align-items: baseline;
  font-size: 9px; letter-spacing: 0.12em; color: var(--text-dim);
  padding-bottom: 6px; border-bottom: 1px solid var(--border);
}
.pvp-prizes-head b { font-family: var(--font-display); font-size: 12px; color: var(--text); letter-spacing: 0; }
.pvp-prizes ul { list-style: none; margin: 6px 0 0; padding: 0; }
.pvp-prize {
  display: grid;
  grid-template-columns: 34px 1fr auto;
  align-items: baseline;
  gap: 8px;
  padding: 3px 0;
}
.pvp-prize-place { font-family: var(--font-display); font-size: 10px; color: var(--text-dim); }
.pvp-prize.is-p1 .pvp-prize-place { color: var(--accent); }
.pvp-prize b { font-family: var(--font-display); font-size: 13px; }
/* A coluna da direita é o SALDO, e ela é a razão de a tabela existir: com 60/25/15 o
   terceiro lugar aparece em vermelho, antes da inscrição. */
.pvp-prize em { font-style: normal; font-size: 10px; }
.pvp-prize em.is-up { color: var(--success); }
.pvp-prize em.is-down { color: var(--danger); }
.pvp-prizes-note { margin: 8px 0 0; font-size: 9px; line-height: 1.5; color: var(--text-dim); }

/* --- o pódio do modal de resultado ---

   `.pvp-respod`, e NÃO `.pvp-podium`: essa segunda já existe neste arquivo desde a aba TOP
   PILOTS (os três degraus do ranking), e usá-la aqui fez as duas regras brigarem — a media
   query do ranking forçava uma coluna só e a arte do pódio do resultado, que é
   `aspect-ratio: 1`, virava um quadrado gigante empurrando a tabela para fora da tela.
   Duas coisas diferentes com o mesmo nome de classe é uma colisão silenciosa: nada quebra
   onde o nome foi escrito, e sim do outro lado do arquivo.

   auto-fit em vez de três colunas fixas com corte por viewport: o pódio vive dentro de um
   modal, e a largura que importa é a DELE e não a da janela. */
.pvp-respod {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  /* `end` alinha os três pela BASE: os degraus crescem para cima a partir de um chão comum,
     que é o que faz a silhueta ser lida como pódio antes de qualquer texto ser lido. */
  align-items: end;
  gap: 8px;
  margin-bottom: 14px;
}
.pvp-pod {
  margin: 0;
  padding: 10px 8px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface-2);
  text-align: center;
  min-width: 0;
}

/* PÓDIO DE VERDADE: 2º à esquerda, 1º no meio e mais alto, 3º à direita e mais baixo.
   
   O DOM continua em ordem de CHEGADA (1, 2, 3) — é assim que a lista é lida em voz alta e
   é assim que ela faz sentido sem CSS. Quem reposiciona é `order`, que é exatamente para
   isso: arranjo visual sem mexer na ordem do conteúdo.
   
   A altura é `margin-bottom` e não `transform`: transform não empurra o layout, então os
   três ficariam com a mesma caixa e o degrau seria só um deslocamento por cima — o
   espaçamento embaixo do pódio ficaria errado e o card do meio invadiria a linha de baixo. */
.pvp-pod.is-p2 { order: 1; margin-bottom: 10px; }
.pvp-pod.is-p1 { order: 2; margin-bottom: 26px; border-color: var(--accent); }
.pvp-pod.is-p3 { order: 3; margin-bottom: 0; }

/* O degrau do vencedor também é MAIOR, não só mais alto: num pódio real o primeiro lugar
   ocupa mais espaço, e num campo de cinco a diferença entre 1º e 2º é a diferença entre
   levar 286 e levar 118. */
.pvp-pod.is-p1 { padding: 14px 10px; }
.pvp-pod.is-p1 .pvp-pod-art { max-height: 150px; }
.pvp-pod.is-p1 figcaption b { font-size: 14px; }
.pvp-pod.is-p1 figcaption em { font-size: 13px; }
.pvp-pod.is-me { box-shadow: 0 0 0 1px rgba(255,255,255,0.35); }
.pvp-pod-place {
  display: block; font-family: var(--font-display); font-size: 11px;
  letter-spacing: 0.12em; color: var(--text-dim); margin-bottom: 6px;
}
.pvp-pod.is-p1 .pvp-pod-place { color: var(--accent); }
/* Teto de altura junto do aspect-ratio: numa coluna estreita o quadrado cresceria com a
   largura e a foto do pódio sozinha ocuparia a tela inteira. */
.pvp-pod-art {
  width: 100%; aspect-ratio: 1; max-height: 130px;
  object-fit: cover; border-radius: 9px; background: var(--bg-deep);
  margin: 0 auto;
}
.pvp-pod figcaption b { display: block; margin-top: 6px; font-size: 12px; }
.pvp-pod figcaption span {
  display: block; font-size: 9px; color: var(--text-dim);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pvp-pod figcaption em { display: block; margin-top: 3px; font-style: normal; font-size: 11px; color: var(--accent); }

.pvp-res-table { list-style: none; margin: 14px 0 0; padding: 0; }
.pvp-res-table li {
  display: grid;
  grid-template-columns: 34px 52px 1fr 62px 62px;
  align-items: center;
  gap: 8px;
  padding: 5px 8px;
  border-radius: 7px;
  font-size: 11px;
}
.pvp-res-thead { font-size: 8px !important; letter-spacing: 0.12em; color: var(--text-dim); }
.pvp-res-table li.is-me { background: rgba(255,255,255,0.06); }
.pvp-res-place { font-family: var(--font-display); color: var(--text-dim); }
.pvp-res-owner { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text-dim); }
.pvp-res-gap, .pvp-res-paid { text-align: right; font-variant-numeric: tabular-nums; }
.pvp-res-paid { color: var(--accent); }
.pvp-res-proof {
  margin: 12px 0 0; font-size: 8px; letter-spacing: 0.06em;
  color: var(--text-dim); text-align: center; word-break: break-all;
}

/* Numa grade a coluna da direita não existe (a classificação ocupa a da esquerda), então
   o palco vira duas colunas e a pista fica com o espaço que sobrou. */
.pvp-stage-grid:has(.pvp-board) { grid-template-columns: 220px 1fr; }

@media (max-width: 900px) {
  .pvp-stage-grid:has(.pvp-board) { grid-template-columns: 1fr; }
  .pvp-res-table li { grid-template-columns: 30px 46px 1fr 54px 54px; font-size: 10px; }
}

/* Numa tela estreita os três degraus continuam lado a lado — um pódio empilhado deixa de
   ser pódio e vira três cards soltos, e aí a ordem visual (2, 1, 3) passaria a ler como
   uma classificação errada. O que encolhe é o conteúdo, não o arranjo. */
@media (max-width: 520px) {
  .pvp-respod { gap: 5px; }
  .pvp-pod { padding: 7px 4px; }
  .pvp-pod.is-p1 { padding: 9px 5px; margin-bottom: 18px; }
  .pvp-pod-art, .pvp-pod.is-p1 .pvp-pod-art { max-height: 78px; }
  .pvp-pod-place { font-size: 9px; }
  .pvp-pod figcaption b, .pvp-pod.is-p1 figcaption b { font-size: 11px; }
  .pvp-pod figcaption span { font-size: 8px; }
  .pvp-pod figcaption em, .pvp-pod.is-p1 figcaption em { font-size: 10px; }
}

/* The `hidden` ATTRIBUTE only works through the browser's own `[hidden]{display:none}`
   rule, and an author stylesheet beats the browser's — so `display: grid` below silently
   won, and setting countEl.hidden = true did nothing at all. The countdown therefore sat
   on top of the race for its whole duration, frozen on "1". Same shape as
   `.modal.hidden` in style.css, which already solved this for the app's modals. */
.pvp-countdown[hidden] { display: none; }

.pvp-countdown {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-size: 64px;
  font-weight: 700;
  color: var(--accent);
  background: rgba(11,11,14,0.72);
  border-radius: 10px;
  z-index: 2;
}

.pvp-hud {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
  text-align: center;
}
/* 8.5px of --text-dim disappeared entirely against the panel. These three labels are
   what make the numbers under them mean anything. */
.pvp-hud span { display: block; font-size: 9.5px; font-weight: 600; letter-spacing: 0.14em; color: #b9b9c2; }
.pvp-hud b { font-size: 17px; }
.pvp-hud-gap { color: var(--danger); }

.pvp-ticker {
  list-style: none;
  margin: 12px 0 0;
  padding: 0;
  max-height: 150px;
  overflow: hidden;
}
/* The ticker is the commentary — if it cannot be read at a glance while a race is
   moving, the events might as well not be generated. First pass used --text-dim on
   --surface-2 and was effectively invisible against the dark track. */
.pvp-tick {
  padding: 6px 10px;
  margin-bottom: 3px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  border-left: 3px solid var(--border-strong);
  background: rgba(255,255,255,0.05);
  border-radius: 0 5px 5px 0;
  color: var(--text);
  animation: pvp-tick-in 0.28s ease-out;
}
/* Slides in, never FADES in. A caption whose legibility depends on an animation having
   finished is unreadable whenever that animation is stalled or suppressed — a backgrounded
   tab freezes the CSS animation clock outright, and the whole ticker sits at 26% opacity
   until the tab is looked at again. The commentary has to be readable at every instant,
   so the entrance moves the line rather than revealing it. */
@keyframes pvp-tick-in {
  from { transform: translateX(-10px); }
  to { transform: translateX(0); }
}
.pvp-tick.is-pass { border-left-color: var(--accent); color: var(--text); }
.pvp-tick.is-spin { border-left-color: var(--danger); color: #f0b3ab; }
.pvp-tick.is-close { border-left-color: #5aa9e6; }
.pvp-tick.is-flag { border-left-color: var(--success); color: var(--text); font-weight: 700; }
.pvp-tick.is-start,
.pvp-tick.is-lap { color: var(--text-dim); font-weight: 500; }

/* The commit-reveal, in the open. It is the difference between "trust us" and "check it
   yourself", and hiding it in a tooltip would waste the only reason it exists. */
.pvp-commit,
.pvp-reveal {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 9px;
  opacity: 0.65;
  cursor: help;
}
.pvp-verdict {
  display: flex;
  align-items: baseline;
  gap: 12px;
  flex-wrap: wrap;
  width: 100%;
  margin-top: 8px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
}
.pvp-verdict b { font-size: 17px; color: var(--success); }
.pvp-verdict em { font-style: normal; color: var(--accent); font-weight: 700; }

/* ---------- responsive ---------- */

@media (max-width: 1100px) {
  .pvp-grid { grid-template-columns: 1fr; }
  .pvp-stage-grid { grid-template-columns: 1fr; }
  /* The track goes first on a phone: it is the thing you came to watch, and two stat
     panels above it would push it below the fold on every device. */
  .pvp-track-wrap { order: -1; }
}

@media (max-width: 620px) {
  .pvp-lobby-card { grid-template-columns: 44px 1fr auto; }
  .pvp-lobby-card .pvp-btn { grid-column: 1 / -1; }
  .pvp-lobby-art { width: 44px; height: 44px; }
  .pvp-hud b { font-size: 14px; }
  .pvp-countdown { font-size: 44px; }
}

/* ---------- result modal ----------
   Uses the app's own .modal / .modal-backdrop / .modal-box shell from style.css, so it
   behaves and dismisses like every other dialog here. Only the inside is PvP's. */

.pvp-noart {
  display: grid;
  place-items: center;
  font-size: 11px;
  font-weight: 700;
  color: var(--text-dim);
  background: #101014;
}

.pvp-res-box { border-top: 3px solid var(--border-strong); }
.pvp-res-box.is-win { border-top-color: var(--success); }
.pvp-res-box.is-loss { border-top-color: var(--danger); }
.pvp-res-box.is-win .modal-head h3 { color: var(--success); }
.pvp-res-box.is-loss .modal-head h3 { color: var(--danger); }

.pvp-res-cars {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;
}
.pvp-res-car { margin: 0; text-align: center; opacity: 0.55; }
/* The winner is the subject of the dialog: full opacity and a ring, so the eye lands on
   the right car before reading a word. */
.pvp-res-car.is-winner { opacity: 1; }
.pvp-res-art {
  width: 100%;
  max-width: 96px;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: 8px;
  margin: 0 auto 6px;
  background: #101014;
  display: block;
}
.pvp-res-car.is-winner .pvp-res-art { box-shadow: 0 0 0 2px var(--accent); }
.pvp-res-car figcaption { font-size: 12px; font-weight: 700; }
/* O @ do dono, entre o número do carro e o papel dele na corrida. Âmbar no vencedor
   porque é a única linha do modal que responde "para quem foi o dinheiro"; no segundo
   colocado fica apagado, junto com o resto do card. `nowrap` + reticências: o apelido
   tem até 20 caracteres e a coluna é metade de um modal estreito — quebrado em duas
   linhas ele empurraria o rótulo WINNER para fora do alinhamento com o 2ND ao lado. */
.pvp-res-car figcaption em {
  display: block;
  max-width: 100%;
  margin: 2px 0 1px;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-size: 10px;
  font-style: normal;
  font-weight: 600;
  color: var(--text-dim);
}
.pvp-res-car.is-winner figcaption em { color: var(--accent); }
.pvp-res-car figcaption span {
  display: block;
  font-size: 8px;
  letter-spacing: 0.14em;
  color: var(--text-dim);
  font-weight: 500;
}
.pvp-res-margin { text-align: center; }
.pvp-res-margin b { display: block; font-size: 18px; color: var(--accent); }
.pvp-res-margin span { font-size: 8px; letter-spacing: 0.14em; color: var(--text-dim); }

.pvp-res-money {
  margin: 0 0 14px;
  padding: 12px;
  border-radius: 8px;
  background: var(--surface-2);
  text-align: center;
}
.pvp-res-money b { display: block; font-size: 22px; }
.pvp-res-money.is-win b { color: var(--success); }
.pvp-res-money.is-loss b { color: var(--danger); }
.pvp-res-money span { font-size: 10px; color: var(--text-dim); }

/* Small and quiet, but present: this is what turns "trust us" into "check it yourself". */
.pvp-res-verify {
  margin: 0 0 14px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 8.5px;
  line-height: 1.6;
  color: var(--text-dim);
  opacity: 0.7;
  text-align: center;
  cursor: help;
  word-break: break-all;
}

.pvp-res-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.pvp-res-actions .pvp-btn.is-primary { width: auto; }

/* Who each panel belongs to. Spelled out rather than implied by position, because the
   left panel is YOUR car only when you are actually in the race — a spectator sees
   CHALLENGER / OPPONENT and must not be told "YOU" about somebody else's Racerz. */
.pvp-panel-who {
  display: block;
  font-size: 8px;
  font-weight: 700;
  letter-spacing: 0.16em;
  color: var(--text-dim);
  margin-bottom: 6px;
}
/* Desde que a etiqueta passou a carregar o NOME do jogador e não uma palavra fixa, ela
   tem comprimento imprevisível: sem isto um username longo quebra em duas linhas e
   empurra a foto do carro para baixo, desalinhando os dois cards. */
.pvp-panel-who {
  max-width: 100%;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.pvp-car-panel.is-a .pvp-panel-who { color: var(--accent); }
.pvp-car-panel.is-b .pvp-panel-who { color: var(--danger); }

/* Time in hand is good news and must not be painted as a warning. */
.pvp-hud-gap.is-ahead { color: var(--success); }
.pvp-hud-gap.is-behind { color: var(--danger); }


/* ---------- live races in the lobby ---------- */

.pvp-lobby-card.is-live { border-color: rgba(233,161,59,0.45); }
.pvp-btn.is-live { background: transparent; border-color: var(--accent); color: var(--accent); }
.pvp-btn.is-live:hover { background: var(--accent); color: #14100a; }
.pvp-lobby-card.is-live .pvp-lobby-fuel { color: var(--accent); display: flex; align-items: center; gap: 5px; }
.pvp-livedot {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--danger);
  animation: pvp-pulse 1.4s ease-in-out infinite;
}
@keyframes pvp-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }
@media (prefers-reduced-motion: reduce) { .pvp-livedot { animation: none; } }

/* ---------- circuit picker ---------- */

.pvp-tracks { margin-bottom: 14px; }
.pvp-tracks h3 { margin: 0 0 8px; }
.pvp-track-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(92px, 1fr));
  gap: 6px;
}
.pvp-track {
  padding: 5px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  cursor: pointer;
  color: var(--text-dim);
  transition: border-color 0.15s;
}
.pvp-track:hover { border-color: var(--border-strong); }
.pvp-track.is-on { border-color: var(--accent); color: var(--text); }
.pvp-track svg { display: block; width: 100%; height: auto; }
/* Miniatura: só o leito, sem linha tracejada — a 90px de largura o tracejado vira ruído. */
.pvp-track-mini {
  fill: none;
  stroke: rgba(255,255,255,0.22);
  stroke-width: 11;
  stroke-linejoin: round;
  stroke-linecap: round;
}
.pvp-track.is-on .pvp-track-mini { stroke: var(--accent); }
.pvp-track span {
  display: block;
  font-size: 8.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-align: center;
  margin-top: 2px;
}

/* ---------- circuit banner ---------- */

.pvp-stage-track {
  font-size: 10px;
  letter-spacing: 0.16em;
  color: var(--text-dim);
}
.pvp-banner {
  position: relative;
  height: 132px;
  margin-bottom: 14px;
  border-radius: 10px;
  overflow: hidden;
  /* O degradê é o fundo REAL, não um placeholder: sem banner cadastrado o cabeçalho
     continua existindo e com a cara certa, em vez de um buraco. */
  background: linear-gradient(115deg, #1b1206 0%, #2a1a08 40%, #12100f 100%);
  border: 1px solid var(--border);
}
.pvp-banner img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Véu por cima da arte: o texto tem que continuar legível seja qual for a imagem que o
   admin colar, e não dá para pedir que ele escolha uma imagem escura. */
.pvp-banner-veil {
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, rgba(11,11,14,0.86) 0%, rgba(11,11,14,0.35) 45%, rgba(11,11,14,0.72) 100%);
}
.pvp-banner-name {
  position: absolute;
  left: 16px; bottom: 12px;
  font-family: var(--font-display);
  font-style: italic;
  font-size: 21px;
  font-weight: 800;
  letter-spacing: 0.04em;
  /* Caixa alta como no mockup: o nome do circuito é uma placa, não uma frase. */
  text-transform: uppercase;
  color: var(--text);
  text-shadow: 0 2px 12px rgba(0,0,0,0.8);
}
.pvp-banner-tag {
  position: absolute;
  right: 14px; top: 12px;
  font-size: 8px;
  letter-spacing: 0.2em;
  color: var(--accent);
  padding: 3px 8px;
  border: 1px solid var(--accent-glow);
  border-radius: 999px;
  background: rgba(11,11,14,0.6);
}
@media (max-width: 620px) { .pvp-banner { height: 96px; } .pvp-banner-name { font-size: 15px; } }

/* ═══════════════════════════════════════════════════════════════════════════
   LOBBY — layout de duas colunas do mockup.
   Painéis escuros com cabeçalhos marcados por uma barra âmbar, que é o que
   organiza a página inteira sem precisar de linha divisória em todo canto.
   ═══════════════════════════════════════════════════════════════════════════ */

.pvp-panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 18px;
}

.pvp-block { margin-bottom: 20px; }
.pvp-block:last-child { margin-bottom: 0; }

/* ---- GRID PLAN: o seletor de quantidade e a faixa da fila em andamento ---- */
/* GRADE, e não flex numa linha só.
   Com sete opções (2 a 8) numa coluna de ~290px, o flex dividia em botões de 28px — e o
   check dentro de 28px vira um borrão colado no número. Em grade eles quebram em duas
   filas com ~50px cada, todos do mesmo tamanho, e a segunda fila fica alinhada com a
   primeira em vez de esticar para preencher a linha (que é o que o flex-wrap faria). */
.pvp-races-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(46px, 1fr));
  gap: 6px;
}
.pvp-rcount {
  flex: 1;
  display: flex; align-items: center; justify-content: center; gap: 4px;
  padding: 8px 0;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: transparent;
  color: var(--text-dim);
  font-family: var(--font-display);
  font-size: 13px;
  letter-spacing: 0.06em;
  cursor: pointer;
  transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}
.pvp-rcount:hover:not(:disabled) { color: var(--text); border-color: var(--border-strong); }
.pvp-rcount.is-on {
  border-color: var(--accent);
  background: rgba(255,138,0,0.12);
  color: var(--accent);
}
.pvp-rcount:disabled { opacity: 0.4; cursor: not-allowed; }
/* O check dentro do botao escolhido. A borda ambar ja diz qual e, mas ela e a MESMA
   linguagem do resto do formulario; o check e o que responde "entao ja esta escolhido?"
   sem obrigar a comparar quatro bordas. Herda a cor do botao, entao fica ambar aqui e
   verde no cabecalho da gaveta, onde o assunto e outro. */
.pvp-rcount .pvp-acc-check { width: 11px; height: 11px; color: currentColor; }
.pvp-rcount b { font-weight: inherit; }
.pvp-races-note {
  margin: 8px 0 0;
  font-size: 10px;
  line-height: 1.5;
  color: var(--text-dim);
}
.pvp-races-note b { color: var(--text); }

/* A faixa fica ACIMA das gavetas: ela responde "por que apareceu uma corrida que eu nao
   criei", e essa pergunta e feita antes de o jogador olhar para qualquer outra coisa. */
.pvp-planbar {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 14px;
  padding: 8px 10px;
  border: 1px solid var(--accent);
  border-radius: 12px;
  background: rgba(255,138,0,0.08);
}
.pvp-planbar-tag {
  font-family: var(--font-display);
  font-size: 9px;
  letter-spacing: 0.14em;
  color: var(--accent);
}
.pvp-planbar-txt { font-size: 11px; color: var(--text-dim); }
.pvp-planbar-txt b { color: var(--text); }
.pvp-planbar-stop {
  margin-left: auto;
  padding: 4px 10px;
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  background: transparent;
  color: var(--text-dim);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.12em;
  cursor: pointer;
}
.pvp-planbar-stop:hover { color: var(--danger, #ff5c5c); border-color: var(--danger, #ff5c5c); }

/* A barra âmbar antes do título. É o único ornamento do layout e faz o trabalho de
   agrupar — cada bloco fica lido como um bloco sem precisar de moldura própria. */
.pvp-h {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 12px;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.16em;
  color: var(--text);
  text-transform: uppercase;
}
.pvp-h::before {
  content: "";
  width: 3px;
  height: 14px;
  border-radius: 2px;
  background: var(--accent);
  flex: none;
}
.pvp-h-note {
  margin-left: auto;
  font-size: 9.5px;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--text-dim);
  text-transform: none;
}
.pvp-pill {
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--accent);
  font-size: 10px;
}

/* ---------- your racer ---------- */

.pvp-hero {
  display: grid;
  grid-template-columns: 152px 1fr;
  gap: 16px;
  align-items: center;
}

.pvp-hero-art {
  position: relative;
  margin: 0;
  border-radius: 10px;
  overflow: hidden;
  border: 1px solid var(--accent-glow);
}
.pvp-hero-img { width: 100%; aspect-ratio: 1; object-fit: cover; display: block; background: #101014; }
/* Legenda POR CIMA do retrato, como no mockup: o número e o OVR são o que identifica a
   peça, e separá-los da arte custaria uma linha inteira de altura. */
.pvp-hero-art figcaption {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: 18px 10px 8px;
  background: linear-gradient(180deg, transparent, rgba(6,6,9,0.92));
}
.pvp-hero-id { display: block; font-size: 13px; font-weight: 700; }
.pvp-hero-ovr { display: block; font-size: 15px; font-weight: 700; color: var(--accent); line-height: 1.1; }
.pvp-hero-lv { display: block; font-size: 9px; color: var(--text-dim); letter-spacing: 0.1em; }

.pvp-hero-stats { display: grid; gap: 12px; }
.pvp-statrow {
  display: grid;
  /* A COLUNA DO NUMERO E AUTO, e nao 34px fixos, e vale registrar por que: os numeros
     sao Orbitron italico (a decisao de "display" mais abaixo neste arquivo), que e uma
     fonte larga, e quando ha carta encaixada a celula carrega "100" MAIS o delta "+16".
     Numa trilha fixa isso vira um item de grade maior que a trilha, entao o texto vazava
     para fora do painel e o "+16" ficava escondido pela borda. Com `minmax(34px, auto)` a
     celula pede a largura que precisa e quem cede e a barra, que e elastica de proposito.
     O `minmax(0, 1fr)` ao lado e o par obrigatorio disso: sem ele a barra tem min-width
     auto e se recusa a encolher, e o vazamento simplesmente muda de lugar. */
  grid-template-columns: 22px minmax(0, 1fr) minmax(34px, auto);
  grid-template-areas: "ico name num" "ico bar num";
  align-items: center;
  gap: 2px 10px;
}
.pvp-stat-ico { grid-area: ico; width: 22px; height: 22px; }
.pvp-stat-ico svg { width: 100%; height: 100%; display: block; }
.pvp-stat-ico.is-speed { color: var(--accent); }
.pvp-stat-ico.is-control { color: #5aa9e6; }
.pvp-stat-ico.is-focus { color: #a78bfa; }
.pvp-stat-ico.is-luck { color: var(--success); }
.pvp-stat-name { grid-area: name; font-size: 9px; letter-spacing: 0.14em; color: var(--text-dim); }
.pvp-stat-track {
  grid-area: bar;
  position: relative;   /* the card segment is positioned against this */
  height: 6px;
  border-radius: 3px;
  background: var(--surface-2);
  overflow: hidden;
}
.pvp-stat-track i { display: block; height: 100%; border-radius: 3px; transition: width 0.3s, left 0.3s; }

/* WHAT THE CARDS ADDED, in its own colour.
   A solid bar answers "how fast is this car" and cannot answer "how much of that did I
   buy". The split is what makes fitting a card feel like it did something, and what lets
   somebody judge a swap without doing arithmetic against a number they memorised. */
.pvp-stat-track i.from-card {
  position: absolute;
  top: 0;
  /* A +1 on a 180px bar is one pixel, which reads as nothing at all. The floor guarantees
     that any contribution is at least a visible sliver — the exact width stops being
     literal below ~2 points, and the number beside the bar carries the precision. */
  min-width: 4px;
  background: repeating-linear-gradient(
    115deg,
    var(--accent-soft) 0 4px,
    var(--accent) 4px 8px
  );
  box-shadow: 0 0 8px -1px var(--accent-glow);
}
/* A negative contribution is drawn PAST the current value: this is what it cost you.
   Hiding it is how a player decides the card is broken when their control bar shrinks. */
.pvp-stat-track i.from-card.is-loss {
  background: repeating-linear-gradient(
    115deg,
    rgba(199, 68, 54, 0.85) 0 4px,
    rgba(199, 68, 54, 0.4) 4px 8px
  );
  box-shadow: none;
}
.pvp-stat-delta {
  margin-left: 4px;
  font-size: 10px;
  font-style: normal;
  font-weight: 700;
  vertical-align: 2px;
}
.pvp-stat-delta.is-up { color: var(--accent); }
.pvp-stat-delta.is-down { color: var(--danger); }
.pvp-stat-track i.is-speed { background: var(--accent); }
.pvp-stat-track i.is-control { background: #5aa9e6; }
.pvp-stat-track i.is-focus { background: #a78bfa; }
.pvp-stat-track i.is-luck { background: var(--success); }
/* nowrap: the delta is an <em> inside this cell, and on a narrow screen "44 -4" wrapped
   into "44" with a lonely "-4" on the line below, which read as a different number. */
.pvp-stat-num { grid-area: num; font-size: 16px; font-weight: 700; text-align: right; white-space: nowrap; }

/* Trocar de Racerz: fileira rolável, para uma carteira grande não empurrar o formulário
   para fora da tela. */
.pvp-swap {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  padding: 12px 2px 2px;
  margin-top: 4px;
  border-top: 1px solid var(--border);
}
.pvp-swap-item {
  flex: none;
  width: 52px;
  padding: 3px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  cursor: pointer;
  color: var(--text-dim);
}
.pvp-swap-item.is-on { border-color: var(--accent); color: var(--text); }
.pvp-swap-item.is-busy { opacity: 0.35; cursor: not-allowed; }
.pvp-swap-art { width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: 5px; display: block; background: #101014; }
.pvp-swap-item span { display: block; font-size: 8px; font-weight: 700; margin-top: 2px; }

/* ---------- fuel ---------- */

.pvp-fuel-rows { display: grid; gap: 8px; }

/* Linha inteira clicável para SELECIONAR, com o botão de COMPRAR à direita. As duas
   ações moram na mesma linha, então precisam ser visualmente diferentes — antes a compra
   era um texto pequeno dentro do card e ninguém percebia que era um botão. */
.pvp-fuel-row {
  display: grid;
  grid-template-columns: 38px 1fr auto;
  align-items: center;
  gap: 12px;
  padding: 11px 12px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-left: 3px solid var(--border-strong);
  border-radius: 10px;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}
.pvp-fuel-row:hover { background: #20202a; }
.pvp-fuel-row.is-on { background: rgba(233,161,59,0.07); }
/* Uma cor por grade, na bomba e na borda esquerda: dá para distinguir as três de relance. */
.pvp-fuel-row.is-regular { border-left-color: var(--accent); }
.pvp-fuel-row.is-premium { border-left-color: #5aa9e6; }
.pvp-fuel-row.is-race { border-left-color: #a78bfa; }
.pvp-fuel-row.is-on.is-regular { border-color: var(--accent); }
.pvp-fuel-row.is-on.is-premium { border-color: #5aa9e6; }
.pvp-fuel-row.is-on.is-race { border-color: #a78bfa; }

.pvp-pump { width: 38px; height: 38px; display: grid; place-items: center; }
.pvp-pump svg { width: 26px; height: 26px; }
.pvp-fuel-row.is-regular .pvp-pump { color: var(--accent); }
.pvp-fuel-row.is-premium .pvp-pump { color: #5aa9e6; }
.pvp-fuel-row.is-race .pvp-pump { color: #a78bfa; }

.pvp-fuel-info { display: grid; gap: 1px; min-width: 0; }
.pvp-fuel-info b { font-size: 12px; font-weight: 700; letter-spacing: 0.06em; }
.pvp-fuel-info i { font-size: 9.5px; font-style: normal; color: var(--accent-soft); }
.pvp-fuel-info em { font-size: 9.5px; font-style: normal; color: var(--text-dim); }

/* O BOTÃO. Preenchido, com contraste alto e sombra — a versão anterior era um chip
   discreto que não lia como algo clicável, que foi exatamente a reclamação. */
.pvp-buy {
  padding: 9px 14px;
  border: none;
  border-radius: 8px;
  background: linear-gradient(180deg, var(--accent) 0%, var(--accent-strong) 100%);
  color: #14100a;
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: 0.08em;
  white-space: nowrap;
  cursor: pointer;
  box-shadow: 0 2px 10px rgba(233,161,59,0.28);
  transition: transform 0.12s, box-shadow 0.12s, filter 0.12s;
}
.pvp-buy:hover { transform: translateY(-1px); filter: brightness(1.08); box-shadow: 0 4px 16px rgba(233,161,59,0.42); }
.pvp-buy:active { transform: translateY(0); box-shadow: 0 1px 6px rgba(233,161,59,0.3); }

/* ---------- medidor de combustivel (topo da pagina) ----------

   A gaveta FUEL responde "com o que eu vou correr". Ela NAO responde "quanto me sobra":
   fica fechada quase sempre e, fechada, o resumo so fala da grade selecionada — o jogador
   descobria que estava sem gasolina pelo botao dizendo NOT ENOUGH FUEL, ja com a corrida
   montada. Este medidor mora ao lado das abas, visivel em qualquer aba, e usa o desenho de
   painel de carro: dez casas de vazio a cheio.

   ACIMA DE DEZ A BARRA SATURA de proposito. Uma barra que continua crescendo depois do
   "cheio" nao significa nada num medidor de tanque, e a precisao ja esta ali do lado, no
   numero — que e o dado exato em qualquer quantidade. */

.pvp-topbar {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  margin-bottom: 14px;
  /* `flex: none`: no desktop >=1180px a `.pvp-body` e uma coluna flex cuja altura sobrante
     vai toda para a grade. Sem isto o topo entra na divisao e encolhe junto. */
  flex: none;
}
/* As abas ja tinham a margem inferior; dentro da faixa quem a carrega e a faixa.
   O `min-width: 0` nao e enfeite: como item de flex a fileira de abas ganha min-width auto
   e se recusa a encolher abaixo do proprio conteudo, e a 320px "TOP PILOTS" saia cortado
   pela borda. Zerando o minimo as abas voltam a apertar e a quebrar o rotulo em duas
   linhas, que e o que faziam antes de existir esta faixa. */
.pvp-topbar .pvp-tabs { margin-bottom: 0; flex: 1 1 auto; min-width: 0; }

.pvp-gauges {
  display: flex;
  gap: 8px;
  margin-left: auto;
}

.pvp-gauge {
  /* Uma cor por grade, a MESMA das linhas da gaveta FUEL — e o que faz os dois lugares
     serem obviamente a mesma informacao sem precisar reler o rotulo. */
  --g: var(--border-strong);
  display: grid;
  gap: 5px;
  min-width: 104px;
  padding: 6px 9px 7px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
}
.pvp-gauge.is-regular { --g: var(--accent); }
.pvp-gauge.is-premium { --g: #5aa9e6; }
.pvp-gauge.is-race { --g: #a78bfa; }
/* A grade escolhida para a proxima corrida ganha a borda na propria cor: o medidor mostra
   tres tanques, e qual deles vai queimar e a metade da pergunta. */
.pvp-gauge.is-sel { border-color: var(--g); }

.pvp-gauge-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}
.pvp-gauge-top b {
  font-size: 8.5px;
  font-weight: 700;
  letter-spacing: 0.12em;
  color: var(--text-dim);
  white-space: nowrap;
}
.pvp-gauge.is-sel .pvp-gauge-top b { color: var(--text); }
.pvp-gauge-top em {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 800;
  font-size: 12.5px;
  line-height: 1;
  color: var(--g);
}
.pvp-gauge.is-empty .pvp-gauge-top em { color: var(--text-dim); }

.pvp-gauge-bar { display: flex; gap: 2px; }
.pvp-gauge-bar i {
  flex: 1 1 0;
  min-width: 0;
  height: 7px;
  border-radius: 1px;
  background: var(--surface-2);
}
.pvp-gauge-bar i.is-on {
  background: var(--g);
  box-shadow: 0 0 6px -2px var(--g);
}

/* Tanque vazio: a linha inteira baixa de tom em vez de gritar em vermelho. Tres tanques
   zerados e o estado NORMAL de quem acabou de abrir a pagina, e alarmar nisso ensina o
   jogador a ignorar o alarme. */
.pvp-gauge.is-empty { opacity: 0.72; }

@media (max-width: 760px) {
  /* No celular a faixa quebra: as abas ficam na linha de cima e os tres medidores dividem
     a largura inteira embaixo. Encolher os medidores para caber ao lado das abas os
     deixaria com ~60px, onde dez casas viram uma mancha. */
  .pvp-topbar { gap: 10px; }
  .pvp-gauges {
    margin-left: 0;
    width: 100%;
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 6px;
  }
  .pvp-gauge { min-width: 0; padding: 6px 7px 7px; }
  .pvp-gauge-top { gap: 5px; }
  .pvp-gauge-top b { font-size: 7.5px; letter-spacing: 0.05em; }
  .pvp-gauge-top em { font-size: 12px; }
  /* Alvo de dedo nenhum aqui — o medidor so mostra — mas casas de 5px de altura somem no
     brilho da tela do celular. */
  .pvp-gauge-bar { gap: 1.5px; }
  .pvp-gauge-bar i { height: 8px; }
}

/* ---------- fields ---------- */

.pvp-field { position: relative; display: flex; align-items: center; }
.pvp-field input {
  width: 100%;
  padding: 12px 14px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 9px;
  color: var(--text);
  font-size: 15px;
  font-weight: 600;
}
.pvp-field input:focus { outline: none; border-color: var(--accent); }
.pvp-field-suffix {
  position: absolute;
  right: 14px;
  font-size: 10px;
  letter-spacing: 0.1em;
  color: var(--text-dim);
  pointer-events: none;
}
.pvp-fineprint { margin: 0 0 14px; font-size: 10px; line-height: 1.6; color: var(--text-dim); }
.pvp-btn.is-big { padding: 15px; font-size: 12px; letter-spacing: 0.16em; }

/* ---------- grid entries ---------- */

.pvp-entry-list { display: grid; gap: 10px; }

.pvp-entry-card {
  position: relative;
  display: grid;
  grid-template-columns: 72px 1fr auto auto;
  align-items: center;
  gap: 14px;
  padding: 12px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 12px;
}
.pvp-entry-card.is-mine { border-color: var(--accent-glow); }
.pvp-entry-card.is-live { border-color: rgba(233,161,59,0.4); }
.pvp-entry-art { width: 72px; height: 72px; object-fit: cover; border-radius: 9px; display: block; background: #101014; }
.pvp-entry-body h4 { margin: 0; font-size: 17px; font-weight: 700; }
.pvp-entry-body h4 span { font-size: 11px; color: var(--text-dim); font-weight: 500; margin-left: 6px; }
.pvp-entry-owner { margin: 3px 0 0; font-size: 11px; color: var(--text-dim); font-family: ui-monospace, Menlo, monospace; }
.pvp-entry-fuel {
  margin: 3px 0 0;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.1em;
  color: var(--accent);
  display: flex;
  align-items: center;
  gap: 5px;
}
.pvp-entry-stake { text-align: right; line-height: 1.2; }
.pvp-entry-stake b { font-size: 22px; font-weight: 700; color: var(--accent); }
.pvp-entry-stake span { display: block; font-size: 9px; color: var(--text-dim); letter-spacing: 0.1em; }
.pvp-entry-stake em { display: block; margin-top: 3px; font-size: 10px; font-style: normal; font-weight: 700; color: var(--success); }
.pvp-entry-tag {
  position: absolute;
  top: -8px; left: 14px;
  font-size: 8px;
  font-weight: 700;
  letter-spacing: 0.16em;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--accent-strong);
  color: #14100a;
}
.pvp-btn.is-accept { padding: 14px 26px; font-size: 12px; }

/* ---------- results ---------- */

.pvp-results { list-style: none; margin: 0; padding: 0; }
.pvp-results li {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 13px 12px;
  margin-bottom: 6px;
  font-size: 12px;
  background: var(--surface-2);
  border-radius: 10px;
  color: var(--text-dim);
}
.pvp-res-flag { width: 18px; height: 18px; color: var(--text-dim); flex: none; }
.pvp-res-flag svg { width: 100%; height: 100%; display: block; }
.pvp-results li b { color: var(--text); font-size: 14px; }
.pvp-results li b.is-dim { color: var(--text-dim); font-weight: 500; }
.pvp-res-verb { font-size: 11px; }
.pvp-res-margin-inline { font-size: 11px; }
.pvp-results li em { margin-left: auto; font-style: normal; font-weight: 700; color: var(--success); }

/* ---------- challenge grid + minhas corridas ---------- */

/* Um desafio ENVIADO nao e um anuncio: nao esta aberto a ninguem e nao ha o que aceitar.
   A borda tracejada e o que diz "isto esta esperando uma pessoa" sem precisar de texto —
   um desafio parado com a mesma moldura solida de uma corrida na grade lia como se ja
   estivesse valendo. */
.pvp-entry-card.is-sent {
  border-style: dashed;
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
  background: color-mix(in srgb, var(--accent) 5%, var(--surface-2));
}
.pvp-entry-card.is-sent .pvp-entry-tag {
  background: transparent;
  color: var(--accent);
  border: 1px solid color-mix(in srgb, var(--accent) 55%, transparent);
}
.pvp-entry-card.is-sent .pvp-entry-owner b { color: var(--accent); font-weight: 700; }

/* O CONVITE PARA A PRÓPRIA CORRIDA AO VIVO.
   Ele deixou de ser um botão entre outros: como o lobby não arrasta mais ninguém para
   dentro da corrida, este bloco é a única porta de volta para quem saiu no meio. A moldura
   âmbar e o fundo quente existem para isso — num grid cheio de blocos iguais, o que a
   pessoa precisa achar em um segundo não pode parecer com os outros. */
.pvp-live-invite {
  padding: 14px;
  border: 1px solid var(--accent-glow);
  border-radius: 12px;
  background: linear-gradient(160deg, rgba(233,161,59,0.10), rgba(233,161,59,0.02));
}
/* Duas corridas suas ao mesmo tempo são dois botões empilhados, e sem isto eles se
   encostam e viram um bloco só. */
.pvp-live-invite .pvp-btn + .pvp-btn { margin-top: 8px; }

/* Linha de apoio sob o titulo de um bloco. Aqui ela carrega a unica informacao que o
   jogador precisa e nao consegue deduzir do card: o dinheiro esta preso, e cancelar
   devolve tudo. */
.pvp-block-note {
  margin: -4px 0 10px;
  font-size: 11px;
  line-height: 1.5;
  color: var(--text-dim);
}

/* Resultado clicavel. Sem o cursor e o hover, uma lista que abre a corrida ao ser clicada
   e uma lista que ninguem descobre que abre a corrida. */
.pvp-results li.is-openable,
.pvp-mine-row { cursor: pointer; transition: background 0.15s, transform 0.15s; }
.pvp-results li.is-openable:hover,
.pvp-mine-row:hover { background: var(--surface-3, rgba(255,255,255,0.06)); transform: translateX(2px); }
.pvp-results li.is-openable:focus-visible,
.pvp-mine-row:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Ganhou/perdeu: a cor do valor e a primeira coisa lida na linha, entao ela tem que dizer
   a verdade sozinha — o mesmo verde nos dois casos transformava uma derrota em algo que
   parecia credito. */
.pvp-mine-row.is-win b:first-of-type { color: var(--success); }
.pvp-mine-row.is-loss b:first-of-type { color: var(--danger); }
.pvp-mine-row.is-loss em { color: var(--danger); }

@media (max-width: 760px) {
  .pvp-hero { grid-template-columns: 1fr; }
  .pvp-hero-art { max-width: 180px; margin: 0 auto; }
  .pvp-entry-card { grid-template-columns: 56px 1fr auto; }
  .pvp-entry-card .pvp-btn { grid-column: 1 / -1; }
  .pvp-entry-art { width: 56px; height: 56px; }
  .pvp-entry-stake b { font-size: 18px; }
}

/* Subtítulo do cabeçalho, com as barras diagonais do mockup. Diz o que a página faz em
   quatro palavras — quem chega pela primeira vez não sabe o que é "Random PvP". */
.pvp-tagline {
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 4px 0 0;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.18em;
  color: var(--text-dim);
}
.pvp-tagline i {
  width: 26px;
  height: 9px;
  flex: none;
  background: repeating-linear-gradient(115deg, var(--accent) 0 3px, transparent 3px 6px);
}

/* ═══════════ RACE STAGE — refinamentos do mockup ═══════════ */

.pvp-chevrons { font-style: normal; color: var(--accent-strong); letter-spacing: -1px; margin-left: 4px; }

/* Regressivo num "pill". "Faltam 74s" é a informação que interessa a quem está torcendo;
   tempo decorrido é dado de telemetria, não de torcida. */
.pvp-endsin {
  display: flex;
  align-items: center;
  gap: 7px;
  margin-left: auto;
  padding: 7px 14px;
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  background: var(--surface-2);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.14em;
  color: var(--text-dim);
}
.pvp-endsin i { font-style: normal; color: var(--accent); }
.pvp-endsin b { font-size: 14px; color: var(--accent); letter-spacing: 0; }

/* ---------- painéis dos corredores ---------- */

.pvp-car-panel {
  position: relative;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 12px;
}
.pvp-car-panel.is-a { border-top: 2px solid var(--accent); }
.pvp-car-panel.is-b { border-top: 2px solid var(--danger); }
.pvp-panel-who { letter-spacing: 0.2em; }
.pvp-panel-art { max-width: 100%; border-radius: 8px; }
.pvp-car-panel h4 { margin: 10px 0 6px; font-size: 12.5px; }
.pvp-car-panel h4 span { font-size: 9px; color: var(--text-dim); font-weight: 500; }

.pvp-panel-ovr { display: flex; align-items: baseline; gap: 7px; margin-bottom: 10px; }
.pvp-panel-ovr span { font-size: 8.5px; letter-spacing: 0.16em; color: var(--text-dim); }
.pvp-panel-ovr b { font-size: 29px; line-height: 1; color: var(--accent); }
.pvp-car-panel.is-b .pvp-panel-ovr b { color: var(--danger); }

.pvp-panel-fuel {
  display: flex; align-items: center; gap: 7px;
  margin: 10px 0 0; padding-top: 9px;
  border-top: 1px solid var(--border);
  font-size: 8.5px; letter-spacing: 0.16em; color: var(--text-dim);
}
.pvp-panel-fuel em {
  font-style: normal; font-weight: 700; color: var(--accent-soft);
  padding: 2px 7px; border-radius: 999px; background: rgba(233,161,59,0.12);
}

.pvp-panel-odds { margin-top: 12px; }
.pvp-panel-odds b { display: block; font-size: 25px; line-height: 1; color: var(--accent); }
.pvp-car-panel.is-b .pvp-panel-odds b { color: var(--danger); }
.pvp-panel-odds span { font-size: 8px; letter-spacing: 0.16em; color: var(--text-dim); }

/* ---------- HUD ---------- */

.pvp-hud {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 8px;
  margin-top: 12px;
}
/* Divisórias entre as três leituras, como no mockup — sem elas os números correm juntos. */
.pvp-hud > div + div { border-left: 1px solid var(--border); }
.pvp-hud b { font-size: 20px; }

/* ---------- live feed ---------- */

.pvp-feed {
  margin-top: 12px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
}
.pvp-feed-head {
  display: flex;
  align-items: center;
  padding: 9px 12px;
  border-bottom: 1px solid var(--border);
}
.pvp-feed-lap { font-size: 9.5px; font-weight: 700; letter-spacing: 0.16em; color: var(--text-dim); }
.pvp-feed-tag { margin-left: auto; font-size: 8px; letter-spacing: 0.2em; color: var(--accent); }

.pvp-ticker { max-height: 176px; padding: 4px; }
.pvp-tick {
  display: grid;
  grid-template-columns: 20px 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 9px 10px;
  margin: 0;
  border-left: none;
  border-bottom: 1px solid var(--border);
  background: transparent;
  border-radius: 0;
  font-weight: 600;
}
.pvp-tick:last-child { border-bottom: none; }
.pvp-tick-ico { width: 20px; height: 20px; opacity: 0.85; }
.pvp-tick-ico svg { width: 100%; height: 100%; display: block; }
.pvp-tick-text b { font-weight: 800; }
/* Coluna do tempo: alinhada à direita e monoespaçada, então os números empilham. */
.pvp-tick-val {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 10.5px;
  font-weight: 700;
  color: var(--accent);
}
.pvp-tick.is-spin .pvp-tick-val { color: var(--danger); }
.pvp-tick.is-close .pvp-tick-val { color: #5aa9e6; }

/* ---------- pot ---------- */

/* O pote mora na coluna da esquerda, colado embaixo do card do jogador. Nada de
   `min-width` aqui: a largura é a da coluna, e um mínimo maior que ela furava a grid. */
.pvp-pot {
  padding: 14px 14px 13px;
  border: 1px solid var(--accent-glow);
  border-radius: 12px;
  background: linear-gradient(160deg, rgba(233,161,59,0.10), rgba(233,161,59,0.02));
}
.pvp-pot > span { display: block; font-size: 9.5px; letter-spacing: 0.2em; color: var(--text-dim); }
.pvp-pot > b { display: block; font-size: 24px; line-height: 1.15; color: var(--accent); }
/* O ticker num corpo menor: numa coluna estreita, "$CAZH" no mesmo tamanho do valor rouba
   metade da linha do número, que é o que se veio ler. */
.pvp-pot > b i { font-size: 12px; letter-spacing: 0.06em; opacity: 0.85; }
/* O commit fica visível, não escondido num tooltip: é a diferença entre "confie em nós"
   e "confira você mesmo", e escondê-lo desperdiça a única razão de ele existir. */
.pvp-pot > em {
  display: block;
  margin-top: 10px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 9px;
  font-style: normal;
  line-height: 1.7;
  color: var(--text-dim);
  cursor: help;
}

/* ═══════════ NÚMEROS — o display itálico ═══════════

   Pedido do founder: os números em "bold cursive". Cursivo de verdade (uma script) não
   existe nesta paleta e brigaria com tudo; o que a marca já usa como voz de velocidade é
   o Orbitron INCLINADO — é o mesmo tratamento do wordmark e do título RANDOM PVP no topo
   da página. Aplicar aqui é estender uma decisão que já estava tomada, e não inventar uma
   sexta fonte.

   Só os números de LEITURA entram: OVR, os quatro atributos, a probabilidade, o HUD, o
   relógio e o pot. A coluna de tempos do live feed continua monoespaçada de propósito —
   ali os números precisam EMPILHAR alinhados, e inclinar uma coluna alinhada desfaz a
   única razão de ela existir. */

.pvp-panel-ovr b,
.pvp-panel-odds b,
.pvp-stat-val,
.pvp-stat-num,
.pvp-hud b,
.pvp-endsin b,
.pvp-pot > b,
.pvp-modal-ovr b,
.pvp-entry-stake b {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 800;
  /* O Orbitron é largo; sem isto os dois dígitos do OVR encostam na borda do card. */
  letter-spacing: -0.01em;
}

/* A coluna dos atributos tinha 26px porque cabia "100" em Inter. Em Orbitron não cabe. */
.pvp-car-panel .pvp-stat { grid-template-columns: 54px 1fr 30px; }
.pvp-stat-val { font-size: 10.5px; }

/* ═══════════ SILHUETA DOS DOIS CARDS ═══════════

   O founder aprovou a moldura vermelha em volta do card do rival. Ela não é enfeite: a
   corrida inteira se lê por cor — o ponto âmbar é você, o vermelho é ele — e até agora
   essa cor só aparecia numa listra de 2px no topo do painel. Levar a cor para a borda
   toda e para o brilho faz o card e o carrinho na pista serem obviamente a mesma coisa. */

.pvp-car-panel.is-a {
  border-color: rgba(233,161,59,0.42);
  box-shadow: 0 0 24px -8px var(--accent-glow), inset 0 0 30px -18px var(--accent);
}
.pvp-car-panel.is-b {
  border-color: rgba(199,68,54,0.46);
  box-shadow: 0 0 24px -8px rgba(199,68,54,0.55), inset 0 0 30px -18px var(--danger);
}
/* A listra sólida do topo continua: é ela que dá o "cabeçalho" do card, e o border-color
   acima apagaria a cor cheia dela se não fosse reposta aqui. */
.pvp-car-panel.is-a { border-top: 2px solid var(--accent); }
.pvp-car-panel.is-b { border-top: 2px solid var(--danger); }

/* A arte também ganha a cor do lado — sem isso o retrato flutua solto dentro da moldura. */
.pvp-car-panel .pvp-panel-art { border: 1px solid var(--border); }
.pvp-car-panel.is-a .pvp-panel-art { border-color: rgba(233,161,59,0.35); }
.pvp-car-panel.is-b .pvp-panel-art { border-color: rgba(199,68,54,0.38); }

/* ═══════════ ADMIN — banners dos circuitos ═══════════ */

/* ============================================================
   ADMIN — GRAND PRIX

   A tela é construída em volta de UMA decisão: como o pote se divide. Por isso a coluna do
   saldo (`em`) tem o mesmo peso visual do prêmio — com 60/25/15 numa grade de cinco o
   terceiro lugar aparece em vermelho, e é isso que precisa estar na frente de quem escolhe.
   ============================================================ */
.pvpadm-gp {
  margin: 0 0 22px;
  padding: 16px 18px;
  border: 1px solid var(--border-strong);
  border-radius: 14px;
  background: var(--surface-2);
}
.pvpadm-gp.is-on { border-color: var(--accent); }
.pvpadm-gp-head { display: flex; align-items: center; gap: 14px; margin-bottom: 10px; }
.pvpadm-gp-head h3 {
  margin: 0; font-family: var(--font-display); font-size: 15px; letter-spacing: 0.12em;
}
.pvpadm-gp.is-on .pvpadm-gp-head h3 { color: var(--accent); }
.pvpadm-switch {
  margin-left: auto; display: flex; align-items: center; gap: 7px;
  font-size: 11px; color: var(--text-dim); cursor: pointer;
}
.pvpadm-gp.is-on .pvpadm-switch span { color: var(--accent); }

.pvpadm-gp-row {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: 14px;
  margin: 14px 0 4px;
}
.pvpadm-gp-row label {
  display: flex; flex-direction: column; gap: 5px;
  font-size: 9px; letter-spacing: 0.12em; color: var(--text-dim);
}
.pvpadm-gp-row input {
  width: 110px; padding: 7px 9px;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--bg-deep); color: var(--text);
  font-family: var(--font-display); font-size: 14px;
}
.pvpadm-gp-pot {
  margin-left: auto; display: flex; align-items: baseline; gap: 6px;
  font-size: 9px; letter-spacing: 0.1em; color: var(--text-dim);
}
.pvpadm-gp-pot b {
  font-family: var(--font-display); font-size: 14px; color: var(--text);
  letter-spacing: 0; margin-right: 8px;
}

.pvpadm-gp-sub {
  margin: 18px 0 8px; font-family: var(--font-display);
  font-size: 10px; letter-spacing: 0.14em; color: var(--text-dim);
}
.pvpadm-split { list-style: none; margin: 0; padding: 0; }
.pvpadm-split li {
  display: grid;
  grid-template-columns: 40px 88px 62px 1fr 90px 26px;
  align-items: center; gap: 8px;
  padding: 4px 0;
}
.pvpadm-split-place { font-family: var(--font-display); font-size: 12px; color: var(--accent); }
.pvpadm-split input {
  padding: 6px 8px; border: 1px solid var(--border); border-radius: 7px;
  background: var(--bg-deep); color: var(--text); font-size: 12px;
}
.pvpadm-split-pct { font-size: 10px; color: var(--text-dim); }
.pvpadm-split-prize { font-family: var(--font-display); font-size: 13px; }
.pvpadm-split li em { font-style: normal; font-size: 12px; text-align: right; }
.pvpadm-split li em.is-up { color: var(--success); }
.pvpadm-split li em.is-down { color: var(--danger); }
.pvpadm-split-x {
  width: 22px; height: 22px; border-radius: 50%;
  border: 1px solid var(--border); background: transparent;
  color: var(--text-dim); cursor: pointer; line-height: 1;
}
.pvpadm-split-x:hover { color: var(--danger); border-color: var(--danger); }

.pvpadm-split-foot { display: flex; align-items: center; gap: 12px; margin-top: 10px; }
.pvpadm-sum { margin-left: auto; font-size: 11px; letter-spacing: 0.06em; }
.pvpadm-sum.is-ok { color: var(--success); }
.pvpadm-sum.is-bad { color: var(--danger); }
.pvpadm-warn {
  margin: 8px 0 0; padding: 8px 10px;
  border-left: 3px solid var(--danger); border-radius: 0 6px 6px 0;
  background: rgba(199,68,54,0.1);
  font-size: 11px; color: var(--text);
}

.pvpadm-presets {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 8px; margin: 16px 0 0;
}
.pvpadm-preset {
  text-align: left; padding: 9px 11px;
  border: 1px solid var(--border); border-radius: 10px;
  background: transparent; color: var(--text-dim); cursor: pointer;
  transition: border-color 0.15s ease, color 0.15s ease;
}
.pvpadm-preset:hover { border-color: var(--accent); color: var(--text); }
.pvpadm-preset b {
  display: block; font-family: var(--font-display); font-size: 13px; color: var(--text);
}
.pvpadm-preset span { display: block; margin-top: 3px; font-size: 10px; line-height: 1.45; }
.pvpadm-gp-actions { margin-top: 16px; }

/* --- admin: a lista de eventos e o formulário --- */
.pvpadm-evlist { list-style: none; margin: 0 0 14px; padding: 0; }
.pvpadm-ev {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 12px; margin-bottom: 6px;
  border: 1px solid var(--border); border-radius: 10px;
  background: var(--bg-deep);
}
.pvpadm-ev.is-done { opacity: 0.55; }
.pvpadm-ev-main { min-width: 0; flex: 1; }
.pvpadm-ev-main b { display: block; font-size: 13px; }
.pvpadm-ev-main span { display: block; font-size: 10px; color: var(--text-dim); }
.pvpadm-ev-main em {
  display: block; margin-top: 2px; font-style: normal; font-size: 10px; color: var(--accent);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pvpadm-ev-main em.is-dim { color: var(--text-dim); }
.pvpadm-ev-status {
  flex: 0 0 auto; font-size: 8px; letter-spacing: 0.12em; color: var(--text-dim);
  padding: 3px 8px; border: 1px solid var(--border); border-radius: 999px;
}
.pvpadm-ev.is-live .pvpadm-ev-status { color: var(--success); border-color: var(--success); }
.pvpadm-ev-actions { display: flex; gap: 6px; flex: 0 0 auto; }
.pvpadm-ev-actions .pvp-btn { padding: 5px 12px; font-size: 9px; }

/* Os botoes do admin sao AÇÕES, e não o CTA de uma coluna: `.pvp-btn` nasce com
   `width: 100%` porque no formulário de corrida ele é a única coisa da linha. Aqui ele
   divide espaço com um título ou com outro botão, e esticado ele empurra tudo. */
.pvpadm-gp-head .pvp-btn,
.pvpadm-gp-actions .pvp-btn { width: auto; padding: 8px 18px; }
.pvpadm-gp-actions { display: flex; gap: 8px; flex-wrap: wrap; }

/* Um campo de NOME com 110px corta o nome — e o nome é o que aparece no card do jogador. */
.pvpadm-gp-row label.is-wide { flex: 1 1 210px; min-width: 0; }
.pvpadm-gp-row label.is-full { flex: 1 1 100%; min-width: 0; }
.pvpadm-gp-row label.is-wide input,
.pvpadm-gp-row label.is-full input { width: 100%; }
.pvpadm-items label.is-wide { flex: 1 1 170px; min-width: 0; }

.pvpadm-evform {
  margin-top: 14px; padding: 14px;
  border: 1px dashed var(--border-strong); border-radius: 12px;
}
.pvpadm-evform select {
  padding: 7px 9px; border: 1px solid var(--border); border-radius: 8px;
  background: var(--bg-deep); color: var(--text); font-size: 12px;
}
.pvpadm-items { list-style: none; margin: 0; padding: 0; }
.pvpadm-items li {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: 8px;
  padding: 9px; margin-bottom: 6px;
  border: 1px solid var(--border); border-radius: 9px; background: var(--bg-deep);
}
.pvpadm-items label {
  display: flex; flex-direction: column; gap: 4px;
  font-size: 8px; letter-spacing: 0.12em; color: var(--text-dim);
}
.pvpadm-items input {
  padding: 6px 8px; border: 1px solid var(--border); border-radius: 7px;
  background: var(--surface-2); color: var(--text); font-size: 11px; width: 100%;
}

/* --- admin: a fila de entrega --- */
.pvpadm-awards { list-style: none; margin: 0; padding: 0; }
.pvpadm-award {
  display: flex; align-items: center; gap: 12px;
  padding: 10px; margin-bottom: 6px;
  border: 1px solid var(--border); border-radius: 10px; background: var(--bg-deep);
}
.pvpadm-award img, .pvpadm-award-noart {
  width: 40px; height: 40px; flex: 0 0 auto;
  border-radius: 8px; object-fit: cover;
  background: var(--surface-2); border: 1px solid var(--border);
}
.pvpadm-award-main { flex: 1 1 160px; min-width: 0; }
.pvpadm-award-main b { display: block; font-size: 12px; }
.pvpadm-award-main span { font-size: 9px; color: var(--text-dim); }
.pvpadm-award-who { flex: 1 1 200px; min-width: 0; }
.pvpadm-award-who b { display: block; font-size: 11px; }
/* A CARTEIRA quebra em vez de cortar: ela é o que vai ser copiado, e uma carteira com
   reticências no meio é inútil para quem precisa colar no explorer. */
.pvpadm-award-who code { font-size: 9px; color: var(--text-dim); word-break: break-all; }
.pvpadm-award-ship { display: flex; gap: 6px; flex: 0 0 auto; align-items: center; }
.pvpadm-award-ship input {
  width: 150px; padding: 6px 8px;
  border: 1px solid var(--border); border-radius: 7px;
  background: var(--surface-2); color: var(--text); font-size: 10px;
}
.pvpadm-award-ship .pvp-btn { padding: 6px 12px; font-size: 9px; }
.pvpadm-award-done {
  flex: 0 0 auto; font-size: 9px; letter-spacing: 0.1em; color: var(--success);
}
.pvpadm-award-done-list { margin-top: 10px; }
.pvpadm-award-done-list summary {
  cursor: pointer; font-size: 10px; color: var(--text-dim); letter-spacing: 0.06em;
}

.pvpadm-note {
  margin: 0 0 16px;
  padding: 12px 14px;
  border-left: 3px solid var(--accent);
  border-radius: 0 8px 8px 0;
  background: var(--surface-2);
  font-size: 11.5px;
  line-height: 1.65;
  color: var(--text-dim);
}
.pvpadm-note b { color: var(--text); }
.pvpadm-note code {
  font-size: 10.5px;
  padding: 1px 5px;
  border-radius: 4px;
  background: rgba(255,255,255,0.06);
  color: var(--accent-soft);
}

.pvpadm-row {
  display: grid;
  grid-template-columns: 150px minmax(260px, 1fr) 220px;
  gap: 16px;
  align-items: center;
  padding: 14px;
  margin-bottom: 10px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
}

/* A miniatura do traçado sem nenhum campo ao lado: identifica a pista e deixa evidente
   que a forma não é coisa que se edite aqui. */
.pvpadm-map { text-align: center; }
.pvpadm-map svg { width: 100%; height: auto; display: block; }
.pvpadm-map b { display: block; font-size: 11.5px; margin-top: 4px; }
.pvpadm-map code { font-size: 9px; color: var(--text-dim); }

.pvpadm-fields label {
  display: block;
  font-size: 9.5px;
  letter-spacing: 0.12em;
  color: var(--text-dim);
}
.pvpadm-fields input[type="url"] {
  width: 100%;
  margin-top: 5px;
  padding: 10px 12px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text);
  font-size: 12px;
  font-family: ui-monospace, Menlo, monospace;
}
.pvpadm-fields input[type="url"]:focus { outline: none; border-color: var(--accent); }
.pvpadm-actions { display: flex; align-items: center; gap: 14px; margin-top: 12px; }
.pvpadm-check { display: flex; align-items: center; gap: 7px; letter-spacing: 0.06em; cursor: pointer; }
.pvpadm-check input { accent-color: var(--accent); cursor: pointer; }
.pvpadm-actions .pvp-btn { width: auto; padding: 10px 22px; margin-left: auto; }

.pvpadm-preview {
  height: 92px;
  border-radius: 9px;
  overflow: hidden;
  display: grid;
  place-items: center;
  background: linear-gradient(115deg, #1b1206, #2a1a08 40%, #12100f);
  border: 1px solid var(--border);
}
.pvpadm-preview img { width: 100%; height: 100%; object-fit: cover; }
.pvpadm-noimg, .pvpadm-broken { font-size: 9.5px; color: var(--text-dim); text-align: center; padding: 0 10px; }
.pvpadm-broken { color: var(--danger); }

@media (max-width: 900px) {
  .pvpadm-row { grid-template-columns: 1fr; }
  .pvpadm-map svg { max-width: 200px; margin: 0 auto; }
}

/* ---------- LOADOUT: the button, the chips, and the equip modal ----------
   The rarity ramp is redefined here rather than imported from cards.css: pvp.css must
   render correctly even if the CARDS page never loads, and two files sharing four custom
   properties is cheaper than a load-order dependency between them. */

.pvp-equip-btn {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  padding: 12px 0;
  border: 1px solid var(--accent);
  border-radius: 12px;
  background: linear-gradient(180deg, rgba(233,161,59,0.18), rgba(233,161,59,0.06));
  color: var(--accent);
  font-family: var(--font-display);
  font-size: 12px;
  letter-spacing: 0.14em;
  cursor: pointer;
  overflow: hidden;
  transition: color 0.18s, background 0.18s;
  /* The glow is what makes this read as the thing to press. It breathes rather than
     flashes: a hard blink in a form the player is filling in is an irritation, and this
     button sits next to a wager field they need to be able to concentrate on. */
  animation: equip-glow 2.6s ease-in-out infinite;
}
@keyframes equip-glow {
  0%, 100% { box-shadow: 0 0 0 0 rgba(233,161,59,0); }
  50% { box-shadow: 0 0 22px -4px var(--accent-glow); }
}
.pvp-equip-btn:hover { background: var(--accent); color: #17110a; }
/* A sweep of light across the button, once per cycle. */
.pvp-equip-btn::after {
  content: "";
  position: absolute;
  top: 0;
  left: -60%;
  width: 40%;
  height: 100%;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,0.16), transparent);
  animation: equip-sweep 2.6s ease-in-out infinite;
}
@keyframes equip-sweep {
  0%, 62% { left: -60%; }
  92%, 100% { left: 120%; }
}
/* Nothing fitted yet: brighter, because there is a real reason to open it. */
.pvp-equip-btn.is-empty { background: var(--accent); color: #17110a; }
.pvp-equip-ico { display: inline-flex; width: 15px; height: 15px; }
.pvp-equip-ico svg { width: 100%; height: 100%; }
.pvp-equip-btn em {
  min-width: 17px;
  padding: 1px 5px;
  border-radius: 999px;
  background: var(--accent);
  color: #17110a;
  font-size: 10px;
  font-style: normal;
  font-weight: 700;
}
.pvp-equip-btn:hover em, .pvp-equip-btn.is-empty em { background: #17110a; color: var(--accent); }

/* The chips are a readout, not a control: four pills that answer "am I ready to race" at a
   glance, so the modal only has to be opened when the answer is no. */
.pvp-loadout-chips {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 5px;
  margin-top: 8px;
}
.pvp-chip {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 4px 2px;
  border: 1px solid var(--border);
  border-radius: 7px;
  font-size: 8px;
  letter-spacing: 0.08em;
  color: var(--text-dim);
}
.pvp-chip i {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--border-strong);
}
.pvp-chip.is-on { color: var(--text); border-color: var(--rar, var(--border-strong)); }
.pvp-chip.is-on i { background: var(--rar, var(--accent)); box-shadow: 0 0 6px -1px var(--rar, var(--accent)); }
.pvp-chip.is-common    { --rar: #9a9aa2; }
.pvp-chip.is-rare      { --rar: var(--success); }
.pvp-chip.is-epic      { --rar: var(--neon-purple); }
.pvp-chip.is-legendary { --rar: var(--accent); }

.pvp-loadout-cap {
  margin: 8px 0 0;
  font-size: 10px;
  line-height: 1.5;
  color: var(--text-dim);
}
.pvp-loadout-cap b { color: var(--accent); }
.pvp-loadout-none { padding: 14px 4px; }

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

.pvp-cards-modal { display: none; }
.pvp-cards-modal.is-open {
  display: flex;
  position: fixed;
  inset: 0;
  z-index: 160;
  align-items: center;
  justify-content: center;
  animation: pvp-modal-in 0.2s var(--ease-smooth);
}
@keyframes pvp-modal-in { from { opacity: 0; } to { opacity: 1; } }
.pvp-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(6, 6, 9, 0.82);
  backdrop-filter: blur(5px);
}
.pvp-modal-box {
  position: relative;
  z-index: 2;
  width: min(94vw, 940px);
  max-height: 88vh;
  display: flex;
  flex-direction: column;
  padding: 18px;
  border: 1px solid var(--border-strong);
  border-radius: 18px;
  background: var(--surface);
  box-shadow: 0 30px 80px -20px rgba(0,0,0,0.8);
}
.pvp-modal-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 14px;
}
.pvp-modal-head h3 {
  margin: 0;
  font-family: var(--font-display);
  font-size: 14px;
  letter-spacing: 0.1em;
}
.pvp-modal-head h3 span {
  margin-left: 8px;
  font-family: var(--font-ui);
  font-size: 10px;
  letter-spacing: 0.12em;
  color: var(--text-dim);
}
.pvp-modal-x {
  margin-left: auto;
  width: 28px;
  height: 28px;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: transparent;
  color: var(--text-dim);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}
.pvp-modal-x:hover { color: var(--text); border-color: var(--border-strong); }

.pvp-modal-grid {
  display: grid;
  grid-template-columns: 260px 1fr;
  gap: 18px;
  min-height: 0;
}
@media (max-width: 820px) {
  .pvp-modal-grid { grid-template-columns: 1fr; }
}

/* The bars travel WITH the cards. This is what answers the objection to using a modal at
   all: the feedback is not behind the overlay, it is inside it, with more room than the
   entry form had. */
.pvp-modal-sheet {
  align-self: start;
  padding: 14px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--bg-deep);
}
.pvp-modal-ovr {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 12px;
  font-size: 10px;
  letter-spacing: 0.16em;
  color: var(--text-dim);
}
.pvp-modal-ovr b {
  font-family: var(--font-display);
  font-size: 26px;
  color: var(--accent);
}
.pvp-modal-legend {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 10px 0 0;
  font-size: 9px;
  color: var(--text-dim);
}
.pvp-modal-legend i {
  display: block;
  width: 18px;
  height: 6px;
  border-radius: 3px;
  background: repeating-linear-gradient(115deg, var(--accent-soft) 0 4px, var(--accent) 4px 8px);
}

.pvp-modal-slots { overflow-y: auto; padding-right: 4px; min-height: 0; }

/* ---------- the SELECTED bay ----------
   The answer to "which one did I pick". An orange border on one tile inside a grid of
   thirty is not an answer — it is something you have to go and find. The bay is a fixed
   place at the head of the slot, and the card visibly flies into it. */
.pvp-bay {
  --rar: var(--border-strong);
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 62px;
  margin-bottom: 10px;
  padding: 8px 10px;
  border: 1px dashed var(--border-strong);
  border-radius: 12px;
  background: var(--bg-deep);
  transition: border-color 0.2s var(--ease-smooth), box-shadow 0.2s var(--ease-smooth);
}
.pvp-bay.is-filled {
  border-style: solid;
  border-color: var(--rar);
  box-shadow: inset 0 0 30px -18px var(--rar);
}
.pvp-bay.is-common    { --rar: #9a9aa2; }
.pvp-bay.is-rare      { --rar: var(--success); }
.pvp-bay.is-epic      { --rar: var(--neon-purple); }
.pvp-bay.is-legendary { --rar: var(--accent); }

.pvp-bay-tag {
  position: absolute;
  top: -7px;
  left: 12px;
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--surface);
  color: var(--text-dim);
  font-size: 8px;
  font-weight: 700;
  letter-spacing: 0.18em;
}
.pvp-bay.is-filled .pvp-bay-tag { color: var(--rar); }
.pvp-bay-none { font-size: 10px; letter-spacing: 0.08em; color: var(--text-dim); opacity: 0.7; }

.pvp-bay-card {
  display: flex;
  align-items: center;
  gap: 10px;
  /* Lands as the ghost arrives. */
  animation: bay-land 0.34s var(--ease-smooth);
}
@keyframes bay-land {
  0% { transform: scale(0.9); opacity: 0; }
  60% { transform: scale(1.03); opacity: 1; }
  100% { transform: scale(1); }
}
.pvp-bay-card img,
.pvp-bay-noart {
  width: 56px;
  height: 42px;
  border-radius: 7px;
  object-fit: cover;
  background: var(--surface-2);
}
.pvp-bay-info { display: flex; flex-direction: column; gap: 2px; }
.pvp-bay-info b { font-size: 12px; }
.pvp-bay-info span { font-size: 9px; letter-spacing: 0.06em; color: var(--text-dim); }
.pvp-bay-stats { display: flex; flex-wrap: wrap; gap: 3px; margin-top: 2px; }
.pvp-bay-clear {
  margin-left: auto;
  width: 22px;
  height: 22px;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: transparent;
  color: var(--text-dim);
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
}
.pvp-bay-clear:hover { border-color: var(--danger); color: var(--danger); }

/* The card in flight. Fixed to the viewport so it can cross the scrolling column without
   being clipped by it. */
.pvp-ghost {
  position: fixed !important;
  z-index: 200;
  margin: 0 !important;
  pointer-events: none;
  transition: transform 0.42s var(--ease-smooth), opacity 0.42s var(--ease-smooth);
}
.pvp-mslot { margin-bottom: 16px; }
.pvp-mslot h4 {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 8px;
  font-size: 10px;
  letter-spacing: 0.16em;
  color: var(--text-dim);
}
.pvp-mslot h4 span {
  font-size: 11px;
  letter-spacing: 0.02em;
  color: var(--text);
  text-transform: none;
}
.pvp-mclear {
  margin-left: auto;
  padding: 3px 9px;
  border: 1px solid var(--danger);
  border-radius: 999px;
  background: transparent;
  color: var(--danger);
  font-size: 8px;
  letter-spacing: 0.1em;
  cursor: pointer;
}
.pvp-mclear:hover { background: var(--danger); color: #fff; }
.pvp-mslot-none { padding: 10px 4px; text-align: left; }

.pvp-mcards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(128px, 1fr));
  gap: 8px;
}
.pvp-mcard {
  --rar: var(--border-strong);
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border);
  border-left: 3px solid var(--rar);
  border-radius: 10px;
  background: var(--surface-2);
  overflow: hidden;
  cursor: pointer;
  transition: transform 0.15s var(--ease-smooth), border-color 0.15s;
}
.pvp-mcard:hover { transform: translateY(-2px); border-color: var(--rar); }
.pvp-mcard.is-common    { --rar: #9a9aa2; }
.pvp-mcard.is-rare      { --rar: var(--success); }
.pvp-mcard.is-epic      { --rar: var(--neon-purple); }
.pvp-mcard.is-legendary { --rar: var(--accent); }

.pvp-mcard-art { position: relative; aspect-ratio: 4 / 3; background: var(--bg-deep); }
.pvp-mcard-art img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pvp-mcard-art span { display: block; width: 100%; height: 100%; }
.pvp-mcard-rar {
  position: absolute !important;
  left: 5px;
  bottom: 5px;
  width: auto !important;
  height: auto !important;
  padding: 1px 5px;
  border-radius: 999px;
  background: rgba(0,0,0,0.66);
  color: var(--rar);
  font-size: 7px;
  font-weight: 700;
  letter-spacing: 0.1em;
}
/* A ESTRELA. Fica no canto da arte e nao na linha do nome de proposito: ali ela tem um
   alvo de toque proprio, longe do centro do card, que e onde o dedo cai para EQUIPAR.
   Apagada ela e quase invisivel (e ruido em duzentas cartas); acesa ela e a unica coisa
   dourada no card. */
.pvp-star {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 22px;
  height: 22px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(0,0,0,0.55);
  color: rgba(255,255,255,0.34);
  font-size: 12px;
  line-height: 1;
  cursor: pointer;
  transition: color 0.15s ease, transform 0.15s ease, background 0.15s ease;
}
.pvp-star:hover { color: rgba(255,255,255,0.75); background: rgba(0,0,0,0.75); }
.pvp-star.is-on { color: var(--accent); text-shadow: 0 0 8px rgba(255,138,0,0.55); }
.pvp-star.is-on:hover { transform: scale(1.12); }

/* A BARRA DE FILTRO, entre o cabecalho e as prateleiras. */
.pvp-filterbar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 12px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border);
}
.pvp-fchip {
  padding: 4px 10px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: transparent;
  color: var(--text-dim);
  font-family: var(--font-ui);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.12em;
  cursor: pointer;
  transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}
.pvp-fchip:hover { color: var(--text); border-color: var(--border-strong); }
.pvp-fchip.is-on {
  border-color: var(--accent);
  background: rgba(255,138,0,0.12);
  color: var(--accent);
}
.pvp-fsep { width: 1px; height: 16px; background: var(--border); margin: 0 2px; }
.pvp-fclear {
  margin-left: auto;
  padding: 4px 6px;
  border: 0;
  background: transparent;
  color: var(--text-dim);
  font-size: 9px;
  letter-spacing: 0.08em;
  text-decoration: underline;
  cursor: pointer;
}
.pvp-fclear:hover { color: var(--text); }

/* CARTA PRESA NUMA CORRIDA. Apagada, sem estrela e sem borda de escolha — tudo o que
   sinaliza "disponivel" sai, e sobra o motivo. Nao usa `pointer-events: none`: o cartao
   ainda recebe o clique para poder explicar, porque um elemento morto le como bug. */
.pvp-mcard.is-racing { opacity: 0.45; cursor: default; }
.pvp-mcard.is-racing:hover { border-color: var(--border); transform: none; }
.pvp-mcard.is-racing .pvp-mcard-art { filter: grayscale(0.75); }
.pvp-mcard-lock {
  position: absolute;
  left: 5px;
  right: 5px;
  top: 5px;
  padding: 2px 0;
  border-radius: 4px;
  background: rgba(0,0,0,0.8);
  color: var(--accent);
  font-size: 7px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-align: center;
}

.pvp-mcard-name { padding: 6px 7px 0; font-size: 11px; line-height: 1.2; }
.pvp-mcard-serial { padding: 0 7px; font-size: 8px; color: var(--text-dim); }
.pvp-mcard-stats { display: flex; flex-wrap: wrap; gap: 3px; padding: 4px 7px 6px; }
.pvp-slot-stat {
  padding: 1px 4px;
  border-radius: 4px;
  background: var(--bg-deep);
  font-size: 8px;
  font-weight: 700;
  color: var(--text-dim);
}
.pvp-slot-stat.is-up { color: var(--success); }
.pvp-slot-stat.is-down { color: var(--danger); }
.pvp-slot-stat.is-none { opacity: 0.6; }
/* The chosen tile stays marked as well as flying to the bay: the bay says WHICH, the mark
   says WHERE it came from, and without the second one a scrolled-away grid gives no way to
   tell an owned card from the selected one. */
.pvp-mcard.is-chosen {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent-glow), 0 0 18px -6px var(--accent-glow);
}
.pvp-mcard.is-chosen::after {
  content: "SELECTED";
  display: block;
  padding: 4px 0;
  border-top: 1px solid var(--accent-glow);
  color: var(--accent);
  font-size: 8px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-align: center;
}

.pvp-modal-foot {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}
.pvp-modal-foot .pvp-btn { width: auto; padding-left: 20px; padding-right: 20px; }
.pvp-modal-foot .pvp-btn.is-primary { width: auto; }
.pvp-modal-dirty {
  margin-right: auto;
  font-size: 10px;
  letter-spacing: 0.08em;
  color: var(--text-dim);
}

/* The OVR reacts when the draft changes it. Nothing has been saved yet, so the number is a
   promise — it has to be legible as one. */
.pvp-modal-ovr b.is-bumped { animation: ovr-bump 0.4s var(--ease-smooth); }
@keyframes ovr-bump {
  0% { transform: scale(1); }
  45% { transform: scale(1.16); text-shadow: 0 0 18px var(--accent-glow); }
  100% { transform: scale(1); }
}
.pvp-modal-cap {
  margin: 8px 0 0;
  font-size: 10px;
  line-height: 1.5;
  color: var(--text-dim);
}
.pvp-modal-cap b { color: var(--accent); }

.pvp-mslot h4 span { margin-left: auto; font-size: 9px; color: var(--text-dim); }

/* ==========================================================================
   MOBILE — RANDOM PVP
   ==========================================================================
   O layout ja empilhava em uma coluna a 1100px; o que faltava era o RITMO VERTICAL.
   Medido a 375px, a coluna de entrada tinha 1217px de altura — mais de uma tela e
   meia de formulario antes de a grade aparecer. E a grade e metade do que a pagina
   faz: quem chega para aceitar uma corrida rolava um formulario inteiro primeiro.

   A ordem NAO foi invertida de proposito. Aceitar uma corrida exige um Racerz
   escolhido, e esse seletor mora no formulario — jogar a grade para cima poria o
   botao ACCEPT antes da escolha que ele exige, trocando "rolagem longa" por
   "erro ao tocar", que e pior. O que da para fazer sem mexer em comportamento e
   apertar o formulario ate ele caber.                                          */

@media (max-width: 620px) {
  /* Respiro entre blocos: o desktop separa por espaco porque tem espaco. */
  .pvp-block { margin-bottom: 16px; }
  .pvp-panel { padding: 14px 12px; }
  .pvp-col-entry .pvp-panel { padding: 14px 12px; }

  /* O retrato NAO e reduzido aqui, e vale registrar por que: a legenda (#307 / OVR /
     LV) fica POR CIMA da arte, e foi dimensionada para os 152px da coluna. A 104px
     ela transborda o retrato e se sobrepoe as barras de atributo — trocar 80px de
     altura por uma legenda quebrada e um mau negocio. Encolher o retrato exigiria
     encolher a legenda junto, o que e uma decisao de arte, nao de responsividade. */

  /* As quatro barras de atributo e as tres linhas de gasolina sao o grosso da
     altura do formulario. Menos padding em cada uma, quatro vezes e tres vezes,
     e o que tira a maior parte dos 1200px. */
  .pvp-statrow { gap: 8px; padding: 4px 0; }
  .pvp-fuel-row { padding: 9px 10px; gap: 9px; }
  .pvp-fuel-row + .pvp-fuel-row { margin-top: 7px; }

  /* Comprar gasolina e uma acao de dedo, e tinha 30px de altura. */
  .pvp-buy { min-height: 40px; padding: 9px 14px; }

  /* Os campos de aposta e de carteira: 16px impede o zoom automatico do Safari ao
     focar, que desalinha a pagina e nao volta sozinho. */
  .pvp-panel input, .pvp-panel select { font-size: 16px; min-height: 44px; }

  /* Botoes de acao dos cards da grade ocupando a linha inteira — a 375px o card ja
     empilha, e um botao de 60px de largura no canto e um alvo perdido. */
  .pvp-entry-card .pvp-btn { width: 100%; min-height: 42px; }
  .pvp-btn.is-live, .pvp-btn.is-accept { min-height: 42px; }

  /* O card de entrada da grade: a arte de 72px rouba largura de tudo o que importa
     ler (quem e, quanto vale). */
  .pvp-entry-card { grid-template-columns: 56px 1fr auto; gap: 11px; padding: 11px; }
  .pvp-entry-art { width: 56px; height: 56px; }
  .pvp-entry-stake b { font-size: 19px; }

  /* Rotulos que caiam abaixo do legivel em tela pequena. */
  .pvp-entry-tag { font-size: 9px; }
  .pvp-h-note { font-size: 10px; }
  .pvp-block-note { font-size: 11px; }

  /* Linhas de resultado clicaveis: alvo de dedo, nao de mouse. */
  .pvp-results li, .pvp-mine-row { padding: 14px 12px; }
}

/* O RETRATO DE UM RACERZ SEM ARTE.
   ==========================================================================
   Bug de mobile que existia antes desta secao e so aparece quando a NFT nao tem
   imagem — o que acontece de verdade: getNftCard devolve null quando a Alchemy
   falha, e o front cai para <div class="pvp-hero-img sim-noimg">#307</div>.

   Abaixo de 760px o heroi empilha e a figure recebe `max-width: 180px`, mas nada
   lhe da LARGURA. Com um <img> dentro isso nao importa, porque a imagem tem
   tamanho proprio; com a div de fallback, `width: 100%` de um bloco dentro de uma
   figure que se auto-dimensiona nao resolve para nada, e a figure encolhia para a
   largura do texto: 56px. A legenda, dimensionada para 152px, transbordava por
   cima das barras de atributo.

   Medido a 375px: 56x65 com legenda vazando -> 180x189, contida.               */

@media (max-width: 760px) {
  .pvp-hero-art { width: 100%; }
  /* O placeholder passa a ocupar o mesmo quadrado que a imagem ocuparia, em vez de
     ser uma linha de texto solta. */
  .pvp-hero-img.sim-noimg {
    aspect-ratio: 1;
    display: grid;
    place-items: center;
  }
}

/* ==========================================================================
   VOLTAR PARA A GRADE
   ==========================================================================
   O unico jeito de sair do palco de uma corrida, e ele era um .pvp-btn.is-ghost:
   fundo transparente, borda a 16% de branco e texto em --text-dim. Ao lado de um
   "LIVE RACE" laranja e de carros piscando, cinza sobre preto nao e discreto, e
   invisivel — e ficar preso numa tela sem achar a saida e a pior coisa que uma
   tela pode fazer.

   Vale no desktop TAMBEM, a pedido: o problema nao e de tamanho de tela, e de
   contraste.

   O brilho e a opacidade de um ::after, e nao a box-shadow do proprio botao, de
   proposito: opacidade e composta na GPU, e esta pagina roda um requestAnimationFrame
   de corrida a 60fps ao lado. Animar box-shadow direto poria trabalho de pintura no
   mesmo quadro que desenha os carros.                                          */

#pvp-back {
  position: relative;
  border-color: var(--accent);
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  white-space: nowrap;
}
#pvp-back:hover:not(:disabled) {
  background: var(--accent);
  color: #14100a;
  filter: none;
}
#pvp-back::after {
  content: "";
  position: absolute;
  inset: -2px;
  border-radius: inherit;
  box-shadow: 0 0 14px 2px var(--accent-glow);
  opacity: 0;
  pointer-events: none;
  animation: pvp-back-breathe 2.6s var(--ease-smooth) infinite;
}
@keyframes pvp-back-breathe {
  0%, 100% { opacity: 0; }
  50%      { opacity: 1; }
}
/* Uma pulsacao perpetua e cansativa para quem pediu para o sistema parar de se mexer.
   O contraste — que e o que resolve o problema — fica; so o brilho para. */
@media (prefers-reduced-motion: reduce) {
  #pvp-back::after { animation: none; }
}

@media (max-width: 620px) {
  /* Sem wrap, "← BACK TO GRID" era espremido em 67px e quebrava em QUATRO linhas
     ("←/BACK/TO/GRID") entre o titulo e o relogio. Uma linha propria, largura
     inteira e alvo de dedo. */
  .pvp-stage-head { flex-wrap: wrap; }
  #pvp-back {
    order: -1;
    width: 100%;
    min-height: 44px;
  }
}

/* ============================================================
   TOP PILOTS — pódio + tabela do ranking de PvP
   Três degraus sempre desenhados (mesmo faltando gente: o vão vazio é o convite), a
   tabela do quarto em diante, e a linha do próprio piloto quando ele está fora dela.
   Toda a animação é CSS com atraso por índice — nenhum timer, nenhuma medida em JS.
   ============================================================ */
.pvp-podium {
  display: grid; grid-template-columns: repeat(3, 1fr);
  align-items: end; gap: 0;   /* zero: os três degraus formam UM pódio, não três caixas */
  margin: 6px 0 22px;
}
.pvp-plinth { display: flex; flex-direction: column; align-items: center; text-align: center; min-width: 0; }

/* A arte do carro que subiu ao pódio. */
.pp-art {
  width: 72px; height: 72px; border-radius: 14px; overflow: hidden;
  background: rgba(255,255,255,0.04); border: 1px solid var(--border);
  display: grid; place-items: center; margin-bottom: 8px;
  animation: podRise 460ms var(--ease-smooth) both;
  animation-delay: calc(var(--d, 0) * 1ms + 120ms);
}
.pp-art img { width: 100%; height: 100%; object-fit: cover; }
.pp-art.is-ghost { border-style: dashed; }
.pp-noart { font-family: var(--font-display); font-size: 12px; color: var(--text-dim); }
.is-p1 .pp-art {
  width: 92px; height: 92px; border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent), 0 0 22px var(--accent-glow);
}
/* Só o primeiro lugar respira. Três brilhos pulsando ao mesmo tempo viram um letreiro. */
.is-p1 .pp-art { animation: podRise 460ms var(--ease-smooth) both, podGlow 3s ease-in-out 900ms infinite; }

.pp-name {
  font-family: var(--font-display); font-size: 12.5px; font-weight: 700; color: var(--text);
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  animation: podFade 380ms ease both; animation-delay: calc(var(--d, 0) * 1ms + 240ms);
}
.is-p1 .pp-name { font-size: 14.5px; color: var(--accent); }
.pp-sub {
  font-size: 10.5px; color: var(--text-dim); margin-top: 2px;
  animation: podFade 380ms ease both; animation-delay: calc(var(--d, 0) * 1ms + 300ms);
}
.pp-you {
  margin-left: 6px; padding: 1px 5px; border-radius: 4px; vertical-align: middle;
  background: var(--accent); color: #14100c;
  font-family: var(--font-ui); font-size: 8px; font-weight: 800; letter-spacing: 0.08em;
}

/* O degrau. Cresce de baixo para cima — é a peça que faz a tela parecer um pódio. */
.pp-base {
  width: 100%; margin-top: 10px; padding: 10px 6px 8px; border-radius: 10px 10px 0 0;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  background: linear-gradient(180deg, rgba(255,255,255,0.07), rgba(255,255,255,0.02));
  border: 1px solid var(--border); border-bottom: none;
  transform-origin: bottom;
  animation: plinthUp 520ms var(--ease-smooth) both;
  animation-delay: calc(var(--d, 0) * 1ms);
}
/* A diferença de altura é o que conta a história: 1º bem acima, 3º quase no chão. Os
   cantos arredondados ficam só nas bordas EXTERNAS, para os três blocos lerem como uma
   peça só; as bordas que se encostam somem para não virar linha dupla. */
.is-p1 .pp-base {
  height: 112px; border-radius: 12px 12px 0 0;
  background: linear-gradient(180deg, rgba(233,161,59,0.22), rgba(233,161,59,0.05));
  border-color: var(--accent-glow);
}
.is-p2 .pp-base { height: 86px; border-radius: 12px 0 0 0; border-right: none; }
.is-p3 .pp-base { height: 52px; border-radius: 0 12px 0 0; border-left: none; }
.is-empty .pp-base { border-style: dashed; background: rgba(255,255,255,0.02); }
.is-empty .pp-name, .is-empty .pp-sub { color: var(--text-dim); opacity: 0.6; }

.pp-place { font-family: var(--font-display); font-weight: 800; font-size: 20px; color: var(--text); line-height: 1; }
.is-p1 .pp-place { font-size: 26px; color: var(--accent); }
.pp-net { font-size: 10px; color: var(--success); letter-spacing: 0.04em; }
.pp-net.is-down { color: var(--danger); }

/* ---- do quarto lugar em diante ---- */
.pvp-rank-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.pvp-rank-row {
  display: grid; align-items: center; gap: 10px;
  grid-template-columns: 26px 28px minmax(0, 1fr) 64px 70px 78px;
  padding: 8px 10px; border-radius: 10px;
  background: rgba(255,255,255,0.03); border: 1px solid var(--border);
  animation: rowIn 320ms var(--ease-smooth) both;
  animation-delay: calc(var(--i, 0) * 45ms + 260ms);
}
.pvp-rank-row.is-me { border-color: var(--accent); background: rgba(233,161,59,0.10); }
.pr-pos { font-family: var(--font-display); font-weight: 700; font-size: 12px; color: var(--text-dim); text-align: center; }
.pvp-rank-row.is-me .pr-pos { color: var(--accent); }
.pr-art { width: 28px; height: 28px; border-radius: 7px; overflow: hidden; background: rgba(255,255,255,0.05); }
.pr-art img { width: 100%; height: 100%; object-fit: cover; }
.pr-name { font-size: 12.5px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pr-wl { font-size: 11px; color: var(--text-dim); }
.pr-wl b { color: var(--text); }
.pr-wl i { font-style: normal; }
/* Barra de aproveitamento: a coluna que deixa a tabela ser lida de relance. */
.pr-bar { height: 5px; border-radius: 99px; background: rgba(255,255,255,0.08); overflow: hidden; }
.pr-bar b { display: block; height: 100%; border-radius: 99px; background: linear-gradient(90deg, var(--accent-soft), var(--accent)); }
.pr-net { font-size: 11.5px; text-align: right; color: var(--success); font-family: var(--font-display); }
.pr-net.is-down { color: var(--danger); }

.pvp-rank-mine { margin-top: 14px; padding-top: 12px; border-top: 1px dashed var(--border); }
.pvp-rank-mine-h { display: block; font-size: 9px; letter-spacing: 0.16em; color: var(--text-dim); margin-bottom: 8px; }
.pvp-rank-foot { margin-top: 14px; font-size: 10.5px; color: var(--text-dim); text-align: center; }

/* Esqueleto da primeira carga. */
.pvp-rank-skel { display: flex; flex-direction: column; gap: 8px; }
.pvp-rank-skel span {
  height: 42px; border-radius: 10px; background: rgba(255,255,255,0.05);
  animation: skelPulse 1.2s ease-in-out infinite;
}
.pvp-rank-skel span:nth-child(2) { animation-delay: 90ms; }
.pvp-rank-skel span:nth-child(3) { animation-delay: 180ms; }
.pvp-rank-skel span:nth-child(4) { animation-delay: 270ms; }
.pvp-rank-skel span:nth-child(5) { animation-delay: 360ms; }
.pvp-rank-skel span:nth-child(6) { animation-delay: 450ms; }

@keyframes plinthUp { from { transform: scaleY(0.15); opacity: 0; } to { transform: scaleY(1); opacity: 1; } }
@keyframes podRise { from { transform: translateY(14px); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes podFade { from { opacity: 0; } to { opacity: 1; } }
@keyframes podGlow {
  0%, 100% { box-shadow: 0 0 0 1px var(--accent), 0 0 14px var(--accent-glow); }
  50% { box-shadow: 0 0 0 1px var(--accent), 0 0 30px 3px var(--accent-glow); }
}
@keyframes rowIn { from { transform: translateY(8px); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes skelPulse { 0%, 100% { opacity: 0.45; } 50% { opacity: 0.9; } }

@media (max-width: 720px) {
  /* Empilhado o pódio perde o sentido de altura: vira 1º, 2º, 3º em ordem de leitura. */
  .pvp-podium { grid-template-columns: 1fr; gap: 14px; }
  .pvp-plinth.is-p1 { order: 1; }
  .pvp-plinth.is-p2 { order: 2; }
  .pvp-plinth.is-p3 { order: 3; }
  .is-p1 .pp-base, .is-p2 .pp-base, .is-p3 .pp-base {
    height: auto; padding: 8px; flex-direction: row; gap: 10px;
    border-radius: 10px; border: 1px solid var(--border);
  }
  .is-p1 .pp-base { border-color: var(--accent-glow); }
  .pvp-rank-row { grid-template-columns: 22px 26px minmax(0, 1fr) 58px 66px; }
  .pvp-rank-row .pr-bar { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .pp-art, .pp-name, .pp-sub, .pp-base, .pvp-rank-row, .pvp-rank-skel span { animation: none; }
}

/* ============================================================
   GAVETAS DO FORMULÁRIO (FUEL / CIRCUIT)
   Uma de cada vez: abrir uma fecha a outra. Fechadas, ocupam uma linha e mostram no
   cabeçalho o que está escolhido — o formulário inteiro cabe sem rolagem, que é o que
   mantém WAGER e PUT IT ON THE GRID sempre à vista.
   ============================================================ */
.pvp-acc {
  border: 1px solid var(--border); border-radius: 12px;
  background: rgba(255,255,255,0.02);
  margin-bottom: 10px; overflow: hidden;
}
.pvp-acc.is-open { border-color: var(--border-strong); background: rgba(255,255,255,0.035); }

.pvp-acc-head {
  width: 100%; display: flex; align-items: center; gap: 10px;
  padding: 12px 13px; cursor: pointer;
  background: none; border: none; text-align: left; color: var(--text);
}
.pvp-acc-title {
  font-family: var(--font-display); font-size: 11px; letter-spacing: 0.14em;
  color: var(--text); flex: 0 0 auto;
}
.pvp-acc.is-open .pvp-acc-title { color: var(--accent); }
/* O resumo é o que faz a gaveta fechada continuar informando. Corta com reticências em
   vez de quebrar linha: o cabeçalho tem de ter altura fixa. */
.pvp-acc-sum {
  flex: 1 1 auto; min-width: 0;
  display: flex; align-items: center; justify-content: flex-end; gap: 5px;
  font-size: 11px; color: var(--text-dim);
}
/* O <i> e quem corta com reticencias — nao o container. Deixar o flex pai cortar levaria o
   check junto, e um "ja escolhido" que some quando o texto e comprido nao serve para nada. */
.pvp-acc-sum i {
  min-width: 0; font-style: normal;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pvp-acc-check { width: 12px; height: 12px; flex: 0 0 auto; color: var(--success); }
.pvp-acc.is-done .pvp-acc-sum i { color: var(--text); }
.pvp-acc-chev {
  width: 15px; height: 15px; flex: 0 0 auto; color: var(--text-dim);
  transition: transform 260ms var(--ease-smooth), color 200ms;
}
.pvp-acc.is-open .pvp-acc-chev { transform: rotate(180deg); color: var(--accent); }
.pvp-acc-head:hover .pvp-acc-chev { color: var(--text); }

/* A altura anima por grid-template-rows (0fr → 1fr): ao contrário do max-height, não
   exige um número mágico maior que o conteúdo — que é justamente o que faz uma gaveta
   "pular" no fim da animação quando o conteúdo cresce. */
.pvp-acc-body {
  display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows 300ms var(--ease-smooth);
}
.pvp-acc.is-open .pvp-acc-body { grid-template-rows: 1fr; }
.pvp-acc-inner {
  min-height: 0; overflow: hidden;
  padding: 0 13px; opacity: 0;
  transition: opacity 200ms var(--ease-smooth), padding 300ms var(--ease-smooth);
}
.pvp-acc.is-open .pvp-acc-inner {
  padding: 2px 13px 13px; opacity: 1;
  /* Teto de altura com rolagem própria: uma gaveta muito alta empurraria o botão de criar
     para fora da tela, que é exatamente o que estamos consertando. */
  max-height: min(320px, 34vh); overflow-y: auto;
}
.pvp-acc-note { margin: 8px 0 0; font-size: 9px; color: var(--text-dim); letter-spacing: 0.06em; text-align: right; }

@media (prefers-reduced-motion: reduce) {
  .pvp-acc-body, .pvp-acc-inner, .pvp-acc-chev { transition: none; }
}

/* ============================================================
   PILOTS no PvP
   ------------------------------------------------------------
   Aqui a marcação não é enfeite: um Pilot corre com a ficha em 150 contra o teto de 100
   do resto da grade, e o adversário precisa VER isso antes de aceitar uma aposta em
   $CAZH. As cores vêm de --pilot-* (aba de admin de Pilots, via main.js).
   ============================================================ */
.pvp-rcard.is-pilot,
.pvp-swap-item.is-pilot {
  border-color: color-mix(in srgb, var(--pilot-glow) 65%, transparent);
  box-shadow: 0 0 20px -6px color-mix(in srgb, var(--pilot-glow) 90%, transparent);
}
.pvp-rcard.is-pilot .pvp-rcard-top b { color: var(--pilot-glow); }

.pvp-hero.is-pilot .pvp-hero-art {
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--pilot-glow) 60%, transparent),
              0 0 34px -8px color-mix(in srgb, var(--pilot-glow) 95%, transparent);
}
.pvp-hero.is-pilot .pvp-hero-id {
  background: linear-gradient(92deg, #fff, var(--pilot-glow) 60%, var(--pilot-glow-2));
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
}

.pvp-slot.is-pilot {
  box-shadow: 0 0 0 1px var(--pilot-glow), 0 0 18px -5px var(--pilot-glow);
}

/* O selo "1/1" ao lado do número, no card de pré-corrida. Pequeno de propósito: ali o
   que decide é a barra de OVR logo ao lado, e o selo só responde "por que tão alto?". */
.pvp-pilot-tag {
  display: inline-block; vertical-align: 1px;
  padding: 1px 5px; margin-left: 4px; border-radius: 5px;
  font-size: 9px; font-weight: 800; letter-spacing: 0.5px; color: #12000c;
  background: linear-gradient(135deg, #fff, var(--pilot-glow) 55%, var(--pilot-glow-2));
  box-shadow: 0 0 10px -2px color-mix(in srgb, var(--pilot-glow) 80%, transparent);
}

/* OGs (Racerz 1/1) no PvP: mesma marcação dos Pilots, nas cores do tier dos OGs. */
.pvp-rcard.is-og, .pvp-swap-item.is-og { border-color: color-mix(in srgb, var(--pilot-glow) 65%, transparent);
  box-shadow: 0 0 20px -6px color-mix(in srgb, var(--pilot-glow) 90%, transparent); }
.pvp-rcard.is-og .pvp-rcard-top b { color: var(--pilot-glow); }
.pvp-hero.is-og .pvp-hero-art { box-shadow: 0 0 0 1px color-mix(in srgb, var(--pilot-glow) 60%, transparent),
  0 0 34px -8px color-mix(in srgb, var(--pilot-glow) 95%, transparent); }
.pvp-hero.is-og .pvp-hero-id { background: linear-gradient(92deg, #fff, var(--pilot-glow) 60%, var(--pilot-glow-2));
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; }
.pvp-slot.is-og { box-shadow: 0 0 0 1px var(--pilot-glow), 0 0 18px -5px var(--pilot-glow); }

/* A marca dos 100 na barra do palco — o teto sob o qual todo Racerz corre. Só aparece
   numa ficha que passa dele (Pilot ou OG); sem ela, uma barra de 200 é só uma barra
   cheia e a diferença some justamente na tela onde o rival decide se aceita. */
.pvp-stat-bar { position: relative; }
.pvp-stat-ceiling {
  position: absolute; top: 0; bottom: 0; width: 1px;
  background: rgba(255,255,255,0.45); pointer-events: none; z-index: 2;
}
