/* ============================================================
   TOK MUSIC BOT — DASHBOARD

   Layout adotado exatamente do arquivo enviado (sem barra lateral --
   a versao anterior com sidebar causava sobreposicoes/quebras).
   Paleta e icones sao os ja estabelecidos no projeto (rosa do TikTok
   + icones SVG proprios), nao os do arquivo de referencia (verde +
   Font Awesome via CDN, que nosso CSP nao libera).
   ============================================================ */

:root {
  --bg: #0d1110;
  --surface: #121815;
  --surface-hover: #161e1a;

  --accent: #fe2c55;
  --accent-hover: #e0264c;
  --accent-soft: rgba(254, 44, 85, 0.08);

  --text: #f3f4f6;
  --text-muted: #8b949e;

  --border: rgba(255, 255, 255, 0.06);
  --border-strong: rgba(255, 255, 255, 0.14);

  --danger: #ef4444;
  --danger-soft: rgba(239, 68, 68, 0.1);
  --info: #60a5fa;
  --info-soft: rgba(96, 165, 250, 0.1);
  --success: #10b981;
  --success-soft: rgba(16, 185, 129, 0.1);
  --warning: #f6c453;
  --warning-soft: rgba(246, 196, 83, 0.12);

  --font-body: Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: "SFMono-Regular", Consolas, "Liberation Mono", monospace;

  --radius-sm: 8px;
  --radius-md: 10px;
  --radius-lg: 14px;
  --radius-xl: 18px;

  --shadow-md: 0 18px 46px rgba(0, 0, 0, 0.32);
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: var(--font-body);
}

html {
  min-height: 100%;
  max-width: 100%;
  overflow-x: hidden;
  /* Reserva o espaco da barra de rolagem vertical em QUALQUER
     navegador, mesmo antes de precisar dela -- sem isso, um navegador
     com scrollbar classica (ocupa espaco real, ex.: Chrome no Windows)
     tem alguns pixels a MENOS de largura de conteudo disponivel do que
     um navegador com scrollbar overlay (nao ocupa espaco, comum em
     Firefox/Safari em certas configuracoes), fazendo layouts que
     cabem perfeitamente num navegador estourarem por poucos pixels no
     outro. Normaliza os dois cenarios para o mesmo calculo. */
  scrollbar-gutter: stable;
  background: var(--bg);
  color-scheme: dark;
}

/* Remove as setinhas (spin buttons) de TODO <input type="number"> da
   aplicacao. Motivo: o Chrome desenha essas setinhas com uma largura
   intrinseca minima diferente do Firefox/Safari -- mesmo com
   width:100% e min-width:0 no campo, o NAVEGADOR ainda reserva espaco
   extra para as proprias setinhas antes de aplicar essas regras,
   fazendo o campo ficar alguns pixels mais largo em Chrome do que em
   outros navegadores. Isso explicava a barra de rolagem horizontal
   aparecer SO no Chrome: nao era uma diferenca de layout nossa, era a
   propria UI nativa do spinner do navegador. Removendo as setinhas de
   vez (o campo continua so aceitando numeros, so perde o clique de
   incrementar/decrementar, que ninguem usa nestes formularios) elimina
   a inconsistencia pela raiz, em vez de tentar calibrar pixel por
   pixel entre navegadores. */
input[type="number"] {
  -moz-appearance: textfield;
  appearance: textfield;
}

input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

body {
  background-color: var(--bg);
  color: var(--text);
  overflow-x: hidden;
}

/* Layout do dashboard principal (index.html): usa <main> como area de
   rolagem interna, entao o body em si fica sem rolagem propria. Isso
   NAO pode ser uma regra generica de "body" -- login/cadastro/
   plataforma tambem carregam este mesmo CSS, e nao tem um <main> com
   rolagem interna equivalente. Antes disso ser uma classe dedicada,
   "overflow:hidden; height:100vh" vazava para TODAS as paginas,
   deixando conteudo mais alto que a tela simplesmente inacessivel (sem
   barra de rolagem nenhuma) -- bug real corrigido aqui. */
body.dashboard-page {
  display: flex;
  flex-direction: column;
  height: 100vh;
  overflow: hidden;
}

button,
input {
  font: inherit;
}

img {
  max-width: 100%;
}

button {
  cursor: pointer;
}

code {
  padding: 2px 6px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.045);
  color: #dde1ea;
  font-family: var(--font-mono);
  font-size: 0.82em;
}

[data-icon] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

[data-icon] svg {
  display: block;
}

/* ============================================================
   MAIN LAYOUT (sem barra lateral)
   ============================================================ */

body.dashboard-page>main {
  flex-grow: 1;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  background-color: var(--bg);
}

header.top-header {
  padding: 16px 32px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  border-bottom: 1px solid var(--border);
  background-color: var(--bg);
  position: sticky;
  top: 0;
  z-index: 10;
}

.header-brand {
  display: flex;
  align-items: center;
  gap: 12px;
  /* NAO fixo (sem flex-shrink:0) -- o bloco inteiro precisa poder
     encolher em telas estreitas. So o icone em si (abaixo) mantem
     tamanho fixo; o texto ao lado (que pode ficar longo com o nome do
     usuario na saudacao) ganha reticencias em vez de empurrar o
     cabecalho inteiro pra fora da tela. */
  min-width: 0;
}

.logo-icon {
  background-color: var(--accent);
  color: #fff;
  width: 36px;
  height: 36px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.logo-text {
  min-width: 0;
}

.logo-text h1 {
  font-size: 14px;
  font-weight: 700;
  line-height: 1.2;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.logo-text p {
  font-size: 11px;
  color: var(--text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.header-center {
  display: flex;
  align-items: center;
  gap: 12px;
  flex: 1;
  min-width: 0;
  justify-content: center;
}

.icon-btn,
.help-btn,
.btn-logout-header {
  background-color: var(--surface);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 7px 14px;
  border-radius: 8px;
  font-size: 13px;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
  transition: all 0.2s;
  white-space: nowrap;
}

.icon-btn:hover,
.help-btn:hover,
.btn-logout-header:hover {
  border-color: var(--border-strong);
}

.help-btn {
  color: var(--accent);
  background-color: var(--accent-soft);
  border-color: rgba(254, 44, 85, 0.2);
  font-weight: 500;
}

/* Botao circular so com icone (usado no menu da conta) -- sem nenhum
   indicador de notificacao: o sino de notificacao foi removido do
   cabecalho por nao ter funcao real (nenhum sistema de notificacoes
   existe no backend), e reaproveitar aquele estilo aqui sem querer
   fazia o botao de conta parecer que tinha uma notificacao pendente. */
.icon-btn {
  position: relative;
  width: 36px;
  height: 36px;
  justify-content: center;
  padding: 0;
  flex-shrink: 0;
}

.btn-logout-header:hover {
  background-color: var(--danger-soft);
  border-color: rgba(239, 68, 68, 0.3);
  color: var(--danger);
}

/* Status de conexao -- indicador real (nao existia no arquivo de
   referencia, mas e informacao critica de monitoramento ao vivo que
   precisa continuar existindo). Estilizado como os outros botoes do
   cabecalho para nao destoar. */
.connection-status {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 13px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background-color: var(--surface);
  color: var(--text-muted);
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
  flex-shrink: 0;
}

.status-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--text-muted);
  box-shadow: 0 0 0 3px rgba(139, 148, 158, 0.12);
}

.connection-connected {
  border-color: rgba(16, 185, 129, 0.3);
  background: var(--success-soft);
  color: #8be6bc;
}

.connection-connected .status-dot {
  background: var(--success);
  box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.14);
}

.connection-error,
.connection-disconnected {
  border-color: rgba(239, 68, 68, 0.3);
  background: var(--danger-soft);
  color: #ffabab;
}

.connection-error .status-dot,
.connection-disconnected .status-dot {
  background: var(--danger);
  box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.14);
}

.connection-connecting .status-dot {
  animation: status-pulse 1.6s ease-in-out infinite;
}

@keyframes status-pulse {

  0%,
  100% {
    opacity: 0.45;
    transform: scale(0.85);
  }

  50% {
    opacity: 1;
    transform: scale(1);
  }
}

/* Botao/menu do usuario -- chip compacto que abre um menu com
   Seguranca da conta / Excluir conta (nao existia no arquivo de
   referencia; adicionado ao lado do "Sair" para nao alterar o botao
   ja especificado, so estender minimamente a area do cabecalho). */
.user-menu-wrap {
  position: relative;
  flex-shrink: 0;
}

.user-menu-dropdown {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 250;

  display: none;
  flex-direction: column;
  gap: 2px;

  width: 240px;
  max-width: calc(100vw - 32px);
  padding: 6px;

  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);

  background: var(--surface);
  box-shadow: var(--shadow-md);
}

.user-menu-dropdown.open {
  display: flex;
}

.user-menu-item {
  display: flex;
  align-items: center;
  gap: 10px;

  padding: 9px 10px;

  border: none;
  border-radius: 8px;

  background: none;
  color: var(--text-muted);

  font-size: 0.82rem;
  font-weight: 600;
  text-align: left;

  transition: background 0.14s ease, color 0.14s ease;
}

.user-menu-item:hover {
  background: rgba(255, 255, 255, 0.06);
  color: var(--text);
}

.user-menu-item-danger {
  color: #ff9b9b;
}

.user-menu-item-danger:hover {
  background: var(--danger-soft);
  color: #ffb3b3;
}

.user-menu-badge {
  margin-left: auto;
  padding: 2px 7px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--text-muted);
  font-size: 0.6rem;
  font-weight: 800;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}

.user-menu-badge.is-on {
  background: var(--success-soft);
  color: #7fe6b8;
}

/* ============================================================
   GRID PRINCIPAL EM LINHAS ALINHADAS
   ============================================================ */

.dashboard-grid {
  padding: 24px 32px;
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: 20px;
}

.col-left,
.col-right {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.card {
  background-color: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 20px;
  display: flex;
  flex-direction: column;
  scroll-margin-top: 90px;
}

.row-1-card {
  height: 350px;
}

.row-2-wrapper {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
}

.row-2-card {
  height: 180px;
  margin: 0;
}

.row-3-card {
  height: 380px;
}

/* Modificador aplicado SO aos cards de conteudo fixo (Tocando Agora,
   Configuracoes, Conta) -- onde faz sentido espalhar os blocos do topo
   ao fundo do card. NAO deve ir em cards que tem uma lista rolavel
   dentro (Eventos, Estatisticas, Fila, Historico): nesses, o
   space-between empurrava a lista inteira pro FUNDO do card quando ela
   tinha poucos itens, dando a impressao de "preencher de baixo para
   cima" -- bug real corrigido aqui. */
.card-spread {
  justify-content: space-between;
}

/* Cards com lista rolavel: a lista cresce para ocupar o espaco
   disponivel e rola por dentro dela mesma, sempre a partir do topo.
   scrollbar-gutter reserva o espaco da barra de rolagem, evitando que
   ela cubra o valor/horario alinhado a direita de cada item. */
.event-list,
#today-stats,
.queue-list,
.history-list {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  scrollbar-gutter: stable;
  padding-right: 4px;
}

.card-header-flex {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
}

.card-title {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.8px;
  color: var(--text-muted);
  font-weight: 700;
}

.card-link {
  font-size: 11px;
  color: var(--accent);
  text-decoration: none;
  font-weight: 500;
  border: none;
  background: none;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.card-link:hover {
  text-decoration: underline;
}

.card-link.muted {
  color: var(--text-muted);
}

/* ============================================================
   TOCANDO AGORA
   ============================================================ */

.playing-container {
  display: flex;
  gap: 16px;
  align-items: center;
}

.album-art {
  position: relative;
  width: 110px;
  height: 110px;
  min-width: 110px;
  border-radius: 10px;
  overflow: hidden;
  background: var(--bg);
}

.album-art img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.album-art-fallback {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  color: var(--text-muted);
}

.play-overlay {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
  display: flex;
  align-items: center;
  justify-content: center;
}

.play-overlay [data-icon] {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.6);
  color: #fff;
}

/* Equalizador animado -- so vibra enquanto de fato esta tocando;
   parado/pausado mostra o icone estatico de play por cima da capa. */
.equalizer {
  display: none;
  align-items: flex-end;
  justify-content: center;
  gap: 3px;
  width: 26px;
  height: 20px;
}

.play-overlay.is-playing .equalizer {
  display: flex;
}

.play-overlay.is-playing .static-play-icon {
  display: none;
}

.equalizer span {
  width: 4px;
  height: 100%;
  border-radius: 3px;
  background: #fff;
  animation: equalize 0.9s ease-in-out infinite;
}

.equalizer span:nth-child(1) {
  animation-delay: -0.6s;
}

.equalizer span:nth-child(2) {
  animation-delay: -0.3s;
}

.equalizer span:nth-child(3) {
  animation-delay: -0.9s;
}

.equalizer span:nth-child(4) {
  animation-delay: -0.15s;
}

@keyframes equalize {

  0%,
  100% {
    transform: scaleY(0.25);
  }

  50% {
    transform: scaleY(1);
  }
}

@media (prefers-reduced-motion: reduce) {
  .equalizer span {
    animation: none !important;
    transform: scaleY(0.6);
  }
}

.track-details {
  min-width: 0;
}

.track-details h3 {
  font-size: 15px;
  font-weight: 700;
  margin-bottom: 4px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.track-details p {
  font-size: 12px;
  color: var(--text-muted);
  margin-bottom: 6px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.requested-by {
  font-size: 11px;
  color: var(--accent);
  font-weight: 500;
}

.live-badge {
  background-color: var(--danger-soft);
  color: #ff9c9c;
  padding: 3px 10px;
  border-radius: 20px;
  font-size: 11px;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 6px;
}

.live-dot {
  width: 6px;
  height: 6px;
  background-color: var(--danger);
  border-radius: 50%;
  animation: pulse 1.5s infinite;
}

@keyframes pulse {
  0% {
    opacity: 1;
  }

  50% {
    opacity: 0.4;
  }

  100% {
    opacity: 1;
  }
}

.player-controls {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  flex-wrap: wrap;
  gap: 8px;
}

.btn-control {
  background-color: var(--surface-hover);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 6px 10px;
  border-radius: 8px;
  font-size: 11px;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 6px;
  transition: background 0.2s;
}

.btn-control.primary {
  background-color: var(--accent);
  color: #fff;
  font-weight: 600;
  border: none;
}

.btn-control.primary:hover {
  background-color: var(--accent-hover);
}

.btn-control:not(.primary):hover {
  background-color: rgba(255, 255, 255, 0.04);
}

.btn-control:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.volume-container {
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--text-muted);
  font-size: 12px;
}

/* Barra de volume -- visualmente identica a referencia (trilho fino +
   preenchimento colorido), mas implementada como <input type="range">
   de verdade por baixo (funcao real: arrastar ajusta o volume). O
   preenchimento e pintado dinamicamente via JS a cada mudanca -- ver
   paintVolumeTrack() em dashboard.js. */
.volume-container input[type="range"] {
  flex-grow: 1;
  height: 4px;
  border-radius: 2px;
  background: var(--border-strong);
  outline: none;
  -webkit-appearance: none;
  appearance: none;
}

.volume-container input[type="range"]::-webkit-slider-thumb {
  width: 12px;
  height: 12px;
  -webkit-appearance: none;
  appearance: none;
  border-radius: 50%;
  background: var(--accent);
  cursor: pointer;
  box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.2);
}

.volume-container input[type="range"]::-moz-range-thumb {
  width: 12px;
  height: 12px;
  border: none;
  border-radius: 50%;
  background: var(--accent);
  cursor: pointer;
}

.volume-container #volume-value {
  flex: 0 0 auto;
  white-space: nowrap;
  min-width: 35px;
  text-align: right;
}

.info-alert {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  background-color: rgba(255, 255, 255, 0.015);
  border: 1px solid var(--border);
  padding: 8px 10px;
  border-radius: 8px;
  font-size: 11px;
  color: var(--text-muted);
  line-height: 1.3;
}

.info-alert [data-icon] {
  color: var(--text);
  margin-top: 1px;
}

/* ============================================================
   CONFIGURAÇÕES E CONTA
   ============================================================ */

.switch-group {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
}

.switch {
  position: relative;
  display: inline-block;
  width: 38px;
  height: 20px;
  flex-shrink: 0;
}

.switch input {
  opacity: 0;
  width: 0;
  height: 0;
}

.switch .slider {
  position: absolute;
  cursor: pointer;
  inset: 0;
  background-color: var(--border-strong);
  transition: 0.3s;
  border-radius: 20px;
}

.switch .slider::before {
  position: absolute;
  content: "";
  height: 14px;
  width: 14px;
  left: 3px;
  bottom: 3px;
  background-color: white;
  transition: 0.3s;
  border-radius: 50%;
}

.switch input:checked+.slider {
  background-color: var(--accent);
}

.switch input:checked+.slider::before {
  transform: translateX(18px);
}

.status-ok {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 10px;
  color: var(--accent);
}

.status-off {
  color: var(--text-muted);
}

.input-group {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 8px;
}

.input-group label {
  font-size: 11px;
  color: var(--text-muted);
}

.input-wrapper {
  display: flex;
  gap: 6px;
}

.input-wrapper input {
  flex-grow: 1;
  min-width: 0;
  background-color: var(--bg);
  border: 1px solid var(--border);
  padding: 6px 10px;
  border-radius: 8px;
  color: var(--text);
  font-size: 11px;
  outline: none;
}

.input-wrapper input:focus {
  border-color: rgba(254, 44, 85, 0.5);
}

.btn-action {
  padding: 6px 12px;
  border-radius: 8px;
  font-size: 11px;
  cursor: pointer;
  border: none;
  font-weight: 500;
}

.btn-green {
  background-color: var(--accent);
  color: #fff;
}

.btn-green:hover {
  background-color: var(--accent-hover);
}

.btn-dark {
  background-color: var(--surface-hover);
  color: var(--text);
  border: 1px solid var(--border);
}

.btn-dark:hover {
  background-color: rgba(255, 255, 255, 0.08);
}

.btn-danger {
  background-color: var(--danger);
  color: #fff;
}

.btn-action:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* ============================================================
   PRESENTES ACEITOS
   ============================================================ */

.gifts-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}

.gift-card {
  position: relative;
  background-color: var(--bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 10px;
  text-align: center;
}

.gift-card-emoji {
  font-size: 20px;
  line-height: 1;
}

.gift-card h4 {
  font-size: 12px;
  margin: 6px 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.gift-meta {
  font-size: 11px;
  color: var(--text-muted);
  display: flex;
  justify-content: center;
  gap: 6px;
}

.gift-card-delete {
  position: absolute;
  top: 5px;
  right: 5px;
  display: grid;
  place-items: center;
  width: 18px;
  height: 18px;
  border: none;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.3);
  color: var(--text-muted);
  opacity: 0;
  transition: opacity 0.16s ease, background 0.16s ease, color 0.16s ease;
}

.gift-card:hover .gift-card-delete {
  opacity: 1;
}

.gift-card-delete:hover {
  background: var(--danger);
  color: #fff;
}

.gifts-empty {
  grid-column: 1 / -1;
  padding: 16px 10px;
  border: 1px dashed var(--border-strong);
  border-radius: 10px;
  color: var(--text-muted);
  font-size: 12px;
  text-align: center;
}

/* modal de gerenciar presentes */
.manage-gifts-list {
  display: flex;
  flex-direction: column;
  gap: 7px;
  max-height: 220px;
  margin-top: 10px;
  overflow-y: auto;
}

.manage-gift-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 11px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, 0.02);
}

.manage-gift-row .gift-card-emoji {
  font-size: 18px;
}

.manage-gift-row-info {
  flex: 1;
  min-width: 0;
}

.manage-gift-row-name {
  overflow: hidden;
  color: var(--text);
  font-size: 0.82rem;
  font-weight: 650;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.manage-gift-row-meta {
  color: var(--text-muted);
  font-size: 0.72rem;
}

.manage-gift-row-edit {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  flex-shrink: 0;
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.03);
  color: var(--text-muted);
}

.manage-gift-row-edit:hover {
  background: var(--accent-soft);
  border-color: rgba(254, 44, 85, 0.4);
  color: var(--accent);
}

.manage-gift-row-delete {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  flex-shrink: 0;
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.03);
  color: var(--text-muted);
}

.manage-gift-row-delete:hover {
  background: var(--danger-soft);
  border-color: rgba(239, 68, 68, 0.4);
  color: var(--danger);
}

/* Selecao de "qual presente libera !musica" -- so um pode estar
   marcado por vez (radio buttons), incluindo a opcao "nenhum" (padrao,
   qualquer presente libera). */
.exclusive-gift-row {
  padding: 8px 11px;
  margin-bottom: 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, 0.02);
}

.exclusive-toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  font-size: 0.78rem;
  color: var(--text-muted);
}

.exclusive-toggle input[type="radio"] {
  accent-color: var(--accent);
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}

.exclusive-toggle input[type="radio"]:checked~span {
  color: var(--text);
  font-weight: 600;
}

.manage-gift-row.is-exclusive {
  border-color: rgba(254, 44, 85, 0.35);
  background: var(--accent-soft);
}

.manage-gift-row-exclusive-badge {
  display: flex;
  align-items: center;
  gap: 3px;
  padding: 2px 6px;
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 0.6rem;
  font-weight: 800;
  text-transform: uppercase;
  flex-shrink: 0;
}

.form-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 110px;
  gap: 10px;
  margin-bottom: 10px;
}

.form-row-3 {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 10px;
  margin-bottom: 12px;
}

.form-row label,
.form-row-3 label {
  display: block;
  margin-bottom: 5px;
  color: var(--text-muted);
  font-size: 0.7rem;
  font-weight: 650;
}

/* Sem isso, um <input> usa a largura padrao do navegador (baseada no
   atributo "size", tipicamente ~150-170px) em vez de respeitar a
   coluna do grid -- e o motivo real do campo "Quantidade" (no modo de
   teste) estourar pra fora do card e ate da propria pagina, forcando
   uma barra de rolagem horizontal indevida. min-width:0 e necessario
   parceiro do width:100% em grid/flex, senao o navegador ainda impede
   o item de encolher abaixo do proprio conteudo minimo. */
.form-row input,
.form-row-3 input,
.input-group input {
  width: 100%;
  min-width: 0;
}

/* ============================================================
   EVENTOS DO BOT
   ============================================================ */

.event-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  overflow-y: auto;
}

/* Grid em vez de flexbox de proposito: com flexbox simples, o
   horario (.event-time) podia acabar empurrado pra baixo do texto
   quando a descricao quebrava em varias linhas, em vez de ficar
   sempre alinhado a direita na mesma altura da primeira linha.
   Grid com 2 colunas (a primeira flexivel, a segunda do tamanho do
   proprio conteudo) garante que o horario SEMPRE fica na propria
   coluna, no topo, non importa quantas linhas a descricao ocupe. */
.event-item {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: start;
  gap: 10px;
  padding: 6px 0;
  border-bottom: 1px solid var(--border);
  font-size: 11px;
}

.event-item:last-child {
  border-bottom: none;
}

.event-desc {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  min-width: 0;
}

/* Antes cortava o texto com reticencias numa linha so
   (overflow:hidden + white-space:nowrap) -- eventos mais longos (ex:
   "presente NAO cadastrado" com nome+ID+diamantes, ou o novo aviso de
   presente exclusivo) ficavam ilegiveis, sem jeito de ver o texto
   inteiro. Agora quebra em varias linhas normalmente, mantendo o
   icone e o horario alinhados ao TOPO da primeira linha (ver
   align-items:flex-start acima e em .event-item), organizado mesmo
   com alturas de linha variaveis. */
.event-desc span {
  overflow-wrap: break-word;
  word-break: break-word;
  white-space: normal;
}

.event-time {
  color: var(--text-muted);
  font-size: 10px;
  flex-shrink: 0;
}

.events-empty {
  padding: 16px 10px;
  color: var(--text-muted);
  font-size: 12px;
  text-align: center;
}

/* ============================================================
   ESTATÍSTICAS
   ============================================================ */

.stats-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 4px 0;
  border-bottom: 1px solid var(--border);
}

.stats-row:last-child {
  border-bottom: none;
}

.stats-item {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 11px;
}

.stats-item [data-icon] {
  color: var(--accent);
}

.stats-value {
  font-weight: 700;
  font-size: 12px;
}

.stats-top-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--border);
  list-style: none;
}

/* O numero de vezes que tocou fica GRUDADO no nome (gap fixo pequeno),
   nunca empurrado pro canto oposto do card. */
.stats-top-list li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 6px;
  overflow: hidden;
  color: var(--text-muted);
  font-size: 11px;
}

.stats-top-list li span:first-child {
  overflow: hidden;
  min-width: 0;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.stat-count {
  color: var(--text-muted);
  font-size: 10px;
  font-variant-numeric: tabular-nums;
}

/* ============================================================
   FILA DE MÚSICAS / HISTÓRICO
   ============================================================ */

.queue-list,
.history-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  overflow-y: auto;
}

.queue-item,
.history-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 4px 0;
  border-bottom: 1px solid var(--border);
}

.queue-item:last-child,
.history-item:last-child {
  border-bottom: none;
}

.queue-track-info {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.queue-track-info .queue-position {
  font-size: 10px;
  color: var(--text-muted);
  width: 8px;
  flex-shrink: 0;
}

.queue-track-info img,
.queue-thumb-fallback {
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  border-radius: 6px;
  object-fit: cover;
  background: var(--bg);
}

.queue-thumb-fallback {
  display: grid;
  place-items: center;
  color: var(--text-muted);
}

.queue-track-info .title,
.history-item .title {
  font-size: 11px;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.queue-track-info .requester,
.history-item .requester {
  font-size: 10px;
  color: var(--accent);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.queue-duration,
.history-item-time {
  font-size: 11px;
  color: var(--text-muted);
  flex-shrink: 0;
  font-variant-numeric: tabular-nums;
}

.queue-empty,
.history-empty {
  padding: 24px 10px;
  color: var(--text-muted);
  font-size: 12px;
  text-align: center;
}

footer.site-footer {
  padding: 20px 32px;
  font-size: 11px;
  color: var(--text-muted);
  border-top: 1px solid var(--border);
  display: flex;
  justify-content: space-between;
}

/* ============================================================
   MODO DE TESTE
   ============================================================ */

.test-panel {
  margin: 0 32px 24px;
  padding: 20px;
  border: 1px solid rgba(246, 196, 83, 0.24);
  border-radius: var(--radius-lg);
  background: linear-gradient(145deg, rgba(246, 196, 83, 0.05), transparent 40%), var(--surface);
}

.test-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 20px;
  margin-bottom: 16px;
}

.test-header h2 {
  margin: 0;
  font-size: 1rem;
  color: var(--text);
}

.test-header p {
  margin: 5px 0 0;
  color: var(--text-muted);
  font-size: 0.76rem;
}

.test-badge {
  padding: 6px 10px;
  border: 1px solid rgba(246, 196, 83, 0.3);
  border-radius: 7px;
  background: var(--warning-soft);
  color: #f5d67e;
  font-size: 0.62rem;
  font-weight: 850;
  letter-spacing: 0.06em;
}

.test-warning {
  display: flex;
  gap: 9px;
  margin-bottom: 14px;
  padding: 10px 12px;
  border: 1px solid rgba(246, 196, 83, 0.2);
  border-radius: 10px;
  background: var(--warning-soft);
  color: #d9c48a;
  font-size: 0.73rem;
}

.test-section {
  padding: 14px 0;
  border-top: 1px solid var(--border);
}

.test-section:first-of-type {
  border-top: 0;
}

.test-section h3 {
  margin: 0 0 3px;
  color: var(--text);
  font-size: 0.82rem;
}

.test-section p {
  margin: 0 0 10px;
  color: var(--text-muted);
  font-size: 0.72rem;
}

.test-log {
  min-height: 120px;
  max-height: 240px;
  margin: 0;
  overflow: auto;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: #07080b;
  color: #9ca4b2;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  line-height: 1.55;
  white-space: pre-wrap;
  word-break: break-word;
}

/* ============================================================
   BOTOES GENERICOS (login/cadastro/plataforma/modais)
   ============================================================ */

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 39px;
  padding: 9px 15px;
  border: 1px solid transparent;
  border-radius: 10px;
  font-size: 0.78rem;
  font-weight: 700;
  line-height: 1;
  transition: transform 0.16s ease, background 0.16s ease, border-color 0.16s ease, box-shadow 0.16s ease, color 0.16s ease;
}

.button:hover {
  transform: translateY(-1px);
}

.button:active {
  transform: translateY(0);
}

.button:focus-visible,
input:focus-visible {
  outline: 2px solid rgba(254, 44, 85, 0.65);
  outline-offset: 2px;
}

.button-primary {
  border-color: rgba(254, 44, 85, 0.45);
  background: var(--accent);
  color: white;
  box-shadow: 0 8px 20px rgba(254, 44, 85, 0.22);
}

.button-primary:hover {
  background: var(--accent-hover);
}

.button-secondary {
  border-color: var(--border-strong);
  background: rgba(255, 255, 255, 0.045);
  color: var(--text-muted);
}

.button-secondary:hover {
  border-color: rgba(255, 255, 255, 0.2);
  background: rgba(255, 255, 255, 0.08);
  color: var(--text);
}

.button-danger-outline {
  color: var(--danger);
  border-color: rgba(239, 68, 68, 0.35);
  background: rgba(239, 68, 68, 0.07);
}

.button-danger-outline:hover {
  color: #fff;
  background: var(--danger);
  border-color: var(--danger);
}

.button-danger-solid {
  width: 100%;
  background: var(--danger);
  color: #fff;
  border-color: var(--danger);
}

.button-danger-solid:hover {
  background: #ff6b6b;
  border-color: #ff6b6b;
}

/* ============================================================
   FORMULARIOS (login/cadastro/modais)
   ============================================================ */

.form-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 12px;
}

.form-field label {
  color: var(--text-muted);
  font-size: 0.7rem;
  font-weight: 650;
}

.form-field input {
  width: 100%;
  min-width: 0;
  min-height: 38px;
  padding: 9px 11px;
  border: 1px solid var(--border-strong);
  border-radius: 9px;
  outline: none;
  background: rgba(0, 0, 0, 0.18);
  color: var(--text);
  font-size: 0.78rem;
  transition: border-color 0.16s ease, background 0.16s ease, box-shadow 0.16s ease;
}

.form-field input::placeholder {
  color: #5f6673;
}

.form-field input:focus {
  border-color: rgba(254, 44, 85, 0.5);
  background: rgba(0, 0, 0, 0.26);
  box-shadow: 0 0 0 3px rgba(254, 44, 85, 0.1);
}

/* ============================================================
   ERROR / SUCCESS BANNER
   ============================================================ */

.error-banner {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  margin: 0 32px 16px;
  padding: 13px 15px;
  border: 1px solid rgba(239, 68, 68, 0.3);
  border-left: 3px solid var(--danger);
  border-radius: var(--radius-md);
  background: var(--danger-soft);
  color: #ffb3b3;
  font-size: 0.84rem;
}

.error-banner [data-icon] {
  margin-top: 1px;
  color: var(--danger);
}

.success-banner {
  background: var(--success-soft) !important;
  border-color: rgba(16, 185, 129, 0.3) !important;
  border-left-color: var(--success) !important;
  color: #a7ecc4 !important;
}

.success-banner [data-icon] {
  color: var(--success) !important;
}

/* ============================================================
   LOGIN / CADASTRO / RECUPERACAO
   ============================================================ */

.login-wrapper {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
}

.login-card {
  width: 100%;
  max-width: 340px;
  padding: 38px 34px;
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  background: linear-gradient(160deg, rgba(255, 255, 255, 0.03), rgba(255, 255, 255, 0)), var(--surface);
  box-shadow: var(--shadow-md);
  text-align: center;
}

.login-title {
  margin: 0 0 4px;
  color: var(--text);
  font-size: 1.3rem;
  font-weight: 750;
}

.login-subtitle {
  margin: 0 0 22px;
  color: var(--text-muted);
  font-size: 0.82rem;
}

.login-card .form-field {
  align-items: center;
  text-align: left;
}

.login-card .form-field label,
.login-card .form-field input {
  width: 88%;
  margin: 0 auto;
}

.login-submit {
  width: 88%;
  margin: 6px auto 0;
}

.login-card .error-banner {
  margin: 0 0 16px;
  text-align: left;
}

.login-links {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 18px;
  font-size: 0.78rem;
}

.login-links a {
  color: var(--text-muted);
  text-decoration: none;
}

.login-links a:hover {
  color: var(--accent);
  text-decoration: underline;
}

.login-links-sep {
  color: var(--text-muted);
}

/* ============================================================
   MODAIS
   ============================================================ */

.modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: none;
  align-items: flex-start;
  justify-content: center;
  padding: 40px 16px;
  overflow-y: auto;
  background: rgba(4, 5, 6, 0.74);
  backdrop-filter: blur(4px);
}

.modal-overlay.open {
  display: flex;
}

.modal-card {
  width: 100%;
  max-width: 640px;
  overflow: hidden;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-xl);
  background: linear-gradient(160deg, rgba(255, 255, 255, 0.035), rgba(255, 255, 255, 0)), var(--surface);
  box-shadow: var(--shadow-md);
}

#delete-account-modal .modal-card,
#twofa-disable-modal .modal-card {
  max-width: 420px;
}

#twofa-setup-modal .modal-card {
  max-width: 460px;
}

#manage-gifts-modal .modal-card {
  max-width: 560px;
}

.modal-header {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 20px 22px;
  border-bottom: 1px solid var(--border);
}

.modal-header::before {
  position: absolute;
  inset: 0 0 auto;
  height: 2px;
  background: var(--accent);
  content: "";
}

.modal-header h2 {
  margin: 0;
  color: var(--text);
  font-size: 1.05rem;
  font-weight: 720;
}

.modal-close {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  flex-shrink: 0;
  border: none;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.05);
  color: var(--text-muted);
}

.modal-close:hover {
  color: var(--text);
  background: rgba(255, 255, 255, 0.1);
}

.modal-body {
  max-height: 70vh;
  padding: 22px;
  margin-bottom: 14px;
  overflow-y: auto;
  overflow-x: hidden;
}

.modal-lead {
  margin: 0 0 16px;
  color: var(--text-muted);
  font-size: 0.84rem;
  line-height: 1.6;
}

.modal-hint {
  margin: 0 0 6px;
  color: var(--text-muted);
  font-size: 0.72rem;
}

.modal-secret {
  margin: 0 0 16px;
}

#twofa-secret-text {
  word-break: break-all;
}

.twofa-qr-wrap {
  display: flex;
  justify-content: center;
  margin-bottom: 16px;
  padding: 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: rgba(255, 255, 255, 0.02);
}

#twofa-qr-image {
  width: 200px;
  height: 200px;
  border-radius: 12px;
  background: #fff;
  padding: 10px;
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.3);
}

.twofa-backup-list {
  margin: 14px 0;
}

.help-section {
  margin-bottom: 26px;
}

.help-section:last-child {
  margin-bottom: 0;
}

.help-section h3 {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 10px;
  color: var(--text);
  font-size: 0.88rem;
  font-weight: 700;
}

.help-steps {
  margin: 0;
  padding-left: 20px;
  color: var(--text-muted);
  font-size: 0.82rem;
  line-height: 1.7;
}

.help-commands {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.help-command-row {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 9px 11px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, 0.02);
}

.help-command-row code {
  flex-shrink: 0;
  min-width: 108px;
}

.help-command-row span {
  color: var(--text-muted);
  font-size: 0.79rem;
}

.help-note {
  margin: 12px 0 0;
  color: var(--text-muted);
  font-size: 0.76rem;
  line-height: 1.55;
}

.help-lead {
  margin: 0 0 12px;
  color: var(--text-muted);
  font-size: 0.82rem;
  line-height: 1.6;
}

/* Da rolagem horizontal PROPRIA para tabelas (o motivo mais comum de
   pagina inteira ganhar rolagem horizontal indevida em celular:
   tabelas nao encolhem abaixo do conteudo minimo das celulas, entao
   sem isso, a tabela empurra a PAGINA TODA pra rolar, em vez de rolar
   só ela mesma dentro do proprio card). */
.table-scroll {
  width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.help-gifts-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.78rem;
}

.help-gifts-table th {
  padding: 8px 10px;
  border-bottom: 1px solid var(--border-strong);
  color: var(--text-muted);
  font-size: 0.68rem;
  font-weight: 750;
  letter-spacing: 0.05em;
  text-align: left;
  text-transform: uppercase;
}

.help-gifts-table td {
  padding: 9px 10px;
  border-bottom: 1px solid var(--border);
  color: var(--text-muted);
}

.help-gifts-table tr:last-child td {
  border-bottom: none;
}

.help-gift-register-btn {
  padding: 5px 10px;
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.04);
  color: var(--text-muted);
  font-size: 0.7rem;
  font-weight: 650;
}

.help-gift-register-btn:hover {
  color: var(--text);
  background: rgba(255, 255, 255, 0.08);
}

.help-gift-register-btn:disabled {
  opacity: 0.5;
  cursor: default;
}

.help-about {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.02);
}

.help-about--contact {
  flex-wrap: wrap;
  row-gap: 8px;
}

.help-about-name {
  color: var(--text);
  font-size: 0.86rem;
  font-weight: 700;
}

.help-about-version {
  color: var(--text-muted);
  font-size: 0.76rem;
}

.delete-warning {
  margin: 0 0 16px;
  color: var(--text-muted);
  font-size: 0.84rem;
  line-height: 1.6;
}

.delete-warning strong {
  color: var(--danger);
}

#delete-account-modal .modal-header h2 {
  color: var(--danger);
}

/* ============================================================
   PLATAFORMA (painel do operador) -- classes reaproveitadas
   ============================================================ */

.stats-number {
  color: var(--text);
  font-size: clamp(2.1rem, 4vw, 2.8rem);
  font-weight: 800;
  letter-spacing: -0.05em;
  line-height: 1;
}

.stats-caption {
  margin-top: 7px;
  color: var(--text-muted);
  font-size: 0.77rem;
}

.stat-count {
  color: var(--text-muted);
  font-size: 0.73rem;
  font-variant-numeric: tabular-nums;
}

.dashboard-card {
  padding: 20px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--surface);
}

.card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 12px;
}

.card-icon {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  flex-shrink: 0;
  border: 1px solid rgba(254, 44, 85, 0.3);
  border-radius: 10px;
  background: var(--accent-soft);
  color: var(--accent);
}

.section-eyebrow {
  display: block;
  margin-bottom: 3px;
  color: var(--text-muted);
  font-size: 0.64rem;
  font-weight: 800;
  letter-spacing: 0.13em;
  line-height: 1.2;
  text-transform: uppercase;
}

.dashboard-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  min-height: 64px;
  margin-bottom: 20px;
  padding: 14px 20px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--surface);
}

.brand {
  display: flex;
  align-items: center;
  gap: 14px;
}

.brand-icon {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: 10px;
  background: var(--accent);
  color: #fff;
}

.brand-text h1 {
  margin: 0;
  font-size: clamp(1.05rem, 2vw, 1.28rem);
  font-weight: 750;
}

.brand-text span {
  display: block;
  margin-top: 2px;
  color: var(--text-muted);
  font-size: 0.78rem;
}

.header-actions {
  display: flex;
  align-items: center;
  gap: 10px;
}

.dashboard-content {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
}

/* Grid dos 4 cards de resumo do painel de plataforma -- classe PROPRIA
   (nao reaproveita .dashboard-grid, que e especifico do layout de duas
   colunas assimetricas do dashboard principal, 1.4fr/1fr). Reaproveitar
   aquele ali forcava os 4 cards de resumo em larguras desiguais, um dos
   pontos "fora do padrao" encontrados nesta revisao. */
.platform-stats-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 20px;
  margin-bottom: 20px;
}

/* Dois dos quatro cards ("Instâncias ativas agora" e "Usuários
   cadastrados") têm um número grande (.stats-number) entre o
   cabeçalho e a legenda; os outros dois ("Processo do servidor" e
   "Cota da API") vão direto do cabeçalho pra legenda, sem esse
   número -- isso fazia a legenda de cada card comecar numa altura
   diferente, ficando visualmente desalinhada quando os 4 cards
   aparecem lado a lado na mesma linha da grade (mais perceptivel no
   ultimo card, "Cota da API"). Como os cards de uma linha de CSS
   Grid ja esticam pra mesma altura por padrao, transformar cada card
   numa coluna flex com o conteudo espalhado do topo ao fundo faz a
   legenda de TODOS ficarem sempre na mesma altura (rente ao fundo do
   card), tenha ou nao o numero grande no meio. */
.platform-stats-grid .dashboard-card {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

@media (max-width: 900px) {
  .platform-stats-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 480px) {
  .platform-stats-grid {
    grid-template-columns: 1fr;
  }
}

/* Sem isso, as secoes fora do grid de resumo (Instancias de bot,
   Usuarios) ficavam coladas umas nas outras, sem nenhum respiro entre
   elas -- inconsistente com o espacamento de 20px usado em todo o
   resto do app (grids, colunas, etc.). Ultimo filho nao precisa de
   margem embaixo (o rodape ja tem seu proprio espacamento). */
main.dashboard-content>.dashboard-card {
  margin-bottom: 20px;
}

main.dashboard-content>.dashboard-card:last-of-type {
  margin-bottom: 0;
}

.dashboard-footer {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin: 26px 0 4px;
  padding-top: 20px;
  border-top: 1px solid var(--border);
  color: var(--text-muted);
  font-size: 0.68rem;
}

.footer-separator {
  opacity: 0.45;
}

/* ============================================================
   RESPONSIVIDADE
   ============================================================ */

@media (max-width: 1100px) {

  .dashboard-grid,
  .row-2-wrapper {
    grid-template-columns: 1fr;
  }

  /* "Achatam" os agrupamentos em colunas para que cada card vire um
     item direto do grid principal -- assim da para reordenar TODOS os
     cards livremente com "order", nao so os dois grupos (coluna
     esquerda/direita) como blocos inteiros. display:contents remove a
     CAIXA do wrapper mas mantem os filhos no lugar, entao o gap do
     .dashboard-grid continua se aplicando entre os cards normalmente. */
  .col-left,
  .col-right,
  .row-2-wrapper {
    display: contents;
  }

  /* Ordem pensada para quem esta monitorando uma live: o que muda em
     tempo real primeiro (tocando agora, fila, eventos, estatisticas),
     o que se configura uma vez e raramente se olha de novo por
     ultimo (presentes, configuracoes, conta), historico ainda depois. */
  #tocando-agora {
    order: 1;
  }

  #fila {
    order: 2;
  }

  #eventos {
    order: 3;
  }

  #estatisticas {
    order: 4;
  }

  #presentes {
    order: 5;
  }

  #configuracoes {
    order: 6;
  }

  #conta {
    order: 7;
  }

  /* Cards de CONTEUDO FIXO (sem lista rolavel dentro) podem virar altura
     automatica com seguranca. */
  .card-spread {
    height: auto;
  }

  .row-1-card:not(.card-spread) {
    height: 300px;
  }

  .row-2-card:not(.card-spread) {
    height: 220px;
  }

  .row-3-card:not(.card-spread) {
    height: 320px;
  }

  #historico {
    height: 260px !important;
  }

  .album-art {
    width: 92px;
    height: 92px;
    min-width: 92px;
  }
}

@media (max-width: 900px) {
  .header-center {
    order: 3;
    width: 100%;
    justify-content: flex-start;
  }

  header.top-header {
    flex-wrap: wrap;
  }

  .gifts-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 640px) {
  header.top-header {
    padding: 12px 16px;
  }

  .help-btn span:last-child {
    display: none;
  }

  .help-btn {
    padding: 0;
    width: 36px;
    justify-content: center;
  }

  .connection-status span.status-text {
    display: none;
  }

  .dashboard-grid {
    padding: 16px;
    gap: 14px;
  }

  .row-2-wrapper {
    gap: 14px;
  }

  .card {
    padding: 16px;
  }

  .playing-container {
    flex-wrap: wrap;
  }

  .album-art {
    width: 100%;
    height: 160px;
  }

  .form-row,
  .form-row-3 {
    grid-template-columns: 1fr;
  }

  /* Telas de celular: listas ficam ainda mais baixas para caber mais
     conteudo na tela sem exigir rolagem excessiva da pagina toda --
     mas continuam com altura FIXA (nunca "auto"), pelo mesmo motivo
     explicado no breakpoint de 1100px. */
  .row-1-card:not(.card-spread) {
    height: 260px;
  }

  .row-2-card:not(.card-spread) {
    height: 200px;
  }

  .row-3-card:not(.card-spread) {
    height: 280px;
  }

  #historico {
    height: 220px !important;
  }

  footer.site-footer {
    flex-direction: column;
    gap: 4px;
    padding: 16px;
  }
}

@media (max-width: 420px) {
  .gifts-grid {
    grid-template-columns: 1fr;
  }

  .logo-text p {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ============================================================
   RESPONSIVIDADE FINAL — PROTEÇÃO CONTRA OVERFLOW HORIZONTAL
   ============================================================
   Este bloco fica por último para prevalecer sobre regras anteriores.
   Objetivos:
   - nenhum card/grid pode empurrar a viewport para os lados;
   - grids sempre usam minmax(0, 1fr);
   - textos/URLs longas podem quebrar;
   - tabelas podem rolar SOMENTE dentro do próprio .table-scroll;
   - cabeçalho e formulários se adaptam progressivamente;
   - preserva a identidade visual e os IDs/classes usados pelo JS.
   ============================================================ */

/* ---------- Base anti-overflow ---------- */

html,
body {
  width: 100%;
  max-width: 100%;
  min-width: 0;
  overflow-x: hidden;
}

body.dashboard-page,
body.dashboard-page>main {
  min-width: 0;
  width: 100%;
  max-width: 100%;
}

body.dashboard-page>main {
  overflow-x: hidden;
}

main,
header,
section,
article,
aside,
footer,
div,
form,
fieldset,
.card,
.dashboard-grid,
.col-left,
.col-right,
.row-2-wrapper,
.test-panel,
.modal-overlay,
.modal-card,
.modal-header,
.modal-body {
  min-width: 0;
  max-width: 100%;
}

img,
svg,
video,
canvas {
  max-width: 100%;
}

button,
input,
select,
textarea {
  max-width: 100%;
}

p,
h1,
h2,
h3,
h4,
h5,
h6,
span,
label,
a,
code {
  min-width: 0;
  overflow-wrap: anywhere;
}

code {
  word-break: break-word;
}

/* ---------- Dashboard principal ---------- */

.dashboard-grid {
  width: 100%;
  min-width: 0;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
}

.dashboard-grid>*,
.col-left>*,
.col-right>*,
.row-2-wrapper>* {
  min-width: 0;
  max-width: 100%;
}

.card {
  width: 100%;
  min-width: 0;
  max-width: 100%;
  overflow: hidden;
}

.card-header-flex,
.card-header,
.playing-container,
.player-controls,
.volume-container,
.input-wrapper,
.switch-group,
.event-item,
.queue-item,
.history-item,
.manage-gift-row,
.test-header,
.test-warning,
.help-about {
  min-width: 0;
  max-width: 100%;
}

.card-header-flex>*,
.card-header>*,
.playing-container>*,
.player-controls>*,
.volume-container>*,
.input-wrapper>*,
.event-item>*,
.queue-item>*,
.history-item>*,
.manage-gift-row>*,
.test-header>*,
.test-warning>*,
.help-about>* {
  min-width: 0;
}

/* O campo range nunca deve criar largura intrínseca. */
.volume-container input[type="range"] {
  width: 100%;
  min-width: 0;
}

/* ---------- Header ---------- */

header.top-header {
  width: 100%;
  min-width: 0;
}

.header-brand {
  flex: 1 1 auto;
  min-width: 0;
}

.header-center {
  min-width: 0;
}

.logo-text {
  min-width: 0;
  max-width: 100%;
}

.user-menu-wrap {
  min-width: 36px;
}

.btn-logout-header,
.help-btn,
.icon-btn {
  max-width: 100%;
}

/* ---------- Formulários ---------- */

.input-wrapper {
  width: 100%;
}

.input-wrapper input,
.form-row input,
.form-row-3 input,
.form-field input,
.form-field select,
.input-group input {
  box-sizing: border-box;
  width: 100%;
  min-width: 0;
  max-width: 100%;
}

.form-row,
.form-row-3 {
  width: 100%;
  min-width: 0;
}

.form-row>*,
.form-row-3>* {
  min-width: 0;
  max-width: 100%;
}

/* ---------- Listas ---------- */

.event-list,
#today-stats,
.queue-list,
.history-list,
.manage-gifts-list,
.test-log {
  width: 100%;
  min-width: 0;
  max-width: 100%;
  overflow-x: hidden;
}

.event-desc,
.queue-track-info,
.history-item>*,
.queue-item>* {
  min-width: 0;
  max-width: 100%;
}

.queue-track-info .title,
.queue-track-info .requester,
.history-item .title,
.history-item .requester,
.stats-top-list li span:first-child,
.manage-gift-row-info {
  min-width: 0;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.test-log {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  word-break: break-word;
}

/* ---------- Presentes ---------- */

.gifts-grid {
  width: 100%;
  min-width: 0;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.gift-card {
  min-width: 0;
  max-width: 100%;
  overflow: hidden;
}

.gift-card h4 {
  min-width: 0;
  max-width: 100%;
}

/* ---------- Modais ---------- */

.modal-overlay {
  width: 100%;
  max-width: 100%;
  min-width: 0;
  box-sizing: border-box;
  overflow-x: hidden;
}

.modal-card {
  width: min(100%, 640px);
  min-width: 0;
  max-width: 100%;
  box-sizing: border-box;
}

.modal-header {
  min-width: 0;
}

.modal-header h2 {
  min-width: 0;
  max-width: 100%;
  overflow-wrap: anywhere;
}

.modal-body {
  min-width: 0;
  max-width: 100%;
  overflow-x: hidden;
}

.table-scroll {
  width: 100%;
  min-width: 0;
  max-width: 100%;
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
}

.help-gifts-table {
  min-width: 520px;
}

/* ---------- 1100px: começa a compactação ---------- */

@media (max-width: 1100px) {
  .dashboard-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .row-2-wrapper {
    grid-template-columns: minmax(0, 1fr);
  }

  .col-left,
  .col-right,
  .row-2-wrapper {
    min-width: 0;
    max-width: 100%;
  }

  .card-spread {
    height: auto;
    min-height: 0;
  }

  .row-1-card:not(.card-spread) {
    height: 300px;
  }

  .row-2-card:not(.card-spread) {
    height: 220px;
  }

  .row-3-card:not(.card-spread) {
    height: 320px;
  }

  #historico {
    height: 260px !important;
  }
}

/* ---------- 900px: tablet ---------- */

@media (max-width: 900px) {
  header.top-header {
    flex-wrap: wrap;
    align-items: center;
  }

  .header-brand {
    flex: 1 1 auto;
    width: auto;
  }

  .header-center {
    order: 3;
    flex: 1 0 100%;
    width: 100%;
    justify-content: flex-start;
  }

  .gifts-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .player-controls {
    width: 100%;
  }

  .btn-control {
    min-width: 0;
  }
}

/* ---------- 768px: tablet pequeno ---------- */

@media (max-width: 768px) {
  .dashboard-grid {
    padding: 18px;
    gap: 14px;
  }

  .card {
    padding: 17px;
  }

  .row-2-wrapper {
    gap: 14px;
  }

  .playing-container {
    align-items: center;
  }

  .track-details {
    flex: 1 1 160px;
    min-width: 0;
  }

  .player-controls {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .btn-control {
    width: 100%;
    min-width: 0;
    justify-content: center;
  }

  .volume-container {
    width: 100%;
  }

  .test-panel {
    margin-left: 18px;
    margin-right: 18px;
  }
}

/* ---------- 640px: celular ---------- */

@media (max-width: 640px) {
  body.dashboard-page>main {
    width: 100%;
  }

  header.top-header {
    padding: 12px 16px;
    gap: 10px;
  }

  .header-brand {
    flex: 1 1 calc(100% - 92px);
    max-width: calc(100% - 92px);
  }

  .header-center {
    flex: 1 0 100%;
  }

  .help-btn {
    width: 36px;
    height: 36px;
    padding: 0;
    justify-content: center;
  }

  .help-btn span:last-child,
  .connection-status .status-text {
    display: none;
  }

  .dashboard-grid {
    padding: 14px;
    gap: 12px;
  }

  .row-2-wrapper {
    gap: 12px;
  }

  .card {
    padding: 15px;
    border-radius: 12px;
  }

  .card-header-flex {
    gap: 8px;
  }

  .card-header-flex>.card-title {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* Capa ocupa a largura disponível sem ultrapassar o card. */
  .playing-container {
    width: 100%;
    flex-wrap: wrap;
    gap: 12px;
  }

  .album-art {
    width: 100%;
    min-width: 0;
    max-width: 100%;
    height: 150px;
  }

  .track-details {
    width: 100%;
    flex: 1 1 100%;
  }

  .track-details h3,
  .track-details p {
    max-width: 100%;
  }

  .player-controls {
    width: 100%;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 7px;
  }

  .btn-control {
    min-width: 0;
    padding: 7px 8px;
  }

  .volume-container {
    gap: 8px;
  }

  .volume-container input[type="range"] {
    flex: 1 1 auto;
    width: 1%;
  }

  .input-wrapper {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
  }

  .input-wrapper input {
    min-width: 0;
  }

  .form-row,
  .form-row-3 {
    grid-template-columns: minmax(0, 1fr);
  }

  .gifts-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .gift-meta {
    flex-wrap: wrap;
  }

  .test-panel {
    margin: 0 14px 18px;
    padding: 15px;
  }

  .test-header {
    align-items: flex-start;
    gap: 10px;
  }

  .test-badge {
    flex-shrink: 0;
  }

  .modal-overlay {
    padding: 12px 10px;
    align-items: flex-start;
  }

  .modal-card {
    width: 100%;
    max-width: 100%;
    border-radius: 14px;
  }

  .modal-header {
    padding: 16px;
    gap: 10px;
  }

  .modal-body {
    max-height: calc(100dvh - 100px);
    padding: 16px;
  }

  .manage-gift-row {
    gap: 7px;
    padding: 8px;
  }

  .manage-gift-row-exclusive-badge {
    display: none;
  }

  footer.site-footer {
    padding: 14px;
  }
}

/* ---------- 480px: celular estreito ---------- */

@media (max-width: 480px) {
  header.top-header {
    padding-left: 12px;
    padding-right: 12px;
  }

  .header-brand {
    max-width: calc(100% - 86px);
  }

  .logo-icon,
  .icon-btn,
  .help-btn {
    width: 34px;
    height: 34px;
  }

  .dashboard-grid {
    padding: 10px;
    gap: 10px;
  }

  .card {
    padding: 13px;
  }

  .row-2-wrapper {
    gap: 10px;
  }

  .gifts-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 7px;
  }

  .gift-card {
    padding: 8px 6px;
  }

  .gift-card-emoji {
    font-size: 18px;
  }

  .gift-card h4 {
    font-size: 11px;
  }

  .gift-meta {
    font-size: 10px;
  }

  .player-controls {
    grid-template-columns: minmax(0, 1fr);
  }

  .btn-control {
    min-height: 34px;
  }

  .input-wrapper {
    grid-template-columns: minmax(0, 1fr);
  }

  .input-wrapper .btn-action {
    width: 100%;
  }

  .test-header {
    flex-direction: column;
  }

  .test-badge {
    align-self: flex-start;
  }

  .modal-overlay {
    padding: 8px;
  }

  .modal-header {
    padding: 14px;
  }

  .modal-body {
    padding: 14px;
  }

  .help-about {
    align-items: flex-start;
    flex-direction: column;
  }
}

/* ---------- 360px: aparelhos muito estreitos ---------- */

@media (max-width: 360px) {
  .dashboard-grid {
    padding: 8px;
  }

  .card {
    padding: 11px;
  }

  .header-brand {
    gap: 7px;
    max-width: calc(100% - 80px);
  }

  .logo-text h1 {
    font-size: 12px;
  }

  .logo-text p {
    display: none;
  }

  .gifts-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .connection-status {
    padding-left: 9px;
    padding-right: 9px;
  }

  .modal-overlay {
    padding: 5px;
  }

  .modal-header {
    padding: 12px;
  }

  .modal-body {
    padding: 12px;
  }
}

/* ---------- Acessibilidade / movimento reduzido ---------- */

@media (prefers-reduced-motion: reduce) {

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ============================================================
   AJUSTE FINAL — DESKTOP NORMAL + BARRA DE ROLAGEM NO CANTO
   ============================================================ */

/*
 * O scrollbar-gutter: stable no <html> estava reservando uma faixa
 * permanente dentro da viewport. Como o dashboard usa o <main> como
 * área de rolagem, isso fazia a barra vertical do dashboard parecer
 * afastada da borda direita da tela.
 *
 * A reserva continua sendo usada somente nas listas internas onde ela
 * realmente é necessária.
 */
html {
  scrollbar-gutter: auto;
}

/*
 * Entre 901px e 1100px continua sendo DESKTOP.
 *
 * O breakpoint anterior de 1100px transformava o dashboard em uma única
 * coluna e usava display:contents nos agrupamentos. Em monitores/desktop
 * menores isso fazia o layout parecer "mobile/tablet".
 *
 * O layout de duas colunas agora permanece até 900px.
 */
@media (min-width: 901px) and (max-width: 1100px) {

  .dashboard-grid {
    grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
    padding: 24px 28px;
    gap: 20px;
  }

  .col-left,
  .col-right {
    display: flex;
    flex-direction: column;
    gap: 20px;
    min-width: 0;
  }

  .row-2-wrapper {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 20px;
    min-width: 0;
  }

  /* Retorna as alturas normais do desktop. */
  .row-1-card {
    height: 350px;
  }

  .row-2-card {
    height: 180px;
  }

  .row-3-card {
    height: 380px;
  }

  .card-spread {
    height: auto;
  }

  .row-1-card:not(.card-spread) {
    height: 350px;
  }

  .row-2-card:not(.card-spread) {
    height: 220px;
  }

  .row-3-card:not(.card-spread) {
    height: 320px;
  }

  #historico {
    height: 260px !important;
  }

  /* Desfaz o order usado exclusivamente no modo de uma coluna. */
  #tocando-agora,
  #fila,
  #eventos,
  #estatisticas,
  #presentes,
  #configuracoes,
  #conta {
    order: initial;
  }
}

/*
 * Garante que a área de rolagem principal ocupe exatamente a viewport,
 * sem criar uma segunda faixa deslocada da borda.
 */
body.dashboard-page>main {
  width: 100%;
  max-width: 100%;
  min-width: 0;
  scrollbar-gutter: auto;
}

/*
 * A proteção contra overflow horizontal permanece ativa, mas sem
 * interferir no posicionamento da barra vertical principal.
 */
body.dashboard-page {
  width: 100%;
  max-width: 100%;
  min-width: 0;
  overflow-x: hidden;
}

/* ============================================================
   BARRA DE ROLAGEM -- fina, no estilo escuro do resto do app, e
   colada corretamente no canto da pagina (SEM o truque de
   "border + background-clip: padding-box" que cria um respiro
   transparente ao redor do polegar da barra -- era exatamente esse
   respiro que fazia a barra parecer flutuar afastada da borda real
   da tela, em vez de ficar rente a ela). Aplicada de forma universal:
   pagina inteira, listas internas dos cards, modais e tabelas usam
   a mesma aparencia, consistente com a paleta escura do projeto.
   ============================================================ */

/* Firefox */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--border-strong) transparent;
}

/* Chrome, Edge, Safari (WebKit) */
*::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}

*::-webkit-scrollbar-track {
  background: transparent;
}

*::-webkit-scrollbar-thumb {
  background-color: var(--border-strong);
  border-radius: 999px;
}

*::-webkit-scrollbar-thumb:hover {
  background-color: var(--accent);
}

*::-webkit-scrollbar-corner {
  background: transparent;
}

/* ============================================================
   CORREÇÕES — CABEÇALHO, "TOCANDO AGORA" E BOTÃO SALVAR (CONTA)
   ============================================================
   Três bugs concretos encontrados nesta revisão, cada um com causa
   raiz identificada no CSS acima. Este bloco fica por último de
   propósito, para vencer a cascata sem precisar reescrever nenhuma
   regra anterior.
   ============================================================ */

/* ------------------------------------------------------------
   1) Botão "Ajuda e comandos" invadindo o botão de menu da conta
      em telas na horizontal (celulares deitados).

   Causa raiz: .help-btn e .btn-logout-header nunca tiveram
   flex-shrink:0 (só .icon-btn tinha). Como o texto deles está em
   white-space:nowrap, quando o espaço aperta o NAVEGADOR encolhe a
   CAIXA do botão mas o texto não acompanha (não pode quebrar linha)
   — o texto vaza pra fora da própria caixa e visualmente "invade" o
   botão vizinho. Isso é mais grave exatamente em celulares deitados
   (~900-930px de largura, ex. iPhone Pro Max, Pixel), uma faixa que
   ficava ACIMA do breakpoint de 900px usado para ativar a quebra de
   linha do cabeçalho — ali o cabeçalho tentava caber tudo numa linha
   só, sem poder quebrar e sem poder encolher os botões com segurança.

   Correção: impede que esses botões encolham (o texto deles é curto
   e fixo, não precisa acompanhar o restante) e permite quebra de
   linha do cabeçalho em QUALQUER largura, não só abaixo de 900px —
   assim, quando não cabe tudo numa linha, o botão inteiro pula pra
   linha de baixo (com o espaçamento normal do "gap"), em vez de ser
   espremido e vazar sobre o vizinho.
   ------------------------------------------------------------ */
header.top-header {
  flex-wrap: wrap;
  row-gap: 10px;
}

.help-btn,
.btn-logout-header {
  flex-shrink: 0;
}

/* Celulares na horizontal especificamente (altura baixa é o sinal
   mais confiável de "celular deitado", já que a largura sozinha
   também aparece em tablets retrato, que têm espaço de sobra).
   Aqui comprime ainda mais o cabeçalho: some com os rótulos de texto
   e deixa só os ícones, do mesmo jeito que já acontecia em telas
   estreitas na vertical — só que agora baseado na altura da tela, não
   na largura. */
@media (orientation: landscape) and (max-height: 500px) {
  header.top-header {
    padding: 10px 20px;
    row-gap: 8px;
  }

  .header-center {
    order: 3;
    flex: 1 0 100%;
    width: 100%;
    justify-content: flex-start;
  }

  .help-btn span:last-child,
  .connection-status .status-text {
    display: none;
  }

  .help-btn,
  .icon-btn {
    width: 34px;
    height: 34px;
    padding: 0;
    justify-content: center;
  }

  /* .btn-logout-header NAO entra no grupo acima: o texto "Sair" está
     solto direto no <button> (sem um <span> proprio em volta, ao
     contrario do "Ajuda e comandos"), entao nao existe um elemento
     pra esconder e transformar o botao em icone-so. Forcar 34x34px
     aqui deixava o texto maior que a propria caixa do botao. Mantem
     o icone + "Sair" visiveis, so com um pouco menos de padding
     lateral pra caber melhor no cabecalho comprimido do landscape. */
  .btn-logout-header {
    padding: 8px 10px;
  }

  .logo-text p {
    display: none;
  }
}

/* ------------------------------------------------------------
   2) "Tocando Agora" com a capa/detalhes colados nos botões do
      player em telas menores.

   Causa raiz: .card-spread só ganha espaçamento interno via
   justify-content:space-between COMBINADO com uma altura fixa
   (350px/380px/180px no desktop). Em telas menores esse mesmo card
   vira height:auto (ver breakpoint de 1100px), e sem altura sobrando
   o space-between não tem o que distribuir — o espaçamento zera,
   porque .card nunca teve um "gap" próprio garantindo um mínimo.

   Correção: um gap fixo no .card garante uma respiração mínima entre
   todos os blocos internos (capa+detalhes, botões do player, barra de
   volume, aviso) em QUALQUER altura — auto ou fixa. Isso não remove o
   space-between: os dois convivem normalmente em flexbox (o gap é o
   mínimo garantido; o space-between só usa o espaço que sobrar além
   dele), então no desktop o efeito de "espalhar" continua igual.
   ------------------------------------------------------------ */
.card {
  gap: 16px;
}

@media (max-width: 768px) {
  .card {
    gap: 14px;
  }
}

@media (max-width: 640px) {
  .card {
    gap: 12px;
  }
}

/* ------------------------------------------------------------
   3) Botão "Salvar" (Conta a monitorar) com o texto desalinhado.

   Causa raiz: .btn-action não define display nem align-items, então
   depende do comportamento padrão do <button> do navegador. Dentro do
   .input-wrapper (que é flex com align-items:stretch, o padrão), o
   botão estica até a altura do campo de texto ao lado — mas nada
   garante que o conteúdo dele fique recentralizado dentro dessa nova
   altura, resultando no texto "flutuando" fora do centro vertical.
   O mesmo vale horizontalmente quando o botão vira width:100% nas
   telas estreitas (480px).

   Correção: define o próprio botão como inline-flex centralizado nos
   dois eixos, o que resolve pela raiz, independente de o botão ter só
   texto, ícone + texto, largura automática ou width:100%.
   ------------------------------------------------------------ */
.btn-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  text-align: center;
}

/* ------------------------------------------------------------
   4) Inputs do modal "Gerenciar presentes" desproporcionais em
      qualquer tela, retrato ou paisagem.

   Causa raiz: .form-row (grid-template-columns: minmax(0,1fr) 110px)
   foi pensada para o Modo de Teste, onde o 1º campo (Usuário) precisa
   de espaço e o 2º (Quantidade) é um número curto e fixo. O formulário
   de Gerenciar Presentes reaproveita a MESMA classe, mas com a ordem
   de necessidade invertida: o 1º campo é o ID (número curto) e o 2º é
   o Nome (texto que precisa de espaço) — só que o layout continua
   dando a coluna flexível pro 1º e a fixa de 110px pro 2º, sobrando
   espaço vazio no ID e espremendo o Nome, em qualquer largura de tela
   (o breakpoint de 640px empilha em coluna única só em telas
   estreitas na vertical; em tablets na vertical e celulares na
   horizontal, cuja largura passa de 640px mas o modal continua
   limitado a 560px de largura máxima, essa desproporção aparecia do
   mesmo jeito).

   Correção: inverte as colunas SÓ dentro deste modal (não mexe no
   .form-row do Modo de Teste, que já está correto do jeito que está),
   deixando o ID com uma coluna curta e fixa e o Nome com o espaço
   flexível que ele realmente precisa — correto em qualquer tamanho de
   tela, sem depender de breakpoint.
   ------------------------------------------------------------ */
#manage-gifts-modal .form-row {
  grid-template-columns: 96px minmax(0, 1fr);
}

/* ------------------------------------------------------------
   5) "Presentes aceitos" só mostrava os 6 primeiros presentes
      cadastrados, escondendo o resto sem nenhum aviso ou forma de
      ver os demais na propria grade.

   Causa raiz: dashboard.js limitava a lista renderizada com
   gifts.slice(0, 6) antes de desenhar a grade -- um limite artificial
   de exibicao, nao um limite de dados (o backend sempre retornava
   todos os presentes cadastrados). Removido esse corte no JS; agora
   TODOS os presentes cadastrados sao renderizados na grade.

   Sem mais nenhum ajuste, isso faria a grade crescer sem limite e
   estourar a altura fixa do card (mesma classe de bug ja corrigida
   antes em Eventos/Fila/Historico: uma lista sem `flex:1` + `overflow`
   dentro de um card de altura fixa so cresce, nunca rola por dentro).
   Aplica aqui o mesmo padrao ja usado por .event-list/.queue-list/
   .history-list/#today-stats: a grade cresce para ocupar o espaco
   sobrando no card (entre o cabecalho e o link "Ver todos os
   presentes") e rola por dentro dela mesma quando tiver mais
   presentes do que cabem. O layout visual (grade de 3 colunas com
   emoji+nome+meta) continua exatamente igual -- so ganhou rolagem
   vertical propria quando necessario.
   ------------------------------------------------------------ */
.gifts-grid {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  align-content: flex-start;
  padding-right: 4px;
  scrollbar-gutter: stable;
}

/* ============================================================
   PRESENTES ACEITOS -- tabela com rolagem vertical (em vez de grade
   de cards, que ia espremendo cada card conforme mais presentes
   eram cadastrados). Uma tabela mantem cada linha com a mesma altura
   sempre, independente da quantidade de presentes; o excesso rola
   dentro do proprio espaco reservado no card, sem nunca comprimir
   nada. Mesmo padrao de rolagem interna ja usado em Eventos/Fila/
   Historico/Estatisticas (flex:1 + overflow-y:auto dentro do card de
   altura fixa).
   ============================================================ */

.gifts-table-wrap {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding-right: 4px;
  scrollbar-gutter: stable;
}

.gifts-preview-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.78rem;
  /* table-layout:fixed + larguras definidas por coluna = previsivel: o
     nome sempre tem a mesma largura reservada, entao o truncamento com
     reticencias (na .gifts-preview-name-text) funciona de verdade, em
     vez de depender do navegador calcular a largura de cada coluna com
     base no conteudo (auto layout), que pode variar. */
  table-layout: fixed;
}

.gifts-preview-table td {
  padding: 7px 4px;
  border-bottom: 1px solid var(--border);
  color: var(--text);
  vertical-align: middle;
}

.gifts-preview-table tr:last-child td {
  border-bottom: none;
}

.gifts-preview-table td:first-child {
  width: 55%;
}

.gifts-preview-table td:nth-child(2),
.gifts-preview-table td:nth-child(3) {
  width: 22.5%;
}

.gifts-preview-name {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  overflow: hidden;
}

.gifts-preview-name-text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

.gifts-preview-meta {
  color: var(--text-muted);
  white-space: nowrap;
  text-align: right;
  padding-left: 10px;
  flex-shrink: 0;
}

/* ============================================================
   EVENTO CLICAVEL -- presente nao cadastrado no log de Eventos do
   bot. Sem isso, a linha era so texto: se a pessoa fechasse o modal
   de cadastro sem agir na hora, a informacao ficava inacessivel depois.
   Agora da pra voltar e clicar na linha a qualquer momento, mesmo mais
   tarde, para reabrir "Gerenciar presentes" com o ID/nome preenchidos.
   ============================================================ */
.event-item-clickable {
  cursor: pointer;
  border-radius: 6px;
  padding-left: 6px;
  padding-right: 6px;
  margin-left: -6px;
  margin-right: -6px;
  transition: background 0.14s ease;
}

.event-item-clickable:hover,
.event-item-clickable:focus-visible {
  background: var(--accent-soft);
}

.event-item-clickable:focus-visible {
  outline: 2px solid rgba(254, 44, 85, 0.5);
  outline-offset: -2px;
}

/* Presente nao cadastrado -- tom avermelhado permanente no texto (nao so
   no hover), pra chamar atencao mesmo sem precisar passar o mouse.
   Mesmo tom usado em outros avisos de atencao do app (.live-badge,
   .connection-error) para manter consistencia visual. */
.event-item-unknown-gift .event-desc span {
  color: #ff9c9c;
}

.event-item-unknown-gift .event-desc svg {
  color: var(--danger);
}

/* ============================================================
   PRESENTES SUGERIDOS -- rolagem vertical propria (a lista ficou
   extensa demais desde que passou a vir do catalogo real do TikTok,
   em vez da lista fixa curta de antes). Cabecalho fixo (sticky) para
   continuar visivel enquanto rola, mantendo organizado mesmo com
   dezenas de linhas.
   ============================================================ */
.suggested-gifts-scroll {
  max-height: 320px;
  overflow-y: auto;
  scrollbar-gutter: stable;
}

.suggested-gifts-scroll thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--surface);
}

/* ============================================================
   LOGIN COM GOOGLE -- divisor "ou" entre o formulario normal e o
   botao de OAuth, e o botao em si (um <a>, nao <button>, ja que o
   fluxo e um redirecionamento de pagina inteira, nao uma chamada
   fetch/JSON -- por isso precisa de reset de sublinhado/cor de link).
   ============================================================ */
.login-divider {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 14px 0;
  color: var(--text-muted);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.login-divider::before,
.login-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--border);
}

.google-signin-btn {
  text-decoration: none;
  width: 88%;
  margin: 0 auto;
}

.google-signin-btn:hover {
  text-decoration: none;
}
