/* @import precisa vir antes de QUALQUER regra: uma so depois dele faz o
   navegador ignora-lo silenciosamente, e a fonte simplesmente nao carrega.
   Por isso este bloco abre o arquivo, antes ate do comentario da paleta.

   A fonte de emoji entra por ultimo na PILHA de font-family (ver --fonte-emoji
   abaixo), e e isso que faz a coisa funcionar: o navegador usa a primeira fonte
   que tem o caractere, entao letras e numeros continuam saindo em Inter e so os
   emojis (que Inter nao tem) caem na Noto. Poe-la antes na pilha trocaria
   digitos e simbolos por versoes emoji. */
@import url("/fonts/noto-color-emoji.css");

/* Paleta clara e minimalista, no espirito do mockup de referencia:
   fundo levemente cinza, cartoes brancos, sombras quase imperceptiveis e
   bolhas em pilula. Tudo deriva do roxo da marca (#625ef1): os cinzas sao o
   mesmo matiz (241.6deg) com saturacao baixa, para o neutro nao brigar com o
   destaque. */
:root {
  --marca:         #625ef1;  /* o roxo da logo — origem de todo o resto */
  --marca-escuro:  #4b47d6;  /* hover/estados pressionados */

  --bg:            #f6f6f9;  /* fundo geral, o cinza mais claro */
  --panel:         #ffffff;  /* cartoes: lista, conversa, cabecalhos */
  --panel-2:       #f9f9fb;  /* faixas internas: busca, composer */
  --border:        #ebebf2;  /* divisorias — quase invisiveis de proposito */
  --text:          #181820;
  --text-dim:      #8f8fa3;
  --accent:        var(--marca);
  --accent-soft:   #e8e7fd;  /* fundo do item ativo / chip selecionado */
  --bubble-in:     #f3f3f7;  /* recebida: cinza claro */
  --bubble-out:    #eaeafd;  /* enviada: roxo bem lavado */

  /* Sombras "sombrinhas": difusas, opacidade baixissima — tingidas de roxo
     em vez de cinza neutro, para o conjunto ficar coeso. */
  --sombra-sutil:  0 1px 2px rgba(37, 34, 90, .05);
  --sombra-card:   0 1px 3px rgba(37, 34, 90, .06), 0 8px 24px rgba(37, 34, 90, .05);

  /* Trilho escuro. E o unico bloco escuro do app, entao os neutros dele sao o
     mesmo matiz roxo (241.6deg) dos claros, so que no fim escuro da escala —
     um cinza neutro aqui destoaria do resto. */
  --rail-bg:       #1c1b22;
  --rail-item:     #a3a2b0;  /* icone/label em repouso */
  --rail-item-on:  #ffffff;  /* item selecionado */
  --rail-ativo:    #2b2a34;  /* cartao do item selecionado */
  --rail-w:        76px;

  /* Silhuetas para o avatar de quem nao tem foto NEM nome. Ficam como data URI
     em variavel para o CSS aplica-las como mascara e a cor vir do tom do
     avatar — um <img> teria cor fixa e destoaria do fundo pastel. */
  --icone-pessoa: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 12a4.2 4.2 0 1 0 0-8.4 4.2 4.2 0 0 0 0 8.4Zm0 1.8c-4 0-7.2 2.3-7.2 5.1v1.3h14.4v-1.3c0-2.8-3.2-5.1-7.2-5.1Z' fill='%23000'/%3E%3C/svg%3E");
  --icone-grupo:  url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 11.4a3.3 3.3 0 1 0 0-6.6 3.3 3.3 0 0 0 0 6.6Zm7.4.4a2.8 2.8 0 1 0 0-5.6 2.8 2.8 0 0 0 0 5.6ZM9 13.1c-3.2 0-5.8 1.9-5.8 4.2v1.1h11.6v-1.1c0-2.3-2.6-4.2-5.8-4.2Zm7.4.8c-.6 0-1.2.1-1.7.2 1 .9 1.6 2 1.6 3.2v1.2h5.5v-1c0-2-2.4-3.6-5.4-3.6Z' fill='%23000'/%3E%3C/svg%3E");
}

* { box-sizing: border-box; margin: 0; padding: 0; }

/* Repetida em todo lugar que mostra texto vindo do WhatsApp. Uma variavel
   evita a pilha inteira copiada em cada regra, e faz `font-family: inherit`
   (que varios controles usam) continuar valendo. */
:root {
  --fonte-texto: "Inter", "Segoe UI", system-ui, -apple-system, sans-serif;
  --fonte-emoji: "Noto Color Emoji", "Apple Color Emoji", "Segoe UI Emoji", sans-serif;
}

body {
  font-family: var(--fonte-texto), var(--fonte-emoji);
  background: var(--bg);
  color: var(--text);
  height: 100vh;
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
}

.hidden { display: none !important; }

/* ---------- tela de conexao ---------- */

.connect-screen {
  height: 100vh;
  display: grid;
  place-items: center;
  background: var(--bg);
}

.connect-card {
  background: var(--panel);
  padding: 40px 48px;
  border-radius: 20px;
  text-align: center;
  max-width: 460px;
  box-shadow: var(--sombra-card);
}

/* Logo opcional (public/img/logo.png). A altura fixa manda no tamanho
   exibido, entao um PNG grande nao estoura o card. */
.marca { height: 44px; width: auto; max-width: 100%; margin-bottom: 14px; }

.connect-card h1 { color: var(--accent); margin-bottom: 12px; font-size: 26px; letter-spacing: -.02em; }
.connect-card p  { color: var(--text-dim); margin-bottom: 20px; }

.qr-box img {
  width: 260px; height: 260px;
  background: #fff; padding: 10px; border-radius: 14px;
  box-shadow: var(--sombra-sutil);
}

.qr-hint { font-size: 13px; margin-top: 16px; line-height: 1.6; color: var(--text-dim); }

.btn {
  background: var(--accent); color: #fff; border: 0;
  padding: 11px 22px; border-radius: 10px; cursor: pointer;
  font-size: 14px; font-weight: 600;
  box-shadow: var(--sombra-sutil);
  transition: filter 120ms;
}
/* Escurece em vez de clarear: o roxo e saturado, e brightness() acima de 1
   lava a cor em vez de dar sensacao de "pressionado". */
.btn:hover { background: var(--marca-escuro); }

/* ---------- layout ---------- */

.layout {
  display: grid;
  /* A largura vive numa variavel para o arraste so trocar o valor dela, sem
     recalcular layout no JS. O minimo (72px) e o avatar (40) mais o padding
     do item (16 de cada lado): abaixo disso a foto de perfil seria cortada. */
  --sidebar-w: 380px;
  /* O trilho e a primeira coluna e tem largura fixa: so a lista de conversas
     e redimensionavel, entao ele fica fora do que a divisa controla. */
  grid-template-columns: var(--rail-w) var(--sidebar-w) 6px 1fr;
  height: 100vh;
  gap: 10px;
  padding: 10px;
  background: var(--bg);
}

/* ---------- trilho escuro de navegacao ---------- */

.railbar {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 14px 8px 12px;
  background: var(--rail-bg);
  border-radius: 16px;
  overflow-y: auto;
  /* A barra de rolagem clara cortaria o painel escuro se a lista de itens
     crescer; escondida, o conteudo ainda rola. */
  scrollbar-width: none;
}
.railbar::-webkit-scrollbar { display: none; }

.rail-logo {
  width: 34px; height: 34px; object-fit: contain;
  margin-bottom: 12px; flex: none;
}

.rail-nav, .rail-rodape {
  display: flex; flex-direction: column; align-items: center;
  gap: 4px; width: 100%;
}
/* Empurra o rodape para baixo, para Perfil/Sair ficarem no pe do trilho
   independente de quantos itens houver em cima. */
.rail-rodape { margin-top: auto; }

.rail-item {
  display: flex; flex-direction: column; align-items: center; gap: 5px;
  width: 100%; padding: 9px 2px 8px;
  background: transparent; border: 0; border-radius: 12px;
  color: var(--rail-item);
  font: inherit; font-size: 10.5px; font-weight: 600;
  text-decoration: none; cursor: pointer;
  transition: background 120ms, color 120ms;
}
.rail-item:hover { background: rgba(255, 255, 255, .06); color: var(--rail-item-on); }
.rail-item:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}
.rail-item.ativo { background: var(--rail-ativo); color: var(--rail-item-on); }

.rail-icone { position: relative; display: block; width: 24px; height: 24px; }
.rail-icone svg { width: 100%; height: 100%; display: block; }

.rail-label {
  max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  letter-spacing: -.01em;
}

/* Contador sobre o icone, como no mockup. Fica no canto superior direito e
   nao empurra o layout do item — por isso posicionado, nao no fluxo. */
.rail-badge {
  position: absolute; top: -5px; right: -8px;
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 17px; height: 17px; padding: 0 5px;
  background: #f04438; color: #fff;
  border: 2px solid var(--rail-bg);
  border-radius: 999px;
  font-size: 10px; font-weight: 700; line-height: 1;
}

/* Interruptor do item de SLA. O trilho inteiro e feito de botoes que parecem
   iguais (icone + rotulo), entao um item que LIGA algo precisa de uma marca
   propria: sem ela, "ativo" e "selecionado como filtro" seriam a mesma
   aparencia, e o unico jeito de saber o estado seria olhar a lista.

   Ele nao usa a classe .ativo dos filtros pelo mesmo motivo: aquele fundo
   significa "esta e a aba que voce esta vendo", e reaproveita-lo aqui diria
   algo que nao e verdade. */
.rail-switch {
  display: block;
  width: 26px; height: 14px; padding: 2px;
  background: rgba(255, 255, 255, .18);
  border-radius: 999px;
  transition: background 120ms;
}
.rail-switch-bola {
  display: block; width: 10px; height: 10px;
  background: #fff; border-radius: 50%;
  transition: transform 120ms;
}
.rail-toggle[aria-pressed="true"] { color: var(--rail-item-on); }
.rail-toggle[aria-pressed="true"] .rail-switch { background: var(--accent); }
.rail-toggle[aria-pressed="true"] .rail-switch-bola { transform: translateX(12px); }

.rail-divisa {
  width: 28px; height: 1px; flex: none;
  margin: 10px 0;
  background: rgba(255, 255, 255, .12);
}

/* Divisa arrastavel. A faixa em si e transparente: entre dois cartoes brancos
   uma barra cinza pesaria demais. So aparece no hover/arraste. */
.resizer {
  position: relative;
  background: transparent;
  cursor: col-resize;
  border-radius: 3px;
  transition: background 120ms;
}
.resizer::before {
  content: '';
  position: absolute;
  inset: 0 -4px;
}
.resizer:hover,
.resizer:focus-visible,
.resizer.arrastando { background: var(--accent); outline: none; }

/* Durante o arraste, o cursor nao pode virar "texto" ao passar por cima das
   mensagens, e a selecao atrapalharia. */
body.redimensionando {
  cursor: col-resize;
  user-select: none;
}

/* Filtros da lista de conversas. */
.filtros {
  display: flex; gap: 6px; flex-wrap: wrap;
  padding: 2px 14px 12px;
  background: var(--panel);
}

.filtro {
  border: 0; border-radius: 999px;
  padding: 5px 12px;
  font-size: 12.5px; font-weight: 500;
  background: var(--panel-2); color: var(--text-dim);
  cursor: pointer;
  white-space: nowrap;
  transition: background 120ms, color 120ms;
}
.filtro:hover { color: var(--text); background: var(--border); }
.filtro.ativo { background: var(--accent-soft); color: var(--accent); font-weight: 600; }

/* O contador some sozinho quando nao ha nao lidas (app.js esvazia o texto). */
.filtro-contador:empty { display: none; }

.sidebar {
  background: var(--panel);
  border-radius: 18px;
  box-shadow: var(--sombra-card);
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}

.sidebar-header {
  display: flex; align-items: center; gap: 12px;
  padding: 16px 16px 12px; background: var(--panel);
}

/* Logo no lugar do avatar vazio do cabecalho da lista. */
.brand-logo { width: 38px; height: 38px; object-fit: contain; flex: none; }

.brand { font-weight: 700; font-size: 17px; letter-spacing: -.02em; flex: 1; }

/* `flex: none` e o que impede a bolinha de deformar: num container flex ela
   e o unico item redondo, e sem isso o texto ao lado a comprime — a largura
   cede, a altura nao, e o circulo vira uma elipse. */
.conn-dot {
  width: 9px; height: 9px; border-radius: 50%;
  flex: none;
  background: #f04438;
  box-shadow: 0 0 0 3px rgba(240, 68, 56, .12);
}
/* Verde, e nao o roxo da marca: aqui a cor informa um estado (conectado), e
   verde/vermelho se le sem legenda. */
.conn-dot.online { background: #12b76a; box-shadow: 0 0 0 3px rgba(18, 183, 106, .18); }

.avatar {
  width: 40px; height: 40px; border-radius: 50%;
  background: var(--border); flex-shrink: 0;
  background-size: cover; background-position: center;
  /* Centraliza as iniciais de quem nao tem foto. Vale sempre: com foto o
     elemento fica vazio, e o flex nao muda nada. */
  display: flex; align-items: center; justify-content: center;
  font-size: 14.5px; font-weight: 600; letter-spacing: .3px;
  user-select: none; overflow: hidden;
}

/* Avatar sem foto: iniciais sobre um pastel.

   A cor sai de `--tom` (0..15), que o JS deriva do ID do chat — estavel, para
   o contato nao mudar de cor a cada redesenho da lista.

   O matiz e `--tom * 22.5deg`, cobrindo o circulo inteiro em 16 passos. O
   fundo e claro (94% de luz, 62% de saturacao) e o texto e o MESMO matiz bem
   escuro (32%): assim cada avatar e monocromatico e o contraste do texto nao
   depende de qual tom saiu — um par fixo de cores falharia em alguns matizes. */
.avatar.sem-foto {
  background-color: hsl(calc(var(--tom, 0) * 22.5deg) 62% 94%);
  color: hsl(calc(var(--tom, 0) * 22.5deg) 42% 32%);
}

/* Sem foto E sem nome: nao ha inicial que sirva (o id e um telefone, e "55"
   nao diz nada). Um contorno de pessoa em SVG no lugar, no mesmo tom. */
.avatar.sem-foto:empty::after,
.avatar.sem-foto.grupo::after {
  content: '';
  width: 58%; height: 58%;
  background: currentColor;
  opacity: .55;
  -webkit-mask: var(--icone-pessoa) center / contain no-repeat;
          mask: var(--icone-pessoa) center / contain no-repeat;
}
.avatar.sem-foto.grupo::after { --icone-pessoa: var(--icone-grupo); }

.search-bar { padding: 4px 14px 10px; background: var(--panel); }

.search-bar input {
  width: 100%; padding: 10px 14px; border-radius: 10px;
  border: 1px solid transparent; background: var(--panel-2);
  color: var(--text); font-size: 14px;
  transition: background 120ms, border-color 120ms;
}
.search-bar input::placeholder { color: var(--text-dim); }
.search-bar input:focus {
  outline: none; background: var(--panel);
  border-color: var(--border);
  box-shadow: var(--sombra-sutil);
}

.chat-list { list-style: none; overflow-y: auto; flex: 1; padding: 0 8px 8px; }

/* Sem divisorias entre os itens: a separacao e feita pelo espaco em branco e
   pelo cartao arredondado do item ativo, como no mockup. */
.chat-item {
  display: flex; align-items: center; gap: 12px;
  padding: 10px;
  cursor: pointer;
  border-radius: 12px;
  transition: background 120ms;
}
.chat-item:hover  { background: var(--panel-2); }
.chat-item.active { background: var(--accent-soft); }

.chat-item .info { flex: 1; min-width: 0; }
.chat-item .name { font-size: 14.5px; font-weight: 600; margin-bottom: 2px; }

/* Nome longo corta com reticencias, como a previa ja fazia. */
.chat-item .name {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* Contato FORA da agenda do WhatsApp pareado. O nome exibido ali e o que a
   pessoa escolheu no perfil dela — ninguem da empresa o conferiu —, entao o
   italico e o cinza o distinguem sem gritar na tela.

   O cinza fica entre o texto normal (#181820) e o esmaecido da previa
   (--text-dim, #8f8fa3): mais claro que o preto para dizer "nao confirmado",
   mais escuro que a previa porque continua sendo o titulo da linha. E um pouco
   menos encorpado, que ajuda a diferenciar sem depender so da cor — quem nao
   distingue bem cinza de preto ainda ve o italico. */
.chat-item .name.nao-salvo {
  color: #6b6b80;
  font-style: italic;
  font-weight: 500;
}

/* Contato SALVO: o nome em verde escuro. Marca os dois lados, para o estado
   nao depender de notar a AUSENCIA do italico.

   O tom e escuro e dessaturado de proposito: um verde vivo puxaria o olho para
   a maioria das linhas e brigaria com o roxo da marca. Assim ele se le como
   "tom", nao como destaque — e o contraste sobre o branco continua alto
   (bem acima de 4.5:1), entao nao ha perda de legibilidade. */
.chat-item .name.salvo {
  color: #1e2b19;
}

.chat-item .preview {
  font-size: 13px; color: var(--text-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* Coluna da direita: hora em cima, badge de nao lidas embaixo, alinhadas a
   direita — sem isso o badge encosta na hora. */
.chat-item .meta {
  display: flex; flex-direction: column; align-items: flex-end; gap: 4px;
  text-align: right; font-size: 11px; color: var(--text-dim);
  flex-shrink: 0;
}

/* Relogio de espera, na coluna da direita sob a hora. So aparece com o toggle
   do trilho ligado — a maioria das conversas do dia esta respondida, e uma
   marca em toda linha viraria ruido para quem nao esta cobrando prazo.

   Fica na `meta` e nao ao lado do nome de proposito: e informacao temporal, da
   mesma familia da hora, e ao lado do nome disputaria o espaco que ja e o
   primeiro a faltar quando a barra encolhe. */
.chat-item .sla {
  display: inline-flex; align-items: center; gap: 3px;
  padding: 1px 6px;
  border-radius: 999px;
  font-size: 10.5px; font-weight: 700; line-height: 16px;
  white-space: nowrap;
  /* Verde ate 15min, amarelo ate 1h, vermelho depois. Os tres tons sao
     escuros sobre fundo lavado: um verde/vermelho chapado brigaria com o
     badge de nao lidas, que e o outro elemento colorido da mesma coluna. */
  background: #e6f4ea; color: #1a7f37;
}
.chat-item .sla.atencao { background: #fef3c7; color: #92400e; }
.chat-item .sla.atrasado { background: #fee4e2; color: #b42318; }

/* O ponto do selo pulsa so no vermelho: um indicador animado em toda linha
   cansaria, mas no estado que exige acao ele e o que puxa o olho na varredura
   da lista. */
.chat-item .sla-ponto {
  width: 5px; height: 5px; border-radius: 50%;
  background: currentColor; flex: none;
}
.chat-item .sla.atrasado .sla-ponto { animation: sla-pulsa 1.6s ease-in-out infinite; }
@keyframes sla-pulsa { 50% { opacity: .25; } }

/* Quem reduz o movimento nao ganha um ponto piscando; a cor ja diz o estado. */
@media (prefers-reduced-motion: reduce) {
  .chat-item .sla.atrasado .sla-ponto { animation: none; }
}

/* Sidebar compacta (<= 240px): a hora nao cabe ao lado do
   nome e quebrava a linha, empurrando o layout do item. Some primeiro; o badge
   de nao lidas fica, porque e a informacao que nao pode se perder. */
.layout.sidebar-compacta .chat-item .hora { display: none; }
.layout.sidebar-compacta .chat-item .meta { gap: 2px; }
/* O selo fica mesmo na compacta: quem ligou o toggle pediu justamente por ele,
   e some junto com o resto da `meta` na estreita, onde so sobra o avatar. */

/* Sidebar estreita: sobra so o avatar. Esconder o texto evita que ele
   quebre em varias linhas e empurre a foto para fora. */
.layout.sidebar-estreita .chat-item .info,
.layout.sidebar-estreita .chat-item .meta,
.layout.sidebar-estreita .search-bar,
.layout.sidebar-estreita .filtros,
.layout.sidebar-estreita .brand,
.layout.sidebar-estreita .user-nome { display: none; }

.layout.sidebar-estreita .chat-item { justify-content: center; padding: 10px 8px; }
.layout.sidebar-estreita .sidebar-header { justify-content: center; padding: 16px 8px; }

.badge {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 18px; padding: 0 6px;
  background: var(--accent); color: #fff;
  border-radius: 999px; font-size: 11px; font-weight: 700;
}

/* ---------- conversa ---------- */

.chat-panel {
  display: flex; flex-direction: column; min-height: 0;
  background: var(--panel);
  border-radius: 18px;
  box-shadow: var(--sombra-card);
  overflow: hidden;
}

.empty-state {
  flex: 1; display: grid; place-content: center; text-align: center;
}
/* Sem titulo: a marca aqui e so o logo. */
.empty-state .empty-logo { width: 84px; height: 84px; object-fit: contain; margin: 0 auto 14px; }
.empty-state p  { color: var(--text-dim); font-size: 14px; }

/* Altura 100% do painel (nao 100vh): o painel agora tem padding em volta. */
/* `relative` ancora a .tela-cofre, que e absolute e cobriria a pagina
   inteira sem um pai posicionado. */
.conversation { display: flex; flex-direction: column; height: 100%; min-height: 0;
                position: relative; }

.chat-header {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 20px; background: var(--panel);
  border-bottom: 1px solid var(--border);
}
.chat-title strong { font-size: 15.5px; font-weight: 600; letter-spacing: -.01em; }
.chat-title small { display: block; color: var(--text-dim); font-size: 12px; }

.messages {
  flex: 1; overflow-y: auto; padding: 24px 8%;
  display: flex; flex-direction: column; gap: 6px;
  background: var(--panel);
}

/* Separador de dia, no formato do WhatsApp: uma pilula centrada que abre cada
   data.

   O separador ocupa a LINHA INTEIRA (`align-self: stretch`) e centra a pilula
   por dentro, com `text-align`. Com `align-self: center` a caixa encolhia ate
   o tamanho do texto, e ai duas datas grudadas no topo do sticky ficavam lado
   a lado em vez de uma cobrir a outra — o empilhamento que aparecia como
   "20/08 ONTEM HOJE" numa linha so. Largura cheia, a pilula seguinte tapa a
   anterior, que e o comportamento do WhatsApp.

   O fundo tambem precisa ser opaco pelo mesmo motivo: uma pilula
   semitransparente deixaria a de baixo aparecer atraves dela.

   O `position: sticky` mantem a data do dia visivel no topo enquanto se rola
   dentro dele: e a pergunta que a pessoa faz ao rolar historico ("de quando e
   isto?"), e sem o sticky a resposta fica na pilula que ja subiu da tela. */
.separador-data {
  align-self: stretch;
  text-align: center;
  position: sticky; top: 0;
  z-index: 1;
  margin: 10px 0 4px;
  pointer-events: none;
}
.separador-data span {
  display: inline-block;
  padding: 5px 12px; border-radius: 999px;
  background: var(--bubble-in);
  color: var(--text-dim);
  font-size: 11.5px; font-weight: 600;
  text-transform: uppercase; letter-spacing: .04em;
}

/* Bolhas em pilula, como no mockup — sem sombra: o contraste com o branco do
   painel ja separa, e sombra em cada bolha sujaria a tela. */
.bubble {
  max-width: 62%; padding: 9px 14px; border-radius: 16px;
  font-size: 14px; line-height: 1.5; position: relative;
  word-wrap: break-word;
}
.bubble.in  { background: var(--bubble-in);  align-self: flex-start; }
.bubble.out { background: var(--bubble-out); align-self: flex-end; }

.bubble .time {
  font-size: 10.5px; color: var(--text-dim);
  float: right; margin: 6px 0 0 8px;
}

/* Tique de leitura: azul so quando a mensagem foi lida — e o unico sinal
   visivel de que o outro lado abriu a conversa. */
.bubble .time .tick { color: #adadc0; font-size: 11px; }
.bubble .time .tick-read { color: var(--accent); }

/* ---------- figurinha ---------- */

/* No WhatsApp a figurinha NAO tem balao: ela flutua sobre o fundo da conversa,
   com so o horario embaixo. Dentro do balao, a transparencia do webp ficava
   recortada contra a cor da bolha — o oposto do que a figurinha e. */
.bubble.figurinha {
  background: none;
  padding: 0;
  box-shadow: none;
  /* Encolhe ate a figurinha em vez de esticar ate o teto de 62%: sem isto
     sobrava uma faixa larga de nada ao lado dela (mesmo motivo da bolha de
     imagem). */
  width: max-content;
  max-width: 62%;
}

.sticker-img {
  /* 150px e o tamanho do WhatsApp; `max-width: 100%` deixa encolher em tela
     estreita, o que o antigo `style="max-width:150px"` inline nao permitia. */
  width: 150px; max-width: 100%;
  height: auto;
  display: block;
}

/* O horario sai de dentro do balao (que nao existe mais) e ganha o proprio
   fundo: sobre a foto de fundo da conversa, texto cinza claro sem contraste
   ficaria ilegivel. */
.bubble.figurinha .time {
  float: none;
  display: inline-flex; align-items: center;
  margin: 2px 0 0;
  padding: 1px 7px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .82);
}
/* Na enviada o horario alinha a direita, acompanhando o lado da bolha. */
.bubble.figurinha.out .time { float: right; }

/* Na figurinha nao ha balao nem padding, e o horario fica logo abaixo da
   imagem: as margens da regra geral fariam o selo COBRIR a hora, que foi
   exatamente o que aconteceu. Aqui ele so acompanha o horario, sem atravessar
   nada — nao ha borda de balao para cruzar. */
.bubble.figurinha .reacoes {
  margin: 2px 0 0;
}

/* ---------- menu de contexto da bolha ---------- */

/* Posicionado em coordenadas de TELA (`fixed`), nao dentro da conversa: a
   lista rola, e um menu absoluto dentro dela rolaria junto e apontaria para a
   bolha errada. Por isso o JS tambem fecha o menu ao rolar. */
.menu-msg {
  position: fixed; z-index: 130;
  background: #fff; border-radius: 12px;
  box-shadow: 0 8px 28px rgba(37, 34, 90, .22);
  padding: 5px;
}
.menu-msg.hidden { display: none; }

.menu-msg-emojis { display: flex; gap: 2px; }

.menu-msg-emoji {
  width: 34px; height: 34px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: 0; border-radius: 50%; cursor: pointer;
  background: transparent;
  font-family: var(--fonte-emoji); font-size: 19px;
  line-height: 1;
  transition: background 120ms, transform 120ms;
}
.menu-msg-emoji:hover { background: rgba(37, 34, 90, .07); transform: scale(1.18); }
.menu-msg-emoji:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/* O emoji que EU ja apliquei fica marcado: sem isso nao da para saber, olhando
   o menu, que um segundo clique vai REMOVER em vez de reagir de novo. */
.menu-msg-emoji.ativo { background: var(--bubble-out); }

/* ---------- reacoes (o emoji que gruda na bolha) ---------- */

/* A marca fica DENTRO do fluxo da bolha, no fim.
 *
 * A primeira versao a pendurava fora (`position: absolute; bottom: -12px`) para
 * nao mexer na altura da linha. Nao funcionou, e a razao demorou a aparecer:
 * `.messages` tem `overflow-y: auto`, e um container com overflow RECORTA o que
 * escapa das bordas — inclusive por baixo. O selo era criado, existia no DOM, e
 * simplesmente nao se via.
 *
 * No fluxo ele empurra a bolha alguns pixels, que era o efeito que a versao
 * absoluta tentava evitar. E o preco certo: uma marca visivel que desloca um
 * pouco vale mais que uma invisivel que nao desloca nada. O deslocamento
 * tambem e menor do que parecia, porque o selo divide a linha com o horario. */
.reacoes {
  display: flex; gap: 3px;
  /* Limpa o float do horario: sem isso o selo sobe e fica ao lado dele. */
  clear: both;

  /* O selo ATRAVESSA a borda de baixo: metade sobre a bolha, metade fora, como
     no WhatsApp.
     ` `
     A conta importa. A bolha tem `padding: 9px 14px`, entao uma margem negativa
     menor que 9px deixa o selo parado DENTRO do acolchoamento, com o fundo da
     bolha em volta — foi o primeiro erro. Precisa passar dos 9px para chegar a
     borda: com -18px ele cruza e sobra metade para fora.
     ` `
     O `margin-top: 4px` e o respiro do HORARIO. Sem ele o selo sobe e cobre a
     hora — o segundo erro, que apareceu na figurinha, onde nao ha padding para
     segurar.
     ` `
     Por que margem e nao `position: absolute`: o absolute foi a primeira
     tentativa e o selo sumia — `.messages` tem `overflow-y: auto`, e um
     container com overflow RECORTA o que escapa das bordas. Com margem o selo
     continua NO FLUXO (nao ha o que recortar) e ainda assim se sobrepoe. */
  margin-top: 4px;
  margin-bottom: -18px;
  /* Para os lados tambem: o padding lateral de 14px o afastaria da quina. */
  margin-left: -8px; margin-right: -8px;
  /* Na frente da bolha, nao atras dela. */
  position: relative; z-index: 1;
}

/* O recuo lateral: no WhatsApp o selo nao encosta na quina, fica um pouco para
   dentro. Do lado de quem falou — na recebida a partir da esquerda, na enviada
   terminando a direita. */
.bubble.in  .reacoes { justify-content: flex-start; padding-left: 2px; }
.bubble.out .reacoes { justify-content: flex-end;   padding-right: 2px; }

/* A bolha reagida precisa de folga embaixo: a margem negativa acima puxa o selo
   para cima da borda, e sem esta folga ele encostaria na bolha seguinte. So a
   reagida — dar a folga a todas afastaria a conversa inteira a toa. */
/* A folga que a margem negativa do selo consumiu: sem ela ele encostaria na
   bolha seguinte, porque o `gap: 6px` de `.messages` nao cobre os 18px. So a
   bolha reagida — dar a folga a todas afastaria a conversa inteira a toa. */
.bubble.com-reacao { margin-bottom: 16px; }
/* A figurinha nao usa margem negativa, entao nao precisa da folga extra. */
.bubble.figurinha.com-reacao { margin-bottom: 0; }

/* A pilula existe mesmo com uma reacao so: sem o fundo, o emoji sobre a foto de
   um album ou sobre a bolha clara fica ilegivel. A borda na cor do painel
   recorta o selo da bolha, como no WhatsApp. */
.reacao {
  display: inline-flex; align-items: center; gap: 2px;
  padding: 1px 6px; border-radius: 999px;
  background: var(--panel);
  border: 1.5px solid var(--panel);
  box-shadow: 0 1px 3px rgba(37, 34, 90, .18);
  font-size: 12px; line-height: 1.35;
}

/* A minha reacao ganha o fundo da bolha enviada: numa caixa compartilhada,
   "fui eu que reagi" e a primeira pergunta ao ver a marca. */
.reacao.minha { background: var(--bubble-out); }

/* A fonte de emoji, explicita: a pilula e pequena e o glifo do sistema
   destoaria do mesmo emoji desenhado na bolha ao lado (ver a secao "Emojis"). */
.reacao-emoji { font-family: var(--fonte-emoji); font-size: 12.5px; }
.reacao-n {
  font-size: 11px; color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}

/* O PNG do tique. Precisa desfazer o `display:block` de `.bubble img`, que
   vale para midia da mensagem e aqui jogaria o tique para a linha de baixo.
   A altura manda no tamanho e a largura segue a proporcao do arquivo (os
   PNGs sao largos: o duplo tique e quase o dobro do simples). */
.bubble .time .tick-img {
  display: inline-block;
  height: 11px;
  width: auto;
  max-width: none;
  border-radius: 0;
  margin-left: 3px;
  vertical-align: -1px;
}

/* Midia na bolha: limitada nos DOIS eixos.
   Antes so a largura era limitada (`max-width: 100%`), e uma foto vertical —
   o formato mais comum de quem manda do celular — esticava a bolha ate ocupar
   a conversa inteira: era preciso rolar a tela para ver a mensagem seguinte.

   `max-height` em vh e nao em px porque o que importa e quanto da JANELA a
   imagem toma; num monitor grande um teto fixo em pixels deixaria a foto
   pequena demais. `object-fit: contain` preserva a proporcao: sem ele a
   imagem seria esticada para caber na caixa.

   `width: auto` desfaz o esticamento horizontal que sobraria numa imagem
   baixa e larga depois do teto de altura. */
.bubble img, .bubble video {
  max-width: 100%;
  max-height: 42vh;
  width: auto;
  object-fit: contain;
  border-radius: 12px; display: block;
}

/* A imagem abre no visualizador; o cursor precisa dizer isso. */
.bubble img.abrivel { cursor: zoom-in; }

/* A bolha encolhe ate a largura da imagem em vez de esticar ate o teto de 62%.
   Sem isto uma foto vertical (estreita depois do limite de altura) deixava uma
   faixa larga de fundo vazio ao lado dela. `max-content` cabe porque o
   `max-width` da bolha continua limitando o outro extremo. */
.bubble:has(> img), .bubble:has(> video) { width: max-content; max-width: 62%; }
/* ---------- album (varias midias enviadas de uma vez) ---------- */

/* A bolha do album nao tem o `width: max-content` das bolhas de midia: a grade
   tem largura propria e precisa de espaco para as colunas. */
/* O padding e pequeno para a grade quase encostar na borda da bolha, como no
   WhatsApp. Quem precisa de respiro e o TEXTO, e ele o pede por conta propria
   (ver `.bubble.album .wa-texto` abaixo) — dar padding lateral aqui afastaria
   as fotos das bordas e a bolha viraria uma moldura grossa em volta delas. */
.bubble.album { width: auto; max-width: 62%; padding: 4px; }

/* Rodape do album: legenda e horario na MESMA caixa.
   Sem isto os dois herdavam o padding de 4px da bolha (colados na borda) e
   ficavam em linhas separadas, deixando um vazio ao lado de uma legenda curta.
   Aqui o texto envolve o horario, como na bolha comum. */
.bubble.album .album-rodape {
  padding: 5px 10px 1px;
  /* Contem o float do horario: sem isto ele escapa da caixa e o fundo da bolha
     nao acompanha a altura. */
  overflow: hidden;
}
/* Rodape sem legenda: so o horario, e o respiro de cima nao e preciso. */
.bubble.album .album-rodape:not(:has(.wa-texto)) { padding-top: 0; }

.bubble.album .album-rodape .wa-texto { line-height: 1.45; }
/* O `float` da bolha comum ja alinha o horario a direita; aqui so a margem de
   cima sai, porque o rodape ja tem o proprio respiro. */
.bubble.album .album-rodape .time { margin-top: 2px; }

.album-grade {
  display: grid;
  gap: 3px;
  border-radius: 12px;
  overflow: hidden;   /* o raio vale para as celulas das pontas */
  width: 300px; max-width: 100%;
}

/* Duas colunas a partir de 2 midias, como no WhatsApp. Com 3, a primeira ocupa
   a linha inteira: uma grade 2x2 com um buraco fica torta, e esticar a terceira
   preenche o mosaico sem cortar mais a foto. */
.album-grade.n2 { grid-template-columns: 1fr 1fr; }
.album-grade.n3 { grid-template-columns: 1fr 1fr; }
.album-grade.n3 > :first-child { grid-column: 1 / -1; }
.album-grade.n4 { grid-template-columns: 1fr 1fr; }

.album-item {
  position: relative; padding: 0; border: 0; overflow: hidden;
  background: rgba(37, 34, 90, .06);
  cursor: zoom-in; display: block;
  /* Quadrado: o mosaico so fica alinhado se as celulas tiverem proporcao fixa,
     e `object-fit: cover` corta o excedente em vez de distorcer. A foto
     inteira continua a um clique de distancia, no visualizador. */
  aspect-ratio: 1;
}
/* A primeira do trio e larga: manter o quadrado ali deixaria a bolha altissima. */
.album-grade.n3 > :first-child { aspect-ratio: 2 / 1; }

.album-item img, .album-item video {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  /* Desfaz os limites da midia solta na bolha: aqui quem manda e a celula. */
  max-width: none; max-height: none; border-radius: 0;
}
.album-item:hover img, .album-item:hover video { filter: brightness(.92); }
.album-item:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/* "+N" sobre a ultima celula quando ha mais midias do que cabem. */
.album-mais {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  background: rgba(12, 12, 18, .55);
  color: #fff; font-size: 22px; font-weight: 600;
  letter-spacing: -.02em;
}

/* Cartaz de video: um triangulo de play no centro da celula. */
.album-item.video::after {
  content: ''; position: absolute; top: 50%; left: 50%;
  width: 34px; height: 34px; margin: -17px 0 0 -17px;
  border-radius: 50%;
  background: rgba(12, 12, 18, .55);
  /* O triangulo e a propria mascara: evita mais um elemento no DOM por celula. */
  -webkit-mask: none; mask: none;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .25);
}
.album-item.video::before {
  content: ''; position: absolute; top: 50%; left: 50%; z-index: 1;
  margin: -6px 0 0 -3px;
  border-style: solid; border-width: 6px 0 6px 10px;
  border-color: transparent transparent transparent #fff;
}

/* ---------- visualizador de imagem ---------- */

/* Fundo bem mais escuro que o dos modais comuns (.modal usa 38% de opacidade):
   aqui o conteudo e a propria imagem, e o escuro serve para a foto ser a unica
   coisa visivel — nao so para indicar que ha um dialogo aberto. */
.visor {
  position: fixed; inset: 0; z-index: 120;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 14px;
  /* O recuo lateral abre a faixa onde as setas do album ficam (elas sao
     absolutas): com os 24px de antes, numa janela estreita a foto passava por
     baixo delas e a seta ficava sobre a imagem. */
  padding: 40px 76px;
  background: rgba(12, 12, 18, .92);
  animation: visor-entra 140ms ease-out;
}
.visor.hidden { display: none; }

@keyframes visor-entra { from { opacity: 0; } to { opacity: 1; } }

/* A imagem cabe na janela inteira, nos dois eixos. `min-height: 0` porque ela
   e item de um flex column: sem isso o item nao encolhe abaixo do tamanho
   natural e uma foto muito alta estouraria a tela, voltando o problema que o
   visor existe para resolver. */
.visor-img {
  max-width: 100%; max-height: 100%; min-height: 0;
  object-fit: contain;
  border-radius: 8px;
  box-shadow: 0 18px 60px rgba(0, 0, 0, .5);
}

.visor-legenda {
  flex: none; max-width: 720px; text-align: center;
  color: #e9e9f2; font-size: 13.5px; line-height: 1.55;
}
.visor-legenda.hidden { display: none; }

.visor-fechar {
  position: absolute; top: 16px; right: 18px;
  width: 40px; height: 40px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: 0; border-radius: 50%; cursor: pointer;
  background: rgba(255, 255, 255, .12); color: #fff;
  transition: background 120ms;
}
.visor-fechar:hover { background: rgba(255, 255, 255, .22); }
.visor-fechar:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.visor-fechar svg { width: 20px; height: 20px; display: block; }

/* As setas do album. Ficam ABSOLUTAS sobre o overlay, e nao como itens do flex,
   para nao disputarem largura com a midia: no flex elas encolheriam a foto em
   ~100px so por existirem, e a foto mudaria de tamanho ao passar de um album
   para uma imagem solta. */
.visor-seta {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 44px; height: 44px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: 0; border-radius: 50%; cursor: pointer;
  background: rgba(255, 255, 255, .12); color: #fff;
  transition: background 120ms;
}
.visor-seta.antes { left: 18px; }
.visor-seta.depois { right: 18px; }
.visor-seta:hover { background: rgba(255, 255, 255, .22); }
.visor-seta:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.visor-seta svg { width: 26px; height: 26px; display: block; }
.visor-seta.hidden { display: none; }

/* "2 / 5". No alto e a esquerda: em cima da midia atrapalharia a leitura, e a
   direita esbarraria no botao de fechar. */
.visor-contador {
  position: absolute; top: 22px; left: 22px;
  color: #d6d6e4; font-size: 13px; font-variant-numeric: tabular-nums;
}
.visor-contador.hidden { display: none; }

/* O video do visor. `.visor-img` ja o dimensiona; aqui so o `hidden`, que
   precisa vencer o `display` que aquela regra nao define mas o elemento tem. */
.visor-img.hidden { display: none; }

/* Trava a rolagem do fundo enquanto o visor esta aberto. */
body.sem-rolagem { overflow: hidden; }

/* ---------- player de audio ----------

   O <audio> fica escondido: ele so toca, quem desenha e o player proprio
   (public/js/audio.js). `display:none` nao serve — o Safari trata o elemento
   escondido assim de forma inconsistente; `position:absolute` fora da vista
   mantem o elemento vivo. */
.bubble audio { position: absolute; width: 0; height: 0; opacity: 0; pointer-events: none; }

.audio-player {
  display: flex; align-items: center; gap: 10px;
  min-width: 250px; max-width: 300px; padding: 2px 0;
}

.audio-player .ap-btn {
  flex: none; width: 36px; height: 36px; border: 0; border-radius: 50%;
  background: var(--accent); color: #fff; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: background .15s, transform .1s;
}
.audio-player .ap-btn:hover  { background: var(--marca-escuro); }
.audio-player .ap-btn:active { transform: scale(.94); }
.audio-player .ap-btn svg { width: 18px; height: 18px; display: block; }

.audio-player .ap-centro { flex: 1; min-width: 0; }

/* A onda. `align-items: center` deixa cada barra crescer para os dois lados a
   partir do meio, como no WhatsApp — alinhadas na base pareceria um grafico. */
.audio-player .ap-onda {
  display: flex; align-items: center; gap: 2px;
  height: 30px; cursor: pointer; touch-action: none;
}
.audio-player .ap-onda:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 4px; }
.audio-player .ap-onda span {
  flex: 1; min-width: 2px; border-radius: 2px;
  background: #c7c7d6;
  transition: height .25s ease, background .1s;
}
/* Barra ja tocada: o preenchimento e a barra de progresso. */
.audio-player .ap-onda span.tocada { background: var(--accent); }
.bubble.out .audio-player .ap-onda span { background: #b9b7ea; }

.audio-player .ap-rodape {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px; margin-top: 2px;
}
.audio-player .ap-tempo {
  font-size: 11px; color: var(--text-dim); font-variant-numeric: tabular-nums;
}

/* O botao de velocidade so aparece como pilula clicavel; discreto em repouso
   para nao competir com o play. */
.audio-player .ap-vel {
  border: 0; cursor: pointer; padding: 1px 7px; border-radius: 10px;
  font: inherit; font-size: 10.5px; font-weight: 600; line-height: 1.6;
  color: var(--text-dim); background: rgba(37, 34, 90, .07);
  font-variant-numeric: tabular-nums;
}
.audio-player .ap-vel:hover { background: rgba(37, 34, 90, .13); color: var(--text); }

/* Microfone: so na mensagem de voz, como no WhatsApp. */
.audio-player .ap-mic {
  flex: none; width: 26px; height: 26px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: rgba(37, 34, 90, .07); color: var(--text-dim);
}
.audio-player .ap-mic svg { width: 14px; height: 14px; display: block; }
.audio-player.tocando .ap-mic { color: var(--accent); }

.bubble .doc {
  display: flex; align-items: center; gap: 10px;
  background: rgba(37, 34, 90, .05); padding: 10px; border-radius: 10px;
  color: var(--text); text-decoration: none;
}

/* ---------- seletor de emoji ---------- */

/* O painel e posicionado em relacao a este wrap, e nao ao composer: assim ele
   abre alinhado ao botao, onde quer que o botao esteja na barra. */
.emoji-wrap { position: relative; display: flex; }

.emoji-painel {
  position: absolute;
  bottom: calc(100% + 10px); left: 0;
  width: 330px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: var(--sombra-card);
  overflow: hidden;
  z-index: 30;
  display: flex; flex-direction: column;
}

.emoji-abas {
  display: flex; gap: 2px;
  padding: 6px 6px 0;
  border-bottom: 1px solid var(--border);
  background: var(--panel-2);
  overflow-x: auto;
  scrollbar-width: none;
}
.emoji-abas::-webkit-scrollbar { display: none; }

.emoji-aba {
  flex: none; border: 0; background: transparent; cursor: pointer;
  padding: 6px 9px 7px; border-radius: 8px 8px 0 0;
  font-size: 17px; line-height: 1;
  opacity: .55;
  transition: opacity 120ms, background 120ms;
}
.emoji-aba:hover { opacity: 1; background: rgba(37, 34, 90, .05); }
/* A aba ativa e opaca e ganha o fundo do painel, para parecer contigua com a
   grade abaixo — a barra tem fundo proprio. */
.emoji-aba.ativa { opacity: 1; background: var(--panel); }

/* Sete colunas cabem em 330px com folga; a altura fixa segura o painel do
   mesmo tamanho em todas as abas, senao ele pularia ao trocar de grupo. */
.emoji-grade {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
  padding: 8px;
  height: 240px;
  overflow-y: auto;
  overscroll-behavior: contain;   /* rolar ate o fim nao rola a conversa atras */
}

.emoji-item {
  border: 0; background: transparent; cursor: pointer;
  aspect-ratio: 1; padding: 0; border-radius: 8px;
  font-size: 24px; line-height: 1;
  display: flex; align-items: center; justify-content: center;
  transition: background 100ms, transform 100ms;
}
.emoji-item:hover { background: var(--accent-soft); transform: scale(1.15); }
.emoji-item:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

.emoji-vazio {
  grid-column: 1 / -1;
  color: var(--text-dim); font-size: 12.5px; text-align: center;
  padding: 28px 16px; line-height: 1.6;
}

/* ---------- composer ---------- */

.composer {
  display: flex; align-items: flex-end; gap: 6px;
  padding: 12px 16px; background: var(--panel);
  border-top: 1px solid var(--border);
  /* Ancora as sugestoes das respostas rapidas, que sobem por cima da conversa.
     Presas ao <body> elas ficariam no lugar errado quando o campo cresce com o
     texto — e o composer e justamente quem cresce. */
  position: relative;
}

.composer textarea {
  flex: 1; resize: none; max-height: 120px;
  padding: 11px 16px; border-radius: 14px;
  border: 1px solid transparent;
  background: var(--panel-2); color: var(--text);
  font-family: inherit; font-size: 14px; line-height: 1.4;
  transition: background 120ms, border-color 120ms;
}
.composer textarea::placeholder { color: var(--text-dim); }
.composer textarea:focus {
  outline: none; background: var(--panel);
  border-color: var(--border);
  box-shadow: var(--sombra-sutil);
}

/* `inline-flex` centrado, e nao o padrao inline: um filho inline (glifo ou
   <svg>) assenta na LINHA DE BASE do texto, que fica abaixo do centro do
   botao — era o que deixava o clipe mais baixo que os icones vizinhos. Com o
   flex o alinhamento nao depende mais da metrica da fonte.

   As medidas fixas fazem os tres botoes da barra terem o mesmo alvo de clique:
   com padding sozinho, cada um herdava a largura do proprio conteudo. */
.icon-btn {
  background: transparent; border: 0; color: var(--text-dim);
  font-size: 18px; cursor: pointer; padding: 0;
  width: 38px; height: 38px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%; line-height: 1;
  transition: background 120ms, color 120ms;
}
/* Sem isto o SVG mantem o espaco extra de descida da linha de texto. */
.icon-btn svg { display: block; }
.icon-btn:hover { background: var(--panel-2); color: var(--text); }

/* O enviar e o unico botao solido da tela — e a acao principal. O tamanho e a
   centralizacao ja vem de .icon-btn; aqui so o que o distingue. */
.icon-btn.send {
  background: var(--accent); color: #fff;
  box-shadow: var(--sombra-sutil);
}
.icon-btn.send:hover { background: var(--marca-escuro); color: #fff; }

/* O botao de acao troca de icone conforme o estado do composer. Quem manda e
   a classe no <footer>, nao o JS mexendo em style de cada svg: assim os tres
   estados (vazio, digitando, gravando) sao um seletor cada, e nao ha combinacao
   possivel em que os dois icones aparecam juntos. */
.icon-btn.send .ico-seta { display: none; }
.composer.digitando .icon-btn.send .ico-mic,
.composer.gravando  .icon-btn.send .ico-mic { display: none; }
.composer.digitando .icon-btn.send .ico-seta,
.composer.gravando  .icon-btn.send .ico-seta { display: block; }

/* Gravando: o vermelho vai no cancelar, nao no enviar — o enviar continua
   sendo a acao principal e mantem a cor da marca. */
.icon-btn.cancelar {
  width: 38px; height: 38px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  color: #f04438;
}
.icon-btn.cancelar:hover { background: rgba(240, 68, 56, .12); color: #f04438; }
/* Encostada nas ondas: o gap padrao do composer deixaria a lixeira solta no
   meio da faixa, longe do painel a que ela pertence. */
.composer.gravando .icon-btn.cancelar { margin-right: -2px; }

/* Enquanto grava, o painel de ondas toma o lugar do campo de texto: digitar no
   meio de um audio nao leva a lugar nenhum, e esconder o textarea (em vez de so
   opaca-lo) deixa as ondas ocuparem a largura inteira do composer. */
.composer.gravando textarea { display: none; }

.ondas {
  flex: 1; display: flex; align-items: center; gap: 10px;
  min-width: 0; height: 42px;
  padding: 0 14px; border-radius: 14px;
  background: var(--panel-2);
}

/* Tabular para o contador nao empurrar as barras a cada segundo. */
.ondas-tempo {
  flex: none; font-size: 13px; color: #f04438;
  font-variant-numeric: tabular-nums;
}
.ondas-tempo::before {
  content: ''; display: inline-block; vertical-align: middle;
  width: 8px; height: 8px; margin-right: 7px; border-radius: 50%;
  background: #f04438;
  animation: pulso-gravacao 1.1s ease-in-out infinite;
}

/* As barras crescem do centro para os dois lados, como no WhatsApp. O overflow
   escondido corta as mais antigas quando a fila passa da largura, em vez de
   espremer todas. */
.ondas-barras {
  flex: 1; min-width: 0; height: 24px; overflow: hidden;
  display: flex; align-items: center; justify-content: flex-end; gap: 3px;
}
/* Barras mais largas e espacadas do que a fila rapida pedia: com uma nascendo
   a cada ~110ms, a onda anda devagar e sobra largura para cada uma. */
.ondas-barras i {
  flex: none; width: 4px; min-height: 3px; border-radius: 2px;
  background: var(--accent); opacity: .75;
  transform-origin: center;
  /* A barra entra com a altura que ja tem; a transicao suaviza o passo
     discreto de uma barra a cada 110ms. */
  transition: height 110ms linear;
}

@keyframes pulso-gravacao {
  0%, 100% { opacity: 1; }
  50%      { opacity: .25; }
}

::-webkit-scrollbar { width: 8px; }
::-webkit-scrollbar-thumb { background: #e4e4ee; border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: #d6d6e4; }

/* ---------------- autenticacao ---------------- */

.auth-form { display: flex; flex-direction: column; gap: 14px; text-align: left; }
.auth-sub { color: var(--text-dim); font-size: 14px; margin: 0 0 4px; text-align: center; }

.field { display: flex; flex-direction: column; gap: 6px; }
.field span { font-size: 13px; color: var(--text-dim); font-weight: 500; }
.field input {
  padding: 11px 13px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--panel-2);
  color: var(--text);
  font-size: 15px;
  outline: none;
  transition: border-color 120ms, background 120ms;
}
.field input:focus { border-color: var(--accent); background: var(--panel); }

.auth-error {
  margin: 0;
  padding: 10px 12px;
  border-radius: 10px;
  background: #fef3f2;
  color: #b42318;
  font-size: 14px;
  border: 1px solid #fee4e2;
}

.auth-hint { margin: 0; font-size: 12px; color: var(--text-dim); line-height: 1.5; }

.user-nome {
  margin-left: auto;
  font-size: 12px;
  color: var(--text-dim);
  /* Encolhe antes de estourar a barra, e o excesso vira reticencias — um nome
     longo nao pode empurrar a bolinha de status para fora. */
  min-width: 0;
  max-width: 140px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Presenca do chat ("digitando…" / "gravando áudio…"). Verde e italico para
   se distinguir da previa da ultima mensagem, que ocupa o mesmo lugar. */
.chat-item .preview.presence,
.chat-header .presence,
#chat-phone.presence {
  color: var(--accent);
  font-style: italic;
}

/* Mensagem de tipo nao reconhecido: e um aviso do sistema, nao texto que
   alguem escreveu — o visual precisa deixar isso obvio. */
.bubble .unsupported {
  display: inline-block;
  font-size: 13px; font-style: italic;
  color: var(--text-dim);
  border-left: 3px solid #f79009;
  padding-left: 8px;
}

/* Autor da mensagem em grupo. Sem isso as bolhas do grupo ficam anonimas. */
.bubble .author {
  display: block;
  font-size: 12px; font-weight: 600;
  color: var(--accent);
  margin-bottom: 2px;
}

/* Falha de envio: vermelho, para nao passar por mensagem entregue. */
.bubble .time .tick-failed { color: #f04438; font-weight: 700; }

/* Estrela de favorita: discreta ate o hover, para nao competir com o nome
   da conversa. Sempre visivel quando ja esta marcada. */
.chat-item .estrela {
  border: 0; background: none; cursor: pointer;
  font-size: 15px; line-height: 1;
  color: #cbcbdc;
  padding: 2px 4px;
  opacity: 0;
  transition: opacity 120ms, color 120ms;
}
.chat-item:hover .estrela { opacity: 1; }
.chat-item .estrela.marcada { opacity: 1; color: #f79009; }
.chat-item .estrela:hover { color: #f79009; }

/* Na barra estreita nao ha espaco para a estrela. */
.layout.sidebar-estreita .chat-item .estrela { display: none; }

/* ---------- tags ---------- */

/* Os chips de tag entram na mesma linha dos filtros fixos, sem caixa propria:
   um container com display:contents deixa o flex-wrap de .filtros governar os
   dois conjuntos juntos. Com display:flex, os chips virariam um unico item e
   nao quebrariam linha junto com "Tudo" e "Nao lidas". */
.filtros-tags { display: contents; }

/* A cor da tag entra por --cor-tag (definida inline por app.js): o chip fica
   discreto em repouso e assume a cor quando selecionado. Pintar sempre com a
   cor cheia faria a barra de filtros competir com a lista. */
.filtro-tag { position: relative; padding-left: 20px; }
.filtro-tag::before {
  content: '';
  position: absolute; left: 9px; top: 50%;
  width: 7px; height: 7px; margin-top: -3.5px;
  border-radius: 50%;
  background: var(--cor-tag, var(--text-dim));
}
.filtro-tag.ativo {
  background: color-mix(in srgb, var(--cor-tag) 16%, transparent);
  color: color-mix(in srgb, var(--cor-tag) 75%, #000);
}

/* O "+ Tag" nao e filtro: fica tracejado para nao parecer selecionavel. */
.filtro-gerenciar {
  background: none;
  border: 1px dashed var(--border);
  color: var(--text-dim);
}
.filtro-gerenciar:hover { background: var(--panel-2); color: var(--accent); }

/* Etiquetas na linha da conversa, abaixo da previa. */
.chat-tags {
  display: flex; gap: 4px; margin-top: 4px;
  overflow: hidden;
}
.chat-tag {
  font-size: 10.5px; font-weight: 600; line-height: 1;
  padding: 3px 7px; border-radius: 999px;
  white-space: nowrap;
  /* A ultima que nao couber e cortada em vez de empurrar a linha: a lista tem
     largura variavel e uma conversa com cinco tags quebraria o item. */
  overflow: hidden; text-overflow: ellipsis;
  max-width: 110px;
}

/* Botao de etiquetar: mesmo comportamento da estrela — discreto ate o hover,
   sempre visivel quando a conversa ja tem tag. */
.chat-item .btn-tag {
  border: 0; background: none; cursor: pointer;
  font-size: 13px; line-height: 1;
  color: #cbcbdc;
  padding: 2px 4px;
  opacity: 0;
  transition: opacity 120ms, color 120ms;
}
.chat-item:hover .btn-tag { opacity: 1; }
.chat-item .btn-tag.tem-tag { opacity: .75; }
.chat-item .btn-tag:hover { color: var(--accent); opacity: 1; }

/* Na barra estreita nao ha espaco, como na estrela. */
.layout.sidebar-estreita .chat-item .btn-tag,
.layout.sidebar-estreita .chat-tags { display: none; }

/* ---------- respostas rapidas ---------- */

/* Sobe a partir do topo do composer, como o autocomplete do WhatsApp Web. O
   `bottom: 100%` a mantem colada nele mesmo quando o campo cresce para varias
   linhas — com uma altura fixa, a lista cobriria o proprio campo. */
.sugestoes {
  position: absolute; z-index: 40;
  left: 16px; right: 16px; bottom: 100%;
  margin-bottom: 8px;
  max-height: 260px; overflow-y: auto;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: var(--sombra-card);
  padding: 6px;
}
.sugestoes.hidden { display: none; }

.sugestao {
  display: flex; align-items: baseline; gap: 10px;
  width: 100%; border: 0; background: none; cursor: pointer;
  padding: 8px 10px; border-radius: 8px;
  font: inherit; font-size: 13px; color: var(--text); text-align: left;
}
/* `.ativa` e nao `:hover` sozinho: quem navega pelas setas precisa ver onde
   esta, e o mouse pode nem estar sobre a lista. */
.sugestao:hover, .sugestao.ativa { background: var(--panel-2); }

.sugestao-atalho {
  flex: none;
  font-weight: 700; color: var(--accent);
  font-variant-numeric: tabular-nums;
}

/* Uma linha so: o texto de uma resposta pode ter paragrafos, e mostrar tudo
   faria a lista virar uma parede antes de se escolher qualquer coisa. */
.sugestao-texto {
  flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--text-dim);
}

/* ---------- gerenciador das respostas rapidas ---------- */

.resposta-form { display: flex; flex-direction: column; gap: 10px; }

.resposta-linha { display: flex; align-items: center; gap: 8px; }

/* A barra fora do campo: ela e o gatilho da interface, nao parte do atalho.
   Dentro do input, alguem a digitaria junto e o cadastro viraria "//bomdia". */
.resposta-barra {
  font-size: 16px; font-weight: 700; color: var(--accent);
  padding-left: 2px;
}

.resposta-form input[type="text"],
.resposta-form textarea {
  border: 1px solid var(--border); border-radius: 10px;
  padding: 9px 12px; font-family: inherit; font-size: 14px;
  background: var(--panel-2); color: var(--text);
}
.resposta-form input[type="text"]:focus,
.resposta-form textarea:focus {
  outline: none; border-color: var(--accent); background: var(--panel);
}
.resposta-form textarea { resize: vertical; min-height: 68px; line-height: 1.45; }

/* O atalho e curto por natureza; o titulo leva o resto da linha. */
#resposta-atalho { width: 150px; flex: none; }
#resposta-titulo { flex: 1; min-width: 0; }

.resposta-acoes { display: flex; justify-content: flex-end; gap: 8px; }

.btn-secundario {
  background: var(--panel-2); color: var(--text);
  box-shadow: none;
}
.btn-secundario:hover { background: var(--border); }

.lista-respostas {
  list-style: none; margin: 16px 0 0; padding: 0;
  display: flex; flex-direction: column; gap: 2px;
}

.lista-resposta {
  display: flex; align-items: flex-start; gap: 9px;
  padding: 8px 6px; border-radius: 8px;
}
.lista-resposta:hover { background: var(--panel-2); }
/* Enquanto se edita, a linha correspondente fica marcada: sem isso o
   formulario preenchido nao diz qual das respostas ele esta alterando. */
.lista-resposta.editando { background: var(--panel-2); box-shadow: inset 2px 0 0 var(--accent); }

.lista-resposta-info { flex: 1; min-width: 0; }

.lista-resposta-topo {
  display: flex; align-items: baseline; gap: 8px;
  overflow: hidden;
}

.lista-resposta-atalho {
  flex: none; font-size: 13.5px; font-weight: 700; color: var(--accent);
}

.lista-resposta-titulo {
  font-size: 13px; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Duas linhas: o suficiente para reconhecer a resposta sem a lista virar uma
   parede de texto. */
.lista-resposta-corpo {
  margin: 2px 0 0;
  font-size: 12.5px; color: var(--text-dim); line-height: 1.4;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}

.lista-resposta-acao {
  flex: none;
  border: 0; background: none; cursor: pointer;
  font-size: 13px; color: var(--text-dim);
  padding: 3px 5px; border-radius: 6px;
  opacity: 0; transition: opacity 120ms;
}
.lista-resposta:hover .lista-resposta-acao { opacity: 1; }
.lista-resposta-acao:hover { color: var(--text); background: var(--panel); }
.lista-resposta-acao.excluir:hover { color: #d92d20; }

/* ---------- menu de tags de uma conversa ---------- */

/* Fica no <body>, posicionado em coordenadas de tela por app.js: dentro do
   item da lista, o overflow da barra o cortaria. */
.menu-tags {
  position: fixed; z-index: 60;
  min-width: 200px; max-height: 320px; overflow-y: auto;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: var(--sombra-card);
  padding: 6px;
}

.menu-tag-item {
  display: flex; align-items: center; gap: 8px;
  width: 100%; border: 0; background: none; cursor: pointer;
  padding: 7px 8px; border-radius: 8px;
  font-size: 13px; color: var(--text); text-align: left;
}
.menu-tag-item:hover { background: var(--panel-2); }
.menu-tag-item.marcada { font-weight: 600; }

.menu-tag-cor { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; }
.menu-tag-nome { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.menu-tag-check { color: var(--accent); font-weight: 700; }

.menu-tags-vazio {
  padding: 10px 8px; font-size: 12.5px; color: var(--text-dim);
}

.menu-tag-gerenciar {
  display: block; width: 100%;
  margin-top: 4px; padding: 7px 8px;
  border: 0; border-top: 1px solid var(--border); background: none;
  cursor: pointer; text-align: left;
  font-size: 12.5px; color: var(--accent); font-weight: 600;
  border-radius: 0 0 8px 8px;
}
.menu-tag-gerenciar:hover { background: var(--panel-2); }

/* ---------- gerenciador de tags ---------- */

.modal {
  position: fixed; inset: 0; z-index: 80;
  display: flex; align-items: center; justify-content: center;
  background: rgba(24, 24, 32, .38);
  padding: 20px;
}
.modal.hidden { display: none; }

.modal-caixa {
  width: 100%; max-width: 420px;
  max-height: 80vh; overflow-y: auto;
  background: var(--panel);
  border-radius: 18px;
  box-shadow: var(--sombra-card);
  padding: 18px 20px 20px;
}

.modal-cabecalho {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 6px;
}
.modal-cabecalho strong { font-size: 16px; }

.modal-fechar {
  border: 0; background: none; cursor: pointer;
  font-size: 22px; line-height: 1; color: var(--text-dim);
  padding: 0 4px;
}
.modal-fechar:hover { color: var(--text); }

.modal-ajuda {
  font-size: 12.5px; color: var(--text-dim);
  margin: 0 0 14px; line-height: 1.45;
}

.tag-form { display: flex; flex-direction: column; gap: 10px; }

.tag-form input[type="text"] {
  border: 1px solid var(--border); border-radius: 10px;
  padding: 9px 12px; font-size: 14px;
  background: var(--panel-2); color: var(--text);
}
.tag-form input[type="text"]:focus {
  outline: none; border-color: var(--accent); background: var(--panel);
}

.tag-cores { display: flex; gap: 8px; flex-wrap: wrap; }

.cor-opcao {
  width: 22px; height: 22px; border-radius: 50%;
  border: 2px solid transparent; cursor: pointer;
  padding: 0;
  /* O anel branco por dentro separa a borda de selecao da propria cor —
     sem ele, escolher a opcao cinza nao mostra diferenca nenhuma. */
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .5);
}
.cor-opcao.escolhida { border-color: var(--text); }

.tag-erro {
  margin: 10px 0 0; font-size: 12.5px; color: #d92d20;
}
.tag-erro.hidden { display: none; }

.lista-tags {
  list-style: none; margin: 16px 0 0; padding: 0;
  display: flex; flex-direction: column; gap: 2px;
}

.lista-tags-vazia {
  padding: 14px 4px; font-size: 13px; color: var(--text-dim); text-align: center;
}

.lista-tag {
  display: flex; align-items: center; gap: 9px;
  padding: 6px 4px; border-radius: 8px;
}
.lista-tag:hover { background: var(--panel-2); }

.lista-tag-cor { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; }

/* Input sem cara de input ate o foco: a lista precisa se ler como lista, mas
   o nome e editavel no lugar. */
.lista-tag-nome {
  flex: 1; min-width: 0;
  border: 1px solid transparent; border-radius: 6px;
  background: none; color: var(--text);
  font-size: 13.5px; font-weight: 500;
  padding: 4px 6px;
}
.lista-tag-nome:hover { border-color: var(--border); }
.lista-tag-nome:focus {
  outline: none; border-color: var(--accent); background: var(--panel);
}

.lista-tag-uso { font-size: 11.5px; color: var(--text-dim); white-space: nowrap; }

.lista-tag-excluir {
  border: 0; background: none; cursor: pointer;
  font-size: 13px; color: var(--text-dim);
  padding: 3px 5px; border-radius: 6px;
  opacity: 0; transition: opacity 120ms;
}
.lista-tag:hover .lista-tag-excluir { opacity: 1; }
.lista-tag-excluir:hover { color: #d92d20; background: var(--panel); }

/* ---------------- criptografia ---------------- */

/* Selo no cabecalho da conversa. Discreto de proposito: e uma garantia
   permanente, nao um alerta — um banner chamativo viraria ruido em uma semana.
   Vira ambar quando o cofre esta trancado, que ai sim e um estado que pede
   acao. */
.selo-cripto {
  margin-left: auto;
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid var(--border); background: var(--panel-2);
  color: var(--text-dim);
  font-size: 12px; font-family: inherit;
  padding: 5px 11px; border-radius: 999px;
  cursor: pointer; white-space: nowrap;
}
.selo-cripto:hover { color: var(--text); border-color: #dcdcea; }
.selo-cripto.hidden { display: none; }
.selo-cripto-icone { font-size: 11px; }

.selo-cripto.trancado {
  color: #9a6b00; border-color: #f0dcae; background: #fdf6e6;
}

/* Tela do cofre trancado. Cobre a area da conversa (nao o app inteiro): a
   lista de conversas continua util, e as mensagens seguem chegando. */
.tela-cofre {
  position: absolute; inset: 0; z-index: 60;
  display: flex; align-items: center; justify-content: center;
  background: rgba(246, 246, 249, .96);
  backdrop-filter: blur(3px);
  padding: 24px;
}
.tela-cofre.hidden { display: none; }

.cofre-caixa {
  width: 100%; max-width: 380px; text-align: center;
  background: var(--panel);
  border: 1px solid var(--border); border-radius: 18px;
  box-shadow: var(--sombra-card);
  padding: 30px 26px;
}
.cofre-icone { font-size: 30px; margin-bottom: 10px; }
.cofre-caixa h2 { font-size: 17px; margin: 0 0 8px; }

.cofre-sub {
  font-size: 13px; color: var(--text-dim);
  line-height: 1.55; margin: 0 0 18px;
}

.cofre-form { display: flex; flex-direction: column; gap: 9px; }
.cofre-form input {
  border: 1px solid var(--border); border-radius: 10px;
  padding: 11px 13px; font-size: 14px; font-family: inherit;
  background: var(--panel-2); color: var(--text);
}
.cofre-form input:focus {
  outline: none; border-color: var(--marca); background: var(--panel);
}

.cofre-erro {
  font-size: 12.5px; color: #c0392b; margin: 11px 0 0;
}
.cofre-erro.hidden { display: none; }

.cofre-nota {
  font-size: 11.5px; color: var(--text-dim);
  line-height: 1.5; margin: 18px 0 0;
  padding-top: 14px; border-top: 1px solid var(--border);
}

/* Bolha cujo conteudo esta cifrado e sem chave nesta sessao. Tracejada e
   apagada: precisa parecer um espaco reservado, nao uma mensagem real. */
.bubble.bloqueada {
  color: var(--text-dim); font-style: italic;
  border: 1px dashed var(--border); background: var(--panel-2);
}

/* Modal "como suas mensagens sao protegidas". */
.cripto-info { font-size: 13px; line-height: 1.6; }
.cripto-lista { margin: 10px 0 0; padding-left: 18px; }
.cripto-lista li { margin-bottom: 9px; color: var(--text); }
.cripto-lista b { font-weight: 600; }

/* O paragrafo do que NAO e coberto. Destacado de proposito: e a parte que
   impede o cliente de supor ponta-a-ponta, e esconde-la seria vender uma
   garantia que o sistema nao da. */
.cripto-honesto {
  margin: 16px 0 0; padding: 12px 14px;
  background: var(--panel-2); border: 1px solid var(--border);
  border-radius: 12px;
  font-size: 12.5px; color: var(--text-dim); line-height: 1.55;
}
.cripto-honesto b { color: var(--text); }

/* ---------------- painel de seguranca ---------------- */

.modal-caixa-larga { max-width: 500px; }

.seg-bloco { display: flex; flex-direction: column; gap: 14px; }

.seg-intro { font-size: 13.5px; color: var(--text-dim); line-height: 1.6; margin: 6px 0 0; }

/* Estado atual do cofre, no topo do painel. */
.seg-estado {
  display: flex; flex-direction: column; gap: 3px;
  padding: 13px 15px; border-radius: 11px;
  border: 1px solid var(--border); background: var(--panel-2);
}
.seg-estado strong { font-size: 13.5px; }
.seg-estado span { font-size: 12.5px; color: var(--text-dim); line-height: 1.5; }
.seg-estado.aberto strong { color: var(--marca); }
.seg-estado.trancado { background: #fdf6e6; border-color: #f0dcae; }
.seg-estado.trancado strong { color: #9a6b00; }

/* Aviso de consequencia irreversivel. Ambar, nao vermelho: nao e um erro, e
   uma condicao que o usuario precisa entender antes de seguir. */
.seg-aviso {
  font-size: 12.5px; line-height: 1.55; color: var(--text);
  background: #fdf6e6; border: 1px solid #f0dcae;
  border-radius: 11px; padding: 12px 14px;
}
.seg-aviso strong { color: #9a6b00; }

/* Cada operacao num <details>: o painel abre mostrando o estado, e quem quer
   trocar a frase abre a secao. Tres formularios sempre visiveis seriam um
   paredao de campos de senha. */
.seg-item {
  border: 1px solid var(--border); border-radius: 11px;
  background: var(--panel); overflow: hidden;
}
.seg-item > summary {
  cursor: pointer; padding: 12px 15px;
  font-size: 13.5px; font-weight: 500;
  list-style: none; user-select: none;
}
.seg-item > summary::-webkit-details-marker { display: none; }
.seg-item > summary::after {
  content: '+'; float: right; color: var(--text-dim); font-size: 15px; line-height: 1;
}
.seg-item[open] > summary::after { content: '−'; }
.seg-item > summary:hover { background: var(--panel-2); }
.seg-item[open] > summary { border-bottom: 1px solid var(--border); }

.seg-perigo > summary { color: #c0392b; }

.seg-form {
  display: flex; flex-direction: column; gap: 12px;
  padding: 15px;
}
.seg-form label { display: flex; flex-direction: column; gap: 5px; }
.seg-form label > span { font-size: 12.5px; font-weight: 500; }
.seg-form label > span em { color: var(--text-dim); font-weight: 400; font-style: normal; }
.seg-form label > small { font-size: 11.5px; color: var(--text-dim); line-height: 1.5; }

.seg-form input {
  border: 1px solid var(--border); border-radius: 9px;
  padding: 10px 12px; font-size: 13.5px; font-family: inherit;
  background: var(--panel-2); color: var(--text);
}
.seg-form input:focus {
  outline: none; border-color: var(--marca); background: var(--panel);
}

.seg-nota { font-size: 11.5px; color: var(--text-dim); line-height: 1.55; margin: 0; }

/* Mesma linha serve para erro e confirmacao: a mensagem aparece no mesmo
   lugar em que o olho ja esta, logo acima do botao. */
.seg-erro { font-size: 12.5px; color: #c0392b; margin: 0; }
.seg-erro.ok { color: var(--marca); }
.seg-erro.hidden { display: none; }

.btn-perigo { background: #c0392b; }
.btn-perigo:hover { background: #a93226; }

/* ---------------- formatacao do WhatsApp ---------------- */

/* O texto vira varios elementos (strong/em/ul/blockquote), entao o span
   precisa se comportar como bloco — senao a lista e a citacao ficariam na
   mesma linha do resto. */
.wa-texto { display: block; }

/* Mensagem que e SO emoji: grande, como no WhatsApp. O tamanho cai conforme a
   quantidade — um emoji sozinho e o maior, tres ja precisam caber lado a lado
   sem estourar a largura da bolha. */
.so-emoji { line-height: 1.15; }
.so-emoji-1 { font-size: 52px; }
.so-emoji-2 { font-size: 42px; }
.so-emoji-3 { font-size: 34px; }

/* Sem o fundo da pilula: com o emoji grande a bolha vira uma mancha de cor em
   volta da figura, e o WhatsApp tambem a remove. O padding menor evita o
   espaco vazio que sobraria em cima e embaixo. */
.bubble:has(.so-emoji) { background: transparent; padding: 2px 4px; }
/* O horario perderia contraste sobre o fundo branco do painel sem a pilula
   atras dele. */
.bubble:has(.so-emoji) .time { color: var(--text-dim); }

/* Espacamento entre blocos dentro da bolha: o primeiro e o ultimo colam nas
   bordas para nao criar um vao no topo/rodape da mensagem. */
.wa-texto > .wa-lista,
.wa-texto > .wa-citacao,
.wa-texto > .wa-bloco { margin: 6px 0; }
.wa-texto > :first-child { margin-top: 0; }
.wa-texto > :last-child  { margin-bottom: 0; }

.wa-lista { padding-left: 22px; margin: 6px 0; }
.wa-lista li { margin: 2px 0; }

/* Citacao com a barra a esquerda, como no WhatsApp. */
.wa-citacao {
  margin: 6px 0; padding: 2px 0 2px 10px;
  border-left: 3px solid var(--marca);
  color: var(--text-dim);
}

/* Codigo em linha e bloco de codigo. O fundo precisa funcionar sobre as DUAS
   bolhas (recebida cinza, enviada roxa), por isso um preto translucido em vez
   de uma cor fixa: ele escurece o que estiver atras, seja qual for. */
.wa-code,
.wa-mono {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: .92em;
  background: rgba(24, 24, 32, .06);
  padding: 1px 5px; border-radius: 5px;
}

.wa-bloco {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: .92em; line-height: 1.45;
  background: rgba(24, 24, 32, .06);
  padding: 9px 11px; border-radius: 9px;
  margin: 6px 0;
  /* Codigo longo rola dentro do proprio bloco: sem isso ele esticaria a bolha
     e, com ela, a largura da conversa inteira. */
  overflow-x: auto;
  white-space: pre;
}

/* Riscado e negrito herdam a cor da bolha; so o peso/decoracao muda. */
.bubble s { opacity: .7; }

/* Conflito de numero: o WhatsApp conectado nesta instancia ja esta pareado em
   outra. Fica no topo, acima de tudo, porque nesse estado o servidor recusa
   gravar — a tela inteira esta parada, e o motivo precisa aparecer. */
.conflito-numero {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  padding: 10px 16px;
  background: #b3261e;
  color: #fff;
  font-size: 14px;
  text-align: center;
}

/* ---------- arrastar arquivos e a previa de envio ---------- */

/* A sobreposicao do arrastar cobre a CONVERSA, nao a pagina: sem chat aberto
   nao ha destino, e soltar um arquivo ali nao teria para onde enviar. */
.drop-zona {
  position: absolute; inset: 0; z-index: 60;
  display: flex; align-items: center; justify-content: center;
  background: rgba(37, 34, 90, .72);
  /* Nao pode roubar os eventos de arrastar do container que os escuta: sem
     isto, `dragleave` dispara ao entrar na propria sobreposicao e ela pisca. */
  pointer-events: none;
}
.drop-zona.hidden { display: none; }

.drop-aviso {
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  padding: 28px 40px; border-radius: 16px;
  border: 2px dashed rgba(255, 255, 255, .55);
  color: #fff; text-align: center;
}
.drop-aviso strong { font-size: 17px; }
.drop-aviso span { font-size: 13px; opacity: .8; }

/* A conversa precisa ser o bloco de referencia da sobreposicao absoluta. */
.conversation { position: relative; }

.envio-caixa {
  width: 100%; max-width: 560px;
  display: flex; flex-direction: column; gap: 12px;
}

/* O palco: a midia selecionada, grande. A altura e limitada em `vh` pelo mesmo
   motivo da bolha — o que importa e quanto da JANELA ela ocupa. */
.envio-palco {
  display: flex; align-items: center; justify-content: center;
  min-height: 180px; max-height: 48vh;
  background: var(--panel); border-radius: 12px;
  overflow: hidden;
}
.envio-palco img, .envio-palco video {
  max-width: 100%; max-height: 48vh;
  object-fit: contain; display: block;
}

/* Audio e documento nao tem previa visual: o nome e o tamanho sao o que ajuda
   a decidir se e o arquivo certo. */
.envio-arquivo {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 24px; color: var(--text-dim); text-align: center;
}
.envio-arquivo strong {
  color: var(--text); font-size: 14px; font-weight: 600;
  word-break: break-all; max-width: 340px;
}
.envio-arquivo span { font-size: 12px; }

/* A fila so existe com dois ou mais arquivos — com um, ela nao acrescenta
   nada e so ocuparia espaco. */
.envio-fila { display: flex; gap: 6px; flex-wrap: wrap; }
.envio-fila.hidden { display: none; }

.envio-mini {
  position: relative;
  width: 52px; height: 52px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: 2px solid transparent; border-radius: 8px;
  background: var(--panel); color: var(--text-dim);
  cursor: pointer; overflow: hidden;
}
.envio-mini img, .envio-mini video {
  width: 100%; height: 100%; object-fit: cover; display: block;
}
.envio-mini.ativa { border-color: var(--accent); }

/* O X aparece no hover: sempre visivel, ele competiria com a miniatura, que e
   pequena demais para dividir espaco. */
.envio-mini-x {
  position: absolute; top: 1px; right: 2px;
  width: 16px; height: 16px; line-height: 15px;
  border-radius: 50%; font-size: 10px; text-align: center;
  background: rgba(24, 24, 32, .72); color: #fff;
  opacity: 0; transition: opacity 120ms;
}
.envio-mini:hover .envio-mini-x, .envio-mini:focus-within .envio-mini-x { opacity: 1; }

.envio-rodape { display: flex; align-items: center; gap: 8px; }

.envio-legenda {
  flex: 1; padding: 10px 14px;
  border: 1px solid var(--border); border-radius: 999px;
  font: inherit; font-size: 14px;
  background: var(--panel); color: var(--text);
}
.envio-legenda:focus { outline: 2px solid var(--accent); outline-offset: -1px; }
