/* ================================================================
   estrutura.css — reaproveitável quase sem mudança entre projetos.
   Reset → tipografia → layout → componentes → responsivo.
   Nunca escreve uma cor "crua" — toda cor vem de var(--token),
   definido em paleta.css (carregado antes deste arquivo). O que muda
   de projeto pra projeto aqui é pouco: talvez a fonte (linha ~24) e o
   nome/domínio de alguma seção específica (ex.: "Agenda" abaixo é um
   EXEMPLO do padrão de calendário — ver PADROES_DESENVOLVIMENTO.md
   seção 20.3 — trocar pelo nome real da feature do projeto novo, a
   estrutura de classes serve igual).
   ================================================================ */

/* ── Tokens estruturais (não são cor) ── */
:root {
  --sidebar-width:   240px;
  --transition-fast: .15s ease;
}
/* Fonte, forma e espaçamento de rótulo vêm da IDENTIDADE (paleta.css, molde em biblioteca-pessoal/identidades/).
   Estes são só o valor de reserva pra paleta antiga que não os declara: :where() tem peso zero, então qualquer
   :root do paleta.css ganha, carregado antes ou depois. */
:where(:root) {
  --radius-card:   14px;
  --radius-btn:    8px;
  --shadow-card:   0 2px 12px var(--shadow-color);
  --fonte-texto:   system-ui, -apple-system, 'Segoe UI', sans-serif;
  --fonte-titulo:  var(--fonte-texto);
  --fonte-numero:  var(--fonte-texto);
  --titulo-peso:   700;
  --titulo-espaco: -.01em;
  --titulo-tamanho: calc(1.275rem + .3vw);
  --numero-peso:   700;
  --rotulo-espaco: .05em;
  --acento-2:      var(--accent);
  --icone-raio:    10px;
  --icone-fundo:   var(--accent-light);
  --icone-cor:     var(--accent);
  --fundo-pagina:  none;
}

/* ── Reset & base ── */
*, *::before, *::after { box-sizing: border-box; }

html { overflow-x: hidden; max-width: 100%; }

body {
  background-color: var(--bg-main);
  /* Brilho sutil da identidade no alto da página (ou nada, no Balcão). Rola junto: some depois da primeira tela. */
  background-image: var(--fundo-pagina);
  background-repeat: no-repeat;
  color: var(--text-main);
  font-family: var(--fonte-texto);
  min-height: 100vh;
  /* clip, não hidden: hidden no body (com o html também cortando) transforma o body numa caixa de rolagem que nunca
     rola — position:sticky (a barra de cima do celular) gruda nela em vez da tela. clip corta igual sem criar a caixa
     (MDN, overflow). O hidden fica de reserva pra navegador antigo. PADRÕES seção 10. */
  overflow-x: hidden;
  overflow-x: clip;
  max-width: 100%;
  -webkit-text-size-adjust: 100%;
  display: flex;
  flex-direction: column;
}

main { flex: 1; }

a { color: var(--accent); text-decoration: none; }
a:hover { color: var(--accent-hover); }

/* Evita zoom automático em inputs no iOS (≥16px) */
input, select, textarea { font-size: 16px !important; }
@media (min-width: 768px) {
  input, select, textarea { font-size: .9rem !important; }
}

button, a, [role="button"] { touch-action: manipulation; }

/* O .text-secondary do Bootstrap é um cinza-azulado fixo (108,117,125) que não lê a paleta — no meio do rosé/creme
   parecia texto de outro sistema. */
.text-secondary { color: var(--text-secondary) !important; }
.min-w-0 { min-width: 0; }   /* Bootstrap não tem (é do Tailwind) — PADRÕES 20.10 */

/* Título de página: um nível só em todo o sistema (PADRÕES 20.1). */
.titulo-pagina { color: var(--text-main); font-size: var(--titulo-tamanho); }

/* Fonte de título da identidade: tudo que é NOME de algo (título da tela, da janelinha, do quadro, da folha, a marca).
   O peso vem da identidade e passa por cima do fw-bold (700 fixo do Bootstrap): serifa a 700 pesa demais. */
.titulo-pagina, h1, h2, h3, .modal-title, .card-header, .sidebar-brand, .topo-marca span, .vs-folha h2 {
  font-family: var(--fonte-titulo);
  letter-spacing: var(--titulo-espaco);
}
.titulo-pagina, .modal-title, .sidebar-brand, .topo-marca span { font-weight: var(--titulo-peso) !important; }
/* Link e botão dentro do cabeçalho do quadro ("Ver todos") continuam na fonte de texto. */
.card-header a, .card-header .btn, .card-header small { font-family: var(--fonte-texto); letter-spacing: normal; }
.voltar-link { font-size: .85rem; color: var(--text-secondary); display: inline-flex; align-items: center; gap: .3rem; min-height: 32px; }
.voltar-link:hover { color: var(--accent); }

.text-accent   { color: var(--accent) !important; }
.bg-accent     { background: var(--accent) !important; }
.border-accent { border-color: var(--card-border-color) !important; }
.rounded-xl    { border-radius: var(--radius-card) !important; }
.shadow-card   { box-shadow: var(--shadow-card) !important; }

/* ── Topnav (portal do cliente) ──────────────────────────────── */
.topnav {
  background: var(--bg-card);
  border-bottom: 1px solid var(--card-border-color);
  box-shadow: 0 2px 12px var(--shadow-color);
  z-index: 1030;
}
.topnav .navbar-brand {
  font-weight: 700;
  color: var(--accent) !important;
  font-size: 1.15rem;
}
.topnav .dropdown-menu {
  border-color: var(--card-border-color);
  z-index: 9999;
}

/* ── Sidebar (painel admin) ──────────────────────────────────── */
.sidebar {
  position: fixed;
  top: 0; left: 0;
  width: var(--sidebar-width);
  height: 100vh;
  background: var(--bg-card);
  color: var(--text-secondary);
  border-right: 1px solid var(--card-border-color);
  display: flex;
  flex-direction: column;
  z-index: 1040;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
.sidebar-brand {
  padding: 1.5rem 1.25rem 1rem;
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: .03em;
  color: var(--text-main);
  border-bottom: 1px solid var(--card-border-color);
  display: flex;
  align-items: center;
  gap: .55rem;
}
.sidebar-brand small {
  display: block;
  color: var(--text-muted);
  font-size: .7rem;
  font-weight: 400;
  letter-spacing: .05em;
  text-transform: uppercase;
}
.sidebar-nav { list-style: none; padding: .75rem 0; margin: 0; flex: 1; }
.sidebar-nav li a {
  display: flex;
  align-items: center;
  gap: .65rem;
  padding: .65rem 1.25rem;
  color: var(--text-secondary);
  font-size: .92rem;
  transition: background var(--transition-fast), color var(--transition-fast);
  border-radius: 0 var(--radius-btn) var(--radius-btn) 0;
  margin-right: .75rem;
  min-height: 44px;
}
.sidebar-nav li a:hover,
.sidebar-nav li a.ativo {
  background: var(--accent-light);
  color: var(--accent);
}
.sidebar-nav li a i { font-size: 1.1rem; width: 1.3rem; flex-shrink: 0; }
.sidebar-hr { border: none; border-top: 1px solid var(--card-border-color); margin: .25rem 1.25rem; }
.sidebar-footer {
  padding: 1rem 1.25rem;
  border-top: 1px solid var(--card-border-color);
  font-size: .82rem;
  color: var(--text-muted);
}
.sidebar-footer a {
  color: var(--text-secondary);
  min-height: 44px;
  display: inline-flex;
  align-items: center;
}
.sidebar-footer a:hover { color: var(--accent); }
.nome-truncado {
  display: inline-block;
  max-width: 150px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: middle;
}

.sidebar-version {
  margin-top: .6rem;
  font-size: .68rem;
  color: var(--text-muted);
  letter-spacing: .02em;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: .3rem;
}

.sidebar-overlay { display: none; position: fixed; inset: 0; background: var(--overlay-bg); z-index: 1039; }
.sidebar-overlay.ativo { display: block; }
.sidebar-brand-link { display: flex; align-items: center; gap: .55rem; color: inherit; }
.sidebar-brand-link:hover { color: inherit; }
.marca-icone { font-size: 1.3rem; color: var(--acento-2); }

/* ── Tela de entrar ── */
.tela-login {
  min-height: calc(100vh - 3rem); display: flex; align-items: center; justify-content: center;
}
/* Um brilho rosé atrás do cartão (sutil): a primeira tela deixa de ser um retângulo solto no creme. */
body:has(.tela-login) {
  background:
    radial-gradient(60rem 30rem at 50% -10%, var(--accent-light), transparent 70%),
    var(--bg-main);
}
.cartao-login { width: 100%; max-width: 400px; box-shadow: 0 20px 50px -24px var(--shadow-color-forte), 0 2px 8px var(--shadow-color); }
.login-icone {
  width: 64px; height: 64px; border-radius: 20px; margin: 0 auto;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent-light); color: var(--acento-2); font-size: 2rem;
}
.login-marca-sub { font-size: .72rem; letter-spacing: .14em; text-transform: uppercase; color: var(--text-muted); }

/* Campo de senha com o olho de mostrar dentro (link de acesso): botão de 44px, alvo de dedo, sem empurrar o campo. */
.campo-senha { position: relative; }
.campo-senha .form-control { padding-right: 3.25rem; }
.btn-olho {
  position: absolute; top: 50%; right: .2rem; transform: translateY(-50%);
  width: 44px; height: 44px; border: 0; border-radius: var(--radius-btn);
  display: flex; align-items: center; justify-content: center;
  background: transparent; color: var(--text-muted); font-size: 1.15rem;
}
.btn-olho:hover, .btn-olho:focus-visible { color: var(--accent); background: var(--accent-light); }

/* ── Barra de cima do celular ──────────────────────────────────────
   Gruda no topo ao rolar (o menu fica sempre a um toque, sem voltar ao começo de uma lista comprida). Fundo creme
   meio transparente com desfoque: o conteúdo passa por baixo sem a barra virar um bloco chapado. */
.topo-celular {
  position: sticky; top: 0; z-index: 1020;
  display: flex; align-items: center; gap: .65rem;
  margin: -1rem -1rem 1rem; padding: .55rem 1rem;
  background: var(--bg-main);
  background: color-mix(in srgb, var(--bg-main) 88%, transparent);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--card-border-color);
}
.topo-menu {
  width: 44px; height: 44px; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--card-border-color); border-radius: 12px;
  background: var(--bg-card); color: var(--text-main); font-size: 1.35rem;
  box-shadow: 0 1px 2px var(--shadow-color);
}
.topo-menu:hover { border-color: var(--borda-forte); }
.topo-marca { display: flex; align-items: center; gap: .5rem; min-width: 0; color: var(--text-main); }
.topo-marca:hover { color: var(--text-main); }
.topo-marca i { color: var(--acento-2); font-size: 1.15rem; }
.topo-marca span { font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.topo-marca small { color: var(--text-muted); font-size: .7rem; letter-spacing: .06em; text-transform: uppercase; white-space: nowrap; }

.painel-content {
  margin-left: var(--sidebar-width);
  min-height: 100vh;
  padding: 1.75rem;
  background: transparent;   /* o fundo é o do body (cor + brilho da identidade); aqui só tampava o brilho */
}

/* ── Cards ────────────────────────────────────────────────────── */
/* --bs-card-inner-border-radius é a camada 1 do "canto quadrado dentro do card arredondado" (PADRÕES seção 10):
   header/footer/list-group do Bootstrap arredondam por ESTA variável, não pelo border-radius do card. A camada 2
   (overflow:hidden) fica só no .card-recorte abaixo — o card do picker de revendedora (maleta nova) precisa deixar
   a lista vazar pra baixo; auditado em 10/11/2026. */
.card {
  --bs-card-border-radius: var(--radius-card);
  --bs-card-inner-border-radius: var(--radius-card);
  background: var(--bg-card);
  border: 1px solid var(--card-border-color);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
}
/* overflow:hidden NÃO pode ser padrão de todo .card — ele corta qualquer
   conteúdo posicionado "absolute" que precise escapar da caixa (o
   dropdown do picker, por exemplo, quando o card é curto e a lista abre
   pra baixo do limite do card: ficava cortado no meio, mesmo o picker
   sendo z-index alto — overflow:hidden do ANCESTRAL corta antes disso
   importar). Fica só na classe abaixo, ligada nos cards que realmente
   têm uma <table> colada na borda (o motivo original: sem isso, a quina
   reta do thead vazava por cima do canto arredondado do card). */
.card-recorte { overflow: hidden; }
.card-header { background: transparent; border-bottom: 1px solid var(--card-border-color); font-weight: 600; }
.card-footer { border-top: 1px solid var(--card-border-color); background: var(--bg-cabeca-tabela); }

/* ── Botões ───────────────────────────────────────────────────── */
/* Centralização vale pra qualquer variante de botão (secondary, danger,
   outline-*...), não só accent — min-height sem isso deixa o conteúdo
   (ícone sozinho, principalmente) fora do centro vertical. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.btn-accent {
  background: var(--accent);
  color: var(--accent-text);
  border: none;
  border-radius: var(--radius-btn);
  font-weight: 500;
  min-height: 44px;
}
.btn-accent:hover, .btn-accent:focus { background: var(--accent-hover); color: var(--accent-text); }
/* Desabilitado = cinza-creme de verdade, não a cor da marca desbotada (PADRÕES 9): sem isto o Bootstrap zerava o
   fundo e "Registrar venda" virava texto solto no meio da barra. */
.btn-accent:disabled, .btn-accent.disabled {
  background: var(--bg-hover); color: var(--text-muted); border: 1px solid var(--card-border-color);
  opacity: 1; cursor: not-allowed;
}
.btn-outline-accent {
  border: 1.5px solid var(--accent);
  color: var(--accent);
  border-radius: var(--radius-btn);
  font-weight: 500;
  min-height: 44px;
}
.btn-outline-accent:hover, .btn-outline-accent:focus { background: var(--accent); color: var(--accent-text); }
.btn-sm { min-height: 36px; }
.btn-lg { min-height: 52px; }

/* ── Badges ───────────────────────────────────────────────────── */
.badge { font-size: .78rem; font-weight: 500; padding: .35em .65em; border-radius: 6px; }

/* Selos de situação — fundo claro + texto escuro da mesma família (contraste ≥ 4,5:1, PADRÕES 20.1). Substituem o
   cinza do Bootstrap (text-bg-secondary), que destoava da paleta, e os style="background:…" soltos nas telas.
   Verde só pra "resolvido, nada a fazer" (pago); âmbar pra "falta agir" (PADRÕES 10, cor semântica é sinal escasso). */
.selo {
  display: inline-flex; align-items: center; gap: .3rem;
  font-size: .76rem; font-weight: 600; line-height: 1.2;
  padding: .3em .7em; border-radius: 999px; white-space: nowrap;
}
.selo-neutro  { background: var(--bg-hover);       color: var(--text-secondary); }
.selo-marca   { background: var(--accent-light);   color: var(--accent-hover); }
.selo-info    { background: var(--cor-info-bg);    color: var(--texto-sobre-info); }
.selo-atencao { background: var(--cor-atencao-bg); color: var(--texto-sobre-atencao); }
.selo-sucesso { background: var(--cor-sucesso-bg); color: var(--texto-sobre-sucesso); }
.selo-grande  { font-size: .85rem; padding: .4em .85em; }

/* Faixa de filtros: quebra em mais linhas, nunca corre pro lado (PADRÕES 20.10). */
.filtro-chips { display: flex; flex-wrap: wrap; gap: .45rem; }
.filtro-chip {
  display: inline-flex; align-items: center; gap: .35rem; min-height: 38px; padding: .35rem .9rem;
  border: 1px solid var(--card-border-color); border-radius: 999px;
  background: var(--bg-card); color: var(--text-secondary); font-size: .86rem; font-weight: 500;
  transition: border-color var(--transition-fast), background var(--transition-fast), color var(--transition-fast);
}
.filtro-chip:hover { border-color: var(--borda-forte); color: var(--text-main); }
.filtro-chip.ativo { background: var(--accent); border-color: var(--accent); color: var(--accent-text); }

/* Aviso discreto no topo de uma lista (ex.: total a receber) */
.aviso-faixa {
  display: flex; align-items: flex-start; gap: .6rem; padding: .85rem 1rem; margin-bottom: 1rem;
  border-radius: var(--radius-card); background: var(--cor-atencao-bg); color: var(--texto-sobre-atencao);
}
.aviso-faixa > i { font-size: 1.1rem; flex-shrink: 0; margin-top: .05rem; }
.aviso-faixa a { color: inherit; font-weight: 700; text-decoration: underline; text-underline-offset: 2px; }

/* ── Stat cards (dashboard) ───────────────────────────────────── */
.stat-card {
  border-radius: var(--radius-card);
  padding: 1.1rem 1.25rem;
  min-height: 110px;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  /* Sem fundo, o card era só uma sombra em cima do creme (print de 09/11) — não parecia cartão. */
  background: var(--bg-card);
  border: 1px solid var(--card-border-color);
  /* O valor em dinheiro mede a largura DO CARD (cqi), não da tela: encolhe junto com ele. */
  container-type: inline-size;
}
/* Dinheiro no stat card nunca ganha reticências (PADRÕES 20.2): encolhe com o card e, se ainda não couber, o número
   desce pra linha de baixo do "R$" miúdo — espaço normal entre os dois, nunca o que não quebra. */
.stat-card-valor-dinheiro { font-size: clamp(.95rem, 10.5cqi, 1.45rem); overflow-wrap: anywhere; }
.stat-moeda { font-size: .62em; font-weight: 600; color: var(--text-muted); }
.stat-card-top { display: flex; align-items: flex-start; justify-content: space-between; gap: .5rem; margin-bottom: .5rem; }
.stat-card-label { font-size: .7rem; font-weight: 600; text-transform: uppercase; letter-spacing: var(--rotulo-espaco); color: var(--text-muted); line-height: 1.3; }
/* Número grande na fonte de número da identidade (serifa no Ateliê, como etiqueta de preço), algarismos de largura igual. */
.stat-card-valor { font-family: var(--fonte-numero); font-variant-numeric: lining-nums tabular-nums; font-size: 1.5rem; font-weight: var(--numero-peso); line-height: 1.1; color: var(--text-main); }
.stat-card-sub { font-size: .68rem; color: var(--text-muted); margin-top: .15rem; }
.stat-icon {
  width: 36px; height: 36px; border-radius: var(--icone-raio);
  display: flex; align-items: center; justify-content: center;
  font-size: 1.05rem; flex-shrink: 0;
  background: var(--icone-fundo); color: var(--icone-cor);
}
/* height:100% nos dois níveis (link E card) — sem isso, o <a> e o <div>
   dentro dele só ficam do tamanho do próprio conteúdo, mesmo a COLUNA do
   Bootstrap já estando esticada pra bater com a mais alta da fileira; um
   card sem texto secundário (só número) ficava visualmente mais baixo que
   um card com .stat-card-sub, mesmo os dois "cabendo" na mesma altura de
   coluna por baixo. */
.stat-card-link { text-decoration: none; color: inherit; transition: transform .12s ease, box-shadow .12s ease; display: block; height: 100%; }
.stat-card-link:hover { transform: translateY(-2px); box-shadow: 0 6px 16px var(--shadow-color); color: inherit; }
.stat-card-active { box-shadow: inset 0 0 0 2px var(--accent); }

/* Card "urgente" — reservado pra métrica que realmente pede ação AGORA
   (estoque zerado, valor pendente de receber). Sem isso, todo card usava
   o mesmo tom clarinho (accent-light) independente de precisar de atenção
   ou não, e nada se destacava de verdade no meio de 6 cards parecidos —
   ver PADROES_DESENVOLVIMENTO.md seção 10 ("cor semântica é sinal
   escasso"). Ícone com fundo SÓLIDO (não só tint claro), borda colorida
   no card inteiro, e o número em si na cor de urgência. */
.stat-card-urgente { box-shadow: inset 0 0 0 2px var(--cor-atencao), var(--shadow-card); }
.stat-card-urgente .stat-icon { background: var(--cor-atencao); color: var(--texto-sobre-solido); }
.stat-card-urgente .stat-card-valor { color: var(--cor-atencao); }

/* Variante informativa (nem neutra nem urgente) — ex.: "maletas em
   consignação", um número que é só pra saber, não pede ação. */
.stat-icon-info { background: var(--cor-info-bg); color: var(--texto-sobre-info); }

/* ── Lista de itens editáveis: uma linha por item, edição na janelinha (PADRÕES 20.21) ──────────────────────
   Materiais e Revendedoras. Ícone + nome + UMA linha de resumo + lápis; tocar abre a janelinha. 1 coluna no celular,
   várias no computador, sem media query. Antes eram tabelas com botões por linha (e a de revendedoras ainda abria
   uma linha extra pra mostrar telefone/CPF). */
.lista-itens {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr)); gap: .6rem;
  list-style: none; margin: 0; padding: 0;
}
.linha-item {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: .8rem;
  width: 100%; min-height: 64px; padding: .65rem .9rem;
  background: var(--bg-card); border: 1px solid var(--card-border-color); border-radius: var(--radius-card);
  box-shadow: 0 1px 2px var(--shadow-color); text-align: left; color: var(--text-main); font: inherit;
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast), transform var(--transition-fast);
}
.linha-item:hover, .linha-item:focus-visible { border-color: rgba(var(--accent-rgb), .35); box-shadow: 0 6px 18px var(--shadow-color-forte); }
.linha-item:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.li-icone {
  width: 42px; height: 42px; border-radius: 12px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent-light); color: var(--accent); font-size: 1.1rem; font-weight: 700;
}
.li-iniciais { border-radius: 50%; font-size: .88rem; letter-spacing: .02em; }
.li-corpo { display: flex; flex-direction: column; min-width: 0; gap: .1rem; }
.li-nome { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.li-resumo { font-size: .8rem; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.li-resumo .li-alerta { color: var(--texto-sobre-atencao); font-weight: 600; }
.li-lapis { color: var(--text-muted); font-size: 1rem; }
.linha-item:hover .li-lapis { color: var(--accent); }

/* Ações secundárias da janelinha (remover, WhatsApp): numa faixa separada por um fio, fora do formulário principal. */
.janela-acoes-extra {
  display: flex; flex-wrap: wrap; align-items: center; gap: .5rem;
  margin-top: 1.25rem; padding-top: 1rem; border-top: 1px solid var(--card-border-color);
}
.janela-acoes-extra form { margin: 0; }
.janela-aviso { font-size: .8rem; color: var(--text-muted); flex-basis: 100%; }
.janela-aviso:empty { display: none; }
.icone-whatsapp { color: var(--cor-whatsapp); }

/* ── Lista simples com link (cadastrados recentemente no painel) ── */
.lista-simples { display: flex; flex-direction: column; }
.lista-simples-item {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: .8rem;
  padding: .7rem 1.1rem; color: var(--text-main); border-bottom: 1px solid var(--card-border-color);
  transition: background var(--transition-fast);
}
.lista-simples-item:last-child { border-bottom: 0; }
.lista-simples-item:hover { background: var(--bg-hover); color: var(--text-main); }
.lista-simples-titulo { font-weight: 600; line-height: 1.3; }
.lista-simples-sub { font-size: .78rem; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lista-simples-valor { font-weight: 700; white-space: nowrap; }

/* ── Atalhos (painel): ícone + ação + uma linha do que acontece ── */
.atalho {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: .8rem;
  padding: .8rem 1.1rem; color: var(--text-main); border-bottom: 1px solid var(--card-border-color);
  transition: background var(--transition-fast);
}
.atalho:last-child { border-bottom: 0; }
.atalho:hover { background: var(--bg-hover); color: var(--text-main); }
.atalho-icone {
  width: 40px; height: 40px; border-radius: 12px; display: flex; align-items: center; justify-content: center;
  background: var(--accent-light); color: var(--accent); font-size: 1.1rem;
}
.atalho-titulo { font-weight: 600; }
.atalho-sub { font-size: .78rem; color: var(--text-muted); }
.atalho-seta { color: var(--text-muted); }
.atalho:hover .atalho-seta { color: var(--accent); }

/* ── Barra de ação que gruda no pé da tela (montar maleta, registrar venda, gerar etiquetas) ──
   Com a lista de produtos comprida, o botão e o total ficavam lá embaixo, fora da vista enquanto a pessoa escolhia. */
.barra-acao {
  position: sticky; bottom: 0; z-index: 5;
  display: flex; flex-wrap: wrap; align-items: center; gap: .5rem 1rem;
  margin: 0 -.25rem; padding: .75rem 1rem;
  background: var(--bg-card); border: 1px solid var(--card-border-color); border-radius: var(--radius-card);
  box-shadow: 0 -6px 24px var(--shadow-color-forte);
}
.barra-acao-info { flex: 1 1 10rem; min-width: 0; }
.barra-acao-total { font-family: var(--fonte-numero); font-variant-numeric: lining-nums tabular-nums; font-size: 1.2rem; font-weight: 700; color: var(--text-main); line-height: 1.2; overflow-wrap: anywhere; }
.barra-acao-dica { font-size: .78rem; color: var(--text-muted); }
.barra-acao .btn { flex: 0 1 auto; }
@media (max-width: 575.98px) {
  .barra-acao { margin: 0 -.5rem; padding: .65rem .75rem calc(.65rem + env(safe-area-inset-bottom, 0px)); }
  .barra-acao .btn { flex: 1 1 100%; }
}

/* ── Pré-visualização de etiqueta (Configurações) ─────────────────────
   Usa unidade "mm" de propósito, igual à tela de impressão de verdade
   (etiquetas-print.css) — o navegador renderiza mm de forma consistente
   entre tela e papel (referência de 96dpi), então isso já é uma prévia
   proporcionalmente correta do tamanho real, não só um desenho ilustrativo. */
.etq-preview-container {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 150px;
  background: repeating-conic-gradient(#e5e5e5 0% 25%, #ededed 0% 50%) 50% / 16px 16px;
  border-radius: var(--radius-btn);
  padding: 18px;
  overflow: auto;
}
.etq-preview {
  background: #fff;
  border: 1px dashed #999;
  box-shadow: 0 3px 10px rgba(0, 0, 0, .18);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: .5mm;
  /* mm fixo, NUNCA porcentagem aqui — padding em % sempre resolve contra
     a largura do elemento PAI (mesmo padding-top/bottom, é uma regra do
     CSS), e o pai desta prévia (.etq-preview-container, o fundo
     quadriculado) é bem mais largo que a etiqueta em si — dava um padding
     gigante (17-25px) sem relação nenhuma com o tamanho real configurado.
     Na tela de impressão de verdade isso não acontece porque lá o
     elemento pai já TEM exatamente o tamanho da etiqueta. */
  padding: 1.5mm 2.5mm;
  text-align: center;
  overflow: hidden;
  flex-shrink: 0;
  font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
}
.etq-preview-nome { font-weight: 700; color: #111; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.etq-preview-material { color: #555; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.etq-preview-preco { font-weight: 700; color: #111; }
.etq-preview-codigos {
  /* flex:1 + min-height:0 (não flex-shrink:0) — é este bloco que precisa
     absorver a sobra/falta de espaço, igual à etiqueta impressa de
     verdade (ver .etq-codigos em etiquetas-print.css). Dar flex-shrink:0
     aqui foi o bug original: sobrava pro flexbox espremer NOME/MATERIAL
     até ficarem menores que a própria fonte (texto cortado, invisível). */
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 3%;
  width: 100%;
  margin-top: 1mm;
  flex: 1;
  /* 5mm = altura mínima de um CODE128 pra leitura confiável (norma
     ISO/IEC 15417 recomenda 5mm ou 15% do comprimento, o que for maior) —
     ver painel/etiquetas_imprimir.php. Sem esse piso, uma etiqueta muito
     baixa (ex.: 15mm) ou nome/material/preço grandes tomam todo o espaço e
     o código sai menor que o mínimo legível por qualquer leitor. */
  min-height: 5mm;
}
/* SVGs de verdade agora (renderizados por JsBarcode/qrcode-generator, o
   MESMO código usado na impressão real — ver painel/configuracoes.php) —
   antes daqui era um padrão de CSS decorativo (linhas idênticas, não um
   código de barras de verdade), o que dava uma ideia errada de como o
   código realmente vai sair no papel. Mesmo dimensionamento de
   .etq-codigos em etiquetas-print.css, pra prévia bater com a impressão. */
.etq-preview-codigo, .etq-preview-qr { max-width: 100%; max-height: 100%; display: block; }
.etq-preview-codigo { flex: 1 1 auto; min-width: 0; }
.etq-preview-qr { flex: 0 0 auto; height: 100%; aspect-ratio: 1 / 1; }
.etq-preview-nome, .etq-preview-material, .etq-preview-preco { flex-shrink: 0; }
.etq-preview-medida { font-size: .72rem; color: var(--text-muted); text-align: center; margin-top: .5rem; }

/* Visão panorâmica da folha A4 (escala reduzida — a folha inteira em mm
   reais não caberia na tela) — só pra conferir se colunas/linhas/margem
   fazem sentido juntos, não é preciso ao pixel como a prévia de uma
   etiqueta só. */
/* Centralizada; a escala é calculada pela largura real desta caixa (configuracoes.php) — com 260px fixos, num celular
   de 320 a folha passava da caixa e rolava por dentro (linha de base de 09/11/2026). */
.etq-preview-folha-wrap { display: flex; justify-content: center; overflow: hidden; background: var(--papel-fundo-tela); border-radius: var(--radius-btn); padding: 10px; }
.etq-preview-aviso { color: var(--cor-perigo); }
.etq-preview-folha {
  background: #fff;
  box-shadow: 0 2px 10px rgba(0, 0, 0, .2);
  position: relative;
  transform-origin: top left;
  flex-shrink: 0;
}
.etq-preview-folha-etiqueta { position: absolute; background: var(--accent-light); border: 1px solid var(--accent); border-radius: 1px; }

.recente-item { padding: .35rem 0; border-radius: 6px; color: var(--text-main); }
.recente-item:hover { background: var(--bg-hover); color: var(--text-main); }

.tr-link { cursor: pointer; }

/* ── Lista de informações (dl/dt/dd) ─────────────────────────────
   dt/dd ficam soltos por padrão (mesmo peso visual, pouco espaço
   entre pares) e acabam se misturando. Aqui cada dt vem com uma
   folga maior ANTES (separa do par anterior) e a dd cola nela logo
   abaixo, então os pares ficam visualmente agrupados. */
.dl-info { margin: 0; }
.dl-info dt {
  font-size: .7rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: var(--rotulo-espaco); color: var(--text-muted);
  margin-top: 1rem;
}
.dl-info dt:first-child { margin-top: 0; }
.dl-info dd { font-size: .95rem; font-weight: 600; color: var(--text-main); margin: .2rem 0 0; }

/* ── Avatar circular (iniciais) ───────────────────────────────── */
.avatar-circle {
  width: 56px; height: 56px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent); color: var(--accent-text);
  font-size: 1.4rem; font-weight: 700; flex-shrink: 0;
}

/* ── Formulários ──────────────────────────────────────────────── */
.form-label { font-weight: 500; }
/* Mesma altura de .btn-accent/.btn-outline-accent (44px) — sem isso,
   input/select ficavam no padrão menor do Bootstrap (~38px) e destoavam
   de um botão ao lado na mesma linha (ex: busca + "Ativos", filtro +
   "Filtrar"). -sm continua menor de propósito, alinhado a .btn-sm. */
.form-control, .form-select { min-height: 44px; }
.form-control-sm, .form-select-sm { min-height: 36px; }
.form-control:focus, .form-select:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 .2rem var(--accent-light);
}
/* Caixa de marcar e chave na cor da marca: sem isto ficavam no azul do Bootstrap — e azul aqui é cor de informação. */
.form-check-input:checked { background-color: var(--accent); border-color: var(--accent); }
.form-check-input:focus { border-color: var(--accent); box-shadow: 0 0 0 .2rem var(--accent-light); }
.input-group-text { background: var(--bg-cabeca-tabela); color: var(--text-secondary); border-color: var(--bs-border-color); }
/* Barra de busca das listas: sem cartão em volta (um contorno a menos na tela), largura de leitura. */
.busca-barra { max-width: 30rem; margin-bottom: 1rem; }
.busca-barra .form-control { min-width: 0; }

/* Lista vazia / busca sem resultado */
.vazio { text-align: center; color: var(--text-secondary); padding: 2.5rem 1rem; }
.vazio > i { font-size: 2.2rem; display: block; margin-bottom: .5rem; color: var(--accent); opacity: .55; }
.vazio p { margin: 0 auto .9rem; max-width: 26rem; }
.vazio p:last-child { margin-bottom: 0; }

.campo-estreito { max-width: 160px; }
.form-ajuste-fino { max-width: 420px; }
.card-estreito { max-width: 480px; }
.separador { border-color: var(--card-border-color); opacity: 1; }

/* ── Tabelas ──────────────────────────────────────────────────── */
/* Acabamento: cabeçalho miúdo em caixa alta num creme mais claro, linhas com respiro, fio suave entre elas e a
   linha inteira acendendo no hover quando ela leva a algum lugar (.tr-link). */
.table {
  --bs-table-bg: transparent;
  --bs-table-color: var(--text-main);
  --bs-table-border-color: var(--card-border-color);
  margin-bottom: 0;
}
.table > thead > tr > th {
  font-size: .7rem; font-weight: 700; letter-spacing: var(--rotulo-espaco); text-transform: uppercase;
  color: var(--text-muted); background: var(--bg-cabeca-tabela);
  padding: .7rem 1rem; white-space: nowrap; border-bottom-width: 1px;
}
.table > tbody > tr > td { padding: .8rem 1rem; }
.table > tbody > tr:last-child > td { border-bottom: 0; }
.tr-link { cursor: pointer; }
.tr-link > td { transition: background var(--transition-fast); }
.tr-link:hover > td { background: var(--bg-hover); }
.td-sub { font-size: .8rem; color: var(--text-muted); margin-top: .1rem; }
.td-num { color: var(--text-muted); font-variant-numeric: tabular-nums; }
.valor { font-weight: 600; white-space: nowrap; font-variant-numeric: tabular-nums; }
.riscado { text-decoration: line-through; }
.so-empilhado { display: none; }

/* REGRA PERMANENTE (Gustavo, 09/10/2026; PADRÕES 20.10): tabela NUNCA rola de lado no celular.
   O .table-responsive do Bootstrap escondia atrás de um arraste justo as colunas da direita (valor, pagamento,
   botões): a de maletas pedia 617px dentro de 356px num celular de 390 (linha de base de 09/11/2026).
   Em vez de rolar, quando o espaço DA TABELA aperta cada linha vira um cartão: o nome em cima, os outros campos com
   o rótulo em cima do valor, lado a lado enquanto couberem. Mede a largura da tabela (container query), não da tela:
   com o menu lateral de 240px, num tablet a tabela de 7 colunas não cabe mesmo "acima do celular".
   Como usar (mesmo HTML nas duas larguras, nada duplicado):
     <div class="tabela">                                          (no lugar de "table-responsive")
       <table class="table"> … <td class="td-titulo" data-rotulo="Revendedora">nome</td>   (vai pro topo, sem rótulo)
                             <td data-rotulo="Peças">7</td>                                (rótulo em cima do valor)
                             <td class="td-lead">foto ou caixinha</td>                     (fica ao lado do nome)
                             <td>botões</td>                                               (sem data-rotulo = ações)
   Não use dentro de .tabela menu suspenso do Bootstrap: o container prende até position:fixed (PADRÕES 20.10). */
.tabela { container: tabela / inline-size; }
.tabela > table { width: 100%; }
.tabela > table > tbody > tr > td { overflow-wrap: anywhere; }
/* A coluna dos botões não quebra: com "anywhere" a tabela larga espremia ela até editar e excluir ficarem um em cima
   do outro (PADRÕES 20.10). Quem cede espaço é a coluna de texto. */
.tabela > table > tbody > tr > td:not([data-rotulo]):not([colspan]) { overflow-wrap: normal; white-space: nowrap; }
.td-lead { width: 1%; }
/* Data não quebra: com o nome comprido ao lado, "10/11/2026" virava "10/11/202" + "6" no computador (print, 10/11). */
.tabela > table > tbody > tr > td.td-data { white-space: nowrap; overflow-wrap: normal; }
.campo-qtd-tabela { width: 5.5rem; margin-inline: auto; }
@container tabela (max-width: 640px) { .campo-qtd-tabela { width: 100%; margin: 0; } }

/* Corta no fim da 2ª linha com reticências — nome comprido não vira 6 linhas. Sem classe d-* junto (o !important
   delas anula o -webkit-box, PADRÕES 20.10). */
.ate-2-linhas {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden; overflow-wrap: anywhere;
}
.rotulo-celular { display: none; }

@container tabela (max-width: 640px) {
  .tabela > table,
  .tabela > table > tbody,
  .tabela > table > tbody > tr > td { display: block; width: auto; max-width: none; }
  .tabela > table > thead { display: none; }
  /* flex-wrap e não grade: o nome ocupa a linha de cima inteira (ou o que sobra ao lado da foto/caixinha) e os campos
     dividem as de baixo, ~3 por linha num celular de 390 e 2 num de 320. */
  .tabela > table > tbody > tr {
    display: flex; flex-wrap: wrap; align-items: center; gap: .6rem 1rem;
    padding: .9rem 1rem; border-bottom: 1px solid var(--card-border-color);
  }
  .tabela > table > tbody > tr:last-child { border-bottom: 0; }
  .tabela > table > tbody > tr > td { flex: 1 1 5.75rem; min-width: 0; padding: 0 !important; border: 0; background: transparent; }
  .tabela > table > tbody > tr > td:empty { display: none; }
  /* Rótulo ACIMA do valor, nunca ao lado: num celular de 320 um rótulo lateral comia 84px e o selo saía cortado. */
  .tabela > table > tbody > tr > td[data-rotulo]::before {
    content: attr(data-rotulo);
    display: block; margin-bottom: .1rem;
    font-size: .66rem; font-weight: 700; letter-spacing: var(--rotulo-espaco); text-transform: uppercase;
    color: var(--text-muted);
  }
  .tabela > table > tbody > tr > td.td-titulo { flex: 1 1 100%; font-size: 1rem; }
  .tabela > table > tbody > tr > td.td-titulo::before { display: none; }
  .tabela > table > tbody > tr > td.td-lead { flex: 0 0 auto; width: auto; }
  /* Com foto/caixinha antes, o nome fica ao lado dela; o "- 6rem" sobra justo pro que vem antes (caixinha + foto). */
  .tabela > table > tbody > tr > td.td-lead ~ td.td-titulo { flex-basis: calc(100% - 6rem); }
  .tabela > table > tbody > tr > td.td-qtd { flex: 0 0 5.5rem; }
  .tabela > table > tbody > tr > td.text-end,
  .tabela > table > tbody > tr > td.text-center { text-align: left !important; }
  /* A célula dos botões ocupa a linha toda e os botões dividem a largura lado a lado (flex 1 1 7rem: 2 cabem lado a lado até num celular de 320); só descem quando
     não cabem. Botão só de ícone ganha o texto (.rotulo-celular): lápis sozinho numa faixa larga não diz o que faz. */
  .tabela > table > tbody > tr > td:not([data-rotulo]):not(.td-lead) { flex: 1 1 100%; display: flex; flex-wrap: wrap; gap: .5rem; }
  .tabela > table > tbody > tr > td:not([data-rotulo]):not(.td-lead) > .btn,
  .tabela > table > tbody > tr > td:not([data-rotulo]):not(.td-lead) > form { display: block !important; flex: 1 1 7rem; margin: 0; }
  .tabela > table > tbody > tr > td:not([data-rotulo]):not(.td-lead) .btn { width: 100%; }
  .tabela > table > tbody > tr > td:not([data-rotulo]) .rotulo-celular { display: inline; margin-left: .35rem; }
  .tabela > table > tbody > tr > td.td-titulo.td-data { white-space: normal; }   /* no cartão o título tem a linha toda */
  .tabela .esconder-empilhado,
  .tabela .vaga-botao { display: none !important; }
  .tabela .so-empilhado { display: inline; }
  .tabela .td-check .form-check-input { width: 1.35rem; height: 1.35rem; margin: 0; }
}

/* ── Utilitário: célula de e-mail truncada ────────────────────── */
.email-cell { max-width: 200px; }
.email-cell span { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── Picker de busca (dropdown com campo de busca) ────────────── */
.picker { position: relative; }
.picker-trigger {
  display: flex; align-items: center; justify-content: space-between;
  padding: .45rem .75rem;
  border: 1px solid var(--card-border-color);
  border-radius: var(--radius-btn);
  background: var(--bg-card);
  cursor: pointer;
  transition: border-color .15s, box-shadow .15s;
  min-height: 44px;
  user-select: none;
  gap: .5rem;
}
.picker-trigger:hover { border-color: var(--accent); }
.picker-trigger.disabled {
  cursor: not-allowed;
  opacity: .55;
  background: var(--bg-hover);
}
.picker-trigger.disabled:hover { border-color: var(--card-border-color); }
.picker-trigger.open {
  border-color: var(--accent);
  border-radius: var(--radius-btn) var(--radius-btn) 0 0;
  box-shadow: 0 0 0 3px var(--accent-light);
}
.picker-placeholder {
  color: var(--text-secondary); font-size: .9rem; flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.picker-selected {
  color: var(--text-main); font-size: .9rem; font-weight: 500; flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.picker-caret { color: var(--text-secondary); transition: transform .2s; flex-shrink: 0; }
.picker-trigger.open .picker-caret { transform: rotate(180deg); }
.picker-dropdown {
  position: absolute; top: 100%; left: 0; right: 0;
  background: var(--bg-card);
  border: 1px solid var(--accent);
  border-top: none;
  border-radius: 0 0 var(--radius-btn) var(--radius-btn);
  z-index: 300;
  box-shadow: 0 8px 28px var(--shadow-color-forte);
  max-height: 260px;
  display: flex; flex-direction: column;
}
.picker-search-wrap {
  padding: .5rem .75rem;
  border-bottom: 1px solid var(--card-border-color);
  display: flex; align-items: center; gap: .5rem;
  flex-shrink: 0;
  background: var(--bg-hover);
}
.picker-search-icon { color: var(--text-secondary); font-size: .82rem; flex-shrink: 0; }
.picker-search {
  border: none; outline: none; background: transparent;
  color: var(--text-main); font-size: .875rem; width: 100%; min-width: 0;
}
.picker-list { overflow-y: auto; flex: 1; }
.picker-item {
  padding: .55rem .9rem;
  cursor: pointer;
  font-size: .875rem;
  transition: background .1s;
  border-bottom: 1px solid var(--card-border-color);
}
.picker-item:last-child { border-bottom: none; }
.picker-item:hover, .picker-item.picker-active { background: var(--accent-light); }
.picker-item-titulo { font-weight: 600; color: var(--text-main); line-height: 1.3; }
.picker-item-sub { font-size: .78rem; color: var(--text-secondary); margin-top: .1rem; }
.picker-item:hover .picker-item-titulo, .picker-item.picker-active .picker-item-titulo { color: var(--accent); }
.picker-empty { padding: .9rem; text-align: center; color: var(--text-secondary); font-size: .85rem; }

/* ── Ícone genérico recolorido via CSS mask (ver funcoes.php:
   iconeMascaraHtml()) — um PNG/SVG de silhueta, qualquer cor via
   background-color, sem duplicar arquivo por cor. ── */
.icone-mascara {
  display: inline-block;
  width: 1.2em;
  height: 1.2em;
  vertical-align: -.2em;
  flex-shrink: 0;
  background-color: var(--accent);
  -webkit-mask-image: var(--icone-mascara-url);
  mask-image: var(--icone-mascara-url);
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
}

/* ── Spinner de carregamento (12 traços girando, tipo iOS) ──────── */
.vs-spinner { position: relative; width: var(--vs-spinner-size, 44px); height: var(--vs-spinner-size, 44px); }
.vs-spinner div {
  position: absolute;
  inset: 0;
  animation: vs-spinner-fade 1.1s linear infinite;
}
.vs-spinner div::after {
  content: '';
  display: block;
  position: absolute;
  top: 5%;
  left: 46%;
  width: 8%;
  height: 27%;
  border-radius: 40%;
  background: var(--accent);
}
.vs-spinner div:nth-child(1)  { transform: rotate(0deg);   animation-delay: -1.0000s; }
.vs-spinner div:nth-child(2)  { transform: rotate(30deg);  animation-delay: -0.9167s; }
.vs-spinner div:nth-child(3)  { transform: rotate(60deg);  animation-delay: -0.8333s; }
.vs-spinner div:nth-child(4)  { transform: rotate(90deg);  animation-delay: -0.7500s; }
.vs-spinner div:nth-child(5)  { transform: rotate(120deg); animation-delay: -0.6667s; }
.vs-spinner div:nth-child(6)  { transform: rotate(150deg); animation-delay: -0.5833s; }
.vs-spinner div:nth-child(7)  { transform: rotate(180deg); animation-delay: -0.5000s; }
.vs-spinner div:nth-child(8)  { transform: rotate(210deg); animation-delay: -0.4167s; }
.vs-spinner div:nth-child(9)  { transform: rotate(240deg); animation-delay: -0.3333s; }
.vs-spinner div:nth-child(10) { transform: rotate(270deg); animation-delay: -0.2500s; }
.vs-spinner div:nth-child(11) { transform: rotate(300deg); animation-delay: -0.1667s; }
.vs-spinner div:nth-child(12) { transform: rotate(330deg); animation-delay: -0.0833s; }
@keyframes vs-spinner-fade {
  0%   { opacity: 1; }
  100% { opacity: .15; }
}
@media (prefers-reduced-motion: reduce) {
  .vs-spinner div { animation: none; opacity: .6; }
}

/* ── Cartão "Instalar o app" (Android/computador + instrução do iPhone) — PADRÕES 12 ──
   Cópia do biblioteca-pessoal/assets/css/estrutura.css. Peça de marca, não o aviso genérico do navegador.
   HTML e JS no geral/footer.php; com a barra de baixo ele sobe pra cima dela (seção da barra, no fim). */
.vs-install-banner {
  position: fixed;
  left: 1rem; right: 1rem;
  bottom: calc(1rem + env(safe-area-inset-bottom, 0px));
  max-width: 420px;
  margin: 0 auto;
  z-index: 1080;
  display: flex;
  align-items: center;
  gap: .85rem;
  background: var(--bg-card);
  border-radius: 18px;
  padding: .9rem 1rem;
  box-shadow: 0 16px 40px -12px var(--shadow-color-forte), 0 2px 10px var(--shadow-color);
  border: 1px solid var(--card-border-color);
  opacity: 0;
  transform: translateY(20px) scale(.98);
  transition: opacity .3s ease, transform .3s ease;
}
.vs-install-banner[hidden] { display: none; }
.vs-install-banner-visivel { opacity: 1; transform: translateY(0) scale(1); }
.vs-install-banner-icone {
  flex-shrink: 0;
  width: 46px; height: 46px;
  border-radius: 13px;
  overflow: hidden;
  box-shadow: 0 6px 14px -4px var(--shadow-color-forte);
}
.vs-install-banner-icone img { display: block; width: 100%; height: 100%; object-fit: cover; }
.vs-install-banner-texto { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: .15rem; }
.vs-install-banner-texto strong { font-size: .9rem; font-weight: 700; color: var(--text-main); }
.vs-install-banner-texto span { font-size: .78rem; color: var(--text-secondary); line-height: 1.4; }
.vs-install-banner-texto span i { color: var(--accent); }
.vs-install-banner-acoes { display: flex; align-items: center; gap: .35rem; flex-shrink: 0; }
.vs-install-banner-acoes .btn { white-space: nowrap; }
@media (prefers-reduced-motion: reduce) { .vs-install-banner { transition: none; } }
@media (max-width: 420px) {
  .vs-install-banner { flex-wrap: wrap; }
  /* Base 0: com "auto" o texto pedia a largura do parágrafo inteiro e descia, deixando o ícone sozinho em cima. */
  .vs-install-banner-texto { flex-basis: 0; }
  /* Largura + recuo = 100%: com width:100% o recuo somava por cima e o "Instalar" e o "×" saíam pra fora da tela. */
  .vs-install-banner-acoes { width: calc(100% - 46px - .85rem); justify-content: flex-end; margin-left: calc(46px + .85rem); }
}

/* ── Overlay de carregamento global (troca de página / envio de form) ── */
.vs-loading-overlay {
  position: fixed;
  inset: 0;
  z-index: 10050;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg-main);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity .18s ease;
}
.vs-loading-overlay.ativo { opacity: .96; visibility: visible; pointer-events: all; }

/* ── Janelas (modais): acabamento + folha que sobe de baixo no celular (PADRÕES 20.11) ────────────────────────
   No computador a janela fica no meio; até 575px vira folha presa no pé da tela, com o tracinho de verdade (o JS do
   rodapé arrasta por ele: arraste curto volta, longo fecha) e o "voltar" do Android fechando (CloseWatcher, rodapé).
   Molde: Central GVTech (30/10/2026). */
.modal-content { border: 0; border-radius: 18px; box-shadow: 0 24px 60px -20px var(--shadow-color-forte); }
.modal-header { border-bottom: 1px solid var(--card-border-color); padding: 1rem 1.25rem; }
.modal-header .modal-title { font-size: 1.05rem; font-weight: 700; color: var(--text-main); }
.modal-body { padding: 1.15rem 1.25rem; }
.modal-footer { border-top: 1px solid var(--card-border-color); padding: .75rem 1.25rem; }
.folha-pegador { display: none; }
@media (max-width: 575.98px) {
  .modal-folha .modal-dialog { position: fixed; left: 0; right: 0; bottom: 0; margin: 0; max-width: none; min-height: 0; align-items: flex-end; transform: translateY(100%); }
  .modal-folha.show .modal-dialog { transform: none; }
  .modal-folha.fade .modal-dialog { transition: transform .25s cubic-bezier(.2, .8, .2, 1); }
  .modal-folha .modal-content {
    border-radius: 20px 20px 0 0; max-height: 92vh; max-height: 92dvh; overflow-y: auto; overscroll-behavior: contain;
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
  /* flex-shrink 0: o .modal-content é coluna flex com altura limitada e o tracinho (sem conteúdo) era o único item que
     encolhia — ficava com 13 dos 22px (medido na Central). */
  .modal-folha .folha-pegador {
    display: block; position: sticky; top: 0; z-index: 2; flex-shrink: 0; height: 22px; margin-bottom: -10px;
    touch-action: none; cursor: grab; background: inherit; border-radius: 20px 20px 0 0;
  }
  .modal-folha .folha-pegador::before { content: ""; display: block; width: 40px; height: 4px; border-radius: 2px; background: var(--borda-forte); margin: 9px auto 0; }
  .modal-folha .modal-footer { position: sticky; bottom: 0; background: var(--bg-card); }
  .modal-folha .modal-footer > .btn { flex: 1 1 0; }
}

/* Confirmação aberta POR CIMA de outra janela (remover, dentro da janelinha de edição): o segundo fundo escuro cobre
   a primeira janela, e a confirmação fica acima dele. */
.modal-backdrop.show ~ .modal-backdrop.show { z-index: 1060; }
#modalConfirm { z-index: 1065; }

/* Janela de confirmação (vsConfirm) */
.confirmar-icone { font-size: 2.4rem; color: var(--accent); display: block; margin-bottom: .75rem; }
.confirmar-msg { color: var(--text-main); font-weight: 600; margin: 0; }

/* ── Miniatura de foto de produto — mesmo elemento serve pra <img> (tem
   foto) ou placeholder (não tem), pra nunca dar "buraco" no layout numa
   lista/tabela quando a foto ainda não foi cadastrada. object-fit:cover
   evita distorcer foto que não seja quadrada. ── */
.foto-produto-mini {
  width: 40px;
  height: 40px;
  border-radius: 8px;
  object-fit: cover;
  flex-shrink: 0;
  background: var(--accent-light);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--accent);
  font-size: 1.1rem;
}
.foto-produto-preview {
  width: 100%;
  max-width: 220px;
  max-height: 220px;
  object-fit: contain;
  border-radius: var(--radius-btn);
  border: 1px solid var(--card-border-color);
  background: var(--accent-light);
  display: block;
}
.foto-produto-preview.foto-pequena { width: 90px; height: 90px; object-fit: cover; flex-shrink: 0; }
.foto-produto-mini.foto-media { width: 48px; height: 48px; border-radius: 10px; }

/* ── Responsivo mobile ────────────────────────────────────────── */
@media (max-width: 767.98px) {
  .sidebar { transform: translateX(-100%); transition: transform .25s ease; }
  .sidebar.aberta { transform: translateX(0); }
  .painel-content { margin-left: 0; padding: 1rem; }
  .card { box-shadow: 0 1px 6px var(--shadow-color); }
  .topnav .navbar-brand { font-size: 1rem; }
}

@media (max-width: 479.98px) {
  .stat-card { padding: .85rem 1rem; min-height: 95px; }
  .stat-card-valor { font-size: 1.25rem; }
  .stat-icon { width: 30px; height: 30px; font-size: .9rem; }
}

/* ── Paginação: Bootstrap traz o azul padrão; aqui vira a cor de marca ── */
.pagination {
  --bs-pagination-color: var(--accent);
  --bs-pagination-hover-color: var(--accent);
  --bs-pagination-hover-bg: var(--accent-light);
  --bs-pagination-hover-border-color: var(--card-border-color);
  --bs-pagination-focus-color: var(--accent);
  --bs-pagination-focus-bg: var(--accent-light);
  --bs-pagination-active-bg: var(--accent);
  --bs-pagination-active-border-color: var(--accent);
  --bs-pagination-active-color: #fff;
  --bs-pagination-border-color: var(--card-border-color);
  --bs-pagination-disabled-color: var(--text-muted);
  --bs-pagination-disabled-border-color: var(--card-border-color);
}
/* ── Barra de baixo (celular) — geral/barra_baixo.php, PADRÕES 20.13 ───────────────────────────────────────────────
   Só abaixo de 768px, o corte em que a sidebar some. Fica ENTRE o fundo da central (1025) e as bolhas (1035): com a
   central aberta as outras abas continuam tocáveis. Computador e tablet: nada muda. */
:root {
  --vs-barra-h: calc(64px + env(safe-area-inset-bottom, 0px));
  --vs-central-x: var(--text-main);   /* a caixa do X com a central aberta: o tom escuro da paleta */
}
.vs-barra { display: none; }
@media (max-width: 767.98px) {
  .vs-barra {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 1030;
    display: flex; align-items: stretch;
    height: var(--vs-barra-h); padding-bottom: env(safe-area-inset-bottom, 0px);
    background: var(--bg-card);
    border-top: 1px solid rgba(var(--accent-rgb), .14);
    box-shadow: 0 -10px 28px -16px var(--shadow-color-forte), 0 -1px 0 var(--shadow-color);
  }
  .vs-barra-item {
    flex: 1 1 0; min-width: 0;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .2rem;
    padding: 0; border: 0; background: none;
    color: var(--text-muted); font-size: .7rem; font-weight: 600; line-height: 1.1;
    text-decoration: none; -webkit-tap-highlight-color: transparent;
    transition: color var(--transition-fast);
  }
  .vs-barra-item:hover { color: var(--accent); }
  .vs-barra-rotulo { max-width: 100%; padding: 0 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .vs-barra-ico {
    width: 46px; height: 28px; border-radius: 999px;
    display: flex; align-items: center; justify-content: center;
    font-size: 1.2rem; transition: background-color var(--transition-fast), transform .12s ease;
  }
  .vs-barra-item.ativo { color: var(--accent); font-weight: 700; }
  .vs-barra-item.ativo .vs-barra-ico { background: var(--accent-light); }
  .vs-barra-item:active .vs-barra-ico { transform: scale(.92); }
  .vs-barra-item:focus-visible { outline: 2px solid var(--accent); outline-offset: -4px; border-radius: 12px; }

  .vs-barra-meio { color: var(--accent); }
  /* A caixa do meio (40px, subindo 18) ocupa 22px na linha; os ícones dos vizinhos, 28. Sem compensar, o rótulo do
     meio ficava 3px acima dos outros (visto no print). */
  .vs-barra-meio .vs-central-ico { margin-bottom: 6px; }
  .vs-barra-meio.ativo .vs-central-ico { box-shadow: 0 0 0 3px rgba(var(--accent-rgb), .22), 0 6px 16px -6px rgba(var(--accent-rgb), .75); }
  .vs-barra-meio:active .vs-central-ico { transform: scale(.94); }
  .vs-barra-meio.central-aberta:active .vs-central-ico { transform: rotate(180deg) scale(.94); }

  /* O conteúdo termina acima da barra; o que flutua no pé (toast, cartão de instalar, barra de ação fixa da tela)
     sobe pra cima dela — a barra de ação do projeto usa bottom: var(--vs-barra-h) do mesmo jeito. */
  body.tem-barra-baixo { padding-bottom: var(--vs-barra-h); }
  .tem-barra-baixo .toast-container { bottom: var(--vs-barra-h) !important; }
  /* O cartão "Instalar o app" (z 1080) ficava POR CIMA das bolhas da central e roubava o toque delas. Abaixo do fundo
     escuro (1025): com a central aberta ele escurece junto. */
  .tem-barra-baixo .vs-install-banner { bottom: calc(var(--vs-barra-h) + .75rem); z-index: 1021; }
}

/* "Mais" (folha que sobe): quem está logado no topo e o resto do menu em grupos, como a sidebar. */
.vs-mais-topo { display: flex; align-items: center; gap: .8rem; margin: .1rem 0 1.1rem; }
.vs-mais-avatar {
  flex-shrink: 0; width: 46px; height: 46px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(140deg, var(--accent) 0%, var(--accent-hover) 100%); color: var(--accent-text);
  font-size: 1.15rem; font-weight: 800;
  box-shadow: 0 6px 14px -6px rgba(var(--accent-rgb), .7);
}
.vs-mais-quem { min-width: 0; display: flex; flex-direction: column; }
.vs-mais-nome { font-weight: 700; color: var(--text-main); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vs-mais-sub { font-size: .78rem; color: var(--text-muted); }
.vs-mais-titulo {
  margin: .9rem .25rem .35rem;
  font-size: .68rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--text-muted);
}
.vs-mais-grupo {
  margin-bottom: .75rem; overflow: hidden;
  border: 1px solid rgba(var(--accent-rgb), .12); border-radius: 16px; background: var(--bg-card);
}
.vs-mais-linha {
  display: flex; align-items: center; gap: .8rem; width: 100%;
  min-height: 52px; padding: .55rem .9rem;
  border: 0; background: none; text-align: left;
  color: var(--text-main); font-weight: 600; font-size: .95rem; text-decoration: none;
  transition: background-color var(--transition-fast);
}
.vs-mais-linha[hidden] { display: none; }
/* Linha seguida de linha, ou do formulário do Sair (que embrulha a linha dele): o fio entre as duas. */
.vs-mais-linha + .vs-mais-linha, .vs-mais-linha + form .vs-mais-linha { border-top: 1px solid rgba(var(--accent-rgb), .08); }
.vs-mais-linha:hover, .vs-mais-linha:active { background: var(--bg-hover); color: var(--text-main); }
.vs-mais-ico {
  flex-shrink: 0; width: 34px; height: 34px; border-radius: 10px;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent-light); color: var(--accent); font-size: 1.05rem;
}
.vs-mais-rotulo { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vs-mais-linha > .bi-chevron-right { color: var(--text-muted); font-size: .8rem; flex-shrink: 0; }
.vs-mais-linha.ativo { color: var(--accent); }
.vs-mais-linha.ativo .vs-mais-ico { background: var(--accent); color: var(--accent-text); }
.vs-mais-linha.sair, .vs-mais-linha.sair .vs-mais-ico { color: var(--cor-perigo); }
.vs-mais-linha.sair .vs-mais-ico { background: var(--cor-perigo-bg); }
.vs-mais-versao { text-align: center; font-size: .7rem; color: var(--text-muted); opacity: .75; margin-top: .25rem; }

/* Maria Clara: a barra de ação da tela (Registrar venda, Montar maleta, Gerar etiquetas) gruda no pé com sticky;
   com a barra de baixo, ela gruda logo ACIMA dela em vez de ficar escondida atrás. */
@media (max-width: 767.98px) {
  .tem-barra-baixo .barra-acao { bottom: var(--vs-barra-h); padding-bottom: .65rem; }
}
