/* ============================================================================
   GLAUDZAP — CAMADA MOBILE
   ----------------------------------------------------------------------------
   Este arquivo NÃO substitui nada: entra DEPOIS do style.css e só sobrescreve
   dentro de media queries. Em telas grandes ele é inerte, byte por byte — o
   painel de computador continua exatamente como está hoje.

   Vai junto com:
     • index.html — uma linha só, a meta viewport (ver §0.1)
     • mobile.js  — só o que CSS não resolve: altura real com teclado aberto

   Um breakpoint só: 760px. Os antigos (520/700/720) continuam válidos onde
   estão; ficam redundantes e podem ser recolhidos para cá numa faxina futura,
   mas mexer neles agora só somaria risco sem somar resultado.

   ⚠️ Toda transição aqui lista as propriedades uma a uma. `transition: .15s`
   vira `transition-property: all`, e aí o Chrome congela as cores derivadas de
   custom property no valor do primeiro paint — o tema escuro simplesmente não
   aplica naquele elemento. Já aconteceu neste projeto.
   ============================================================================ */

/* ============================================================================
   §0 — FUNDAÇÃO. Sem desenho novo, só o que faz o painel parar de brigar com
   o celular. Se você aprovar UMA coisa deste arquivo, que seja esta seção.
   ============================================================================ */

/* --- §0.1 ALTURA REAL DA TELA ------------------------------------------------
   `html, body { height: 100% }` resolve 100% do quê? Do viewport de LAYOUT, que
   no iOS Safari tem a altura da tela COM a barra de endereço escondida. Como ela
   começa visível, o painel nasce mais alto que o espaço visível e o composer
   fica abaixo da dobra — a pessoa abre a conversa e não acha onde digitar.

   `dvh` acompanha a barra de endereço. Mas não acompanha o TECLADO: no iOS o
   teclado sobe por cima sem encolher o layout. Por isso o `--vvh`, que o
   mobile.js alimenta a partir do visualViewport. A ordem importa — `dvh` é o
   piso decente para quem chegar antes do JS rodar. */
@media (max-width: 760px) {
  html, body {
    height: 100dvh;
    height: var(--vvh, 100dvh);
  }
}

/* --- §0.2 ZOOM AUTOMÁTICO DO SAFARI ------------------------------------------
   Campo com fonte menor que 16px = o iPhone dá zoom ao focar, e NÃO desfaz
   quando o campo perde o foco. Hoje todos estão abaixo: busca 14, composer
   14.5, modal 15, janela do admin 13.

   16px cravado, não 16.1 nem `1rem` — a regra do WebKit é o valor computado
   ser >= 16px, e `rem` depende do font-size do html, que pode mudar. */
@media (max-width: 760px) {
  #search-input,
  #composer-input,
  #admin-janela,
  .conv-campanha,
  #login-form input,
  .modal-body input,
  .modal-body select,
  .modal-body textarea,
  .crm-filtro select {
    font-size: 16px;
  }
}

/* --- §0.3 ÁREA SEGURA (entalhe e barra de gestos) ----------------------------
   Só funciona com `viewport-fit=cover` na meta viewport. Sem ele o iOS já
   encolhe a página sozinho e sobra uma faixa morta; com ele a página ocupa a
   tela toda e nós devolvemos o respiro onde importa.

   Em aparelho sem entalhe, todo env() vale 0px: não muda nada. */
@media (max-width: 760px) {
  #topbar {
    padding-left: max(16px, env(safe-area-inset-left));
    padding-right: max(16px, env(safe-area-inset-right));
  }

  /* A barra de navegação encosta no fundo: o padding é o que separa o ícone
     da barra de gestos do iPhone. */
  #nav-rail {
    padding-bottom: env(safe-area-inset-bottom);
  }

  /* O composer NÃO leva safe-area quando a barra inferior está embaixo dele
     (conversa aberta esconde a barra — ver §1.4), então aqui ele precisa. */
  body.mobile-chat-open #composer {
    padding-bottom: max(10px, env(safe-area-inset-bottom));
  }
}

/* --- §0.4 ALVO DE TOQUE -------------------------------------------------------
   O mínimo confortável é 44x44 (Apple) / 48x48 (Google). Hoje: ações do topo
   da sidebar ~34px, abas do admin ~38px, fechar modal ~28px. Não é questão de
   gosto: 28px é o tamanho em que o dedo erra e arquiva a conversa errada. */
@media (max-width: 760px) {
  .sidebar-actions button {
    min-width: 44px;
    min-height: 44px;
    padding: 10px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }

  .admin-aba {
    padding: 13px 16px;
    min-height: 46px;
  }

  .modal-close {
    min-width: 44px;
    min-height: 44px;
    padding: 8px 12px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }

  .chat-header-actions button,
  #chat-back {
    min-width: 44px;
    min-height: 44px;
  }

  /* Item de menu de contexto: hoje é confortável no mouse, apertado no dedo. */
  .menu-item {
    min-height: 46px;
    display: flex;
    align-items: center;
  }
}

/* --- §0.5 ROLAGEM ------------------------------------------------------------
   A barra de 8px do desktop desperdiça largura preciosa e no toque nem aparece.
   E `overscroll-behavior` impede que rolar até o fim da lista de mensagens
   arraste a página inteira junto (efeito elástico que parece bug). */
@media (max-width: 760px) {
  ::-webkit-scrollbar { width: 0; height: 0; }
  * { scrollbar-width: none; }

  #conversation-list,
  #messages-container,
  #campaign-list,
  .admin-conteudo,
  .crm-col-cards {
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
  }
}

/* ============================================================================
   §1 — NAVEGAÇÃO: o rail lateral vira barra inferior
   ----------------------------------------------------------------------------
   60px de largura fixa é 16% de um iPhone SE gasto com 6 botões, e ainda no
   canto superior esquerdo — o ponto mais longe do polegar em qualquer aparelho.
   Embaixo, os mesmos botões ficam no alcance natural e devolvem a largura.

   O truque é `column-reverse` no #app-linha: o rail continua sendo o primeiro
   elemento do DOM (leitor de tela e ordem de tabulação seguem certos, a
   navegação vem antes do conteúdo) e desenha embaixo.
   ============================================================================ */

/* Os dois elementos que só existem no celular. Ficam DESLIGADOS aqui, antes da
   media query — se viessem depois, a cascata os desligaria também no celular
   (mesma especificidade, ganha quem vem por último; media query não conta como
   especificidade). */
.nav-rotulo { display: none; }
#nav-rail #nav-mais { display: none; }

@media (max-width: 760px) {
  #app-linha {
    flex-direction: column-reverse;
  }

  /* Sem isto o painel inteiro sobe 23px e come a barra de topo.
     `.view` tem `min-width: 0` porque no computador o eixo principal é o
     horizontal. Virando coluna, o eixo principal passa a ser o VERTICAL, e aí
     quem manda é `min-height`, que continua em `auto` — ou seja, a view se
     recusa a encolher abaixo do conteúdo e vaza. Em `column-reverse` o
     transbordo sai pelo TOPO, que é justamente onde está a barra de topo.

     Vale para os filhos também: a corrente de `min-height: 0` precisa descer
     até quem tem `overflow: auto`, senão a rolagem interna vira rolagem da
     tela inteira. */
  #app-linha > .view,
  #sidebar,
  #campaign-sidebar,
  #chat-area,
  #campaign-detail-area,
  #admin-area,
  #crm-area {
    min-height: 0;
  }

  #nav-rail {
    flex-direction: row;
    width: 100%;
    min-width: 0;
    height: auto;
    border-right: none;
    border-top: 1px solid var(--bd);
    padding: 4px 4px 0;
    gap: 0;
    justify-content: space-around;
    /* a barra é o chão do app: nada rola por baixo dela */
    flex: 0 0 auto;
  }

  /* O "g" já está na barra de topo dentro do lockup. Repetir aqui só rouba
     um quinto da barra. */
  .rail-logo { display: none; }
  .nav-spacer { display: none; }

  /* "Meu perfil" sai da barra e vai para a folha do "Mais" (index.html).
     Com ele aqui seriam SEIS colunas: o rótulo de 10px encolhe até virar
     pictograma sem legenda, que é exatamente o que a regra acima evita. */
  #nav-rail .nav-btn[data-view="perfil"] { display: none; }

  /* Cada botão vira uma coluna igual, com o rótulo embaixo do ícone. Sem
     rótulo, quatro pictogramas parecidos viram adivinhação — e "Disparos" e
     "Admin" são justamente os dois que ninguém acerta no chute. */
  #nav-rail .nav-btn {
    flex: 1 1 0;
    width: auto;
    height: auto;
    min-height: 52px;
    border-radius: 10px;
    flex-direction: column;
    gap: 3px;
    padding: 6px 2px;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: -.01em;
  }

  #nav-rail .nav-btn .nav-rotulo {
    display: block;
    line-height: 1;
  }

  /* Ativo no celular: o fundo azul-claro isolado ficava tímido demais numa
     barra de 5 itens. A cor sozinha resolve, e sem fundo o botão não parece
     "apertado". */
  #nav-rail .nav-btn.active {
    background: transparent;
    color: var(--brand);
  }

  /* Contador de não lidas: no rail ele morava no canto do quadrado de 44px.
     Aqui precisa colar no ícone, não no bloco inteiro (que agora tem rótulo). */
  /* O ícone tem 20px e fica centrado: a borda direita dele está a (50% + 10px)
     da esquerda. O contador encosta ali com 4px de avanço. */
  #nav-rail .nav-btn .nav-dot {
    top: 2px;
    right: calc(50% - 14px);
  }

  /* Tema e Sair saem da barra e vão para a folha "Mais" (§1.2). O seletor de
     tema continua fora da barra de topo, como combinado. */
  #nav-rail .tema-wrap,
  #nav-rail #logout-btn {
    display: none;
  }
  #nav-rail #nav-mais {
    display: flex;
  }
}

/* --- §1.2 FOLHA "MAIS" --------------------------------------------------------
   Aparência (os 3 estados) e Sair. É a mesma lista que estava no pé do rail,
   agora numa folha que sobe do rodapé. */
.mais-sheet {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: flex-end;
  background: var(--overlay);
}
.mais-sheet.hidden { display: none; }

/* Alargar a janela com a folha aberta deixaria um painel de rodapé no meio do
   computador, onde tema e Sair já moram no rail. Some sozinha na hora — e
   volta a aparecer se a janela encolher de novo, porque quem manda é só a
   largura, não um estado guardado em JavaScript. */
@media (min-width: 761px) {
  .mais-sheet { display: none; }
}

.mais-sheet-corpo {
  width: 100%;
  background: var(--surface);
  border-radius: 16px 16px 0 0;
  padding: 8px 8px calc(8px + env(safe-area-inset-bottom));
  box-shadow: var(--shadow-1);
}

/* Pegador: o risquinho que diz "isto sobe e desce". Custa 4px e é a diferença
   entre a folha parecer um menu e parecer um erro de layout. */
.mais-sheet-pegador {
  width: 36px;
  height: 4px;
  border-radius: 999px;
  background: var(--bd-strong);
  margin: 6px auto 10px;
}

.mais-sheet-titulo {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--fg-3);
  padding: 10px 12px 4px;
}

.mais-sheet-item {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 50px;
  padding: 0 12px;
  border: none;
  background: none;
  border-radius: 10px;
  font-size: 15px;
  font-family: inherit;
  color: var(--fg);
  text-align: left;
  transition-property: background-color, color;
  transition-duration: .15s;
  transition-timing-function: ease;
}
.mais-sheet-item:hover { background: var(--surface-3); }
.mais-sheet-item.ativo { color: var(--brand); font-weight: 600; }
.mais-sheet-item.ativo .mais-sheet-check { margin-left: auto; }
.mais-sheet-check { display: none; }
.mais-sheet-item.ativo .mais-sheet-check { display: block; }
.mais-sheet-item.perigo { color: var(--err); }
.mais-sheet-sep { height: 1px; background: var(--bd); margin: 6px 12px; }

/* --- §1.3 BARRA DE TOPO -------------------------------------------------------
   Continua existindo em toda tela, com a marca inteira, como combinado. Só
   aperta: o nome de quem está logado vira só o primeiro nome, e o contexto
   ("Conversas", "CRM"…) some quando não cabe — a barra de baixo já diz em que
   tela você está, com rótulo. */
@media (max-width: 760px) {
  #topbar { height: 46px; gap: 8px; }
  #topbar .lockup { --lk: 17px; }
  #topbar .topbar-sep { display: none; }
  #topbar .topbar-ctx { display: none; }
  #topbar .topbar-eu b { max-width: 11ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}

/* --- §1.4 CONVERSA ABERTA = TELA CHEIA ----------------------------------------
   Com a conversa aberta a barra de navegação sai. Motivos, nesta ordem:
   1) o composer + teclado + barra deixariam a mensagem espremida em ~35% da
      tela; 2) o polegar que digita fica a milímetros de "Disparos", e trocar de
      tela sem querer apaga o que estava sendo escrito. O caminho de volta é o
      ← do cabeçalho, que já existe e é o gesto que todo mundo já conhece do
      WhatsApp.

   O `mobile-chat-open` já é ligado e desligado pelo app.js — é a mesma classe
   que hoje troca lista por conversa. */
@media (max-width: 760px) {
  body.mobile-chat-open #nav-rail,
  body.mobile-chat-open #topbar {
    display: none;
  }

  /* Sem a barra de topo, o cabeçalho da conversa vira o topo da tela e precisa
     do respiro do entalhe. */
  body.mobile-chat-open .chat-header {
    padding-top: max(10px, env(safe-area-inset-top));
  }
}

/* ============================================================================
   §2 — CONVERSAS
   ============================================================================ */

@media (max-width: 760px) {
  /* Um pouco mais de ar na lista: no dedo, 3px a mais de altura por item é a
     diferença entre acertar e abrir a conversa de cima. */
  .conv-item { padding-top: 11px; padding-bottom: 11px; }

  /* Filtro de campanha é caso de uso de gestor, e ocupa uma linha inteira.
     Vira mais um chip da fileira que já rola de lado. */
  .conv-filtros { flex-direction: column; align-items: stretch; gap: 8px; }
  .conv-chips { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
  .conv-chips::-webkit-scrollbar { display: none; }

  /* Cabeçalho da conversa: "Assumir" e "Devolver ao agente" perdem o texto e
     ficam só o ícone. São dois botões de 130px numa tela de 375. O title
     continua lá, e a folha de ações (⋯) repete os dois com o nome inteiro. */
  .chat-header-actions #assumir-btn .rotulo,
  .chat-header-actions #devolver-btn .rotulo {
    display: none;
  }

  /* Nome e status em uma linha cada, com reticências. Sem isto o cabeçalho
     cresce para 80px por causa de "Janela aberta · 19h restantes", e são 80px
     roubados das mensagens em toda conversa. O `min-width: 0` é o que autoriza
     o filho de um flex a encolher abaixo do próprio texto — sem ele o
     text-overflow nunca dispara. */
  .chat-header-info { min-width: 0; }
  #chat-name,
  #chat-window-status {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  #messages-container { padding: 12px 3%; }
  .msg { max-width: 86%; }

  /* O composer é a peça mais tocada do app inteiro.

     O botão de emoji SAI no celular: o teclado do telefone já tem a tecla de
     emoji, e o painel dele custa 46px de largura — que é exatamente o que
     faltava para o campo caber "Digite uma mensagem" sem quebrar linha
     (199px antes, 255px depois). */
  #composer { padding: 8px; gap: 6px; }
  #composer-input { max-height: 38dvh; padding: 12px 14px; }
  #emoji-btn, #emoji-panel { display: none; }
  #attach-btn, #send-btn {
    width: 46px; min-width: 46px; height: 46px;
  }

  /* Barra de formatação: rola de lado em vez de quebrar em duas linhas. Sem o
     `nowrap` nos filhos, "Prévia" desce para debaixo do próprio ícone. */
  #fmt-bar {
    overflow-x: auto;
    flex-wrap: nowrap;
    scrollbar-width: none;
  }
  #fmt-bar::-webkit-scrollbar { display: none; }
  #fmt-bar > * { flex: none; white-space: nowrap; }
}

/* ============================================================================
   §3 — CRM
   ----------------------------------------------------------------------------
   Duas mudanças. A visível: cada etapa ocupa quase a tela toda e o funil
   "passa página" no deslize, com uma fresta da próxima coluna aparecendo — é
   ela que avisa que existe mais coisa para o lado.

   A invisível e mais importante: arrastar card NÃO FUNCIONA no toque. O
   `dragstart` do HTML5 não dispara em dedo, nem no Chrome Android nem no
   Safari. Hoje, no celular, o CRM é uma vitrine. O botão "Mover para" no card
   é o que devolve a função — precisa de duas linhas no app.js (marcadas
   com PATCH APP.JS no fim deste arquivo).
   ============================================================================ */

/* Em tela grande o "Mover para" não existe: lá o arrastar funciona e é mais
   rápido. Desligado ANTES da media query, pelo mesmo motivo do #nav-mais. */
.crm-card-mover { display: none; }

@media (max-width: 760px) {
  .crm-kanban {
    padding: 12px;
    gap: 10px;
    scroll-snap-type: x mandatory;
    /* a rolagem passa a ser a da própria coluna, não a de dentro dela */
    overflow-y: hidden;
  }

  .crm-col {
    /* 86vw deixa ~14% da próxima coluna à mostra: é a "fresta" que ensina o
       gesto sem precisar de seta nem de texto explicativo. */
    min-width: 86vw;
    width: 86vw;
    scroll-snap-align: start;
  }

  .crm-col-topo { padding: 12px; }
  .crm-col-nome { font-size: 14px; }

  /* Card no dedo: mais alvo, e o cursor de arrastar sai (não arrasta mesmo). */
  .crm-card { padding: 12px; cursor: default; }
  .crm-card-titulo { font-size: 14.5px; }

  /* O botão que substitui o arrastar. Largura total, embaixo de tudo no card:
     não compete com o toque que abre a ficha. */
  .crm-card-mover {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    width: 100%;
    min-height: 40px;
    margin-top: 10px;
    border: 1px solid var(--bd);
    border-radius: 8px;
    background: var(--surface-2);
    color: var(--fg-2);
    font-family: inherit;
    font-size: 12.5px;
    font-weight: 600;
    transition-property: background-color, border-color, color;
    transition-duration: .15s;
    transition-timing-function: ease;
  }
  .crm-card-mover:hover {
    background: var(--brand-soft);
    border-color: var(--brand-solid);
    color: var(--brand);
  }

  /* Topo do CRM. Empilhando tudo, esta barra come 156px dos 766 disponíveis —
     um quinto da tela gasto em filtro, antes de aparecer um card sequer.

     `display: contents` dissolve os dois agrupadores (.crm-topo-esq e
     .crm-topo-dir): os filhos deles passam a ser itens do MESMO flex, e aí dá
     para intercalar coisas que no HTML estão em caixas diferentes sem tocar no
     markup. O rótulo sobe para cima do select (o par ocupa a mesma altura de
     um select sozinho com rótulo ao lado, e sobra largura), os dois botões de
     gestão viram ícone, e o resumo fica numa linha fina embaixo.

     Resultado: 156px → ~96px, com tudo ainda visível e nada escondido. */
  .crm-topo {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 8px;
    padding: 10px 12px;
  }
  .crm-topo-esq, .crm-topo-dir { display: contents; }

  .crm-topo .crm-filtro {
    flex: 1 1 0;
    min-width: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
  }
  .crm-topo .crm-filtro > span {
    font-size: 10.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--fg-3);
  }
  .crm-filtro select { width: 100%; min-width: 0; }

  .crm-topo-dir .secondary-btn {
    order: 3;
    flex: 0 0 auto;
    min-width: 44px;
    min-height: 40px;
    margin-top: 0;
    justify-content: center;
  }
  .crm-topo-dir .secondary-btn .rotulo { display: none; }

  /* Última linha, largura inteira. */
  .crm-resumo { order: 4; flex: 1 1 100%; }
}

/* ============================================================================
   §4 — ADMINISTRAÇÃO
   ============================================================================ */

@media (max-width: 760px) {
  /* O cabeçalho não rola junto com o conteúdo, então cada pixel dele é um
     pixel a menos de métrica visível o tempo todo. 144px → ~124px sem cortar
     o texto explicativo, que é o que evita a equipe ler a classificação da
     Meta como se fosse volume de envio. */
  .admin-header { padding: 10px 12px; gap: 8px; }
  .admin-header h2 { font-size: 16px; }
  .admin-sub { font-size: 12px; line-height: 1.4; margin-top: 2px; }
  .admin-header-acoes { width: 100%; }
  #admin-janela { flex: 1; }
  .admin-conteudo { padding: 14px 12px 30px; }

  /* 190px de mínimo dava UMA coluna em 375px de tela: os cartões viravam uma
     pilha de blocos gigantes e a pessoa rolava três telas para ver 6 números.
     150px dá duas colunas e a tela inteira cabe de uma vez. */
  .metricas-grid { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; }
  .metrica { padding: 11px 12px; }
  .metrica-valor { font-size: 22px; }

  .admin-bloco { padding: 13px 14px; }
  .admin-nota { max-width: none; }

  /* Abas: rolam de lado em vez de quebrar linha. */
  .admin-abas { overflow-x: auto; scrollbar-width: none; padding: 0 12px; }
  .admin-abas::-webkit-scrollbar { display: none; }
  .admin-aba { white-space: nowrap; }

  /* TABELA VIRA CARTÃO.
     Uma tabela de 8 colunas em 375px é ilegível em qualquer tamanho de fonte —
     e encolher a fonte só troca "ilegível" por "ilegível e pequeno". Cada linha
     vira um bloco com "rótulo à esquerda, valor à direita".

     Depende de cada <td> carregar `data-rotulo` (o texto do <th>), que o
     `rotularTabelas()` do app.js carimba depois de renderizar. Sem isso a
     tabela continua tabela: degrada, não quebra.

     A linha de cabeçalho é escondida por CLASSE, não por `thead`: estas tabelas
     são escritas como `<table><tr><th>…` direto, sem `<thead>` nenhum — o
     navegador embrulha tudo num `<tbody>` só, e um seletor `thead` nunca casa.
     Quem carimba a classe é o mesmo `rotularTabelas()`. */
  table[data-cartoes] .tabela-cabecalho { display: none; }
  table[data-cartoes],
  table[data-cartoes] thead,
  table[data-cartoes] tbody,
  table[data-cartoes] tr,
  table[data-cartoes] td {
    display: block;
    width: 100%;
  }
  /* `flex` em vez de `block` só para o `order` abaixo funcionar: a célula do
     título pode não ser a primeira do HTML (na lista de destinatários ela é a
     segunda, depois do número da linha), e sem isso o cartão abriria com
     "# 7" e só então diria de quem é. */
  table[data-cartoes] tr {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--bd);
    border-radius: 10px;
    padding: 4px 12px;
    margin-bottom: 10px;
    background: var(--surface-2);
  }
  table[data-cartoes] td.cartao-titulo { order: -1; }
  table[data-cartoes] td {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    padding: 7px 0;
    border-bottom: 1px solid var(--bd);
    text-align: left;
  }
  table[data-cartoes] tr td:last-child { border-bottom: none; }
  table[data-cartoes] td::before {
    content: attr(data-rotulo);
    flex: 0 0 auto;
    font-size: 11.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .03em;
    color: var(--fg-2);
  }
  /* Uma célula vira o TÍTULO do cartão: sem rótulo, maior, no topo. Qual delas
     é escolha da tabela — o valor de `data-cartoes` é o índice da coluna, e as
     do admin usam o padrão 0. A lista de destinatários usa `data-cartoes="1"`,
     porque a coluna 0 ali é o número da linha e um cartão intitulado "7" não
     diz nada. Quem marca a célula com .cartao-titulo é o rotularTabelas(). */
  table[data-cartoes] td.cartao-titulo {
    font-weight: 600;
    font-size: 14.5px;
    padding-top: 10px;
  }
  table[data-cartoes] td.cartao-titulo::before { content: none; }
  table[data-cartoes] td.num { text-align: left; }

  /* Célula de texto longo (o corpo da mensagem do disparo) empilha: rótulo em
     cima, texto embaixo. Lado a lado, uma mensagem de 3 linhas sobra num
     filete de 180px. */
  table[data-cartoes] td.rec-body {
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    max-width: none;
  }

  /* Gráficos: a barra some antes de virar risco ininteligível. */
  .gr-legenda { flex-wrap: wrap; gap: 8px 16px; }

  /* ---- LINHA DA EQUIPE ----------------------------------------------------
     A linha é `avatar | dados | botões` numa fila só. Em 390px os botões
     (Telefone, Senha, Nome, Desativar) somam 275px e a coluna de dados era
     espremida até 1px de largura: o nome saía uma palavra por linha, com os
     botões desenhados por cima. Medido, não estimado.

     Já estava apertado com três botões; o de Telefone deixou insustentável.
     Aqui os botões descem para uma segunda linha e dividem a largura entre si,
     virando alvos de 40px em vez de tirinhas. */
  .usuario-linha { flex-wrap: wrap; }
  /* base 0, nao `auto`: com base no conteudo, a linha de quem esta com
     telefone pendente (texto longo) empurrava a coluna inteira para baixo do
     avatar, e a mesma lista ficava com duas formas diferentes de linha. */
  .usuario-info { flex: 1 1 0; }
  .usuario-acoes {
    flex: 1 1 100%;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 4px;
  }
  .usuario-acoes button {
    flex: 1 1 auto;
    min-height: 40px;
    justify-content: center;
  }
}

/* ============================================================================
   §5 — DISPAROS EM LOTE
   ----------------------------------------------------------------------------
   A troca lista ↔ detalhe já funciona (a mesma `mobile-chat-open`). O que falta
   é o conteúdo do detalhe, que é a tela mais densa do painel inteiro.
   ============================================================================ */

@media (max-width: 760px) {
  /* Sem a barra de topo na tela de detalhe, mesma lógica da conversa. */
  body.mobile-chat-open #campaign-detail-area { padding-top: env(safe-area-inset-top); }

  .camp-item { padding-top: 12px; padding-bottom: 12px; }
  .camp-detail-header { padding: 14px 12px; }
  .camp-detail-title { flex-wrap: wrap; gap: 8px; }
  .camp-detail-title h2 { font-size: 17px; }

  /* Todo par de campos lado a lado cai para uma coluna. */
  .crm-form-linha { grid-template-columns: 1fr; }

  /* Os números da campanha (enviados / entregues / lidos / falhas): de fileira
     que quebra torto para grade de dois, alinhada como os cartões do admin. */
  .camp-counts { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; }
  .count-chip { padding: 8px 12px; }

  /* Ações da campanha (pausar, retomar, reenviar): empilham em vez de espremer
     três rótulos numa linha de 375px. */
  .camp-actions { flex-direction: column; align-items: stretch; }
  .camp-actions button { width: 100%; min-height: 46px; justify-content: center; }

  /* ---- A TELA INTEIRA ROLA COMO UMA COISA SÓ ----------------------------
     No computador o detalhe da campanha tem duas zonas: cabeçalho parado em
     cima e lista de destinatários rolando embaixo. Faz sentido numa tela de
     900px de altura.

     Em 390x760 medi: cabeçalho 489px (título, andamento, os seis números e
     três botões de ação), barra de filtro 52px — sobrava uma fresta de 219px
     para a lista, com rolagem própria. Numa campanha de 180 pessoas, você
     enxerga três por vez por uma janelinha. Foi exatamente o relato: "a lista
     fica escondida por conta do cabeçalho".

     Ninguém precisa dos seis números na tela o tempo todo. Aqui o cabeçalho
     sai de cena conforme a pessoa desce, e a lista usa a tela inteira —
     que é o padrão de qualquer aplicativo de celular. */
  #campaign-detail {
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  /* `flex: none` nos dois: sem isto o cabeçalho continuaria tentando encolher
     e a lista continuaria virando caixa de rolagem própria dentro da página
     que já rola — duas rolagens aninhadas, que no toque é uma briga. */
  .camp-detail-header { flex: none; }
  /* Sem  aqui de proposito: pela especificacao,      diferente de  num eixo força o OUTRO eixo a  — foi assim
     que a primeira tentativa desta correção continuou com a lista rolando
     dentro da página em vez de a página rolar. A tabela vira cartão logo
     abaixo, então não há mais nada de largo para rolar de lado. */
  .camp-recipients {
    flex: none;
    overflow: visible;
    padding: 0 12px 20px;
  }

  /* Continua alcançável depois de rolar o cabeçalho para fora. */
  .camp-filter-bar {
    padding: 10px 12px;
    flex-wrap: wrap;
    position: sticky;
    top: 0;
    z-index: 2;
  }

  /* A lista de destinatários é a tabela mais larga do painel: 5 colunas, uma
     delas o corpo inteiro da mensagem. Em 390px, deixá-la como tabela dava
     linhas de 440px de altura — 24 destinatários viravam 5.200px de coluna
     espremida. Vai pelo mesmo caminho das tabelas do admin: um cartão por
     destinatário. O `th` sticky do desktop deixa de importar, porque em modo
     cartão o cabeçalho não é exibido. */
}

/* ============================================================================
   §6 — MODAIS VIRAM FOLHA DE RODAPÉ
   ----------------------------------------------------------------------------
   Modal centralizado no celular é o pior dos dois mundos: fica longe do polegar
   e, com o teclado aberto, `max-height: 86vh` calcula em cima da tela SEM
   teclado — o botão de confirmar vai parar atrás do teclado.

   Colado embaixo, com altura em dvh, o botão fica sempre no alcance e a folha
   encolhe junto com o teclado.
   ============================================================================ */

@media (max-width: 760px) {
  .modal-overlay {
    align-items: flex-end;
    padding: 0;
  }

  .modal,
  .modal-small,
  .modal-large,
  .modal-wide {
    width: 100%;
    max-width: none;
    border-radius: 16px 16px 0 0;
    max-height: 92dvh;
  }

  .modal-header { padding: 14px 16px; }
  .modal-body {
    padding: 16px 16px calc(16px + env(safe-area-inset-bottom));
  }

  /* Botão principal de modal (o grupo da regra #newchat-start, … do style.css)
     e os secundários: largura total e alvo de 48px. */
  #newchat-start,
  #template-send-btn,
  #contact-save-btn,
  #erro-ok-btn,
  .modal-body .secondary-btn {
    width: 100%;
    min-height: 48px;
  }
  .crm-acoes { flex-direction: column; align-items: stretch; }
  .crm-acoes button { width: 100%; min-height: 46px; }
}

/* ============================================================================
   §7 — TELA DE LOGIN
   ============================================================================ */

@media (max-width: 760px) {
  /* `height: 100vh` aqui é o mesmo problema da §0.1, e nesta tela o efeito é
     o botão "Entrar" abaixo da dobra com o teclado aberto. */
  #login-view {
    height: 100dvh;
    height: var(--vvh, 100dvh);
    padding: 20px 16px calc(20px + env(safe-area-inset-bottom));
    align-items: flex-start;
    padding-top: 14dvh;
  }
  .login-card { width: 100%; max-width: 420px; }
  #login-form input { min-height: 48px; }
  #login-form button { min-height: 48px; }
}

/* ============================================================================
   O QUE VIVE FORA DESTE ARQUIVO
   ----------------------------------------------------------------------------
   CSS não alcança tudo. Estas peças estão APLICADAS no painel; a lista existe
   para quem for mexer saber que elas fazem parte do mesmo conjunto e não são
   detalhes soltos. Nenhuma delas muda o comportamento no computador.

   index.html
     · meta viewport com `viewport-fit=cover` (libera env(safe-area-inset-*))
       e `interactive-widget=resizes-content` (no Android o teclado encolhe o
       layout sozinho; no iOS quem resolve é o mobile.js)
     · <link> deste arquivo e <script> do mobile.js, depois do style.css
     · <span class="nav-rotulo"> nos 4 botões do rail
     · 5º botão #nav-mais e a folha #mais-sheet
     · <span class="rotulo"> em volta do texto de "Assumir", "Devolver ao
       agente", "Funis e etapas" e "Importar leads" — sem esse span não há como
       esconder só o texto e manter o ícone

   mobile.js
     · --vvh: a altura realmente visível, com o teclado do iPhone aberto
     · fecha a folha "Mais" ao passar de celular para computador

   app.js
     · aplicarTema() marca o tema ativo nos DOIS lugares (rail e folha)
     · iniciarMais(): abre/fecha a folha; o "Sair" dela delega no #logout-btn
     · moverCard(): porta única para trocar de etapa. O arrastar e o botão
       "Mover para…" chamam a mesma função
     · abrirFolhaEtapas(): a folha de etapas do botão
     · rotularTabelas(): carimba data-rotulo em cada <td> do admin a partir do
       <th>, e a classe .tabela-cabecalho na linha de cabeçalho
     · a aba "Leads em tratamento" abre em cartões quando a tela é estreita
   ============================================================================ */
