/* Ajustes específicos do lfp que não têm equivalente pronto no Halfmoon (ver
   web/public/vendor/halfmoon/) — tudo mais (cards, botões, campos, tabelas, alertas, nav) usa as
   classes do framework diretamente, sem CSS autoral. */

.acp-main {
  max-width: 480px;
  margin: 2rem auto;
  padding: 0 1rem;
}

.acp-main.wide {
  max-width: 960px;
}

/* ---------------------------------------------------------------------------------------------
   Termos de Serviço / Política de Privacidade (ver web/views/legal.js) — texto corrido longo,
   por isso ganham sua própria largura de leitura confortável dentro do `.acp-main.wide` que os
   envolve (ver `wide: true` nas rotas /terms e /privacy em web/app.js), em vez de esticar até os
   960px inteiros.
   --------------------------------------------------------------------------------------------- */
.acp-legal {
  max-width: 720px;
  margin: 0 auto;
}

.acp-legal-header {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.acp-legal-header h1 {
  margin: 0;
}

.acp-legal-notice {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 1.25rem 0 1.5rem;
  padding: 0.65rem 0.9rem;
  background: hsla(var(--bs-primary-hsl), 0.08);
  border: 1px solid hsla(var(--bs-primary-hsl), 0.25);
  border-radius: var(--acp-radius-md);
  color: var(--bs-secondary-color);
  font-size: 0.825rem;
}

.acp-legal-notice svg {
  flex-shrink: 0;
  width: 1.1rem;
  height: 1.1rem;
  color: var(--bs-primary);
}

.acp-legal h2 {
  margin-top: 2rem;
  margin-bottom: 0.6rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--acp-border-color);
  font-size: 1rem;
  font-weight: 600;
  color: var(--bs-body-color);
}

.acp-legal h2:first-of-type {
  margin-top: 1.5rem;
  padding-top: 0;
  border-top: none;
}

.acp-legal p,
.acp-legal li {
  line-height: 1.65;
}

.acp-legal ul {
  padding-left: 1.25rem;
}

.acp-legal-footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.25rem;
  margin-top: 2rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--acp-border-color);
  font-size: 0.9rem;
}

/* ---------------------------------------------------------------------------------------------
   Shell de altura cheia (admin/jogador autenticados): a sidebar ocupa toda a altura da viewport
   abaixo do header (ver imagem de referência do reskin), e sidebar/conteúdo rolam de forma
   independente um do outro. Ativado via `.acp-has-shell` no <body> (ver renderLayout em
   web/views/layout.js), que detecta a marca `.acp-shell` no corpo da página — produzida por
   renderAdminShell/renderPlayerShell — sem precisar passar um flag por toda a cadeia de handlers
   de web/app.js. Páginas sem sidebar (login, assistente de instalação) não ganham essa classe e
   continuam com o `.acp-main` centralizado de sempre.
   --------------------------------------------------------------------------------------------- */
body.acp-has-shell {
  height: 100vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

body.acp-has-shell .navbar {
  flex-shrink: 0;
}

body.acp-has-shell .acp-main {
  flex: 1 1 auto;
  min-height: 0;
  max-width: none;
  width: 100%;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}

body.acp-has-shell .acp-main > .alert {
  flex-shrink: 0;
  margin: 1rem 1rem 0;
}

.acp-shell {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
}

.acp-shell-content {
  flex: 1 1 auto;
  min-width: 0;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.acp-shell-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 1.5rem;
}

/* Rodapé institucional das telas com sidebar. Dois blocos: a marca fixa do produto (Aden
   Control Panel, com troca de logo dourada/prateada conforme o tema — não depende da
   identidade visual configurada pelo operador) à esquerda, e os links institucionais do
   PRÓPRIO servidor (Termos/Privacidade, ver web/views/legal.js) à direita — sem eles a logo
   fica sozinha numa barra vazia. */
.acp-panel-footer {
  flex: 0 0 auto;
  min-height: 4rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.75rem 1.5rem;
  padding: 0.75rem 1.5rem;
  background: var(--acp-surface-bg);
  color: var(--bs-secondary-color);
}

.acp-panel-footer-logo-link {
  display: inline-flex;
  flex-shrink: 0;
  opacity: 0.78;
  transition: opacity 160ms ease, transform 160ms ease;
}

.acp-panel-footer-logo-link:hover {
  opacity: 1;
  transform: translateY(-1px);
}

.acp-panel-footer-logo {
  display: block;
  width: min(150px, 36vw);
  height: auto;
}

/* Troca dourada/prateada da marca Aden Control Panel conforme o tema — compartilhada pelo
   logo do rodapé (ver acima) e pelo logo da tela de autenticação (ver .acp-auth-brand-logo em
   web/views/authLayout.js), os dois pontos onde a marca do PRODUTO aparece fixa, independente da
   identidade configurada pelo operador. */
:root[data-bs-theme='dark'] .acp-logo-swap-light,
:root[data-bs-theme='light'] .acp-logo-swap-dark {
  display: none;
}

.acp-panel-footer-links {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 1rem;
  font-size: 0.75rem;
  white-space: nowrap;
}

.acp-panel-footer-link {
  color: var(--bs-secondary-color);
  text-decoration: none;
  transition: color 160ms ease;
}

.acp-panel-footer-link:hover {
  color: var(--bs-primary);
}

/* Botão hamburguer do header (ver renderSidebarToggle em web/views/layout.js) — só existe no
   HTML quando a página tem sidebar, mas só aparece visualmente abaixo do breakpoint mobile (no
   desktop a sidebar já fica sempre visível, não precisa de botão pra abrir). */
.acp-sidebar-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  flex-shrink: 0;
  margin-right: 0.75rem;
  border: 1px solid var(--bs-border-color);
  border-radius: var(--acp-radius-md);
  background: transparent;
  color: var(--bs-body-color);
  cursor: pointer;
}

.acp-sidebar-toggle svg {
  width: 1.15rem;
  height: 1.15rem;
}

/* Breadcrumb "Seção / Página atual" fixo no topo da coluna de conteúdo (ver renderBreadcrumb em
   web/views/icons.js) — fica visível enquanto só o conteúdo abaixo rola. */
.acp-breadcrumb {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-shrink: 0;
  padding: 0.85rem 1.5rem;
  border-bottom: 1px solid var(--bs-border-color);
  font-size: 0.82rem;
}

.acp-breadcrumb-sep {
  color: var(--bs-secondary-color);
  opacity: 0.6;
}

.acp-breadcrumb-section {
  color: var(--bs-secondary-color);
}

.acp-breadcrumb-current {
  color: var(--bs-body-color);
  font-weight: 500;
}

/* Saldo no header (ver renderHeaderBalance em web/views/layout.js) — sempre visível pro jogador
   logado, em qualquer tela (login/e-mail já aparecem no topo da sidebar, ver .acp-sidebar-user). */
.acp-header-balance {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  height: 2.1rem;
  padding: 0 0.65rem;
  border-radius: var(--acp-radius-md);
  background: hsla(var(--bs-primary-hsl), 0.12);
  border: 1px solid hsla(var(--bs-primary-hsl), 0.3);
  color: var(--bs-primary);
  font-weight: 600;
  font-size: 0.85rem;
  text-decoration: none;
  white-space: nowrap;
}

.acp-header-balance svg {
  width: 1rem;
  height: 1rem;
}

.acp-header-balance:hover {
  background: hsla(var(--bs-primary-hsl), 0.2);
  color: var(--bs-primary);
}

/* Ícone do globo no seletor de idioma (header e, no mobile, dentro do drawer — ver
   renderLanguageSwitcher/renderSidebarLanguageSwitcher em web/views/layout.js). Sem essa regra o
   SVG cai no tamanho intrínseco padrão (300x150) por não ter width/height próprios: dentro do
   botão flex do header ele acaba encolhido a 0x0 (sem espaço sobrando), e dentro do drawer (bem
   mais largo) ele estica gigante — os dois sintomas do mesmo problema. */
.acp-lang-switcher svg {
  width: 1rem;
  height: 1rem;
  flex-shrink: 0;
}

/* Mesma altura do saldo (.acp-header-balance) e do grupo sol/lua (.acp-theme-switch) ao lado —
   sem isso o botão herda a altura do `.btn-sm` do Bootstrap, mais baixa que os outros dois.
   Só no header: a instância de dentro do drawer mobile (.acp-sidebar-lang) já tem seu próprio
   tamanho, maior, definido mais abaixo. */
header .acp-lang-switcher .dropdown-toggle {
  height: 2.1rem;
}

/* Grupo segmentado sol/lua do tema (ver renderThemeSwitch/THEME_TOGGLE_SCRIPT em
   web/views/layout.js) — cada ícone seta o tema direto, com o ativo destacado. */
.acp-theme-switch {
  display: inline-flex;
  height: 2.1rem;
  border: 1px solid var(--bs-border-color);
  border-radius: var(--acp-radius-md);
  overflow: hidden;
}

.acp-theme-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.1rem;
  height: 100%;
  border: none;
  background: transparent;
  color: var(--bs-secondary-color);
  cursor: pointer;
}

.acp-theme-btn:not(:last-child) {
  border-right: 1px solid var(--bs-border-color);
}

.acp-theme-btn svg {
  width: 1rem;
  height: 1rem;
}

.acp-theme-btn.active {
  background: hsla(var(--bs-primary-hsl), 0.14);
  color: var(--bs-primary);
}

.acp-logo {
  max-height: 40px;
}

/* ---------------------------------------------------------------------------------------------
   Reskin (aproxima o visual de componentes shadcn/ui: superfícies planas, bordas finas sem glow,
   cantos rounded-md/lg, tipografia sem serifa). Usa só variáveis que a própria Halfmoon já expõe
   (--bs-primary-hsl vem como "H, S%, L%" — dá pra montar hsla(var(--bs-primary-hsl), alpha)
   direto) — nada de cor fixa em hex aqui, então continua respeitando o primaryColor escolhido em
   /admin/settings/theme; só a cor de destaque (dourado, por padrão) sobrevive da pegada RPG
   anterior, sem glow/serifada/uppercase.
   --------------------------------------------------------------------------------------------- */
:root {
  --acp-border-width: 0.5px;
  --acp-radius-lg: 0.375rem;
  --acp-radius-md: 0.25rem;
  --acp-radius-sm: 0.1875rem;
}

.card {
  border-radius: var(--acp-radius-lg) !important;
  border-color: var(--acp-border-color) !important;
  box-shadow: none !important;
  background-color: var(--acp-surface-raised-bg) !important;
}

.btn {
  border-radius: var(--acp-radius-md) !important;
  font-weight: 500;
}

/* Marca (logo + nome do site) — cabeçalho e topo da sidebar admin */
.acp-brand {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
}

.acp-brand-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  flex-shrink: 0;
  border-radius: var(--acp-radius-md);
  background: hsla(var(--bs-primary-hsl), 0.12);
  border: 1px solid hsla(var(--bs-primary-hsl), 0.3);
  color: var(--bs-primary);
  font-weight: 600;
  overflow: hidden;
}

.acp-brand-mark img {
  max-width: 100%;
  max-height: 100%;
}

.acp-brand-word {
  font-family: var(--acp-display-font);
  font-weight: 700;
  font-size: 1.05rem;
  letter-spacing: 0.03em;
  color: var(--bs-primary);
  white-space: nowrap;
}

/* Selo de ícone reaproveitado pelos stat-tiles e pelos cards de pacote/serviço */
.acp-icon-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  flex-shrink: 0;
  border-radius: var(--acp-radius-md);
  background: var(--acp-surface-hover-bg);
  border: 1px solid var(--acp-border-color);
  color: var(--bs-primary);
}

.acp-icon-badge svg {
  width: 1.25rem;
  height: 1.25rem;
}

/* Selo de status (ex.: pedido pago/pendente, notícia publicada/rascunho) — ponto colorido +
   rótulo, mesmo padrão do badge "Active workflow" do projeto de referência do reskin. Cor via
   modificador (.acp-badge-success/-warning/-danger/-muted); sem modificador cai no primary. */
.acp-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.3rem 0.65rem;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  white-space: nowrap;
  background: hsla(var(--bs-primary-hsl), 0.14);
  color: var(--bs-primary);
  border: 1px solid hsla(var(--bs-primary-hsl), 0.3);
}

.acp-badge::before {
  content: '';
  width: 0.4rem;
  height: 0.4rem;
  border-radius: 50%;
  background: currentColor;
  flex-shrink: 0;
}

.acp-badge-success { background: hsla(var(--bs-green-hsl), 0.14); color: var(--bs-green); border-color: hsla(var(--bs-green-hsl), 0.3); }
.acp-badge-warning { background: hsla(var(--bs-yellow-hsl), 0.16); color: var(--bs-yellow); border-color: hsla(var(--bs-yellow-hsl), 0.32); }
.acp-badge-danger { background: hsla(var(--bs-red-hsl), 0.14); color: var(--bs-red); border-color: hsla(var(--bs-red-hsl), 0.3); }
.acp-badge-muted { background: var(--acp-surface-hover-bg); color: var(--bs-secondary-color); border-color: var(--bs-border-color); }

/* Tiles de estatística — dashboard do jogador e visão geral do admin */
.acp-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-bottom: 1.25rem;
}

.acp-stat {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  flex: 1 1 180px;
  padding: 0.75rem 1rem;
  border-radius: var(--acp-radius-md);
  border: 1px solid var(--acp-border-color);
  background: var(--acp-surface-raised-bg);
}

.acp-stat-label {
  margin: 0;
  font-size: 0.8rem;
  color: var(--bs-secondary-color);
}

.acp-stat-value {
  margin: 0;
  font-size: 1.25rem;
  font-weight: 700;
  line-height: 1.2;
}

/* Cards e grid de visão geral (estilo shadcn) */
.acp-metrics-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1rem;
}

.acp-metric-card {
  background-color: var(--acp-surface-raised-bg) !important;
  border: 1px solid var(--acp-border-color) !important;
  border-radius: var(--acp-radius-lg) !important;
  padding: 1.25rem 1.25rem;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.acp-metric-card:hover {
  border-color: hsla(var(--bs-primary-hsl), 0.35) !important;
  box-shadow: none !important;
}

.acp-metric-label {
  font-size: 0.825rem;
  font-weight: 500;
  color: var(--bs-secondary-color);
}

.acp-metric-value {
  font-size: 1.75rem;
  font-weight: 700;
  line-height: 1.2;
  color: var(--bs-body-color);
  letter-spacing: -0.02em;
  margin: 0.25rem 0 0.35rem;
}

.acp-metric-sub {
  font-size: 0.775rem;
  color: var(--bs-secondary-color);
}

.acp-metric-icon .acp-icon-badge {
  width: 2.25rem;
  height: 2.25rem;
}

/* Tabela limpa (estilo shadcn) */
.acp-clean-table {
  border-collapse: separate;
  border-spacing: 0;
  width: 100%;
  margin-bottom: 0;
}

.acp-clean-table th {
  border-top: none;
  border-left: none;
  border-right: none;
  border-bottom: 1px solid var(--bs-border-color);
  padding: 0.75rem 1rem;
  background: transparent;
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  font-weight: 600;
}

.acp-clean-table td {
  border-top: none;
  border-left: none;
  border-right: none;
  border-bottom: 1px solid hsla(var(--bs-border-color-hsl, 0, 0%, 100%), 0.06);
  padding: 0.9rem 1rem;
  background: transparent;
}

.acp-clean-table tbody tr:last-child td {
  border-bottom: none;
}

.acp-clean-table tbody tr:hover td {
  background: var(--acp-surface-hover-bg);
}

.acp-login-link:hover {
  color: var(--bs-primary) !important;
}

/* Grid de pacotes/serviços — donate, store, shop */
.acp-pack-card {
  border-radius: var(--acp-radius-lg) !important;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.acp-pack-card:hover {
  border-color: hsla(var(--bs-primary-hsl), 0.5) !important;
  box-shadow: none !important;
}

/* ---------------------------------------------------------------------------------------------
   Tela Minha Carteira (/wallet) — Hero Stat Card, Forms encapsulados e Badges de Lançamento
   --------------------------------------------------------------------------------------------- */
.acp-wallet-hero {
  background-color: var(--acp-surface-raised-bg) !important;
  border: var(--acp-border-width) solid var(--acp-border-color) !important;
  border-radius: var(--acp-radius-lg) !important;
  padding: 1.5rem !important;
}

:root[data-bs-theme='light'] .acp-wallet-hero {
  background-color: var(--acp-surface-bg) !important;
  border: 1px solid var(--bs-border-color) !important;
}

.acp-wallet-hero-icon .acp-icon-badge {
  width: 3rem;
  height: 3rem;
}

.acp-wallet-hero-label {
  font-size: 0.8rem;
  color: var(--bs-secondary-color);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.acp-wallet-hero-value {
  font-size: 1.75rem;
  font-weight: 700;
  line-height: 1.2;
  color: #fff;
  letter-spacing: -0.02em;
}

:root[data-bs-theme='light'] .acp-wallet-hero-value {
  color: #111;
}

.acp-wallet-hero-unit {
  font-size: 0.95rem;
  font-weight: 500;
  color: var(--bs-secondary-color);
  margin-left: 0.35rem;
}

.acp-wallet-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 1.5rem;
  margin-bottom: 1.5rem;
}

.acp-wallet-card {
  background-color: var(--acp-surface-raised-bg) !important;
  border: var(--acp-border-width) solid var(--acp-border-color) !important;
  border-radius: var(--acp-radius-lg) !important;
}

:root[data-bs-theme='light'] .acp-wallet-card {
  background-color: var(--acp-surface-raised-bg) !important;
  border: 1px solid var(--bs-border-color) !important;
}

.acp-wallet-section {
  background-color: var(--acp-surface-raised-bg) !important;
  border: var(--acp-border-width) solid var(--acp-border-color) !important;
  border-radius: var(--acp-radius-lg) !important;
}

:root[data-bs-theme='light'] .acp-wallet-section {
  background-color: var(--acp-surface-raised-bg) !important;
  border: 1px solid var(--bs-border-color) !important;
}

.acp-form-input {
  height: 38px !important;
  background-color: var(--acp-input-bg) !important;
  border: var(--acp-border-width) solid var(--acp-input-border-color) !important;
  border-radius: var(--acp-radius-md) !important;
  color: #ededed !important;
  font-size: 0.875rem !important;
}

:root[data-bs-theme='light'] .acp-form-input {
  background-color: var(--acp-input-bg) !important;
  border: 1px solid var(--acp-input-border-color) !important;
  color: #111 !important;
}

.acp-wallet-transfer-modal .modal-dialog {
  max-width: 460px;
}

.acp-wallet-transfer-modal .modal-content {
  background: var(--acp-surface-raised-bg);
  border: var(--acp-border-width) solid var(--acp-border-color);
  border-radius: var(--acp-radius-lg);
  box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.35);
}

.acp-wallet-transfer-modal :is(.modal-header, .modal-footer) {
  border-color: var(--acp-border-color);
}

.acp-form-input:focus {
  border-color: var(--bs-primary) !important;
  box-shadow: 0 0 0 2px hsla(var(--bs-primary-hsl), 0.2) !important;
}

.acp-badge-credit {
  background: rgba(34, 197, 94, 0.12) !important;
  color: #4ade80 !important;
  border: 1px solid rgba(34, 197, 94, 0.25) !important;
  font-weight: 600;
  font-size: 0.825rem;
  padding: 0.25rem 0.55rem;
  border-radius: var(--acp-radius-sm);
  display: inline-block;
}

.acp-badge-debit {
  background: rgba(239, 68, 68, 0.12) !important;
  color: #f87171 !important;
  border: 1px solid rgba(239, 68, 68, 0.25) !important;
  font-weight: 600;
  font-size: 0.825rem;
  padding: 0.25rem 0.55rem;
  border-radius: var(--acp-radius-sm);
  display: inline-block;
}

/* ---------------------------------------------------------------------------------------------
   Loja de Itens (/shop) — Hero Banner, Tabs de Categorias e Product Cards (shadcn / e-Commerce)
   --------------------------------------------------------------------------------------------- */
.acp-shop-hero {
  background: radial-gradient(ellipse at 50% 0%, hsla(var(--bs-primary-hsl), 0.06) 0%, var(--acp-surface-raised-bg) 75%) !important;
  border: var(--acp-border-width) solid var(--acp-border-color) !important;
  border-radius: var(--acp-radius-lg) !important;
  padding: 2.25rem 1.5rem !important;
  text-align: center;
  position: relative;
  overflow: hidden;
}

:root[data-bs-theme='light'] .acp-shop-hero {
  background: radial-gradient(ellipse at 50% 0%, hsla(var(--bs-primary-hsl), 0.08) 0%, var(--acp-surface-bg) 75%) !important;
  border: 1px solid var(--bs-border-color) !important;
}

.acp-shop-hero-title {
  font-size: 1.75rem;
  font-weight: 700;
  color: #fff;
  letter-spacing: -0.02em;
  margin-bottom: 0.4rem;
}

:root[data-bs-theme='light'] .acp-shop-hero-title {
  color: #111;
}

.acp-shop-hero-subtitle {
  color: var(--bs-secondary-color);
  font-size: 0.925rem;
  max-width: 540px;
  margin: 0 auto;
}

.acp-shop-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  justify-content: center;
  margin-bottom: 1.75rem;
}

.acp-shop-tab {
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.06);
  color: var(--bs-secondary-color);
  padding: 0.45rem 1.15rem;
  border-radius: 9999px;
  font-size: 0.875rem;
  font-weight: 500;
  cursor: pointer;
  text-decoration: none;
  transition: all 0.15s ease;
  user-select: none;
}

:root[data-bs-theme='light'] .acp-shop-tab {
  background: #f1f3f5;
  border: 1px solid var(--bs-border-color);
  color: #495057;
}

.acp-shop-tab:hover {
  background: rgba(255, 255, 255, 0.07);
  color: #fff;
  border-color: rgba(255, 255, 255, 0.12);
}

:root[data-bs-theme='light'] .acp-shop-tab:hover {
  background: #e9ecef;
  color: #111;
}

.acp-shop-tab.active {
  background: hsla(var(--bs-primary-hsl), 0.15) !important;
  color: var(--bs-primary) !important;
  border-color: hsla(var(--bs-primary-hsl), 0.4) !important;
  font-weight: 600;
}

.acp-shop-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 1.25rem;
  margin-bottom: 2rem;
}

.acp-product-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  justify-content: space-between;
  background-color: var(--acp-surface-raised-bg) !important;
  border: var(--acp-border-width) solid var(--acp-border-color) !important;
  border-radius: var(--acp-radius-lg) !important;
  padding: 1.25rem 1rem !important;
  transition: transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
  position: relative;
}

:root[data-bs-theme='light'] .acp-product-card {
  background-color: var(--acp-surface-raised-bg) !important;
  border: 1px solid var(--bs-border-color) !important;
}

.acp-product-card:hover {
  transform: translateY(-4px);
  border-color: hsla(var(--bs-primary-hsl), 0.4) !important;
  box-shadow: none;
}

.acp-product-image-box {
  width: 76px;
  height: 76px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: radial-gradient(circle, hsla(var(--bs-primary-hsl), 0.12) 0%, rgba(255, 255, 255, 0.02) 75%);
  border: var(--acp-border-width) solid var(--acp-border-color);
  border-radius: var(--acp-radius-md);
  margin-bottom: 0.9rem;
  flex-shrink: 0;
}

.acp-product-image-box img {
  max-width: 56px;
  max-height: 56px;
  object-fit: contain;
  display: block;
}

.acp-product-image-box .acp-icon-badge {
  width: 2.75rem;
  height: 2.75rem;
}

.acp-product-body {
  width: 100%;
  margin-bottom: 1rem;
}

.acp-product-title {
  font-size: 0.95rem;
  font-weight: 600;
  color: #fff;
  margin-bottom: 0.35rem;
  line-height: 1.3;
  word-break: break-word;
}

:root[data-bs-theme='light'] .acp-product-title {
  color: #111;
}

.acp-product-desc {
  font-size: 0.825rem;
  color: var(--bs-secondary-color);
  margin-bottom: 0;
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
  min-height: 2.3em;
}

.acp-product-footer {
  width: 100%;
  margin-top: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.acp-product-price {
  font-size: 1.2rem;
  font-weight: 700;
  color: #fff;
  margin-bottom: 0.75rem;
  letter-spacing: -0.01em;
}

:root[data-bs-theme='light'] .acp-product-price {
  color: #111;
}

.acp-product-unit {
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--bs-secondary-color);
  margin-left: 0.2rem;
}

.acp-product-cta {
  width: 100%;
  font-weight: 600;
  font-size: 0.875rem;
  border-radius: 6px;
  padding: 0.45rem 0.75rem;
}

.acp-shop-pack-card {
  background-color: var(--acp-surface-raised-bg) !important;
  border: var(--acp-border-width) solid var(--acp-border-color) !important;
  border-radius: var(--acp-radius-lg) !important;
  max-width: 600px;
  margin: 0 auto;
}

:root[data-bs-theme='light'] .acp-shop-pack-card {
  background-color: var(--acp-surface-raised-bg) !important;
  border: 1px solid var(--bs-border-color) !important;
}

.acp-shop-item-row {
  background-color: var(--acp-input-bg) !important;
  border: var(--acp-border-width) solid var(--acp-border-color) !important;
  border-radius: var(--acp-radius-md) !important;
  padding: 0.75rem 1rem !important;
  color: #ededed;
  font-size: 0.875rem;
}

:root[data-bs-theme='light'] .acp-shop-item-row {
  background-color: var(--acp-surface-bg) !important;
  border: 1px solid var(--bs-border-color) !important;
  color: #111;
}

/* Sidebar admin/jogador — painel de altura cheia (ver `.acp-shell` acima), com seções rotuladas
   (ver ADMIN_NAV_SECTION_* em adminNav.js / PLAYER_NAV_SECTION_* em playerNav.js), aproximando do
   padrão "MAIN / RESOURCES / BILLING" do projeto de referência do reskin. Só a borda direita
   separa da coluna de conteúdo — sem cantos arredondados, pra ficar rente às bordas da viewport. */
.acp-sidebar {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 260px;
  flex-shrink: 0;
  border-right: 1px solid var(--acp-border-color);
  background: var(--acp-surface-bg);
  height: 100%;
  overflow: hidden;
}

:root[data-bs-theme='light'] .acp-sidebar {
  background: var(--acp-surface-bg);
  border-right: 1px solid var(--bs-border-color);
}

/* Área rolável do meio — só ela rola quando os itens não cabem; o bloco de usuário (topo) e o
   botão de sair (rodapé, ver renderSidebarLogout em web/views/layout.js) ficam sempre fixos. */
.acp-sidebar-nav {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
  padding: 1.25rem 0.75rem;
}

/* Identidade no topo da sidebar (avatar + login + e-mail) — só a sidebar do jogador tem isso
   (ver renderSidebarUserBlock em web/views/layout.js); a do admin não injeta esse marcador. */
.acp-sidebar-user {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0.5rem;
  padding: 1.5rem 1rem 1.25rem;
  border-bottom: 1px solid var(--acp-border-color);
}

.acp-sidebar-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  background: hsla(var(--bs-primary-hsl), 0.1);
  border: 1px solid hsla(var(--bs-primary-hsl), 0.25);
  color: var(--bs-primary);
}

.acp-sidebar-avatar svg {
  width: 1.4rem;
  height: 1.4rem;
}

.acp-sidebar-username {
  margin: 0;
  font-weight: 600;
  font-size: 0.9rem;
  color: var(--bs-body-color);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}

.acp-sidebar-email {
  margin: 0;
  font-size: 0.75rem;
  color: var(--bs-secondary-color);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}

/* Botão de sair no rodapé da sidebar do jogador (ver renderSidebarLogout) */
.acp-sidebar-logout-form {
  flex-shrink: 0;
  margin: 0;
}

.acp-sidebar-logout {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  gap: 0.65rem;
  width: 100%;
  padding: 0.85rem 1.25rem;
  border: none;
  border-top: 1px solid var(--acp-border-color);
  background: transparent;
  color: var(--bs-danger);
  font-weight: 500;
  font-size: 0.85rem;
  text-decoration: none;
  cursor: pointer;
}

.acp-sidebar-logout:hover {
  background: hsla(var(--bs-red-hsl), 0.1);
  color: var(--bs-danger);
}

.acp-sidebar-logout svg {
  width: 1.05rem;
  height: 1.05rem;
  flex-shrink: 0;
}

/* Seletor de idioma dentro do drawer (ver renderSidebarLanguageSwitcher em web/views/layout.js)
   — só existe pra mostrar no mobile (ver override em `@media (max-width: 767.98px)` no fim do
   arquivo, junto com a regra que esconde a versão do header nessas páginas). No desktop o
   seletor já mora no header, então esse bloco fica escondido aqui. */
.acp-sidebar-lang {
  display: none;
  flex-shrink: 0;
  padding: 0.85rem 1rem;
  border-top: 1px solid var(--acp-border-color);
}

.acp-sidebar-lang .acp-lang-switcher,
.acp-sidebar-lang .dropdown-toggle {
  width: 100%;
}

/* Sobrescreve o `.btn-sm` (pensado pro botão compacto do header): aqui dentro sobra espaço, então
   o botão vira um toque confortável, do mesmo porte dos outros itens do rodapé da sidebar (ver
   .acp-sidebar-logout). Também garante o nome do idioma por extenso ao lado do globo — a regra
   que esconde esse texto (`.acp-lang-switcher-label`) só existe pro botão apertado do header. */
.acp-sidebar-lang .dropdown-toggle {
  justify-content: center;
  gap: 0.65rem;
  padding: 0.85rem 1.25rem;
  font-size: 0.9rem;
}

.acp-sidebar-lang .acp-lang-switcher-label {
  display: inline;
}

.acp-sidebar-section {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.acp-sidebar-section:not(:last-child) {
  padding-bottom: 1.1rem;
}

.acp-sidebar-label {
  margin: 0 0 0.15rem 0.6rem;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--bs-secondary-color);
  opacity: 0.75;
}

.acp-sidebar .nav-link {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  border-radius: var(--acp-radius-md);
  color: var(--bs-secondary-color);
  border: 1px solid transparent;
  transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease, transform 0.2s ease;
}

.acp-sidebar .nav-link:hover:not(.active) {
  background: var(--acp-surface-hover-bg);
  color: var(--bs-body-color);
  transform: translateX(2px);
}

.acp-sidebar .nav-link svg {
  width: 1.05rem;
  height: 1.05rem;
  flex-shrink: 0;
}

.acp-sidebar .nav-link.active {
  background: var(--acp-nav-active-bg) !important;
  border-color: var(--acp-border-color);
  color: var(--bs-body-color) !important;
  font-weight: 600;
  border-left: var(--acp-border-width) solid var(--bs-primary) !important;
  border-top-left-radius: 0;
  border-bottom-left-radius: 0;
}

.acp-sidebar .nav-link.active svg {
  color: var(--bs-primary);
}

/* ---------------------------------------------------------------------------------------------
   Superfícies planas estilo shadcn/ui — sem glow, sem serifada, sem uppercase forçado. Só a cor
   de destaque (dourado por padrão) sobrevive da pegada RPG anterior, e só como accent color
   (foco, seleção, item ativo da sidebar, valores em destaque) — tudo derivado de
   --bs-primary-hsl, então continua respeitando o primaryColor escolhido em
   /admin/settings/theme. --bs-body-bg / --bs-border-color garantem claro+escuro. Nenhum asset
   externo.
   --------------------------------------------------------------------------------------------- */

/* Fundo fixo e neutro (não derivado do primaryColor/secondaryColor do tema). `data-bs-theme`
   fica em <html> (ver THEME_DETECT_SCRIPT em web/views/layout.js), nunca
   sem valor (o script sempre define 'light' ou 'dark' antes do primeiro paint), então os dois
   seletores cobrem os dois estados por completo. Não conflita com o fundo em tela cheia das
   telas de autenticação (`.acp-auth-bg`, ver web/views/authLayout.js): aquele é um elemento
   position:fixed por cima, este é só a cor de base do <body> por baixo dele. */
:root[data-bs-theme='dark'] body.acp-rpg {
  background-color: var(--acp-page-bg);
}

:root[data-bs-theme='light'] body.acp-rpg {
  background-color: var(--acp-page-bg);
}

/* Header, sidebar, cards, hover e seleção compartilham uma escala neutra de degraus próximos. */
:root[data-bs-theme='dark'] {
  --acp-page-bg: #0d0f10;
  --acp-surface-bg: #0e1011;
  --acp-surface-raised-bg: #0e1011;
  --acp-input-bg: #0e1011;
  --acp-surface-hover-bg: #121314;
  --acp-nav-active-bg: #121314;
  --acp-border-color: transparent;
  /* Cards/superfícies ficam sem borda visível de propósito no escuro (só a diferença de fundo já
     separa os planos) — mas isso deixava os campos de formulário sem nenhuma pista visual de que
     são clicáveis/preenchíveis, sumindo no fundo. Só os inputs ganham uma borda de verdade aqui. */
  --acp-input-border-color: rgba(255, 255, 255, 0.14);
  --bs-body-bg: var(--acp-page-bg);
  --bs-body-bg-rgb: 13, 15, 16;
  --bs-border-width: var(--acp-border-width);
  --bs-body-color: #ededed;
  --bs-secondary-color: #9496a1;
  --bs-card-bg: var(--acp-surface-raised-bg);
  --bs-border-color: var(--acp-border-color);
  --bs-border-color-translucent: var(--acp-border-color);
}

:root[data-bs-theme='light'] {
  /* Cinza claro em vez de branco puro — o branco estourado (#fff) cansa a vista sob luz de tela e
     não deixa nenhum degrau visível entre página/superfície/cartão. Escala levemente azulada
     (baixa saturação), do fundo da página até a superfície "elevada" dos cartões/inputs. */
  --acp-page-bg: #eceef1;
  --acp-surface-bg: #f1f2f5;
  --acp-surface-raised-bg: #f7f8fa;
  --acp-input-bg: #f7f8fa;
  --acp-surface-hover-bg: #e8eaed;
  --acp-nav-active-bg: #e3e6ea;
  --acp-border-color: rgba(15, 23, 42, 0.1);
  --acp-input-border-color: var(--acp-border-color);
  --bs-border-width: var(--acp-border-width);
  --bs-border-color: var(--acp-border-color);
}

:root[data-bs-theme='dark'] .card {
  background-color: var(--acp-surface-raised-bg);
  border: 1px solid var(--acp-border-color);
}

/* `.text-white` é um utilitário do Bootstrap/Halfmoon (força #fff) usado em alguns títulos e
   valores dentro de cards/tabelas que, no escuro, ficam sobre um fundo bem escuro — mas esses
   mesmos cards/tabelas viram claros no tema claro (ver --acp-surface-raised-bg acima), deixando o
   texto branco sobre fundo quase branco: ilegível. Sobrescreve pra a cor de texto padrão do tema
   só dentro do `.acp-rpg` (não mexe em usos do utilitário fora do nosso escopo, se houver). */
:root[data-bs-theme='light'] .acp-rpg .text-white {
  color: var(--bs-body-color) !important;
}

:root[data-bs-theme='dark'] .list-group-item {
  background-color: var(--acp-surface-raised-bg);
  border-color: var(--acp-border-color);
}

/* Header: substitui o `bg-body-tertiary` (utilitário do Halfmoon, tingido pela cor secundária)
   pela superfície fixa acima — exceto nas telas de autenticação, onde o header fica transparente
   por cima da arte de fundo (ver `.acp-has-auth-bg .navbar` mais abaixo). */
body.acp-rpg:not(.acp-has-auth-bg) .navbar.bg-body-tertiary {
  position: relative;
  background-color: var(--acp-surface-bg) !important;
  border-bottom: 1px solid var(--acp-border-color) !important;
}

.acp-shell-content {
  background: var(--acp-page-bg);
}

:root[data-bs-theme='light'] body.acp-rpg:not(.acp-has-auth-bg) .navbar.bg-body-tertiary {
  background-color: var(--acp-surface-bg) !important;
  border-bottom: 1px solid var(--bs-border-color) !important;
}

/* Mesma arte de fundo da tela de login (ver AUTH_BACKGROUND_SRC em web/views/authLayout.js),
   quase apagada, dentro do header e da sidebar — textura sutil que amarra o visual das telas
   internas com o das telas de autenticação, sem competir com o conteúdo (opacity bem baixa, e
   fica atrás de tudo: z-index negativo pinta acima só do próprio fundo da superfície, nunca por
   cima do conteúdo em fluxo normal — ver stacking order do CSS). Sem o arquivo da imagem, o
   pseudo-elemento fica vazio e só a cor sólida da superfície aparece — nada quebra. */
body.acp-rpg:not(.acp-has-auth-bg) .navbar.bg-body-tertiary::before,
.acp-sidebar::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image: url('/public/images/auth-background.png');
  background-size: cover;
  background-position: center;
  opacity: 0.025;
  pointer-events: none;
}

.acp-rpg h1, .acp-rpg .h3 {
  font-weight: 700;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

.acp-rpg h2, .acp-rpg .h5 {
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--bs-secondary-color);
}

.acp-rpg .acp-stat-value {
  color: var(--bs-body-color);
}

/* Tabelas: cabeçalho discreto, sem uppercase pesado */
.acp-rpg .table thead th {
  font-size: 0.78rem;
  font-weight: 500;
  color: var(--bs-secondary-color);
}

/* Sidebar: item ativo com barra lateral fina (sem glow) */
.acp-sidebar .nav-link.active {
  box-shadow: none;
}

/* Foco e seleção com a cor de destaque */
.acp-rpg :focus-visible {
  outline: 2px solid hsla(var(--bs-primary-hsl), 0.7);
  outline-offset: 2px;
}

.acp-rpg ::selection {
  background: hsla(var(--bs-primary-hsl), 0.35);
}

/* ---------------------------------------------------------------------------------------------
   Telas de autenticação (login/cadastro/recuperação de senha, ver web/views/pages.js) e todo o
   assistente de instalação (web/views/wizard.js) — fundo em tela cheia com overlay escuro + card
   translúcido, ver web/views/authLayout.js. Ativado via `.acp-has-auth-bg` no <body> (mesma
   técnica de detecção do `.acp-has-shell`, ver web/views/layout.js). Sempre com aparência escura
   (o tema forçado pra 'dark' só nessas telas — ver themeDetectScript em layout.js — e o toggle
   some, ver regra abaixo) porque a arte de fundo pressupõe overlay escuro; alternar pra claro
   deixaria o card ilegível sobre a imagem.
   --------------------------------------------------------------------------------------------- */
.acp-auth-bg {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  background: #0b0d14;
}

.acp-auth-bg-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  display: block;
}

.acp-auth-bg-overlay {
  position: absolute;
  inset: 0;
  /* Escurece bastante em qualquer ponto — não dá pra saber de antemão quão clara é a imagem que
     vai entrar em AUTH_BACKGROUND_SRC, então o overlay garante contraste pro texto branco do
     card/painel lateral mesmo sem calibrar caso a caso. */
  background: linear-gradient(100deg, hsla(0, 0%, 0%, 0.82) 0%, hsla(0, 0%, 0%, 0.6) 50%, hsla(0, 0%, 0%, 0.7) 100%);
}

body.acp-has-auth-bg {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

body.acp-has-auth-bg .navbar {
  flex-shrink: 0;
  background: transparent !important;
  border-bottom: none !important;
  box-shadow: none !important;
}

body.acp-has-auth-bg .navbar-brand {
  display: none;
}

body.acp-has-auth-bg #theme-toggle {
  display: none;
}

body.acp-has-auth-bg .acp-main {
  flex: 1 1 auto;
  max-width: none;
  width: 100%;
  margin: 0;
  padding: 0;
  display: flex;
}

.acp-auth-shell {
  flex: 1 1 auto;
  width: 100%;
  max-width: 860px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1.5rem;
  flex-wrap: wrap;
  padding: 2rem;
}

.acp-auth-shell-single {
  justify-content: center;
}

.acp-auth-card-wrap {
  width: 100%;
  max-width: 420px;
  flex-shrink: 0;
}

.acp-auth-brand {
  min-height: 6rem;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 1.25rem;
  padding: 0 1rem;
  text-align: center;
}

.acp-auth-brand-logo {
  display: block;
  width: min(300px, 72vw);
  max-height: 96px;
  object-fit: contain;
  filter: drop-shadow(0 0.75rem 1.5rem rgba(0, 0, 0, 0.28));
}

.acp-auth-brand-name {
  max-width: 100%;
  color: #fff;
  font-family: var(--acp-display-font);
  font-size: clamp(1.75rem, 5vw, 2.5rem);
  font-weight: 700;
  line-height: 1.05;
  text-wrap: balance;
  text-shadow: 0 0.75rem 1.5rem rgba(0, 0, 0, 0.4);
}

.acp-auth-tabs {
  display: flex;
  border: 1px solid hsla(0, 0%, 100%, 0.12);
  border-bottom: none;
  border-radius: var(--acp-radius-lg) var(--acp-radius-lg) 0 0;
  overflow: hidden;
}

.acp-auth-tab {
  flex: 1 1 50%;
  padding: 0.85rem 1rem;
  background: hsla(0, 0%, 0%, 0.35);
  color: hsla(0, 0%, 100%, 0.65);
  text-decoration: none;
  border-bottom: 2px solid transparent;
}

.acp-auth-tab.active {
  background: hsla(0, 0%, 0%, 0.55);
  color: #fff;
  border-bottom-color: var(--bs-primary);
}

.acp-auth-tab-title {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 700;
  font-size: 0.95rem;
}

.acp-auth-tab-title svg {
  width: 1.05rem;
  height: 1.05rem;
  flex-shrink: 0;
}

.acp-auth-tab-subtitle {
  display: block;
  font-size: 0.72rem;
  margin-top: 0.15rem;
  color: hsla(0, 0%, 100%, 0.55);
}

.acp-auth-card {
  background: hsla(0, 0%, 0%, 0.55) !important;
  border: 1px solid hsla(0, 0%, 100%, 0.12) !important;
  border-radius: var(--acp-radius-lg) !important;
  backdrop-filter: blur(12px);
}

.acp-auth-tabs ~ .acp-auth-card {
  border-top-left-radius: 0 !important;
  border-top-right-radius: 0 !important;
}

.acp-auth-card h1 {
  font-size: 1.4rem;
  margin-bottom: 0.75rem;
}

.acp-auth-side {
  flex: 1 1 320px;
  max-width: 360px;
  color: #f2f0ea;
}

/* Painel de boas-vindas em destaque — moldura própria (fundo + borda dourada) em vez de texto
   solto sobre a imagem, pra chamar mais atenção e garantir contraste com qualquer arte de fundo. */
.acp-auth-side-panel {
  margin-bottom: 1.5rem;
  padding: 1.5rem 1.75rem;
  background: hsla(0, 0%, 0%, 0.4);
  border: 1px solid hsla(var(--bs-primary-hsl), 0.35);
  border-radius: var(--acp-radius-lg);
  backdrop-filter: blur(10px);
  box-shadow: 0 0 40px -20px hsla(var(--bs-primary-hsl), 0.5);
}

.acp-auth-side-panel h2 {
  font-family: var(--acp-display-font);
  color: var(--bs-primary);
  font-size: 1.75rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  margin-bottom: 0.6rem;
  text-shadow: 0 2px 12px hsla(0, 0%, 0%, 0.5);
}

.acp-auth-side-panel p {
  font-size: 1.02rem;
  line-height: 1.55;
  color: hsla(0, 0%, 100%, 0.88);
}

.acp-auth-side .card {
  background: hsla(0, 0%, 0%, 0.45) !important;
  border: 1px solid hsla(0, 0%, 100%, 0.12) !important;
  backdrop-filter: blur(8px);
}

.acp-auth-side .card h2 {
  font-family: var(--acp-display-font);
  color: var(--bs-primary);
  font-size: 1.15rem;
  font-weight: 700;
}

/* Painel de notícias do login/cadastro (ver renderAuthNewsPanel em web/views/pages.js) — no
   lugar do texto fixo de boas-vindas que ficava aqui antes. Altura fixa com rolagem própria pra
   não esticar o painel lateral (e a tela toda) por mais notícias que existam. */
.acp-auth-news h2 {
  margin-bottom: 1rem;
}

.acp-auth-news-scroll {
  max-height: min(28rem, 60vh);
  overflow-y: auto;
  padding-right: 0.25rem;
}

@media (max-width: 991.98px) {
  .acp-auth-shell {
    justify-content: center;
    padding: 1.5rem;
  }

  .acp-auth-side {
    display: none;
  }
}

/* Passo a passo do assistente de instalação (ver stepsNav em web/views/wizard.js) — dentro do
   mesmo card translúcido escuro acima, por isso as cores são baseadas em branco/transparência em
   vez das variáveis de tema (que mudariam com claro/escuro, mas essa tela é sempre escura). */
.acp-wizard-steps {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1rem;
  margin-bottom: 1.5rem;
}

.acp-wizard-step {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.78rem;
  color: hsla(0, 0%, 100%, 0.45);
}

.acp-wizard-step-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.4rem;
  height: 1.4rem;
  flex-shrink: 0;
  border-radius: 50%;
  border: 1px solid currentColor;
  font-size: 0.7rem;
  font-weight: 700;
}

.acp-wizard-step.done {
  color: hsla(0, 0%, 100%, 0.75);
}

.acp-wizard-step.done .acp-wizard-step-num {
  background: hsla(0, 0%, 100%, 0.15);
  border-color: transparent;
}

.acp-wizard-step.active {
  color: var(--bs-primary);
}

.acp-wizard-step.active .acp-wizard-step-num {
  background: hsla(var(--bs-primary-hsl), 0.2);
  border-color: var(--bs-primary);
}

/* Botão de mostrar/ocultar senha (ver renderPasswordToggle em web/views/icons.js) — junto de
   qualquer <input type="password"> envolvido num wrapper `.acp-password-field`. */
.acp-password-field {
  position: relative;
}

.acp-password-field .form-control {
  padding-right: 2.5rem;
}

.acp-password-toggle {
  position: absolute;
  right: 0.4rem;
  top: 50%;
  transform: translateY(-50%);
  display: inline-flex;
  background: none;
  border: none;
  padding: 0.3rem;
  color: var(--bs-secondary-color);
  cursor: pointer;
}

.acp-password-toggle svg {
  width: 1.1rem;
  height: 1.1rem;
}

.acp-password-toggle .acp-eye-hide {
  display: none;
}

.acp-password-toggle.showing .acp-eye-show {
  display: none;
}

.acp-password-toggle.showing .acp-eye-hide {
  display: inline-flex;
}

/* ---------------------------------------------------------------------------------------------
   Dashboard do jogador (ver renderDashboardPage em web/views/pages.js) — banner de boas-vindas +
   stat bar contígua + grid principal/lateral no estilo minimalista.
   --------------------------------------------------------------------------------------------- */
.acp-dashboard-hero {
  position: relative;
  overflow: hidden;
  border-radius: var(--acp-radius-lg);
  padding: 2.75rem 2.25rem;
  margin-bottom: 1.5rem;
  width: 100%;
  background: var(--acp-surface-raised-bg);
  border: 1px solid var(--acp-border-color);
}

.acp-dashboard-hero-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

.acp-dashboard-hero-overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(to right, rgba(10, 10, 10, 1) 0%, rgba(10, 10, 10, 0.4) 50%, rgba(10, 10, 10, 1) 100%);
}

.acp-dashboard-hero-content {
  position: relative;
  z-index: 1;
}

.acp-dashboard-hero-content h1 {
  font-family: var(--bs-body-font-family);
  color: #fff;
  font-size: 1.75rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  margin-bottom: 0.4rem;
}

.acp-dashboard-hero-content p {
  color: rgba(255, 255, 255, 0.7);
  margin: 0;
  font-size: 0.95rem;
}

/* Stat bar: painéis horizontais contíguos de dados numéricos (saldo, personagens, etc.) */
.acp-stat-bar {
  display: flex;
  flex-direction: row;
  align-items: stretch;
  background: var(--acp-surface-raised-bg) !important;
  border: 1px solid var(--acp-border-color) !important;
  border-radius: var(--acp-radius-lg);
  overflow: hidden;
  margin-bottom: 1.5rem;
  width: 100%;
}

.acp-stat-bar-item {
  flex: 1 1 0;
  display: flex;
  align-items: center;
  gap: 1.1rem;
  padding: 1.25rem 1.5rem;
  min-width: 0;
}

.acp-stat-bar-divider {
  width: 1px;
  background: var(--acp-border-color);
}

.acp-stat-bar-icon .acp-icon-badge {
  width: 2.5rem;
  height: 2.5rem;
}

.acp-stat-bar-icon svg {
  width: 1.25rem;
  height: 1.25rem;
}

.acp-dashboard-grid {
  display: flex;
  align-items: flex-start;
  gap: 1.5rem;
}

.acp-dashboard-main {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.acp-dashboard-side {
  flex: 0 0 320px;
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

/* Card de link rápido (ver renderQuickLink em web/views/pages.js) */
.acp-quicklink {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  padding: 0.85rem 1rem;
  border: 1px solid var(--acp-border-color);
  border-radius: var(--acp-radius-md);
  text-decoration: none;
  color: inherit;
  background: var(--acp-surface-bg);
  transition: background-color 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
}

.acp-quicklink:hover {
  border-color: var(--acp-border-color);
  background: var(--acp-surface-hover-bg);
  color: inherit;
  transform: translateY(-1px);
}

.acp-quicklink-title {
  display: block;
  font-weight: 600;
  font-size: 0.9rem;
  color: var(--bs-body-color);
}

.acp-quicklink-desc {
  display: block;
  font-size: 0.78rem;
  color: var(--bs-secondary-color);
}

@media (max-width: 991.98px) {
  .acp-dashboard-grid {
    flex-direction: column;
  }

  /* `.acp-dashboard-grid` usa `align-items: flex-start` (de propósito no desktop, pra não
     esticar as duas colunas na mesma altura) — mas isso também faz os filhos encolherem pro
     tamanho do próprio conteúdo quando a direção vira coluna aqui, em vez de ocupar a largura
     toda. Sem esse `width: 100%` explícito, só a seção "Links úteis" (dentro de
     `.acp-dashboard-side`, que já tinha essa regra) ficava esticada — o resto (banner, notícias,
     atividade recente) ficava menor que a tela. */
  .acp-dashboard-main,
  .acp-dashboard-side {
    flex: 1 1 auto;
    width: 100%;
  }

  .acp-dashboard-activity-row {
    flex-direction: column;
  }
}

@media (max-width: 420px) {
  /* Só em telas bem estreitas os dois KPIs empilham — "um do lado do outro" é o padrão mesmo no
     celular, já que a `.acp-dashboard-activity-row` acima libera a largura toda pro card de
     estatísticas nesses tamanhos. */
  .acp-dashboard-stats-card {
    flex-direction: column;
    align-items: stretch;
    gap: 1rem;
  }

  .acp-dashboard-stat-divider {
    width: auto;
    height: 1px;
    margin: 0;
  }
}

/* ---------------------------------------------------------------------------------------------
   Sidebar como drawer no mobile (ver renderSidebarToggle/SIDEBAR_DRAWER_SCRIPT em
   web/views/layout.js). Este bloco fica deliberadamente no FINAL do arquivo: a regra
   `.acp-sidebar` de dentro do media query abaixo tem a mesma especificidade da regra base
   `.acp-sidebar` (ambas são uma única classe) — em empate de especificidade, quem vem DEPOIS no
   arquivo vence, mesmo dentro de media query, independente da condição bater ou não. Colocar
   antes da regra base (como uma primeira versão fez) faz a regra base sempre vencer e a sidebar
   nunca virar drawer de verdade.
   --------------------------------------------------------------------------------------------- */
@media (max-width: 767.98px) {
  .acp-sidebar-toggle {
    display: inline-flex;
  }

  /* Fica fora da tela por padrão e desliza por cima do conteúdo quando o hamburguer é clicado,
     em vez de empilhar acima dele — não sobra altura de viewport suficiente pra sidebar E
     conteúdo convivendo lado a lado ou empilhados num celular. */
  .acp-sidebar {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 1050;
    width: 85vw;
    max-width: 300px;
    height: 100vh;
    border-right: 1px solid var(--bs-border-color);
    transform: translateX(-100%);
    transition: transform 0.25s ease;
    box-shadow: 12px 0 32px hsla(0, 0%, 0%, 0.35);
  }

  body.acp-sidebar-open .acp-sidebar {
    transform: translateX(0);
  }

  /* Área escurecida atrás do drawer — clicar nela fecha (ver SIDEBAR_DRAWER_SCRIPT). */
  body.acp-sidebar-open::after {
    content: '';
    position: fixed;
    inset: 0;
    z-index: 1040;
    background: hsla(0, 0%, 0%, 0.5);
  }

  /* Evita "scroll dentro de scroll": o padrão de altura fixa (100vh) + rolagem independente por
     coluna (pensado pro desktop, sidebar ao lado do conteúdo) não faz mais sentido aqui — a
     sidebar já virou um drawer fixo (acima), então não precisa mais desse truque. A página volta
     a rolar do jeito normal, um scroll só, o que de quebra evita a inconsistência do `100vh` em
     navegador mobile (a barra de endereço aparecendo/sumindo mexe na viewport e sobrava um
     scroll fantasma dentro do `.acp-shell-body` mesmo com o body "travado"). */
  body.acp-has-shell {
    height: auto;
    overflow: visible;
    display: block;
  }

  body.acp-has-shell .acp-main {
    display: block;
  }

  .acp-shell {
    display: block;
  }

  .acp-shell-content {
    height: auto;
    display: block;
  }

  .acp-shell-body {
    overflow-y: visible;
    padding: 1rem;
  }

  .acp-panel-footer {
    flex-direction: column;
    justify-content: center;
    gap: 0.65rem;
    padding: 1rem;
    text-align: center;
  }

  /* Header: muita coisa pra pouco espaço (hamburguer + marca + saldo + idioma + tema) — corta o
     que dá pra cortar sem perder função (nome do site e o texto do idioma, mantendo os ícones) e
     aperta o respiro lateral/entre itens. */
  header.navbar {
    padding-left: 0.75rem;
    padding-right: 0.75rem;
  }

  header.navbar .d-flex.ms-auto {
    gap: 0.4rem;
  }

  .acp-brand-word {
    display: none;
  }

  .acp-lang-switcher-label {
    display: none;
  }

  header .acp-lang-switcher .dropdown-toggle {
    gap: 0.25rem;
    padding-left: 0.5rem;
    padding-right: 0.4rem;
  }

  /* Idioma agora mora dentro do drawer (ver .acp-sidebar-lang acima) — o botão do header vira
     redundante em páginas com sidebar, então some daqui e reaparece lá dentro. Páginas sem
     drawer (login/cadastro/instalação) não têm pra onde mover, então mantêm o seletor no
     header mesmo no mobile. */
  body.acp-has-shell header .acp-lang-switcher {
    display: none;
  }

  .acp-sidebar-lang {
    display: flex;
  }
}

/* ---------------------------------------------------------------------------------------------
   Acabamento compacto: hairlines e superfícies escuras quase no mesmo plano visual. Este bloco
   fica no fim para também normalizar componentes especializados que definem shorthand de borda.
   --------------------------------------------------------------------------------------------- */
.acp-rpg :is(
  .card,
  .btn,
  .dropdown-menu,
  .form-control,
  .form-select,
  .list-group-item,
  .acp-header-balance,
  .acp-icon-badge,
  .acp-metric-card,
  .acp-wallet-hero,
  .acp-wallet-card,
  .acp-wallet-section,
  .acp-form-input,
  .acp-shop-hero,
  .acp-shop-tab,
  .acp-product-card,
  .acp-product-image-box,
  .acp-shop-pack-card,
  .acp-shop-item-row,
  .acp-dashboard-hero,
  .acp-stat-bar,
  .acp-quicklink
) {
  border-width: var(--acp-border-width) !important;
}

.acp-rpg :is(
  .card,
  .acp-metric-card,
  .acp-wallet-hero,
  .acp-wallet-card,
  .acp-wallet-section,
  .acp-shop-hero,
  .acp-product-card,
  .acp-shop-pack-card,
  .acp-dashboard-hero,
  .acp-stat-bar
) {
  border-radius: var(--acp-radius-lg) !important;
}

.acp-rpg :is(
  .btn,
  .dropdown-menu,
  .form-control,
  .form-select,
  .acp-form-input,
  .acp-icon-badge,
  .acp-product-image-box,
  .acp-shop-item-row,
  .acp-quicklink
) {
  border-radius: var(--acp-radius-md) !important;
}

.acp-sidebar {
  border-right-width: var(--acp-border-width) !important;
}

.acp-rpg :is(.navbar, .acp-breadcrumb, .acp-sidebar-user) {
  border-bottom-width: var(--acp-border-width) !important;
}

.acp-rpg :is(.acp-sidebar-logout, .acp-sidebar-lang) {
  border-top-width: var(--acp-border-width) !important;
}

.acp-rpg :is(.acp-clean-table th, .acp-clean-table td) {
  border-bottom-width: var(--acp-border-width);
}

:root[data-bs-theme='dark'] .acp-rpg :is(.form-control, .form-select, .acp-form-input) {
  background-color: var(--acp-input-bg) !important;
  border-color: var(--acp-input-border-color) !important;
}

:root[data-bs-theme='dark'] .acp-rpg :is(
  .card,
  .acp-metric-card,
  .acp-wallet-hero,
  .acp-wallet-card,
  .acp-wallet-section,
  .acp-product-card,
  .acp-shop-pack-card,
  .acp-stat-bar
) {
  background-color: var(--acp-surface-raised-bg) !important;
  border-color: var(--acp-border-color) !important;
}

:root[data-bs-theme='dark'] .acp-rpg :is(.acp-shop-item-row, .acp-quicklink) {
  background-color: var(--acp-surface-bg) !important;
  border-color: var(--acp-border-color) !important;
}
