/* Estilos complementares ao Tailwind (build self-hosted). Marca ZalpieCRM + dark mode. */

@font-face {
  font-family: "InterVariable";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/static/fonts/inter.woff2") format("woff2");
}

:root { color-scheme: light; }
.dark { color-scheme: dark; }

/* Utilitários de grid ausentes no build purgado do Tailwind (o tailwind.css não
   incluiu estas classes-base, mas os templates as usam — ex.: seletor de figurinhas).
   Sem elas, `.grid` cai numa única coluna implícita e os itens ficam empilhados. */
.grid-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grid-cols-6 { grid-template-columns: repeat(6, minmax(0, 1fr)); }
.space-y-5 > :not([hidden]) ~ :not([hidden]) { margin-top: 1.25rem; }
.space-y-6 > :not([hidden]) ~ :not([hidden]) { margin-top: 1.5rem; }
.h-32 { height: 8rem; }
.aspect-square { aspect-ratio: 1 / 1; }
/* Posições ausentes no build purgado — usadas na bolinha (knob) dos toggles/switches. */
.top-0\.5 { top: 0.125rem; }
.left-0\.5 { left: 0.125rem; }
.left-4 { left: 1rem; }
.left-5 { left: 1.25rem; }
/* Larguras/alturas/posições ausentes no build (menus, pickers, popovers). */
.pl-1 { padding-left: 0.25rem; }
.pr-9 { padding-right: 2.25rem; }   /* P12: busca de mensagens com o botão de período à direita */
.w-60 { width: 15rem; }
/* Inbox — larguras dos painéis laterais em CSS puro (valores arbitrários do Tailwind exigiriam
   rebuild do vendor/tailwind.css e não há Node no ambiente).

   IMPORTANTE: as larguras que dependem do espaço disponível usam PORCENTAGEM (não vw/calc-vw),
   porque o inbox vive dentro de #app-col (flex-1), que já é 100vw MENOS a barra de navegação do app
   (rail ~68px / expandida 16rem). Uma % de um flex-child é relativa a esse container — então o
   cálculo exclui a sidebar automaticamente, em qualquer estado, sem esmagar a conversa (thread). */

/* Painel ESQUERDO (lista de conversas): +25% (md:20→25rem, lg:24→30rem); mobile = largura total.
   No xl (3 colunas: lista + conversa + contexto inline) limita a 30% do container. */
.inbox-list-panel { width: 100%; }
@media (min-width: 768px)  { .inbox-list-panel { width: 25rem; } }        /* md: 20 -> 25rem (+25%) */
@media (min-width: 1024px) { .inbox-list-panel { width: 30rem; } }        /* lg: 24 -> 30rem (+25%) */
@media (min-width: 1280px) { .inbox-list-panel { width: min(30rem, 30%); } }

/* Painel DIREITO (contexto contato/CRM). < xl: drawer overlay (fixed) = min(33rem, 92vw).
   >= xl (coluna inline): alvo de 33rem, capado a 34% do container do inbox — assim a conversa
   sempre fica com >= ~36% (nunca esmaga), largo nos monitores grandes e são nos ~1280px. */
.inbox-context-panel { width: min(33rem, 92vw); }
@media (min-width: 1280px) { .inbox-context-panel { width: min(33rem, 34%); } }
.w-72 { width: 18rem; }
.top-full { top: 100%; }
.h-4\.5 { height: 1.125rem; }
.w-4\.5 { width: 1.125rem; }
.max-w-\[8rem\] { max-width: 8rem; }
.max-w-\[13rem\] { max-width: 13rem; }
.w-\[min\(20rem\,calc\(100vw-1\.5rem\)\)\] { width: min(20rem, calc(100vw - 1.5rem)); }
.w-\[min\(22rem\,calc\(100vw-1\.5rem\)\)\] { width: min(22rem, calc(100vw - 1.5rem)); }
/* Cores com opacidade, variantes e utilitários visuais ausentes no build. */
.bg-black\/5 { background-color: rgba(0, 0, 0, 0.05); }
.bg-white\/10 { background-color: rgba(255, 255, 255, 0.1); }
.bg-white\/5 { background-color: rgba(255, 255, 255, 0.05); }
.border-white\/25 { border-color: rgba(255, 255, 255, 0.25); }
.border-white\/60 { border-color: rgba(255, 255, 255, 0.6); }
.dark\:bg-white\/5:is(.dark *) { background-color: rgba(255, 255, 255, 0.05); }
.rounded-sm { border-radius: 0.125rem; }
.italic { font-style: italic; }
.sticky { position: sticky; }
/* Ring de hover/foco do seletor de figurinhas (variantes purgadas). */
.hover\:ring-2:hover { box-shadow: 0 0 0 2px var(--tw-ring-color, rgb(12 146 121 / 0.5)); }
.hover\:ring-brand-500:hover { --tw-ring-color: #0c9279; }
.focus\:ring-brand-500:focus { --tw-ring-color: #0c9279; }
/* Variantes 2xl ausentes (dashboard KPIs / colunas do kanban em telas largas). */
@media (min-width: 1536px) {
  .\32xl\:grid-cols-6 { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .\32xl\:w-80 { width: 20rem; }
}
.group:hover .group-hover\:flex { display: flex; }
@media (min-width: 640px) { .sm\:flex { display: flex; } }

/* Compatibilidade mobile nº1: altura DINÂMICA (dvh) — a barra do navegador não "come" mais a tela.
   Cascateia p/ todo o app (html.h-full → body → shells). Fallback 100vh onde dvh não existir. */
html.h-full { height: 100vh; height: 100dvh; }
/* Trava o scroll do DOCUMENTO nas telas com o app-shell (sidebar). Só os contêineres
   internos (lista de conversas, área de mensagens, páginas com overflow-y-auto) rolam.
   Sem isto, clicar FORA de uma área rolável e rolar arrastava a página inteira e o shell
   "desenquadrava", deixando um vão embaixo. Escopo via :has p/ NÃO travar login/signup. */
html.h-full:has(#app-row),
html.h-full:has(#app-row) body { overflow: hidden; }
/* NÃO transformar #conteudo em flex-column esticando o filho por flex-grow: isso dá
   ao root uma altura "indefinida" e os filhos flex do root (colunas do inbox) deixam
   de esticar, criando o vão preto interno. A cadeia h-full (base.html: #app-col tem
   h-full → main flex-1 vira DEFINIDO → h-full do root resolve) já preenche tudo. */
/* Safe-area (notch/home-bar do iPhone). Requer viewport-fit=cover no meta. */
.composer-safe { padding-bottom: calc(0.75rem + env(safe-area-inset-bottom, 0px)); }
.toasts-safe   { bottom: calc(1rem + env(safe-area-inset-bottom, 0px)); right: calc(1rem + env(safe-area-inset-right, 0px)); }
.pb-safe { padding-bottom: env(safe-area-inset-bottom, 0px); }
.pt-safe { padding-top: env(safe-area-inset-top, 0px); }
/* Paisagem de celular (telas baixas): encolhe as barras fixas p/ devolver altura à conversa. */
@media (max-height: 450px) {
  header.h-14 { height: 2.75rem; }
  .h-16 { height: 3rem; }
}
/* Impressão / PDF dos relatórios: isola o conteúdo e some com a moldura. */
@media print {
  body * { visibility: hidden; }
  #conteudo, #conteudo * { visibility: visible; }
  #conteudo { position: absolute; left: 0; top: 0; width: 100%; }
  html, body, main, #conteudo, #conteudo .h-full, #conteudo .overflow-hidden, #conteudo .overflow-y-auto { height: auto !important; overflow: visible !important; }
  body { background: #fff !important; }
  aside, header, #global-progress { display: none !important; }
  /* Relatórios (P09): abas/filtros/botões somem, a linha "Período: …" aparece, card não quebra no meio. */
  .no-print { display: none !important; }
  .print-only { display: block !important; }
  .print-card { break-inside: avoid; page-break-inside: avoid; }
  /* Gráficos: o canvas nasce com a largura do layout de TELA (inline style do Chart.js) e sairia
     cortado à direita. O resize() do beforeprint (common.js) não resolve no Chrome: o evento dispara
     ANTES do layout de impressão e lê a largura de tela. Escala o bitmap à página, mantendo a proporção. */
  .print-card canvas { max-width: 100% !important; height: auto !important; }
  .print-card :has(> canvas) { height: auto !important; }   /* o wrapper h-56/h-72 acompanha o canvas escalado */
  /* Heatmap Chats × Horas: a célula É o fundo — sem isto sai em branco com "gráficos de fundo" desligado. */
  .heat-cell { print-color-adjust: exact; -webkit-print-color-adjust: exact; }
  /* Tabela larga (ex.: 8 colunas do Relatório de Usuários): no A4 a última coluna saía cortada pelo
     overflow-x-auto — célula mais justa só no papel. */
  .print-dense th, .print-dense td { padding-left: 4px !important; padding-right: 4px !important; }
  /* Tabela de 9 colunas (aba Mensagens): o wrapper solta o overflow (senão recorta à direita), a célula
     quebra linha, a coluna larga perde o min-width da tela e o Chat_ID (`print-hide`) sai do papel.
     overflow-wrap (não word-break: break-word) nas células: com o "quebra em qualquer ponto" valendo para
     todas, a tabela apertada partia palavras curtas ("Rece|bida", "Client|e"); só o corpo da mensagem
     (.break-words) quebra em qualquer ponto — uma URL comprida ali não alarga a coluna para fora do papel. */
  .overflow-x-auto:has(> .print-dense) { overflow: visible !important; }
  .print-dense th, .print-dense td { white-space: normal !important; overflow-wrap: break-word; }
  .print-dense .break-words { overflow-wrap: anywhere; }
  .print-dense .min-w-64 { min-width: 0 !important; }
  .print-hide { display: none !important; }
}
.print-only { display: none; }
/* Seletor em <details> dos relatórios: sem o triângulo nativo do <summary> (o Safari ignora o display:flex). */
.picker-summary { list-style: none; }
.picker-summary::-webkit-details-marker { display: none; }

/* Scrollbar */
::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-thumb { background: #c3cdd7; border-radius: 5px; }
::-webkit-scrollbar-thumb:hover { background: #909daa; }
::-webkit-scrollbar-track { background: transparent; }
.dark ::-webkit-scrollbar-thumb { background: #343e48; }
.dark ::-webkit-scrollbar-thumb:hover { background: #48535e; }

[x-cloak] { display: none !important; }

/* Aviso que começa em minúscula no texto (literal do backend/especificação) e abre a frase na tela — ex.: a pendência
   do proxy em Celulares. Só vale em bloco (::first-letter não pega em inline). */
.cap-first::first-letter { text-transform: uppercase; }

/* Selects nativos: popup de opções legível (evita texto claro em fundo branco no dark). */
select option { background-color: #ffffff; color: #14181d; padding: 6px 10px; }
.dark select option { background-color: #212830; color: #ebeff3; }

/* Modo claro: os cinzas de texto "apagado" estavam claros demais (baixo contraste no branco).
   Escurece SÓ no modo claro (o dark precisa deles claros, então fica intacto).
   P12: TODA cor de TEXTO do claro vai em `:where(html:not(.dark)) .text-x` = especificidade (0,1,0): ganha
   da utilitária base pela ORDEM (app.css carrega depois do tailwind.css) e PERDE para `hover:`/`group-hover:`
   (0,2,0+). Com `html:not(.dark) .text-x` (0,2,1) o hover sumia no claro (ex.: o ✕ de remover usuário). */
:where(html:not(.dark)) .text-slate-400 { color: #5f6670; }   /* era #949ca6; #6b6b72 dava 4,38:1 no body claro (P12) → 4,8:1 */
:where(html:not(.dark)) .text-slate-500 { color: #48535e; }   /* era #71717a (labels/prévia mais nítidos) */

/* Modo claro: mais DEFINIÇÃO — bordas e placeholders sumiam no branco (tudo "apagado"). */
html:not(.dark) .border-slate-200 { border-color: #d2d2d7; }  /* era #dde2e7: contorno de campos/cards visível */
html:not(.dark) .border-slate-100 { border-color: #e2e2e6; }  /* divisórias com um tico mais de presença */
html:not(.dark) .border-slate-300 { border-color: #828287; } /* inputs/filtros: contorno ≥ 3:1 no branco E no painel cinza (WCAG 1.4.11) */
html:not(.dark) body { background-color: #e7eaee; } /* canvas grafite suave: painéis e cards "saltam" */
html:not(.dark) ::placeholder { color: #6b6b72; opacity: 1; } /* 5.3:1 no branco (era #8c8c93 = 3.3:1) */
/* P12 — Tema CLARO (opcional; o escuro continua o padrão). A marca é o VERDE: brand-600 (#08745f) passa AA
   no branco e no body claro. Só o brand-500 (#0c9279 ≈ 3,9:1 no branco) reprova como texto/ícone: no
   claro ele vira o brand-600. O escuro fica intacto (lá o brand-500 é o tom legível). */
:where(html:not(.dark)) .text-brand-500 { color: #08745f; }
/* P12 — conferência do claro: texto -600 de status/sucesso/aviso reprovava AA no branco/painel (emerald 3,8:1,
   teal 3,7:1, amber 3,2:1, sky 4,1:1, orange 3,6:1, cyan 3,7:1; red-600 3,95:1 sobre red-100). No claro, o -700
   — e o -800 em amber/orange/cyan, cujo -700 reprovava no body claro (#e7eaee). Todas ≥ 4,5:1 no card e no body. */
:where(html:not(.dark)) .text-emerald-600 { color: #047857; }
:where(html:not(.dark)) .text-teal-600 { color: #0f766e; }
:where(html:not(.dark)) .text-amber-600 { color: #92400e; }
:where(html:not(.dark)) .text-sky-600 { color: #0369a1; }
:where(html:not(.dark)) .text-orange-600 { color: #9a3412; }
:where(html:not(.dark)) .text-cyan-600 { color: #155e75; }
:where(html:not(.dark)) .text-red-600 { color: #b91c1c; }

/* Modo ESCURO — acessibilidade: cinzas apagados reprovavam contraste; SÓ clareia (nunca piora). */
html.dark .text-slate-500 { color: #909daa; }   /* 3.67:1 → 6.9:1: labels, horários, hints, estados vazios */
html.dark .text-slate-600 { color: #909daa; }   /* 2.29:1 → 6.9:1: micro-labels uppercase */
html.dark .border-slate-700 { border-color: #71717a; } /* inputs/cards: contorno ≥ 3:1 no escuro (3.67:1) */
html.dark ::placeholder { color: #909daa; opacity: 1; } /* 5.8:1 (era ~3.1:1) */

/* Status/badges no ESCURO: fundo SÓLIDO (o /15 transparente dificultava a leitura).
   Seletor encadeado (bg+texto juntos) mira SÓ os badges — não afeta realces de seleção/hover que usam /15 sem cor de texto. */
.dark .dark\:bg-blue-500\/15.dark\:text-blue-300       { background-color: #1e3a8a; }
.dark .dark\:bg-emerald-500\/15.dark\:text-emerald-300 { background-color: #064e3b; }
.dark .dark\:bg-teal-500\/15.dark\:text-teal-300       { background-color: #134e4a; }
.dark .dark\:bg-amber-500\/15.dark\:text-amber-300     { background-color: #78350f; }
.dark .dark\:bg-red-500\/15.dark\:text-red-300         { background-color: #7f1d1d; }
.dark .dark\:bg-violet-500\/15.dark\:text-violet-300   { background-color: #4c1d95; }
.dark .dark\:bg-brand-500\/15.dark\:text-brand-300     { background-color: #143e37; }

/* ==== Design v2: superfície, tipografia, movimento ==== */
/* Superfície de chrome tokenizada (mata o #eeeef0 hardcoded; o escuro ganha a 3ª camada). */
:root { --panel: #eef1f3; }
.dark { --panel: #16191d; }
.bg-panel { background-color: var(--panel); }

/* Botão primário: verde profundo da marca com texto branco no claro; faceta turquesa
   com texto escuro no dark. Ambos passam AAA para texto normal. */
.btn-primary {
  background-color: #075d4f;
  color: #ffffff;
}
.btn-primary:hover { background-color: #143e37; }
.dark .btn-primary { background-color: #26b99b; color: #0b0e12; }
.dark .btn-primary:hover { background-color: #56d5b5; }
.btn-primary:disabled,
.btn-primary[disabled] { background-color: #164f43; color: #ebeff3; }
.dark .btn-primary:disabled,
.dark .btn-primary[disabled] { background-color: #0c9279; color: #0b0e12; }

/* Números de dados: tabulares + zero cortado (0≠O em telefone/código/contador). */
.nums { font-variant-numeric: tabular-nums slashed-zero; }
/* cv05 ('l' com cauda) é feature OpenType específica da Inter — Voz do Inter, e Inter é a
   fonte do corpo. calt segue válido p/ qualquer fonte. */
html { font-feature-settings: "cv05" 1, "calt" 1; text-rendering: optimizeLegibility; }
/* Micro-rótulo (eyebrow) como token único. */
.eyebrow { font-size: .625rem; line-height: 1; font-weight: 600; text-transform: uppercase; letter-spacing: .09em; }

/* Feedback de PRESS (só ações primárias) — confiança tátil, sobretudo no mobile. */
.press { transition: transform .08s ease, background-color .15s ease; }
.press:active:not(:disabled) { transform: translateY(1px) scale(.985); }

/* 'Digitando…' estilo mensageria: 3 pontos em onda (herda currentColor). */
.typing-dots { display: inline-flex; align-items: flex-end; gap: 3px; height: .7em; }
.typing-dots i { width: 5px; height: 5px; border-radius: 9999px; background: currentColor; opacity: .45; animation: typing-bounce 1.2s infinite ease-in-out; }
.typing-dots i:nth-child(2) { animation-delay: .15s; }
.typing-dots i:nth-child(3) { animation-delay: .3s; }
@keyframes typing-bounce { 0%,60%,100% { transform: translateY(0); opacity: .4; } 30% { transform: translateY(-3px); opacity: 1; } }

/* Hero do onboarding: superfície sólida da marca + eco de 'sinal' (SEM gradiente-herói). */
.hero-petrol { background-color: #164f43; background-image: url("data:image/svg+xml,%3Csvg width='40' height='40' viewBox='0 0 40 40' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23ffffff' fill-opacity='0.06'%3E%3Ccircle cx='20' cy='20' r='1.4'/%3E%3C/g%3E%3C/svg%3E"); }
.dark .hero-petrol { background-color: #143e37; }

/* ---- Sidebar "rail" (desktop): só ícones, expande no hover --------------- */
/* No mobile a sidebar continua off-canvas (w-64). O modo rail só age em lg+. */
.sidebar-rail { transition: transform .2s ease, width .2s ease; }
/* Espaçador (desktop): reserva a largura da barra fixa; a barra cresce POR CIMA no hover (sem reflow).
   Dirigido por 'html.rail' (aplicado no <head>, antes da pintura) — não por Alpine — p/ não animar no load. */
.rail-spacer { width: 16rem; transition: width .2s ease; }
html.rail .rail-spacer { width: 4.25rem; }
.rail-label { transition: opacity .15s ease; }
@media (min-width: 1024px) {
  html.rail:not(.rail-peek) aside.sidebar-rail { width: 4.25rem; }         /* 68px — só ícones */
  html.rail:not(.rail-peek) aside.sidebar-rail:hover { width: 16rem; }     /* cresce no hover */
  /* Rótulos no rail: colapso HORIZONTAL animável (max-width + opacity), sincronizado
     com a largura da barra (.2s). Assim o texto "cresce/encolhe" junto — nada de
     display:none piscando (que dava a sensação de "esconder algo"). Fica fora do
     layout (max-width:0) p/ o ícone permanecer centrado no estado recolhido. */
  html.rail:not(.rail-peek) aside.sidebar-rail .rail-label {
    display: inline-block; max-width: 0; opacity: 0; overflow: hidden;
    white-space: nowrap; vertical-align: middle;
    transition: max-width .2s ease, opacity .16s ease;
  }
  html.rail:not(.rail-peek) aside.sidebar-rail:hover .rail-label { max-width: 14rem; opacity: 1; }
  /* Itens com ALTURA própria (rótulo de seção, onboarding): esconder de vez evita
     vão vertical. Vêm depois p/ vencer a regra .rail-label acima (mesma specificity). */
  html.rail:not(.rail-peek) aside.sidebar-rail .nav-section-label,
  html.rail:not(.rail-peek) aside.sidebar-rail .rail-hide { display: none; }
  html.rail:not(.rail-peek) aside.sidebar-rail:hover .nav-section-label,
  html.rail:not(.rail-peek) aside.sidebar-rail:hover .rail-hide { display: revert; }
  /* Cards de navegação: no rail viram botões quadrados centrados (sem "caixa" torta). */
  html.rail:not(.rail-peek) aside.sidebar-rail .nav-card {
    width: 2.75rem; height: 2.75rem;   /* 44×44 — botão quadrado perfeito */
    margin-left: auto; margin-right: auto;
    padding: 0;
    justify-content: center;
    gap: 0;
  }
  html.rail:not(.rail-peek) aside.sidebar-rail:hover .nav-card {
    width: auto; height: auto;
    margin-left: .625rem; margin-right: .625rem;
    padding: .625rem .75rem;
    justify-content: flex-start;
    gap: .75rem;
  }
  /* Cabeçalho da marca: no rail o logo centraliza (o px-5 espremia num rail de 68px). */
  html.rail:not(.rail-peek) aside.sidebar-rail .sidebar-head {
    padding-left: 0; padding-right: 0; justify-content: center; gap: 0;
  }
  html.rail:not(.rail-peek) aside.sidebar-rail:hover .sidebar-head {
    padding-left: 1.25rem; padding-right: 1.25rem; justify-content: flex-start; gap: .625rem;
  }
  /* Link do simulador (caixa tracejada): fica só o ícone centrado no rail. */
  html.rail:not(.rail-peek) aside.sidebar-rail .rail-mini {
    width: 2.75rem; margin-left: auto; margin-right: auto;
    padding-left: 0; padding-right: 0;
    justify-content: center; gap: 0;
    border-color: transparent;
  }
  html.rail:not(.rail-peek) aside.sidebar-rail:hover .rail-mini {
    width: auto; margin-left: .75rem; margin-right: .75rem;
    padding-left: .75rem; padding-right: .75rem;
    justify-content: flex-start; gap: .5rem;
  }
}

/* Acessibilidade: foco visível consistente com a marca — WCAG 2.4.7. */
a:focus-visible,
button:focus-visible,
[role="button"]:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid #075d4f;      /* brand-700 */
  outline-offset: 2px;
  border-radius: 6px;
}
.dark a:focus-visible,
.dark button:focus-visible,
.dark [role="button"]:focus-visible,
.dark input:focus-visible,
.dark select:focus-visible,
.dark textarea:focus-visible,
.dark [tabindex]:focus-visible { outline-color: #56d5b5; }

/* Fundo da conversa: superfície LIMPA (claro e escuro). O grid de pontos regular anterior
   lia como "papel milimetrado / editor de nós" e cansava a vista — trocado por um leve
   degradê vertical, quase imperceptível, que dá profundidade sem virar textura. */
.chat-bg {
  background-color: #e9edf1;
  background-image: linear-gradient(180deg, #eef1f4 0%, #e6eaee 100%);
}
.dark .chat-bg {
  background-color: #0f1013;
  background-image: linear-gradient(180deg, #131519 0%, #0d0e11 100%);
}

/* A bolha NÃO pode ter white-space:pre-wrap: isso transformaria as quebras de linha e a
   indentação do HTML ENTRE os filhos (citação, mídia, texto, horário, ações) em linhas em
   branco visíveis — inflando a bolha (bug das "bolhas gigantes vazias"). O pre-wrap fica só
   no .msg-text (o corpo da mensagem), preservando quebras REAIS digitadas pelo cliente/bot. */
.msg-bubble { max-width: min(75%, 46rem); overflow-wrap: break-word; position: relative; }
.msg-text { white-space: pre-wrap; overflow-wrap: break-word; }
/* Ações da mensagem (reagir/responder/…): pílula FLUTUANTE. Antes eram inline dentro da
   bolha (hidden -> flex no hover), o que CRESCIA a bolha ~28px ao passar o mouse — um
   layout-shift que incomodava. Agora ficam absolutas: aparecem no hover SEM redimensionar
   nada. Cor neutra (ficam fora da bolha colorida) e um leve chip p/ legibilidade. */
.msg-actions {
  position: absolute; top: calc(100% - 5px); z-index: 6;
  margin: 0 !important; padding: 2px 7px; border-radius: 9999px;
  background: var(--panel); box-shadow: var(--shadow-1);
  color: #6b7280 !important; max-width: max-content;
}
/* Ancora no lado da bolha e cresce para o ESPAÇO VAZIO — senão em bolha estreita a pílula
   sai pra fora da tela (bug): saída (dir.) ancora à direita e cresce p/ esquerda; entrada
   (esq.) ancora à esquerda e cresce p/ direita. */
.msg-actions.a-right { right: 2px; }
.msg-actions.a-left  { left: 2px; }
.dark .msg-actions { background: #212830; color: #9aa3ad !important; }
/* P12: pílula "nova mensagem" — flutua centralizada no rodapé da thread (fora do scroll). */
.thread-pill { position: absolute; left: 50%; bottom: .75rem; transform: translateX(-50%); z-index: 20; }
/* P12: "mostrar na conversa" — anel na cor da marca que some sozinho. */
@keyframes msg-flash { 0%, 55% { box-shadow: 0 0 0 3px var(--brand); } 100% { box-shadow: 0 0 0 0 transparent; } }
.msg-flash { animation: msg-flash 2.2s ease-out; }
@media (prefers-reduced-motion: reduce) { .msg-flash { animation: none; box-shadow: 0 0 0 3px var(--brand); } }
/* P12: botões redondos sobre a miniatura da galeria (baixar / mostrar na conversa). */
.gal-btn { display: inline-flex; align-items: center; justify-content: center; width: 1.75rem; height: 1.75rem;
           border-radius: 9999px; background: rgba(11, 14, 18, .66); color: #fff; }
.gal-btn:hover { background: rgba(11, 14, 18, .85); }
/* P12: painel do sino de alertas. No celular o botão fica no meio da barra e um dropdown de 20rem
   ancorado nele sairia da tela: preso à viewport, logo abaixo da barra (h-14), com 1rem de margem.
   Do sm em diante, dropdown normal alinhado à direita do botão. */
.alerts-panel { position: fixed; left: 1rem; right: 1rem; top: 3.5rem; }
@media (min-width: 640px) { .alerts-panel { position: absolute; left: auto; right: 0; top: 100%; width: 20rem; } }
/* Aba de emoji: grid fixo (CSS puro, sem risco de purge do Tailwind). */
.emoji-grid { display: grid; grid-template-columns: repeat(9, minmax(0, 1fr)); gap: 2px; }
.emoji-grid > button { font-size: 1.35rem; line-height: 1; padding: 3px; border-radius: 6px; }

/* ==========================================================================
   OV1 — Fundação premium: tokens de marca, polimento sensorial
   ========================================================================== */

/* Tokens VIVOS: acento da marca (barra de progresso global) + escada de elevação
   (consumida pelos boxShadow tokens) + cores semânticas. Os antigos --surface/--text/
   --border/--radius/--shadow-card foram removidos (0 consumidores — o app usa os
   utilitários Tailwind bg-white/slate-*). --brand aponta para o verde da marca. */
:root {
  --brand: #08745f;
  --brand-ink: #26b99b;
  --ok: #047857; --warn: #b7791f; --danger: #b91c1c;
  --shadow-1: 0 1px 2px -1px rgba(9,9,11,.10), 0 1px 3px 0 rgba(9,9,11,.05);
  --shadow-2: 0 2px 4px -2px rgba(9,9,11,.10), 0 8px 18px -6px rgba(9,9,11,.14);
  --shadow-3: 0 12px 24px -8px rgba(9,9,11,.16), 0 28px 56px -16px rgba(9,9,11,.30);
}
.dark {
  --brand: #26b99b;
  --brand-ink: #95f0cd;
  --ok: #34c99a; --warn: #e6ac4c; --danger: #f0696d;
  --shadow-1: 0 1px 2px 0 rgba(0,0,0,.45), inset 0 1px 0 0 rgba(255,255,255,.03);
  --shadow-2: 0 4px 14px -4px rgba(0,0,0,.60), inset 0 1px 0 0 rgba(255,255,255,.045);
  --shadow-3: 0 16px 40px -12px rgba(0,0,0,.75), inset 0 1px 0 0 rgba(255,255,255,.06);
}

/* Checkbox/radio nativos na cor da marca. Remove o AZUL default do browser — um dos "tells"
   clássicos de front gerado por IA. Cobre TODO o app de uma vez (inclusive telas novas),
   sem tocar em cada template. Onde o forms-plugin já pinta via text-brand-*, isto não atrapalha. */
input[type="checkbox"], input[type="radio"] { accent-color: var(--brand, #08745f); }

/* Seleção de texto na cor da marca. */
::selection { background: rgba(8, 116, 95, .22); }
::-moz-selection { background: rgba(8, 116, 95, .22); }

/* Skeletons com shimmer (percepção de velocidade premium). */
.skel { position: relative; overflow: hidden; background: #dbe2e9; border-radius: 8px; }
.dark .skel { background: #212830; }
.skel::after {
  content: ""; position: absolute; inset: 0; transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.55), transparent);
  animation: skel-shimmer 1.3s infinite;
}
.dark .skel::after { background: linear-gradient(90deg, transparent, rgba(255,255,255,.08), transparent); }
@keyframes skel-shimmer { 100% { transform: translateX(100%); } }
.skel-line { height: .8rem; border-radius: 6px; }

/* Barra de progresso global (topo) para requisições htmx/fetch. */
#global-progress {
  position: fixed; top: 0; left: 0; height: 2.5px; width: 0;
  background: linear-gradient(90deg, var(--brand), var(--brand-ink));
  z-index: 60; opacity: 0; transition: width .2s ease, opacity .3s ease;
  box-shadow: 0 0 8px var(--brand);
}
#global-progress.active { opacity: 1; }

/* Botões em requisição htmx: mostram estado "trabalhando". */
.htmx-request.btn-loading, button.htmx-request { position: relative; opacity: .75; pointer-events: none; }

/* Toasts premium: barra de progresso do TTL. */
@keyframes toast-countdown { from { width: 100%; } to { width: 0%; } }
.toast-progress { animation: toast-countdown linear forwards; }

/* Respeita preferência de menos movimento (WCAG 2.3.3). */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* Ações da mensagem (Reagir/Responder/Encaminhar/…): no desktop aparecem no hover ou ao
   focar por teclado (group-focus-within). Em telas de toque não há hover — então ficam
   sempre visíveis, senão seriam inalcançáveis (WCAG 2.5.x / operável sem ponteiro fino). */
@media (hover: none) {
  .msg-actions { display: flex !important; }
}

/* Inbox: status como informação, sem blocos saturados competindo com a conversa.
   P12 (tema claro): os textos claros que usavam #667380 davam 4,28:1 no painel (#eef1f3) → #48535e (7,1:1). */
.status--open { --inbox-status-color: #3d648a; }
.status--in-service { --inbox-status-color: #08745f; }
.status--pending { --inbox-status-color: #8b651f; }
.status--resolved { --inbox-status-color: #386d53; }
.status--closed { --inbox-status-color: #48535e; }
.dark .status--open { --inbox-status-color: #91b6dc; }
.dark .status--in-service { --inbox-status-color: #72d5bb; }
.dark .status--pending { --inbox-status-color: #d5b677; }
.dark .status--resolved { --inbox-status-color: #a0d5ae; }
.dark .status--closed { --inbox-status-color: #909daa; }
.inbox-status { display: inline-flex; align-items: center; gap: .4rem; font-size: 11px; font-weight: 600;
  line-height: 1.3; white-space: nowrap; color: var(--inbox-status-color, #667380); }
.inbox-status::before { content: ""; width: 6px; height: 6px; border-radius: 50%; flex: none;
  background: currentColor; }
.inbox-select-toggle { padding: .25rem .35rem; border: 0; border-radius: 4px; background: transparent;
  color: #48535e; font-size: 11px; font-weight: 600; cursor: pointer; }   /* P12: #667380 = 4,28:1 no painel claro */
.dark .inbox-select-toggle { color: #909daa; }
.inbox-select-toggle:hover, .inbox-select-toggle.is-active { color: #08745f; background: #ecfcf5; }
.dark .inbox-select-toggle:hover, .dark .inbox-select-toggle.is-active { color: #95f0cd; background: #173a33; }
.inbox-queue-filter { width: 100%; justify-content: center; padding: .35rem .25rem; border: 0;
  border-radius: 4px; background: transparent; cursor: pointer; }
.inbox-queue-filter:hover, .inbox-queue-count:hover { background: #ebeff3; }
.dark .inbox-queue-filter:hover, .dark .inbox-queue-count:hover { background: #343e48; }
.inbox-queue-count { width: 100%; padding: .25rem .5rem; border: 0; border-radius: 4px;
  background: transparent; color: #5f6670; font-size: 13px; font-variant-numeric: tabular-nums; cursor: pointer; }
.dark .inbox-queue-count { color: #909daa; }   /* P12: o #909daa (≈2,8:1 no branco) era o cinza do escuro também no claro */
.inbox-queue-count.is-present { color: var(--inbox-status-color); font-weight: 600; }
.inbox-status-control { display: flex; align-items: center; gap: .45rem; width: 133px; height: 34px;
  padding: 0 .6rem; border: 1px solid #c3cdd7; border-radius: 5px; background: #fff; }
.dark .inbox-status-control { border-color: #343e48; background: #1b2229; }
.inbox-status-control:focus-within { outline: 2px solid #08745f; outline-offset: 1px; }
.dark .inbox-status-control:focus-within { outline-color: #95f0cd; }
.inbox-status-dot { width: 7px; height: 7px; border-radius: 50%; flex: none; }
.inbox-status-dot { background: var(--inbox-status-color, #909daa); }
.inbox-status-select { min-width: 0; flex: 1; appearance: none; border: 0; padding: 0; outline: 0;
  background: transparent; color: #343e48; font: 500 12px InterVariable, Inter, sans-serif; cursor: pointer; }
.dark .inbox-status-select { color: #dbe2e9; }
.inbox-status-chevron { width: 13px; height: 13px; flex: none; color: #909daa; pointer-events: none; }
.inbox-icon-action { width: 34px; height: 34px; align-items: center; justify-content: center;
  border: 0; border-radius: 6px; background: transparent; color: #667380; cursor: pointer; }
.dark .inbox-icon-action { color: #909daa; }
.inbox-icon-action:hover { background: #ebeff3; color: #343e48; }
.dark .inbox-icon-action:hover { background: #29333b; color: #dbe2e9; }
.inbox-icon-action:focus-visible, .inbox-select-toggle:focus-visible, .inbox-queue-filter:focus-visible,
.inbox-queue-count:focus-visible, .inbox-tag-add:focus-visible, .inbox-tag-remove:focus-visible,
.inbox-field-manage:focus-visible { outline: 2px solid #08745f; outline-offset: 2px; }
.dark .inbox-icon-action:focus-visible, .dark .inbox-select-toggle:focus-visible,
.dark .inbox-queue-filter:focus-visible, .dark .inbox-queue-count:focus-visible,
.dark .inbox-tag-add:focus-visible, .dark .inbox-tag-remove:focus-visible,
.dark .inbox-field-manage:focus-visible { outline-color: #95f0cd; }
.inbox-window { display: inline-flex; align-items: center; gap: .35rem; white-space: nowrap;
  font-size: 11px; font-weight: 500; }
.inbox-window::before { content: ""; width: 5px; height: 5px; border-radius: 50%; background: currentColor; }
.inbox-window.is-closed { color: #a05b50; }
.inbox-window.is-waiting { color: #8b651f; }
.inbox-window.is-open { color: #48535e; }
.dark .inbox-window.is-closed { color: #d29a89; }
.dark .inbox-window.is-waiting { color: #d5b677; }
.dark .inbox-window.is-open { color: #909daa; }
.inbox-section-label { margin-bottom: .55rem; color: #48535e; font-size: 12px; font-weight: 600; }
.dark .inbox-section-label { color: #909daa; }
.inbox-tag-add { display: inline-flex; align-items: center; gap: .3rem; min-height: 28px;
  border: 0; padding: 0 .2rem; background: transparent; color: #48535e; font-size: 12px; cursor: pointer; }
.dark .inbox-tag-add { color: #aab7bf; }
.inbox-tag-add:hover, .inbox-field-manage:hover { color: #08745f; }
.dark .inbox-tag-add:hover, .dark .inbox-field-manage:hover { color: #95f0cd; }
.inbox-tag { display: inline-flex; align-items: center; gap: .4rem; min-height: 28px; max-width: 100%;
  padding: 0 .25rem 0 .55rem; border: 1px solid rgba(0,0,0,.1); border-radius: 5px;
  font-size: 12px; font-weight: 500; }
.inbox-tag-preview { min-height: 23px; padding: 0 .5rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.inbox-tag-remove { display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 20px; height: 20px; border: 0; border-radius: 4px; background: transparent;
  color: inherit; cursor: pointer; }
.inbox-tag-remove:hover { background: rgba(0,0,0,.14); }
.inbox-field-manage { margin-top: .6rem; border: 0; padding: 0; background: transparent;
  color: #48535e; font-size: 12px; font-weight: 500; cursor: pointer; }
.dark .inbox-field-manage { color: #aab7bf; }
@media (max-width: 639px) {
  .inbox-thread-header { display: grid; grid-template-columns: 28px minmax(0, 1fr) 34px 34px;
    grid-template-rows: auto 34px; column-gap: 8px; row-gap: 6px; height: auto;
    min-height: 0; padding: 10px 12px; }
  .inbox-thread-back { grid-column: 1; grid-row: 1; margin-left: 0; }
  .inbox-thread-avatar { display: none; }
  .inbox-contact-summary { grid-column: 2 / 5; grid-row: 1; }
  .inbox-contact-phone { white-space: nowrap; }
  .inbox-thread-header .inbox-status-control { grid-column: 1 / 3; grid-row: 2; }
  .inbox-thread-header .inbox-more { grid-column: 3; grid-row: 2; }
  .inbox-thread-header .inbox-context-trigger { grid-column: 4; grid-row: 2; }
}
