/* Interface interna do gerador. Paleta e tipografia de referencia/IDENTIDADE-VISUAL.md */

:root {
  --verde-eco: #4E982E;
  --verde-folha: #3B7542;
  --verde-broto: #8EB864;
  --verde-eco-texto: #3E7A24;
  --dourado-25: #C9A62F;
  --grafite: #474747;
  --cinza: #646C66;
  --linha: #DDE5DA;
  --verde-nevoa: #F2F7EE;
  --branco: #FFFFFF;
  --vermelho: #B23A3A;
  --classe-a: #7A6A55;
  --classe-b: #4E982E;
  --classe-c: #C07F1F;
  --classe-d: #B23A3A;
}

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

body {
  font-family: 'Inter', system-ui, sans-serif;
  color: var(--grafite);
  background: #F6F8F4;
  font-size: 14px;
  line-height: 1.5;
}

/* Barra da marca: só verdes, como nos modelos — o dourado saiu. */
.filete {
  height: 6px;
  background: linear-gradient(90deg, var(--verde-folha) 0%, var(--verde-eco) 55%, var(--verde-broto) 100%);
}

/* Alinhamento monetário: R$ em posição fixa, número à direita.
   Aqui a largura mínima vai em `ch` — com tabular-nums, 1ch é a largura de um
   dígito, então a coluna acompanha qualquer grandeza sem cálculo por tela.
   No documento a mesma regra usa px, porque lá o CSS é verbatim dos modelos. */
.v { display: inline-flex; gap: 4px; justify-content: flex-end; }
.v i { font-style: normal; color: var(--cinza); }
.v b { font-weight: inherit; min-width: var(--largura-valor, 8ch); text-align: right; font-variant-numeric: tabular-nums; }

a { color: var(--verde-eco-texto); }

/* ===== Topo ===== */
.topo { background: var(--branco); border-bottom: 1px solid var(--linha); }
.topo-interno {
  max-width: 1180px; margin: 0 auto;
  display: flex; align-items: center; gap: 28px;
  padding: 12px 24px;
}
.marca { display: flex; align-items: center; gap: 12px; text-decoration: none; }
/* Logo horizontal: mínimo de 140 px de largura em tela (identidade visual).
   Proporção 1200×445 → 52 px de altura dá ~140 px de largura. */
.marca img { height: 52px; width: auto; min-width: 140px; display: block; }
.marca span {
  font-family: 'Quicksand', sans-serif; font-weight: 700; font-size: 15px;
  color: var(--verde-folha);
}
/* A barra de abas CRESCE: cada aba nova (Diesel, Fila do CDF…) alarga a
   linha, e quem vê todas é o admin. Sem poder encolher, a nav empurrava o
   cabeçalho inteiro para fora da tela — 216px de estouro num viewport de
   1355px, com o "Sair" escapando pela direita.
   `min-width: 0` é o que a deixa encolher: item de flex não passa do próprio
   min-content sem isso, e a nav inteira contava como uma palavra só. Com o
   `flex-wrap`, as abas se reorganizam em duas fileiras DENTRO da nav.
   Quebrar aqui, e não no `.topo-interno`: quebrando lá, a nav ganhava a linha
   toda e o "Administrador" e o "Sair" desciam para a esquerda da segunda
   linha, longe de onde a pessoa os procura. */
.abas { display: flex; flex-wrap: wrap; gap: 4px; margin-left: auto; min-width: 0; }
.aba {
  padding: 7px 14px; border-radius: 8px; text-decoration: none;
  font-weight: 600; font-size: 13.5px; color: var(--cinza);
}
.aba:hover { background: var(--verde-nevoa); }
.aba.ativa { background: var(--verde-nevoa); color: var(--verde-eco-texto); }
.sair { margin-left: 8px; }

/* Nav LONGA ganha a linha inteira (`.abas-longas`, posto pelo layout a partir
   de 10 abas — o número está medido lá).

   Ao lado do logo a nav disputa o que sobra: em 1024px são 481px de coluna
   para 11 abas, que empilham em QUATRO fileiras — 173px de cabeçalho fixo,
   acima do teto de 160px, e piorando para 211, 288 e 443px conforme a janela
   estreita. E não é falta de tela: as 11 abas numa fileira só medem 1307px, e
   o cabeçalho é limitado a 1180px — ao lado do logo elas nunca caberiam em
   largura nenhuma. Na linha inteira são 1132px úteis, e ficam DUAS fileiras
   fixas: 147px em 1366, 1180, 1024, 940, 860 e 780px, o mesmo cabeçalho em
   toda largura, em vez de um que cresce quando a janela encolhe.

   `order: 5` é o que mantém o selo "Administrador" e o "Sair" em cima: sem
   ele a nav levava a linha e os dois desciam para a ESQUERDA da segunda,
   longe de onde a pessoa os procura. É o mesmo arranjo do celular.

   Daí o `min-width: 701px`: no celular a régua auditada já manda — lá a nav é
   UMA fileira que rola, e esta regra, mais específica, sobrescreveria o
   respiro e o tamanho de aba que aquela mediu. */
@media (min-width: 701px) {
  .topo-interno.abas-longas { flex-wrap: wrap; row-gap: 6px; padding: 10px 24px; }
  .topo-interno.abas-longas .abas { order: 5; width: 100%; margin-left: 0; }
  .topo-interno.abas-longas .etiqueta-admin { margin-left: auto; }
  .topo-interno.abas-longas .aba { padding: 6px 12px; }
}
/* Abaixo do notebook largo o admin — que hoje vê VINTE itens (as doze abas,
   os atalhos e as áreas dele) — passa para TRÊS fileiras, e o cabeçalho é fixo
   em toda tela: crescendo, come o conteúdo de todas.

   A faixa e os números saíram de MEDIÇÃO, não de gosto (com a aba Faturas, em
   16/09/2026), e em duas etapas porque o estouro tem duas causas diferentes:

     sem aperto    1366→1060: 147px (2 fileiras) · 1024→1010: 183px (3) ·
                   1000→980: 140px (2, pelo aperto antigo) · 900→720: 172px (3)
     com o aperto  1366→1180: 147px · 1100→900: 138px (2 fileiras) ·
                   800→720: 150px (3 fileiras, mas dentro do teto)

   O buraco de 1001 a 1059px era a faixa que o aperto antigo (max-width: 1000px)
   não alcançava — ali a aba larga já não cabia em duas fileiras e nada a
   apertava. Por isso o teto subiu para 1100px.

   Abaixo de 860px três fileiras são inevitáveis com vinte itens: o que a
   segunda etapa faz é caberem DENTRO do teto (150px), apertando o respiro
   entre elas além da aba. Acima de 1100px a largura já basta. */
@media (min-width: 701px) and (max-width: 1100px) {
  .topo-interno.abas-longas .aba { padding: 5px 7px; font-size: 12px; }
}
@media (min-width: 701px) and (max-width: 860px) {
  .topo-interno.abas-longas { row-gap: 4px; padding: 8px 16px; }
  .topo-interno.abas-longas .aba { padding: 3px 6px; font-size: 11.5px; }
}

/* ===== As duas navegações =====
   A mesma lista de abas desenhada de dois jeitos, e quem escolhe é quem olha
   (cookie, `src/lib/navegacao.js`). A diferença é REAL e não gosto: a Sabrina
   tem UMA aba e o admin tem vinte itens. Não há desenho bom para os dois.

     `areas`  (padrão) — as sete ÁREAS na linha do logo e, abaixo, a faixa com
                         as telas da área aberta. O conteúdo mantém a largura.
     `coluna`          — cabeçalho fino e a lista inteira numa coluna à
                         esquerda, que cabe sem empilhar.

   O que NÃO muda: a ÁREA é `.aba` e a faixa é `.abas`, de propósito — toda a
   régua auditada do celular (a sombra que promete rolagem, o anel de foco
   desenhado para dentro, o `abas.js`) está escrita sobre essas duas classes,
   medida em pixel. Classe nova perderia as três de uma vez, sem nada acusar.
   E abaixo de 700px as duas navegações caem naquela MESMA faixa que rola: a
   coluna a 390px desfaria o que aquela medição comprou. */

/* A faixa do segundo nível (só na `areas`): as telas da área que está aberta.
   Fundo branco como o cabeçalho, porque ela é a segunda linha dele — e é o
   branco que deixa a faixa reusar, no celular, a mesma tampa da sombra. */
.faixa-area { background: var(--branco); border-top: 1px solid var(--linha); }
.faixa-area-interna {
  max-width: 1180px; margin: 0 auto; padding: 0 24px;
  display: flex; gap: 2px; align-items: stretch;
}
.item-area {
  padding: 7px 12px 6px; text-decoration: none; white-space: nowrap;
  font-size: 13px; font-weight: 600; color: var(--cinza);
  border-bottom: 2px solid transparent;
}
.item-area:hover { color: var(--grafite); }
/* O item aberto se marca por TRAÇO embaixo, não por pílula: a pílula é a marca
   da ÁREA, lá em cima, e repeti-la aqui faria os dois níveis parecerem o mesmo
   nível. Cor mais borda, as duas pistas, pela régua de sempre. */
.item-area.ativo { color: var(--verde-eco-texto); border-bottom-color: var(--verde-eco); }
.item-area:focus-visible { outline: 2px solid var(--verde-folha); outline-offset: -3px; }

/* O botão que troca a navegação — ao lado do "Sair", que é onde se vê o que se
   está trocando. Só o ícone: o rótulo vai no `title`/`aria-label`. */
.troca-nav .btn { padding: 6px 8px; }
.troca-nav svg { display: block; }

@media (min-width: 701px) {
  /* A coluna é um IRMÃO do cabeçalho, não um filho: assim o filete e o
     cabeçalho seguem atravessando a tela inteira e só o miolo se divide. */
  body.nav-coluna {
    display: grid;
    grid-template-columns: 196px minmax(0, 1fr);
    /* A linha da faixa da homologação existe sempre: sem a faixa ela é `auto`
       sem item, isto é, altura zero; sem a linha, a faixa caía numa linha
       IMPLÍCITA no fim da página, longe de quem precisa vê-la. */
    grid-template-rows: auto auto auto minmax(0, 1fr);
    grid-template-areas: 'filete filete' 'faixa faixa' 'topo topo' 'nav conteudo';
    min-height: 100vh;
  }
  body.nav-coluna > .filete { grid-area: filete; }
  body.nav-coluna > .faixa-homologacao { grid-area: faixa; }
  body.nav-coluna > .topo { grid-area: topo; }
  body.nav-coluna > .coluna-nav { grid-area: nav; }
  /* As DUAS declarações é que fazem a coluna do conteúdo valer, e nenhuma
     sozinha resolve — medido, porque a primeira tentativa foi só o `min-width`
     e a tela continuou estourando os mesmos 149px em 720px:
       - `margin: 0 auto` (que o `.conteudo` traz, para centralizar) faz o item
         de grade NÃO esticar: ele passa a ser shrink-to-fit, e shrink-to-fit
         tem o min-content como piso — a fila de títulos ficava com 673px numa
         trilha de 604px, sem reflow nenhum ao estreitar a janela. `width: 100%`
         devolve a largura da trilha, e as margens automáticas continuam
         centralizando quando ela passa do `max-width`;
       - `min-width: 0` porque item de grade nasce com `min-width: auto`, que
         voltaria a subir a largura para o min-content. É a mesma lição do
         `min-width: 0` da nav, duas telas acima neste arquivo. */
  body.nav-coluna > .conteudo { grid-area: conteudo; width: 100%; min-width: 0; }

  /* Cabeçalho SEM abas: só o logo, o selo, a troca e o "Sair". O logo mantém
     os 52px de altura — encolher a altura com o `min-width: 140px` da
     identidade em pé esticaria a imagem, porque não há `object-fit` aqui. */
  .topo-fino .marca { margin-right: auto; }

  .coluna-nav {
    flex-direction: column; flex-wrap: nowrap; align-content: start;
    gap: 2px; margin-left: 0; padding: 14px 10px;
    background: var(--branco); border-right: 1px solid var(--linha);
  }
  .coluna-nav .aba { display: block; }
  /* A tela dentro da área aberta: recuada e em corpo menor, para os dois
     níveis se distinguirem sem uma segunda cor. */
  .coluna-nav .aba.filho {
    padding: 5px 10px 5px 24px; font-size: 12.5px; font-weight: 500;
  }
  .coluna-nav .aba.filho.ativa { font-weight: 600; }

  /* Com a coluna, a largura do CONTEÚDO não é a da janela: são 196px a menos.
     As media queries escritas para a largura do conteúdo passam a mentir, e a
     dos tiles é a que estoura primeiro — medido na fila de títulos: 26px além
     da borda em 720px e 6px em 800px, porque quatro tiles fixos não cabem em
     476px e o `.v` tem largura mínima. Aqui eles respondem ao ESPAÇO.
     O certo a longo prazo é `@container` no `main` e converter as regras de
     largura de conteúdo — fica anotado, e não se faz agora por ser uma
     varredura no arquivo inteiro, não uma correção. */
  body.nav-coluna .tiles-monitoramento {
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  }
}

/* A troca some no celular, e não é economia de espaço: abaixo de 700px as duas
   navegações SÃO a mesma faixa que rola, então o botão não mudaria nada — e
   ainda empurrava o selo e o "Sair" para uma segunda fileira, 39px de
   cabeçalho a mais num aparelho de 390px. A escolha continua valendo: ela mora
   no cookie e volta a valer no computador. */
@media (max-width: 700px) {
  .troca-nav { display: none; }
}

/* ===== Conteúdo ===== */
.conteudo { max-width: 1180px; margin: 0 auto; padding: 24px; }
.conteudo.estreito { max-width: 520px; }
.conteudo.largo { max-width: 1320px; }

.cabecalho-pagina {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 16px; margin-bottom: 18px; flex-wrap: wrap;
}
h1 {
  font-family: 'Quicksand', sans-serif; font-weight: 700;
  font-size: 24px; color: var(--verde-folha); letter-spacing: -.01em;
}
h2 {
  font-family: 'Quicksand', sans-serif; font-weight: 700; font-size: 13px;
  text-transform: uppercase; letter-spacing: .1em; color: var(--cinza);
  margin-bottom: 12px;
}
h3 { font-family: 'Quicksand', sans-serif; font-weight: 700; font-size: 15px; color: var(--verde-folha); }
.subtitulo { color: var(--cinza); font-size: 13px; }

/* ===== Cartões ===== */
.cartao {
  background: var(--branco); border: 1px solid var(--linha);
  border-radius: 12px; padding: 18px 20px; margin-bottom: 16px;
}
.cartao > h2 { margin-bottom: 14px; }
.cartao-suave { background: var(--verde-nevoa); }

/* ===== Formulários ===== */
.campos { display: grid; gap: 14px 18px; }
.campos.col-2 { grid-template-columns: 1fr 1fr; }
.campos.col-3 { grid-template-columns: 1fr 1fr 1fr; }
.campos.col-4 { grid-template-columns: repeat(4, 1fr); }
.col-cheia { grid-column: 1 / -1; }
/* O campo que ocupa DUAS colunas é classe, não `style="grid-column:span 2"`:
   quando a grade colapsa para uma coluna (abaixo de 900px), um `span` fixo
   cria colunas IMPLÍCITAS — medido no formulário do vigia a 390px: a coluna
   explícita ficou com 65px (o campo "Valor" ilegível) e as duas implícitas
   com 154px cada, 85px além do cartão. A classe volta a `auto` na mesma
   media query; o `.col-cheia` (1 / -1) já não tem esse problema. */
.col-dupla { grid-column: span 2; }
/* Texto que não tem espaço para quebrar (um e-mail comprido, um hash): sem
   isto ele empurra a página inteira para fora do celular. */
.quebra-tudo, .origem.quebra-tudo { overflow-wrap: anywhere; white-space: normal; }
/* A LINHA DIGITÁVEL do boleto: 47 dígitos (48 na arrecadação) que o banco
   guarda sem pontuação. Quem dá onde quebrar é `linhaDigitavelImpressa`, que a
   devolve nos campos do próprio papel — aqui só se garante que a quebra VALE
   (`normal`) e se põe a rede de baixo: comprimento que o formatador não
   reconhece volta cru, e `anywhere` impede que essa palavra única estique a
   coluna de novo. Sem isso a tabela da pasta de boletos saía ~300px além do
   cartão, com o fim da linha atrás da barra de rolagem. */
.linha-digitavel {
  font-size: 11px; line-height: 1.55; display: inline-block;
  white-space: normal; overflow-wrap: anywhere;
}

label, .rotulo-campo {
  display: block;
  font-size: 10px; font-weight: 600; text-transform: uppercase;
  letter-spacing: .08em; color: var(--verde-eco-texto); margin-bottom: 4px;
}
label .opcional { color: var(--cinza); font-weight: 500; letter-spacing: 0; text-transform: none; }

/* Todo tipo de campo de texto que o app usa, inclusive mês e hora: campo cujo
   tipo não está aqui sai com a cara crua do navegador (menor, sem borda
   arredondada, desalinhado do rótulo) — e `input` SEM `type` também, por
   isso `test/mobile.test.js` recusa os dois. */
input[type="text"], input[type="password"], input[type="date"], input[type="number"],
input[type="search"], input[type="email"], input[type="month"], input[type="time"],
input[type="tel"], select, textarea {
  width: 100%; font-family: inherit; font-size: 14px; color: var(--grafite);
  background: var(--branco);
  border: 1px solid var(--linha); border-radius: 8px; padding: 8px 10px;
}
input:focus, select:focus, textarea:focus {
  outline: 2px solid var(--verde-eco); outline-offset: -1px; border-color: var(--verde-eco);
}
input.dinheiro { text-align: right; font-variant-numeric: tabular-nums; }
textarea { resize: vertical; min-height: 68px; line-height: 1.5; }
input:disabled, select:disabled, textarea:disabled { background: #F3F5F2; color: var(--cinza); }
.ajuda { font-size: 11.5px; color: var(--cinza); margin-top: 4px; }
.erro-campo { font-size: 11.5px; color: var(--vermelho); margin-top: 4px; }
input.invalido, select.invalido { border-color: var(--vermelho); }

/* ===== Botões ===== */
.btn {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: inherit; font-size: 13.5px; font-weight: 600;
  border-radius: 8px; padding: 8px 14px; border: 1px solid transparent;
  cursor: pointer; text-decoration: none; background: var(--branco);
  color: var(--grafite);
}
.btn:disabled { opacity: .55; cursor: not-allowed; }
.btn-primario { background: var(--verde-folha); color: #fff; }
.btn-primario:hover:not(:disabled) { background: #326239; }
.btn-secundario { border-color: var(--linha); color: var(--verde-eco-texto); }
.btn-secundario:hover:not(:disabled) { background: var(--verde-nevoa); }
.btn-texto { border-color: transparent; color: var(--cinza); background: transparent; }
.btn-texto:hover:not(:disabled) { color: var(--grafite); text-decoration: underline; }
.btn-perigo { border-color: var(--linha); color: var(--vermelho); }
.btn-perigo:hover:not(:disabled) { background: #FBF1F1; }
.btn-pequeno { padding: 5px 10px; font-size: 12.5px; }
.acoes { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.acoes-fim { margin-left: auto; }

/* ===== Alertas ===== */
.alerta {
  border-radius: 10px; padding: 11px 14px; margin-bottom: 16px;
  font-size: 13px; border: 1px solid;
}
.alerta-erro { background: #FBF1F1; border-color: #E7C9C9; color: #8E2E2E; }
.alerta-ok { background: var(--verde-nevoa); border-color: #C9DEBC; color: var(--verde-eco-texto); }
.alerta-aviso { background: #FDF7E6; border-color: #EBDCA8; color: #7A5F12; }
/* A lista das retiradas que a montagem deixou de fora: uma por linha, com o motivo. */
.alerta-recusas ul { margin: 6px 0 0; padding-left: 18px; }
.alerta-recusas li + li { margin-top: 4px; }

/* ===== Tabelas ===== */
/* `overflow-x: auto` em TODA largura, não só no celular.
   O `hidden` de antes servia para as pontas arredondadas não vazarem, e de
   quebra CORTAVA a tabela larga: no desktop a coluna sumia sem barra de
   rolagem e sem sinal nenhum de que havia mais coisa à direita — aconteceu
   com a fila do CDF, que perdeu a coluna do excluir inteira. Cortar em
   silêncio é pior que rolar: quem olha não sabe que está vendo menos.
   O `overflow-y: hidden` continua clipando as pontas. */
.tabela-envelope {
  background: var(--branco); border: 1px solid var(--linha);
  border-radius: 12px; overflow-x: auto; overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
}
table { width: 100%; border-collapse: collapse; }
th {
  text-align: left; font-size: 10px; font-weight: 600; text-transform: uppercase;
  letter-spacing: .08em; color: var(--verde-eco-texto);
  padding: 10px 14px; background: var(--verde-nevoa);
  border-bottom: 1px solid var(--linha); white-space: nowrap;
}
td { padding: 10px 14px; border-top: 1px solid var(--linha); font-size: 13.5px; vertical-align: top; }
tbody tr:hover { background: #FAFCF8; }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
td.nao-quebra { white-space: nowrap; }
td.acoes-linha { white-space: nowrap; text-align: right; }
td.acoes-linha a, td.acoes-linha button { margin-left: 4px; }
.vazio { padding: 28px 16px; text-align: center; color: var(--cinza); font-size: 13.5px; }

/* ===== Etiquetas ===== */
.etiqueta {
  display: inline-block; font-size: 10.5px; font-weight: 600; letter-spacing: .04em;
  padding: 2px 8px; border-radius: 999px; border: 1px solid var(--linha);
  color: var(--cinza); background: var(--branco); white-space: nowrap;
}
.etiqueta-emitido { background: var(--verde-nevoa); border-color: #C9DEBC; color: var(--verde-eco-texto); }
/* A fatura e se ela foi paga, na fila do CDF e nas retiradas: é frase ("Fatura
   nº 12 vencida, sem pagamento") e por isso QUEBRA — `nowrap` numa célula
   esticaria a coluna, a régua das frases nas tabelas. */
.pagamento-fatura { margin-top: 4px; }
.pagamento-fatura .etiqueta { white-space: normal; border-radius: 10px; }
.pagamento-fatura a { color: inherit; }
.etiqueta-rascunho { background: #FDF7E6; border-color: #EBDCA8; color: #7A5F12; }
.etiqueta-mensal { background: #FBF4E3; border-color: #EBDCB4; color: #8A6A24; font-weight: 700; }
.etiqueta-admin { background: #FBF4E3; border-color: #EBDCB4; color: #8A6A24; font-weight: 700; }
.etiqueta-excluido { background: #FBF1F1; border-color: #E7C9C9; color: #8E2E2E; }
/* Excluído continua visível para o admin, mas recuado do resto da lista. */
.linha-excluida td { background: #FCFAFA; }
.linha-excluida td:not(.acoes-linha) { opacity: .72; }
.etiqueta-classe {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 26px; height: 22px; padding: 0 6px; border-radius: 6px;
  font-family: 'Quicksand', sans-serif; font-weight: 700; font-size: 12px; color: #fff;
}
.etiqueta-classe.a { background: var(--classe-a); }
.etiqueta-classe.b { background: var(--classe-b); }
.etiqueta-classe.ab { background: linear-gradient(135deg, var(--classe-a) 50%, var(--classe-b) 50%); }
.etiqueta-classe.c { background: var(--classe-c); }
.etiqueta-classe.d { background: var(--classe-d); }
.etiqueta-classe.outro { background: var(--cinza); }
/* Ícone da caçamba (identidade visual) + o volume ao lado, nunca dentro dele. */
.icone-cacamba { flex: none; width: 30px; height: 19px; color: var(--verde-folha); }
.icone-cacamba.larga { width: 40px; }
.etiqueta-m3 {
  display: inline-flex; align-items: center; gap: 6px;
  color: var(--verde-folha); white-space: nowrap;
  font-family: 'Quicksand', sans-serif; font-weight: 700; font-size: 12.5px;
}
.pendente { color: var(--vermelho); }

/* ===== Login ===== */
.login-caixa { margin-top: 12vh; }
/* Na entrada usa a horizontal (preferencial em cabeçalhos), acima do mínimo. */
.login-caixa .logo { display: block; margin: 0 auto 22px; height: 64px; width: auto; }

/* ===== Editor ===== */
.editor-barra {
  position: sticky; top: 0; z-index: 20;
  background: rgba(246, 248, 244, .94); backdrop-filter: blur(4px);
  border-bottom: 1px solid var(--linha);
  padding: 12px 0; margin-bottom: 18px;
}
.editor-barra .interno {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
}

.bloco-cacamba-editor {
  border: 1px solid var(--linha); border-radius: 12px;
  background: var(--branco); margin-bottom: 14px; overflow: hidden;
}
.bloco-cacamba-editor > .cabeca {
  display: flex; align-items: center; gap: 12px;
  background: var(--verde-nevoa); border-bottom: 1px solid var(--linha);
  padding: 10px 16px;
}
.bloco-cacamba-editor > .cabeca .titulo-bloco {
  font-family: 'Quicksand', sans-serif; font-weight: 700; font-size: 15px; color: var(--verde-folha);
}
.bloco-cacamba-editor > .cabeca label { margin-bottom: 0; }
/* Ícone da caçamba no cabeçalho do bloco — mesmas medidas do documento. */
.icone-bloco { display: inline-flex; flex: none; }
.icone-bloco .icone-cacamba { width: 58px; height: 37px; }
.icone-bloco .icone-cacamba.larga { width: 76px; }
.campo-volume { display: flex; align-items: center; gap: 8px; }
.campo-volume select { width: auto; }
.campo-volume input[type="number"] { width: 92px; }
/* Quantidade de caçambas do modelo — anotação opcional, campo curto. */
.campo-quantidade { display: flex; align-items: center; gap: 6px; }
.campo-quantidade input[type="number"] { width: 72px; }

/* Faixa dos dois valores fixos do bloco em locação mensal. */
.valores-fixos-editor {
  background: var(--verde-nevoa); border-top: 1px solid var(--linha); padding: 14px 16px;
}
.bloco-cacamba-editor > .cabeca select[data-modalidade] { width: auto; }
.bloco-cacamba-editor.mensal > .cabeca { background: #FBF4E3; border-color: #EBDCB4; }
.bloco-cacamba-editor.mensal > .cabeca select[data-modalidade] { border-color: #EBDCB4; }

.rodape-bloco { padding: 12px 16px; border-top: 1px solid var(--linha); }
.linha-classe-editor { border-top: 1px solid var(--linha); padding: 14px 16px; }
.linha-classe-editor:first-of-type { border-top: none; }
.linha-classe-editor .topo-linha {
  display: flex; align-items: center; gap: 10px; margin-bottom: 12px;
}
.linha-classe-editor .topo-linha select { width: auto; min-width: 250px; }
.opcoes-descarte { display: grid; gap: 8px; }
.opcao-descarte {
  display: grid; grid-template-columns: 1fr 150px 130px auto; gap: 10px; align-items: end;
  background: var(--verde-nevoa); border: 1px solid var(--linha);
  border-radius: 8px; padding: 10px 12px;
}
.unitario-calculado {
  font-size: 13px; font-weight: 700; color: var(--verde-folha);
  font-variant-numeric: tabular-nums; padding-top: 6px;
}
.unitario-calculado .rot {
  display: block; font-size: 10px; font-weight: 600; text-transform: uppercase;
  letter-spacing: .08em; color: var(--verde-eco-texto);
}
.arrastar { cursor: grab; color: var(--cinza); font-size: 16px; user-select: none; }

/* Taxas municipais: caixa de seleção + valor, uma por taxa. */
.taxa-municipal {
  border: 1px solid var(--linha); border-radius: 10px; padding: 12px 14px;
  background: var(--branco);
}
.marcador {
  display: flex; align-items: center; gap: 8px; margin-bottom: 0;
  font-size: 13.5px; font-weight: 600; text-transform: none; letter-spacing: 0;
  color: var(--grafite); cursor: pointer;
}
.marcador input[type="checkbox"] { width: 16px; height: 16px; accent-color: var(--verde-folha); }
.taxa-municipal .ajuda { margin-top: 4px; }

/* Extrato Itaú: dia como cabeçalho de grupo, conferência inline por linha. */
.tabela-extrato .dia-extrato th {
  background: var(--verde-fundo); color: var(--grafite);
  font-size: 13px; text-transform: none; letter-spacing: 0;
  border-top: 2px solid var(--linha);
}
.tabela-extrato .descricao-banco { font-variant-numeric: tabular-nums; white-space: nowrap; }

/* NOME DE ARQUIVO numa tabela: quebra, e quebra até no meio da palavra.
   É o oposto da descrição do banco logo acima — aquela é código curto e
   tabular, e não pode quebrar. O nome de um MTR é uma frase de 115
   caracteres ("MTR 411032704021 - Plaenge - Caçamba 469 - Rua Professor
   Pedro Viriato Parigot De Souza, 4555, Condomínio Átrio.pdf"), e com o
   nowrap daquela classe ele sozinho empurrava a tabela da fila do CDF para
   1393px: as colunas do vencimento e do excluir saíam da tela, cortadas sem
   barra de rolagem nenhuma. O `anywhere` cobre o nome sem espaços, que
   nenhuma quebra normal separaria. */
.tabela-extrato .nome-documento { overflow-wrap: anywhere; }
/* Recebimento envelhecendo sem OK — degraus do dono: âmbar > 7 dias, vermelho
   > 15. Cor cheia e faixa na borda: o dono pediu a fila da baixa GRITANDO. */
.tabela-extrato tr.atraso-atencao td { background: #F8E7A9; }
.tabela-extrato tr.atraso-atencao td:first-child { box-shadow: inset 5px 0 0 #C9A62F; }
.tabela-extrato tr.atraso-critico td { background: #F5C8C8; }
.tabela-extrato tr.atraso-critico td:first-child { box-shadow: inset 5px 0 0 #B23A3A; }
/* O "R$" cinza sumia sobre a cor cheia: nas linhas pintadas ele escurece. */
.tabela-extrato tr.atraso-atencao .v i,
.tabela-extrato tr.atraso-critico .v i { color: #474747; }
.legenda-atraso { padding: 1px 8px; border-radius: 6px; font-weight: 600; }
.legenda-atraso.atencao { background: #F8E7A9; color: #6B520D; }
.legenda-atraso.critico { background: #F5C8C8; color: #8E2E2E; }
/* Os totais da conferência sob o total do mês: OK × sem OK, lado a lado. */
.totais-conferencia { display: flex; gap: 14px; flex-wrap: wrap; font-size: 12.5px; margin-top: 4px; }
.totais-conferencia .tot-ok { color: var(--verde-eco-texto); font-weight: 600; }
.totais-conferencia .tot-sem-ok { color: #8E2E2E; font-weight: 600; }

/* O alvo do "Ver mais" respira ao aterrissar pela âncora, em vez de colar no topo. */
[id] { scroll-margin-top: 14px; }

/* Log de ações (admin): dia como cabeçalho de grupo, como no extrato. */
.tabela-logs .dia-log th {
  background: var(--verde-fundo); color: var(--grafite);
  font-size: 13px; text-transform: none; letter-spacing: 0;
  border-top: 2px solid var(--linha);
}
.tabela-logs .hora-log { font-variant-numeric: tabular-nums; white-space: nowrap; }
.tabela-logs .caminho-log {
  font-family: ui-monospace, 'Cascadia Mono', 'Consolas', monospace;
  font-size: 12px; color: var(--cinza); word-break: break-all; max-width: 340px;
}
/* Id da máquina (cookie do navegador) com o IP embaixo, os dois em mono. */
.tabela-logs .maquina-log {
  font-family: ui-monospace, 'Cascadia Mono', 'Consolas', monospace;
  font-size: 12px; white-space: nowrap;
}
.tabela-logs .maquina-log .origem { display: block; }

/* Usuários (admin): cargo/e-mail e a explicação da situação embaixo, quebrando
   à vontade — a linha nunca pode estourar a largura no celular. */
.tabela-usuarios .origem { display: block; white-space: normal; margin-top: 2px; }
.tabela-usuarios td.acoes-linha form { display: inline; }
/* As caixas de aba em grade curta (2 colunas): seis numa linha só empurrariam
   a tabela para fora do celular; os botões ficam embaixo, alinhados. */
.tabela-usuarios .caixas-abas {
  display: grid; grid-template-columns: repeat(2, minmax(120px, max-content));
  gap: 2px 14px;
}
.tabela-usuarios .caixas-abas .marcavel { white-space: nowrap; }
.tabela-usuarios .acoes-abas {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 6px;
}
.tabela-usuarios .acoes-abas .acao-doc { margin: 0; }
.conferencia-extrato { display: flex; align-items: center; gap: 8px; }
/* A barra do salvar em lote: a ajuda de um lado, o botao do outro; no
   celular empilha em vez de estourar a largura. */
.barra-conferencia { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 8px; }
.barra-conferencia .ajuda { margin: 0; flex: 1 1 260px; }
.conferencia-extrato input[type="text"] { flex: 1 1 170px; min-width: 130px; }
.conferencia-extrato .campo-observacao { flex: 1 1 200px; }
.conferencia-extrato .marcavel { white-space: nowrap; }
.destaque-total { font-size: 15px; font-weight: 600; color: var(--grafite); padding-top: 6px; }
.destaque-total .origem { font-weight: 400; }

/* Monitoramento de km: média km/serviço com os dois degraus de alerta do
   dono — atenção (ambar, rota a revisar) e crítico (vermelho, urgente). */
.media-atencao { color: #7A5F12; font-weight: 700; }
.media-critica { color: var(--vermelho); font-weight: 700; }
.media-ok { color: var(--verde-folha); }
.etiqueta-confirmar { background: #FDF7E6; border-color: #EBDCA8; color: #7A5F12; }
.etiqueta-confirmado { background: var(--verde-nevoa); border-color: #C9DEBC; color: var(--verde-eco-texto); }
.etiqueta-critica { background: #FBF1F1; border-color: #E7C9C9; color: #8E2E2E; }
.etiqueta-neutra { background: var(--verde-nevoa); }
/* Afastamentos: encerrar (data + botão) e excluir dividem a célula de ações —
   quebra de linha em vez de estourar o cartão na horizontal. */
#afastamentos td.acoes-linha { white-space: normal; }
/* A divisão e o desconto ficam cada um num grupo compacto, que pode quebrar
   de linha por inteiro dentro do formulário — nunca no meio de um rótulo. */
.divisao-caminhao { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; white-space: nowrap; }
.divisao-caminhao select { max-width: 180px; min-width: 0; }
.divisao-caminhao .campo-km1 { width: 58px; }
.divisao-caminhao .campo-obs-desconto { flex: 1 1 130px; min-width: 120px; max-width: 200px; }
/* A anotação do desconto embaixo do km: bloco estreito alinhado à direita,
   quebrando dentro dele — em linha única ela alargava a coluna inteira. */
td .desconto-nota { display: block; white-space: normal; max-width: 190px; margin-left: auto; text-align: right; }
#afastamentos .acao-doc { display: inline-flex; gap: 6px; align-items: center; margin: 2px 0 2px 4px; }
#afastamentos .acao-doc input[type="date"] { width: 150px; }
.servicos-motorista, .vinculo-caminhao, .cadastro-motorista {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
.servicos-motorista .campo-servicos { width: 64px; }
.servicos-motorista .campo-observacao { flex: 1 1 0; min-width: 0; }
/* O vínculo empilha os grupos (motorista, divisão, desconto, salvar) numa
   coluna de largura limitada: numa linha só, o desconto estourava o cartão. */
.vinculo-caminhao { flex-direction: column; align-items: flex-start; gap: 6px; max-width: 400px; }
.vinculo-caminhao > select { width: 100%; max-width: 320px; }
.acoes-vinculo { display: flex; align-items: center; gap: 8px; }
.cadastro-motorista input[type="text"] { flex: 1 1 170px; min-width: 130px; }
.cadastro-motorista .campo-placa { flex: 0 1 150px; min-width: 110px; }
.cadastro-motorista .marcavel { white-space: nowrap; }
.legenda-media { margin: 8px 2px 16px; }
details.cartao > summary { cursor: pointer; list-style-position: outside; }
details.cartao > summary h2 { display: inline; }
/* A nota ao lado do título da gaveta é uma frase: o `nowrap` do `.origem`
   (feito para a anotação curta de célula) a empurrava para 442px no celular. */
details.cartao > summary .origem { white-space: normal; }

/* O navegador de dia: setas ontem/amanhã e o campo de data numa cápsula só. */
.dia-navegador-caixa {
  display: inline-flex; align-items: stretch; max-width: 100%;
  background: var(--branco); border: 1px solid var(--linha); border-radius: 8px;
}
.dia-seta {
  display: flex; align-items: center; padding: 0 12px; text-decoration: none;
  color: var(--verde-eco-texto); font-weight: 700; font-size: 15px;
}
.dia-seta:first-child { border-right: 1px solid var(--linha); }
.dia-seta:last-child { border-left: 1px solid var(--linha); }
.dia-seta:hover { background: var(--verde-nevoa); }
/* Num celular de 360px a cápsula inteira (setas + data + dia da semana + Ir)
   passava da largura da tela em 14px; o `flex-wrap` deixa o dia da semana
   descer para uma segunda linha em vez de empurrar a página para o lado. */
.dia-navegador { display: flex; align-items: center; gap: 8px; padding: 4px 10px; flex-wrap: wrap; min-width: 0; }
.dia-navegador input[type="date"] { border: none; padding: 3px 0; width: auto; font-weight: 600; }
.dia-navegador input[type="date"]:focus { outline: none; }
.dia-navegador .dia-semana { font-size: 12.5px; color: var(--cinza); white-space: nowrap; }

/* Tiles de resumo do dia. */
.tiles-monitoramento {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 14px; margin-bottom: 18px;
}
.tile-monitoramento {
  background: var(--branco); border: 1px solid var(--linha);
  border-radius: 12px; padding: 14px 16px;
}
.tile-monitoramento .rotulo {
  font-size: 10px; font-weight: 600; text-transform: uppercase;
  letter-spacing: .08em; color: var(--cinza);
}
.tile-monitoramento .valor {
  font-family: 'Quicksand', sans-serif; font-weight: 700; font-size: 24px;
  color: var(--grafite); font-variant-numeric: tabular-nums;
}
.tile-monitoramento .sufixo { font-family: 'Inter', sans-serif; font-size: 11px; font-weight: 400; color: var(--cinza); }
.tile-atencao { background: #FDF7E6; border-color: #EBDCA8; }
.tile-atencao .rotulo, .tile-atencao .valor { color: #7A5F12; }

/* Um card por motorista: a média é o número grande, colorida pelo degrau. */
.cards-motoristas {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 14px; margin-bottom: 8px;
}
.card-motorista { display: flex; flex-direction: column; gap: 8px; padding: 14px 16px; margin-bottom: 0; }
.card-motorista .cabeca { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.card-motorista .nome { font-family: 'Quicksand', sans-serif; font-weight: 700; font-size: 15px; color: var(--grafite); }
.card-motorista .placas { margin-left: auto; display: flex; gap: 6px; flex-wrap: wrap; }
.card-motorista .media-linha { display: flex; align-items: baseline; gap: 6px; }
.card-motorista .media-valor {
  font-family: 'Quicksand', sans-serif; font-weight: 700; font-size: 32px;
  font-variant-numeric: tabular-nums; line-height: 1.1;
}
.card-motorista .media-valor.media-vazia { color: var(--cinza); font-weight: 700; }
.card-motorista .media-rotulo {
  font-size: 10px; text-transform: uppercase; letter-spacing: .08em; color: var(--cinza);
}
.card-motorista .selo-media { margin-left: auto; }
.card-motorista .meta { font-size: 12.5px; color: var(--cinza); font-variant-numeric: tabular-nums; }

/* Caminhões do dia e acumulado lado a lado; empilham no celular. */
.duas-colunas-monitoramento {
  display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); gap: 16px;
  align-items: start; margin-bottom: 16px;
}
.duas-colunas-monitoramento .cartao { margin-bottom: 0; min-width: 0; }
.rolagem-tabela { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.rolagem-tabela table { width: 100%; border-collapse: collapse; }
.acao-excluir { color: var(--vermelho); }

@media (max-width: 1000px) {
  .duas-colunas-monitoramento { grid-template-columns: minmax(0, 1fr); }
}

/* Painel de gestão (aba Início): cinco tiles, gráficos em grade, pendências. */
.tiles-painel { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.tile-monitoramento .tile-nota { font-size: 11px; color: var(--cinza); }
.grade-painel-2 {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px; margin-bottom: 16px;
}
.grade-painel-3 {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px; margin-bottom: 16px;
}
.grade-painel-2 .cartao, .grade-painel-3 .cartao { margin-bottom: 0; min-width: 0; }
.nota-h2 { font-weight: 400; letter-spacing: 0; text-transform: none; }
.acoes-painel { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; }
.acao-painel { display: flex; align-items: baseline; gap: 10px; }
.acao-painel .numero {
  font-family: 'Quicksand', sans-serif; font-weight: 700; font-size: 22px; color: #7A5F12;
}
.acao-painel .numero.zerado { color: var(--verde-folha); }
.acao-painel .texto { font-size: 12.5px; }

@media (max-width: 1000px) {
  .tiles-painel { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grade-painel-2, .grade-painel-3 { grid-template-columns: minmax(0, 1fr); }
  .acoes-painel { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 680px) {
  .acoes-painel { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 680px) {
  .tiles-monitoramento { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .rolagem-tabela table { min-width: max-content; }
}

/* Documentos entregues: o que sai na linha do pé do orçamento. */
.lista-documentos { display: flex; flex-wrap: wrap; gap: 6px 20px; }
.marcavel {
  display: flex; align-items: center; gap: 7px; margin-bottom: 0;
  font-size: 13px; font-weight: 500; text-transform: none; letter-spacing: 0;
  color: var(--grafite); cursor: pointer;
}
.marcavel input[type="checkbox"] { width: 15px; height: 15px; accent-color: var(--verde-folha); }

/* Autocomplete de clientes */
.autocomplete { position: relative; }
.sugestoes {
  position: absolute; z-index: 30; left: 0; right: 0; top: calc(100% + 4px);
  background: var(--branco); border: 1px solid var(--linha); border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, .10); overflow: hidden; max-height: 280px; overflow-y: auto;
}
.sugestoes[hidden] { display: none; }
.sugestoes button {
  display: block; width: 100%; text-align: left; background: none; border: none;
  padding: 8px 12px; font: inherit; font-size: 13.5px; cursor: pointer; color: var(--grafite);
}
.sugestoes button:hover, .sugestoes button.marcada { background: var(--verde-nevoa); }
.sugestoes button small { display: block; color: var(--cinza); font-size: 11.5px; }

/* Filtros da busca */
/* A grade dos filtros pelo ESPAÇO, não por contagem. Era `2fr 1fr 1fr 1fr 1fr
   auto`: cinco trilhas fixas com piso no min-content, e o campo de data (que
   não encolhe) comia o resto — a busca dos orçamentos ficava com 57px de caixa
   e o seletor de mês do envio ganhava a trilha larga que a busca precisava
   (medido em 07/10/2026). O campo que carrega instrução longa (a busca, o
   cliente) é `.col-dupla`. */
.filtros { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 170px), 1fr)); gap: 12px; align-items: end; }
.filtros .acoes { grid-column: 1 / -1; }
/* O seletor de arquivos tem largura própria ("Escolher arquivos  Nenhum
   arquivo escolhido", ~250px) e numa trilha de 170 passava da borda. */
.filtros input[type="file"] { max-width: 100%; }
/* O extrato filtra por mês (e intervalo), por dia e pela situação do OK: os
   cinco campos ficam justos à esquerda e o total ocupa a sobra, para o
   dinheiro não colar no seletor de data. */
.filtros-extrato { grid-template-columns: auto auto auto auto auto minmax(220px, 1fr); }
.filtros-extrato input[type="date"] { width: auto; }
@media (max-width: 1100px) { .filtros-extrato { grid-template-columns: repeat(3, auto); } }
.filtros-monitoramento { grid-template-columns: auto 1fr auto; }
.filtros-monitoramento input[type="date"] { width: auto; }
/* A busca de clientes tem um campo só: o botão fica ao lado, não embaixo. */
.filtros-clientes { grid-template-columns: minmax(240px, 2fr) auto; }
.filtros-clientes .acoes { grid-column: auto; align-self: start; padding-top: 21px; }

/* Prévia dos documentos entregues: em destaque quando a lista encolhe por não
   haver coleta — é a consequência que passava despercebida até o PDF pronto. */
.alerta-documentos { color: #7A5F12; background: #FDF7E6; border: 1px solid #EBDCA8; border-radius: 8px; padding: 8px 10px; }

/* Faturamento mensal */
.doc-faturamento { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 4px 0; }
.doc-faturamento input[data-exportar] { flex: none; }
/* Cabeçalho do grupo de cliente com o "Marcar todos" da exportação ao lado. */
.cabeca-grupo-faturamento { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
/* A barra da exportação gruda no topo enquanto se rola marcando documentos —
   sem isso o botão de baixar fica fora da tela num mês cheio. */
.barra-exportar {
  position: sticky; top: 8px; z-index: 5;
  display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap;
  border-color: var(--verde-broto);
}
/* O display:flex acima venceria o atributo hidden (regra de autor bate a do
   navegador) e a barra vazia ficava sempre à vista — some até alguém marcar. */
.barra-exportar[hidden] { display: none; }
.doc-faturamento .acao-doc { display: inline-flex; gap: 6px; align-items: center; margin: 0; }
.tipo-doc { margin-top: 10px; }
.tipo-doc ul { list-style: none; margin: 4px 0 0; padding: 0 0 0 2px; }
.faturamento-cliente li { padding: 2px 0; }
/* Ficha do cliente: a divisão por mês do faturamento é uma faixa cheia, com
   respiro antes — sem ela os meses somem no meio das linhas de documento. */
.mes-faturamento {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  margin-top: 16px; padding: 7px 12px;
  background: var(--verde-nevoa); border: 1px solid var(--linha); border-radius: 8px;
  font-size: 13.5px; font-weight: 700; color: var(--verde-folha);
  text-transform: uppercase; letter-spacing: .05em;
}
.tipo-doc:first-of-type .mes-faturamento { margin-top: 6px; }
.mes-faturamento + .faturamento-cliente { padding: 2px 12px 0; }

/* A OBRA dentro do cliente (aba Faturamento) e dentro do mês (ficha): agrupa a
   nota, o boleto e o relatório do mesmo endereço. É um nível ABAIXO do mês, e
   por isso não repete a faixa cheia — um filete à esquerda basta para o olho
   saber onde uma obra termina e a outra começa. Só aparece quando o cliente
   tem mais de uma obra; com uma só seria moldura em volta da lista inteira. */
.obra-doc { margin-top: 10px; padding-left: 10px; border-left: 3px solid var(--verde-broto); }
.cabeca-obra {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  font-size: 13.5px; font-weight: 600; color: var(--grafite);
}
.cabeca-obra .origem { font-weight: 400; white-space: nowrap; }
/* Dentro da obra o tipo já vem logo abaixo do endereço: o respiro de cima
   sobraria e afastava o "Notas fiscais" da obra a que ele pertence. */
.obra-doc .tipo-doc:first-of-type { margin-top: 4px; }
.obra-doc .faturamento-cliente { padding-left: 0; }

/* "Gavetas" por período na ficha (faturamento e orçamentos): os meses recentes
   ficam à vista e o histórico antigo abre no clique — <details> puro, sem JS.
   O summary é a etiqueta da gaveta: período + contagem, para ninguém precisar
   abrir só para descobrir o que tem dentro. */
details.gaveta {
  margin-top: 12px; border: 1px solid var(--linha); border-radius: 8px;
  background: var(--branco);
}
details.gaveta > summary {
  cursor: pointer; padding: 9px 12px; font-size: 13.5px; font-weight: 600;
  color: var(--cinza); list-style: none;
  display: flex; align-items: baseline; gap: 8px;
}
details.gaveta > summary::-webkit-details-marker { display: none; }
details.gaveta > summary::before { content: '▸'; color: var(--cinza); }
details.gaveta[open] > summary::before { content: '▾'; }
details.gaveta > summary .origem { font-weight: 400; }
details.gaveta > .tipo-doc, details.gaveta > .tabela-envelope { margin: 0 10px 10px; }

/* Gaveta de MENU (a subnav do financeiro, dezessete telas): o que se usa todo
   dia fica à vista e o resto abre no clique — o mesmo <details> puro, sem JS.
   O painel é ABSOLUTO de propósito: aberto, ele não pode empurrar para baixo o
   conteúdo que se está lendo. `z-index` porque ele passa por cima da tela. */
details.gaveta-menu { position: relative; }
details.gaveta-menu > summary { cursor: pointer; list-style: none; }
details.gaveta-menu > summary::-webkit-details-marker { display: none; }
details.gaveta-menu > summary::after { content: '▾'; font-size: 11px; }
details.gaveta-menu[open] > summary::after { content: '▴'; }
.gaveta-menu-painel {
  position: absolute; z-index: 20; top: calc(100% + 4px); left: 0;
  display: flex; flex-direction: column; gap: 4px; padding: 6px;
  background: var(--branco); border: 1px solid var(--linha); border-radius: 10px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, .1);
}
.gaveta-menu-painel .btn { justify-content: flex-start; white-space: nowrap; }
/* No celular a gaveta pode cair perto da borda direita, e um painel ancorado à
   esquerda sairia da tela. Ancorado à direita ele cresce para DENTRO — e o
   painel é mais estreito que a tela, então não há o caso simétrico. */
@media (max-width: 700px) {
  .gaveta-menu-painel { left: auto; right: 0; }
}

/* Histórico do cliente */
.destaque-valores { border: 1px solid var(--linha); border-radius: 12px; overflow: hidden; background: var(--branco); }
/* Cabeçalho de obra dentro da tabela de valores: mesma escala dos títulos de
   seção internos (13px caps cinza), para separar os preços por endereço. */
.subgrupo-obra td { background: var(--verde-nevoa); color: var(--cinza); font-size: 12px; padding: 6px 12px; border-top: 1px solid var(--linha); }
.subgrupo-obra b { font-weight: 600; color: var(--grafite); }
.origem { font-size: 11.5px; color: var(--cinza); white-space: nowrap; }
/* O `nowrap` acima existe para a anotação CURTA dentro de uma célula ("3 dias
   de atraso", o emissor ao lado do vencimento), onde quebrar a linha parte um
   dado em dois. Num PARÁGRAFO ele é o contrário do que se quer: uma frase
   inteira sem quebra empurra a página para 750px de largura no celular, e o
   estouro aparece longe daqui — nas abas do cabeçalho, que só foram arrastadas
   junto. Um `<p>` é prosa, sempre. */
p.origem { white-space: normal; }
/* O assunto do e-mail na fila do vigia: é frase, quebra — e tem teto, senão
   um assunto de 120 caracteres vira a coluna mais larga da tabela. Mora
   DEPOIS do `.origem` e com as duas classes na régua, porque a primeira
   versão (só `.assunto-email`, escrita antes) perdia para o `nowrap` de cima
   pela ordem do arquivo: a tabela da fila saía com 1.432px num cartão de
   1.228px e o botão "conferir" ficava fora da tela (medido em 14/09/2026). */
.origem.assunto-email { white-space: normal; max-width: 240px; overflow-wrap: anywhere; }
/* PROSA dentro de uma CÉLULA — a régua que faltava, e o assunto do e-mail
   acima é um caso dela. O `nowrap` do `.origem` faz o mínimo da coluna ser
   IGUAL ao máximo, e com isso a tabela deixa de ter como caber em largura
   nenhuma: ela não rola por desenho, rola porque não cabe, e quem olha perde
   o fim da linha. Foi o que o dono viu na pasta de boletos em 16/09/2026, e a
   auditoria das telas de tabela achou os irmãos — todos frase, nenhum dado:
     • a DESCRIÇÃO do título (a discriminação do que foi comprado, que o vigia
       grava com até 500 caracteres): 534px de mínimo, tabela com 1.325px de
       mínimo num cartão de 1.227px, escondendo 207px na largura do dono;
     • a RESPOSTA do canal no histórico de envios do laudo (até 300 caracteres
       dizendo POR QUE o laudo não chegou): 757px, e a frase que existe para
       ser lida ficava atrás da barra de rolagem;
     • o MEMO do banco na conciliação (a linha diz de quem é o dinheiro):
       554px numa caixa de 533px;
     • a ressalva do cabeçalho do extrato ("OK = carimbado como pago…"): 613px,
       porque o `th` também é `nowrap`.
   O teto existe pela razão do assunto do e-mail: sem ele a frase comprida fica
   com a maior fatia e empurra as outras colunas para tiras estreitas. Depois
   do `.origem` e com as duas classes na régua, pela mesma lição de ordem do
   arquivo. Isto NÃO vale para dado — CNPJ, placa, número de nota seguem
   `nowrap`, porque ali quebrar a linha parte um dado em dois. */
.origem.prosa { white-space: normal; max-width: 280px; overflow-wrap: anywhere; }
.lista-opcoes-valor { margin: 0; padding: 0; list-style: none; font-size: 12.5px; }
.lista-opcoes-valor li { white-space: nowrap; }
.lista-opcoes-valor .rot { color: var(--cinza); }

@media (max-width: 900px) {
  .campos.col-2, .campos.col-3, .campos.col-4 { grid-template-columns: 1fr; }
  .col-dupla { grid-column: auto; }
  .filtros { grid-template-columns: 1fr 1fr; }
  .opcao-descarte { grid-template-columns: 1fr; }
}

/* ===== Celular =====
   A ferramenta é usada na rua: conferir um orçamento, emitir da obra. Nada
   pode depender de largura de desktop. Auditado por medição de overflow em
   390 px e 360 px (test/mobile.test.js falha se alguma tela voltar a estourar). */
@media (max-width: 700px) {
  /* Topo em duas linhas: logo + selo + sair em cima, abas embaixo.
     O logo mantém os 140 px de largura mínima da identidade. */
  .topo-interno { flex-wrap: wrap; gap: 8px 12px; padding: 10px 12px; }
  .marca span { display: none; } /* o logo já diz onde estamos */
  /* `flex-wrap: nowrap` DESFAZ, só aqui, o wrap da regra base. Aquele existe
     para a nav encolher no desktop; herdado aqui ele brigava com este
     `overflow-x: auto` — com wrap o conteúdo nunca excede a largura, então a
     rolagem virava código morto e as 11 abas do admin empilhavam em quatro
     fileiras: 215px de cabeçalho num celular de 360px, antes de qualquer
     conteúdo. Aqui a barra é UMA fileira que rola, e é por isso que o
     `.aba` logo abaixo tem `white-space: nowrap`. */
  /* A faixa ROLA, e tem de PARECER que rola. Com 14 abas o admin vê quatro em
     390px, e as quatro terminavam certinho na borda: a fileira parecia
     completa, e as outras dez não existiam para quem olha. A barra de rolagem
     não resolve — no celular ela é sobreposta e só aparece DURANTE o gesto,
     que é justamente o gesto que a pessoa não sabe que pode dar.

     A sombra é de CSS puro, sem script e sem saber a posição da rolagem, pelo
     par `local`/`scroll`: as duas primeiras camadas (as TAMPAS, brancas) são
     `local` e andam com o conteúdo, então moram nas pontas da faixa INTEIRA;
     as duas de baixo (as SOMBRAS) são `scroll` e ficam presas às bordas da
     caixa. No começo a tampa da esquerda está em cima da sombra da esquerda e
     a apaga, enquanto a sombra da direita aparece sozinha; rolando, a tampa da
     esquerda sai de cena (a sombra acende) e a da direita chega (apaga a de
     lá). Cabendo tudo, as duas tampas ficam nas duas bordas e não há sombra
     nenhuma — quem tem duas abas não vê promessa de coisa que não há.

     A tampa é BRANCA E SÓLIDA na largura inteira da sombra (os primeiros 18px)
     e só então desbota: fosse ela um degradê desde a borda, cobriria a sombra
     pela metade e a ponta ficaria suja mesmo no começo, sem nada para rolar. E
     o desbotamento termina em BRANCO com alfa zero, escrito por extenso —
     `transparent` é preto transparente por definição, e o meio do caminho
     acinzentaria a faixa. A sombra é preta de alfa baixo, como as outras do
     arquivo: cor da paleta aqui teria de ser escrita em canais (`rgba()` não
     lê variável em hexadecimal), virando uma cópia do `--grafite` que ninguém
     atualizaria junto.

     E é por causa dela que a aba ativa NÃO tem pílula no celular (decisão do
     dono, 14/09/2026): a sombra é FUNDO da faixa, e fundo de filho pinta por
     cima do fundo do pai — a pílula (`--verde-nevoa`, opaca, da altura exata
     da faixa) apagava a sombra sempre que caísse sobre os 18px da ponta. Não
     era hipótese: varrendo as 14 abas do admin a 390px, era a Faturamento,
     cuja aba ativa para bem na dobra da direita, e é uma das telas mais
     abertas da casa — a promessa de rolagem sumia justamente ali. Em CSS não
     há como ter as duas coisas, porque pintar ACIMA dos filhos exigiria
     elemento posicionado e elemento posicionado não sabe a posição da
     rolagem sem script. Sem a pílula, o que pinta sobre a sombra é só o
     desenho da letra, como nas abas vizinhas. */
  /* A faixa do segundo nível (navegação `areas`) ganha a MESMA sombra, na
     mesma declaração: são duas fileiras que rolam pela mesma razão, e duas
     cópias do degradê divergiriam no dia em que alguém mexesse numa. É por
     isso que ela é BRANCA como o cabeçalho — a tampa é branca sólida, e num
     fundo de outra cor ela apareceria como uma faixa clara na ponta. */
  .abas, .faixa-area-interna {
    /* A largura da sombra numa declaração só: ela aparece nas quatro camadas
       abaixo e o `abas.js` a LÊ daqui para não parar o foco do teclado debaixo
       dela. Número repetido em CSS e em JS divergiria sem ninguém notar — e a
       variável só existe nesta media query, que é onde a sombra existe: fora
       daqui o JS lê vazio e não afasta nada, que é o certo. */
    --sombra-abas: 18px;
    overflow-x: auto; flex-wrap: nowrap;
    background:
      linear-gradient(to right, var(--branco) 0 var(--sombra-abas), rgba(255, 255, 255, 0) 34px) left center / 34px 100% no-repeat local,
      linear-gradient(to left, var(--branco) 0 var(--sombra-abas), rgba(255, 255, 255, 0) 34px) right center / 34px 100% no-repeat local,
      radial-gradient(farthest-side at 0 50%, rgba(0, 0, 0, .25), rgba(0, 0, 0, 0)) left center / var(--sombra-abas) 100% no-repeat scroll,
      radial-gradient(farthest-side at 100% 50%, rgba(0, 0, 0, .25), rgba(0, 0, 0, 0)) right center / var(--sombra-abas) 100% no-repeat scroll;
  }
  /* O que é só da faixa DE CIMA: ela divide a linha com o logo e o "Sair", e
     por isso desce para a linha de baixo (`order: 5`) e toma a largura toda.
     A do segundo nível já é um bloco próprio, fora do `.topo-interno`. */
  .abas { order: 5; width: 100%; margin-left: 0; }
  /* Aba menor e sem quebra: a faixa é UMA fileira que rola (ver o `nowrap`
     acima), e nome quebrado no meio viraria duas linhas dentro dela. */
  .aba { padding: 6px 10px; font-size: 12.5px; white-space: nowrap; }
  /* NENHUMA aba tem fundo aqui — nem a ativa, nem a apontada pelo ponteiro.
     São as duas únicas coisas opacas que existem DENTRO da faixa (o selo de
     admin e o "Sair" são irmãos da nav, não filhos, e por isso nunca tapam
     nada), e fundo de filho pinta por cima do fundo do pai: qualquer uma
     delas sobre os 18px da ponta apaga a sombra que promete a rolagem.
     A ativa se marca por TRAÇO, não só por cor: cor sozinha não distingue
     para quem não separa verde de cinza, e era a pílula que dava a segunda
     pista. O traço é `text-decoration`, que não ocupa espaço nenhum — borda
     ou `box-shadow` entrariam na altura da faixa, medida no mobile.test.js. */
  /* Os dois estados perdem o fundo na MESMA declaração, de propósito: em
     regras separadas, "ativa" e ":hover" empatam em especificidade (0-2-0) e
     quem venceria na aba ativa APONTADA seria a que estivesse por último no
     arquivo — verdade que se desfaz sozinha no dia em que alguém reordenar. */
  .aba:hover, .aba.ativa { background: none; }
  .aba.ativa {
    text-decoration: underline;
    text-decoration-thickness: 2px;
    text-underline-offset: 3px;
  }
  /* No lugar da pílula, apontar ESCURECE a letra: no celular o ponteiro nem
     existe, mas em janela estreita de desktop existe, e tirar o fundo sem pôr
     nada deixaria a aba muda ao apontar. `:not(.ativa)` porque a ativa já tem
     cor própria — sem ele, apontar a ativa apagaria o verde dela. */
  .aba:not(.ativa):hover { color: var(--grafite); }
  /* O anel do teclado é desenhado PARA DENTRO (deslocamento negativo), e é a
     rolagem que obriga: `overflow-x: auto` faz o `overflow-y` computar `auto`
     junto, então a faixa RECORTA o que passa da altura dela — e a aba tem
     exatamente a altura da faixa. Com o anel para fora (o padrão do
     navegador, 1px de largura a 1px de distância) sobravam só as laterais
     curvas, como parênteses em volta do texto: some justamente a parte de
     cima e a de baixo, que é o que faz um anel parecer um anel.
     Cor e espessura são as do `:focus-visible` que o app já usa no mapa —
     duas aparências de foco no mesmo app fariam a segunda parecer outra
     coisa. E é `:focus-visible`, não `:focus`: com o segundo, todo toque no
     celular deixaria o anel aceso na aba recém-tocada. */
  .aba:focus-visible { outline: 2px solid var(--verde-folha); outline-offset: -3px; }
  /* Segundo nível: só o respiro lateral encolhe; o traço de baixo fica, porque
     é ele que diz qual tela está aberta (aqui a ÁREA já está sublinhada em
     cima, e as duas marcas juntas são o que separa os dois níveis). */
  .faixa-area-interna { padding: 0 12px; }
  .item-area { padding: 6px 10px 5px; font-size: 12.5px; }
  /* A COLUNA vira a mesma faixa que rola. Não é concessão: aquela sombra, o
     anel de foco e o `abas.js` foram medidos em pixel, e uma coluna de 196px
     num aparelho de 360px comeria mais da metade da tela. Abaixo de 700px as
     duas navegações são a mesma coisa — o que a pessoa escolheu só volta a
     valer no computador. */
  body.nav-coluna { display: block; }
  .coluna-nav { flex-direction: row; border-right: 0; border-bottom: 1px solid var(--linha); }
  /* `background-color` em longhand, DEPOIS do `background` da regra da sombra:
     o atalho zera a cor de fundo, e sem esta linha a faixa ficaria no cinza da
     página, com as tampas brancas aparecendo como duas manchas nas pontas. */
  .coluna-nav { background-color: var(--branco); }
  .etiqueta-admin { margin-left: auto; }
  .sair { margin-left: 0; }
  .etiqueta-admin + .sair, .abas + .sair { margin-left: auto; }

  .conteudo { padding: 16px 12px; }

  /* Tabela larga rola dentro do próprio cartão — a página nunca estoura. */
  .tabela-envelope, .destaque-valores { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .tabela-envelope table, .destaque-valores table { min-width: max-content; }

  /* Filtros e busca em coluna única. */
  .filtros, .filtros-clientes { grid-template-columns: 1fr; }
  .filtros-clientes .acoes { padding-top: 0; }

  /* Editor: cabeçalho do bloco e topo da linha quebram em vez de estourar. */
  .bloco-cacamba-editor > .cabeca { flex-wrap: wrap; }
  .bloco-cacamba-editor > .cabeca .acoes-fim { margin-left: 0; }
  .linha-classe-editor .topo-linha { flex-wrap: wrap; }
  .linha-classe-editor .topo-linha select { min-width: 0; flex: 1 1 220px; }
}

/* Preços por região: cabeçalho da cidade/bairro com a distância editável. */
.cabeca-regiao {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between;
  gap: 10px; margin-bottom: 10px;
}
.distancia-regiao { display: flex; align-items: center; gap: 8px; margin: 0; }
.distancia-regiao input[type="text"] { width: 76px; }
.km-regiao { font-weight: 600; color: var(--verde-folha); white-space: nowrap; }

/* ===== Endereço da obra: campos separados + mapa =====
   Os campos à esquerda, o mapa à direita. No celular o mapa vai para baixo —
   e continua útil: é onde se confere se o pino caiu na obra certa. */
/* Campos e mapa lado a lado só quando os dois cabem (360px cada): com o mapa
   preso em 320px, a coluna dos campos encolhia até a Cidade e o Número terem
   0px de caixa em 1024px de janela (medido em 07/10/2026). */
.endereco-composto {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 360px), 1fr));
  gap: 16px; align-items: start;
  border: 1px solid var(--linha); border-radius: 10px; padding: 14px;
  background: var(--verde-nevoa);
}
.endereco-campos {
  display: grid; gap: 10px 12px;
  /* 176px: o CEP com o botão "Buscar" do lado e a instrução "00000-000"
     inteira; com 150 ela cortava, e o complemento (que cai nesta trilha) também. */
  grid-template-columns: 176px 60px minmax(0, 1fr);
}
.endereco-campos label { font-size: 11.5px; }
.endereco-campos .campo-logradouro { grid-column: 1 / 3; }
.endereco-campos .campo-numero, .endereco-campos .campo-complemento { grid-column: auto; }
.endereco-campos .campo-bairro { grid-column: 1 / 3; }
.endereco-campos .com-botao { display: flex; gap: 6px; align-items: center; }
.endereco-campos .com-botao input { min-width: 0; }
.endereco-campos input { background: var(--branco); }

.endereco-mapa { display: grid; gap: 8px; }
.endereco-mapa .mapa {
  height: 210px; border-radius: 8px; overflow: hidden;
  border: 1px solid var(--linha); background: var(--branco);
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; color: var(--cinza); text-align: center; padding: 8px;
}
/* O MapLibre posiciona a tela do mapa em absoluto: a caixa não pode
   centralizar nada depois que ele assume. */
.endereco-mapa .mapa.mapboxgl-map { display: block; padding: 0; }
/* O crédito do mapa em corpo de nota — a caixa tem 210 px de altura. Ele
   NUNCA é escondido, nem a marca do Mapbox: os dois são condição de uso. */
.endereco-mapa .mapboxgl-ctrl-attribution { font-size: 10px; }
/* Chave de liga/desliga: a caixa de seleção vira interruptor. O alvo fica
   grande o bastante para o dedo, que é como o editor é usado na obra. */
.endereco-mapa .chave { display: flex; align-items: center; gap: 8px; font-size: 12px; margin: 0; cursor: pointer; }
.endereco-mapa .chave input {
  appearance: none; -webkit-appearance: none;
  width: 34px; height: 18px; flex: 0 0 34px; margin: 0;
  border-radius: 9px; background: #C6CFC2; border: 0;
  position: relative; cursor: pointer; transition: background 0.15s ease;
}
.endereco-mapa .chave input::after {
  content: ''; position: absolute; top: 2px; left: 2px;
  width: 14px; height: 14px; border-radius: 50%; background: var(--branco);
  box-shadow: 0 1px 2px rgba(0,0,0,0.3); transition: transform 0.15s ease;
}
.endereco-mapa .chave input:checked { background: var(--verde-eco); }
.endereco-mapa .chave input:checked::after { transform: translateX(16px); }
.endereco-mapa .chave input:focus-visible { outline: 2px solid var(--verde-folha); outline-offset: 2px; }
.endereco-mapa .coordenadas {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  font-size: 11.5px; color: var(--cinza); font-variant-numeric: tabular-nums;
}
.pino-mapa { background: none; border: 0; }

/* No celular, uma coluna só: em duas, o CEP dividia a meia fileira com o
   botão "Buscar" e ficava com 28px de caixa em 360px — nem "00000-000" cabia. */
@media (max-width: 700px) {
  .endereco-campos { grid-template-columns: minmax(0, 1fr); }
  .endereco-campos .campo-logradouro, .endereco-campos .campo-bairro { grid-column: auto; }
}

/* Distância medida até o pátio: informação de apoio, não valor negociado. */
.endereco-mapa .distancia-patio {
  font-size: 11.5px; font-weight: 600; color: var(--verde-eco-texto);
  font-variant-numeric: tabular-nums;
}
/* Distância medida pela rota: referência ao lado da cadastrada, em tom menor —
   quem manda é a da operação. */
.km-medido { font-size: 12px; color: var(--cinza); white-space: nowrap; }

/* Resíduos do relatório: os selos numa linha, o mix em outra.
   Há relatório com dez materiais e percentual em cada um. Numa coluna sem
   teto, esse texto empurrava as colunas de dinheiro para fora da tela — e é
   justamente o dinheiro que a conferência veio ler. O teto vai nos DIVs de
   dentro, não no <td>: em tabela de layout automático o navegador estica a
   célula além do max-width dela, mas respeita o do bloco interno. */
.celula-residuos > div { max-width: 420px; }
.celula-residuos .linha-classes { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; }
.celula-residuos .mix-residuos {
  font-size: 11.5px; color: var(--cinza); margin-top: 3px; line-height: 1.45;
  /* Material longo e sem espaço (o mix vem grudado do PDF) quebra dentro da
     coluna em vez de alargá-la. */
  overflow-wrap: anywhere;
}
.celula-residuos .pendente { margin-top: 2px; overflow-wrap: anywhere; }

/* Rede de segurança em qualquer largura: se ainda assim a tabela passar do
   cartão, ela rola dentro dele — coluna cortada em silêncio é pior que barra
   de rolagem, porque quem confere não sabe que falta coluna. */
.destaque-valores { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* Lançar km à mão (caminhão sem rastreamento): é a exceção, não a rotina —
   fica recolhido embaixo da tabela do dia, com a mesma cara dos outros
   <details> da tela. */
.km-estimado { margin-top: 12px; border-top: 1px solid var(--linha); padding-top: 10px; }
.km-estimado > summary { cursor: pointer; font-size: 13px; font-weight: 600; color: var(--cinza); }
.km-estimado .ajuda { margin: 8px 0; }
.km-estimado .filtros { margin: 0; }

/* Busca do extrato: o campo de nome é o mais largo da faixa de filtros —
   nome de cliente e descrição do banco não cabem em caixa de data. */
.filtros-extrato .campo-busca-extrato { min-width: 230px; }

/* "Atualizado em …": a frescura do extrato, logo abaixo do subtítulo. Em
   selo verde — o par auditado da etiqueta "emitido" —, porque é a primeira
   pergunta de quem abre a aba e em cinza de 12px ela se perdia no subtítulo.
   O ponto à esquerda é o sinal de vivo. */
.atualizacao-extrato {
  display: inline-flex; align-items: baseline; gap: 7px;
  margin-top: 8px; padding: 5px 13px; border-radius: 999px;
  background: var(--verde-nevoa); border: 1px solid #C9DEBC;
  color: var(--verde-eco-texto); font-size: 12.5px; font-weight: 600;
}
.atualizacao-extrato::before {
  content: ''; width: 7px; height: 7px; border-radius: 50%;
  background: var(--verde-eco); flex: none; align-self: center;
}
.atualizacao-extrato .origem { color: var(--verde-folha); font-weight: 500; }

/* ===== MTR e vencimentos (a fila do CDF) ===== */

/* Os dois campos do vencimento ficam lado a lado no assinador — a obs é
   SOBRE a data, e separá-los sugeriria coisas independentes. */
.campos-vencimento { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 10px; }
.campos-vencimento > div { flex: 1 1 190px; }

/* A anotação da fila é uma linha só: data, observação e salvar. A data tem
   largura própria (o padrão dos campos é 100%, que aqui empurraria o resto
   para a linha de baixo) e a observação toma a folga. */
.anotar-vencimento { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.anotar-vencimento input[type="date"] { flex: 0 0 auto; width: auto; }
.anotar-vencimento input[type="text"] { min-width: 140px; flex: 1 1 140px; }
.anotar-vencimento .btn { flex: 0 0 auto; }

/* Vencido é a fila de verdade: a etiqueta usa o vermelho do atraso do extrato,
   e o "sem data" fica em âmbar — não é atraso, é dado que falta. */
.etiqueta-vencido { background: #FBF1F1; border-color: #E7C9C9; color: #8E2E2E; }
.etiqueta-sem-data { background: #FDF7E6; border-color: #EBDCA8; color: #7A5F12; }
/* CDF já emitido é trabalho concluído: a linha recua, como o excluído recua na
   lista do admin — continua à vista, sem disputar atenção com a fila. */
.tabela-extrato tr.linha-concluida td { background: #FBFCFA; color: var(--cinza); }

/* Chip de ESCALA no card do motorista: declaração de hoje, ainda sem km — a
   borda tracejada diz "prometido, aguardando a telemetria". O confirmado usa
   a etiqueta verde de sempre. */
.card-motorista .etiqueta-escala {
  border-style: dashed; border-color: #C9DEBC; color: var(--verde-eco-texto);
}

/* Ficha do cliente: a linha do MTR carrega os MESMOS controles da fila do CDF
   (vencimento do boleto, obs, carimbo do CDF). Eles entram numa segunda faixa
   da própria linha — ao lado do nome do arquivo não caberiam, e o documento
   continua sendo a linha, não um cartão. */
.doc-faturamento .anotar-vencimento {
  flex: 1 0 100%; margin: 2px 0 6px 2px; padding-left: 10px;
  border-left: 2px solid var(--linha);
}

/* Lembretes dos dias anteriores na aba do monitoramento: é o que faz a
   anotação de ontem ("ajustar amanhã o km de hoje") chegar a quem abre hoje.
   Ficam acima do campo, recuados, para se lerem como recado e não como o que
   se está escrevendo agora. */
.lembretes-dia { margin-bottom: 12px; }
.lembrete-dia {
  display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap;
  padding: 6px 10px; margin-bottom: 4px;
  background: var(--verde-nevoa); border-left: 3px solid var(--verde-broto); border-radius: 0 6px 6px 0;
  font-size: 13px; white-space: pre-wrap;
}
.lembrete-dia a { white-space: nowrap; }

/* Monitoramento de diesel: a tabela dos abastecimentos com o consumo por
   linha, o detalhe em segunda linha (posto, cupom, alertas) e a correção
   compacta na última célula. Reaproveita os degraus da média (media-*). */
.tabela-diesel td.num, .tabela-diesel th.num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.tabela-diesel .detalhe-linha { display: block; font-size: 11.5px; color: var(--cinza); white-space: normal; max-width: 300px; font-weight: 400; }
.tabela-diesel td.num .detalhe-linha { margin-left: auto; text-align: right; }
.tabela-diesel td { vertical-align: top; }
.correcao-abastecimento { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; max-width: 340px; }
.correcao-abastecimento .campo-odometro, .correcao-abastecimento .campo-litros, .correcao-abastecimento .campo-placa-abast { width: 84px; }
/* O odômetro com 8px a mais: com 84 a instrução "odômetro" cortava no "r". */
.correcao-abastecimento .campo-odometro { width: 92px; }
.correcao-abastecimento select { max-width: 160px; min-width: 0; }
.correcao-abastecimento .campo-obs { flex: 1 1 140px; min-width: 120px; }
.etiqueta-estimado { background: #FDF7E6; border-color: #EBDCA8; color: #7A5F12; }
.lista-alertas { display: flex; flex-direction: column; gap: 8px; }
.alerta-diesel { display: flex; flex-wrap: wrap; gap: 8px; align-items: baseline; font-size: 13px; }
.alerta-diesel a { white-space: nowrap; }
.filtros-diesel { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.filtros-diesel input, .filtros-diesel select { width: 100%; max-width: 100%; }
/* ---------------------------------------------------------------- impressão
   Só o relatório do monitoramento imprime hoje (o documento do orçamento tem
   CSS próprio, extraído dos modelos, e não passa por aqui). O que sai do papel
   é o que não é conteúdo: menu, filtro e botões — inclusive o "Imprimir", que
   impresso vira uma caixa cinza sem função. */
@media print {
  .topo, .sem-impressao { display: none !important; }
  /* A coluna da esquerda some com o `sem-impressao`, mas a GRADE fica: sem
     isto o papel sairia com 196px de margem à esquerda, reservados para um
     menu que não está lá. */
  body.nav-coluna { display: block; }
  body { background: #fff; }
  .folha-relatorio { border: 0; box-shadow: none; padding: 0; margin: 0; }
  .rolagem-tabela { overflow: visible; }
  .tabela-monitoramento { font-size: 11pt; }
  .tabela-monitoramento tr { break-inside: avoid; }
  .observacoes-relatorio { break-inside: avoid; }
}

/* O cabeçalho do relatório: título à esquerda, "emitido em" à direita. */
.cabecalho-relatorio {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: 16px; flex-wrap: wrap; margin-bottom: 12px;
}
.observacoes-relatorio { margin-top: 18px; }
.observacoes-relatorio h3 { font-family: 'Quicksand', sans-serif; font-size: 13px; color: var(--verde-folha); }
.observacoes-relatorio ul { margin: 8px 0 0; padding-left: 18px; color: var(--grafite); font-size: 13.5px; }
.observacoes-relatorio li { margin-bottom: 4px; }

/* ===== Triagens no pátio (o lado do escritório do app) ===== */
/* Os oito filtros da lista cabem em quantas colunas a largura der. */
.filtros-triagens { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.filtros-triagens input, .filtros-triagens select { width: 100%; max-width: 100%; }
/* Nas grades de filtro que se ajustam ao espaço, o campo de duas colunas
   CONTINUA de duas colunas abaixo de 900px (a regra geral o devolve a `auto`
   porque lá as grades viram uma coluna só, e um `span 2` fixo criaria coluna
   implícita); abaixo de 700px ele toma a fileira inteira, que é `1 / -1` e
   nunca cria coluna. Sem isto a busca voltava a uma trilha de 130px em 900px
   de janela e cortava a própria instrução. */
@media (max-width: 900px) {
  .filtros-triagens .col-dupla, .filtros-diesel .col-dupla { grid-column: span 2; }
}
@media (max-width: 700px) {
  .filtros-triagens .col-dupla, .filtros-diesel .col-dupla { grid-column: 1 / -1; }
}
/* A obra na lista quebra dentro da coluna em vez de alargá-la — endereço do
   Caçambas Online vem com complemento, bairro e cidade. */
.tabela-triagens .obra-triagem { white-space: normal; max-width: 320px; }
/* Dados em pares rótulo/valor: o rótulo na escala dos eyebrows, o valor ao lado. */
.dados-triagem { display: grid; grid-template-columns: max-content 1fr; gap: 6px 14px; margin: 0; font-size: 13.5px; }
.dados-triagem dt { font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: .08em; color: var(--verde-eco-texto); padding-top: 3px; }
.dados-triagem dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
/* O veredito na tela: verde para conforme, vermelho da classe D para não
   conforme — texto grande, então o verde da marca vale como cor de texto. */
.veredito-tela { font-family: 'Quicksand', sans-serif; font-weight: 700; font-size: 22px; color: var(--cinza); }
.veredito-tela.conforme { color: var(--verde-eco); }
.veredito-tela.nao-conforme { color: var(--vermelho); }
.observacao-triagem { font-size: 13px; color: var(--grafite); padding-left: 10px; border-left: 3px solid var(--linha); white-space: pre-wrap; }
/* Os três relógios lado a lado; no celular empilham. */
.relogios-triagem { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; font-size: 13px; }
.relogios-triagem > div { background: var(--verde-nevoa); border: 1px solid var(--linha); border-radius: 10px; padding: 10px 12px; min-width: 0; }
.relogios-triagem .rotulo-campo { margin-bottom: 4px; }
/* A galeria: cada foto num cartão com a legenda embaixo; a imagem enche a
   largura do cartão e corta o excesso, para as fileiras alinharem. */
.galeria-fotos { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 12px; }
.foto-triagem { margin: 0; border: 1px solid var(--linha); border-radius: 10px; overflow: hidden; background: var(--branco); min-width: 0; }
.foto-triagem a { display: block; background: #e8eae7; }
.foto-triagem img { display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.legenda-foto { padding: 6px 9px; font-size: 11.5px; color: var(--cinza); line-height: 1.5; overflow-wrap: anywhere; }
.legenda-foto b { color: var(--grafite); }
.hash-foto { font-family: ui-monospace, 'Cascadia Mono', 'Consolas', monospace; font-size: 11px; }
/* Texto secundário DENTRO da triagem quebra de linha: a classe `.origem` nasce
   com `nowrap` (é código curto e tabular nas outras tabelas), e aqui ela
   carrega o detalhe do evento e a observação — "Chegada ao pátio · sha256
   503edcf5c22576e0…" numa linha só estourava 9px num celular de 360px. */
.linha-tempo .origem, .dados-triagem .origem, .legenda-foto .origem, .tabela-triagens .origem { white-space: normal; }
/* As opções da consulta na tela de vínculo (endereço, "Atendimento … ·
   concluída … · motorista · placa") e a nota do vínculo por pedido quebram
   dentro do cartão: numa linha só estouravam 470px num celular de 360px. */
.opcao-vinculo .origem, .nota-vinculo { white-space: normal; }
/* A trilha da triagem: uma lista com a hora à esquerda. */
.linha-tempo { list-style: none; margin: 0; padding: 0; font-size: 13px; }
.linha-tempo li { padding: 6px 0; border-top: 1px solid var(--linha); }
.linha-tempo li:first-child { border-top: none; }
.linha-tempo .quando { display: inline-block; min-width: 130px; color: var(--cinza); font-variant-numeric: tabular-nums; }
/* As opções do vínculo (as coletas que a consulta achou): uma linha por
   coleta, o rádio à esquerda, tudo clicável. */
.opcoes-vinculo { display: grid; gap: 6px; }
.opcao-vinculo { display: flex; gap: 10px; align-items: flex-start; padding: 8px 10px; border: 1px solid var(--linha); border-radius: 8px; background: var(--branco); cursor: pointer; font-size: 13px; }
.opcao-vinculo:has(input:checked) { border-color: var(--verde-eco); background: var(--verde-nevoa); }
.opcao-vinculo input { margin-top: 3px; accent-color: var(--verde-folha); }
@media (max-width: 700px) {
  .relogios-triagem { grid-template-columns: minmax(0, 1fr); }
  .dados-triagem { grid-template-columns: 1fr; gap: 2px; }
  .dados-triagem dd { margin-bottom: 6px; }
  .galeria-fotos { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/* ------------------------------------------------------- plano de contas
   A linha de GRUPO (1, 2, 3…) não é lançável: ela organiza a árvore. Fundo
   névoa e código em verde para separá-la das contas sem precisar de recuo
   maior — o recuo já diz o nível, e recuo duplo empurraria "2.4.1" para fora
   da tela no celular. */
.linha-grupo td, .linha-grupo th { background: var(--verde-nevoa); }
.linha-grupo td:first-child, .linha-grupo th:first-child { color: var(--verde-eco-texto); }

/* ------------------------------------------------------- relatórios (f) e (g)
   A linha de TOTAL fecha um bloco da DRE e do DFC. O traço em cima é o que
   separa "mais uma conta" de "a soma das de cima" — sem ele o EBITDA parece
   outra despesa da lista, e é ele o número que se foi ler. */
.linha-total td, .linha-total th {
  border-top: 1.5px solid var(--linha-forte, #C9D4C5);
  font-weight: 600; background: var(--branco);
}
.linha-total th { text-align: left; }

/* O dia em que o saldo projetado fica negativo. Cor NUNCA sozinha: a linha
   também traz o número com o sinal, e a tabela diz "Saldo" na coluna. */
.linha-critica td { background: #FBF0F0; }

/* ------------------------------------------------- fechamento do mês (h)
   A conferência é uma LISTA, não uma tabela: cada item tem um texto que explica
   o que aquilo significa, e texto de explicação numa célula de tabela vira
   coluna gigante ao lado de colunas vazias. A etiqueta à esquerda carrega o
   número (ou o "ok"), então a cor nunca está sozinha. */
.lista-conferencias { list-style: none; margin: 12px 0 0; padding: 0; display: grid; gap: 10px; }
.lista-conferencias li { display: flex; gap: 10px; align-items: flex-start; }
.lista-conferencias li > div { min-width: 0; }
/* A cobrança da diferença de classificação, dentro do aviso: rótulo, valor e
   botão numa linha que quebra no celular. */
.cobrar-diferenca { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin-top: 6px; }
.cobrar-diferenca label { font-size: 12.5px; font-weight: 600; }
.cobrar-diferenca input[type="text"] { width: 110px; }
/* Nota e boleto de cada empresa, no cartão de envio da fatura. */
.papeis-da-fatura { border: 1px solid var(--linha); border-radius: 10px; padding: 12px 14px; margin-bottom: 14px; }
.lista-papeis { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.lista-papeis li { display: grid; gap: 4px; min-width: 0; }
.boleto-da-empresa { margin-top: 4px; min-width: 0; }
.boleto-da-empresa .etiqueta { white-space: normal; }
.lista-conferencias .etiqueta { flex: 0 0 auto; min-width: 34px; text-align: center; }
/* O item resolvido recua para o fundo: quem abre a tela procura o que falta. */
.lista-conferencias li.confere { opacity: .62; }

/* Prosa curta dentro de um cartão. Existe porque `.origem` é `nowrap` (ela
   serve à anotação de uma célula), e uma frase inteira sem quebra empurra a
   página inteira para fora da tela do celular. */
.origem-bloco { font-size: 11.5px; color: var(--cinza); white-space: normal; margin: 4px 0 0; }

/* O DFC tem 13 colunas de dinheiro. Num mês de doze, a tabela passa da largura
   da tela — ela rola dentro do próprio cartão (a regra do celular), e na
   IMPRESSÃO encolhe a fonte em vez de cortar: folha de fluxo de caixa com o
   último mês faltando é pior que folha de letra pequena. */
.tabela-dfc { font-size: 12.5px; }
.tabela-dfc th:first-child { position: sticky; left: 0; background: var(--branco); }
@media print {
  .tabela-dfc { font-size: 8.5pt; }
  .tabela-dfc th, .tabela-dfc td { padding: 3px 4px; }
}

/* ------------------------------------------------------- lançar (financeiro)
   Os três tipos de lançamento são a primeira escolha da tela e por isso são
   botões grandes, não um `<select>`: quem lança o dia inteiro decide isso
   dezenas de vezes, e um clique num alvo largo é mais rápido (e erra menos)
   que abrir uma lista de três. Continuam sendo radios de verdade — o teclado
   anda neles com as setas e o formulário funciona sem JS. */
.escolha-tipos { display: flex; flex-wrap: wrap; gap: 8px; }
.escolha-tipo {
  flex: 1 1 140px; justify-content: center; gap: 8px;
  border: 1px solid var(--linha); border-radius: 10px;
  padding: 10px 12px; background: var(--branco); font-size: 14px;
}
.escolha-tipo:has(input:checked) {
  border-color: var(--verde-broto); background: var(--verde-nevoa);
  color: var(--verde-eco-texto); font-weight: 600;
}
.escolha-tipo input { width: 15px; height: 15px; accent-color: var(--verde-folha); }

/* A regra do dono para a conta escolhida, à vista de quem lança. É ela que faz
   o mês que vem ser classificado igual ao mês passado. */
.ajuda-categoria {
  margin: 10px 0 0; padding: 8px 10px; font-size: 12.5px;
  color: var(--cinza); background: var(--verde-nevoa);
  border: 1px solid var(--linha); border-radius: 8px;
}

/* O RATEIO por centro de custo: uma linha por caminhão, o quanto dele e o
   botão de tirar. A nota que cita quatro caminhões não tem outra saída — o
   campo era um `<select>` só, e pôr a nota inteira num deles é justamente o
   número errado que a régua das quatro placas existe para evitar.

   O seletor leva `1fr` e a cifra largura fixa: ela guarda um número, não um
   nome. `minmax(0, 1fr)` foi TENTADO e MEDIDO como inerte aqui (390, 560, 700
   e 900px dão o MESMO tamanho de seletor com e sem o piso zero — o `select`
   já tem `width: 100%`) e ficou de fora, como o `scroll-margin-inline` das
   abas: linha que não faz o que o comentário promete é pior que linha
   nenhuma. */
.rateio-linha { display: grid; grid-template-columns: 1fr 118px auto; gap: 6px; align-items: center; }
.rateio-linha + .rateio-linha { margin-top: 6px; }
.rateio-linha [data-rateio-valor] { text-align: right; font-variant-numeric: tabular-nums; }
/* Abaixo de 520px as três colunas não cabem: o seletor toma a linha inteira e
   a cifra fica embaixo, ao lado do "Tirar". Em três colunas apertadas o nome
   do caminhão ficava em 138px a 390px, medido, que não diz qual é. */
@media (max-width: 520px) {
  .rateio-linha { grid-template-columns: 1fr auto; }
  .rateio-linha [data-centro-custo] { grid-column: 1 / -1; }
}
/* Com UM caminhão só não há cifra nem "Tirar", e o seletor volta a ocupar a
   linha inteira — que é a cara que o campo sempre teve, e é o caso de todo
   dia. Vem por ÚLTIMO para valer também dentro da faixa do celular. */
.rateio-linha:has([data-rateio-valor][hidden]) { grid-template-columns: 1fr; }

.lista-simples { list-style: none; }
.lista-simples li { padding: 4px 0; border-bottom: 1px solid var(--linha); }
.lista-simples li:last-child { border-bottom: 0; }

/* ------------------------------------------------- contas a pagar e receber
   A baixa mora na PRÓPRIA LINHA: o caso de todo dia é "recebi hoje o que
   faltava", e mandar quem confere abrir uma tela para cada título transformaria
   trinta boletos em sessenta cliques. Os campos ficam na horizontal e encolhem
   junto com a coluna. */
.baixa-rapida { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.baixa-rapida input, .baixa-rapida select { width: auto; min-width: 0; font-size: 12px; padding: 4px 6px; }

/* ------------------------------------------------- conferência de cobrança
   A tabela das faturas tem de CABER no cartão (está em `DEVEM_CABER`), e o
   que a impedia foi medido: o cabeçalho e as etiquetas em `nowrap` ("PAGAMENTO
   NA CENTRAL", "Paga — falta baixar no site") e a coluna das anotações, que
   foi para a linha de baixo (ver `linhaFatura`). O cabeçalho e a etiqueta
   quebram AQUI, não no app inteiro: nas outras tabelas a etiqueta numa linha
   só é o que as alinha. O raio de 9px é o da pílula de uma linha (ela tem
   ~19px de altura) e não vira cápsula esticada quando a etiqueta quebra. */
.tabela-cobranca th { white-space: normal; }
/* Respiro lateral de 8px em vez de 14: com sete colunas são 84px, que é o
   que faz a tabela caber em 900px de janela (com 14px o mínimo passava do
   cartão de 808px; com 10px, ainda passava 11px depois de o atraso voltar a
   ficar numa linha só). */
.tabela-cobranca th, .tabela-cobranca td { padding-left: 8px; padding-right: 8px; }
.tabela-cobranca .etiqueta { white-space: normal; border-radius: 9px; }
/* Menos a das colunas estreitas que não quebram (o atraso, a pista do
   controle): "96 d de atraso" em duas linhas sobrava espaço na tabela. */
.tabela-cobranca td.nao-quebra .etiqueta { white-space: nowrap; }
.tabela-cobranca .obra-triagem { overflow-wrap: anywhere; }
/* As duas linhas da fatura são uma: a de baixo não tem traço em cima, e o
   realce do mouse pega o `<tbody>` inteiro. */
.tabela-cobranca tbody:hover td { background: #FAFCF8; }
.tabela-cobranca tr.linha-anotacao td { border-top: 0; padding-top: 0; }
/* Cada campo da anotação com a largura do próprio texto — select estreito
   corta a opção escolhida, que é justamente o que se veio ler. A observação
   fica com o que sobra da linha. */
.anotacao-cobranca select { flex: 0 0 auto; }
.anotacao-cobranca input[name="observacao"] { flex: 1 1 220px; min-width: 160px; }
.anotacao-cobranca textarea { flex: 1 1 100%; }
/* A data do comprovante: rótulo curto e o campo de data na largura dele — é
   por esse dia que a cabeça de lote se acha no arquivo. */
.anotacao-cobranca .campo-comprovante { font-size: 12px; white-space: nowrap; gap: 5px; }
/* O título da lista com o botão do relatório para imprimir ao lado: no
   celular o botão desce para a linha de baixo em vez de espremer o título. */
.cabecalho-lista-cobranca { flex-wrap: wrap; margin-bottom: 4px; }
/* A busca do cadastro para vincular: no `.baixa-rapida` ela ficava com a
   largura padrão do campo (150px) e cortava a própria instrução ("Vincular ao
   cliente do cadastro…", 198px). */
.vincular-cobranca .autocomplete { flex: 1 1 280px; min-width: 0; }
.vincular-cobranca .autocomplete input { width: 100%; }

/* A folha de cobrança é papel: um bloco por cliente, e o bloco não se parte
   entre duas páginas — cliente cortado ao meio é telefonema perdido. */
.cabecalho-folha { margin-bottom: 14px; }
/* O título da FOLHA é um `h2` vestido de `h1`: a página já tem o seu `h1` no
   cabeçalho da tela, e dois `h1` na mesma página confundem leitor de tela e
   quem navega por títulos — na impressão o cabeçalho da tela some e este é o
   único que sobra, por isso ele tem de PARECER o título principal. */
.cabecalho-folha .titulo-folha {
  font-family: 'Quicksand', sans-serif; font-weight: 700; font-size: 24px;
  color: var(--verde-folha); letter-spacing: -.01em; text-transform: none; margin: 0;
}
.cabecalho-grupo { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }
.cabecalho-grupo h2 { margin: 0; }
/* A tabela de cada cliente rola dentro do próprio bloco no celular (estourava
   176px em 390 e 206px em 360); dentro do bloco, sem moldura própria — o
   cartão do cliente já é a moldura. */
.grupo-cobranca .tabela-envelope { border: 0; border-radius: 0; background: transparent; }

/* A conciliação é de DUAS COLUNAS porque a pergunta é de duas colunas: "esta
   linha do banco é qual pagamento meu?". No celular vira uma só — o banco em
   cima, que é por onde se começa. */
.duas-colunas-conciliacao { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); gap: 14px; align-items: start; }
/* `minmax(0, …)` e `min-width: 0` no cartão: sem eles a coluna cresce até o
   conteúdo da tabela do banco (a descrição do memo é longa) e a página inteira
   estourava 149px em 390 e 179px em 360 — o `.tabela-envelope` só rola quando
   o cartão em volta aceita ficar mais estreito que a tabela. É a mesma regra
   das duas colunas do monitoramento. */
.duas-colunas-conciliacao > .cartao { min-width: 0; }
@media (max-width: 900px) { .duas-colunas-conciliacao { grid-template-columns: minmax(0, 1fr); } }

/* Como o cliente paga e com quem se fala, em duas colunas acima da lista de
   dívidas — é a resposta que vinha da planilha à parte. Vira uma coluna no
   celular, como todo par de colunas do app. */
.condicoes-cobranca {
  display: grid; grid-template-columns: 1fr 1fr; gap: 8px 20px;
  margin: 10px 0; padding: 8px 0; font-size: 12px; line-height: 1.5;
  border-top: 1px solid var(--linha); border-bottom: 1px solid var(--linha);
}
.condicoes-cobranca .rotulo-campo { margin-bottom: 2px; }
@media (max-width: 620px) { .condicoes-cobranca { grid-template-columns: 1fr; } }

@media print {
  .grupo-cobranca { break-inside: avoid; border: 0; box-shadow: none; padding: 0 0 12px; margin: 0 0 12px; }
  .cabecalho-folha .titulo-folha { font-size: 16pt; }
}

/* A FOLHA no papel. Três coisas que só aparecem quando alguém imprime de
   verdade, e que passam despercebidas na tela:
   1. `.tabela-envelope` rola na horizontal — no papel isso CORTA a tabela em
      silêncio, e é o defeito que a fila do CDF já teve uma vez;
   2. sem `table-header-group` a segunda folha sai sem cabeçalho de coluna, e
      quem lê não sabe mais qual número é qual;
   3. o recuo e a borda do cartão viram moldura desperdiçando margem.
   Tudo escopado em `.folha-relatorio`: há outras onze tabelas usando as mesmas
   classes, e soltá-las globalmente mudaria a impressão de telas que ninguém
   pediu para mudar. */
@media print {
  .folha-relatorio .tabela-envelope { overflow: visible; border: 0; border-radius: 0; }
  .folha-relatorio thead { display: table-header-group; }
  .folha-relatorio tfoot { display: table-footer-group; }
}

/* ===== Retiradas (a fila da Sabrina: destino, tíquete, SINIR) ===== */
/* A tile é LINK para a fila que ela conta — o número diz quantas, o clique
   abre quais. Herda a cor do texto: tile azul de link não é tile. */
.tile-link { text-decoration: none; color: inherit; display: block; }
.tile-link:hover { border-color: var(--verde-broto); }
/* Um select ou uma busca de cliente com o botão ao lado; no celular
   empilham, porque o `flex-wrap` deixa. */
.linha-formulario { display: flex; flex-wrap: wrap; gap: 8px; align-items: flex-end; margin-top: 8px; }
.linha-formulario label { width: 100%; }
.linha-formulario select, .linha-formulario .autocomplete { flex: 1 1 220px; min-width: 0; max-width: 100%; }
.linha-formulario .origem { white-space: normal; width: 100%; }
/* O SINIR desta retirada e o padrão do cliente: dois fieldsets em coluna. */
.formulario-sinir { display: grid; gap: 8px; margin-top: 10px; }
.formulario-sinir fieldset { border: 1px solid var(--linha); border-radius: 8px; padding: 8px 10px; display: grid; gap: 6px; min-width: 0; }
.formulario-sinir legend { font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: .08em; color: var(--verde-eco-texto); padding: 0 4px; }
.formulario-sinir input[type=text], .formulario-sinir select { width: 100%; max-width: 100%; }
.formulario-sinir .btn { justify-self: start; }
.formulario-sinir .ajuda { white-space: normal; }
.padrao-cliente { margin-top: 14px; }
/* O envio do tíquete: rótulo, arquivo, botão — um por linha. */
/* O valor de cada caçamba na fatura: campo de dinheiro, à direita e da
   largura de "99.999,99" — com `width: 100%` ele seguiria a coluna. */
.celula-valor input.valor-item { width: 110px; text-align: right; font-variant-numeric: tabular-nums; }
.envio-anexo { display: grid; gap: 6px; margin-top: 10px; }
.envio-anexo input[type=text] { width: 100%; max-width: 100%; }
.envio-anexo .btn { justify-self: start; }
.inline { display: inline; }
.lista-simples .inline { margin-left: 6px; }
.lista-simples .origem { white-space: normal; }
/* A fila do pátio na aba Triagens: cartão âmbar, porque é o que falta fazer. */
.fila-do-patio { margin-bottom: 16px; border-color: #EBDCA8; background: #FDFBF3; }
/* As linhas repetidas do extrato: o mesmo âmbar — é o que falta o financeiro
   decidir. Os fatos saem um por linha: são as pistas que separam "colei de
   novo" de "o cliente pagou de novo", e corridos numa frase só ninguém os lê. */
.fila-decisao { margin-bottom: 16px; border-color: #EBDCA8; background: #FDFBF3; }
.fila-decisao .lote-repetidas { margin: 10px 0; }
.fila-decisao .lote-repetidas p { margin: 0 0 8px; }
.tabela-repetidas td.fatos-repetida {
  min-width: 240px; max-width: 420px; font-size: 12px; color: var(--grafite);
  white-space: normal; overflow-wrap: anywhere;
}
.fato-repetida { display: block; }
.fato-repetida + .fato-repetida { margin-top: 2px; }
.aviso-repetidas-extrato { margin: 6px 0 0; }
.decididas-repetidas { margin-top: 12px; }
.decididas-repetidas > summary { cursor: pointer; font-size: 13px; }
/* Dentro do dia, a linha que espera decisão: fora do subtotal, e por isso
   tracejada e sem valor na coluna do dinheiro. */
.tabela-extrato tr.linha-repetida-pendente td { background: #FDF7E6; border-top: 1px dashed #EBDCA8; }

/* A faixa da HOMOLOGAÇÃO (CENTRAL_HOMOLOGACAO=1): em toda tela, o login
   inclusive, para ninguém confundir o serviço de teste com a Central. */
.faixa-homologacao { background: var(--vermelho); color: #fff; text-align: center; font-size: 13px; font-weight: 600; line-height: 1.4; padding: 6px 16px; }
