/* ==========================================================================
   Componentes de interface — GV Auditoria
   Mobile first. Alvos de toque nunca abaixo de --toque-min na operação.
   ========================================================================== */

/* --- botões --------------------------------------------------------------- */
/* Uma altura (`--controle-h`), um raio, um espaçamento de ícone para todas
   as variantes — botão e campo lado a lado numa barra ficam alinhados sem
   ajuste por página. Em tela de toque a altura sobe para 44px (alvo mínimo);
   a contagem de campo tem os próprios botões grandes (pages/contagem.css). */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--e-2);
  min-height: var(--controle-h);
  padding: 0 var(--e-4);
  border-radius: var(--raio);
  border: 1px solid transparent;
  font-size: var(--txt-sm);
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
  transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}
@media (pointer: coarse) { .btn { min-height: 44px; } }

.btn:disabled,
.btn[aria-disabled="true"] { opacity: .5; cursor: not-allowed; }
.btn:focus-visible { outline: none; box-shadow: var(--foco-anel); }
.btn svg { flex: 0 0 auto; }

/* Primário institucional: azul-marinho. Salvar/confirmar/aplicar. */
.btn--primario { background: var(--acao-primaria); color: var(--neutro-0); }
.btn--primario:hover:not(:disabled) { background: var(--acao-primaria-hover); }

/*
 * CTA (laranja da marca): "usar com parcimônia — é o acento, não o fundo".
 * UMA por tela: a ação principal do cabeçalho da página (Nova auditoria,
 * Nova loja, Importar…). Nunca confirmar/salvar dentro de modal — ali é
 * `--primario`. Assim só um botão laranja aparece por vez.
 */
.btn--destaque { background: var(--acao-cta); color: var(--neutro-0); }
.btn--destaque:hover:not(:disabled) { background: var(--acao-cta-hover); }

.btn--secundario {
  background: var(--surface);
  color: var(--texto);
  border-color: var(--linha-2);
}
.btn--secundario:hover:not(:disabled) { background: var(--surface-2); border-color: var(--neutro-500); }

/* Fantasma: ação terciária ("Limpar filtros", "Cancelar" ao lado de outra). */
.btn--fantasma { background: transparent; color: var(--azul-700); }
.btn--fantasma:hover:not(:disabled) { background: var(--azul-100); }

/* Destrutiva: vermelho semântico — NÃO o laranja da marca. */
.btn--perigo { background: var(--perigo); color: var(--neutro-0); }
.btn--perigo:hover:not(:disabled) { background: var(--perigo-hover); }

.btn--bloco { width: 100%; }
.btn--pequeno { min-height: var(--controle-h-sm); font-size: var(--txt-xs); padding: 0 var(--e-3); }
@media (pointer: coarse) { .btn--pequeno { min-height: 40px; } }

/* --- menu ancorado (components/ui/menuBotao.js) ---------------------------- */
.menu-botao { position: relative; display: inline-block; }

/* Remove o marcador/triângulo nativo de `<summary>` nos navegadores que o
   desenham por padrão — a seta própria (`.menu-botao__seta`) substitui. */
.menu-botao__gatilho { cursor: pointer; list-style: none; }
.menu-botao__gatilho::-webkit-details-marker { display: none; }

.menu-botao__seta {
  width: 8px;
  height: 8px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg) translateY(-2px);
  transition: transform .15s ease;
  flex: 0 0 auto;
}
.menu-botao[open] .menu-botao__seta { transform: rotate(-135deg) translateY(2px); }

.menu-botao__lista {
  /* `position`/`top`/`left` de verdade são inline, calculados em `menuBotao.js`
     a partir do botão no momento em que o menu abre (`fixed`, não `absolute`
     — precisa escapar de ancestrais com `overflow: hidden`, como
     `.dashboard-pagina`). O que segue aqui é só o fallback antes do JS
     rodar, pra nunca haver um frame com a lista sem posição nenhuma. */
  position: fixed;
  top: 0;
  left: 0;
  /* Não `--z-dropdown` (100): esse token serve o `.sino-painel`, que fica
     `position: absolute` DENTRO de `.shell__topo` e por isso já herda o
     `z-index: var(--z-header)` (200) do pai. Esta lista é `fixed` no root —
     compete direto com `.shell__nav`, que também é 200 (achado real: a
     barra lateral cobria a metade esquerda do menu "Exportar" aberto).
     `--z-drawer` (300) é a primeira camada acima de header/nav. */
  z-index: var(--z-drawer);
  min-width: 12rem;
  margin: 0;
  padding: var(--e-2);
  list-style: none;
  background: var(--surface);
  border: 1px solid var(--linha-2);
  border-radius: var(--raio);
  box-shadow: var(--sombra-lg);
}

/* --- botão de ajuda ("?") (components/ui/Ajuda.js) -------------------------
   Mesma base de `.menu-botao` (details/summary nativo) E mesma técnica de
   posicionamento: `.ajuda__painel` nasce `position: fixed`, calculada em JS
   a partir do botão (Ajuda.js#posicionar) — precisa escapar do
   `overflow: hidden` dos cards da Central (o que mantém o cockpit sem
   rolagem, ver central-cockpit.css), senão o painel fica CORTADO mesmo com
   a posição certa (achado real: o balão de "Onde agir" sumia na borda do
   card). Um `position: absolute` comum não escapa de `overflow: hidden`
   ancestral; `fixed` mede a partir do viewport e ignora isso. */
.ajuda { display: inline-flex; margin-left: auto; }

.ajuda__botao {
  all: unset;
  box-sizing: border-box;
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 1.5px solid var(--linha-2);
  color: var(--texto-3);
  font: 700 0.6875rem/1 var(--fonte);
  display: grid;
  place-items: center;
  cursor: pointer;
  list-style: none;
}
.ajuda__botao::-webkit-details-marker { display: none; }
.ajuda__botao:hover { border-color: var(--azul-700); color: var(--azul-700); background: var(--azul-50); }
.ajuda__botao:focus-visible { outline: none; box-shadow: var(--foco-anel); }
.ajuda[open] .ajuda__botao { border-color: var(--azul-900); color: var(--neutro-0); background: var(--azul-900); }

/* Dentro de um KPI o botão fica junto do ícone+rótulo, menor que o padrão. */
.metrica__cabecalho .ajuda__botao { width: 16px; height: 16px; font-size: 0.625rem; }

.ajuda__painel {
  position: fixed;
  /* `top`/`left` de verdade são inline, calculados em Ajuda.js#posicionar a
     partir do botão no momento em que o balão abre — o que segue aqui é só
     o fallback antes do JS rodar, pra nunca haver um frame com o painel sem
     posição nenhuma (mesmo padrão de `.menu-botao__lista`). */
  top: 0;
  left: 0;
  /* Não `--z-dropdown` (100): a sidebar (`.shell__nav`) é `--z-header` (200)
     e um card da Central pode ficar logo ao lado dela — mesmo problema que
     `.menu-botao__lista` já documenta e resolve com `--z-drawer` (300), a
     primeira camada acima de header/nav. */
  z-index: var(--z-drawer);
  width: 17.5rem;
  max-width: calc(100vw - 2 * var(--e-4));
  background: var(--surface);
  border: 1px solid var(--linha-2);
  border-radius: var(--raio);
  box-shadow: var(--sombra-lg);
  padding: var(--e-3) var(--e-4);
  font-family: var(--fonte);
  color: var(--texto);
}
/* Seta apontando pro CENTRO do botão — `--ajuda-seta-x` é a distância do
   botão até a borda esquerda do painel, calculada junto da posição
   (Ajuda.js), porque o painel pode abrir tanto à esquerda quanto à direita
   do botão. Mesma técnica de balão que os gráficos usam (ver
   `.grafico-tooltip` em indicadores.css), só que com a posição variável em
   vez de fixa num canto. */
.ajuda__painel::before {
  content: "";
  position: absolute;
  top: -6px;
  left: var(--ajuda-seta-x, 12px);
  width: 12px;
  height: 12px;
  margin-left: -6px;
  background: var(--surface);
  border-left: 1px solid var(--linha-2);
  border-top: 1px solid var(--linha-2);
  transform: rotate(45deg);
}
/* Balão aberto ACIMA do botão (sem espaço embaixo, perto do fim da página)
   — a seta inverte pra baixo. */
.ajuda--cima .ajuda__painel::before {
  top: auto;
  bottom: -6px;
  border-left: none;
  border-top: none;
  border-right: 1px solid var(--linha-2);
  border-bottom: 1px solid var(--linha-2);
}
.ajuda__titulo { margin: 0 0 var(--e-2); font-size: var(--txt-sm); font-weight: 700; color: var(--azul-900); }
.ajuda__corpo { margin: 0; font-size: 0.8125rem; line-height: 1.55; color: var(--neutro-900); }
.ajuda__corpo + .ajuda__corpo { margin-top: var(--e-2); }
.ajuda__formula {
  margin: var(--e-2) 0 0;
  padding: var(--e-2) var(--e-3);
  background: var(--surface-2);
  border-radius: var(--raio-sm);
  font-family: var(--fonte-mono);
  font-size: 0.72rem;
  color: var(--texto);
}

@media (max-width: 420px) {
  .ajuda__painel { width: calc(100vw - 2 * var(--e-4)); }
}

.menu-botao__item {
  display: block;
  width: 100%;
  text-align: left;
  padding: var(--e-2) var(--e-3);
  border: none;
  background: transparent;
  border-radius: var(--raio-sm);
  font: inherit;
  font-size: var(--txt-sm);
  color: var(--texto);
  cursor: pointer;
}
.menu-botao__item:hover:not(:disabled) { background: var(--surface-2); }
.menu-botao__item:disabled { opacity: .55; cursor: not-allowed; }
.menu-botao__item:focus-visible { outline: 2px solid var(--azul-500); outline-offset: -2px; }

/* --- campos --------------------------------------------------------------- */
.campo-grupo { display: flex; flex-direction: column; gap: var(--e-2); }

.rotulo {
  font-size: var(--txt-sm);
  font-weight: 600;
  color: var(--neutro-900);
}

.campo {
  width: 100%;
  min-height: var(--controle-h);
  padding: 0 var(--e-3);
  border: 1px solid var(--linha-2);
  border-radius: var(--raio);
  background: var(--surface);
  color: var(--texto);
  font-size: var(--txt-sm);
  transition: border-color .15s ease, box-shadow .15s ease;
}
@media (pointer: coarse) { .campo { min-height: 44px; font-size: var(--txt-md); } }
textarea.campo { padding: var(--e-2) var(--e-3); line-height: 1.5; }
.campo::placeholder { color: var(--texto-3); opacity: 1; }
.campo:hover:not(:disabled):not(:focus) { border-color: var(--neutro-500); }

.campo:focus {
  outline: none;
  border-color: var(--foco);
  box-shadow: var(--foco-anel);
}

.campo:disabled { background: var(--surface-2); color: var(--texto-3); cursor: not-allowed; }
.campo[aria-invalid="true"] { border-color: var(--falta); }
.campo[aria-invalid="true"]:focus { box-shadow: 0 0 0 3px var(--falta-100); }

/* Senha: o botão de mostrar/ocultar fica sobre o campo, e o padding à direita
   reserva o espaço dele — assim o texto nunca passa por baixo do ícone e a
   altura do campo não muda ao alternar. */
.campo-senha { position: relative; display: flex; }
.campo-senha .campo--senha { padding-right: calc(var(--controle-h) + var(--e-1)); }

.campo-senha__olho {
  position: absolute;
  top: 0;
  right: 0;
  width: var(--controle-h);
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  border-radius: var(--raio);
  color: var(--texto-3);
  cursor: pointer;
}
.campo-senha__olho:hover { color: var(--texto-2); }
.campo-senha__olho:focus-visible { outline: 2px solid var(--azul-500); outline-offset: -2px; }

.campo-dica { font-size: var(--txt-xs); color: var(--texto-3); }
.campo-erro { font-size: var(--txt-xs); color: var(--falta); }

/* --- cartões e grades ----------------------------------------------------- */
.cartao {
  background: var(--surface);
  border: 1px solid var(--linha);
  border-radius: var(--raio-lg);
  padding: var(--e-5);
  /* Sem sombra por padrão: borda + branco sobre o fundo creme já define a
     superfície sem precisar de dois sinais de elevação empilhados. A sombra
     fica reservada a `.metricas--principal` — assim ela de fato sinaliza
     destaque, em vez de "todo cartão tem a mesma sombra". */
}

.cartao__titulo {
  font-size: var(--txt-md);
  font-weight: 600;
  letter-spacing: -0.005em;
  margin-bottom: var(--e-4);
  color: var(--azul-900);
}
/* Só vira flex quando tem botão de ajuda dentro (`secao({ ajuda })`) — os
   demais `.cartao__titulo` do sistema continuam texto simples. `.ajuda` aqui
   não usa `margin-left: auto` (isso empurraria o "?" pra ponta do cartão,
   não logo depois do texto do título). */
.cartao__titulo:has(.ajuda) { display: inline-flex; align-items: center; gap: var(--e-2); }
.cartao__titulo .ajuda { margin-left: 0; }

.cartao__nota { margin-top: var(--e-4); font-size: var(--txt-sm); }

/* Descrição logo abaixo do título do cartão: texto de apoio, não corpo —
   sem isto um parágrafo `.texto-suave` herdava os 16px do corpo e competia
   com o próprio título (achado em Não Conformidades). */
.cartao__titulo + p.texto-suave {
  margin: calc(var(--e-3) * -1) 0 var(--e-4);
  font-size: var(--txt-sm);
  color: var(--texto-3);
  max-width: 72ch;
}

/* Título + ação (ex.: "Suas metas" + botão "Definir meta" do gestor) no
   mesmo cartão — o `.cartao__titulo` some sua margem própria aqui porque o
   espaçamento passa a ser do cabeçalho como um todo. */
.cartao__cabecalho {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--e-3);
  margin-bottom: var(--e-4);
}
.cartao__cabecalho .cartao__titulo { margin-bottom: 0; }

.grade { display: grid; gap: var(--e-4); }
@media (min-width: 768px) { .grade { grid-template-columns: repeat(2, 1fr); } }

.texto-suave { color: var(--texto-3); }

.lista-simples {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--e-2);
}
.lista-numerada { counter-reset: item; }
.lista-numerada li { counter-increment: item; padding-left: var(--e-5); position: relative; }
.lista-numerada li::before {
  content: counter(item);
  position: absolute;
  left: 0;
  font-family: var(--fonte);
  font-variant-numeric: tabular-nums;
  font-size: var(--txt-sm);
  color: var(--azul-500);
  font-weight: 600;
}

/* --- estado vazio / erro -------------------------------------------------- */
.estado-vazio {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--e-3);
  padding: var(--e-6);
  text-align: center;
}
.estado-vazio__codigo {
  font-family: var(--fonte-mono);
  font-size: var(--txt-3xl);
  font-weight: 700;
  color: var(--linha-2);
}
.estado-vazio__titulo { font-size: var(--txt-xl); color: var(--azul-900); }
.estado-vazio__msg { color: var(--texto-3); max-width: 40ch; }
.estado-vazio .btn { margin-top: var(--e-3); }

/* Variante de `.estado-vazio` para dentro de um `.cartao` (dashboard, evolução
   de loja) — mesma linguagem visual, sem tomar a tela inteira. `.estado-vazio`
   continua reservado a página cheia (404, etc.). */
.estado-vazio-cartao {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--e-2);
  padding: var(--e-5) var(--e-3);
  text-align: center;
  color: var(--texto-3);
  font-size: var(--txt-sm);
}
.estado-vazio-cartao__icone { font-size: var(--txt-2xl); opacity: .5; }

/* --- skeleton (carregamento) ------------------------------------------------
   Único lugar do projeto que já animava um estado de espera era o selo de
   sincronismo da contagem (pages/contagem.css, `.sinc--enviando`) — mesma
   técnica aqui: gradiente deslizante atrás de `prefers-reduced-motion`, sem
   a media query vira só um bloco estático (fallback automático, não
   degradado). Reaproveitado pelo DataTable e pelo dashboard no primeiro
   carregamento, no lugar do texto "Carregando…". */
.skeleton {
  display: block;
  border-radius: var(--raio-sm);
  background: var(--linha);
}
@media (prefers-reduced-motion: no-preference) {
  .skeleton {
    background: linear-gradient(90deg, var(--linha) 25%, var(--surface-2) 50%, var(--linha) 75%);
    background-size: 200% 100%;
    animation: skeleton-desliza 1.4s ease-in-out infinite;
  }
}
@keyframes skeleton-desliza {
  from { background-position: 200% 0; }
  to   { background-position: -200% 0; }
}

/* --- notificações --------------------------------------------------------- */
.toasts {
  position: fixed;
  left: var(--e-3);
  right: var(--e-3);
  bottom: var(--e-3);
  z-index: var(--z-toast);
  display: flex;
  flex-direction: column;
  gap: var(--e-2);
  pointer-events: none;
}
@media (min-width: 640px) {
  .toasts { left: auto; width: min(28rem, calc(100vw - 2rem)); }
}

.toast {
  pointer-events: auto;
  display: flex;
  align-items: flex-start;
  gap: var(--e-3);
  padding: var(--e-3) var(--e-4);
  border-radius: var(--raio);
  border-left: 4px solid var(--info);
  background: var(--surface);
  box-shadow: var(--sombra-lg);
  animation: toast-entra .18s ease-out;
}

.toast--sucesso { border-left-color: var(--conforme); }
.toast--erro    { border-left-color: var(--falta); }
.toast--aviso   { border-left-color: var(--atencao); }
.toast--saindo  { animation: toast-sai .18s ease-in forwards; }

.toast__corpo { flex: 1; display: flex; flex-direction: column; gap: 2px; }
.toast__titulo { font-size: var(--txt-sm); }
.toast__msg { font-size: var(--txt-sm); color: var(--texto-2); }

.toast__acao {
  font-size: var(--txt-sm);
  font-weight: 600;
  color: var(--azul-500);
  padding: var(--e-1) var(--e-2);
}

/* Botão só com ícone: o alvo de clique não pode ser do tamanho do desenho. */
.toast__fechar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  min-width: var(--toque-min);
  min-height: var(--toque-min);
  color: var(--texto-3);
}
.toast__fechar:hover { color: var(--texto); }

@keyframes toast-entra {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}
@keyframes toast-sai {
  to { opacity: 0; transform: translateY(8px); }
}

/* --- indicador de conexão ------------------------------------------------- */
.conexao {
  display: inline-flex;
  align-items: center;
  gap: var(--e-2);
  font-size: var(--txt-xs);
  font-weight: 600;
  color: var(--neutro-0);
  background: rgba(255, 255, 255, .14);
  padding: var(--e-1) var(--e-3);
  border-radius: 999px;
}
.conexao__ponto {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--atencao);
}

/* --- abas (components/ui/Abas.js) ------------------------------------------
   Sublinhado, não pílula: aba troca PAINEL; pílula (`aria-pressed`) fica
   para filtro que recorta a mesma lista. */
.abas {
  display: flex;
  gap: var(--e-1);
  border-bottom: 1px solid var(--linha);
  overflow-x: auto;
  scrollbar-width: none;
}
.abas::-webkit-scrollbar { display: none; }
.abas__item {
  display: inline-flex;
  align-items: center;
  gap: var(--e-2);
  flex: 0 0 auto;
  min-height: var(--controle-h);
  padding: 0 var(--e-3);
  margin-bottom: -1px;
  border-bottom: 2px solid transparent;
  font-size: var(--txt-sm);
  font-weight: 600;
  color: var(--texto-2);
  white-space: nowrap;
  transition: color .15s ease, border-color .15s ease;
}
.abas__item:hover { color: var(--azul-900); }
.abas__item[aria-selected="true"] { color: var(--azul-900); border-bottom-color: var(--laranja); }
.abas__item:focus-visible { outline: none; box-shadow: var(--foco-anel); border-radius: var(--raio-sm); }
.abas__contador {
  min-width: 1.25rem;
  padding: 0 6px;
  border-radius: 999px;
  background: var(--surface-2);
  font-size: var(--txt-xs);
  line-height: 1.25rem;
  text-align: center;
}

/* --- estados de bloco (components/ui/Estados.js) --------------------------- */
.estado-bloco__titulo { color: var(--azul-900); font-size: var(--txt-sm); font-weight: 600; }
.estado-bloco__mensagem { max-width: 48ch; }
.estado-bloco .btn { margin-top: var(--e-2); }
.estado-bloco--erro .estado-vazio-cartao__icone { color: var(--falta); opacity: .8; }
.estado-bloco--carregando { display: flex; flex-direction: column; gap: var(--e-2); padding: var(--e-3) 0; }

/* --- ritmo vertical dentro de cartão ---------------------------------------
   Barra de ações logo após um formulário/zona de upload ganha respiro; o
   separador `<hr>` vira filete da paleta (não a linha cinza-escura padrão
   do navegador); o parágrafo de apoio depois dele é texto pequeno. */
.cartao > .formulario + .formulario__acoes,
.cartao > .formulario + .barra-acoes { margin-top: var(--e-4); }
.cartao > hr {
  margin: var(--e-5) 0 var(--e-4);
  border: 0;
  border-top: 1px solid var(--linha);
}
.cartao > hr + p.texto-suave { font-size: var(--txt-sm); margin-bottom: var(--e-3); }
