/* ==========================================================================
   COMPONENTES — o padrão de elementos do Hórus.

   Depende de `tokens.css`, que precisa ser carregado ANTES deste arquivo.

   ---------------------------------------------------------------------------
   ESTE ARQUIVO NÃO MUDA NENHUMA TELA EXISTENTE

   De propósito. Todo seletor aqui começa com `.hrs-`, um prefixo que hoje não
   aparece em nenhum template. Nada é reaproveitado de `.btn`, `.card` ou
   `.modal`, então incluir este CSS no sistema tem efeito visual ZERO até que
   alguém escreva a classe nova num template.

   A repintura dos componentes que já existem (os 204 `btn-primary` passando a
   usar a cor da marca) é uma mudança visível e entra junto com a adoção no
   CRM, não aqui.

   ---------------------------------------------------------------------------
   POR QUE CLASSE NOVA E NÃO MAIS UMA `botao_*`

   O sistema já tem dois vocabulários de botão convivendo: os 866 `.btn` do
   Bootstrap e 16 classes `botao_*` nossas (`botao_acao` 39 usos,
   `botao_voltar_acao` 24, `botao_direito` 18...), sem regra escrita de quando
   usar cada uma. Criar uma terceira família sem um plano de convergência só
   pioraria isso.

   O plano é o contrário: `.hrs-*` é o destino. À medida que cada módulo for
   padronizado, as `botao_*` daquele módulo somem. Elas não ganham alias aqui
   porque alias é o que faz vocabulário velho sobreviver para sempre.

   ---------------------------------------------------------------------------
   ÍNDICE
      1. Botões
      2. Cards
      3. Cabeçalho de modal (a "caixinha de ícone")
      4. Confirmação
      5. Etiquetas
      6. Estado vazio
      7. Campo obrigatório
      8. Modal
      9. Feedback (SweetAlert)
     10. Campo de formulário
     11. Botões do Bootstrap — repintura e forma
     12. .campo-vazio — a marca de erro que o JS legado usa
     13. Avatar
     14. Link
   ========================================================================== */


/* ==========================================================================
   1. BOTÕES
   ========================================================================== */

.hrs-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--esp-2);

  /* 2.375rem = 38px, a mesma altura que o `.btn` do Bootstrap resolve com
     padding + line-height. Os dois vão conviver enquanto os módulos são
     convertidos; 2px de diferença aparecem quando ficam na mesma linha. */
  height: 2.375rem;
  padding: 0 var(--esp-4);
  border: 1px solid transparent;
  border-radius: var(--raio-xl);

  font-size: var(--fonte-md);
  font-weight: var(--peso-medio);
  line-height: 1;
  white-space: nowrap;
  text-decoration: none;

  cursor: pointer;
  transition: background-color var(--transicao-rapida),
              border-color var(--transicao-rapida),
              color var(--transicao-rapida);
}

/* O anel de foco não é enfeite: é como quem navega por teclado sabe onde
   está. `:focus-visible` mostra para o teclado sem poluir o clique de mouse. */
.hrs-btn:focus-visible {
  outline: none;
  box-shadow: var(--sombra-foco);
}

.hrs-btn:disabled,
.hrs-btn.hrs-btn-desabilitado {
  opacity: .55;
  cursor: not-allowed;
  pointer-events: none;
}

/* --- variantes de intenção --------------------------------------------- */

.hrs-btn-primario {
  background-color: var(--cor-primaria);
  color: #fff;
}
.hrs-btn-primario:hover  { background-color: var(--cor-primaria-hover); color: #fff; }
.hrs-btn-primario:active { background-color: var(--cor-primaria-ativa); }

/* Secundário = a ação que acompanha a primária ("Cancelar" ao lado de
   "Salvar"). Contorno, para não competir com ela. */
.hrs-btn-secundario {
  background-color: transparent;
  border-color: var(--cor-borda-forte);
  color: var(--cor-texto);
}
.hrs-btn-secundario:hover {
  background-color: var(--cor-superficie-alt);
  color: var(--cor-texto);
}

.hrs-btn-perigo {
  background-color: var(--cor-perigo);
  color: #fff;
}
.hrs-btn-perigo:hover  { background-color: var(--cor-perigo-hover); color: #fff; }

.hrs-btn-sucesso {
  background-color: var(--cor-sucesso);
  color: #fff;
}
.hrs-btn-sucesso:hover { background-color: var(--cor-sucesso-hover); color: #fff; }

/* Fantasma = ação terciária, discreta. Para "Ver mais", "Desfazer". */
.hrs-btn-fantasma {
  background-color: transparent;
  color: var(--cor-primaria);
}
.hrs-btn-fantasma:hover {
  background-color: var(--cor-primaria-suave);
  color: var(--cor-primaria-ativa);
}

/* Fantasma destrutivo = "apagar"/"tirar" que se repete linha a linha numa
   lista. O hrs-btn-perigo (vermelho cheio) em cada linha vira uma parede
   vermelha que grita mais que o conteúdo; aqui o vermelho fica só no ícone
   e no texto, e o fundo aparece no hover. Adicionado em 25/09/2026 para a
   biblioteca do estúdio da home. A confirmação continua obrigatória. */
.hrs-btn-fantasma-perigo {
  background-color: transparent;
  color: var(--cor-perigo-texto);
}
.hrs-btn-fantasma-perigo:hover {
  background-color: var(--cor-perigo-suave);
  color: var(--cor-perigo-texto);
}

/* --- tamanhos ----------------------------------------------------------- */

.hrs-btn-sm {
  height: 1.9375rem; /* = .btn-sm */
  padding: 0 var(--esp-3);
  font-size: var(--fonte-sm);
  border-radius: var(--raio-lg);
}

.hrs-btn-lg {
  height: 3rem; /* = .btn-lg */
  padding: 0 var(--esp-5);
  font-size: var(--fonte-lg);
}

/* Ocupa a linha toda. No celular esse costuma ser o padrão, não a exceção. */
.hrs-btn-bloco {
  display: flex;
  width: 100%;
}

/* Só ícone: quadrado, da altura do tamanho escolhido. Para a ação que se
   repete linha a linha (tirar, apagar, adicionar), onde o rótulo repetido
   vira ruído. Sem rótulo visível, `aria-label` (leitor de tela) e `title`
   (mouse) são OBRIGATÓRIOS. Adicionado em 25/09/2026 (estúdio da home).
     <button type="button" class="hrs-btn hrs-btn-sm hrs-btn-icone hrs-btn-secundario"
             aria-label="Pôr Placar na home" title="Pôr na home"><i class="fas fa-plus" aria-hidden="true"></i></button> */
.hrs-btn-icone { width: 2.375rem; padding: 0; }
.hrs-btn-sm.hrs-btn-icone { width: 1.9375rem; }
.hrs-btn-lg.hrs-btn-icone { width: 3rem; }
/* No celular o alvo de toque cresce para 36px, como o kebab das tabelas. */
@media (max-width: 575.98px) {
  .hrs-btn-sm.hrs-btn-icone { width: 2.25rem; height: 2.25rem; }
}

/* --- carregando ---------------------------------------------------------
   Estado que o sistema não tinha e fazia falta: hoje cada tela improvisa o
   seu (troca o texto, troca o ícone, desabilita e não avisa nada).
   Uso: adicionar a classe e deixar o texto no lugar; ele some sozinho.
   ------------------------------------------------------------------------ */
.hrs-btn-carregando {
  position: relative;
  color: transparent !important;
  pointer-events: none;
}
.hrs-btn-carregando::after {
  content: "";
  position: absolute;
  width: 1rem;
  height: 1rem;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: var(--raio-circulo);
  animation: hrs-girar .6s linear infinite;
  /* herda a cor do texto original da variante */
  color: #fff;
}
.hrs-btn-secundario.hrs-btn-carregando::after,
.hrs-btn-fantasma.hrs-btn-carregando::after { color: var(--cor-primaria); }

@keyframes hrs-girar { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  .hrs-btn-carregando::after { animation-duration: 2s; }
}


/* ==========================================================================
   2. CARDS
   ========================================================================== */

/* O card padrão é PLANO: borda, sem sombra.

   A escolha é de densidade. Numa etapa do funil aparecem vinte cards de uma
   vez; com sombra em todos, borda e sombra fazem o mesmo trabalho duas vezes
   e a lista fica pesada. Plano cabe mais na tela e lê melhor. */
.hrs-card {
  background: var(--cor-superficie);
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio-lg);
  overflow: hidden;
  /* Mesmo respiro do .card do AdminLTE (1rem). Sem isso, um hrs-card usado
     sozinho (sem a classe .card) encosta no de baixo — aconteceu na tela do
     negócio em 03/09. Numa lista com gap, zere com mb-0. */
  margin-bottom: 1rem;
}

/* Elevado: só para o que FLUTUA sobre a página — menu suspenso, painel de
   filtro, card sendo arrastado. Sombra aqui tem função: dizer que aquilo está
   numa camada acima. Card de lista não leva. */
.hrs-card-elevado { box-shadow: var(--sombra-md); }

/* Card clicável. Só use quando o card INTEIRO leva a um lugar; se só um
   pedaço é clicável, o cursor de mão no resto é mentira.

   O destaque do hover é a BORDA, não um pulo do card: num card plano, mover
   o elemento chama mais atenção do que o necessário e atrapalha quem está
   percorrendo uma lista com o mouse. */
.hrs-card-clicavel {
  cursor: pointer;
  transition: border-color var(--transicao-rapida), box-shadow var(--transicao-rapida);
}
.hrs-card-clicavel:hover {
  border-color: var(--cor-primaria);
  box-shadow: var(--sombra-sm);
}

/* A LINHA DIVISÓRIA é intencional (opção A, escolhida em 28/08/2026). Foi
   comparada com um cabeçalho sem linha e com um com faixa de cor à esquerda;
   ficou a linha, que é o que os 144 cabeçalhos do sistema já usam via
   AdminLTE. Trocar isso seria muito churn para pouco ganho, e a faixa de cor
   só se pagaria se existissem TIPOS de card de verdade — hoje não existem.

   Quando existirem, a faixa já está pronta em `.hrs-card-faixa-*` acima. */
.hrs-card-cab {
  display: flex;
  align-items: center;
  gap: var(--esp-3);
  padding: var(--esp-3) var(--esp-4);
  border-bottom: 1px solid var(--cor-borda);
  font-weight: var(--peso-forte);
  color: var(--cor-texto);
}

/* Ferramentas do cabeçalho (minimizar, fechar, menu) — 20 dos 144 cabeçalhos
   têm. Vão para a direita sozinhas, sem precisar de `ml-auto` no HTML. */
.hrs-card-cab-ferramentas {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: var(--esp-1);
  color: var(--cor-texto-suave);
}

/* O ícone do cabeçalho usa a cor da marca; o título continua no cinza-texto.
   Isso dá o ponto de cor sem transformar o título inteiro em link.

   As duas sintaxes do Font Awesome entram na lista. Ate 04/09/2026 so `fas`,
   `far` e `fab` estavam aqui, entao todo cabecalho escrito na sintaxe do FA6
   (`fa-solid`, `fa-regular`) ficava com o icone PRETO — 9 cards da tela do
   negocio (Grupo, Cliente, Contato, Pedido, Reparos, Subnegocios, Logistica)
   estavam assim, ao lado de outros azuis na mesma coluna. */
.hrs-card-cab > .fas,
.hrs-card-cab > .far,
.hrs-card-cab > .fab,
.hrs-card-cab > .fa-solid,
.hrs-card-cab > .fa-regular,
.hrs-card-cab > .fa-brands { color: var(--cor-primaria); }

.hrs-card-corpo   { padding: var(--esp-4); }

.hrs-card-rodape {
  padding: var(--esp-3) var(--esp-4);
  border-top: 1px solid var(--cor-borda);
  background: var(--cor-superficie-alt);
}

/* Faixa de cor à esquerda, para dar estado ao card sem pintar o fundo
   inteiro (fundo colorido cansa a vista numa lista longa). */
.hrs-card-faixa-primaria { border-left: 3px solid var(--cor-primaria); }
.hrs-card-faixa-sucesso  { border-left: 3px solid var(--cor-sucesso); }
.hrs-card-faixa-perigo   { border-left: 3px solid var(--cor-perigo); }
.hrs-card-faixa-aviso    { border-left: 3px solid var(--cor-aviso); }


/* ==========================================================================
   3. CABEÇALHO DE MODAL

   O Hórus já tinha um padrão de cabeçalho de modal bonito e reconhecível: um
   ícone dentro de uma caixinha de fundo claro, ao lado do título. O problema
   é que ele existia como HTML copiado, com os valores escritos à mão em
   `style=` — `background-color: #EEF3FF; border-radius: 5px;` repetido a cada
   novo modal, e a cor do ícone repetida junto.

   Aqui ele vira classe, e a cor passa a ser a da intenção do modal: azul para
   informação, vermelho para exclusão, verde para confirmação.
   ========================================================================== */

.hrs-modal-cab {
  display: flex;
  align-items: center;
  gap: var(--esp-3);
}

.hrs-modal-cab-icone {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: var(--raio-md);
  font-size: var(--fonte-lg);

  /* padrão: informação */
  background-color: var(--cor-primaria-suave);
  color: var(--cor-primaria);
}

.hrs-modal-cab-icone-perigo  { background-color: var(--cor-perigo-suave);  color: var(--cor-perigo); }
.hrs-modal-cab-icone-sucesso { background-color: var(--cor-sucesso-suave); color: var(--cor-sucesso); }
.hrs-modal-cab-icone-aviso   { background-color: var(--cor-aviso-suave);   color: var(--cor-aviso-texto); }

/* Dois seletores de propriedade: o <h5> tambem carrega `.modal-title` (ver o
   include), e ha paginas do sistema que estilizam essa classe. Com dois
   seletores a nossa regra vence sem depender da ordem de carregamento. */
.hrs-modal-cab .hrs-modal-cab-titulo {
  margin: 0;
  font-size: var(--fonte-xl);
  font-weight: var(--peso-forte);
  color: var(--cor-texto);
}

/* Linha de apoio abaixo do título, quando o modal precisa explicar algo antes
   do corpo ("Cliente e contatos são copiados do negócio 4821"). */
.hrs-modal-cab-apoio {
  margin: 2px 0 0;
  font-size: var(--fonte-sm);
  color: var(--cor-texto-suave);
}

/* Cabeçalho com mais coisa além do X — um botão "Como usar", um interruptor
   CIF/FOB, um aviso de pedido zerado. Tudo isso vai num único bloco encostado
   à direita, junto do X. Sem o bloco, dois `margin-left: auto` (o do botão e
   o do X) dividiriam o espaço livre e o botão ficaria boiando no meio. */
.hrs-modal-cab-acoes {
  display: flex;
  align-items: center;
  flex: 0 0 auto;
  gap: var(--esp-2);
  margin-left: auto;
}


/* ==========================================================================
   4. CONFIRMAÇÃO

   O padrão de "tem certeza?". Hoje cada tela resolve de um jeito — umas com
   modal próprio, outras com o SweetAlert, outras com `confirm()` do navegador.

   Duas regras de conteúdo que valem mais que o CSS:

   - O botão diz o que VAI ACONTECER, não "Sim". "Excluir negócio" é honesto;
     "Sim" obriga a pessoa a reler a pergunta para saber o que está clicando.
   - Ação destrutiva usa a variante de perigo E fica à direita, na posição que
     o resto do sistema usa para a ação principal. Esconder o botão perigoso
     não protege ninguém; deixar claro o que ele faz, sim.
   ========================================================================== */

.hrs-confirm-corpo {
  padding: var(--esp-5) var(--esp-5) var(--esp-4);
  text-align: center;
}

.hrs-confirm-icone {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3.5rem;
  height: 3.5rem;
  margin-bottom: var(--esp-3);
  border-radius: var(--raio-circulo);
  font-size: 1.5rem;

  background-color: var(--cor-perigo-suave);
  color: var(--cor-perigo);
}
.hrs-confirm-icone-aviso { background-color: var(--cor-aviso-suave); color: var(--cor-aviso-texto); }
.hrs-confirm-icone-info  { background-color: var(--cor-primaria-suave); color: var(--cor-primaria); }

.hrs-confirm-titulo {
  margin: 0 0 var(--esp-2);
  font-size: var(--fonte-xl);
  font-weight: var(--peso-forte);
  color: var(--cor-texto);
}

/* Aqui vai a consequência, não a repetição do título. Ex.: "Os 12 anexos
   deste negócio também serão removidos." */
.hrs-confirm-texto {
  margin: 0;
  font-size: var(--fonte-md);
  color: var(--cor-texto-suave);
}

.hrs-confirm-acoes {
  display: flex;
  justify-content: flex-end;
  gap: var(--esp-2);
  padding: var(--esp-3) var(--esp-5) var(--esp-5);
}

/* No celular os dois botões ocupam a linha inteira e a ação principal fica
   EM CIMA, mais perto do polegar. */
@media (max-width: 575.98px) {
  .hrs-confirm-acoes {
    flex-direction: column-reverse;
    padding-left: var(--esp-4);
    padding-right: var(--esp-4);
  }
  .hrs-confirm-acoes .hrs-btn { width: 100%; }
}


/* ==========================================================================
   5. ETIQUETAS
   ========================================================================== */

.hrs-etiqueta {
  display: inline-flex;
  align-items: center;
  gap: var(--esp-1);
  padding: 2px var(--esp-2);
  border-radius: var(--raio-pilula);
  font-size: var(--fonte-xs);
  font-weight: var(--peso-forte);
  line-height: 1.5;
  white-space: nowrap;
}

.hrs-etiqueta-primaria { background: var(--cor-primaria-suave); color: var(--cor-primaria-ativa); }
.hrs-etiqueta-sucesso  { background: var(--cor-sucesso-suave);  color: var(--cor-sucesso-texto); }
.hrs-etiqueta-perigo   { background: var(--cor-perigo-suave);   color: var(--cor-perigo-texto); }
.hrs-etiqueta-aviso    { background: var(--cor-aviso-suave);    color: var(--cor-aviso-texto); }
.hrs-etiqueta-info     { background: var(--cor-info-suave);     color: var(--cor-info-texto); }
/* escala de urgência em 4 níveis (sucesso → aviso → laranja → perigo); não é intenção de ação */
.hrs-etiqueta-laranja  { background: var(--cor-laranja-suave);  color: var(--cor-laranja-texto); }
/* texto no cinza MÉDIO: o suave sobre a superfície alternativa dá 4,45:1, logo abaixo do mínimo de 4,5:1 (24/09/2026) */
.hrs-etiqueta-neutra   { background: var(--cor-superficie-alt); color: var(--cor-texto-medio); }

/* --- cor que vem do banco ------------------------------------------------
   A etapa do funil tem a cor gravada no banco e escolhida pelo usuário na
   tela — nossa paleta não consegue prever qual é.

   O que existia: `style="color:white;background-color:{{ etapa.cor }}"`, com
   o branco FIXO seja qual for a cor. Das 102 etapas cadastradas, 93 ficavam
   abaixo do mínimo de contraste de 4,5:1; a pior (#FBD965) dava 1,38:1 —
   texto branco sobre amarelo, praticamente ilegível. E como a cor é escolhida
   na tela, cada etapa nova podia repetir o problema.

   Aqui a cor vira um PONTO (opção C, escolhida em 28/08/2026) e o texto fica
   sempre no cinza legível. Perde-se destaque: numa tabela longa a etapa não
   salta mais aos olhos como um bloco de cor. Ganha-se que funciona com
   qualquer cor, sem cálculo nenhum e sem depender de quem cadastrou.

   USO  <span class="hrs-etiqueta hrs-etiqueta-cor"
              style="--hrs-etiqueta-cor: {{ etapa.cor|cor_hex }}">{{ etapa }}</span>

   Passe SEMPRE pelo filtro `cor_hex`: ele deixa passar só `#rgb`/`#rrggbb`.
   Sem ele, o conteúdo do banco entra cru num atributo `style`. */
.hrs-etiqueta-cor {
  background: var(--cor-superficie-alt);
  color: var(--cor-texto-medio);
}

.hrs-etiqueta-cor::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: var(--raio-circulo);
  background: var(--hrs-etiqueta-cor, var(--cor-texto-fraco));
  flex: 0 0 auto;
}

/* --- contador ------------------------------------------------------------
   Ícone + número (opção A, escolhida em 28/08/2026) — é o formato que o card
   do funil já usava, mas escrito à mão em cada um dos quatro contadores, com
   padding, borda e sombra em `style=`.

   Cabe quatro numa coluna de 250px, que era o requisito. Em compensação
   depende do ícone para dizer o que o número é, então o `title` NÃO é
   opcional: use o `components/contador.html`, que obriga o rótulo. */
.hrs-etiqueta-contador {
  padding: 3px var(--esp-2);
  /* numeral tabular: o contador não muda de largura quando o número troca de
     9 para 10, senão a fila inteira dança a cada atualização. */
  font-variant-numeric: tabular-nums;
}


/* ==========================================================================
   6. ESTADO VAZIO

   Levantamento no CRM: 16 lugares dizem "não há nada aqui", em três
   tratamentos diferentes. Um deles usa `alert alert-danger` — uma caixa
   VERMELHA DE ERRO — para dizer "Nenhum negócio vinculado a esse contato",
   que é uma situação perfeitamente normal. Outro usa `alert-info` para o
   mesmo caso, e um terceiro é um `<td colspan="4">` com texto solto.

   Lista vazia não é erro. O componente é neutro de propósito.

   Duas regras de conteúdo:
   - O título diz o que não tem, na linguagem do usuário: "Nenhum negócio
     por aqui", não "Sem registros".
   - A linha de apoio explica QUANDO aparece algo ali. É a diferença entre
     a pessoa achar que quebrou e entender que ainda não preencheu.
   ========================================================================== */

.hrs-vazio {
  padding: var(--esp-6) var(--esp-4);
  text-align: center;
  color: var(--cor-texto-suave);
}

.hrs-vazio-icone {
  display: block;
  margin-bottom: var(--esp-3);
  font-size: 1.9rem;
  /* cinza mais claro que o texto: o ícone ambienta, não informa. Fica cru
     de propósito: o token mais próximo (--cor-texto-fraco) é mais escuro e
     deixaria o ícone competindo com o texto. */
  color: #c9d1da;
}

.hrs-vazio-titulo {
  margin: 0 0 var(--esp-1);
  font-size: var(--fonte-lg);
  font-weight: var(--peso-forte);
  color: var(--cor-texto);
}

.hrs-vazio-texto {
  margin: 0;
  font-size: var(--fonte-md);
}

/* Espaço para o botão, quando existe uma ação óbvia ("criar o primeiro"). */
.hrs-vazio-acao { margin-top: var(--esp-4); }

/* Variante compacta: dentro de aba ou painel curto, onde o bloco inteiro
   não cabe. Mesmo vocabulário, uma linha só. */
.hrs-vazio-compacto {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--esp-2);
  padding: var(--esp-3) var(--esp-4);
  border: 1px dashed var(--cor-borda);
  border-radius: var(--raio-lg);
  font-size: var(--fonte-md);
  text-align: left;
}
.hrs-vazio-compacto .hrs-vazio-icone {
  display: inline;
  margin: 0;
  font-size: var(--fonte-lg);
}


/* ==========================================================================
   7. CAMPO OBRIGATÓRIO

   Hoje é `<b style="color:red;">*</b>` escrito à mão: 22 vezes só no CRM,
   41 no sistema. O vermelho puro (#ff0000) não é nenhuma cor da paleta e é
   mais forte que o próprio vermelho de erro — o formulário parece já estar
   com problema antes de a pessoa digitar.

   Mesma marca de sempre, agora na cor de perigo da paleta e com nome.
   ========================================================================== */

.hrs-obrigatorio {
  color: var(--cor-perigo);
  font-weight: var(--peso-forte);
  margin-left: 2px;
}


/* ==========================================================================
   8. MODAL

   O Bootstrap 4 já desenha a caixa, o fundo e o comportamento. O que falta
   é o miolo: cabeçalho e rodapé consistentes. São 34 modais só no CRM, em
   8 variações de `modal-header` — 27 com cabeçalho branco e 7 com faixa
   colorida (`bg-info`, `bg-danger`, `bg-success`), sem regra de quando usar
   cada um. Fica o cabeçalho branco com caixinha de ícone; a faixa colorida
   sai, porque manter os dois é manter o problema.

   Use junto das classes do Bootstrap:
     <div class="modal-dialog modal-dialog-centered">
       <div class="modal-content">
         <div class="modal-header hrs-modal-cab"> … </div>
         <div class="modal-body"> … </div>
         <div class="modal-footer hrs-modal-rod"> … </div>
   ========================================================================== */

/* O `.modal-header` do Bootstrap usa `align-items: flex-start`, que
   desalinha o ícone em relação ao título, e `justify-content: space-between`.
   O space-between só parecia inofensivo porque o `margin-left: auto` do X
   absorvia o espaço livre antes de ele ser distribuído; num modal SEM o X
   (`sem_fechar`) não há margem auto nenhuma e o título ia parar na borda
   direita — visto no `modalValidacaoSenior`, que abre em toda página.
   O `flex-start` tira essa dependência: título junto do ícone sempre, e o X,
   quando existe, continua indo para a direita pela própria margem auto. */
.modal-header.hrs-modal-cab { align-items: center; justify-content: flex-start; }

/* O X de fechar — botão circular.

   Dois problemas resolvidos aqui, os dois vistos no render, não deduzidos:

   1. O Bootstrap aplica `.modal-header .close { margin: -1rem -1rem -1rem auto }`
      (adminlte.css:6103). Essa margem negativa puxa o botão para FORA da caixa
      de padding do cabeçalho. No original os 1rem de padding compensavam; ao
      trocar o padding sem zerar a margem, o X saía do alinhamento e encostava
      no canto. Por isso o `margin: 0 0 0 auto` — o `auto` só na esquerda
      mantém o botão encostado à direita, dentro do padding.

   2. O alvo de toque. Como ícone solto o X tinha ~26px de área clicável, o que
      é apertado no celular. O círculo de 2rem dá 32px e, com o fundo no hover,
      deixa claro que aquilo é um botão e não um enfeite. */
.hrs-modal-cab .close,
.hrs-modal-cab .hrs-modal-fechar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  margin: 0 0 0 auto;
  padding: 0;
  border: none;
  border-radius: var(--raio-circulo);
  background: transparent;
  color: var(--cor-texto-suave);
  font-size: 1.05rem;
  line-height: 1;
  cursor: pointer;
  /* o `.close` do Bootstrap nasce com opacity .5, que lavaria a cor */
  opacity: 1;
  transition: background-color var(--transicao-rapida), color var(--transicao-rapida);
}
.hrs-modal-cab .close:hover,
.hrs-modal-cab .hrs-modal-fechar:hover {
  background-color: var(--cor-hover-neutro);
  color: var(--cor-texto);
}
.hrs-modal-cab .close:focus-visible,
.hrs-modal-cab .hrs-modal-fechar:focus-visible {
  outline: none;
  box-shadow: var(--sombra-foco);
}

/* Rodapé: ações à direita, principal por último — a posição que o resto do
   sistema já usa. */
.modal-footer.hrs-modal-rod {
  justify-content: flex-end;
  gap: var(--esp-2);
}
/* O Bootstrap 4 dá margem a cada filho do modal-footer; com `gap` isso vira
   espaço dobrado. */
.modal-footer.hrs-modal-rod > * { margin: 0; }

/* Variante para modal destrutivo: afasta o Cancelar do botão de perigo, para
   dificultar o clique errado. */
.modal-footer.hrs-modal-rod-separado { justify-content: space-between; }

/* No celular as ações viram linha inteira, principal em cima. */
@media (max-width: 575.98px) {
  .modal-footer.hrs-modal-rod,
  .modal-footer.hrs-modal-rod-separado {
    flex-direction: column-reverse;
    align-items: stretch;
  }
  .modal-footer.hrs-modal-rod > .hrs-btn,
  .modal-footer.hrs-modal-rod-separado > .hrs-btn { width: 100%; }
}


/* ==========================================================================
   9. FEEDBACK (SweetAlert)

   O `feedback.js` desliga o estilo próprio de botão do SweetAlert
   (`buttonsStyling: false`) e usa os nossos `.hrs-btn`. Faltam então só os
   ajustes de espaço que o estilo dele fazia.
   ========================================================================== */

.hrs-swal {
  border-radius: var(--raio-lg);
}

/* Sem o estilo do SweetAlert, os botões ficam colados. */
.hrs-swal .swal2-actions {
  gap: var(--esp-2);
  margin-top: var(--esp-4);
}

/* O SweetAlert dá margem a cada botão; com `gap` vira espaço dobrado. */
.hrs-swal .swal2-actions > .hrs-btn { margin: 0; }

.hrs-swal .swal2-title {
  font-size: var(--fonte-xl);
  font-weight: var(--peso-forte);
  color: var(--cor-texto);
}

.hrs-swal .swal2-html-container {
  font-size: var(--fonte-md);
  color: var(--cor-texto-suave);
}

/* No celular as ações viram linha inteira, principal em cima — mesma regra do
   rodapé de modal e da confirmação. */
@media (max-width: 575.98px) {
  .hrs-swal .swal2-actions {
    flex-direction: column-reverse;
    align-items: stretch;
  }
  .hrs-swal .swal2-actions > .hrs-btn { width: 100%; }
}


/* ==========================================================================
   10. CAMPO DE FORMULÁRIO

   NÃO cria vocabulário novo. O Bootstrap 4 já traz `.is-invalid` e
   `.invalid-feedback`, e a regra que mostra a mensagem
   (`.is-invalid ~ .invalid-feedback { display: block }`) já está no
   adminlte.css. O sistema simplesmente nunca usou: em 39 templates do CRM
   havia ZERO ocorrências das duas. Era por isso que toda validação virava um
   `alert()` — não existia lugar para o erro aparecer.

   Aqui a gente só veste isso com os tokens e cobre o que o Bootstrap não
   cobre: o select2 e o campo dentro de input-group.

   Quem aplica e limpa é o `feedback.js` (Horus.campoErro / Horus.limparErros).
   ========================================================================== */

/* Mensagem de erro. O `display` continua vindo do Bootstrap. */
.invalid-feedback {
  margin-top: var(--esp-1);
  font-size: var(--fonte-sm);
  color: var(--cor-perigo);
}

/* Ícone antes da mensagem: quem tem dificuldade de distinguir vermelho
   precisa de outro sinal além da cor. */
.invalid-feedback::before {
  content: "\f06a"; /* fa-exclamation-circle */
  font-family: "Font Awesome 6 Free", "Font Awesome 5 Free";
  font-weight: 900;
  margin-right: 5px;
}

/* O Bootstrap desenha um ícone de exclamação DENTRO do campo, o que colide
   com a seta do <select> e com o ícone do select2. Fica só a borda. */
.form-control.is-invalid,
select.is-invalid,
textarea.is-invalid {
  border-color: var(--cor-perigo);
  background-image: none;
  padding-right: var(--esp-3);
}

/* Fundo levemente rosado: reforça o estado sem depender só da borda fina. */
.form-control.is-invalid,
textarea.is-invalid { background-color: var(--cor-perigo-suave); }

.form-control.is-invalid:focus,
select.is-invalid:focus,
textarea.is-invalid:focus {
  border-color: var(--cor-perigo);
  box-shadow: 0 0 0 .2rem rgba(220, 53, 69, .25);
}

/* select2 esconde o <select> real e desenha o seu próprio. Sem isto, o campo
   fica marcado no elemento invisível e o usuário não vê nada. */
select.is-invalid + .select2 .select2-selection {
  border-color: var(--cor-perigo) !important;
  background-color: var(--cor-perigo-suave);
}

/* Dentro de um input-group o feedback é irmão do `.input-group`, não do
   controle, então a regra do Bootstrap não alcança. */
.input-group.hrs-campo-erro ~ .invalid-feedback { display: block; }
.input-group.hrs-campo-erro .form-control { border-color: var(--cor-perigo); }

/* Linha de ajuda abaixo do campo — explica o formato ANTES de a pessoa errar,
   que é melhor que corrigir depois. */
.hrs-campo-dica {
  margin-top: var(--esp-1);
  font-size: var(--fonte-sm);
  color: var(--cor-texto-suave);
}

/* Com erro na tela, a dica sai. As duas dizem quase a mesma coisa ("use
   (11) 91234-5678" na dica e no erro), e ler a mesma instrução duas vezes,
   uma em cinza e outra em vermelho, só atrapalha quem está corrigindo. */
.is-invalid ~ .hrs-campo-dica,
.input-group.hrs-campo-erro ~ .hrs-campo-dica { display: none; }


/* ==========================================================================
   11. BOTÕES DO BOOTSTRAP — repintura e forma

   Decisão: cor + formato no sistema inteiro (não só no CRM).

   Antes disto o sistema usava DOIS azuis primários lado a lado sem ninguém
   ter decidido: `btn-primary` renderizava #007bff (Bootstrap 4) e
   `botao_acao` era #5788fd (base.css:667). Dois botões vizinhos, cores
   diferentes, na mesma tela.

   ---------------------------------------------------------------------------
   POR QUE SÓ RAIO E COR, E NÃO ALTURA/PADDING

   O `.btn` do Bootstrap já tem altura ~2.25rem (padding .375rem + line-height
   1.5), que é exatamente a do nosso `.hrs-btn`. A diferença visível entre o
   botão de hoje e o novo é o ARREDONDAMENTO. Mexer em altura e padding daria
   o mesmo resultado visual e quebraria muita coisa: são 849 botões, 90 deles
   dentro de `input-group` (onde a altura precisa casar com o campo), 54
   `btn-block`, 46 `btn-link`, 20 `btn-tool`, 20 `btn-circle` e 60 aplicados
   em `<a>` em vez de `<button>`.

   Então: raio + cor. Mesmo resultado, uma fração do risco.

   ---------------------------------------------------------------------------
   O QUE FICA DE FORA, E POR QUÊ

   - `.btn-circle` e `.btn-tool`: são botões de ícone, redondos ou sem forma.
   - `.btn-close`: é o X do Bootstrap 5, que não estilizamos.
   - Dentro de `.btn-group` e `.input-group` o Bootstrap zera os cantos
     internos para os controles se encaixarem. Nossa regra é mais específica
     e venceria, descolando os botões — por isso o encaixe é reafirmado
     explicitamente no fim desta seção.
   ========================================================================== */

/* --- cor ----------------------------------------------------------------- */

.btn-primary {
  background-color: var(--cor-primaria);
  border-color: var(--cor-primaria);
}
.btn-primary:hover {
  background-color: var(--cor-primaria-hover);
  border-color: var(--cor-primaria-hover);
}
.btn-primary:not(:disabled):not(.disabled):active,
.btn-primary:not(:disabled):not(.disabled).active,
.show > .btn-primary.dropdown-toggle {
  background-color: var(--cor-primaria-ativa);
  border-color: var(--cor-primaria-ativa);
}
.btn-primary.disabled,
.btn-primary:disabled {
  background-color: var(--cor-primaria);
  border-color: var(--cor-primaria);
}

/* O anel de foco vinha com o azul do Bootstrap 5 em 16 lugares do sistema. */
.btn-primary:focus,
.btn-primary.focus,
.btn-primary:not(:disabled):not(.disabled):active:focus {
  box-shadow: var(--sombra-foco);
}

.btn-outline-primary {
  color: var(--cor-primaria);
  border-color: var(--cor-primaria);
}
/* `.active` entra na lista (04/09/2026): num grupo segmentado
   (`btn-group-toggle`, filtro Hoje/Semana/Total) a opcao escolhida leva a
   classe `.active`, e sem esta linha ela enchia com o #007bff do Bootstrap —
   visto no "Filtrar negocios / Filtrar contatos" de mensagens modelo. */
.btn-outline-primary:hover,
.btn-outline-primary.active,
.btn-outline-primary:not(:disabled):not(.disabled):active,
.btn-outline-primary:not(:disabled):not(.disabled).active {
  background-color: var(--cor-primaria);
  border-color: var(--cor-primaria);
  color: #fff;
}
.btn-outline-primary:focus,
.btn-outline-primary.focus { box-shadow: var(--sombra-foco); }

/* .btn-link é link, não botão: usa a cor de link (contraste de texto) */
.btn-link { color: var(--cor-link); }
.btn-link:hover { color: var(--cor-link-hover); }

/* (03/09/2026: `botao_acao`, `botao_voltar_acao` e `botao_acao_ganhar` foram
   trocadas por btn-* nos 54 usos e as regras saíram do base.css. O texto
   abaixo fica como registro do porquê de não repintá-las aqui.)

   As classes `botao_*` NÃO são tratadas aqui — de propósito.

   Elas são definidas no `lib/css/base.css`, que o `base.html` carrega DEPOIS
   deste arquivo. Uma regra `.botao_acao` escrita aqui empata em especificidade
   e perde por ordem: seria código morto. A primeira versão desta seção tinha
   exatamente isso, e só não deu problema porque as duas cores eram iguais —
   no dia em que o token mudasse, o `botao_acao` teria ficado para trás.

   A correção foi na origem: o `base.css` passou a usar `var(--cor-primaria)`
   no lugar do hexadecimal. Ele também ganhou a cor de perigo da paleta no
   `botao_voltar_acao` (era #fc1010) e a altura de 38px, igual à do `.btn`. */

/* --- forma --------------------------------------------------------------- */

/* O raio sai de uma VARIÁVEL, não do valor direto.

   Motivo: a regra abaixo tem quatro `:not()`, ou seja (0,5,0) — cada `:not()`
   vale o peso do argumento. Qualquer tentativa de sobrescrever o raio com
   `.btn-sm` (0,1,0) perde, e o botão pequeno sai com o raio do grande. Foi o
   que aconteceu nas duas primeiras versões desta seção.

   Com variável não há disputa: `.btn-sm` só precisa DEFINIR `--btn-raio` no
   próprio elemento, e a regra abaixo lê o que estiver lá. Especificidade
   deixa de importar. */
.btn:not(.btn-circle):not(.btn-tool):not(.btn-close):not(.btn-app) {
  border-radius: var(--btn-raio, var(--raio-xl));
}
.btn-sm,
.btn-xs,
.btn-group-sm > .btn { --btn-raio: var(--raio-lg); }

/* Reafirma o encaixe que o Bootstrap faz nos grupos.

   ATENÇÃO À ESPECIFICIDADE: a regra de raio acima tem quatro `:not()`, ou
   seja (0,5,0). Uma reafirmação escrita como `.btn-group > .btn:not(:first-child)`
   seria (0,3,0) e PERDERIA para ela — foi o que aconteceu na primeira versão,
   e os botões de um `btn-group` apareceram descolados, cada um com os quatro
   cantos redondos. Por isso as regras abaixo repetem a mesma cadeia de
   `:not()`: elas precisam ser mais específicas que a nossa própria regra, não
   que a do Bootstrap. */
.btn-group > .btn.btn:not(.btn-circle):not(.btn-tool):not(.btn-close):not(:first-child),
.btn-group > .btn-group:not(:first-child) > .btn.btn:not(.btn-circle):not(.btn-tool),
.input-group > .input-group-append > .btn.btn:not(.btn-circle):not(.btn-tool),
.input-group > .input-group-append > .btn-group > .btn.btn:not(.btn-circle) {
  border-top-left-radius: 0;
  border-bottom-left-radius: 0;
}
.btn-group > .btn.btn:not(.btn-circle):not(.btn-tool):not(.btn-close):not(:last-child):not(.dropdown-toggle),
.btn-group > .btn-group:not(:last-child) > .btn.btn:not(.btn-circle):not(.btn-tool),
.input-group > .input-group-prepend > .btn.btn:not(.btn-circle):not(.btn-tool),
.input-group > .input-group-prepend > .btn-group > .btn.btn:not(.btn-circle) {
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
}

/* Botão colado num campo: o raio externo acompanha o do campo (4px), não o do
   botão solto — senão sobra uma barriga arredondada ao lado do input. */
.input-group > .input-group-append > .btn.btn:not(.btn-circle):last-child,
.input-group > .input-group-prepend > .btn.btn:not(.btn-circle):first-child {
  border-radius: var(--raio-sm);
}
.input-group > .input-group-append > .btn.btn:not(.btn-circle):last-child {
  border-top-left-radius: 0;
  border-bottom-left-radius: 0;
}
.input-group > .input-group-prepend > .btn.btn:not(.btn-circle):first-child {
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
}

/* `<a class="btn">` (60 no sistema) não deve ganhar sublinhado no hover. */
a.btn:hover { text-decoration: none; }


/* ==========================================================================
   12. .campo-vazio — a marca de erro que o JS legado usa

   O sistema tem uma validação própria em JS, anterior a este design system,
   que marca campo faltando com `addClass("campo-vazio")` — 27 usos.

   O problema: a classe estava COPIADA em DEZ arquivos de CSS de página
   (atividades, cadcliente, cadcontato, cadprojetos, fluxo_pedido, motoristas,
   negocio, negocios, recebimentos, veiculos), todos com o mesmo
   `border: 1px solid red`. E como é CSS de página, ela só funcionava onde
   alguém tivesse lembrado de copiar: no `edtcontato.html`, que inclui o modal
   de criar negócio mas carrega só o `edtcontato.css`, a classe NÃO EXISTIA —
   validação falhava e nenhum campo era marcado. O usuário via só o aviso
   genérico "Preencha todos os campos obrigatórios", sem saber qual campo.

   Definindo aqui, que é carregado em todo lugar, o buraco fecha e as dez
   cópias podem sair conforme cada módulo for padronizado.

   O vermelho puro também sai: passa a ser o da paleta, igual ao do
   `.is-invalid`. Quem escrever validação nova deve usar `Horus.campoErro()`,
   que além da borda mostra a mensagem dizendo o que falta.
   ========================================================================== */

.campo-vazio,
.campo-vazio .select2-selection,
.select2-container.campo-vazio .select2-selection {
  border: 1px solid var(--cor-perigo) !important;
  background-color: var(--cor-perigo-suave);
}

.campo-vazio:focus,
.campo-vazio .select2-selection:focus {
  box-shadow: 0 0 0 .2rem rgba(220, 53, 69, .25);
}


/* ==========================================================================
   13. AVATAR — a moldura de foto de perfil

   Antes deste componente havia TRÊS implementações concorrentes da mesma
   bolinha com iniciais:

     `.avatar-iniciais`      aprovacao.css — 44px, gradiente azul/ciano, e o
                             gradiente mudava com o STATUS da aprovação
                             (verde/vermelho/amarelo), o que faz a cor do
                             avatar competir com a etiqueta de status ao lado.
     `.responsavel_inicial`  duplicada IDÊNTICA em fluxo_pedido.css:221 e
                             negocios.css:240 — e sem nenhum uso em template
                             ou JS. É CSS morto nos dois arquivos.
     `.mw-resumo-avatar`     programacao_mobile.css — 30px, cinza, com um anel
                             laranja para marcar o motorista principal.

   Mais oito `<img>` de foto em seis grafias diferentes de classe
   (`user-image img-circle elevation-2`, `avatar avatar-md bg-danger-lt`...).

   ---------------------------------------------------------------------------
   POR QUE A COR SAI DO NOME (opção B, escolhida em 28/08/2026)

   Quase ninguém no sistema tem foto, então na prática o avatar é sempre
   iniciais. Se todos forem da mesma cor, ele deixa de informar e vira
   enfeite. Derivando a cor do nome, a mesma pessoa fica com a mesma cor em
   todas as telas e vira reconhecível de relance numa lista de tarefas.

   O custo, que é real: a cor não significa nada. Quem estiver acostumado a
   ler cor como status pode se confundir no começo. Foi por isso que a paleta
   (tokens `--cor-avatar-*`) não tem verde-sucesso, vermelho-perigo nem
   amarelo-aviso: nenhum avatar deve parecer um estado.
   ========================================================================== */

.hrs-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: var(--hrs-avatar-tam, 34px);
  height: var(--hrs-avatar-tam, 34px);
  border-radius: var(--raio-circulo);
  overflow: hidden;
  /* as iniciais escalam com o tamanho: um avatar de 24px com fonte fixa de
     13px fica com as letras encostando na borda. Tamanho INTEIRO por
     variante (abaixo), não calc(): 28px × .38 dava 10,64px e o navegador
     rasterizava as letras meio pixel fora do centro — ficava "GF" subindo
     para a esquerda em alguns círculos e não em outros (03/09/2026). */
  font-size: var(--hrs-avatar-fonte, 13px);
  font-weight: var(--peso-forte);
  line-height: 1;
  color: #fff;
  background: var(--cor-texto-suave);  /* sem cor definida, cinza neutro */
  text-transform: uppercase;
  user-select: none;
}

/* A foto preenche o círculo inteiro. `object-fit: cover` é o que impede o
   rosto de esticar quando a imagem não é quadrada — e quase nenhuma é. */
.hrs-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* --- tamanhos ----------------------------------------------------------- */
.hrs-avatar-xs { --hrs-avatar-tam: 24px; --hrs-avatar-fonte: 9px; }
.hrs-avatar-sm { --hrs-avatar-tam: 28px; --hrs-avatar-fonte: 11px; }
.hrs-avatar-lg { --hrs-avatar-tam: 44px; --hrs-avatar-fonte: 17px; }
.hrs-avatar-xl { --hrs-avatar-tam: 64px; --hrs-avatar-fonte: 24px; }

/* --- cor por pessoa ------------------------------------------------------
   Não escreva estas classes à mão. Use `{{ nome|avatar_cor }}` no template
   ou `Horus.avatarCor(nome)` no JS: os dois usam o MESMO cálculo, então a
   pessoa não muda de cor ao trocar de tela. */
.hrs-avatar-c1 { background: var(--cor-avatar-1); }
.hrs-avatar-c2 { background: var(--cor-avatar-2); }
.hrs-avatar-c3 { background: var(--cor-avatar-3); }
.hrs-avatar-c4 { background: var(--cor-avatar-4); }
.hrs-avatar-c5 { background: var(--cor-avatar-5); }
.hrs-avatar-c6 { background: var(--cor-avatar-6); }
.hrs-avatar-c7 { background: var(--cor-avatar-7); }
.hrs-avatar-c8 { background: var(--cor-avatar-8); }

/* Anel de destaque — para marcar UM avatar dentro de um grupo (o motorista
   principal, o responsável atual). Usa box-shadow em vez de border para não
   mudar o tamanho do círculo e desalinhar a fila. */
.hrs-avatar-destaque { box-shadow: 0 0 0 2px var(--cor-superficie), 0 0 0 4px var(--cor-primaria); }

/* Fila de avatares sobrepostos, para "5 pessoas neste negócio" sem gastar a
   largura de cinco avatares. O primeiro fica na frente. */
.hrs-avatar-fila { display: inline-flex; align-items: center; }
.hrs-avatar-fila .hrs-avatar {
  border: 2px solid var(--cor-superficie);
  margin-left: calc(var(--hrs-avatar-tam, 34px) * -.3);
}
.hrs-avatar-fila .hrs-avatar:first-child { margin-left: 0; }


/* ==========================================================================
   14. LINK

   Medido em 28/08/2026: 115 `<a>` sem classe nenhuma, herdando o azul do
   Bootstrap (#007bff, que não é a nossa cor), e 29 com a cor escrita à mão
   no `style=`.

   ---------------------------------------------------------------------------
   POR QUE SUBLINHADO SEMPRE (opção B, escolhida em 28/08/2026)

   O padrão do Bootstrap — só cor, sublinha no hover — depende exclusivamente
   da cor para dizer o que é clicável. Isso falha em dois lugares concretos
   aqui: para quem não distingue bem cores, e no CELULAR, onde não existe
   hover — lá o link só se revela depois que a pessoa já tocou nele.

   Onde o sublinhado pesa (tabela densa em que quase toda célula é link), use
   `.hrs-link-discreto`.
   ========================================================================== */

.hrs-link {
  color: var(--cor-link);
  text-decoration: underline;
  /* afasta o traço da base das letras; sem isso o sublinhado corta o rabo do
     "g" e do "ç", que aparecem bastante em português. */
  text-underline-offset: 2px;
  text-decoration-thickness: 1px;
  transition: color var(--transicao-rapida);
}

.hrs-link:hover,
.hrs-link:focus {
  color: var(--cor-link-hover);
  text-decoration: underline;
}

.hrs-link:focus-visible {
  outline: none;
  box-shadow: var(--sombra-foco);
  border-radius: var(--raio-sm);
}

/* Variante discreta: cor do texto, sublinhado leve. Para tabela em que a
   linha inteira é navegável e o azul em toda célula vira ruído. */
.hrs-link-discreto {
  color: inherit;
  text-decoration-color: var(--cor-texto-fraco);
}
.hrs-link-discreto:hover,
.hrs-link-discreto:focus {
  color: var(--cor-link);
  text-decoration-color: currentColor;
}

/* Link que é só um ícone (editar, abrir mapa) NÃO leva sublinhado — o traço
   embaixo do glifo lê como sujeira, não como link. */
.hrs-link-icone { text-decoration: none; }
.hrs-link-icone:hover { text-decoration: none; }


/* ==========================================================================
   TABELA DE LISTAGEM — repintura (01/09/2026)

   Mescla das opções B e C das três renderizadas com este mesmo CSS: as linhas
   horizontais e o cabeçalho da B, a zebra da C.

   Sem verticais. Elas não separam nada que o espaçamento não separe melhor, e
   cobram o olho atravessar uma linha por coluna para ler uma linha só. O que
   separa as linhas é a alternância de fundo; o traço horizontal fecha cada
   uma; o hover diz qual delas o olho está seguindo.

   POR QUE REPINTAR EM VEZ DE CRIAR UMA CLASSE .hrs-tabela

   São 128 tabelas em 61 combinações de classe diferentes e 8 jeitos de
   escrever o <thead> (`thead-light` 15x, `table-light` 3x, `bg-white` 2x,
   `thead-dark`, um com `style` inline...). Uma classe nova só padroniza quem
   for reescrito à mão, tabela por tabela — que é exatamente o custo que fez a
   padronização de filtro parar. Repintando o `.table` que já está em todas
   elas, as 128 mudam juntas e nenhum template é tocado. É o mesmo caminho da
   repintura dos botões.

   Estas regras vencem as do Bootstrap por ORDEM, não por peso: o
   componentes.css entra depois do AdminLTE (base.html:21 vs :32), então em
   empate de especificidade a última declarada ganha.

   O QUE FICA DE FORA, E POR QUÊ

   - `.table-dark` e `thead-dark`: são tabelas escuras de propósito; pintar o
     cabeçalho de cinza-claro apagaria o texto branco delas.
   - `background-color`, nunca `background`: o DataTables desenha as setas de
     ordenação como pseudo-elemento, mas outras tabelas do sistema usam
     `background-image` no <th>. A forma curta apagaria as duas coisas.
   - `.table-sm` continua compacta, com padding menor. São 20+ tabelas que
     pediram densidade de propósito — quase sempre dentro de modal.
   - As 3 telas que carregam `dataTable.css` (consulta de pedidos, custo de
     modelo e de componente) carregam esse CSS DEPOIS deste, então lá o vendor
     continua mandando. É esperado.

   O hover vale para toda tabela, e não só para as que pediram `table-hover`:
   numa lista de 8 colunas ele é o que diz qual linha o olho está seguindo.
   ========================================================================== */

.table:not(.table-dark) thead:not(.thead-dark) th,
.table:not(.table-dark) thead:not(.thead-dark) td {
  border: 0;
  border-bottom: 2px solid var(--cor-borda);
  background-color: var(--cor-tabela-cabecalho);
  padding: 10px 14px;
  font-size: var(--fonte-xs);
  font-weight: var(--peso-forte);
  letter-spacing: .02em;
  text-transform: uppercase;
  color: var(--cor-texto-medio);
  white-space: nowrap;
}

/* DENSIDADE (18/09/2026) — a leitura da tabela, não só a pintura.

   Medido na lista de pedidos internos, que foi onde o incômodo apareceu:
   a célula herdava os 16px do corpo do texto, tamanho de PARÁGRAFO. Em coluna
   estreita isso faz "10/09/2026 14:52", "Isabella Gomes" e "AQUARELA STORE"
   quebrarem em duas linhas — nas 50 linhas da página, sem exceção. A linha
   ficava com 74px onde caberia em 46, e entravam 9 linhas na tela.

   Com --fonte-sm (13px) e o respiro menor: linha de 44px, 15 linhas na tela.
   Quase o dobro, sem tirar nenhuma coluna nem nenhum dado.

   `tabular-nums` vale para a tabela inteira e só afeta dígitos: número embaixo
   de número alinha pela casa decimal, que é o que deixa uma coluna de valores
   comparável de relance. Em texto não muda nada.

   O tamanho é do CORPO da célula. O cabeçalho já era --fonte-xs em caixa alta
   desde 01/09 e não muda. */
.table:not(.table-dark) tbody th,
.table:not(.table-dark) tbody td {
  border: 0;
  border-bottom: 1px solid var(--cor-borda);
  padding: 7px 10px;
  font-size: var(--fonte-sm);
  line-height: 20px;
  vertical-align: middle;
}
.table:not(.table-dark) { font-variant-numeric: tabular-nums; }

/* O cabeçalho acompanha o respiro menor do corpo, senão fica desproporcional. */
.table:not(.table-dark) thead:not(.thead-dark) th,
.table:not(.table-dark) thead:not(.thead-dark) td { padding: 8px 10px; }

/* Hora ao lado da data, em cinza: continua legível e para de disputar com o
   dia, que é o que a pessoa procura. Uso: <td>10/09/2026 <span class="hrs-hora">14:52</span></td> */
.hrs-hora { color: var(--cor-texto-suave); }

/* Célula sem valor. Um traço cinza diz "não tem" sem parecer dado. */
.hrs-vazio { color: var(--cor-texto-fraco); }
.table:not(.table-dark) tbody tr:last-child > th,
.table:not(.table-dark) tbody tr:last-child > td { border-bottom: 0; }

/* A zebra é do Bootstrap (`table-striped`), mas com um cinza forte demais
   (rgba(0,0,0,.05)). Aqui ela vale para toda tabela e num tom mais leve —
   leve, não invisível: a primeira tentativa foi #fafbfc e não se via. */
.table:not(.table-dark) tbody tr:nth-of-type(odd) { background-color: var(--cor-zebra); }
.table:not(.table-dark) tbody tr:hover { background-color: var(--cor-hover-neutro); }

/* As verticais saem. `.table-bordered` está em 40% das tabelas e põe borda em
   cada célula. */
.table-bordered { border: 0; }
.table-bordered thead th, .table-bordered thead td {
  border: 0; border-bottom: 2px solid var(--cor-borda);
}
.table-bordered tbody th, .table-bordered tbody td {
  border: 0; border-bottom: 1px solid var(--cor-borda);
}

/* Canto arredondado no contêiner da tabela. Funciona sem `overflow: hidden`
   porque o `.table-responsive` do Bootstrap já é `overflow-x: auto`, e
   overflow diferente de visible recorta o conteúdo no raio: o cinza do
   cabeçalho e a zebra ganham o canto sem tocar na <table>. Como a tabela
   repintada não tem borda externa (acima), não sobra traço cortado no canto. */
.table-responsive { border-radius: var(--raio-xl); }

/* EXCEÇÃO: tabela encostada na borda do card ("sangrada"). Ali quem faz a
   moldura é o card; arredondar a tabela abre um dente entre o cabeçalho do
   card e o cinza do <thead> (visto em projetos/processo_pedido, 23/09/2026).
   São dois jeitos de sangrar, e só eles:
   - filha direta do card, sem card-body no meio (hrs-card de processo_pedido
     e cadastro_modelo, card do faturamento.js);
   - card-body sem padding (`p-0`): pcp/derivacoes, gestao_derivacoes,
     lista de rotas.
   `card-body table-responsive` COM padding (crm/tarefas) não entra: o padding
   afasta a tabela da borda e o canto dela continua valendo. */
.card > .table-responsive:not(.card-body),
.hrs-card > .table-responsive:not(.card-body),
.table-responsive.card-body.p-0,
.card-body.p-0 > .table-responsive { border-radius: 0; }

/* Densidade menor continua existindo para quem pediu. */
.table-sm:not(.table-dark) thead th,
.table-sm:not(.table-dark) thead td,
.table-sm:not(.table-dark) tbody th,
.table-sm:not(.table-dark) tbody td { padding: 6px 10px; }

/* Coluna de número: `.text-right` do Bootstrap continua sendo o jeito de
   alinhar valor à direita. Não dá para o CSS adivinhar qual coluna é
   dinheiro, então isso segue sendo escolha da tela. */


/* ==========================================================================
   CARD — repintura (01/09/2026)

   O card é a caixa de quase toda tela: 761 usos das classes `card-*`, sendo
   131 `.card`, 136 `.card-body` e 71 `.card-header` — quase metade dos cards
   não tem cabeçalho nenhum. Em 38 deles havia `style` escrito à mão por cima
   do AdminLTE, quase sempre para consertar borda, canto ou sombra.

   Escolhida a opção B de três renderizadas com este CSS: BORDA, sem sombra.

   POR QUE BORDA E NÃO SOMBRA

   1. O fundo do Hórus é cinza (--cor-fundo, #f4f6f9). Sombra precisa de
      contraste com o que está atrás para desenhar a beirada; sobre cinza ela
      fica embaçada e o card perde o limite. Borda de 1px marca o limite em
      qualquer fundo.
   2. É o que o resto do sistema já faz. Tabela, painel de filtro, campo de
      formulário e dropdown resolvem "onde isto começa e termina" com
      --cor-borda. Card com sombra seria a única exceção — e exceção não é
      padrão.
   3. Card dentro de card acontece em várias telas do Hórus. Duas sombras
      empilhadas viram uma mancha; duas bordas continuam sendo duas caixas.

   O CABEÇALHO COLORIDO VIRA UM FIO NO TOPO

   São 47 cards com cor (25 `card-primary`, 22 `card-secondary`, mais 2
   `card-success` e 2 `card-info`). No AdminLTE a cor toma o cabeçalho
   inteiro e engole o título em texto branco. Virando um fio de 3px no topo,
   a cor continua marcando o card e o título volta a ser legível — que é,
   aliás, o que o próprio `.card-outline` do AdminLTE já fazia nos 8 cards
   que o usavam. Aqui isso deixa de depender de alguém lembrar da classe.

   O QUE FICA DE FORA

   - `.small-box` e `.info-box`: são outros componentes do AdminLTE, com
     cor de fundo cheia por definição. Não são card.
   - `.card-tools` e o botão de recolher continuam como estão: são
     comportamento, não forma.
   ========================================================================== */

.card {
  box-shadow: none;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio-lg);
}

.card > .card-header {
  background-color: transparent;
  border-bottom: 1px solid var(--cor-borda);
  padding: var(--esp-3) var(--esp-4);
}

.card > .card-header .card-title {
  font-size: var(--fonte-lg);
  font-weight: var(--peso-forte);
  color: var(--cor-texto);
}

.card > .card-body { padding: var(--esp-4); }

.card > .card-footer {
  background-color: transparent;
  border-top: 1px solid var(--cor-borda);
  padding: var(--esp-3) var(--esp-4);
}

/* A cor sai do cabeçalho e vira o fio do topo. O `:not(.card-outline)` existe
   porque nos 8 cards que já usavam `card-outline` o AdminLTE JÁ desenha esse
   fio — repetir a regra dobraria a espessura. */
/* Os `card-outline` (5 telas: auditoria, perfil, aprovação, configurações, orçamento) ficam
   com o fio que o AdminLTE desenha — mas ele desenha em #007bff, o azul velho. Só a cor muda. */
.card.card-primary.card-outline   { border-top-color: var(--cor-primaria); }
.card.card-secondary.card-outline { border-top-color: var(--cor-texto-suave); }
.card.card-success.card-outline   { border-top-color: var(--cor-sucesso); }
.card.card-info.card-outline      { border-top-color: var(--cor-info); }
.card.card-warning.card-outline   { border-top-color: var(--cor-aviso); }
.card.card-danger.card-outline    { border-top-color: var(--cor-perigo); }
.card.card-primary:not(.card-outline)   { border-top: 3px solid var(--cor-primaria); }
.card.card-secondary:not(.card-outline) { border-top: 3px solid var(--cor-texto-suave); }
.card.card-success:not(.card-outline)   { border-top: 3px solid var(--cor-sucesso); }
.card.card-info:not(.card-outline)      { border-top: 3px solid var(--cor-info); }
.card.card-warning:not(.card-outline)   { border-top: 3px solid var(--cor-aviso); }
.card.card-danger:not(.card-outline)    { border-top: 3px solid var(--cor-perigo); }

.card.card-primary:not(.card-outline) > .card-header,
.card.card-secondary:not(.card-outline) > .card-header,
.card.card-success:not(.card-outline) > .card-header,
.card.card-info:not(.card-outline) > .card-header,
.card.card-warning:not(.card-outline) > .card-header,
.card.card-danger:not(.card-outline) > .card-header {
  background-color: transparent;
  border-bottom: 1px solid var(--cor-borda);
  color: var(--cor-texto);
}
/* O AdminLTE pinta de branco TODO <a> dentro do cabeçalho de um card colorido
   (`.card-primary:not(.card-outline) > .card-header a`). Com o cabeçalho agora
   transparente, esse branco ficaria invisível. As abas são tratadas na seção
   ABAS, por isso o `:not(.nav-link)` — senão esta regra, que é mais específica,
   apagaria a cor delas. */
.card.card-primary:not(.card-outline) > .card-header a:not(.nav-link),
.card.card-secondary:not(.card-outline) > .card-header a:not(.nav-link),
.card.card-success:not(.card-outline) > .card-header a:not(.nav-link),
.card.card-info:not(.card-outline) > .card-header a:not(.nav-link),
.card.card-warning:not(.card-outline) > .card-header a:not(.nav-link),
.card.card-danger:not(.card-outline) > .card-header a:not(.nav-link) { color: var(--cor-texto); }

/* O botão de recolher/expandir herdava o branco do cabeçalho colorido. */
.card.card-primary:not(.card-outline) > .card-header .btn-tool,
.card.card-secondary:not(.card-outline) > .card-header .btn-tool,
.card.card-success:not(.card-outline) > .card-header .btn-tool,
.card.card-info:not(.card-outline) > .card-header .btn-tool,
.card.card-warning:not(.card-outline) > .card-header .btn-tool,
.card.card-danger:not(.card-outline) > .card-header .btn-tool { color: var(--cor-texto-suave); }


/* ==========================================================================
   PAGINAÇÃO — repintura (01/09/2026)

   19 telas, 137 `page-item`. A marcação já é a mesma em todas — o
   `.pagination > .page-item > .page-link` do Bootstrap — então isto muda as
   19 de uma vez, sem tocar em template.

   O QUE ESTAVA ERRADO

   A paginação era o ÚLTIMO lugar do sistema ainda no azul velho do Bootstrap.
   A repintura dos botões trocou `.btn-*` para a cor da marca e não passou por
   aqui: media na tela de clientes, o item ativo vinha rgb(0,123,255) e os
   inativos com o texto na mesma cor. Duas famílias de azul na mesma tela.

   E onze números azuis competem com o conteúdo: em #007bff eles gritam mais
   que os nomes dos clientes da tabela que estão paginando. O número vira
   cinza; azul fica só no ativo, que é a única informação que a régua dá.

   A fonte também estava em 16px — maior que o texto da tabela que ela pagina.

   Escolhida a opção B de três: mesma forma (o grupo unido diz "estes botões
   são uma coisa só, escolha um"), cor e tamanho certos.

   O QUE NÃO ESTÁ AQUI

   Com 11 páginas a régua cabe; há telas com muito mais, e aí ela estoura. A
   saída é a versão compacta (« ‹ 1 … 5 6 7 … 11 › »), que exige mexer na
   marcação das 19 telas — não é repintura, é outro trabalho.
   ========================================================================== */

.page-link {
  color: var(--cor-texto-medio);
  background-color: var(--cor-superficie);
  border-color: var(--cor-borda);
  font-size: var(--fonte-md);
  padding: 6px 12px;
  min-width: 38px;
  text-align: center;
}

/* O arredondamento fica nas pontas do grupo, não em cada botão. */
.page-item:first-child .page-link {
  border-top-left-radius: var(--raio-md);
  border-bottom-left-radius: var(--raio-md);
}
.page-item:last-child .page-link {
  border-top-right-radius: var(--raio-md);
  border-bottom-right-radius: var(--raio-md);
}

.page-link:hover {
  background-color: var(--cor-hover-neutro);
  border-color: var(--cor-borda);
  color: var(--cor-texto);
}
.page-link:focus {
  outline: none;
  box-shadow: var(--sombra-foco);
  z-index: 3;  /* o anel some sob o vizinho, que tem margin-left: -1px */
}

.page-item.active .page-link {
  background-color: var(--cor-primaria);
  border-color: var(--cor-primaria);
  color: #fff;
}

.page-item.disabled .page-link {
  color: var(--cor-texto-fraco);
  background-color: var(--cor-superficie);
  border-color: var(--cor-borda);
}

/* `pagination-sm` continua menor para quem pediu (5 usos). */
.pagination-sm .page-link {
  font-size: var(--fonte-sm);
  padding: 4px 8px;
  min-width: 32px;
}


/* ==========================================================================
   ABAS — repintura (01/09/2026)

   13 telas usam `nav-tabs`: perfil, cliente, contato, grupo, configurações,
   config de URLs, e-mail de boletos, faturamento, editar parcelas, proposta,
   tagear parques, auditoria e o dashboard.

   Escolhida a opção B de três renderizadas com o CSS real: SUBLINHADO.

   POR QUE SUBLINHADO E NÃO A CAIXA DE HOJE

   O card já é uma caixa. Aba em caixa dentro de caixa é contorno demais para
   dizer uma coisa só — "você está aqui". Um traço de 2px diz isso com uma
   linha. E hoje TODAS as abas inativas são azuis, o que faz a ativa não se
   destacar de nada: inativa passa a cinza e escurece no hover, que é a
   hierarquia que faltava.

   PRESO A `.nav-tabs`, NUNCA A `.nav-link` SOZINHO

   `.nav-link` é a mesma classe do MENU LATERAL (`nav-sidebar`), da NAVBAR
   (`navbar-nav`) e do menu em árvore (`nav-treeview`). Repintar `.nav-link`
   solto pintaria o menu do sistema inteiro. Todo seletor daqui começa em
   `.nav-tabs`.

   O QUE FICA DE FORA

   Cinco das 13 telas têm CSS próprio para as abas — edtcliente.css,
   edtcontato.css, edtperfil.css, perfil_grupo.css e proposta.css — e esses
   arquivos entram DEPOIS deste. Onde eles falam, continuam mandando; onde
   não falam, o padrão daqui vale. Uniformizar as cinco significa mexer nesses
   arquivos, o que é outro passo.
   ========================================================================== */

.nav-tabs {
  border-bottom: 1px solid var(--cor-borda);
  padding: 0 var(--esp-2);
}

.nav-tabs .nav-link {
  border: 0;
  border-bottom: 2px solid transparent;
  border-radius: 0;
  margin-bottom: -1px;  /* o traço cobre a linha do grupo, não fica acima dela */
  padding: var(--esp-3);
  color: var(--cor-texto-suave);
  font-weight: var(--peso-medio);
}

.nav-tabs .nav-link:hover {
  background-color: transparent;
  border-color: transparent transparent var(--cor-borda);
  color: var(--cor-texto);
}

.nav-tabs .nav-link.active,
.nav-tabs .nav-item.show .nav-link {
  background-color: transparent;
  border-color: transparent transparent var(--cor-primaria);
  color: var(--cor-primaria);
  font-weight: var(--peso-forte);
}

.nav-tabs .nav-link:focus-visible {
  outline: none;
  box-shadow: var(--sombra-foco);
  border-radius: var(--raio-sm) var(--raio-sm) 0 0;
}

.nav-tabs .nav-link.disabled {
  color: var(--cor-texto-fraco);
  border-color: transparent;
}

/* ABA DENTRO DO CABEÇALHO DE UM CARD (`card-tabs`, usado em configurações,
   perfil e cliente)

   Ali o AdminLTE pinta todo <a> de branco com peso maior que `.nav-tabs
   .nav-link`, e a aba inativa ficava branca sobre branco — invisível. As
   mesmas cores, repetidas com a especificidade necessária. */
.card > .card-header .nav-tabs .nav-link { color: var(--cor-texto-suave); }
.card > .card-header .nav-tabs .nav-link:hover { color: var(--cor-texto); }
.card > .card-header .nav-tabs .nav-link.active { color: var(--cor-primaria); }


/* ==========================================================================
   RODAPÉ DE MODAL — repintura (01/09/2026)

   160 rodapés em 189 modais, em 14 combinações de classe.

   O QUE MAIS PESAVA NÃO ERA A FORMA: ERA A ORDEM

   Contado nos templates: "Cancelar | Salvar" em 23 rodapés, "Salvar |
   Cancelar" em 10, "Sim | Não" em 7. O mesmo gesto — desistir — exigia clicar
   em lugares diferentes conforme a tela.

   Dá para consertar sem tocar em template porque 123 dos 132 botões de saída
   já trazem `data-dismiss="modal"`: o CSS usa isso para pôr a saída sempre
   antes da ação. Escolhida a opção B de três — os dois juntos no canto
   direito, ação por último, que é onde o olho e o polegar terminam de ler.
   (A opção C, com a saída na outra ponta, existe para afastar botão
   DESTRUTIVO; no Hórus a saída é quase sempre "Cancelar".)

   O QUE ESTA REGRA NÃO FAZ

   1. `order` muda o que se VÊ, não a ordem do Tab. Com dois botões a diferença
      é pequena, mas existe; corrigir de verdade seria editar os 160 rodapés.
   2. Os 9 botões de saída sem `data-dismiss` continuam onde o HTML os põe:
      base.html, negocio.html, dashboard_crm.html (4), config.html e
      tabela_proj_vincproduto.html.
   3. A COR da ação principal continua variando — btn-primary 61x, btn-danger
      59x, btn-success 39x, btn-warning 5x. "Salvar" é azul numa tela e verde
      na outra. Isso é markup, não CSS, e é decisão à parte.

   Os rodapés que pediram outro alinhamento (`justify-content-between` e
   afins) continuam como estão: utilitário do Bootstrap vem com !important, e
   ali a escolha foi deliberada.
   ========================================================================== */

.modal-footer {
  justify-content: flex-end;
  gap: var(--esp-2);
  padding: var(--esp-3) var(--esp-4);
  border-top: 1px solid var(--cor-borda);
}

/* O Bootstrap separa os botões com margem no irmão; com `gap` isso vira
   espaço dobrado no meio e nenhum nas pontas. */
.modal-footer > * { margin: 0; }

/* Largura mínima igual: sem ela "Sim" e "Cancelar" viram dois botões de
   tamanhos bem diferentes lado a lado. */
.modal-footer > .btn { min-width: 104px; }

/* A saída vem antes da ação, sempre — venha na ordem que vier no HTML. */
.modal-footer [data-dismiss="modal"] { order: -1; }

@media (max-width: 767.98px) {
  /* Empilhado, a ação fica em cima e a saída embaixo: `column-reverse` com o
     `order: -1` acima já produz isso, e de quebra o polegar alcança primeiro
     o botão que se usa mais. */
  .modal-footer { flex-direction: column-reverse; }
  .modal-footer > .btn { width: 100%; min-height: var(--mob-alvo-toque-min); }
}


/* ==========================================================================
   BADGE — repintura (01/09/2026)

   189 badges em 47 templates. O problema não era só a aparência: o design
   system criou a `.hrs-etiqueta`, adotada em 26 lugares do CRM, e os 189
   `.badge` do Bootstrap continuaram com outra forma e outras cores — os dois
   conviviam na mesma tela, e cada tela nova tinha de escolher entre eles.

   Aqui o `.badge` passa a ser desenhado como a `.hrs-etiqueta`: fundo suave,
   texto escuro da mesma família, pílula, tamanho fixo. Escolhida a opção B de
   três renderizadas com o CSS real.

   POR QUE FUNDO SUAVE E NÃO A COR CHEIA DE HOJE

   1. Uma tabela do Hórus tem duas ou três colunas de badge. Em cor cheia a
      linha vira uma fileira de retângulos que gritam mais que o nome do
      cliente, que é o conteúdo.
   2. O `font-size: 75%` do Bootstrap é relativo ao PAI: o mesmo badge tem
      tamanhos diferentes conforme onde está. Aqui é fixo.
   3. O verde e o amarelo cheios do Bootstrap com texto branco por cima têm
      contraste ruim. Os tons de texto daqui são os mesmos já usados na
      etiqueta, escolhidos com contraste >= 5:1.

   Se algum status crítico precisar berrar, a saída é declarar a exceção na
   tela — não voltar tudo para cor cheia.

   O QUE FICA DE FORA

   `.navbar-badge` — a bolinha de contagem sobre o sino de notificações. Não é
   rótulo de status: é um contador pequeno sobre um ícone, onde fundo pálido
   simplesmente não se vê. Continua vermelha e sólida.
   ========================================================================== */

.badge:not(.navbar-badge) {
  display: inline-flex;
  align-items: center;
  gap: var(--esp-1);
  padding: 2px var(--esp-2);
  border-radius: var(--raio-pilula);
  font-size: var(--fonte-xs);
  font-weight: var(--peso-forte);
  line-height: 1.5;
  white-space: nowrap;
  vertical-align: middle;
  background-color: var(--cor-superficie-alt);
  color: var(--cor-texto-suave);
}

.badge-primary:not(.navbar-badge)   { background-color: var(--cor-primaria-suave); color: var(--cor-primaria-ativa); }
.badge-success:not(.navbar-badge)   { background-color: var(--cor-sucesso-suave);  color: var(--cor-sucesso-texto); }
.badge-danger:not(.navbar-badge)    { background-color: var(--cor-perigo-suave);   color: var(--cor-perigo-texto); }
.badge-warning:not(.navbar-badge)   { background-color: var(--cor-aviso-suave);    color: var(--cor-aviso-texto); }
.badge-info:not(.navbar-badge)      { background-color: var(--cor-info-suave);     color: var(--cor-info-texto); }
.badge-secondary:not(.navbar-badge),
.badge-light:not(.navbar-badge)     { background-color: var(--cor-superficie-alt); color: var(--cor-texto-suave); }
.badge-dark:not(.navbar-badge)      { background-color: var(--cor-superficie-alt); color: var(--cor-texto); }

/* Badge que é link continua parecendo clicável. */
a.badge:hover, a.badge:focus { text-decoration: none; filter: brightness(.96); }


/* ==========================================================================
   ALERTA — repintura (01/09/2026)

   87 alertas em 45 templates.

   DOIS PROBLEMAS, E O SEGUNDO É O QUE IMPORTA

   1. No Hórus o alerta NÃO é o pastel do Bootstrap: o AdminLTE sobrescreve com
      cor sólida e texto branco. Um aviso vira um bloco vermelho ou amarelo de
      largura inteira — e a tela de cancelamento de NF tem quatro seguidos.

   2. O tipo do alerta é dito SÓ PELA COR. Quem não distingue vermelho de verde
      não tem outro sinal. Aqui entra um ícone, desenhado pelo CSS (`::before`
      com o Font Awesome), sem tocar em template nenhum.

   Escolhida a opção B de três: barra de 3px à esquerda, onde a leitura começa,
   com o fundo e o texto nos mesmos tons da etiqueta e do badge. A barra existe
   porque o alerta é a única coisa da tela que INTERROMPE — ele precisa de uma
   beirada que o badge não precisa.

   POR QUE `position: absolute` E NÃO `display: flex`

   Alerta tem conteúdo livre: alguns têm `<h6>` e `<p>`, outros uma lista. Com
   flex, cada filho viraria uma coluna ao lado do ícone. O ícone posicionado
   sobre um `padding-left` funciona com qualquer conteúdo.

   O `:not(:has(i))` existe porque 16 alertas JÁ começam com um ícone escrito à
   mão (faturamento.html é o caso). Sem isso, apareceriam dois. O `:has` já é
   usado no CSS mobile do sistema, então não é novidade para o navegador daqui.
   ========================================================================== */

.alert {
  position: relative;
  border: 0;
  /* Sem modificador de cor o alerta fica neutro — antes ele herdava o que
     estivesse por perto e podia sair sem cor nenhuma. */
  border-left: 3px solid var(--cor-borda);
  border-radius: 0 var(--raio-md) var(--raio-md) 0;
  padding: var(--esp-3) var(--esp-4);
  background-color: var(--cor-superficie-alt);
  color: var(--cor-texto-medio);
  font-size: var(--fonte-md);
  line-height: 1.45;
}

.alert:not(:has(i)) { padding-left: calc(var(--esp-4) + 22px); }
.alert:not(:has(i))::before {
  position: absolute;
  left: var(--esp-4);
  top: var(--esp-3);
  font-family: "Font Awesome 6 Free";
  font-weight: 900;
  font-size: 15px;
  line-height: 1.45;
}

.alert-danger  { background-color: var(--cor-perigo-suave);  border-left-color: var(--cor-perigo);  color: var(--cor-perigo-texto); }
.alert-warning { background-color: var(--cor-aviso-suave);   border-left-color: var(--cor-aviso);   color: var(--cor-aviso-texto); }
.alert-success { background-color: var(--cor-sucesso-suave); border-left-color: var(--cor-sucesso); color: var(--cor-sucesso-texto); }
.alert-info    { background-color: var(--cor-info-suave);    border-left-color: var(--cor-info);    color: var(--cor-info-texto); }
.alert-secondary,
.alert-light,
.alert-dark    { background-color: var(--cor-superficie-alt); border-left-color: var(--cor-borda);  color: var(--cor-texto-medio); }

/* O padrão é o "i" de informação. Esta regra vem ANTES das coloridas de
   propósito: todas têm o mesmo peso, então quem vem depois vence. */
.alert:not(:has(i))::before         { content: "\f05a"; }

.alert-danger:not(:has(i))::before  { content: "\f06a"; }  /* circle-exclamation */
.alert-warning:not(:has(i))::before { content: "\f071"; }  /* triangle-exclamation */
.alert-success:not(:has(i))::before { content: "\f058"; }  /* circle-check */
.alert-info:not(:has(i))::before    { content: "\f05a"; }  /* circle-info */
.alert-secondary:not(:has(i))::before,
.alert-light:not(:has(i))::before,
.alert-dark:not(:has(i))::before    { content: "\f05a"; }

/* Link dentro do alerta segue a cor do texto, sublinhado para não sumir. */
.alert .alert-link { color: inherit; text-decoration: underline; font-weight: var(--peso-forte); }


/* ==========================================================================
   CHECKBOX E RADIO — repintura (01/09/2026)

   105 controles no sistema: 64 NATIVOS (33 checkbox, 31 radio) e 41 do
   Bootstrap (23 custom-switch, 16 custom-checkbox, 2 custom-radio).

   Ou seja, 61% dos checkbox e radio do Hórus eram os do navegador — quadrado
   cinza, marcado no azul do SISTEMA OPERACIONAL, que nem é o nosso — e 39%
   eram os do Bootstrap. Duas aparências para o mesmo controle, muitas vezes
   na mesma tela.

   E o do Bootstrap ainda estava no azul velho: o AdminLTE marca o
   `custom-control` com #007bff. É o mesmo #007bff que já saiu dos botões e da
   paginação; aqui ele sai do último lugar onde ainda aparecia.

   Escolhida a opção C de três: forma única. O nativo é redesenhado com o mesmo
   tamanho, canto e cor do padrão — quadrado de 16px com o check do Font
   Awesome, redondo com o ponto branco.

   O QUE NÃO MEXO, DE PROPÓSITO

   A MARGEM. O navegador dá ao checkbox nativo uma margem própria, e é ela que
   segura o espaçamento de 24 telas que ninguém revisou. Mexer no tamanho já
   desloca ~3px (o nativo do Chrome tem ~13px); mexer também na margem
   multiplicaria isso por cada layout apertado.

   `custom-switch` continua sendo um interruptor — é outro controle, com outro
   significado (liga/desliga na hora, sem precisar salvar).

   `:indeterminate` não é usado em lugar nenhum do sistema (conferido), então
   `appearance: none` não apaga nada que exista hoje.
   ========================================================================== */

input[type="checkbox"]:not(.custom-control-input),
input[type="radio"]:not(.custom-control-input) {
  appearance: none;
  -webkit-appearance: none;
  width: 16px;
  height: 16px;
  vertical-align: -3px;
  border: 1px solid var(--cor-borda-forte);
  background-color: var(--cor-superficie);
  display: inline-block;
  position: relative;
  cursor: pointer;
  flex: 0 0 auto;  /* dentro de flex, não deixa o quadrado esticar */
}

input[type="checkbox"]:not(.custom-control-input) { border-radius: var(--raio-sm); }
input[type="radio"]:not(.custom-control-input)    { border-radius: 50%; }

input[type="checkbox"]:not(.custom-control-input):hover:not(:disabled),
input[type="radio"]:not(.custom-control-input):hover:not(:disabled) {
  border-color: var(--cor-primaria);
}

input[type="checkbox"]:not(.custom-control-input):checked,
input[type="radio"]:not(.custom-control-input):checked {
  background-color: var(--cor-primaria);
  border-color: var(--cor-primaria);
}

input[type="checkbox"]:not(.custom-control-input):checked::after {
  content: "\f00c";
  font-family: "Font Awesome 6 Free";
  font-weight: 900;
  font-size: 9px;
  color: #fff;
  /* centrado por flex, não por left/top: a métrica da fonte muda o encaixe
     de 1–2px e o check ficava puxado para o canto (10/09/2026). */
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
}

input[type="radio"]:not(.custom-control-input):checked::after {
  content: "";
  position: absolute;
  left: 4px;
  top: 4px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background-color: #fff;
}

input[type="checkbox"]:not(.custom-control-input):disabled,
input[type="radio"]:not(.custom-control-input):disabled {
  background-color: var(--cor-superficie-alt);
  border-color: var(--cor-borda);
  cursor: not-allowed;
}
input[type="checkbox"]:not(.custom-control-input):disabled:checked,
input[type="radio"]:not(.custom-control-input):disabled:checked {
  background-color: var(--cor-texto-fraco);
  border-color: var(--cor-texto-fraco);
}

input[type="checkbox"]:not(.custom-control-input):focus-visible,
input[type="radio"]:not(.custom-control-input):focus-visible {
  outline: none;
  box-shadow: var(--sombra-foco);
}

/* O do Bootstrap sai do #007bff e passa a usar a cor da marca. */
.custom-control-input:checked ~ .custom-control-label::before {
  background-color: var(--cor-primaria);
  border-color: var(--cor-primaria);
}
.custom-control-input:focus ~ .custom-control-label::before { box-shadow: var(--sombra-foco); }
.custom-control-input:disabled:checked ~ .custom-control-label::before {
  background-color: var(--cor-texto-fraco);
  border-color: var(--cor-texto-fraco);
}


/* ==========================================================================
   DROPDOWN — repintura (01/09/2026)

   27 menus com 82 itens, concentrados em três lugares: os cards do funil, as
   atividades da logística e o header.

   POR QUE A OPÇÃO C FOI ABANDONADA NA HORA DE TESTAR

   A escolha na tela tinha sido a C: o ícone sairia do fluxo do texto e viraria
   uma coluna, alinhando os rótulos — 17 dos 82 itens não têm ícone e começavam
   ~22px à esquerda dos vizinhos.

   A guarda planejada era `> i:first-child`, para o ícone que NÃO abre o item
   ficar onde está. Existe exatamente um caso assim: o seletor de funil em
   cards_negocio.html:14, onde um cadeado no FIM do texto marca funil privado.

   A guarda não funciona. `:first-child` em CSS quer dizer "primeiro elemento
   filho", e nó de texto não é elemento — então naquele item o cadeado É o
   primeiro filho, mesmo vindo depois do nome do funil. Medido no navegador:
   `iconePos: absolute` nos quatro itens do menu de funis, com o cadeado
   arrancado do fim e jogado por cima do nome.

   CSS não sabe distinguir ícone que ABRE de ícone que FECHA um item. Para a C
   valer seria preciso marcar isso no HTML dos 25 menus — o que deixa de ser
   repintura. Fica então a opção B: o ícone continua no fluxo. Os 17 itens sem
   ícone seguem começando mais à esquerda; é o preço de não tocar em template,
   e está registrado aqui para quem retomar.

   O DESTRUTIVO PARA DE PARECER COM O RESTO

   Os três "Excluir" do sistema já vinham com `.text-danger` no HTML — só
   ninguém tinha feito o menu respeitar isso além da cor do texto. Agora o
   hover também é vermelho suave, então o item avisa antes do clique.
   ========================================================================== */

.dropdown-menu {
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio-lg);
  box-shadow: var(--sombra-md);
  padding: var(--esp-2) 0;
  min-width: 200px;
}

.dropdown-item {
  padding: var(--esp-2) var(--esp-4);
  font-size: var(--fonte-md);
  color: var(--cor-texto);
}

.dropdown-item:hover,
.dropdown-item:focus {
  background-color: var(--cor-hover-neutro);
  color: var(--cor-texto);
}

.dropdown-item.active,
.dropdown-item:active {
  background-color: var(--cor-primaria-suave);
  color: var(--cor-primaria-ativa);
}

/* Ícone no fluxo, cinza — ele acompanha o rótulo, não compete com ele. */
.dropdown-item > i {
  width: 14px;
  margin-right: var(--esp-2);
  text-align: center;
  color: var(--cor-texto-fraco);
}
.dropdown-item:hover > i { color: var(--cor-texto-suave); }

.dropdown-divider {
  border-top-color: var(--cor-borda);
  margin: var(--esp-2) 0;
}

.dropdown-header {
  padding: var(--esp-1) var(--esp-4) var(--esp-2);
  font-size: var(--fonte-xs);
  font-weight: var(--peso-forte);
  text-transform: uppercase;
  letter-spacing: .02em;
  color: var(--cor-texto-suave);
}

/* `.text-danger` do Bootstrap vem com !important, então o hover precisa
   responder na mesma moeda. */
.dropdown-item.text-danger > i { color: var(--cor-perigo); }
.dropdown-item.text-danger:hover,
.dropdown-item.text-danger:focus {
  background-color: var(--cor-perigo-suave);
  color: var(--cor-perigo-texto) !important;
}
.dropdown-item.text-danger:hover > i { color: var(--cor-perigo-texto); }


/* ==========================================================================
   ACABAMENTO — utilities, tooltip, lista, progresso e select2 (01/09/2026)

   O fim do grupo das repinturas: cinco coisas pequenas que sobraram depois
   das dez grandes.

   UTILITIES -PRIMARY — CORREÇÃO, NÃO ESCOLHA

   `.text-primary` (22 usos), `.bg-primary` (23) e `.border-primary` ainda
   eram #007bff !important — o azul velho sobreviveu nas utilities depois de
   sair de botão, paginação, aba e checkbox. E o spinner usa `text-primary`
   (o `spinner-border` herda de currentColor), então os 5 spinners azuis
   estavam errados por tabela. O !important aqui responde ao !important do
   Bootstrap; sem ele a regra nunca vence.
   ========================================================================== */

.text-primary { color: var(--cor-primaria) !important; }
a.text-primary { color: var(--cor-link) !important; }
a.text-primary:hover,
a.text-primary:focus { color: var(--cor-link-hover) !important; }
.bg-primary { background-color: var(--cor-primaria) !important; }
.border-primary { border-color: var(--cor-primaria) !important; }

/* --- tooltip ---------------------------------------------------------------
   Escuro de propósito: ele aparece em cima de QUALQUER fundo, e escuro sobre
   claro é o único contraste garantido nas 9 telas em que existe. A versão
   clara com borda perdia o limite sobre card branco. */
.tooltip.show { opacity: 1; }
.tooltip-inner {
  background-color: var(--cor-texto);
  border-radius: var(--raio-md);
  padding: 6px 10px;
  font-size: var(--fonte-sm);
  max-width: 260px;
  text-align: left;
  box-shadow: var(--sombra-md);
}
.bs-tooltip-top .arrow::before,
.bs-tooltip-auto[x-placement^="top"] .arrow::before { border-top-color: var(--cor-texto); }
.bs-tooltip-bottom .arrow::before,
.bs-tooltip-auto[x-placement^="bottom"] .arrow::before { border-bottom-color: var(--cor-texto); }
.bs-tooltip-left .arrow::before,
.bs-tooltip-auto[x-placement^="left"] .arrow::before { border-left-color: var(--cor-texto); }
.bs-tooltip-right .arrow::before,
.bs-tooltip-auto[x-placement^="right"] .arrow::before { border-right-color: var(--cor-texto); }

/* --- lista (list-group) ----------------------------------------------------
   O item ativo era um bloco azul cheio — o mesmo problema do badge antigo:
   grita mais que o conteúdo. Vira o desenho das abas: fundo suave e um traço
   na cor. */
.list-group-item {
  border-color: var(--cor-borda);
  padding: var(--esp-3) var(--esp-4);
}
.list-group-item:first-child {
  border-top-left-radius: var(--raio-lg);
  border-top-right-radius: var(--raio-lg);
}
.list-group-item:last-child {
  border-bottom-left-radius: var(--raio-lg);
  border-bottom-right-radius: var(--raio-lg);
}
.list-group-item-action:hover,
.list-group-item-action:focus { background-color: var(--cor-hover-neutro); }
.list-group-item.active {
  background-color: var(--cor-primaria-suave);
  border-color: var(--cor-borda);
  color: var(--cor-primaria-ativa);
  font-weight: var(--peso-medio);
  box-shadow: inset 3px 0 0 var(--cor-primaria);
}

/* --- barra de progresso ----------------------------------------------------
   Fina e em pílula, como as barras de capacidade que a logística já usa. As
   barras do kit mobile têm classes próprias e CSS que entra depois — não são
   tocadas por isto. */
.progress {
  height: 8px;
  border-radius: var(--raio-pilula);
  background-color: var(--cor-superficie-alt);
}
.progress-bar { background-color: var(--cor-primaria); }

/* --- select2 ---------------------------------------------------------------
   O widget de escolha mais usado do sistema (165 chamadas, tema `bootstrap-5`
   dentro de um site Bootstrap 4). Até 10/09/2026 o dropdown misturava dois
   padrões: caixa de busca com o anel azul do Bootstrap 5, texto de 16px num
   site de 14px, escolhido em azul chapado. Agora ele é o MENU SUSPENSO da
   seção 20 — mesma borda, canto, sombra e densidade — com a busca num campo
   pequeno e as etiquetas do múltiplo em pílula (opção A de três, 10/09/2026).

   O !important é obrigatório: o CSS do select2 e o tema entram DEPOIS do
   componentes.css no base.html, então sem ele nenhuma destas regras vence. */
.select2-dropdown {
  border: 1px solid var(--cor-borda) !important;
  border-radius: 0 0 var(--raio-lg) var(--raio-lg) !important;
  box-shadow: var(--sombra-md) !important;
  padding: 4px 0 !important;
  color: var(--cor-texto);
}
.select2-dropdown--above { border-radius: var(--raio-lg) var(--raio-lg) 0 0 !important; }

/* Busca: campo pequeno (32px) com o anel de foco do site, não o do Bootstrap 5. */
.select2-dropdown .select2-search { padding: 6px 10px 8px !important; }
.select2-dropdown .select2-search__field {
  height: 32px !important;
  padding: 4px 10px !important;
  font-size: var(--fonte-md) !important;
  border: 1px solid var(--cor-borda) !important;
  border-radius: var(--raio-md) !important;
  box-shadow: none !important;
}
.select2-dropdown .select2-search__field:focus {
  outline: none;
  border-color: var(--cor-primaria) !important;
  box-shadow: var(--sombra-foco) !important;
}

/* Opções: a densidade do .dropdown-item (8×16, 14px). */
.select2-results__option {
  padding: 8px 16px !important;
  font-size: var(--fonte-md) !important;
  line-height: 1.4 !important;
  color: var(--cor-texto) !important;
}
/* Só a lista de fora (a que rola). A de dentro de cada optgroup também é
   .select2-results__options: limitada a 264px sem rolagem, o grupo seguinte
   era desenhado por cima dos itens que sobravam. */
.select2-results__options:not(.select2-results__options--nested) { max-height: 264px !important; }
.select2-results__option--highlighted {
  background-color: var(--cor-hover-neutro) !important;
  color: var(--cor-texto) !important;
}
/* Só `--selected`: no select2 4.1 o `aria-selected="true"` marca o item sob o
   mouse/teclado, não o escolhido — com ele aqui, o destacado ganhava o check. */
.select2-results__option--selected {
  display: flex;
  align-items: center;
  font-weight: var(--peso-forte);
  background-color: var(--cor-primaria-suave) !important;
  color: var(--cor-primaria-ativa) !important;
}
.select2-results__option--selected::after {
  content: "\f00c";
  font-family: "Font Awesome 6 Free";
  font-weight: 900;
  font-size: 11px;
  margin-left: auto;
  color: var(--cor-primaria);
}
/* Grupo (optgroup) e as mensagens do próprio select2 ("Digite pelo menos…",
   "Nenhum resultado", "Buscando…"). */
.select2-results__group {
  display: block;
  padding: 8px 16px 4px !important;
  font-size: var(--fonte-xs) !important;
  font-weight: 700 !important;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--cor-texto-suave) !important;
}
.select2-results__option--group { padding: 0 !important; }
.select2-results__message {
  padding: 8px 16px !important;
  font-size: var(--fonte-sm) !important;
  color: var(--cor-texto-suave) !important;
  background-color: transparent !important;
}
.select2-results__message::before {
  content: "\f05a";
  font-family: "Font Awesome 6 Free";
  font-weight: 900;
  margin-right: 6px;
  color: var(--cor-texto-fraco);
}

/* Múltiplo: as escolhas viram pílulas primária-suave, com o × desenhado pela
   fonte de ícones (o tema desenha o × como imagem de fundo, e some quando o
   fundo muda). O select2 4.1 põe o botão ANTES do texto; `order: 2` leva
   para depois. */
.select2-container--bootstrap-5 .select2-selection--multiple .select2-selection__rendered .select2-selection__choice {
  gap: 4px;
  padding: 2px 8px !important;
  margin: 3px 4px 3px 0 !important;
  font-size: var(--fonte-xs) !important;
  font-weight: var(--peso-forte);
  border: 0 !important;
  border-radius: var(--raio-pilula) !important;
  background-color: var(--cor-primaria-suave) !important;
  color: var(--cor-primaria-ativa) !important;
}
.select2-container--bootstrap-5 .select2-selection--multiple .select2-selection__rendered .select2-selection__choice .select2-selection__choice__remove {
  order: 2;
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
  width: 16px !important;
  height: 16px !important;
  padding: 0 !important;
  margin: 0 -2px 0 0 !important;
  border: 0 !important;
  border-radius: var(--raio-circulo);
  background: none !important;
  text-indent: 0 !important;
  overflow: visible !important;
  font-size: 10px;
  line-height: 1;
  color: var(--cor-primaria) !important;
  cursor: pointer;
}
.select2-selection__choice__remove > span { display: none; }
.select2-selection__choice__remove::before {
  content: "\f00d";
  font-family: "Font Awesome 6 Free";
  font-weight: 900;
}
.select2-container--bootstrap-5 .select2-selection--multiple .select2-selection__rendered .select2-selection__choice .select2-selection__choice__remove:hover {
  background: var(--cor-primaria) !important;
  color: #fff !important;
}

/* O tema `bootstrap-5` do select2 escreve o foco com um seletor mais pesado
   e também com !important — aí especificidade desempata, e a genérica perdia.
   Por isso a variante com o nome do tema junto. */
.select2-container--open .select2-selection,
.select2-container--bootstrap-5.select2-container--open .select2-selection,
.select2-container--bootstrap-5 .select2-selection:focus {
  border-color: var(--cor-primaria) !important;
  box-shadow: var(--sombra-foco) !important;
}


/* ==========================================================================
   16. AÇÕES DE TABELA

   O botão "Ações" que abre o menu de operações da linha. Antes eram cinco
   aparências diferentes conforme a tela: "Ações ⌄" outline-secondary sm
   (venda interna, componentes), a mesma coisa em xs com style inline
   (regras de comissão, tabelas de preço), btn-light com borda (usuários e
   grupos), outline-primary sem sm (lista de orçamentos) e um kebab ⋮
   outline-primary com padding inline (faturamento).

   Padrão de 02/09/2026: o HÍBRIDO — "Ações ⌄" no desktop, kebab ⋮ abaixo
   de 576px.

   TROCADO EM 04/09/2026 pelo kebab em qualquer largura (opção A de três
   novos protótipos). O híbrido estava certo linha a linha e errado na
   página: numa tabela de 30 linhas a última coluna virava uma parede de 30
   caixas iguais, e o rótulo repetia o cabeçalho "AÇÕES" que já estava ali.
   Sem borda e sem fundo a coluna cai de ~90px para 48px, e o desktop passa a
   mostrar o mesmo botão do celular — uma aparência a menos para manter.

   O markup tem os dois ícones e o CSS mostra um por vez — assim a troca
   desktop/celular não precisa de JS nem de markup duplicado:

     <button type="button" class="hrs-tabela-acoes" data-toggle="dropdown"
             aria-haspopup="true" aria-expanded="false" aria-label="Ações">
       <span class="hrs-tabela-acoes-texto">Ações</span>
       <i class="fas fa-chevron-down hrs-tabela-acoes-seta" aria-hidden="true"></i>
       <i class="fas fa-ellipsis-vertical hrs-tabela-acoes-kebab" aria-hidden="true"></i>
     </button>

   Em template use o include components/acoes_tabela.html; em JS,
   Horus.acoesTabelaHtml() (componentes.js) — os três lugares precisam
   concordar no markup.

   NÃO use a classe `dropdown-toggle` junto: ela desenharia o caret do
   Bootstrap além da nossa seta. O `data-display="static"` é OBRIGATÓRIO no
   botão: ele desliga o Popper, que senão reescreveria a posição DEPOIS do
   nosso conserto (o translate3d dele atropelava o position:fixed — visto no
   teste, não deduzido). O conserto do menu cortado pelo .table-responsive
   vive no componentes.js: position:fixed enquanto aberto, escolhido no
   lugar do reparent pro <body> porque reparentar quebraria handlers
   delegados no container (lista de orçamentos) e os closest("tr") dos
   itens (custo de componente).
   ========================================================================== */

.hrs-tabela-acoes {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: none;
  border-radius: var(--raio-circulo);
  background: transparent;
  color: var(--cor-texto-suave);
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  transition: background-color var(--transicao-rapida), color var(--transicao-rapida);
}
.hrs-tabela-acoes:hover {
  background: var(--cor-hover-neutro);
  color: var(--cor-texto);
}
.hrs-tabela-acoes:focus-visible {
  outline: none;
  box-shadow: var(--sombra-foco);
}
/* Com o menu aberto o circulo fica marcado: sem borda nem fundo em repouso,
   ele e a unica pista de qual linha esta aberta. */
.hrs-tabela-acoes[aria-expanded="true"] {
  background: var(--cor-hover-neutro);
  color: var(--cor-texto);
}

/* O rotulo e a seta do desenho anterior ficam ESCONDIDOS, nao apagados: o
   include e o helper ja nao os trazem, mas basta uma copia antiga em tela
   para aparecer "Acoes v" ao lado do kebab.
   Dois seletores de proposito: o all.min.css do Font Awesome carrega DEPOIS
   do componentes.css e traz `.fas { display: inline-block }` — com um
   seletor so, o `display: none` da seta perderia o empate (visto no teste). */
.hrs-tabela-acoes .hrs-tabela-acoes-texto,
.hrs-tabela-acoes .hrs-tabela-acoes-seta { display: none; }

/* No celular o alvo de toque cresce; o desenho e o mesmo. */
@media (max-width: 575.98px) {
  .hrs-tabela-acoes { width: 36px; height: 36px; }
}


/* ==========================================================================
   18. INPUT-GROUP (repintado) — opção A, escolhida em 02/09/2026

   279 usos em 52 telas: campo com calendário, "R$" na frente, lupa atrás. O
   addon do Bootstrap vinha cinza #e9ecef com borda #ced4da e raio de 4px,
   destoando do campo já repintado. Fica a caixa suave da paleta, a borda do
   sistema e o raio do campo nos cantos externos — só CSS, nenhum template
   muda.
   ========================================================================== */
.input-group > .input-group-prepend > .input-group-text,
.input-group > .input-group-append > .input-group-text {
  background-color: var(--cor-superficie-alt);
  border-color: var(--cor-borda);
  color: var(--cor-texto-suave);
}
.input-group > .input-group-prepend > .input-group-text { border-radius: var(--raio-md) 0 0 var(--raio-md); }
.input-group > .input-group-append > .input-group-text,
.input-group > .input-group-append > .btn:last-child { border-top-right-radius: var(--raio-md); border-bottom-right-radius: var(--raio-md); }
.input-group > .form-control:not(:first-child) { border-top-left-radius: 0; border-bottom-left-radius: 0; }
.input-group > .form-control:not(:last-child) { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.input-group > .form-control:first-child { border-top-left-radius: var(--raio-md); border-bottom-left-radius: var(--raio-md); }
.input-group > .form-control:last-child { border-top-right-radius: var(--raio-md); border-bottom-right-radius: var(--raio-md); }
/* botão anexado fantasma: continua a borda do campo em vez de virar um botão cinza sólido */
.input-group > .input-group-append > .btn-outline-secondary,
.input-group > .input-group-append > .btn-default,
.input-group > .input-group-append > .btn-secondary,
.input-group > .input-group-append > .btn-light {
  background-color: var(--cor-superficie-alt);
  border-color: var(--cor-borda);
  color: var(--cor-texto-suave);
}
.input-group > .input-group-append > .btn-outline-secondary:hover,
.input-group > .input-group-append > .btn-default:hover,
.input-group > .input-group-append > .btn-secondary:hover,
.input-group > .input-group-append > .btn-light:hover {
  background-color: var(--cor-hover-neutro);
  color: var(--cor-texto);
}


/* ==========================================================================
   19. COR DA AÇÃO NO RODAPÉ DE MODAL (repintado) — opção A, 02/09/2026

   271 botões em 166 rodapés, a cor decidida por tela: "Salvar" azul aqui,
   verde ali; "Cancelar" cinza em 65 modais e VERMELHO em 38. A regra agora é
   uma e não interpreta verbo:

     quem fecha o modal (data-dismiss)  → fantasma (borda fina, sem cor)
     a ação principal                    → primária, seja "Salvar" ou "Concluir"
     a ação destrutiva (btn-danger)      → continua vermelha

   É repintura porque o markup já diz tudo que precisa: `data-dismiss` marca
   o Cancelar, `btn-danger` sem dismiss marca o destrutivo. btn-success,
   btn-warning e btn-info sem dismiss viram primária.

   O SEGUNDO BOTÃO DE AÇÃO (markup, opção A de 03/09/2026)

   O único caso que o CSS não alcança é um rodapé com DUAS ações ("Baixar" ao
   lado de "Abrir em nova aba"): sem marcação, os dois ficam primários. A
   regra é de markup, e vale para os 7 rodapés que tinham isso:

     Cancelar (data-dismiss)  |  2ª ação: btn-outline-primary  |  principal: btn-primary
     2ª ação destrutiva ("Excluir aviso" ao lado de "Salvar aviso"): btn-outline-danger

   Não há regra extra aqui: o .btn-outline-primary já é repintado na seção 11
   e o .btn-outline-danger do Bootstrap já usa a cor de perigo da paleta.
   Nada de `justify-content-between` para separar a 2ª ação — ela fica junto
   da principal, e a ordem visual é a do HTML.
   ========================================================================== */
.modal-footer .btn[data-dismiss="modal"],
.modal-footer .btn[data-dismiss="modal"]:focus {
  background-color: transparent;
  background-image: none;
  border-color: var(--cor-borda);
  color: var(--cor-texto-medio);
  box-shadow: none;
}
.modal-footer .btn[data-dismiss="modal"]:hover {
  background-color: var(--cor-hover-neutro);
  border-color: var(--cor-borda-forte);
  color: var(--cor-texto);
}
.modal-footer .btn-success:not([data-dismiss]),
.modal-footer .btn-warning:not([data-dismiss]),
.modal-footer .btn-info:not([data-dismiss]) {
  background-color: var(--cor-primaria);
  background-image: none;
  border-color: var(--cor-primaria);
  color: #fff;
}
.modal-footer .btn-success:not([data-dismiss]):hover,
.modal-footer .btn-warning:not([data-dismiss]):hover,
.modal-footer .btn-info:not([data-dismiss]):hover {
  background-color: var(--cor-primaria-hover);
  border-color: var(--cor-primaria-hover);
  color: #fff;
}


/* ==========================================================================
   20. KPI — info-box e small-box (repintados) — opção A, 02/09/2026

   ~97 usos na home e nos dashboards, em 7 cores. O info-box do AdminLTE tem
   o ícone num bloco colorido cheio e sombra; o small-box é o bloco inteiro
   colorido. Fica o cartão com borda (como o card), o ícone na caixinha suave
   — o mesmo desenho do cabeçalho de modal e da timeline — e o número em
   destaque. As cores por classe (bg-*) viram o par cor/fundo suave; como o
   AdminLTE declara `.bg-x { background-color: … !important }`, aqui também
   precisa de !important para ganhar.
   ========================================================================== */
.info-box {
  box-shadow: none;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio-lg);
  background-color: var(--cor-superficie);
  min-height: 0;
  padding: var(--esp-3) var(--esp-4);
  align-items: center;
}
.info-box .info-box-icon {
  width: 44px;
  height: 44px;
  border-radius: var(--raio-md);
  font-size: 18px;
  flex: 0 0 44px;
}
.info-box .info-box-content { padding: 0 0 0 var(--esp-3); line-height: 1.25; }
.info-box .info-box-text { font-size: 12px; color: var(--cor-texto-suave); text-transform: uppercase; letter-spacing: .04em; }
.info-box .info-box-number { font-size: 22px; font-weight: 700; color: var(--cor-texto); margin-top: 2px; }

.info-box .info-box-icon.bg-primary, .info-box .info-box-icon.bg-blue   { background-color: var(--cor-primaria-suave) !important; color: var(--cor-primaria) !important; }
.info-box .info-box-icon.bg-success, .info-box .info-box-icon.bg-green  { background-color: var(--cor-sucesso-suave) !important;  color: var(--cor-sucesso) !important; }
.info-box .info-box-icon.bg-danger,  .info-box .info-box-icon.bg-red    { background-color: var(--cor-perigo-suave) !important;   color: var(--cor-perigo) !important; }
.info-box .info-box-icon.bg-warning, .info-box .info-box-icon.bg-yellow { background-color: var(--cor-aviso-suave) !important;    color: var(--cor-aviso-texto) !important; }
.info-box .info-box-icon.bg-info,    .info-box .info-box-icon.bg-teal   { background-color: var(--cor-info-suave) !important;     color: var(--cor-info) !important; }
.info-box .info-box-icon.bg-default, .info-box .info-box-icon.bg-secondary, .info-box .info-box-icon.bg-gray, .info-box .info-box-icon.bg-dark {
  background-color: var(--cor-hover-neutro) !important; color: var(--cor-texto-suave) !important;
}

.small-box {
  box-shadow: none;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio-lg);
  background-color: var(--cor-superficie) !important;
  color: var(--cor-texto) !important;
}
.small-box > .inner { padding: var(--esp-3) var(--esp-4); }
.small-box > .inner h3 { font-size: 22px; font-weight: 700; color: var(--cor-texto); }
.small-box > .inner p { font-size: 12px; color: var(--cor-texto-suave); text-transform: uppercase; letter-spacing: .04em; margin: 2px 0 0; }
.small-box > .icon { top: 12px; right: 14px; font-size: 44px; color: var(--cor-borda) !important; transition: none; }
.small-box:hover > .icon { font-size: 44px; }
.small-box > .small-box-footer { background-color: var(--cor-superficie-alt) !important; color: var(--cor-texto-medio) !important; border-top: 1px solid var(--cor-borda); border-radius: 0 0 var(--raio-lg) var(--raio-lg); }
.small-box > .small-box-footer:hover { color: var(--cor-texto) !important; }
.small-box.bg-primary > .icon, .small-box.bg-blue > .icon   { color: var(--cor-primaria-suave) !important; }
.small-box.bg-success > .icon, .small-box.bg-green > .icon  { color: var(--cor-sucesso-suave) !important; }
.small-box.bg-danger  > .icon, .small-box.bg-red > .icon    { color: var(--cor-perigo-suave) !important; }
.small-box.bg-warning > .icon, .small-box.bg-yellow > .icon { color: var(--cor-aviso-suave) !important; }
.small-box.bg-info    > .icon, .small-box.bg-teal > .icon   { color: var(--cor-info-suave) !important; }
/* a cor do bloco vira uma faixa fina no topo, para não perder a leitura rápida */
.small-box.bg-primary, .small-box.bg-blue   { border-top: 3px solid var(--cor-primaria); }
.small-box.bg-success, .small-box.bg-green  { border-top: 3px solid var(--cor-sucesso); }
.small-box.bg-danger,  .small-box.bg-red    { border-top: 3px solid var(--cor-perigo); }
.small-box.bg-warning, .small-box.bg-yellow { border-top: 3px solid var(--cor-aviso); }
.small-box.bg-info,    .small-box.bg-teal   { border-top: 3px solid var(--cor-info); }


/* ==========================================================================
   21. COLLAPSE / ACORDEÃO (repintado) — opção B, 02/09/2026

   O padrão do sistema é o acordeão de cards: `.card > .card-header
   [data-toggle="collapse"]` seguido de `.collapse`. Cada seção vira um bloco
   com borda; a aberta ganha o cabeçalho em fundo suave primário, para ficar
   claro onde se está. O chevron (quando existe) gira. Só alcança o padrão
   card + collapse; botões soltos com data-toggle="collapse" são outra coisa
   (mostrar/esconder um trecho) e ficam como estão.
   ========================================================================== */
.card > .card-header[data-toggle="collapse"] {
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-weight: 600;
  background-color: transparent;
  transition: background-color var(--transicao-rapida), color var(--transicao-rapida);
}
.card > .card-header[data-toggle="collapse"] .fa-chevron-down,
.card > .card-header[data-toggle="collapse"] .fa-angle-down {
  color: var(--cor-texto-fraco);
  transition: transform var(--transicao-rapida);
}
.card:has(> .collapse.show) > .card-header[data-toggle="collapse"] {
  background-color: var(--cor-primaria-suave);
  color: var(--cor-primaria);
}
.card:has(> .collapse.show) > .card-header[data-toggle="collapse"] .fa-chevron-down,
.card:has(> .collapse.show) > .card-header[data-toggle="collapse"] .fa-angle-down {
  transform: rotate(180deg);
  color: var(--cor-primaria);
}
.accordion > .card { margin-bottom: var(--esp-2); border: 1px solid var(--cor-borda); border-radius: var(--raio-md); overflow: hidden; }
.accordion > .card > .card-header { border-radius: 0; }


/* ==========================================================================
   22. INTERRUPTOR custom-switch (repintado) — opção A, 02/09/2026

   Ficou fora da repintura de checkbox de propósito: é outro controle (liga
   na hora, sem salvar). Aqui só troca o azul velho #007bff do "ligado" pela
   primária e a borda pelo token; o desenho do Bootstrap fica.
   ========================================================================== */
.custom-switch .custom-control-label::before { border-color: var(--cor-borda-forte); background-color: var(--cor-superficie); }
.custom-switch .custom-control-input:checked ~ .custom-control-label::before { background-color: var(--cor-primaria); border-color: var(--cor-primaria); }
.custom-switch .custom-control-input:focus ~ .custom-control-label::before { box-shadow: var(--sombra-foco); }
.custom-switch .custom-control-input:focus:not(:checked) ~ .custom-control-label::before { border-color: var(--cor-primaria); }
.custom-switch .custom-control-label::after { background-color: var(--cor-borda-forte); }
.custom-switch .custom-control-input:checked ~ .custom-control-label::after { background-color: #fff; }


/* ==========================================================================
   23. AÇÕES NO CABEÇALHO DO CARD — card-tools (repintado) — opção A, 02/09/2026

   Os botões do canto do card (`.btn-tool`: recolher, atualizar, fechar…)
   viram ícones fantasma circulares com fundo no hover — a mesma família do X
   do modal e do kebab no celular.
   ========================================================================== */
.card-tools .btn-tool,
.card:not(.card-outline) > .card-header .btn-tool {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  margin-left: 2px;
  border-radius: var(--raio-circulo);
  background-color: transparent;
  color: var(--cor-texto-suave);
  font-size: 13px;
}
.card-tools .btn-tool:hover,
.card:not(.card-outline) > .card-header .btn-tool:hover {
  background-color: var(--cor-hover-neutro);
  color: var(--cor-texto);
}
.card-tools .btn-tool:focus-visible { outline: none; box-shadow: var(--sombra-foco); }


/* ==========================================================================
   24. form-check (repintado)

   O Bootstrap 4 alinha o checkbox pelo topo da linha do rótulo (margin-top
   .3rem), o que deixa o quadrado de 16px da repintura de checkbox flutuando
   acima do texto. Centraliza.
   ========================================================================== */
.form-check { display: flex; align-items: center; gap: 8px; padding-left: 0; }
.form-check .form-check-input { position: static; margin: 0; }
.form-check .form-check-label { margin: 0; }
.form-check-inline { margin-right: var(--esp-4); }


/* ==========================================================================
   25. PAGINAÇÃO COMPACTA (componente) — components/paginacao.html
   O desenho dos números já é a repintura da seção 4; aqui só o arranjo
   resumo + navegação.
   ========================================================================== */
.hrs-paginacao { display: flex; align-items: center; justify-content: flex-end; gap: var(--esp-4); flex-wrap: wrap; }
.hrs-paginacao-com-resumo { justify-content: space-between; }
.hrs-paginacao-resumo { color: var(--cor-texto-medio); font-size: 13px; }
.hrs-paginacao .page-item.disabled .page-link { color: var(--cor-texto-fraco); background-color: transparent; }


/* ==========================================================================
   26. CABEÇALHO DE CARD COM UTILITY bg-* (repintado)

   A repintura do card (seção 3) deixou o cabeçalho branco com linha e
   transformou as variantes coloridas (card-primary, card-secondary…) numa
   faixa de 3px no topo. Sobrou um caso que ela não alcançava: a utility
   direto no cabeçalho — `card-header bg-secondary` nos dois dashboards da
   home e um `bg-primary` no admin. Ficavam como um bloco cinza-escuro com
   texto branco ao lado de cards brancos: era o "meio bugado" da home.

   Mesmo tratamento das variantes: cabeçalho branco, cor vira a faixa do
   topo. Com !important porque o AdminLTE declara `.bg-x { background-color:
   … !important; color: #fff !important }`.
   ========================================================================== */
.card > .card-header.bg-primary, .card > .card-header.bg-secondary, .card > .card-header.bg-success,
.card > .card-header.bg-danger, .card > .card-header.bg-warning, .card > .card-header.bg-info, .card > .card-header.bg-dark {
  background-color: transparent !important;
  color: var(--cor-texto) !important;
  border-bottom: 1px solid var(--cor-borda) !important;
}
.card > .card-header[class*="bg-"] .card-title,
.card > .card-header[class*="bg-"] a:not(.btn) { color: inherit !important; }
.card:has(> .card-header.bg-primary)   { border-top: 3px solid var(--cor-primaria); }
.card:has(> .card-header.bg-secondary) { border-top: 3px solid var(--cor-texto-suave); }
.card:has(> .card-header.bg-success)   { border-top: 3px solid var(--cor-sucesso); }
.card:has(> .card-header.bg-danger)    { border-top: 3px solid var(--cor-perigo); }
.card:has(> .card-header.bg-warning)   { border-top: 3px solid var(--cor-aviso); }
.card:has(> .card-header.bg-info)      { border-top: 3px solid var(--cor-info); }
.card:has(> .card-header.bg-dark)      { border-top: 3px solid var(--cor-texto); }


/* ==========================================================================
   27. AÇÃO NO CABEÇALHO DO CARD — card-tools com botão de texto — opção A, 03/09/2026

   "Novo grupo", "Nova rota", "Salvar alterações": 24 cabeçalhos tinham um
   botão de ação, em 4 cores (primary, success, info, bg-gradient-*) e 2
   tamanhos, cada um com seu próprio arranjo de row/col/d-flex. A regra:

     <div class="card-header d-flex align-items-center">
       <h3 class="card-title mb-0">Grupos</h3>
       <div class="card-tools">
         <button class="btn btn-sm btn-outline-secondary">Exportar</button>   auxiliar
         <button class="btn btn-sm btn-outline-primary">Novo grupo</button>   2ª ação
         <button class="btn btn-sm btn-primary">Nova hierarquia</button>      principal
       </div>
     </div>

   As cores são as mesmas do rodapé de modal (seção 19). O tamanho é o
   pequeno (31px): cabe na altura do cabeçalho sem engordá-lo — e aqui o CSS
   garante isso para qualquer .btn que caia no card-tools, com ou sem btn-sm.
   O `.card-tools` é o slot que o AdminLTE já tem (e que os .btn-tool da
   seção 23 usam); ele vem com margem negativa à direita, que aqui vira zero.
   ========================================================================== */
.card > .card-header > .card-tools {
  float: right;
  display: flex;
  align-items: center;
  gap: var(--esp-2);
  flex-shrink: 0; /* o texto do título encolhe; os botões, não */
  margin: 0 0 0 auto; /* o AdminLTE dá .3rem em cima e embaixo, que só engorda o cabeçalho */
}
/* Com botão de texto o cabeçalho encolhe o respiro vertical para ficar da
   mesma altura (≈47px) que um cabeçalho só com título (44px). */
.card > .card-header:has(> .card-tools > .btn:not(.btn-tool)) {
  padding-top: var(--esp-2);
  padding-bottom: var(--esp-2);
}
.card > .card-header > .card-tools > .btn:not(.btn-tool) {
  padding: .25rem .5rem;
  font-size: .875rem;
  line-height: 1.5;
  margin: 0;
}


/* ==========================================================================
   28. LINHA DO TEMPO — componente (03/09/2026)

   Escolhida a opção B entre três protótipos (A trilho com caixas, B feed sem
   caixas, C por dia com hora à esquerda): a maioria dos eventos é uma linha
   só ("fulano anexou o arquivo"), e caixa em volta de uma linha é contorno
   demais. Só ganha painel o evento que tem conteúdo (nota, De/Para, conversa).

   Markup: tag {% tl_item %} (templatetags/design_system.py) ou
   Horus.timelineItemHtml() (componentes.js). Cinco telas usam:
   negócio, perfil do grupo, histórico da atividade, histórico da rota (JS)
   e solicitação de projeto. Antes eram cinco cópias do .timeline do AdminLTE,
   cada uma com o seu inline style.
   ========================================================================== */
.hrs-timeline { padding: var(--esp-3) var(--esp-4) var(--esp-2); }

/* abas de filtro logo abaixo do cabeçalho do card (negócio) */
.hrs-timeline-filtros {
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--esp-2);
  padding: 0 var(--esp-4); border-bottom: 1px solid var(--cor-borda);
}
.hrs-timeline-filtros .nav-tabs { border-bottom: 0; flex-wrap: nowrap; overflow-x: auto; overflow-y: hidden; scrollbar-width: none; }
.hrs-timeline-filtros .nav-tabs::-webkit-scrollbar { display: none; }
.hrs-timeline-filtros .nav-link { padding: var(--esp-2) var(--esp-3); font-size: 14px; white-space: nowrap; }

.hrs-timeline-dia {
  font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--cor-texto-suave); margin: var(--esp-2) 0 var(--esp-3);
}

.hrs-timeline-item { position: relative; display: flex; gap: var(--esp-3); padding-bottom: var(--esp-4); }
/* o trilho é um pseudo por item: liga o ícone ao próximo e some no último */
.hrs-timeline-item::before {
  content: ""; position: absolute; left: 15px; top: 32px; bottom: 0; width: 2px; background: var(--cor-borda);
}
.hrs-timeline-item:last-child::before { display: none; }

.hrs-timeline-icone {
  width: 32px; height: 32px; border-radius: 50%; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center; font-size: 13px;
  background: var(--cor-primaria-suave); color: var(--cor-primaria);
}
.hrs-timeline-icone-sucesso { background: var(--cor-sucesso-suave); color: var(--cor-sucesso-texto); }
.hrs-timeline-icone-perigo  { background: var(--cor-perigo-suave);  color: var(--cor-perigo-texto); }
.hrs-timeline-icone-aviso   { background: var(--cor-aviso-suave);   color: var(--cor-aviso-texto); }
.hrs-timeline-icone-info    { background: var(--cor-info-suave);    color: var(--cor-info-texto); }
.hrs-timeline-icone-neutro  { background: var(--cor-superficie-alt); color: var(--cor-texto-suave); border: 1px solid var(--cor-borda); }

.hrs-timeline-texto { flex: 1; min-width: 0; padding-top: 6px; }
.hrs-timeline-linha1 { display: flex; align-items: baseline; gap: var(--esp-2); flex-wrap: wrap; }
.hrs-timeline-titulo { font-size: 14px; color: var(--cor-texto); line-height: 1.35; overflow-wrap: anywhere; }
.hrs-timeline-titulo b, .hrs-timeline-titulo strong { font-weight: 600; }
.hrs-timeline-quando { font-size: 12px; color: var(--cor-texto-suave); white-space: nowrap; }
.hrs-timeline-acoes { margin-left: auto; display: flex; align-items: center; gap: 2px; }
.hrs-timeline-acoes .btn-tool { padding: 2px 6px; }

.hrs-timeline-painel {
  margin-top: var(--esp-2); padding: var(--esp-2) var(--esp-3);
  border-radius: var(--raio-md); background: var(--cor-superficie-alt); border: 1px solid var(--cor-borda);
  font-size: 14px; color: var(--cor-texto-medio); overflow-wrap: anywhere;
}
.hrs-timeline-painel-texto { white-space: pre-line; }
.hrs-timeline-painel-tabela { padding: 0; overflow: hidden; }
.hrs-timeline-painel-tabela .table { margin: 0; font-size: 13px; }
.hrs-timeline-painel-tabela .table th { font-weight: 600; color: var(--cor-texto-suave); background: var(--cor-superficie); border-top: 0; white-space: nowrap; }
.hrs-timeline-painel-tabela .table td, .hrs-timeline-painel-tabela .table th { padding: .4rem .6rem; }
.hrs-timeline-painel-tabela .table-responsive { margin: 0; }
/* Mudanças campo a campo ({% tl_conteudo %}, design_system.py). Mesmo desenho no
   desktop e no celular, sem tabela: valor curto em uma linha ("de" riscado → "para");
   texto de várias linhas mostra só o que mudou (+ entrou, − saiu) com o resto apagado. */
.hrs-mudancas { display: flex; flex-direction: column; }
.hrs-mudanca { display: flex; align-items: baseline; gap: var(--esp-1) var(--esp-3); padding: 6px 0; }
.hrs-mudanca + .hrs-mudanca { border-top: 1px solid var(--cor-borda); }
.hrs-mudanca-campo {
  flex: 0 0 9rem; font-size: 12px; font-weight: 600; letter-spacing: .02em;
  text-transform: uppercase; color: var(--cor-texto-suave);
}
.hrs-mudanca-valores { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px var(--esp-2); min-width: 0; }
.hrs-mudanca-de { color: var(--cor-texto-suave); text-decoration: line-through; text-decoration-color: var(--cor-borda-forte); }
.hrs-mudanca-seta { font-size: 11px; color: var(--cor-texto-fraco); }
.hrs-mudanca-para { color: var(--cor-texto); font-weight: 600; }
.hrs-mudanca-longa { flex-direction: column; align-items: stretch; gap: var(--esp-1); }
.hrs-mudanca-longa .hrs-mudanca-campo { flex-basis: auto; }
.hrs-mudanca-texto { line-height: 1.5; border-radius: var(--raio-sm); overflow: hidden; }
.hrs-mudanca-linha { display: flex; gap: var(--esp-2); padding: 2px var(--esp-2); }
.hrs-mudanca-sinal { flex: 0 0 .75rem; font-weight: 700; }
.hrs-mudanca-linha-mais { background: var(--cor-sucesso-suave); color: var(--cor-sucesso-texto); }
.hrs-mudanca-linha-menos { background: var(--cor-perigo-suave); color: var(--cor-perigo-texto); }
.hrs-mudanca-linha-menos del { text-decoration-color: currentColor; }
.hrs-mudanca-linha-igual { color: var(--cor-texto-suave); }
.hrs-mudanca-linha-oculto { color: var(--cor-texto-suave); font-size: 12px; padding-left: calc(.75rem + 2 * var(--esp-2)); }
/* Texto trocado inteiro: o novo corrido e o anterior recolhido. Texto comprido:
   as linhas que mudaram passando de _TL_CORTE ficam em "Ver mais". */
.hrs-mudanca-nota { margin-left: var(--esp-1); font-size: 12px; font-weight: 600; text-transform: none; letter-spacing: 0; color: var(--cor-texto); }
.hrs-mudanca-subrotulo { display: block; font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .03em; color: var(--cor-texto-suave); }
.hrs-mudanca-agora { line-height: 1.5; color: var(--cor-texto); overflow-wrap: anywhere; }
.hrs-mudanca-anterior { line-height: 1.5; color: var(--cor-texto-suave); overflow-wrap: anywhere; border-left: 2px solid var(--cor-borda-forte); padding-left: var(--esp-3); margin-top: 2px; }
.hrs-mudanca-recolhido > summary { cursor: pointer; font-size: 12px; color: var(--cor-texto-suave); padding: 4px var(--esp-2); }
.hrs-mudanca-recolhido > summary:hover { color: var(--cor-texto); }
.hrs-mudanca-origem { font-size: 12px; color: var(--cor-texto-suave); margin-top: var(--esp-2); }
/* Vários itens de uma vez (as parcelas de um pedido): um bloco por item. */
.hrs-mudancas-grupo + .hrs-mudancas-grupo { border-top: 1px solid var(--cor-borda); margin-top: var(--esp-1); padding-top: var(--esp-1); }
.hrs-mudancas-grupo-titulo { display: flex; flex-wrap: wrap; align-items: center; gap: var(--esp-2); padding: 4px 0 2px; font-weight: 600; color: var(--cor-texto); }
.hrs-mudancas-grupo-valor { font-weight: 400; color: var(--cor-texto-suave); }
.hrs-mudancas-grupo .hrs-mudanca { padding-left: var(--esp-3); }
.hrs-mudancas-grupo .hrs-mudanca + .hrs-mudanca { border-top-style: dashed; }
/* Lista só reordenada (mesmos itens): a ordem inteira, Antes | Depois. */
.hrs-mudanca-colunas { display: grid; grid-template-columns: 1fr 1fr; gap: 0 var(--esp-3); }
.hrs-mudanca-coluna { min-width: 0; }
.hrs-mudanca-coluna + .hrs-mudanca-coluna { border-left: 1px solid var(--cor-borda); padding-left: var(--esp-3); }
.hrs-mudanca-coluna-rotulo {
  font-size: 11px; font-weight: 600; letter-spacing: .02em; text-transform: uppercase;
  color: var(--cor-texto-suave); margin-bottom: 2px;
}
.hrs-mudanca-coluna-item { display: flex; gap: var(--esp-2); padding: 2px 0; line-height: 1.5; color: var(--cor-texto); overflow-wrap: anywhere; }
.hrs-mudanca-coluna-num { flex: 0 0 1.25em; color: var(--cor-texto-suave); font-variant-numeric: tabular-nums; text-align: right; }
@media (max-width: 767.98px) {
  .hrs-mudanca { flex-direction: column; align-items: stretch; gap: 2px; }
  .hrs-mudanca-campo { flex-basis: auto; }
  .hrs-mudanca-colunas { grid-template-columns: 1fr; gap: var(--esp-2) 0; }
  .hrs-mudanca-coluna + .hrs-mudanca-coluna { border-left: 0; padding-left: 0; border-top: 1px solid var(--cor-borda); padding-top: var(--esp-2); }
  .hrs-mudanca-recolhido > summary { min-height: var(--mob-alvo-toque); padding-top: 14px; padding-bottom: 14px; font-size: 13px; }
}

@media (max-width: 575.98px) {
  .hrs-timeline { padding-left: var(--esp-3); padding-right: var(--esp-3); }
  .hrs-timeline-quando { flex-basis: 100%; }
}


/* ==========================================================================
   29. ANEXO — item de arquivo em lista (03/09/2026, opção A)

   Oito telas desenhavam "um arquivo" de oito jeitos (negócio, fluxo,
   solicitação de projeto, filas de upload…). Agora é um item só:
   ícone de 40px colorido pelo tipo (ou a miniatura), nome como link,
   meta em cinza (tamanho · data) e as ações em btn-tool à direita.
   Markup por Horus.anexoHtml()/anexoEl() (componentes.js) ou pelo include
   components/anexo.html. O container da lista leva .hrs-anexos.
   ========================================================================== */
.hrs-anexos { padding: 0; }
.hrs-anexo { display: flex; align-items: center; gap: var(--esp-3); padding: var(--esp-2) var(--esp-4); border-bottom: 1px solid var(--cor-borda); }
.hrs-anexo:last-child { border-bottom: 0; }
.hrs-anexo-ic {
  width: 40px; height: 40px; border-radius: var(--raio-md); flex-shrink: 0; overflow: hidden;
  display: flex; align-items: center; justify-content: center; font-size: 17px;
  background: var(--cor-superficie-alt); color: var(--cor-texto-suave); text-decoration: none;
}
a.hrs-anexo-ic:hover { color: var(--cor-texto); text-decoration: none; }
.hrs-anexo-ic img { width: 100%; height: 100%; object-fit: cover; display: block; }
.hrs-anexo-ic-pdf          { background: var(--cor-perigo-suave);   color: var(--cor-perigo-texto); }
.hrs-anexo-ic-documento,
.hrs-anexo-ic-apresentacao,
.hrs-anexo-ic-codigo       { background: var(--cor-primaria-suave); color: var(--cor-primaria); }
.hrs-anexo-ic-planilha     { background: var(--cor-sucesso-suave);  color: var(--cor-sucesso-texto); }
.hrs-anexo-ic-compactado,
.hrs-anexo-ic-modelo3d     { background: var(--cor-aviso-suave);    color: var(--cor-aviso-texto); }
.hrs-anexo-txt { flex: 1; min-width: 0; }
.hrs-anexo-nome { font-size: 14px; font-weight: 600; display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hrs-anexo-meta { font-size: 12px; color: var(--cor-texto-suave); }
.hrs-anexo-acoes { display: flex; align-items: center; gap: 2px; flex-shrink: 0; }
.hrs-anexo-acoes .btn-tool { padding: 3px 7px; color: var(--cor-texto-suave); }
.hrs-anexo-acoes .btn-tool:hover { color: var(--cor-texto); }
.hrs-anexo-acoes .btn-tool.hrs-anexo-perigo:hover { color: var(--cor-perigo); }
.hrs-anexo-enviando { background: var(--cor-superficie-alt); }
.hrs-anexo-progresso { height: 4px; border-radius: 2px; background: var(--cor-borda); margin-top: 6px; overflow: hidden; }
.hrs-anexo-progresso > span { display: block; height: 100%; background: var(--cor-primaria); transition: width .2s; }
@media (max-width: 575.98px) { .hrs-anexo { padding-left: var(--esp-3); padding-right: var(--esp-3); } }

/* ==========================================================================
   30. CARD DE TAREFA

   Nasceu na tela do negócio (opção B, 03/09/2026) e passou para cá quando
   o modal do fluxo de pedido precisou do mesmo card: um card por tarefa,
   tudo à vista, faixa colorida à esquerda pelo estado.

     <div class="card hrs-card tarefa-card hrs-card-faixa-primaria">
       <div class="card-header tarefa-cab">
         <div class="tarefa-icone"><i class="fa-regular fa-calendar fa-lg"></i></div>
         <div class="tarefa-texto">
           <div class="tarefa-titulo">…</div>
           <div class="tarefa-meta">…</div>
         </div>
         <div class="tarefa-acoes">…</div>
       </div>
       <div class="tarefa-corpo">descrição</div>
     </div>

   O wrapper mantém `.card` e o cabeçalho `.card-header` porque o JS do
   negócio usa closest(".card") e closest(".card-header").attr("id").
   Faixas: primaria (aberta), perigo (vencida ou análise reprovada), sucesso
   (análise aprovada / encerrada). `.tarefa-encerrada` apaga o título.
   ========================================================================== */
.tarefa-card { box-shadow: none; margin-bottom: var(--esp-3); }
/* a faixa perdia para a borda do .card do AdminLTE; repete com mais peso */
.card.tarefa-card.hrs-card-faixa-perigo   { border-left: 3px solid var(--cor-perigo); }
.card.tarefa-card.hrs-card-faixa-primaria { border-left: 3px solid var(--cor-primaria); }
.tarefa-card > .card-header.tarefa-cab {
  display: flex; align-items: flex-start; gap: var(--esp-3);
  padding: var(--esp-3) var(--esp-4); border-bottom: 0; background: transparent;
}
.tarefa-icone {
  width: 40px; height: 40px; flex-shrink: 0; border-radius: var(--raio-md);
  display: flex; align-items: center; justify-content: center;
  background: var(--cor-primaria-suave); color: var(--cor-primaria);
}
.tarefa-icone-vencida { background: var(--cor-perigo-suave); color: var(--cor-perigo); }
.tarefa-texto { min-width: 0; flex: 1; }
.tarefa-titulo { font-weight: 600; font-size: 15px; line-height: 1.3; color: var(--cor-texto); }
.tarefa-meta {
  display: flex; align-items: center; gap: var(--esp-2); flex-wrap: wrap;
  margin-top: 2px; font-size: 13px; color: var(--cor-texto-suave);
}
.tarefa-meta + .tarefa-meta { margin-top: 4px; }
.tarefa-sep { opacity: .5; }
/* 'criada por' fica sempre numa linha própria, em vez de quebrar no meio */
.tarefa-criador { flex-basis: 100%; }
.tarefa-acoes { margin-left: auto; display: flex; align-items: center; gap: var(--esp-2); flex-shrink: 0; }
.tarefa-acoes .btn-tool { color: var(--cor-texto-suave); }
.tarefa-corpo {
  padding: 0 var(--esp-4) var(--esp-3) calc(var(--esp-4) + 40px + var(--esp-3));
  font-size: 14px; color: var(--cor-texto-medio); white-space: pre-line; overflow-wrap: anywhere;
}
/* Sem descrição: o rodapé vem logo depois do cabeçalho, sem bloco vazio. */
.tarefa-card > .card-header.tarefa-cab { padding-bottom: var(--esp-3); }
@media (max-width: 767.98px) {
  .tarefa-card > .card-header.tarefa-cab { flex-wrap: wrap; }
  .tarefa-acoes { margin-left: 0; width: 100%; justify-content: flex-end; }
  .tarefa-corpo { padding-left: var(--esp-4); }
}
/* Análise de crédito: mesmo card. A identidade do tipo é o ÍCONE verde; a faixa segue a
   situação (primaria aberta, sucesso aprovada, perigo reprovada) — ver README, seção 30. */
.tarefa-icone-analise { background: var(--cor-sucesso-suave); color: var(--cor-sucesso); }
.card.tarefa-card.hrs-card-faixa-sucesso { border-left: 3px solid var(--cor-sucesso); }
.tarefa-encerrada .tarefa-titulo { color: var(--cor-texto-suave); }
.tarefa-encerrada .tarefa-icone-analise { opacity: .6; }


/* ==========================================================================
   31. BOTÃO SOBRE COR — opção A "vidro" (03/09/2026)

   Os botões do cabeçalho da etapa no board de negócios viraram
   btn-outline-secondary na leva da paleta (eecfcc29d) e sumiram sobre a cor
   da etapa: cinza sobre laranja, roxo, azul… Este é o botão para qualquer
   superfície colorida ou escura: branco translúcido, que pega a cor do fundo
   por transparência e clareia no hover.

     <div class="card-header" style="background:#FF8730">
       <button class="btn btn-xs btn-sobre-cor" title="Ordenar"><i class="fas fa-sort-amount-down"></i></button>
     </div>

   Em fundo CLARO (amarelo, verde-água) o branco não segura: o contêiner
   recebe `.sobre-cor-clara` (filtro `cor_clara` do design_system.py) e o
   botão e o texto viram escuros.
   ========================================================================== */
.btn-sobre-cor {
  color: #fff;
  background-color: rgba(255, 255, 255, .22);
  border: 1px solid rgba(255, 255, 255, .35);
  box-shadow: none;
}
.btn-sobre-cor:hover, .btn-sobre-cor:focus, .btn-sobre-cor:not(:disabled):active,
.show > .btn-sobre-cor.dropdown-toggle {
  color: #fff;
  background-color: rgba(255, 255, 255, .4);
  border-color: rgba(255, 255, 255, .5);
  box-shadow: none;
}
.btn-sobre-cor:focus-visible { box-shadow: 0 0 0 3px rgba(255, 255, 255, .45); }
/* ícone sozinho: quadrado, para os três alinharem */
.btn-sobre-cor.btn-xs { width: 26px; height: 26px; padding: 0; display: inline-flex; align-items: center; justify-content: center; font-size: 12px; }
.btn-sobre-cor.dropdown-toggle::after { display: none; }

.sobre-cor-clara { color: var(--cor-texto); }
.sobre-cor-clara .btn-sobre-cor {
  color: var(--cor-texto);
  background-color: rgba(0, 0, 0, .08);
  border-color: rgba(0, 0, 0, .15);
}
.sobre-cor-clara .btn-sobre-cor:hover, .sobre-cor-clara .btn-sobre-cor:focus,
.sobre-cor-clara .btn-sobre-cor:not(:disabled):active {
  color: var(--cor-texto);
  background-color: rgba(0, 0, 0, .16);
  border-color: rgba(0, 0, 0, .22);
}
/* título e alça de arrastar seguem o mesmo contraste (o inline `color: white`
   do template perde para o !important aqui de propósito) */
.sobre-cor-clara .card-title, .sobre-cor-clara .etapa-drag-handle { color: var(--cor-texto) !important; }


/* ==========================================================================
   32. BARRA DE ROLAGEM — opção 1 (03/09/2026): fina, sempre visível

   Uma regra para o site inteiro: a página e qualquer caixa que role. Antes
   havia dez arquivos de CSS com barras próprias (painel de filtros, anexos,
   menu lateral, rotas, propostas…), cada uma de uma cor e largura. No
   celular o sistema desenha as barras dele e nada disto vale.

   Quem precisa ESCONDER a barra (abas que rolam de lado, kit mobile) continua
   com `scrollbar-width: none` + `::-webkit-scrollbar { display: none }` no
   próprio seletor, que vence o `*` daqui.
   ========================================================================== */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--cor-borda-forte) transparent;
}
*::-webkit-scrollbar { width: 8px; height: 8px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-corner { background: transparent; }
*::-webkit-scrollbar-thumb {
  background: var(--cor-borda-forte);
  border-radius: 8px;
  border: 2px solid transparent;   /* respiro: o polegar não encosta na borda da caixa */
  background-clip: padding-box;
}
*::-webkit-scrollbar-thumb:hover { background: var(--cor-texto-fraco); background-clip: padding-box; }
/* fundo escuro (menu lateral e o que mais usar .hrs-rolagem-escura) */
.main-sidebar .sidebar, .hrs-rolagem-escura { scrollbar-color: rgba(255, 255, 255, .3) transparent; }
.main-sidebar .sidebar::-webkit-scrollbar-thumb, .hrs-rolagem-escura::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, .3); background-clip: padding-box; }
.main-sidebar .sidebar::-webkit-scrollbar-thumb:hover, .hrs-rolagem-escura::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, .5); background-clip: padding-box; }


/* ==========================================================================
   33. CAMPO NATIVO — o <select class="custom-select"> e o foco dos campos
   (04/09/2026)

   Varredura de 04/09: sete telas usam o `<select class="custom-select">` do
   Bootstrap (rotas, veículos, motoristas, atividades, montagem de rota,
   metragens e o fluxo). Ele nunca tinha sido repintado, e ficava diferente do
   `.form-control` ao lado por duas coisas medidas no CSS do AdminLTE:

   1. **Sombra interna.** O `.custom-select` traz `inset 0 1px 2px rgba(0,0,0,.075)`
      e o `.form-control` teve a dele zerada (`inset 0 0 0 transparent`). Um
      campo de texto e um select lado a lado, com a mesma borda e o mesmo raio,
      pareciam controles de famílias diferentes: um plano, outro afundado.
   2. **O foco em azul velho.** `#80bdff` é o azul do Bootstrap, não o nosso —
      o mesmo caso das utilities `-primary` corrigidas em 01/09. E o campo de
      texto nem anel tinha: o AdminLTE trocou o `box-shadow` do foco por
      `transparent`, então focar um input não mudava nada além da borda.

   Isto é correção, não escolha: borda, raio e altura já eram iguais nos dois
   (1px #ced4da, .25rem, 2.25rem) e continuam como estavam.
   ========================================================================== */

.custom-select {
  box-shadow: none;
  transition: border-color var(--transicao-rapida), box-shadow var(--transicao-rapida);
}

/* Um seletor só por regra, e as duas vêm depois do adminlte.min.css no
   base.html — empate de especificidade, a última vence, sem !important. */
.form-control:focus,
.custom-select:focus {
  border-color: var(--cor-primaria);
  box-shadow: var(--sombra-foco);
}

/* Desabilitado continua com o cinza do Bootstrap (igual ao do input), mas sem
   o anel: campo que não recebe digitação não anuncia foco. */
.custom-select:disabled { box-shadow: none; }


/* ==========================================================================
   34. DUAS COLUNAS COM DIVISOR ARRASTÁVEL (04/09/2026)

   Tela de trabalho + coluna de acompanhamento (comentários, linha do tempo,
   histórico). Ate aqui isso era `col-md-8` + `col-md-4` escrito em cada
   pagina: a proporcao era decisao de quem escreveu o template, e quem usa a
   tela nao podia mudar. Agora o vao entre as colunas é um divisor: arrastar
   muda a proporcao, e a escolha fica no `localStorage` do navegador (nao vai
   para o banco — é preferencia de quem esta olhando, nao dado do sistema).

   <div class="hrs-colunas" data-hrs-colunas="visualizar-projetos">
     <div class="hrs-colunas-a">…</div>
     <div class="hrs-colunas-divisor" role="separator" aria-orientation="vertical" tabindex="0"></div>
     <div class="hrs-colunas-b">…</div>
   </div>

   Abaixo de 992px as colunas empilham e o divisor some — arrastar largura nao
   faz sentido no celular. O `data-hrs-colunas` é a chave da preferencia; sem
   ele, todas as telas compartilhariam a mesma. O JS vive no componentes.js.
   ========================================================================== */

.hrs-colunas {
  --hrs-colunas-a: 66%;
  display: grid;
  grid-template-columns: minmax(0, var(--hrs-colunas-a)) 14px minmax(0, 1fr);
  /* `stretch` (o padrao do grid) de proposito: com `align-items: start` cada
     coluna fica com a altura do proprio conteudo, e ai um filho `position:
     sticky` da coluna curta nao tem para onde deslizar — ele parece ignorar o
     sticky e sobe junto com a rolagem (visto no teste em 04/09/2026). */
  align-items: stretch;
}

/* O divisor tem 14px de area de clique mas desenha uma linha de 2px no meio:
   alvo confortavel para o mouse sem um vao visivel largo entre as colunas. */
.hrs-colunas-divisor {
  position: relative;
  align-self: stretch;
  cursor: col-resize;
  touch-action: none;
}
.hrs-colunas-divisor::before {
  content: "";
  position: absolute;
  top: 0; bottom: 0; left: 50%;
  width: 2px;
  margin-left: -1px;
  border-radius: 1px;
  background: transparent;
  transition: background-color var(--transicao-rapida);
}
.hrs-colunas-divisor:hover::before,
.hrs-colunas-divisor:focus-visible::before,
.hrs-colunas.hrs-colunas-arrastando .hrs-colunas-divisor::before { background: var(--cor-primaria); }
.hrs-colunas-divisor:focus-visible { outline: none; }

/* Enquanto arrasta, o cursor vale para a pagina inteira e o texto para de ser
   selecionado — senao o gesto marca o conteudo das duas colunas. */
.hrs-colunas.hrs-colunas-arrastando { cursor: col-resize; user-select: none; }

@media (max-width: 991.98px) {
  .hrs-colunas { grid-template-columns: minmax(0, 1fr); }
  .hrs-colunas-divisor { display: none; }
}


/* ==========================================================================
   35. FICHA DE LEITURA (04/09/2026)

   Dado que nao se edita: rotulo pequeno em caixa alta em cima, valor
   embaixo. E a regra 2 do padrao ("dado que nao se edita e ficha, nunca
   input readonly"), e ja existia em tres lugares com tres nomes — os
   `neg-campos` da tela do negocio, os `pj-rot`/`pj-val` da tela de projetos
   e os `.rot`/`.val` dos prototipos. Agora tem um nome so.

   <div class="hrs-ficha">
     <div class="hrs-ficha-campo">
       <span class="hrs-ficha-rotulo">Entrega do projeto</span>
       <span class="hrs-ficha-valor">24/07/2026 08:36</span>
     </div>
   </div>

   O rotulo sozinho (`hrs-ficha-rotulo`) tambem serve para <label> de campo
   de formulario quando a tela quer o mesmo peso visual da ficha.
   ========================================================================== */
.hrs-ficha {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--esp-3) var(--esp-5);
}
.hrs-ficha-campo { min-width: 0; }
.hrs-ficha-rotulo {
  display: block;
  margin-bottom: 2px;
  font-size: 11px;
  font-weight: var(--peso-forte);
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--cor-texto-suave);
}
.hrs-ficha-valor {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: var(--fonte-md);
  color: var(--cor-texto);
}
/* Bloco de texto longo (observacao, descricao): fundo suave e as quebras de
   linha da pessoa preservadas sem virar <br>. */
.hrs-ficha-texto {
  padding: var(--esp-3);
  border-radius: var(--raio-md);
  background: var(--cor-superficie-alt);
  font-size: var(--fonte-md);
  color: var(--cor-texto);
  white-space: pre-line;
}


/* ==========================================================================
   36. CHIP (04/09/2026)

   Pilula pequena e clicavel: contador que abre alguma coisa ("2 versoes"),
   filtro ativo, atalho. Difere da etiqueta (secao 6) por ser ACAO — a
   etiqueta e estado e nao se clica. Sem borda; fundo suave; quando esta
   "ligado" (`aria-expanded="true"` ou `.hrs-chip-ativo`) ganha a cor da
   marca. Ja existia como `.pj-chip`, `.vs-chip` e o chip do painel de
   filtros, cada um com o proprio CSS.

   <button class="hrs-chip" data-toggle="collapse" data-target="#x">
     <i class="fa-solid fa-folder-open"></i>2 versoes<i class="fas fa-chevron-down hrs-chip-seta"></i>
   </button>
   ========================================================================== */
.hrs-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 26px;
  padding: 0 10px;
  border: 0;
  border-radius: var(--raio-pilula);
  background: var(--cor-superficie-alt);
  color: var(--cor-texto-suave);
  font-size: var(--fonte-sm);
  font-weight: var(--peso-medio);
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  text-decoration: none;
  transition: background-color var(--transicao-rapida), color var(--transicao-rapida);
}
.hrs-chip:hover,
.hrs-chip.hrs-chip-ativo,
.hrs-chip[aria-expanded="true"] { background: var(--cor-primaria-suave); color: var(--cor-primaria); text-decoration: none; }
/* O navegador desenha o proprio anel preto no clique; fica so o do teclado. */
.hrs-chip:focus { outline: none; }
.hrs-chip:focus-visible { outline: none; box-shadow: var(--sombra-foco); }
.hrs-chip-seta { font-size: 9px; transition: transform var(--transicao-rapida); }
.hrs-chip[aria-expanded="true"] .hrs-chip-seta { transform: rotate(180deg); }


/* ==========================================================================
   37. AÇÃO ÚNICA NA LINHA (04/09/2026) — opção 3 de três protótipos

   Quando a linha da tabela tem UMA ação so, abrir o menu do kebab para
   escolher a unica opcao que existe e um clique jogado fora. Oito tabelas
   estavam assim (projetos, recebimentos, motoristas, veiculos, parceiros,
   grupos, filtros, status). A acao passa a ficar escrita na propria linha:
   texto em azul, sem borda e sem fundo, com o fundo suave no hover.

   Rejeitado: botao com rotulo (traz de volta a parede de caixas que o kebab
   tirou). Rotulo de UMA palavra ("Editar", "Ver"). Quando o nome precisa de
   duas ("Editar parcelas", "Ver projetos"), repetido em toda linha vira uma
   coluna de texto: nesses casos usa-se .hrs-acao-linha-so-icone, que deixa
   so o icone (como no celular) com o nome no title — escolha do usuario em
   04/09/2026 para recebimentos e solicitacoes de projeto.

   <a class="hrs-acao-linha" href="…"><i class="fas fa-pen"></i><span class="hrs-acao-linha-texto">Editar</span></a>
   <a class="hrs-acao-linha hrs-acao-linha-so-icone" title="Editar parcelas" href="…"><i class="fas fa-pen"></i><span class="hrs-acao-linha-texto">Editar parcelas</span></a>

   Mantem as classes/ids/data-* que o JS da tela escuta; so o wrapper
   .dropdown e o botao de menu saem. Duas ou mais acoes = kebab (secao 16).
   ========================================================================== */
.hrs-acao-linha {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 30px;
  padding: 0 8px;
  border: 0;
  border-radius: var(--raio-md);
  background: transparent;
  color: var(--cor-primaria);
  font-size: 13px;
  font-weight: var(--peso-medio);
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  text-decoration: none;
  transition: background-color var(--transicao-rapida), color var(--transicao-rapida);
}
.hrs-acao-linha:hover {
  background: var(--cor-primaria-suave);
  color: var(--cor-primaria-ativa);
  text-decoration: none;
}
.hrs-acao-linha:focus { outline: none; }
.hrs-acao-linha:focus-visible { outline: none; box-shadow: var(--sombra-foco); }
.hrs-acao-linha .fas, .hrs-acao-linha .far, .hrs-acao-linha .fa-solid, .hrs-acao-linha .fa-regular { font-size: 12px; }
/* So o icone (rotulo de duas palavras): o nome vai no title. */
.hrs-acao-linha-so-icone { width: 32px; height: 32px; padding: 0; justify-content: center; border-radius: var(--raio-circulo); }
.hrs-acao-linha-so-icone .hrs-acao-linha-texto { display: none; }
.hrs-acao-linha-so-icone .fas, .hrs-acao-linha-so-icone .far, .hrs-acao-linha-so-icone .fa-solid, .hrs-acao-linha-so-icone .fa-regular { font-size: 14px; }
/* No celular todas viram so o icone e o alvo de toque cresce. */
@media (max-width: 575.98px) {
  .hrs-acao-linha { width: 36px; height: 36px; padding: 0; justify-content: center; border-radius: var(--raio-circulo); }
  .hrs-acao-linha .hrs-acao-linha-texto { display: none; }
  .hrs-acao-linha .fas, .hrs-acao-linha .far, .hrs-acao-linha .fa-solid, .hrs-acao-linha .fa-regular { font-size: 14px; }
}


/* ==========================================================================
   38. ENVIO DE ARQUIVOS (04/09/2026) — opção C de três protótipos

   O site pedia arquivo de quatro jeitos: a zona tracejada cujo CSS nem era
   carregado (projetos, leads, cadastro de projeto — aparecia o input cru do
   navegador), o custom-file do Bootstrap (rotas, boleto), o form-control-file
   (assinatura de e-mail) e zonas com estilo inline (rotas, faturamento).
   Vira uma familia so, em dois tamanhos:

   ZONA — card de anexos. O <label> envolve o input, que cobre a zona inteira
   com opacidade zero: clicar e soltar arquivo funcionam sem JS. O botao dentro
   e so desenho (pointer-events: none), o clique cai no input.

   <label class="hrs-envio">
     <input type="file" name="…" multiple>
     <span class="hrs-envio-icone"><i class="fa-solid fa-cloud-arrow-up"></i></span>
     <span class="hrs-envio-corpo"><span class="hrs-envio-texto">Solte os arquivos aqui</span>
       <span class="hrs-envio-dica">PDF, imagens, DWG e ZIP</span></span>
     <span class="btn btn-primary btn-sm">Escolher arquivos</span>
   </label>

   Quando o JS da tela ja cuida do clique e do drop (rotas, faturamento), a
   zona e um <div class="hrs-envio hrs-envio-por-js"> com o input escondido.

   CAMPO — formulario e modal, um arquivo. O nome escolhido aparece no proprio
   campo (componentes.js troca o texto e poe .preenchido).

   <label class="hrs-envio-campo">
     <input type="file" name="…" accept=".pdf">
     <span class="hrs-envio-botao"><i class="fa-solid fa-cloud-arrow-up"></i>Escolher</span>
     <span class="hrs-envio-nome">Nenhum arquivo escolhido</span>
   </label>

   A lista do que foi escolhido e o componente de anexo (secao 24) e o botao
   Enviar fica num .hrs-envio-rodape, escondido enquanto nao ha nada para enviar.
   Rejeitadas: zona alta com icone em cima (A) e barra de uma linha (B).
   ========================================================================== */
.hrs-envio {
  position: relative;
  display: flex;
  align-items: center;
  gap: 14px;
  margin: 0;
  padding: 16px 18px;
  min-height: 92px;
  border: 1px dashed var(--cor-borda-forte);
  border-radius: var(--raio-md);
  background: var(--cor-superficie);
  color: var(--cor-texto);
  font-weight: var(--peso-normal);
  cursor: pointer;
  transition: border-color var(--transicao-rapida), background-color var(--transicao-rapida);
}
.hrs-envio:hover, .hrs-envio.arrastando, .hrs-envio:focus-within {
  border-color: var(--cor-primaria);
  background: var(--cor-primaria-suave);
}
.hrs-envio:focus-within { box-shadow: var(--sombra-foco); }
.hrs-envio.invalido { border-color: var(--cor-perigo); }
.hrs-envio > input[type="file"] {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
.hrs-envio-por-js > input[type="file"] { display: none; }
.hrs-envio-icone {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  border-radius: var(--raio-circulo);
  background: var(--cor-primaria-suave);
  color: var(--cor-primaria);
  font-size: 18px;
  transition: background-color var(--transicao-rapida);
}
.hrs-envio:hover .hrs-envio-icone, .hrs-envio.arrastando .hrs-envio-icone { background: var(--cor-superficie); }
.hrs-envio-corpo { flex: 1; min-width: 0; }
.hrs-envio-texto { display: block; font-weight: var(--peso-medio); color: var(--cor-texto); }
.hrs-envio-dica { display: block; margin-top: 2px; font-size: 12px; color: var(--cor-texto-suave); }
.hrs-envio > .btn { position: relative; z-index: 1; flex: 0 0 auto; pointer-events: none; }
/* Rodape da lista: contagem a esquerda, Enviar a direita. Some sem arquivo. */
.hrs-envio-rodape { display: flex; align-items: center; justify-content: space-between; gap: var(--esp-2); margin-top: var(--esp-3); }
.hrs-envio-rodape[hidden] { display: none; }
.hrs-envio-rodape .hrs-envio-dica { margin: 0; }
@media (max-width: 575.98px) {
  .hrs-envio { flex-wrap: wrap; padding: 14px; }
  .hrs-envio > .btn { width: 100%; }
}

.hrs-envio-campo {
  position: relative;
  display: flex;
  align-items: stretch;
  height: 38px;
  margin: 0;
  border: 1px dashed var(--cor-borda-forte);
  border-radius: var(--raio-md);
  background: var(--cor-superficie);
  font-weight: var(--peso-normal);
  overflow: hidden;
  cursor: pointer;
  transition: border-color var(--transicao-rapida);
}
.hrs-envio-campo:hover, .hrs-envio-campo.arrastando { border-color: var(--cor-primaria); }
.hrs-envio-campo:focus-within { border-color: var(--cor-primaria); box-shadow: var(--sombra-foco); }
.hrs-envio-campo > input[type="file"] { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.hrs-envio-botao {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
  padding: 0 12px;
  font-size: 13px;
  font-weight: var(--peso-medio);
  color: var(--cor-primaria);
  white-space: nowrap;
}
.hrs-envio-nome {
  display: flex;
  align-items: center;
  flex: 1;
  min-width: 0;
  padding: 0 12px 0 0;
  font-size: 14px;
  color: var(--cor-texto-suave);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.hrs-envio-campo.preenchido .hrs-envio-nome { color: var(--cor-texto); }


/* ==========================================================================
   39. ESQUELETO — o "carregando" do site (04/09/2026), opção C de três

   Irmao do estado vazio (secao 6): a area ainda nao tem conteudo porque esta
   buscando. Eram cinco desenhos — spinner do FA em div cinza, spinner-border
   azul, "Carregando..." solto, celula de tabela, ate um alert-info. Agora a
   area mostra a FORMA do que vai chegar.

   As barras e o brilho sao da Skeleton Elements 4.0.1 (static/lib, local,
   carregada no base.html antes deste arquivo): .skeleton-block (barra),
   .skeleton-text (o texto real vira barras, pela fonte "skeleton") e
   .skeleton-effect-wave (brilho). Aqui ficam so a cor, os tamanhos e os moldes.

   Tamanhos: .hrs-esq-linha | -titulo | -bloco | -circulo | -etiqueta (usar junto
             com "skeleton-block skeleton-effect-wave")
   Moldes:   .hrs-esqueleto (bloco) + -lista | -cards | -timeline; tabela e so <tr>/<td>
   JS:       Horus.esqueletoHtml("tabela", {colunas: 6, linhas: 4})
             Horus.esqueletoHtml("linhas" | "lista" | "cards" | "timeline" | "bloco", n)
             Horus.vazioHtml({icone, titulo, texto, compacto})
   HTML fixo: quando o HTML final ja esta na tela, basta "skeleton-text
             skeleton-effect-wave" no elemento; o proprio texto vira barra.

   Rejeitadas: anel girando ao lado do texto (A) e tres pontos pulsando (B).
   Onde NAO usar: spinner dentro de botao ("Salvando…") e texto inline curto.
   ========================================================================== */
:root { --skeleton-color: var(--cor-hover-neutro); }
.skeleton-block { border-radius: 6px; }
.hrs-esq-linha    { height: 12px; margin: 6px 0; }
.hrs-esq-titulo   { height: 16px; width: 45%; margin: 4px 0 10px; }
.hrs-esq-bloco    { height: 120px; border-radius: var(--raio-md); }
.hrs-esq-circulo  { width: 32px; height: 32px; border-radius: var(--raio-circulo); flex: 0 0 auto; }
.hrs-esq-etiqueta { display: inline-block; width: 64px; height: 18px; border-radius: var(--raio-pilula); }
@media (prefers-reduced-motion: reduce) {
  .skeleton-effect-wave, .skeleton-effect-fade, .skeleton-effect-pulse, .skeleton-effect-blink { animation: none; -webkit-mask-image: none; mask-image: none; }
}

.hrs-esqueleto { padding: var(--esp-4); cursor: progress; }
.hrs-esqueleto p.skeleton-text { margin: 0 0 6px; line-height: 1.5; }
/* tabela: uma barra por celula, sem margem para a linha nao crescer */
td > .hrs-esq-linha { margin: 2px 0; }
/* lista: circulo + duas linhas + etiqueta, separadas como itens de verdade */
.hrs-esqueleto-lista .hrs-esq-item { display: flex; align-items: center; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--cor-borda); }
.hrs-esqueleto-lista .hrs-esq-item:last-child { border-bottom: 0; }
.hrs-esqueleto-lista .hrs-esq-meio { flex: 1; min-width: 0; }
.hrs-esqueleto-lista .hrs-esq-meio .hrs-esq-linha:first-child { margin-top: 0; }
.hrs-esqueleto-lista .hrs-esq-meio .hrs-esq-linha:last-child { margin-bottom: 0; height: 9px; }
/* cards: grade de tres, bloco de midia + duas linhas */
.hrs-esqueleto-cards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
.hrs-esqueleto-cards .hrs-esq-card { padding: 14px; border: 1px solid var(--cor-borda); border-radius: var(--raio-lg); background: var(--cor-superficie); }
.hrs-esqueleto-cards .hrs-esq-card .hrs-esq-bloco { height: 80px; margin-bottom: 10px; }
@media (max-width: 767.98px) { .hrs-esqueleto-cards { grid-template-columns: 1fr 1fr; } }
/* linha do tempo: icone redondo + titulo + painel */
.hrs-esqueleto-timeline .hrs-esq-item { display: flex; gap: 12px; padding: 8px 0; }
.hrs-esqueleto-timeline .hrs-esq-meio { flex: 1; min-width: 0; }
.hrs-esqueleto-timeline .hrs-esq-painel { height: 38px; border-radius: var(--raio-md); margin-top: 6px; }
/* Conteudo que esta sendo atualizado (Horus.esqueletizar): sem clique, e o que
   nao e texto — imagem, icone, etiqueta, botao, campo — desbota junto. */
.hrs-atualizando { pointer-events: none; cursor: progress; }
.hrs-atualizando img, .hrs-atualizando .fas, .hrs-atualizando .far, .hrs-atualizando .fa-solid, .hrs-atualizando .fa-regular,
.hrs-atualizando .hrs-etiqueta, .hrs-atualizando .btn, .hrs-atualizando input, .hrs-atualizando select, .hrs-atualizando .custom-select { opacity: .35; }


/* ==========================================================================
   40. ESPERA — o overlay de carregamento (04/09/2026), opção A de três

   O #loading-overlay do base.html aparece em 50 arquivos de JS (545
   show()/hide()), para salvar, enviar, buscar. Era um veu preto a 90% na tela
   inteira, anel branco de 100px e "Por favor, aguarde..." em 24px com sombra.
   Agora: veu claro com leve desfoque — a tela continua visivel — e um cartao
   branco no centro com o anel do padrao e o texto. Os ids nao mudaram, entao
   nenhum JS precisou mudar; o texto continua entrando por #loading-text.

   <div id="loading-overlay" class="hrs-espera" style="display:none;">
     <div class="hrs-espera-cartao"><span class="hrs-espera-anel"></span>
       <div id="loading-text" class="hrs-espera-texto">Por favor, aguarde…</div></div>
   </div>

   Bloqueia a tela de proposito: e a protecao contra clique duplo em telas que
   ninguem revisou uma a uma. Rejeitadas: barra fina no topo com pilula (B —
   some atras da barra de certificados e do cabecalho fixo no celular) e cartao
   no canto sem bloquear (C — exige revisar botao por botao).
   Para BUSCAR conteudo de modal, o certo e o esqueleto (secao 39), nao isto.
   ========================================================================== */
/* Aviso (SweetAlert, 1060 por padrão) acima do véu: um erro mostrado sem
   esconder o véu antes ficava por baixo dele (revisão do design system,
   28/09/2026 — ex. remover hierarquia em Permissões). */
.swal2-container { z-index: 10000; }
.hrs-espera {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(244, 246, 249, .72);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  cursor: progress;
}
.hrs-espera-cartao {
  display: flex;
  align-items: center;
  gap: 12px;
  max-width: min(420px, calc(100vw - 32px));
  padding: 14px 18px;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio-lg);
  background: var(--cor-superficie);
  box-shadow: 0 8px 24px rgba(16, 24, 40, .12);
}
.hrs-espera-anel {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  border: 2.5px solid var(--cor-borda);
  border-top-color: var(--cor-primaria);
  border-radius: var(--raio-circulo);
  animation: hrs-girar .8s linear infinite;
}
@media (prefers-reduced-motion: reduce) { .hrs-espera-anel { animation: none; border-top-color: var(--cor-borda); } }
.hrs-espera-texto { font-size: var(--fonte-md); font-weight: var(--peso-medio); color: var(--cor-texto); line-height: 1.35; }


/* ==========================================================================
   41. DATA (04/09/2026) — opção B de três

   O site pedia data de tres jeitos: o <input type="date"> nativo (109 campos
   em 32 telas, cada sistema operacional com uma cara), o daterangepicker nos
   filtros de periodo (23) e o flatpickr em tres telas. Agora:

   - Todo <input type="date"> e <input type="datetime-local"> vira flatpickr
     sozinho (componentes.js, Horus.data): campo de texto dd/mm/aaaa com o
     calendario nas cores do sistema. O input original fica escondido com o
     valor no formato de sempre (Y-m-d / Y-m-dTH:i) — nenhuma view muda, e
     $("#campo").val("2026-09-15") continua funcionando (o setter sincroniza).
     Para NAO converter um campo: data-nativo. No celular o flatpickr usa o
     seletor nativo (disableMobile:false).
   - Os 23 filtros de periodo continuam no daterangepicker, so repintados.
     Periodo novo: flatpickr com mode:"range".

   Rejeitadas: nativo repintado (A — calendario diferente por sistema, periodo
   vira dois campos) e daterangepicker em tudo (C — jQuery+moment, pesado).
   ========================================================================== */
.hrs-data { position: relative; }
.hrs-data > .form-control, .hrs-data > .flatpickr-input { padding-right: 36px; }
.hrs-data-icone {
  position: absolute; right: 11px; top: 50%; transform: translateY(-50%);
  color: var(--cor-primaria); pointer-events: none; font-size: 14px;
}
.hrs-data-icone.hrs-data-icone-sm { right: 8px; font-size: 12px; }
/* o input visivel do flatpickr herda o form-control; readonly do original vira cinza */
.flatpickr-input[readonly]:not(.hrs-data-editavel) { background-color: var(--cor-superficie-alt); }

/* --- calendario do flatpickr --- */
.flatpickr-calendar {
  font-family: inherit;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio-lg);
  box-shadow: 0 8px 24px rgba(16, 24, 40, .12);
}
.flatpickr-calendar.arrowTop::before, .flatpickr-calendar.arrowTop::after,
.flatpickr-calendar.arrowBottom::before, .flatpickr-calendar.arrowBottom::after { display: none; }
.flatpickr-months .flatpickr-month, .flatpickr-current-month, .flatpickr-weekdays, span.flatpickr-weekday { background: transparent; color: var(--cor-texto); }
.flatpickr-current-month .flatpickr-monthDropdown-months { font-weight: var(--peso-forte); }
.flatpickr-day { border-radius: var(--raio-md); color: var(--cor-texto); }
.flatpickr-day.today { border-color: var(--cor-primaria); color: var(--cor-primaria); }
.flatpickr-day.today:hover { background: var(--cor-primaria-suave); color: var(--cor-primaria); }
.flatpickr-day:hover, .flatpickr-day.prevMonthDay:hover, .flatpickr-day.nextMonthDay:hover { background: var(--cor-primaria-suave); border-color: var(--cor-primaria-suave); }
.flatpickr-day.selected, .flatpickr-day.startRange, .flatpickr-day.endRange,
.flatpickr-day.selected:hover, .flatpickr-day.startRange:hover, .flatpickr-day.endRange:hover { background: var(--cor-primaria); border-color: var(--cor-primaria); color: #fff; }
.flatpickr-day.inRange { background: var(--cor-primaria-suave); border-color: var(--cor-primaria-suave); box-shadow: -5px 0 0 var(--cor-primaria-suave), 5px 0 0 var(--cor-primaria-suave); }

/* --- leitura do calendario (18/09/2026) ---------------------------------
   Tres ajustes que sairam de comparar as versoes lado a lado no prototipo:

   1. O cabecalho ganha uma regua. Sem ela o mes e os dias da semana viravam
      um bloco so de texto escuro no topo.
   2. Dia da semana em caixa alta discreta: ele rotula a coluna, nao compete
      com o numero.
   3. "Hoje" vira um PONTO embaixo do numero, nao uma borda. A borda competia
      com o preenchimento do dia selecionado — nos dois calendarios do
      prototipo o dia de hoje parecia tao clicado quanto o escolhido. Quando
      hoje E o selecionado, o ponto some (o preenchimento ja diz tudo).

   Altura de 40px em vez dos 39 do flatpickr: max-width NAO entra aqui. O dia
   tem flex-basis de 14,28% e apertar a largura tira dias da linha — o
   prototipo quebrou assim antes de eu medir quantos dias dividiam a linha. */
.flatpickr-months { padding-bottom: var(--esp-1); border-bottom: 1px solid var(--cor-borda); margin-bottom: var(--esp-1); }
.flatpickr-current-month { font-size: 15px; }
span.flatpickr-weekday { font-size: 11px; font-weight: var(--peso-forte); letter-spacing: .04em; text-transform: uppercase; color: var(--cor-texto-fraco); }
.flatpickr-day { height: 40px; line-height: 40px; }
.flatpickr-day.prevMonthDay, .flatpickr-day.nextMonthDay { color: var(--cor-texto-fraco); opacity: .55; }
.flatpickr-day.today:not(.selected) { border-color: transparent; font-weight: var(--peso-forte); position: relative; }
.flatpickr-day.today:not(.selected)::after {
  content: ""; position: absolute; left: 50%; bottom: 5px; transform: translateX(-50%);
  width: 4px; height: 4px; border-radius: 50%; background: var(--cor-primaria);
}

/* --- atalhos do rodape ---------------------------------------------------
   Num filtro de data a maioria dos cliques e "hoje" ou "inicio do mes", e sem
   isto custa navegar mes a mes. O rodape e montado pelo componentes.js, que
   tambem esconde o atalho que cair fora do min/max do campo. */
.hrs-data-atalhos {
  display: flex; flex-wrap: wrap; gap: var(--esp-1);
  padding: var(--esp-2) var(--esp-2) calc(var(--esp-2) + 2px);
  border-top: 1px solid var(--cor-borda);
}
.hrs-data-atalhos button {
  flex: 1 1 auto; border: 1px solid var(--cor-borda); background: var(--cor-superficie);
  color: var(--cor-texto-medio); border-radius: var(--raio-md);
  font-size: var(--fonte-xs); font-weight: var(--peso-forte);
  padding: 5px var(--esp-2); cursor: pointer; white-space: nowrap;
}
.hrs-data-atalhos button:hover { background: var(--cor-primaria-suave); border-color: var(--cor-primaria-suave); color: var(--cor-primaria-ativa); }
.flatpickr-day.flatpickr-disabled, .flatpickr-day.prevMonthDay, .flatpickr-day.nextMonthDay { color: var(--cor-texto-suave); opacity: .6; }
.flatpickr-months .flatpickr-prev-month:hover svg, .flatpickr-months .flatpickr-next-month:hover svg { fill: var(--cor-primaria); }
.flatpickr-time input:hover, .flatpickr-time .flatpickr-am-pm:hover, .flatpickr-time input:focus, .flatpickr-time .flatpickr-am-pm:focus { background: var(--cor-primaria-suave); }
.numInputWrapper:hover, .numInputWrapper span:hover { background: var(--cor-primaria-suave); }

/* --- daterangepicker (filtros de periodo que ficaram) repintado --- */
.daterangepicker { font-family: inherit; border: 1px solid var(--cor-borda); border-radius: var(--raio-lg); box-shadow: 0 8px 24px rgba(16, 24, 40, .12); }
.daterangepicker::before, .daterangepicker::after { display: none; }
.daterangepicker .calendar-table th, .daterangepicker .calendar-table td { font-size: 13px; }
.daterangepicker td.active, .daterangepicker td.active:hover { background: var(--cor-primaria); border-radius: var(--raio-md); }
.daterangepicker td.in-range { background: var(--cor-primaria-suave); color: var(--cor-texto); }
.daterangepicker td.available:hover, .daterangepicker th.available:hover { background: var(--cor-primaria-suave); border-radius: var(--raio-md); }
.daterangepicker .ranges li.active { background: var(--cor-primaria); }
.daterangepicker .ranges li:hover { background: var(--cor-primaria-suave); }
.daterangepicker .drp-buttons .btn { font-size: 13px; padding: 5px 12px; }
.daterangepicker .drp-buttons .btn.applyBtn { background: var(--cor-primaria); border-color: var(--cor-primaria); }

/* ==========================================================================
   42. CASCA — menu lateral e cabeçalho (09/10/2026, opção B de três)

   Protótipo: static/prototipos/casca-layout.html. Antes, menu, cabeçalho e
   rodapé eram o mesmo cinza do AdminLTE (#343a40): três faixas escuras em
   volta do conteúdo, e o item ativo era um bloco cheio na primária.

   - Menu: fundo de tinta azulada (--cor-casca-*), módulos agrupados em seções
     (tb_menu_secao, editáveis em Configurações › Menu; o render_menu ordena).
     Recolhido, o título da seção vira um traço e o submenu aberto some: sobra
     o ícone do módulo, marcado. Antes a lista de telas ficava em pé e a coluna
     virava uma fila de ícones sem nome.
   - Ativo: o módulo fica branco com o ícone em destaque; a tela, com um
     fundo leve da primária. Sem sombra e sem barra (pedido do Ivan).
   - Cabeçalho: branco, com o caminho "Módulo › Tela" (.hrs-migalha).
   - Rodapé: saiu do site. A versão foi para o menu do perfil.

   O recuo do submenu mora no base.css (regra do treeview), porque ele carrega
   depois deste arquivo e venceria por ordem.

   `!important` no ativo porque o AdminLTE pinta o .active com a mesma
   especificidade e CSS antigo de página também usava.
   ========================================================================== */
.main-sidebar[class*="sidebar-dark-"] { background-color: var(--cor-casca-fundo); }
.main-sidebar[class*="sidebar-dark-"] .brand-link { border-bottom-color: var(--cor-casca-borda); }
.main-sidebar[class*="sidebar-dark-"] .brand-link .brand-text { color: #fff; font-weight: var(--peso-forte) !important; }

.main-sidebar[class*="sidebar-dark-"] .nav-header {
  color: var(--cor-casca-texto-fraco);
  font-size: .68rem;
  font-weight: var(--peso-forte);
  letter-spacing: .08em;
  text-transform: uppercase;
  padding: 1rem 1rem .35rem;
}
.main-sidebar[class*="sidebar-dark-"] .nav-sidebar > .nav-header:first-child { padding-top: .35rem; }
.sidebar-mini.sidebar-collapse .main-sidebar[class*="sidebar-dark-"]:not(:hover) .nav-header {
  display: block !important;
  height: 0;
  padding: 0;
  margin: .5rem 1rem;
  overflow: hidden;
  border-top: 1px solid var(--cor-casca-borda);
}
.sidebar-mini.sidebar-collapse .main-sidebar[class*="sidebar-dark-"]:not(:hover) .nav-sidebar > .nav-header:first-child { border-top: 0; margin: 0; }

.main-sidebar[class*="sidebar-dark-"] .nav-sidebar .nav-link { color: var(--cor-casca-texto); border-radius: var(--raio-lg); }
.main-sidebar[class*="sidebar-dark-"] .nav-sidebar .nav-link p { white-space: nowrap; }
/* Nome longo de tela ("Orçamento de Pedido") não quebra a linha deixando o ícone
   sozinho em cima: com a barra de rolagem do celular, o menu fica uns 15px mais
   estreito. A tela encolhe com reticências; o nome inteiro fica no title. */
body:not(.sidebar-collapse) .main-sidebar[class*="sidebar-dark-"] .nav-treeview .nav-link { display: flex; align-items: center; }
body:not(.sidebar-collapse) .main-sidebar[class*="sidebar-dark-"] .nav-treeview .nav-link p { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.main-sidebar[class*="sidebar-dark-"] .nav-sidebar .nav-link .nav-icon { color: var(--cor-casca-texto-fraco); }
.main-sidebar[class*="sidebar-dark-"] .nav-sidebar .nav-link:hover,
.main-sidebar[class*="sidebar-dark-"] .nav-sidebar .nav-link:focus { background-color: var(--cor-casca-hover); color: #fff; }
.main-sidebar[class*="sidebar-dark-"] .nav-sidebar > .nav-item.menu-open > .nav-link { background-color: transparent; color: #fff; }

.main-sidebar[class*="sidebar-dark-"] .nav-sidebar > .nav-item > .nav-link.active,
.main-sidebar[class*="sidebar-dark-"] .nav-sidebar > .nav-item > .nav-link.active:focus,
.main-sidebar[class*="sidebar-dark-"] .nav-sidebar > .nav-item > .nav-link.active:hover {
  background-color: transparent !important;
  color: #fff !important;
  box-shadow: none !important;
  font-weight: var(--peso-medio);
}
.main-sidebar[class*="sidebar-dark-"] .nav-treeview > .nav-item > .nav-link.active,
.main-sidebar[class*="sidebar-dark-"] .nav-treeview > .nav-item > .nav-link.active:focus,
.main-sidebar[class*="sidebar-dark-"] .nav-treeview > .nav-item > .nav-link.active:hover {
  background-color: var(--cor-casca-ativo) !important;
  color: #fff !important;
  box-shadow: none !important;
  font-weight: var(--peso-medio);
}
.main-sidebar[class*="sidebar-dark-"] .nav-sidebar .nav-link.active .nav-icon { color: var(--cor-casca-destaque); }

/* Seta do módulo: o menu usa fa-angle-down (fechado = para baixo) e o AdminLTE
   gira -90° ao abrir, o que deixava a seta do aberto apontando para o lado. */
.main-sidebar .nav-sidebar .menu-open > .nav-link i.right,
.main-sidebar .nav-sidebar .menu-is-opening > .nav-link i.right { transform: rotate(180deg); }

/* Recolhido: só o ícone do módulo, marcado; as telas aparecem ao passar o mouse. */
.sidebar-mini.sidebar-collapse .main-sidebar[class*="sidebar-dark-"]:not(:hover) .nav-treeview { display: none !important; }
.sidebar-mini.sidebar-collapse .main-sidebar[class*="sidebar-dark-"]:not(:hover) .nav-sidebar > .nav-item > .nav-link.active {
  background-color: var(--cor-casca-ativo) !important;
}

/* Cabeçalho branco. */
.main-header.navbar-white { border-bottom: 1px solid var(--cor-borda); }
.main-header .navbar-nav .nav-link { color: var(--cor-texto-medio); border-radius: var(--raio-lg); }
.main-header .navbar-nav .nav-link:hover,
.main-header .navbar-nav .nav-link:focus { background-color: var(--cor-hover-neutro); color: var(--cor-texto); }
.hrs-migalha {
  align-items: center;
  gap: var(--esp-2);
  min-width: 0;
  padding: 0 var(--esp-2);
  color: var(--cor-texto-suave);
  font-size: var(--fonte-md);
  white-space: nowrap;
}
.hrs-migalha > i { font-size: .6rem; }
.hrs-migalha [aria-current] { color: var(--cor-texto); font-weight: var(--peso-medio); overflow: hidden; text-overflow: ellipsis; }
/* Menu do usuário (09/10/2026, opção A de três): lista agrupada no lugar do
   bloco cinza com o avatar gigante. Sair em vermelho, por último. */
.hrs-menu-usuario { width: 300px; padding: 0; overflow: hidden; border: 1px solid var(--cor-borda); border-radius: 12px; box-shadow: var(--sombra-lg); }
.hrs-menu-usuario .dropdown-divider { margin: 0; }
.hrs-menu-usuario-cab { display: flex; align-items: center; gap: var(--esp-3); padding: 14px var(--esp-4); min-width: 0; }
.hrs-menu-usuario-cab > div { min-width: 0; }
.hrs-menu-usuario-cab b { display: block; color: var(--cor-texto); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hrs-menu-usuario-cab small { display: block; color: var(--cor-texto-suave); font-size: var(--fonte-sm); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hrs-menu-usuario .dropdown-item { display: flex; align-items: center; gap: var(--esp-3); width: auto; margin: 2px 6px; padding: 8px 10px; border-radius: var(--raio-lg); color: var(--cor-texto); }
.hrs-menu-usuario .dropdown-divider + .dropdown-item { margin-top: 6px; }
.hrs-menu-usuario .dropdown-item:hover, .hrs-menu-usuario .dropdown-item:focus { background: var(--cor-hover-neutro); color: var(--cor-texto); }
.hrs-menu-usuario .dropdown-item > i { width: 18px; text-align: center; color: var(--cor-texto-suave); }
.hrs-menu-usuario .dropdown-item > kbd, .hrs-menu-usuario .dropdown-item > .hrs-etiqueta { margin-left: auto; }
.hrs-menu-usuario .dropdown-item > kbd { padding: 0 5px; border: 1px solid var(--cor-borda); border-radius: 4px; background: var(--cor-superficie); color: var(--cor-texto-suave); font: 600 11px/1.6 inherit; box-shadow: none; }
/* no celular não há teclado: o atalho só ocupa espaço */
@media (max-width: 767.98px) { .hrs-menu-usuario .dropdown-item > kbd { display: none; } }
.hrs-menu-usuario .hrs-menu-usuario-sair, .hrs-menu-usuario .hrs-menu-usuario-sair > i { color: var(--cor-perigo-texto); }
.hrs-menu-usuario .hrs-menu-usuario-sair:hover, .hrs-menu-usuario .hrs-menu-usuario-sair:focus { background: var(--cor-perigo-suave); color: var(--cor-perigo-texto); }
.hrs-menu-usuario-pe { display: flex; justify-content: space-between; margin-top: 6px; padding: 8px var(--esp-4); border-top: 1px solid var(--cor-borda); background: var(--cor-superficie-alt); color: var(--cor-texto-suave); font-size: var(--fonte-xs); }

/* ==========================================================================
   43. DATATABLES — os controles da lib no padrão (04/09/2026, opção C)

   Dezesseis telas usam a lib. A tabela em si já era a repintada (seção 9);
   os controles em volta não: seletor "Exibir N", caixa "Buscar:", contagem
   e uma paginação própria, diferente da .pagination do site. Cinco telas
   ainda repintavam isso localmente (dataTable.css, auditoria com o azul
   velho, e quatro CSS de página). Opção escolhida entre três protótipos
   (datatables.html): a integração Bootstrap 4 da própria lib — carregada no
   base — faz a paginação virar .pagination e os campos virarem
   form-control/custom-select, que já são repintados; os defaults em
   componentes.js montam a barra compacta e o pt-BR único. Aqui só o que a
   integração não dá: o arranjo da barra, a lupa, a paginação pequena e as
   setas de ordenação discretas.

   As telas que injetam botões na barra ($("#x_filter").prepend, lista de
   orçamentos e custo/produtos) continuam funcionando: os ids da lib são os
   mesmos e o bloco é flex.
   ========================================================================== */
.hrs-dt-topo,
.hrs-dt-rodape { display: flex; align-items: center; justify-content: space-between; gap: var(--esp-3); flex-wrap: wrap; }
.hrs-dt-topo { margin-bottom: var(--esp-3); }
.hrs-dt-rodape { margin-top: var(--esp-3); }
.hrs-dt-topo:empty, .hrs-dt-rodape:empty { display: none; }
.hrs-dt-topo .btn { white-space: nowrap; } /* 390px: "+ Novo orçamento" quebrava em duas linhas */

.dataTables_wrapper .dataTables_length,
.dataTables_wrapper .dataTables_filter { display: inline-flex; align-items: center; gap: var(--esp-2); }
.dataTables_wrapper .dataTables_length label,
.dataTables_wrapper .dataTables_filter label {
  display: inline-flex; align-items: center; gap: var(--esp-2); margin: 0;
  font-weight: 400; font-size: 13px; color: var(--cor-texto-medio);
}
.dataTables_wrapper .dataTables_length select { width: auto; min-width: 76px; }
.dataTables_wrapper .dataTables_filter label { position: relative; }
.dataTables_wrapper .dataTables_filter label::before {
  content: "\f002"; font-family: "Font Awesome 6 Free"; font-weight: 900;
  position: absolute; left: 10px; top: 50%; transform: translateY(-50%);
  color: var(--cor-texto-fraco); font-size: 12px; pointer-events: none;
}
.dataTables_wrapper .dataTables_filter input { width: 240px; max-width: 100%; margin: 0; padding-left: 28px; }
.dataTables_wrapper .dataTables_info { padding: 0; font-size: 13px; color: var(--cor-texto-medio); }

/* paginação pequena, como a paginação compacta das listas (seção 33) */
.dataTables_wrapper .dataTables_paginate { padding: 0; }
.dataTables_wrapper .dataTables_paginate .pagination { margin: 0; }
.dataTables_wrapper .dataTables_paginate .paginate_button { padding: 0; margin: 0; border: 0; background: none; }
.dataTables_wrapper .dataTables_paginate .page-link { font-size: var(--fonte-sm); padding: 4px 8px; min-width: 32px; text-align: center; }

/* setas de ordenação: só a ativa chama atenção */
table.dataTable thead > tr > th.sorting::before,
table.dataTable thead > tr > th.sorting::after,
table.dataTable thead > tr > th.sorting_asc::before,
table.dataTable thead > tr > th.sorting_asc::after,
table.dataTable thead > tr > th.sorting_desc::before,
table.dataTable thead > tr > th.sorting_desc::after { opacity: .25; font-size: 9px; }
table.dataTable thead > tr > th.sorting_asc::before,
table.dataTable thead > tr > th.sorting_desc::after { opacity: 1; color: var(--cor-primaria); }

/* "Processando…" da lib: o cartão de espera da seção 40, não a caixa cinza */
div.dataTables_wrapper div.dataTables_processing {
  top: 40%; padding: var(--esp-3) var(--esp-4); font-size: 13px; color: var(--cor-texto-medio);
  background: var(--cor-superficie); border: 1px solid var(--cor-borda); border-radius: var(--raio-lg); box-shadow: var(--sombra-md);
}
td.dataTables_empty { padding: var(--esp-5) !important; color: var(--cor-texto-suave); }

@media (max-width: 575.98px) {
  .hrs-dt-topo, .hrs-dt-rodape { justify-content: center; }
  .dataTables_wrapper .dataTables_filter, .dataTables_wrapper .dataTables_filter label, .dataTables_wrapper .dataTables_filter input { width: 100%; }
  /* botão da tela na mesma linha (+ Novo orçamento): a busca ocupa a sobra e não passa da borda */
  .hrs-dt-topo .dataTables_filter { flex: 1 1 160px; min-width: 0; }
  .dataTables_wrapper .dataTables_filter label, .dataTables_wrapper .dataTables_filter input { min-width: 0; }
}

/* ==========================================================================
   44. BOTÃO EM ESPERA e ESPERA DE ÁREA (04/09/2026, opção A)

   Vinte e dois botões improvisavam o "salvando": só texto ("Salvando..."),
   ícone FA girando + texto, spinner do Bootstrap, anel sozinho. Cada um
   mudava a largura do botão e a tela pulava. Agora é um helper só:

     Horus.botaoOcupado($btn, "Salvando…");   // trava, guarda o conteúdo,
     Horus.botaoLivre($btn);                   // mostra anel + verbo; devolve

   O helper fixa min-width na largura que o botão tinha, então "Salvar
   alterações" → "Salvando…" não encolhe. Texto vazio = só o anel (botões de
   ícone). O anel herda a cor do texto (currentColor): funciona em cheio,
   contorno e destrutivo sem regra por cor.

   Espera de área: onde o conteúdo que vem é lista/tabela/texto, entra o
   esqueleto (seção 39). Onde é uma caixa pequena sem forma previsível
   (cálculo, contador, pré-visualização, "carregar mais"), entra
   `.hrs-espera-area`: o anel do cartão de espera (seção 40), menor, com
   uma frase curta. Os 15 spinners grandes soltos viraram um dos dois.
   ========================================================================== */
.hrs-anel {
  display: inline-block;
  width: 1em;
  height: 1em;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: var(--raio-circulo);
  animation: hrs-girar .6s linear infinite;
  vertical-align: -.15em;
  opacity: .85;
}
.btn.hrs-ocupado { pointer-events: none; }
.btn.hrs-ocupado .hrs-anel { margin-right: 6px; }
.btn.hrs-ocupado .hrs-anel:only-child { margin-right: 0; }

.hrs-espera-area {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--esp-2);
  padding: var(--esp-4);
  color: var(--cor-texto-suave);
  font-size: 13px;
}
.hrs-espera-area .hrs-espera-anel { width: 18px; height: 18px; border-width: 2px; }
.overlay > .hrs-espera-anel { width: 28px; height: 28px; border-width: 3px; } /* dentro do .overlay do AdminLTE (card) */

/* ==========================================================================
   45. ACABAMENTOS — popover, <hr> e tamanhos de fonte (08/09/2026)

   Popover: era o do Bootstrap cru (borda cinza-escura, cabeçalho #f7f7f7,
   raio .3rem) em 46 usos (erro da venda interna, motivo de cancelamento,
   preview da proposta). Ganha a mesma família do tooltip (seção 15): raio,
   sombra e borda dos tokens, cabeçalho em superfície-alt.

   <hr>: 68 usos; a linha era rgba(0,0,0,.1) do Bootstrap — vira a borda do
   sistema, a mesma dos cards e das tabelas.

   Tamanho de fonte: 130 `style="font-size: …"` em 38 arquivos, com 30
   valores diferentes (12px, .8rem, .85rem, 8pt, .9em…). Os de texto viram
   as cinco classes abaixo, presas aos tokens --fonte-*; os de destaque
   (larger, x-large, 150%, 1.5em…) ficam, porque são tamanho de número/KPI,
   não de texto, e cada um foi escolhido para o seu lugar.
   ========================================================================== */
.popover {
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio-md);
  box-shadow: var(--sombra-md);
  font-size: var(--fonte-sm);
  max-width: 300px;
}
.popover-header {
  background-color: var(--cor-superficie-alt);
  border-bottom-color: var(--cor-borda);
  color: var(--cor-texto);
  font-size: var(--fonte-sm);
  font-weight: 600;
  padding: 6px 10px;
}
.popover-body { color: var(--cor-texto); padding: 8px 10px; }
.bs-popover-top > .arrow::before, .bs-popover-auto[x-placement^="top"] > .arrow::before { border-top-color: var(--cor-borda); }
.bs-popover-right > .arrow::before, .bs-popover-auto[x-placement^="right"] > .arrow::before { border-right-color: var(--cor-borda); }
.bs-popover-bottom > .arrow::before, .bs-popover-auto[x-placement^="bottom"] > .arrow::before { border-bottom-color: var(--cor-borda); }
.bs-popover-left > .arrow::before, .bs-popover-auto[x-placement^="left"] > .arrow::before { border-left-color: var(--cor-borda); }
.bs-popover-bottom .popover-header::before { border-bottom-color: var(--cor-superficie-alt); }

hr { border-top-color: var(--cor-borda); }

.hrs-fonte-xs { font-size: var(--fonte-xs) !important; }
.hrs-fonte-sm { font-size: var(--fonte-sm) !important; }
.hrs-fonte-md { font-size: var(--fonte-md) !important; }
.hrs-fonte-lg { font-size: var(--fonte-lg) !important; }
.hrs-fonte-xl { font-size: var(--fonte-xl) !important; }

/* ==========================================================================
   46. WIDGETS DE TERCEIROS E SOBRAS DO ADMINLTE (08/09/2026)

   Auditoria antes do push: tudo que ainda desenhava com o tema da própria lib.
   - Tour guiado (driver.js): balão em fonte do sistema, botões crus do
     navegador, X preto. Vira cartão do padrão com botões da tabela de cores.
   - .callout (AdminLTE): usado no aviso do 2FA e na justificativa da edição
     de pedido. Ganha fundo suave + fio da cor do estado.
   - .bg-gradient-primary (AdminLTE): era o azul velho #007bff em degradê —
     estava no banner do perfil. Vira a primária.
   - jQuery UI autocomplete (cidade nos filtros de atividades): lista do
     tema Smoothness. Vira a lista do select2 (seção 16).
   - Lista dupla (bootstrap-duallistbox, roleta e representantes): caixas
     nativas e botões `btn` sem cor. Botões viram contorno cinza; caixas e
     filtros ganham borda e raio do padrão.
   - intl-tel-input (telefone com bandeira): a lista de países ganha raio,
     sombra e hover do padrão.
   ========================================================================== */
/* Tudo com `.driver-popover` na frente: o driver.min.css costuma carregar
   DEPOIS deste arquivo, com seletores da mesma força, e vencia (sombra branca
   no texto do "Próximo", fonte genérica no título) — 28/09/2026. */
.driver-popover.driver-popover {
  font-family: inherit;
  border-radius: var(--raio-lg);
  box-shadow: var(--sombra-lg);
  padding: var(--esp-4);
  max-width: 340px;
  color: var(--cor-texto);
}
.driver-popover .driver-popover-title { font-size: 15px; font-weight: 600; color: var(--cor-texto); }
.driver-popover .driver-popover-description { font-size: 13.5px; line-height: 1.5; color: var(--cor-texto-medio); margin-top: 6px; }
.driver-popover .driver-popover-progress-text { font-size: 12px; color: var(--cor-texto-suave); }
.driver-popover .driver-popover-footer { margin-top: var(--esp-3); gap: 6px; }
.driver-popover .driver-popover-navigation-btns button,
.driver-popover .driver-popover-footer button {
  font-family: inherit; font-size: 13px; font-weight: 500; line-height: 1.4;
  padding: 5px 12px; border-radius: var(--raio-md); text-shadow: none; box-shadow: none;
  border: 1px solid var(--cor-borda-forte); background: var(--cor-superficie); color: var(--cor-texto-medio);
}
.driver-popover .driver-popover-navigation-btns button:hover { background: var(--cor-hover-neutro); color: var(--cor-texto); }
.driver-popover .driver-popover-navigation-btns .driver-popover-next-btn { background: var(--cor-primaria); border-color: var(--cor-primaria); color: #fff; }
.driver-popover .driver-popover-navigation-btns .driver-popover-next-btn:hover { background: var(--cor-primaria-hover); border-color: var(--cor-primaria-hover); color: #fff; }
.driver-popover .driver-popover-btn-disabled { opacity: .5; }
.driver-popover .driver-popover-close-btn { color: var(--cor-texto-fraco); font-size: 18px; width: 28px; height: 28px; border-radius: var(--raio-circulo); top: 8px; right: 8px; }
.driver-popover .driver-popover-close-btn:hover { background: var(--cor-hover-neutro); color: var(--cor-texto); }
.driver-popover-arrow-side-top.driver-popover-arrow { border-top-color: var(--cor-superficie); }
.driver-popover-arrow-side-bottom.driver-popover-arrow { border-bottom-color: var(--cor-superficie); }
.driver-popover-arrow-side-left.driver-popover-arrow { border-left-color: var(--cor-superficie); }
.driver-popover-arrow-side-right.driver-popover-arrow { border-right-color: var(--cor-superficie); }

.callout {
  border-radius: var(--raio-md);
  border: 1px solid var(--cor-borda);
  border-left-width: 4px;
  background: var(--cor-superficie-alt);
  box-shadow: none;
  padding: var(--esp-3) var(--esp-4);
}
.callout.callout-warning { border-left-color: var(--cor-aviso); background: var(--cor-aviso-suave); }
.callout.callout-success { border-left-color: var(--cor-sucesso); background: var(--cor-sucesso-suave); }
.callout.callout-danger  { border-left-color: var(--cor-perigo); background: var(--cor-perigo-suave); }
.callout.callout-info    { border-left-color: var(--cor-info); background: var(--cor-info-suave); }

.bg-gradient-primary { background: var(--cor-primaria) linear-gradient(180deg, var(--cor-primaria), var(--cor-primaria-ativa)) repeat-x !important; color: #fff; }
.bg-gradient-success { background: var(--cor-sucesso) !important; color: #fff; }
.bg-gradient-danger  { background: var(--cor-perigo) !important; color: #fff; }
.bg-gradient-warning { background: var(--cor-aviso) !important; color: var(--cor-texto); }
.bg-gradient-info    { background: var(--cor-info) !important; color: #fff; }

.ui-autocomplete.ui-menu {
  border: 1px solid var(--cor-borda-forte); border-radius: var(--raio-md); box-shadow: var(--sombra-md);
  background: var(--cor-superficie); padding: 4px 0; font-family: inherit; font-size: 14px; max-height: 260px; overflow-y: auto;
}
.ui-autocomplete.ui-menu .ui-menu-item { padding: 0; }
.ui-autocomplete.ui-menu .ui-menu-item-wrapper { padding: 6px 12px; border: 0; margin: 0; color: var(--cor-texto); }
.ui-autocomplete.ui-menu .ui-menu-item-wrapper.ui-state-active { background: var(--cor-primaria); color: #fff; border-radius: 0; }

.bootstrap-duallistbox-container .box1, .bootstrap-duallistbox-container .box2 { }
.bootstrap-duallistbox-container .btn { border: 1px solid var(--cor-borda-forte); background: var(--cor-superficie); color: var(--cor-texto-medio); font-size: 13px; }
.bootstrap-duallistbox-container .btn:hover { background: var(--cor-hover-neutro); color: var(--cor-texto); }
.bootstrap-duallistbox-container .filter { border-radius: var(--raio-md); font-size: 13px; }
.bootstrap-duallistbox-container select { border: 1px solid var(--cor-borda-forte); border-radius: 0 0 var(--raio-md) var(--raio-md); font-size: 13px; padding: 4px; }
.bootstrap-duallistbox-container select option { padding: 3px 6px; }
.bootstrap-duallistbox-container .info { font-size: 12px; color: var(--cor-texto-suave); }

.iti__dropdown-content { border: 1px solid var(--cor-borda-forte); border-radius: var(--raio-md); box-shadow: var(--sombra-md); font-size: 13px; }
.iti__country.iti__highlight { background: var(--cor-hover-neutro); }
.iti__dial-code { color: var(--cor-texto-suave); }

/* ==========================================================================
   47. BOTÃO FLUTUANTE (10/09/2026, opção A de três)

   O botão redondo do canto inferior direito, com ou sem menu. Existia em dez
   telas com NOVE cópias do CSS (`.floating-button button`, cada uma com uma
   diferença: com/sem borda, `white`/superfície, padding que ovalava o círculo)
   e três desenhos de menu (cards soltos, o do negócio, nenhum). Agora é um só:
   tag de bloco `{% botao_flutuante %}` (templatetags/design_system.py) e o
   markup em components/botao_flutuante.html.

   O menu é o MENU SUSPENSO da seção 20, aberto para cima — mesma borda, canto,
   sombra e densidade. Rejeitadas: discagem rápida (bolinhas com rótulo; alta
   com 4+ ações, sem separador) e lista de cards repintada (ocupa mais tela).
   ========================================================================== */
.hrs-fab {
  position: fixed;
  /* --hrs-fab-dx/-dy: arrastado (computador) numa área do canto, pelo base.js */
  right: calc(25px + var(--hrs-fab-dx, 0px));
  /* respeita o indicador de home / cantos curvos (safe area); 0 quando não há */
  bottom: calc(30px + env(safe-area-inset-bottom, 0px) + var(--hrs-fab-dy, 0px));
  z-index: 1000;
  transition: right var(--transicao-rapida);
}
.hrs-fab-btn {
  width: 52px;
  height: 52px;
  padding: 0;
  border: 0;
  border-radius: var(--raio-circulo);
  /* o tom do menu lateral, como a pílula da fila: flutuante é casca, não ação da tela */
  background-color: var(--cor-casca-fundo);
  color: #fff;
  font-size: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-shadow: var(--sombra-md);
  cursor: pointer;
  transition: background-color var(--transicao-rapida), transform var(--transicao-rapida), box-shadow var(--transicao-rapida);
}
/* arrastável no computador (base.js): sem isto, em tablet ≥ 768px o dedo rolava a página */
@media (min-width: 768px) { .hrs-fab:not(.mapa-fab) .hrs-fab-btn { touch-action: none; } }
.hrs-fab-btn:hover {
  filter: brightness(1.4);  /* o fundo é quase preto: 1.15 (o da pílula) não se via */
  color: #fff;
  box-shadow: var(--sombra-lg);
  transform: translateY(-1px);
}
.hrs-fab-btn:focus { outline: 0; }
.hrs-fab-btn:focus-visible { box-shadow: var(--sombra-foco), var(--sombra-md); }
.hrs-fab-btn i { transition: transform .15s; }
.hrs-fab.aberto .hrs-fab-btn i.fa-plus { transform: rotate(45deg); }
.hrs-fab.hrs-fab-arrastando { transition: none; }
.hrs-fab.hrs-fab-arrastando .hrs-fab-btn { cursor: grabbing; transform: none; }

/* O menu: fechado por padrão; `.aberto` no invólucro abre (base.js). */
.hrs-fab-menu {
  display: none;
  position: absolute;
  right: 0;
  bottom: 62px;
  min-width: 220px;
  max-width: calc(100vw - 50px);
  padding: var(--esp-2) 0;
  background-color: var(--cor-superficie);
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio-lg);
  box-shadow: var(--sombra-md);
}
.hrs-fab.aberto .hrs-fab-menu { display: block; }
.hrs-fab-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: var(--esp-2) var(--esp-4);
  border: 0;
  background: none;
  font-size: var(--fonte-md);
  color: var(--cor-texto);
  text-align: left;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}
.hrs-fab-item > i { width: 16px; text-align: center; color: var(--cor-texto-fraco); }
.hrs-fab-item:hover,
.hrs-fab-item:focus { background-color: var(--cor-hover-neutro); color: var(--cor-texto); text-decoration: none; outline: 0; }
/* o outline acima tirava o anel sem devolver nada: quem navega por teclado
   perdia o rastro dentro do menu do botão flutuante (24/09/2026) */
.hrs-fab-item:focus-visible { box-shadow: var(--sombra-foco); }
.hrs-fab-item:hover > i { color: var(--cor-texto-suave); }
.hrs-fab-sep { border-top: 1px solid var(--cor-borda); margin: var(--esp-2) 0; }

/* Com o painel de filtros aberto o botão anda junto, para não ficar atrás
   dele (antes só o fluxo fazia isso, por JS). No celular o painel ocupa a
   tela toda e o botão simplesmente fica atrás. */
@media (min-width: 768px) {
  body:has(#sidebar-wrapper.toggled) .hrs-fab { right: calc(475px + var(--hrs-fab-dx, 0px)); }
}

/* ==========================================================================
   48. TÍTULO DE SEÇÃO NO CORPO e RÓTULO DE GRUPO (10/09/2026, opção A de três)

   Fora do cabeçalho de card e do modal, cada tela desenhava o título de seção
   de um jeito: <h2><b> centralizado no pedido, <h5> com ícone nas rotas, <h5>
   com bolinha azul no perfil, <h6> em caixa alta na auditoria. Dois desenhos
   já eram quase o padrão — o cabeçalho de seção do modal do fluxo e o rótulo
   em caixa alta do negócio — e são eles que viram as classes daqui.

   DOIS NÍVEIS:
     .hrs-secao   título de seção: ícone na primária, título 15px, apoio
                  opcional em 12px, contador/ações à direita, divisor fino
                  embaixo (é o que separa o título de uma tabela sem borda).
     .hrs-rotulo  rótulo de grupo: caixa alta 11px cinza, para agrupar campos
                  dentro de uma seção ("Resumo do negócio", "Operação Senior").

   MARKUP
     <div class="hrs-secao">
       <i class="fa-solid fa-list"></i>
       <h6 class="hrs-secao-titulo">Lista de itens</h6>
       <div class="hrs-secao-acoes"><span class="hrs-etiqueta hrs-etiqueta-neutra">12</span><a …>Nova</a></div>
     </div>
   Com texto de apoio, título e apoio vão num .hrs-secao-txt:
     <div class="hrs-secao"><i …></i><div class="hrs-secao-txt"><h6 class="hrs-secao-titulo">Dados pessoais</h6><span class="hrs-secao-apoio">Informações básicas.</span></div></div>

   Rejeitadas: B ícone numa caixa primária-suave sem divisor (o do perfil; sem
   o divisor a tabela solta embaixo fica sem começo) e C caixa alta com filete
   (bonita no negócio, pequena demais para abrir tabela ou formulário, e fica
   igual ao rótulo de grupo).
   ========================================================================== */
.hrs-secao {
  display: flex;
  /* flex-start, não center: com apoio de 2-3 linhas (organograma de grupos) o
     ícone e as ações ficavam "flutuando" no meio do bloco em vez de alinhados
     com a primeira linha do título. Nos casos de 1 linha (a maioria) o
     resultado é idêntico a center, então não muda nada nos outros 6 usos. */
  align-items: flex-start;
  gap: 10px;
  margin: 0 0 var(--esp-3);
  padding-bottom: var(--esp-2);
  border-bottom: 1px solid var(--cor-borda);
}
.hrs-secao > i { width: 20px; flex: none; text-align: center; font-size: 15px; color: var(--cor-primaria); }
.hrs-secao-txt { min-width: 0; }
.hrs-secao > h6,
.hrs-secao-titulo { margin: 0; font-size: 15px; font-weight: 700; line-height: 1.2; color: var(--cor-texto); }
.hrs-secao-apoio { display: block; margin-top: 1px; font-size: 12px; color: var(--cor-texto-suave); }
.hrs-secao-acoes { margin-left: auto; display: flex; align-items: center; gap: var(--esp-2); }
.hrs-secao-acoes .btn { margin: 0; }

.hrs-rotulo {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0 0 6px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--cor-texto-suave);
}
.hrs-rotulo > i { font-size: 11px; color: var(--cor-texto-fraco); }

/* ==========================================================================
   49. VISUALIZADOR DE ARQUIVO (10/09/2026, opção A de três)

   Havia quatro: desenhos técnicos (modal claro só com imagem, sem Baixar),
   fluxo (modal com imagem/PDF/vídeo/3D), rotas (modal de corpo escuro que
   fechava e reabria o modal de arquivos) e produto (overlay escuro próprio
   com setas). Agora é um só, montado pelo JS: Horus.visualizar({ itens, indice }).

   É o modal claro do site — cabeçalho do padrão com ações (Baixar, Abrir em
   nova aba, Fechar), palco no cinza-fundo, setas quando há mais de um arquivo
   e faixa de miniaturas. Rejeitadas: tela cheia escura (bonita para foto, mas
   destoa de todo o resto do Hórus) e modal com corpo escuro e ações no rodapé
   (dois X e o rodapé roubava altura do PDF). Espaçamento aprovado em protótipo
   de tamanho real.

   Abre por cima de outro modal (rotas, produto, fluxo): o JS sobe o z-index
   dele e do fundo, e devolve o `modal-open` ao body quando fecha.
   ========================================================================== */
.hrs-vis .modal-dialog { max-width: min(1200px, calc(100vw - 2 * var(--esp-5))); }
.hrs-vis .modal-content {
  height: min(880px, calc(100vh - 2 * var(--esp-5)));
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.hrs-vis .modal-header { flex: none; }
.hrs-vis .hrs-modal-cab > div { min-width: 0; }
.hrs-vis .hrs-modal-cab-titulo { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hrs-vis-acoes { margin-left: auto; display: flex; align-items: center; gap: var(--esp-1); flex: none; }
.hrs-vis-acoes .close { margin: 0 0 0 var(--esp-1); }
.hrs-vis-contador { font-weight: var(--peso-forte); color: var(--cor-texto-medio); }

/* O palco: cinza-fundo, o arquivo centrado. As laterais de 72px são a calha
   das setas — a imagem nunca passa por baixo delas. */
.hrs-vis-palco {
  flex: 1;
  min-height: 0;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--esp-5) 72px;
  background: var(--cor-fundo);
}
.hrs-vis-palco.sozinho { padding: var(--esp-5); }
.hrs-vis-palco > img,
.hrs-vis-palco > video {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: var(--raio-md);
  box-shadow: var(--sombra-md);
  background: var(--cor-superficie);
}
/* PDF e 3D já têm moldura própria: ocupam o palco inteiro, sem respiro. */
.hrs-vis-palco.cheio { padding: 0; }
.hrs-vis-palco > iframe,
.hrs-vis-palco > model-viewer { width: 100%; height: 100%; border: 0; display: block; background: var(--cor-superficie-alt); }

/* Tipo sem pré-visualização, ou que falhou ao carregar. */
.hrs-vis-outro { text-align: center; max-width: 360px; }
.hrs-vis-outro > i { font-size: 40px; color: var(--cor-texto-fraco); }
.hrs-vis-outro-titulo { margin: var(--esp-3) 0 2px; font-weight: var(--peso-forte); color: var(--cor-texto); overflow-wrap: anywhere; }
.hrs-vis-outro-texto { margin: 0 0 var(--esp-3); font-size: var(--fonte-sm); color: var(--cor-texto-suave); }

.hrs-vis-seta {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 1;
  width: 40px;
  height: 40px;
  padding: 0;
  border-radius: var(--raio-circulo);
  border: 1px solid var(--cor-borda);
  background: var(--cor-superficie);
  color: var(--cor-texto);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-shadow: var(--sombra-md);
  cursor: pointer;
  transition: border-color var(--transicao-rapida), color var(--transicao-rapida);
}
.hrs-vis-seta:hover:not(:disabled) { border-color: var(--cor-primaria); color: var(--cor-primaria); }
.hrs-vis-seta:focus-visible { outline: 0; box-shadow: var(--sombra-foco), var(--sombra-md); }
.hrs-vis-seta:disabled { opacity: .35; cursor: default; }
.hrs-vis-seta-ant { left: var(--esp-4); }
.hrs-vis-seta-prox { right: var(--esp-4); }

.hrs-vis-miniaturas {
  flex: none;
  display: flex;
  gap: var(--esp-2);
  padding: var(--esp-3) var(--esp-4);
  overflow-x: auto;
  border-top: 1px solid var(--cor-borda);
  background: var(--cor-superficie);
}
.hrs-vis-miniatura {
  flex: none;
  width: 64px;
  height: 48px;
  padding: 0;
  border: 2px solid transparent;
  border-radius: var(--raio-md);
  overflow: hidden;
  background: var(--cor-superficie-alt);
  color: var(--cor-texto-fraco);
  cursor: pointer;
  opacity: .7;
}
.hrs-vis-miniatura img { width: 100%; height: 100%; object-fit: cover; display: block; }
.hrs-vis-miniatura:hover { opacity: 1; }
.hrs-vis-miniatura.ativa { border-color: var(--cor-primaria); opacity: 1; }
.hrs-vis-miniatura:focus-visible { outline: 0; box-shadow: var(--sombra-foco); }

/* Celular: tela cheia (um modal de 90% num celular é tela cheia com moldura). */
@media (max-width: 767.98px) {
  /* O Bootstrap soma padding-right no .modal para compensar a barra de rolagem
     do body; na tela cheia isso vira uma faixa da página à direita. */
  .hrs-vis { padding-right: 0 !important; }
  .hrs-vis .modal-dialog { max-width: 100%; margin: 0; min-height: 100%; }
  .hrs-vis .modal-content { height: 100dvh; border-radius: 0; border: 0; }
  .hrs-vis-palco { padding: var(--esp-3); }
  .hrs-vis-palco.cheio { padding: 0; }
  .hrs-vis-seta { width: 36px; height: 36px; background: rgba(255, 255, 255, .92); }
  .hrs-vis-seta-ant { left: var(--esp-2); }
  .hrs-vis-seta-prox { right: var(--esp-2); }
  .hrs-vis-nova-aba { display: none; }
  .hrs-vis-miniatura { width: 52px; height: 40px; }
}

/* ==========================================================================
   50. CHECKLIST DE TAREFA (23/09/2026)

   Itens de execução de uma tarefa, montados pelo JS: Horus.checklistTarefa
   (componentes.js). Saíram do CSS do modal do /fluxo_pedido/ quando os
   cards de /crm/negocio/<id>/ passaram a mostrar o mesmo checklist.

   Grade com colunas fixas (finalizado / item / valor / responsável) para as
   linhas alinharem como uma mini-tabela. Barra de progresso no topo conta só
   os itens finalizados (checkbox) — verde só quando todos estão. O collapse fica DENTRO do .card da tarefa
   (mesma faixa lateral colorida do status), então só margin-top não separa
   nada — a faixa continua descendo e o bloco parece grudado. Margem nos 4
   lados faz o checklist "flutuar" dentro do card, recuado da faixa e das
   bordas, como um cartão próprio — não uma extensão do corpo da tarefa.
   ========================================================================== */
.hrs-checklist {
  margin: var(--esp-2) var(--esp-3) var(--esp-3);
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio-md);
  background: var(--cor-superficie-alt);
  overflow: hidden;
}
.hrs-checklist-progresso {
  display: flex;
  align-items: center;
  gap: var(--esp-2);
  padding: var(--esp-2) var(--esp-3);
  border-bottom: 1px solid var(--cor-borda);
}
.hrs-checklist-barra { flex: 1; }
.hrs-checklist-barra .progress-bar { transition: width .3s ease, background-color .3s ease; }
.hrs-checklist-barra .progress-bar.hrs-checklist-barra-completa { background-color: var(--cor-sucesso); }
.hrs-checklist-progresso-texto { font-size: 12px; color: var(--cor-texto-suave); white-space: nowrap; }
@media (prefers-reduced-motion: reduce) {
  .hrs-checklist-barra .progress-bar { transition: none; }
}
.hrs-checklist-cabecalho,
.hrs-checklist-item {
  display: grid;
  grid-template-columns: 20px 1fr 170px 160px;
  align-items: center;
  gap: var(--esp-2);
  padding: var(--esp-2) var(--esp-3);
}
.hrs-checklist-cabecalho {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .03em;
  color: var(--cor-texto-suave);
  border-bottom: 1px solid var(--cor-borda);
}
.hrs-checklist-item { font-size: 13.5px; border-bottom: 1px solid var(--cor-borda); }
.hrs-checklist-item:last-child { border-bottom: 0; }
.hrs-checklist-descricao { min-width: 0; color: var(--cor-texto-medio); }
.hrs-checklist-finalizado .hrs-checklist-descricao { color: var(--cor-texto-suave); text-decoration: line-through; }
.hrs-checklist-controle { display: flex; justify-content: flex-start; }
.hrs-checklist-resp { min-width: 0; }
.hrs-checklist-check { display: flex; align-items: center; margin: 0; }
.hrs-checklist-check input { width: 16px; height: 16px; margin: 0; cursor: pointer; accent-color: var(--cor-sucesso); }
.hrs-checklist-check input:disabled { cursor: not-allowed; opacity: .5; }
/* Item "bool": par Sim/Não (3 estados — nenhum ativo = pendente) + limpar. */
.hrs-checklist-bool .btn { min-width: 44px; }
.hrs-checklist-bool .btn.ativo-sim { background: var(--cor-sucesso); border-color: var(--cor-sucesso); color: #fff; }
.hrs-checklist-bool .btn.ativo-nao { background: var(--cor-perigo); border-color: var(--cor-perigo); color: #fff; }
@media (max-width: 575.98px) {
  .hrs-checklist-cabecalho { display: none; }
  /* checkbox e item na 1ª linha; valor e responsável embaixo, alinhados ao item */
  .hrs-checklist-item { grid-template-columns: 20px 1fr; gap: 6px var(--esp-2); }
  .hrs-checklist-controle,
  .hrs-checklist-resp { grid-column: 2; }
}

/* 
   50. GALERIA DE ESCOLHA (25/09/2026)

   Popover fixo com uma lista de opções que mostram um VALOR grande + o nome
   — "troque isto por aquilo, vendo o valor de cada opção antes de decidir".
   Nasceu no estúdio da home (trocar um número do placar do vendedor por
   outra métrica); migrada para cá por ser genérica — serve para qualquer
   tela que precise trocar uma métrica ou um item com prévia de valor, não
   só o placar. O GATILHO (no placar, o botão "Trocar" de cada número,
   `.hs-trocar-vaga`) continua sendo da tela; só o popover é peça do sistema.

   Item ATUAL: `aria-selected="true"` é a única fonte do estado (sem
   duplicar em classe `.on` — o JS antigo tinha os dois). Item
   SECUNDÁRIO/USADO (já ocupa outro lugar; escolher ele troca os dois):
   `.hrs-galeria-item-usado`, com a nota que explica a troca.

   <div class="hrs-galeria" role="dialog" aria-label="Trocar “Negócios abertos”">
     <div class="hrs-galeria-titulo">Trocar “Negócios abertos” por…</div>
     <ul class="hrs-galeria-lista" role="listbox" aria-label="Números disponíveis">
       <li class="hrs-galeria-item" role="option" tabindex="-1" aria-selected="true">
         <b class="hrs-galeria-valor">42</b><span class="hrs-galeria-nome">Negócios abertos</span>
       </li>
       <li class="hrs-galeria-item hrs-galeria-item-usado" role="option" tabindex="-1" aria-selected="false">
         <b class="hrs-galeria-valor">7</b><span class="hrs-galeria-nome">Tarefas atrasadas</span>
         <small class="hrs-galeria-nota">troca com o 2º</small>
       </li>
     </ul>
   </div>

   Acessibilidade herdada do estúdio, não inventada agora: alvo de toque
   >= 44px (token `--mob-alvo-toque-min`), foco visível no item, navegação
   por setas/Enter/Esc feita pelo JS de cada tela (é comportamento, não
   CSS) e `prefers-reduced-motion` já coberto pelos tokens de transição.
   ========================================================================== */
.hrs-galeria {
  position: fixed;
  z-index: var(--z-popover);
  background: var(--cor-superficie);
  border: 1px solid var(--cor-borda);
  border-radius: 12px;
  /* Sombra maior e colorida (não `--sombra-lg`): é um popover solto sobre a
     tela, não um card — precisa se destacar mais do fundo cinza da home. */
  box-shadow: 0 14px 40px rgba(20, 28, 45, .2);
  padding: var(--esp-3);
  max-height: 70vh;
  overflow: auto;
}
.hrs-galeria-titulo { font-size: 12.5px; font-weight: var(--peso-forte); color: var(--cor-texto); margin-bottom: var(--esp-2); }
.hrs-galeria-lista { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: 6px; }
.hrs-galeria-item {
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio-lg);
  padding: 7px 9px;
  font-size: 11.5px;
  color: var(--cor-texto-medio);
  cursor: pointer;
  min-height: var(--mob-alvo-toque-min);
}
.hrs-galeria-valor { display: block; font-size: var(--fonte-lg); color: var(--cor-texto); font-variant-numeric: tabular-nums; }
.hrs-galeria-nome { display: block; }
.hrs-galeria-nota { display: block; font-size: 10.5px; color: var(--cor-texto-suave); }
.hrs-galeria-item:hover,
.hrs-galeria-item:focus { border-color: var(--cor-link); outline: none; background: var(--cor-primaria-suave); }
.hrs-galeria-item[aria-selected="true"] { border-color: var(--cor-link); background: var(--cor-primaria-suave); }
.hrs-galeria-item[aria-selected="true"] .hrs-galeria-nome::after { content: " · atual"; font-weight: var(--peso-forte); color: var(--cor-link); }
/* Secundário: já ocupa outro lugar. Opacidade leve, não a do desabilitado
   (`.hrs-lista-opcoes-off`, seção 51) — este item continua clicável, só
   avisa que escolhê-lo troca os dois. Estado sem estilo próprio no código
   de origem (só a nota em texto); ganhou este toque ao virar peça do
   sistema, documentada como parte do vocabulário. */
.hrs-galeria-item-usado { opacity: .82; }

/* ==========================================================================
   51. FRASE EDITÁVEL — "construtor por frase" (25/09/2026)

   Texto corrido com partes clicáveis que trocam de valor sem sair da frase
   ("Negócios ABERTOS de TODOS os vendedores neste MÊS"). Nasceu no editor de
   receita do estúdio da home; migrada para cá por ser um padrão de
   interação genérico — qualquer "monte uma regra lendo a frase", não algo
   específico de card de home.

   PEÇAS
     .hrs-frase           a caixa da frase (fundo suave; `position: relative`
                           é onde a lista de opções se ancora)
     .hrs-frase-peca       cada parte clicável — sempre `<button>`, nunca link
     .hrs-frase-destaque   parte que não se clica AGORA porque a edição dela
                           está em outro lugar (ex.: no formulário do modo
                           avançado); é um `<mark>` semântico, cor de aviso
     .hrs-frase-resumo    modificador: a frase virou resumo só-leitura (o
                           formulário embaixo passou a ser a única fonte da
                           verdade) — as peças viram `<b>`, sem clique
     .hrs-lista-opcoes     o popover da lista de escolhas (role=listbox) que
                           abre sob a peça clicada
     .hrs-lista-opcoes-off opção indisponível na lista — o motivo vem por
                           texto (`<small>`/`aria-describedby`), nunca só cor
     .hrs-lista-opcoes-grupo cabeçalho de grupo na lista (`<li role=
                           "presentation">`); o teclado pula de opção em opção

   <div class="hrs-frase" role="group" aria-labelledby="frase_rot">
     Negócios
     <button type="button" class="hrs-frase-peca" data-chave="medida" aria-haspopup="listbox" aria-expanded="false">abertos <i class="fas fa-caret-down"></i></button>
     de <button type="button" class="hrs-frase-peca" data-chave="escopo" aria-haspopup="listbox" aria-expanded="false">todos <i class="fas fa-caret-down"></i></button>
     <mark class="hrs-frase-destaque">no estado SP</mark>
   </div>
   <ul class="hrs-lista-opcoes" role="listbox" aria-label="De quem">
     <li role="option" tabindex="-1" aria-selected="true">Todos</li>
     <li role="option" tabindex="-1" aria-selected="false" aria-disabled="true" class="hrs-lista-opcoes-off">Só meus<small>Esta fonte não separa por vendedor</small></li>
   </ul>

   Estado atual da lista é `aria-selected="true"` — mesma regra da galeria
   (seção 50). Abrir/fechar, foco e navegação por setas/Enter/Esc são do JS
   de cada tela; o CSS só desenha os estados.
   ========================================================================== */
.hrs-frase {
  font-size: 14.5px;
  line-height: 2.2;
  color: var(--cor-texto);
  background: var(--cor-superficie-alt);
  border-radius: var(--raio-xl);
  padding: var(--esp-2) var(--esp-3);
  position: relative;
}
.hrs-frase-resumo { line-height: 1.6; font-size: 13.5px; }
/* Nas duas formas — peça clicável (abaixo) e texto só-leitura do resumo — a
   parte "viva" da frase usa a cor de link: é o mesmo azul que já marcava
   `.hs-peca`/`.hs-frase b` (#1d4ed8) antes de virar token. */
.hrs-frase b { color: var(--cor-link); }
.hrs-frase-peca {
  border: 0;
  border-bottom: 2px solid var(--cor-link);
  background: var(--cor-primaria-suave);
  color: var(--cor-link);
  font-weight: var(--peso-forte);
  border-radius: 6px 6px 2px 2px;
  padding: 2px 7px;
  min-height: 26px;
  font-size: inherit;
  line-height: 1.3;
  cursor: pointer;
}
.hrs-frase-peca:hover {
  /* Um tom mais saturado que --cor-primaria-suave (o fundo em repouso) para
     o hover se notar; não existe token de "hover da suave" hoje — a suave é
     um valor único, sem variante mais escura. Documentado aqui em vez de
     inventar um token para um uso só. */
  background: #dbe6ff;
}
.hrs-frase-peca:focus-visible { outline: 3px solid var(--cor-link); outline-offset: 2px; }
.hrs-frase-peca i { font-size: 10px; }
.hrs-frase-destaque {
  /* Família "aviso" (âmbar) para o destaque: é a cor semântica mais perto de
     "chamar atenção sem ser erro" que o Hórus já tem — não existe token de
     "mark"/highlight dedicado, e criar um só para isto seria uma paleta
     concorrente do tamanho que os tokens existem para evitar. */
  background: var(--cor-aviso-suave);
  color: var(--cor-aviso-texto);
  border-radius: var(--raio-sm);
  padding: 1px 4px;
  font-weight: var(--peso-forte);
}
.hrs-lista-opcoes {
  position: absolute;
  /* z-index local (não `--z-popover`): a lista é `position: absolute` dentro
     do `.hrs-frase`, que não é fixo nem sai do fluxo da página — só precisa
     ficar acima do conteúdo vizinho ali dentro, não competir com modal/
     dropdown globais. */
  z-index: 30;
  left: var(--esp-2);
  right: var(--esp-2);
  margin-top: 2px;
  list-style: none;
  padding: var(--esp-1);
  background: var(--cor-superficie);
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio-xl);
  box-shadow: 0 10px 30px rgba(20, 28, 45, .18);
  max-height: 260px;
  overflow: auto;
  line-height: 1.35;
}
.hrs-lista-opcoes li { padding: 7px 10px; border-radius: 7px; font-size: 13px; cursor: pointer; min-height: 32px; }
.hrs-lista-opcoes li:hover,
.hrs-lista-opcoes li:focus { background: var(--cor-primaria-suave); outline: none; }
.hrs-lista-opcoes li[aria-selected="true"] { font-weight: var(--peso-forte); color: var(--cor-link); }
.hrs-lista-opcoes li small { display: block; font-size: 11px; color: var(--cor-texto-suave); font-weight: var(--peso-normal); }
.hrs-lista-opcoes-off { opacity: .6; cursor: not-allowed !important; }
/* Cabeçalho de grupo dentro da lista (ex.: a área da fonte). Não é opção:
   role=presentation, sem hover, e o teclado pula de opção em opção. */
.hrs-lista-opcoes li.hrs-lista-opcoes-grupo { font-size: 10.5px; font-weight: var(--peso-forte); text-transform: uppercase; letter-spacing: .04em;
  color: var(--cor-texto-suave); min-height: 0; padding: 8px 10px 3px; cursor: default; background: none; }

/* ==========================================================================
   52. SEGMENTADO — escolha entre poucas opções vizinhas (25/09/2026)

   Um grupo de botões em que só UM vale por vez ("Computador | Celular",
   "Ajustar | 100%", "¼ ⅓ ½ ⅔ Inteira"). Nasceu no estúdio da home, onde
   havia dois grupos locais com estados ativos diferentes (um suave, outro
   primário cheio) e nenhum mostrava o foco do teclado — o overflow: hidden
   do grupo cortava o anel. Aqui: um estado ativo só (o suave, que não
   compete com o botão primário da tela) e foco sempre visível.

   <span class="hrs-segmentado" role="group" aria-label="Prévia por tamanho de tela">
     <button type="button" aria-pressed="true">Computador</button>
     <button type="button" aria-pressed="false">Celular</button>
   </span>

   Estado: `aria-pressed="true"` é a fonte do estado (sem classe paralela).
   `.hrs-segmentado-bloco`: ocupa a largura toda, opções de mesma largura
   (dentro de painel/formulário). Poucas opções (2 a 5); mais que isso é
   select.
   ========================================================================== */
.hrs-segmentado {
  display: inline-flex;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio-lg);
  background: var(--cor-superficie);
}
.hrs-segmentado > button {
  border: 0;
  background: transparent;
  padding: 5px 11px;
  font-size: 12.5px;
  color: var(--cor-texto-medio);
  line-height: 1.4;
  cursor: pointer;
  transition: background-color var(--transicao-rapida);
}
.hrs-segmentado > button + button { border-left: 1px solid var(--cor-borda); }
.hrs-segmentado > button:first-child { border-radius: var(--raio-lg) 0 0 var(--raio-lg); }
.hrs-segmentado > button:last-child { border-radius: 0 var(--raio-lg) var(--raio-lg) 0; }
.hrs-segmentado > button:hover { background: var(--cor-superficie-alt); color: var(--cor-texto); }
.hrs-segmentado > button[aria-pressed="true"] { background: var(--cor-primaria-suave); color: var(--cor-link); font-weight: var(--peso-forte); }
/* Anel por DENTRO do botão: o grupo não corta e o vizinho não cobre. */
.hrs-segmentado > button:focus-visible { outline: 2px solid var(--cor-link); outline-offset: -2px; position: relative; z-index: 1; }
.hrs-segmentado-bloco { display: flex; width: 100%; }
.hrs-segmentado-bloco > button { flex: 1 1 0; padding: 6px 0; }

/* 53. (número livre — era o medidor da meta em barra linear; 29/10/2026:
   substituído pelo gauge em canvas (.hb-graf--medidor, home_graficos.js),
   o mesmo desenho do card pronto. Removido por não ter mais nenhum uso.) */

/* ==========================================================================
   54. FUNIL EM LISTA — etapa, barra e % do total (30/09/2026, opção B de três)

   As etapas de um funil em linhas: nome, barra proporcional à maior e o
   número com o % sobre o total. Não é trapézio de propósito: a foto de hoje
   não diminui etapa a etapa (Follow up tinha 247, Enviar proposta 47), e o
   trapézio sugeria uma conversão que não existe.

   <div class="hrs-funil" role="list">
     <div class="hrs-funil-item" role="listitem">
       <span class="hrs-funil-nome">Follow up</span>
       <span class="hrs-funil-trilho"><i style="width: 100%"></i></span>
       <b>247 <small>39%</small></b>
     </div>
   </div>
   ========================================================================== */
.hrs-funil { display: flex; flex-direction: column; gap: 6px; }
.hrs-funil-item { display: grid; grid-template-columns: minmax(0, 38%) minmax(0, 1fr) auto; align-items: center; gap: 10px;
  font-size: var(--fonte-sm); }
.hrs-funil-nome { color: var(--cor-texto-medio); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hrs-funil-trilho { display: block; height: 18px; }
.hrs-funil-trilho > i { display: block; height: 100%; border-radius: 4px; background: var(--cor-primaria); }
.hrs-funil-item > b { font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }
.hrs-funil-item > b small { font-weight: var(--peso-normal); color: var(--cor-texto-suave); margin-left: 2px; }

/* ==========================================================================
   55. MAPA DE LADRILHOS POR ESTADO (30/09/2026, opção B de três)

   Os 27 estados em quadrados, na posição aproximada do mapa, pintados em 5
   tons pelo valor, ao lado do ranking. Sem biblioteca nem desenho de mapa
   (GeoJSON): o contorno real pediria os dois em static/lib. A posição de cada
   estado vem do servidor (home_receita.LADRILHOS_UF: coluna e linha).

   <div class="hrs-mapa-uf-bloco">
     <div class="hrs-mapa-uf" role="img" aria-label="Valor por estado">
       <span class="hrs-mapa-uf-l hrs-mapa-uf-t4" style="grid-column: 4; grid-row: 6" title="SP: R$ 23,4 mi">SP</span>
       …
     </div>
     <ol class="hrs-mapa-uf-rank"><li><span>SP</span><b>R$ 23,4 mi</b></li>…</ol>
   </div>

   Tons: `.hrs-mapa-uf-t0` (menos) a `-t4` (mais); sem classe de tom = zero.
   ========================================================================== */
.hrs-mapa-uf-bloco { display: flex; flex-wrap: wrap; align-items: center; gap: 16px 24px; }
.hrs-mapa-uf { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 3px; width: 100%; max-width: 280px; }
.hrs-mapa-uf-l { aspect-ratio: 1; display: flex; align-items: center; justify-content: center; border-radius: 5px;
  font-size: 10.5px; font-weight: var(--peso-forte); background: var(--cor-superficie-alt); color: var(--cor-texto-medio); }
.hrs-mapa-uf-t0 { background: color-mix(in srgb, var(--cor-primaria) 14%, var(--cor-superficie)); color: var(--cor-texto); }
.hrs-mapa-uf-t1 { background: color-mix(in srgb, var(--cor-primaria) 32%, var(--cor-superficie)); color: var(--cor-texto); }
.hrs-mapa-uf-t2 { background: color-mix(in srgb, var(--cor-primaria) 52%, var(--cor-superficie)); color: var(--cor-texto); }
/* Texto escuro em todos os tons: branco sobre a primária dava 3,3:1 (e 2,4:1 no t3). */
.hrs-mapa-uf-t3 { background: color-mix(in srgb, var(--cor-primaria) 74%, var(--cor-superficie)); color: var(--cor-texto); }
.hrs-mapa-uf-t4 { background: var(--cor-primaria); color: var(--cor-texto); }
.hrs-mapa-uf-rank { flex: 1 1 160px; margin: 0; padding-left: 20px; font-size: var(--fonte-sm); }
.hrs-mapa-uf-rank li { padding: 2px 0; }
.hrs-mapa-uf-rank li b { float: right; font-variant-numeric: tabular-nums; font-weight: var(--peso-medio); }

/* ==========================================================================
   56. GAVETA LATERAL — uma lista curta sem sair da tela (30/09/2026, opção C de três)

   Painel que entra pela direita por cima da tela, com fundo escurecido. Nasceu
   no "do número para a lista" da home: clicar num número do card mostra os
   registros que ele conta. O rodapé (.hrs-gaveta-pe) é opcional — ações que
   valem para a lista inteira, como abrir a tela completa.
   No celular vira uma folha que sobe de baixo (como os modais).

   <div class="hrs-gaveta-fundo"></div>
   <aside class="hrs-gaveta" role="dialog" aria-modal="true" aria-labelledby="g_t">
     <header class="hrs-gaveta-cab">
       <div><h2 id="g_t">Mautic · jul/26</h2><p>1.963 negócios · os 8 mais recentes</p></div>
       <button type="button" class="hrs-btn hrs-btn-sm hrs-btn-icone hrs-btn-fantasma" aria-label="Fechar">…</button>
     </header>
     <div class="hrs-gaveta-corpo">
       <ul class="hrs-gaveta-lista">
         <li><a class="hrs-gaveta-item" href="/crm/negocio/1/">
           <b>Título do registro</b><span>R$ 12 mil</span><small>Etapa · Pessoa · 28/09/26</small>
         </a></li>
       </ul>
     </div>
     <footer class="hrs-gaveta-pe">…</footer>
   </aside>

   Item sem link: <div class="hrs-gaveta-item">. Carregando: `.hrs-gaveta-carregando`
   no corpo. O JS da tela cuida do foco (vai para a gaveta, volta ao que abriu)
   e do Esc.
   ========================================================================== */
.hrs-gaveta-fundo { position: fixed; inset: 0; z-index: var(--z-modal-fundo); background: rgba(15, 23, 42, .28); }
.hrs-gaveta { position: fixed; top: 0; right: 0; bottom: 0; z-index: var(--z-modal); width: min(440px, 92vw);
  display: flex; flex-direction: column; background: var(--cor-superficie); box-shadow: var(--sombra-lg); }
.hrs-gaveta-cab { display: flex; align-items: flex-start; gap: 10px; padding: 16px 16px 12px 20px;
  border-bottom: 1px solid var(--cor-borda); }
.hrs-gaveta-cab > div { flex: 1; min-width: 0; }
.hrs-gaveta-cab h2 { margin: 0; font-size: var(--fonte-lg); font-weight: var(--peso-forte); color: var(--cor-texto);
  overflow-wrap: anywhere; }
.hrs-gaveta-cab p { margin: 2px 0 0; font-size: var(--fonte-sm); color: var(--cor-texto-medio); }
.hrs-gaveta-corpo { flex: 1; overflow-y: auto; padding: 6px 10px; }
.hrs-gaveta-corpo > p { padding: 14px 10px; margin: 0; color: var(--cor-texto-medio); font-size: var(--fonte-sm); }
.hrs-gaveta-lista { list-style: none; margin: 0; padding: 0; }
.hrs-gaveta-lista li + li { border-top: 1px solid var(--cor-borda); }
.hrs-gaveta-item { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px 12px; padding: 10px;
  border-radius: var(--raio-md); color: var(--cor-texto); font-size: var(--fonte-sm); }
a.hrs-gaveta-item:hover, a.hrs-gaveta-item:focus-visible { background: var(--cor-hover-neutro); color: var(--cor-texto);
  text-decoration: none; }
a.hrs-gaveta-item:focus-visible { outline: none; box-shadow: var(--sombra-foco); }
.hrs-gaveta-item b { font-weight: var(--peso-medio); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hrs-gaveta-item span { font-variant-numeric: tabular-nums; white-space: nowrap; text-align: right; }
.hrs-gaveta-item small { grid-column: 1 / -1; color: var(--cor-texto-suave); font-size: var(--fonte-xs);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hrs-gaveta-pe { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 12px; padding: 12px 20px;
  border-top: 1px solid var(--cor-borda); font-size: var(--fonte-sm); color: var(--cor-texto-medio); }
.hrs-gaveta-carregando { height: 44px; margin: 8px 0; border-radius: var(--raio-md);
  background: linear-gradient(90deg, var(--cor-superficie-alt), var(--cor-hover-neutro), var(--cor-superficie-alt));
  background-size: 200% 100%; animation: hrs-gaveta-brilho 1.2s linear infinite; }
@keyframes hrs-gaveta-brilho { from { background-position: 200% 0; } to { background-position: 0 0; } }
@media (prefers-reduced-motion: reduce) { .hrs-gaveta-carregando { animation: none; } }
@media (max-width: 767.98px) {
  /* Folha que sobe de baixo, como os modais no celular. */
  .hrs-gaveta { top: auto; left: 0; width: auto; max-height: 85vh; border-radius: var(--raio-xl) var(--raio-xl) 0 0; }
  .hrs-gaveta-pe { padding-bottom: calc(12px + env(safe-area-inset-bottom, 0px)); }
}

/* ==========================================================================
   57. AVISO DE NOTIFICAÇÃO — o toast que aparece no canto quando chega uma
       notificação (02/10/2026, opção C3 de quatro)

   Faixa na cor do tipo, quem fez e o módulo numa linha pequena, o rótulo do
   evento em destaque, o texto sem repetir o nome e o botão "Abrir" quando o
   aviso leva a algum lugar. O X é o botão de ícone do DS e só aparece ao
   passar o mouse (o aviso some sozinho); em tela de toque, sempre.
   Montado em notificacao.js (createToastHtml) com Horus.toast(..., {semIcone,
   classe: "hrs-aviso-toast"}).

   <div class="hrs-aviso" style="--hrs-aviso-cor: #2a9d8f;">
     <div class="hrs-aviso-cab"><span class="hrs-avatar hrs-avatar-xs …">CA</span><b>Carol</b><span>· Tarefas</span>
       <button class="hrs-btn hrs-btn-sm hrs-btn-icone hrs-btn-fantasma hrs-aviso-fechar">…</button></div>
     <div class="hrs-aviso-titulo">Tarefa atribuída</div>
     <div class="hrs-aviso-texto">Atribuiu a tarefa …</div>
     <div class="hrs-aviso-acoes"><button class="hrs-btn hrs-btn-sm hrs-btn-primario hrs-aviso-abrir">Abrir</button></div>
   </div>
   ========================================================================== */
/* O SweetAlert monta o toast numa grade de 3 colunas (ícone | texto | X) com
   padding próprio: aqui o conteúdo ocupa a linha inteira. Seletor com o
   container para vencer o .swal2-popup.swal2-toast dele. */
.swal2-container .swal2-popup.swal2-toast.hrs-aviso-toast { padding: 0; overflow: hidden; grid-template-columns: 1fr; }
.swal2-container .hrs-aviso-toast .swal2-html-container { grid-column: 1 / -1; margin: 0; padding: 0; text-align: left; }
.swal2-container .hrs-aviso-toast .swal2-timer-progress-bar-container { grid-column: 1 / -1; }
.hrs-aviso { border-left: 4px solid var(--hrs-aviso-cor, var(--cor-primaria)); padding: var(--esp-2) var(--esp-2) var(--esp-3) var(--esp-3); }
.hrs-aviso-cab { display: flex; align-items: center; gap: var(--esp-2); font-size: var(--fonte-xs); color: var(--cor-texto-suave); min-height: 28px; }
.hrs-aviso-cab b { color: var(--cor-texto-medio); font-weight: var(--peso-forte); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.hrs-aviso-cab > span:not(.hrs-avatar) { white-space: nowrap; flex: 0 0 auto; }
.hrs-aviso-cab .hrs-avatar { flex: 0 0 auto; }
.hrs-aviso-fechar { margin-left: auto; color: var(--cor-texto-suave); opacity: 0; transition: opacity var(--transicao-rapida); }
.hrs-aviso-toast:hover .hrs-aviso-fechar, .hrs-aviso-fechar:focus-visible { opacity: 1; }
.hrs-aviso-titulo { font-size: var(--fonte-md); font-weight: var(--peso-forte); color: var(--cor-texto); margin: var(--esp-1) 0 2px; line-height: 1.35; }
.hrs-aviso-texto { font-size: var(--fonte-sm); color: var(--cor-texto-medio); line-height: 1.4; }
.hrs-aviso-acoes { margin-top: var(--esp-2); }
@media (hover: none) { .hrs-aviso-fechar { opacity: 1; } }
@media (max-width: 575.98px) { .swal2-container .swal2-popup.swal2-toast.hrs-aviso-toast { width: calc(100vw - 16px); } }

/* ==========================================================================
   BOTÃO SÓ ÍCONE QUADRADO (.btn-icone-quadrado)
   Ação de ícone dentro de formulário (adicionar/remover linha de uma lista de
   edição): quadrado na altura do campo (38px), cantos do raio do botão. Usa as
   variantes do Bootstrap (btn-outline-primary para adicionar, btn-outline-danger
   para remover) — o sinal de ação fica no ícone, sem preenchimento vermelho.
   Sem texto: title e aria-label são obrigatórios.
   ========================================================================== */
.btn-icone-quadrado {
  width: 38px;
  height: 38px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
}
.btn-icone-quadrado i { font-size: 14px; }

/* ==========================================================================
   ALÇA DE ARRASTAR DO CARD (.card-alca)
   Único ponto de arrastar de um card de quadro (fluxo e negócio): o resto do card
   abre a ficha. Fica no rodapé, à direita, em área de toque de 44px. Só ícone,
   por isso o title e o aria-label são obrigatórios. Sem preenchimento: é ação de
   apoio, não ação principal.
   ========================================================================== */
.card-alca {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 44px;
  height: 44px;
  margin-left: auto;
  padding: 0;
  border: 0;
  border-radius: var(--raio-md);
  background: transparent;
  color: var(--cor-texto-fraco);
  cursor: grab;
  touch-action: none;
}
.card-alca i { font-size: 14px; }
.card-alca:hover { background: var(--cor-hover-neutro); color: var(--cor-texto-medio); }
.card-alca:active { cursor: grabbing; }
.card-alca:focus { outline: none; }
.card-alca:focus-visible { box-shadow: var(--sombra-foco); }
/* alça no canto superior direito do card (negócios): não ocupa linha, não muda a altura */
.card-alca--topo { position: absolute; top: 0; right: 0; margin-left: 0; border-radius: 0 var(--raio-md) 0 0; z-index: 3; }

/* Dica "arraste pelo ícone": balão claro acima do card, com seta para a alça.
   Aparece só quando alguém arrasta pelo corpo com o mouse (card_alca_dica.js). */
.card-alca-dica {
  position: fixed;
  z-index: var(--z-tooltip);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 12px;
  border-radius: var(--raio-md);
  background: var(--cor-superficie);
  border: 1px solid var(--cor-primaria);
  color: var(--cor-texto);
  font-size: var(--fonte-sm);
  white-space: nowrap;
  box-shadow: var(--sombra-md);
  pointer-events: none;
}
.card-alca-dica i { color: var(--cor-primaria); font-size: 12px; }
.card-alca-dica b { color: var(--cor-primaria); font-weight: var(--peso-forte); }
.card-alca-dica::after {
  content: "";
  position: absolute;
  right: 8px;
  bottom: -6px;
  width: 10px;
  height: 10px;
  background: var(--cor-superficie);
  border-right: 1px solid var(--cor-primaria);
  border-bottom: 1px solid var(--cor-primaria);
  transform: rotate(45deg);
}
/* no computador a alça some (o card inteiro arrasta); no toque ela aparece e o título
   ganha espaço para não passar por baixo */
@media (pointer: fine) {
  .card-alca { display: none; }
}
@media (pointer: coarse) {
  .card-titulo-com-alca { padding-right: 44px; }
}
/* a alça ganha fundo suave enquanto a dica aponta para ela */
.card-alca--destaque { background: var(--cor-primaria-suave) !important; color: var(--cor-primaria) !important; }

/* ==========================================================================
   GRADE DE TILES COM CAPA — telas que listam negócios/cards como tiles
   (Processo Pedido e Cadastro de Modelo). A capa segue o tratamento de
   .fx-card-capa do Kanban (fluxo_pedido.css); sem capa vira um ícone.
   Sem overflow:hidden no tile: menus (dropdown) não podem ser cortados.

     <div class="hrs-grade-tiles">
       <div class="hrs-card hrs-tile">
         <div class="hrs-tile-capa"><img src="…" alt="" loading="lazy"> | <i class="fa-regular fa-image"></i></div>
         <div class="hrs-card-cab">…</div> …
   ========================================================================== */
.hrs-grade-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
  gap: 16px;
  margin-bottom: 16px;
  align-items: start;
}
.hrs-tile { margin-bottom: 0; }
.hrs-tile .hrs-card-cab { flex-wrap: wrap; gap: 4px 10px; }
.hrs-tile-capa {
  height: 140px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--cor-superficie-alt);
  border-bottom: 1px solid var(--cor-borda);
  color: var(--cor-texto-suave);
  font-size: 2rem;
}
.hrs-tile-capa img { max-height: 130px; max-width: 90%; object-fit: contain; }

/* ==========================================================================
   58. PALETA DE COMANDOS — Ctrl+K / ⌘K (09/10/2026, opção A de três)

   Protótipo: static/prototipos/paleta-comandos.html. Uma caixa no meio da
   tela, sobre um fundo escurecido, que busca telas do menu, configurações,
   negócios, clientes, contatos, pedidos e cards do fluxo. Componente: components/
   paleta_comandos.html + static/js/paleta_comandos.js.

   É um <dialog> nativo aberto com showModal(), não um .modal do Bootstrap:
   o navegador o põe na camada de cima (acima de qualquer modal, sem disputa
   de z-index), deixa a página de trás inerte (sem clique, foco nem tab) e
   fecha no Esc. A rolagem de trás trava pela regra genérica de diálogo logo
   abaixo. No celular vira tela cheia.
   ========================================================================== */

/* Qualquer <dialog> aberto como modal trava a rolagem da página. O gutter
   estável segura o lugar da barra de rolagem: sem ele o conteúdo pularia de
   lado ao abrir. */
html:has(dialog:modal) { overflow: hidden; scrollbar-gutter: stable; }

.hrs-paleta {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  overflow: hidden;
}
.hrs-paleta::backdrop { background: var(--cor-veu); }
.hrs-paleta-caixa {
  position: absolute;
  left: 50%;
  top: calc(var(--top-bars-offset, 0px) + 9vh);
  transform: translateX(-50%);
  width: min(640px, calc(100vw - 32px));
  max-height: min(560px, 76vh);
  display: flex;
  flex-direction: column;
  background: var(--cor-superficie);
  border-radius: 12px;
  box-shadow: var(--sombra-xl);
  overflow: hidden;
}
.hrs-paleta-campo { display: flex; align-items: center; gap: var(--esp-3); height: 54px; padding: 0 var(--esp-4); border-bottom: 1px solid var(--cor-borda); flex: none; }
.hrs-paleta-campo > i { color: var(--cor-texto-suave); }
.hrs-paleta-campo input { flex: 1; min-width: 0; border: 0; outline: 0; background: transparent; color: var(--cor-texto); font-size: 16px; }
.hrs-paleta-campo input::placeholder { color: var(--cor-texto-fraco); }
.hrs-paleta-esc { border: 0; background: none; padding: 0; }
.hrs-paleta-caixa kbd {
  display: inline-block;
  min-width: 20px;
  padding: 1px 6px;
  border: 1px solid var(--cor-borda-forte);
  border-bottom-width: 2px;
  border-radius: 5px;
  background: var(--cor-superficie);
  color: var(--cor-texto-medio);
  font: 600 11px/1.5 inherit;
  text-align: center;
  box-shadow: none;
}
.hrs-paleta-lista { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 6px; }
.hrs-paleta-grupo { padding: 10px 10px 4px; color: var(--cor-texto-suave); font-size: .66rem; font-weight: var(--peso-forte); letter-spacing: .07em; text-transform: uppercase; }
.hrs-paleta-item { display: flex; align-items: center; gap: var(--esp-3); padding: 8px 10px; border-radius: var(--raio-lg); color: var(--cor-texto); text-decoration: none !important; }
.hrs-paleta-item:hover { color: var(--cor-texto); }
.hrs-paleta-ic {
  display: grid; place-items: center; flex: none;
  width: 30px; height: 30px;
  border: 1px solid var(--cor-borda); border-radius: var(--raio-lg);
  background: var(--cor-superficie-alt); color: var(--cor-texto-medio); font-size: 13px;
}
.hrs-paleta-tx { flex: 1; min-width: 0; }
.hrs-paleta-t, .hrs-paleta-s { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hrs-paleta-t { font-weight: var(--peso-medio); }
.hrs-paleta-t mark { padding: 0; background: none; color: var(--cor-link); }
.hrs-paleta-s { color: var(--cor-texto-suave); font-size: 12.5px; }
.hrs-paleta-dir { color: var(--cor-texto-fraco); font-size: 12px; white-space: nowrap; }
.hrs-paleta-item[aria-selected="true"] { background: var(--cor-primaria-suave); }
.hrs-paleta-item[aria-selected="true"] .hrs-paleta-ic { border-color: var(--cor-primaria); background: var(--cor-primaria); color: #fff; }
.hrs-paleta-item[aria-selected="true"] .hrs-paleta-dir { color: var(--cor-link); }
.hrs-paleta-aviso { padding: 8px 10px; color: var(--cor-texto-suave); font-size: 12.5px; }
.hrs-paleta-vazio { padding: 28px 16px; text-align: center; color: var(--cor-texto-suave); }
.hrs-paleta-vazio i { display: block; margin-bottom: 8px; font-size: 22px; color: var(--cor-texto-fraco); }
.hrs-paleta-pe { display: flex; align-items: center; gap: var(--esp-4); flex: none; padding: 8px var(--esp-4); border-top: 1px solid var(--cor-borda); background: var(--cor-superficie-alt); color: var(--cor-texto-suave); font-size: 12px; }
.hrs-paleta-pe span { display: flex; align-items: center; gap: 5px; }

/* Gatilho no cabeçalho: parece um campo, mas abre a paleta. */
.hrs-paleta-cabecalho { flex: 1 1 auto; justify-content: center; min-width: 0; padding: 0 var(--esp-3); }
.hrs-paleta-gatilho {
  display: flex; align-items: center; gap: var(--esp-2);
  width: 100%; max-width: 420px; height: 36px; padding: 0 8px 0 12px;
  border: 1px solid var(--cor-borda); border-radius: var(--raio-lg);
  background: var(--cor-superficie-alt); color: var(--cor-texto-suave);
  font-size: var(--fonte-md); text-align: left; cursor: text;
}
.hrs-paleta-gatilho:hover { border-color: var(--cor-borda-forte); }
.hrs-paleta-gatilho:focus-visible { outline: 0; border-color: var(--cor-primaria); box-shadow: var(--sombra-foco); }
.hrs-paleta-gatilho > span { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hrs-paleta-gatilho kbd { padding: 0 5px; border: 1px solid var(--cor-borda); border-radius: 4px; background: var(--cor-superficie); color: var(--cor-texto-suave); font: 600 11px/1.6 inherit; box-shadow: none; }

@media (max-width: 767.98px) {
  .hrs-paleta-caixa { top: var(--top-bars-offset, 0px); bottom: 0; width: 100vw; max-height: none; border-radius: 0; }
  .hrs-paleta-item { min-height: var(--mob-alvo-toque); }
  .hrs-paleta-pe { display: none; }
}

/* ==========================================================================
   59. SELETOR MÚLTIPLO COM BUSCA e CHIP COM REMOVER (15/10/2026, opção A
       "campos à vista" de três + a busca com chips da opção C)

   Escolher VÁRIOS valores de uma lista que pode ser longa ("só PR e SC",
   "todos, menos Licitação"). Parece um select fechado com o resumo do que
   está valendo; clicar abre, logo embaixo (no fluxo, não flutuando), um
   painel com o modo (segmentado, seção 52), a busca, a lista e o rodapé.
   Nasceu nos filtros do editor de card do estúdio da home. Antes dele, cada
   lista de marcar era montada à mão (`.hs-funis-lista`, a do compartilhar…),
   sem busca nem contagem; e não havia chip que se tirasse com um X — o único
   era o do select2, preso ao plugin.

   PEÇAS
     .hrs-multi              o invólucro (gatilho + painel)
     .hrs-multi-aberto        modificador: painel à vista
     .hrs-multi-gatilho       o botão — use JUNTO com `custom-select
                              custom-select-sm`, que dá a seta e a altura
     .hrs-multi-com-valor     no gatilho: o filtro vale (fundo
                              --cor-primaria-suave, texto forte)
     .hrs-multi-exceto        o "Todos, menos" dentro do gatilho
                              (--cor-perigo-texto: o que fica de fora)
     .hrs-multi-painel        o painel que abre embaixo do gatilho
     .hrs-multi-busca         a busca com a lupa à esquerda
     .hrs-multi-lista         lista de marcar (custom-checkbox) com rolagem
     .hrs-multi-qtd           a quantidade à direita de cada valor
     .hrs-multi-grupo         cabeçalho de grupo ("Marcados", "Todos")
     .hrs-multi-sugestoes     no lugar da lista quando são milhares (cliente):
                              role=listbox com <li role=option>; escolher vira chip
     .hrs-multi-chips         os escolhidos, como chips com remover
     .hrs-multi-aviso         carregando / nada encontrado / erro (role=status);
                              `.hrs-multi-aviso-erro` pinta o erro
     .hrs-multi-pe            rodapé: "N marcados · Limpar · Pronto"

     .hrs-chip-remover        chip (seção 36) com o X de tirar
     .hrs-chip-x              o X — botão próprio, com aria-label "Tirar …"
     .hrs-chip-exceto         chip do que fica DE FORA: perigo, riscado

   <label for="fl_uf">Estado</label>
   <div class="hrs-multi hrs-multi-aberto">
     <button type="button" class="custom-select custom-select-sm hrs-multi-gatilho hrs-multi-com-valor"
             id="fl_uf" aria-expanded="true" aria-controls="fl_uf_pnl">PR e SC</button>
     <div class="hrs-multi-painel" id="fl_uf_pnl" role="group" aria-label="Filtrar por estado">
       <span class="hrs-segmentado hrs-segmentado-bloco" role="group" aria-label="Como filtrar estado">
         <button type="button" aria-pressed="true">Só estes</button><button type="button" aria-pressed="false">Todos, menos estes</button>
       </span>
       <div class="hrs-multi-busca"><i class="fa-solid fa-magnifying-glass" aria-hidden="true"></i>
         <input type="search" class="form-control form-control-sm" aria-label="Buscar estado"></div>
       <div class="hrs-multi-lista" role="group" aria-label="Valores de estado">
         <div class="custom-control custom-checkbox"><input type="checkbox" class="custom-control-input" id="v1" checked>
           <label class="custom-control-label" for="v1"><span>PR</span><span class="hrs-multi-qtd">96</span></label></div>
       </div>
       <p class="hrs-multi-aviso" role="status"></p>
       <div class="hrs-multi-pe"><span>2 marcados</span>
         <button type="button" class="btn btn-sm btn-link">Limpar</button>
         <button type="button" class="btn btn-sm btn-outline-secondary">Pronto</button></div>
     </div>
   </div>

   <li class="hrs-chip hrs-chip-remover"><span class="hrs-chip-rot">Hotel Rio Bonito</span>
     <button type="button" class="hrs-chip-x" aria-label="Tirar Hotel Rio Bonito"><i class="fa-solid fa-xmark" aria-hidden="true"></i></button></li>

   Abrir/fechar, o foco (Esc fecha e devolve ao gatilho), a busca com espera
   e o carregar sob demanda são do JS de cada tela (o estúdio: home_estudio.js,
   "filtros por categoria"). O CSS só desenha os estados.
   ========================================================================== */
.hrs-multi { position: relative; min-width: 0; }
.hrs-multi-gatilho {
  display: block;
  width: 100%;
  text-align: left;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--cor-texto-suave);
  cursor: pointer;
}
/* Só a cor do fundo: o `background` do custom-select traz a seta, que fica. */
.hrs-multi-gatilho.hrs-multi-com-valor { color: var(--cor-texto); font-weight: var(--peso-medio); border-color: var(--cor-primaria); background-color: var(--cor-primaria-suave); }
.hrs-multi-gatilho[aria-expanded="true"] { border-color: var(--cor-primaria); box-shadow: var(--sombra-foco); }
.hrs-multi-gatilho:disabled { cursor: not-allowed; }
.hrs-multi-exceto { color: var(--cor-perigo-texto); }
.hrs-multi-painel {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: -2px;
  padding: var(--esp-2);
  border: 1px solid var(--cor-borda);
  border-top: 0;
  border-radius: 0 0 var(--raio-md) var(--raio-md);
  background: var(--cor-superficie);
}
.hrs-multi-painel[hidden] { display: none; }
.hrs-multi-painel .hrs-segmentado > button { font-size: 12px; }
.hrs-multi-busca { position: relative; }
.hrs-multi-busca > i { position: absolute; left: 10px; top: 50%; transform: translateY(-50%); color: var(--cor-texto-suave); font-size: 12px; pointer-events: none; }
.hrs-multi-busca > input { padding-left: 30px; }
.hrs-multi-lista { max-height: 210px; overflow-y: auto; border: 1px solid var(--cor-borda); border-radius: var(--raio-md); padding: 2px 10px; }
.hrs-multi-lista:empty { display: none; }
.hrs-multi-lista .custom-control { display: flex; align-items: center; margin: 6px 0; font-size: var(--fonte-sm); }
/* label.: o AdminLTE pinta label:not(.form-check-label) em 700. */
.hrs-multi-lista label.custom-control-label { display: flex; flex: 1; min-width: 0; font-weight: var(--peso-normal); cursor: pointer; }
.hrs-multi-lista .custom-control-label > span:first-child { overflow-wrap: anywhere; }
.hrs-multi-qtd { margin-left: auto; padding-left: 8px; font-size: var(--fonte-xs); color: var(--cor-texto-suave); font-variant-numeric: tabular-nums; }
.hrs-multi-grupo { font-size: 10.5px; font-weight: var(--peso-forte); text-transform: uppercase; letter-spacing: .04em; color: var(--cor-texto-suave); padding: 8px 0 0; }
.hrs-multi-sugestoes { list-style: none; margin: 0; padding: var(--esp-1); max-height: 230px; overflow-y: auto; border: 1px solid var(--cor-borda); border-radius: var(--raio-md); }
.hrs-multi-sugestoes:empty { display: none; }
.hrs-multi-sugestoes li[role="option"] { display: flex; align-items: center; gap: 8px; padding: 6px 8px; border-radius: 7px; font-size: 13px; cursor: pointer; }
.hrs-multi-sugestoes li[role="option"]:hover,
.hrs-multi-sugestoes li[role="option"]:focus { background: var(--cor-primaria-suave); outline: none; }
.hrs-multi-sugestoes li[aria-disabled="true"] { opacity: .6; cursor: not-allowed; }
.hrs-multi-sugestoes li.hrs-multi-grupo { padding: 6px 8px 2px; }
.hrs-multi-chips { list-style: none; display: flex; flex-wrap: wrap; gap: 4px; margin: 0; padding: 0; }
.hrs-multi-chips:empty { display: none; }
.hrs-multi-aviso { margin: 0; font-size: 12px; color: var(--cor-texto-medio); }
.hrs-multi-aviso:empty { display: none; }
.hrs-multi-aviso-erro { color: var(--cor-perigo-texto); }
.hrs-multi-pe { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--cor-texto-medio); }
.hrs-multi-pe > :last-child { margin-left: auto; }

/* Chip com remover: o chip deixa de ser o botão (o X é que é). */
.hrs-chip-remover,
.hrs-chip-remover:hover { cursor: default; padding-right: 3px; background: var(--cor-primaria-suave); color: var(--cor-link); }
.hrs-chip-rot { overflow: hidden; text-overflow: ellipsis; max-width: 220px; }
.hrs-chip-x {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 20px;
  height: 20px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: inherit;
  font-size: 11px;
  cursor: pointer;
}
.hrs-chip-x:hover { background: var(--cor-superficie); }
.hrs-chip-x:focus { outline: none; }
.hrs-chip-x:focus-visible { box-shadow: var(--sombra-foco); }
.hrs-chip-exceto,
.hrs-chip-exceto:hover { background: var(--cor-perigo-suave); color: var(--cor-perigo-texto); }
.hrs-chip-exceto .hrs-chip-rot { text-decoration: line-through; text-decoration-thickness: 1px; }

@media (max-width: 767.98px) {
  .hrs-multi-gatilho,
  .hrs-multi-busca > input { min-height: var(--mob-alvo-toque); }
  .hrs-multi-lista .custom-control { min-height: var(--mob-alvo-toque); margin: 0; }
  .hrs-multi-sugestoes li[role="option"] { min-height: var(--mob-alvo-toque); }
  .hrs-multi-painel .hrs-segmentado > button,
  .hrs-multi-pe .btn { min-height: var(--mob-alvo-toque); }
  .hrs-chip-remover { height: auto; min-height: var(--mob-alvo-toque-min); }
  .hrs-chip-x { width: var(--mob-alvo-toque-min); height: var(--mob-alvo-toque-min); }
}

/* ==========================================================================
   60. ESCOLHA EM CARTÃO (15/10/2026, homes pessoais — protótipo C)

   Um rádio por opção, cada opção num cartão com título e uma linha de apoio
   ("Em branco · Você escolhe os cards no estúdio."). Para quando a escolha
   precisa de explicação curta e as opções são poucas (2 a 4): um select
   esconderia o apoio, e rádio solto não deixa claro onde clicar. O cartão
   INTEIRO é o <label> do rádio — clicar em qualquer ponto escolhe.

   <fieldset class="hrs-escolha">
     <legend class="sr-only">Como a home começa</legend>
     <label class="hrs-escolha-op" for="nh_branco">
       <input type="radio" name="nasce" id="nh_branco" value="branco" checked>
       <span class="hrs-escolha-txt"><b>Em branco</b><small>Você escolhe os cards no estúdio.</small></span>
     </label>
     …
   </fieldset>

   Controle extra de uma opção (o select "qual home copiar") vai dentro do
   .hrs-escolha-txt, com aria-label (<label> dentro de <label> não vale).
   ========================================================================== */
.hrs-escolha { display: grid; gap: var(--esp-2); margin: 0; padding: 0; border: 0; min-width: 0; }
.hrs-escolha-op {
  display: flex;
  align-items: flex-start;
  gap: var(--esp-3);
  margin: 0;
  padding: 10px 12px;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio-md);
  background: var(--cor-superficie);
  font-weight: var(--peso-normal);
  cursor: pointer;
}
.hrs-escolha-op:hover { background: var(--cor-hover-neutro); }
.hrs-escolha-op:has(input:checked) { border-color: var(--cor-primaria); background: var(--cor-primaria-suave); }
.hrs-escolha-op:has(input:focus-visible) { box-shadow: var(--sombra-foco); }
.hrs-escolha-op:has(input:disabled) { opacity: .6; cursor: not-allowed; }
.hrs-escolha-op > input { flex: none; margin-top: 3px; }
.hrs-escolha-txt { display: block; flex: 1; min-width: 0; }
.hrs-escolha-txt > b { display: block; color: var(--cor-texto); font-size: var(--fonte-sm); font-weight: var(--peso-medio); }
.hrs-escolha-txt > small { display: block; color: var(--cor-texto-suave); font-size: var(--fonte-xs); }
.hrs-escolha-txt > select,
.hrs-escolha-txt > .custom-select { margin-top: 6px; }

@media (max-width: 767.98px) {
  .hrs-escolha-op { min-height: var(--mob-alvo-toque); }
  .hrs-escolha-txt > select,
  .hrs-escolha-txt > .custom-select { min-height: var(--mob-alvo-toque); }
}

/* ==========================================================================
   61. ROTEIRO EM PASSOS (15/10/2026, migração do Dashboard CRM — protótipo C)

   Uma tarefa longa de admin dividida em passos numerados, um embaixo do
   outro, ligados por um traço: o número vira ✓ quando o passo está feito e
   ganha a cor da marca no passo da vez. Cada passo tem título, etiqueta de
   situação, ações à direita, uma linha de apoio e o conteúdo. Não é wizard:
   todos os passos ficam à vista e cada um pode ser refeito.

   <ol class="hrs-roteiro">
     <li class="hrs-passo hrs-passo--feito">
       <span class="hrs-passo-n" aria-hidden="true"><i class="fa-solid fa-check"></i></span>
       <div class="hrs-passo-corpo">
         <div class="hrs-passo-cab"><h3>Conferir o que muda</h3>
           <span class="hrs-etiqueta hrs-etiqueta-sucesso">Conferido em 14/10</span>
           <span class="hrs-passo-acoes"><button class="btn btn-sm btn-outline-secondary">…</button></span></div>
         <p class="hrs-passo-apoio">…</p>
         <div class="hrs-passo-caixa">…</div>
       </div>
     </li>
   </ol>

   Situação no leitor de tela: a etiqueta diz "feito"/"agora" em texto — a
   cor do número é só reforço.
   ========================================================================== */
.hrs-roteiro { list-style: none; margin: 0; padding: 0; }
.hrs-passo {
  display: grid;
  grid-template-columns: 36px minmax(0, 1fr);
  gap: 0 var(--esp-3);
  position: relative;
  padding-bottom: var(--esp-4);
}
.hrs-passo::before {
  content: "";
  position: absolute;
  left: 17px;
  top: 36px;
  bottom: 0;
  width: 2px;
  background: var(--cor-borda);
}
.hrs-passo:last-child::before { display: none; }
.hrs-passo-n {
  width: 36px;
  height: 36px;
  border-radius: var(--raio-circulo);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-weight: var(--peso-forte);
  background: var(--cor-superficie);
  border: 2px solid var(--cor-borda-forte);
  color: var(--cor-texto-medio);
  position: relative;
  z-index: 1;
}
.hrs-passo--feito .hrs-passo-n { background: var(--cor-sucesso); border-color: var(--cor-sucesso); color: var(--cor-superficie); }
.hrs-passo--agora .hrs-passo-n { border-color: var(--cor-primaria); color: var(--cor-primaria); background: var(--cor-primaria-suave); }
.hrs-passo-corpo { min-width: 0; }
.hrs-passo-cab { display: flex; flex-wrap: wrap; align-items: center; gap: var(--esp-2); min-height: 36px; }
.hrs-passo-cab > h3 { font-size: var(--fonte-lg); font-weight: var(--peso-forte); margin: 0; }
.hrs-passo-acoes { margin-left: auto; display: flex; flex-wrap: wrap; gap: var(--esp-2); }
.hrs-passo-apoio { font-size: var(--fonte-sm); color: var(--cor-texto-medio); margin: 2px 0 var(--esp-2); }
.hrs-passo-caixa {
  background: var(--cor-superficie);
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio-lg);
  overflow: hidden;
}

@media (max-width: 767.98px) {
  .hrs-passo { grid-template-columns: 28px minmax(0, 1fr); gap: 0 var(--esp-2); }
  .hrs-passo-n { width: 28px; height: 28px; font-size: var(--fonte-sm); }
  .hrs-passo::before { left: 13px; top: 28px; }
  .hrs-passo-acoes { margin-left: 0; width: 100%; }
  .hrs-passo-acoes .btn { flex: 1; min-height: var(--mob-alvo-toque); }
}

/* ==========================================================================
   62. FILA DE ENVIOS À SENIOR — pílula, painel, cartão de envio e
       mini-etapas (16/10/2026, opção V1 de três)

   O cadastro, a edição e o cancelamento de pedido vão para uma fila
   (tb_fila_senior); um worker fala com a Senior. Esta é a peça que mostra a
   fila em qualquer tela: uma pílula no canto inferior ESQUERDO (o direito é
   do botão flutuante .hrs-fab), colada ao menu lateral, que abre um painel
   com os envios da pessoa. Tradução do FilaFlutuante do Aquarela Finance.
   Protótipos em /tmp/proto_fila (ff-v1-*); V2 (no pé do menu) e V3 (some
   quando parada) foram descartadas: a pílula fica SEMPRE visível.

   Montada por JS (static/js/fila_senior_flutuante.js), carregada no
   base.html só para quem está logado. A tela "Envios à Senior"
   (/fila-senior/) e o negócio reaproveitam o cartão e as mini-etapas.

   <div class="hrs-fila-ancora">
     <button class="hrs-fila-pilula" aria-expanded="false">
       <span class="hrs-fila-bolinha hrs-fila-bolinha-info"></span>Envios à Senior
       <span class="hrs-fila-pilula-n">2 enviando</span>
       <span class="hrs-fila-pilula-atencao" title="Precisam de você">3</span>
     </button>
     <section class="hrs-fila-painel">
       <div class="hrs-fila-alca"></div>
       <header class="hrs-fila-cab"><h2>…</h2> botões só ícone </header>
       <div class="hrs-fila-resumo"> etiquetas </div>
       <div class="hrs-fila-corpo"> .hrs-fila-envio… </div>
       <footer class="hrs-fila-pe"> … </footer>
     </section>
   </div>

   Bolinha (elemento sólido → papel "cheia"): parada = neutra; enviando =
   info, pulsando; precisa de alguém = perigo; sucesso só como um piscar
   quando um envio termina. Mini-etapas: o par suave/texto de cada família,
   com a borda na cheia.

   No celular (< 768px) a pílula ganha alvo de 48px e o painel vira uma
   folha que sobe de baixo, como os modais. Tela com barra fixa no rodapé
   define --hrs-recuo-rodape (tokens.css) e a pílula sobe junto.

   No celular a pílula sai do conteúdo (cobria listas e o fim da página, em
   Rotas, Tarefas, Clientes…) e vira um ícone no cabeçalho (.hrs-fila-nav),
   antes da busca: número vermelho = precisam de você; ponto azul = só envio
   andando. O JS só esconde a pílula (.hrs-fila-no-cabecalho) se achou o
   cabeçalho.
   ========================================================================== */
.hrs-fila-ancora { position: fixed; z-index: var(--z-fixo); left: calc(4.6rem + 16px + var(--hrs-fila-dx, 0px));
  bottom: calc(16px + var(--hrs-recuo-rodape, 0px) + var(--hrs-fila-dy, 0px)); transition: left var(--transicao-rapida); }
body:not(.sidebar-collapse) .hrs-fila-ancora { left: calc(250px + 16px + var(--hrs-fila-dx, 0px)); }
/* A pílula se arrasta (no computador) numa área do canto: --hrs-fila-dx/-dy saem
   do JS. Aberto, o painel desce ao rodapé na coluna dela — subir cortaria o topo. */
.hrs-fila-ancora.hrs-fila-aberta { bottom: calc(16px + var(--hrs-recuo-rodape, 0px)); }
.hrs-fila-ancora.hrs-fila-arrastando { transition: none; }
.hrs-fila-ancora.hrs-fila-arrastando .hrs-fila-pilula { cursor: grabbing; }
/* Com o painel aberto a pílula some: o painel ocupa o lugar dela. */
.hrs-fila-ancora .hrs-fila-painel { display: none; }
.hrs-fila-ancora.hrs-fila-aberta .hrs-fila-painel { display: flex; }
.hrs-fila-ancora.hrs-fila-aberta .hrs-fila-pilula { display: none; }

/* --- pílula ------------------------------------------------------------- */
.hrs-fila-pilula { display: inline-flex; align-items: center; gap: 8px; min-height: 40px; padding: 8px 14px;
  border: 0; border-radius: var(--raio-pilula); background: var(--cor-casca-fundo); color: var(--cor-superficie);
  font-size: var(--fonte-sm); font-weight: var(--peso-medio); box-shadow: var(--sombra-lg); cursor: pointer;
  touch-action: none; user-select: none; }
.hrs-fila-pilula:hover { filter: brightness(1.15); }
.hrs-fila-pilula:focus { outline: none; }
.hrs-fila-pilula:focus-visible { box-shadow: var(--sombra-foco), var(--sombra-lg); }
.hrs-fila-pilula-n { font-size: var(--fonte-xs); background: var(--cor-casca-ativo); color: var(--cor-superficie);
  border-radius: var(--raio-pilula); padding: 1px 8px; }
.hrs-fila-pilula-atencao { font-size: var(--fonte-xs); background: var(--cor-perigo-suave); color: var(--cor-perigo-texto);
  border-radius: var(--raio-pilula); padding: 1px 8px; font-weight: var(--peso-forte); }
/* O time (quem tem subordinados, 29/10/2026): depois de um separador, o ícone de
   pessoas, o número em andamento e, se algo do time parou, o âmbar. O vermelho
   (.hrs-fila-pilula-atencao) é só do que é da pessoa. */
.hrs-fila-pilula-sep { width: 1px; align-self: stretch; margin: 2px 0; background: var(--cor-casca-texto-fraco); opacity: .5; }
.hrs-fila-pilula-time { font-size: var(--fonte-xs); background: var(--cor-aviso-suave); color: var(--cor-aviso-texto);
  border-radius: var(--raio-pilula); padding: 1px 8px; font-weight: var(--peso-forte); }

/* --- bolinha de estado ---------------------------------------------------- */
.hrs-fila-bolinha { width: 9px; height: 9px; border-radius: var(--raio-circulo); flex: 0 0 auto;
  background: var(--cor-casca-texto-fraco); }
.hrs-fila-painel .hrs-fila-bolinha { background: var(--cor-texto-suave); }
.hrs-fila-bolinha.hrs-fila-bolinha-info { background: var(--cor-info); animation: hrs-fila-pulso 1.4s ease-in-out infinite; }
.hrs-fila-bolinha.hrs-fila-bolinha-perigo { background: var(--cor-perigo); }
.hrs-fila-bolinha.hrs-fila-bolinha-sucesso { background: var(--cor-sucesso); }
@keyframes hrs-fila-pulso { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }
@media (prefers-reduced-motion: reduce) { .hrs-fila-bolinha.hrs-fila-bolinha-info { animation: none; } }

/* --- painel ----------------------------------------------------------------- */
.hrs-fila-painel { position: relative; width: 380px; height: var(--hrs-fila-altura, auto); max-height: 70vh;
  flex-direction: column; background: var(--cor-superficie); border: 1px solid var(--cor-borda);
  border-radius: var(--raio-xl); box-shadow: var(--sombra-lg); overflow: hidden; color: var(--cor-texto);
  font-size: var(--fonte-sm); }
.hrs-fila-alca { position: absolute; top: 0; left: 0; right: 0; height: 10px; cursor: ns-resize; touch-action: none; z-index: 2; }
.hrs-fila-alca::after { content: ""; position: absolute; top: 4px; left: 50%; transform: translateX(-50%);
  width: 36px; height: 4px; border-radius: 2px; background: var(--cor-borda-forte); }
.hrs-fila-cab { display: flex; align-items: center; gap: 4px; padding: 14px 10px 10px 14px;
  border-bottom: 1px solid var(--cor-borda); background: var(--cor-superficie-alt); }
.hrs-fila-cab h2 { flex: 1; min-width: 0; margin: 0; font-size: var(--fonte-md); font-weight: var(--peso-forte);
  display: flex; align-items: center; gap: 8px; white-space: nowrap; }
.hrs-fila-cab .hrs-btn-icone { color: var(--cor-texto-medio); }
/* Abas "Meus | Do meu time" (só para quem tem time): coladas às etiquetas de
   resumo embaixo; sem etiquetas, fecham o bloco com a borda. */
.hrs-fila-abas { padding: 8px 14px 0; }
.hrs-fila-abas:has(+ .hrs-fila-resumo:empty) { padding-bottom: 8px; border-bottom: 1px solid var(--cor-borda); }
.hrs-fila-abas .hrs-segmentado > button span { font-weight: var(--peso-forte); }
.hrs-fila-resumo { display: flex; gap: 6px; flex-wrap: wrap; padding: 8px 14px; border-bottom: 1px solid var(--cor-borda); }
.hrs-fila-resumo:empty { display: none; }
.hrs-fila-corpo { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 8px; scrollbar-width: thin; }
.hrs-fila-corpo > .hrs-vazio { padding: 28px 12px; }
.hrs-fila-pe { padding: 8px 14px; border-top: 1px solid var(--cor-borda); font-size: var(--fonte-xs);
  color: var(--cor-texto-medio); display: flex; justify-content: space-between; align-items: center; gap: 8px; }

/* --- cartão de um envio (painel, negócio) ----------------------------------- */
.hrs-fila-envio { border: 1px solid var(--cor-borda); border-radius: var(--raio-md); background: var(--cor-superficie);
  margin-bottom: 6px; overflow: hidden; }
.hrs-fila-envio-aberto { border-color: var(--cor-borda-forte); }
.hrs-fila-envio-cab { display: flex; gap: 8px; align-items: flex-start; width: 100%; padding: 9px 10px; border: 0;
  background: transparent; text-align: left; color: inherit; cursor: pointer; }
.hrs-fila-envio-cab:hover { background: var(--cor-hover-neutro); }
.hrs-fila-envio-cab:focus { outline: none; }
.hrs-fila-envio-cab:focus-visible { box-shadow: inset var(--sombra-foco); }
.hrs-fila-seta { color: var(--cor-texto-suave); transition: transform var(--transicao-rapida); margin-top: 4px; width: 12px; flex: 0 0 auto; }
.hrs-fila-envio-aberto .hrs-fila-seta { transform: rotate(90deg); }
.hrs-fila-envio-meio { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.hrs-fila-envio-topo { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.hrs-fila-envio-titulo { font-weight: var(--peso-forte); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hrs-fila-envio-sub { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; color: var(--cor-texto-medio);
  font-size: var(--fonte-xs); }
.hrs-fila-envio-corpo { padding: 4px 12px 12px 30px; border-top: 1px dashed var(--cor-borda); }
.hrs-fila-envio-msg { margin: 8px 0 4px; padding: 8px 10px; border-radius: var(--raio-sm); font-size: var(--fonte-xs);
  background: var(--cor-perigo-suave); color: var(--cor-perigo-texto); overflow-wrap: anywhere; }
.hrs-fila-envio-msg.hrs-fila-envio-msg-aviso { background: var(--cor-aviso-suave); color: var(--cor-aviso-texto); }
.hrs-fila-envio-msg.hrs-fila-envio-msg-info { background: var(--cor-info-suave); color: var(--cor-info-texto); }
/* Duas ações numa linha, nunca quebrando: a saída ("Detalhes"/"Fechar") à
   esquerda e a ação principal à direita. O resto vai para o ⋮ do cabeçalho
   (.hrs-fila-menu, o dropdown das tabelas). Vale para o cartão e a gaveta. */
.hrs-fila-envio-acoes { display: flex; flex-wrap: nowrap; align-items: center; justify-content: space-between;
  gap: 8px; margin-top: 8px; }
.hrs-fila-gaveta-pe { flex-wrap: nowrap; justify-content: space-between; }
.hrs-fila-envio-acoes .btn, .hrs-fila-gaveta-pe .btn { white-space: nowrap; }
.hrs-fila-envio-linha { display: flex; align-items: flex-start; }
/* Filtros da tela "Envios à Senior": numa linha no computador; no celular o
   segmentado fica em cima e os chips viram uma linha rolável. */
.hrs-fila-filtros { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.hrs-fila-filtros-chips { display: contents; }
/* Espaçamentos que estavam inline (style="gap:…"). */
/* Faixa do envio (FilaSenior.faixaHtml): o ícone na linha do título, o texto
   ao lado dele — sem o ícone sozinho numa linha acima. */
.hrs-fila-faixa { display: flex; align-items: flex-start; gap: 10px; overflow-wrap: anywhere; }
.hrs-fila-faixa > i { flex: 0 0 auto; width: 1.1em; margin-top: 3px; text-align: center; }
.hrs-fila-faixa > div { flex: 1 1 auto; min-width: 0; }
.hrs-fila-faixa-acoes { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
/* Faixa numa linha (opcoes.linha, topo da tela do cliente): ações à direita; no
   celular elas descem para baixo do texto. */
.hrs-fila-faixa--linha { align-items: center; }
.hrs-fila-faixa--linha > i { margin-top: 0; }
.hrs-fila-faixa--linha > .hrs-fila-faixa-acoes { flex: 0 0 auto; margin-top: 0; }
@media (max-width: 767.98px) {
  .hrs-fila-faixa--linha { flex-wrap: wrap; align-items: flex-start; }
  .hrs-fila-faixa--linha > i { margin-top: 3px; }
  .hrs-fila-faixa--linha > div { flex-basis: calc(100% - 1.1em - 10px); }
  .hrs-fila-faixa--linha > .hrs-fila-faixa-acoes { flex-basis: 100%; }
}
.hrs-fila-aviso-acoes { gap: 6px; }
/* "O quê" da tabela é botão (abre a gaveta), mas com o texto da tabela. */
.hrs-fila-o-que { font-size: inherit; line-height: inherit; vertical-align: baseline; }
/* A linha inteira abre a gaveta (o "O quê" continua sendo o botão do teclado). */
#fila_tabela tbody tr[data-id] { cursor: pointer; }
.hrs-fila-quem { display: inline-flex; align-items: center; flex-wrap: wrap; gap: 6px; }
/* Na gaveta, a mensagem de cada etapa é texto, não caixa (parecia campo de
   formulário) — a mesma regra do cartão do painel. */
.hrs-fila-gaveta .hrs-timeline-painel { background: none; border: 0; padding: 0; margin-top: 2px;
  color: var(--cor-texto-medio); font-size: var(--fonte-sm); }
/* Texto técnico (mensagem crua da Senior) recolhido, embaixo da frase legível. */
.hrs-fila-detalhe { margin-top: 4px; font-size: var(--fonte-xs); }
.hrs-fila-detalhe summary { cursor: pointer; text-decoration: underline; }
.hrs-fila-detalhe > div { margin-top: 4px; overflow-wrap: anywhere; }
.hrs-fila-envio-linha > .hrs-fila-envio-cab { flex: 1; min-width: 0; }
.hrs-fila-menu { flex: 0 0 auto; padding: 6px 6px 0 0; }
/* O cabeçalho da gaveta estica todo <div> filho (o título); o ⋮ não. */
.hrs-gaveta-cab .hrs-fila-menu { flex: 0 0 auto; padding: 0; }
.hrs-fila-envio-corpo .hrs-timeline { padding: 0; }
.hrs-fila-envio-corpo .hrs-timeline-item { padding-bottom: 6px; }
.hrs-fila-envio-corpo .hrs-timeline-painel { background: none; border: 0; padding: 0; margin-top: 0;
  color: var(--cor-texto-medio); font-size: var(--fonte-xs); }
.hrs-fila-etapa-futura { opacity: .55; }
/* Um envio terminou agora: o cartão pisca uma vez na cor do resultado. */
.hrs-fila-envio-novo { animation: hrs-fila-novo 1.6s ease-out 1; }
@keyframes hrs-fila-novo { from { background: var(--cor-sucesso-suave); } to { background: var(--cor-superficie); } }
@media (prefers-reduced-motion: reduce) { .hrs-fila-envio-novo { animation: none; } }

/* Aviso no canto que não some sozinho (erro): o X é o do componente, sempre à
   vista; o do SweetAlert (que ele põe quando não há timer) sairia repetido.
   O !important vence o display inline que o próprio SweetAlert escreve. */
.swal2-container .hrs-fila-aviso-fixo .swal2-close { display: none !important; }
.hrs-fila-aviso-fixo .hrs-aviso-fechar { opacity: 1; }

/* --- mini-etapas: Senior → Hórus → PDF → Comissão, no lugar do "n/m" -------- */
.hrs-fila-etapas { display: inline-flex; gap: 3px; align-items: center; flex: 0 0 auto; }
.hrs-fila-etapas i { width: 16px; height: 16px; border-radius: var(--raio-circulo); display: grid; place-items: center;
  font-size: 9px; font-style: normal; background: var(--cor-superficie-alt); color: var(--cor-texto-suave);
  border: 1px solid var(--cor-borda); }
.hrs-fila-etapas i.hrs-fila-etapa-ok { background: var(--cor-sucesso-suave); color: var(--cor-sucesso-texto); border-color: var(--cor-sucesso); }
.hrs-fila-etapas i.hrs-fila-etapa-erro { background: var(--cor-perigo-suave); color: var(--cor-perigo-texto); border-color: var(--cor-perigo); }
.hrs-fila-etapas i.hrs-fila-etapa-incerto { background: var(--cor-aviso-suave); color: var(--cor-aviso-texto); border-color: var(--cor-aviso); }
.hrs-fila-etapas i.hrs-fila-etapa-andando { background: var(--cor-info-suave); color: var(--cor-info-texto); border-color: var(--cor-info); }
.hrs-fila-etapas b { margin-left: 4px; font-size: var(--fonte-xs); color: var(--cor-texto-medio); font-weight: var(--peso-medio); }

/* --- celular ------------------------------------------------------------------ */
@media (max-width: 767.98px) {
  /* Sem menu lateral: canto esquerdo, acima de barra fixa do rodapé. */
  .hrs-fila-ancora, body:not(.sidebar-collapse) .hrs-fila-ancora { left: 12px;
    bottom: calc(12px + var(--hrs-recuo-rodape, 0px) + env(safe-area-inset-bottom, 0px)); }
  .hrs-fila-pilula { min-height: var(--mob-alvo-toque); padding: 10px 16px; }
  .hrs-fila-ancora.hrs-fila-no-cabecalho .hrs-fila-pilula { display: none; }
  .hrs-fila-nav .nav-link { position: relative; display: flex; align-items: center; justify-content: center;
    min-width: var(--mob-alvo-toque-min); min-height: var(--mob-alvo-toque-min); }
  .hrs-fila-nav-ponto { position: absolute; top: 9px; right: 7px; width: 8px; height: 8px;
    border-radius: var(--raio-circulo); background: var(--cor-info); box-shadow: 0 0 0 2px var(--cor-superficie); }
  /* Aberto = folha que sobe de baixo, como os modais e o .fm-sheet. */
  .hrs-fila-ancora.hrs-fila-aberta, body:not(.sidebar-collapse) .hrs-fila-ancora.hrs-fila-aberta {
    left: 0; right: 0; bottom: 0; z-index: var(--z-modal); }
  .hrs-fila-ancora.hrs-fila-aberta::before { content: ""; position: fixed; inset: 0; background: var(--cor-veu); z-index: -1; }
  .hrs-fila-ancora.hrs-fila-aberta .hrs-fila-painel { width: auto; height: auto; max-height: 85vh;
    border-radius: var(--raio-xl) var(--raio-xl) 0 0; border-bottom: 0;
    padding-bottom: env(safe-area-inset-bottom, 0px); }
  .hrs-fila-alca { position: static; height: auto; padding: 8px 0 0; cursor: pointer; }
  .hrs-fila-alca::after { position: static; display: block; margin: 0 auto; width: 40px; transform: none; }
  .hrs-fila-cab { padding-top: 6px; }
  .hrs-fila-cab .hrs-btn-icone { width: var(--mob-alvo-toque-min); height: var(--mob-alvo-toque-min); }
  .hrs-fila-envio-cab { min-height: var(--mob-alvo-toque); }
  .hrs-fila-abas .hrs-segmentado > button, .hrs-fila-corpo > .btn-link { min-height: var(--mob-alvo-toque); }
  /* Empilhadas, a ação principal em cima (alcance do polegar) e a saída
     embaixo — a mesma regra dos rodapés de modal (column-reverse). */
  .hrs-fila-envio-acoes, .hrs-fila-gaveta-pe { flex-direction: column-reverse; align-items: stretch; }
  .hrs-fila-envio-acoes .btn, .hrs-fila-gaveta-pe .btn { width: 100%; min-height: var(--mob-alvo-toque); }
  .hrs-fila-envio-acoes .hrs-link { align-self: center; padding: 10px; }
  .hrs-fila-menu .hrs-tabela-acoes { width: var(--mob-alvo-toque-min); height: var(--mob-alvo-toque-min); }
  /* Cartão "em andamento" na cor info, como a etiqueta e as mini-etapas. */
  .m-card.hrs-fila-card-info { border-left-color: var(--cor-info); }
  .hrs-fila-filtros-chips { display: flex; flex-wrap: nowrap; gap: 8px; width: 100%; overflow-x: auto;
    padding-bottom: 4px; scrollbar-width: none; }
  .hrs-fila-filtros-chips::-webkit-scrollbar { height: 0; }
  .hrs-fila-filtros-chips .hrs-chip { flex: 0 0 auto; white-space: nowrap; }
  .hrs-fila-filtros .hrs-chip, .hrs-fila-filtros .hrs-segmentado button { min-height: var(--mob-alvo-toque-min); }
  /* "Limpar filtros" do estado vazio da tela Envios à Senior (fila_senior_tela.js). */
  .hrs-fila-vazio-acao .btn { min-height: var(--mob-alvo-toque); }
  /* A pílula (sem cabeçalho) flutua sobre o fim da página: reserva o lugar
     dela, para o último botão/linha da tela não ficar embaixo. */
  body:has(#hrs-fila-ancora:not(.hrs-fila-no-cabecalho)) .content-wrapper { padding-bottom: calc(var(--mob-alvo-toque) + 24px + var(--hrs-recuo-rodape, 0px)); }
  /* Avisos 409 ("já há envio deste pedido na fila", "o pedido mudou desde que
     você abriu"): o texto diz quem e quando, então fica alinhado à esquerda e
     menor que o título; as ações (já em coluna, a principal em cima) ganham o
     alvo de toque. */
  .hrs-swal.hrs-fila-aviso-409 { padding-bottom: calc(var(--esp-4) + env(safe-area-inset-bottom, 0px)); }
  .hrs-swal.hrs-fila-aviso-409 .swal2-icon { margin-top: var(--esp-3); transform: scale(.8); }
  .hrs-swal.hrs-fila-aviso-409 .swal2-title { font-size: var(--fonte-lg); padding-top: 0; }
  .hrs-swal.hrs-fila-aviso-409 .swal2-html-container { text-align: left; margin-left: var(--esp-4); margin-right: var(--esp-4); }
  .hrs-swal.hrs-fila-aviso-409 .swal2-actions { width: 100%; padding: 0 var(--esp-4); }
  .hrs-swal.hrs-fila-aviso-409 .swal2-actions > .hrs-btn { min-height: var(--mob-alvo-toque); }
}

/* Faixa (ribbon) do AdminLTE, ex.: "Inadimplente": é só aviso visual. Sem isto
   ela fica por cima dos botões do cabeçalho do card e rouba o clique. */
.ribbon-wrapper { pointer-events: none; }
