/* ==========================================================================
   components.css - botoes, cards, badges, estados
   Padrao_Box_Card, Padrao_Acao_Primaria_na_Topbar, Responsividade_Sempre
   As telas de formulario, tabela, modal e toggle entram nas fases 5, 7 e 8.
   ========================================================================== */

/* --------------------------------------------------------------------------
   BOTOES
   -------------------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-height: 36px;
  padding: 8px 14px;
  border-radius: var(--raio-sm);
  border: 1px solid var(--borda);
  background: var(--branco);
  color: var(--texto-suave);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  text-decoration: none;
  transition: background var(--transicao), border-color var(--transicao), color var(--transicao);
  white-space: nowrap;
}
.btn:hover { background: var(--fundo); border-color: var(--borda-forte); text-decoration: none; }
.btn:disabled, .btn[disabled] { opacity: .55; cursor: not-allowed; }

.btn-primary {
  background: var(--cor-primaria);
  border-color: var(--cor-primaria);
  color: #fff;
  font-weight: 600;
}
.btn-primary:hover {
  background: var(--cor-primaria-escura);
  border-color: var(--cor-primaria-escura);
  color: #fff;
}

.btn-perigo {
  background: var(--vermelho);
  border-color: var(--vermelho);
  color: #fff;
  font-weight: 600;
}
.btn-perigo:hover { filter: brightness(.94); color: #fff; }

.btn-fantasma { background: transparent; border-color: transparent; color: var(--texto-secundario); }
.btn-fantasma:hover { background: var(--fundo); color: var(--texto); }

.btn-sm { min-height: 32px; padding: 6px 10px; font-size: 12px; }

/* Botao so de icone, usado na coluna de acoes da tabela.
   O slot NUNCA some por falta de permissao: vira .desabilitado, mesmo tamanho,
   com title explicando (Matriz_VER_EDITAR). */
.btn-icone {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px; height: 32px;
  border-radius: var(--raio-sm);
  border: 1px solid transparent;
  background: transparent;
  color: var(--texto-secundario);
  cursor: pointer;
}
.btn-icone:hover { background: var(--fundo); color: var(--texto); }
.btn-icone.desabilitado {
  color: var(--texto-fraco);
  opacity: .5;
  cursor: not-allowed;
  pointer-events: none;
}
.btn-icone.perigo:hover { background: var(--vermelho-suave); color: var(--vermelho); }

/* --------------------------------------------------------------------------
   CARD (Padrao_Box_Card)
   -------------------------------------------------------------------------- */

.cd {
  background: var(--branco);
  border: 1px solid var(--borda);
  border-radius: var(--raio);
  padding: 16px;
  box-shadow: var(--sombra-sm);
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.cd-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
}
.cd-titulo { font-size: 14px; font-weight: 600; color: var(--texto); margin: 0; }
.cd-acoes { display: flex; gap: 4px; }

/* Grid de cards irmaos: TODOS com a mesma altura. Sem isso o visual fica
   irregular e parece bug (Padrao_Box_Card, regra critica). */
.cd-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 16px;
  align-items: stretch;
}
.cd-grid > .cd { height: 100%; }

/* Card clicavel: hover muda borda e sombra, NUNCA background */
.cd-clicavel { cursor: pointer; transition: var(--transicao); }
.cd-clicavel:hover {
  border-color: var(--cor-primaria);
  box-shadow: var(--sombra);
  transform: translateY(-2px);
}

/* Empty state */
.cd-vazio { align-items: center; text-align: center; padding: 40px 20px; gap: 8px; }
.cd-vazio .icon-xl { color: var(--texto-fraco); }
.cd-vazio-titulo { font-size: 16px; font-weight: 600; margin: 8px 0 0; }
.cd-vazio-msg { font-size: 13px; color: var(--texto-suave); margin: 0 0 16px; }

/* Card de estado */
.cd-sucesso { border-color: var(--verde);    background: var(--verde-suave); }
.cd-aviso   { border-color: var(--ambar);    background: var(--ambar-suave); }
.cd-erro    { border-color: var(--vermelho); background: var(--vermelho-suave); }

/* --------------------------------------------------------------------------
   BADGE
   -------------------------------------------------------------------------- */

.badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 9px;
  border-radius: var(--raio-full);
  font-size: 11.5px;
  font-weight: 600;
  background: var(--fundo);
  color: var(--texto-secundario);
}
.badge-sucesso { background: var(--verde-suave);    color: var(--verde); }
.badge-aviso   { background: var(--ambar-suave);    color: var(--ambar); }
.badge-erro    { background: var(--vermelho-suave); color: var(--vermelho); }
.badge-primaria{ background: var(--cor-primaria-suave); color: var(--cor-primaria-escura); }

/* --------------------------------------------------------------------------
   FLASH
   -------------------------------------------------------------------------- */

.flash-area {
  position: fixed;
  top: 70px; right: 20px;
  z-index: 60;
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-width: 380px;
}
.flash {
  padding: 12px 16px;
  border-radius: var(--raio-sm);
  border: 1px solid var(--borda);
  background: var(--branco);
  box-shadow: var(--sombra-md);
  font-size: 13px;
}
.flash.success { border-color: var(--verde);    background: var(--verde-suave); }
.flash.error   { border-color: var(--vermelho); background: var(--vermelho-suave); }
.flash.warning { border-color: var(--ambar);    background: var(--ambar-suave); }

/* --------------------------------------------------------------------------
   LOADING (Padrao_Loading_Estado / Sempre_Mostrar_Loading)
   -------------------------------------------------------------------------- */

/* Spinner unico do sistema: 44x44, borda 4px, topo na cor da marca, 0.8s.
   PROIBIDO loading DENTRO do botao: o botao so desabilita, e o spinner aparece
   na area que vai receber o resultado (regra 8 da nota). */
.spinner-circle {
  width: 44px;
  height: 44px;
  border: 4px solid var(--borda);
  border-top-color: var(--cor-primaria);
  border-radius: 50%;
  animation: spinner-rotate .8s linear infinite;
}
@keyframes spinner-rotate { to { transform: rotate(360deg); } }

.loading-text { font-size: 14px; font-weight: 600; color: var(--texto); }
.loading-sub  { font-size: 12px; color: var(--texto-secundario); font-variant-numeric: tabular-nums; }

/* Inline: substitui o conteudo de um container (tabela, card, painel) */
.loading-inline {
  padding: 80px 20px;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  background: var(--branco);
}

/* Overlay: cobre a tela toda, so pra operacao que nao pode ser interrompida */
.loading-overlay {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, .45);
  backdrop-filter: blur(2px);
  z-index: 9999;
  display: none;
  align-items: center;
  justify-content: center;
}
.loading-overlay.aberto { display: flex; }

.loading-spinner {
  background: var(--branco);
  border-radius: var(--raio);
  padding: 28px 44px;
  box-shadow: var(--sombra-lg);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  animation: modalSobe .2s ease;
}

@keyframes modalSobe {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* --------------------------------------------------------------------------
   BARRA DE FORMULARIO (Padrao_Formulario: TUDO com 40px, nunca 36 nem 38)
   -------------------------------------------------------------------------- */

.bf {
  display: flex;
  gap: 14px;
  align-items: flex-end;      /* alinha pela BASE: cada campo tem label em cima */
  flex-wrap: wrap;
  background: var(--branco);
  border: 1px solid var(--borda);
  border-radius: var(--raio);
  padding: 14px 18px;
  margin-bottom: 14px;
}

.campo { display: flex; flex-direction: column; gap: 5px; }

.bf .input,
.bf .sb-control,
.bf .sb-control .sb-btn,
.bf > .btn,
.bf .campo > .btn {
  height: var(--campo-h);     /* 40px */
  box-sizing: border-box;
}
.bf .input { min-width: 240px; }
.bf .sb-control { min-width: 170px; }

/* ---- campo recusado ---------------------------------------------------
   Vermelho na borda E recado embaixo, nunca so a cor: quem nao distingue bem
   vermelho de cinza tem que conseguir achar o campo do mesmo jeito. */
.input.erro, .textarea.erro {
  border-color: var(--vermelho);
  background: var(--vermelho-suave);
}
.input.erro:focus, .textarea.erro:focus {
  border-color: var(--vermelho);
  box-shadow: 0 0 0 3px rgba(220, 38, 38, .14);
}
/* O rotulo avisa que o campo passou a ser obrigatorio. So aparece quando o JS
   liga a classe no grupo, e some sozinho quando o campo e preenchido. */
.campo-exigido-tag { display: none; }
.campo-exigido .campo-exigido-tag {
  display: inline-block;
  margin-left: 7px;
  padding: 1px 7px;
  border-radius: var(--raio-full);
  background: var(--ambar-suave);
  color: var(--ambar);
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .03em;
}
.campo-exigido .input { border-color: var(--ambar); }

.campo-erro {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 5px;
  font-size: var(--fs-xs);
  font-weight: 600;
  color: var(--vermelho);
}

.input, .textarea {
  width: 100%;
  border: 1px solid var(--borda-forte);
  border-radius: var(--raio-sm);
  padding: 9px 12px;
  background: var(--branco);
  color: var(--texto);
  font-size: 16px;            /* menos de 16px faz o iOS dar zoom no foco */
}
.input:focus, .textarea:focus {
  outline: none;
  border-color: var(--cor-primaria);
  box-shadow: 0 0 0 3px var(--cor-primaria-suave);
}
.input:disabled { background: var(--fundo); color: var(--texto-fraco); }
.textarea { min-height: 90px; resize: vertical; }

/* Desktop pode ter texto menor: o zoom do iOS so existe no celular */
@media (min-width: 721px) {
  .input, .textarea { font-size: 14px; }
}

/* --------------------------------------------------------------------------
   CAMPO DE FORMULARIO (so a tipografia do label; o resto vem na FASE 5)
   -------------------------------------------------------------------------- */

/* Label comum e 13px peso 600, SEM uppercase e SEM letter-spacing. Uppercase
   com peso 800 e cara de sistema legado, e uppercase moderno so vale em
   cabecalho categorial: grupo de menu, <th> de tabela, label de KPI
   (Sistema_de_Estilos, "Regra dura sobre labels de form"). */
.campo label {
  display: block;
  font-size: 13px;
  font-weight: 600;
  color: var(--texto-suave);
  margin-bottom: 6px;
  text-transform: none;
  letter-spacing: 0;
}

/* --------------------------------------------------------------------------
   MOBILE (Responsividade_Sempre)
   -------------------------------------------------------------------------- */

@media (max-width: 720px) {
  /* Alvo de toque de 44px: recomendacao da Apple. Botao menor que isso
     erra o dedo. */
  .btn { min-height: 44px; padding: 11px 16px; }
  .btn-sm { min-height: 40px; padding: 9px 12px; }
  .btn-icone { width: 44px; height: 44px; }

  .flash-area { top: 64px; left: 14px; right: 14px; max-width: none; }
}

/* --------------------------------------------------------------------------
   TABELA (Padrao_Tabela / Tabela_Sempre_com_Ferramentas)
   -------------------------------------------------------------------------- */

.te-wrap {
  background: var(--branco);
  border: 1px solid var(--borda);
  border-radius: var(--raio);
  overflow: hidden;
}

/* Barra de cima da tabela: contagem a esquerda, busca e 3 pontos a direita */
.te-topo {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--borda);
  flex-wrap: wrap;
}
.te-topo .te-info { font-size: 12.5px; color: var(--texto-secundario); flex: 1; }
.te-topo .input { max-width: 260px; min-width: 160px; }

/* Rolagem horizontal no mobile (Responsividade_Sempre) */
.te-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }

table.te-tab { width: 100%; border-collapse: collapse; }

table.te-tab th {
  text-align: left;
  font-size: 11.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--texto-secundario);
  padding: 10px 12px;
  border-bottom: 1px solid var(--borda);
  white-space: nowrap;
  background: var(--branco);
}
table.te-tab th[data-col-key] { cursor: pointer; user-select: none; }
table.te-tab th .te-ord { font-size: 11px; opacity: .55; margin-left: 4px; }
table.te-tab th.ordenando .te-ord { opacity: 1; color: var(--cor-primaria); }

table.te-tab td {
  padding: 11px 12px;
  border-bottom: 1px solid var(--borda);
  font-size: 14px;
  vertical-align: middle;
}
table.te-tab tbody tr:last-child td { border-bottom: none; }
table.te-tab tbody tr:hover { background: var(--fundo); }

/* Linha de filtros por coluna, estilo Excel */
table.te-tab tr.te-filtros th { padding: 6px 8px; }
table.te-tab tr.te-filtros input {
  width: 100%;
  min-width: 90px;
  border: 1px solid var(--borda);
  border-radius: var(--raio-sm);
  padding: 5px 8px;
  font-size: 12.5px;
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0;
  color: var(--texto);
}
table.te-tab tr.te-filtros input:focus { outline: none; border-color: var(--cor-primaria); }

.te-vazio { padding: 40px 20px; text-align: center; color: var(--texto-fraco); font-size: 13px; }

/* Menu de 3 pontos: Ordenar, Colunas, Exportar */
.ta-menu-wrapper { position: relative; }
.ta-menu-btn {
  width: 32px; height: 32px;
  display: grid; place-items: center;
  border: 1px solid var(--borda);
  border-radius: var(--raio-sm);
  background: var(--branco);
  cursor: pointer;
  color: var(--texto-secundario);
}
.ta-menu-btn:hover { border-color: var(--cor-primaria); color: var(--cor-primaria); }
.ta-menu-btn i { font-size: 18px; }

.ta-menu, .ta-popup {
  position: absolute; top: 100%; right: 0;
  margin-top: 6px;
  background: var(--branco);
  border: 1px solid var(--borda);
  border-radius: var(--raio);
  box-shadow: var(--sombra-md);
  display: none;
}
.ta-menu { min-width: 200px; z-index: 50; }
.ta-popup { min-width: 260px; z-index: 60; }
.ta-menu.aberto, .ta-popup.aberto { display: block; }

.ta-menu-item {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 14px;
  font-size: 13px; cursor: pointer;
  color: var(--texto);
  background: none; border: none; width: 100%; text-align: left;
}
.ta-menu-item:hover { background: var(--fundo); color: var(--cor-primaria); }
.ta-menu-item i { font-size: 16px; color: var(--texto-secundario); }
.ta-menu-item:hover i { color: var(--cor-primaria); }
.ta-menu-divider { height: 1px; background: var(--borda); margin: 4px 0; }

.ta-popup-cab {
  padding: 12px 14px;
  border-bottom: 1px solid var(--borda);
  font-weight: 700;
  font-size: 13px;
  display: flex; align-items: center; gap: 8px;
}
.ta-popup-cab i { color: var(--cor-primaria); }
.ta-popup-corpo { padding: 8px 14px; max-height: 40vh; overflow-y: auto; }
.ta-popup-corpo label {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 0; font-size: 13px; cursor: pointer;
}

/* Coluna de acoes: slots SEMPRE do mesmo tamanho, nunca somem */
.celula-acoes {
  display: inline-flex;
  gap: 4px;
  align-items: center;
  justify-content: flex-end;
}
.celula-acoes form { display: inline; }

.btn-icone.desabilitado { opacity: .30; cursor: not-allowed; }
.btn-icone.desabilitado:hover { background: transparent; color: var(--texto-secundario); }

/* --------------------------------------------------------------------------
   MODAL (Padrao_Modal). Substitui alert/confirm/prompt do navegador.
   -------------------------------------------------------------------------- */

.modal-bg {
  position: fixed; inset: 0;
  background: rgba(15, 23, 42, .55);
  z-index: 200;
  display: none;
  align-items: center; justify-content: center;
  padding: 20px;
  backdrop-filter: blur(2px);
}
.modal-bg.visivel { display: flex; }

.modal-caixa {
  background: var(--branco);
  border-radius: var(--raio-lg);
  width: 100%;
  overflow-y: auto;
  box-shadow: var(--sombra-lg);
  animation: modalSobe .2s ease;
}

/* Tamanho em vw/vh, nunca px: modal calibrado em pixel encolhe no ultrawide
   e estoura no notebook (Padrao_Modal, principio 3) */
.modal-caixa.modal-sm { width: 34vw; max-height: 42vh; }
.modal-caixa.modal-md { width: 55vw; max-height: 70vh; }
.modal-caixa.modal-lg { width: 89vw; max-height: 90vh; }
.modal-caixa:not(.modal-sm):not(.modal-md):not(.modal-lg):not(.modal-confirm) {
  width: 55vw; max-height: 70vh;
}

@media (max-width: 1280px) {
  .modal-caixa.modal-md,
  .modal-caixa:not(.modal-sm):not(.modal-md):not(.modal-lg):not(.modal-confirm) { width: 68vw; }
}
@media (max-width: 880px) {
  .modal-caixa.modal-sm,
  .modal-caixa.modal-md,
  .modal-caixa.modal-lg,
  .modal-caixa.modal-confirm,
  .modal-caixa:not(.modal-sm):not(.modal-md):not(.modal-lg):not(.modal-confirm) {
    width: 96vw; max-height: 92vh;
  }
}

.modal-cab {
  padding: 18px 22px;
  border-bottom: 1px solid var(--borda);
  display: flex; align-items: center; justify-content: space-between;
}
.modal-cab h3 { font-size: 17px; }

.modal-x {
  background: none; border: none; cursor: pointer;
  font-size: 22px; color: var(--texto-fraco);
  display: grid; place-items: center;
}
.modal-x:hover { color: var(--texto); }

.modal-corpo { padding: 22px; display: flex; flex-direction: column; gap: 14px; }

/* --------------------------------------------------------------------------
   MODAL POPUP-CENTRADO (Padrao_Modal_Popup_Centrado)

   Obrigatorio quando o modal tem SelectBusca dentro. `.modal-caixa` tem
   `overflow-y: auto`, entao o painel de opcoes do SelectBusca sai cortado pela
   borda da caixa. `<dialog>` vai pra top-layer do navegador e, com
   `overflow: visible`, o painel escapa por cima.

   Desvio declarado: a nota escreve `max-width: 520px; width: 92%`. Aqui o
   tamanho fica em vw/vh, como manda Padrao_Modal e como ja estao os quatro
   tamanhos de `.modal-caixa` acima. Medida em px calibrada no notebook estoura
   no ultrawide, e este projeto e mobile-first. Vence a nota de tamanho.
   -------------------------------------------------------------------------- */

dialog.popup-centrado {
  position: fixed;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  margin: 0;
  border: 0;
  padding: 0;
  width: 55vw;
  max-height: 80vh;
  border-radius: var(--raio-lg);
  background: var(--branco);
  box-shadow: var(--sombra-lg);
  overflow: visible !important;   /* CRITICO: sem isto o SelectBusca corta */
  animation: modalSobe .2s ease;
}
dialog.popup-centrado::backdrop { background: rgba(15, 23, 42, .45); }

@media (max-width: 1280px) { dialog.popup-centrado { width: 68vw; } }
@media (max-width: 880px)  { dialog.popup-centrado { width: 96vw; max-height: 92vh; } }

/* Botao primario SEMPRE a direita, Cancelar a esquerda dele */
.modal-rodape {
  padding: 16px 22px;
  border-top: 1px solid var(--borda);
  display: flex; gap: 10px; justify-content: flex-end;
}

.modal-caixa.modal-confirm { width: 34vw; max-height: 42vh; text-align: center; }
.confirm-corpo { padding: 32px 28px 12px; }
.confirm-corpo h3 { font-size: 18px; margin-bottom: 8px; }
.confirm-corpo p  { color: var(--texto-suave); font-size: 14px; line-height: 1.5; }
.confirm-icone {
  width: 68px; height: 68px;
  border-radius: 50%;
  display: grid; place-items: center;
  margin: 0 auto 18px;
}
.confirm-icone i { font-size: 36px; }
.confirm-icone.confirm-perigo { background: var(--vermelho-suave); color: var(--vermelho); }
.confirm-icone.confirm-aviso  { background: var(--ambar-suave);    color: var(--ambar); }
.modal-confirm .modal-rodape { justify-content: center; }

/* --------------------------------------------------------------------------
   TOGGLE ON/OFF (Padrao_Toggle_OnOff, o tipo 3). 42x24, ligado em verde.
   -------------------------------------------------------------------------- */

.cv-sw { position: relative; width: 42px; height: 24px; flex: 0 0 auto; display: inline-block; }

/* Sem esta linha o navegador desenha a caixinha nativa por cima e o
   interruptor desenhado nunca aparece. E o bug do "Windows 98" da vault. */
.cv-sw input { display: none; }

.cv-sw label {
  position: absolute;
  inset: 0;
  background: var(--borda-forte);
  border-radius: 999px;
  cursor: pointer;
  transition: .15s;
}
.cv-sw label::after {
  content: "";
  position: absolute;
  top: 2px; left: 2px;
  width: 20px; height: 20px;
  background: #fff;
  border-radius: 50%;
  transition: .15s;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .25);
}
.cv-sw input:checked + label { background: var(--verde); }
.cv-sw input:checked + label::after { transform: translateX(18px); }

/* --------------------------------------------------------------------------
   SELECTBUSCA (Componente_SelectBusca). Nunca <select> nativo.
   Os nomes de token da nota (--bg-elev, --accent) sao do preset escuro da
   casa; aqui valem os deste projeto (LASTRO, regra local 12).
   -------------------------------------------------------------------------- */

.selectbusca { position: relative; min-width: 170px; }

.selectbusca .sb-display {
  height: var(--campo-h);
  padding: 9px 12px;
  background: var(--branco);
  border: 1px solid var(--borda-forte);
  border-radius: var(--raio-sm);
  cursor: pointer;
  display: flex; justify-content: space-between; align-items: center;
  gap: 8px;
  font-size: 14px;
}
.selectbusca.aberto .sb-display { border-color: var(--cor-primaria); }
.selectbusca .sb-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.selectbusca .sb-label.vazio { color: var(--texto-fraco); }
.selectbusca .sb-display i { color: var(--texto-secundario); flex-shrink: 0; }

.selectbusca .sb-panel {
  position: absolute; top: 100%; left: 0; right: 0; z-index: 210;
  background: var(--branco);
  border: 1px solid var(--borda);
  border-radius: var(--raio-sm);
  margin-top: 4px;
  box-shadow: var(--sombra-md);
  max-height: 280px; overflow-y: auto;
  display: none;
}
.selectbusca.aberto .sb-panel { display: block; }

.selectbusca .sb-search {
  width: 100%;
  padding: 10px 12px;
  border: none;
  border-bottom: 1px solid var(--borda);
  font-size: 14px;
  color: var(--texto);
}
.selectbusca .sb-search:focus { outline: none; }

.selectbusca .sb-opt { padding: 10px 12px; cursor: pointer; font-size: 14px; }
.selectbusca .sb-opt:hover,
.selectbusca .sb-opt.marcado {
  background: var(--cor-primaria-suave);
  color: var(--cor-primaria-escura);
}
.selectbusca .sb-vazio { padding: 12px; font-size: 13px; color: var(--texto-fraco); }

/* Utilitarios de largura de campo. Existem porque Padrao_Formulario mostra
   style="flex:1" inline, e Sistema_de_Estilos proibe atributo de estilo em
   template. Vence a proibicao, que e a regra provavel por comando. */
.campo-cresce { flex: 1; }
.campo-num .input { min-width: 90px; }
.campo-data .input { min-width: 140px; }

/* Texto de ajuda embaixo de um campo */
.ajuda { font-size: 12px; color: var(--texto-fraco); }

/* Matriz de permissoes */
.perm-grupo { margin-bottom: 14px; }
.perm-tab th.perm-col, .perm-tab td.perm-col { width: 90px; text-align: center; }
.perm-tab td.perm-col .cv-sw { margin: 0 auto; display: block; }
.perm-auto {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  border-top: 1px solid var(--borda);
  padding-top: 12px;
}
.perm-auto-txt { font-size: 13px; color: var(--texto-secundario); }
.perm-auto-lbl { font-size: 13px; font-weight: 600; margin-right: 10px; }

/* Aviso em linha, com icone ao lado do texto */
.seg-aviso, .login-aviso {
  flex-direction: row;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  font-size: 13px;
}

/* --------------------------------------------------------------------------
   UPLOAD DE ARQUIVO (Padrao_Upload_Arquivo). Tres estados: parada, por cima,
   escolhida. O input nativo fica escondido fora da tela.
   -------------------------------------------------------------------------- */

.im-drop {
  display: block;
  border: 2px dashed var(--borda-forte);
  border-radius: var(--raio);
  padding: 32px;
  text-align: center;
  color: var(--texto-secundario);
  cursor: pointer;
  transition: .15s;
  user-select: none;
  margin-top: 4px;
}
.im-drop:hover,
.im-drop.over {
  border-color: var(--cor-primaria);
  background: var(--cor-primaria-suave);
  color: var(--cor-primaria-escura);
  border-style: solid;
}
.im-drop.loaded {
  border-style: solid;
  border-color: var(--verde);
  background: var(--verde-suave);
  color: var(--verde);
}
.im-drop i { font-size: 36px; display: block; margin-bottom: 6px; }
.im-arq { display: block; margin-top: 6px; font-weight: 600; }

.im-inp { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }

.im-acao {
  display: flex; gap: 10px; align-items: center; flex-wrap: wrap;
  margin-top: 14px;
}
.im-acao .btn:disabled { opacity: .45; cursor: not-allowed; }

/* Previa do logo que ja esta cadastrado */
.id-previa { display: flex; align-items: center; gap: 14px; }
.id-previa img {
  width: 72px; height: 72px;
  object-fit: cover;
  border-radius: var(--raio);
  border: 1px solid var(--borda);
  background: var(--branco);
}
.id-previa-info { font-size: 12.5px; color: var(--texto-secundario); }

/* Campo de cor: o seletor nativo do navegador e o unico jeito honesto de
   escolher cor sem inventar um seletor proprio. Nao e <select>, entao a regra
   Sem_Select_Nativo nao alcanca ele. */
.campo-cor .input-cor {
  /* min-width vence width, e a barra de formulario poe 240px em todo .input.
     Sem repetir o min-width aqui, o seletor de cor sai do tamanho de um campo
     de texto. */
  width: 64px;
  min-width: 64px;
  padding: 4px;
  cursor: pointer;
}

/* No celular a barra de formulario vira coluna, e o label vazio que alinha o
   botao pela base (o macete <label>&nbsp;</label> de Padrao_Formulario) vira
   so um buraco. Some com ele: nao ha mais nada ao lado pra alinhar. */
@media (max-width: 720px) {
  .bf .campo:has(> .btn) > label { display: none; }
  .bf .campo:has(> .btn) { width: 100%; }
  .bf .campo:has(> .btn) > .btn { width: 100%; justify-content: center; }
}

/* --------------------------------------------------------------------------
   ESCALA DA SEMANA (tela de jornada por colaboradora)
   -------------------------------------------------------------------------- */

.jr-dia { margin-bottom: 12px; }
.jr-dia.jr-folga { background: var(--fundo); }
.jr-dia.jr-folga .jr-marcos { opacity: .45; }
.jr-dia.jr-folga .jr-dica { display: none; }

.jr-folga-box { display: flex; align-items: center; gap: 8px; }
.jr-folga-lbl { font-size: 13px; font-weight: 600; color: var(--texto-secundario); }

.jr-marcos { margin-bottom: 0; }
.campo-hora .input { min-width: 130px; }

.jr-previsto { justify-content: flex-end; }
.jr-previsto-valor {
  height: var(--campo-h);
  display: inline-flex;
  align-items: center;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--cor-primaria-escura);
}

.jr-dica { margin-top: 10px; }

/* --------------------------------------------------------------------------
   LANCAMENTO DE PONTO
   -------------------------------------------------------------------------- */

/* Navegacao entre dias: no fim do mes se lanca um dia atras do outro */
.pt-dias {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 12px;
  flex-wrap: wrap;
}
.pt-dia-atual {
  font-weight: 600;
  font-size: 14px;
  color: var(--texto-suave);
}

/* Toggle TIPO 1 (multi opcoes) do Padrao_Toggle_Tipos: escolhido fica com
   borda e fundo na cor da marca. Nunca sublinhado (isso e aba), nunca solido
   (isso e o tipo 2), nunca verde (isso e estado ligado). */
.pt-presets {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  flex-wrap: wrap;
  padding: 3px;
  border: 1px solid var(--borda);
  border-radius: 7px;
  background: var(--branco);
}
.pt-presets button {
  min-height: 32px;
  border: 1px solid transparent;
  background: var(--branco);
  border-radius: 5px;
  padding: 0 10px;
  font-size: 12px;
  font-weight: 600;
  color: var(--texto-secundario);
  cursor: pointer;
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  gap: 5px;
}
.pt-presets button:hover { color: var(--cor-primaria); }
.pt-presets button.on {
  border-color: var(--cor-primaria);
  background: var(--cor-primaria-suave);
  color: var(--cor-primaria-escura);
}
.pt-presets button:disabled { opacity: .55; cursor: not-allowed; }

.pt-marcos.pt-escondido { display: none; }
.pt-extras.pt-escondido, .pt-extras-vazio.pt-escondido { display: none; }

.pt-acoes { display: flex; gap: 10px; flex-wrap: wrap; }

/* ---- o dia de hoje, que pode ser lancado pela metade ------------------- */
.pt-hoje {
  display: flex;
  align-items: flex-start;
  gap: 7px;
  margin-top: 12px;
  padding: 10px 12px;
  border: 1px solid var(--cor-primaria);
  background: var(--cor-primaria-suave);
  border-radius: var(--raio-sm);
  color: var(--texto-suave);
}
.pt-hoje i { color: var(--cor-primaria-escura); margin-top: 2px; flex-shrink: 0; }

.pt-andamento {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  font-size: var(--fs-sm);
  color: var(--texto-secundario);
  line-height: 1.55;
}
.pt-andamento i { color: var(--cor-primaria); font-size: 18px; flex-shrink: 0; }

/* ---- saidas extras: uma linha por saida -------------------------------
   Cada linha e um mini formulario. No celular ela quebra em duas faixas, com o
   par de horarios em cima e o motivo embaixo, porque quatro campos lado a lado
   em 360px viram quatro campos ilegiveis (Responsividade_Sempre). */
.pt-extras { margin-top: 18px; }
.pt-extras-topo {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 4px;
}
.pt-extras-tit {
  font-family: var(--font-titulo);
  font-size: var(--fs-base);
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  gap: 7px;
}
.pt-extras-vazio {
  font-size: var(--fs-sm);
  color: var(--texto-fraco);
  padding: 10px 0 2px;
}

.pt-saida {
  display: flex;
  gap: 12px;
  align-items: flex-end;
  flex-wrap: wrap;
  margin-top: 10px;
  padding: 12px 14px;
  border: 1px solid var(--borda);
  border-radius: var(--raio-sm);
  background: var(--fundo);
}
.pt-saida .input { height: var(--campo-h); box-sizing: border-box; }
.pt-saida-motivo { flex: 1 1 200px; }
.pt-saida-motivo .input { width: 100%; min-width: 0; }
.pt-saida-abono { display: flex; flex-direction: column; gap: 4px; }
/* o switch fica na altura dos campos, senao ele boia acima da linha de base */
.pt-saida-abono .cv-sw { margin-bottom: 9px; }
.pt-saida-x { align-self: center; margin-bottom: 4px; }

@media (max-width: 640px) {
  .pt-saida { gap: 10px; }
  .pt-saida-motivo { flex: 1 1 100%; }
  .campo-hora .input { min-width: 110px; }
}

/* Resultado do dia: tres caixas independentes.
   PROIBIDO somar ou subtrair negativas com extras aqui, nem visualmente. */
.res-caixas {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
}
.res-box {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 14px;
  border: 1px solid var(--borda);
  border-radius: var(--raio);
  background: var(--branco);
}
.res-box-lbl {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--texto-secundario);
  min-height: 25px;
}
.res-box-valor {
  font-family: var(--font-titulo);
  font-weight: 700;
  font-size: 24px;
  letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
}
.res-box-sub { font-size: 12px; color: var(--texto-fraco); min-height: 14px; }

.res-box-neg .res-box-valor { color: var(--vermelho); }
.res-box-ext .res-box-valor { color: var(--verde); }
.res-box.res-zero .res-box-valor { color: var(--texto-fraco); }

.pt-parcelas { margin-top: 14px; }

/* De onde veio o horario. Fica colado no rotulo do campo porque a pergunta
   "quem digitou isso?" so faz sentido olhando pro campo. */
.pt-origem {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 7px;
  border-radius: var(--raio-full);
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .03em;
  vertical-align: middle;
}
.pt-origem-app { background: var(--cor-primaria-suave); color: var(--cor-primaria-escura); }
.pt-origem-mao { background: var(--ambar-suave); color: var(--ambar); }

@media (max-width: 720px) {
  .res-caixas { grid-template-columns: 1fr; }
  .pt-acoes .btn { flex: 1 1 100%; justify-content: center; }
  /* No celular os tres nao cabem lado a lado e o flex-wrap deixava "Proximo
     dia" pendurado sozinho no meio da linha. Data em cima, os dois botoes
     dividindo a linha de baixo. */
  .pt-dias { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
  .pt-dia-atual { grid-column: 1 / -1; order: -1; text-align: center; }
  .pt-dias .btn { justify-content: center; }
}

/* --------------------------------------------------------------------------
   BARRA DE FILTROS (Padrao_Barra_de_Filtros) e KPI (Padrao_KPI_Dashboard)

   Prefixos novos, um por modulo, como a nota manda: `dh-` no dashboard e
   `hi-` no historico. A altura unica da barra vive em --dh-h / --hi-h.

   O KPI so aparece no dashboard. Listagem operacional vai do titulo direto
   pros filtros (Listagens_sem_KPI).
   -------------------------------------------------------------------------- */

.dh-bar, .hi-bar {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  align-items: flex-end;
  margin-bottom: 16px;
  --dh-h: 38px;
  --hi-h: 38px;
}
.dh-bar .g, .hi-bar .g { display: flex; flex-direction: column; gap: 4px; }

.dh-lbl, .hi-lbl {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--texto-secundario);
}

/* Altura unica: sem isto os presets engordam mais que o campo e desalinham */
.dh-bar .input, .dh-bar .sb-display, .dh-bar .btn,
.hi-bar .input, .hi-bar .sb-display, .hi-bar .btn {
  height: var(--dh-h);
  min-height: var(--dh-h);
  box-sizing: border-box;
  font-size: 13px;
}
.dh-bar .sp, .hi-bar .sp { flex: 1; }

/* Presets de periodo: toggle TIPO 1 (Padrao_Toggle_Tipos), o mesmo visual do
   tipo do dia na tela de ponto. Escolhido fica com borda e fundo da marca. */
.dh-presets, .hi-presets {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  flex-wrap: nowrap;
  height: var(--dh-h);
  padding: 3px;
  border: 1px solid var(--borda);
  border-radius: var(--raio-sm);
  background: var(--branco);
}
.dh-presets button, .hi-presets button {
  height: calc(var(--dh-h) - 8px);
  border: 1px solid transparent;
  background: var(--branco);
  border-radius: 5px;
  padding: 0 10px;
  font-size: 12px;
  font-weight: 600;
  color: var(--texto-secundario);
  cursor: pointer;
  white-space: nowrap;
}
.dh-presets button:hover, .hi-presets button:hover { color: var(--cor-primaria); }
.dh-presets button.on, .hi-presets button.on {
  border-color: var(--cor-primaria);
  background: var(--cor-primaria-suave);
  color: var(--cor-primaria-escura);
}

/* ---- KPI ---------------------------------------------------------------- */

.dh-kpis {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 10px;
  margin-bottom: 18px;
}

.dh-kpi {
  background: var(--branco);
  border: 1px solid var(--borda);
  border-radius: var(--raio);
  padding: 14px;
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  gap: 12px;
}

/* Faixa de 3px no topo dizendo o tipo do numero */
.dh-kpi::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 3px;
  background: var(--borda-forte);
}
.dh-kpi.ac-feito::before   { background: linear-gradient(90deg, var(--cor-primaria), var(--cor-primaria-escura)); }
.dh-kpi.ac-previsto::before{ background: linear-gradient(90deg, var(--borda-forte), var(--texto-fraco)); }
.dh-kpi.neg::before        { background: linear-gradient(90deg, #F87171, var(--vermelho)); }
.dh-kpi.pos::before        { background: linear-gradient(90deg, #4ADE80, var(--verde)); }

.dh-kpi .ico {
  width: 44px;
  height: 44px;
  border-radius: 11px;
  display: grid;
  place-items: center;
  font-size: 22px;
  flex-shrink: 0;
  align-self: center;
  background: var(--fundo);
  color: var(--texto-secundario);
}
.dh-kpi.ac-feito .ico { background: var(--cor-primaria-suave); color: var(--cor-primaria-escura); }
.dh-kpi.neg .ico      { background: var(--vermelho-suave); color: var(--vermelho); }
.dh-kpi.pos .ico      { background: var(--verde-suave); color: var(--verde); }

.dh-kpi .corpo { min-width: 0; flex: 1; display: flex; flex-direction: column; }

/* min-height nos dois: sem eles, card com legenda e card sem legenda saem de
   alturas diferentes e a fileira inteira desalinha */
.dh-kpi .lbl {
  font-size: 10.5px;
  color: var(--texto-secundario);
  text-transform: uppercase;
  letter-spacing: .03em;
  font-weight: 700;
  line-height: 1.2;
  min-height: 25px;
  display: flex;
  align-items: flex-end;
}
.dh-kpi .val {
  font-size: 20px;
  font-weight: 800;
  letter-spacing: -.5px;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  margin-top: 3px;
}
.dh-kpi .disc {
  font-size: 10.5px;
  color: var(--texto-fraco);
  margin-top: 4px;
  line-height: 1.2;
  font-style: italic;
  min-height: 14px;
}
.dh-kpi.neg .val { color: var(--vermelho); }
.dh-kpi.pos .val { color: var(--verde); }
.dh-kpi.zerado .val { color: var(--texto-fraco); }

/* Duas variantes a mais desde a reescrita do dashboard em 2026-08-27: aviso
   (o que pede acao mas nao esta errado) e info (o que so informa). Saem dos
   tokens que ja existem, nenhuma cor nova entrou no sistema. */
.dh-kpi.ac-aviso::before { background: linear-gradient(90deg, #FBBF24, var(--ambar)); }
.dh-kpi.ac-info::before  { background: linear-gradient(90deg, var(--cor-primaria), var(--azul-info)); }
.dh-kpi.ac-aviso .ico { background: var(--ambar-suave); color: var(--ambar); }
.dh-kpi.ac-info .ico  { background: var(--cor-primaria-suave); color: var(--azul-info); }
.dh-kpi.ac-aviso .val { color: var(--ambar); }
.dh-kpi.ac-info .val  { color: var(--azul-info); }

/* ---- card clicavel ----------------------------------------------------
   O Padrao_KPI_Dashboard nao previa card que abre uma tela. O desenho dele
   ficou intacto (faixa de 3px, icone 44px, grade de 6): o que entrou foi so a
   afordancia, seta no canto, realce no hover e anel de foco pelo teclado.
   Sem o anel, quem navega por Tab nao enxerga onde esta. */
a.dh-kpi-link {
  color: inherit;
  text-decoration: none;
  cursor: pointer;
  transition: border-color var(--transicao), box-shadow var(--transicao),
              transform var(--transicao);
}
a.dh-kpi-link:hover {
  border-color: var(--borda-forte);
  box-shadow: var(--sombra);
  text-decoration: none;
}
a.dh-kpi-link:focus-visible {
  outline: 2px solid var(--cor-primaria);
  outline-offset: 2px;
}
.dh-seta {
  color: var(--texto-fraco);
  font-size: 16px;
  flex-shrink: 0;
  align-self: center;
}
a.dh-kpi-link:hover .dh-seta { color: var(--cor-primaria); }

/* ---- titulo de secao e explicacao da lista ---------------------------- */
.dh-sec {
  font-family: var(--font-titulo);
  font-size: var(--fs-lg);
  font-weight: 700;
  letter-spacing: -.01em;
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 22px 0 10px;
}
/* o primeiro titulo da tela vem logo abaixo da barra de filtros, entao nao
   precisa do respiro de cima que separa uma secao da outra */
.dh-sec-topo { margin-top: 4px; }
.dh-sec-sub {
  font-family: var(--font);
  font-size: var(--fs-xs);
  font-weight: 500;
  color: var(--texto-fraco);
}

/* A explicacao fica ACIMA do filtro porque ela diz o que a lista e; filtro
   antes da explicacao faz o dono filtrar sem saber o que esta filtrando. */
.dh-explica {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin-bottom: 14px;
  padding: 11px 13px;
  border: 1px solid var(--borda);
  background: var(--branco);
  border-radius: var(--raio-sm);
  font-size: var(--fs-sm);
  color: var(--texto-secundario);
  line-height: 1.5;
}
.dh-explica i { color: var(--cor-primaria); margin-top: 2px; flex-shrink: 0; }

/* Lista vazia nao e erro: quase sempre e a boa noticia (nenhum dia pela
   metade). Entao fundo neutro e icone de certo, nunca cara de falha. */
.dh-vazio {
  text-align: center;
  color: var(--texto-secundario);
  padding: 26px 14px !important;
}
.dh-vazio i { color: var(--verde); font-size: 18px; vertical-align: -3px; margin-right: 6px; }

/* Marca do horario que o responsavel corrigiu na mao, na lista de hoje. A
   mesma distincao que o espelho impresso faz com A e C. */
.dh-corr {
  display: inline-block;
  margin-left: 4px;
  padding: 0 4px;
  border-radius: 4px;
  background: var(--ambar-suave);
  color: var(--ambar);
  font-size: 9.5px;
  font-weight: 700;
  vertical-align: 1px;
}

/* Numeros da tabela: mesma largura por digito, senao a coluna serrilha */
.dh-num, .hi-num { font-variant-numeric: tabular-nums; text-align: right; }
.dh-neg { color: var(--vermelho); font-weight: 600; }
.dh-ext { color: var(--verde); font-weight: 600; }
.dh-zero { color: var(--texto-fraco); }

/* ---- Historico: o mes dia a dia ---------------------------------------- */

.hi-dia-fds td { background: var(--fundo); }

/* Rodape de totais: e a linha que se confere contra o papel, entao ela pesa */
table.te-tab tfoot td {
  border-top: 2px solid var(--borda-forte);
  padding: 12px 14px;
  font-size: 13px;
  background: var(--branco);
}
.hi-tag {
  display: inline-block;
  padding: 2px 8px;
  border-radius: var(--raio-full);
  font-size: 11px;
  font-weight: 600;
  background: var(--fundo);
  color: var(--texto-secundario);
}
.hi-tag.tipo-falta { background: var(--vermelho-suave); color: var(--vermelho); }
/* pastilha da saida extra, na propria celula da entrada: o detalhe vai no
   title, porque coluna nova nao cabe numa tabela que ja tem dez no celular */
.hi-tag.hi-saida {
  background: var(--ambar-suave);
  color: var(--ambar);
  margin-left: 4px;
  font-size: 9.5px;
}
.hi-tag.tipo-pendente { background: var(--ambar-suave); color: var(--ambar); }
.hi-tag.tipo-normal { background: var(--cor-primaria-suave); color: var(--cor-primaria-escura); }

@media (max-width: 1300px) { .dh-kpis { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 720px) {
  .dh-kpis { grid-template-columns: repeat(2, 1fr); gap: 8px; }
  .dh-kpi { padding: 12px 11px; gap: 9px; }
  .dh-kpi .ico { width: 36px; height: 36px; font-size: 18px; border-radius: 9px; }
  .dh-kpi .lbl { font-size: 9.5px; min-height: 23px; }
  .dh-kpi .val { font-size: 18px; }
  .dh-kpi .disc { font-size: 10px; min-height: 13px; }
  .dh-seta { display: none; }
  .dh-bar .g, .hi-bar .g { flex: 1 1 100%; }
  .dh-presets, .hi-presets { flex-wrap: wrap; height: auto; }
  .dh-presets button, .hi-presets button { flex: 1 1 auto; }
}

/* ---- regra liga/desliga na tela de seguranca -------------------------- */
/* Texto de um lado, switch do outro. O texto explica a consequencia de
   desligar, porque este toggle decide se a loja consegue bater ponto. */
.sg-regra {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  margin-top: 16px;
}
.sg-regra-txt { flex: 1 1 auto; }
.sg-regra-tit {
  display: block;
  font-family: var(--font-titulo);
  font-size: 15px;
  font-weight: 700;
  color: var(--texto);
  margin-bottom: 6px;
  cursor: pointer;
}
.sg-regra-msg {
  font-size: 13px;
  color: var(--texto-secundario);
  margin: 0 0 6px;
}
.sg-regra-msg:last-child { margin-bottom: 0; }
.sg-regra .cv-sw { margin-top: 2px; }

@media (max-width: 640px) {
  .sg-regra { flex-direction: column; gap: 10px; }
}
