/* Tokens, reset, barra de rolagem, shell da chamada e os controles base
   (button/select/input) de que todas as telas dependem.

   Este arquivo carrega PRIMEIRO em toda pagina: e ele que declara as
   variaveis :root que o resto usa. O @import das fontes precisa continuar
   sendo a primeira regra do arquivo. */

@import url('https://fonts.googleapis.com/css2?family=Familjen+Grotesk:wght@400;500;600;700&display=swap');

:root {
  /* DIRECAO VISUAL -- cartaz serigrafado sobre papel escuro.

     Nasceu na landing (src/pages/index.html) e vale para o produto inteiro:
     login, lobby, comunidade, sala. Duas tintas, e a divisao entre elas e' o
     que segura a identidade:

       --verde  estado ao vivo / falando / ativo / acao que conclui.
                NUNCA decoracao. E' a unica coisa da tela que "acende".
       --roxo   a folga de registro, o foco e a marca tipografica
                (icone de secao, numeral, sublinhado de link).

     O chao NAO e' o slate #0f172a de antes: e' a propria tinta do cartaz, um
     preto com veio verde. E nada desfoca -- no cartaz nao existe sombra
     borrada; o que separa uma camada da outra e' a folga de registro ou um
     veu chapado.

     Tela nova pinta com estes tokens, nao com hex proprio. */
  color-scheme: dark;

  --tinta: #E7EBE2;
  --tinta-70: rgba(231, 235, 226, 0.70);
  --tinta-45: rgba(231, 235, 226, 0.46);
  --tinta-15: rgba(231, 235, 226, 0.16);
  --regra: rgba(231, 235, 226, 0.28);
  --verde: #4AEC7D;
  --roxo: #9B80EC;
  --noite: #0B0F0C;

  /* A folga de registro: a segunda tinta escapando do registro, o defeito
     caracteristico da risografia. Duas medidas -- painel e botao --, como no
     bloco final da landing. Gasta em todo elemento ela vira enfeite, entao so'
     recebe folga o que FLUTUA (modal, cartao de chamada) e o botao que conclui
     a acao (.primary). Botao de icone, item de canal e barra de chat ficam
     chapados: herdam paleta e tipografia, nao a folga. */
  --folga: 8px;
  --folga-btn: 4px;

  --color-background: #141A16;
  --color-foreground: var(--tinta);
  --color-card: #1B221C;
  --color-card-foreground: var(--tinta);
  --color-secondary: rgba(231, 235, 226, 0.10);
  --color-secondary-hover: rgba(231, 235, 226, 0.16);
  --color-accent: var(--verde);
  --color-accent-hover: #3ED86C;
  --color-on-accent: #141A16;
  --color-muted: #1B221C;
  --color-muted-foreground: var(--tinta-70);
  --color-border: var(--tinta-15);
  /* Fio entre colunas e sob cabecalho: a mudanca de fundo ja' separa as
     areas, o fio so' confirma. Na forca de `--color-border` ele virava grade. */
  --color-divisa: rgba(231, 235, 226, 0.06);
  /* O #ef4444 do slate foi desenhado contra azul; sobre o papel escuro ele
     perde contraste no tamanho de texto corrido. */
  --color-destructive: #FF6B6B;
  --color-destructive-hover: #F04848;
  --color-warning: #F0B232;
  /* O anel de foco e' a segunda tinta: foco nao e' estado ao vivo, entao nao
     pode ser verde. */
  --color-ring: var(--roxo);

  --font-sans: "Familjen Grotesk", "Segoe UI", system-ui, -apple-system, sans-serif;

  --transition-fast: 150ms ease-out;

  /* Controles (input, textarea, select, button). Tudo o que e' caixa clicavel
     ou digitavel sai daqui: a mesma altura, o mesmo raio e a mesma borda em
     toda tela. Quem precisa de um controle menor (linha de membro, filtro da
     coluna) so' troca `min-height` e `font-size` -- nunca o resto. */
  --control-h: 40px;
  --control-h-md: 36px;
  --control-h-sm: 32px;
  --control-radius: 12px;
  --control-pad-x: 0.7rem;
  --control-bg: var(--noite);
  --control-bg-hover: #10170F;
  --control-ring: rgba(155, 128, 236, 0.30);

  /* Raio de painel (cartao, modal, tile). O da landing. */
  --raio-cartao: 14px;

  /* Superficies do app de comunidades. A escada vai do trilho (a tinta mais
     escura do cartaz) ate o conteudo, que e' o papel. E' o que da profundidade
     as quatro colunas sem precisar de sombra em nenhuma. */
  --color-rail: var(--noite);
  --color-sidebar: #171E18;
  --color-sidebar-hover: rgba(231, 235, 226, 0.07);
  --color-elevado: #232B24;

  /* Estados de presenca. Online e' o verde da marca -- presenca ao vivo e' o
     dono legitimo dele. Os outros tres seguem a convencao universal, so'
     ajustados para o papel escuro. */
  --status-online: var(--verde);
  --status-ausente: #F0B232;
  --status-ocupado: #FF6B6B;
  --status-offline: rgba(231, 235, 226, 0.40);
}

/* Multiplicador do texto do chat (ver `.msg-texto`). Fica aqui, e nao so' no
   JS, para a pagina ter um valor valido antes de config-ui.js rodar. */
:root {
  --fonte-chat: 1;
}

/* Bolinhas de nao lidas desligadas nas configuracoes. E' so' pintura: o
   contador continua sendo calculado, o que muda e' nao mostrar. */
:root[data-badges='off'] .rail-badge,
:root[data-badges='off'] .canal-badge,
:root[data-badges='off'] .nav-badge {
  display: none;
}

* {
  box-sizing: border-box;
}

/* Barra de rolagem propria, pra nao destoar do resto da identidade visual com
   a barra padrao (branca, grossa) do sistema. `.rail` continua escondendo a
   dela por conta propria (regra mais especifica, ganha desta aqui). */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--color-secondary-hover) transparent;
}

*::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}

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

*::-webkit-scrollbar-thumb {
  background-color: var(--color-secondary-hover);
  background-clip: padding-box;
  border: 2px solid transparent;
  border-radius: 999px;
}

*::-webkit-scrollbar-thumb:hover {
  background-color: var(--color-muted-foreground);
  background-clip: padding-box;
}

body {
  margin: 0;
  font-family: var(--font-sans);
  background: var(--color-background);
  color: var(--color-foreground);
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
  /* Numero de largura fixa: contador e cronometro nao tremem ao mudar. */
  font-variant-numeric: tabular-nums;
}

/* Grao do papel. Por cima de tudo -- inclusive de modal e de video --, sem
   capturar clique. E' o que faz a tela parecer impressa em vez de renderizada;
   sem ele a paleta sozinha vira "mais um app escuro". */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 2000;
  pointer-events: none;
  opacity: 0.07;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23g)'/%3E%3C/svg%3E");
}

/* No teatro da chamada o conteudo e' a tela de alguem: o grao por cima dela
   muda as cores da transmissao. room.js liga a classe ao abrir o teatro. */
body.no-teatro::after {
  display: none;
}

/* Uma fonte so' no app inteiro: Familjen Grotesk. O que separa titulo, texto
   e rotulo e' peso, caixa e espacamento -- nunca outra familia.

   Titulo: maiuscula pesada, a voz do cartaz. Vale para h1 e h2 -- titulo de
   pagina e de secao. h3 fica em caixa normal de proposito: no app ele rotula
   coisa densa (mensagens fixadas, secao do perfil), onde a maiuscula so'
   dificulta a leitura. Quem quiser o tratamento num elemento que nao e'
   cabecalho usa `.titulo-cartaz`. A fonte vai ate' 700; peso 800/900 pedido
   em outra folha cai nele. */
h1,
h2,
.titulo-cartaz {
  font-family: var(--font-sans);
  font-weight: 700;
  text-transform: uppercase;
  line-height: 1;
  letter-spacing: -0.015em;
}

/* Rotulo utilitario: o que e' voz do produto (estado, contador, slug, rotulo
   de campo) vai em maiuscula pequena e espacada. Texto de leitura nunca usa. */
.rotulo {
  font-family: var(--font-sans);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-muted-foreground);
}

.hidden {
  display: none !important;
}

/* Icone de traco (utils/icones.js). Mede 1em e pinta com a cor do texto, entao
   ocupa o lugar exato do emoji que substituiu: quem precisa de outro tamanho
   muda o font-size do pai, nao o SVG. */
.icone {
  width: 1em;
  height: 1em;
  flex: none;
  vertical-align: -0.125em;
}

/* --- Movimento dos icones ---
   Todo icone de traco carrega um movimento em `data-anima` (a tabela fica em
   utils/icones.js; SVG escrito no HTML recebe o atributo a mao). O movimento
   toca uma vez quando o botao ou link que contem o icone recebe hover ou foco
   de teclado: o icone responde ao gesto, nunca fica se mexendo sozinho.

   Usa `rotate`/`translate`/`scale` (propriedades separadas), que se somam ao
   `transform` que alguma tela ja' aplique para alinhar o desenho. Por isso um
   icone com `data-anima` nao deve girar por `transform` em outra folha: os
   dois giros se somariam.

   `virar` e' o unico de estado -- o chevron aponta para o menu: baixo
   fechado, cima aberto (`aria-expanded="true"` no botao). Esse giro vale
   mesmo com reduced-motion, porque diz algo; so' a transicao some. */
[aria-expanded='true'] [data-anima='virar'] {
  rotate: 180deg;
}

@media (prefers-reduced-motion: no-preference) {
  [data-anima] {
    --anima-nome: none;
    --anima-duracao: 500ms;
    --anima-curva: ease-in-out;
    transition: rotate 280ms cubic-bezier(0.34, 1.56, 0.64, 1), translate 200ms ease-out;
  }

  [data-anima='balancar'] { --anima-nome: icone-balancar; --anima-duracao: 650ms; transform-origin: 50% 15%; }
  [data-anima='pular']    { --anima-nome: icone-pular; --anima-duracao: 480ms; }
  [data-anima='pulsar']   { --anima-nome: icone-pulsar; --anima-duracao: 380ms; }
  [data-anima='rolar']    { --anima-nome: icone-rolar; --anima-duracao: 600ms; --anima-curva: cubic-bezier(0.34, 1.3, 0.64, 1); }
  [data-anima='deslizar'] { --anima-nome: icone-deslizar; --anima-duracao: 420ms; --anima-dx: 0.2em; }
  [data-anima='recuar']   { --anima-nome: icone-deslizar; --anima-duracao: 420ms; --anima-dx: -0.2em; }
  [data-anima='voar']     { --anima-nome: icone-voar; --anima-duracao: 520ms; }

  :is(button, a, summary, [role='button'], [role='menuitem'], [role='tab']):is(:hover, :focus-visible) [data-anima] {
    animation: var(--anima-nome) var(--anima-duracao) var(--anima-curva);
  }

  /* Os de transicao ficam na pose enquanto o hover durar e voltam ao sair. */
  :is(button, a, summary, [role='button'], [role='menuitem'], [role='tab']):is(:hover, :focus-visible) [data-anima='girar'] {
    rotate: 90deg;
  }

  :is(button, a, summary, [role='button'], [role='menuitem'], [role='tab']):is(:hover, :focus-visible) [data-anima='inclinar'] {
    rotate: -14deg;
  }

  :is(button, a, summary, [role='button'], [role='menuitem'], [role='tab']):is(:hover, :focus-visible) [data-anima='virar'] {
    translate: 0 0.1em;
  }

  /* Alto-falante: o corpo fica, as ondas (tudo depois do primeiro traco)
     piscam de dentro para fora. */
  :is(button, a, summary, [role='button'], [role='menuitem'], [role='tab']):is(:hover, :focus-visible) [data-anima='ondas'] > :not(:first-child) {
    animation: icone-onda 700ms ease-in-out;
  }

  :is(button, a, summary, [role='button'], [role='menuitem'], [role='tab']):is(:hover, :focus-visible) [data-anima='ondas'] > :last-child {
    animation-delay: 120ms;
  }
}

@keyframes icone-balancar {
  20% { rotate: 14deg; }
  40% { rotate: -10deg; }
  60% { rotate: 6deg; }
  80% { rotate: -3deg; }
}

@keyframes icone-pular {
  35% { translate: 0 -0.18em; }
  65% { translate: 0 0.04em; }
  85% { translate: 0 -0.05em; }
}

@keyframes icone-pulsar {
  40% { scale: 1.18; }
  70% { scale: 0.94; }
}

@keyframes icone-rolar {
  from { rotate: 0deg; }
  to { rotate: 360deg; }
}

@keyframes icone-deslizar {
  45% { translate: var(--anima-dx) 0; }
}

/* Sai pela diagonal, reaparece do lado oposto e assenta: o aviao de enviar. */
@keyframes icone-voar {
  45% { translate: 0.35em -0.35em; opacity: 0; }
  46% { translate: -0.35em 0.35em; opacity: 0; }
}

@keyframes icone-onda {
  40% { opacity: 0.15; }
}

.screen {
  min-height: 100vh;
}

#main-screen.screen {
  display: flex;
  flex-direction: column;
  height: 100vh;
}

/* A chamada divide a tela com o trilho de comunidades. Sem trilho (enquanto
   ele carrega, ou em telas estreitas) a chamada ocupa tudo sozinha. */
.call-shell {
  display: flex;
  height: 100vh;
  height: 100dvh;
}

.call-shell > #main-screen {
  flex: 1;
  min-width: 0;
}

.call-shell > #main-screen.screen {
  height: 100%;
}

.rail-chamada {
  flex: none;
  width: 72px;
  border-right: 1px solid var(--color-divisa);
}

/* `.rail` define `display: flex` mais abaixo no arquivo, entao a regra estreita
   precisa de mais especificidade para vencer. */
@media (max-width: 640px) {
  .call-shell > .rail-chamada {
    display: none;
  }
}

/* ---------------------------------------------------------------------------
   Controles
   ---------------------------------------------------------------------------
   Uma caixa so' para input, textarea e select: mesma altura, mesmo raio,
   mesma borda, mesmo foco. Antes cada tela redesenhava o seu campo -- e o que
   escapava (um `type="search"`, que nenhuma regra pegava) caia no desenho do
   sistema, branco, no meio de um modal escuro.

   `.controle` existe para o caso raro de um elemento que precisa da mesma
   caixa sem ser um destes tres.
   --------------------------------------------------------------------------- */

button,
select,
input,
textarea {
  font-family: inherit;
}

/* Os `:not()` moram dentro de `:where()` porque `:where()` nao soma
   especificidade. Soltos, os cinco valiam (0,5,1) -- mais que
   `input[type='search']` e mais que qualquer classe de ajuste --, entao esta
   regra apagava o espaco reservado para a lupa e as alturas menores logo
   abaixo. Com `:where()` a caixa continua sendo o padrao e volta a ser
   sobrescrevivel, que era a intencao. */
input:where(:not([type='checkbox']):not([type='radio']):not([type='color']):not([type='file']):not([type='range'])),
textarea,
select,
.controle {
  appearance: none;
  -webkit-appearance: none;
  min-height: var(--control-h);
  padding: 0.45rem var(--control-pad-x);
  border: 1px solid var(--color-border);
  border-radius: var(--control-radius);
  background-color: var(--control-bg);
  color: var(--color-foreground);
  font-size: 0.88rem;
  line-height: 1.3;
  transition: border-color var(--transition-fast), background-color var(--transition-fast),
    box-shadow var(--transition-fast);
}

input::placeholder,
textarea::placeholder {
  color: var(--color-muted-foreground);
}

input:hover:not(:disabled):not(:focus),
textarea:hover:not(:disabled):not(:focus),
select:hover:not(:disabled) {
  border-color: var(--color-secondary-hover);
  background-color: var(--control-bg-hover);
}

/* O foco troca a borda por verde e ganha um halo. O `outline` branco global
   continua valendo para botao e link -- num campo ele so' brigava com a
   borda que ja diz a mesma coisa. */
input:focus,
textarea:focus,
select:focus,
.controle:focus {
  outline: none;
  border-color: var(--color-accent);
  box-shadow: 0 0 0 3px var(--control-ring);
}

input:disabled,
textarea:disabled,
select:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

textarea {
  resize: vertical;
}

/* Campo de busca: a lupa e' background, entao qualquer `type="search"` da
   aplicacao ja nasce com ela sem precisar de markup em volta. O `x` nativo do
   WebKit sai -- ele vem com o desenho do sistema e nao acompanha o tema. */
input[type='search'] {
  padding-left: 2.1rem;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M21 21l-4.3-4.3'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: left 0.65rem center;
  background-size: 15px;
}

input[type='search']::-webkit-search-cancel-button,
input[type='search']::-webkit-search-decoration {
  -webkit-appearance: none;
  appearance: none;
}

/* O `select` nativo se pinta com as cores do sistema -- no Windows, caixa
   branca e seta cinza -- e ficava claro dentro de um modal escuro. Sem o
   desenho nativo, a seta passa a ser um SVG no background: e' a unica parte
   da caixa fechada que da' para estilizar em todos os navegadores. */
select {
  padding-right: 1.9rem;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none' stroke='%2394a3b8' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 4.5 6 7.5 9 4.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.65rem center;
  background-size: 11px;
  cursor: pointer;
}

/* A lista aberta quem desenha e' o sistema; so' da' para pedir as cores dela. */
select option {
  background: var(--color-card);
  color: var(--color-foreground);
}

:focus-visible {
  outline: 2px solid var(--color-ring);
  outline-offset: 2px;
}

.card {
  background: var(--color-card);
  color: var(--color-card-foreground);
  padding: 2.5rem;
  width: 320px;
  max-width: 100%;
  border: 1px solid var(--color-border);
  border-radius: var(--raio-cartao);
}

.register-screen {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
}

/* Margem positiva por padrao: a dica aparece depois de coisas muito diferentes
   (linha de botoes, grade, medidor) e um recuo negativo geral fazia o texto
   subir por cima do elemento anterior sempre que ele nao tinha margem embaixo
   para consumir. O recuo so' volta na regra abaixo, no unico caso em que
   existe essa margem: logo depois de um campo. */
.form-hint {
  font-size: 0.875rem;
  color: var(--color-muted-foreground);
  margin: 0.4rem 0 1rem;
}

label + .form-hint,
input + .form-hint,
select + .form-hint,
textarea + .form-hint {
  margin-top: -0.5rem;
}

.form-hint a {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: var(--roxo);
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
}

.form-hint a:hover {
  text-decoration-color: currentColor;
}

button + .form-hint,
.button-link + .form-hint {
  margin-top: 1rem;
  margin-bottom: 0;
  text-align: center;
}

.form-error {
  font-size: 0.8rem;
  color: var(--color-destructive);
  margin: -0.5rem 0 1rem;
}

.button-link {
  cursor: pointer;
  text-align: center;
  text-decoration: none;
  border-radius: var(--control-radius);
  min-height: var(--control-h);
  font-size: 0.88rem;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background var(--transition-fast);
}

.card h1 {
  margin: 0 0 1.5rem;
  font-size: 1.9rem;
}

/* O widget do Turnstile (ver captcha.js) nasce sem moldura propria: sem isto
   ele cola no campo de cima e no botao de baixo, e o iframe interno herda a
   largura do container e' quem centraliza o quadrado 130x120 do 'compact'. */
#captcha-container {
  display: flex;
  justify-content: center;
  margin-bottom: 1rem;
}

.divider {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin: 1.25rem 0;
  font-size: 0.8rem;
  color: var(--color-muted-foreground);
}

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

.card label {
  display: block;
  margin-bottom: 1rem;
  font-size: 0.85rem;
  color: var(--color-muted-foreground);
}

/* Dentro do cartao o campo e' a peca principal da tela (login, cadastro), e
   nao um controle de canto: ocupa a linha inteira e cresce um pouco. A caixa
   em si continua sendo a de cima. */
.card input:not([type='checkbox']):not([type='radio']):not([type='color']):not([type='file']),
.card textarea,
.card label select {
  display: block;
  width: 100%;
  margin-top: 0.4rem;
  min-height: 44px;
  font-size: 0.95rem;
}

/* O botao usa a mesma altura e o mesmo raio do campo: numa linha em que os
   dois convivem (busca + acao) eles terminam do mesmo tamanho sem ninguem
   precisar de ajuste local.

   O botao comum continua chapado e sem borda: o app tem dezenas de botoes de
   icone (barra da sala, cabecalho do canal, linha de membro) que herdam desta
   regra, e uma moldura em cada um deles vira ruido. A folga de registro fica
   com `.primary`, que e' o botao que conclui a acao. */
button {
  cursor: pointer;
  border: none;
  border-radius: var(--control-radius);
  padding: 0.5rem 1rem;
  min-height: var(--control-h);
  font-size: 0.88rem;
  font-weight: 500;
  background: var(--color-secondary);
  color: var(--color-foreground);
  transition: background var(--transition-fast), transform var(--transition-fast),
    opacity var(--transition-fast);
}

button:hover:not(:disabled) {
  background: var(--color-secondary-hover);
}

button:active:not(:disabled) {
  transform: scale(0.97);
}

button:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

/* Botao que existe mas nao pode agora -- e que, ao contrario do `disabled`,
   continua recebendo o clique de proposito: e' o clique que conta o motivo
   ("Fulano esta offline"). Parece igual a um desligado; a diferenca e' que
   responde. */
button[aria-disabled='true'] {
  opacity: 0.55;
}

/* O botao de acao e' o `.btn` da landing: verde chapado, borda de tinta e a
   folga de registro roxa saindo por baixo. O hover nao acende nada -- so'
   encosta o papel no registro, o mesmo movimento de la. */
.primary {
  background: var(--color-accent);
  color: var(--color-on-accent);
  border: 2.5px solid var(--tinta);
  border-radius: var(--raio-cartao);
  box-shadow: var(--folga-btn) var(--folga-btn) 0 var(--roxo);
  font-family: var(--font-sans);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  transition: transform var(--transition-fast), box-shadow var(--transition-fast),
    background var(--transition-fast);
}

.primary:hover:not(:disabled) {
  background: var(--color-accent-hover);
  transform: translate(2px, 2px);
  box-shadow: 2px 2px 0 var(--roxo);
}

/* `button:active` global encolhe em 3%; aqui o movimento e' outro -- o papel
   encosta no registro e a folga zera. */
.primary:active:not(:disabled) {
  transform: translate(var(--folga-btn), var(--folga-btn));
  box-shadow: 0 0 0 var(--roxo);
}

/* Enquanto a requisicao corre o botao fica `disabled`: encostado no registro,
   como um botao ja' apertado -- e nao levantado, com cara de que ainda da'
   para apertar de novo. */
.primary:disabled {
  transform: translate(var(--folga-btn), var(--folga-btn));
  box-shadow: none;
}

button.danger {
  background: transparent;
  color: var(--color-destructive);
  border: 2px solid var(--color-destructive);
  border-radius: var(--control-radius);
}

button.danger:hover:not(:disabled) {
  background: var(--color-destructive);
  color: var(--noite);
}

/* Linha de acoes de uma lista (amigo, membro, convite, waitlist, card de
   perfil): o `.primary` cheio, em maiuscula espacada e com folga roxa, ficava
   maior e com outro desenho de letra que o botao ao lado. Aqui todos tem a mesma letra,
   a mesma borda de 2px e nenhuma folga -- o verde ja' diz qual e' a acao. */
:is(.amigo-acoes, .perfil-card-acoes, .convidar-linha, .convidar-link-linha, .movimento-acoes,
    .ec-membro-acoes, .waitlist-item-acoes, .admin-perfil-acoes, .msg-editor-acoes,
    .plugin-barra, .atividade-acoes) button {
  border: 2px solid transparent;
  border-radius: var(--control-radius);
  box-shadow: none;
  font-family: inherit;
  font-weight: 600;
  letter-spacing: normal;
  text-transform: none;
}

:is(.amigo-acoes, .perfil-card-acoes, .convidar-linha, .convidar-link-linha, .movimento-acoes,
    .ec-membro-acoes, .waitlist-item-acoes, .admin-perfil-acoes, .msg-editor-acoes,
    .plugin-barra, .atividade-acoes) button.primary {
  border-color: var(--tinta);
}

:is(.amigo-acoes, .perfil-card-acoes, .convidar-linha, .convidar-link-linha, .movimento-acoes,
    .ec-membro-acoes, .waitlist-item-acoes, .admin-perfil-acoes, .msg-editor-acoes,
    .plugin-barra, .atividade-acoes) button.danger {
  border-color: var(--color-destructive);
}

:is(.amigo-acoes, .perfil-card-acoes, .convidar-linha, .convidar-link-linha, .movimento-acoes,
    .ec-membro-acoes, .waitlist-item-acoes, .admin-perfil-acoes, .msg-editor-acoes,
    .plugin-barra, .atividade-acoes) button.primary:is(:hover, :active, :disabled) {
  box-shadow: none;
  transform: none;
}

.card button,
.card .button-link {
  width: 100%;
  min-height: 44px;
  margin-top: 0.5rem;
  padding: 0.7rem;
}

/* Fila de aprovacao da waitlist (secao "Administracao" do painel de
   configuracoes, ver config-ui.js): uma linha por pedido, e-mail+quando de um
   lado, dois botoes pequenos do outro -- os botoes pisam a regra
   ".card button" acima (mesma especificidade, mas depois no arquivo) de
   proposito, porque aqui nao fazem sentido ocupando a largura inteira do
   cartao. */
.waitlist-lista {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-top: 1rem;
}

.waitlist-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.75rem;
  border: 1px solid var(--color-border);
  border-radius: var(--control-radius);
  background: var(--control-bg);
}

.waitlist-item-info {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
}

.waitlist-item-email {
  font-size: 0.9rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.waitlist-item-quando {
  font-size: 0.75rem;
  color: var(--color-muted-foreground);
}

.waitlist-item-acoes {
  display: flex;
  gap: 0.5rem;
  flex-shrink: 0;
}

.waitlist-item-acoes button {
  width: auto;
  min-height: 36px;
  margin-top: 0;
  padding: 0.4rem 0.9rem;
  font-size: 0.82rem;
}

/* Acesso a plugins (admin do CatVoice): a linha do waitlist com avatar na frente. */
.waitlist-item > .avatar { flex-shrink: 0; }
.waitlist-item .waitlist-item-info { flex: 1; }
.waitlist-item.oculto { opacity: 0.55; }
.admin-plugins-filtros {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin: 0.5rem 0;
}
.admin-plugins-filtros input[type="text"],
.admin-plugins-filtros select { flex: 1 1 160px; min-width: 0; margin-top: 0; }
.admin-plugins-ocultos { display: flex; align-items: center; gap: 0.4rem; font-size: 0.82rem; white-space: nowrap; }
.admin-plugins-ocultos input { width: auto; margin: 0; }

.admin-plugins-permissoes { position: relative; }
.admin-plugins-dropdown {
  position: absolute;
  top: calc(100% + 0.4rem);
  right: 0;
  z-index: 10;
  min-width: 190px;
  padding: 0.75rem;
  margin: 0;
  background: var(--color-card);
  color: var(--color-foreground);
  border: 1px solid var(--color-border);
  border-radius: var(--control-radius);
}
.admin-plugins-dropdown legend { font-size: 0.8rem; color: var(--color-muted-foreground); }
.admin-plugins-dropdown label { display: flex; align-items: center; gap: 0.5rem; padding: 0.3rem; }
.admin-plugins-dropdown input { width: auto; margin: 0; }
.admin-plugins-dropdown input:focus-visible { outline: 2px solid var(--color-ring); outline-offset: 3px; }

/* Mesma ideia do item de waitlist acima, com um avatar de 40px na frente
   para confirmar visualmente que a busca por apelido achou a conta certa
   antes de apagar a imagem dela. */
.admin-perfil-card {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-top: 1rem;
  padding: 0.75rem;
  border: 1px solid var(--color-border);
  border-radius: var(--control-radius);
  background: var(--control-bg);
}

.admin-perfil-info {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
  flex: 1;
}

.admin-perfil-nome {
  font-size: 0.9rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.admin-perfil-apelido {
  font-size: 0.75rem;
  color: var(--color-muted-foreground);
}

.admin-perfil-acoes {
  display: flex;
  gap: 0.5rem;
  flex-shrink: 0;
}

.admin-perfil-acoes button {
  width: auto;
  min-height: 36px;
  margin-top: 0;
  padding: 0.4rem 0.9rem;
  font-size: 0.82rem;
}

/* Combobox de busca: so' aparece depois que ha' algo digitado, listando quem
   comeca com aquelas letras. Fica embutido no fluxo do card, sem flutuar por
   cima de nada -- mesma escolha do resultado unico de "convidar por apelido"
   em lobby.js. */
.admin-perfil-sugestoes {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  margin: 0 0 1rem;
  max-height: 260px;
  overflow-y: auto;
}

.admin-perfil-sugestoes .admin-perfil-sugestao {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  width: 100%;
  min-height: 0;
  margin-top: 0;
  padding: 0.5rem 0.6rem;
  border: 1px solid var(--color-border);
  border-radius: var(--control-radius);
  background: var(--control-bg);
  text-align: left;
  cursor: pointer;
}

.admin-perfil-sugestoes .admin-perfil-sugestao:hover {
  border-color: var(--color-accent);
}

/* Apelido pode ter 20 caracteres quaisquer -- sem o corte, um apelido longo
   empurra a linha e some com a borda do cartao. */
.admin-perfil-sugestao-apelido {
  font-size: 0.85rem;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.admin-perfil-sugestao-nome {
  font-size: 0.75rem;
  color: var(--color-muted-foreground);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex-shrink: 0;
}

.admin-perfil-sugestao-vazio {
  font-size: 0.8rem;
  color: var(--color-muted-foreground);
  margin: 0;
}

