/* Componentes reutilizáveis.
 *
 * Nesta fase entram botões, cards e mensagens flash, que são o que a casca da
 * aplicação usa. Tabela, barra de filtros, modal, SelectBusca, toggle e loading
 * entram nas fases que os introduzem, com as notas próprias de cada um.
 */

/* ---------- Botões ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  min-height: 36px;
  padding: 8px 14px;
  border: 1px solid var(--borda);
  border-radius: var(--raio-sm);
  background: var(--branco);
  color: var(--texto-secundario);
  font-weight: 500;
  font-size: 13px;
  cursor: pointer;
  text-decoration: none;
  transition: background var(--transicao), border-color var(--transicao),
              color var(--transicao), box-shadow var(--transicao);
}

.btn:hover {
  border-color: var(--borda-forte);
  background: var(--fundo);
  text-decoration: none;
}

.btn:disabled,
.btn[aria-disabled="true"] {
  opacity: .5;
  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-fantasma {
  background: transparent;
  border: 1px solid 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;
}

/* ---------- Campo de formulário ----------
 * Controle em 40px, label 13px peso 600, SEM uppercase e SEM letter-spacing.
 * Regra: Padrao_Formulario e Sistema_de_Estilos. */

.campo {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
}

.campo label {
  font-size: 13px;
  font-weight: 600;
  color: var(--texto-secundario);
}

.input {
  height: 40px;
  padding: 0 12px;
  border: 1px solid var(--borda);
  border-radius: var(--raio-sm);
  background: var(--branco);
  color: var(--texto);
  font-size: 16px;
  transition: border-color var(--transicao), box-shadow var(--transicao);
}

.input:focus {
  border-color: var(--cor-primaria);
  box-shadow: 0 0 0 3px var(--cor-primaria-sombra);
  outline: none;
}

/* iOS dá zoom no foco quando a fonte do input é menor que 16px. No desktop
 * pode voltar para 14px. Regra: Responsividade_Sempre. */
@media (min-width: 720px) {
  .input { font-size: 14px; }
}

/* ---------- Tela de login (standalone) ---------- */

.login-body {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: var(--sp-5);
  background: var(--fundo);
}

.login-caixa {
  width: 100%;
  max-width: 380px;
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  background: var(--branco);
  border: 1px solid var(--borda);
  border-radius: var(--raio);
  box-shadow: var(--sombra);
  padding: var(--sp-6) var(--sp-5);
}

.login-marca {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}

.login-logo {
  width: 38px;
  height: 38px;
  border-radius: var(--raio-full);
  border: 2px solid var(--cor-primaria);
  color: var(--cor-primaria);
  display: grid;
  place-items: center;
  flex-shrink: 0;
}

.login-logo i { font-size: 20px; }

/* Sora 800/17px, o único lugar em que o peso 800 aparece.
 * Regra: Sistema_de_Estilos, tabela do Sora. */
.login-marca-nome {
  font-family: var(--font-titulo);
  font-weight: 800;
  font-size: 17px;
  letter-spacing: -.02em;
}

.login-titulo {
  font-size: var(--fs-xl);
  margin-top: var(--sp-2);
}

.login-sub {
  font-size: var(--fs-sm);
  color: var(--texto-suave);
  margin-bottom: var(--sp-2);
}

.login-form {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}

.login-btn {
  margin-top: var(--sp-2);
  width: 100%;
}

.login-rodape {
  font-size: var(--fs-xs);
  color: var(--texto-fraco);
  text-align: center;
  margin-top: var(--sp-2);
}

/* Na tela de login a mensagem não flutua: ela empilha dentro da caixa. */
.login-caixa .flash {
  position: static;
  box-shadow: none;
}

/* ---------- Card ---------- */

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

/* Boxes irmãos numa grid têm a MESMA altura. Regra: Padrao_Box_Card. */
.grid-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--sp-4);
  align-items: stretch;
}

.grid-cards > .cd { height: 100%; }

.cd-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2);
}

.cd-titulo {
  font-size: 14px;
  font-weight: 600;
  color: var(--texto);
  margin: 0;
}

.cd-acoes {
  display: flex;
  gap: var(--sp-1);
  margin-left: auto;
}

.cd-corpo {
  font-size: var(--fs-sm);
  color: var(--texto-suave);
}

/* Hover muda border-color, shadow e translate. Nunca background.
 * Regra: Padrao_Box_Card. */
.cd-clicavel {
  cursor: pointer;
  transition: border-color var(--transicao), box-shadow var(--transicao),
              transform var(--transicao);
}

.cd-clicavel:hover {
  border-color: var(--cor-primaria);
  box-shadow: var(--sombra);
  transform: translateY(-2px);
}

.cd-vazio {
  align-items: center;
  text-align: center;
  padding: 40px 20px;
  gap: var(--sp-2);
}

.cd-vazio-titulo {
  font-size: var(--fs-lg);
  font-weight: 600;
  margin: var(--sp-2) 0 0;
}

.cd-vazio-msg {
  font-size: var(--fs-sm);
  color: var(--texto-suave);
  margin: 0 0 var(--sp-4);
}

/* ---------- Badge ---------- */

.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  padding: 2px 8px;
  border-radius: var(--raio-full);
  font-size: 11.5px;
  font-weight: 600;
}

.badge-ok    { background: var(--verde-suave);     color: var(--verde); }
.badge-erro  { background: var(--vermelho-suave);  color: var(--vermelho); }
.badge-aviso { background: var(--ambar-suave);     color: var(--ambar); }
.badge-info  { background: var(--azul-info-suave); color: var(--azul-info); }

/* ---------- Mensagens flash ---------- */

.flash-area {
  position: fixed;
  top: calc(var(--topbar-h) + var(--sp-3));
  right: var(--sp-5);
  z-index: 60;
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  max-width: 380px;
}

.flash {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--borda);
  border-radius: var(--raio);
  background: var(--branco);
  box-shadow: var(--sombra-md);
  font-size: var(--fs-sm);
}

.flash-sucesso { border-color: var(--verde);    background: var(--verde-suave); }
.flash-erro    { border-color: var(--vermelho); background: var(--vermelho-suave); }
.flash-aviso   { border-color: var(--ambar);    background: var(--ambar-suave); }

/* ---------- Responsivo ---------- */

@media (max-width: 720px) {
  .btn { min-height: 44px; padding: 11px 16px; }
  .btn-sm { min-height: 40px; }
  .flash-area { left: 16px; right: 16px; max-width: none; }
}

/* ---------- Barra de formulario (.ra-bar) ----------
 * Regra: Padrao_Formulario. Controles em 40px, label 13px/600 sem uppercase,
 * botao alinhado pela base via <label>&nbsp;</label>. */

.ra-bar {
  display: flex;
  gap: 14px;
  align-items: flex-end;
  flex-wrap: wrap;
  background: var(--branco);
  border: 1px solid var(--borda);
  border-radius: var(--raio);
  padding: 14px 18px;
}

.ra-bar .campo { display: flex; flex-direction: column; gap: 5px; }
.ra-bar label { font-size: 13px; font-weight: 600; color: var(--texto-secundario); }

.ra-bar .input,
.ra-bar .sb-display,
.ra-bar .btn {
  /* descendente, nao filho direto: o botao de acao normalmente vive dentro
     de um <form> com display:contents (fica "transparente" no LAYOUT do
     flex, mas continua um ancestral de verdade pro seletor CSS, que so
     enxerga a arvore do DOM). Achado da verificacao adversarial de
     2026-08-03: ">" nao casava, e o botao Filtrar saia com 32px em vez
     de 40px. */
  height: 40px;
  box-sizing: border-box;
}

.ra-bar .input { min-width: 220px; }
.ra-bar .selectbusca { min-width: 170px; }
.ra-bar .campo.ra-acao { flex: 0 0 auto; } /* botao de acao nao estica no flex, so os campos de texto */

/* ---------- Tabela de listagem ----------
 * Padrao_Tabela. escada: DUAS regras da nota (1 e 2) dependem do componente
 * tabela-avancada.js (523 linhas na nota, fonte dataevo_central):
 *   - Regra 1: menu sanduiche (filtro por coluna, ordenar, colunas, exportar
 *     CSV/Excel, linhas por pagina) em toda tabela com >10 linhas
 *   - Regra 2: filtro por coluna em toda tabela operacional (incondicional,
 *     verificado na verificacao adversarial da fase 5 pelo agente 1)
 * Nenhuma copia local existe em disco (so selectbusca.js existia em outros
 * projetos); e nenhuma listagem administrativa ou de cadastros desta fase 5
 * passa de 10 linhas reais (poucos perfis, poucos usuarios de staff, salao
 * piloto com poucos clientes cadastrados). Teto: quando qualquer listagem
 * passar de 10 linhas de verdade, portar ou escrever tabela-avancada.js e
 * aplicar em TODAS as tabelas do projeto (nao remendar so a que estourou -
 * seria mais uma inconsistencia). O que a escada NAO dispensa, e por isso ja
 * entra: coluna Acoes com slots fixos e esmaecimento, cabecalho tipografico
 * e estado vazio embutido (Padrao_Estado_Vazio, agora com .vz sem card). */

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

.tabela-cab {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  padding: var(--sp-4);
  border-bottom: 1px solid var(--borda);
}

.tabela-cab h2 { font-size: 15px; }

.tabela-cab .contagem {
  font-size: var(--fs-xs);
  color: var(--texto-fraco);
  font-weight: 500;
}

.tabela-listagem { width: 100%; border-collapse: collapse; }

.tabela-listagem th {
  text-align: left;
  font-size: 11.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--texto-fraco);
  padding: 10px var(--sp-4);
  border-bottom: 1px solid var(--borda);
  white-space: nowrap;
}

.tabela-listagem td {
  padding: 11px var(--sp-4);
  border-bottom: 1px solid var(--borda);
  font-size: var(--fs-sm);
  vertical-align: middle;
}

.tabela-listagem tbody tr:last-child td { border-bottom: none; }
.tabela-listagem tbody tr:hover { background: var(--fundo); }
/* Linha cujo toggle de ativo/inativo foi desligado no onchange. Regra:
 * Padrao_Toggle_OnOff, variante "linha desativada". */
.tabela-listagem tbody tr.off { opacity: .6; }
.tabela-listagem th.col-acoes,
.tabela-listagem td.col-acoes { text-align: right; }

/* Coluna de acoes: slots fixos, esmaecimento em vez de sumir.
 * Regra: Padrao_Tabela, secao "Coluna de Acoes - slots fixos". */
.celula-acoes {
  display: inline-flex;
  gap: 4px;
  align-items: center;
  justify-content: flex-end;
}

.btn-icone {
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--raio-sm);
  background: transparent;
  border: none;
  cursor: pointer;
  color: var(--texto-secundario);
  transition: background var(--transicao), color var(--transicao);
}

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

/* Badge do tipo de usuario (staff | operador). */
.badge-staff    { background: var(--azul-info-suave); color: var(--azul-info); }
.badge-operador { background: var(--cor-primaria-suave); color: var(--cor-primaria-escura); }

/* Estado vazio de tabela que e SECAO de um card (nao a tela inteira).
 * Regra: Padrao_Estado_Vazio, variante .vz-inline. */
.vz-inline {
  flex: none;
  min-height: 150px;
  padding: 22px 16px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
}

.vz-inline .vz-icone { font-size: 30px; color: var(--texto-fraco); margin-bottom: 10px; }

.vz-inline .vz-titulo {
  margin: 0;
  font-family: var(--font-titulo);
  font-size: 14.5px;
  font-weight: 700;
  letter-spacing: -.02em;
  color: var(--texto);
}

.vz-inline .vz-sub {
  margin: 7px 0 0;
  font-size: 12.5px;
  color: var(--texto-suave);
  line-height: 1.5;
  max-width: 360px;
}

/* ---------- SelectBusca ----------
 * Regra: Componente_SelectBusca. Nunca <select> nativo. */

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

.selectbusca .sb-display {
  height: 40px;
  padding: 0 12px;
  background: var(--branco);
  border: 1px solid var(--borda);
  border-radius: var(--raio-sm);
  cursor: pointer;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--sp-2);
  font-size: 14px;
  color: var(--texto);
}

.selectbusca .sb-display:hover { border-color: var(--borda-forte); }
.selectbusca.open .sb-display { border-color: var(--cor-primaria); box-shadow: 0 0 0 3px var(--cor-primaria-sombra); }
.selectbusca .sb-label.placeholder { color: var(--texto-fraco); }
.selectbusca .sb-display i { color: var(--texto-fraco); font-size: 14px; flex-shrink: 0; }

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

.selectbusca.open .sb-panel { display: block; }

.selectbusca .sb-search {
  width: 100%;
  height: 36px;
  padding: 0 12px;
  background: var(--fundo);
  border: none;
  border-bottom: 1px solid var(--borda);
  color: var(--texto);
  font-size: 13.5px;
  outline: none;
}

.selectbusca .sb-opt { padding: 9px 12px; cursor: pointer; font-size: 13.5px; }
.selectbusca .sb-opt:hover { background: var(--cor-primaria-suave); color: var(--cor-primaria-escura); }
.selectbusca .sb-opt.selecionado { font-weight: 600; color: var(--cor-primaria-escura); }
.selectbusca .sb-opt-vazio { padding: 12px; font-size: 13px; color: var(--texto-fraco); text-align: center; }
/* Wrapper opcional das opcoes (o selectbusca.js pega .sb-opt profundo
   dentro do .sb-panel, entao o wrapper e so agrupamento estrutural). */
.selectbusca .sb-opts { display: contents; }

/* Dentro de <dialog class="popup-centrado">: marca do caso, pra quem inspeciona
 * a tela saber por que o painel esta flutuante. Regra: Padrao_Modal_Popup_Centrado. */
.selectbusca .sb-panel.sb-in-dialog { position: absolute; }

/* Painel ancorado na JANELA, nao no fluxo. Entra quando algum ancestral clipa
 * (`overflow` diferente de `visible`), caso em que o `position: absolute` seria
 * cortado na borda do ancestral e as ultimas opcoes ficariam inalcancaveis.
 * O JS (selectbusca.js) calcula top/left/width e decide abrir pra baixo ou pra
 * cima; aqui fica so o que e estrutural. Achado da conferencia visual de
 * 2026-08-04, medido com elementFromPoint. */
.selectbusca .sb-panel.sb-flutuante,
.selectbusca .sb-panel.sb-in-dialog.sb-flutuante {
  position: fixed;
  top: auto; left: auto; right: auto;
  margin-top: 0;
  z-index: 400;   /* acima do .modal-bg (200) e do backdrop do dialog */
}

/* ---------- Modal (.modal-bg / .modal-caixa) ----------
 * Regra: Padrao_Modal + Padrao_Modal_Nao_Fecha_Sozinho (ESC e backdrop NAO
 * fecham; fechar e so pelo X e pelo Cancelar). Tamanho sempre vw/vh. */

.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;
}

.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; }

@media (max-width: 1280px) {
  .modal-caixa.modal-md { width: 68vw; }
}

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

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

.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: var(--sp-3); }

.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; }
@media (max-width: 880px) { .modal-caixa.modal-confirm { width: 96vw; max-height: 92vh; } }

.confirm-corpo { padding: 32px 28px 12px !important; }
.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); }
.confirm-icone.confirm-info   { background: var(--azul-info-suave); color: var(--azul-info); }
.modal-confirm .modal-rodape { justify-content: center; }
.btn-perigo { background: var(--vermelho); border-color: var(--vermelho); color: #fff; font-weight: 600; }
.btn-perigo:hover { background: #B91C1C; border-color: #B91C1C; color: #fff; }

/* Variante <dialog> HTML5, obrigatoria quando o modal contem SelectBusca.
 * Regra: Padrao_Modal_Popup_Centrado. */
/* Centralizacao por `inset: 0` + `margin: auto`, NAO por
 * `top/left: 50%` + `transform: translate(-50%,-50%)`.
 * Motivo (conferencia visual 2026-08-04): `transform` num ancestral cria um
 * containing block novo, e `position: fixed` de qualquer descendente passa a
 * ser relativo ao dialog em vez da janela. Era o que empurrava o dropdown do
 * SelectBusca 217px pra baixo do lugar calculado, jogando as ultimas opcoes
 * pra fora da tela. Sem transform, `fixed` volta a valer contra a viewport. */
dialog.popup-centrado {
  position: fixed;
  inset: 0;
  margin: auto;
  border: 0;
  border-radius: var(--raio-lg);
  padding: 0;
  width: 55vw;
  max-height: 82vh;
  box-shadow: var(--sombra-lg);
  overflow: visible !important;
}

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

dialog.popup-centrado::backdrop { background: rgba(15, 23, 42, .55); }
dialog.popup-centrado .modal-corpo { max-height: 55vh; overflow-y: auto; }

/* Aviso de validacao dentro do modal, nao fecha e nao envia. Regra:
 * Padrao_Modal_Nao_Fecha_Sozinho, "validacao e o dado digitado". */
.modal-aviso {
  background: var(--vermelho-suave);
  border: 1px solid var(--vermelho);
  border-radius: var(--raio-sm);
  padding: 12px 14px;
  font-size: 13px;
  color: #7F1D1D;
}

.modal-aviso ul { margin: 6px 0 0 18px; list-style: disc; padding: 0; }
.modal-aviso li { margin-bottom: 2px; }

.campo-invalido .input,
.campo-invalido .sb-display { border-color: var(--vermelho) !important; }

/* ---------- Toggle on/off (.cv-sw) ----------
 * Regra: Padrao_Toggle_OnOff. 42x24, pista verde #16a34a quando ligado,
 * persiste no onchange, sem botao salvar. */

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

.cv-sw label {
  position: absolute;
  inset: 0;
  background: var(--borda);
  border-radius: 999px;
  cursor: pointer;
  transition: .15s;
}

.cv-sw label::after {
  content: '';
  position: absolute;
  top: 2px; left: 2px;
  width: 20px; height: 20px;
  background: white;
  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); }
.cv-sw input:focus-visible + label { outline: 2px solid var(--cor-primaria); outline-offset: 2px; }

/* ---------- Toggle tipo 2: duas opcoes (escolha de valor) ----------
 * Regra: Padrao_Toggle_Tipos, "Tipo 2". Colado, solido na cor da marca no
 * selecionado, texto branco. Usado aqui para tipo do usuario (staff|operador),
 * decisao PASSO 0 (estilo 2 para escolha entre duas opcoes). */

.seg2 {
  display: inline-flex;
  align-items: stretch;
  height: 40px;
  border: 1px solid var(--borda);
  border-radius: var(--raio-sm);
  overflow: hidden;
  box-sizing: border-box;
  background: var(--branco);
}

.seg2 button {
  border: none;
  background: var(--branco);
  padding: 0 14px;
  font-size: 13px;
  font-weight: 700;
  color: var(--texto-secundario);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.seg2 button + button { border-left: 1px solid var(--borda); }
.seg2 button.on { background: var(--cor-primaria); color: #fff; }

/* ---------- Loading inline ----------
 * Regra: Padrao_Loading_Estado + Sempre_Mostrar_Loading. Nunca so no botao,
 * spinner sempre com texto descritivo especifico. */

.loading-inline {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4);
  font-size: var(--fs-sm);
  color: var(--texto-suave);
}

.loading-inline .spinner {
  width: 18px; height: 18px;
  border: 3px solid var(--borda);
  border-top-color: var(--cor-primaria);
  border-radius: 50%;
  animation: girar .7s linear infinite;
  flex-shrink: 0;
}

/* Variante canonica da nota Padrao_Loading_Estado (spinner-circle + loading-text),
   usada em fluxos novos (fase 6+). Mantem `.spinner` acima como alias historico
   pra nao quebrar telas antigas. */
.loading-inline .spinner-circle {
  width: 18px; height: 18px;
  border: 3px solid var(--borda);
  border-top-color: var(--cor-primaria);
  border-radius: 50%;
  animation: girar .7s linear infinite;
  flex-shrink: 0;
}
.loading-inline .loading-text {
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--texto);
}
/* -sm: compact, cabe dentro de modal-corpo */
.loading-inline.loading-inline-sm { padding: 8px 4px; }
.loading-inline.loading-inline-sm .spinner-circle { width: 16px; height: 16px; border-width: 2px; }
.loading-inline.loading-inline-sm .loading-text { font-size: 12.5px; }

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

/* ---------- Cracha do convite (tela publica de aceite) ---------- */

.cracha {
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: var(--fundo);
  border: 1px solid var(--borda);
  border-radius: var(--raio);
  padding: var(--sp-4);
  font-size: 13px;
}

.cracha-linha { display: flex; align-items: center; gap: 8px; color: var(--texto-secundario); }
.cracha-linha strong { color: var(--texto); }

/* ---------- Cards de convite aberto ----------
 * Regra: Padrao_Convite_de_Acesso, "Em card proprio, nao como linha da
 * tabela de usuarios". */

.convite-cd {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  background: var(--branco);
  border: 1px solid var(--borda);
  border-radius: var(--raio);
  padding: var(--sp-3) var(--sp-4);
}

.convite-cd .info { display: flex; flex-direction: column; gap: 2px; }
.convite-cd .titulo { font-weight: 600; font-size: 13.5px; }
.convite-cd .meta { font-size: 12px; color: var(--texto-fraco); }
.convite-cd .acoes { display: flex; gap: 6px; flex-shrink: 0; }

/* ---------- Matriz de permissoes ----------
 * Grade de checkbox, NAO e tabela de listagem: Padrao_Tabela declara essa
 * exclusao explicitamente ("Quando a tabela NAO recebe o componente"). */

.matriz-grupo { margin-bottom: var(--sp-4); }

.matriz-grupo-cab {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  padding: 10px 14px;
  background: var(--fundo);
  border-radius: var(--raio-sm) var(--raio-sm) 0 0;
  flex-wrap: wrap;
}

.matriz-grupo-cab .nome { font-weight: 700; font-size: 13px; }

.matriz-grupo-acoes { display: flex; gap: 6px; flex-wrap: wrap; }
.matriz-grupo-acoes button {
  font-size: 11.5px;
  font-weight: 600;
  padding: 4px 9px;
  border-radius: var(--raio-sm);
  border: 1px solid var(--borda);
  background: var(--branco);
  color: var(--texto-secundario);
  cursor: pointer;
}
.matriz-grupo-acoes button:hover { border-color: var(--cor-primaria); color: var(--cor-primaria); }

.matriz-tabela { width: 100%; border-collapse: collapse; border: 1px solid var(--borda); border-top: none; }
.matriz-tabela td { padding: 9px 14px; border-bottom: 1px solid var(--borda); font-size: 13px; }
.matriz-tabela tr:last-child td { border-bottom: none; }
.matriz-tabela td.mod-nome { width: 60%; }
.matriz-tabela td.mod-check { text-align: center; width: 20%; }
.matriz-tabela input[type="checkbox"] { width: 17px; height: 17px; cursor: pointer; accent-color: var(--cor-primaria); }
.matriz-blindado { opacity: .7; }
.matriz-blindado input[type="checkbox"] { cursor: not-allowed; }

/* ---------- Meta discreta (Padrao_Formulario: fonte menor, cor secundaria) --- */

.cd-meta {
  font-size: 12px;
  color: var(--texto-fraco);
  font-weight: 500;
}

/* ---------- Grade de modulos por cliente (dialog de contratacao) ------------ */
/* Um item por modulo vendavel, com toggle on/off individual (cv-sw). */

.modulos-grade {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 8px;
}

.modulo-linha {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 14px;
  border: 1px solid var(--borda);
  border-radius: var(--raio-sm);
  background: var(--branco);
}

.modulo-info {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.modulo-info .icon { color: var(--texto-secundario); font-size: 18px; }

.modulo-nome {
  font-weight: 600;
  font-size: 13.5px;
  color: var(--texto);
}

/* ---------- Campo com controle inline (label a esquerda, controle a direita) - */

.campo-inline {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 10px 12px;
  border: 1px solid var(--borda);
  border-radius: var(--raio-sm);
  background: var(--fundo);
}

/* ---------- Lista com checkbox e busca (multi-selecao em modal) ------------ */

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

.lista-multi-busca {
  width: 100%;
  border: none;
  border-bottom: 1px solid var(--borda);
  border-radius: 0;
}

.lista-multi-busca:focus {
  outline: none;
  border-bottom-color: var(--cor-primaria);
}

.lista-multi-itens {
  max-height: 240px;
  overflow-y: auto;
}

.lista-multi-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  cursor: pointer;
  font-size: 13.5px;
  border-bottom: 1px solid var(--borda);
}

.lista-multi-item:last-child { border-bottom: none; }
.lista-multi-item:hover { background: var(--fundo); }

.lista-multi-item input[type="checkbox"] {
  width: 15px;
  height: 15px;
  cursor: pointer;
  accent-color: var(--cor-primaria);
  flex-shrink: 0;
}

/* ---------------------------------------------------------------- FASE 5
 * Cadastros base (clientes do salao, profissionais, servicos).
 * Grades de 2 e 3 colunas dentro do modal-corpo, pra alinhar campos irmaos
 * (telefone/e-mail, apelido/comissao, duracao/preco/comissao). Padrao_Formulario
 * pede label acima e altura de 40px nos controles, ja garantido pela regra
 * global `.modal-corpo .campo .input`. Aqui a grade so distribui os campos.
 */
.grade-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-4);
}

.grade-3 {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: var(--sp-4);
}

@media (max-width: 720px) {
  .grade-2,
  .grade-3 { grid-template-columns: 1fr; }
}

/* Coluna numerica: alinhamento a direita no cabecalho e no dado, com
 * font-variant-numeric: tabular-nums pra digitos com a mesma largura
 * (Padrao_KPI_Dashboard usa a mesma regra pra o valor grande; a
 * consistencia entre tabela e KPI e o proprio ponto). */
.tabela-listagem th.num,
.tabela-listagem td.num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ---------------------------------------------------------------- Barra de filtros
 * Regra: Padrao_Barra_de_Filtros. Aparece em tela que FILTRA listagem
 * (busca no topo, seletor de status, periodo). Diferente da .ra-bar do
 * Padrao_Formulario, que e pra ENTRAR dado num form. Altura unica de 38px,
 * label 11px uppercase pequeno.
 *
 * Prefixo `.fu-` (filter) canonico, mesmo usado no dataevo. O botao de
 * ancora "Filtrar" fica na direita via align-self: flex-end.
 */
.fu-bar {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  align-items: flex-end;
  margin-bottom: 16px;
  --fu-h: 38px;
}

.fu-bar .g {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

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

.fu-bar .input,
.fu-bar .btn,
.fu-bar .seg2,
.fu-bar .seg2 button,
.fu-bar .selectbusca .sb-display {
  height: var(--fu-h);
  box-sizing: border-box;
}
.fu-bar .input,
.fu-bar .btn {
  padding: 0 12px;
  border-radius: var(--raio-sm);
  font-size: 13px;
  display: inline-flex;
  align-items: center;
}
/* seg2 dentro de barra de filtros usa a mesma altura da barra (38px),
   nao a altura padrao standalone (40px). Achado do agente de conformidade
   2026-08-04: sem esse override, .seg2 e .selectbusca ficam 2px mais altos
   que Data e Filtrar, quebrando Padrao_Barra_de_Filtros regra 1. */
.fu-bar .seg2 button { height: calc(var(--fu-h) - 8px); }

/* Presets de periodo (Padrao_Barra_de_Filtros, seg "Chips ou select").
   Lista fixa fechada, 6 chips na ordem Mes atual, Mes passado, Hoje,
   Ult. 7 dias, Ult. 30 dias, Periodo customizado. Tipo 1 do
   Padrao_Toggle_Tipos: borda + fundo suave no ativo. */
.fu-presets {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  flex-wrap: nowrap;
  height: var(--fu-h);
  padding: 3px;
  border: 1px solid var(--borda);
  border-radius: var(--raio-sm);
  background: var(--branco);
}
.fu-presets button {
  height: calc(var(--fu-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;
}
.fu-presets button:hover { color: var(--cor-primaria); }
.fu-presets button.on {
  border-color: var(--cor-primaria);
  background: var(--cor-primaria-suave);
  color: var(--cor-primaria-escura);
}

/* Bloco De/Ate customizado, so aparece quando preset=customizado.
   Precisa do `.fu-bar` na frente: `.fu-bar .g { display: flex }` tem
   especificidade (0,2,0) e venceria um `.fu-custom` solto (0,1,0), deixando os
   campos visiveis sempre. Pego pela conferencia visual de 2026-08-04: o HTML
   estava certo e o grep passava, mas a tela mostrava De/Ate no preset errado. */
.fu-bar .fu-custom { display: none; gap: 8px; align-items: flex-end; }
.fu-bar .fu-custom.on { display: inline-flex; }

/* ---------------------------------------------------------------- Estado vazio "tela inteira" (.vz sem card)
 * Regra: Padrao_Estado_Vazio, secao "O bloco". Quando a tabela E o
 * conteudo inteiro da tela, o `.tabela-wrap` inteiro some e entra o `.vz`
 * (sem card, sem borda, centrado em X e Y na area sobrando). Diferente do
 * `.vz-inline` (secao dentro de card).
 *
 * O flex:1 herdado do pai .conteudo garante que sobre altura pra centrar.
 * min-height: 300px cobre o caso em que o pai ainda nao definiu altura.
 */
.vz {
  flex: 1;
  min-height: 300px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 32px 20px;
}
.vz .vz-icone { font-size: 40px; color: var(--texto-fraco); line-height: 1; margin-bottom: 16px; }
.vz .vz-titulo {
  margin: 0; font-family: var(--fonte-titulo, var(--font-titulo, inherit));
  font-size: 17px; font-weight: 700; letter-spacing: -.02em; color: var(--texto);
}
.vz .vz-sub { margin: 7px 0 0; font-size: 13.5px; color: var(--texto-suave); line-height: 1.5; max-width: 400px; }
/* Padrao_Estado_Vazio, secao "gate": estado vazio bloqueando a tela por
   pre-requisito ganha botao/link pra suprir o pre-requisito. */
.vz .vz-acao { margin-top: 18px; }

/* ---------------------------------------------------------------- Upload de arquivo
 * Regra: Padrao_Upload_Arquivo. CSS canonico, prefixo im- (import).
 * O input file fica off-screen pra clique+drop caberem no mesmo <label>.
 * Estado carregado tem borda solida + fundo verde suave, o inicial tem
 * borda tracejada cinza.
 */
.im-card {
  background: var(--branco);
  border: 1px solid var(--borda);
  border-radius: var(--raio);
  padding: 18px;
  margin-bottom: 16px;
}
.im-card h3 {
  margin: 0 0 14px;
  font-size: 14px;
  font-weight: 800;
  display: flex;
  align-items: center;
  gap: 8px;
  justify-content: space-between;
}

.im-explica {
  color: var(--texto-suave);
  font-size: 13px;
  line-height: 1.5;
  margin: 0 0 14px;
}

.im-lbl {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--texto-secundario);
  display: block;
  margin-bottom: 8px;
}

.im-drop {
  display: block;
  border: 2px dashed var(--borda);
  border-radius: 10px;
  padding: 32px;
  text-align: center;
  color: var(--texto-secundario);
  cursor: pointer;
  transition: .15s;
  user-select: none;
  margin-top: 8px;
}
.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-escuro);
}
.im-drop i {
  font-size: 36px;
  display: block;
  margin-bottom: 6px;
}

.im-arq {
  display: block;
  margin-top: 6px;
  font-weight: 600;
  color: var(--verde-escuro);
}

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

.im-acao {
  display: flex;
  gap: 10px;
  align-items: center;
  flex-wrap: wrap;
  justify-content: flex-end;
  margin-top: 14px;
}
.im-acao .im-msg {
  margin-right: auto;
  font-size: 12.5px;
  color: var(--texto-secundario);
}
.im-acao .im-msg.ok   { color: var(--verde-escuro); font-weight: 600; }
.im-acao .im-msg.erro { color: var(--vermelho);     font-weight: 600; }

#imBtn:disabled { opacity: .45; cursor: not-allowed; }

.im-res-titulo {
  margin: 18px 0 8px;
  font-size: 13px;
  font-weight: 700;
  color: var(--texto);
}

/* ================================================================
   FASE 6 - AGENDA
   Regem: Padrao_Modal + Popup_Centrado + Nao_Fecha_Sozinho,
   Padrao_Toggle_Tipos (seg2), Padrao_Formulario (altura 40px),
   Sistema_de_Estilos (cores por token).
   ================================================================ */

/* Input numero alinhado a direita (Convencoes de tabela) */
input.input.num { text-align: right; font-variant-numeric: tabular-nums; }

/* Subtexto de opcao no SelectBusca (telefone do cliente, duracao do
   servico) - texto secundario dentro da opcao. */
.selectbusca .sb-opt-sub {
  color: var(--texto-fraco);
  font-size: 12px;
  margin-left: 6px;
}

/* Grade da agenda: cabecalho fixo + corpo com scroll vertical.
   Colunas fixas 130px pra .ag-col-horas (horarios) e o resto flex 1. */
.ag-grade {
  background: var(--branco);
  border: 1px solid var(--borda);
  border-radius: var(--raio);
  overflow: hidden;
  margin-top: 14px;
}
.ag-cabecalho {
  display: grid;
  grid-template-columns: 80px repeat(auto-fit, minmax(140px, 1fr));
  border-bottom: 1px solid var(--borda);
  background: var(--cor-primaria-suave);
}
.ag-cel-h {
  padding: 12px 10px;
  font-size: 13px;
  font-weight: 700;
  color: var(--cor-primaria-escura);
  text-align: center;
  border-left: 1px solid var(--borda);
}
.ag-cel-h:first-child { border-left: 0; }
.ag-cel-h-data {
  display: block;
  font-size: 11px;
  font-weight: 500;
  color: var(--texto-secundario);
  margin-top: 2px;
}
.ag-corpo {
  display: grid;
  grid-template-columns: 80px repeat(auto-fit, minmax(140px, 1fr));
  max-height: 70vh;
  overflow-y: auto;
}
.ag-col {
  position: relative;
  border-left: 1px solid var(--borda);
}
.ag-col:first-child { border-left: 0; }
.ag-col-horas { background: var(--fundo); }
.ag-slot {
  height: 42px;
  border-bottom: 1px dashed var(--borda);
  box-sizing: border-box;
}
.ag-slot.ag-hora {
  font-size: 11px;
  color: var(--texto-fraco);
  padding: 4px 8px;
  border-bottom: 1px solid var(--borda);
  text-align: right;
}
.ag-col-drop .ag-slot { cursor: pointer; transition: background-color .12s; }
.ag-col-drop .ag-slot:hover { background: var(--cor-primaria-suave); }

/* Cards de agendamento: posicionados absoluto dentro da coluna,
   top/height calculados no JS. Cor da borda por status. */
.ag-card {
  position: absolute;
  left: 4px;
  right: 4px;
  padding: 4px 6px;
  background: var(--branco);
  border: 1px solid var(--borda);
  border-left: 3px solid var(--cor-primaria);
  border-radius: 4px;
  font: inherit;
  text-align: left;
  cursor: pointer;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  gap: 1px;
  z-index: 1;
  box-shadow: 0 1px 2px rgba(15, 23, 42, .05);
}
.ag-card:hover {
  box-shadow: 0 3px 8px rgba(15, 23, 42, .12);
  transform: translateY(-1px);
  z-index: 2;
}
.ag-card-hora   { font-size: 11px; font-weight: 700; color: var(--texto-secundario); }
.ag-card-cliente{ font-size: 12.5px; font-weight: 600; color: var(--texto); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ag-card-servico{ font-size: 11.5px; color: var(--texto-secundario); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.ag-card.status-agendado   { border-left-color: var(--cor-primaria); background: var(--branco); }
.ag-card.status-confirmado { border-left-color: var(--azul-info); background: var(--azul-info-suave); }
.ag-card.status-atendido   { border-left-color: var(--verde); background: var(--verde-suave); }
.ag-card.status-faltou     { border-left-color: var(--ambar); background: var(--ambar-suave); }
.ag-card.status-cancelado  {
  border-left-color: var(--vermelho);
  background: var(--vermelho-suave);
  opacity: .55;
}

/* Modal de detalhe: chaves da bateria de campos + toggle de status */
.det-linha {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 14px;
  padding: 8px 0;
  border-bottom: 1px solid var(--borda);
}
.det-linha:last-child { border-bottom: 0; }
.det-lbl {
  font-size: 12px;
  font-weight: 600;
  color: var(--texto-fraco);
  text-transform: uppercase;
  letter-spacing: .04em;
}
.det-val {
  font-size: 13.5px;
  color: var(--texto);
  text-align: right;
  flex: 1;
}

/* Seletor de status no modal de detalhe: multi opcoes (tipo 1) da
   taxonomia oficial de Padrao_Toggle_Tipos - "escolha entre valores
   usa a cor da marca, borda + fundo suave + texto escuro". A cor
   semantica de cada status (verde=atendido, ambar=faltou, etc) vive
   NO CARD da grade (.ag-card.status-*), nao aqui: o toggle de status
   e escolha, o card e display do resultado. */
.seg-status {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 8px 0 0;
}
.seg-status .ss-op {
  flex: 1 1 calc(50% - 4px);
  min-width: 0;
  height: 38px;
  border: 1px solid var(--borda);
  background: var(--branco);
  border-radius: 6px;
  padding: 0 10px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--texto-secundario);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}
.seg-status .ss-op:hover { color: var(--cor-primaria); }
.seg-status .ss-op:disabled { opacity: .35; cursor: not-allowed; }
.seg-status .ss-op.on {
  border-color: var(--cor-primaria);
  background: var(--cor-primaria-suave);
  color: var(--cor-primaria-escura);
}

/* ---------------------------------------------------------------- FASE 7 - COMANDA
 * Cabecalho de uma comanda especifica (tela detalhe.html). Cartao amplo com
 * duas colunas: metadados a esquerda (numero, cliente, timestamps) e valores
 * a direita (status, total, comissao, forma). Reusa .cd como container base.
 */
.cd-comanda-cab {
  display: flex;
  gap: 24px;
  padding: 18px 22px;
  margin-bottom: 16px;
  flex-wrap: wrap;
}
.cd-comanda-cab .cd-lado { flex: 1; min-width: 260px; }
.cd-comanda-cab .cd-lado-direito {
  display: flex; flex-direction: column; align-items: flex-end; gap: 6px;
}
.cd-comanda-cab .cd-titulo {
  font-family: var(--fonte-titulo);
  font-size: 22px; font-weight: 700;
  color: var(--texto);
  margin-bottom: 6px;
}
.cd-comanda-cab .cd-cliente {
  font-size: 14px; color: var(--texto);
  display: flex; align-items: center; gap: 6px;
  margin-bottom: 4px;
}
.cd-comanda-cab .cd-linha-info {
  font-size: 12.5px; color: var(--texto-fraco);
  display: flex; gap: 6px; flex-wrap: wrap;
}
.cd-comanda-cab .cd-status { margin-bottom: 8px; }
.cd-comanda-cab .cd-valores {
  display: grid; grid-template-columns: auto auto; gap: 3px 12px;
  align-items: center; justify-items: end;
}
.cd-total-label { font-size: 11.5px; color: var(--texto-fraco); text-transform: uppercase; letter-spacing: .04em; }
.cd-total-valor {
  font-family: var(--fonte-titulo);
  font-size: 22px; font-weight: 700;
  color: var(--cor-primaria-escura);
  font-variant-numeric: tabular-nums;
}
.cd-total-com, .cd-total-fp {
  font-size: 13px; color: var(--texto);
  font-variant-numeric: tabular-nums;
}
.cd-sub { color: var(--texto-fraco); font-size: 12.5px; }

/* Acoes secundarias abaixo da tabela de itens: cancelar/excluir a comanda
 * inteira. Botao "fantasma" com aviso vermelho por ser destrutivo. */
.cd-acoes-secundarias {
  margin-top: 20px;
  display: flex; gap: 10px; flex-wrap: wrap;
}
.btn-perigo-txt { color: var(--vermelho); border-color: var(--vermelho-suave); }
.btn-perigo-txt:hover { background: var(--vermelho-suave); }

/* Dica curta dentro de modal ou card (fonte menor, cor fraca). */
.dica { font-size: 12px; color: var(--texto-fraco); margin: 4px 0 0; line-height: 1.4; }

/* ============================================================================
 * FASE 8 - ESTOQUE
 * ============================================================================
 * .badge-alerta: badge amber pra "Estoque baixo". Padrao_Tabela nao tem cor
 * propria pra alerta em linha, so pra tipo (ok/aviso/info); reuso o token
 * ambar da vault via var(--ambar) pra manter identidade.
 * .fu-inline: texto pequeno inline ao lado do cv-sw dentro da .fu-bar (label
 * curta que nao merece um <label class="fu-lbl"> proprio).
 * .fraco: valor secundario numa celula ("-" quando produto nao tem minimo).
 * .col-linha: primeira coluna estreita na tabela de resultados da importacao.
 */
.badge-alerta { background: var(--ambar-suave); color: var(--ambar); }
.fu-inline { font-size: 12.5px; color: var(--texto); font-weight: 500; }
.fraco { color: var(--texto-fraco); }
.col-linha { width: 80px; }

/* Wrapper de cv-sw + label descritiva ao lado, dentro de .fu-bar (filtro).
 * Padrao_Toggle_OnOff exige o trio <span class="cv-sw"> + <input> + <label for>;
 * quando ha texto proprio descrevendo a acao, ele fica NUM label separado que
 * tambem casa com o input (redundante, mas ajuda quem clica com dedo grande). */
.fu-inline-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: var(--fu-h, 38px);
}
.fu-inline-toggle .fu-inline { cursor: pointer; user-select: none; }

/* Setas de entrada/saida no estoque (verde escuro / vermelho). Padrao_Upload_Arquivo
 * por analogia: cor sai de CLASSE, nunca de style.color inline no template. */
.icon-entrada { color: var(--verde-escuro); }
.icon-saida { color: var(--vermelho); }

/* Variante da .dica com espacamento superior maior (usada em rodape de modal
 * pra separar da linha de campos). Evita `style="margin-top:12px"` inline. */
.dica-espacada { margin-top: 12px; }

/* Esmaecimento programatico de um .campo quando outra escolha o torna
 * irrelevante (ex: escolher agendamento no dlgNovaComanda esmaece o campo
 * de cliente). Padrao_Upload_Arquivo por analogia: sem style.* inline no JS. */
.campo-esmaecido { opacity: .5; pointer-events: none; }

/* .cv-row + .off: linha de tabela com registro inativo. .cv-row e a classe
 * base do padrao Toggle_OnOff aplicada em <tr>; .off e o esmaecimento. */
.cv-row.off, tr.cv-row.off { opacity: .6; }

/* ============================================================================
 * FASE 9 - FINANCEIRO
 * ============================================================================
 * Padrao_KPI_Dashboard: grid 6 col (3 em <=1300px, 2 em <=720px), faixa 3px
 * topo, .lbl min-height 25px + align-items flex-end pra baseline igual entre
 * cards de labels de 1 e 2 linhas, .disc min-height 14px pra alinhar altura
 * mesmo sem legenda. Cores da nota (nao usa var(--) porque a nota crava hex
 * pra manter a mesma paleta em qualquer tema; sao as unicas cores hex fora
 * de tokens.css, e sao SEMANTICAS de tipo, nao decorativas).
 */
.mg-kpis {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 10px;
  margin-bottom: 18px;
}
@media (max-width: 1300px) { .mg-kpis { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 720px) { .mg-kpis { grid-template-columns: repeat(2, 1fr); gap: 8px; } }

.mg-kpi {
  background: white;
  border: 1px solid var(--borda);
  border-radius: 12px;
  padding: 14px;
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  gap: 12px;
}
.mg-kpi::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 3px;
  background: #cbd5e1;
}
.mg-kpi.ac-fat::before { background: linear-gradient(90deg, #22c55e, #16a34a); }
.mg-kpi.ac-traf::before { background: linear-gradient(90deg, #475569, #334155); }
.mg-kpi.ac-imp::before { background: linear-gradient(90deg, #94a3b8, #64748b); }
.mg-kpi.ac-fin::before { background: linear-gradient(90deg, #fbbf24, #a16207); }
.mg-kpi.pos::before { background: linear-gradient(90deg, #22c55e, #16a34a); }
.mg-kpi.neg::before { background: linear-gradient(90deg, #f87171, #dc2626); }

/* Variantes do dominio SALAO. A tabela de variantes da nota e do dashboard de
 * margem do DataEvo (faturamento, trafego pago, imposto, custo financeiro):
 * cada classe ali carrega um SIGNIFICADO. Reusar `ac-traf` (trafego pago) pra
 * "Despesa paga" seria mentir no codigo semantico, entao as tres que este
 * dominio precisa e a nota nao tem nascem aqui, com o mesmo desenho (faixa 3px
 * + ico pastel) e nome do que sao. Achado do agente de conformidade 2026-08-04. */
.mg-kpi.ac-desp::before { background: linear-gradient(90deg, #f87171, #dc2626); }
.mg-kpi.ac-aberto::before { background: linear-gradient(90deg, #94a3b8, #64748b); }
.mg-kpi.ac-ticket::before { background: linear-gradient(90deg, #60a5fa, #2563eb); }
.mg-kpi.ac-com::before { background: linear-gradient(90deg, #d4a418, #8f6a08); }

.mg-kpi .ico {
  width: 44px;
  height: 44px;
  border-radius: 11px;
  display: grid;
  place-items: center;
  font-size: 22px;
  flex-shrink: 0;
  align-self: center;
}
.mg-kpi.ac-fat .ico { background: #dcfce7; color: #16a34a; }
.mg-kpi.ac-traf .ico { background: #e2e8f0; color: #334155; }
.mg-kpi.ac-imp .ico { background: #f1f5f9; color: #64748b; }
.mg-kpi.ac-fin .ico { background: #fef3c7; color: #a16207; }
.mg-kpi.pos .ico { background: #bbf7d0; color: #15803d; }
.mg-kpi.neg .ico { background: #fecaca; color: #b91c1c; }
.mg-kpi.ac-desp .ico { background: #fee2e2; color: #b91c1c; }
.mg-kpi.ac-aberto .ico { background: #f1f5f9; color: #64748b; }
.mg-kpi.ac-ticket .ico { background: #dbeafe; color: #2563eb; }
.mg-kpi.ac-com .ico { background: #fdf5e1; color: #8f6a08; }

.mg-kpi .corpo {
  min-width: 0;
  flex: 1;
  display: flex;
  flex-direction: column;
}
.mg-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;
}
.mg-kpi .val {
  font-size: 20px;
  font-weight: 800;
  letter-spacing: -.5px;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  margin-top: 3px;
}
.mg-kpi .disc {
  font-size: 10.5px;
  color: var(--texto-fraco);
  margin-top: 4px;
  line-height: 1.2;
  font-style: italic;
  min-height: 14px;
}

.mg-kpi.pos { background: #f0fdf4; border-color: #bbf7d0; }
.mg-kpi.pos .lbl, .mg-kpi.pos .val { color: #15803d; }
.mg-kpi.neg { background: #fef2f2; border-color: #fecaca; }
.mg-kpi.neg .lbl, .mg-kpi.neg .val { color: #b91c1c; }

@media (max-width: 720px) {
  .mg-kpi { padding: 12px 11px; gap: 9px; }
  .mg-kpi .ico { width: 36px; height: 36px; font-size: 18px; border-radius: 9px; }
  .mg-kpi .lbl { font-size: 9.5px; min-height: 23px; }
  .mg-kpi .val { font-size: 18px; }
  .mg-kpi .disc { font-size: 10px; min-height: 13px; }
}

/* Link "abrir comanda" ao lado da descricao do lancamento */
.ln-ext { color: var(--texto-fraco); margin-left: 4px; }
.ln-ext:hover { color: var(--cor-primaria); }

/* Lista de bullets curta dentro de card explicativo */
.lista-explica {
  margin: 8px 0 0;
  padding-left: 18px;
  color: var(--texto);
  line-height: 1.55;
}
.lista-explica li { margin-bottom: 4px; }
.lista-explica strong { font-weight: 700; }
.lista-explica em { color: var(--texto-fraco); font-style: normal; }




/* ===================================================================
   FASE 11: classes que substituem os `style="..."` que estavam nas telas.

   Sistema_de_Estilos:14, literal: "Nenhuma tela escreve CSS inline ou
   `<style>` proprio. Tudo via classe. Mudou cor, mudou em tokens.css. Mudou
   componente, mudou em components.css." A auditoria de fechamento achou 40
   declaracoes inline espalhadas por 14 telas, sendo que a matriz de
   conformidade afirmava, desde a fase 2, que a busca voltava vazia. Voltou a
   voltar.
   =================================================================== */

/* Form que existe so pra carregar o method/action e nao pode criar caixa
   propria no meio de um flex container (a linha de filtros). */
.form-transparente { display: contents; }

/* Form que precisa continuar na mesma linha do vizinho (acoes de uma celula). */
.form-inline { display: inline; }

/* Campo que ocupa a sobra da linha de filtros. */
.cresce { flex: 1; }

/* Campo estreito que ainda precisa de um piso legivel. */
.min-200 { min-width: 200px; }

/* Botao de acao no fim de uma linha de campos: alinha pela BASE, junto do
   controle, nao pelo centro da linha (Padrao_Formulario). */
.btn-fim-linha { align-self: flex-end; }

/* Bloco de acao ancorado a direita. */
.acao-fim { display: flex; justify-content: flex-end; }
.acao-fim-espacada { margin-top: var(--sp-2); }

/* Duas colunas de conteudo, uma de cada lado da mesma linha. */
.linha-entre {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
}

/* Pilha vertical curta (form de configuracao, lista de convites). */
.form-coluna { display: flex; flex-direction: column; gap: var(--sp-3); }
.coluna-compacta { display: flex; flex-direction: column; gap: 8px; }

/* Card de configuracao: largura de leitura, nao a largura da tela. */
.cd-estreito { max-width: 560px; }

/* Aviso que mora DENTRO do card, sem flutuar nem sombrear como o flash global. */
.flash-embutido { position: static; box-shadow: none; }

/* Espacamentos pontuais que estavam inline. */
.ra-bar-espacada { margin-bottom: var(--sp-4); }
.campo-espacado { margin-top: 14px; }
.bloco-espacado { margin-top: 10px; }
.p-espacado { margin-bottom: 12px; }
.cd-meta-vazio { padding: 10px; }

/* Rodape do grupo na matriz de permissoes: encosta no bloco de cima. */
.matriz-grupo-rodape { border-top: 1px solid var(--borda); border-radius: 0; }

/* Label do auto-liberar, dentro do rodape do grupo. */
.matriz-auto-lbl {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12.5px;
  font-weight: 500;
}

/* Variante do rodape de modal com acao secundaria a esquerda e primaria a
   direita (excecao consciente declarada na fase 6). */
.modal-rodape-entre { justify-content: space-between; }
