/* ---------- Inter, autohospedada ----------
   Servida do próprio domínio em vez do CDN do Google: não entrega o IP de
   cada visitante a terceiro e tira fonts.googleapis.com/gstatic.com da CSP.
   É a fonte variável (peso 400 a 900), então um arquivo cobre todos os pesos
   que o projeto usa. Só latin e latin-ext — cobrem o português inteiro. */
/* latin-ext */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 900;
  font-display: swap;
  src: url(/assets/fontes/inter-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 900;
  font-display: swap;
  src: url(/assets/fontes/inter-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* Rodolatini - Painel / Portal do Motorista (mobile first) */

:root {
  --verde: #0D6B3C;
  --verde-escuro: #0A5530;
  --amarelo: #FFC629;
  --azul: #3B4A9F;
  --preto: #131313;
  --fundo: #F3F6F4;
  --branco: #FFFFFF;
  --texto: #1E2724;
  --texto-suave: #5B6B64;
  --borda: #DDE5E0;
  --vermelho: #C0392B;
  --ambar: #7A5D00;
  /* Superfície de aviso. O texto em --ambar sobre ela dá 5,7:1. */
  --ambar-fundo: #FFF6DC;
  --ambar-borda: #F1DFA0;
  --raio: 12px;
  --sombra: 0 1px 3px rgba(19, 40, 30, .08), 0 4px 14px rgba(19, 40, 30, .06);
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: "Inter", system-ui, -apple-system, sans-serif;
  background: var(--fundo);
  color: var(--texto);
  font-size: 16px;
  line-height: 1.5;
}
img { max-width: 100%; }
a { color: var(--verde); }

/* ---------- Layout com sidebar ---------- */
:root { --sidebar-w: 236px; --sidebar-rail: 62px; --topbar-h: 56px; }
.app-layout { display: flex; min-height: 100vh; }

/* ===== Sidebar ===== */
.sidebar {
  width: var(--sidebar-w);
  flex: 0 0 var(--sidebar-w);
  background: linear-gradient(180deg, var(--verde-escuro), #08331d);
  color: #eaf3ee;
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  z-index: 50;
  transition: width .18s ease, flex-basis .18s ease;
}
.sidebar-cabecalho {
  height: var(--topbar-h);
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 10px 0 16px;
  border-bottom: 1px solid rgba(255,255,255,.1);
  flex: none;
}
.sidebar-logo { display: flex; align-items: center; overflow: hidden; }
/* flex: none + object-fit impedem que a régua estreita esprema a marca:
   sem isso a logo encolhia só na largura e chegava achatada. */
.sidebar-logo img { flex: none; width: auto; object-fit: contain; }
.sidebar-logo .logo-full { height: 26px; }
.sidebar-logo .logo-mini { height: 28px; display: none; }
.sidebar-recolher {
  margin-left: auto;
  background: rgba(255,255,255,.08);
  border: none;
  color: #eaf3ee;
  width: 30px; height: 30px;
  border-radius: 8px;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  flex: none;
}
.sidebar-recolher svg { width: 18px; height: 18px; }
.sidebar-recolher:hover { background: rgba(255,255,255,.16); }

.sidebar-nav { flex: 1; overflow-y: auto; padding: 10px 8px; display: flex; flex-direction: column; gap: 2px; scrollbar-width: thin; }
.side-item, .side-grupo > summary {
  display: flex; align-items: center; gap: 11px;
  padding: 10px 12px;
  /* Alvo de toque: o padding sozinho dava 41px aqui e 36px no submenu, abaixo
     do piso de 44px. A altura mínima resolve sem inchar o texto nem o ícone. */
  min-height: 44px;
  border-radius: 9px;
  color: rgba(255,255,255,.85);
  text-decoration: none;
  font-size: 14px; font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}
.side-item:hover, .side-grupo > summary:hover { background: rgba(255,255,255,.09); color: #fff; }
.side-item.ativo { background: rgba(255,255,255,.15); color: #fff; box-shadow: inset 3px 0 0 var(--amarelo); }
.side-ico { flex: none; display: flex; }
.side-ico .ico-svg { width: 20px; height: 20px; }
.side-txt { flex: 1; overflow: hidden; text-overflow: ellipsis; }

.side-grupo > summary { list-style: none; }
.side-grupo > summary::-webkit-details-marker { display: none; }
.side-grupo.ativo > summary { color: #fff; }
.side-seta { flex: none; display: flex; transition: transform .15s; opacity: .7; }
.side-seta svg { width: 16px; height: 16px; }
.side-grupo[open] > summary .side-seta { transform: rotate(180deg); }
.side-sub { display: flex; flex-direction: column; gap: 1px; margin: 2px 0 4px; }
.side-sub a {
  display: flex; align-items: center; gap: 10px;
  color: rgba(255,255,255,.72);
  text-decoration: none;
  font-size: 13.5px; font-weight: 500;
  /* A indentação era de 43px porque o item era só texto. Com ícone, a
     hierarquia vem do desenho: recuo menor e ícone um pouco reduzido. */
  padding: 8px 12px 8px 20px;
  min-height: 44px;
  border-radius: 8px;
  white-space: nowrap;
}
.side-sub .side-ico .ico-svg { width: 17px; height: 17px; }
.side-sub a:hover { background: rgba(255,255,255,.08); color: #fff; }
.side-sub a.ativo { background: rgba(255,198,41,.16); color: var(--amarelo); font-weight: 600; }

/* ===== Sidebar recolhida (rail, desktop) ===== */
.sidebar-recolhida .sidebar { flex: 0 0 var(--sidebar-rail); width: var(--sidebar-rail); }
.sidebar-recolhida .sidebar-logo .logo-full { display: none; }
.sidebar-recolhida .sidebar-logo .logo-mini { display: block; }
/* Na régua sobram 62px: o "R" (quadrado) e o botão precisam caber lado a
   lado sem se espremer — daí os tamanhos menores e o respiro apertado. */
.sidebar-recolhida .sidebar-cabecalho { padding: 0 4px; gap: 4px; justify-content: center; }
.sidebar-recolhida .sidebar-logo .logo-mini { height: 22px; }
.sidebar-recolhida .sidebar-recolher { width: 26px; height: 26px; margin-left: 0; position: relative; }
/* O botão encolhe para caber ao lado do "R", mas o alvo de clique não:
   o ::after devolve os 44px sem inflar o desenho. */
.sidebar-recolhida .sidebar-recolher::after { content: ""; position: absolute; inset: -9px; }
.sidebar-recolhida .sidebar-recolher { transform: rotate(180deg); }
/* Recolhido, todo destino vira um ícone — e todos ficam visíveis e clicáveis
   de uma vez. Antes era preciso passar o mouse no grupo e esperar um flyout
   para alcançar qualquer tela de dentro dele. */
.sidebar-recolhida .side-txt,
.sidebar-recolhida .side-seta { display: none; }

/* O cabeçalho do grupo sai: o ícone dele competiria com os dos itens, criando
   dois níveis de ícone sem texto para diferenciá-los. Um traço preserva o
   agrupamento sem ocupar altura. */
.sidebar-recolhida .side-grupo > summary { display: none; }
.sidebar-recolhida .side-grupo + .side-grupo,
.sidebar-recolhida .side-item + .side-grupo {
  border-top: 1px solid rgba(255,255,255,.14);
  margin-top: 7px; padding-top: 7px;
}
.sidebar-recolhida .side-sub { margin: 0; }
.sidebar-recolhida .side-item,
.sidebar-recolhida .side-sub a { justify-content: center; padding: 11px; gap: 0; }
.sidebar-recolhida .side-sub .side-ico .ico-svg { width: 20px; height: 20px; }

/* Com o texto oculto, o rótulo ao passar o mouse é a única pista do destino.
   Feito em CSS, e não pelo title do navegador, que demora ~1s para aparecer.

   É position:fixed, e não absolute: o .sidebar-nav tem overflow-y auto, o que
   pela especificação torna o overflow-x também não-visível. Posicionado por
   absolute, o balão nascia fora do menu e era recortado — ficava invisível.
   As coordenadas vêm do JS, em --tt-x/--tt-y, atualizadas a cada hover (assim
   acompanham a rolagem do menu). */
.sidebar-recolhida .side-item,
.sidebar-recolhida .side-sub a { position: relative; }
.sidebar-recolhida .side-item::after,
.sidebar-recolhida .side-sub a::after {
  content: attr(data-rotulo);
  position: fixed;
  left: var(--tt-x, -9999px);
  top: var(--tt-y, -9999px);
  transform: translateY(-50%);
  background: #0b3d24; color: #fff;
  padding: 7px 11px; border-radius: 8px;
  font-size: 13px; font-weight: 600; white-space: nowrap;
  box-shadow: 0 8px 24px rgba(0,0,0,.4);
  opacity: 0; visibility: hidden; transition: opacity .12s;
  z-index: 80;
}
.sidebar-recolhida .side-item:hover::after,
.sidebar-recolhida .side-sub a:hover::after,
.sidebar-recolhida .side-item:focus-visible::after,
.sidebar-recolhida .side-sub a:focus-visible::after { opacity: 1; visibility: visible; }

/* ===== Área principal + topbar ===== */
.app-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.topbar {
  height: var(--topbar-h);
  background: #fff;
  border-bottom: 1px solid var(--borda);
  display: flex; align-items: center; gap: 12px;
  padding: 0 16px;
  position: sticky; top: 0; z-index: 40;
}
.topbar-menu { display: none; background: none; border: none; cursor: pointer; color: var(--texto); padding: 4px; }
.topbar-menu svg { width: 24px; height: 24px; }
.topbar-titulo { font-size: 16px; font-weight: 700; color: var(--texto); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.topbar-dir { margin-left: auto; display: flex; align-items: center; gap: 12px; min-width: 0; }
.badge-ambiente { background: var(--amarelo); color: var(--preto); font-size: 11px; font-weight: 800; letter-spacing: .06em; padding: 3px 8px; border-radius: 999px; white-space: nowrap; }
/* O seletor não encolhia (158px fixos) e era ele que estourava a topbar em
   375px, desde antes do menu da conta. Agora divide o aperto com o resto. */
.seletor-empresa { min-width: 0; }
.seletor-empresa select {
  background: var(--fundo); color: var(--texto);
  min-width: 0; max-width: 100%;
  border: 1px solid var(--borda); border-radius: 8px;
  font: inherit; font-size: 13px; font-weight: 600; padding: 6px 8px; max-width: 42vw;
}
/* O selo da empresa também encolhe: sem isso ele fica inteiro e é o nome do
   usuário, ao lado, que some por completo em tela estreita. */
.topo-empresa { font-size: 12px; font-weight: 700; background: #E6F4EC; color: var(--verde-escuro); padding: 5px 11px; border-radius: 999px;
  white-space: nowrap; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
/* ---------- Menu da conta (no nome do usuário) ---------- */
/* O piso vai no <details>, não no <summary>: é ele o item flex da topbar.
   Nascendo com min-width auto ele recusava encolher e empurrava a barra para
   498px numa tela de 375px; com o piso no resumo, o resumo é que transbordava
   e cobria o botão Sair. 84px deixam o nome começar a aparecer sem estourar a barra em 360px. */
.menu-conta { position: relative; min-width: 0; }
@media (min-width: 861px) {
  .menu-conta { min-width: 84px; }
}
.menu-conta > summary { list-style: none; cursor: pointer; }
.menu-conta > summary::-webkit-details-marker { display: none; }
.menu-conta > summary:hover { background: var(--fundo); }
.menu-conta > summary:focus-visible { outline: 2px solid var(--verde); outline-offset: 2px; }
.menu-conta[open] > summary .tb-seta { transform: rotate(180deg); }
.tb-seta { width: 16px; height: 16px; flex: none; color: var(--texto-suave); transition: transform .15s ease; }
/* min-width: 0 é o que permite o bloco de textos encolher dentro do flex —
   sem ele o gatilho do menu não cabia na topbar em 375px. O perfil ganha
   reticências como o nome; o texto inteiro fica no title do resumo. */
.tb-textos { display: flex; flex-direction: column; min-width: 0; overflow: hidden; }
.menu-conta > summary .tb-perfil { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.menu-conta-lista {
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  z-index: 60;
  min-width: 200px;
  max-width: calc(100vw - 24px);
  background: #fff;
  border: 1px solid var(--borda);
  border-radius: var(--raio);
  box-shadow: var(--sombra);
  padding: 6px;
}
.menu-conta-lista a {
  display: flex; align-items: center; gap: 10px;
  padding: 11px 12px;
  border-radius: 8px;
  color: var(--texto);
  text-decoration: none;
  font-size: 16px;
  white-space: nowrap;
}
.menu-conta-lista a:hover { background: var(--fundo); }
.menu-conta-lista a svg { width: 18px; height: 18px; flex: none; color: var(--texto-suave); }

.topbar-usuario { display: flex; align-items: center; gap: 8px; line-height: 1.15; min-width: 0; padding: 5px 8px; border-radius: 8px; }
.topbar-usuario .tb-nome { font-size: 13px; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 30vw; }
.topbar-usuario .tb-perfil { font-size: 11px; color: var(--texto-suave); }
/* Sair mora no menu da conta; o vermelho separa a ação destrutiva das demais
   sem depender só da cor — ela vem acompanhada do traço divisor acima. */
.menu-conta-lista .menu-conta-sair { margin-top: 4px; padding-top: 12px; border-top: 1px solid var(--borda); border-radius: 0 0 8px 8px; }
.menu-conta-lista .menu-conta-sair:hover { background: #FDECEA; color: var(--vermelho); }
.menu-conta-lista .menu-conta-sair:hover svg { color: var(--vermelho); }
.sidebar-overlay { display: none; }

/* ---------- Layout conteúdo ---------- */
/* O teto era 1200px: num monitor de 1920, descontada a barra lateral, sobravam
   uns 240px vazios de cada lado — espaço que as tabelas de cadastro e os
   gráficos aproveitam bem. 1600px enche a tela larga e ainda evita que num
   monitor ultralargo a linha de texto fique longa demais para acompanhar. */
.conteudo { max-width: 1600px; width: 100%; margin: 0 auto; padding: 18px; }

/* ===== Responsivo: sidebar off-canvas no mobile ===== */
@media (max-width: 860px) {
  .sidebar {
    position: fixed; left: 0; top: 0;
    transform: translateX(-100%);
    transition: transform .2s ease;
    box-shadow: 0 0 40px rgba(0,0,0,.4);
    width: var(--sidebar-w) !important; flex-basis: var(--sidebar-w) !important;
  }
  .sidebar-aberta .sidebar { transform: translateX(0); }
  /* No celular o menu é off-canvas e sempre em largura cheia: tudo o que o
     modo recolhido esconde precisa voltar, inclusive o rótulo do grupo. */
  .sidebar-recolhida .sidebar-logo .logo-full { display: block; }
  .sidebar-recolhida .sidebar-logo .logo-mini { display: none; }
  .sidebar-recolhida .sidebar-cabecalho { padding: 0 10px 0 16px; gap: 8px; justify-content: flex-start; }
  .sidebar-recolhida .side-txt, .sidebar-recolhida .side-seta { display: flex; }
  .sidebar-recolhida .side-grupo > summary { display: flex; }
  .sidebar-recolhida .side-grupo + .side-grupo,
  .sidebar-recolhida .side-item + .side-grupo { border-top: none; margin-top: 0; padding-top: 0; }
  .sidebar-recolhida .side-item,
  .sidebar-recolhida .side-sub a { justify-content: flex-start; gap: 10px; }
  .sidebar-recolhida .side-item::after,
  .sidebar-recolhida .side-sub a::after { content: none; }
  .sidebar-recolher { display: none; }
  .topbar-menu { display: flex; }
  .sidebar-aberta .sidebar-overlay { display: block; position: fixed; inset: 0; background: rgba(10,25,18,.5); z-index: 45; }
  .conteudo { padding: 14px; }
}
.pagina-cabecalho {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin: 8px 0 16px;
}
.pagina-cabecalho h1 { font-size: 22px; margin: 0; font-weight: 800; }
.pagina-cabecalho .acoes { margin-left: auto; display: flex; gap: 8px; }

.cartao {
  background: var(--branco);
  border: 1px solid var(--borda);
  border-radius: var(--raio);
  box-shadow: var(--sombra);
  padding: 16px;
  margin-bottom: 16px;
}
.cartao h2 { margin-top: 0; font-size: 17px; }

/* Seções recolhíveis (ex.: administração do site) */
.secao-config > summary { font-size: 16px; font-weight: 700; cursor: pointer; list-style: none; display: flex; align-items: center; gap: 8px; }
.secao-config > summary::-webkit-details-marker { display: none; }
.secao-config > summary::before { content: "▸"; color: var(--verde); transition: transform .15s; }
.secao-config[open] > summary::before { transform: rotate(90deg); }

/* ---------- Mensagens ---------- */
.flash {
  padding: 12px 14px;
  border-radius: 10px;
  margin: 0 0 14px;
  font-size: 14px;
  font-weight: 500;
  border: 1px solid transparent;
}
.flash-sucesso { background: #E6F4EC; color: #0A5530; border-color: #BCE0CB; }
.flash-erro    { background: #FBEAE8; color: #92271B; border-color: #F0C3BD; }
.flash-aviso   { background: var(--ambar-fundo); color: var(--ambar); border-color: var(--ambar-borda); }

/* ---------- Botões ---------- */
.botao {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  background: var(--verde);
  color: #fff;
  border: 1px solid var(--verde);
  font: inherit;
  font-size: 14px;
  font-weight: 700;
  padding: 10px 18px;
  border-radius: 10px;
  cursor: pointer;
  text-decoration: none;
  transition: background .15s;
}
.botao:hover { background: var(--verde-escuro); }
.botao-secundario { background: #fff; color: var(--verde); }
.botao-secundario:hover { background: #EDF5F0; }
.botao-perigo { background: var(--vermelho); border-color: var(--vermelho); }
.botao-perigo:hover { background: #A03225; }
.botao-mini { padding: 6px 12px; font-size: 13px; border-radius: 8px; }
.botao[disabled] { opacity: .6; cursor: not-allowed; }

/* ---------- Formulários ---------- */
.form-grade { display: grid; grid-template-columns: 1fr; gap: 12px; }
/* O rótulo identifica o campo: é o texto mais forte do conjunto.
   Antes usava a mesma cor da dica, e os dois se confundiam. */
.campo label { display: block; font-size: 13px; font-weight: 700; margin-bottom: 5px; color: var(--texto); }
/* Seletor CPF/CNPJ na MESMA linha do rótulo (decisão do usuário, 2026-08-15):
   em linha própria os radios empurravam o campo para baixo do vizinho. */
.rotulo-com-opcoes { display: flex; align-items: baseline; gap: 4px 18px; flex-wrap: wrap; }
.rotulo-com-opcoes > label { margin-bottom: 5px; }
.opcoes-doc { display: inline-flex; gap: 16px; }
.opcoes-doc label {
  display: inline-flex; align-items: center; gap: 6px;
  /* alvo de toque de ~44px sem ocupar altura: o padding cria a área clicável
     e a margem negativa devolve a linha ao tamanho do rótulo */
  margin: -12px 0; padding: 12px 0;
  font-size: 13px; font-weight: 600; cursor: pointer;
}
.opcoes-doc input { width: 16px; height: 16px; margin: 0; accent-color: var(--verde); }
.campo input, .campo select, .campo textarea {
  width: 100%;
  font: inherit;
  font-size: 16px; /* evita zoom no iOS */
  padding: 10px 12px;
  border: 1px solid var(--borda);
  border-radius: 10px;
  background: #fff;
  color: var(--texto);
}
.campo input:focus, .campo select:focus, .campo textarea:focus {
  outline: 2px solid var(--verde);
  outline-offset: 0;
  border-color: var(--verde);
}
/* Texto auxiliar: um degrau abaixo do rótulo, mas ainda legível.
   Mantido em --texto-suave (5,6:1 sobre branco) — clarear mais reprovaria no
   critério de contraste da WCAG, então quem muda de tom é o rótulo. */
/* Ajuda contextual: ícone "?" ao lado do rótulo (helper ajuda() do PHP).
   O balão abre no hover, no foco de teclado e no toque (classe .ajuda-aberta,
   alternada pelo app.js — no iOS tocar num botão não o foca). */
.ajuda { position: relative; display: inline-flex; vertical-align: -2px; margin-left: 4px; }
/* 16px cabe na linha do rótulo (13px/20px) sem esticá-la — com 21px o ícone
   passava da linha e a engordava */
.ajuda-icone {
  position: relative;
  width: 16px; height: 16px; border-radius: 50%; padding: 0;
  border: 1.5px solid #67756F; background: none; color: #4E5C56;
  font: 700 10px/1 Inter, system-ui, sans-serif;
  display: inline-flex; align-items: center; justify-content: center;
  cursor: help;
}
/* Alvo de toque de ~44px sem inflar a linha do rótulo */
.ajuda-icone::after { content: ""; position: absolute; inset: -14px; border-radius: 50%; }
.ajuda-icone:hover, .ajuda-icone:focus-visible, .ajuda-aberta .ajuda-icone {
  border-color: var(--verde); color: var(--verde-escuro);
}
.ajuda-balao {
  /* Fechado fica em left negativo, não só invisível: elemento com visibility
     hidden ainda conta na área de rolagem, e um balão largo pendurado à
     direita criava rolagem horizontal na página inteira. Deslocamento
     negativo em LTR não gera rolagem. */
  /* display explícito vence o atributo hidden do markup — que é o estado
     seguro quando este CSS ainda não carregou (cache de deploy anterior) */
  display: block;
  position: absolute; bottom: calc(100% + 9px); left: -9999px;
  width: max-content; max-width: min(300px, 76vw);
  background: #12291C; color: #FFFFFF;
  font-size: 13px; font-weight: 500; line-height: 1.5; text-align: left; white-space: normal;
  /* Zera o que o rótulo em volta impõe: no card de KPI o texto vinha TODO
     EM MAIÚSCULAS e espaçado, herdado do .kpi-rotulo. O balão é frase
     corrida e precisa se ler como frase. */
  text-transform: none; letter-spacing: normal;
  padding: 9px 12px; border-radius: 9px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, .35);
  opacity: 0; visibility: hidden; transition: opacity .12s;
  z-index: 90;
}
/* :focus-visible, e não :focus-within: showModal() foca o primeiro focável do
   diálogo — que agora é o "?" do primeiro rótulo — e com :focus-within todo
   diálogo abriria já com um balão aceso. :focus-visible só acende quando o
   foco chega por teclado, que é quando o balão é realmente pedido. */
/* --ajuste desloca o balão quando, centrado no ícone, ele estouraria a borda
   da janela (ícone perto da borda, tela estreita). O valor exato é medido e
   posto pelo app.js ao abrir; centrado, vale 0. */
.ajuda:hover .ajuda-balao, .ajuda-icone:focus-visible + .ajuda-balao, .ajuda-aberta .ajuda-balao {
  left: 50%; transform: translateX(calc(-50% + var(--ajuste, 0px)));
  opacity: 1; visibility: visible;
}
/* Virado para baixo quando não há espaço acima — dentro de um <dialog>, que
   recorta no próprio limite, o balão do primeiro campo sairia pelo topo.
   Classe posta pelo app.js junto com o --ajuste. */
.ajuda .ajuda-balao.balao-baixo { bottom: auto; top: calc(100% + 9px); }

/* Texto dentro do campo: some ao digitar, então é o mais fraco dos três —
   ainda assim em 4,8:1, acima do mínimo. */
.campo input::placeholder,
.campo textarea::placeholder { color: #67756F; opacity: 1; }
/* Campos que ficam sempre em maiúsculas (o valor é normalizado no servidor) */
.campo input.maiusculas { text-transform: uppercase; }
.form-acoes { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 4px; }

/* ---------- Filtros ---------- */
.filtros { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; align-items: end; }
.filtros .campo { min-width: 0; }
.filtros .form-acoes { grid-column: 1 / -1; margin: 0; }

/* ---------- Filtro rápido de período (Semana / Mês / Ano) ---------- */
/* A linha do período: o atalho abre a linha, as datas que ele preenche vêm
   em seguida e as ações fecham à direita. Flex em vez da grade do formulário
   porque são quatro blocos de larguras bem diferentes — o grupo de pílulas
   tem largura própria, as datas esticam e os botões encostam na borda. */
.linha-datas {
  grid-column: 1 / -1;
  display: flex; flex-wrap: wrap; gap: 10px; align-items: end;
}
.linha-datas .campo { flex: 1 1 150px; min-width: 0; }
.linha-datas .campo-periodo { flex: 0 0 auto; }
.linha-datas .form-acoes { margin-left: auto; }
/* Empilhado, "encostar à direita" viraria um botão solto no canto */
@media (max-width: 719px) {
  .linha-datas .form-acoes { margin-left: 0; width: 100%; }
}
.periodo-rotulo {
  display: block; font-size: 13px; font-weight: 700;
  margin-bottom: 5px; color: var(--texto);
}
.periodo-rapido {
  display: inline-flex; gap: 4px; flex-wrap: wrap;
  padding: 4px;
  background: var(--fundo);
  border: 1px solid var(--borda);
  border-radius: 999px;
}
.periodo-rapido button {
  min-height: 44px; padding: 0 18px;
  border: 0; border-radius: 999px;
  background: transparent;
  color: var(--texto);
  font: inherit; font-size: 14px; font-weight: 600;
  cursor: pointer;
}
.periodo-rapido button:hover { background: rgba(13, 107, 60, .10); }
.periodo-rapido button:focus-visible { outline: 2px solid var(--verde); outline-offset: 2px; }
/* O período em uso é preenchido, não só colorido: cor sozinha não pode ser
   o único sinal de estado. */
.periodo-rapido button.ativo { background: var(--verde); color: var(--branco); }
.periodo-rapido button.ativo:hover { background: var(--verde-escuro); }

/* As ações dos filtros usam o mesmo desenho do período rápido: a cápsula
   clara com as pílulas dentro. Vale para todo formulário de filtro do
   painel, não só as telas com período — quatro telas num desenho e doze
   noutro destoaria. Fora do cartão de filtros o botão continua o de sempre.
   A ação principal fica preenchida, como o período em uso, e a secundária
   vazada: mesmo desenho, hierarquia preservada. */
.filtros .form-acoes,
.filtros-fretes .form-acoes,
.filtros-dashboard .form-acoes,
.linha-datas .form-acoes {
  display: inline-flex; gap: 4px; flex-wrap: wrap;
  padding: 4px;
  background: var(--fundo);
  border: 1px solid var(--borda);
  border-radius: 999px;
  /* Item de grade estica por padrão: sem isto a cápsula preenche a coluna
     inteira e sobra uma cauda vazia depois do último botão — aparece na
     cara em telas de um botão só, como Meus fretes. */
  justify-self: start;
}
.filtros .form-acoes .botao,
.filtros-fretes .form-acoes .botao,
.filtros-dashboard .form-acoes .botao,
.linha-datas .form-acoes .botao {
  min-height: 44px; padding: 0 18px;
  border: 0; border-radius: 999px;
  font-size: 14px; font-weight: 600;
}
.filtros .form-acoes .botao-secundario,
.filtros-fretes .form-acoes .botao-secundario,
.filtros-dashboard .form-acoes .botao-secundario,
.linha-datas .form-acoes .botao-secundario {
  background: transparent; color: var(--texto);
}
.filtros .form-acoes .botao-secundario:hover,
.filtros-fretes .form-acoes .botao-secundario:hover,
.filtros-dashboard .form-acoes .botao-secundario:hover,
.linha-datas .form-acoes .botao-secundario:hover { background: rgba(13, 107, 60, .10); }

/* Filtros da tela de fretes: status/cliente/motorista na 1ª linha, datas na 2ª */
.filtros-fretes { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; align-items: end; }
.filtros-fretes .campo { min-width: 0; }
.filtros-fretes .f-status, .filtros-fretes .f-cliente, .filtros-fretes .f-motorista,
.filtros-fretes .form-acoes { grid-column: 1 / -1; }
.filtros-fretes .form-acoes { margin: 0; }
@media (min-width: 720px) {
  .filtros-fretes { grid-template-columns: 0.8fr 1.6fr 1.6fr; }
  .filtros-fretes .f-status, .filtros-fretes .f-cliente, .filtros-fretes .f-motorista,
  .filtros-fretes .form-acoes { grid-column: auto; }
}

/* Duas datas lado a lado. Abaixo de 720px vira uma coluna: o input type=date
   tem largura mínima própria que a trilha 1fr não consegue encolher, e o par
   estourava o cartão em 375px (rolagem horizontal na tela do motorista). */
.campos-duplos { display: grid; grid-template-columns: 1fr; gap: 12px; }
.campos-duplos .campo { min-width: 0; }
@media (min-width: 720px) {
  .campos-duplos { grid-template-columns: 1fr 1fr; }
}

/* Filtros do dashboard: Cliente (2x) + Motorista + Material na 1ª linha; datas na 2ª */
.filtros-dashboard { display: grid; grid-template-columns: 1fr; gap: 10px; align-items: end; }
.filtros-dashboard .campo { min-width: 0; }
@media (min-width: 720px) {
  /* Cliente, Motorista e Material na 1ª linha; datas + botões na 2ª */
  .filtros-dashboard { grid-template-columns: repeat(3, 1fr); }
}

/* ---------- Busca dentro da grid ----------
   Fica no cartão da tabela, e não junto dos filtros, porque é a tabela que ela
   estreita. Fora do .tabela-scroll de propósito: lá dentro a barra rolaria na
   horizontal junto com a tabela larga e sumiria da vista. */
.busca-tabela {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--borda);
}
.busca-tabela > label { font-size: 13px; font-weight: 700; color: var(--texto); }
/* No celular o campo fica sozinho na linha e os botões descem: dividir a linha
   com os dois deixava sobrando ~120px de campo, que cortava o termo digitado
   no meio. Da largura de tablet em diante os três cabem lado a lado. */
.busca-campo { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; flex: 1 1 240px; min-width: 0; }
.busca-campo input[type="search"] {
  flex: 1 1 100%; min-width: 0;
  font: inherit;
  font-size: 16px; /* evita zoom no iOS */
  min-height: 44px; padding: 10px 14px;
  border: 1px solid var(--borda); border-radius: 999px;
  background: var(--branco); color: var(--texto);
}
.busca-campo input[type="search"]:focus {
  outline: 2px solid var(--verde); outline-offset: 0;
  border-color: var(--verde);
}
.busca-campo input[type="search"]::placeholder { color: #67756F; opacity: 1; }
.busca-campo .botao { min-height: 44px; border-radius: 999px; font-size: 14px; }
/* .botao declara display:inline-flex, e regra de classe vence o hidden do
   agente de usuário — sem esta linha o "Limpar" aparece com o campo vazio.
   Escopado de propósito: um [hidden]{display:none} global apagaria o balão de
   ajuda, que nasce com hidden justamente para o CSS reexibi-lo. */
.busca-campo .botao[hidden] { display: none; }
@media (min-width: 560px) {
  .busca-campo { flex-wrap: nowrap; }
  .busca-campo input[type="search"] { flex: 1 1 auto; }
}
/* Ocupa a linha inteira para o contador não empurrar o campo ao aparecer. */
.busca-status { flex: 1 0 100%; margin: 0; font-size: 13px; color: var(--texto-suave); }

/* ---------- Parcelas do fechamento (informadas à mão) ---------- */
/* .tabela tem min-width de 640px, pensada para grades largas. Aqui são três
   colunas de formulário, e a largura mínima jogava o campo de valor para trás
   da rolagem horizontal — campo que se digita precisa estar à vista. */
.parcelas-editaveis table.tabela { min-width: 0; }

/* No celular a linha vira bloco, com o rótulo em cima de cada campo: um
   input[type=date] e um de valor não caberiam lado a lado em 375px sem cortar
   um dos dois. Da largura de tablet em diante volta a ser tabela. */
.parcelas-editaveis thead { display: none; }
.parcelas-editaveis tbody, .parcelas-editaveis tr { display: block; }
.parcelas-editaveis tr { border-bottom: 1px solid var(--borda); padding: 10px 0; }
.parcelas-editaveis tr:hover td { background: none; }
.parcelas-editaveis td { display: block; border: 0; padding: 4px 0; }
.parcelas-editaveis td[data-rotulo]::before {
  content: attr(data-rotulo);
  display: block;
  font-size: 13px; font-weight: 700; color: var(--texto);
  margin-bottom: 4px;
}
.parcelas-editaveis .parcela-numero::before { content: "Parcela "; }
@media (min-width: 560px) {
  /* Larguras mínimas por campo: com seis colunas, a trilha do valor encolhia
     até cortar os centavos em tela de ~1100px. O mínimo é o texto que cada
     campo precisa mostrar inteiro. */
  .parcelas-editaveis td input[type="date"] { min-width: 140px; }
  .parcelas-editaveis td input[name="valor[]"] { min-width: 110px; }
  .parcelas-editaveis td input[name="numero[]"] { min-width: 120px; }
  .parcelas-editaveis td select { min-width: 130px; }
  .parcelas-editaveis thead { display: table-header-group; }
  .parcelas-editaveis tbody { display: table-row-group; }
  .parcelas-editaveis tr { display: table-row; padding: 0; border-bottom: 0; }
  .parcelas-editaveis td { display: table-cell; padding: 8px 6px; vertical-align: middle; }
  .parcelas-editaveis td[data-rotulo]::before,
  .parcelas-editaveis .parcela-numero::before { display: none; content: none; }
}
.parcelas-editaveis .parcela-numero { font-weight: 800; width: 1%; white-space: nowrap; }
.parcelas-editaveis td input,
.parcelas-editaveis td select { width: 100%; min-height: 44px; font: inherit; font-size: 16px;
  padding: 8px 10px; border: 1px solid var(--borda); border-radius: 10px; background: var(--branco); color: var(--texto); }
.parcelas-editaveis td input:focus,
.parcelas-editaveis td select:focus { outline: 2px solid var(--verde); border-color: var(--verde); }
/* .botao declara display, e regra de classe vence o atributo hidden — sem esta
   linha o "Remover" e o "+ Adicionar parcela" apareceriam sem o JS que os usa. */
.parcelas-editaveis .botao[hidden] { display: none; }

/* Atalho "fechar o total nesta parcela".

   Fica colado ao campo que recebe o valor, e não no card do resumo: no celular
   tocar no campo levanta o teclado, que cobre o rodapé da tela justamente
   quando o atalho estaria disponível. Aqui ele nasce ao lado do polegar.

   O .botao-mini tem cerca de 33px de altura — abaixo do piso de 44px para alvo
   de toque. A altura mínima corrige sem mexer no tamanho do texto. */
.parcela-fechar { margin-top: 6px; width: 100%; min-height: 44px; }
@media (min-width: 720px) {
  /* Na tabela a largura acompanha o texto: esticado, virava um bloco largo
     debaixo de um campo de número. */
  .parcela-fechar { width: auto; }
}
/* Os três números do parcelamento em cards: em texto corrido a diferença
   passava despercebida justamente quando importava. A cor não é o único sinal —
   o rótulo do card muda entre "Diferença", "Falta distribuir" e "Excedente". */
.kpis-parcelas { margin: 12px 0 0; }
.kpis-parcelas .kpi-fecha { border-top: 3px solid var(--verde); }
.kpis-parcelas .kpi-fecha .kpi-valor { color: var(--verde-escuro); }
.kpis-parcelas .kpi-difere { border-top: 3px solid var(--vermelho); }
.kpis-parcelas .kpi-difere .kpi-valor { color: var(--vermelho); }

/* Ainda usado na tela de seleção de fretes do novo fechamento. */
.parcelas-resumo { margin: 10px 0 0; font-size: 14px; color: var(--texto-suave); }
.parcelas-resumo.parcelas-fecha { color: var(--verde-escuro); font-weight: 700; }

/* ---------- Tabelas ---------- */
.tabela-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* Formulário curto (troca de senha): esticar três campos por 1600px de
   largura só afasta o olho do que ele precisa ler. */
.form-estreito { max-width: 460px; }
table.tabela { width: 100%; border-collapse: collapse; font-size: 14px; min-width: 640px; }
.tabela th {
  text-align: left;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--texto-suave);
  padding: 10px 12px;
  border-bottom: 2px solid var(--borda);
  white-space: nowrap;
}
.tabela td { padding: 10px 12px; border-bottom: 1px solid var(--borda); vertical-align: middle; }
.tabela tr:hover td { background: #F7FAF8; }
.tabela .num { text-align: right; white-space: nowrap; }
.tabela .centro { text-align: center; white-space: nowrap; }
/* Valores atômicos — CPF, CNPJ, placa: quebrar no meio deles atrapalha a leitura */
.tabela .nao-quebra { white-space: nowrap; }
.tabela-compacta { min-width: auto; }
.col-acao { white-space: nowrap; width: 1%; }
.col-acao > * { display: inline-block; vertical-align: middle; }
.col-acao form { margin-left: 5px; }

/* Rodapé do modal: Salvar/Cancelar à esquerda, Excluir à direita */
.dialogo-rodape {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: 4px;
  padding-top: 14px;
  border-top: 1px solid var(--borda);
}
.dialogo-rodape .form-excluir { margin-left: auto; }

/* Ação indisponível: continua clicável de propósito, para explicar o motivo.
   Um botão realmente desabilitado não dispara clique e deixaria o usuário sem
   resposta, tentando de novo sem entender. */
.botao-inativo { opacity: .5; cursor: not-allowed; }
.botao-inativo:hover { transform: none; box-shadow: none; }

.cel-sub { font-size: 12px; color: var(--texto-suave); }
.cel-sub code { background: var(--fundo); padding: 1px 5px; border-radius: 5px; }

/* ---------- Select pesquisável ---------- */
.combo { position: relative; }
/* O select segue no DOM (valor enviado no formulário), mas fora da tela */
.combo .combo-oculto { display: none; }
.combo-campo {
  width: 100%;
  font: inherit;
  font-size: 16px; /* evita zoom no iOS */
  padding: 10px 12px;
  border: 1px solid var(--borda);
  border-radius: 10px;
  /* Seta igual à dos selects: o campo se parece com uma lista, não com uma busca */
  background: #fff url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235B6B64' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E") no-repeat right 10px center;
  background-size: 18px;
  padding-right: 34px;
  color: var(--texto);
  cursor: pointer;
}
.combo-campo:focus { cursor: text; }
.combo-campo::placeholder { color: #9aa8a1; }
.combo-campo:focus { outline: 2px solid var(--verde); border-color: var(--verde); }
.combo-lista {
  position: absolute;
  top: calc(100% + 4px);
  left: 0; right: 0;
  background: #fff;
  border: 1px solid var(--borda);
  border-radius: 10px;
  box-shadow: 0 10px 30px rgba(19,40,30,.18);
  max-height: 260px;
  overflow-y: auto;
  z-index: 70;
  padding: 5px;
  -webkit-overflow-scrolling: touch;
}
.combo-item {
  display: block;
  width: 100%;
  text-align: left;
  font: inherit;
  font-size: 14px;
  padding: 12px;        /* ~45px de altura: alvo confortável no toque */
  border-radius: 8px;
  cursor: pointer;
  color: var(--texto);
}
.combo-item:hover, .combo-item.destacado { background: var(--fundo); }
.combo-item.ativo { background: #E6F4EC; color: var(--verde-escuro); font-weight: 600; }
.combo-sem-itens { padding: 12px; font-size: 13px; color: var(--texto-suave); }

/* Grade de checkboxes (ex.: empresas de acesso) */
.checkbox-grade { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 6px 14px; }
.chk-item { display: flex; align-items: center; gap: 7px; font-size: 14px; font-weight: 500; cursor: pointer; padding: 4px 0; }
.chk-item input { width: 16px; height: 16px; flex: none; }

/* ---------- Badges ---------- */
.badge {
  display: inline-block;
  font-size: 12px;
  font-weight: 700;
  padding: 3px 10px;
  border-radius: 999px;
  white-space: nowrap;
}
.badge-analise  { background: #FFF3CC; color: #7A5D00; }
.badge-aprovado { background: #E6F4EC; color: #0A5530; }
.badge-rejeitado{ background: #FBEAE8; color: #92271B; }
.badge-enviado  { background: #E4E8F7; color: #28357A; }
/* Fretes no fluxo de faturamento: o azul indica "a caminho do financeiro" e o
   verde cheio marca o fim da linha, distinguindo-o do verde claro de aprovado. */
.badge-em-fechamento { background: #E4E8F7; color: #28357A; }
.badge-fechado       { background: var(--verde); color: var(--branco); }
.badge-ativo    { background: #E6F4EC; color: #0A5530; }
/* Excluído convive com Rejeitado na mesma coluna do histórico, e dois tons
   claros vizinhos viram a mesma mancha em texto de 12px. Por isso ele é
   preenchimento sólido, como o "Fechamento concluído": grafite com texto
   branco (10,1:1), a 305 de distância do rosa do Rejeitado. */
.badge-excluido { background: #3A4440; color: var(--branco); }
/* ---------- Controle segmentado (escolha entre poucas opções) ----------
   Por baixo são <input type="radio">: o visual muda, o comportamento é o
   nativo — envia sem JS, anda com as setas do teclado e é anunciado como
   grupo de opções. O input fica por cima, transparente, para continuar
   sendo ele quem recebe o clique e o foco. */
.segmentado {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 6px;
  background: var(--fundo);
  border: 1px solid var(--borda);
  border-radius: 14px;
}
.seg-opcao { position: relative; flex: 1 1 180px; margin: 0; }
.seg-opcao input {
  position: absolute; inset: 0; width: 100%; height: 100%;
  margin: 0; opacity: 0; cursor: pointer;
}
.seg-opcao span {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 44px; padding: 10px 16px;
  border-radius: 10px;
  background: transparent;
  color: var(--texto-suave);
  font-size: 15px; font-weight: 600; line-height: 1.25;
  text-align: center;
  transition: background .15s ease, color .15s ease;
}
.seg-opcao span svg { width: 18px; height: 18px; flex: none; }
.seg-opcao:hover span { background: rgba(13,107,60,.08); color: var(--texto); }
/* Marcada: preenchimento sólido — a diferença não é só de cor, é de peso. */
.seg-opcao input:checked + span {
  background: var(--verde);
  color: #fff;
  box-shadow: var(--sombra);
}
.seg-opcao input:focus-visible + span { outline: 2px solid var(--verde-escuro); outline-offset: 2px; }
.seg-opcao input:disabled + span { opacity: .5; cursor: not-allowed; }
/* Fornecedor de material transportado: o mesmo azul do "em fechamento",
   que já é o tom de "classificação", não de "situação". */
.badge-material { background: #E4E8F7; color: #28357A; }
.badge-inativo  { background: #ECEFF0; color: #5B6B64; }

/* ---------- KPIs / Dashboard ---------- */
.kpis { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 16px; }
.kpi {
  background: var(--branco);
  border: 1px solid var(--borda);
  border-radius: var(--raio);
  padding: 14px;
  box-shadow: var(--sombra);
}
.kpi .kpi-rotulo { font-size: 12px; font-weight: 600; color: var(--texto-suave); text-transform: uppercase; letter-spacing: .04em; }
.kpi .kpi-valor { font-size: 22px; font-weight: 800; margin-top: 2px; }
.kpi.kpi-destaque { border-top: 3px solid var(--amarelo); }
/* Flex em vez de separadores "·" escritos no HTML: com cinco status a linha
   quebra, e o separador sobrava órfão no início da linha de baixo. */
.kpi-detalhe { display: flex; flex-wrap: wrap; gap: 1px 10px; font-size: 12px; font-weight: 600; margin-top: 4px; line-height: 1.6; }
.kpi-detalhe b { font-weight: 800; }
/* As cores acompanham os badges de status do frete, para o card e a lista de
   fretes contarem a mesma história. "Em análise" saiu do azul justamente para
   liberá-lo a "em fechamento" — dois azuis lado a lado não se distinguem. */
.kpi-detalhe .det-analise { color: #7A5D00; }
.kpi-detalhe .det-aprovado { color: var(--verde); }
.kpi-detalhe .det-fechamento { color: var(--azul); }
.kpi-detalhe .det-concluido { color: var(--verde-escuro); }
.kpi-detalhe .det-reprovado { color: var(--vermelho); }
.grafico-caixa { position: relative; height: 280px; }

/* Grades de painéis (gráficos/tabelas): 1 coluna no celular */
.grade-paineis { display: grid; grid-template-columns: 1fr; gap: 16px; margin-bottom: 16px; }

/* ---------- Kanban ---------- */
.kanban { display: grid; grid-template-columns: 1fr; gap: 12px; }
.kanban-coluna {
  background: #ECF1EE;
  border-radius: var(--raio);
  padding: 10px;
  border-top: 4px solid var(--borda);
}
.kanban-coluna h3 { margin: 4px 6px 10px; font-size: 14px; text-transform: uppercase; letter-spacing: .04em; }
.kanban-coluna.analise  { border-top-color: var(--amarelo); }
.kanban-coluna.aprovado { border-top-color: var(--verde); }
.kanban-coluna.rejeitado{ border-top-color: var(--vermelho); }
.kanban-card[data-href] { cursor: pointer; }
.kanban-card[data-href]:hover { border-color: var(--verde); }
.kanban-card {
  background: #fff;
  border: 1px solid var(--borda);
  border-radius: 10px;
  padding: 12px;
  margin-bottom: 10px;
  box-shadow: var(--sombra);
  font-size: 14px;
}
.kanban-card .titulo { font-weight: 700; }
.kanban-card .meta { color: var(--texto-suave); font-size: 13px; margin: 4px 0; }
.kanban-card .valores { display: flex; gap: 12px; font-size: 13px; margin: 6px 0; }
.kanban-card .acoes { display: flex; gap: 8px; margin-top: 8px; }

/* ---------- Cards de frete (mobile / motorista) ---------- */
.frete-card {
  background: #fff;
  border: 1px solid var(--borda);
  border-radius: var(--raio);
  box-shadow: var(--sombra);
  padding: 14px;
  margin-bottom: 12px;
  display: block;
  color: inherit;
  text-decoration: none;
}
.frete-card .linha1 { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.frete-card .cliente { font-weight: 700; }
.frete-card .meta { color: var(--texto-suave); font-size: 13px; margin-top: 4px; }
.frete-card .rodape { display: flex; justify-content: space-between; margin-top: 8px; font-size: 14px; }
.frete-card .ganho { font-weight: 800; color: var(--verde); }

/* ---------- Anexos ---------- */
/* Documentos do fechamento: lista, não grade de miniaturas — o que identifica
   um boleto é o nome do arquivo, não uma prévia. */
.lista-documentos { list-style: none; margin: 10px 0 0; padding: 0; }
.lista-documentos li {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 12px;
  padding: 3px 0;
  border-bottom: 1px solid var(--borda);
}
.lista-documentos li:last-child { border-bottom: 0; }
/* O padding vertical leva o alvo de toque do nome a 44px */
.lista-documentos a { display: inline-block; padding: 10px 0; font-weight: 600; word-break: break-word; }
/* Empurra o botão para a direita, e o tamanho fica colado no nome */
.lista-documentos button { margin-left: auto; }

.anexos-grade { display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: 10px; }
.anexo-item {
  border: 1px solid var(--borda);
  border-radius: 10px;
  overflow: hidden;
  background: #fff;
  text-align: center;
  font-size: 12px;
  color: var(--texto-suave);
  text-decoration: none;
  display: block;
}
.anexo-item img { width: 100%; height: 90px; object-fit: cover; display: block; }
.anexo-item .anexo-pdf { height: 90px; display: flex; align-items: center; justify-content: center; font-size: 30px; background: #F7FAF8; }
.anexo-item .anexo-nome { padding: 6px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.anexo-item .anexo-remover { margin: 0 6px 8px; width: calc(100% - 12px); min-height: 36px; }
.anexos-resumo { margin: 8px 0 0; font-size: 13px; color: var(--texto-suave); }
.anexos-resumo .anexos-recusados { display: block; color: var(--vermelho); }

/* ---------- Diálogos ---------- */
dialog.dialogo {
  border: none;
  border-radius: var(--raio);
  box-shadow: 0 10px 40px rgba(0,0,0,.25);
  padding: 28px;
  width: min(720px, calc(100vw - 32px));
}
dialog.dialogo-largo { width: min(980px, calc(100vw - 32px)); }
dialog.dialogo::backdrop { background: rgba(15, 30, 22, .5); }
dialog.dialogo h2 { margin-top: 0; margin-bottom: 10px; font-size: 20px; }
/* Texto de apoio do diálogo: espaço para respirar antes do formulário */
dialog.dialogo > p { margin: 0 0 18px; font-size: 15px; line-height: 1.5; }

/* ---------- Login ---------- */
.login-pagina {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(160deg, var(--verde-escuro), var(--verde) 60%, #0E7A45);
  padding: 20px;
}
.login-caixa {
  background: #fff;
  border-radius: 16px;
  box-shadow: 0 20px 60px rgba(0,0,0,.3);
  width: min(400px, 100%);
  padding: 28px;
}
.login-caixa img { display: block; margin: 0 auto 18px; height: 52px; }
.login-caixa h1 { font-size: 18px; text-align: center; margin: 0 0 18px; }

/* ---------- Utilidades ---------- */
.texto-suave { color: var(--texto-suave); }
.texto-vencido { color: var(--vermelho); font-weight: 700; }

/* Alerta discreto (ex.: pendências fora do período) */
.alerta-aviso {
  display: flex; align-items: center; gap: 10px;
  background: #FFF6E6; border: 1px solid #F5D9A8; color: #8A5A00;
  border-radius: 10px; padding: 10px 14px; margin-bottom: 14px;
  font-size: 14px; font-weight: 600;
}
.alerta-aviso svg { width: 20px; height: 20px; flex: none; color: #E28A00; }
.texto-direita { text-align: right; }
.sem-registros { text-align: center; color: var(--texto-suave); padding: 30px 10px; }
.resumo-ganhos { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 14px; }

/* ---------- Telas maiores ---------- */
@media (min-width: 720px) {
  .form-grade { grid-template-columns: 1fr 1fr; }
  .form-grade .campo-cheio { grid-column: 1 / -1; }
  /* auto-fit no lugar de 4 colunas fixas: nas telas com um único filtro, as
     colunas vazias sumiam e o campo continuava com 1/4 da largura — estreito
     demais para o texto de ajuda, que era cortado no meio. Agora as colunas
     sem conteúdo colapsam e o campo ocupa o espaço livre. */
  .filtros { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
  .filtros .form-acoes { grid-column: auto; }
  /* auto-fit, e não 4 colunas fixas, pelo mesmo motivo dos filtros logo acima:
     com 4 fixas a tela de 2 cards (Fechamentos, registro de frete) deixaria
     metade da linha vazia e os cards com 1/4 da largura. Assim os quatro do
     Contas a Receber cabem numa linha só e as telas menores continuam
     preenchendo o espaço. */
  .kpis { grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); }
  .resumo-ganhos { grid-template-columns: repeat(3, 1fr); }
}
@media (min-width: 1000px) {
  .kanban { grid-template-columns: 1fr 1fr 1fr; align-items: start; }
  .conteudo { padding: 24px; }
  .grade-paineis { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
}

/* ---------- Financeiro: lançamentos de baixa dentro da linha do título ---------- */
.detalhe-baixas { margin-top: 6px; }
.detalhe-baixas > summary { font-size: 12px; color: var(--texto-suave); cursor: pointer; padding: 4px 0; }
.lista-baixas { list-style: none; margin: 4px 0 0; padding: 0; font-size: 12.5px; }
.lista-baixas li {
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px;
  padding: 6px 0; border-top: 1px solid var(--borda);
}
/* Cada lançamento ocupa duas linhas: os dados na primeira, quem registrou na
   segunda. Por isso o item empilha e o flex vive na .baixa-linha. */
.lista-baixas li { flex-direction: column; align-items: stretch; gap: 2px; }
.baixa-linha { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; }
/* O estorno é ação destrutiva: fica à direita, longe do texto que se lê */
.baixa-linha > button { margin-left: auto; }

/* Âmbar, não amarelo: #7A5D00 dá 6,2:1 sobre branco; o #FFC629 da marca
   reprova como cor de texto. */
.baixa-ajuste { color: var(--ambar); font-weight: 600; }
.baixa-registro { font-size: 12.5px; color: var(--texto-suave); }

/* Linha de apoio do card: a diferença entre o que foi cobrado e o que entrou */
.kpi .kpi-nota { font-size: 13px; color: var(--texto-suave); margin-top: 2px; }

/* ---------- Diálogo de baixa: contexto da parcela e total calculado ---------- */

/* Quem lança precisa saber de qual fechamento e parcela se trata ANTES de
   digitar valor — daí o bloco ficar acima do formulário, e não num parágrafo
   corrido, onde os quatro dados se misturavam numa frase só. */
.baixa-contexto {
  display: grid; gap: 4px;
  background: var(--fundo); border-radius: var(--raio);
  padding: 10px 12px; margin-bottom: 14px;
}
.baixa-contexto > div { display: flex; flex-wrap: wrap; gap: 4px 10px; justify-content: space-between; }
.baixa-contexto-rotulo { color: var(--texto-suave); }

/* Os três valores lado a lado no desktop, empilhados no celular: são a mesma
   conta e ler um sem os outros não diz nada. */
.baixa-valores { display: grid; grid-template-columns: 1fr; gap: 12px; }
@media (min-width: 620px) {
  .baixa-valores { grid-template-columns: 1fr 1fr 1fr; }
}

/* O total é o número que se confere contra o extrato: maior que os campos e
   com borda de 2px (6,6:1 contra o branco, acima do piso de 3:1 para borda). */
.baixa-total {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px;
  border: 2px solid var(--verde); border-radius: var(--raio);
  padding: 10px 12px; background: var(--fundo);
}
.baixa-total-rotulo { font-weight: 600; color: var(--texto); }
.baixa-total-valor { font-size: 22px; font-weight: 800; color: var(--verde); }
.baixa-total-conta { font-size: 13px; color: var(--ambar); font-weight: 600; }
/* Houve ajuste: a conta aparece por extenso ao lado, nunca só a cor mudando */
.baixa-total-ajustado { border-color: var(--ambar); }
.baixa-total-ajustado .baixa-total-valor { color: var(--ambar); }
/* Inválido é anunciado por texto na própria caixa (ver baixa-total-conta no JS)
   e pelo balão de validação do navegador — a borda vermelha é reforço. */
.baixa-total-invalido { border-color: var(--vermelho); }
.baixa-total-invalido .baixa-total-valor,
.baixa-total-invalido .baixa-total-conta { color: var(--vermelho); }

/* ---------- Título com edição restrita (veio de um fechamento) ---------- */

/* Diz o que o formulário não vai aceitar, e por quê. Campo travado sem
   explicação faz a pessoa insistir até achar que o sistema quebrou. */
.aviso-travado {
  margin: 0 0 14px;
  padding: 10px 12px;
  border: 1px solid var(--ambar-borda);
  border-radius: var(--raio);
  background: var(--ambar-fundo);
  color: var(--ambar);
  font-size: 14px;
  line-height: 1.45;
}

/* O valor continua legível (14:1 sobre este fundo): ele é a referência que se
   quer consultar, não um campo desligado. O que muda é o convite a digitar. */
.campo-travado input,
.campo-travado select,
.campo-travado .combo-campo {
  background: var(--fundo);
  cursor: not-allowed;
}
/* O rótulo avisa da trava por texto, e não só pelo tom do campo. Serve aos dois
   motivos de travar (veio do fechamento, ou a parcela já foi quitada); o aviso
   no topo do diálogo é que diz qual deles é. */
.campo-travado > label::after {
  content: " (não editável)";
  font-weight: 400;
  color: var(--texto-suave);
}

/* CEP + Endereço na mesma linha: o CEP tem largura fixa por natureza (9
   caracteres) e ocupava metade da linha à toa, empurrando o endereço para uma
   linha só dele. Uma coluna para o CEP, três para o endereço.
   No celular volta a empilhar, como todo o formulário. */
.campos-cep-endereco { display: grid; grid-template-columns: 1fr; gap: 12px; }
@media (min-width: 720px) {
  .campos-cep-endereco { grid-template-columns: 1fr 3fr; }
}

/* Validade a vencer: o badge repete o amarelo sólido do selo HOMOLOGAÇÃO
   (decisão do usuário, 2026-08-19) — o laranja anterior ficava perto demais
   do vermelho de vencido para diferenciar de relance. O texto usa o âmbar
   da paleta: o amarelo puro reprova como cor de texto. */
.texto-a-vencer { color: var(--ambar); font-weight: 700; }
.badge-a-vencer { background: var(--amarelo); color: var(--preto); }
