/* Exo 2, a tipografia da marca. Servida daqui e nao do Google: uma fonte a
   menos para carregar de terceiro, e funciona igual sem internet aberta.
   E variavel, por isso um arquivo por subconjunto cobre 400 a 700. */
@font-face {
  font-family: 'Exo 2';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('fonte/exo2-latin.woff2?v=7437c24c7298') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Exo 2';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('fonte/exo2-latin-ext.woff2?v=55ea7d522dd6') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB,
    U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  /* Paleta oficial: #2455A4 azul, #EFE9DA creme, #242424 escuro, #B7B0A3 cinza quente.
     O fundo azul-noite (#030D1D) e o do material da marca; os paineis usam a familia
     do #242424, como o proprio mockup da identidade faz. */
  --azul: #2455A4;
  --azul-forte: #1E4789;
  --azul-claro: #3A72CE;
  --azul-suave: #9EBEEC;
  --creme: #EFE9DA;
  --cinza-quente: #B7B0A3;

  --fundo-0: #030D1D;
  --fundo-1: #06101F;
  --painel: #1A1D22;
  --painel-2: #242424;
  --painel-3: #2E3038;
  --vidro: rgba(20, 24, 32, .74);
  --borda: #2A2D33;
  --borda-forte: #3B3F49;

  --texto: #EFE9DA;
  --texto-medio: var(--cinza-quente);
  --texto-fraco: #8A8478;

  --verde: #46C98A;
  --ambar: #E8A33D;
  --vermelho: #E06C5A;

  --raio: 14px;
  --raio-p: 10px;
  --sombra: 0 18px 44px rgba(0, 0, 0, .55);
  --transicao: 160ms cubic-bezier(.2, .7, .3, 1);

  --lateral-w: 268px;
  --chat-w: 320px;
}

* { box-sizing: border-box; }

/* O atributo `hidden` vale pela regra [hidden]{display:none} da folha do
   navegador, que perde para qualquer classe nossa com `display`. Sem esta linha,
   .tela-entrada (grid), .app (grid), .aviso (flex), .controle (inline-flex),
   .grade-telas (grid) e .pilula (inline-block) continuariam aparecendo com
   hidden ligado, e a tela de entrada nunca sumia. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  height: 100%;
  background: linear-gradient(178deg, var(--fundo-0) 0%, var(--fundo-1) 100%);
  color: var(--texto);
  font-family: 'Exo 2', "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
body { overflow: hidden; }

/* ----- Fundo ambiente: três manchas de cor desfocadas, atrás de tudo ----- */
.ambiente { position: fixed; inset: 0; overflow: hidden; z-index: 0; pointer-events: none; }
.orbe { position: absolute; border-radius: 50%; filter: blur(90px); opacity: .5; }
.orbe-a { width: 46vw; height: 46vw; left: -12vw; top: -16vw; background: radial-gradient(circle, #2455A4, transparent 70%); opacity: .46; }
.orbe-b { width: 40vw; height: 40vw; right: -10vw; top: 18vh; background: radial-gradient(circle, #1B3E78, transparent 70%); opacity: .5; }
.orbe-c { width: 38vw; height: 38vw; left: 26vw; bottom: -22vw; background: radial-gradient(circle, #3A72CE, transparent 70%); opacity: .2; }

/* ----- Base de formulário ----- */
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; border: 1px solid var(--borda-forte); background: var(--painel-2); color: var(--texto); border-radius: var(--raio-p); padding: 9px 14px; transition: background var(--transicao), border-color var(--transicao), color var(--transicao), transform var(--transicao); }
button:hover:not(:disabled) { background: var(--painel-3); border-color: var(--azul-claro); }
button:active:not(:disabled) { transform: translateY(1px); }
button:disabled { opacity: .5; cursor: default; }
button:focus-visible, input:focus-visible, select:focus-visible, a:focus-visible { outline: 2px solid var(--azul); outline-offset: 2px; }

.primario { background: linear-gradient(180deg, var(--azul) 0%, var(--azul-forte) 100%); border-color: transparent; color: var(--creme); font-weight: 600; box-shadow: 0 6px 18px rgba(36, 85, 164, .42); }
.primario:hover:not(:disabled) { background: linear-gradient(180deg, #3A72CE 0%, #1E4789 100%); border-color: transparent; }
.primario.grande { padding: 12px 18px; font-size: 16px; width: 100%; }
.primario.pequeno { padding: 5px 12px; font-size: 13px; }
.fantasma { background: transparent; border-color: transparent; color: var(--texto-medio); }
.fantasma:hover:not(:disabled) { background: var(--painel-2); color: var(--texto); border-color: transparent; }
.perigo { border-color: rgba(224, 108, 90, .45); color: #F0B7AA; }
.perigo:hover:not(:disabled) { background: rgba(224, 108, 90, .14); border-color: var(--vermelho); }

input[type="text"], input[type="password"], select {
  width: 100%; padding: 11px 13px; background: #050F1F; border: 1px solid var(--borda);
  border-radius: var(--raio-p); transition: border-color var(--transicao), box-shadow var(--transicao);
}
input[type="text"]:focus, input[type="password"]:focus, select:focus { border-color: var(--azul); box-shadow: 0 0 0 3px rgba(58, 114, 206, .18); outline: none; }
input::placeholder { color: #79736A; }
label { display: block; margin: 14px 0 6px; font-size: 13px; color: var(--texto-medio); font-weight: 500; }

.titulo-secao { margin: 0; font-size: 11px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--texto-fraco); }
.erro { margin: 12px 0 0; padding: 10px 12px; border-radius: var(--raio-p); background: rgba(224, 108, 90, .12); border: 1px solid rgba(224, 108, 90, .35); color: #F2C4B8; font-size: 14px; }
.dica { margin: 8px 0 0; font-size: 12.5px; color: var(--texto-fraco); line-height: 1.45; }
/* O que está saindo da sua tela agora. Quem compartilha é o único que não vê o
   próprio resultado, e era preciso adivinhar por que a imagem tinha piorado. */
.relato-tela { margin: 7px 2px 0; font-size: 11.5px; color: var(--texto-fraco); line-height: 1.4; }
.relato-tela b { color: var(--texto-medio); font-weight: 600; }
.relato-tela[data-apertado="sim"] b { color: var(--ambar); }
.pilula { display: inline-block; min-width: 18px; padding: 0 5px; border-radius: 999px; background: var(--azul); color: var(--creme); font-size: 11px; font-weight: 700; text-align: center; }

/* ----- Marca ----- */
.marca { display: flex; align-items: center; gap: 10px; }
.marca-icone { display: block; width: 34px; height: 34px; flex: none; }
.marca-icone img { width: 100%; height: 100%; object-fit: contain; display: block; }
.marca-texto { font-size: 17px; font-weight: 700; letter-spacing: -.005em; }
.marca-texto b { color: var(--azul-suave); font-weight: 700; }
.marca-grande { justify-content: center; }
.marca-grande { flex-direction: column; gap: 12px; }
.marca-grande .marca-icone { width: 78px; height: 78px; }
.marca-grande .marca-texto { font-size: 30px; }

/* ============ Tela de entrada ============ */
.tela-entrada { position: relative; z-index: 1; display: grid; place-items: center; min-height: 100dvh; padding: 24px; }
.cartao-entrada {
  width: 100%; max-width: 400px; padding: 34px 30px 26px;
  background: var(--vidro); backdrop-filter: blur(22px); -webkit-backdrop-filter: blur(22px);
  border: 1px solid var(--borda-forte); border-radius: 22px; box-shadow: var(--sombra);
}
.assinatura { margin: 10px 0 22px; text-align: center; font-size: 11.5px; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase; color: var(--cinza-quente); }
.assinatura b { color: var(--azul-suave); font-weight: 700; }
.cartao-entrada .sub { margin: 14px 0 4px; text-align: center; color: var(--texto-fraco); font-size: 14px; }
.cartao-entrada #btn-entrar { margin-top: 22px; }
.baixar-app { margin: 14px 0 0; text-align: center; font-size: 12.5px; color: var(--texto-fraco); line-height: 1.45; }
.baixar-app a { color: var(--azul-suave); }
body.aplicativo .baixar-app { display: none; }
.rodape-entrada { margin: 18px 0 0; text-align: center; font-size: 11.5px; color: #79736A; }
.versao { opacity: .75; }

/* ============ Aplicação ============ */
/* Areas nomeadas para o painel do usuario ser UM elemento so: coluna da lateral
   no desktop, barra embaixo no celular, sem duplicar botao. */
.app {
  position: relative; z-index: 1; display: grid; height: 100dvh;
  grid-template-columns: var(--lateral-w) 1fr var(--chat-w);
  grid-template-rows: 1fr auto;
  grid-template-areas: "lateral palco chat" "usuario palco chat";
}
.app.sem-chat {
  grid-template-columns: var(--lateral-w) 1fr;
  grid-template-areas: "lateral palco" "usuario palco";
}
.app.sem-chat .chat-area { display: none; }
.lateral { grid-area: lateral; }
.painel-usuario { grid-area: usuario; }
.palco-area { grid-area: palco; }
.chat-area { grid-area: chat; }

/* ----- Painel do usuario ----- */
.painel-usuario {
  display: flex; flex-direction: column; min-width: 0;
  background: rgba(6, 16, 31, .84); border-right: 1px solid var(--borda);
}
.controles-lateral { display: flex; flex-direction: column; gap: 6px; padding: 12px; border-top: 1px solid var(--borda); }
.controle-linha { display: flex; gap: 5px; }
.controle-linha .controle { flex: 1; min-width: 0; }
.expandir {
  flex: none; width: 34px; padding: 0; display: grid; place-items: center;
  background: var(--painel); border-color: var(--borda); color: var(--texto-fraco);
  border-radius: var(--raio-p); font-size: 13px; line-height: 1;
}
.expandir:hover:not(:disabled) { color: var(--texto); border-color: var(--azul-claro); }
.expandir[aria-expanded="true"] { background: var(--painel-3); color: var(--azul-suave); border-color: var(--azul); }
.controle.largo { width: 100%; }

/* Só para leitor de tela: o rótulo existe sem ocupar espaço. */
.sr { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
.icone-so { padding: 7px 9px; font-size: 15px; line-height: 1; }
.perigo-texto { color: #F0B7AA; }
.perigo-texto:hover:not(:disabled) { background: rgba(224, 108, 90, .14); color: #F3CBC1; }

/* ----- Menus de dispositivo ----- */
.menu-disp {
  position: fixed; z-index: 60; min-width: 244px; max-width: min(340px, calc(100vw - 24px));
  padding: 8px; border: 1px solid var(--borda-forte); border-radius: var(--raio);
  background: var(--vidro); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
  box-shadow: var(--sombra);
}
.menu-titulo { margin: 2px 6px 8px; font-size: 11px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--texto-fraco); }
.lista-disp { list-style: none; margin: 0; padding: 0; max-height: min(46vh, 320px); overflow-y: auto; }
.lista-disp button {
  width: 100%; display: flex; align-items: center; gap: 9px; padding: 8px 10px;
  background: transparent; border: 1px solid transparent; border-radius: var(--raio-p);
  color: var(--texto-medio); text-align: left; font-size: 13.5px;
}
.lista-disp button:hover { background: var(--painel-2); color: var(--texto); border-color: transparent; }
.lista-disp button .marca-sel { width: 14px; flex: none; color: var(--azul-suave); font-weight: 700; }
.lista-disp button .rotulo-disp { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lista-disp li[aria-selected="true"] button { color: var(--texto); background: rgba(36, 85, 164, .16); }
.menu-vazio { margin: 6px; font-size: 12.5px; color: var(--texto-fraco); }

/* ----- Lateral ----- */
.lateral { display: flex; flex-direction: column; min-height: 0; overflow: hidden; background: rgba(6, 16, 31, .84); border-right: 1px solid var(--borda); }
.lateral > .marca { padding: 16px 18px; border-bottom: 1px solid var(--borda); }
.lateral > .marca .fantasma { margin-left: auto; font-size: 22px; padding: 0 8px; }
.canais { flex: 1; min-height: 0; overflow-y: auto; padding: 16px 12px; }
.canais .titulo-secao { padding: 0 6px 10px; }
.lista-canais { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 3px; }

.canal-cabeca {
  width: 100%; display: flex; align-items: center; gap: 9px; padding: 9px 10px;
  background: transparent; border: 1px solid transparent; border-radius: var(--raio-p);
  color: var(--texto-medio); text-align: left; font-size: 14.5px;
}
.canal-cabeca:hover { background: var(--painel-2); border-color: transparent; color: var(--texto); }
.canal-cabeca .cerquilha { color: var(--texto-fraco); font-weight: 600; }
.canal-cabeca .rotulo { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.canal-cabeca .contagem { font-size: 11.5px; color: var(--texto-fraco); background: var(--painel-2); border-radius: 999px; padding: 1px 8px; }
.canal.ativo > .canal-cabeca { background: linear-gradient(90deg, rgba(58, 114, 206, .2), rgba(58, 114, 206, .06)); border-color: rgba(58, 114, 206, .4); color: var(--creme); font-weight: 600; }
.canal.ativo > .canal-cabeca .cerquilha { color: var(--azul-suave); }
.canal.ativo > .canal-cabeca .contagem { background: rgba(58, 114, 206, .3); color: #DCE7F6; }

.canal-membros { list-style: none; margin: 2px 0 6px; padding: 0 0 0 12px; display: flex; flex-direction: column; gap: 1px; }
.membro { display: flex; align-items: center; gap: 8px; padding: 5px 8px; border-radius: 8px; font-size: 13.5px; color: var(--texto-medio); contain: layout paint; }
.membro-icones, .pessoa-icones { display: inline-flex; align-items: center; gap: 5px; }
.membro .nome { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Ícones de estado: mesmos traços dos botões, tamanho e cor sob controle. */
.ic-estado { width: 15px; height: 15px; flex: none; display: block; }
.ic-estado.ic-mudo { color: var(--vermelho); }
.ic-estado.ic-tela { color: var(--azul-suave); }
.membro .ic-estado { width: 14px; height: 14px; }
.pessoa-tags .ic-estado { width: 16px; height: 16px; }
.membro.falando { color: var(--creme); }

/* Avatar com inicial; a cor vem do nome (ver corDoNome no app.js) */
.avatar { display: grid; place-items: center; border-radius: 50%; font-weight: 700; color: var(--creme); flex: none; background: var(--azul); text-transform: uppercase; user-select: none; letter-spacing: .02em; }
.avatar.pequeno { width: 26px; height: 26px; font-size: 11px; }
.avatar.medio { width: 34px; height: 34px; font-size: 14px; }
.avatar.grande { width: 76px; height: 76px; font-size: 28px; }

/* Anel de quem está falando. O pulso anima transform e opacity num
   pseudo-elemento, que são as duas únicas propriedades que ficam no compositor:
   animar box-shadow custaria pintura na thread principal a cada quadro, para
   cada pessoa falando ao mesmo tempo. */
.anel { position: relative; border-radius: 50%; padding: 2px; border: 2px solid transparent; transition: border-color var(--transicao); }
.anel::after {
  content: ''; position: absolute; inset: -3px; border-radius: 50%;
  box-shadow: 0 0 0 3px rgba(70, 201, 138, .35);
  opacity: 0; transform: scale(.92); pointer-events: none;
}
.falando > .anel, .anel.falando { border-color: var(--verde); }
.falando > .anel::after, .anel.falando::after { animation: pulso 1.5s ease-in-out infinite; }
@keyframes pulso {
  0%, 100% { opacity: .85; transform: scale(1); }
  50% { opacity: .15; transform: scale(1.16); }
}

.eu { display: flex; align-items: center; gap: 8px; padding: 10px 12px; border-top: 1px solid var(--borda); background: rgba(3, 13, 29, .62); }
.eu-info { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.25; }
.eu-nome { font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.eu-estado { font-size: 11.5px; color: var(--texto-fraco); }

/* Barrinhas de sinal */
.sinal { display: inline-flex; align-items: flex-end; gap: 2px; height: 15px; flex: none;
  padding: 3px 5px; background: transparent; border: 1px solid transparent; border-radius: 7px; cursor: default; }
.sinal:hover { background: var(--painel-2); border-color: transparent; }
.sinal i { width: 3px; border-radius: 2px; background: var(--borda-forte); display: block; }
.sinal i:nth-child(1) { height: 5px; } .sinal i:nth-child(2) { height: 9px; } .sinal i:nth-child(3) { height: 13px; }
.sinal[data-q="excellent"] i, .sinal[data-q="good"] i { background: var(--verde); }
.sinal[data-q="good"] i:nth-child(3) { background: var(--borda-forte); }
.sinal[data-q="poor"] i:nth-child(1) { background: var(--ambar); }
.sinal[data-q="poor"] i:nth-child(2), .sinal[data-q="poor"] i:nth-child(3) { background: var(--borda-forte); }
.sinal[data-q="lost"] i:nth-child(1) { background: var(--vermelho); }


/* ----- Mapa: o mundo em tiles -----
   Um canvas só. O pixel art precisa de duas coisas do CSS:
   `image-rendering: pixelated`, para o navegador não interpolar e borrar, e
   nenhuma sombra ou filtro em cima, que forçaria uma camada extra por quadro. */
.palco-barra { display: flex; gap: 6px; align-items: center; }
.aba { display: inline-flex; align-items: center; gap: 6px; padding: 5px 11px; font: inherit;
  font-size: 12.5px; color: var(--texto-fraco); background: transparent; border: 1px solid var(--borda);
  border-radius: 999px; cursor: pointer; transition: color var(--transicao), background var(--transicao), border-color var(--transicao); }
.aba svg { width: 15px; height: 15px; }
.aba:hover { color: var(--creme); background: var(--painel-2); }
.aba[aria-pressed="true"] { color: #DCE7F6; background: rgba(58, 114, 206, .16); border-color: var(--azul); }

/* ⚠️ Altura EXPLÍCITA, não `flex: 1`. Com `flex: 1` o .mapa encolhia junto com
   o palco, mas o canvas tem `min-height` e não encolhe: os filhos
   transbordavam o pai e a grade de pessoas era pintada por cima da dica. Altura
   fixa resolve, e quem rola é o palco. */
.mapa { display: flex; flex-direction: column; gap: 8px; flex: none; }
.mapa-tela {
  display: block; width: 100%; flex: none;
  height: min(58vh, 620px); min-height: 280px;
  border: 1px solid var(--borda); border-radius: 14px;
  background: var(--fundo-0); cursor: pointer;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  /* o canvas se redimensiona sozinho pelo ResizeObserver; sem isto ele
     empurraria o layout num laço de crescer-e-medir */
  contain: strict;
}
.mapa-tela:focus-visible { outline: 2px solid var(--azul-claro); outline-offset: 2px; }
.mapa-dica { margin: 0; font-size: 11.5px; color: var(--texto-fraco); text-align: center; }
/* No toque não existe tecla: mostrar WASD ali seria instrução para um teclado
   que a pessoa não tem. */
.mapa-dica .so-desktop { display: inline; }
.mapa-dica .so-mobile { display: none; }
@media (max-width: 900px) {
  .mapa-dica .so-desktop { display: none; }
  .mapa-dica .so-mobile { display: inline; }
}
.mapa-dica kbd { display: inline-block; min-width: 17px; padding: 1px 4px; margin: 0 1px;
  font: inherit; font-size: 10.5px; text-align: center; color: var(--creme);
  background: var(--painel-2); border: 1px solid var(--borda-forte);
  border-bottom-width: 2px; border-radius: 4px; }

/* ----- Palco ----- */
.palco-area { display: flex; flex-direction: column; min-width: 0; min-height: 0; }
.topo { display: flex; align-items: center; gap: 12px; padding: 12px 18px; border-bottom: 1px solid var(--borda); background: rgba(6, 16, 31, .66); }
.topo-canal { display: flex; align-items: center; gap: 9px; min-width: 0; flex: 1; }
.topo-canal .cerquilha { color: var(--texto-fraco); font-size: 19px; }
#nome-canal { font-size: 17px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.topo-acoes { display: flex; gap: 6px; align-items: center; }

.status { font-size: 11.5px; padding: 3px 10px; border-radius: 999px; border: 1px solid var(--borda-forte); color: var(--texto-fraco); }
.status[data-estado="conectado"] { color: var(--verde); border-color: rgba(70, 201, 138, .45); background: rgba(70, 201, 138, .08); }
.status[data-estado="conectando"], .status[data-estado="reconectando"] { color: var(--ambar); border-color: rgba(232, 163, 61, .45); background: rgba(232, 163, 61, .08); }
.status[data-estado="desconectado"] { color: var(--vermelho); border-color: rgba(224, 108, 90, .45); background: rgba(224, 108, 90, .08); }

/* Faixa de atualizacao. Azul da marca, nao ambar: nao e defeito, e novidade.
   `fixed` porque ela vive fora do #app (aparece tambem na tela de entrada) e
   nao deve empurrar layout nenhum ao surgir: `position: fixed` sai do fluxo,
   entao mostrar a faixa nao relayouta a pagina inteira.
   Sem animacao CONTINUA (ver CLAUDE.md): a entrada e uma transicao unica em
   transform e opacity, que ficam no compositor, e acaba. */
.faixa-atualizacao {
  /* 70: acima do menu de dispositivos (60) e das gavetas do celular (30).
     O <dialog> de configuracoes usa a top layer nativa e continua na frente,
     o que esta certo: um modal aberto e o foco da pessoa naquele instante. */
  position: fixed; top: 0; left: 0; right: 0; z-index: 70;
  display: flex; align-items: center; gap: 12px;
  padding: 10px 18px; padding-top: max(10px, env(safe-area-inset-top));
  background: #16346B; border-bottom: 1px solid rgba(58, 114, 206, .55);
  color: var(--creme); font-size: 14px;
  box-shadow: 0 6px 18px rgba(3, 13, 29, .45);
  animation: faixa-entra .22s ease-out;
}
/* Fundo opaco, nao translucido: por cima do mapa em canvas um fundo com alfa
   deixaria o texto ilegivel dependendo do que estivesse pintado atras. */
.faixa-atualizacao span { flex: 1; min-width: 0; }
.faixa-atualizacao button { flex: none; }
/* Barra do download no aplicativo. `appearance: none` porque o desenho nativo
   ignora a paleta; os dois seletores existem porque o pseudo-elemento do
   preenchimento tem nome diferente em cada motor, e um seletor invalido
   descartaria a regra inteira se estivessem juntos. */
.atualizacao-progresso {
  flex: none; width: 140px; height: 6px; appearance: none; border: none;
  border-radius: 3px; overflow: hidden; background: rgba(239, 233, 218, .18);
}
.atualizacao-progresso::-webkit-progress-bar { background: rgba(239, 233, 218, .18); }
.atualizacao-progresso::-webkit-progress-value { background: var(--creme); }
.atualizacao-progresso::-moz-progress-bar { background: var(--creme); }
@keyframes faixa-entra { from { opacity: 0; transform: translateY(-100%); } }
@media (prefers-reduced-motion: reduce) { .faixa-atualizacao { animation: none; } }
@media (max-width: 620px) {
  .faixa-atualizacao { flex-wrap: wrap; font-size: 13px; padding: 8px 12px; }
}

.aviso { display: flex; align-items: center; gap: 12px; padding: 10px 18px; background: rgba(232, 163, 61, .12); border-bottom: 1px solid rgba(232, 163, 61, .35); color: #F2D7A9; font-size: 14px; }
.aviso span { flex: 1; }

.palco { flex: 1; min-height: 0; overflow-y: auto; padding: 18px; display: flex; flex-direction: column; gap: 18px; }
/* Só pessoas no palco: centraliza, em vez de deixar tudo encostado num canto. */
.palco.so-pessoas { justify-content: center; }
/* No modo mapa o palco NAO rola: o canvas ocupa o espaco e a camera anda
   dentro do mundo. Rolagem e camera juntas dariam duas formas de mover a vista. */
.palco[data-modo="mapa"] { justify-content: flex-start; overflow-y: auto; }
.palco[data-modo="mapa"] .grade-pessoas { flex: none; }
.palco.so-pessoas .grade-pessoas { justify-content: center; grid-template-columns: repeat(auto-fit, minmax(170px, 210px)); }

.grade-telas { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(min(100%, 460px), 1fr)); }
.grade-telas.foco { grid-template-columns: 1fr; }
.tela-remota { margin: 0; background: #000; border: 1px solid var(--borda-forte); border-radius: var(--raio); overflow: hidden; display: flex; flex-direction: column; box-shadow: var(--sombra); }
.tela-remota video { width: 100%; aspect-ratio: 16 / 9; background: #000; display: block; cursor: zoom-in; object-fit: contain; }
.tela-remota video:fullscreen { cursor: zoom-out; }
.tela-remota figcaption { display: flex; align-items: center; gap: 8px; padding: 8px 12px; font-size: 13px; color: var(--texto-medio); background: var(--painel); flex-wrap: wrap; }
.tela-titulo { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tela-remota figcaption .ponto { width: 7px; height: 7px; border-radius: 50%; background: var(--azul-suave); box-shadow: 0 0 8px var(--azul-suave); flex: none; }
.tela-remota.tela-muda figcaption .ponto { background: var(--vermelho); box-shadow: 0 0 8px var(--vermelho); }
.tela-audio { display: flex; align-items: center; gap: 8px; margin-left: auto; min-width: min(100%, 220px); flex: 1 1 180px; }
.tela-audio-rotulo { font-size: 11px; color: var(--texto-fraco); white-space: nowrap; }
.tela-audio .tela-vol-faixa { flex: 1; min-width: 72px; }
.tela-audio-aviso { font-size: 11px; color: #F3CBC1; margin-left: 4px; }
.tela-remota:not(.tela-muda) .tela-audio-aviso { display: none; }

.grade-pessoas { display: grid; gap: 14px; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); }
.grade-pessoas.compacta { grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); }
.pessoa {
  display: flex; flex-direction: column; align-items: center; gap: 10px; padding: 18px 12px 14px;
  background: var(--painel); border: 1px solid var(--borda); border-radius: var(--raio);
  transition: border-color var(--transicao), background var(--transicao);
  /* contenção: o que muda num cartão não força layout nem pintura dos vizinhos */
  contain: layout paint;
}
.pessoa.falando { border-color: rgba(70, 201, 138, .55); background: var(--painel-2); }
.pessoa .pessoa-nome { font-size: 14px; font-weight: 500; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pessoa .pessoa-tags { display: flex; gap: 6px; align-items: center; min-height: 18px; font-size: 11.5px; color: var(--texto-fraco); }
.etiqueta { padding: 1px 7px; border-radius: 999px; background: var(--painel-3); }
.etiqueta.voce { color: var(--azul-suave); background: rgba(58, 114, 206, .16); }
/* ⚠️ `opacity: 0` esconde mas NAO desarma: a faixa continuava recebendo clique.
   Como ela mora dentro do cartao e tem 4 px de altura, um clique perdido no
   cartao caia nela e silenciava aquela pessoa em segredo, sem nada na tela
   dizer o que tinha acontecido. Invisivel tem de vir com pointer-events: none. */
.pessoa .volume { width: 100%; display: flex; align-items: center; gap: 7px; opacity: 0;
  pointer-events: none; transition: opacity var(--transicao); }
.pessoa:hover .volume, .pessoa:focus-within .volume,
.pessoa.calado .volume, .pessoa .volume.fixo { opacity: 1; pointer-events: auto; }
@media (hover: none) { .pessoa .volume { opacity: 1; pointer-events: auto; } }
.pessoa .volume span { font-size: 12px; color: var(--texto-fraco); }

/* Silenciado por mim: estado visivel e reversivel num clique. */
.etiqueta.silenciado { color: #F3CBC1; background: rgba(224, 108, 90, .18); }
.pessoa.calado { border-color: rgba(224, 108, 90, .4); }
.pessoa.calado .avatar { filter: saturate(.35) brightness(.75); }
.vol-mudo { display: grid; place-items: center; width: 22px; height: 22px; flex: none; padding: 0;
  border: 0; border-radius: 6px; background: transparent; color: var(--texto-fraco); cursor: pointer; }
.vol-mudo:hover { background: var(--painel-3); color: var(--creme); }
.vol-mudo svg { width: 15px; height: 15px; }
.vol-mudo .ic-som-off { display: none; }
.vol-mudo[aria-pressed="true"] { color: #E06C5A; }
.vol-mudo[aria-pressed="true"] .ic-som { display: none; }
.vol-mudo[aria-pressed="true"] .ic-som-off { display: block; }
.grade-pessoas.compacta .pessoa { padding: 12px 8px 10px; }
.grade-pessoas.compacta .avatar.grande { width: 48px; height: 48px; font-size: 18px; }
.grade-pessoas.compacta .volume { display: none; }

input[type="range"] { -webkit-appearance: none; appearance: none; width: 100%; height: 4px; border-radius: 999px; background: var(--painel-3); }
input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; width: 13px; height: 13px; border-radius: 50%; background: var(--azul); border: 0; cursor: pointer; }
input[type="range"]::-moz-range-thumb { width: 13px; height: 13px; border-radius: 50%; background: var(--azul); border: 0; cursor: pointer; }

.palco-vazio { grid-column: 1 / -1; display: flex; flex-direction: column; align-items: center; gap: 12px;
  text-align: center; color: var(--texto-fraco); padding: 30px 10px; }
.palco-vazio img { width: 108px; height: auto; opacity: .92; }
/* Convite fica ao lado do cartao de quem esta sozinho, nao ocupando a linha toda. */
.palco-vazio.convite { grid-column: auto; justify-content: center; padding: 18px 12px; font-size: 13.5px; }
.palco-vazio.convite img { width: 84px; }
.palco-vazio p { margin: 0; }
.chat-vazio img { width: 84px; height: auto; margin: 0 auto 10px; display: block; opacity: .85; }

/* ----- Barra de controles: aqui o vidro fosco cabe ----- */
.controle { display: inline-flex; align-items: center; gap: 9px; padding: 9px 13px; border-radius: 12px; }
/* Na lateral o rotulo alinha a esquerda e o estado encosta na direita. Vale
   para os botoes que AINDA tem rotulo (compartilhar/parar tela). */
.controles-lateral .controle { justify-content: flex-start; }
.controles-lateral .controle .controle-texto { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ⚠️ Microfone e silenciar sao SO ICONE, como no Discord: o icone centraliza e
   o botao nao estica com o rotulo de ninguem. Quem conta o estado e a COR
   (verde aberto, vermelho fechado, azul silenciado) mais o icone que troca por
   aria-pressed — e o `title`, escrito pelo app.js. Um <span class="sr"> guarda
   o nome para leitor de tela, que nao ve cor. */
#btn-mic, #btn-surdo { justify-content: center; padding: 9px 10px; }

/* No fone o icone tambem muda, nao so a cor. */
.controle .ic-fone-off { display: none; }
.controle[aria-pressed="true"] .ic-fone { display: none; }
.controle[aria-pressed="true"] .ic-fone-off { display: inline; }
.icone-so svg { width: 17px; height: 17px; display: block; }
.controle-icone { display: inline-grid; place-items: center; width: 20px; height: 20px; font-size: 17px; line-height: 1; }
.controle-icone svg { width: 19px; height: 19px; }
.controle-texto { font-size: 14px; }

/* Microfone: o estado LIGADO é o que fica evidente, porque é o de risco.
   O padrão oposto (destacar só o mudo) é a origem clássica do "achei que
   estava mutado". Sem a palavra no botão, a redundância que sobra é cor +
   ícone + title; o ícone é o que salva quem não distingue verde de vermelho,
   por isso ele TEM de trocar junto com a cor, nunca só a cor. */
.controle.mic .ic-mic-off { display: none; }
.controle.mic[aria-pressed="true"] { background: linear-gradient(180deg, rgba(70, 201, 138, .22), rgba(70, 201, 138, .1)); border-color: var(--verde); color: #E4F7EE; box-shadow: 0 0 0 1px rgba(70, 201, 138, .2), 0 6px 18px rgba(70, 201, 138, .14); }
.controle.mic[aria-pressed="false"] { background: rgba(224, 108, 90, .1); border-color: rgba(224, 108, 90, .5); color: #F3CBC1; }
.controle.mic[aria-pressed="false"] .ic-mic { display: none; }
.controle.mic[aria-pressed="false"] .ic-mic-off { display: inline; }

.controle[aria-pressed="true"]:not(.mic) { background: rgba(58, 114, 206, .16); border-color: var(--azul); color: #DCE7F6; }
.controle.ptt-ativo { border-color: var(--azul-suave); box-shadow: 0 0 0 2px rgba(158, 190, 236, .25); }

/* ----- Chat ----- */
.chat-area { display: flex; flex-direction: column; min-height: 0; background: rgba(6, 16, 31, .84); border-left: 1px solid var(--borda); }
.chat-topo { display: flex; align-items: center; gap: 10px; padding: 14px 16px; border-bottom: 1px solid var(--borda); }
.chat-topo .titulo-secao { flex: 1; }
.chat-mensagens { flex: 1; min-height: 0; overflow-y: auto; padding: 14px 16px; display: flex; flex-direction: column; gap: 12px; }
.chat-vazio { margin: auto; text-align: center; color: var(--texto-fraco); font-size: 13.5px; }
.msg { display: flex; gap: 9px; }
.msg-corpo { min-width: 0; flex: 1; }
.msg-cabeca { display: flex; align-items: baseline; gap: 8px; }
.msg-autor { font-size: 13.5px; font-weight: 600; color: var(--azul-suave); }
.msg.propria .msg-autor { color: var(--verde); }
.msg-hora { font-size: 11px; color: var(--texto-fraco); }
.msg-texto { font-size: 14px; color: var(--texto-medio); overflow-wrap: anywhere; white-space: pre-wrap; margin: 1px 0 0; }
.msg-texto a { color: var(--azul-suave); }
.msg.seguida { margin-top: -8px; }
.msg.seguida .avatar, .msg.seguida .msg-cabeca { display: none; }
.msg.seguida .msg-texto { padding-left: 35px; }
.chat-sistema { text-align: center; font-size: 12px; color: var(--texto-fraco); font-style: italic; }

.chat-form { display: flex; gap: 8px; padding: 12px 14px; border-top: 1px solid var(--borda); }
.chat-form input { flex: 1; }
.chat-form button { padding: 0 15px; }

/* ----- Diálogo de configurações ----- */
.dialogo { width: min(500px, calc(100vw - 32px)); max-height: min(88vh, 820px); padding: 0; border: 1px solid var(--borda-forte); border-radius: 18px; background: var(--vidro); backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px); color: var(--texto); box-shadow: var(--sombra); overflow: hidden; }
.dialogo[open] { display: flex; flex-direction: column; }
.dialogo::backdrop { background: rgba(3, 13, 29, .72); backdrop-filter: blur(3px); }
.dialogo form { padding: 22px 24px 20px; overflow-y: auto; }
.dialogo h2 { margin: 0 0 4px; font-size: 19px; }
.dialogo h3 { margin: 0 0 2px; font-size: 13px; color: var(--azul-suave); letter-spacing: .02em; }
.grupo-config { margin: 20px 0; padding-top: 16px; border-top: 1px solid var(--borda); }
.grupo-config:first-of-type { border-top: 0; padding-top: 8px; }
.linha-config { display: flex; align-items: flex-start; gap: 10px; margin: 12px 0 0; font-size: 14px; color: var(--texto); cursor: pointer; }
.linha-config input { margin-top: 3px; accent-color: var(--azul); width: 16px; height: 16px; flex: none; }
.linha-config small { color: var(--texto-fraco); }
.faixa-config { display: flex; align-items: center; gap: 12px; }
.faixa-config input[type="range"] { flex: 1; }
.faixa-config span { flex: none; min-width: 3.2em; text-align: right; font-size: 13px; color: var(--texto-medio); font-variant-numeric: tabular-nums; }

/* Medidor de voz + marca de abertura, no mesmo eixo. A barra cresce com a
   sua voz; o ponteiro do range é o limite. Passou da marca, está saindo. */
.sensibilidade { position: relative; height: 22px; display: flex; align-items: center; }
.sensibilidade-trilha { position: absolute; inset: 9px 0; height: 4px; border-radius: 999px; background: var(--painel-3); overflow: hidden; pointer-events: none; }
.sensibilidade-nivel { height: 100%; width: 0; background: var(--azul-claro); border-radius: 999px; }
.sensibilidade-nivel.aberto { background: var(--verde); }
.sensibilidade input[type="range"] { position: relative; z-index: 1; background: transparent; }
.sensibilidade input[type="range"]:disabled { opacity: .55; }
.mic-porta-estado { margin: 6px 0 0; font-size: 12px; color: var(--texto-fraco); min-height: 1.2em; }
.caixa-sensibilidade[data-ptt="1"] { opacity: .45; }

.lista-atalhos { list-style: none; margin: 10px 0 8px; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.linha-atalho { display: grid; grid-template-columns: 1fr minmax(7.5em, auto) auto; gap: 8px; align-items: center; }
.atalho-nome { font-size: 14px; color: var(--texto); line-height: 1.25; }
.atalho-nome small { display: block; color: var(--texto-fraco); font-size: 12px; font-weight: 400; }
.atalho-tecla { font-variant-numeric: tabular-nums; min-width: 7.5em; padding: 7px 10px; font-size: 12.5px; }
.atalho-tecla[data-capturando="1"] { border-color: var(--azul); color: var(--azul-suave); box-shadow: 0 0 0 2px rgba(158, 190, 236, .28); }
.atalho-limpar { padding: 7px 8px; font-size: 12px; }
#btn-atalhos-padrao { margin: 4px 0 0; padding: 6px 10px; font-size: 13px; }
kbd { display: inline-block; padding: 1px 6px; border-radius: 6px; border: 1px solid var(--borda-forte); background: var(--painel-2); font-family: inherit; font-size: 11.5px; color: var(--texto); }
@media (max-width: 520px) {
  .linha-atalho { grid-template-columns: 1fr auto; }
  .atalho-nome { grid-column: 1 / -1; }
}
.dialogo .primario { margin-top: 22px; }

/* ----- Rolagem ----- */
* { scrollbar-width: thin; scrollbar-color: var(--borda-forte) transparent; }
::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-thumb { background: var(--borda-forte); border-radius: 999px; border: 2px solid transparent; background-clip: content-box; }
::-webkit-scrollbar-thumb:hover { background: #36455F; background-clip: content-box; }

/* ----- Responsivo ----- */
.so-mobile { display: none; }
@media (max-width: 1080px) {
  :root { --chat-w: 280px; }
}
@media (max-width: 900px) {
  .so-mobile { display: inline-grid; }
  .so-desktop { display: none; }
  .app, .app.sem-chat {
    grid-template-columns: 1fr;
    grid-template-rows: 1fr auto;
    grid-template-areas: "palco" "usuario";
  }
  .lateral {
    position: fixed; z-index: 30; inset: 0 auto 0 0; width: min(84vw, var(--lateral-w));
    transform: translateX(-102%); transition: transform var(--transicao); box-shadow: var(--sombra);
    background: #050F1F;
  }
  .app.lateral-aberta .lateral { transform: none; }
  .chat-area { position: fixed; z-index: 30; inset: 0 0 0 auto; width: min(88vw, 380px); transform: translateX(102%); transition: transform var(--transicao); background: #050F1F; box-shadow: var(--sombra); }
  .app:not(.sem-chat) .chat-area { display: flex; transform: none; }
  .app.sem-chat .chat-area { display: flex; transform: translateX(102%); }

  /* Uma barra so: controles e identidade lado a lado, sempre alcancaveis. O
     microfone nao pode ficar atras da gaveta. */
  .painel-usuario {
    flex-direction: row; align-items: center; gap: 8px; padding: 8px 10px;
    border-right: 0; border-top: 1px solid var(--borda);
    background: var(--vidro); backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px);
  }
  .controles-lateral { flex: 1; flex-direction: row; gap: 6px; padding: 0; border-top: 0; }
  .controles-lateral .controle { flex: 1; justify-content: center; padding: 10px 6px; }
  .controle-linha { flex: 1; }
  .controle-linha .controle { padding-right: 4px; }
  .expandir { width: 28px; }
  /* No celular o rotulo dos botoes que ainda tem um (tela) tambem sai: a barra
     de baixo e estreita. Microfone e silenciar ja sao so icone em toda largura. */
  .controle-texto { display: none; }
  .eu { border-top: 0; background: transparent; padding: 0; gap: 4px; }
  .eu-info { display: none; }
  .palco { padding: 12px; }
}
@media (max-width: 420px) {
  .grade-pessoas { grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; }
}
