/* O visual vem do design system publicado (@thunderx/ui), trazido como CSS puro
   em ds/thunderx.css: tokens no :root e as classes de componente (tx-btn,
   tx-card, tx-badge, tx-heading...). O bundle React que acompanha o pacote NÃO
   é usado — este renderer não tem passo de build, e as classes sozinhas dão o
   visual inteiro.

   Atualizar o design system = trocar ds/thunderx.css. O que fica AQUI é só o
   que é do app: layout das telas, casca e os poucos tokens que o pacote não
   traz. */
@import url('ds/thunderx.css');

/* As fontes são LOCAIS. Não é preferência: a CSP desta página proíbe rede, e um
   app instalado que espera o Google Fonts para desenhar o próprio nome fica feio
   offline. O bundle do design system declara as famílias mas descarta os
   @font-face (marcando-os como "unresolvable src"), então quem as serve é este
   arquivo. */
@font-face { font-family: 'Orbitron'; font-weight: 600; font-display: swap; src: url('assets/fonts/orbitron-600.woff2') format('woff2'); }
@font-face { font-family: 'Orbitron'; font-weight: 700; font-display: swap; src: url('assets/fonts/orbitron-700.woff2') format('woff2'); }
@font-face { font-family: 'Rajdhani'; font-weight: 500; font-display: swap; src: url('assets/fonts/rajdhani-500.woff2') format('woff2'); }
@font-face { font-family: 'Rajdhani'; font-weight: 600; font-display: swap; src: url('assets/fonts/rajdhani-600.woff2') format('woff2'); }
@font-face { font-family: 'Rajdhani'; font-weight: 700; font-display: swap; src: url('assets/fonts/rajdhani-700.woff2') format('woff2'); }
@font-face { font-family: 'Saira'; font-weight: 400; font-display: swap; src: url('assets/fonts/saira-400.woff2') format('woff2'); }
@font-face { font-family: 'Saira'; font-weight: 500; font-display: swap; src: url('assets/fonts/saira-500.woff2') format('woff2'); }
@font-face { font-family: 'Saira Condensed'; font-weight: 600; font-display: swap; src: url('assets/fonts/saira-condensed-600.woff2') format('woff2'); }
@font-face { font-family: 'Saira Condensed'; font-weight: 700; font-display: swap; src: url('assets/fonts/saira-condensed-700.woff2') format('woff2'); }
@font-face { font-family: 'Saira Condensed'; font-weight: 800; font-display: swap; src: url('assets/fonts/saira-condensed-800.woff2') format('woff2'); }

/* Só o que o design system não traz. Vermelho e verde são de ESTADO (erro,
   presença), não de marca, e por isso ficaram de fora do pacote. */
:root {
  --tx-red: #ff5470;
  --tx-green: #2fd6a2;

  --tx-titulo: 40px;   /* altura da titlebar própria — 40px é o valor do desenho */
  --tx-menu: 232px;      /* sidebar aberta — valor do desenho */
  --tx-menu-rail: 64px;  /* sidebar recolhida: só os ícones */
}
/* Existiu aqui um `--tx-controles`, que reservava espaço para os botões de
   janela quando eles flutuavam sobre o conteúdo. Com a titlebar própria os
   botões ganharam faixa exclusiva e a reserva deixou de fazer sentido — junto
   com a classe inteira de defeito que ela existia para evitar. */

* { box-sizing: border-box; }

/* Barra de rolagem discreta.
   A do Chromium era a última peça com cara de navegador: cinza, larga e com
   trilho sólido. Some tudo isso e fica só o polegar — 4px visíveis dentro de
   uma pista de 8px, sem trilho, na cor da marca.

   E ela SÓ APARECE QUANDO ALGUÉM VAI ROLAR (2026-08-17, pedido do Otávio):
   invisível parada, acende com o ponteiro na área ou enquanto a área rola de
   verdade — inclusive por roda e teclado, sem ponteiro nenhum, que é o que a
   classe `.rolando` marca (ver cosmeticos.js). Some sozinha ~900ms depois.

   A PISTA de 8px continua reservada mesmo com o polegar invisível, e é de
   propósito: barra que nasce e morre tirando largura faz o texto se remontar a
   cada rolagem — o defeito que o menu tinha e que custou uma rodada inteira.

   GLOBAL de propósito: cada área rolável estilizando a sua dava o mesmo
   resultado até alguém criar a próxima e esquecer — foi assim que as fileiras
   do catálogo ficaram sem barra e o resto do app não.

   NÃO usar `scrollbar-width` nem `scrollbar-color` aqui: no Chromium, definir
   qualquer um dos dois faz ele IGNORAR os pseudo-elementos abaixo, e a barra
   volta a ser a padrão. Como o único navegador que roda isto é o do Electron,
   os pseudo-elementos são o caminho com controle. */
*::-webkit-scrollbar { width: 8px; height: 8px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-corner { background: transparent; }
/* A borda transparente com `background-clip: padding-box` é o que afina o
   polegar sem afinar a área de clique: ele continua com 8px de alvo. */
*::-webkit-scrollbar-thumb {
  background-clip: padding-box;
  background-color: transparent;
  border: 2px solid transparent;
  border-radius: 8px;
  transition: background-color 0.18s ease;
}
*:hover::-webkit-scrollbar-thumb,
.rolando::-webkit-scrollbar-thumb { background-color: rgba(123, 140, 255, 0.3); }
*::-webkit-scrollbar-thumb:hover { background-color: rgba(123, 140, 255, 0.5); }

body {
  margin: 0;
  background: #04050a;
  color: var(--tx-text);
  font-family: var(--tx-font-ui);
  font-size: 15px;
  user-select: none;
  /* Titlebar em cima, e abaixo dela menu à esquerda e palco à direita. */
  display: flex;
  flex-direction: column;
  height: 100vh;
  isolation: isolate;
  overflow: hidden;
  position: relative;
}

/* ===== a camada que faz o vidro existir =====
   Quatro brilhos radiais atrás de TUDO — azul em cima à esquerda, violeta em
   cima à direita, verde-água embaixo à direita, rosa embaixo à esquerda.
   Não é enfeite: `backdrop-filter` desfoca o que está atrás, e sem nada atrás
   toda superfície de vidro do app renderiza como retângulo chapado. Era isto
   que faltava — o app tinha o desfoque, não tinha o que desfocar. */
body::before {
  content: "";
  inset: 0;
  pointer-events: none;
  position: absolute;
  z-index: -1;
  background:
    radial-gradient(58% 46% at 12% 8%, rgba(61, 90, 254, 0.30), transparent 68%),
    radial-gradient(48% 44% at 88% 14%, rgba(124, 58, 237, 0.26), transparent 66%),
    radial-gradient(60% 50% at 76% 88%, rgba(47, 214, 162, 0.14), transparent 70%),
    radial-gradient(52% 42% at 24% 92%, rgba(255, 84, 112, 0.12), transparent 68%),
    #04050a;
}

/* `relative` porque o menu é absoluto dentro dele: a trilha de 64px que o palco
   reserva na margem é o lugar do menu recolhido. */
.corpo { display: flex; flex: 1; min-height: 0; position: relative; }
/* O menu NÃO precisa desviar de nada: os controles flutuam no canto direito, e
   o topo da faixa deixou de ser região de arrasto (ver `.titulo`). Ele tinha
   +40px aqui enquanto a barra invisível existia. */

.oculto { display: none !important; }

/* ===== controles de janela =====
   SEM BARRA: nem fundo, nem borda, nem marca, nem nome de tela. Decisão do
   Otávio, repetida em 2026-08-15 — o topo do app é conteúdo, e os três
   controles flutuam sobre ele no canto direito.

   O que mudou nesta rodada foi só o que NÃO se vê. Esta faixa carregava
   `-webkit-app-region: drag` na largura inteira, e isso é uma BARRA INVISÍVEL:
   região de arrasto não é CSS, é uma área que o Chromium entrega ao
   gerenciador de janelas, e clique que cai nela nunca chega ao conteúdo. Dava
   no que o Otávio viu: botão desenhado, visível, e o clique não fazia nada —
   pior na lista de conversas do Social, que começa em y=0, e em qualquer coisa
   que subisse com a rolagem.

   Agora a faixa é só um trilho para posicionar os controles: `pointer-events:
   none`, sem arrasto. Quem arrasta é o punho ao lado dos botões, e o que fica
   morto é o canto direito (punho + 3 botões), onde nenhuma tela põe nada. */
.titulo {
  align-items: center;
  display: flex;
  height: var(--tx-titulo);
  justify-content: flex-end;
  left: 0;
  pointer-events: none;
  position: absolute;
  right: 0;
  top: 0;
  z-index: 40;
}

/* O `padding-left` é o punho de arrastar: 72px invisíveis colados nos botões.
   Ele existe porque janela sem moldura precisa de ALGUM lugar de onde se
   puxa — e este é o único canto do app onde não mora nada clicável. */
.controles {
  -webkit-app-region: drag;
  display: flex;
  margin-left: auto;
  padding-left: 72px;
  pointer-events: auto;
}
.controle {
  -webkit-app-region: no-drag;
  align-items: center;
  background: none;
  border: none;
  color: var(--tx-text-muted);
  cursor: pointer;
  display: flex;
  height: var(--tx-titulo);
  justify-content: center;
  padding: 0;
  width: 46px;
}
.controle:hover { background: rgba(255, 255, 255, 0.08); color: var(--tx-text); }
/* Vermelho só no fechar, e só no hover: é a convenção do Windows, e o usuário
   não deve precisar ler o ícone para saber qual é o botão perigoso. */
.controle.fechar:hover { background: #e81123; color: #fff; }

@keyframes txbrilho { to { background-position: -200% 0; } }
@keyframes txsurge { from { opacity: 0; } to { opacity: 1; } }

/* ===== menu lateral =====
   Ele MORA RECOLHIDO na trilha de 64px e abre com o ponteiro em cima (ou com o
   foco do teclado dentro dele). Não há mais alça, nem Ctrl B, nem estado
   guardado — 2026-08-17, pedido do Otávio.

   Aberto, ele passa POR CIMA do palco em vez de empurrá-lo: está fora do fluxo
   (`position: absolute`) e quem reserva a trilha é a margem do `#palco`. Se ele
   empurrasse, cada passada de mouse remontaria a grade de cards da tela inteira
   — o app inteiro pulando por causa de um gesto que a pessoa nem quis fazer. */
.menu {
  /* A superfície mais funda do vidro: 28px de desfoque sobre 34% de opacidade. */
  background: rgba(8, 10, 18, 0.34);
  backdrop-filter: blur(28px) saturate(1.3);
  -webkit-backdrop-filter: blur(28px) saturate(1.3);
  border-right: 1px solid rgba(146, 163, 255, 0.18);
  bottom: 0;
  display: flex;
  flex-direction: column;
  gap: 18px;
  left: 0;
  /* Corta o que ainda não coube. É o que transforma abrir em REVELAR. */
  overflow: hidden;
  padding: 14px 12px 12px;
  position: absolute;
  top: 0;
  transition: width 0.22s cubic-bezier(0.2, 0.7, 0.3, 1), box-shadow 0.22s ease;
  width: var(--tx-menu-rail);
  z-index: 30;
}
/* Abre com o ponteiro em cima, e com o foco DE TECLADO dentro — `:focus-visible`
   e não `:focus-within`, que era o defeito: clicar num item foca o botão, o foco
   não sai quando o mouse sai, e o menu ficava aberto para sempre depois da
   primeira navegação. Com `:has(:focus-visible)` quem chega de Tab continua
   vendo o menu abrir, e quem clica não fica com ele preso. */
.menu:hover,
.menu:has(:focus-visible) {
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.5);
  width: var(--tx-menu);
}

/* ===== por que o menu não sanfona =====
   O conteúdo é desenhado SEMPRE na largura aberta (208px = 232 menos os dois
   recuos de 12) e não encolhe junto com a sidebar. Assim nada se remonta no
   meio do caminho: o ícone fica parado no mesmo x nos dois estados, as linhas
   mantêm a mesma altura, e o que a trilha de 64px mostra é só o pedaço
   esquerdo de um menu que já estava pronto. Antes as peças de texto entravam e
   saíam com `display: none` — o rótulo voltava inteiro enquanto a largura ainda
   andava, cada linha se rearrumava, e era isso que dava o efeito de sanfona. */
.menu > * { flex-shrink: 0; width: calc(var(--tx-menu) - 24px); }

/* O texto some antes e volta depois: fechando, apaga rápido para o corte não
   pegar palavra pela metade; abrindo, espera a largura sair do lugar. */
.item span,
.atalho,
.nav-secao,
.conta-menu-txt,
.conta-chevron,
.atz-txt,
.atz-pista,
.atz-acao,
.voz-txt,
.voz-gente,
.voz-cameras,
.voz-som,
.voz-acoes { transition: opacity 0.16s ease 0.08s; }
.menu:not(:hover):not(:has(:focus-visible)) .item span,
.menu:not(:hover):not(:has(:focus-visible)) .atalho,
.menu:not(:hover):not(:has(:focus-visible)) .nav-secao,
.menu:not(:hover):not(:has(:focus-visible)) .conta-menu-txt,
.menu:not(:hover):not(:has(:focus-visible)) .conta-chevron,
.menu:not(:hover):not(:has(:focus-visible)) .atz-txt,
.menu:not(:hover):not(:has(:focus-visible)) .atz-pista,
.menu:not(:hover):not(:has(:focus-visible)) .atz-acao,
.menu:not(:hover):not(:has(:focus-visible)) .voz-txt,
.menu:not(:hover):not(:has(:focus-visible)) .voz-gente,
.menu:not(:hover):not(:has(:focus-visible)) .voz-cameras,
.menu:not(:hover):not(:has(:focus-visible)) .voz-som,
.menu:not(:hover):not(:has(:focus-visible)) .voz-acoes {
  opacity: 0;
  transition: opacity 0.1s ease;
}

/* O selo de não lidas é a exceção: recolhido ele vive no canto do ícone, como
   em qualquer trilha de ícones. Se ficasse na ponta da linha (que continua com
   208px), o corte o levaria junto — e o app perderia justamente o aviso de que
   alguém falou com você. */
.menu:not(:hover):not(:has(:focus-visible)) .item .selo-nao-lidas {
  font-size: 9px;
  left: 22px;
  min-width: 15px;
  padding: 1px 4px;
  position: absolute;
  top: 5px;
}

/* Rótulo de seção do menu. Agrupar "Navegar" e "Você" separa o que é lugar do
   que é seu — sem isso, seis itens em lista viram uma parede. */
.nav-secao {
  color: var(--tx-text-faint);
  font-family: var(--tx-font-ui);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.18em;
  margin: 14px 0 6px;
  padding: 0 12px;
  text-transform: uppercase;
}
.nav-secao:first-child { margin-top: 0; }

.atalho {
  border: 1px solid var(--tx-border);
  border-radius: var(--tx-radius-sm);
  color: var(--tx-text-faint);
  font-family: var(--tx-font-ui);
  font-size: 10.5px;
  letter-spacing: 0.06em;
  padding: 2px 6px;
}

/* Últimos jogados no rodapé do menu. Rola sozinho se crescer, para não empurrar
   a conta para fora da janela. */
.continuar { display: flex; flex-direction: column; min-height: 0; overflow-y: auto; }
.recente {
  align-items: center;
  background: none;
  border: none;
  border-radius: var(--tx-radius-md);
  cursor: pointer;
  display: flex;
  gap: 10px;
  padding: 6px 12px;
  text-align: left;
  width: 100%;
}
.recente:hover { background: var(--tx-surface); }
.recente-arte {
  background: var(--tx-surface-2);
  border-radius: var(--tx-radius-sm);
  flex: 0 0 44px;
  height: 26px;
  object-fit: cover;
  width: 44px;
}
.recente-txt { display: flex; flex-direction: column; min-width: 0; }
.recente-nome {
  color: var(--tx-text);
  font-size: 12.5px;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.recente-quando { color: var(--tx-text-faint); font-size: 11px; }

.nav { display: flex; flex-direction: column; gap: 2px; }
.item {
  align-items: center;
  background: none;
  border: none;
  border-radius: 10px;
  color: var(--tx-text-muted);
  cursor: pointer;
  display: flex;
  font-family: var(--tx-font-ui);
  font-size: 15px;
  font-weight: 600;
  gap: 12px;
  height: 44px;
  letter-spacing: 0.04em;
  padding: 0 12px;
  position: relative;
  text-align: left;
  width: 100%;
}
.item svg { flex: 0 0 19px; height: 19px; position: relative; width: 19px; }
.item span { flex: 1; position: relative; }
.item:hover { background: rgba(123, 140, 255, 0.07); color: var(--tx-text); }
/* Item selecionado, como no desenho. Três coisas que a versão anterior errava:
   o preenchimento tem raio 8px (não o 10 do item), a barra de acento NÃO é azul
   chapada — é o degradê da marca, com brilho — e ela não acompanha a altura da
   linha: para 9px antes de cada ponta e fica colada na borda da sidebar
   (left:-12px é exatamente o padding do menu), arredondada só do lado de
   dentro. */
/* A linha da conta (o item Perfil, desde 2026-08-15) entra por aqui em vez de
   ganhar a classe `.item`: `.item span { flex: 1 }` venceria o `flex: 0 0 28px`
   do `.avatar` por especificidade, e o disco esticaria pela linha inteira. */
.item.ativo,
.conta-menu.ativo {
  background: linear-gradient(90deg, rgba(91, 127, 255, 0.20), rgba(91, 127, 255, 0.03));
  border-radius: 8px;
  color: var(--tx-text);
}
.item.ativo::before,
.conta-menu.ativo::before {
  background: var(--tx-gradient);
  border-radius: 0 4px 4px 0;
  bottom: 9px;
  box-shadow: 0 0 14px rgba(91, 127, 255, 0.75);
  content: "";
  left: -12px;
  position: absolute;
  top: 9px;
  width: 3px;
}
.item.ativo span { font-weight: 700; }
.item.ativo svg { color: var(--tx-blue-bright); }

.selo-nao-lidas {
  background: var(--tx-blue);
  border-radius: var(--tx-radius-pill);
  color: #fff;
  font-family: var(--tx-font-ui);
  font-size: 11px;
  font-style: normal;
  font-weight: 700;
  min-width: 20px;
  padding: 2px 6px;
  text-align: center;
}

/* `margin-top: auto` gruda o rodapé embaixo sem precisar de altura fixa em cima
   — e é o que deixa a lista de recentes crescer até onde couber. Ele mora no
   BLOCO, e não em cada filho: com dois `auto` irmãos, o flex reparte a sobra
   entre eles e a barra de voz para no meio da coluna. */
.menu-rodape { display: flex; flex-direction: column; gap: 12px; margin-top: auto; }

/* A linha da conta é o gatilho inteiro — 48px, como no desenho. Foi o primeiro
   item do menu de 2026-08-15 a 09-11; hoje FECHA a coluna, último bloco do
   rodapé, com a marca no topo. O `position: relative` fica — a barra de acento
   do item ativo precisa dele. */
.conta-menu {
  align-items: center;
  background: none;
  border: none;
  border-radius: 10px;
  color: inherit;
  cursor: pointer;
  display: flex;
  gap: 10px;
  height: 48px;
  padding: 0 8px;
  position: relative;
  text-align: left;
  width: 100%;
}
.conta-menu:hover { background: rgba(123, 140, 255, 0.07); }
.conta-menu-txt { display: flex; flex: 1; flex-direction: column; gap: 1px; min-width: 0; }
.quem { color: var(--tx-text); font-family: var(--tx-font-ui); font-size: 14px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.plano { color: var(--tx-text-faint); font-size: 11px; letter-spacing: 0.04em; }
.conta-menu[aria-expanded="true"] .conta-chevron { transform: rotate(180deg); }
/* A linha da conta não muda de forma ao recolher: o avatar já nasce no mesmo x
   do ícone dos itens, e o texto ao lado apaga como todo o resto. */

/* A marca no topo do menu (2026-09-11): recolhido, o disco do raio na trilha,
   no mesmo x dos ícones; aberto, o disco dá lugar ao wordmark — os três PNGs
   do login, empilhados pelo `.logo`. Os dois vivem sobrepostos e trocam por
   opacidade, no mesmo compasso dos rótulos: quem entra espera a largura, quem
   sai apaga rápido. */
.marca-menu {
  align-items: center;
  display: flex;
  height: 48px;
  margin-bottom: 4px;
  padding: 0 8px;
  position: relative;
}
.marca-bolt {
  align-items: center;
  color: #fff;
  display: flex;
  flex-shrink: 0;
  height: 32px;
  justify-content: center;
  left: 8px;
  position: absolute;
  transition: opacity 0.16s ease 0.08s;
  width: 32px;
}
.marca-bolt svg { height: 17px; width: 17px; }
/* O X do wordmark (assets/logo-x-mark.png, recorte do logo-x.png), solto,
   com o próprio degradê — sem disco atrás. */
.marca-bolt .marca-x {
  display: block;
  height: 26px;
  object-fit: contain;
  width: 26px;
}
.marca-menu .logo { transition: opacity 0.16s ease 0.08s; width: 148px; }
.menu:not(:hover):not(:has(:focus-visible)) .marca-menu .logo { opacity: 0; transition: opacity 0.1s ease; }
.menu:hover .marca-bolt,
.menu:has(:focus-visible) .marca-bolt { opacity: 0; transition: opacity 0.1s ease; }





/* A capa é o degradê da marca esmaecendo no fundo do cartão: é ela que dá ao
   avatar o lugar de onde ele sai, meio para fora. */
.conta-pop-capa {
  background: var(--tx-gradient);
  flex-shrink: 0;
  height: 64px;
  position: relative;
}
.conta-pop-capa::after {
  background: linear-gradient(0deg, #101427, rgba(16, 20, 39, 0.15) 78%);
  content: "";
  inset: 0;
  position: absolute;
}
.conta-pop-topo { display: flex; gap: 12px; padding: 0 18px 14px; }
.conta-pop-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; padding-top: 6px; }
.conta-pop-linha { background: rgba(146, 163, 255, 0.18); height: 1px; }
.conta-pop-itens { display: flex; flex-direction: column; gap: 2px; padding: 10px; }
.conta-pop-itens .conta-pop-linha { margin: 2px 0; }
.conta-pop-item {
  align-items: center;
  background: transparent;
  border: none;
  border-radius: 8px;
  color: var(--tx-text-muted);
  cursor: pointer;
  display: flex;
  font-family: var(--tx-font-ui);
  font-size: 14px;
  font-weight: 600;
  height: 42px;
  padding: 0 12px;
  text-align: left;
  white-space: nowrap;
}
.conta-pop-item:hover { background: rgba(123, 140, 255, 0.12); color: var(--tx-text); }
.conta-pop-item.sair { color: #ff8298; }
.conta-pop-item.sair:hover { color: #fff; }

.icone {
  background: none;
  border: 1px solid transparent;
  border-radius: var(--tx-radius-md);
  color: var(--tx-text-muted);
  cursor: pointer;
  font-size: 15px;
  line-height: 1;
  padding: 7px 9px;
}
.icone:hover { background: var(--tx-surface); border-color: var(--tx-border); color: var(--tx-text); }
/* Ícones são SVG, não caractere. O ⏻ (U+23FB) não existe nas fontes de uma
   Ubuntu limpa e vira tofu — apareceu na primeira execução em Linux. */
.icone svg { display: block; }
/* Ícone ACESO = estado ligado (a tranca do canal). PERIGO = o segundo clique
   de apagar, que é o que confirma. */
.icone.aceso { color: var(--tx-blue-bright); }
.icone.perigo { border-color: rgba(255, 84, 112, 0.45); color: var(--tx-red); }
/* Renomear no lugar do título da conversa. */
.thread-renomear { font-size: 15px; max-width: 260px; padding: 6px 10px; }
/* O cadeado do canal trancado, colado no nome. Discreto: é um fato sobre o
   canal, não um aviso. */
.trancado { color: var(--tx-text-faint); flex: 0 0 auto; margin-left: 5px; }
/* A linha da sala virou botão (entra no canal). Parece texto até o ponteiro
   chegar — uma coluna de botões com moldura viraria formulário. */
.sala-abrir {
  background: none;
  border: 0;
  color: inherit;
  cursor: pointer;
  font: inherit;
  padding: 0;
  text-align: left;
}
.sala:hover { background: rgba(123, 140, 255, 0.05); }
.sala.ativa { background: rgba(123, 140, 255, 0.09); }
/* "ao vivo": ponto pulsando + palavra. Vermelho e não verde de propósito — o
   verde já quer dizer "tem gente na voz". */
.ao-vivo {
  align-items: center;
  background: rgba(255, 84, 112, 0.16);
  border-radius: 999px;
  color: var(--tx-red);
  display: inline-flex;
  font-family: var(--tx-font-ui);
  font-size: 9.5px;
  font-style: normal;
  font-weight: 700;
  gap: 4px;
  letter-spacing: 0.1em;
  margin-left: 6px;
  padding: 1px 7px 1px 5px;
  text-transform: uppercase;
  vertical-align: middle;
}
.ao-vivo::before {
  animation: pulso-vivo 2.4s ease-out infinite;
  background: var(--tx-red);
  border-radius: 50%;
  content: '';
  height: 5px;
  width: 5px;
}
@keyframes pulso-vivo {
  0% { box-shadow: 0 0 0 0 rgba(255, 84, 112, 0.5); }
  70% { box-shadow: 0 0 0 6px rgba(255, 84, 112, 0); }
  100% { box-shadow: 0 0 0 0 rgba(255, 84, 112, 0); }
}

/* ===== palco =====
   Sem padding: o catálogo sangra até a borda, e as telas de formulário criam o
   próprio respiro. */
#palco {
  flex: 1;
  /* A trilha do menu recolhido. É margem e não um vão de flex porque o menu
     está fora do fluxo — e ela some no login, quando não há menu nenhum. */
  margin-left: var(--tx-menu-rail);
  min-width: 0;
  overflow-y: auto;
}
#menu.oculto + #palco { margin-left: 0; }

/* O recuo do topo desvia dos controles flutuantes: sem ele, o canto direito de
   toda tela (o par de botões de `.tela-topo`, por exemplo) fica embaixo de
   minimizar/maximizar/fechar. */
.painel { margin: 0 auto; max-width: 880px; padding: calc(24px + var(--tx-titulo)) 24px 24px; }

.cartao {
  /* Cartão de vidro: 22px de desfoque sobre 30% de opacidade, como no desenho. */
  background: rgba(18, 22, 38, 0.30);
  backdrop-filter: blur(22px) saturate(1.3);
  -webkit-backdrop-filter: blur(22px) saturate(1.3);
  border: 1px solid rgba(146, 163, 255, 0.18);
  border-radius: var(--tx-radius-lg);
  margin-bottom: 18px;
  padding: 20px 22px;
}

h2 {
  font-family: var(--tx-font-display);
  font-size: 18px;
  letter-spacing: 1px;
  margin: 0 0 10px;
  text-transform: uppercase;
}

.dica { color: var(--tx-text-muted); font-size: 13px; line-height: 1.5; margin: 0 0 14px; }
.dica.erro { color: var(--tx-red); }
code { color: var(--tx-blue-bright); font-family: var(--tx-font-digital); font-size: 12px; }
a { color: var(--tx-blue-bright); }

/* ===== login ===== */
/* O fundo é o vídeo de raios da landing (landing/contador/bg-video-720), e o
   formulário fica CENTRADO por cima dele — a mesma cena de thunder-x.com, para
   que instalar o app não pareça chegar a outro produto.

   Isto substituiu as duas colunas portadas do protótipo `app-desktop` (arte de
   um seat desfocada à esquerda, formulário à direita). O que sobreviveu de lá
   são os materiais: campo de vidro, provedores e tipografia, logo abaixo. */
.tela-auth { height: 100%; min-height: 0; overflow: hidden; position: relative; }

.auth-video {
  height: 100%;
  inset: 0;
  object-fit: cover;
  pointer-events: none;
  position: absolute;
  width: 100%;
}
/* Véu do site, com uma mão a mais de escuro no centro: lá o miolo é um contador
   de números grandes, aqui é texto de 14px dentro de campos — sem isto o raio
   passa por trás do formulário e come o contraste. */
.auth-veu {
  inset: 0;
  pointer-events: none;
  position: absolute;
  background:
    radial-gradient(ellipse at center, rgba(8, 9, 18, 0.58) 0%, rgba(8, 9, 18, 0.88) 100%),
    linear-gradient(180deg, rgba(5, 6, 11, 0.35), transparent 30%, rgba(5, 6, 11, 0.5));
}

.auth-corpo {
  align-items: center;
  display: flex;
  height: 100%;
  justify-content: center;
  overflow-y: auto;
  /* Simétrico de propósito: o cartão fica no MEIO da janela. A faixa de
     arrastar é transparente e os controles moram no canto direito, longe de um
     cartão de 392px centrado — não há o que desviar aqui. */
  padding: 40px 24px;
  position: relative;
}
/* O cartão agora é uma superfície de verdade: por trás dele há vídeo, e o que
   era uma coluna solta sobre fundo chapado viraria texto boiando. */
.auth-cartao {
  background: rgba(12, 15, 28, 0.44);
  backdrop-filter: blur(26px) saturate(1.35);
  -webkit-backdrop-filter: blur(26px) saturate(1.35);
  border: 1px solid rgba(146, 163, 255, 0.2);
  border-radius: var(--tx-radius-lg);
  box-shadow: 0 28px 80px rgba(2, 3, 8, 0.6);
  display: flex;
  flex-direction: column;
  gap: 20px;
  margin: auto;
  max-width: 392px;
  padding: 32px 32px 28px;
  width: 100%;
}
/* Só o cabeçalho é centrado. Rótulo, erro e link continuam alinhados à
   esquerda: formulário centrado obriga o olho a procurar onde cada campo
   começa. */
.auth-topo { align-items: center; display: flex; flex-direction: column; gap: 10px; text-align: center; }
.auth-topo .dica { color: var(--tx-text-faint); margin: 0; }
.auth-lema {
  font-family: var(--tx-font-display);
  font-size: 26px;
  font-style: italic;
  font-weight: 800;
  letter-spacing: 0.02em;
  line-height: 1.05;
  margin: 0;
  text-transform: uppercase;
}
.auth-provedores { display: grid; gap: 10px; grid-template-columns: 1fr 1fr; }
/* Os provedores no desenho não são o botão secundário genérico: são a mesma
   superfície de vidro dos campos, com o texto em Rajdhani. */
.auth-provedores .provedor {
  background: rgba(10, 12, 21, 0.34);
  backdrop-filter: blur(18px) saturate(1.3);
  -webkit-backdrop-filter: blur(18px) saturate(1.3);
  border: 1px solid rgba(146, 163, 255, 0.18);
  border-radius: 10px;
  color: var(--tx-text-muted);
  cursor: pointer;
  font-family: var(--tx-font-ui);
  font-size: 13px;
  font-weight: 600;
  height: 44px;
  letter-spacing: 0.06em;
}
.auth-provedores .provedor:hover { border-color: var(--tx-border-strong); color: var(--tx-text); }

/* O logo são três PNGs empilhados — base, raio e X, na mesma ordem do site. */
.logo { position: relative; width: 224px; }
.logo img { display: block; height: auto; width: 100%; }
.logo img + img { inset: 0; position: absolute; }
/* Dentro do cartão ele divide a largura com o formulário: 224px encostaria nas
   duas bordas. */
.auth-topo .logo { margin-bottom: 2px; width: 188px; }

.tagline {
  color: var(--tx-text-muted);
  font-size: 12px;
  letter-spacing: 0.2em;
  margin: 0;
  text-transform: uppercase;
}

.auth-form { display: flex; flex-direction: column; gap: 14px; }
.grupo { display: flex; flex-direction: column; gap: 7px; }
.linha-entre { align-items: center; display: flex; gap: 12px; justify-content: space-between; }

.rotulo {
  color: var(--tx-text-faint);
  display: flex;
  flex-direction: column;
  font-family: var(--tx-font-ui);
  font-size: 10px;
  font-weight: 600;
  gap: 7px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

/* Campo de vidro: o desfoque por trás é o que dá o material do desenho — sem
   ele o campo vira um retângulo chapado, que era o nosso caso. */
.entrada {
  background: rgba(10, 12, 21, 0.34);
  backdrop-filter: blur(18px) saturate(1.3);
  -webkit-backdrop-filter: blur(18px) saturate(1.3);
  border: 1px solid rgba(146, 163, 255, 0.18);
  border-radius: 10px;
  box-sizing: border-box;
  color: var(--tx-text);
  font-family: var(--tx-font-body);
  font-size: 14px;
  height: 44px;
  outline: none;
  padding: 0 14px;
  user-select: text;
  width: 100%;
}
.entrada:focus { border-color: var(--tx-blue-bright); box-shadow: 0 0 0 3px rgba(91, 127, 255, 0.14); }

.senha-caixa { display: flex; position: relative; }
.senha-caixa .entrada { padding-right: 84px; }
.senha-ver {
  background: transparent;
  border: 1px solid transparent;
  border-radius: 8px;
  color: var(--tx-text-faint);
  cursor: pointer;
  font-family: var(--tx-font-ui);
  font-size: 10px;
  font-weight: 600;
  height: 32px;
  letter-spacing: 0.14em;
  padding: 0 10px;
  position: absolute;
  right: 6px;
  text-transform: uppercase;
  top: 6px;
}
.senha-ver:hover { border-color: var(--tx-border); color: var(--tx-blue-bright); }

.erro { color: #ff7a8a; font-size: 13px; margin: 0; }
.elo { color: var(--tx-text-faint); font-size: 12px; text-decoration: none; }
.elo:hover { color: var(--tx-blue-bright); }
.elo-forte { color: var(--tx-blue-bright); text-decoration: none; }

.btn-primario {
  background: var(--tx-gradient);
  border: none;
  border-radius: var(--tx-radius-md);
  color: #fff;
  cursor: pointer;
  font-family: var(--tx-font-ui);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.1em;
  padding: 13px;
  text-transform: uppercase;
}
.btn-primario:hover { box-shadow: var(--tx-glow); }
.btn-primario:disabled { cursor: default; opacity: 0.6; }
.btn-primario.estreito { align-self: flex-start; padding: 12px 28px; }

.btn-fantasma {
  align-items: center;
  background: transparent;
  border: 1px solid var(--tx-border);
  border-radius: var(--tx-radius-md);
  color: var(--tx-text-muted);
  cursor: pointer;
  display: flex;
  font-family: var(--tx-font-ui);
  font-size: 13px;
  font-weight: 600;
  justify-content: center;
  padding: 11px 6px;
}
.btn-fantasma:hover { border-color: var(--tx-blue-bright); color: var(--tx-blue-bright); }

.separador { align-items: center; color: var(--tx-text-faint); display: flex; font-size: 12px; gap: 12px; }
.separador::before, .separador::after { background: var(--tx-border); content: ""; flex: 1; height: 1px; }

.auth-nota { color: var(--tx-text-faint); font-size: 12px; margin: 0; min-height: 1em; text-align: center; }
.auth-alt { color: var(--tx-text-faint); font-size: 13px; margin: 0; text-align: center; }

/* ===== catálogo ===== */
.tela-catalogo { display: flex; flex-direction: column; min-height: 100%; }

.destaque {
  background: #05060b;
  flex-shrink: 0;
  height: clamp(340px, 48vh, 520px);
  overflow: hidden;
  position: relative;
}
.brilho {
  animation: txbrilho 1.4s linear infinite;
  background: linear-gradient(100deg, #10152e 40%, #1c2450 50%, #10152e 60%) 0 0 / 200% 100%;
  inset: 0;
  position: absolute;
}
.destaque-arte {
  animation: txsurge 0.4s ease both;
  height: 100%;
  inset: 0;
  object-fit: cover;
  position: absolute;
  width: 100%;
}
/* Sem arte, o card não fica branco: o degradê da marca faz as vezes de capa. */
.capa-lisa {
  inset: 0;
  position: absolute;
  background:
    radial-gradient(ellipse 80% 80% at 30% 20%, rgba(61, 90, 254, 0.18), transparent 60%),
    linear-gradient(135deg, #10152e 0%, #161a2b 55%, #1c2450 100%);
}
.cobertura {
  inset: 0;
  position: absolute;
  background:
    linear-gradient(180deg, rgba(5, 6, 11, 0.7) 0%, transparent 35%),
    linear-gradient(0deg, #05060b 0%, rgba(5, 6, 11, 0.97) 10%, rgba(5, 6, 11, 0.87) 22%, rgba(5, 6, 11, 0.7) 35%, rgba(5, 6, 11, 0.48) 48%, rgba(5, 6, 11, 0.28) 60%, rgba(5, 6, 11, 0.12) 70%, rgba(5, 6, 11, 0.03) 78%, transparent 86%),
    linear-gradient(90deg, rgba(5, 6, 11, 0.55), transparent 55%);
}
.destaque-conteudo {
  align-items: flex-start;
  bottom: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
  left: 0;
  padding: 0 64px 40px;
  position: absolute;
  right: 0;
}
.selo {
  align-self: flex-start;
  backdrop-filter: blur(14px);
  background: rgba(8, 12, 24, 0.6);
  border-radius: var(--tx-radius-pill);
  color: #eaf2ff;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  padding: 4px 12px;
  text-transform: uppercase;
}
/* O título tem o mesmo risco da descrição, e nome de jogo às vezes é uma frase
   ("Middle-earth: Shadow of Mordor - Game of the Year Edition"). Duas linhas é
   o que cabe no hero mínimo junto com o resto. */
.destaque-titulo {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  font-family: var(--tx-font-display);
  font-size: clamp(32px, 4.4vw, 54px);
  font-style: italic;
  font-weight: 800;
  line-height: 1.08;
  /* O par padding/margem existe por causa do `overflow: hidden` que o clamp
     exige: entrelinha de 1.08 e a fonte precisando de ~1.33 fazem o glifo
     passar da caixa, e o corte comia o rabo do "g" e o til do "Ã". O recorte
     acontece na borda do PADDING, então o respiro aqui e a margem negativa
     devolvendo o espaço deixam o texto inteiro sem mexer no layout. */
  margin: -0.26em 0;
  overflow: hidden;
  padding: 0.26em 0;
  text-shadow: 0 4px 30px rgba(0, 0, 0, 0.6);
  text-transform: uppercase;
}
/* DUAS LINHAS, e não "o que vier": o conteúdo do hero é ancorado no RODAPÉ
   (position: absolute; bottom: 0), então texto que sobra cresce para CIMA e
   empurra o título para fora — e o hero tem `overflow: hidden`, então o título
   simplesmente some. Com descrição de seis linhas numa janela de 660px de
   altura, o bloco media 348px dentro de um hero de 340.
   A descrição do catálogo é um parágrafo inteiro; aqui ela é chamariz. */
.destaque-desc {
  color: var(--tx-text-muted);
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  font-size: 15px;
  line-height: 1.5;
  margin: 0;
  max-width: 520px;
  overflow: hidden;
  text-shadow: 0 2px 12px rgba(0, 0, 0, 0.8);
}
.destaque-meta { color: rgba(234, 242, 255, 0.72); font-size: 14px; margin: 0; }
.destaque-desc:empty, .destaque-meta:empty { display: none; }
.destaque-acoes { align-items: center; display: flex; gap: 16px; margin-top: 8px; }
.destaque-cta {
  background: var(--tx-gradient);
  border: none;
  border-radius: var(--tx-radius-md);
  box-shadow: var(--tx-glow);
  color: #fff;
  cursor: pointer;
  font-family: var(--tx-font-ui);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.08em;
  padding: 13px 34px;
  text-transform: uppercase;
}
.destaque-cta:hover { box-shadow: var(--tx-glow-strong); }
.destaque-cta:disabled { cursor: default; opacity: 0.6; }

.pontos { display: flex; gap: 8px; }
.ponto {
  background: rgba(255, 255, 255, 0.3);
  border: none;
  border-radius: var(--tx-radius-pill);
  cursor: pointer;
  height: 6px;
  padding: 0;
  transition: width 0.2s, background 0.2s;
  width: 12px;
}
.ponto:hover { background: rgba(255, 255, 255, 0.6); }
.ponto.ativo { background: var(--tx-blue-bright); box-shadow: var(--tx-glow); width: 26px; }

.abaixo-destaque {
  background: linear-gradient(180deg, #05060b 0%, rgba(5, 6, 11, 0.97) 60px, rgba(5, 6, 11, 0.88) 160px, rgba(5, 6, 11, 0.72) 300px, rgba(5, 6, 11, 0.5) 460px, rgba(5, 6, 11, 0.28) 630px, rgba(5, 6, 11, 0.12) 790px, rgba(5, 6, 11, 0) 900px);
}
.fileiras {
  display: flex;
  flex-direction: column;
  gap: 32px;
  margin: 0 auto;
  max-width: 1600px;
  padding: 32px 48px 48px;
  width: 100%;
}
.fileira { display: flex; flex-direction: column; gap: 12px; }
.fileira-titulo {
  color: var(--tx-text-muted);
  font-family: var(--tx-font-ui);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.18em;
  margin: 0;
  text-transform: uppercase;
}

.trilho-caixa { position: relative; }
.trilho {
  /* Nº de cards inteiros por tela; a sobra do próximo é o convite pra rolar. */
  --colunas: 4;
  --sobra: 28px;
  display: flex;
  gap: 24px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
}
/* A exceção à barra discreta: a fileira tem setas próprias e a sobra do
   próximo card como convite. Uma barra sob os cards seria uma terceira pista
   dizendo a mesma coisa. */
.trilho::-webkit-scrollbar { display: none; }
.trilho > * {
  flex: 0 0 calc((100% - var(--sobra) - var(--colunas) * 24px) / var(--colunas));
  min-width: 0;
  scroll-snap-align: start;
}
@media (max-width: 1100px) { .trilho { --colunas: 3; } }
@media (min-width: 1400px) { .trilho { --colunas: 5; } }
@media (min-width: 1750px) { .trilho { --colunas: 6; } }

.seta {
  align-items: center;
  border: 0;
  bottom: 0;
  color: var(--tx-text);
  cursor: pointer;
  display: flex;
  font-size: 20px;
  justify-content: center;
  opacity: 0;
  padding: 0;
  position: absolute;
  top: 0;
  transition: opacity 0.2s;
  width: 52px;
  z-index: 2;
}
.seta.esq { background: linear-gradient(90deg, rgba(5, 6, 11, 0.85), transparent); left: 0; }
.seta.dir { background: linear-gradient(270deg, rgba(5, 6, 11, 0.85), transparent); right: 0; }
.trilho-caixa:hover .seta:not(.oculto), .seta:focus-visible { opacity: 1; }

.card {
  aspect-ratio: 16 / 9;
  background: rgba(13, 17, 38, 0.45);
  border: none;
  border-radius: 8px;
  /* O card é um <button>, e button não herda a cor do body: sem isto o Chromium
     usa `buttontext`, que é quase preto, e o nome do jogo some dentro da arte. */
  color: var(--tx-text);
  cursor: pointer;
  overflow: hidden;
  padding: 0;
  position: relative;
  text-align: left;
  width: 100%;
}
.card:disabled { cursor: default; }
.card-arte {
  animation: txsurge 0.4s ease both;
  height: 100%;
  inset: 0;
  object-fit: cover;
  position: absolute;
  transition: transform 0.35s ease;
  width: 100%;
}
.card:hover .card-arte { transform: scale(1.08); }
.card:focus-visible { outline: 2px solid var(--tx-blue-bright); outline-offset: 2px; }
.card-loja {
  backdrop-filter: blur(14px);
  background: rgba(8, 12, 24, 0.6);
  border-radius: var(--tx-radius-pill);
  color: #eaf2ff;
  font-family: var(--tx-font-ui);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.05em;
  padding: 3px 10px;
  position: absolute;
  right: 10px;
  text-transform: uppercase;
  top: 10px;
  z-index: 2;
}
.card-esmaece {
  background: linear-gradient(0deg, rgba(5, 6, 11, 0.85), transparent 45%);
  inset: 0;
  pointer-events: none;
  position: absolute;
}
.card-meta { bottom: 12px; left: 14px; pointer-events: none; position: absolute; right: 14px; }
.card-nome {
  font-family: var(--tx-font-ui);
  font-size: 15px;
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.8);
  white-space: nowrap;
}
.card-sub {
  color: var(--tx-text-muted);
  font-size: 11px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.vazio {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin: 0 auto;
  max-width: 900px;
  padding: 72px 48px;
  width: 100%;
}
.vazio-titulo {
  font-family: var(--tx-font-display);
  font-size: 32px;
  font-style: italic;
  font-weight: 800;
  line-height: 1.1;
  margin: 0;
  text-transform: uppercase;
}
.vazio-sub { color: var(--tx-text-muted); font-size: 15px; margin: 0; }

/* ===== social: Mensagens e Canais =====
   Porte de `Chat.dc.html` (2026-08-17). O desenho é uma PÁGINA: cabeçalho por
   cima e um quadro de vidro de 1260x680 embaixo. Aqui a tela é a janela, então o
   quadro cresce até a borda e a rolagem mora dentro dele — nas duas colunas,
   nunca no palco.

   O recuo do topo é o mesmo dos painéis, e pelo mesmo motivo: sem ele o canto
   direito da tela fica embaixo dos controles de janela, desenhado e sem
   responder ao clique. */
.tela-social {
  display: flex;
  flex-direction: column;
  gap: 16px;
  height: 100%;
  padding: calc(20px + var(--tx-titulo)) 24px 24px;
}

/* ===== o chat da v4, nativo (2026-09-05) =====
   Três colunas: trilho (amigos ou espaços e canais), a conversa, e o lado
   (quem está no espaço, ou o cartão do amigo). Os componentes são os do app —
   `.msg`, `.face`, `.entrada`, `.coluna-*` —, o prefixo `v4-` marca só o que
   nasceu para esta tela. Quem monta o DOM é o v4chat.js. */
.tela-v4chat {
  display: flex;
  flex-direction: column;
  height: 100%;
  padding-top: var(--tx-titulo);
}
.v4-login { align-items: center; display: flex; flex: 1; justify-content: center; }
.v4-login-caixa {
  background: rgba(10, 12, 21, 0.5);
  border: 1px solid rgba(146, 163, 255, 0.18);
  border-radius: 16px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  max-width: 360px;
  padding: 28px;
  width: 100%;
}
.v4-login-caixa h2 { margin: 0; }
.v4-quadro {
  display: grid;
  flex: 1;
  gap: 0;
  grid-template-columns: 272px minmax(0, 1fr) 232px;
  min-height: 0;
}
.v4-trilho, .v4-lado {
  border-right: 1px solid rgba(146, 163, 255, 0.12);
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow-y: auto;
  padding: 12px 10px 16px;
}
.v4-lado { border-left: 1px solid rgba(146, 163, 255, 0.12); border-right: 0; gap: 8px; }
.v4-abas { display: flex; gap: 4px; margin-bottom: 10px; }
.v4-aba {
  background: transparent;
  border: 1px solid transparent;
  border-radius: 9px;
  color: var(--tx-text-muted);
  cursor: pointer;
  flex: 1;
  font-family: var(--tx-font-ui);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.1em;
  padding: 8px 4px;
  text-transform: uppercase;
}
.v4-aba.ativa { background: rgba(61, 90, 254, 0.14); border-color: rgba(146, 163, 255, 0.22); color: var(--tx-text); }
.v4-trilho-corpo { display: flex; flex-direction: column; gap: 14px; }
.v4-trilho-acoes { display: flex; justify-content: center; padding-top: 4px; }
.v4-linha {
  align-items: center;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 12px;
  color: var(--tx-text);
  cursor: pointer;
  display: flex;
  gap: 10px;
  padding: 7px 8px;
  text-align: left;
  width: 100%;
}
.v4-linha:hover { background: rgba(123, 140, 255, 0.07); }
.v4-linha.ativa { background: rgba(61, 90, 254, 0.14); border-color: rgba(146, 163, 255, 0.22); }
.v4-linha-texto { display: flex; flex: 1; flex-direction: column; min-width: 0; }
.v4-linha-nome { align-items: center; display: flex; font-weight: 600; gap: 6px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v4-linha-sub { color: var(--tx-text-faint); font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v4-linha-sub.jogando { color: var(--tx-blue-bright); }
.v4-pedido { cursor: default; flex-wrap: wrap; }
.v4-pedido .coluna-acao { font-size: 11px; padding: 4px 10px; }
.coluna-acao.secundaria { background: transparent; color: var(--tx-text-muted); }
.v4-selo {
  background: rgba(61, 90, 254, 0.18);
  border-radius: 999px;
  color: var(--tx-blue-bright);
  font-family: var(--tx-font-ui);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.1em;
  padding: 2px 7px;
  text-transform: uppercase;
}
.v4-add { display: flex; flex-wrap: wrap; gap: 8px; }
.v4-add .entrada { flex: 1; height: 36px; min-width: 0; padding: 0 12px; }
.v4-add .coluna-acao { height: 36px; }
.v4-add .dica { flex-basis: 100%; margin: 0; }
.v4-marca {
  align-items: center;
  border-radius: 10px;
  color: #fff;
  display: inline-flex;
  flex: 0 0 auto;
  font-family: var(--tx-font-ui);
  font-size: 11px;
  font-weight: 800;
  height: 32px;
  justify-content: center;
  letter-spacing: 0.06em;
  width: 32px;
}
.v4-canais { display: flex; flex-direction: column; gap: 2px; margin: 4px 0 6px 14px; }
.v4-canais-rotulo {
  color: var(--tx-text-faint);
  font-family: var(--tx-font-ui);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.14em;
  margin: 8px 8px 2px;
  text-transform: uppercase;
}
.v4-canal {
  align-items: center;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 9px;
  color: var(--tx-text-muted);
  cursor: pointer;
  display: flex;
  font-size: 13.5px;
  gap: 7px;
  padding: 5px 8px;
  text-align: left;
  width: 100%;
}
.v4-canal:hover { background: rgba(123, 140, 255, 0.07); color: var(--tx-text); }
.v4-canal.ativa { background: rgba(61, 90, 254, 0.14); border-color: rgba(146, 163, 255, 0.22); color: var(--tx-text); }
.v4-canal-cerquilha { color: var(--tx-text-faint); flex: 0 0 auto; width: 14px; }
.v4-canal-nome { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v4-canal-cadeado, .v4-canal-conta { color: var(--tx-text-faint); font-size: 11px; }
.v4-canal-voz { cursor: default; }
.v4-canal-novo { color: var(--tx-blue-bright); font-size: 12.5px; }
.v4-na-sala { align-items: center; display: flex; gap: 6px; padding: 2px 8px 2px 26px; }
.face.mini { font-size: 9px; height: 18px; width: 18px; }
.face.grande { border-radius: 22px; font-size: 24px; height: 72px; width: 72px; }

/* a conversa */
.v4-meio { display: flex; flex-direction: column; min-height: 0; min-width: 0; }
.v4-nada { align-items: center; display: flex; flex: 1; flex-direction: column; gap: 6px; justify-content: center; }
.v4-nada h2 { margin: 0; }
.v4-conversa { display: flex; flex: 1; flex-direction: column; min-height: 0; }
.v4-explorar { display: flex; flex: 1; flex-direction: column; gap: 14px; min-height: 0; overflow-y: auto; padding: 8px 24px 24px; }
.v4-topo {
  align-items: center;
  border-bottom: 1px solid rgba(146, 163, 255, 0.12);
  display: flex;
  flex: 0 0 auto;
  gap: 10px;
  padding: 10px 16px;
}
.v4-topo-nome { font-family: var(--tx-font-ui); font-size: 16px; font-weight: 700; }
.v4-topo .icone.ativo { background: rgba(61, 90, 254, 0.18); color: var(--tx-text); }
.v4-fixados {
  background: rgba(250, 204, 21, 0.05);
  border-bottom: 1px solid rgba(250, 204, 21, 0.18);
  display: flex;
  flex: 0 0 auto;
  flex-direction: column;
  gap: 4px;
  max-height: 180px;
  overflow-y: auto;
  padding: 8px 16px;
}
.v4-fixados-rotulo { color: var(--tx-text-faint); font-size: 12px; }
.v4-fixada {
  align-items: center;
  background: rgba(10, 12, 21, 0.35);
  border: 1px solid rgba(146, 163, 255, 0.12);
  border-radius: 9px;
  color: var(--tx-text);
  cursor: pointer;
  display: flex;
  font-size: 12.5px;
  gap: 8px;
  padding: 5px 10px;
  text-align: left;
}
.v4-fixada span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v4-fixada-x { background: transparent; border: 0; color: var(--tx-text-faint); cursor: pointer; font-size: 14px; }
.v4-mensagens { flex: 1; }
.v4-anteriores {
  align-self: center;
  background: rgba(61, 90, 254, 0.12);
  border: 1px solid rgba(146, 163, 255, 0.2);
  border-radius: 999px;
  color: var(--tx-text-muted);
  cursor: pointer;
  font-family: var(--tx-font-ui);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.1em;
  margin: 8px auto;
  padding: 6px 14px;
  text-transform: uppercase;
}
.msg.fixada { background: rgba(250, 204, 21, 0.04); }
.msg.pisca { animation: txpop 0.9s ease-out; background: rgba(61, 90, 254, 0.16); }
.v4-alfinete { color: #facc15; font-size: 11px; }
.v4-acoes { display: none; gap: 2px; grid-column: 2; justify-self: end; }
.msg:hover .v4-acoes { display: flex; }
.v4-texto { white-space: pre-wrap; word-break: break-word; }
.v4-midia { display: flex; flex-direction: column; gap: 4px; max-width: 360px; }
.v4-midia-quadro {
  aspect-ratio: 16 / 10;
  background: var(--tx-surface-2) center / cover no-repeat;
  border: 1px solid rgba(146, 163, 255, 0.14);
  border-radius: 12px;
  cursor: zoom-in;
  width: 100%;
}
.v4-midia-legenda { color: var(--tx-text-faint); display: flex; font-size: 12px; justify-content: space-between; }
.v4-arquivo {
  align-items: center;
  background: rgba(10, 12, 21, 0.4);
  border: 1px solid rgba(146, 163, 255, 0.16);
  border-radius: 12px;
  color: var(--tx-text);
  cursor: pointer;
  display: flex;
  gap: 10px;
  padding: 8px 12px;
  text-align: left;
}
.v4-arquivo:disabled { cursor: default; opacity: 0.6; }
.v4-arquivo-icone { font-size: 18px; }
.v4-visualizador {
  align-items: center;
  background: rgba(3, 4, 9, 0.9);
  cursor: zoom-out;
  display: flex;
  flex-direction: column;
  gap: 12px;
  inset: 0;
  justify-content: center;
  position: fixed;
  z-index: 90;
}
.v4-visualizador img { border-radius: 10px; max-height: 88vh; max-width: 92vw; }
.v4-visualizador p { color: var(--tx-text-muted); margin: 0; }

/* efeitos de texto — os três nomes da lista branca do servidor */
@keyframes v4raio { 0%, 100% { text-shadow: 0 0 6px rgba(142, 166, 255, 0.9); } 45% { text-shadow: none; } 50% { text-shadow: 0 0 14px #fff; } 55% { text-shadow: none; } }
@keyframes v4arco { 0% { filter: hue-rotate(0deg); } 100% { filter: hue-rotate(360deg); } }
@keyframes v4pulso { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.06); } }
.v4-fx-raio { animation: v4raio 2.2s ease-in-out infinite; }
.v4-fx-arco { animation: v4arco 4s linear infinite; color: #8ea6ff; }
.v4-fx-pulso { animation: v4pulso 1.6s ease-in-out infinite; display: inline-block; }

/* o compositor */
.v4-compositor { display: flex; flex: 0 0 auto; flex-direction: column; }
.v4-compositor .respondendo { margin: 0 24px; }
.v4-form { align-items: flex-end; }
.v4-ferramentas { display: flex; flex: 0 0 auto; gap: 4px; padding-bottom: 6px; }
.v4-ferramentas .icone.ativo { background: rgba(61, 90, 254, 0.18); color: var(--tx-text); }
.v4-compositor .erro { margin: 0 24px 12px; }
.v4-estilo {
  background: rgba(10, 12, 21, 0.5);
  border-top: 1px solid rgba(146, 163, 255, 0.14);
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px 24px;
}
.v4-estilo-linha { align-items: center; display: flex; flex-wrap: wrap; gap: 6px; }
.v4-estilo-op {
  background: transparent;
  border: 1px solid rgba(146, 163, 255, 0.18);
  border-radius: 999px;
  color: var(--tx-text-muted);
  cursor: pointer;
  font-size: 12.5px;
  padding: 4px 12px;
}
.v4-estilo-op.ativa { background: rgba(61, 90, 254, 0.18); border-color: var(--tx-blue-bright); color: var(--tx-text); }
.v4-tinta {
  background: rgba(10, 12, 21, 0.5);
  border: 2px solid rgba(146, 163, 255, 0.18);
  border-radius: 50%;
  color: var(--tx-text);
  cursor: pointer;
  font-size: 12px;
  height: 26px;
  width: 26px;
}
.v4-tinta.ativa { border-color: #fff; box-shadow: var(--tx-glow); }
.v4-paleta {
  background: rgba(10, 12, 21, 0.96);
  border: 1px solid rgba(146, 163, 255, 0.22);
  border-radius: 14px;
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.55);
  display: grid;
  gap: 2px;
  grid-template-columns: repeat(10, 28px);
  padding: 8px;
  position: fixed;
  z-index: 80;
}
.v4-paleta-emoji { background: transparent; border: 0; border-radius: 7px; cursor: pointer; font-size: 18px; height: 28px; width: 28px; }
.v4-paleta-emoji:hover { background: rgba(123, 140, 255, 0.14); }

/* o lado e o explorar */
.v4-lado-titulo { font-family: var(--tx-font-ui); font-size: 15px; font-weight: 700; }
.v4-lado-desc { color: var(--tx-text-muted); font-size: 12.5px; margin: 0 0 6px; }
.v4-membro { cursor: default; padding: 4px 6px; }
.v4-cartao-amigo { align-items: center; display: flex; flex-direction: column; gap: 8px; padding: 16px 0; text-align: center; }
.v4-explorar-topo h2 { margin: 0 0 4px; }
.v4-explorar-topo .dica { margin: 0; }
.v4-busca .entrada { width: 100%; }
.v4-cartoes { display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); }
.v4-cartao {
  background: rgba(10, 12, 21, 0.4);
  border: 1px solid rgba(146, 163, 255, 0.14);
  border-radius: 14px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 14px;
}
.v4-cartao-cab { align-items: center; display: flex; gap: 10px; }
.v4-cartao-desc { color: var(--tx-text-muted); font-size: 13px; margin: 0; }
.v4-cartao .coluna-acao { align-self: flex-start; }
.v4-criar { align-items: center; display: flex; flex-wrap: wrap; gap: 8px; }
.v4-criar .coluna-secao-rotulo { flex-basis: 100%; }
.v4-criar .entrada { flex: 1; min-width: 160px; }
.v4-criar select.entrada { padding: 0 10px; }
.v4-criar .btn-primario { flex: 0 0 auto; height: 44px; padding: 0 22px; }
.v4-criar .dica { flex-basis: 100%; margin: 0; }

/* O topo da tela Social (o título e a nota) saiu em 2026-08-28: com Mensagens e
   Canais no menu, aquele bloco repetia em letra grande o caminho que o menu já
   mostra aceso. As regras dele foram junto — órfã é a próxima a ser copiada por
   engano.

   O `.social-olho` FICA: apesar do nome, ele é o eyebrow de outras telas
   também (a de Personalizar perfil usa "Conta · Perfil"). Apagá-lo junto era o
   erro fácil aqui. */
.social-olho {
  color: var(--tx-text-faint);
  font-family: var(--tx-font-ui);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.24em;
  text-transform: uppercase;
}

/* As abas Mensagens|Canais viviam aqui e saíram em 2026-08-28, junto com o
   `.social-abas` que as embrulhava: a escolha subiu para a seção Social do
   menu. O CSS foi embora com elas — regra órfã é a próxima a ser copiada por
   engano. */

.social-quadro {
  background: rgba(10, 12, 22, 0.42);
  backdrop-filter: blur(22px) saturate(1.3);
  -webkit-backdrop-filter: blur(22px) saturate(1.3);
  border: 1px solid rgba(146, 163, 255, 0.18);
  border-radius: var(--tx-radius-lg);
  box-shadow: 0 30px 70px rgba(0, 0, 0, 0.45);
  display: flex;
  flex: 1;
  min-height: 0;
  overflow: hidden;
}

.social-coluna {
  background: rgba(7, 9, 16, 0.3);
  border-right: 1px solid rgba(146, 163, 255, 0.18);
  display: flex;
  flex: 0 0 296px;
  flex-direction: column;
  min-height: 0;
}
.coluna-topo {
  border-bottom: 1px solid rgba(146, 163, 255, 0.18);
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px;
}
.coluna-linha { align-items: center; display: flex; gap: 10px; justify-content: space-between; }
.coluna-rotulo {
  color: var(--tx-text-faint);
  font-family: var(--tx-font-ui);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.2em;
  overflow: hidden;
  text-overflow: ellipsis;
  text-transform: uppercase;
  white-space: nowrap;
}
.coluna-acao {
  background: var(--tx-gradient);
  border: none;
  border-radius: var(--tx-radius-sm);
  color: #fff;
  cursor: pointer;
  flex: 0 0 auto;
  font-family: var(--tx-font-ui);
  font-size: 9.5px;
  font-weight: 700;
  height: 28px;
  letter-spacing: 0.14em;
  padding: 0 11px;
  text-transform: uppercase;
}
.coluna-acao:hover { box-shadow: var(--tx-glow); }

.coluna-busca { display: flex; position: relative; }
.coluna-busca-icone {
  align-items: center;
  color: var(--tx-text-faint);
  display: flex;
  left: 12px;
  pointer-events: none;
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
}
.coluna-busca input {
  background: rgba(15, 19, 38, 0.38);
  border: 1px solid rgba(146, 163, 255, 0.18);
  border-radius: var(--tx-radius-md);
  color: var(--tx-text);
  font-family: var(--tx-font-body);
  font-size: 13px;
  height: 40px;
  outline: none;
  padding: 0 12px 0 34px;
  user-select: text;
  width: 100%;
}
.coluna-busca input:focus { border-color: var(--tx-blue-bright); box-shadow: 0 0 0 3px rgba(91, 127, 255, 0.14); }
.coluna-busca input::-webkit-search-cancel-button { display: none; }

.coluna-corpo {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 16px;
  min-height: 0;
  overflow-y: auto;
  padding: 10px 10px 16px;
}
/* O pé da coluna: onde o cartão de voz fica enquanto o Chat está aberto. Fora
   do corpo rolável de propósito — quem está numa chamada não pode perder o
   botão de sair ao rolar a lista de canais. Sem canal (ou com o cartão de volta
   no menu) o pé não existe: o `:has` evita uma borda solta embaixo da lista. */
.coluna-voz {
  border-top: 1px solid rgba(146, 163, 255, 0.18);
  flex: 0 0 auto;
  padding: 10px;
}
.coluna-voz:not(:has(> .voz-barra:not(.oculto))) { display: none; }

.coluna-secao { display: flex; flex-direction: column; gap: 4px; }
.coluna-secao-topo { align-items: center; display: flex; justify-content: space-between; padding: 0 6px 2px; }
.coluna-secao-rotulo {
  color: var(--tx-text-faint);
  font-family: var(--tx-font-ui);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}
.coluna-secao-conta { color: var(--tx-text-faint); font-family: var(--tx-font-digital); font-size: 10px; }
.coluna-vazio { color: var(--tx-text-faint); font-size: 12.5px; line-height: 1.5; margin: 0; padding: 0 8px; }

/* A linha é um <div> com dois botões dentro — rosto e resto —, e não um <button>
   com outro dentro: <button> aninhado é HTML inválido e o Chromium desmonta a
   árvore sozinho (o de dentro sai do lugar e o clique vai para o errado). São
   duas portas de propósito: o rosto abre o RETRATO, o resto abre a conversa. */
.conversa {
  align-items: center;
  border-radius: var(--tx-radius-md);
  color: var(--tx-text-muted);
  display: flex;
  gap: 10px;
  min-height: 52px;
  overflow: hidden;
  padding: 0 8px;
  position: relative;
}
.conversa:hover { background: rgba(123, 140, 255, 0.07); color: var(--tx-text); }
.conversa.ativa { background: linear-gradient(90deg, rgba(91, 127, 255, 0.28), rgba(91, 127, 255, 0.04)); color: var(--tx-text); }
/* Amigo offline continua na lista, mas apagado: a coluna é ordenada por quem
   está disponível agora, e a diferença precisa aparecer sem ler o rótulo. */
.conversa.apagada { opacity: 0.62; }
/* O banho da moldura da PESSOA tinge a linha dela. No desenho quem tinge é o
   fundo do perfil (um cosmético que o beta não tem); a moldura é o cosmético
   que existe, e o `banho` dela já é essa mancha de cor. */
.conversa-banho { inset: 0; opacity: 0.5; pointer-events: none; position: absolute; }
.conversa-abrir {
  background: none;
  border: none;
  color: inherit;
  cursor: pointer;
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  padding: 6px 0;
  position: relative;
  text-align: left;
}
.conversa-nome {
  color: var(--tx-text);
  font-family: var(--tx-font-ui);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.02em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.conversa-sub { color: rgba(244, 246, 255, 0.55); font-size: 11px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.conversa .selo-nao-lidas { flex: 0 0 auto; position: relative; }
.cerquilha { color: var(--tx-text-faint); font-size: 18px; font-weight: 700; width: 28px; text-align: center; }

/* A linha em branco do canal novo: é a linha da lista com um campo no lugar do
   nome, e não um diálogo. Enter cria, Escape desiste. */
.novo-canal {
  background: rgba(15, 19, 38, 0.5);
  border: 1px solid var(--tx-blue-bright);
  border-radius: var(--tx-radius-sm);
  color: var(--tx-text);
  flex: 1;
  font-family: var(--tx-font-ui);
  font-size: 14px;
  height: 34px;
  min-width: 0;
  outline: none;
  padding: 0 10px;
  user-select: text;
}

/* O rosto: avatar com o ponto de presença grudado nele. Vira botão em toda
   lista de gente, e o que ele abre é sempre o mesmo retrato. */
.face {
  background: none;
  border: none;
  cursor: pointer;
  display: block;
  flex: 0 0 auto;
  line-height: 0;
  padding: 0;
  position: relative;
}
.face-ponto {
  border: 2px solid #0b0e1a;
  border-radius: 50%;
  bottom: -1px;
  height: 12px;
  position: absolute;
  right: -1px;
  width: 12px;
  background: var(--tx-text-faint);
}
.face-ponto.online { background: var(--tx-green); }
.face-ponto.playing { background: var(--tx-blue-bright); }
.face-ponto.viva { animation: txlive 2.4s ease-out infinite; }
/* O anel que pulsa é o mesmo do desenho: diz "agora", e some quando a pessoa
   está offline. */
@keyframes txlive {
  0%, 100% { box-shadow: 0 0 0 0 rgba(47, 214, 162, 0.5); }
  70% { box-shadow: 0 0 0 6px rgba(47, 214, 162, 0); }
}

/* ===== pedidos de amizade, na coluna =====
   Vieram para cá porque não tinham casa: a tela `#tela-amigos` que os mostrava
   deixou de ser alcançável no redesenho, e desde então um pedido só aparecia
   como aviso. Na coluna eles ficam onde a pessoa vai olhar de qualquer forma. */
.pedido { align-items: center; display: flex; gap: 10px; min-height: 52px; padding: 0 8px; }
.pedido-meio { display: flex; flex: 1; flex-direction: column; gap: 1px; min-width: 0; }
.pedido-nome {
  color: var(--tx-text);
  font-family: var(--tx-font-ui);
  font-size: 13px;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.pedido-sub { color: var(--tx-text-faint); font-size: 11px; }
.pedido-sim, .pedido-nao {
  align-items: center;
  border-radius: var(--tx-radius-sm);
  cursor: pointer;
  display: flex;
  flex: 0 0 auto;
  height: 30px;
  justify-content: center;
  width: 30px;
}
.pedido-sim { background: var(--tx-gradient); border: none; color: #fff; }
.pedido-sim:hover { box-shadow: var(--tx-glow); }
.pedido-nao { background: transparent; border: 1px solid rgba(146, 163, 255, 0.18); color: var(--tx-text-faint); }
.pedido-nao:hover { border-color: rgba(255, 84, 112, 0.4); color: var(--tx-red); }
.pedido-cancelar {
  background: transparent;
  border: 1px solid rgba(146, 163, 255, 0.18);
  border-radius: var(--tx-radius-sm);
  color: var(--tx-text-faint);
  cursor: pointer;
  flex: 0 0 auto;
  font-family: var(--tx-font-ui);
  font-size: 10px;
  font-weight: 700;
  height: 30px;
  letter-spacing: 0.14em;
  padding: 0 12px;
  text-transform: uppercase;
}
.pedido-cancelar:hover { border-color: var(--tx-border-strong); color: var(--tx-text); }
.pedido-sim:disabled, .pedido-nao:disabled, .pedido-cancelar:disabled { cursor: default; opacity: 0.5; }

/* ===== sala de voz, na coluna dos Canais =====
   Todo canal do beta é as duas coisas: uma conversa de texto e uma sala de voz.
   O desenho mostra as duas listas separadas ("Texto" e "Voz") e é o que fica:
   entrar na conversa e entrar na voz são cliques diferentes — no beta também. */
.sala { border-radius: var(--tx-radius-md); display: flex; flex-direction: column; gap: 6px; padding: 8px; }
.sala:hover { background: rgba(123, 140, 255, 0.06); }
.sala-linha { align-items: center; display: flex; gap: 10px; }
.sala-icone {
  align-items: center;
  border: 1px solid rgba(146, 163, 255, 0.2);
  border-radius: 9px;
  color: var(--tx-text-faint);
  display: flex;
  flex: 0 0 30px;
  height: 30px;
  justify-content: center;
}
.sala-icone.viva { background: rgba(47, 214, 162, 0.1); border-color: rgba(47, 214, 162, 0.35); color: #4ce0ad; }
.sala-meio { display: flex; flex: 1; flex-direction: column; gap: 1px; min-width: 0; }
.sala-nome {
  color: var(--tx-text);
  font-family: var(--tx-font-ui);
  font-size: 13.5px;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.sala-sub { color: var(--tx-text-faint); font-size: 11px; }
.sala-sub.viva { color: #4ce0ad; }
.sala-btn {
  background: transparent;
  border: 1px solid rgba(146, 163, 255, 0.2);
  border-radius: var(--tx-radius-sm);
  color: var(--tx-text-muted);
  cursor: pointer;
  flex: 0 0 auto;
  font-family: var(--tx-font-ui);
  font-size: 9.5px;
  font-weight: 700;
  height: 28px;
  letter-spacing: 0.14em;
  padding: 0 11px;
  text-transform: uppercase;
}
.sala-btn:hover { border-color: var(--tx-blue-bright); color: var(--tx-text); }
.sala-btn.dentro { background: rgba(47, 214, 162, 0.14); border-color: rgba(47, 214, 162, 0.45); color: #4ce0ad; }
.sala-gente { align-items: center; display: flex; padding-left: 40px; }
.sala-gente .face + .face { margin-left: -7px; }

/* Selo da distribuidora: 36px de vidro com a marca dentro, medida do protótipo.
   A cor vem do JS (a da marca quando conectada), e por isso não está aqui. */
.loja-icone {
  align-items: center;
  background: rgba(10, 12, 21, 0.34);
  backdrop-filter: blur(18px) saturate(1.3);
  -webkit-backdrop-filter: blur(18px) saturate(1.3);
  border: 1px solid rgba(146, 163, 255, 0.18);
  border-radius: 9px;
  color: var(--tx-text-muted);
  display: flex;
  flex: 0 0 36px;
  font-family: var(--tx-font-ui);
  font-size: 14px;
  font-weight: 700;
  height: 36px;
  justify-content: center;
}

/* A borda transparente existe SEMPRE, com ou sem moldura: é o que a moldura
   pinta (fundo em duas camadas — cor no `padding-box`, degradê no `border-box`)
   e o que impede o avatar de crescer 4px no instante em que alguém escolhe uma.
   Com `border-box`, os 28px continuam sendo 28px. */
.avatar {
  align-items: center;
  background: var(--tx-gradient);
  border: 2px solid transparent;
  border-radius: 50%;
  box-sizing: border-box;
  color: #fff;
  display: flex;
  flex: 0 0 28px;
  font-family: var(--tx-font-ui);
  font-size: 13px;
  font-weight: 700;
  height: 28px;
  justify-content: center;
  width: 28px;
}
/* Sem moldura a borda não pode roubar espaço do miolo: 28px de disco com 2px de
   nada em volta deixa a inicial apertada. */
.avatar:not(.com-moldura) { border-width: 0; }

/* Os outros dois tamanhos do desenho: o rosto das listas de gente (34px) e o
   retrato (150px), que é o disco grande do cartão de perfil. A espessura da
   moldura acompanha o tamanho — 2px num disco de 150px seria um fio. */
.avatar.rosto { flex: 0 0 34px; font-size: 15px; height: 34px; width: 34px; }
.avatar.retrato {
  flex: 0 0 156px;
  font-family: var(--tx-font-display);
  font-size: 62px;
  font-style: italic;
  font-weight: 800;
  height: 156px;
  width: 156px;
}
.avatar.retrato.com-moldura { border-width: 5px; }

.ponto-presenca { border-radius: 50%; flex: 0 0 8px; height: 8px; width: 8px; background: var(--tx-text-faint); }
.ponto-presenca.online { background: var(--tx-green); }
.ponto-presenca.playing { background: var(--tx-blue-bright); box-shadow: 0 0 8px var(--tx-blue); }

.thread { display: flex; flex: 1; flex-direction: column; min-height: 0; min-width: 0; }
.thread-nada {
  align-items: center;
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 6px;
  justify-content: center;
  text-align: center;
}
.thread-nada h2 { margin: 0; }
.thread-viva { display: flex; flex: 1; flex-direction: column; min-height: 0; }
.thread-topo {
  align-items: center;
  background: rgba(8, 10, 18, 0.34);
  border-bottom: 1px solid rgba(146, 163, 255, 0.18);
  display: flex;
  flex: 0 0 64px;
  gap: 12px;
  padding: 0 20px;
}
.thread-quem { display: flex; flex: 1 1 auto; flex-direction: column; gap: 1px; min-width: 140px; }
/* O nome é botão porque abre o retrato — o mesmo que o rosto ao lado. Continua
   parecendo texto: um nome com cara de botão no alto da conversa competiria com
   o de Ligar. */
.thread-nome {
  background: none;
  border: none;
  color: var(--tx-text);
  cursor: pointer;
  font-family: var(--tx-font-ui);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.02em;
  overflow: hidden;
  padding: 0;
  text-align: left;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.thread-nome:disabled { cursor: default; }
.thread-sub { color: var(--tx-text-faint); font-size: 12px; margin: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cerquilha-selo {
  align-items: center;
  background: rgba(15, 19, 38, 0.38);
  border: 1px solid rgba(146, 163, 255, 0.18);
  border-radius: 9px;
  color: var(--tx-text-faint);
  display: flex;
  flex: 0 0 36px;
  font-family: var(--tx-font-ui);
  font-size: 15px;
  font-weight: 700;
  height: 36px;
  justify-content: center;
}
.thread-ligar {
  align-items: center;
  background: var(--tx-gradient);
  border: none;
  border-radius: 9px;
  color: #fff;
  cursor: pointer;
  display: flex;
  flex: 0 0 auto;
  font-family: var(--tx-font-ui);
  font-size: 11px;
  font-weight: 700;
  gap: 8px;
  height: 36px;
  letter-spacing: 0.14em;
  padding: 0 14px;
  text-transform: uppercase;
  white-space: nowrap;
}
.thread-ligar:hover { box-shadow: var(--tx-glow); }
/* Dentro da chamada o botão deixa de convidar e passa a informar — e clicar
   nele desliga, igual ao "Desligar" da faixa de baixo. */
.thread-ligar.dentro {
  background: rgba(47, 214, 162, 0.16);
  border: 1px solid rgba(47, 214, 162, 0.45);
  box-shadow: none;
  color: #4ce0ad;
}

.chamada {
  align-items: center;
  background: linear-gradient(90deg, rgba(47, 214, 162, 0.14), rgba(47, 214, 162, 0.02));
  border-bottom: 1px solid rgba(47, 214, 162, 0.28);
  display: flex;
  flex: 0 0 auto;
  gap: 12px;
  padding: 12px 20px;
}
.chamada-farol {
  animation: txlive 2.4s ease-out infinite;
  background: var(--tx-green);
  border-radius: 50%;
  flex: 0 0 9px;
  height: 9px;
  width: 9px;
}
.chamada-rotulo {
  color: #4ce0ad;
  font-family: var(--tx-font-ui);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  white-space: nowrap;
}
.chamada-tempo { color: var(--tx-text-muted); font-family: var(--tx-font-digital); font-size: 12px; }
.chamada-nomes {
  color: var(--tx-text-faint);
  flex: 1;
  font-size: 12px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.chamada-btn {
  background: transparent;
  border: 1px solid rgba(146, 163, 255, 0.2);
  border-radius: 9px;
  color: var(--tx-text-muted);
  cursor: pointer;
  flex: 0 0 auto;
  font-family: var(--tx-font-ui);
  font-size: 10px;
  font-weight: 700;
  height: 32px;
  letter-spacing: 0.14em;
  padding: 0 13px;
  text-transform: uppercase;
}
.chamada-btn:hover { border-color: var(--tx-border-strong); color: var(--tx-text); }
.chamada-btn:disabled { cursor: default; opacity: 0.5; }
.chamada-btn.sair { background: rgba(255, 84, 112, 0.16); border-color: rgba(255, 84, 112, 0.45); color: #ff8298; }
.chamada-btn.sair:hover { background: rgba(255, 84, 112, 0.28); color: #fff; }

.mensagens {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 2px;
  min-height: 0;
  overflow-y: auto;
  padding: 16px 20px;
  user-select: text;
}
/* Conversa curta encosta embaixo, junto do compositor, em vez de flutuar no
   alto de uma área vazia. `margin-top: auto` no primeiro filho e não
   `justify-content: flex-end` no container: com flex-end o topo da lista fica
   inalcançável pela rolagem quando ela cresce. */
.mensagens > :first-child { margin-top: auto; }

/* Grade de duas colunas: avatar à esquerda, tudo o mais à direita. As
   mensagens seguidas do mesmo autor omitem avatar e cabeçalho e continuam
   alinhadas porque a coluna 1 permanece reservada. */
.msg {
  border-radius: var(--tx-radius-md);
  display: grid;
  gap: 2px 12px;
  grid-template-columns: 34px 1fr;
  padding: 5px 8px;
  position: relative;
}
/* Realce no hover, como no desenho: dá o alvo da reação e mostra onde a linha
   começa e acaba numa conversa sem balões. */
.msg:hover { background: rgba(123, 140, 255, 0.04); }
.msg.junta { padding-top: 0; }
.msg > .face { grid-column: 1; grid-row: 1 / span 3; margin-top: 2px; }
.msg-cabecalho { align-items: baseline; display: flex; flex-wrap: wrap; gap: 8px; grid-column: 2; }
/* Autor é botão (abre o retrato) e continua com cara de nome. */
.msg-autor {
  background: none;
  border: none;
  color: var(--tx-text);
  cursor: pointer;
  font-family: var(--tx-font-ui);
  font-size: 13.5px;
  font-weight: 700;
  padding: 0;
  text-align: left;
}
.msg.minha .msg-autor { color: var(--tx-blue-bright); }
.msg-hora { color: var(--tx-text-faint); font-family: var(--tx-font-digital); font-size: 10px; letter-spacing: 0.08em; }
.msg-corpo {
  color: var(--tx-text);
  font-size: 14.5px;
  grid-column: 2;
  line-height: 1.5;
  overflow-wrap: anywhere;
  white-space: pre-wrap;
}
.msg-reacoes { align-items: center; display: flex; flex-wrap: wrap; gap: 4px; grid-column: 2; position: relative; }
.msg-reacoes:empty { display: none; }

.reacao {
  background: var(--tx-surface);
  border: 1px solid var(--tx-border);
  border-radius: var(--tx-radius-pill);
  color: var(--tx-text-muted);
  cursor: pointer;
  font-size: 12px;
  padding: 1px 8px;
}
.reacao.minha { background: rgba(61, 90, 254, 0.18); border-color: var(--tx-border-strong); color: var(--tx-text); }
.reacao:hover { border-color: var(--tx-blue-bright); }

/* O botão de reagir só aparece no hover da mensagem: uma coluna de ＋ em toda
   linha compete com o texto pela atenção. */
.reagir {
  background: none;
  border: none;
  color: var(--tx-text-faint);
  cursor: pointer;
  font-size: 13px;
  line-height: 1;
  opacity: 0;
  padding: 2px 4px;
}
.msg:hover .reagir, .reagir:focus-visible { opacity: 1; }
.reagir:hover { color: var(--tx-blue-bright); }
.reagir.perigo { color: var(--tx-red); }
/* Citação: o bloco acima da resposta, com a barrinha à esquerda. */
.msg-citacao {
  align-items: baseline;
  background: none;
  border: 0;
  border-left: 2px solid var(--tx-border-strong);
  color: var(--tx-text-faint);
  cursor: pointer;
  display: flex;
  font-size: 12px;
  gap: 6px;
  grid-column: 2;
  margin-bottom: 2px;
  min-width: 0;
  padding: 0 0 0 8px;
  text-align: left;
}
.msg-citacao:hover { color: var(--tx-text-muted); }
.msg-citacao-autor { color: var(--tx-text-muted); flex: 0 0 auto; font-weight: 600; }
.msg-citacao-corpo { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.msg-editado { color: var(--tx-text-faint); font-size: 11px; }
.msg-editar { font-size: 14px; padding: 8px 10px; width: 100%; }
.msg-dica { color: var(--tx-text-faint); display: block; font-size: 11px; margin-top: 4px; }
/* A mensagem citada pisca quando se chega nela pelo clique na citação. */
@keyframes txpisca {
  0%, 100% { background: transparent; }
  30% { background: rgba(123, 140, 255, 0.16); }
}
.msg.piscando { animation: txpisca 1.2s ease-out; }
/* A faixa de "respondendo a", colada no compositor. */
.respondendo {
  align-items: baseline;
  background: rgba(123, 140, 255, 0.07);
  border-top: 1px solid var(--tx-border);
  display: flex;
  font-size: 12px;
  gap: 8px;
  padding: 8px 14px 6px;
}
.respondendo-rotulo { color: var(--tx-text-muted); flex: 0 0 auto; }
.respondendo-corpo {
  color: var(--tx-text-faint);
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.respondendo-x {
  background: none;
  border: 0;
  color: var(--tx-text-faint);
  cursor: pointer;
  font-size: 12px;
  padding: 0 2px;
}
.respondendo-x:hover { color: var(--tx-red); }

/* Fixa e no body: ver o comentário em abrirPaleta(). Dentro da lista de
   mensagens ela era recortada pelo overflow ou tapava a própria mensagem. */
.paleta {
  background: var(--tx-surface-2);
  border: 1px solid var(--tx-border-strong);
  border-radius: var(--tx-radius-md);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
  padding: 6px;
  position: fixed;
  width: 176px;
  z-index: 50;
}
.paleta button {
  background: none;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  font-size: 16px;
  line-height: 1;
  padding: 4px;
}
.paleta button:hover { background: var(--tx-surface); }

.compositor {
  /* `flex-end` e não `stretch`: o textarea cresce com o texto, e o botão
     Enviar fica ancorado embaixo, na altura de uma linha, em vez de esticar
     junto. */
  align-items: flex-end;
  background: rgba(8, 10, 18, 0.34);
  border-top: 1px solid rgba(146, 163, 255, 0.18);
  display: flex;
  flex: 0 0 auto;
  gap: 10px;
  padding: 14px 24px 20px;
}
.compositor .entrada { flex: 1; }
/* O textarea do chat: nasce com a altura de uma linha (a mesma dos inputs) e
   cresce até ~5 linhas; quem mede é o app.js. Sem alça de redimensionar e sem
   rolagem horizontal. */
.compositor .entrada-texto {
  display: block;
  font-family: var(--tx-font-body);
  height: 44px;
  line-height: 20px;
  max-height: 140px;
  min-height: 44px;
  overflow-y: auto;
  padding: 11px 14px;
  resize: none;
}
.compositor .btn-primario { flex: 0 0 120px; font-size: 12px; height: 44px; letter-spacing: 0.16em; padding: 0; }
.tela-social .erro { margin: 0 24px 12px; }

/* ===== retrato =====
   O cartão de perfil do desenho, ancorado na linha clicada. Fica no <body> e
   não na lista, pela mesma razão da paleta de emoji: dentro da coluna ele seria
   recortado pelo `overflow` ou taparia a própria pessoa.

   É o cartão que a tela Perfil edita, visto de fora — e é por isso que o botão
   do dono leva para lá em vez de repetir os controles aqui. */
.retrato-veu { background: rgba(4, 5, 10, 0.55); inset: 0; position: fixed; z-index: 60; }
/* Só posição: o cartão em si é `.cartao-perfil`, e o nome desta classe NÃO pode
   ser "retrato" — é o nome de um dos modelos de cartão, e as duas regras se
   misturavam. */
.cartao-popover {
  animation: txpop 180ms cubic-bezier(0.2, 0.7, 0.3, 1);
  position: fixed;
  z-index: 61;
}
@keyframes txpop {
  from { opacity: 0; transform: translateY(8px) scale(0.98); }
  to { opacity: 1; transform: none; }
}

/* ===== o cartão de perfil =====
   Um só, desenhado por `cartaoDePerfil` em app.js, usado no retrato que abre no
   chat e na prévia da tela Perfil. O que muda entre os dois é o rodapé.

   Quase tudo aqui é estrutura: a pintura (fundo, borda, apelido) vem do JS,
   porque é escolha da pessoa e não do app. */
.cartao-perfil { box-shadow: 0 28px 64px rgba(0, 0, 0, 0.6); position: relative; width: 100%; z-index: 1; }
.cartao-dentro { display: flex; flex-direction: column; overflow: hidden; position: relative; width: 100%; }
.cartao-perfil.retrato .cartao-dentro { min-height: 452px; }
.cartao-fundo { inset: 0; pointer-events: none; position: absolute; }

/* O risco do Scanline e os três efeitos. Todos são camadas irmãs do fundo, e
   nenhuma responde ao ponteiro. */
.cartao-risco {
  animation: txscan 6s linear infinite;
  background: linear-gradient(180deg, transparent, rgba(139, 163, 255, 0.26), transparent);
  height: 26%;
  left: 0;
  pointer-events: none;
  position: absolute;
  right: 0;
}
@keyframes txscan { 0% { transform: translateY(-110%); } 100% { transform: translateY(320%); } }
.cartao-faisca {
  animation-iteration-count: infinite;
  animation-name: txspark;
  animation-timing-function: linear;
  background: #cfe0ff;
  border-radius: 50%;
  bottom: 10px;
  box-shadow: 0 0 8px rgba(150, 190, 255, 0.95);
  height: 3px;
  pointer-events: none;
  position: absolute;
  width: 3px;
}
@keyframes txspark {
  0% { opacity: 0; transform: translateY(6px) scale(0.5); }
  18% { opacity: 1; }
  100% { opacity: 0; transform: translateY(-90px) scale(0.15); }
}
.cartao-raio {
  animation: txflash 3.4s linear infinite;
  background: radial-gradient(70% 60% at 50% 0%, rgba(200, 224, 255, 0.85), transparent 60%);
  inset: 0;
  pointer-events: none;
  position: absolute;
}
@keyframes txflash { 0%, 86%, 100% { opacity: 0; } 88% { opacity: 0.95; } 91% { opacity: 0.15; } 94% { opacity: 0.7; } 97% { opacity: 0.1; } }
.cartao-nevoa {
  animation: txfog 9s ease-in-out infinite;
  background: radial-gradient(60% 60% at 40% 60%, rgba(210, 225, 255, 0.2), transparent 70%);
  inset: -20%;
  pointer-events: none;
  position: absolute;
}
@keyframes txfog { 0% { transform: translate3d(-7%, 0, 0); } 50% { transform: translate3d(7%, 0, 0); } 100% { transform: translate3d(-7%, 0, 0); } }
@keyframes txdrift { 0% { background-position: 0 0; } 100% { background-position: 90px 90px; } }
/* As duas animações do apelido. `pulse` respira; `bolt` pisca como contato
   ruim, que é o raio da marca. */
@keyframes txnickpulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.58; } }
@keyframes txnickbolt { 0%, 82%, 100% { opacity: 1; } 84% { opacity: 0.28; } 86% { opacity: 1; } 88% { opacity: 0.45; } 90% { opacity: 1; } }

.cartao-kit {
  background: rgba(6, 8, 16, 0.72);
  border: 1px solid rgba(146, 163, 255, 0.28);
  border-radius: var(--tx-radius-pill);
  color: rgba(244, 246, 255, 0.82);
  font-family: var(--tx-font-ui);
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.16em;
  padding: 7px 12px;
  position: absolute;
  right: 14px;
  text-transform: uppercase;
  top: 14px;
  white-space: nowrap;
  z-index: 2;
}
.cartao-palco { align-items: center; display: flex; flex: 1; justify-content: center; padding: 44px 22px 12px; position: relative; }
.cartao-palco .avatar { position: relative; }
.cartao-txt {
  align-items: center;
  display: flex;
  flex-direction: column;
  gap: 11px;
  padding: 26px 22px 24px;
  position: relative;
  text-align: center;
}
/* O véu embaixo existe para o texto: sobre Aurora ou uma arte de jogo, apelido
   e bio ficariam ilegíveis direto no fundo. */
.cartao-perfil.retrato .cartao-txt {
  background: linear-gradient(0deg, rgba(6, 8, 16, 0.96) 14%, rgba(6, 8, 16, 0.86) 56%, rgba(6, 8, 16, 0.1));
}
.cartao-nome { display: block; max-width: 100%; }
.cartao-linha { align-items: center; display: flex; flex-wrap: wrap; gap: 11px; justify-content: center; }
.cartao-handle { color: rgba(244, 246, 255, 0.6); font-family: var(--tx-font-digital); font-size: 11px; letter-spacing: 0.06em; }
.cartao-status { align-items: center; display: flex; gap: 7px; }
.cartao-status span {
  color: rgba(244, 246, 255, 0.8);
  font-family: var(--tx-font-ui);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.cartao-ponto { border-radius: 50%; flex: 0 0 8px; height: 8px; width: 8px; }
.cartao-ponto.viva { animation: txlive 2.4s ease-out infinite; }
.cartao-bio { color: rgba(244, 246, 255, 0.7); font-size: 13px; line-height: 1.6; margin: 0; }
.cartao-selos { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; }
.cartao-acoes { align-items: center; display: flex; gap: 8px; padding-top: 4px; width: 100%; }
.cartao-acoes .btn-primario { flex: 1; font-size: 10.5px; letter-spacing: 0.16em; padding: 12px 10px; }

/* Plaquinha: a mesma matéria numa faixa. O disco à esquerda, o texto alinhado
   no canto e o rodapé na ponta. */
.cartao-faixa {
  align-items: center;
  background: linear-gradient(90deg, rgba(6, 8, 16, 0.92) 30%, rgba(6, 8, 16, 0.55));
  display: flex;
  gap: 18px;
  padding: 20px 22px;
  position: relative;
}
.cartao-perfil.plaquinha .cartao-txt { align-items: flex-start; gap: 8px; padding: 0; text-align: left; }
.cartao-perfil.plaquinha .cartao-txt { flex: 1; min-width: 0; }
.cartao-perfil.plaquinha .cartao-linha { justify-content: flex-start; }
.cartao-perfil.plaquinha .cartao-selos { justify-content: flex-start; }
.cartao-perfil.plaquinha .cartao-acoes { padding-top: 0; width: auto; }
.retrato-icone {
  align-items: center;
  background: rgba(6, 8, 16, 0.6);
  border: 1px solid rgba(146, 163, 255, 0.24);
  border-radius: var(--tx-radius-md);
  color: rgba(244, 246, 255, 0.7);
  cursor: pointer;
  display: flex;
  flex: 0 0 38px;
  height: 38px;
  justify-content: center;
}
.retrato-icone:hover { border-color: var(--tx-blue-bright); color: #fff; }
/* O botão do dono. É o único do cartão que não age sobre outra pessoa: leva
   para a tela que edita este mesmo cartão. */
.retrato-editar {
  align-items: center;
  background: rgba(6, 8, 16, 0.6);
  border: 1px solid rgba(146, 163, 255, 0.24);
  border-radius: var(--tx-radius-md);
  color: rgba(244, 246, 255, 0.82);
  cursor: pointer;
  display: flex;
  flex: 1;
  font-family: var(--tx-font-ui);
  font-size: 10.5px;
  font-weight: 700;
  height: 38px;
  justify-content: center;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.retrato-editar:hover { border-color: var(--tx-blue-bright); color: #fff; }

/* ===== voz =====
   A barra fica no MENU e não numa tela, porque a voz não é um lugar: dá para
   entrar num canal e ir para o catálogo, ou entrar no jogo com os amigos
   falando. Só existe quando há canal, então não cobra espaço de quem não usa. */
/* ===== aviso de versão nova ===== */
/* Mesma anatomia de cartão da barra de voz, que é a vizinha de baixo: duas
   peças coladas no mesmo rodapé não podem parecer de apps diferentes. O que
   muda é o peso — a voz é onde a pessoa mexe o tempo todo, isto aparece poucas
   vezes na vida do app e não disputa atenção com ela. */
.atz {
  background: var(--tx-surface);
  border: 1px solid var(--tx-border);
  border-radius: var(--tx-radius-md);
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px;
}
.atz-txt { display: flex; flex-direction: column; min-width: 0; }
.atz-titulo { color: var(--tx-text); font-size: 13px; font-weight: 700; }
.atz-detalhe {
  color: var(--tx-text-faint);
  font-size: 11px;
  line-height: 1.35;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.atz-pista { background: var(--tx-bg); border-radius: var(--tx-radius-pill); height: 4px; overflow: hidden; }
.atz-pista i { background: var(--tx-blue-bright); display: block; height: 100%; transition: width 0.2s ease; }
.atz-acao {
  align-items: center;
  background: var(--tx-bg);
  border: 1px solid var(--tx-border);
  border-radius: var(--tx-radius-md);
  color: var(--tx-text-muted);
  cursor: pointer;
  display: flex;
  font-family: var(--tx-font-ui);
  font-size: 11.5px;
  font-weight: 600;
  justify-content: center;
  padding: 7px 6px;
}
.atz-acao:hover { border-color: var(--tx-border-strong); color: var(--tx-text); }
/* Com o menu recolhido sobra a borda esquerda do cartão, e o texto apaga junto
   com o resto (o bloco de opacidade lá em cima). Ele deixou de sumir com
   `display: none` em 2026-08-17: escondido assim, o cartão mudava de altura no
   meio da animação de abrir. Quem recolhe não fica sem saber da versão nova —
   o menu abre ao passar o mouse, e o aviso também vive na bandeja. */

.voz-barra {
  background: var(--tx-surface);
  border: 1px solid var(--tx-border);
  border-radius: var(--tx-radius-md);
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px;
}
.voz-cabecalho { align-items: center; display: flex; gap: 8px; }
.voz-farol { background: var(--tx-text-faint); border-radius: 50%; flex: 0 0 8px; height: 8px; width: 8px; }
.voz-farol.viva { background: var(--tx-green); }
/* Pulsa quando ALGUÉM fala, inclusive você: é o retorno que diz que o canal
   está vivo sem precisar de medidor de volume. */
.voz-farol.falando { background: var(--tx-green); box-shadow: 0 0 0 4px rgba(47, 214, 162, 0.18); }
.voz-farol.ruim { background: var(--tx-red); }
.voz-txt { display: flex; flex-direction: column; min-width: 0; }
.voz-canal { color: var(--tx-text); font-size: 13px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.voz-estado { color: var(--tx-text-faint); font-size: 11px; line-height: 1.35; }
.voz-estado.ruim { color: var(--tx-red); }

.voz-gente { display: flex; flex-direction: column; gap: 4px; max-height: 132px; overflow-y: auto; }
.voz-gente:empty { display: none; }
.voz-pessoa { align-items: center; color: var(--tx-text-muted); display: flex; font-size: 12.5px; gap: 7px; }
.voz-pessoa.falando { color: var(--tx-text); }
.voz-pessoa.falando .avatar { box-shadow: 0 0 0 2px var(--tx-green); }
.voz-pessoa-nome { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* O nome dos OUTROS é botão (abre o volume) e precisa parecer texto até o
   ponteiro chegar — uma coluna de botões com borda viraria formulário. */
.voz-pessoa-abrir {
  background: none;
  border: 0;
  color: inherit;
  cursor: pointer;
  font: inherit;
  padding: 0;
  text-align: left;
}
.voz-pessoa-abrir:hover { color: var(--tx-text); text-decoration: underline; }
.voz-pessoa-abrir.calado { color: var(--tx-text-faint); text-decoration: line-through; }
.voz-volume { align-items: center; display: flex; gap: 8px; padding: 2px 0 6px 26px; }
.voz-volume input { accent-color: var(--tx-blue-bright); flex: 1; min-width: 0; }
.voz-volume span {
  color: var(--tx-text-faint);
  font-family: var(--tx-font-digital);
  font-size: 10px;
  font-variant-numeric: tabular-nums;
  width: 30px;
}
/* Barrinhas de sinal — só existem em conexão ruim ou perdida. */
.voz-sinal { align-items: flex-end; display: inline-flex; gap: 1px; flex: 0 0 auto; height: 9px; }
.voz-sinal i { background: currentColor; border-radius: 1px; display: block; opacity: 0.28; width: 2px; }
.voz-sinal i:nth-child(1) { height: 3px; }
.voz-sinal i:nth-child(2) { height: 6px; }
.voz-sinal i:nth-child(3) { height: 9px; }
.voz-sinal.poor { color: var(--tx-amber, #ffb45c); }
.voz-sinal.poor i:nth-child(1) { opacity: 1; }
.voz-sinal.lost { color: var(--tx-red); }
.voz-mudo { color: var(--tx-red); flex: 0 0 13px; }
/* O aro acompanha o disco: 2px num avatar de 20px seria um décimo do diâmetro,
   e a moldura viraria o assunto de uma lista de gente falando. */
.avatar.mini { flex: 0 0 20px; font-size: 10px; height: 20px; width: 20px; }
.avatar.mini.com-moldura { border-width: 1.5px; }

/* As câmeras ligadas no canal. Duas por linha na largura do menu; com mais
   gente a caixa rola, porque a barra de voz mora no rodapé e não pode crescer
   até empurrar o menu inteiro. */
.voz-cameras { display: flex; flex-wrap: wrap; gap: 5px; max-height: 148px; overflow-y: auto; }
.voz-cameras:empty { display: none; }
.voz-camera-quadro {
  background: #05060b;
  border: 1px solid rgba(123, 140, 255, 0.2);
  border-radius: var(--tx-radius-md);
  flex: 1 1 46%;
  min-width: 0;
  overflow: hidden;
  position: relative;
}
.voz-camera-quadro video { aspect-ratio: 16 / 9; display: block; object-fit: cover; width: 100%; }
/* A própria imagem espelhada — é como a pessoa se vê no espelho. A dos
   outros, não: texto ao fundo ficaria de trás para frente. */
.voz-camera-quadro.eu video { transform: scaleX(-1); }
.voz-camera-nome {
  background: rgba(5, 6, 11, 0.72);
  border-radius: 999px;
  bottom: 4px;
  color: var(--tx-text);
  font-size: 10.5px;
  left: 5px;
  max-width: calc(100% - 10px);
  overflow: hidden;
  padding: 1px 6px;
  position: absolute;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.voz-camera-erro { color: var(--tx-red); flex: 1 1 100%; font-size: 11.5px; margin: 0; }

/* Quem está telando. Uma linha por transmissão, clicável — abre o telão. */
.voz-telas { display: flex; flex-direction: column; gap: 4px; }
.voz-telas:empty { display: none; }
.voz-tela {
  background: rgba(79, 195, 255, 0.1);
  border: 1px solid rgba(79, 195, 255, 0.3);
  border-radius: var(--tx-radius-md);
  color: var(--tx-text-muted);
  cursor: pointer;
  font-family: var(--tx-font-ui);
  font-size: 11.5px;
  overflow: hidden;
  padding: 6px 8px;
  text-align: left;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.voz-tela:hover, .voz-tela.vendo { border-color: var(--tx-blue-bright); color: var(--tx-text); }
.voz-tela-erro { color: var(--tx-red); font-size: 11.5px; margin: 0; }

/* Quatro ações não cabem lado a lado na largura do menu: quebram em 2 + 2. */
.voz-acoes { display: flex; flex-wrap: wrap; gap: 6px; }
.voz-acao {
  align-items: center;
  background: var(--tx-bg);
  border: 1px solid var(--tx-border);
  border-radius: var(--tx-radius-md);
  color: var(--tx-text-muted);
  cursor: pointer;
  display: flex;
  flex: 1;
  font-family: var(--tx-font-ui);
  font-size: 11.5px;
  font-weight: 600;
  gap: 6px;
  justify-content: center;
  padding: 7px 6px;
}
.voz-acao { flex: 1 1 44%; min-width: 0; }
.voz-acao span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.voz-acao svg { flex: 0 0 14px; height: 14px; width: 14px; }
.voz-acao:hover { border-color: var(--tx-blue-bright); color: var(--tx-text); }
.voz-acao:disabled { cursor: default; opacity: 0.5; }
.voz-acao.sair:hover { border-color: var(--tx-red); color: var(--tx-red); }
/* Surdo é estado, não ação: o botão fica aceso enquanto durar. */
.voz-acao.aceso {
  background: rgba(255, 84, 112, 0.16);
  border-color: rgba(255, 84, 112, 0.45);
  color: var(--tx-red);
}
.voz-som {
  background: rgba(61, 90, 254, 0.18);
  border: 1px solid var(--tx-border-strong);
  border-radius: var(--tx-radius-md);
  color: var(--tx-text);
  cursor: pointer;
  font-family: var(--tx-font-ui);
  font-size: 11.5px;
  font-weight: 700;
  padding: 7px;
}

/* ===== telar =====
   O seletor de janela e o telão. Os dois são camadas por cima de tudo, criadas
   em app.js e destruídas junto com a transmissão — daí não haver marcação
   nenhuma para eles no index.html. */
.seletor-veu, .telao-veu {
  align-items: center;
  background: rgba(4, 5, 10, 0.72);
  display: flex;
  inset: 0;
  justify-content: center;
  position: fixed;
  z-index: 130;
}
.seletor {
  background: var(--tx-bg-elevated, var(--tx-bg));
  border: 1px solid var(--tx-border-strong);
  border-radius: var(--tx-radius-lg, 14px);
  display: flex;
  flex-direction: column;
  gap: 14px;
  max-height: 80vh;
  max-width: 760px;
  padding: 20px;
  width: 88vw;
}
.seletor-topo { font-family: var(--tx-font-display); font-size: 18px; }
.seletor-grade {
  display: grid;
  gap: 10px;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  overflow-y: auto;
}
.seletor-fonte {
  background: var(--tx-bg);
  border: 1px solid var(--tx-border);
  border-radius: var(--tx-radius-md);
  color: var(--tx-text-muted);
  cursor: pointer;
  display: flex;
  flex-direction: column;
  font-family: var(--tx-font-ui);
  font-size: 12px;
  gap: 8px;
  padding: 8px;
  text-align: left;
}
.seletor-fonte:hover { border-color: var(--tx-blue-bright); color: var(--tx-text); }
.seletor-fonte img { aspect-ratio: 16 / 9; background: #000; border-radius: 6px; object-fit: contain; width: 100%; }
.seletor-nome { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.seletor-vazio { color: var(--tx-text-faint); font-size: 13px; margin: 0; }

.telao {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-height: 92vh;
  max-width: 94vw;
}
.telao-topo { align-items: center; display: flex; gap: 12px; }
.telao-nome { color: var(--tx-text-muted); flex: 1; font-size: 13px; }
.telao-video {
  background: #000;
  border: 1px solid var(--tx-border-strong);
  border-radius: var(--tx-radius-md);
  max-height: 84vh;
  max-width: 94vw;
  min-height: 200px;
}

/* O fone ao lado de cada conversa (`.linha-conversa`, `.voz-entrar`) e a lista
   de nomes embaixo do canal (`.voz-lista`) saíram em 2026-08-17, com o porte do
   desenho Chat: entrar na voz virou a aba Canais (seção "Voz", com os rostos de
   quem está dentro) e, na conversa, o botão Ligar do cabeçalho. */

/* ===== amigos e conta ===== */
.lista-pessoas { display: flex; flex-direction: column; }
.lista-pessoas:empty { display: none; }

.pessoa {
  align-items: center;
  border-top: 1px solid var(--tx-border);
  display: flex;
  gap: 12px;
  padding: 10px 0;
}
.pessoa:first-child { border-top: none; }
.pessoa-meio { display: flex; flex: 1; flex-direction: column; min-width: 0; }
.pessoa-nome { font-size: 14.5px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pessoa-sub { color: var(--tx-text-faint); font-size: 12px; }
.pessoa-acoes { align-items: center; display: flex; gap: 8px; }

/* Botão de linha: os de tela cheia (.botao, .btn-primario) têm margem e
   espaçamento grandes demais para caber numa lista.
   Também iguala fonte, borda e altura entre os dois — sem isso, "Aceitar"
   (primário, sem borda, fonte de UI) e "Recusar" (com borda, fonte display)
   saem com alturas diferentes lado a lado. */
.miudo {
  border: 1px solid transparent;
  font-family: var(--tx-font-ui);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  line-height: 1.25;
  margin: 0;
  padding: 7px 14px;
  text-transform: uppercase;
  white-space: nowrap;
}
.botao.miudo { border-color: var(--tx-border-strong); }
.miudo:disabled { cursor: default; opacity: 0.5; }

.conta-topo { align-items: center; display: flex; gap: 16px; margin-bottom: 12px; }
.conta-topo h2 { margin: 0 0 2px; }
.avatar.grande { flex: 0 0 56px; font-size: 24px; height: 56px; width: 56px; }
.avatar.grande.com-moldura { border-width: 3px; }

.chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.chip {
  background: rgba(123, 140, 255, 0.1);
  border: 1px solid var(--tx-border);
  border-radius: var(--tx-radius-pill);
  color: var(--tx-text-muted);
  font-size: 11.5px;
  letter-spacing: 0.04em;
  padding: 3px 10px;
}

/* ===== números do consumo =====
   Refeitos contra o protótipo (2026-08-13), que tem a medida exata desta
   fileira. O que estava aqui errava em três coisas ao mesmo tempo:

   1. FUNDO CHAPADO. `var(--tx-bg)` é #05060b OPACO. Num app inteiro de vidro,
      quatro retângulos pretos leem como buraco furado na superfície, e não como
      bloco em cima dela. Agora é o mesmo vidro dos campos: 34% sobre blur 18.
   2. VIDRO DENTRO DE VIDRO. A fileira morava num `.cartao`, então eram duas
      camadas translúcidas empilhadas — o protótipo põe estes blocos SOLTOS, com
      só o título de seção em cima. Quem virou cartão de vidro foi a seção de
      baixo, que tem texto e botão; números não precisam de moldura.
   3. NÚMERO PEQUENO E RÓTULO GRANDE. 22px contra 11,5px é quase o mesmo peso,
      e o número perdia a briga. O protótipo abre a distância: 28 contra 10.

   Quatro colunas FIXAS porque são sempre quatro números; `auto-fit` deixava a
   última coluna esticar sozinha quando a janela crescia. */
.numeros { display: grid; gap: 12px; grid-template-columns: repeat(4, 1fr); }
/* Abaixo de ~780px quatro colunas espremem o rótulo em três linhas. */
@media (max-width: 780px) {
  .numeros { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
}
.numero {
  background: rgba(10, 12, 21, 0.34);
  backdrop-filter: blur(18px) saturate(1.3);
  -webkit-backdrop-filter: blur(18px) saturate(1.3);
  border: 1px solid rgba(146, 163, 255, 0.18);
  border-radius: 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 16px;
}
.numero strong { color: var(--tx-text); font-family: var(--tx-font-digital); font-size: 28px; font-weight: 700; line-height: 1; }
/* Variante para o que não é número: data em Orbitron 28 ocupa meia tela e
   compete com a contagem ao lado. O protótipo faz igual — só o número é
   digital. */
.numero.texto strong { font-family: var(--tx-font-ui); font-size: 15px; line-height: 1.3; }
.numero span {
  color: var(--tx-text-faint);
  font-family: var(--tx-font-ui);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

/* Seção sem cartão: título pequeno em cima do conteúdo, do jeito que o
   protótipo apresenta o bloco de números. */
.secao { margin-bottom: 18px; }
.secao > .secao-titulo { margin-bottom: 12px; }

/* ===== formulários (ferramentas) ===== */
.linha { display: flex; flex-wrap: wrap; gap: 12px; }
.campo { display: flex; flex: 1 1 130px; flex-direction: column; gap: 5px; justify-content: flex-end; }
.campo.grande { flex: 2 1 220px; }
.campo span { color: var(--tx-text-faint); font-size: 12px; letter-spacing: 1px; text-transform: uppercase; }

input, select {
  background: rgba(10, 12, 21, 0.34);
  backdrop-filter: blur(18px) saturate(1.3);
  -webkit-backdrop-filter: blur(18px) saturate(1.3);
  border: 1px solid rgba(146, 163, 255, 0.18);
  border-radius: var(--tx-radius-md);
  color: var(--tx-text);
  font-family: inherit;
  font-size: 14px;
  padding: 9px 11px;
  user-select: text;
}
input:focus, select:focus { border-color: var(--tx-border-strong); box-shadow: var(--tx-glow); outline: none; }
.entrada:focus { box-shadow: none; }

.chaves { gap: 18px; margin-top: 14px; }
.chave { align-items: center; color: var(--tx-text-muted); display: flex; flex: 0 0 auto; font-size: 14px; gap: 7px; }
.chave input { accent-color: var(--tx-blue); padding: 0; }

.dobra { margin: 16px 0; }
.dobra summary { color: var(--tx-blue-bright); cursor: pointer; font-size: 13px; margin-bottom: 10px; }

.botao {
  background: var(--tx-surface-2);
  border: 1px solid var(--tx-border-strong);
  border-radius: var(--tx-radius-md);
  color: var(--tx-text);
  cursor: pointer;
  font-family: var(--tx-font-display);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 1.5px;
  margin-top: 18px;
  padding: 11px 26px;
  text-transform: uppercase;
}
.botao:hover { border-color: var(--tx-blue-bright); }
.botao.primario { background: var(--tx-gradient); border: none; box-shadow: var(--tx-glow); }
.botao:disabled { box-shadow: none; cursor: default; opacity: 0.5; }
.botao + .botao { margin-left: 10px; }

.salvo { color: var(--tx-green); font-size: 13px; margin-left: 12px; }

/* ===== sessão ===== */
/* ===== sessão (a tela de "jogando") =====
   Portada do protótipo `design-system/templates/app-desktop`, tela "Sessão".
   Ocupa a janela inteira: não é um formulário nem uma lista, é um momento — a
   pessoa está esperando um jogo abrir e não tem o que fazer aqui além de olhar
   ou desistir. */
.tela-jogando { height: 100%; overflow: hidden; position: relative; }

/* A MESMA arte do seat que era o fundo do login antes do vídeo de raios (é o
   `wallpaper-seat-2560.jpg` do protótipo, byte por byte). 26px de desfoque,
   42% de opacidade e 40px para fora de cada lado, para o desfoque não revelar
   borda. */
.jogando-arte {
  filter: blur(26px) saturate(1.15);
  height: calc(100% + 80px);
  inset: -40px;
  object-fit: cover;
  opacity: 0.42;
  position: absolute;
  width: calc(100% + 80px);
}
.jogando-veu {
  inset: 0;
  position: absolute;
  background:
    radial-gradient(ellipse 70% 60% at 50% 40%, rgba(61, 90, 254, 0.16), transparent 70%),
    linear-gradient(180deg, rgba(5, 6, 11, 0.82), rgba(5, 6, 11, 0.94));
}
.jogando-centro {
  align-items: center;
  display: flex;
  flex-direction: column;
  gap: 34px;
  height: 100%;
  justify-content: center;
  overflow-y: auto;
  padding: 40px;
  position: relative;
  text-align: center;
}

.jogando-jogo { align-items: center; display: flex; gap: 10px; white-space: nowrap; }
.jogando-jogo-meta {
  color: var(--tx-text-faint);
  font-family: var(--tx-font-ui);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

/* ===== a trilha de passos =====
   Cinco colunas de 132px. A linha que liga um passo ao outro é feita de duas
   metades — a da esquerda de cada bolinha e a da direita —, e não de um trilho
   atrás de tudo: é assim que o trecho já percorrido fica aceso e o resto
   apagado sem precisar calcular largura nenhuma. */
.passos { display: flex; list-style: none; margin: 0; padding: 0; }
.passo {
  align-items: center;
  cursor: default;
  display: flex;
  flex-direction: column;
  gap: 10px;
  white-space: nowrap;
  width: 132px;
}
.passo-marca { align-items: center; display: flex; height: 28px; justify-content: center; position: relative; width: 100%; }
.passo-linha { height: 2px; position: absolute; top: 13px; width: 50%; }
.passo-linha--esq { background: var(--tx-border-strong); left: 0; }
.passo-linha--dir { background: rgba(146, 163, 255, 0.18); right: 0; }
.passo-bolha {
  align-items: center;
  border-radius: 50%;
  display: flex;
  height: 26px;
  justify-content: center;
  position: relative;
  width: 26px;
}
.passo--feito .passo-bolha {
  background: rgba(91, 127, 255, 0.18);
  border: 1px solid var(--tx-blue-bright);
  color: var(--tx-blue-bright);
}
/* O anel que sai pulsando da bolinha atual é o único movimento da trilha — é
   ele que diz qual passo está acontecendo agora. */
.passo--atual .passo-bolha { animation: passo-anel 1.6s ease-out infinite; background: var(--tx-gradient); }
.passo--atual .passo-ponto { background: #fff; height: 8px; width: 8px; }
.passo--fazer .passo-bolha {
  background: rgba(10, 12, 21, 0.34);
  backdrop-filter: blur(18px) saturate(1.3);
  -webkit-backdrop-filter: blur(18px) saturate(1.3);
  border: 1px solid rgba(146, 163, 255, 0.18);
}
.passo--fazer .passo-ponto { background: var(--tx-text-faint); height: 6px; width: 6px; }
.passo--falhou .passo-bolha { background: rgba(255, 84, 112, 0.14); border: 1px solid var(--tx-red); color: var(--tx-red); }
.passo-ponto { border-radius: 50%; display: block; }
.passo-nome {
  color: var(--tx-text-faint);
  font-family: var(--tx-font-ui);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.passo--aceso .passo-nome { color: var(--tx-text); font-weight: 700; }

@keyframes passo-anel {
  0% { box-shadow: 0 0 0 0 rgba(91, 127, 255, 0.45); }
  100% { box-shadow: 0 0 0 14px rgba(91, 127, 255, 0); }
}

.jogando-texto { align-items: center; display: flex; flex-direction: column; gap: 12px; max-width: 600px; }
.jogando-titulo {
  font-family: var(--tx-font-display);
  font-size: 46px;
  font-style: italic;
  font-weight: 800;
  letter-spacing: 0.02em;
  line-height: 1;
  margin: 0;
  text-shadow: 0 6px 30px rgba(0, 0, 0, 0.6);
  text-transform: uppercase;
}
.jogando-titulo.erro { color: var(--tx-red); }
.jogando-sub { color: var(--tx-text-muted); font-size: 15px; line-height: 1.6; margin: 0; min-height: 1.5em; }

/* A barra não mede nada — ninguém sabe quanto falta para um seat ligar. É um
   brilho correndo: diz "está andando", que é a única verdade disponível. Uma
   barra que ENCHE seria mentira, e a mentira aparece quando ela chega a 90% e
   fica lá. */
.jogando-barra {
  background: rgba(123, 140, 255, 0.12);
  border-radius: 99px;
  height: 6px;
  overflow: hidden;
  width: min(560px, 100%);
}
.jogando-barra span {
  background: linear-gradient(100deg, rgba(91, 127, 255, 0) 35%, var(--tx-blue-bright) 50%, rgba(91, 127, 255, 0) 65%) 0 0 / 200% 100%;
  display: block;
  height: 100%;
  width: 100%;
  animation: barra-brilho 1.3s linear infinite;
}
@keyframes barra-brilho { to { background-position: -200% 0; } }

.jogando-acoes { align-items: center; display: flex; gap: 12px; }
.jogando-acoes .botao { margin-top: 0; }
/* Encerrar uma sessão em andamento é destrutivo — o desenho pinta de vermelho,
   e é a única ação do app que não é neutra. */
.jogando-acoes .botao.encerrar {
  background: rgba(255, 84, 112, 0.1);
  border-color: rgba(255, 84, 112, 0.45);
  color: #ff8298;
}
.jogando-acoes .botao.encerrar:hover { background: rgba(255, 84, 112, 0.2); border-color: var(--tx-red); color: #fff; }

@media (prefers-reduced-motion: reduce) {
  .passo--atual .passo-bolha, .jogando-barra span { animation: none; }
}

/* O raio-corrida da splash chegou a viver aqui também, como indicador de
   espera desta tela. Saiu quando ela foi portada do protótipo: lá quem diz
   "está andando" é a barra de brilho, e dois indicadores na mesma tela é um a
   mais. Ele continua na splash, em `splash.css`. */

.pin {
  align-items: center;
  background: var(--tx-bg);
  border: 1px solid var(--tx-border-strong);
  border-radius: var(--tx-radius-md);
  display: flex;
  gap: 14px;
  margin: 14px 0;
  padding: 12px 16px;
}
.pin span { color: var(--tx-text-faint); font-size: 12px; letter-spacing: 2px; }
.pin strong {
  color: var(--tx-blue-bright);
  font-family: var(--tx-font-digital);
  font-size: 26px;
  letter-spacing: 6px;
  user-select: text;
}
.pin em { color: var(--tx-text-muted); font-size: 12px; font-style: normal; }

/* Existiu aqui um `.log`, o painel monoespaçado que desenhava as linhas do
   fluxo na tela de sessão. Saiu em 2026-08-13 junto com o `<pre>` que ele
   pintava: log é para quem conserta, e quem conserta lê o terminal. */

/* Sair da conta: mesma caixa dos outros botões, cor de aviso. Voltou para a
   tela de Conta quando a janela da conta virou telas do menu. */
.botao.sair { border-color: rgba(255, 130, 152, 0.34); color: #ff8298; }
.botao.sair:hover { background: rgba(255, 130, 152, 0.12); color: #fff; }

/* ===== cabeçalho de tela =====
   O desenho dizia o nome da tela na barra de título de 40px; a barra foi
   removida (decisão do Otávio) e cada tela passou a se apresentar como quisesse
   — ou a não se apresentar. Este bloco é o nome de volta, agora DENTRO da tela:
   título à esquerda, e um espaço à direita para o que aquela tela precisa dizer
   ou fazer (contador, Salvar/Cancelar).

   Nasceu como `.perfil-*`, do Perfil, que era a única tela com título de
   verdade. Virou `.tela-*` quando deixou de ser exceção. */
.tela-topo { align-items: flex-end; display: flex; gap: 20px; justify-content: space-between; margin-bottom: 18px; }
.tela-titulo { font-family: var(--tx-font-display); font-size: 26px; font-style: italic; font-weight: 800; letter-spacing: 0.02em; margin: 0 0 4px; text-transform: uppercase; }
/* A dica do cabeçalho não empurra: quem dá o respiro embaixo é o `.tela-topo`. */
.tela-topo .dica { margin-bottom: 0; }
.tela-acoes { align-items: center; display: flex; flex-shrink: 0; gap: 10px; }
.tela-acoes .botao:disabled { cursor: default; opacity: 0.45; }

/* ===== personalizar perfil ===== */
/* Duas colunas: a prévia fica parada à esquerda enquanto os controles rolam. */
/* A coluna da prévia é mais larga desde 2026-08-17: ela deixou de mostrar um
   cartãozinho de 96px e passou a mostrar o CARTÃO, que tem 392px no Retrato e
   664 na Plaquinha. */
.perfil-grade { align-items: start; display: grid; gap: 18px; grid-template-columns: minmax(320px, 430px) 1fr; }
.perfil-coluna { display: flex; flex-direction: column; }
.previa { display: flex; flex-direction: column; gap: 12px; position: sticky; top: 0; }

.previa-abas {
  background: rgba(10, 12, 21, 0.45);
  border: 1px solid rgba(146, 163, 255, 0.18);
  border-radius: var(--tx-radius-md);
  display: flex;
  gap: 4px;
  padding: 4px;
}
.previa-aba {
  background: none;
  border: none;
  border-radius: 7px;
  color: var(--tx-text-muted);
  cursor: pointer;
  flex: 1;
  font-family: var(--tx-font-ui);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  padding: 8px 6px;
  white-space: nowrap;
}
.previa-aba:hover { color: var(--tx-text); }
.previa-aba.ativa { background: rgba(91, 127, 255, 0.16); box-shadow: inset 0 0 0 1px var(--tx-blue-bright); color: var(--tx-text); }

.previa-forma { display: flex; flex-direction: column; gap: 6px; }
.previa-forma .perfil-rotulo { margin-top: 4px; }

/* O palco onde o cartão mora. Cada contexto o encena de um jeito: o Perfil é o
   cartão solto, o Card no chat mostra o véu por trás (é uma popover), e o
   Overlay põe o cartão sobre uma cena escura como a do jogo. */
.previa-palco { border-radius: 12px; display: flex; justify-content: center; padding: 4px; }
.previa-palco.ctx-chat { background: rgba(4, 5, 10, 0.55); box-shadow: inset 0 0 0 1px rgba(146, 163, 255, 0.14); padding: 18px; }
.previa-palco.ctx-jogo {
  background: radial-gradient(80% 60% at 50% 0%, rgba(61, 90, 254, 0.18), transparent 70%), rgba(2, 3, 7, 0.9);
  box-shadow: inset 0 0 0 1px rgba(146, 163, 255, 0.14);
  padding: 18px;
}
/* Dentro da prévia o cartão não pode mandar na largura da coluna: ele encolhe
   proporcionalmente, e o `zoom` mantém as medidas internas do desenho. */
.previa-palco .cartao-perfil { max-width: 100%; }

/* Selo: o `Badge` do design system, na forma que esta tela precisa. */
.selo {
  background: rgba(91, 127, 255, 0.16);
  border: 1px solid rgba(91, 127, 255, 0.4);
  border-radius: 999px;
  color: var(--tx-text);
  font-family: var(--tx-font-ui);
  font-size: 10px;
  font-style: normal;
  font-weight: 700;
  letter-spacing: 0.12em;
  padding: 3px 9px;
  text-transform: uppercase;
}
.selo.fraco { background: rgba(146, 163, 255, 0.08); border-color: rgba(146, 163, 255, 0.22); color: var(--tx-text-muted); }

.paleta-perfil { display: flex; flex-wrap: wrap; gap: 8px; }
.amostra {
  border: 2px solid transparent;
  border-radius: 50%;
  cursor: pointer;
  height: 34px;
  width: 34px;
}
.amostra:hover { border-color: rgba(146, 163, 255, 0.34); }
.amostra.ativa { border-color: var(--tx-blue-bright); box-shadow: 0 0 12px rgba(91, 127, 255, 0.55); }
/* Vira caixa flex por causa do SVG: como texto, o emoji se centralizava
   sozinho na linha de base; desenho precisa de eixo. */
.amostra.emblema {
  align-items: center;
  background: rgba(10, 12, 21, 0.34);
  border-color: rgba(146, 163, 255, 0.18);
  color: var(--tx-text-muted);
  display: flex;
  justify-content: center;
  padding: 0;
}
.amostra.emblema:hover { color: var(--tx-text); }
.amostra.emblema.ativa { color: var(--tx-blue-bright); }
.amostra.emblema.ativa { border-color: var(--tx-blue-bright); }

/* ===== molduras =====
   Grade de cartões e não linha de bolinhas (2026-08-15): cada moldura mostra um
   avatar SEU dentro dela e diz o próprio nome. 108px é o menor cartão em que o
   nome ("Predador") cabe numa linha só. */
.molduras { display: grid; gap: 10px; grid-template-columns: repeat(auto-fill, minmax(108px, 1fr)); }
.moldura-cartao {
  align-items: center;
  background: rgba(10, 12, 21, 0.34);
  border: 1px solid rgba(146, 163, 255, 0.14);
  border-radius: 12px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 14px 8px 11px;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.moldura-cartao:hover { background: rgba(91, 127, 255, 0.08); border-color: rgba(146, 163, 255, 0.34); }
.moldura-cartao.ativa { background: rgba(91, 127, 255, 0.14); border-color: var(--tx-blue-bright); }
.moldura-nome {
  color: var(--tx-text-muted);
  font-family: var(--tx-font-ui);
  font-size: 11.5px;
  font-weight: 600;
  white-space: nowrap;
}
.moldura-cartao.ativa .moldura-nome { color: var(--tx-text); }

/* ===== controles novos do perfil (2026-08-17) ===== */

/* Pílula: o botão de escolha do desenho — modelo, borda, animação, efeito. */
.pilulas { display: flex; flex-wrap: wrap; gap: 8px; }
.pilula {
  align-items: center;
  background: rgba(10, 12, 21, 0.45);
  border: 1px solid rgba(146, 163, 255, 0.18);
  border-radius: var(--tx-radius-md);
  color: var(--tx-text-muted);
  cursor: pointer;
  display: flex;
  font-family: var(--tx-font-ui);
  font-size: 11.5px;
  font-weight: 700;
  height: 36px;
  letter-spacing: 0.1em;
  padding: 0 14px;
  white-space: nowrap;
}
.pilula:hover { border-color: rgba(146, 163, 255, 0.34); color: var(--tx-text); }
.pilula.ativa { background: rgba(91, 127, 255, 0.16); border-color: var(--tx-blue-bright); color: var(--tx-text); }

/* A amostra de fonte mostra o SEU apelido escrito nela — a mesma regra dos
   cartões de moldura: ninguém escolhe "Circuito" no abstrato. */
.fontes { display: grid; gap: 8px; grid-template-columns: repeat(auto-fill, minmax(124px, 1fr)); }
.fonte-cartao {
  align-items: center;
  background: rgba(10, 12, 21, 0.45);
  border: 1px solid rgba(146, 163, 255, 0.18);
  border-radius: 12px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 8px;
  justify-content: center;
  min-height: 74px;
  overflow: hidden;
  padding: 12px 8px;
}
.fonte-cartao:hover { border-color: rgba(146, 163, 255, 0.34); }
.fonte-cartao.ativa { background: rgba(91, 127, 255, 0.14); border-color: var(--tx-blue-bright); }
.fonte-amostra { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fonte-nome {
  color: var(--tx-text-faint);
  font-family: var(--tx-font-ui);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.fonte-cartao.ativa .fonte-nome { color: var(--tx-text-muted); }

/* Interruptor liga/desliga, como no desenho: 46x26 com o botão correndo dentro.
   NÃO se chama `.chave`: esse nome já era das caixas de seleção da Configuração
   (`.linha.chaves`), e como este bloco vem depois no arquivo ele vencia — os
   rótulos "Encerrar o app no host ao sair" e "Overlay de desempenho" foram
   espremidos em 46px e se empilharam por cima dos campos. */
.perfil-chave { align-items: center; display: flex; gap: 14px; justify-content: space-between; padding: 10px 0; }
.perfil-chave-txt { display: flex; flex-direction: column; gap: 2px; }
.perfil-chave-txt strong { color: var(--tx-text); font-family: var(--tx-font-ui); font-size: 13.5px; font-weight: 600; }
.perfil-chave-txt em { color: var(--tx-text-faint); font-size: 11.5px; font-style: normal; }
.interruptor {
  align-items: center;
  background: rgba(20, 24, 48, 0.6);
  border: 1px solid rgba(146, 163, 255, 0.22);
  border-radius: 99px;
  cursor: pointer;
  display: flex;
  flex: 0 0 46px;
  height: 26px;
  justify-content: flex-start;
  padding: 0 3px;
  width: 46px;
}
.interruptor i { background: #6f7ba8; border-radius: 50%; display: block; height: 18px; width: 18px; }
.interruptor.ligada { background: var(--tx-gradient); border-color: transparent; box-shadow: 0 0 16px rgba(91, 127, 255, 0.45); justify-content: flex-end; }
.interruptor.ligada i { background: #fff; height: 20px; width: 20px; }

/* Os oito fundos, como cartões que mostram o fundo. */
.fundos-cosmeticos { display: grid; gap: 8px; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); }
.fundo-cartao {
  background: none;
  border: 2px solid transparent;
  border-radius: 10px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 0 0 6px;
  position: relative;
}
.fundo-cartao:hover .fundo-arte { border-color: rgba(146, 163, 255, 0.34); }
.fundo-cartao.ativa { border-color: var(--tx-blue-bright); }
.fundo-arte {
  border: 1px solid rgba(146, 163, 255, 0.18);
  border-radius: 8px;
  display: block;
  height: 56px;
  overflow: hidden;
  position: relative;
  width: 100%;
}
.fundo-cartao-nome {
  color: var(--tx-text-muted);
  font-family: var(--tx-font-ui);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-align: center;
}
.fundo-cartao.ativa .fundo-cartao-nome { color: var(--tx-text); }
.fundo-vivo {
  background: rgba(6, 8, 16, 0.72);
  border-radius: 99px;
  color: rgba(244, 246, 255, 0.75);
  font-family: var(--tx-font-ui);
  font-size: 8px;
  font-style: normal;
  font-weight: 700;
  left: 6px;
  letter-spacing: 0.14em;
  padding: 2px 6px;
  position: absolute;
  text-transform: uppercase;
  top: 6px;
}

.fundos { display: grid; gap: 8px; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); }
/* O nome do jogo mora dentro da arte, sobre um degradê de baixo para cima —
   por isso o cartão vira caixa flex e o texto encosta no rodapé. */
.fundo {
  align-items: flex-end;
  background-position: center;
  background-size: cover;
  border: 2px solid transparent;
  border-radius: 8px;
  cursor: pointer;
  display: flex;
  height: 62px;
  overflow: hidden;
  padding: 0;
}
.fundo-nome {
  background: linear-gradient(transparent, rgba(5, 6, 11, 0.88));
  color: var(--tx-text);
  font-family: var(--tx-font-ui);
  font-size: 10.5px;
  font-weight: 600;
  line-height: 1.25;
  overflow: hidden;
  padding: 12px 6px 5px;
  text-align: left;
  text-overflow: ellipsis;
  white-space: nowrap;
  width: 100%;
}
.fundo:hover { border-color: rgba(146, 163, 255, 0.34); }
.fundo.ativa { border-color: var(--tx-blue-bright); box-shadow: 0 0 12px rgba(91, 127, 255, 0.55); }

.perfil-linha { display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px; }
.perfil-rotulo { color: var(--tx-text-faint); font-family: var(--tx-font-ui); font-size: 10px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; }

/* ===== Loja (prévia da parceria Nuuvem) =====
   A vitrine pede mais largura que as telas de texto: 880px dá três colunas e
   sobra faixa morta dos dois lados numa janela de 1280. */
.painel.largo { max-width: 1120px; }
/* 220px e não 240: com o menu aberto numa janela de 1280 sobram 1000px de
   conteúdo, e 240 dá 1008 — oito pixels de nada faziam a grade cair de quatro
   colunas para três, e vitrine com três colunas mostra metade da loja. */
.grade-loja { display: grid; gap: 16px; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); }
.produto {
  background: rgba(18, 22, 38, 0.30);
  backdrop-filter: blur(22px) saturate(1.3);
  -webkit-backdrop-filter: blur(22px) saturate(1.3);
  border: 1px solid rgba(146, 163, 255, 0.18);
  border-radius: 12px;
  color: var(--tx-text);
  cursor: pointer;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding: 0;
  position: relative;
  text-align: left;
}
.produto:hover { border-color: var(--tx-border-strong); }
/* Zoom só na arte, como no card do catálogo — a borda azul foi decisão do
   desenho lá, e vale aqui pela mesma razão. */
.produto-arte { aspect-ratio: 16 / 9; object-fit: cover; transition: transform 0.35s ease; width: 100%; }
.produto:hover .produto-arte { transform: scale(1.04); }
.produto-off {
  background: var(--tx-gradient);
  border-radius: var(--tx-radius-pill);
  color: #fff;
  font-family: var(--tx-font-ui);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  padding: 3px 9px;
  position: absolute;
  right: 10px;
  top: 10px;
}
.produto-txt { display: flex; flex: 1; flex-direction: column; gap: 3px; padding: 12px 14px 14px; }
/* DUAS LINHAS SEMPRE, mesmo quando o nome cabe em uma: o `min-height` reserva a
   segunda. Sem isso a grade vira sanfona — o card mede 225, 243 ou 261px
   conforme o titulo quebre, e cada fileira fica de uma altura. Reservar o
   espaco e o que faz todos os cards nascerem do mesmo tamanho. */
.produto-titulo {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  font-size: 14.5px;
  font-weight: 600;
  line-height: 1.25;
  min-height: 2.5em;
  overflow: hidden;
}
.produto-sub { color: var(--tx-text-faint); font-size: 11.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* `margin-top: auto` gruda o preço no pé: com títulos de uma e de duas linhas
   na mesma fileira, sem isto os preços saem desalinhados entre os cards. */
.produto-precos { align-items: baseline; display: flex; gap: 8px; margin-top: auto; padding-top: 10px; }
.produto-de { color: var(--tx-text-faint); font-size: 12px; }
.produto-por { font-family: var(--tx-font-digital); font-size: 16px; font-weight: 700; }
.rodape-loja { margin-bottom: 0; margin-top: 18px; }
/* ===== tela do jogo =====
   Capa larga em cima e duas colunas embaixo, como no protótipo. A tela é
   `overflow-y: auto` própria porque a capa sangra até as bordas — dentro de um
   `.painel` ela teria a mesma margem do texto e deixaria de ser capa. */
.tela-jogo { display: flex; flex-direction: column; min-height: 0; overflow-y: auto; }
.jogo-capa { flex-shrink: 0; height: clamp(220px, 30vh, 320px); overflow: hidden; position: relative; }
.jogo-arte { height: 100%; inset: 0; object-fit: cover; position: absolute; width: 100%; }
/* Riscas diagonais: textura de fundo do desenho, quase invisível de perto. */
.jogo-riscas {
  background: repeating-linear-gradient(118deg, rgba(255, 255, 255, 0.045) 0 1px, transparent 1px 9px);
  inset: 0;
  position: absolute;
}
.jogo-fantasma {
  color: rgba(255, 255, 255, 0.055);
  font-family: var(--tx-font-display);
  font-size: 190px;
  font-style: italic;
  font-weight: 800;
  line-height: 1;
  pointer-events: none;
  position: absolute;
  right: -20px;
  text-transform: uppercase;
  top: -10px;
  user-select: none;
}
.jogo-veu {
  background:
    linear-gradient(90deg, rgba(5, 6, 11, 0.92) 0%, rgba(5, 6, 11, 0.6) 45%, rgba(5, 6, 11, 0.15) 80%),
    linear-gradient(0deg, #04050a 0%, rgba(5, 6, 11, 0.55) 30%, transparent 65%);
  inset: 0;
  pointer-events: none;
  position: absolute;
}
/* Ele fica à ESQUERDA, longe dos controles de janela — por isso 20px do topo e
   não o recuo dos painéis. */
.jogo-voltar { left: 40px; position: absolute; top: 20px; }
.jogo-voltar svg { margin-right: 6px; vertical-align: -2px; }
.jogo-capa-txt { bottom: 26px; display: flex; flex-direction: column; gap: 10px; left: 40px; position: absolute; right: 40px; }
.jogo-titulo {
  font-family: var(--tx-font-display);
  font-size: clamp(30px, 3.6vw, 52px);
  font-style: italic;
  font-weight: 800;
  line-height: 1;
  margin: 0;
  text-shadow: 0 6px 30px rgba(0, 0, 0, 0.7);
  text-transform: uppercase;
}
.jogo-corpo {
  align-items: start;
  display: grid;
  gap: 24px;
  grid-template-columns: minmax(0, 1fr) 300px;
  padding: 26px 40px 44px;
}
/* Numa janela estreita a coluna de amigos vira fileira embaixo, em vez de
   espremer a descrição a três palavras por linha. */
@media (max-width: 980px) {
  .jogo-corpo { grid-template-columns: minmax(0, 1fr); }
}
.jogo-principal { display: flex; flex-direction: column; gap: 22px; min-width: 0; }
.jogo-acoes { align-items: center; display: flex; gap: 12px; }
.jogo-desc { color: #dfe4f7; font-size: 15px; line-height: 1.7; margin: 0; max-width: 620px; }
.jogo-principal .numeros { max-width: 620px; }
.jogo-lado { margin-bottom: 0; }

/* ===== camaleão =====
   As duas camadas do fundo que segue a arte. Ficam ATRÁS de tudo (z-index -1,
   como o `body::before`) e pintam por cima dele, porque filho desenha depois do
   pseudo-elemento — é o que deixa o brilho de marca aparecer quando não há cor
   extraída. 900ms é o tempo em que a troca lê como maré, e não como flash. */
.ambiente {
  inset: 0;
  opacity: 0;
  pointer-events: none;
  position: absolute;
  transition: opacity 900ms ease;
  z-index: -1;
}
.ambiente.ativa { opacity: 1; }

/* Hero da Loja: o `.destaque` do Início, mas DENTRO de um painel — lá ele é
   full-bleed e encosta nas bordas da janela; aqui precisa de canto arredondado
   e de menos altura, senão empurra a busca e as prateleiras para fora da tela. */
.destaque.vitrine { border-radius: 16px; height: clamp(230px, 30vh, 320px); margin-bottom: 18px; }
.destaque.vitrine .destaque-conteudo { gap: 8px; padding: 0 28px 22px; }
.destaque.vitrine .destaque-titulo { font-size: clamp(24px, 2.4vw, 34px); }
.destaque.vitrine .destaque-acoes { align-items: center; gap: 16px; }
.hero-precos { align-items: baseline; display: flex; gap: 8px; }
.hero-por { font-family: var(--tx-font-digital); font-size: 20px; font-weight: 700; }
/* Os pontos ficam ao lado do preço, e não jogados na borda: é a ordem do
   Início (ação, depois navegação), e o hero aqui tem um terço da largura da
   janela — na borda eles pareceriam de outro elemento. */
.destaque.vitrine .pontos { margin-left: 4px; }

/* Trilhos da Loja: a mesma peça do Início, com uma coluna a mais — o card de
   produto é mais estreito que o do catálogo, e com quatro sobrava faixa. */
.loja-fileiras { display: flex; flex-direction: column; gap: 26px; margin-bottom: 26px; }
.loja-fileiras .trilho { --colunas: 4; gap: 16px; }
.loja-fileiras .trilho > * { flex: 0 0 calc((100% - var(--sobra) - var(--colunas) * 16px) / var(--colunas)); }

/* ===== aba Conquistas ===== */
/* Grade elástica: são oito cartões de texto curto, e coluna fixa deixaria uma
   faixa morta do lado direito em janela larga. */
.grade-conquistas { display: grid; gap: 14px; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); }
.conquista {
  align-items: center;
  background: rgba(18, 22, 38, 0.30);
  backdrop-filter: blur(22px) saturate(1.3);
  -webkit-backdrop-filter: blur(22px) saturate(1.3);
  border: 1px solid var(--tx-border);
  border-radius: 12px;
  display: flex;
  gap: 12px;
  padding: 14px 16px;
}
.conquista-icone {
  align-items: center;
  background: var(--tx-gradient-soft);
  border: 1px solid var(--tx-border-strong);
  border-radius: 10px;
  /* O emblema herda esta cor (os paths são `currentColor`), então desbloqueada
     acende no azul da marca e trancada apaga no cinza. */
  color: var(--tx-blue-bright);
  display: flex;
  flex: 0 0 42px;
  height: 42px;
  justify-content: center;
}
.conquista-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
/* Mesma regra dos produtos, pelo mesmo motivo: hoje as oito conquistas cabem em
   duas linhas de descrição e a grade sai reta, mas basta a janela estreitar (ou
   nascer uma conquista de nome comprido) para as fileiras desalinharem. O nome
   fica em uma linha e a descrição em duas, reservadas. */
.conquista-nome { font-size: 15px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.conquista .pessoa-sub {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-height: 1.35;
  min-height: 2.7em;
  overflow: hidden;
  white-space: normal;
}
/* Trancada é a MAIORIA da tela no começo da vida da conta. Esmaece, mas não
   some: a graça é ler o que falta fazer. */
.conquista.trancada { opacity: 0.55; }
.conquista.trancada .conquista-icone { background: rgba(138, 147, 166, 0.12); border-color: rgba(138, 147, 166, 0.3); color: #8a93a6; }

.nivel { margin-bottom: 18px; }
.nivel-topo { align-items: baseline; display: flex; gap: 12px; justify-content: space-between; margin-bottom: 10px; }
.nivel-topo strong { font-family: var(--tx-font-digital); font-size: 20px; font-weight: 700; }
.nivel-trilho { background: rgba(123, 140, 255, 0.12); border-radius: var(--tx-radius-pill); height: 8px; overflow: hidden; }
.nivel-trilho span { background: var(--tx-gradient); border-radius: inherit; display: block; height: 100%; width: 0; }

/* ===== aba Jogos ===== */
/* `.jogos-topo` continua sendo o cabeçalho de SEÇÃO (os blocos "Jogos" e
   "Pessoas" da Busca). O nome da TELA é outro papel e mora no `.tela-topo`. */
.jogos-topo { align-items: baseline; display: flex; gap: 12px; justify-content: space-between; margin-bottom: 14px; }
/* As pílulas perderam o `.jogos-topo` em volta quando o contador subiu para o
   cabeçalho; o respiro de baixo vinha dele. */
.jogos-filtros { margin-bottom: 14px; }
.jogos-filtros:empty { margin-bottom: 0; }
.secao-titulo { color: var(--tx-text-muted); font-family: var(--tx-font-ui); font-size: 12px; font-weight: 700; letter-spacing: 0.2em; margin: 0; text-transform: uppercase; }
/* 264px é a largura de card do desenho; `auto-fill` deixa a grade respirar
   quando a janela cresce, sem esticar card nenhum. */
.grade-jogos { display: grid; gap: 18px; grid-template-columns: repeat(auto-fill, 264px); }
.grade-jogos .card { width: 264px; }

/* Busca da biblioteca — campo do protótipo: 52px, vidro e borda forte. */
.busca-caixa { margin-bottom: 16px; position: relative; }
.busca-caixa input {
  background: rgba(15, 19, 38, 0.38);
  backdrop-filter: blur(16px) saturate(1.3);
  -webkit-backdrop-filter: blur(16px) saturate(1.3);
  border: 1px solid var(--tx-border-strong);
  border-radius: 12px;
  font-family: var(--tx-font-body);
  font-size: 16px;
  height: 52px;
  padding: 0 52px 0 46px;
  width: 100%;
}
.busca-caixa input:focus { border-color: var(--tx-blue-bright); box-shadow: 0 0 0 3px rgba(91, 127, 255, 0.14); }
.busca-caixa input::-webkit-search-cancel-button { display: none; }
.busca-icone { color: var(--tx-text-faint); display: flex; left: 16px; pointer-events: none; position: absolute; top: 50%; transform: translateY(-50%); }
.busca-limpar {
  background: transparent;
  border: 1px solid transparent;
  border-radius: 9px;
  color: var(--tx-text-faint);
  cursor: pointer;
  height: 36px;
  position: absolute;
  right: 8px;
  top: 8px;
  width: 36px;
}
.busca-limpar:hover { border-color: var(--tx-border); color: var(--tx-text); }

.filtros { display: flex; flex-wrap: wrap; gap: 8px; }
.filtro {
  background: transparent;
  border: 1px solid rgba(146, 163, 255, 0.18);
  border-radius: 99px;
  color: var(--tx-text-muted);
  cursor: pointer;
  font-family: var(--tx-font-ui);
  font-size: 13px;
  font-weight: 600;
  height: 32px;
  padding: 0 14px;
  white-space: nowrap;
}
.filtro:hover { border-color: var(--tx-border-strong); color: var(--tx-text); }
.filtro.ativo { background: rgba(91, 127, 255, 0.14); border-color: var(--tx-blue-bright); color: var(--tx-text); }

/* ===== véu (PoC, 2026-08-15) =====
   A mesma janela do app virando camada por cima do jogo.

   Não há tela nova aqui: `.veu-ativo` apaga a casca inteira (titlebar, menu,
   palco, camaleão) e deixa a janela translúcida; `.veu-aberto` acende o painel.
   Entre os dois estados a janela continua sendo a mesma, com o mesmo DOM e o
   mesmo estado de voz — é essa a economia que justificou não fazer overlay em
   segunda janela.

   O fundo opaco do app é pintado em DOIS lugares (`body` e `body::before`), e
   os dois precisam sair: deixar qualquer um deles opaco faz a janela
   transparente continuar preta, e o jogo nunca aparece embaixo. */
body.veu-ativo { background: transparent; }
body.veu-ativo::before { display: none; }
body.veu-ativo .titulo,
body.veu-ativo .corpo,
body.veu-ativo .ambiente { display: none !important; }

.veu {
  align-items: flex-end;
  bottom: 0;
  display: flex;
  justify-content: center;
  left: 0;
  padding: 0 0 56px;
  position: fixed;
  right: 0;
  top: 0;
  z-index: 90;
  /* Escurece o jogo em vez de tapá-lo: o que está acontecendo continua legível
     atrás do painel, e é essa a diferença para o alt+tab.

     SEM `backdrop-filter` aqui, e não por gosto: numa janela transparente ele
     não enxerga o jogo. O filtro só amostra o que a PÁGINA desenhou atrás do
     elemento, e atrás desta camada não há página nenhuma — há o vazio por onde
     o jogo aparece. Blur nesta camada é CSS morto que custa GPU. O escurecido
     translúcido, esse funciona: ele é pintado pela página e o compositor o
     mistura com o que está embaixo da janela. */
  background: rgba(4, 5, 10, 0.52);
}

.veu-caixa {
  /* Opaco o bastante para ser um cartão de verdade: o vidro fosco do resto do
     app depende de blur, e aqui blur não há (ver a nota acima). */
  background: rgba(10, 12, 22, 0.94);
  border: 1px solid var(--tx-border-strong);
  border-radius: var(--tx-radius-lg);
  padding: 20px 22px 18px;
  width: min(860px, 92vw);
  /* O painel cresce com o que há dentro — a lista de canais, os amigos online,
     e desde 2026-08-23 o bloco da transmissão. Numa tela de 720p a soma já
     passa da altura disponível, e sem isto o que sobra sai pela BORDA DE CIMA
     (a caixa é ancorada embaixo): some o relógio, some o nome do jogo, e não há
     como rolar até eles. */
  max-height: calc(100vh - 96px);
  overflow-y: auto;
}

.veu-topo {
  align-items: flex-end;
  border-bottom: 1px solid var(--tx-border);
  display: flex;
  justify-content: space-between;
  padding-bottom: 14px;
}
.veu-rotulo {
  color: var(--tx-text-muted);
  display: block;
  font-size: 12px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}
.veu-jogo { font-family: var(--tx-font-display); font-size: 24px; margin: 2px 0 0; }
.veu-tempo { color: var(--tx-text-muted); font-family: var(--tx-font-digital); font-size: 20px; }

.veu-corpo {
  display: grid;
  gap: 20px;
  grid-template-columns: minmax(0, 260px) minmax(0, 1fr);
  padding: 16px 0 18px;
}
.veu-titulo {
  color: var(--tx-text-muted);
  font-size: 12px;
  letter-spacing: 0.09em;
  margin: 0 0 10px;
  text-transform: uppercase;
}
.veu-vazio { color: var(--tx-text-faint); font-size: 13px; margin: 0; }

/* A barra de voz chega aqui EMPRESTADA do menu, com a largura que ela tem lá.
   Solta-la é o único ajuste — o resto do visual dela continua valendo. */
.veu-voz .voz-barra { margin: 0; width: 100%; }

.veu-amigos { display: flex; flex-direction: column; gap: 6px; max-height: 190px; overflow-y: auto; }
.veu-amigo {
  align-items: center;
  border-radius: var(--tx-radius-md);
  display: flex;
  gap: 10px;
  padding: 6px 8px;
}
.veu-amigo:hover { background: rgba(255, 255, 255, 0.05); }
.veu-amigo-txt { display: flex; flex-direction: column; min-width: 0; }
.veu-amigo-nome { font-size: 14px; }
.veu-amigo-sub {
  color: var(--tx-text-muted);
  font-size: 12px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.veu-acoes { border-top: 1px solid var(--tx-border); display: flex; gap: 10px; padding-top: 14px; }
.veu-dica { align-self: center; color: var(--tx-text-faint); font-size: 12px; margin-left: auto; }

/* Entrar num canal de dentro do jogo. A linha é a `.sala` da coluna de canais
   do app — mesma matéria, mesmo desenho —, só mais apertada: aqui ela divide um
   painel com os amigos e o relógio da partida. */
.veu-subtitulo { color: var(--tx-text-faint); font-size: 11px; margin: 14px 0 6px; text-transform: uppercase; letter-spacing: 0.08em; }
.veu-salas { display: flex; flex-direction: column; gap: 2px; max-height: 176px; overflow-y: auto; }
.veu-salas .sala { padding: 6px; }
.veu-amigo-sub.viva { color: #4ce0ad; }
.veu-amigo .sala-btn { flex: 0 0 auto; }

/* ===== a transmissão =====
   O terceiro bloco do painel, e o único que atravessa as duas colunas: voz e
   amigos já dividem os 860px da caixa, e espremer cinco controles numa faixa de
   260px daria campos que ninguém acerta com o mouse no meio de uma partida.

   Os campos são os `input`/`select` do app (a regra global lá em cima vale
   aqui: é a mesma folha), só mais baixos — este painel divide a tela com um
   jogo, e cada pixel a mais é jogo a menos. */
.veu-bloco--largo { border-top: 1px solid var(--tx-border); grid-column: 1 / -1; padding-top: 16px; }
.veu-tx { align-items: flex-end; display: flex; flex-wrap: wrap; gap: 14px; }
.veu-tx-campo { display: flex; flex: 1 1 132px; flex-direction: column; gap: 5px; min-width: 0; }
.veu-tx-campo--larga { flex: 1.6 1 190px; }
.veu-tx-campo > span {
  align-items: baseline;
  color: var(--tx-text-faint);
  display: flex;
  font-size: 11px;
  gap: 6px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
/* O número da banda dentro do rótulo: não há espaço para um campo ao lado da
   barra, e barra sem número é escolha que não se repete depois. */
.veu-tx-campo em { color: var(--tx-text); font-size: 12px; font-style: normal; letter-spacing: 0; }
.veu-tx-campo select { font-size: 13px; padding: 7px 9px; }
.veu-tx-campo input[type='range'] {
  accent-color: var(--tx-blue-bright);
  background: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border: 0;
  height: 30px;
  padding: 0;
  width: 100%;
}
.veu-tx-chave { align-items: center; color: var(--tx-text-muted); display: flex; flex: 0 0 auto; font-size: 13px; gap: 7px; padding-bottom: 8px; }
.veu-tx-chave input { accent-color: var(--tx-blue); padding: 0; }

.veu-tx-rodape { align-items: center; display: flex; gap: 14px; margin-top: 14px; }
.veu-tx-rodape .tx-btn { flex: 0 0 auto; }
/* A nota troca de assunto conforme o momento (o teto do plano antes de mexer, o
   preço da mudança depois), então ela não pode saltar de altura a cada troca —
   daí a linha reservada. */
.veu-tx-nota { color: var(--tx-text-faint); font-size: 12px; line-height: 1.45; margin: 0; min-height: 17px; }

/* A pastilha da transmissão no HUD, irmã da pastilha da voz: mesma casca,
   outro assunto. O ponto que pulsa é o que diz que ainda está acontecendo —
   sem ele, "Reabrindo a transmissão…" parado numa tela sem imagem parece o
   aviso de algo que travou. */
.veu-hud-tx { border-color: rgba(146, 163, 255, 0.45); color: var(--tx-text); }
.veu-hud-tx-pulso {
  animation: veu-tx-pulso 1.1s ease-in-out infinite;
  background: var(--tx-blue-bright);
  border-radius: 999px;
  flex: 0 0 7px;
  height: 7px;
  width: 7px;
}
@keyframes veu-tx-pulso {
  0%, 100% { opacity: 0.25; }
  50% { opacity: 1; }
}

/* ===== o HUD da voz =====
   A voz com o véu FECHADO, que é como a partida corre a maior parte do tempo.
   Ele resolve o que o painel não resolvia: saber se o próprio microfone está
   aberto e quem está falando, sem tirar os olhos do jogo nem apertar F9.

   Duas regras governam o desenho:

   1. APAGADO por padrão. O jogo é o que a pessoa está olhando; a pastilha vive
      a 40% e só acende (`.viva`) quando há motivo — alguém falando, você no
      mudo, a voz caindo, ou a piscada de confirmação do Ctrl+Shift+M.
   2. ATRAVESSÁVEL sempre. A janela do véu ignora o mouse enquanto está fechada
      (`setIgnoreMouseEvents`), e o `pointer-events: none` aqui é o cinto de
      segurança: se um dia o véu passar a receber clique com o painel fechado,
      o HUD continua não roubando o tiro que era para o jogo. */
.veu-hud {
  display: flex;
  flex-direction: column;
  gap: 6px;
  align-items: flex-end;
  opacity: 0.4;
  pointer-events: none;
  position: fixed;
  right: 18px;
  top: 18px;
  transition: opacity 0.22s ease;
  z-index: 80;
}
.veu-hud.viva { opacity: 1; }
.veu-hud-pastilha {
  align-items: center;
  /* Opaco o bastante para ser legível sobre QUALQUER cena do jogo — o fundo
     aqui não é o app, é o que estiver na tela naquele quadro. */
  background: rgba(6, 8, 16, 0.82);
  border: 1px solid var(--tx-border-strong);
  border-radius: 999px;
  color: var(--tx-text-muted);
  display: flex;
  font-size: 12.5px;
  gap: 7px;
  padding: 5px 12px 5px 10px;
}
.veu-hud-pastilha svg { flex: 0 0 15px; height: 15px; width: 15px; }
.veu-hud-pastilha.mudo { border-color: rgba(255, 99, 110, 0.5); color: var(--tx-red); }
.veu-hud-pastilha.ruim { border-color: var(--tx-red); color: var(--tx-red); }
/* Reconectando: nem verde nem vermelho — a sala não caiu, mas por enquanto
   ninguém te ouve. */
.veu-hud-pastilha.atencao { border-color: rgba(255, 193, 94, 0.55); color: #ffc15e; }
.veu-hud-gente { display: flex; flex-direction: column; gap: 4px; align-items: flex-end; }
.veu-hud-pessoa {
  align-items: center;
  background: rgba(6, 8, 16, 0.82);
  border: 1px solid rgba(47, 214, 162, 0.45);
  border-radius: 999px;
  color: var(--tx-text);
  display: flex;
  font-size: 12.5px;
  gap: 7px;
  padding: 3px 12px 3px 4px;
}

/* ===== avisos =====
   A caixa de entrada e as torradas. O desenho é o da lista de pessoas (mesma
   altura de linha, mesmo avatar, mesmas ações miúdas à direita) porque é a
   mesma matéria — gente falando com você. O que muda é a marca de não lido: uma
   barra de marca à esquerda, e não um fundo diferente, que numa lista longa
   viraria zebra. */
.avisos { display: flex; flex-direction: column; gap: 2px; }
.aviso {
  align-items: center;
  border-bottom: 1px solid var(--tx-border);
  border-left: 2px solid transparent;
  display: flex;
  gap: 12px;
  padding: 12px 14px;
}
.aviso:last-child { border-bottom: none; }
.aviso.novo { background: rgba(146, 163, 255, 0.05); border-left-color: var(--tx-blue-bright); }
.aviso-meio { display: flex; flex: 1; flex-direction: column; gap: 2px; min-width: 0; }
.aviso-titulo { font-size: 14.5px; font-weight: 600; }
.aviso-corpo {
  color: var(--tx-text-muted);
  font-size: 12.5px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.aviso-quando { color: var(--tx-text-faint); font-size: 11.5px; }
.aviso-arte { border-radius: 6px; flex: 0 0 auto; height: 44px; object-fit: cover; width: 78px; }
.aviso-acoes { align-items: center; display: flex; gap: 8px; }
/* O ícone ocupa o lugar do avatar quando não há quem: promoção da loja não tem
   remetente, e a linha sem a coluna da esquerda desalinharia a lista toda. */
.aviso-icone {
  align-items: center;
  background: var(--tx-surface-2);
  border-radius: 50%;
  color: var(--tx-blue-bright);
  display: flex;
  flex: 0 0 auto;
  height: 28px;
  justify-content: center;
  width: 28px;
}
.aviso-dispensar {
  background: none;
  border: none;
  color: var(--tx-text-faint);
  cursor: pointer;
  font-size: 18px;
  line-height: 1;
  padding: 2px 6px;
}
.aviso-dispensar:hover { color: var(--tx-text); }

/* ===== torradas =====
   Canto inferior direito, empilhadas de baixo para cima. Ficam acima do véu
   (z-index 90) para a ordem das camadas ficar certa quando ele estiver aberto —
   em jogo com o véu FECHADO quem avisa é o balão do sistema, porque aí a janela
   não tem foco (ver `emFoco` em src/main/avisos.js). */
.torradas {
  bottom: 18px;
  display: flex;
  flex-direction: column-reverse;
  gap: 8px;
  pointer-events: none;
  position: fixed;
  right: 18px;
  z-index: 120;
}
.torrada {
  align-items: center;
  animation: torrada-entra 0.22s ease;
  backdrop-filter: blur(22px) saturate(1.3);
  -webkit-backdrop-filter: blur(22px) saturate(1.3);
  background: rgba(18, 22, 38, 0.86);
  border: 1px solid var(--tx-border-strong);
  border-radius: var(--tx-radius-md);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.55);
  color: var(--tx-text);
  cursor: pointer;
  display: flex;
  gap: 10px;
  max-width: 340px;
  padding: 10px 14px;
  pointer-events: auto;
  text-align: left;
}
.torrada:hover { border-color: var(--tx-blue-bright); }
.torrada.saindo { animation: torrada-sai 0.2s ease forwards; }
.torrada-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.torrada-txt strong { font-size: 14px; }
.torrada-txt span {
  color: var(--tx-text-muted);
  font-size: 12.5px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
@keyframes torrada-entra { from { opacity: 0; transform: translateX(16px); } to { opacity: 1; transform: none; } }
@keyframes torrada-sai { to { opacity: 0; transform: translateX(16px); } }

/* ===== escolher um amigo =====
   Mesma folha flutuante da paleta de emoji (herda posição, fundo e sombra de
   `.paleta`); o que muda é ser uma coluna de gente em vez de uma grade de
   emoji. */
.paleta.escolha { flex-direction: column; flex-wrap: nowrap; max-height: 320px; overflow-y: auto; width: 232px; }
.escolha-titulo {
  color: var(--tx-text-faint);
  font-family: var(--tx-font-ui);
  font-size: 10.5px;
  letter-spacing: 0.14em;
  padding: 4px 6px 6px;
  text-transform: uppercase;
}
.escolha-item {
  align-items: center;
  display: flex;
  font-size: 14px;
  gap: 8px;
  justify-content: flex-start;
  padding: 6px;
  text-align: left;
  width: 100%;
}
.escolha .dica { padding: 4px 6px 6px; }

/* Mandar a oferta para um amigo: canto oposto ao selo de desconto, e só no
   hover — a vitrine é para olhar, e um botão fixo em cada card competiria com
   o preço. */
.produto-enviar {
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  background: rgba(6, 8, 18, 0.72);
  border: 1px solid var(--tx-border-strong);
  border-radius: var(--tx-radius-pill);
  color: var(--tx-text);
  cursor: pointer;
  font-family: var(--tx-font-ui);
  font-size: 10.5px;
  font-weight: 700;
  left: 10px;
  letter-spacing: 0.1em;
  opacity: 0;
  padding: 4px 10px;
  position: absolute;
  text-transform: uppercase;
  top: 10px;
  transition: opacity 0.16s ease;
  z-index: 2;
}
.produto:hover .produto-enviar, .produto-enviar:focus-visible { opacity: 1; }
.produto-enviar:hover { border-color: var(--tx-blue-bright); }

/* ===== oferta e convite DENTRO da conversa =====
   Card na bolha da mensagem: a oferta que um amigo mandou é conteúdo do papo,
   não um link colado. */
.card-oferta {
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--tx-border);
  border-radius: var(--tx-radius-md);
  display: flex;
  gap: 12px;
  max-width: 420px;
  overflow: hidden;
  padding: 10px;
}
.card-oferta-arte { border-radius: 8px; flex: 0 0 auto; height: 68px; object-fit: cover; width: 120px; }
.card-oferta-txt { display: flex; flex: 1; flex-direction: column; gap: 6px; min-width: 0; }
.card-oferta-txt strong { font-size: 14px; }
.card-oferta-precos { align-items: baseline; display: flex; gap: 8px; }
.card-oferta-precos s { color: var(--tx-text-faint); font-size: 12px; }
.card-oferta-precos b { font-size: 15px; }
.card-oferta-off {
  background: var(--tx-gradient);
  border-radius: var(--tx-radius-pill);
  color: #fff;
  font-family: var(--tx-font-ui);
  font-size: 10.5px;
  font-style: normal;
  font-weight: 700;
  padding: 2px 8px;
}
.card-oferta-nota { color: var(--tx-text-muted); font-size: 12.5px; margin: 0; }
.card-oferta .botao, .card-convite .btn-primario { align-self: flex-start; }

.card-convite {
  align-items: flex-start;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--tx-border);
  border-radius: var(--tx-radius-md);
  display: flex;
  flex-direction: column;
  gap: 6px;
  max-width: 420px;
  padding: 12px 14px;
}
.card-convite strong { font-size: 15px; }
.card-convite-sub { color: var(--tx-text-muted); font-size: 12.5px; }

/* ===== o perfil da v4 (2026-09-05) =====
   O rodapé "eu" do trilho e o painel no meio: capa, foto com moldura, nome
   com efeito, números, conquistas, contas e o formulário. As listas de capa,
   cor, moldura e efeito são as do desenho da v4; aqui só a roupa. */
.v4-eu {
  align-items: center;
  border-top: 1px solid rgba(146, 163, 255, 0.12);
  display: flex;
  gap: 4px;
  margin-top: auto;
  padding-top: 10px;
}
.v4-eu .v4-linha { flex: 1; min-width: 0; }
.v4-perfil { display: flex; flex: 1; flex-direction: column; gap: 18px; min-height: 0; overflow-y: auto; padding: 8px 24px 28px; }
/* coluna flex que rola: sem isto o flex-shrink esmaga a capa e o cartão antes de rolar */
.v4-perfil > *, .v4-explorar > * { flex-shrink: 0; }
.v4-cartao-perfil {
  background: rgba(10, 12, 21, 0.4);
  border: 1px solid rgba(146, 163, 255, 0.14);
  border-radius: 18px;
  overflow: hidden;
}
.v4-capa { display: flex; height: 132px; justify-content: flex-end; padding: 10px; position: relative; }
.v4-trocar {
  align-self: flex-start;
  background: rgba(5, 6, 11, 0.62);
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 999px;
  color: #fff;
  cursor: pointer;
  font-family: var(--tx-font-ui);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  padding: 5px 12px;
  text-transform: uppercase;
}
.v4-cabeca { align-items: flex-start; display: flex; gap: 18px; padding: 0 20px 18px; }
.v4-foto-caixa { display: flex; flex-direction: column; gap: 8px; margin-top: -44px; }
.face.v4-foto { border-radius: 26px; font-size: 30px; height: 88px; width: 88px; }
.v4-trocar-foto { align-self: center; }
.v4-quem { display: flex; flex: 1; flex-direction: column; gap: 4px; min-width: 0; padding-top: 10px; }
.v4-nome { display: inline-block; font-family: var(--tx-font-display); font-size: 30px; letter-spacing: 0.02em; margin: 0; }
.v4-bio { color: var(--tx-text-muted); margin: 4px 0 0; }
.v4-numeros { display: grid; gap: 10px; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); }
.v4-numero {
  background: rgba(10, 12, 21, 0.4);
  border: 1px solid rgba(146, 163, 255, 0.14);
  border-radius: 14px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 12px 14px;
}
.v4-numero b { font-family: var(--tx-font-digital); font-size: 22px; }
.v4-numero span { color: var(--tx-text-faint); font-size: 12px; }
.v4-secao-perfil { display: flex; flex-direction: column; gap: 8px; }
.v4-conquistas { display: grid; gap: 8px; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); }
.v4-conquista {
  align-items: center;
  background: rgba(10, 12, 21, 0.4);
  border: 1px solid rgba(146, 163, 255, 0.12);
  border-radius: 12px;
  display: flex;
  gap: 10px;
  opacity: 0.55;
  padding: 10px 12px;
}
.v4-conquista.feita { border-color: rgba(250, 204, 21, 0.35); opacity: 1; }
.v4-emblema { font-size: 22px; }
.v4-conquista.feita .v4-emblema { filter: drop-shadow(0 0 8px rgba(250, 204, 21, 0.6)); }
.v4-conta {
  align-items: center;
  background: rgba(10, 12, 21, 0.4);
  border: 1px solid rgba(146, 163, 255, 0.12);
  border-radius: 12px;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  padding: 10px 14px;
}
.v4-conta.apagada { opacity: 0.55; }
.v4-conta-loja { font-family: var(--tx-font-ui); font-weight: 700; letter-spacing: 0.06em; min-width: 64px; text-transform: uppercase; }
.v4-conta-avatar { border-radius: 8px; height: 28px; width: 28px; }
.v4-editar { display: flex; flex-direction: column; gap: 12px; }
.v4-editar .entrada-texto { min-height: 60px; }
.v4-escolha { align-items: center; display: flex; flex-wrap: wrap; gap: 10px; }
.v4-escolha-rotulo { color: var(--tx-text-faint); font-size: 12px; min-width: 110px; }
.v4-capa-op {
  border: 2px solid rgba(146, 163, 255, 0.18);
  border-radius: 8px;
  cursor: pointer;
  height: 30px;
  width: 52px;
}
.v4-capa-op.ativa { box-shadow: var(--tx-glow); }
.v4-alternar { align-items: center; color: var(--tx-text-muted); cursor: pointer; display: flex; font-size: 13.5px; gap: 8px; }
.v4-editar-rodape { align-items: center; display: flex; gap: 14px; }
.v4-editar-rodape .dica { margin: 0; }
/* os efeitos do nome — os mesmos quadros do desenho, com prefixo para não bater no app */
@keyframes v4inkneon { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } }
@keyframes v4inkraio { 0%, 100% { color: #3d5afe; } 40% { color: #8b5cf6; } 70% { color: #22d3ee; } }
@keyframes v4inkarco { 0%, 100% { color: #f472b6; } 20% { color: #facc15; } 40% { color: #4ade80; } 60% { color: #22d3ee; } 80% { color: #b7a4ff; } }
@keyframes v4inkpulso { 0%, 100% { text-shadow: 0 0 14px currentColor; } 50% { text-shadow: 0 0 2px transparent; } }

/* ===== palco: a sala de voz dos espaços (2026-09-10) =====
   O meio do chat vira palco ao entrar numa sala: quadros de tela, câmera e
   gente, controles embaixo. Quem desenha é o palco.js; aqui é só a roupa. */
.v4-palco { box-sizing: border-box; display: flex; flex: 1; flex-direction: column; gap: 12px; min-height: 0; padding: 14px 18px 16px; }
.palco-topo { align-items: center; display: flex; gap: 12px; }
.palco-selo {
  align-items: center;
  background: rgba(91, 127, 255, 0.14);
  border: 1px solid rgba(123, 140, 255, 0.3);
  border-radius: 10px;
  color: var(--tx-blue-bright);
  display: flex;
  flex: 0 0 36px;
  height: 36px;
  justify-content: center;
}
.palco-nome { font-family: var(--tx-font-display); font-size: 19px; font-style: italic; letter-spacing: 0.5px; }
.palco-sub { color: var(--tx-text-faint); font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.palco-titulos { min-width: 0; }
.palco-topo-dir { align-items: center; display: flex; gap: 14px; margin-left: auto; }
.palco-conta { color: var(--tx-text-muted); font-size: 12.5px; white-space: nowrap; }
.palco-tempo { color: var(--tx-blue-bright); font-family: var(--tx-font-digital); font-size: 13px; letter-spacing: 0.1em; }

/* A grade dos quadros. auto-fit: 1 vídeo ocupa tudo, 4 viram 2×2 sozinhos. */
.palco-grade {
  align-content: center;
  display: grid;
  flex: 1;
  gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  min-height: 0;
  overflow-x: hidden;
  overflow-y: auto;
}
.ptile {
  aspect-ratio: 16 / 9;
  background: #05060b;
  border: 1px solid rgba(123, 140, 255, 0.22);
  border-radius: var(--tx-radius-md);
  overflow: hidden;
  position: relative;
}
.ptile canvas, .ptile video { display: block; height: 100%; object-fit: cover; width: 100%; }
/* A própria imagem espelhada — é como a pessoa se vê no espelho. */
.ptile.eu.ptile-cam video { transform: scaleX(-1); }
.ptile.clicavel { cursor: zoom-in; }
.ptile.clicavel:hover { border-color: var(--tx-blue-bright); }
/* Quem fala ganha o anel — no quadro da pessoa, nunca no da tela. */
.ptile.falando { border-color: var(--tx-blue-bright); box-shadow: 0 0 0 2px rgba(91, 127, 255, 0.35), 0 0 24px rgba(61, 90, 254, 0.35); }
.ptile-avatar { align-items: center; background: var(--tx-surface); display: flex; justify-content: center; }
.ptile-face {
  align-items: center;
  border-radius: 50%;
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.45);
  display: flex;
  height: 84px;
  justify-content: center;
  width: 84px;
}
.ptile-inicial { color: #fff; font-family: var(--tx-font-display); font-size: 34px; font-style: italic; }
.ptile-chip {
  align-items: center;
  background: rgba(5, 6, 11, 0.75);
  border-radius: 999px;
  bottom: 10px;
  color: var(--tx-text);
  display: flex;
  font-family: var(--tx-font-ui);
  font-size: 12px;
  font-weight: 600;
  gap: 6px;
  left: 10px;
  max-width: calc(100% - 20px);
  padding: 4px 10px;
  position: absolute;
}
.ptile-chip > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ptile-chip svg { flex: 0 0 auto; }
.ptile-selo {
  background: rgba(91, 127, 255, 0.3);
  border-radius: 999px;
  color: #c3d0ff;
  flex: 0 0 auto;
  font-size: 9.5px;
  font-style: normal;
  letter-spacing: 0.08em;
  padding: 2px 7px;
  text-transform: uppercase;
  white-space: nowrap;
}
/* Ações do quadro: Parar/Desligar nos meus, reduzir no destacado. Aparecem no
   hover para não sujar o vídeo. */
.ptile-parar {
  background: rgba(255, 84, 112, 0.16);
  border: 1px solid rgba(255, 84, 112, 0.5);
  border-radius: 999px;
  color: #ff8298;
  cursor: pointer;
  font-family: var(--tx-font-ui);
  font-size: 11.5px;
  font-weight: 700;
  left: 10px;
  letter-spacing: 0.05em;
  opacity: 0;
  padding: 4px 12px;
  position: absolute;
  top: 10px;
  transition: opacity 0.12s ease;
}
.ptile-parar:hover { background: rgba(255, 84, 112, 0.3); color: #fff; }
.ptile-acao {
  align-items: center;
  background: rgba(5, 6, 11, 0.75);
  border: 1px solid var(--tx-border-strong);
  border-radius: 8px;
  color: var(--tx-text-muted);
  cursor: pointer;
  display: flex;
  justify-content: center;
  opacity: 0;
  padding: 6px;
  position: absolute;
  right: 10px;
  top: 10px;
  transition: opacity 0.12s ease;
}
.ptile:hover .ptile-parar, .ptile:hover .ptile-acao { opacity: 1; }
.ptile-acao:hover { color: var(--tx-text); }

/* Destaque: um quadro grande + a fita dos outros embaixo. */
.palco-foco { display: flex; flex: 1; flex-direction: column; gap: 10px; min-height: 0; }
.palco-foco .ptile.grande { aspect-ratio: auto; cursor: zoom-out; flex: 1; min-height: 0; }
.ptile.grande canvas, .ptile.grande video { background: #000; object-fit: contain; }
.palco-filme { display: flex; flex: 0 0 auto; gap: 10px; overflow-x: auto; overflow-y: hidden; padding-bottom: 2px; scrollbar-width: thin; }
.palco-filme .ptile { flex: 0 0 148px; }
.palco-filme .ptile-face { height: 44px; width: 44px; }
.palco-filme .ptile-inicial { font-size: 18px; }
.palco-filme .ptile-chip { bottom: 6px; font-size: 10.5px; left: 6px; padding: 2px 8px; }

.palco-erro { color: var(--tx-red); font-size: 12.5px; margin: 0; text-align: center; }
/* Sem quadro nenhum ainda (entrando, reconectando, erro) o meio diz o que está
   acontecendo em vez de ficar vazio. */
.palco-espera { align-items: center; color: var(--tx-text-faint); display: flex; flex: 1; font-size: 13px; justify-content: center; margin: 0; }
/* O quadro de tela ou câmera sem vídeo ainda: a faixa não chegou, ou a pessoa
   largou a tela do outro e assistir de novo é um clique. */
.ptile-espera { align-items: center; color: var(--tx-text-faint); display: flex; flex-direction: column; font-size: 12.5px; gap: 10px; height: 100%; justify-content: center; padding: 12px; text-align: center; }
.ptile-espera .btn-primario { padding: 8px 18px; width: auto; }
.palco-controles { align-items: center; display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; }
.palco-btn {
  align-items: center;
  background: var(--tx-surface);
  border: 1px solid var(--tx-border);
  border-radius: 999px;
  color: var(--tx-text-muted);
  cursor: pointer;
  display: flex;
  font-family: var(--tx-font-ui);
  font-size: 13px;
  font-weight: 700;
  gap: 8px;
  justify-content: center;
  letter-spacing: 0.04em;
  min-height: 44px;
  width: 44px;
}
.palco-btn:hover { border-color: var(--tx-border-strong); color: var(--tx-text); }
.palco-btn.aceso { background: rgba(91, 127, 255, 0.16); border-color: var(--tx-blue-bright); box-shadow: 0 0 18px rgba(61, 90, 254, 0.3); color: var(--tx-blue-bright); }
.palco-btn.desligado { background: rgba(255, 84, 112, 0.12); border-color: rgba(255, 84, 112, 0.5); color: #ff8298; }
.palco-btn.sair { border-color: rgba(255, 84, 112, 0.45); color: var(--tx-red); }
.palco-btn.sair:hover { background: rgba(255, 84, 112, 0.14); color: #fff; }
.palco-btn:disabled { cursor: default; opacity: 0.6; }

/* A sala no trilho agora é porta: ponteiro, e verde quando é a SUA sala. */
.v4-canal-voz { cursor: pointer; }
.v4-canal-conta.na-sala { color: var(--tx-green); }

/* O pezinho da chamada no trilho: você está numa sala, olhando outra conversa. */
.v4-voz-pe { align-items: center; border-top: 1px solid var(--tx-border); display: flex; gap: 6px; padding: 8px 8px 0; }
.v4-voz-pe-corpo {
  align-items: center;
  background: rgba(47, 214, 162, 0.08);
  border: 1px solid rgba(47, 214, 162, 0.25);
  border-radius: 10px;
  color: var(--tx-text);
  cursor: pointer;
  display: flex;
  flex: 1;
  gap: 8px;
  min-width: 0;
  padding: 7px 10px;
  text-align: left;
}
.v4-voz-pe-corpo:hover { border-color: rgba(47, 214, 162, 0.55); }
.v4-voz-pe-farol { background: var(--tx-green); border-radius: 50%; box-shadow: 0 0 10px var(--tx-green); flex: 0 0 8px; height: 8px; width: 8px; }
.v4-voz-pe-txt { display: flex; flex-direction: column; min-width: 0; }
.v4-voz-pe-nome { font-family: var(--tx-font-ui); font-size: 12.5px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v4-voz-pe-sub { color: var(--tx-text-faint); font-size: 11px; }
.v4-voz-pe-btn {
  align-items: center;
  background: none;
  border: 1px solid var(--tx-border);
  border-radius: 8px;
  color: var(--tx-text-muted);
  cursor: pointer;
  display: flex;
  justify-content: center;
  padding: 8px;
}
.v4-voz-pe-btn:hover { border-color: var(--tx-border-strong); color: var(--tx-text); }
.v4-voz-pe-btn.desligado { border-color: rgba(255, 84, 112, 0.45); color: #ff8298; }
.v4-voz-pe-btn.sair { color: var(--tx-red); }
.v4-voz-pe-btn.sair:hover { background: rgba(255, 84, 112, 0.12); border-color: rgba(255, 84, 112, 0.5); color: #fff; }

/* ===== o seletor de compartilhar (sv2) e a prévia da câmera (pcam) =====
   Camadas por cima de tudo, criadas pelo palco.js e destruídas ao fechar. */
.sv2-veu, .pcam-veu {
  align-items: center;
  background: rgba(4, 5, 10, 0.72);
  display: flex;
  inset: 0;
  justify-content: center;
  position: fixed;
  z-index: 140;
}
.sv2, .pcam {
  background: var(--tx-bg-elevated, var(--tx-bg));
  border: 1px solid var(--tx-border-strong);
  border-radius: var(--tx-radius-lg);
  box-shadow: 0 30px 90px rgba(2, 3, 8, 0.65);
  display: flex;
  flex-direction: column;
  gap: 14px;
  max-height: 86vh;
  overflow: hidden;
  padding: 18px 20px 20px;
}
.sv2 { width: min(880px, 92vw); }
.pcam { width: min(560px, 92vw); }
.sv2-topo { align-items: flex-start; display: flex; gap: 12px; }
.sv2-titulos { flex: 1; min-width: 0; }
.sv2-titulo { font-family: var(--tx-font-display); font-size: 20px; font-style: italic; letter-spacing: 0.5px; margin: 0; }
.sv2-sub { color: var(--tx-text-muted); font-size: 12.5px; margin: 4px 0 0; }
.sv2-fechar {
  align-items: center;
  background: none;
  border: 1px solid transparent;
  border-radius: 8px;
  color: var(--tx-text-faint);
  cursor: pointer;
  display: flex;
  padding: 7px;
}
.sv2-fechar:hover { border-color: var(--tx-border); color: var(--tx-text); }
.sv2-abas { display: flex; gap: 6px; }
.sv2-aba {
  background: none;
  border: 1px solid var(--tx-border);
  border-radius: 999px;
  color: var(--tx-text-muted);
  cursor: pointer;
  font-family: var(--tx-font-ui);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  padding: 7px 14px;
  text-transform: uppercase;
  white-space: nowrap;
}
.sv2-aba:hover { border-color: var(--tx-border-strong); color: var(--tx-text); }
.sv2-aba.ativa { background: rgba(91, 127, 255, 0.16); border-color: var(--tx-blue-bright); color: var(--tx-blue-bright); }
.sv2-corpo { display: grid; gap: 16px; grid-template-columns: 1.2fr 1fr; min-height: 0; overflow-y: auto; scrollbar-width: thin; }
.sv2-grade {
  align-content: start;
  display: grid;
  gap: 10px;
  grid-template-columns: repeat(2, 1fr);
  padding-right: 4px;
}
.sv2-fonte {
  background: var(--tx-bg);
  border: 1px solid var(--tx-border);
  border-radius: var(--tx-radius-md);
  color: var(--tx-text-muted);
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 8px;
  text-align: left;
}
.sv2-fonte:hover { border-color: var(--tx-border-strong); color: var(--tx-text); }
.sv2-fonte.ativa { border-color: var(--tx-blue-bright); box-shadow: 0 0 0 2px rgba(91, 127, 255, 0.25); color: var(--tx-text); }
.sv2-fonte img { aspect-ratio: 16 / 9; background: #000; border-radius: 6px; object-fit: cover; width: 100%; }
.sv2-fonte-txt { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.sv2-fonte-nome { font-size: 12.5px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sv2-fonte-app { color: var(--tx-text-faint); font-size: 11px; }
.sv2-painel { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.sv2-previa { aspect-ratio: 16 / 9; background: #000; border: 1px solid var(--tx-border-strong); border-radius: var(--tx-radius-md); overflow: hidden; }
.sv2-previa canvas, .sv2-previa img { display: block; height: 100%; object-fit: cover; width: 100%; }
.sv2-previa-nome { font-size: 13px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sv2-audio {
  align-items: center;
  background: var(--tx-bg);
  border: 1px solid var(--tx-border);
  border-radius: var(--tx-radius-md);
  color: var(--tx-text-muted);
  cursor: pointer;
  display: flex;
  gap: 10px;
  padding: 10px 12px;
  text-align: left;
}
.sv2-audio:hover { border-color: var(--tx-border-strong); }
.sv2-audio-trilho { background: rgba(146, 163, 255, 0.22); border-radius: 999px; flex: 0 0 34px; height: 20px; position: relative; transition: background 0.15s ease; }
.sv2-audio-trilho::after { background: #cdd6ff; border-radius: 50%; content: ''; height: 16px; left: 2px; position: absolute; top: 2px; transition: left 0.15s ease; width: 16px; }
.sv2-audio.ligado .sv2-audio-trilho { background: var(--tx-blue); }
.sv2-audio.ligado .sv2-audio-trilho::after { background: #fff; left: 16px; }
.sv2-audio-txt { display: flex; flex-direction: column; gap: 1px; }
.sv2-audio-rotulo { color: var(--tx-text); font-size: 13px; font-weight: 600; }
.sv2-audio-sub { color: var(--tx-text-faint); font-size: 11.5px; }
.sv2-rodape { align-items: center; display: flex; flex: 0 0 auto; gap: 10px; }
.sv2-dica { color: var(--tx-text-faint); flex: 1; font-size: 11.5px; line-height: 1.45; margin: 0; }
.sv2-cancelar {
  background: none;
  border: 1px solid var(--tx-border);
  border-radius: 10px;
  color: var(--tx-text-muted);
  cursor: pointer;
  font-family: var(--tx-font-ui);
  font-size: 13px;
  font-weight: 600;
  padding: 10px 16px;
}
.sv2-cancelar:hover { border-color: var(--tx-border-strong); color: var(--tx-text); }
.sv2-cancelar { white-space: nowrap; }
.sv2-rodape .btn-primario { padding: 10px 22px; white-space: nowrap; width: auto; }

.pcam-quadro { aspect-ratio: 16 / 9; background: #000; border: 1px solid var(--tx-border-strong); border-radius: var(--tx-radius-md); overflow: hidden; position: relative; }
.pcam-quadro video, .pcam-quadro canvas { display: block; height: 100%; object-fit: cover; width: 100%; }
/* A prévia é espelhada: é assim que a pessoa se reconhece. */
.pcam-quadro video { transform: scaleX(-1); }
.pcam-status { align-items: center; color: var(--tx-text-faint); display: flex; font-size: 13px; height: 100%; justify-content: center; margin: 0; }
.pcam-selo {
  background: rgba(91, 127, 255, 0.3);
  border-radius: 999px;
  color: #c3d0ff;
  font-size: 9.5px;
  font-style: normal;
  font-weight: 700;
  left: 10px;
  letter-spacing: 0.1em;
  padding: 3px 9px;
  position: absolute;
  text-transform: uppercase;
  top: 10px;
  white-space: nowrap;
}
.pcam-quadro { flex: 0 1 auto; min-height: 120px; }
.pcam-selo.simulada { background: rgba(250, 204, 21, 0.18); color: #facc15; }
.pcam-linha { align-items: center; display: flex; gap: 10px; }
.pcam-rotulo { color: var(--tx-text-faint); font-family: var(--tx-font-ui); font-size: 11px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; }
.pcam-sel { flex: 1; height: 40px; }


/* ===== telemetria in-game (2026-09-11) =====
   Os números da transmissão, em duas casas: o HUD no canto com o véu fechado
   (canto escolhido em Telemetria, sem clique — a janela é atravessável) e o
   bloco do véu com o histórico. As cores contam o estado sem ninguém ler
   número: neutro estável, âmbar mordendo, vermelho instável — os mesmos tons
   da pastilha da voz. */
.veu-tele { display: flex; flex-direction: column; gap: 6px; pointer-events: none; position: fixed; z-index: 78; }
.veu-tele.canto-se { align-items: flex-start; left: 14px; top: 14px; }
/* No canto da voz, a telemetria desce: a pastilha da voz é transitória e mora
   em cima. */
.veu-tele.canto-sd { align-items: flex-end; right: 14px; top: 64px; }
.veu-tele.canto-ie { align-items: flex-start; bottom: 14px; flex-direction: column-reverse; left: 14px; }
.veu-tele.canto-id { align-items: flex-end; bottom: 14px; flex-direction: column-reverse; right: 14px; }

.veu-tele-hud {
  background: rgba(6, 8, 16, 0.84);
  border: 1px solid var(--tx-border-strong);
  border-radius: 9px;
  display: flex;
  flex-direction: column;
  gap: 7px;
  padding: 7px 12px;
}
.veu-tele-hud.atencao { border-color: rgba(255, 193, 94, 0.55); }
.veu-tele-hud.ruim { border-color: rgba(255, 99, 110, 0.65); }
.veu-tele-linha { align-items: baseline; display: flex; gap: 10px; }
.veu-tele-par { align-items: baseline; display: flex; gap: 4px; }
.veu-tele-n { color: var(--tx-text); font-family: var(--tx-font-digital); font-size: 13px; letter-spacing: 0.02em; }
.veu-tele-n.atencao { color: #ffc15e; }
.veu-tele-n.ruim { color: var(--tx-red); }
.veu-tele-u { color: var(--tx-text-faint); font-family: var(--tx-font-ui); font-size: 10.5px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; }
.veu-tele-sep { align-self: center; background: var(--tx-border); height: 12px; width: 1px; }
.veu-tele-mais { display: grid; gap: 3px 16px; grid-template-columns: auto auto; margin: 0; }
.veu-tele-mais > div { display: contents; }
.veu-tele-mais dt { color: var(--tx-text-faint); font-family: var(--tx-font-ui); font-size: 10.5px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; }
.veu-tele-mais dd { color: var(--tx-text-muted); font-family: var(--tx-font-ui); font-size: 12px; font-weight: 600; margin: 0; text-align: right; white-space: nowrap; }

/* O aviso que aparece sozinho. Vermelho e pulsando porque é a única coisa que
   esta camada pode fazer por cima de um jogo: ser vista num relance. */
.veu-tele-aviso {
  align-items: center;
  background: rgba(26, 8, 12, 0.88);
  border: 1px solid var(--tx-red);
  border-radius: 999px;
  color: var(--tx-red);
  display: flex;
  font-family: var(--tx-font-ui);
  font-size: 12.5px;
  font-weight: 600;
  gap: 8px;
  letter-spacing: 0.02em;
  padding: 6px 12px;
}
.veu-tele-ponto { animation: veu-tx-pulso 1.1s ease-in-out infinite; background: var(--tx-red); border-radius: 999px; flex: 0 0 7px; height: 7px; width: 7px; }

/* O bloco no véu. */
/* Cartões e gráficos nunca pagam com rolagem lateral: o véu rola só no eixo
   que tem conteúdo. */
.veu-caixa { overflow-x: hidden; }
.veu-tele-cab { align-items: center; display: flex; gap: 10px; justify-content: space-between; }
.veu-tele-cab .veu-titulo { margin: 0; }
.veu-tele-cab-acoes { align-items: center; display: flex; gap: 10px; }
.veu-tele-fixar {
  background: none;
  border: 1px solid var(--tx-border-strong);
  border-radius: 999px;
  color: var(--tx-text-muted);
  cursor: pointer;
  font-family: var(--tx-font-ui);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.05em;
  padding: 5px 14px;
  text-transform: uppercase;
  white-space: nowrap;
}
.veu-tele-fixar:hover { border-color: var(--tx-blue-bright); color: var(--tx-text); }
.veu-tele-fixar.ativo {
  background: var(--tx-gradient);
  border-color: transparent;
  box-shadow: var(--tx-glow);
  color: #fff;
}
.veu-tele-chip {
  border: 1px solid var(--tx-border-strong);
  border-radius: 999px;
  color: var(--tx-text-faint);
  font-family: var(--tx-font-ui);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  padding: 3px 10px;
  text-transform: uppercase;
  white-space: nowrap;
}
.veu-tele-chip.boa { border-color: rgba(47, 214, 162, 0.45); color: #2fd6a2; }
.veu-tele-chip.ruim { border-color: rgba(255, 99, 110, 0.6); color: var(--tx-red); }
/* Seis cartões (três medidores, três listas) em duas fileiras de três: o
   mínimo de 200px é o que impede a quarta coluna na caixa de 860px — com ela
   as listas caíam sozinhas numa segunda fileira torta. */
.veu-tele-grade { display: grid; gap: 10px; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); margin-top: 12px; }
.tele-carta {
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--tx-border);
  border-radius: var(--tx-radius-md);
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
  padding: 10px 12px 8px;
}
.tele-rotulo { color: var(--tx-text-faint); font-family: var(--tx-font-ui); font-size: 10.5px; font-weight: 600; letter-spacing: 0.07em; text-transform: uppercase; }
.tele-valor { align-items: baseline; display: flex; gap: 4px; }
.tele-valor em { color: var(--tx-text); font-family: var(--tx-font-digital); font-size: 21px; font-style: normal; }
.tele-valor i { color: var(--tx-text-faint); font-size: 11px; font-style: normal; letter-spacing: 0.05em; text-transform: uppercase; }
.tele-sub { color: var(--tx-text-faint); font-size: 11px; min-height: 14px; white-space: nowrap; }
.tele-grafico { display: block; height: 30px; margin-top: 4px; width: 100%; }
.tele-carta--lista { gap: 6px; justify-content: center; }
.tele-linha { align-items: baseline; display: flex; flex-wrap: wrap; gap: 2px 10px; justify-content: space-between; }
.tele-linha span { color: var(--tx-text-faint); font-family: var(--tx-font-ui); font-size: 10.5px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; }
.tele-linha b { color: var(--tx-text-muted); font-size: 12px; font-weight: 600; text-align: right; white-space: nowrap; }

.veu-tele-controles { align-items: center; display: flex; flex-wrap: wrap; gap: 14px; margin-top: 12px; }
.veu-tele-seg { border: 1px solid var(--tx-border-strong); border-radius: 999px; display: flex; overflow: hidden; }
.veu-tele-seg button {
  background: none;
  border: 0;
  color: var(--tx-text-muted);
  cursor: pointer;
  font-family: var(--tx-font-ui);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  padding: 5px 12px;
}
.veu-tele-seg button.ativo { background: rgba(91, 127, 255, 0.16); color: var(--tx-text); }
/* O seletor de canto é a própria tela em miniatura: quatro cantos, um aceso. */
.veu-tele-cantos { display: grid; gap: 3px; grid-template-columns: repeat(2, 15px); }
.veu-tele-cantos button {
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--tx-border-strong);
  border-radius: 3px;
  cursor: pointer;
  height: 11px;
  padding: 0;
  width: 15px;
}
.veu-tele-cantos button:hover { border-color: var(--tx-blue-bright); }
.veu-tele-cantos button.ativo { background: var(--tx-blue-bright); border-color: var(--tx-blue-bright); }
#veu-tele-copiar { margin-left: auto; }
.veu-tele-nota { color: var(--tx-text-faint); font-size: 11.5px; margin: 8px 0 0; }
