/* Componentes reutilizáveis — cada um pensado para ser usado em qualquer
   view, mantendo o visual consistente sem repetir estilo. */

/* Botões */
button {
  cursor: pointer;
  border: none;
  border-radius: var(--radius-sm);
  padding: 8px 13px;
  font-weight: 600;
  font-size: 12.5px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition: filter 0.12s, background 0.12s;
}
button:active {
  transform: translateY(0.5px);
}
.btn-primary {
  background: var(--accent);
  color: #fff;
}
.btn-primary:hover {
  background: var(--accent-hover);
}
.btn-outline {
  background: var(--surface);
  color: var(--ink-primary);
  border: 1px solid var(--border-strong);
}
.btn-outline:hover {
  background: var(--surface-sunken);
}
.btn-ghost {
  background: transparent;
  color: var(--ink-secondary);
  padding: 6px 8px;
}
.btn-ghost:hover {
  background: var(--surface-sunken);
  color: var(--ink-primary);
}
.btn-danger {
  background: var(--danger-soft);
  color: var(--danger);
}
.btn-danger:hover {
  filter: brightness(0.97);
}
.btn-sm {
  padding: 5px 9px;
  font-size: 11.5px;
  border-radius: 5px;
}

/* Toolbar: uma linha de ações/filtros acima do conteúdo que ela controla */
.toolbar {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  flex-wrap: wrap;
  margin-bottom: var(--sp-4);
}
.toolbar .spacer,
.modal-foot .spacer {
  flex: 1;
}
/* Campo de busca que ocupa a sobra da linha de filtros. A base é pequena de
   propósito: assim os selects de filtro cabem todos na mesma linha em telas
   normais, e é a busca que cede espaço primeiro quando a janela encolhe. */
.toolbar .grow {
  flex: 1 1 200px;
  min-width: 150px;
}

/* Segmented control — atalhos de período da Linha do Tempo. Um grupo só,
   visualmente uma peça: bordas compartilhadas em vez de N botões soltos. */
.segmented {
  display: inline-flex;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.segmented button {
  padding: 6px 11px;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--ink-secondary);
  background: var(--surface);
  border: 0;
  border-left: 1px solid var(--border);
  border-radius: 0;
}
.segmented button:first-child {
  border-left: 0;
}
.segmented button:hover {
  background: var(--surface-sunken);
}
.segmented button.active {
  background: var(--accent);
  color: var(--ink-on-accent);
}

input[type="text"],
input[type="number"],
input[type="date"],
input[type="datetime-local"],
select {
  font-family: inherit;
  font-size: 12.5px;
  padding: 7px 10px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink-primary);
}
input:focus,
select:focus {
  outline: 2px solid var(--accent);
  outline-offset: -1px;
}
label {
  font-size: 11.5px;
  font-weight: 700;
  color: var(--ink-secondary);
}
.field {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.field-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-3);
}

/* Card — moldura plana, 1px, usada por stat tile / chart card / painéis */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
.panel-head {
  padding: var(--sp-3) var(--sp-4);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  flex-wrap: wrap;
  border-bottom: 1px solid var(--border);
}
.panel-head h2 {
  font-size: 13px;
  color: var(--ink-primary);
}

/* Painel com barra de destaque azul no topo — usado quando o painel precisa
   se distinguir visualmente do content-header logo acima dele (que já tem
   seu próprio fundo/linha), pra não virar duas linhas coladas uma na outra. */
.panel--accent-top {
  border-top: 3px solid transparent;
  background:
    linear-gradient(var(--surface), var(--surface)) padding-box,
    linear-gradient(90deg, var(--accent), var(--accent-hover)) border-box;
}
/* Cabeçalho de painel com título + descrição empilhados (h3/p), em vez do
   título único do .panel-head — com respiro por baixo antes da lista. */
.panel-simple-head {
  padding: var(--sp-4) var(--sp-4) var(--sp-3);
  border-bottom: 1px solid var(--border);
}
.panel-simple-head h3 {
  margin: 0 0 var(--sp-1);
}
.panel-simple-head > p.muted {
  margin: 0 0 var(--sp-3);
}
.panel-simple-head .toolbar {
  margin-bottom: 0;
}

/* Stat tile — neutro, no lugar dos cards de KPI coloridos do app anterior */
.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: var(--sp-3);
  margin-bottom: var(--sp-4);
}
.stat-tile {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--sp-3) var(--sp-4);
}
.stat-tile .label {
  font-size: 10.5px;
  font-weight: 700;
  color: var(--ink-secondary);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  display: flex;
  align-items: center;
  gap: 5px;
}
.stat-tile .value {
  font-size: 22px;
  font-weight: 800;
  color: var(--ink-primary);
  margin-top: 4px;
  line-height: 1.15;
}
/* Segunda linha discreta, para o dado que dá contexto ao número principal
   (ex.: quantos lançamentos somam o valor em destaque) sem competir com ele. */
.stat-tile .foot {
  font-size: 11px;
  margin-top: 3px;
}
/* % do arrecadado que foi distribuída (Dashboard de Fechamento e Programar
   pagamento). Verde até o limite combinado, vermelho acima dele — ver
   LIMITE_DISTRIBUICAO_PCT em js/sosRateio.js. O quadro inteiro ganha um friso
   da cor: só o número colorido some no meio de uma fileira de quadros iguais,
   que é exatamente quando este precisa ser notado. */
.stat-tile.tile-dentro-meta {
  border-left: 4px solid var(--success);
}
.stat-tile.tile-acima-meta {
  border-left: 4px solid var(--danger);
}
.stat-tile .value.dentro-meta {
  color: var(--success);
}
.stat-tile .value.acima-meta {
  color: var(--danger);
}
.stat-tile .foot {
  font-size: 11px;
  color: var(--ink-secondary);
  margin-top: 4px;
}
.stat-tile.is-critical .value {
  color: var(--danger);
}
.stat-tile.is-warn .value {
  color: var(--warning);
}
.stat-tile.is-good .value {
  color: var(--success);
}
.help {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: var(--surface-sunken);
  border: 1px solid var(--border);
  color: var(--ink-secondary);
  font-size: 9px;
  font-weight: 800;
  cursor: help;
  flex: none;
}

/* Chart card — moldura consistente ao redor dos 6 gráficos SVG */
.chart-card .card-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4) 0;
}
.chart-card .card-head h3 {
  font-size: 13px;
  color: var(--ink-primary);
}
.chart-card .card-head .sub {
  font-size: 11px;
  color: var(--ink-secondary);
  margin-top: 2px;
}
.chart-card .card-body {
  padding: var(--sp-2) var(--sp-4) var(--sp-4);
}
.legend {
  display: flex;
  gap: var(--sp-4);
  flex-wrap: wrap;
  font-size: 11px;
  color: var(--ink-secondary);
  padding: var(--sp-2) var(--sp-4) 0;
}
.legend .k {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.legend i {
  width: 10px;
  height: 10px;
  border-radius: 3px;
  display: inline-block;
  flex: none;
}
.chart-empty {
  padding: 32px 12px;
  text-align: center;
  color: var(--ink-muted);
  font-size: 12px;
}

/* "Acumulado por departamento" (js/charts/deptoAcumulado.js): tabela com um
   pontinho colorido na variação, em vez do texto/seta de .flag — mais perto
   do "de relance" que um dumbbell chart pede o mouse pra dar.

   table-layout:fixed com largura por coluna: em table-layout:auto (padrão),
   uma coluna cujo conteúdo não pode quebrar linha (o pontinho + percentual)
   pode ser desenhada mais larga que o espaço calculado pra ela — a CAIXA da
   célula não cresce (por isso não aparecia no boundingBox), mas o texto
   pinta por cima do card vizinho. Com largura fixa por coluna, o navegador
   nunca tenta encolher essa coluna abaixo do que ela precisa. */
.acc-depto-table {
  table-layout: fixed;
}
.acc-depto-table th:first-child,
.acc-depto-table td:first-child {
  width: 34%;
}
.acc-depto-table th:last-child,
.acc-depto-table td:last-child {
  width: 22%;
}
.acc-depto-table th {
  white-space: normal;
}
.acc-delta {
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  gap: 6px;
  font-weight: 700;
}
.acc-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  flex: none;
  display: inline-block;
}

/* Rede de segurança: se o conteúdo (ex.: uma tabela com cabeçalho em
   nowrap) ainda precisar de mais largura que o card tem — mesmo com
   min-width:0 no card (ver .charts-grid) —, rola em vez de vazar por cima
   do card vizinho. */
.chart-host,
.tbl-view {
  overflow-x: auto;
}

/* Áreas de captura de mouse/teclado dos gráficos: sem esta regra, o SVG usa
   o preto padrão (fill não declarado) em vez de ficar invisível. */
.chart-host svg {
  display: block;
  width: 100%;
}
.chart-host .hit {
  fill: transparent;
  cursor: pointer;
}
.chart-host [tabindex]:focus {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
.chart-host [tabindex]:focus:not(:focus-visible) {
  outline: none;
}
.chart-host .pt .guide,
.chart-host .pt .dot {
  opacity: 0;
  transition: opacity 0.1s;
}
.chart-host .pt:hover .guide,
.chart-host .pt:hover .dot,
.chart-host .pt:focus .guide,
.chart-host .pt:focus .dot {
  opacity: 1;
}
.chart-host .band:hover .bandbg,
.chart-host .band:focus .bandbg {
  fill: var(--accent);
  fill-opacity: 0.07;
}

.charts-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(420px, 1fr));
  gap: var(--sp-3);
}
/* Sem isso, um item de grid tem min-width:auto por padrão — se o conteúdo
   não pode encolher (ex.: cabeçalho de tabela em nowrap), o card "estoura"
   a largura da coluna em vez de encolher, e o card vizinho (opaco) pinta
   por cima do que passou da borda. É por isso que uma tabela larga só
   parecia cortada em monitores grandes: com mais colunas cabendo lado a
   lado, cada card recebe menos espaço. */
.charts-grid > .card {
  min-width: 0;
}

/* Tabela de dados */
table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12.5px;
}
th {
  text-align: left;
  padding: 9px 13px;
  background: linear-gradient(90deg, var(--accent), var(--accent-hover));
  color: var(--ink-on-accent);
  font-weight: 700;
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  border-bottom: 1px solid var(--accent);
  white-space: nowrap;
}
td {
  padding: 9px 13px;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}
tr:hover td {
  background: var(--surface-sunken);
}

/* Contêiner de rolagem das planilhas (listas de cadastro) — a lista cresce
   pra dentro dele em vez de empurrar rodapé/paginação pra fora da tela (ex.:
   224 condomínios numa lista sem paginação). O cabeçalho azul fica "colado"
   no topo do contêiner ao rolar, porque já é opaco (degradê, não transparente). */
.table-scroll {
  max-height: 62vh;
  overflow-y: auto;
  overflow-x: auto;
}
.table-scroll table thead th {
  position: sticky;
  top: 0;
  z-index: 1;
}

/* Seleção única de linha (clique pra destacar, só uma por vez) — ver
   enableRowSelection em js/components/tableTools.js. Especificidade maior que
   `tr:hover td` pra continuar destacada mesmo sem o mouse em cima. */
tbody tr.row-selected td,
tbody tr.row-selected:hover td {
  background: var(--accent-soft);
}
.num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.empty-row td {
  text-align: center;
  color: var(--ink-muted);
  padding: 28px;
}
tfoot td {
  font-weight: 800;
  background: var(--surface-sunken);
  color: var(--ink-primary);
  border-top: 2px solid var(--border-strong);
}
.row-actions {
  display: flex;
  gap: 5px;
  flex-wrap: wrap;
}

/* Pills / badges */
.pill {
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 10.5px;
  font-weight: 700;
  display: inline-block;
}
.pill-ok {
  background: var(--success-soft);
  color: var(--success);
}
.pill-low {
  background: var(--danger-soft);
  color: var(--danger);
}
/* Tipos de lançamento: entrada = pill-ok (verde), saída = azul, ajuste = âmbar */
.pill-accent {
  background: var(--accent-soft);
  color: var(--accent-hover);
}
.pill-warn {
  background: var(--warning-soft);
  color: var(--warning);
}
.abc-pill {
  padding: 2px 7px;
  border-radius: 5px;
  font-size: 10px;
  font-weight: 800;
  color: #fff;
  display: inline-block;
}
.abc-A {
  background: var(--chart-abc-a);
}
.abc-B {
  background: var(--chart-abc-b);
}
.abc-C {
  background: var(--chart-abc-c);
  color: var(--accent);
}
.flag {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 11px;
  font-weight: 700;
}
.flag-critical {
  color: var(--danger);
}
.flag-warn {
  color: var(--warning);
}
.flag-serious {
  color: #9a4a20;
}
.flag-good {
  color: var(--success);
}
.muted {
  color: var(--ink-muted);
}

/* Modal */
.overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(20, 20, 24, 0.45);
  z-index: 50;
  align-items: flex-start;
  justify-content: center;
  padding: 48px 16px;
  overflow-y: auto;
}
.overlay.open {
  display: flex;
}
.modal {
  background: var(--surface);
  border-radius: 10px;
  width: 100%;
  max-width: 480px;
  box-shadow: var(--shadow-overlay);
  overflow: hidden;
}
/* Foto ampliada: acompanha o tamanho da própria imagem, até 1000x1000px —
   grande o bastante pra examinar o produto de verdade, não só confirmar que
   é a foto certa. Encolhe em telas menores (92vw/80vh) pra nunca vazar da
   janela. Seletor com duas classes pra vencer .modal-body (max-height:68vh)
   sem depender da ordem de declaração no arquivo. */
.modal-foto {
  max-width: min(1040px, 96vw);
}
.modal-body.foto-ampliada-body {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 160px;
  max-height: 88vh;
  padding: var(--sp-4);
}
.foto-ampliada-body img {
  width: auto;
  height: auto;
  max-width: min(1000px, 92vw);
  max-height: min(1000px, 80vh);
  display: block;
  border-radius: var(--radius-sm);
}
.modal-table-wrap {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  max-height: 42vh;
  overflow-y: auto;
  overflow-x: auto;
}
.modal-table-wrap input[type="number"] {
  width: 100px;
  text-align: right;
}
.modal-head {
  padding: var(--sp-4) var(--sp-5);
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px solid var(--border);
}
.modal-head h3 {
  font-size: 14px;
  color: var(--ink-primary);
}
.modal-body {
  padding: var(--sp-5);
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  max-height: 68vh;
  overflow-y: auto;
}
/* O corpo do modal já rola sozinho (overflow-y acima), então NENHUM filho dele
   pode ser espremido: passou de 68vh, quem rola é o modal. Sem isto, qualquer
   filho que tenha rolagem própria — as tabelas dentro de
   <div style="overflow-x:auto"> e as .modal-table-wrap — encolhe até ALTURA
   ZERO e desaparece inteiro, cabeçalho junto. Motivo: o flexbox só respeita o
   tamanho mínimo do conteúdo (min-height:auto) enquanto o overflow do item é
   visible; declarar overflow próprio zera esse mínimo e libera o item pra
   encolher até nada. Era exatamente o que sumia com a tabela de Propostas na
   Ordem de Orçamento (a coluna Anexo, com o campo de anexar o PDF, junto). */
.modal-body > * {
  flex-shrink: 0;
}
.modal-foot {
  padding: var(--sp-3) var(--sp-5);
  border-top: 1px solid var(--border);
  display: flex;
  justify-content: flex-end;
  gap: var(--sp-2);
}

/* Foto do produto — modal de cadastro/edição */
.foto-row {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
}
.foto-preview {
  width: 72px;
  height: 72px;
  flex: none;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--surface-sunken);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  cursor: pointer;
}
.foto-preview img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.foto-placeholder {
  font-size: 9.5px;
  color: var(--ink-muted);
  text-align: center;
  padding: 0 4px;
}
.foto-actions {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
}

/* Miniatura na listagem de produtos — sempre a mesma caixa, com ou sem
   foto, pra não deslocar as colunas vizinhas quando a imagem carrega
   (lazy) depois do resto da linha. */
.thumb-cell {
  width: 34px;
  height: 34px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--surface-sunken);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
/* Só quem TEM foto vira link de verdade — a caixa vazia (sem
   data-thumb-path) não reage a clique, porque não há nada pra ampliar. */
.thumb-cell[data-thumb-path] {
  cursor: pointer;
}
.thumb-cell[data-thumb-path]:hover {
  border-color: var(--accent-hover);
}
.thumb-cell img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.thumb-cell .thumb-placeholder {
  width: 14px;
  height: 14px;
  border-radius: 3px;
  border: 1.5px solid var(--ink-muted);
  opacity: 0.5;
}
/* Seletor de material com a foto do item escolhido ao lado (nova requisição):
   a miniatura fica DENTRO do campo, não como uma coluna da grade de campos —
   senão ela contaria como célula e empurraria os campos seguintes de linha. */
.campo-com-foto {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}
.campo-com-foto select {
  flex: 1 1 auto;
  min-width: 0;
}
.campo-com-foto .thumb-cell {
  flex: none;
}

/* Resumo de materiais na lista de requisições: a miniatura fica ao lado do
   "2× Papel A4", não numa coluna própria — são até dois itens por linha da
   tabela, uma coluna separada não teria como alinhar com ambos. */
.req-item-linha {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 3px;
}
.thumb-cell-inline {
  width: 26px;
  height: 26px;
  flex: none;
}
.thumb-cell-inline .thumb-placeholder {
  width: 11px;
  height: 11px;
}
.info-box {
  background: var(--accent-soft);
  border: 1px solid #cddce8;
  border-radius: var(--radius-sm);
  padding: 9px 12px;
  font-size: 12px;
  color: var(--accent-hover);
}
.warn-box {
  background: var(--warning-soft);
  border: 1px solid #f0d9a8;
  border-radius: var(--radius-sm);
  padding: 9px 12px;
  font-size: 12px;
  color: var(--warning);
}
/* Aviso que NÃO se fecha: usado pelo estouro de limite mensal, que precisa
   continuar visível enquanto a condição existir (não é um toast). */
.danger-box {
  background: var(--danger-soft);
  border: 1px solid #efc7c0;
  border-radius: var(--radius-sm);
  padding: 9px 12px;
  font-size: 12px;
  color: var(--danger);
}
/* Problemas de carteira na tela de Serviços. Vermelho = o condomínio não está
   em carteira nenhuma (a comissão não vai pra ninguém); roxo = está, mas na
   carteira de outro gerente que não o lançado no serviço (ou em duas ao mesmo
   tempo) — o dinheiro vai pra pessoa errada, não some.
   Os dois levam ícone junto da cor: cor sozinha não serve como único sinal
   para quem não distingue bem tons, e a tabela já usa cor em outras colunas. */
.sem-carteira {
  color: var(--danger);
  font-weight: 700;
}
.carteira-divergente {
  color: var(--alerta-cadastro);
  font-weight: 700;
}
/* Caixa que resume os dois problemas de carteira de uma vez. Fundo NEUTRO de
   propósito: ela carrega dentro os dois rótulos coloridos (vermelho e roxo), e
   um fundo vermelho faria o roxo parecer parte do mesmo aviso. */
.carteira-box {
  background: var(--surface-sunken);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 9px 12px;
  font-size: 12px;
  color: var(--ink-secondary);
}
.danger-box b,
.warn-box b {
  font-weight: 800;
}

/* Barra de paginação, no pé de uma tabela longa. `flex-wrap` porque em janela
   estreita a contagem e os botões não cabem na mesma linha — e aí eles
   empilham em vez de escapar para fora do painel. */
.paginacao {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--sp-2);
  padding: var(--sp-3);
  border-top: 1px solid var(--border);
  font-size: 12px;
  color: var(--ink-secondary);
}
.paginacao-info b {
  color: var(--ink-primary);
  font-variant-numeric: tabular-nums;
}
.paginacao-botoes {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  flex-wrap: wrap;
}
.paginacao-pagina {
  padding: 0 var(--sp-1);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.paginacao-pagina b {
  color: var(--ink-primary);
}
.paginacao button[disabled] {
  opacity: 0.45;
  cursor: default;
}

/* Banner da janela de requisições: a faixa que responde "dá pra pedir agora?"
   antes de qualquer outra coisa na tela. Aberta e fechada usam as mesmas
   cores semânticas dos outros avisos (verde de sucesso / vermelho de
   bloqueio), com a borda esquerda grossa marcando que é um estado do
   sistema, e não um alerta pontual que some. */
.janela-banner {
  border-radius: var(--radius-sm);
  border: 1px solid;
  border-left-width: 4px;
  padding: 10px 14px;
  margin-bottom: var(--sp-4);
  font-size: 12.5px;
  max-width: 820px;
}
.janela-banner .titulo {
  font-weight: 800;
  font-size: 13px;
  display: flex;
  align-items: center;
  gap: 7px;
}
.janela-banner .detalhe {
  margin-top: 3px;
}
.janela-banner.aberta {
  background: var(--success-soft);
  border-color: #b9dcc8;
  border-left-color: var(--success);
  color: var(--success);
}
.janela-banner.fechada {
  background: var(--danger-soft);
  border-color: #efc7c0;
  border-left-color: var(--danger);
  color: var(--danger);
}

/* Checkbox com rótulo na mesma linha (cabeçalho de painel) */
.check-inline {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--ink-secondary);
  cursor: pointer;
}

/* Medidor de consumo do limite mensal — a barra é redundante com o % ao lado,
   nunca a única forma de ler o valor. */
.meter {
  display: block;
  height: 7px;
  border-radius: 999px;
  background: var(--surface-sunken);
  border: 1px solid var(--border);
  overflow: hidden;
}
.meter > i {
  display: block;
  height: 100%;
  background: var(--accent);
}
.meter.is-warn > i {
  background: var(--warning);
}
.meter.is-critical > i {
  background: var(--danger);
}
.meter-row {
  display: flex;
  align-items: center;
  gap: 8px;
}
.meter-row .meter {
  flex: 1;
  min-width: 90px;
}
.meter-row .pctv {
  font-size: 11px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  min-width: 44px;
  text-align: right;
}

/* Tooltip compartilhado dos gráficos */
#vizTip {
  position: fixed;
  z-index: 200;
  pointer-events: none;
  background: var(--ink-primary);
  color: #fff;
  border-radius: 7px;
  padding: 8px 10px;
  font-size: 12px;
  line-height: 1.45;
  box-shadow: var(--shadow-overlay);
  display: none;
  max-width: 280px;
}
#vizTip b {
  color: #fff;
}
#vizTip .tk {
  display: inline-block;
  width: 9px;
  height: 9px;
  border-radius: 2px;
  margin-right: 5px;
}

/* Toast — acima da barra fixa do rodapé (.app-bottom-bar, layout.css), senão
   ele cobre os créditos que vivem ali. */
#toast {
  position: fixed;
  bottom: 52px;
  right: 20px;
  background: var(--ink-primary);
  color: #fff;
  padding: 11px 16px;
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-overlay);
  font-size: 12.5px;
  font-weight: 600;
  z-index: 100;
  display: none;
  max-width: 320px;
}
#toast.error {
  background: var(--danger);
}
#toast.success {
  background: var(--success);
}

/* Matriz do Retrospecto (departamento × 12 meses): 14 colunas não cabem numa
   tela normal, então rola na horizontal com a coluna do departamento e o
   cabeçalho fixos — sem isso o usuário perde a referência da linha no meio
   da rolagem. */
.matrix-wrap {
  overflow: auto;
  max-height: 70vh;
}
.matrix {
  border-collapse: separate;
  border-spacing: 0;
  font-size: 12px;
  white-space: nowrap;
}
.matrix th,
.matrix td {
  border-bottom: 1px solid var(--border);
  padding: 7px 10px;
}
.matrix thead th {
  position: sticky;
  top: 0;
  z-index: 2;
}
.matrix .col-dept {
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--surface);
  border-right: 1px solid var(--border);
  font-weight: 700;
  min-width: 168px;
}
.matrix thead .col-dept {
  z-index: 3;
  background: var(--accent);
  color: var(--ink-on-accent);
}
.matrix tbody tr:hover .col-dept {
  background: var(--surface-sunken);
}
/* Coluna do Total do ano — mesma formatação das colunas de mês, só em
   negrito para destacar o resultado (sem cor/fundo diferentes). */
.matrix .col-total {
  font-weight: 800;
}
.matrix tfoot td {
  position: sticky;
  bottom: 0;
  z-index: 2;
  background: var(--surface);
}
.matrix tfoot .col-dept {
  z-index: 3;
  background: var(--accent);
  color: var(--ink-on-accent);
}
/* A linha de TOTAL geral é a mais importante da planilha — o cruzamento
   dela com a coluna de total do ano é o único número que resume tudo. */
.matrix tfoot .col-total {
  background: var(--accent);
  color: var(--ink-on-accent);
  font-size: 13px;
  border-left: 2px solid var(--accent-hover);
}
/* Mês sem nenhum lançamento em nenhuma fonte: fica visivelmente "vazio" em
   vez de exibir R$ 0,00, que seria uma afirmação que não temos. */
.matrix td.vazio {
  color: var(--ink-muted);
}
.matrix .zero {
  color: var(--ink-muted);
}
.fonte-tag {
  font-size: 9.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  display: block;
  margin-top: 2px;
  color: var(--ink-muted);
}

/* Tela de erro de inicialização (pasta dados/ sem permissão de escrita) */
.startup-error {
  max-width: 560px;
  margin: 80px auto;
  text-align: center;
}
.startup-error .big {
  font-size: 34px;
  margin-bottom: var(--sp-3);
}
.startup-error pre {
  text-align: left;
  background: var(--surface-sunken);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: var(--sp-3);
  font-size: 11.5px;
  white-space: pre-wrap;
  margin: var(--sp-4) 0;
}

/* ====================================================================
   Login, sessão e permissões
   ==================================================================== */

/* Tela de login — ocupa a janela inteira; o app só aparece depois que o
   backend confirma quem entrou. */
.login-screen {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-6);
  background: linear-gradient(135deg, var(--accent) 0%, var(--accent-hover) 100%);
}
.login-card {
  background: var(--surface);
  border-radius: 18px;
  box-shadow: var(--shadow-overlay);
  width: 100%;
  max-width: 860px;
  min-height: 520px;
  display: flex;
  overflow: hidden;
}

/* Painel esquerdo — mesmo gradiente da marca, com "bolhas" decorativas
   flutuando atrás do texto, igual à referência que o usuário mandou. */
.login-side {
  position: relative;
  flex: 0 0 44%;
  overflow: hidden;
  background: linear-gradient(160deg, var(--accent) 0%, var(--accent-hover) 100%);
  color: #fff;
  display: flex;
  align-items: center;
  padding: var(--sp-7, 40px);
}
.login-side-blob {
  position: absolute;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.10);
  pointer-events: none;
}
.login-side-blob-1 { width: 260px; height: 260px; top: -80px; left: -90px; }
.login-side-blob-2 { width: 200px; height: 200px; bottom: -70px; right: -60px; background: rgba(255, 255, 255, 0.08); }
.login-side-blob-3 { width: 130px; height: 130px; bottom: 18%; left: -40px; background: rgba(255, 255, 255, 0.07); }

.login-side-content {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}
.login-side-logo {
  width: 46px;
  height: 46px;
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, 0.16);
  border: 1px solid rgba(255, 255, 255, 0.35);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 800;
  font-size: 15px;
  margin-bottom: var(--sp-2);
}
.login-side-content h1 {
  font-size: 26px;
  font-weight: 800;
  margin: 0;
}
.login-side-headline {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.78);
}
.login-side-content p {
  margin: var(--sp-2) 0 0;
  font-size: 13px;
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.82);
  max-width: 30ch;
}

/* Painel direito — o formulário em si. */
.login-form {
  flex: 1 1 56%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--sp-4);
  padding: var(--sp-7, 40px);
}
.login-form h2 {
  font-size: 22px;
  font-weight: 800;
  margin: 0;
}
.login-form-sub {
  font-size: 12.5px;
  color: var(--ink-muted);
  margin-top: calc(-1 * var(--sp-3));
}
.login-input-icon {
  position: relative;
}
.login-input-icon .ico {
  position: absolute;
  left: 12px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 14px;
  opacity: 0.55;
  pointer-events: none;
}
.login-input-icon input {
  width: 100%;
  padding-left: 34px;
}
.login-submit {
  width: 100%;
  justify-content: center;
  padding: 10px 14px;
  background: linear-gradient(90deg, var(--accent), var(--accent-hover));
  border: none;
}
.login-erro {
  background: var(--danger-soft);
  border: 1px solid var(--danger);
  color: var(--danger);
  border-radius: var(--radius-sm);
  padding: var(--sp-2) var(--sp-3);
  font-size: 12px;
}
.login-foot {
  text-align: center;
  font-size: 10px;
  color: var(--ink-muted);
}
@media (max-width: 720px) {
  .login-card { flex-direction: column; min-height: 0; max-width: 420px; }
  .login-side { flex: none; padding: var(--sp-6); }
  .login-side-content p { max-width: none; }
}
/* Número da atualização — discreto em toda tela (login e interna), só para
   identificar a versão instalada se precisar comparar com uma mais nova. */
.app-version {
  opacity: 0.7;
  font-variant-numeric: tabular-nums;
}

/* Cartão de quem está logado — o GATILHO do menu de ações, na barra fixa do
   rodapé (.app-bottom-bar, layout.css). Clicar em qualquer parte (avatar,
   nome, papel) abre o menu com Trocar senha/Sair/Encerrar — sem esses botões
   disputarem espaço com as informações na barra. */
.user-box {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 2px var(--sp-2);
  border: none;
  border-radius: var(--radius);
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background-color .15s ease;
}
.user-box:hover,
.user-box[aria-expanded="true"] {
  background: rgba(255, 255, 255, 0.08);
}
.user-box-chevron {
  width: 13px;
  height: 13px;
  flex: none;
  color: var(--ink-muted);
  transition: transform .15s ease;
}
.user-box[aria-expanded="true"] .user-box-chevron {
  transform: rotate(180deg);
}
.user-box .who {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  min-width: 0;
}
/* Sem cor própria: o cartão vive na barra grafite, onde --accent-soft já é
   um branco translúcido e o texto acompanha o resto do menu (branco). */
.user-box .avatar {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--ink-primary);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 800;
  font-size: 9px;
  flex: none;
}
/* Nome e papel LADO A LADO (não empilhados): a barra do rodapé é uma faixa
   fina, duas linhas de texto não caberiam nela. */
.user-box .ident {
  display: flex;
  align-items: baseline;
  gap: 5px;
  min-width: 0;
}
.user-box .nome {
  font-size: 11.5px;
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.user-box .papel {
  font-size: 9.5px;
  color: var(--ink-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Menu de ações (Trocar senha/Sair/Encerrar) — some por padrão; abre para
   CIMA a partir do gatilho (.user-box), ancorado em .app-bottom-bar, porque
   não há espaço abaixo (é o rodapé da tela). Largura pelo conteúdo e
   alinhado à esquerda, junto do gatilho. Aberto via classe `.open` (ver
   wireUserMenu em app.js) — clique fora, Esc ou escolher uma ação fecham. */
.user-menu {
  display: none;
  flex-direction: column;
  gap: 2px;
  position: absolute;
  left: var(--sp-4);
  bottom: 100%;
  min-width: 180px;
  margin-bottom: var(--sp-2);
  padding: var(--sp-1);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
  z-index: 60;
}
.user-menu.open {
  display: flex;
}
.user-menu-item {
  width: 100%;
  padding: var(--sp-2) var(--sp-2);
  border: none;
  border-radius: calc(var(--radius) - 2px);
  background: transparent;
  color: var(--ink-primary);
  font-size: 12.5px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
  transition: background-color .15s ease;
}
.user-menu-item:hover {
  background: rgba(255, 255, 255, 0.08);
}

/* Modal mais largo — matriz de permissões e itens de requisição não cabem
   nos 480px do modal padrão. min() é a mesma blindagem de .modal-foto/
   .modal-import-lote/.modal-vinculo — nunca ultrapassa a janela mesmo numa
   tela bem pequena. */
.modal.modal-wide {
  max-width: min(720px, 96vw);
}

/* Matriz CRUD da tela de Permissões: a primeira coluna explica o que cada
   caixinha libera, para a permissão não virar adivinhação. */

/* A matriz rola dentro da própria caixa, e não junto com o modal, para o
   cabeçalho poder ficar fixo: sem ele, ao chegar nas últimas funções ninguém
   sabe mais qual coluna é "editar" e qual é "excluir". */
.perm-matrix-wrap {
  max-height: 44vh;
  overflow: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
.perm-matrix thead th {
  position: sticky;
  top: 0;
  z-index: 1;
}
.perm-matrix th:not(:first-child),
.perm-matrix td:not(:first-child) {
  text-align: center;
  width: 84px;
}
.perm-matrix .feat-nome {
  font-weight: 700;
}
.perm-matrix .feat-hint {
  font-size: 10.5px;
  color: var(--ink-muted);
  line-height: 1.35;
  margin-top: 2px;
}
.perm-matrix input[type="checkbox"] {
  width: 16px;
  height: 16px;
  cursor: pointer;
  accent-color: var(--accent);
}
.perm-matrix td.na {
  color: var(--ink-muted);
}

/* Resumo compacto das permissões de um grupo (linha da tabela de grupos) */
.perm-summary {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.perm-summary .chip {
  font-size: 10px;
  font-weight: 700;
  padding: 2px 6px;
  border-radius: 20px;
  background: var(--accent-soft);
  color: var(--accent);
  white-space: nowrap;
}
.perm-summary .chip i {
  font-style: normal;
  opacity: 0.75;
  margin-left: 3px;
  letter-spacing: 0.5px;
}

/* Situação da requisição */
.pill-pendente {
  background: var(--warning-soft);
  color: #8a6410;
}
.pill-aprovado {
  background: var(--accent-soft);
  color: var(--accent);
}
.pill-entregue {
  background: var(--success-soft);
  color: var(--success);
}
.pill-rejeitado,
.pill-cancelado {
  background: var(--danger-soft);
  color: var(--danger);
}

/* Status da Ordem de Orçamento (Compras > Orçamentos) — 5 cores fixas pedidas
   pelo usuário, sem reaproveitar .pill-pendente/.pill-aprovado de cima porque
   o significado de cor ali é outro (aprovado = azul de destaque, não verde). */
.pill-ord-pendente {
  background: #eceef0;
  color: #5b6470;
}
.pill-ord-solicitado {
  background: var(--warning-soft);
  color: var(--warning);
}
.pill-ord-enviado_cliente {
  background: #ede4f7;
  color: #6a3fa0;
}
.pill-ord-aprovado {
  background: var(--success-soft);
  color: var(--success);
}
.pill-ord-declinado {
  background: #fbe3cf;
  color: #a4501a;
}

/* Andamento do pedido: solicitação, aprovação e entrega, cada um com autor
   e data/hora — é a coluna que responde "quem pediu, quem liberou, quando". */
.req-track {
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: 11px;
}
.req-track .step {
  display: flex;
  gap: 6px;
  align-items: baseline;
  color: var(--ink-secondary);
}
.req-track .step .marca {
  flex: none;
  width: 12px;
  text-align: center;
  font-size: 10px;
}
.req-track .step.pendente {
  color: var(--ink-muted);
  font-style: italic;
}
.req-track .step b {
  color: var(--ink-primary);
  font-weight: 700;
}

/* Lista de materiais dentro do modal de requisição */
.req-itens-vazio td {
  color: var(--ink-muted);
  text-align: center;
  padding: var(--sp-4);
}

/* Caixa de busca acima de um <select> longo (ver js/components/filtroSelect.js).
   Levemente recuada e menor que o campo que filtra: é uma ferramenta de apoio
   à lista, não mais um dado a preencher no formulário. */
.filtro-select {
  font-family: inherit;
  font-size: 12px;
  padding: 6px 9px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-sunken);
  color: var(--ink-primary);
  width: 100%;
}
.filtro-select::placeholder {
  color: var(--ink-muted);
}
.filtro-select:focus {
  outline: 2px solid var(--accent);
  outline-offset: -1px;
  background: var(--surface);
}

/* Baixa em Massa: linha cuja quantidade passou do saldo. O destaque aparece
   enquanto se digita — com dezenas de linhas na tela, um toast genérico no
   fim não diria QUAL delas está errada. */
.linha-excedida td {
  background: var(--danger-soft);
}
.linha-excedida .bm-qtd {
  border-color: var(--danger);
  color: var(--danger);
  font-weight: 700;
}
/* Mesma caixa de resumo do rodapé do modal, em tom de erro */
.info-box.info-box-erro {
  background: var(--danger-soft);
  border-color: var(--danger);
  color: var(--danger);
}

/* Resumo do lote (Entrada/Baixa em Massa). Com o filtro ativo os itens já
   escolhidos saem da tabela — esta lista é o único lugar onde o pedido
   inteiro continua visível antes de registrar. */
.info-box.info-box-lote {
  text-align: left;
}
.lote-lista {
  list-style: none;
  margin: 6px 0 0;
  padding: 0;
  max-height: 132px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.lote-lista li {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11.5px;
  padding: 2px 0;
  border-top: 1px solid var(--border);
}
.lote-tirar {
  margin-left: auto;
  border: none;
  background: none;
  cursor: pointer;
  color: var(--ink-muted);
  font-size: 12px;
  line-height: 1;
  padding: 2px 4px;
  border-radius: var(--radius-sm);
}
.lote-tirar:hover {
  background: var(--danger-soft);
  color: var(--danger);
}

/* Tela de módulo ainda sem conteúdo (Cadastro de Empresas, Gestão SOS,
   Gestão de Prazos). Existe para o menu já ter a estrutura final enquanto
   cada área é construída — e para quem clica saber que não é erro. */
.modulo-vazio {
  padding: var(--sp-6) var(--sp-5);
  text-align: center;
  max-width: 560px;
  margin: var(--sp-5) auto 0;
}
.modulo-vazio-ico {
  font-size: 34px;
  line-height: 1;
  margin-bottom: var(--sp-3);
  opacity: 0.85;
}
.modulo-vazio h2 {
  font-size: 15px;
  color: var(--ink-primary);
  margin-bottom: var(--sp-2);
}
.modulo-vazio p {
  font-size: 12.5px;
  color: var(--ink-secondary);
}

/* Bolinha da cor de identificação do tipo de serviço (Gestão de Prazos). A cor
   é escolhida pelo usuário no cadastro, então vem inline no style — aqui fica
   só a forma. Nunca é a ÚNICA informação numa linha: o nome do serviço está
   sempre ao lado, e a situação do vencimento é dita por extenso na pílula. */
.dot-cor {
  display: inline-block;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  margin-right: 7px;
  vertical-align: baseline;
  flex: none;
}

/* ============ Fornecedores e Prestadores de Serviços ============ */

/* O cadastro de empresa tem três blocos (dados, contato, especialidades) e a
   grade de chips precisa de largura para não virar uma coluna de um item só.
   min() protege janelas bem pequenas, mesma blindagem de .modal-foto/
   .modal-import-lote/.modal-vinculo/.modal-wide. */
.modal-largo {
  max-width: min(720px, 96vw);
}

/* Importar em Lote (Serviços): tabela de prévia com até 8 colunas (# +
   colunas coladas + Situação) — precisa de bem mais largura que o
   modal-largo padrão, senão força rolagem horizontal mesmo com poucas
   colunas marcadas. Especificidade dupla (.modal.modal-import-lote) pra
   ganhar de .modal-largo independente da ordem no arquivo. */
.modal.modal-import-lote {
  max-width: min(1120px, 96vw);
}
/* Novo Vínculo (Gestão de Prazos): com .modal-largo (720px) o select de
   tipo de serviço + o campo de data ficavam espremidos e forçavam rolagem
   horizontal dentro do modal — pedido explícito de pelo menos 980px. */
.modal.modal-vinculo {
  max-width: min(980px, 96vw);
}
.imp-resumo-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  flex-wrap: wrap;
}
/* Pendências agrupadas por texto colado (ex.: "Alencar" aparecendo em 6
   linhas) — resolver uma vez aqui aplica a todas de uma vez, em vez de abrir
   6 selects iguais na tabela abaixo. */
.imp-pendencias-lote {
  border: 1px solid var(--danger);
  border-radius: var(--radius-sm);
  background: var(--danger-soft);
  padding: var(--sp-3);
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
}
.imp-pendencias-lote-titulo {
  font-weight: 700;
  color: var(--danger);
  font-size: 12.5px;
}
.imp-pendencias-lote-item {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  flex-wrap: wrap;
  font-size: 12.5px;
}
.imp-pendencias-lote-item select {
  min-width: 220px;
}
/* Linha com pendência: fundo avermelhado sutil pra saltar aos olhos rolando
   a prévia inteira, sem depender só da cor da pill na última coluna. */
tr.imp-row-pendente {
  background: color-mix(in srgb, var(--danger-soft) 70%, transparent);
}
tr.imp-row-pendente:hover {
  background: color-mix(in srgb, var(--danger-soft) 100%, transparent);
}

.field-row-3 {
  display: grid;
  grid-template-columns: 1fr 2fr 0.8fr;
  gap: var(--sp-3);
}

/* Três colunas IGUAIS (diferente de .field-row-3, que é 1fr/2fr/0.8fr de
   propósito para outros formulários) — para filtros lado a lado tipo
   Mês/Ano/Parceiro. select/input dentro de um grid item não esticam sozinhos
   (tamanho intrínseco do controle, não da célula), por isso o width:100%
   explícito aqui. */
.field-row-eq3 {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--sp-3);
}
.field-row-eq3 select,
.field-row-eq3 input {
  width: 100%;
}

/* Texto de apoio abaixo de um rótulo. NÃO confundir com .help, que é o badge
   circular de interrogação. */
.field-hint {
  font-size: 11.5px;
  color: var(--ink-secondary);
  margin: -2px 0 2px;
}

/* Valor não editável dentro de um .field (ex.: condomínio da ordem de
   orçamento, só leitura no modal de detalhe) — mesma caixa visual de um
   input, sem borda de foco nem cursor de edição. */
.field-static {
  min-height: 34px;
  display: flex;
  align-items: center;
  padding: 0 2px;
  font-weight: 600;
  color: var(--ink-primary);
}

/* Área de arrastar-e-soltar o PDF/imagem da proposta (Compras > Orçamentos),
   uma por linha da tabela de propostas — pequena, cabe dentro de uma célula. */
.anexo-dropzone {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-width: 110px;
  padding: 6px 8px;
  border: 1.5px dashed var(--border-strong);
  border-radius: var(--radius, 6px);
  font-size: 11.5px;
  color: var(--ink-secondary);
  cursor: pointer;
  text-align: center;
}
.anexo-dropzone:hover {
  border-color: var(--accent-hover);
  color: var(--accent-hover);
}
.anexo-dropzone.is-dragover {
  border-color: var(--accent-hover);
  background: var(--accent-soft);
  color: var(--accent);
}
.anexo-presente {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}
.anexo-presente a {
  cursor: pointer;
}

/* Contagem dentro de uma aba do .segmented (quantos nichos o setor tem) */
.seg-count {
  display: inline-block;
  margin-left: 5px;
  padding: 0 5px;
  border-radius: 999px;
  background: var(--surface-sunken);
  color: var(--ink-secondary);
  font-size: 10px;
  font-weight: 800;
}
.segmented button.active .seg-count {
  background: rgba(255, 255, 255, 0.22);
  color: #fff;
}
/* Cinco abas (Todos + 4 setores) não caberiam numa linha em janela estreita —
   e a barra lateral já encolhe antes do conteúdo, então aqui é melhor quebrar
   do que cortar. */
.segmented {
  flex-wrap: wrap;
}

.chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

/* Especialidade só de LEITURA (linha da tabela, cartão do catálogo) */
.chip-esp {
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--accent-hover);
  font-size: 10.5px;
  font-weight: 700;
  white-space: nowrap;
}

/* Especialidade CLICÁVEL (seleção no cadastro da empresa). O estado marcado
   não é só a cor: o ✓ entra no rótulo, para quem não distingue as cores. */
.chip-toggle {
  padding: 5px 11px;
  border-radius: 999px;
  border: 1px solid var(--border-strong);
  background: var(--surface);
  color: var(--ink-secondary);
  font-size: 11.5px;
  font-weight: 600;
  cursor: pointer;
  transition: background-color .12s ease, border-color .12s ease, color .12s ease;
}
.chip-toggle:hover {
  border-color: var(--accent);
  color: var(--ink-primary);
}
.chip-toggle.on {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.chip-toggle.on::before {
  content: "✓ ";
  font-weight: 800;
}
/* × interno de um chip ativo (ex.: colunas configuráveis da importação em
   lote) — remove SÓ essa coluna, sem desligar o chip inteiro no clique
   normal (esse clique reordena, ver ativarOuReordenar em servicosImportar.js). */
.chip-toggle-x {
  display: inline-block;
  margin-left: 5px;
  opacity: .75;
}
.chip-toggle-x:hover {
  opacity: 1;
}

/* Lista rolável de condomínios (Carteira de um gerente) — troca a grade de
   chips por uma lista alfabética compacta, porque com centenas de
   condomínios a grade quebrava em dezenas de linhas e não sobrava espaço
   pra filtrar rápido. */
.carteira-lista {
  max-height: 46vh;
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
.carteira-item {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 7px var(--sp-3);
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  font-size: 12.5px;
  color: var(--ink-secondary);
}
.carteira-item:last-child {
  border-bottom: none;
}
.carteira-item:hover {
  background: var(--accent-soft);
}
.carteira-item input[type="checkbox"] {
  flex: none;
  width: 15px;
  height: 15px;
  cursor: pointer;
}
.carteira-item.on {
  color: var(--ink-primary);
  font-weight: 600;
  background: var(--accent-soft);
}
/* Dashboard de Fechamento — campos editáveis dentro da tabela de gerentes
   (Carteira, Eficácia, %, A+P). Borda tracejada avisa "isto é editável" sem
   parecer um formulário separado da tabela; .is-override marca o que foi
   digitado à mão nesta sessão (distinto do valor calculado). */
.df-campo {
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-sm);
  padding: 2px 5px;
  font-size: 12px;
  background: var(--surface);
  color: var(--ink-primary);
}
.df-campo.is-override {
  border-style: solid;
  border-color: var(--warning);
  background: color-mix(in srgb, var(--warning) 12%, var(--surface));
}

.carteira-lista-vazio {
  padding: var(--sp-4);
  text-align: center;
  color: var(--ink-muted);
  font-size: 12px;
}

/* Lista travada (ver Delta Síndicos): só leitura até clicar em "Destravar",
   pra evitar clique sem querer trocando o condomínio marcado. */
.carteira-lista.locked .carteira-item {
  cursor: default;
}
.carteira-lista.locked .carteira-item:hover {
  background: none;
}
.carteira-lista.locked .carteira-item input[type="checkbox"] {
  cursor: default;
  opacity: 0.6;
}

.esp-grupo {
  margin-bottom: var(--sp-3);
}
.esp-grupo-titulo {
  font-size: 10.5px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-muted);
  margin-bottom: 5px;
}

/* ---- Catálogo de empresas (tela de leitura, agrupada por segmento) ---- */
/* Lista inteira rola dentro de um contêiner de altura fixa — mesmo critério
   de .table-scroll (a lista cresce pra dentro dele, nunca empurra o rodapé
   da janela pra fora da tela). */
#catResultado {
  max-height: 68vh;
  overflow-y: auto;
}
/* Cada SETOR (a barra "de tópico") ganha sua própria cor — mesma forma de
   etiqueta que .section-title (degradê, texto branco maiúsculo), só que a
   cor vem inline por setor (ver corSetor() em catalogoEmpresas.js), pra
   distinguir um segmento do outro ao rolar uma lista longa. */
.cat-setor-titulo {
  color: var(--ink-on-accent);
  padding: 6px 11px;
  border-radius: var(--radius-sm);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: var(--sp-6) 0 var(--sp-3);
}
.cat-setor-titulo:first-child {
  margin-top: 0;
}
.cat-setor {
  padding: var(--sp-2) 0;
}
.cat-esp {
  padding: var(--sp-3) var(--sp-5);
  border-bottom: 1px solid var(--border);
}
.cat-esp:last-child {
  border-bottom: 0;
}
.cat-esp-cab {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  margin-bottom: var(--sp-2);
}
.cat-esp-cab b {
  font-size: 13px;
  color: var(--ink-primary);
}
/* Lista de empresas do catálogo. Era uma grade de cartões: com uma carteira
   de dezenas de empresas — e a mesma empresa repetida em cada especialidade
   que atende — virava uma parede de blocos impossível de varrer com o olho.
   Tabela é o formato certo aqui: uma linha por empresa, colunas alinhadas,
   e a comparação entre duas empresas vira uma leitura vertical. */
.cat-tabela {
  width: 100%;
}
.cat-tabela .cat-col-check {
  width: 34px;
  text-align: center;
}
.cat-tabela input[type="checkbox"] {
  cursor: pointer;
}
.cat-tabela tr.is-selecionada > td {
  background: var(--accent-soft);
}
.cat-razao {
  font-size: 11px;
  margin-top: 1px;
}
.cat-contato {
  color: var(--ink-secondary);
  font-size: 11.5px;
  white-space: nowrap;
}
.cat-setor-conta {
  font-weight: 400;
  opacity: 0.85;
  margin-left: 6px;
  text-transform: none;
  letter-spacing: 0;
}
/* Segunda linha da barra de filtros — mais discreta que a primeira, que é
   onde ficam a busca e as ações. */
.cat-filtros {
  padding-top: 0;
}
.cat-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--ink-secondary);
  white-space: nowrap;
  cursor: pointer;
}
.cat-toggle input {
  cursor: pointer;
}

/* Sim/Não da ficha da empresa. Dois rádios lado a lado em vez de um checkbox:
   "é parceira?" é uma PERGUNTA com duas respostas, e um checkbox desmarcado
   não distingue "respondi Não" de "não respondi". */
.radio-row {
  display: flex;
  gap: var(--sp-4);
  align-items: center;
}
.radio-opt {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink-primary);
  cursor: pointer;
}
.radio-opt input[type="radio"] {
  accent-color: var(--accent);
  cursor: pointer;
  margin: 0;
}

/* ---- Gestão SOS > Parceiros ---- */
/* Cartões maiores que os do Catálogo: aqui o telefone é o conteúdo principal,
   não um detalhe do cartão. */
.parceiros-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: var(--sp-3);
}
.parceiro-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--sp-4);
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.parceiro-nome {
  font-size: 14px;
  font-weight: 800;
  color: var(--ink-primary);
}
.parceiro-local {
  font-size: 11.5px;
  margin-top: -4px;
}
.parceiro-tel {
  font-size: 15px;
  font-weight: 700;
  color: var(--accent);
}
.parceiro-tel.muted {
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-muted);
}
.parceiro-emails {
  font-size: 11.5px;
  color: var(--ink-secondary);
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.parceiro-obs {
  font-size: 11.5px;
  color: var(--ink-secondary);
  border-top: 1px solid var(--border);
  padding-top: 6px;
  margin-top: 2px;
}
.imp-select {
  max-width: 220px;
  font-size: 11.5px;
  padding: 4px 6px;
}
/* Janela de confirmação de ação destrutiva (ver js/components/confirmar.js).
   Estreita de propósito: tem uma pergunta e duas saídas, e qualquer largura
   a mais só afastaria os botões do texto que se acabou de ler. */
.modal-confirmar {
  max-width: 460px;
}
.confirmar-corpo {
  display: flex;
  gap: var(--sp-3);
  align-items: flex-start;
}
.confirmar-ico {
  font-size: 26px;
  line-height: 1;
  flex-shrink: 0;
}
.confirmar-corpo p {
  margin: 0;
  font-size: 13.5px;
  color: var(--ink-primary);
  /* Várias perguntas quebram a mensagem em parágrafos com \n\n (o formato que
     o confirm() nativo pedia). Preservar a quebra mantém essas mensagens
     legíveis sem reescrever cada chamada. */
  white-space: pre-line;
}
/* A CONSEQUÊNCIA da ação, separada da pergunta: é a linha que faz alguém
   desistir a tempo, então não pode se misturar ao resto do texto. */
.confirmar-aviso {
  margin-top: var(--sp-2) !important;
  font-size: 12px !important;
  color: var(--danger) !important;
}
