/* ============================================================================
   Utor Agent — tema da plataforma
   ----------------------------------------------------------------------------
   2026-11-05 (pedido do dono): a mesma FAMÍLIA visual do utor-nexus — fonte
   (Instrument Sans), tokens de cor, raio, sombra e movimento, barra lateral
   clara e estreita com o cartão da organização no rodapé. O que distingue os
   dois produtos é o acento: aqui o VIOLETA (#7c3aed), lá o índigo (#6366f1),
   mais a marca "Utor Agent" e o selo de produto no topo.

   O AdminLTE saiu da casca. Este arquivo carrega DEPOIS do Bootstrap 4 e tem
   duas partes: (1) os tokens e a casca (lateral, topo, conteúdo), que são
   deste arquivo; (2) a camada sobre os componentes do Bootstrap (cartões,
   botões, formulários, tabelas, selos, alertas…) que as 118 telas usam — essa
   parte veio do tema anterior e continua valendo. Os nomes antigos de token
   (`--brand-*`, `--page-bg`, `--ink`, `--muted`, `--line`) são mantidos como
   sinônimos dos novos (`--accent*`, `--bg`, `--text*`, `--border`) para a
   segunda parte não precisar mudar.

   Piso de ofício (Impeccable): texto sempre na cor oposta ao fundo e ≥ 4,5:1,
   nada de texto em gradiente, superfícies do navegador tematizadas (seleção,
   caret, foco). Movimento (Emil Kowalski): 100–200 ms, ease-out, nunca empurra
   a tela; tudo desligado com `prefers-reduced-motion`.
   ========================================================================== */
:root {
  /* ---- Tokens compartilhados com o Nexus (`spa/src/index.css`, tema claro) ---- */
  --bg: #f4f5fb;
  --bg-elevado: #ffffff;
  --bg-sidebar: #f7f7fc;
  --bg-hover: #eceef8;
  --bg-selecionado: #e4e7f6;
  --text: #4b5170;
  --text-h: #1e2235;
  --text-fraco: #5c6382;
  --border: #e8eaf3;
  --border-forte: #cfd3e8;
  --border-campo: #868cad;

  /* ---- O acento deste produto: violeta (o Nexus usa índigo) ---- */
  --accent: #7c3aed;
  --accent-forte: #6d28d9;
  --accent-bg: rgba(124, 58, 237, 0.10);
  --accent-border: rgba(124, 58, 237, 0.32);
  --accent-texto: #6d28d9;          /* 7,0:1 sobre branco — passa como texto e link */
  --accent-botao: #6d28d9;          /* branco sobre ele: 7,0:1 */
  --accent-botao-hover: #5b21b6;
  --accent-gradiente: linear-gradient(135deg, #7c3aed 0%, #6366f1 100%);

  --sucesso: #0f766e; --sucesso-bg: rgba(15, 118, 110, 0.10);
  --aviso: #b45309;   --aviso-bg: rgba(180, 83, 9, 0.10);
  --erro: #be123c;    --erro-bg: rgba(190, 18, 60, 0.10);
  --neutro-bg: rgba(0, 0, 0, 0.04);
  --code-bg: #f4f1ec;

  --sans: 'Instrument Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;

  /* ---- Sinônimos para a camada de componentes (nomes do tema anterior) ---- */
  --brand-a: var(--accent);
  --brand-b: #8b5cf6;
  --brand-gradient: var(--accent-gradiente);
  --brand-gradient-soft: linear-gradient(135deg, rgba(124, 58, 237, 0.10), rgba(99, 102, 241, 0.10));
  --brand-texto: var(--accent-texto);
  --brand-botao: var(--accent-botao);
  --brand-botao-hover: var(--accent-botao-hover);
  --page-bg: var(--bg);
  --surface: var(--bg-elevado);
  --ink: var(--text-h);
  --ink-soft: var(--text);
  --muted: var(--text-fraco);
  --line: var(--border);
  --ok: var(--sucesso);   --ok-soft: #ccfbf1;
  --warn: var(--aviso);   --warn-soft: #fef3c7;
  --bad: var(--erro);     --bad-soft: #ffe4e6;
  --info: #0369a1;        --info-soft: #e0f2fe;

  /* Raios do Nexus: cartão 14, botão 10, campo 6. */
  --radius: 14px;
  --radius-sm: 10px;
  --radius-xs: 6px;

  /* Escala de espaçamento base 4 (a mesma do Nexus). */
  --space-1: 4px; --space-2: 8px; --space-3: 12px; --space-4: 16px; --space-5: 24px; --space-6: 32px;

  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
  --shadow: 0 1px 2px rgba(30, 34, 53, 0.04), 0 8px 24px -12px rgba(30, 34, 53, 0.12);
  --shadow-lift: 0 2px 4px rgba(30, 34, 53, 0.05), 0 16px 32px -16px rgba(124, 58, 237, 0.25);

  /* ---- Medidas da casca ---- */
  --lateral-largura: 252px;
  --lateral-recolhida: 64px;
  --topo-altura: 56px;
  --anel-foco: var(--accent);
  --anel-foco-contraste: var(--bg-elevado);

  /* Mantidos por compatibilidade com regras antigas que ainda os citem. */
  --sidebar-a: var(--bg-sidebar);
  --sidebar-b: var(--bg-sidebar);
}

/* ---------------------------------------------------------------------------
   Base
--------------------------------------------------------------------------- */
html { scrollbar-width: thin; }
body {
  font-family: var(--sans);
  font-size: 0.9375rem;
  line-height: 1.5;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5 { color: var(--text-h); font-weight: 650; letter-spacing: -0.01em; }
a { color: var(--brand-texto); text-underline-offset: 2px; }
a:hover { color: var(--brand-botao-hover); }
::selection { background: color-mix(in srgb, var(--accent) 24%, transparent); color: var(--text-h); }
:root { caret-color: var(--accent); accent-color: var(--accent); }
code { font-family: var(--mono); }

.text-muted { color: var(--muted) !important; }
/* As cores de texto do Bootstrap 4 reprovam como texto sobre branco e `text-primary` é azul, fora da marca. */
.text-primary { color: var(--brand-texto) !important; }
.text-success { color: var(--ok) !important; }
.text-warning { color: var(--warn) !important; }
.text-danger { color: var(--bad) !important; }
.text-info { color: var(--info) !important; }

/* "Pular para o conteúdo": primeiro Tab da página; invisível até receber o foco. */
.pular-conteudo {
  position: fixed; top: -100px; left: 16px; z-index: 2147483001;
  padding: 10px 16px; border-radius: var(--radius-sm); border: 1px solid var(--accent);
  background: var(--bg-elevado); color: var(--text-h); font-weight: 600; text-decoration: none; box-shadow: var(--shadow);
  transition: top 0.15s var(--ease-out);
}
.pular-conteudo:focus { top: 16px; }

/* ---------------------------------------------------------------------------
   A casca: lateral + principal (topo, conteúdo, rodapé)
--------------------------------------------------------------------------- */
.wrapper { display: flex; min-height: 100vh; }
.principal { flex: 1; min-width: 0; display: flex; flex-direction: column; min-height: 100vh; }
.content-wrapper { flex: 1; background: var(--bg); }

/* Lateral: coluna fixa à esquerda, grudada; estreita quando recolhida. */
.lateral {
  position: sticky; top: 0; height: 100vh; z-index: 1040;
  width: var(--lateral-largura); flex: 0 0 auto;
  display: flex; flex-direction: column;
  background: var(--bg-sidebar);
  border-right: 1px solid var(--border);
  transition: width 0.2s var(--ease-out);
}
html.lateral-recolhida .lateral { width: var(--lateral-recolhida); }

.lateral-topo { display: flex; align-items: center; gap: 6px; min-height: var(--topo-altura); padding: 10px 10px 6px 12px; flex-shrink: 0; }
.lateral-marca { display: flex; align-items: center; gap: 10px; min-width: 0; color: var(--text-h); text-decoration: none; }
.lateral-marca:hover { color: var(--text-h); text-decoration: none; }
.lateral-marca__logo { width: 28px; height: 28px; border-radius: 7px; object-fit: contain; flex: none; }
.lateral-marca__nome { font-weight: 700; font-size: 1rem; letter-spacing: -0.01em; white-space: nowrap; }
.lateral-marca__nome b { color: var(--accent-texto); font-weight: 700; }

/* O botão de ícone da casca: 32px, quadrado arredondado, sem fundo até o hover. */
.lateral-botao {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; padding: 0; border: 0; border-radius: var(--radius-sm);
  background: transparent; color: var(--text-fraco); font-size: 0.95rem; line-height: 1; cursor: pointer;
  position: relative; text-decoration: none; flex: none;
  transition: background 0.12s var(--ease-out), color 0.12s var(--ease-out);
}
.lateral-botao:hover { background: var(--bg-hover); color: var(--text-h); text-decoration: none; }
.lateral-recolher { margin-left: auto; }
html.lateral-recolhida .lateral-recolher i { transform: rotate(180deg); }
.lateral-fechar { display: none; margin-left: auto; }

/* Navegação: itens de 36px, raio 10, acento no ativo — o `.nav-item` do Nexus. */
.lateral-nav { flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden; padding: 2px 10px 12px; display: grid; gap: 2px; align-content: start; scrollbar-width: thin; }
.lateral-secao { font-size: 0.68rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-fraco); padding: 14px 10px 6px; white-space: nowrap; overflow: hidden; }
.lateral-item {
  display: flex; align-items: center; gap: 10px; min-height: 36px; padding: 0 10px;
  border-radius: var(--radius-sm); border: 1px solid transparent;
  color: var(--text-fraco); font-size: 0.9333rem; font-weight: 500; text-decoration: none; cursor: pointer; user-select: none;
  transition: background 0.1s ease, color 0.1s ease, border-color 0.1s ease;
}
.lateral-item:hover { background: var(--bg-hover); color: var(--text-h); border-color: color-mix(in srgb, var(--border) 72%, transparent); text-decoration: none; }
.lateral-item.ativo { background: var(--accent-bg); border-color: var(--accent-border); color: var(--text-h); }
.lateral-item__icone { width: 22px; flex: 0 0 22px; display: flex; align-items: center; justify-content: center; opacity: 0.72; font-size: 0.95rem; }
.lateral-item:hover .lateral-item__icone, .lateral-item.ativo .lateral-item__icone { opacity: 1; }
.lateral-item.ativo .lateral-item__icone { color: var(--accent); }
.lateral-item__texto { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Grupos: <details> nativo. A seta gira; o marcador padrão sai. */
.lateral-grupo > summary { list-style: none; }
.lateral-grupo > summary::-webkit-details-marker { display: none; }
.lateral-grupo__seta { margin-left: auto; font-size: 0.65rem; opacity: 0.6; transition: transform 0.15s var(--ease-out); }
.lateral-grupo[open] .lateral-grupo__seta { transform: rotate(90deg); }
.lateral-sub { display: grid; gap: 1px; padding: 2px 0 4px 30px; }
.lateral-subitem {
  display: block; padding: 6px 10px; border-radius: 8px;
  font-size: 0.88rem; color: var(--text-fraco); text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  transition: background 0.1s ease, color 0.1s ease;
}
.lateral-subitem:hover { background: var(--bg-hover); color: var(--text-h); text-decoration: none; }
.lateral-subitem.ativo { color: var(--accent-texto); background: var(--accent-bg); font-weight: 600; }
.lateral-subitem--beta { opacity: 0.55; cursor: default; }
.lateral-subitem--beta:hover { background: transparent; color: var(--text-fraco); }

/* Selo "Beta": presente, identificado, morto. */
.beta-badge {
  display: inline-block; font-size: 0.58rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  padding: 0.14em 0.55em; border-radius: 999px; vertical-align: 0.12em; margin-left: 0.4rem;
  background: var(--accent-bg); color: var(--accent-texto); border: 1px solid var(--accent-border);
}

/* Rodapé da lateral: o cartão de quem está logado e onde, mais Senha e Sair. */
.lateral-rodape { flex-shrink: 0; display: flex; align-items: center; gap: 4px; padding: 8px 10px; border-top: 1px solid var(--border); }
.lateral-conta { flex: 1; min-width: 0; display: flex; align-items: center; gap: 8px; padding: 4px 6px; border-radius: var(--radius-sm); }
.lateral-conta__texto { display: flex; flex-direction: column; min-width: 0; gap: 1px; }
.lateral-conta__nome { font-size: 0.86rem; font-weight: 600; color: var(--text-h); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lateral-conta__sub { font-size: 0.74rem; color: var(--text-fraco); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.avatar-chip {
  width: 28px; height: 28px; flex: none; border-radius: 999px;
  background: var(--accent-gradiente); color: #fff; font-size: 0.8rem; font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center;
}
.user-chip { display: flex; align-items: center; gap: 0.55rem; }
.user-chip .user-email { font-size: 0.82rem; font-weight: 600; color: var(--text); }

/* Recolhida: só ícones, centrados; textos, seções, setas, subitens e o cartão somem. */
html.lateral-recolhida .lateral-marca__nome,
html.lateral-recolhida .lateral-item__texto,
html.lateral-recolhida .lateral-grupo__seta,
html.lateral-recolhida .lateral-sub,
html.lateral-recolhida .lateral-conta__texto,
html.lateral-recolhida .lateral-secao { display: none; }
html.lateral-recolhida .lateral-topo { flex-direction: column; gap: 8px; padding: 10px 0 6px; align-items: center; }
html.lateral-recolhida .lateral-recolher { margin-left: 0; }
html.lateral-recolhida .lateral-nav { padding: 2px 8px 12px; }
html.lateral-recolhida .lateral-item { justify-content: center; padding: 0; }
html.lateral-recolhida .lateral-grupo { position: relative; }
html.lateral-recolhida .lateral-rodape { flex-direction: column; padding: 8px 6px; }
html.lateral-recolhida .lateral-conta { justify-content: center; padding: 4px 0; }

/* Topo: grudado, translúcido, com o selo do produto e a organização. */
.topo {
  position: sticky; top: 0; z-index: 1035;
  display: flex; align-items: center; gap: 12px;
  min-height: var(--topo-altura); padding: 0 var(--space-5);
  background: color-mix(in srgb, var(--bg) 86%, transparent);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
}
.topo-menu { display: none; }
.topo-contexto { display: flex; align-items: center; gap: 10px; min-width: 0; font-size: 0.9rem; color: var(--text-fraco); }
.topo-contexto strong { color: var(--text-h); font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.topo-produto {
  flex: none; font-size: 0.7rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--accent-texto); background: var(--accent-bg); border: 1px solid var(--accent-border); border-radius: 999px; padding: 2px 9px;
}
.topo-acoes { margin-left: auto; display: flex; align-items: center; gap: 2px; }
.topo-acao { width: 36px; height: 36px; font-size: 1rem; }

/* O fundo escuro atrás da gaveta (celular). */
.casca-fundo { display: none; position: fixed; inset: 0; background: rgba(30, 34, 53, 0.42); z-index: 1039; }

/* Tela estreita: a lateral vira gaveta; o topo ganha o botão de abrir. */
@media (max-width: 991.98px) {
  .lateral {
    position: fixed; left: 0; top: 0; height: 100vh; width: var(--lateral-largura) !important;
    transform: translateX(-100%); box-shadow: 0 0 0 1px var(--border), 0 24px 48px -24px rgba(30, 34, 53, 0.4);
    transition: transform 0.2s var(--ease-out);
  }
  html.lateral-aberta .lateral { transform: none; }
  html.lateral-aberta .casca-fundo { display: block; }
  html.lateral-aberta { overflow: hidden; }
  .lateral-recolher { display: none; }
  .lateral-fechar { display: inline-flex; }
  .topo-menu { display: inline-flex; }
  .topo { padding: 0 var(--space-4); }
  /* Na gaveta a lateral está sempre expandida, mesmo com a preferência "recolhida" guardada. */
  html.lateral-recolhida .lateral-marca__nome, html.lateral-recolhida .lateral-item__texto, html.lateral-recolhida .lateral-grupo__seta,
  html.lateral-recolhida .lateral-sub, html.lateral-recolhida .lateral-conta__texto, html.lateral-recolhida .lateral-secao { display: revert; }
  html.lateral-recolhida .lateral-sub { display: grid; }
  html.lateral-recolhida .lateral-conta__texto { display: flex; }
  html.lateral-recolhida .lateral-topo { flex-direction: row; padding: 10px 10px 6px 12px; }
  html.lateral-recolhida .lateral-item { justify-content: flex-start; padding: 0 10px; }
  html.lateral-recolhida .lateral-rodape { flex-direction: row; padding: 8px 10px; }
}

@media (prefers-reduced-motion: reduce) {
  .lateral, .lateral-item, .lateral-subitem, .lateral-botao, .lateral-grupo__seta, .pular-conteudo { transition: none !important; }
}

/* ---------------------------------------------------------------------------
   Respiro da área de conteúdo — o mesmo em toda tela

   Não há mais cabeçalho de página (nem h1, nem barra de breadcrumb): o topo
   de toda tela é o topo do Painel, e o conteúdo começa sempre na mesma
   altura. O que sobra é definir esse "sempre" em um lugar só.

   O AdminLTE entrega `.content-wrapper > .content { padding: 0 .5rem }` —
   zero em cima e embaixo, que é o que deixava o primeiro card colado na
   barra superior.

   O SELETOR AQUI PRECISA SER O MESMO, e isso não é estilo: escrito como
   `.content` (uma classe) a regra perde para a do AdminLTE (duas classes)
   por especificidade e não vale nada — o arquivo carregar depois não salva.
   Foi exatamente o que aconteceu na primeira tentativa: o CSS estava certo,
   a página não mudava, e o motivo era este. Mesma especificidade + carregado
   depois = ganha.

   Duas variáveis, não uma — mesmo o topo valendo hoje o mesmo que os outros
   três lados (ajuste do dono, 2026-09-07: primeiro 48px/o dobro pareceu
   grande demais na tela real, agora é igual ao resto, 24px). `--page-pad-top`
   continua separada de `--page-pad` porque o chat lê as duas por fora
   (`chat/index.html`, no `calc()` da altura da casca) — remover a variável
   quebraria essa conta silenciosamente. `--page-pad-top: var(--page-pad)`
   deixa a igualdade de hoje explícita e reversível: subir o topo de novo é
   trocar um valor num lugar só, sem caçar todo `padding-top` da plataforma.

   Nos lados, os 0.5rem daqui somam com os 15px do `.container-fluid` de
   dentro (~1.44rem no total).

   Toda tela da plataforma passa por `.content` (o `base.html` é a casca de
   todas as 65 páginas do app), então mexer aqui move o respiro de todas de
   uma vez — que é o ponto. Fora daqui ficam só as telas que não usam a
   casca: login, erros 403/404/500 e a página pública, todas centralizadas
   na tela inteira, onde margem de topo não significa a mesma coisa.
--------------------------------------------------------------------------- */
:root {
  --page-pad: var(--space-5);     /* 24px — respiro geral (lados e base) */
  --page-pad-top: var(--page-pad); /* 24px — igual aos outros três lados */
}
.content-wrapper > .content { padding: var(--page-pad-top) 0.5rem var(--page-pad); }

/* ---------------------------------------------------------------------------
   Cards
--------------------------------------------------------------------------- */
/* Cartão no idioma do Nexus (2026-11-05): superfície branca com borda fina e sombra leve — não a
   "caixa flutuante" sem borda do AdminLTE. */
.card {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-elevado);
  box-shadow: 0 1px 2px rgba(30, 34, 53, 0.03);
  /* FE15/B5: 20px estava fora da escala de 4 (FE2). Card irmão de card é
     "uma seção e a próxima" — o mesmo degrau da `.section-label` nova. */
  margin-bottom: var(--gap-md);
}

.card-header {
  background: transparent;
  border-bottom: 1px solid var(--line);
  padding: 0.95rem 1.25rem;
  border-top-left-radius: var(--radius) !important;
  border-top-right-radius: var(--radius) !important;
}

.card-title {
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--ink);
  /* FE15/A1: o AdminLTE flutua o título (`float: left`) e `d-block`/`mb-1`
     não cancelam float — o subtítulo escorria ao lado ("APIs cadastradasCada
     linha…" em seis telas). Título é bloco; quem quer ação na mesma linha usa
     `d-flex justify-content-between` no `.card-header`. */
  float: none;
}

/* FE15/B6-B7: a linha de apoio — o subtítulo sob o `.card-title` e o texto
   que explica uma tela ou um bloco. Antes era `<p class="text-muted mb-0"
   style="font-size:.82rem;">` copiado em ~30 templates, sem teto de largura
   (chegava a ~1150px numa linha). Mesmo teto de leitura do `.form-text`. */
.linha-de-apoio {
  font-size: 0.82rem;
  color: var(--muted);
  margin: 0;
  max-width: 60ch;
  text-align: left;
}
.card-title + .linha-de-apoio { margin-top: 0.25rem; }

.card-footer {
  background: var(--bg);
  border-top: 1px solid var(--line);
  border-bottom-left-radius: var(--radius) !important;
  border-bottom-right-radius: var(--radius) !important;
}

/* Cards de destaque com faixa em gradiente no topo.
   FE15/B3 — quando a faixa aparece (uma regra, não gosto de quem escreveu o
   template): ela marca o card que a pessoa LÊ ou PREENCHE — o guia de uma
   tela, o formulário principal, a política, o widget principal do painel.
   Lista, histórico e card secundário nunca a usam ("Últimas alterações" do
   painel a tinha e perdeu). Irmãos só a repetem quando são etapas do mesmo
   formulário (organizations/create). */
.card.card-accent { overflow: hidden; position: relative; }
.card.card-accent::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 3px;
  background: var(--accent);
}

/* ---------------------------------------------------------------------------
   Stat cards — os widgets do dashboard (substituem o .small-box do AdminLTE)
--------------------------------------------------------------------------- */
.stat-card {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.15rem 1.25rem;
  background: var(--surface);
  box-shadow: 0 1px 2px rgba(30, 34, 53, 0.03);
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: var(--gap-md);
  transition: transform 0.15s ease, box-shadow 0.15s ease;
  color: inherit;
}
a.stat-card { text-decoration: none; }
a.stat-card:hover {
  transform: translateY(-1px);
  border-color: var(--accent-border);
  box-shadow: var(--shadow);
  color: inherit;
}

/* O ícone do número: pastilha SUAVE (fundo tingido, ícone na cor) em vez do bloco saturado
   com gradiente e sombra colorida — o idioma do Nexus, e menos gritaria num painel com
   quatro números lado a lado. */
/* `.stat-icon` tambem fora de um `.stat-card` (ex.: a inicial da organizacao na lista de
   organizacoes, 2026-11-06): sem o flex a letra ficava descentralizada. */
.stat-icon,
.stat-card .stat-icon {
  width: 44px;
  height: 44px;
  min-width: 44px;
  border-radius: 12px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  font-weight: 700;
  color: var(--accent-texto);
  background: var(--accent-bg);
  font-size: 1.05rem;
}

.stat-card .stat-value {
  font-size: 1.7rem;
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.stat-card .stat-label {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--muted);
  margin-top: 0.15rem;
}

.stat-card .stat-hint {
  font-size: 0.72rem;
  color: var(--muted);
  margin-top: 0.1rem;
}

/* A fração "/ total" ao lado do número (painel) — era `style="font-size:
   .55em"` em cada stat-card. */
.stat-card .stat-value small { font-size: 0.55em; font-weight: 600; color: var(--muted); }

/* Variantes de gradiente dos ícones */
/* As "variantes de gradiente" viraram pastilhas suaves por estado; os nomes `grad-*` ficam
   porque os templates os usam. */
.stat-icon.grad-brand { background: var(--accent-bg); color: var(--accent-texto); }
.stat-icon.grad-teal { background: var(--ok-soft); color: var(--ok); }
.stat-icon.grad-amber { background: var(--warn-soft); color: var(--warn); }
.stat-icon.grad-rose { background: var(--bad-soft); color: var(--bad); }
.stat-icon.grad-sky { background: var(--info-soft); color: var(--info); }
.stat-icon.grad-slate { background: var(--neutro-bg); color: var(--text-fraco); }

/* ---------------------------------------------------------------------------
   Botões
--------------------------------------------------------------------------- */
.btn {
  border-radius: var(--radius-sm);
  font-weight: 600;
  font-size: 0.875rem;
  padding: 0.5rem 1rem;
  line-height: 1.25;
  transition: background-color 0.1s ease, border-color 0.1s ease, color 0.1s ease,
              transform 0.1s var(--ease-out);
}
.btn-sm { padding: 0.3rem 0.75rem; font-size: 0.78rem; }

/* FE16/B15 (2026-10-27) — quando um botão ocupa a largura toda (`btn-block`):
   só numa COLUNA ESTREITA, onde a largura do botão é a da coluna — a coluna
   do chat ("Nova conversa"), a coluna da inbox ("Conectar canal", ações do
   contato), o sub-card de um canal na aba Canais, a lateral de um formulário
   de integração, as telas de login/senha. Num card ou formulário de largura
   total, nunca: o botão fica do tamanho do texto, à esquerda da barra de
   ações (`.builder-actions`). Os 18 usos de hoje seguem a regra. */

/* FE15/A3: o AdminLTE sublinha todo `a` dentro de `.alert` (`.alert a {
   text-decoration: underline }`), e um `<a class="btn">` no alerta ("Ver o
   que mudou", "Ver as ferramentas") ficava com borda de botão E sublinhado
   de link — dois sinais de clicável no mesmo elemento. */
.btn, .btn:hover, .btn:focus, .alert .btn, .alert .btn:hover { text-decoration: none; }

/* FE15/A8 (achado ao medir o A3): o mesmo AdminLTE pinta de BRANCO todo `a`
   dentro de `.alert` (`.alert a { color: #fff }`) — um `<a class="btn
   btn-outline-dark">` no alerta amarelo ficava branco sobre amarelo ("Ver o
   que mudou" quase invisível nas 14 abas; medido: rgb(255,255,255)). Cada
   contornado recupera a própria cor; no hover o Bootstrap já põe o fundo da
   variante com texto branco. */
.alert a.btn-outline-dark { color: #343a40; }
.alert a.btn-outline-secondary { color: #6c757d; }
.alert a.btn-outline-primary { color: var(--brand-texto); }
.alert a.btn-outline-danger { color: var(--bad); }
.alert a.btn-outline-success { color: var(--ok); }
.alert a.btn-outline-dark:hover, .alert a.btn-outline-secondary:hover,
.alert a.btn-outline-primary:hover, .alert a.btn-outline-danger:hover,
.alert a.btn-outline-success:hover { color: #fff; }

/* O botão responde ao clique na hora (padrão do Nexus) — sem isto a tela
   parece não ter "ouvido". Nunca no desabilitado: não há o que confirmar. */
.btn:active:not(:disabled):not(.disabled) { transform: scale(0.97); }

/* O anel do Bootstrap aparecia também no CLIQUE de mouse; o foco de teclado
   agora vem do anel único de `:focus-visible` (ver "Foco", abaixo). */
.btn:focus, .btn.focus { box-shadow: none; }

/* Botões SÓLIDOS, como no Nexus. O gradiente da marca segue na identidade
   (sidebar, ícones, selos), mas como fundo de texto branco reprovava: 4,23
   a 4,47:1 no primário, 3,74 no sucesso, 3,19 no aviso. Os sólidos abaixo dão
   5,0 a 6,3:1. */
.btn-primary {
  background: var(--brand-botao);
  /* FE15/A2: `border: 0` encolhia o sólido 2px em relação ao contornado do
     mesmo tamanho (28 × 30 no par Testar/Publicar). A borda existe,
     transparente — mesma caixa, mesma cor. Vale para todos os sólidos. */
  border: 1px solid transparent;
  box-shadow: 0 6px 16px -10px rgba(109, 40, 217, 0.6);
}
.btn-primary:hover, .btn-primary:focus, .btn-primary:active,
.btn-primary:not(:disabled):not(.disabled):active {
  background: var(--brand-botao-hover) !important;
  border-color: transparent;
  box-shadow: 0 8px 20px -10px rgba(91, 33, 182, 0.7);
}

.btn-outline-primary {
  color: var(--brand-texto);
  border-color: var(--accent-border);
}
.btn-outline-primary:hover {
  background: var(--brand-botao);
  border-color: transparent;
}

.btn-success { background: var(--ok); border: 1px solid transparent; }
.btn-success:hover { background: #115e59; }
.btn-danger { background: var(--bad); border: 1px solid transparent; }
.btn-danger:hover { background: #9f1239; }
.btn-warning { background: var(--warn); border: 1px solid transparent; color: #fff; }
.btn-warning:hover { background: #92400e; color: #fff; }

.btn-light, .btn-default, .btn-secondary.btn-flat {
  border-radius: var(--radius-sm);
}

/* ---------------------------------------------------------------------------
   Builder — padrão único de seção, ação e espaçamento (Ciclo v22, FE1-FE7)
   ----------------------------------------------------------------------------
   Antes desta faixa, cada aba do builder (Modelo, Canais, Regras, Limites,
   Intenções, Ferramentas, Versões, Atividade…) resolvia divisor de seção,
   tamanho de botão e respiro vertical à mão, sozinha — o resultado eram 14
   telas com a MESMA função (form + lista + ação) e 14 aparências diferentes.
   Esta faixa fixa três padrões reutilizáveis em vez de continuar deixando
   cada template inventar o próprio.

   1. `.section-label` substitui o `<h5>Título solto</h5>` usado só para
      separar um bloco do outro — mesma informação, uma linha compacta em
      vez de um heading inteiro com a métrica de uma página. É o padrão para
      TODA divisão dentro de uma aba que já tem seu próprio título (a aba
      inteira já diz "Canais"; "Canais conectados" dentro dela é redundante
      e caro em altura).
   2. `.builder-actions` é a barra de ação única: botão principal + texto de
      status ao lado, sempre no mesmo espaçamento — hoje cada aba escrevia
      esse par com classe (`ml-2`, `mt-2`) e alinhamento levemente diferentes.
   3. Escala fixa de respiro entre blocos (`--gap-tight/sm/md`) para trocar
      a mistura de `mb-3`/`mb-4`/`mt-3`/`mt-4` por uma decisão sobre O QUE o
      espaço representa (item de lista, bloco de formulário, seção nova) em
      vez de qual valor "pareceu certo" para quem escreveu aquele template.
--------------------------------------------------------------------------- */
:root {
  --gap-tight: var(--space-2); /* 8px — entre linhas de uma lista compacta (card mb-2) */
  --gap-sm: var(--space-4);    /* 16px — entre um bloco de formulário e o seguinte */
  --gap-md: var(--space-5);    /* 24px — entre uma seção lógica e a próxima, dentro da aba
                                  (era 28px, fora da escala; o degrau mais perto é 24) */
}

/* Rótulo de seção compacto — troca heading solto por uma linha fina com
   régua embaixo. Ocupa ~1.6rem de altura contra os ~3rem de um `<h5>` com
   margem; a régua já faz o trabalho visual de "acabou um bloco, começa
   outro" que o texto sozinho fazia com espaço em branco. */
.section-label {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  /* FE4 (ajuste do dono, 2026-09-07): a primeira versão deixava o conteúdo
     colado embaixo da régua — compacto demais lido como "quebrado", não
     como "denso". `--gap-sm` dá o respiro mínimo para separar visualmente
     sem devolver a altura de um heading inteiro. */
  margin: 0 0 var(--gap-sm);
  padding-bottom: 0.4rem;
  border-bottom: 1px solid var(--line);
}
/* Primeiro rótulo da aba não herda respiro de nada acima; os seguintes
   marcam a entrada numa seção lógica nova (mesmo valor sempre, `--gap-md`,
   nunca escolhido ad-hoc por template). */
.section-label { margin-top: 0; }
.section-label.is-new-section { margin-top: var(--gap-md); }

/* Barra de ação única: botão + status inline, sempre com o mesmo respiro
   entre os dois — reusada em toda aba que salva algo no rascunho. */
.builder-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.65rem;
  margin-top: 0.25rem;
}
.builder-actions .builder-actions-note {
  font-size: 0.82rem;
  color: var(--muted);
  margin: 0;
}

/* Bloco de código reutilizável — os três trechos de exemplo em "Como
   embarcar" (assinatura HMAC, script na página) e o embed do widget
   repetiam o mesmo `style=` inline em cada `<pre>`; um só lugar agora. */
.code-block {
  background: #f7f8fe;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  font-size: 0.8rem;
  overflow-x: auto;
  padding: 0.9rem 1rem;
  margin: 0 0 0.75rem;
}
.code-block:last-child { margin-bottom: 0; }

/* Cartão de linha compacta — a mesma estrutura de "card com uma linha de
   conteúdo + uma ação à direita" se repete em Regras, Intenções e o
   comportamento por canal (antes cada template escrevia `card-body py-2`
   à mão; a classe no `<div class="card">` agora garante o mesmo padding
   sem repetir o valor em cada `card-body`). Regra geral de padding de
   `.card-body` no builder, agora explícita:
     - padrão (sem classe extra) → conteúdo denso: formulário, texto
       explicativo, bloco de código (`tab_limits`, `tab_mapa` "Colocar no
       site");
     - `.builder-row-card` → uma linha de lista dentro de um `card` (uma
       regra, uma intenção, um vínculo de canal — sempre com botão de ação
       à direita);
     - `p-0` → conteúdo que já é uma lista flush (`list-group-flush`) e não
       precisa de respiro extra do card por cima do próprio da lista;
     - vários `card-body` no MESMO card (o widget de consumo): só o lado que
       encosta no vizinho zera (`pb-0` no de cima, `pt-0` no de baixo);
     - lista de linhas "rótulo … número" → `p-0` + `.lista-de-numeros`, nunca
       `py-2` no body com `py-2` em cada linha por cima (FE15/B4).
--------------------------------------------------------------------------- */
.builder-row-card + .builder-row-card { margin-top: var(--gap-tight); }
.builder-row-card .card-body { padding-top: 0.5rem; padding-bottom: 0.5rem; }

/* Grid de campo — resolve FE5 sem exigir que cada template decida à mão
   quais campos são "curtos" (cabem par a par) e quais são "longos" (textarea,
   lista de opções). `:has()` deixa a REGRA no CSS, olhando o que o widget
   realmente é, em vez de o template chutar `col-md-6` só nalguns lugares
   (`tab_channels`) e empilhar tudo em largura total nos demais (`tab_model`,
   `tab_tools`). Campo estreito → ocupa a menor coluna que couber (mín.
   16rem); campo largo (texto corrido, lista de checkbox) → a linha inteira,
   sempre. Degrada bem em navegador sem `:has()`: vira uma coluna só, que já
   era o comportamento antigo. */
.field-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: 0 var(--gap-sm);
  align-items: start;
}
.field-grid .form-group:has(textarea),
.field-grid .form-group:has(.custom-control),
.field-grid .form-group:has(input[type="checkbox"]),
.field-grid .form-group:has(input[type="radio"]),
.field-grid .form-group:has(.alert) {
  grid-column: 1 / -1;
}

/* ---------------------------------------------------------------------------
   Formulários
--------------------------------------------------------------------------- */
/* Contorno do campo: #dfe3f0 dava 1,3:1 com o fundo, e o contorno de um campo
   é componente (WCAG 1.4.11 pede 3:1). #868cad é o `--border-campo` do Nexus. */
.form-control, .custom-select {
  border-radius: var(--radius-xs);
  border-color: #868cad;
  color: var(--ink);
  font-size: 0.9rem;
}
/* A borda acompanha a marca; o anel vem da regra única de foco. */
.form-control:focus, .custom-select:focus {
  border-color: var(--brand-a);
  box-shadow: none;
}

label { font-weight: 600; font-size: 0.85rem; color: var(--ink-soft); }
/* FE9: texto de apoio nunca justifica (blocos curtos de HTML com
   justificação geram buracos de espaço irregulares) e nunca estica além do
   confortável para leitura — ~75 caracteres é o teto reconhecido antes de a
   linha cansar o olho. Sem isso, um `form-text` dentro de uma coluna larga
   (ex.: `.field-grid` de uma coluna só) vira uma linha corrida a largura de
   tela inteira, mais larga que o próprio campo que ela explica. */
.form-text, .helptext {
  font-size: 0.78rem;
  color: var(--muted);
  max-width: 60ch;
  text-align: left;
}

.input-group-text {
  border-radius: var(--radius-xs);
  border-color: #868cad;
  background: var(--bg);
  color: var(--muted);
}

/* ---------------------------------------------------------------------------
   Tabelas
   FE15/B9 — qual tabela onde: lista de entidades (agentes, credenciais,
   trabalhos, documentos) é `table table-hover mb-0` dentro de `card-body
   p-0`; lista de pares campo→valor (alterações pendentes, versões) é `table
   table-sm`. `.table td` já fixa o tamanho da fonte — nenhum `<td>` precisa
   de `style="font-size"` (os 21 que tinham foram limpos).
--------------------------------------------------------------------------- */
.table thead th {
  border-top: 0;
  border-bottom: 1px solid var(--line);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 0.7rem 1.25rem;
  white-space: nowrap;
}

.table td {
  padding: 0.75rem 1.25rem;
  border-top: 1px solid var(--line);
  vertical-align: middle;
  font-size: 0.875rem;
}

.table-hover tbody tr:hover { background: var(--bg-hover); }

.table td a { font-weight: 600; }

/* ---------------------------------------------------------------------------
   Badges — pílulas suaves (fundo pastel + texto forte)
--------------------------------------------------------------------------- */
.badge {
  border-radius: 999px;
  font-weight: 600;
  font-size: 0.72rem;
  padding: 0.36em 0.8em;
  letter-spacing: 0.01em;
}
.badge-success { background: var(--ok-soft); color: var(--ok); }
/* `badge-secondary` é sempre o mesmo sentido em toda tela: algo que existe
   mas está DESLIGADO/neutro (Pausado, Inativa, Arquivada, "todo canal deste
   tipo" como contraste a "canal específico"). `badge-light border` nunca
   significa estado — é etiqueta informativa (contagem, estimativa, nível
   atual) que não é boa nem má. Antes do Ciclo v22 os dois eram usados de
   forma intercambiável para "desligado" (achado em `tab_channels`); manter
   essa distinção evita que a mesma cor precise ser lida com dois
   significados diferentes dependendo da tela. */
.badge-secondary { background: #eceef6; color: var(--muted); }
.badge-info { background: var(--info-soft); color: var(--info); }
.badge-warning { background: var(--warn-soft); color: var(--warn); }
.badge-danger { background: var(--bad-soft); color: var(--bad); }
/* Era gradiente com texto branco em 0,72rem — o caso que mais reprova. */
.badge-primary { background: var(--accent-bg); color: var(--accent-texto); }
.badge-light { background: #f1f2f9; color: var(--ink-soft); }

/* Selo de ESTADO com o ponto da cor do estado, como no Nexus — só nos três
   que são sempre estado (bom, atenção, problema). `secondary` e `light`
   também servem de etiqueta ("todo canal deste tipo", contagem), e um ponto
   ali diria "estado" onde não há. */
.badge-success::before, .badge-warning::before, .badge-danger::before {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-right: 5px;
  border-radius: 50%;
  background: currentColor;
  vertical-align: 0.12em;
}

/* ---------------------------------------------------------------------------
   Alertas
--------------------------------------------------------------------------- */
.alert {
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  font-size: 0.875rem;
  box-shadow: none;
}
.alert-success { background: var(--ok-soft); color: #065f46; }
.alert-danger { background: var(--bad-soft); color: #9f1239; }
.alert-warning { background: var(--warn-soft); color: #92400e; }
.alert-info { background: var(--info-soft); color: #075985; }

/* ---------------------------------------------------------------------------
   Paginação
--------------------------------------------------------------------------- */
.page-link {
  border-radius: var(--radius-sm) !important;
  border: 1px solid var(--line);
  color: var(--ink-soft);
  margin: 0 2px;
  font-size: 0.82rem;
  font-weight: 600;
}
.page-item.active .page-link { background: var(--accent-botao); border-color: transparent; color: #fff; }
.page-item.disabled .page-link { color: var(--muted); }

/* `.page-tabs` / `.tab-pill` viviam aqui e saíram junto com a barra de abas da
   organização, que era a única a usá-las. Estilo de um elemento que não existe
   mais é convite para alguém reintroduzi-lo sem pensar. */

/* Nav-pills do bootstrap (usadas no builder) alinhadas ao mesmo idioma */
.nav-pills .nav-link { border-radius: 999px; font-weight: 600; font-size: 0.85rem; color: var(--ink-soft); }
.nav-pills .nav-link.active { background: var(--accent-botao); color: #fff; }

/* ---------------------------------------------------------------------------
   Filtros de lista (pílulas com contagem)
--------------------------------------------------------------------------- */
.filter-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}
.filter-pills .filter-pill {
  border-radius: 999px;
  padding: 0.32rem 0.85rem;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--ink-soft);
  background: #eef0f9;
  text-decoration: none;
  transition: background 0.12s ease, color 0.12s ease;
}
.filter-pills .filter-pill:hover { background: var(--accent-bg); color: var(--accent-texto); }
.filter-pills .filter-pill.active { background: var(--accent-botao); color: #fff; }
.filter-pills .filter-pill .count {
  opacity: 0.75;
  font-weight: 700;
  margin-left: 0.3rem;
  font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------------------
   Estado vazio
--------------------------------------------------------------------------- */
.empty-state {
  text-align: center;
  padding: 3rem 1.5rem;
}
.empty-state .empty-icon {
  width: 64px;
  height: 64px;
  border-radius: 20px;
  background: var(--accent-bg);
  color: var(--accent-texto);
  font-size: 1.5rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 1rem;
}
.empty-state p { color: var(--muted); margin-bottom: 1rem; }

/* O texto que ensina. Largura limitada em ~46ch porque uma explicação que
   atravessa uma tela larga inteira não é lida — e esta é a única frase da
   página que precisa ser. */
.empty-title {
  font-size: 1.05rem;
  font-weight: 650;
  color: var(--ink);
  margin-bottom: 0.4rem;
}
.empty-text {
  max-width: 46ch;
  margin: 0 auto 1.15rem;
  line-height: 1.55;
}
/* A dica não compete com a ação: vem depois dela e mais apagada, porque diz
   onde a coisa nasce, não o que fazer agora. */
.empty-hint {
  font-size: 0.85rem;
  color: var(--muted);
  max-width: 46ch;
  margin: 1rem auto 0;
}

/* ---------------------------------------------------------------------------
   Integrações

   O módulo é um catálogo antes de ser uma lista: quem chega está escolhendo um
   serviço, e escolher pede reconhecer um logo e ler uma frase — não comparar
   colunas. Daí o cartão, o logo colorido pela marca do serviço e o "o que fica
   possível" em vez da ficha técnica.
--------------------------------------------------------------------------- */

/* Subseções — Catálogo / Minhas integrações / Acessos */
.int-subsecoes {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-bottom: 1rem;
  border-bottom: 1px solid var(--line);
  padding-bottom: 0.6rem;
}
.int-subsecao {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--ink-soft);
  padding: 0.4rem 0.9rem;
  border-radius: 999px;
  text-decoration: none;
  transition: background 0.12s ease, color 0.12s ease;
}
.int-subsecao:hover { background: var(--brand-gradient-soft); color: var(--brand-texto); }
.int-subsecao.active { background: var(--accent-botao); color: #fff; }
.int-subsecao.active:hover { color: #fff; }

.int-busca { min-width: 19rem; }

/* Logo do serviço. A cor vem do template (--logo-cor) porque ela é dado do
   catálogo, não decisão de folha de estilo: uma cor por serviço aqui dentro
   seria uma segunda lista para manter em sincronia com a primeira. */
.int-logo {
  width: 44px;
  height: 44px;
  flex: 0 0 44px;
  border-radius: 12px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1.25rem;
  color: var(--logo-cor, var(--brand-a));
  /* A declaração neutra vem antes de propósito: um navegador sem `color-mix`
     ignora a linha seguinte e fica com um fundo cinza legível, em vez de um
     ícone colorido sobre nada. */
  background: #f4f5fb;
  border: 1px solid var(--line);
  background: color-mix(in srgb, var(--logo-cor, #6366f1) 12%, #fff);
  border: 1px solid color-mix(in srgb, var(--logo-cor, #6366f1) 22%, #fff);
}
.int-logo-sm { width: 32px; height: 32px; flex-basis: 32px; font-size: 0.95rem; border-radius: 9px; }
.int-logo-lg { width: 56px; height: 56px; flex-basis: 56px; font-size: 1.6rem; border-radius: 16px; }

/* Cartão do catálogo */
.int-card {
  display: flex;
  flex-direction: column;
  width: 100%;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 1rem 1.1rem;
  margin-bottom: 1rem;
  transition: box-shadow 0.15s ease, border-color 0.15s ease;
}
.int-card:hover { box-shadow: var(--shadow-lift); border-color: transparent; }
.int-card-topo { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 0.6rem; }
.int-card-identidade h4 { font-size: 1rem; font-weight: 650; margin: 0 0 0.15rem; color: var(--ink); }
.int-categoria { font-size: 0.72rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.03em; }
.int-tagline { color: var(--ink-soft); font-size: 0.88rem; margin-bottom: 0.6rem; }

.int-podefazer { list-style: none; padding: 0; margin: 0 0 0.9rem; }
.int-podefazer li {
  position: relative;
  padding-left: 1.15rem;
  font-size: 0.82rem;
  color: var(--muted);
  margin-bottom: 0.2rem;
}
.int-podefazer li::before {
  content: "\f00c";              /* check, Font Awesome */
  font-family: "Font Awesome 6 Free";
  font-weight: 900;
  position: absolute;
  left: 0;
  font-size: 0.68rem;
  color: var(--ok);
}

/* O rodapé é empurrado para baixo para que dois cartões lado a lado tenham os
   botões alinhados mesmo com textos de alturas diferentes. */
.int-card-rodape {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: auto;
  padding-top: 0.4rem;
}
.int-nota { font-size: 0.75rem; color: var(--muted); }
.int-doc-link { font-size: 0.78rem; color: var(--muted); }
.int-doc-link:hover { color: var(--brand-texto); }

/* Estado de uma conexão. Quatro, não dois: "nunca testada" não é "com erro",
   e pintar as duas de vermelho ensina a ignorar o vermelho. */
.int-status {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.8rem;
  font-weight: 600;
}
.int-status .ponto { width: 8px; height: 8px; border-radius: 50%; background: currentColor; }
.int-status-ok { color: var(--ok); }
.int-status-falha { color: var(--bad); }
.int-status-nao_testada { color: var(--warn); }
.int-status-inativa { color: var(--muted); }

/* Cabeçalho da tela de configuração */
.int-cabecalho {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 1rem;
  flex-wrap: wrap;
}
/* FE15/A4: a coluna de texto do cabeçalho tem base fixa — sem isto, uma
   linha de apoio longa (política de dados) media o próprio conteúdo, não
   cabia ao lado do ícone e caía para a linha de baixo, deixando o ícone
   sozinho. */
.int-cabecalho > .flex-grow-1 { flex: 1 1 16rem; min-width: 0; }
/* Sem regra de `h2` aqui: o cabeçalho de página perdeu o título (dono,
   2026-09-07) e virou só o ícone + a linha que explica a tela. Quem abriu
   a página sabe o que abriu — o nome do item aparece no conteúdo. */

/* Campo explicado. O espaçamento é maior do que o de um formulário comum de
   propósito: cada campo aqui carrega quatro linhas de texto, e apertá-las
   transforma a explicação num bloco cinza que ninguém lê. */
.int-campo { margin-bottom: 1.6rem; }
.int-campo > label { font-weight: 600; margin-bottom: 0.15rem; color: var(--ink); }
.int-opcional {
  font-weight: 500;
  font-size: 0.72rem;
  color: var(--muted);
  background: #eef0f9;
  border-radius: 999px;
  padding: 0.05rem 0.45rem;
  margin-left: 0.35rem;
}
.int-campo-oque { font-size: 0.85rem; color: var(--ink-soft); margin-bottom: 0.45rem; }
.int-campo-porque { font-size: 0.8rem; color: var(--muted); margin: 0.4rem 0 0; line-height: 1.5; }
.int-campo-dica { font-size: 0.78rem; color: var(--muted); margin: 0.3rem 0 0; }
.int-campo-dica code,
.int-campo-porque code {
  background: #f4f5fb;
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 0 0.3rem;
  color: var(--ink-soft);
}

/* "Onde encontrar?" recolhido: a resposta é longa e só interessa a quem ainda
   não tem o valor em mãos. Aberta por padrão, ela empurraria para fora da tela
   o campo seguinte para todo mundo — inclusive para quem já colou a chave. */
.int-onde {
  margin-top: 0.55rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: #f8fafc;
  padding: 0.5rem 0.75rem;
}
.int-onde > summary {
  cursor: pointer;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--brand-texto);
  list-style: none;
}
.int-onde > summary::-webkit-details-marker { display: none; }
.int-onde > summary::before { content: "\203A"; margin-right: 0.4rem; display: inline-block; transition: transform 0.15s ease; }
.int-onde[open] > summary::before { transform: rotate(90deg); }
.int-onde ol { margin: 0.6rem 0 0.6rem; padding-left: 1.2rem; font-size: 0.82rem; color: var(--ink-soft); }
.int-onde ol li { margin-bottom: 0.3rem; }

/* Cabeçalho de um grupo de cartões. Existe para que a explicação que vale
   para vários deles seja dita UMA vez, no alto — repetida em cada cartão, ela
   deixa de ser informação e vira o texto da tela. */
.int-grupo { margin-bottom: 0.75rem; }
.int-grupo h4 {
  font-size: 0.92rem;
  font-weight: 650;
  color: var(--ink);
  margin-bottom: 0.2rem;
}
.int-grupo p {
  font-size: 0.83rem;
  color: var(--muted);
  max-width: 68ch;
  margin-bottom: 0;
}

/* Permissões que se pede a um serviço externo. Cada uma é uma decisão — "a
   Utor vai poder ler e enviar e-mails desta conta" — e uma decisão precisa de
   espaço para ser lida. Como caixa de seleção com o escopo cru ao lado, a
   lista era rolada sem leitura, que é o pior resultado possível numa tela de
   autorização. */
.int-permissoes { display: grid; gap: 0.5rem; }
.int-permissao {
  display: flex;
  gap: 0.6rem;
  align-items: flex-start;
  margin: 0;
  padding: 0.7rem 0.85rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  font-weight: 400;
  cursor: pointer;
  transition: border-color 0.12s ease, background 0.12s ease;
}
.int-permissao:hover { border-color: var(--brand-a); background: var(--brand-gradient-soft); }
.int-permissao input { margin-top: 0.25rem; flex-shrink: 0; }
.int-permissao-corpo { display: flex; flex-direction: column; gap: 0.1rem; }
.int-permissao-titulo { font-weight: 600; font-size: 0.88rem; color: var(--ink); }
.int-permissao-texto { font-size: 0.82rem; color: var(--ink-soft); }
.int-permissao-exemplo { font-size: 0.76rem; color: var(--muted); }

/* Exclusão recolhida pelo mesmo motivo, invertido: é a ação que ninguém deve
   alcançar por distração. */
.int-perigo > summary {
  cursor: pointer;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--bad);
  list-style: none;
}
.int-perigo > summary::-webkit-details-marker { display: none; }
.int-perigo > summary::before { content: "\203A"; margin-right: 0.4rem; display: inline-block; }
.int-perigo[open] > summary::before { transform: rotate(90deg); }
.int-perigo p { color: var(--muted); }

/* ---------------------------------------------------------------------------
   Sino de notificações
--------------------------------------------------------------------------- */
.sino-contador {
  position: absolute;
  top: 2px;
  right: 0;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 8px;
  background: #dc2626;
  color: #fff;
  font-size: 0.62rem;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
}
.sino-lista {
  width: 340px;
  max-height: 420px;
  overflow-y: auto;
  padding: 0;
}
.sino-item {
  white-space: normal;
  padding: 0.6rem 1rem;
  border-bottom: 1px solid var(--line);
  /* A faixa colorida à esquerda carrega o nível sem depender de cor de texto:
     um aviso crítico precisa se distinguir de um informativo à distância. */
  border-left: 3px solid transparent;
}
.sino-item.nivel-warning { border-left-color: #f59e0b; }
.sino-item.nivel-critical { border-left-color: #dc2626; }
.sino-item.nao-lido { background: var(--brand-gradient-soft); }
.sino-titulo { font-weight: 600; font-size: 0.85rem; color: var(--ink); }
.sino-texto { font-size: 0.78rem; color: var(--muted); line-height: 1.4; }
.sino-quando { font-size: 0.7rem; color: var(--muted); margin-top: 0.2rem; }

/* ---------------------------------------------------------------------------
   Filtros de consumo, dentro do cabeçalho do cartão
--------------------------------------------------------------------------- */
.consumo-filtros {
  font-size: 0.78rem;
}
.consumo-filtros .form-control {
  /* `width: auto` é o que faz os controles ocuparem só o que precisam: em
     `display:flex`, um `.form-control` de largura 100% empurraria cada um
     para a sua própria linha. */
  width: auto;
  height: auto;
  padding: 0.2rem 0.45rem;
  font-size: 0.8rem;
  line-height: 1.5;
}
.consumo-filtros select.form-control {
  /* O seletor nativo reserva espaço para a seta; sem isto o texto encosta. */
  padding-right: 1.4rem;
  max-width: 12rem;
}
.consumo-rotulo {
  color: var(--muted);
  font-size: 0.72rem;
  white-space: nowrap;
}

/* Seleção de vários agentes, sobre `<details>` — abre e fecha sozinho e é
   navegável por teclado sem uma linha de JavaScript. */
.consumo-multi {
  position: relative;
}
.consumo-multi > summary {
  cursor: pointer;
  min-width: 9rem;
  list-style: none;
}
.consumo-multi > summary::-webkit-details-marker { display: none; }
.consumo-multi > summary::after {
  content: "▾";
  float: right;
  margin-left: 0.5rem;
  opacity: 0.55;
}
.consumo-multi[open] > summary::after { content: "▴"; }
.consumo-multi-lista {
  position: absolute;
  z-index: 30;
  margin-top: 0.25rem;
  min-width: 100%;
  max-height: 15rem;
  overflow-y: auto;
  padding: 0.35rem 0;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 8px;
  box-shadow: 0 8px 24px -8px rgba(30, 34, 53, 0.25);
}
.consumo-multi-item {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  margin: 0;
  padding: 0.3rem 0.7rem;
  font-weight: 400;
  white-space: nowrap;
  cursor: pointer;
}
.consumo-multi-item:hover { background: var(--brand-gradient-soft); }

/* Flatpickr: só o que precisa concordar com o tema. O resto vem do CSS da
   própria biblioteca, hospedada em static/vendor/. */
.flatpickr-day.selected,
.flatpickr-day.startRange,
.flatpickr-day.endRange {
  background: var(--brand-b);
  border-color: var(--brand-b);
}
.flatpickr-day.inRange {
  background: var(--brand-gradient-soft);
  border-color: transparent;
  box-shadow: none;
}

/* ---------------------------------------------------------------------------
   Gráfico de consumo — barras com altura vinda do servidor
--------------------------------------------------------------------------- */
/* SVG e não divs: a altura de cada barra é um atributo, e não um valor de CSS
   montado no template — o que mantém o arquivo livre de erro falso no editor
   e o desenho livre de JavaScript. */
.consumo-grafico {
  display: block;
  width: 100%;
  height: 120px;
  border-bottom: 1px solid var(--line);
}
.consumo-barra {
  /* Gradiente não se aplica a `fill` sem um `<defs>`; uma cor sólida da marca
     comunica o mesmo num gráfico desta altura. */
  fill: var(--brand-b);
  transition: opacity 0.12s ease;
}
.consumo-barra:hover { opacity: 0.7; }

/* ---------------------------------------------------------------------------
   Ajuda no lugar do trabalho — o `?` ao lado de um conceito
--------------------------------------------------------------------------- */
.ajuda {
  /* Discreto de propósito: quem já sabe não deve tropeçar nele a cada campo,
     e quem não sabe encontra assim que procura. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  margin-left: 0.35rem;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--line);
  color: var(--muted);
  font-size: 0.65rem;
  font-weight: 700;
  line-height: 1;
  cursor: help;
  vertical-align: middle;
  transition: background 0.12s ease, color 0.12s ease;
}
.ajuda:hover,
.ajuda:focus {
  background: var(--accent-botao);
  color: #fff;
}
.popover { max-width: 320px; }
.popover-body { font-size: 0.85rem; line-height: 1.5; }

/* ---------------------------------------------------------------------------
   Checklist de primeiros passos (dashboard)
--------------------------------------------------------------------------- */
.activation-bar {
  height: 6px;
  border-radius: 99px;
  background: var(--line);
  overflow: hidden;
}
.activation-bar span {
  display: block;
  height: 100%;
  border-radius: 99px;
  background: var(--accent-botao);
  /* Anima só a largura, e devagar: a barra andando é o retorno de ter feito
     o passo, e é a única coisa nesta tela que compensa animar. */
  transition: width 0.5s ease;
}

.activation-steps {
  list-style: none;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1.25rem;
  font-size: 0.85rem;
}
.activation-steps li {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--muted);
}
.activation-steps li i {
  font-size: 0.75rem;
  opacity: 0.45;
}
.activation-steps li.done { color: var(--ink); }
.activation-steps li.done i { color: #16a34a; opacity: 1; }
/* O próximo passo é o único em destaque — os outros são contexto, não convite. */
.activation-steps li.next { color: var(--brand-dark, var(--brand-b)); font-weight: 600; }
.activation-steps li.next i { color: var(--brand-b); opacity: 1; }

/* ---------------------------------------------------------------------------
   Lista de ações rápidas (dashboard)
--------------------------------------------------------------------------- */
.quick-actions .quick-action {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  padding: 0.7rem 1.25rem;
  color: var(--ink);
  text-decoration: none;
  border-top: 1px solid var(--line);
  transition: background 0.12s ease;
}
.quick-actions .quick-action:first-child { border-top: 0; }
.quick-actions .quick-action:hover { background: #f7f8fe; }
.quick-actions .qa-icon {
  width: 36px;
  height: 36px;
  min-width: 36px;
  border-radius: 10px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-size: 0.85rem;
}
.quick-actions .qa-label { font-size: 0.86rem; font-weight: 600; }
.quick-actions .qa-hint { font-size: 0.73rem; color: var(--muted); }

/* ---------------------------------------------------------------------------
   Footer
--------------------------------------------------------------------------- */
.main-footer {
  background: transparent;
  border-top: 1px solid var(--line);
  color: var(--muted);
  font-size: 0.78rem;
}

/* ---------------------------------------------------------------------------
   Login — página inteira no gradiente da marca
--------------------------------------------------------------------------- */
/* Sem o AdminLTE, a centralização e a medida do logo são daqui (2026-11-05). O campo escuro
   é o mesmo índigo profundo do site institucional; a marca "Utor Agent" com o produto em
   destaque, como na lateral. */
body.login-page {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  background: radial-gradient(900px 600px at 80% 10%, rgba(124, 58, 237, 0.45), transparent 60%),
              linear-gradient(135deg, #1a1733 0%, #1b1740 55%, #312e81 100%);
  min-height: 100vh; padding: 24px 0;
}

.login-page .login-box { width: 400px; max-width: 92vw; }

.login-page .login-logo a, .login-page .login-logo {
  display: flex; align-items: center; justify-content: center; gap: 2px;
  color: #fff; font-size: 1.9rem; font-weight: 500; letter-spacing: -0.01em; text-align: center;
}
.login-page .login-logo b { font-weight: 800; color: #c4b5fd; margin-left: 0.3rem; }
.login-page .login-box-msg { text-align: center; padding: 0 0 1rem; }
.pagina-erro { background: var(--bg); color: var(--text); }
.pagina-erro .display-1 { color: var(--accent-texto); font-weight: 700; }

.login-page .card {
  border-radius: 20px;
  box-shadow: 0 24px 60px -20px rgba(0, 0, 0, 0.55);
}

.login-card-body { border-radius: 20px; padding: 1.8rem; }

.login-page .login-box-msg { color: var(--muted); font-size: 0.9rem; }

/* ---------------------------------------------------------------------------
   Ajustes menores
--------------------------------------------------------------------------- */
.modal-content { border: 0; border-radius: var(--radius); box-shadow: var(--shadow-lift); }
.dropdown-menu { border: 1px solid var(--line); border-radius: var(--radius-sm); box-shadow: var(--shadow-lift); }

/* small-box legado (se alguma página ainda usar) herda o raio novo */
.small-box { border-radius: var(--radius); box-shadow: var(--shadow); }

code { color: #7c3aed; background: #f5f3ff; padding: 0.15em 0.4em; border-radius: 6px; }

/* ---------------------------------------------------------------------------
   Foco, seleção e superfícies do navegador — o mesmo padrão do Nexus
   ----------------------------------------------------------------------------
   Foco por TECLADO (`:focus-visible` não dispara no clique de mouse) com anel
   DUPLO: por fora a marca, por dentro 2px do fundo — um anel #6366f1 em volta
   de um botão da mesma cor ficaria invisível. Antes, cada componente tinha o
   seu (o brilho translúcido do Bootstrap, `outline: none` aqui e ali). */
:where(a, button, [role="button"], [tabindex], input, select, textarea, summary,
       [role="tab"], [role="menuitem"], [role="option"], [role="radio"],
       [role="checkbox"], [role="switch"]):focus-visible {
  /* `!important` de propósito: o Bootstrap zera o contorno com `.btn:focus`,
     `.form-control:focus`… (duas classes, vencem um `:where`). O anel de
     teclado tem de valer em qualquer componente — medido: sem isto, o Tab
     no "Aplicar" do painel não mostrava nada. */
  outline: 2px solid var(--brand-a) !important;
  outline-offset: 2px !important;
  box-shadow: 0 0 0 2px var(--surface) !important;
}

::selection {
  background: rgba(99, 102, 241, 0.28);
  color: var(--ink);
}
:root {
  caret-color: var(--brand-a);
  accent-color: var(--brand-a);  /* checkbox, rádio e range nativos na cor da marca */
}

/* Rolagem fina no conteúdo (a da sidebar tem regra própria, acima). */
.content-wrapper, .content-wrapper * { scrollbar-width: thin; scrollbar-color: #cfd3e8 transparent; }
.content-wrapper ::-webkit-scrollbar { width: 10px; height: 10px; }
.content-wrapper ::-webkit-scrollbar-thumb {
  background: #cfd3e8;
  border-radius: 6px;
  border: 2px solid transparent;
  background-clip: padding-box;
}
.content-wrapper ::-webkit-scrollbar-track { background: transparent; }

/* Movimento reduzido (igual ao Nexus): "menos", nunca zero — o estado ainda
   muda (cor, opacidade), só nada viaja pela tela. Vale para tudo de uma vez,
   em vez da lista de três componentes que existia aqui. */
@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;
  }
  .btn:active:not(:disabled):not(.disabled) { transform: none; }
}

/* ---------------------------------------------------------------------------
   Automações — o construtor de frequência e as opções de "o que fazer"
   ----------------------------------------------------------------------------
   A frequência é escolhida em pílulas (modo) e ajustada em campos pequenos
   dentro de um bloco. O cron continua existindo, atrás de "Avançado", mas
   não é a primeira coisa que a pessoa vê — ver apps/schedules/frequencia.py.
--------------------------------------------------------------------------- */
.auto-modos, .auto-dias {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-bottom: 0.75rem;
}
.auto-modo, .auto-dia {
  position: relative;
  margin: 0;
  cursor: pointer;
  font-weight: 500;
}
.auto-modo input, .auto-dia input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  pointer-events: none;
}
.auto-modo span, .auto-dia span {
  display: inline-block;
  border-radius: 999px;
  padding: 0.38rem 0.95rem;
  font-size: 0.83rem;
  font-weight: 600;
  color: var(--ink-soft);
  background: #eef0f9;
  border: 1px solid transparent;
  transition: background 0.12s ease, color 0.12s ease;
}
.auto-dia span { padding: 0.3rem 0.7rem; text-transform: capitalize; }
.auto-modo span:hover, .auto-dia span:hover { background: var(--brand-gradient-soft); color: var(--brand-texto); }
.auto-modo input:checked + span, .auto-dia input:checked + span { background: var(--accent-botao); color: #fff; }
.auto-modo input:focus-visible + span, .auto-dia input:focus-visible + span {
  outline: 2px solid var(--brand-a);
  outline-offset: 2px;
}

.auto-bloco {
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: #f8fafc;
  padding: 0.9rem 1rem;
}
.auto-bloco + .auto-bloco { margin-top: 0.75rem; }
.auto-linha {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  font-size: 0.88rem;
  color: var(--ink-soft);
}
.auto-linha + .auto-linha, .auto-linha + [data-modo-bloco], [data-modo-bloco] + .auto-linha { margin-top: 0.6rem; }
.auto-linha label { margin: 0; font-weight: 600; color: var(--ink); }
.auto-rotulo { font-weight: 600; font-size: 0.85rem; color: var(--ink); margin-bottom: 0.4rem; }
.auto-hora { width: 8.5rem; }
.auto-numero { width: 6rem; }
.auto-unidade { width: auto; }

/* A frase "lendo de volta" — a única linha do bloco que precisa ser lida. */
.auto-leitura {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  margin: 0.9rem 0 0;
  font-weight: 600;
  font-size: 0.92rem;
  color: var(--ink);
}
.auto-leitura::before {
  content: "\f017";                /* clock, Font Awesome */
  font-family: "Font Awesome 6 Free";
  font-weight: 400;
  color: var(--brand-texto);
  margin-top: 0.1rem;
}
.auto-leitura.is-erro { color: var(--bad); }
.auto-leitura.is-erro::before { content: "\f071"; font-weight: 900; color: var(--bad); }
.auto-leitura.is-calculando { opacity: 0.6; }

/* As próximas execuções, no painel ao lado. */
.auto-proximas { list-style: none; padding: 0; margin: 0 0 0.6rem; }
.auto-proximas li {
  padding: 0.35rem 0;
  border-bottom: 1px dashed var(--line);
  font-size: 0.83rem;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}
.auto-proximas li:first-child { color: var(--ink); font-weight: 600; }
.auto-proximas li:last-child { border-bottom: 0; }

/* "O que fazer": duas escolhas, cada uma dita pelo que acontece. Cartões e
   não um select, porque a diferença entre elas é a decisão inteira da tela. */
.auto-opcoes { display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: 0.6rem; margin-bottom: 1rem; }
.auto-opcao {
  position: relative;
  display: flex;
  gap: 0.6rem;
  align-items: flex-start;
  margin: 0;
  padding: 0.8rem 0.9rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
  cursor: pointer;
  font-weight: 400;
  transition: border-color 0.12s ease, background 0.12s ease, box-shadow 0.12s ease;
}
.auto-opcao:hover { border-color: var(--brand-a); }
.auto-opcao input { margin-top: 0.25rem; flex-shrink: 0; }
.auto-opcao:has(input:checked) { border-color: var(--brand-a); background: var(--brand-gradient-soft); box-shadow: 0 0 0 1px var(--brand-a) inset; }
.auto-opcao-corpo { display: flex; flex-direction: column; gap: 0.15rem; }
.auto-opcao-titulo { font-weight: 600; font-size: 0.9rem; color: var(--ink); }
.auto-opcao-texto { font-size: 0.8rem; color: var(--ink-soft); line-height: 1.45; }

/* Um bloco de campos que só vale para a opção marcada. */
fieldset.auto-bloco { margin-bottom: 0; }
fieldset.auto-bloco .int-campo:last-child { margin-bottom: 0; }

/* Situação de uma tarefa / fluxo, no mesmo idioma das integrações. */
.auto-situacao-active, .auto-situacao-ativo { color: var(--ok); }
.auto-situacao-paused, .auto-situacao-pausado { color: var(--muted); }
.auto-situacao-suspended, .auto-situacao-suspenso { color: var(--bad); }

/* O detalhe técnico de uma execução: guardado, não jogado fora — e recolhido,
   porque a primeira leitura é a frase em português logo acima. */
.auto-tecnico { margin-top: 0.25rem; }
.auto-tecnico > summary {
  cursor: pointer;
  font-size: 0.72rem;
  color: var(--muted);
  list-style: none;
}
.auto-tecnico > summary::-webkit-details-marker { display: none; }
.auto-tecnico > summary::before { content: "\203A"; margin-right: 0.3rem; display: inline-block; }
.auto-tecnico[open] > summary::before { transform: rotate(90deg); }
.auto-tecnico code {
  display: block;
  white-space: pre-wrap;
  word-break: break-word;
  font-size: 0.72rem;
  margin-top: 0.2rem;
  color: var(--ink-soft);
  background: #f4f5fb;
}

/* Lista de definição das telas de detalhe: rótulo à esquerda, valor à direita. */
.auto-dl { display: grid; grid-template-columns: 11rem 1fr; gap: 0.55rem 1rem; margin: 0; }
.auto-dl dt { font-size: 0.8rem; font-weight: 600; color: var(--muted); }
.auto-dl dd { margin: 0; font-size: 0.9rem; color: var(--ink); }
.auto-dl dd pre { white-space: pre-wrap; margin: 0; font-family: inherit; font-size: 0.88rem; }
@media (max-width: 575.98px) { .auto-dl { grid-template-columns: 1fr; gap: 0.15rem 0; } .auto-dl dd { margin-bottom: 0.5rem; } }

/* Números pequenos do painel "Saúde". */
.auto-saude { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.5rem; }
.auto-saude div { text-align: center; padding: 0.55rem 0.25rem; border: 1px solid var(--line); border-radius: var(--radius-sm); background: #f8fafc; }
.auto-saude strong { display: block; font-size: 1.25rem; font-weight: 800; color: var(--ink); font-variant-numeric: tabular-nums; }
.auto-saude span { font-size: 0.72rem; color: var(--muted); font-weight: 600; }

/* ---------------------------------------------------------------------------
   Consumo por origem — conversa × execução × indexação
   ----------------------------------------------------------------------------
   Três barras finas em vez de uma pizza: a pergunta é "qual das três está
   levando o dinheiro", e a comparação de comprimentos responde isso mais
   rápido que ângulos. As três aparecem sempre, inclusive zeradas.
--------------------------------------------------------------------------- */
.consumo-origens { display: grid; gap: 0.7rem; }
.consumo-origem-rotulo { font-size: 0.83rem; font-weight: 600; color: var(--ink); }
.consumo-origem-numero { font-size: 0.83rem; font-variant-numeric: tabular-nums; color: var(--ink); }
.consumo-origem-barra {
  height: 8px;
  border-radius: 999px;
  background: #eef0f9;
  overflow: hidden;
  margin: 0.2rem 0 0.1rem;
}
.consumo-origem-barra span { display: block; height: 100%; border-radius: 999px; }
/* Uma cor por origem, e não o gradiente da marca: aqui a cor é dado — ela
   distingue as três — e não identidade. */
.consumo-origem-barra .origem-conversation { background: var(--brand-a); }
.consumo-origem-barra .origem-run { background: var(--info); }
.consumo-origem-barra .origem-indexing { background: var(--warn); }
.consumo-origem-nota { font-size: 0.72rem; color: var(--muted); }

/* ---------------------------------------------------------------------------
   Assistente do primeiro acesso
   ----------------------------------------------------------------------------
   O modal é aberto pelo servidor (classe `show` + display inline no template),
   então estas regras só cuidam da aparência. O `z-index` fica acima do
   backdrop do Bootstrap, que é 1040.
--------------------------------------------------------------------------- */
.pa-modal { z-index: 1050; }
.pa-modal .modal-content { border: 0; border-radius: var(--radius); box-shadow: var(--shadow-lift); }
.pa-modal .modal-header { border-bottom: 1px solid var(--line); padding: 1.1rem 1.25rem 0.9rem; }
.pa-modal .modal-title { font-size: 1.15rem; font-weight: 650; color: var(--ink); }
.pa-modal .modal-body { padding: 1.1rem 1.25rem; }
.pa-modal .modal-footer { border-top: 0; gap: 0.5rem; }
/* O contador é informação, não cobrança: pequeno, cinza, sem barra. */
.pa-contador {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}

/* ── Interruptores (toggles) — correção global (Ciclo v20, 2026-09-03) ──────
   Problema relatado pelo dono: o input nativo ficava VISÍVEL atrás do desenho
   do switch (os widgets do Django entram sem a classe `custom-control-input`),
   a área clicável era minúscula, e o switch não mudava de visual entre
   ligado/desligado (o seletor `:checked ~ label` do Bootstrap exige a classe
   que faltava). Este bloco conserta o componente PARA QUALQUER checkbox dentro
   de `.custom-control.custom-switch`, com ou sem a classe:
   1. o input cobre o controle inteiro, invisível → a ÁREA TODA é clicável;
   2. trilho/botão redesenhados no ::before/::after do label;
   3. estado ligado = trilho no gradiente da marca + botão deslocado — diferença
      visual inequívoca; foco de teclado ganha anel. */
.custom-control.custom-switch {
  position: relative;
  padding-left: 3rem;
  min-height: 1.5rem;
  display: flex;
  align-items: center;
}
.custom-control.custom-switch input[type="checkbox"] {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;            /* invisível, mas por cima: é ele que recebe o clique */
  z-index: 2;
  cursor: pointer;
}
.custom-control.custom-switch .custom-control-label {
  cursor: pointer;
  position: static;      /* o ::before/::after ancoram no contêiner */
  margin-bottom: 0;
  line-height: 1.5rem;
}
.custom-control.custom-switch .custom-control-label::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 2.4rem;
  height: 1.3rem;
  border-radius: 0.75rem;
  background: #c3c8d4;   /* desligado: cinza claro, sem dúvida */
  border: 1px solid #aab0bf;
  transition: background-color 0.15s ease, border-color 0.15s ease;
  box-shadow: none;
}
.custom-control.custom-switch .custom-control-label::after {
  content: "";
  position: absolute;
  left: 0.2rem;
  top: 50%;
  transform: translateY(-50%);
  width: 0.95rem;
  height: 0.95rem;
  border-radius: 50%;
  background: #ffffff;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
  transition: transform 0.15s ease, left 0.15s ease;
}
.custom-control.custom-switch input[type="checkbox"]:checked ~ .custom-control-label::before {
  background: var(--accent-botao, #6d28d9);
  border-color: transparent;
}
.custom-control.custom-switch input[type="checkbox"]:checked ~ .custom-control-label::after {
  left: calc(2.4rem - 0.95rem - 0.2rem);  /* botão vai para a direita */
  /* Achado do dono (2026-11-10, "Ativa" do formulário): com a classe `custom-control-input`, o Bootstrap 4 casa
     `.custom-switch .custom-control-input:checked ~ .custom-control-label::after` com `translateX(.75rem)`
     (0,4,1), mais específico que o `transform: translateY(-50%)` da base acima — LIGADO, a bolinha perdia o
     centro vertical e caía para fora do trilho (e andava .75rem a mais). Aqui o mesmo transform da base vence. */
  transform: translateY(-50%);
}
.custom-control.custom-switch input[type="checkbox"]:focus-visible ~ .custom-control-label::before {
  box-shadow: 0 0 0 0.2rem rgba(99, 102, 241, 0.3);
}
.custom-control.custom-switch input[type="checkbox"]:disabled {
  cursor: not-allowed;
}
.custom-control.custom-switch input[type="checkbox"]:disabled ~ .custom-control-label {
  opacity: 0.55;
  cursor: not-allowed;
}

/* ---------------------------------------------------------------------------
   FE15 (2026-10-27) — componentes que o inventário visual achou escritos
   com `style=` inline, cada tela do seu jeito. Ver
   docs/analises/inventario-visual-2026-10-27.md.
--------------------------------------------------------------------------- */

/* Métricas de desempenho (OB7, painel): rótulo nunca quebra — antes
   "Retrabalho/exec." virava duas linhas com o "." sozinho e os números
   desalinhavam na vertical. */
.metricas { display: flex; flex-wrap: wrap; gap: var(--gap-sm); }
/* Cinco colunas iguais; o rótulo pode quebrar em duas linhas LIMPAS (nunca
   um "." sozinho), e o número fica alinhado pela base em todas as colunas. */
.metrica { flex: 1 1 6rem; min-width: 6rem; display: flex; flex-direction: column; justify-content: flex-end; }
.metrica-rotulo { font-size: 0.75rem; color: var(--muted); line-height: 1.25; }
.metrica-valor {
  font-size: 1.5rem;
  font-weight: 600;
  line-height: 1.2;
  margin: 0;
  font-variant-numeric: tabular-nums;
}
.metrica-valor small { font-size: 0.6em; font-weight: 500; }
.metrica-valor .metrica-nota { font-size: 0.5em; color: var(--muted); font-weight: 500; }
.lista-de-execucoes { list-style: none; margin: 0; padding: 0; }
.lista-de-execucoes li {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.5rem;
  padding: 0.3rem 0;
  border-top: 1px solid var(--line);
  font-size: 0.85rem;
}
.lista-de-execucoes li > span:first-child { max-width: 70%; }

/* Lista "rótulo … número" dentro de um card (painel: "Plataforma em
   números"): o card fica `p-0` e cada linha carrega o próprio respiro. */
.lista-de-numeros > div {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.5rem 1.25rem;
  border-top: 1px solid var(--line);
  font-size: 0.85rem;
}
.lista-de-numeros > div:first-child { border-top: 0; }

/* Notas do widget de consumo (antes `.7rem`/`1.35rem` inline). */
.consumo-nota { font-size: 0.7rem; color: var(--muted); }
.consumo-total { font-size: 1.35rem; }

/* Campo de arquivo (aba Conhecimento): o único controle que aparecia cru,
   com o botão nativo do navegador. O botão do seletor vira um botão do
   tema; o nome do arquivo escolhido continua sendo mostrado pelo navegador. */
input[type="file"].form-control-file { font-size: 0.82rem; color: var(--muted); width: 24rem; max-width: 100%; }
input[type="file"].form-control-file::file-selector-button {
  font: inherit;
  font-size: 0.78rem;
  font-weight: 600;
  padding: 0.3rem 0.75rem;
  margin-right: 0.6rem;
  border: 1px solid #868cad;
  border-radius: var(--radius-sm);
  background: #fff;
  color: var(--ink-soft);
  cursor: pointer;
}
input[type="file"].form-control-file::file-selector-button:hover { background: #f7f8fe; }

/* ------------------------------------------------------------------
   Órfãos do AdminLTE (2026-11-05, etapa 4). Três telas ainda usam classes
   que só o AdminLTE estilizava e ficaram cruas quando ele saiu da casca:
   as abas do construtor (`.card-outline-tabs`), o chat de teste do
   construtor (`.direct-chat-*`) e os botões de ferramenta no cabeçalho
   de cartão (`.card-tools`/`.btn-tool`). Redesenhados aqui no idioma do
   Nexus; os templates não mudam.
   ------------------------------------------------------------------ */

/* Abas do construtor: família em pílulas (linha de cima) + abas sublinhadas. */
.card-outline-tabs > .card-header { padding: 0; border-bottom: 0; }
.card-outline-tabs .nav-pills {
  background: var(--bg-sidebar) !important;
  border-bottom: 1px solid var(--line);
  border-top-left-radius: var(--radius);
  border-top-right-radius: var(--radius);
  gap: 0.25rem;
  padding: 0.6rem 0.75rem !important;
}
.nav-tabs { border-bottom: 1px solid var(--line); padding: 0 0.5rem; gap: 0.125rem; }
.nav-tabs .nav-item { margin-bottom: 0; }
.nav-tabs .nav-link {
  border: 0;
  border-bottom: 2px solid transparent;
  border-radius: 0;
  margin-bottom: -1px;
  padding: 0.65rem 0.85rem;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--ink-soft);
  transition: color var(--mov-rapido, 150ms) ease-out, border-color var(--mov-rapido, 150ms) ease-out;
}
.nav-tabs .nav-link:hover { color: var(--ink); border-bottom-color: #c9cce0; }
.nav-tabs .nav-link.active,
.nav-tabs .nav-item.show .nav-link {
  color: var(--accent-texto);
  background: transparent;
  border-color: transparent;
  border-bottom-color: var(--accent);
}
.nav-tabs .nav-link i { margin-right: 0.3rem; opacity: 0.85; }
.card-outline-tabs > .card-body { padding-top: 1.25rem; }

/* Ferramentas no cabeçalho de cartão. */
.card-tools { margin-left: auto; display: flex; align-items: center; gap: 0.25rem; }
.btn-tool {
  width: 30px;
  height: 30px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--muted);
  font-size: 0.85rem;
  box-shadow: none;
}
.btn-tool:hover, .btn-tool:focus { background: var(--bg-hover); color: var(--ink); box-shadow: none; }

/* Chat de teste do construtor: bolhas no idioma do Nexus. */
.direct-chat-messages {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  padding: 0.25rem 0.25rem 0.5rem;
}
.direct-chat-msg { max-width: 78%; align-self: flex-start; }
.direct-chat-msg.right { align-self: flex-end; }
.direct-chat-infos {
  display: flex;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.25rem;
  padding: 0 0.25rem;
  font-size: 0.72rem;
  color: var(--muted);
}
.direct-chat-msg.right .direct-chat-infos { flex-direction: row-reverse; }
.direct-chat-infos .float-left, .direct-chat-infos .float-right { float: none !important; }
.direct-chat-name { font-weight: 600; color: var(--ink-soft); }
.direct-chat-text {
  padding: 0.6rem 0.9rem;
  border: 1px solid var(--line);
  border-radius: 16px;
  border-top-left-radius: 6px;
  background: var(--bg);
  color: var(--ink);
  font-size: 0.9rem;
  line-height: 1.5;
  overflow-wrap: anywhere;
}
.direct-chat-msg.right .direct-chat-text {
  border-radius: 16px;
  border-top-right-radius: 6px;
  border-color: var(--accent-botao);
  background: var(--accent-botao);
  color: #fff;
}
.direct-chat-text::before, .direct-chat-text::after { display: none; }

/* Resto do azul do Bootstrap que ainda vazava (2026-11-05, etapa 4): tudo
   que recebe o acento passa pelo mesmo token. Nada aqui muda a estrutura. */
.btn-link { color: var(--accent-texto); font-weight: 600; text-decoration: none; }
.btn-link:hover, .btn-link:focus { color: var(--accent-botao-hover, #5b21b6); text-decoration: underline; }
.custom-control-input:checked ~ .custom-control-label::before {
  border-color: var(--accent-botao);
  background-color: var(--accent-botao);
}
.custom-control-input:focus ~ .custom-control-label::before { box-shadow: 0 0 0 0.2rem rgba(124, 58, 237, 0.2); }
.custom-control-input:focus:not(:checked) ~ .custom-control-label::before { border-color: var(--accent); }
.custom-control-input:not(:disabled):active ~ .custom-control-label::before {
  background-color: var(--accent-bg, #f5f3ff);
  border-color: var(--accent);
}
.progress { background: var(--bg-hover); border-radius: 999px; }
.progress-bar { background-color: var(--accent-botao); }
.dropdown-item.active, .dropdown-item:active { background: var(--accent-botao); color: #fff; }
.list-group-item.active { background: var(--accent-botao); border-color: var(--accent-botao); color: #fff; }
.border-primary { border-color: var(--accent) !important; }
.bg-primary { background-color: var(--accent-botao) !important; }
.alert-primary { background: var(--accent-bg, #f5f3ff); border-color: #ddd6fe; color: var(--accent-texto); }
.custom-range::-webkit-slider-thumb { background: var(--accent-botao); }
.custom-range::-moz-range-thumb { background: var(--accent-botao); }
.table-primary, .table-primary > td, .table-primary > th { background-color: var(--accent-bg, #f5f3ff); }

/* UX-7 (2026-11-10): avisos do servidor flutuando no canto, por cima da tela — não empurram o conteúdo (a rolagem
   restaurada depois de salvar fica no lugar). `continuidade.js` some com sucesso/informação em 6 s. */
.avisos-rapidos { position: fixed; top: 4.25rem; right: 1rem; z-index: 1080; width: min(420px, calc(100vw - 2rem));
  display: flex; flex-direction: column; gap: .5rem; pointer-events: none; }
.avisos-rapidos:empty { display: none; }
.avisos-rapidos .alert { margin: 0; pointer-events: auto; box-shadow: 0 10px 30px -12px rgba(23, 20, 44, .45); }
