:root {
  --primaria: #123D66;
  --primaria-escura: #0B2A49;
  --primaria-clara: #1E5488;
  /* cor_destaque no DEFAULT_CONFIG do Mac é #C9A227 (dourado) — o cloud não tem
     tabela de configuração (banco Postgres não guarda CONFIG nenhum, conferido
     direto no schema), então essa cor é fixa aqui, e antes estava errada (um
     verde-limão que não existe no app.py). Corrigido pro tom exato do Mac. */
  --destaque: #C9A227;
  --destaque-escuro: #9C7D1E;
  --fundo: #F4F6F8;
  --card: #FFFFFF;
  --borda: #E5E9EE;
  --texto: #1F2937;
  --texto-suave: #6B7280;
  --verde: #15803D;
  --verde-bg: #DCFCE7;
  /* Redesenho (Netto pediu identidade mais profissional em todo o sistema): o
     vermelho aqui era #fb0207, um vermelho "de alarme de navegador", puro e muito
     saturado, e destoava do vermelho já usado nos relatórios em PDF (COR_VERMELHA =
     #B91C1C em exportacoes.py) e no timbrado oficial. Trocado pro mesmo tom dos
     PDFs: mais sóbrio, mais alinhado com o resto da identidade visual do projeto,
     continua com contraste de sobra pra alertar (saldo negativo, pendência,
     governança crítica). */
  --vermelha: #B91C1C;
  --vermelha-bg: #FBEAEA;
  --laranja: #C2410C;
  --laranja-bg: #FFEDD5;
  --atencao: #B45309;
  --atencao-bg: #FEF3E2;
  /* Escala de elevação em 3 níveis (era só 2: sombra/sombra-forte). --sombra-media
     entra em cards ao passar o mouse e em cabeçalhos fixos — dá um degrau visual
     intermediário entre "repousando" e "flutuando" (modal), reforçando qual
     elemento está em primeiro plano sem exagerar. */
  --sombra: 0 2px 10px rgba(18, 61, 102, .06);
  --sombra-media: 0 8px 22px rgba(18, 61, 102, .14);
  --sombra-forte: 0 16px 40px rgba(11, 42, 73, .28);
  --raio: 14px;
  --raio-pequeno: 10px;
  /* Curva de easing única pra toda transição "de elevação" do sistema (hover/active
     de card, botão, linha de lista) — mesma curva usada nos gráficos de entrada dos
     modais (modalCaixaSurge, mais abaixo), pra todo movimento do app ter a mesma
     "textura", em vez de cada componente ter sua própria aceleração. */
  --easing: cubic-bezier(.2, .8, .2, 1);
  /* Escala de espaçamento fixa (múltiplos de 4px), pra toda distância entre blocos
     do sistema vir de um número com nome, não de um valor solto inventado na hora.
     Usada a partir daqui pra fechar, com matemática, o espaço entre a barra de
     abas e o conteúdo (ver comentário em .nav-inferior/.nav-item/.conteudo). */
  --esp-1: 4px;
  --esp-2: 8px;
  --esp-3: 12px;
  --esp-4: 16px;
  --esp-5: 24px;
  --esp-6: 32px;
  /* Bloco de tipografia (Configurações > Tipografia, ver aplicarMarca em app.js):
     valores padrão aqui, sobrescritos em tempo real via JS (setProperty no :root)
     assim que a conta tiver algo configurado — nunca precisa editar este arquivo
     pra mudar fonte/cor/alinhamento por projeto. */
  --fonte-app: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --alinhamento-titulos: center;
}

* { box-sizing: border-box; }

/* Achado do Netto: Lançamentos e Fornecedores apareciam com letra enorme só no
   celular deitado, sem nenhuma regra nossa de CSS mudando fonte por orientação
   (procurado no arquivo inteiro, não existe). Causa real: "Text Autosizing" do
   Safari/Chrome no iPhone — o próprio navegador aumenta sozinho a letra de
   blocos de texto que ele julga "pequenos demais pra ler", e decide isso de
   forma diferente conforme a largura da tela (por isso variava girando o
   aparelho) e conforme quantas linhas de texto cada cartão empilha (por isso
   Lançamentos/Fornecedores, com mais linhas de detalhe por cartão, ficavam mais
   evidentes que Financiadores/Orçamento). Esse recurso existe pra sites de
   texto corrido sem responsividade nenhuma — aqui atrapalha, porque todo
   tamanho de fonte já foi calibrado a dedo pra cada tela. Desligado de vez. */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

html, body {
  margin: 0;
  font-family: var(--fonte-app);
  background: var(--fundo);
  color: var(--texto);
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
  /* Sem isso, arrastar além do topo ou do final da página no iPhone (rolagem
     elástica nativa do iOS) mostra um vão branco por baixo do cabeçalho fixo ou do
     menu inferior fixo, revelando o fundo da própria janela do navegador por trás
     deles — trava esse "quique" na borda da própria página, sem afetar a rolagem
     normal de dentro das tabelas/listas. */
  overscroll-behavior-y: contain;
}

/* Quando um modal está aberto (classe aplicada via JS em abrirModal/fecharModal),
   trava a rolagem da página por trás: sem isso, no iPhone, um toque que começa no
   fundo escuro do modal podia rolar a página de baixo junto, e a abertura do
   teclado (ao tocar num campo de data/texto do formulário) por vezes fazia o modal
   "pular" de posição — bug conhecido do Safari quando um elemento fixed convive
   com uma página normal ainda rolável atrás dele. */
body.modal-aberto { position: fixed; inset: 0; overflow: hidden; width: 100%; }

.oculto { display: none !important; }

/* Auditoria de uso mobile: aviso fixo no topo quando o navegador detecta que a
   internet caiu (evento offline/online do navegador, ver app.js). Fica acima de
   tudo (inclusive do cabeçalho sticky), respeitando o notch/status bar do celular. */
.aviso-offline {
  position: fixed; top: 0; left: 0; right: 0; z-index: 30;
  background: var(--atencao); color: #fff; text-align: center;
  font-size: .74rem; font-weight: 700; padding: 7px 14px;
  padding-top: calc(7px + env(safe-area-inset-top));
}

/* ---------- LOGIN ----------
   Auditoria (pedido do Netto: "não foi otimizada responsivamente para todas as
   plataformas"): até aqui essa tela era um layout ÚNICO, sem nenhuma media query —
   o mesmo cartão de 380px, pensado pro celular em pé, aparecia idêntico (e sozinho
   no meio de um vazio enorme) num iPad ou num Mac, e sem nenhum tratamento
   específico pro celular DEITADO, onde logo (280px) + cartão + rodapé somados
   facilmente passam da altura da tela e cortam/empurram o botão Entrar pra fora
   da área visível. Três ajustes abaixo, nessa ordem: 1) melhorias universais que
   valem em qualquer tamanho de tela (notch/home indicator, altura real do
   navegador mobile); 2) modo compacto só pro celular deitado (altura curta); 3)
   versão maior/mais proporcional a partir de tablet/desktop. */
.tela-login {
  min-height: 100vh;
  /* 100dvh (altura "dinâmica" do viewport) em vez de 100vh: no Safari/Chrome do
     iPhone, 100vh conta com a barra de endereço RECOLHIDA, que nem sempre é o
     estado real da tela — isso podia deixar uma sobra de espaço embaixo (ou
     forçar rolagem) só por causa da barra do navegador aparecer/sumir ao rolar.
     Navegadores que não conhecem dvh ignoram a linha e ficam só com o 100vh
     acima, sem quebrar nada. */
  min-height: 100dvh;
  display: flex;
  align-items: center;
  justify-content: center;
  background:
    radial-gradient(circle at 20% 15%, rgba(163,201,100,.25), transparent 45%),
    linear-gradient(160deg, var(--primaria-clara), var(--primaria-escura) 70%);
  /* env(safe-area-inset-*) soma a área do notch/Dynamic Island (topo) e do
     indicador de home (embaixo) ao padding normal — sem isso, em pé, o cartão
     de login podia nascer colado demais nessas áreas em aparelhos com esses
     recortes. Em aparelho sem notch, o env() vale 0 e não muda nada. */
  padding: calc(32px + env(safe-area-inset-top)) 24px calc(32px + env(safe-area-inset-bottom));
  overflow-y: auto;
}
.login-wrap { width: 100%; max-width: 380px; display: flex; flex-direction: column; align-items: center; }
.login-logo { width: 100%; max-width: 280px; margin-bottom: 28px; filter: drop-shadow(0 8px 20px rgba(0,0,0,.25)); }
.login-card {
  background: var(--card);
  border-radius: 20px;
  padding: 30px 26px 26px;
  width: 100%;
  box-shadow: var(--sombra-forte);
}
.login-card .login-chamada { margin: 0 0 2px; color: var(--destaque-escuro); font-size: .78rem; font-weight: 700; text-transform: uppercase; letter-spacing: .08em; }
.login-card h1 { margin: 0 0 20px; font-size: 1.35rem; color: var(--primaria); font-weight: 700; }
.login-card label { display: block; font-size: .8rem; color: var(--texto-suave); margin: 14px 0 6px; font-weight: 600; }
.login-card input {
  width: 100%; padding: 13px 14px; border-radius: 11px; border: 1.5px solid var(--borda); font-size: 1rem;
  background: #FAFBFC; transition: border-color .15s, background .15s;
}
.login-card input:focus {
  outline: none; border-color: var(--primaria-clara); background: #fff;
}
.login-card button {
  margin-top: 22px; width: 100%; padding: 14px; border: none; border-radius: 11px;
  background: var(--primaria); color: #fff; font-size: 1rem; font-weight: 700;
  transition: background .15s, transform .1s;
  box-shadow: 0 8px 18px rgba(18,61,102,.28);
}
.login-card button:active { transform: scale(.98); background: var(--primaria-escura); }
.erro { color: var(--vermelha); font-size: .85rem; margin-top: 12px; text-align: center; }
.login-rodape { color: rgba(255,255,255,.7); font-size: .74rem; margin-top: 24px; text-align: center; }

/* ---- Celular DEITADO: modo compacto ----
   orientation:landscape + altura curta (max-height:500px cobre qualquer iPhone
   deitado, do SE ao Pro Max — o maior deles chega a ~430px de altura útil) é o
   sinal certo de "pouca altura de verdade", sem precisar de nenhuma classe JS:
   um iPad, mesmo deitado, nunca fica tão baixo (menor deles passa de 750px),
   então esse bloco nunca pega tablet, só telefone de verdade virado de lado.
   Sem isso, logo (28px de margem + até 280px de largura, proporcional em
   altura) + cartão com bastante respiro + rodapé somados passam fácil da altura
   da tela, empurrando o botão Entrar pra fora da área visível sem rolagem óbvia
   pro usuário perceber. Em vez de cortar, comprime tudo pra caber inteiro. */
@media (orientation: landscape) and (max-height: 500px) {
  .tela-login { align-items: flex-start; padding-top: calc(14px + env(safe-area-inset-top)); padding-bottom: calc(14px + env(safe-area-inset-bottom)); }
  .login-wrap { max-width: 340px; }
  .login-logo { max-width: 110px; margin-bottom: 10px; }
  .login-card { padding: 16px 20px 14px; border-radius: 16px; }
  .login-card .login-chamada { font-size: .68rem; }
  .login-card h1 { font-size: 1.05rem; margin-bottom: 10px; }
  .login-card label { margin: 8px 0 4px; font-size: .74rem; }
  .login-card input { padding: 9px 12px; }
  .login-card button { margin-top: 12px; padding: 10px; }
  .login-rodape { margin-top: 10px; font-size: .64rem; }
}

/* ---- Tablet/desktop: cartão proporcional à tela grande ----
   Puramente por largura de viewport (sem depender de toque/orientação real):
   mesmo um iPad "disfarçado" de computador só ganha um cartão de login maior e
   mais bonito, nunca um comportamento diferente — não existe risco de bug de
   zoom/rolagem aqui como em outras telas do sistema, é só um cartão estático
   centralizado, então não precisa da blindagem extra que outras partes do
   projeto usam pra separar iPad de Mac de verdade. */
@media (min-width: 600px) {
  .login-wrap { max-width: 420px; }
  .login-logo { max-width: 300px; margin-bottom: 32px; }
  .login-card { padding: 38px 36px 32px; border-radius: 24px; }
  .login-card .login-chamada { font-size: .82rem; }
  .login-card h1 { font-size: 1.55rem; margin-bottom: 24px; }
  .login-card label { font-size: .84rem; }
  .login-card input { padding: 14px 16px; font-size: 1.02rem; }
  .login-card button { padding: 15px; font-size: 1.02rem; }
  .login-rodape { font-size: .8rem; margin-top: 28px; }
}

/* ---------- APP ---------- */
/* Achado do Netto: no celular, quando a página tem pouco conteúdo, dava pra
   continuar arrastando pra baixo bem depois do fim das informações, sem limite
   nenhum visível. Causa: min-height:100vh no Safari/Chrome do iPhone conta com a
   barra de endereço RECOLHIDA (o valor "cheio" da tela) — quando ela está expandida
   (estado normal ao abrir o app), o navegador reserva aquele espaço extra mesmo
   assim, sobrando uma faixa em branco arrastável depois do rodapé. 100dvh (altura
   "dinâmica" de verdade) resolve isso, mesmo padrão já usado em .tela-login pro
   mesmo tipo de sobra de espaço — navegador que não conhece dvh ignora a linha e
   fica só com 100vh, sem quebrar nada.*/
.app { min-height: 100vh; min-height: 100dvh; display: flex; flex-direction: column; padding-bottom: 74px; }

/* Cabeçalho em 3 colunas (logo | título centralizado | ações), para o "Painel
   Financeiro" ficar sempre no centro de verdade, não só encostado na logo. */
.topo {
  background: var(--primaria); color: #fff; padding: 10px 14px;
  padding-top: calc(10px + env(safe-area-inset-top));
  display: grid; grid-template-columns: auto 1fr auto; align-items: center; column-gap: 8px;
  position: sticky; top: 0; z-index: 10;
  box-shadow: 0 2px 12px rgba(11,42,73,.18);
}
.topo-marca { display: flex; align-items: center; min-width: 0; }
/* Logo completa (com o nome escrito), sem cortar nada, como no sistema desktop. */
.topo-icone { height: 52px; width: auto; display: block; flex: none; }
.topo-titulo {
  font-size: .92rem; font-weight: 700; letter-spacing: -.01em; text-align: center;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.topo-acoes { display: flex; align-items: center; gap: 6px; justify-self: end; }
.btn-icone-topo {
  background: rgba(255,255,255,.14); color: #fff; border: none; border-radius: 10px; padding: 8px;
  display: flex; align-items: center; justify-content: center;
}
.btn-icone-topo:disabled { opacity: .32; }
/* Só o botão de Limpar anexos ganha texto (ver index.html); desfazer/refazer/sair
   continuam só ícone em qualquer tamanho de tela — texto só cabe/faz sentido a
   partir do computador, onde a barra de topo tem espaço sobrando (ver override em
   min-width:1024px). No celular fica exatamente como já era: só o ícone. */
.btn-limpar-anexos-texto { display: none; }
/* Abaixo de 1024px o ícone de Limpar anexos sai do cabeçalho e entra dentro do
   menu "..." (ver #btn-mais-topo), pra sobrar espaço pro título "Painel
   Financeiro" não ser cortado. A partir de 1024px volta a aparecer no cabeçalho
   do jeito que já era (ver display:flex no override de min-width:1024px). */
#btn-limpar-anexos-topo { display: none; }
/* Mesma lógica: Desfazer/Refazer saem do cabeçalho abaixo de 1024px e entram no
   menu "..." (pedido do Netto, ordem: Desfazer, Refazer, Limpar anexos, Usuários,
   Auditoria, Configurações — ver abrirMenuMaisMobile no app.js). É o MESMO botão
   do computador, só escondido por CSS; o listener de clique e a trava de
   histórico (desabilita sozinho sem nada pra desfazer/refazer) continuam os
   mesmos, sem duplicar lógica. */
#btn-desfazer, #btn-refazer { display: none; }
/* Pedido do Netto: no celular DEITADO sobra largura de sobra (diferente do em
   pé, onde os 2 ícones ajudavam a espremer o título), então Desfazer/Refazer
   voltam pro cabeçalho, saindo do menu "...". Faixa 700-1023px: nenhum iPhone
   em pé chega a 700px (o maior é ~430px) e nenhum iPad deitado fica abaixo de
   1024px — é território exclusivo de celular deitado de verdade. A trava extra
   ":not(.orientacao-retrato-real)" é por segurança: um iPad em pé que a Apple
   disfarce com largura estreita demais (fora do normal) ainda cai fora daqui,
   porque o sensor de giroscópio (não a largura, que é fingível) confirma que
   ele está em pé. */
@media (min-width: 700px) and (max-width: 1023px) {
  html.dispositivo-tablet-real:not(.orientacao-retrato-real) #btn-desfazer,
  html.dispositivo-tablet-real:not(.orientacao-retrato-real) #btn-refazer {
    display: flex;
  }
}
.btn-sair {
  background: rgba(255,255,255,.14); color: #fff; border: none; border-radius: 10px; padding: 9px;
  display: flex; align-items: center; justify-content: center;
}
.btn-sair:active { background: rgba(255,255,255,.24); }

.conteudo { flex: 1; padding: 18px 16px; }

/* Busca global do cabeçalho: só existe a partir da tela larga (lá o celular busca
   dentro de cada lista); "Limpar anexos" virou ícone (ver index.html) e agora fica
   visível em qualquer tamanho de tela, igual desfazer/refazer, sem depender mais de
   nenhuma aba pra ser acionado. */
.topo-busca { display: none !important; }

/* Achado do Netto: com 8 abas (antes eram 7), o flex:1 de cada uma espremia tudo
   demais no iPhone pra caber a força na largura da tela. Em vez de encolher
   ícone/texto até ficar ilegível, a barra agora rola na horizontal — cada aba
   mantém o tamanho normal (mesmo ícone, mesmo texto) e quem quiser ver as abas
   de fora da tela arrasta pro lado, igual ao seletor de "Análise dinâmica" e outras
   faixas com rolagem própria que o sistema já usa em outros lugares. */
.nav-inferior {
  position: fixed; bottom: 0; left: 0; right: 0; background: var(--card);
  display: flex; border-top: 1px solid var(--borda);
  padding-bottom: env(safe-area-inset-bottom);
  z-index: 10;
  box-shadow: 0 -4px 16px rgba(18,61,102,.05);
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
  /* Achado do Netto: no celular deitado (mais largo que em pé) as abas cabiam
     todas sem precisar rolar, mas ficavam coladas à esquerda, com um vão vazio
     grande à direita — pedido pra centralizar quando sobra espaço. "safe center"
     centraliza só quando cabe; se não couber (celular em pé, sempre rola), cai
     sozinho pro alinhamento à esquerda de sempre, sem esconder nenhuma aba do
     lado de fora do toque. A linha de cima (flex-start) é o valor que fica de
     pé em navegadores antigos que não entendem "safe center" — nada muda pra
     eles, zero risco. */
  justify-content: flex-start;
  justify-content: safe center;
}
.nav-inferior::-webkit-scrollbar { display: none; }
/* Largura calculada (1/5 da faixa) em vez de largura livre por conteúdo: antes
   cabiam 5 abas inteiras e sobrava uma tirinha da 6ª — pedaço de aba cortado
   que o Netto achou feio, igual o problema já resolvido nos cartões do
   Dashboard. Com 1/5 exato, 5 abas preenchem a faixa toda sem sobra nenhuma; as
   demais (Orçamento, Relatórios) ficam por conta da rolagem, sem espiar cortadas. */
.nav-item {
  flex: 0 0 calc(100% / 5); min-width: 74px; background: none; border: none; padding: 10px 6px 8px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  font-size: .6rem; color: var(--texto-suave); font-weight: 600; line-height: 1;
  transition: color .15s, transform .1s ease;
  scroll-snap-align: start;
}
/* Feedback tátil ao tocar numa aba no celular (não existia nenhum antes — o dedo
   tocava e nada indicava visualmente que o toque foi registrado até a tela trocar). */
.nav-item:active { transform: scale(.92); }
/* display:block tira uma folga invisível que o SVG inline ganha por padrão (herdada
   do alinhamento de texto), que fazia os ícones parecerem "descentralizados" entre
   si mesmo com o mesmo tamanho. Aumentei um pouco o tamanho também, a pedido do Netto. */
.nav-item svg { width: 23px; height: 23px; stroke-width: 2; flex: none; display: block; }
/* Uniforme mesmo com nomes de tamanhos diferentes (Início x Fornecedores): uma linha
   só, sem quebrar e sem empurrar os ícones para alturas diferentes. */
.nav-item span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; line-height: 1.3; }
.nav-item.ativo { color: var(--primaria); }
.nav-item.ativo svg { stroke: var(--primaria); }

/* ---------- CARDS / DASHBOARD ---------- */
.grid-cards { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 22px; }

/* Faixa única com rolagem horizontal para os cartões de saldo, igual à faixa de KPIs
   em linha do sistema desktop. Evita empilhar muitos cartões e "poluir" a tela no
   celular; a rolagem fica contida só nessa faixa, sem esticar o resto do painel. */
.tira-cards {
  display: flex; gap: 10px; overflow-x: auto; margin-bottom: 22px; padding-bottom: 4px;
  -webkit-overflow-scrolling: touch; scroll-snap-type: x proximity;
}
/* Largura calculada (2 cartões + o vão entre eles = 100% da faixa), não mais um
   valor fixo em px: antes (140px) sobrava espaço suficiente pra "espiar" um
   pedaço grande do 3º cartão, o que o Netto achou feio. Assim os 2 primeiros
   preenchem a faixa exatamente, sem sobra, e o 3º só aparece rolando de vez. */
.tira-cards .card { flex: 0 0 calc((100% - 10px) / 2); scroll-snap-align: start; padding: 11px 10px; }

/* Sem a legenda embaixo do valor (removida a pedido do Netto), o cartão não precisa
   mais da mesma altura de antes — padding reduzido (18/16 -> 14/12) deixa o cartão
   mais enxuto sem cortar nada, já que agora só tem 2 linhas de texto (rótulo + valor). */
.card {
  background: var(--card); border-radius: var(--raio); padding: 14px 12px; box-shadow: var(--sombra);
  border: 1px solid var(--borda); text-align: center;
  transition: box-shadow .2s var(--easing), transform .2s var(--easing), border-color .2s var(--easing);
}
/* Classe própria pra cartão clicável (troca o antigo seletor [style*="cursor:pointer"],
   mais frágil): mesmo efeito de hover/active, só que via classe de verdade. */
.card-clicavel { cursor: pointer; }
/* Redesenho: --sombra-media (nível intermediário) em vez de pular direto pra
   --sombra-forte (reservada pro modal, o elemento mais "em primeiro plano" da
   tela) — um card levantando não deveria competir visualmente com um modal aberto. */
.card[style*="cursor:pointer"]:hover, .card-clicavel:hover { box-shadow: var(--sombra-media); transform: translateY(-2px); border-color: #D7E0EA; }
.card[style*="cursor:pointer"]:active, .card-clicavel:active { transform: translateY(0) scale(.98); }
.card .rotulo {
  font-size: .62rem; color: var(--texto-suave); text-transform: uppercase; letter-spacing: .02em;
  font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.card .valor { font-size: 1.05rem; font-weight: 700; margin-top: 5px; color: var(--primaria); letter-spacing: -.01em; }
.card .valor.verde { color: var(--verde); }
.card .valor.vermelha { color: var(--vermelha); }
.card .valor.laranja { color: var(--laranja); }

/* Igual ao formSectionTitle do sistema desktop: azul (cor primária), centralizado,
   com uma linha fina embaixo separando da seção anterior. */
.secao-titulo {
  font-size: .94rem; font-weight: 700; margin: 22px 0 10px; color: var(--primaria);
  text-align: var(--alinhamento-titulos); padding-bottom: 6px; border-bottom: 1px solid var(--borda);
}

.card .legenda { font-size: .68rem; color: var(--texto-suave); margin-top: 3px; }

/* ---------- Cabeçalho de seção (identifica o módulo + ordenação no celular) ----------
   Pedido do Netto: hoje não existe nenhuma identificação de qual módulo a pessoa
   está vendo (o cabeçalho fixo do topo sempre mostra "Painel Financeiro", nunca o
   nome da aba), e no celular também não existe como trocar a ordenação da lista
   (só a tabela do computador tem cabeçalho de coluna clicável). Um bloco só resolve
   os dois, lado a lado: título + descrição curta do módulo à esquerda, seletor de
   ordenação à direita (ver cabecalhoSecao() no app.js). */
.cabecalho-secao {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 12px;
  margin-bottom: 14px;
}
.cabecalho-secao-texto h2 { margin: 0; font-size: 1.1rem; font-weight: 700; color: var(--primaria); }
.cabecalho-secao-texto p { margin: 2px 0 0; font-size: .76rem; color: var(--texto-suave); }
.ordenacao-mobile { display: flex; align-items: center; gap: 6px; flex: none; }
.ordenacao-mobile select {
  font-size: .8rem; padding: 7px 10px; border-radius: 9px; border: 1px solid var(--borda);
  background: var(--card); color: var(--texto); max-width: 148px;
}
.btn-direcao-ordenacao {
  width: 34px; height: 34px; flex: none; border-radius: 9px; border: 1px solid var(--borda);
  background: var(--card); color: var(--primaria); font-size: 1rem; font-weight: 700; line-height: 1;
}
.btn-direcao-ordenacao:active { background: #EEF4FA; }
/* A partir do tablet/computador, a própria tabela já ordena clicando no cabeçalho
   da coluna (ver celulaCabecalho/ordenarTabela no app.js) — mostrar os dois juntos
   seria redundante, então o seletor mobile some aqui. O título+descrição continuam
   visíveis em qualquer tela, já que a identificação do módulo vale nos dois casos. */
@media (min-width: 1024px) {
  .ordenacao-mobile { display: none; }
}

/* Moldura do gráfico dinâmico (QFrame#chartCard do Mac): altura FIXA de 310px, não
   cresce com a largura da tela. O seletor de visão fica no topo e o canvas ocupa o
   resto do quadro (flex:1) — junto com maintainAspectRatio:false no Chart.js (ver
   app.js), isso evita o gráfico gigante que aparecia em monitor largo. */
.cartao-grafico {
  background: var(--card); border: 1px solid var(--borda); border-radius: var(--raio);
  padding: 14px 9px; margin-bottom: 22px; height: 310px;
  display: flex; flex-direction: column;
  box-shadow: 0 4px 18px rgba(18,61,102,.11);
}
/* dynamic_top no Mac é uma linha (QHBoxLayout) com o título à esquerda, um stretch
   e o seletor de visão à direita — bem menor que a largura toda, não um campo de
   busca esticado como eu tinha colocado. */
.cartao-grafico-topo { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 8px; flex: none; }
/* Achado do Netto: título e seletor com largura fixa (flex:none), brigando pelo
   mesmo espaço, estouravam a largura do cartão num celular estreito (o seletor
   "passava do card"). Primeira tentativa cortou o título com "..." quando
   faltava espaço — o Netto preferiu diminuir a fonte do título até caber
   inteiro, nunca cortar o texto. Por isso agora o título tem largura própria
   (flex:none, sem encolher) numa fonte menor que já cabe sozinha em qualquer
   tela, e quem absorve toda a variação de espaço é só o seletor (flex:1,
   min-width:0, com o próprio texto selecionado cortando sozinho se precisar —
   isso é nativo do <select>, não afeta a leitura do título). */
.cartao-grafico-titulo {
  font-size: .78rem; font-weight: 700; color: var(--primaria);
  flex: none; white-space: nowrap;
}
.cartao-grafico-topo select {
  /* font-size 16px: abaixo disso o Safari do iPhone dá zoom na tela ao tocar num
     <select> também, não só em <input> — esse seletor fica bem no Dashboard, a
     primeira tela que qualquer pessoa vê ao abrir o app. */
  flex: 1 1 auto; min-width: 0; width: auto; max-width: 240px; padding: 7px 10px; border-radius: 9px;
  border: 1px solid var(--borda); font-size: 1rem; background: var(--card); color: var(--texto);
}
.cartao-grafico-area { flex: 1; min-height: 0; position: relative; }

/* Faixa de governança: no Mac os 3 cartões (Top fornecedor + as duas pendências) ficam
   lado a lado; no celular o Top fornecedor (.card-top) fica sozinho em cima, largura
   total, e só as duas pendências dividem esta linha embaixo. */
/* top_fornecedor_selector no Mac: QComboBox largura FIXA 180px, altura 30px, texto
   centralizado, centralizado dentro do próprio cartão (insertWidget com
   Qt.AlignCenter) — não um campo de busca esticado igual eu tinha colocado. */
.card-top { text-align: center; }
.card-top .seletor-top-fornecedor {
  /* Largura 195px (medida exata do QComboBox do Mac). A altura FIXA de 34px
     (achado do Netto no iPad deitado) cortava o texto "Top 1 Fornecedor" —
     o <select> nativo do Safari/iPadOS reserva mais espaço vertical pro texto
     do que o Chrome/desktop reservava, então 34px sobrava no Mac mas faltava
     no iPad. Trocado height fixo por min-height (nunca fica menor que isso,
     mas cresce sozinho se a plataforma precisar de mais espaço pro texto não
     cortar) + line-height explícito, em vez de depender do valor padrão do
     navegador (que varia de plataforma pra plataforma e foi a causa real do
     corte). */
  width: 195px; min-height: 40px; line-height: 1.3; margin: 0 auto 10px; display: block;
  padding: 6px 10px; border-radius: 9px; border: 1px solid var(--borda);
  font-size: 1rem; text-align: center; text-align-last: center; background: var(--card); color: var(--texto);
}
.linha-governanca { display: flex; gap: 10px; margin-bottom: 22px; align-items: stretch; }
.linha-governanca .card { flex: 1; min-width: 0; }
/* Número principal das duas pendências (financeiras/SALIC): no Mac é o QLabel#pendencyValue,
   bem maior e mais pesado que o valor comum dos outros cartões (é o dado que importa
   nesses dois cartões). As duas legendas de baixo também têm objectName próprio
   (pendencySub em negrito escuro, pendencyDetail menor e mais claro) e, principalmente,
   as DUAS têm sempre exatamente essas duas linhas — nunca uma terceira linha condicional —
   pra financeiras e SALIC renderizarem sempre do mesmo tamanho, com ou sem pendência. */
.linha-governanca .card .valor { font-size: 1.7rem; margin-top: 6px; }
.linha-governanca .card .legenda-sub { font-size: .74rem; font-weight: 700; color: #334155; margin-top: 5px; }
.linha-governanca .card .legenda-detail { font-size: .68rem; color: #6B7280; margin-top: 3px; }

/* Antes o ID (LAN-001/FOR-001/FIN-001/ORC-001) ficava na MESMA linha do nome, com
   "travessão" entre os dois, e a linha inteira cortava com "..." assim que estourava
   a largura do cartão. Com o prefixo de 3 dígitos (padronização pedida pelo Netto), o
   ID passou a ocupar mais espaço de texto, sobrando menos para o nome — daí nomes de
   fornecedor/financiador ficarem cortados no celular. Fix: o ID vira uma linha própria,
   pequena e discreta (display:block), acima do nome — assim ele nunca mais disputa
   espaço de texto com o nome. O nome ganha a linha toda pra ele. */
.id-tag {
  display: block; color: var(--texto-suave); font-weight: 700;
  font-size: .72rem; letter-spacing: .02em; margin-bottom: 2px;
}

/* Igual à regra de cor de fundo do sistema desktop: lançamento ainda sem prestação de
   contas enviada fica com um fundo vermelho claro na lista, para chamar atenção. */
.linha-lista.linha-pendente-pc { background: var(--vermelha-bg); border-color: var(--vermelha-bg); }

.barra-progresso { background: #EEF1F4; border-radius: 8px; height: 7px; overflow: hidden; margin-top: 10px; }
.barra-progresso > div { background: linear-gradient(90deg, var(--destaque-escuro), var(--destaque)); height: 100%; border-radius: 8px; }
/* Regra de cor do orçamento igual ao sistema desktop: verde (100% executado), laranja
   (em andamento) ou vermelho (ainda não iniciado). */
.barra-progresso > div.verde { background: var(--verde); }
.barra-progresso > div.laranja { background: var(--laranja); }
.barra-progresso > div.vermelha { background: var(--vermelha); }

/* Barra de execução financeira do painel (QProgressBar#mainProgress no Mac): fundo
   branco, borda #D1D5DB, cantos 10px, altura entre 28 e 32px — igual ao QSS exato —
   com o texto centralizado por CIMA de toda a barra (preenchida ou não), não um
   título e número empilhados acima de uma tarja fina. */
.barra-progresso-principal {
  position: relative; background: #fff; border: 1px solid #D1D5DB; border-radius: 10px;
  min-height: 30px; overflow: hidden;
}
.barra-progresso-principal-preenchimento {
  /* O usuário confirmou direto no sistema real: o preenchimento dessa barra é verde
     (não o dourado do valor padrão de cor_destaque que eu tinha usado, já que não
     dá pra checar remotamente qual cor está configurada de fato no Mac). */
  position: absolute; top: 0; left: 0; height: 100%; background: var(--verde); border-radius: 10px; z-index: 0;
}
/* Texto ganhou o comparativo Executado x Saldo (pedido do Netto, ver renderDashboard
   em app.js) — bem mais longo que só a porcentagem de antes. Trocado de
   position:absolute+inset:0 (uma linha só, cortava em tela estreita) pra fluxo normal
   com white-space:normal: quebra em 2 linhas sozinho quando não couber, e a barra
   (min-height, não height fixo) cresce junto — sem isso o texto ficava cortado ou
   vazando da barra no celular. */
.barra-progresso-principal-texto {
  position: relative; z-index: 1; width: 100%; box-sizing: border-box;
  display: flex; align-items: center; justify-content: center; text-align: center;
  padding: 7px 10px; white-space: normal; line-height: 1.3;
  font-size: .84rem; font-weight: 700; color: var(--primaria);
}
@media (max-width: 480px) {
  .barra-progresso-principal-texto { font-size: .74rem; }
}

/* Número de WhatsApp do fornecedor: usado tanto na tabela do computador quanto no
   cartão do celular (ver renderFornecedores em app.js) — por isso fica FORA de
   qualquer @media de tela larga, senão não aparecia estilizado no celular (onde
   esse cartão é o único jeito de ver o contato). Cor verde mostra que é clicável
   sem depender só do sublinhado padrão de link do navegador. */
.celula-whatsapp { color: var(--verde); font-weight: 600; cursor: pointer; text-decoration: underline dotted; }
/* Flash verde de confirmação ao copiar por clique direito (desktop) ou toque
   longo (celular) — ver copiarValorCelula em app.js. Genérico (não só dentro de
   tabela) porque também cobre o span de WhatsApp no cartão do celular. Some
   sozinho depois de meio segundo, não precisa de clique nenhum pra fechar. */
.celula-copiada { background: #DCFCE7 !important; transition: background-color .4s ease; }

.linha-lista {
  background: var(--card); border-radius: 13px; padding: 14px 16px; margin-bottom: 9px;
  display: flex; justify-content: space-between; align-items: center; gap: 10px;
  border: 1px solid var(--borda);
  transition: box-shadow .2s var(--easing), transform .12s var(--easing), border-color .2s var(--easing);
}
.linha-lista:active { transform: scale(.99); }
@media (hover: hover) {
  .linha-lista:hover { box-shadow: var(--sombra-media); border-color: #D7E0EA; transform: translateY(-1px); }
}

/* Cartão centralizado (só aparece no celular; a partir de 1024px vira tabela, ver
   .vista-cartoes): tudo centralizado — em altura (padding igual dos 4 lados), largura
   (text-align:center) e comprimento (cada linha ocupa a largura toda, sem nada
   "sobrando" de um lado) — organização criada primeiro pro Orçamento (pedido do Netto,
   no lugar do título-à-esquerda x valor-à-direita de antes) e depois adotada como
   padrão em Lançamentos, Fornecedores e Financiadores também (mesmo pedido, "copiar a
   organização do Orçamento" pros outros 3 módulos). .cartao-orcamento continua existindo
   só porque a barra de progresso é exclusiva dele; os outros 3 usam .cartao-centralizado,
   que só herda o alinhamento — sem barra, porque nenhum dos 3 tem "executado/restante". */
.cartao-orcamento, .cartao-centralizado {
  flex-direction: column; align-items: center; text-align: center; gap: 4px; padding: 12px 14px;
}
.cartao-orcamento .valor, .cartao-centralizado .valor { font-size: 1.05rem; }
.cartao-orcamento .barra-progresso { width: 100%; margin-top: 4px; }

/* No celular DEITADO volta o valor pra frente, do jeito que já era antes de centralizar
   (pedido do Netto): sobra largura de sobra nessa orientação, então o layout
   lado-a-lado aproveita melhor o espaço do que empilhado. Usa grid em vez de flex pra
   não precisar mexer no HTML: título em cima à esquerda, detalhe(s) embaixo dele na
   mesma coluna, e o valor ocupando a coluna da direita, alto o bastante pra cobrir
   título+detalhe(s) e verticalmente centralizado. A barra de progresso do Orçamento
   (quando existir) sempre vira uma linha própria, ocupando a largura toda embaixo de
   tudo. Mesmo seletor "celular real deitado" já usado no resto do sistema (nem iPad,
   nem celular em pé disfarçado de tablet largo). */
@media (min-width: 700px) and (max-width: 1023px) {
  html.dispositivo-tablet-real:not(.orientacao-retrato-real) .cartao-orcamento,
  html.dispositivo-tablet-real:not(.orientacao-retrato-real) .cartao-centralizado {
    display: grid; grid-template-columns: 1fr auto; align-items: start;
    column-gap: 12px; text-align: left; padding: 14px 16px;
  }
  html.dispositivo-tablet-real:not(.orientacao-retrato-real) .cartao-orcamento .titulo,
  html.dispositivo-tablet-real:not(.orientacao-retrato-real) .cartao-centralizado .titulo,
  html.dispositivo-tablet-real:not(.orientacao-retrato-real) .cartao-orcamento .detalhe,
  html.dispositivo-tablet-real:not(.orientacao-retrato-real) .cartao-centralizado .detalhe {
    grid-column: 1;
  }
  html.dispositivo-tablet-real:not(.orientacao-retrato-real) .cartao-centralizado .valor {
    grid-column: 2; grid-row: 1 / -1; align-self: center; justify-self: end;
  }
  html.dispositivo-tablet-real:not(.orientacao-retrato-real) .cartao-orcamento .valor {
    grid-column: 2; grid-row: 1 / span 3; align-self: center; justify-self: end;
  }
  html.dispositivo-tablet-real:not(.orientacao-retrato-real) .cartao-orcamento .barra-progresso {
    grid-column: 1 / -1;
  }
}

.linha-lista .info { flex: 1; min-width: 0; }
/* Nome agora quebra em até 2 linhas (em vez de cortar tudo numa linha só com "..."),
   já que o ID saiu para sua própria linha acima (ver .id-tag) e não precisa mais
   disputar espaço de texto com o nome. Corta com "..." só se passar de 2 linhas. */
.linha-lista .titulo {
  font-weight: 700; font-size: .93rem; color: var(--texto);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; text-overflow: ellipsis; white-space: normal;
}
.linha-lista .detalhe { font-size: .78rem; color: var(--texto-suave); margin-top: 2px; }
.linha-lista .valor { font-weight: 700; font-size: .93rem; white-space: nowrap; }

.busca {
  /* font-size mínimo de 16px (1rem): abaixo disso o Safari do iPhone dá zoom
     automático na página inteira assim que o campo ganha foco, obrigando a
     pessoa a dar pinça pra voltar ao tamanho normal toda vez que for buscar
     algo — comportamento nativo do iOS, não tem como desligar, só evitar
     ficando em 16px ou mais. */
  width: 100%; padding: 13px 15px; border-radius: 13px; border: 1.5px solid var(--borda);
  font-size: 1rem; margin-bottom: 14px; background: var(--card);
}
.busca:focus { outline: none; border-color: var(--primaria-clara); }

/* Achado do Netto: em Financiadores, a partir do computador, essa busca de dentro
   da lista e a busca do cabeçalho (.topo-busca) mostravam o mesmo texto "Buscar
   financiador..." ao mesmo tempo — duas caixas fazendo a mesma coisa. Escondida
   só a partir de 1024px, só pra este módulo: no celular ela continua sendo a
   ÚNICA forma de buscar (a busca do topo fica escondida lá, ver .topo-busca). */
@media (min-width: 1024px) {
  #busca-financiadores { display: none; }
}

.btn-flutuante {
  position: fixed; right: 18px; bottom: 90px; width: 56px; height: 56px; border-radius: 50%;
  background: var(--primaria); color: #fff; border: none; font-size: 1.7rem; line-height: 1;
  box-shadow: 0 10px 24px rgba(18,61,102,.35);
  display: flex; align-items: center; justify-content: center;
  z-index: 9;
}
.btn-flutuante:active { transform: scale(.95); }

.btn-primario, .btn-secundario, .btn-perigo {
  transition: transform .16s var(--easing), background-color .18s var(--easing), box-shadow .2s var(--easing), filter .18s var(--easing);
}
/* Levantada sutil no hover (só em telas com mouse de verdade — "hover:hover" evita
   esse efeito ficar "grudado" depois de um toque no celular, onde não existe cursor
   pairando de fato). Dá aquele feedback de "isso aqui é clicável" sem exagerar. */
@media (hover: hover) {
  .btn-primario:hover, .btn-secundario:hover, .btn-perigo:hover { transform: translateY(-1px); }
}
.btn-primario:active, .btn-secundario:active, .btn-perigo:active { transform: scale(.97); }
.btn-primario {
  background: var(--primaria); color: #fff; border: none; border-radius: 11px; padding: 13px; font-size: .95rem;
  font-weight: 700; width: 100%; box-shadow: 0 6px 16px rgba(18,61,102,.22);
}
.btn-primario:active { background: var(--primaria-escura); }
/* Redesenho: sombra cresce junto no hover (não só o brilho), reforçando a sensação
   de elevação/profundidade em vez de só clarear a cor. */
@media (hover: hover) {
  .btn-primario:hover { filter: brightness(1.08); box-shadow: 0 10px 22px rgba(18,61,102,.3); }
}
.btn-secundario {
  background: #EEF1F4; color: var(--texto); border: none; border-radius: 11px; padding: 12px; font-size: .9rem;
  width: 100%; margin-top: 8px; font-weight: 600;
}
.btn-secundario:hover { filter: brightness(.96); }
/* Desfazer/Refazer dentro do menu "..." (ver abrirMenuMaisMobile): sem isso, o
   botão desabilitado (nada pra desfazer/refazer) ficava com a mesma cara de um
   botão clicável, só não reagindo ao toque — visual confuso. */
.btn-secundario:disabled { opacity: .45; }
.btn-perigo {
  background: var(--vermelha-bg); color: var(--vermelha); border: none; border-radius: 11px; padding: 12px;
  font-size: .88rem; font-weight: 700; width: 100%; margin-top: 10px;
}
.btn-perigo:hover { filter: brightness(.96); }

/* Redesenho: anel de foco consistente com a marca em qualquer botão/link navegado
   por teclado (Tab), em vez do anel azul-genérico padrão do navegador, acessibilidade
   e identidade visual resolvidas na mesma correção. :focus-visible (não :focus puro)
   só aparece pra quem navega por teclado, nunca ao clicar/tocar com o mouse/dedo. */
.btn-primario:focus-visible, .btn-secundario:focus-visible, .btn-perigo:focus-visible,
.sidebar-btn:focus-visible, .nav-item:focus-visible, .btn-flutuante:focus-visible {
  outline: 2px solid var(--primaria-clara);
  outline-offset: 2px;
}

.form-campo { margin-bottom: 13px; }
.form-campo label { display: block; font-size: .78rem; color: var(--texto-suave); margin-bottom: 5px; font-weight: 600; }
/* font-size 16px (1rem) é o mínimo pra não disparar o zoom automático do Safari no
   iPhone ao tocar no campo — estava em .95rem (15.2px) e isso incluía o campo de
   saldo do novo Confronto, o mais usado do módulo de Rendimentos. Sem o zoom
   automático, o teclado abre e fecha sem a tela "pular" de tamanho. */
.form-campo input, .form-campo select, .form-campo textarea {
  width: 100%; padding: 12px; border-radius: 10px; border: 1.5px solid var(--borda); font-size: 1rem; background: #FAFBFC;
}
.form-campo input:focus, .form-campo select:focus, .form-campo textarea:focus { outline: none; border-color: var(--primaria-clara); background: #fff; }
/* Campo calculado (ex.: Valor Total do Orçamento = Quantidade x Ocorrência x Valor
   unitário): visual diferente de um campo digitável, pra ficar claro que é resultado,
   não entrada manual — sem precisar de disabled (que atrapalharia leitura via JS). */
.form-campo input[readonly] { background: var(--fundo); color: var(--texto-suave); cursor: not-allowed; }
.form-linha { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }

/* Campo Contato do Fornecedor com ícone de WhatsApp ao lado (pedido do Netto:
   tirar o link do cartão da lista, deixar só aqui dentro do formulário). O ícone
   só aparece quando o texto do campo parece um número válido (ver
   atualizarIconeWhatsappContato em app.js), começa escondido via display:none
   inline pra não "piscar" antes do JS rodar. */
.campo-com-icone { display: flex; align-items: center; gap: 10px; }
.campo-com-icone input { flex: 1; }
.icone-whatsapp-form {
  display: none; align-items: center; justify-content: center;
  width: 40px; height: 40px; flex-shrink: 0; border-radius: 50%;
  background: var(--verde); color: #fff; cursor: pointer;
}
.icone-whatsapp-form svg { width: 22px; height: 22px; }

/* Campo de anexo igual ao AnexoField do sistema desktop: botão de anexar, botão de
   remover ao lado e um rótulo mostrando o nome do arquivo atual. */
.anexo-campo { margin-bottom: 13px; }
.anexo-campo label { display: block; font-size: .78rem; color: var(--texto-suave); margin-bottom: 5px; font-weight: 600; }
.anexo-linha { display: flex; gap: 8px; align-items: center; }
.anexo-linha .btn-anexar {
  flex: 1; background: #EEF1F4; color: var(--texto); border: none; border-radius: 10px; padding: 11px; font-size: .88rem; font-weight: 700;
}
.anexo-linha .btn-remover-anexo {
  width: 78px; flex: none; background: var(--vermelha-bg); color: var(--vermelha); border: none; border-radius: 10px; padding: 11px 0; font-size: .82rem; font-weight: 700;
}
.anexo-rotulo { font-size: .78rem; color: var(--texto-suave); margin-top: 5px; }
.anexo-rotulo a { color: var(--primaria-clara); font-weight: 600; }

.tag { display: inline-block; padding: 3px 9px; border-radius: 7px; font-size: .72rem; font-weight: 700; margin-left: 6px; }
.tag.sim { background: var(--verde-bg); color: var(--verde); }
.tag.nao { background: var(--vermelha-bg); color: var(--vermelha); }

/* ---------- EDITOR DE TEXTO RICO (Quill) ----------
   Mantém fundo branco sempre (mesmo no tema escuro), igual "papel de escrever" —
   padrão comum em editores de texto dentro de apps escuros (Notion, Google Docs),
   pra formatação (cor de fonte etc.) continuar previsível independente do tema. */
.editor-rico { border-radius: 11px; overflow: hidden; border: 1.5px solid var(--borda); background: #fff; }
.editor-rico .ql-toolbar.ql-snow { border: none; border-bottom: 1px solid var(--borda); background: #F7F8FA; }
.editor-rico .ql-container.ql-snow { border: none; }
.editor-rico .ql-editor { min-height: 90px; font-size: 1rem; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; color: #1F2937; }
/* Somente leitura: sem toolbar nenhuma (nem criada, ver iniciarEditorRico), só o
   texto com um fundo levemente acinzentado pra indicar "não editável". */
.editor-rico .ql-container.ql-disabled { background: #F7F8FA; }

/* Formulário compacto no celular (pedido do Netto: "os formulários do celular são
   muito grandes"). Só entra abaixo de 1024px — o Mac/iPad deitado (modal centralizado
   de 700px, ver .modal-caixa em @media min-width:1024px) continua exatamente do
   jeito que já era, com espaço de sobra pra respirar. No celular, onde o formulário
   ocupa a tela inteira de baixo pra cima e um cadastro como Lançamento tem VÁRIAS
   seções (Financeiro, Documentos, Observações...), cada margem/padding cortado aqui
   soma rápido ao longo do formulário inteiro. font-size dos campos (1rem/16px) fica
   INTOCADO de propósito — é o mínimo pra não disparar o zoom automático do Safari no
   iPhone ao tocar num campo, encolher isso voltaria um bug já resolvido. */
@media (max-width: 1023px) {
  .form-campo { margin-bottom: 10px; }
  .form-campo label { margin-bottom: 3px; }
  .form-campo input, .form-campo select, .form-campo textarea { padding: 10px; }
  .form-linha { gap: 8px; }
  .anexo-campo { margin-bottom: 10px; }
  .secao-titulo { margin: 16px 0 8px; padding-bottom: 5px; }
  /* Observações é o campo mais usado no fim de todo formulário (Lançamento,
     Fornecedor, Financiador) — 90px de altura mínima do editor sozinho já
     era quase 1/4 da tela útil de um iPhone SE com o teclado fechado. */
  .editor-rico .ql-editor { min-height: 64px; }
  .btn-secundario { margin-top: 6px; }
  .btn-perigo { margin-top: 8px; }
}

/* Ilustração genérica de "nada por aqui" via mask (não background-image comum) de
   propósito: assim o ícone herda a cor do tema (--texto-suave) automaticamente,
   inclusive no escuro, sem precisar de uma versão clara e outra escura do SVG. Cobre
   TODOS os "Nenhum X encontrado" do sistema de uma vez, sem mexer em cada tela. */
.vazio { text-align: center; color: var(--texto-suave); padding: 36px 10px; font-size: .9rem; }
.vazio::before {
  content: "";
  display: block;
  width: 52px; height: 52px;
  margin: 0 auto 12px;
  background-color: var(--texto-suave);
  opacity: .32;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 12h-6l-2 3h-4l-2-3H2'%3E%3C/path%3E%3Cpath d='M5.45 5.11L2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z'%3E%3C/path%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 12h-6l-2 3h-4l-2-3H2'%3E%3C/path%3E%3Cpath d='M5.45 5.11L2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z'%3E%3C/path%3E%3C/svg%3E");
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center; mask-position: center;
  -webkit-mask-size: contain; mask-size: contain;
}

/* ---------- GOVERNANÇA DE FORNECEDORES ---------- */
.linha-lista.governanca-critico { border-color: var(--vermelha); background: var(--vermelha-bg); }
.linha-lista.governanca-alerta { border-color: var(--laranja); background: var(--laranja-bg); }
.linha-lista.governanca-atencao { border-color: var(--atencao); background: var(--atencao-bg); }
.linha-lista.governanca-ok { border-color: var(--verde); }

/* Só o nome do status em cor, sem balão/fundo ao redor, a pedido do Netto. */
.tag-governanca { font-size: .78rem; font-weight: 800; white-space: nowrap; }
.tag-governanca.tag-critico { color: var(--vermelha); }
.tag-governanca.tag-alerta { color: var(--laranja); }
.tag-governanca.tag-atencao { color: var(--atencao); }
.tag-governanca.tag-ok { color: var(--verde); }

/* ---------- MODAL ---------- */
.modal-fundo {
  position: fixed; inset: 0; background: rgba(11,42,73,.45); z-index: 20;
  display: flex; align-items: flex-end;
  backdrop-filter: blur(1px);
}
@keyframes modalFundoSurge { from { opacity: 0; } to { opacity: 1; } }
@keyframes modalCaixaSurge { from { transform: translateY(28px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
.modal-fundo:not(.oculto) { animation: modalFundoSurge .16s ease; }
.modal-fundo:not(.oculto) .modal-caixa { animation: modalCaixaSurge .22s cubic-bezier(.16,1,.3,1); }
.modal-caixa {
  background: var(--card); width: 100%; max-height: 82vh; overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  border-radius: 22px 22px 0 0; padding: 8px 18px 16px;
  padding-bottom: calc(22px + env(safe-area-inset-bottom));
  box-shadow: 0 -12px 40px rgba(11,42,73,.25);
}
.modal-alca { width: 40px; height: 4px; background: var(--borda); border-radius: 4px; margin: 8px auto 14px; }
.modal-topo { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; }
.modal-topo strong { font-size: 1.08rem; color: var(--primaria); font-weight: 700; }
#modal-fechar { background: #EEF1F4; border: none; width: 30px; height: 30px; border-radius: 50%; font-size: 1.3rem; color: var(--texto-suave); line-height: 1; }

/* ---------- CONFIRMAÇÃO DE SENHA (reautenticação) ----------
   Janelinha própria, por cima até do #modal-fundo normal (z-index maior), porque
   as 3 ações que pedem senha (excluir usuário, reverter auditoria, limpar anexos)
   podem acontecer com outro modal já aberto por baixo (editar usuário, Trilha de
   Auditoria) — usar o mesmo #modal-fundo fecharia o de baixo sem querer. */
.confirmacao-senha-fundo {
  position: fixed; inset: 0; background: rgba(11,42,73,.55); z-index: 40;
  display: flex; align-items: center; justify-content: center; padding: 20px;
  animation: modalFundoSurge .16s ease;
}
.confirmacao-senha-caixa {
  background: var(--card); width: 100%; max-width: 360px; border-radius: 16px;
  padding: 20px; box-shadow: 0 20px 60px rgba(11,42,73,.35);
  animation: modalCaixaSurge .22s cubic-bezier(.16,1,.3,1);
}
.confirmacao-senha-titulo { font-size: 1.02rem; font-weight: 700; color: var(--primaria); margin-bottom: 8px; }
.confirmacao-senha-texto { font-size: .84rem; color: var(--texto-suave); margin: 0 0 14px; line-height: 1.4; }
.confirmacao-senha-input {
  width: 100%; padding: 12px; border-radius: 10px; border: 1.5px solid var(--borda);
  font-size: 1rem; background: #FAFBFC; box-sizing: border-box; margin-bottom: 8px;
}
.confirmacao-senha-input:focus { outline: none; border-color: var(--primaria-clara); background: #fff; }
.confirmacao-senha-erro { font-size: .78rem; color: var(--vermelha); font-weight: 600; margin-bottom: 8px; }
.confirmacao-senha-acoes { display: flex; justify-content: flex-end; gap: 8px; margin-top: 4px; }

/* Histórico: primeiro era justify-content:space-between (botão ia pro canto
   direito da tela em monitor largo, vão enorme — "ficou muito longe"). Depois
   virou flex-start (nome colado ao botão), mas aí cada linha tem o botão numa
   posição diferente porque "Lançamentos", "Orçamento", "Relatório Financeiro
   Completo" etc. têm tamanhos diferentes — o Netto reportou que "não ficam
   organizados". A solução que resolve os dois problemas ao mesmo tempo é grid
   de 2 colunas: a primeira coluna (nome) tem largura FIXA, então os botões da
   segunda coluna começam sempre na mesma posição X em todas as linhas, igual
   uma tabela — e como a coluna é fixa (não 1fr esticando com a tela), o botão
   nunca fica jogado lá longe num monitor largo. */
.export-item {
  background: var(--card); border-radius: 13px; padding: 16px; margin-bottom: 10px;
  display: grid; grid-template-columns: minmax(160px, 260px) 1fr;
  align-items: center; gap: 10px 14px;
  border: 1px solid var(--borda);
  transition: box-shadow .2s var(--easing), border-color .2s var(--easing);
}
/* Redesenho: mesma elevação sutil do .card/.linha-lista ao passar o mouse — antes
   este cartão era o único bloco "clicável" (tem botão de ação dentro) sem nenhum
   feedback visual de hover, destoando do resto do sistema. */
@media (hover: hover) {
  .export-item:hover { box-shadow: var(--sombra-media); border-color: #D7E0EA; }
}
.export-item span { font-weight: 600; }
.export-item .export-item-acoes { display: flex; gap: 8px; flex-wrap: wrap; justify-content: flex-start; }
/* Celular estreito: nome acima, botões abaixo (uma coluna só) — 260px fixos não
   cabem num vidro de 360-390px de largura. */
@media (max-width: 480px) {
  .export-item { grid-template-columns: 1fr; }
  /* Empilhado numa coluna só, nome e botões ficavam colados na esquerda (herança
     do layout em grade, pensado pra colunas lado a lado) — pedido do Netto pra
     centralizar os dois nessa largura estreita, nome e botões inclusive. */
  .export-item span { text-align: center; }
  .export-item .export-item-acoes { justify-content: center; }
}

/* REVERTIDO A PEDIDO DO NETTO: cheguei a testar um teto de largura maior (700px)
   e uma grade pros cartões de KPI nessa faixa (720-899px, que é exatamente o que
   o iPad Air 11" M2 EM PÉ recebe hoje), mas sem visualizar o resultado de verdade.
   Perguntado direto, a escolha foi "igual ao celular, sem exceção" — então essa
   faixa agora NÃO tem nenhuma regra própria: herda 100% do bloco mobile-first lá
   em cima (sem teto de largura no .conteudo/.nav-inferior, cartões de KPI rolando
   de lado). Documentado aqui, e não simplesmente apagado sem explicação, porque
   uma versão futura pode reconsiderar isso com uma captura de tela real em mãos. */

/* ---------- TABELA (tablet/desktop) ----------
   Igual à lógica das tabelas do sistema desktop (cabeçalho de coluna, uma linha por
   registro). No celular isso fica ilegível, então continua escondida por padrão e só
   aparece a partir de uma tela larga o bastante (tablet paisagem/computador); o
   celular sempre vê os cartões, nunca a tabela. */
.vista-tabela { display: none; }

/* Barra lateral (igual à sidebar azul do sistema desktop): escondida por padrão, só
   aparece a partir da tela larga (ver media query 1024px abaixo). */
.sidebar-desktop { display: none; }

@media (min-width: 1024px) {
  /* No computador/iPad deitado sobra espaço de sobra nessa linha (título +
     seletor), então o título volta pro tamanho original — a fonte reduzida
     (ver .cartao-grafico-titulo na base) é só uma necessidade do celular
     estreito, não uma mudança visual pretendida aqui. */
  .cartao-grafico-titulo { font-size: .94rem; }
  /* Botão flutuante "+" só existe no celular (atalho de toque); no computador o
     Mac já tem "Adicionar" na barra de ferramentas acima da tabela, então esse
     círculo azul flutuando por cima do conteúdo não faz sentido aqui. */
  .btn-flutuante { display: none; }

  /* No Mac a JANELA em si nunca rola: ela tem tamanho fixo, sidebar/cabeçalho/abas
     ficam parados e só o CONTEÚDO de cada aba tem sua própria área de rolagem — o
     Dashboard tem seu próprio QScrollArea (self.dashboard_scroll, linha 2485 do
     app.py) e as tabelas rolam pelo viewport interno do QTableWidget. Nada disso
     nunca "puxa" a janela inteira. Pra copiar esse comportamento aqui, a página web
     também trava sem rolagem própria (html/body/.app com altura fixa = 100vh) e só
     o #conteudo por baixo da sidebar/cabeçalho/abas é que rola — exatamente como o
     QScrollArea do Mac.
     ACHADO (pedido do Netto: planilhas do iPad seguirem a mesma lógica "fixa e
     responsiva" do MacBook): no Mac de verdade 100vh é estável (não existe barra
     de endereço recolhível), então essa conta sempre bateu certinho ali. No
     Safari do iPad, 100vh conta com a barra de ferramentas RECOLHIDA (maior que
     a área realmente visível quando ela está à mostra) — isso deixava toda a
     grade (.app), e tudo que depende dela por baixo (#conteudo, .vista-tabela,
     .tabela-scroll), com um "total disponível" errado, e é raiz provável de
     vários dos bugs de rolagem só no iPad. 100dvh (altura DINÂMICA de verdade)
     resolve isso — mesmo padrão já usado em .tela-login/.app no mobile. */
  html, body { height: 100%; height: 100dvh; overflow: hidden; }

  /* Layout em grade: barra lateral fixa ocupando toda a altura (igual ao Mac), cabeçalho
     e abas de navegação à direita dela, conteúdo por baixo. No celular o #app continua
     em coluna simples (cabeçalho, conteúdo, menu inferior fixo); aqui ele vira uma
     grade de 2 colunas x 3 linhas. */
  .app {
    display: grid;
    grid-template-columns: 250px 1fr;
    grid-template-rows: auto auto 1fr;
    grid-template-areas: "lateral cabecalho" "lateral abas" "lateral conteudo";
    padding-bottom: 0;
    height: 100vh;
    height: 100dvh;
    overflow: hidden;
  }

  /* Sidebar igual ao QFrame#sidebar do Mac de verdade (conferido linha a linha no
     app.py, não só nas fotos): fundo azul sólido (cor primária), botões brancos com
     texto azul flutuando por cima — não uma barra branca. */
  .sidebar-desktop {
    display: flex;
    flex-direction: column;
    grid-area: lateral;
    /* Gradiente sutil em vez de azul chapado: mesma cor de marca, só com um pouco
       mais de profundidade — sem mudar a identidade, só dando mais riqueza visual. */
    background: linear-gradient(165deg, var(--primaria-clara) 0%, var(--primaria) 45%, var(--primaria-escura) 100%);
    padding: 25px 22px;
    box-shadow: 4px 0 28px rgba(0,0,0,.22);
    position: sticky;
    top: 0;
    height: 100vh;
    height: 100dvh;
    overflow-y: auto;
  }
  /* A logo (render_logo no Mac) é sempre exibida com as cores originais do arquivo —
     não existe nenhuma inversão para branco no código-fonte. A logo real já tem
     amarelo/verde-oliva com bom contraste sobre o azul da sidebar. */
  .sidebar-logo { width: 100%; max-width: 170px; margin: 0 auto 20px; }
  /* Valores exatos do QPushButton#sideButton no app.py (apply_style): border-radius
     12px, borda #D7E0EA, min-height 46px (self.btn_add.setMinimumHeight(46) etc.,
     linha ~2380), padding herdado da regra QPushButton genérica (10px 16px),
     font-size herdado de QWidget (13px = .81rem aqui), margin 4px 0 vertical. */
  .sidebar-btn {
    background: #fff; color: var(--primaria); border: 1px solid #D7E0EA;
    border-radius: 12px; padding: 10px 16px; font-size: .81rem; font-weight: 700;
    min-height: 46px; margin: 4px 0; text-align: center;
    display: flex; align-items: center; justify-content: center; gap: 8px;
    transition: background-color .15s ease, box-shadow .15s ease, transform .1s ease;
  }
  .sidebar-btn svg { flex: none; width: 16px; height: 16px; }
  .sidebar-btn:hover { background: #EEF4FA; box-shadow: 0 2px 8px rgba(11,42,73,.12); }
  .sidebar-btn:active { transform: scale(.97); }
  /* Redesenho: o estado ativo (só o botão Relatórios usa, ver .nav-item.ativo em
     app.js) era um contorno branco fino sobre um botão já branco, quase invisível
     encostado no gradiente da sidebar. Preenchido com a cor da marca e texto branco,
     igual a como um item "selecionado" de verdade se destaca em qualquer barra
     lateral de sistema profissional. */
  .sidebar-btn.ativo { background: var(--primaria); color: #fff; border-color: var(--primaria); box-shadow: 0 4px 14px rgba(0,0,0,.22); }
  .sidebar-btn.ativo svg { stroke: #fff; }
  .sidebar-espaco { flex: 1; }
  .sidebar-rodape { color: #DCE7F3; font-size: .72rem; text-align: center; font-weight: 600; line-height: 1.5; }

  /* Redesenho: barra de rolagem nativa do computador (sidebar e tabelas) num tom
     discreto da marca, em vez do cinza padrão do sistema operacional — mesmo
     espírito da barra "harmônica" já criada pro tablet (pílula, sem nunca sumir de
     vez), só que aqui é a barra NATIVA do navegador (o mouse/trackpad já mostra a
     barra sozinho ao pairar, então não precisa do indicador customizado do
     tablet/touch). scrollbar-color cobre Firefox; ::-webkit-scrollbar cobre Chrome/
     Edge/Safari — juntos, cobrem praticamente todo navegador de computador. */
  .sidebar-desktop, .tabela-scroll {
    scrollbar-width: thin;
    scrollbar-color: rgba(18,61,102,.35) transparent;
  }
  .sidebar-desktop::-webkit-scrollbar, .tabela-scroll::-webkit-scrollbar { width: 9px; height: 9px; }
  .sidebar-desktop::-webkit-scrollbar-track, .tabela-scroll::-webkit-scrollbar-track { background: transparent; }
  .sidebar-desktop::-webkit-scrollbar-thumb {
    background: rgba(255,255,255,.28); border-radius: 999px; border: 2px solid transparent; background-clip: content-box;
  }
  .sidebar-desktop::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,.42); background-clip: content-box; }
  .tabela-scroll::-webkit-scrollbar-thumb {
    background: rgba(18,61,102,.28); border-radius: 999px; border: 2px solid transparent; background-clip: content-box;
  }
  .tabela-scroll::-webkit-scrollbar-thumb:hover { background: rgba(18,61,102,.45); background-clip: content-box; }

  /* No Mac o cabeçalho (header QHBoxLayout) não tem cor própria: herda o fundo cinza
     claro padrão da janela (#F5F7FA) com o título em azul — não é uma barra azul
     sólida com texto branco. Essa barra azul sólida é só o visual mobile; aqui, a
     partir de 1024px, ela vira clara igual ao Mac. */
  .topo {
    grid-area: cabecalho; position: static; grid-template-columns: auto 1fr auto;
    background: var(--fundo); color: var(--texto); box-shadow: none;
    border-bottom: 1px solid var(--borda); padding: 14px 28px;
  }
  .topo-marca { display: none; }
  /* QLabel#pageTitle: 26px, weight 700, cor primária, letter-spacing -0.3px, encostado
     à esquerda (Qt.AlignLeft por padrão de alinhamento configurado). */
  .topo-titulo { text-align: left; justify-self: start; font-size: 1.625rem; color: var(--primaria); letter-spacing: -.02em; }
  .topo-acoes { gap: 10px; }
  /* QLineEdit padrão do Mac: fundo branco, borda cinza, texto centralizado — a busca
     aqui já não está mais sobre fundo azul, então usa as mesmas cores do resto dos
     campos do sistema. Tamanho padronizado e fixo (não muda de largura conforme a
     aba ou o espaço sobrando do cabeçalho). */
  /* Mais discreta (pedido do Netto): fundo igual ao do cabeçalho em vez de branco
     sólido, borda mais clara e um pouco mais estreita — deixa de "gritar" tanto
     quanto um campo de formulário normal, já que aqui é só um atalho de busca no
     topo, não o protagonista da tela. Ganha o fundo branco de volta só ao focar
     (ver :focus embaixo), pra continuar óbvio que virou editável. */
  .topo-busca {
    width: 260px; flex: none;
    padding: 8px 12px; border-radius: 9px; border: 1px solid var(--borda);
    background: var(--fundo); color: var(--texto); font-size: .78rem; text-align: center;
  }
  .topo-busca::placeholder { color: var(--texto-suave); }
  .topo-busca:focus { outline: none; border-color: var(--primaria-clara); background: #fff; }
  /* QPushButton#iconActionButton: fundo azul sólido, ícone branco, border-radius 9 —
     precisa ficar sólido agora que o fundo do cabeçalho é claro (a versão translúcida
     branca-sobre-azul só fazia sentido no mobile). Vale pra desfazer/refazer/limpar
     anexos, os 3 ícones do cabeçalho. */
  .btn-icone-topo { background: var(--primaria); color: #fff; }
  .btn-icone-topo:hover:not(:disabled) { background: #0B2F50; }
  /* CORREÇÃO: a "redução de 30%" ficou pequena demais. Valor exato do app.py
     (apply_style, QPushButton#iconActionButton + self.btn_undo.setFixedSize(34,34),
     linha ~2393): quadrado fixo 34x34px, ícone 18x18 (setIconSize(QSize(18,18))). */
  .btn-icone-topo { width: 34px; height: 34px; padding: 0; }
  .btn-icone-topo svg { width: 18px; height: 18px; }
  /* Desfazer/Refazer voltam a aparecer no cabeçalho a partir daqui — abaixo disso
     (celular e iPad em pé) ficam escondidos e entram no menu "...", ver acima. */
  #btn-desfazer, #btn-refazer { display: flex; }
  /* Limpar anexos com texto ao lado do ícone, só no computador (pedido do Netto):
     largura deixa de ser quadrada. Valor exato do app.py (smallActionButton:
     padding:7px 11px, self.btn_clean.setFixedHeight(34), font herdado 13px=.81rem). */
  #btn-limpar-anexos-topo { display: flex; width: auto; height: 34px; padding: 7px 11px; gap: 6px; }
  .btn-limpar-anexos-texto { display: inline; font-size: .81rem; font-weight: 700; white-space: nowrap; }
  /* A partir daqui a sidebar (.sidebar-desktop) já assume Configurações/Usuários/
     Auditoria, e Limpar anexos volta a aparecer com texto (linha acima), então o
     menu "..." pensado pra quem só tem celular/tablet em mãos (ver #btn-mais-topo
     no index.html) deixa de fazer sentido e some. */
  #btn-mais-topo { display: none; }
  .btn-sair { background: #fff; color: var(--primaria); border: 1px solid #D7E0EA; }
  .btn-sair:hover { background: #EEF4FA; }
  /* Sem equivalente no app.py (sair não existe no desktop, é próprio da versão web
     multiusuário) — mantido no mesmo padrão visual dos outros ícones do cabeçalho
     (34x34, ícone 18px) por consistência. */
  .btn-sair { width: 34px; height: 34px; padding: 0; }
  .btn-sair svg { width: 18px; height: 18px; }
  /* CORREÇÃO: valores exatos do app.py pros botões de modal/formulário (só desktop;
     a regra base/mobile abaixo de 1024px continua intocada, alvo de toque no celular).
     primaryButton: padding:10px 18px | secondaryButton: padding:10px 16px |
     dangerButton: padding:9px 14px | font-size herdado de QWidget 13px = .81rem. */
  .btn-primario { padding: 10px 18px; font-size: .81rem; }
  .btn-secundario { padding: 10px 16px; font-size: .81rem; }
  .btn-perigo { padding: 9px 14px; font-size: .81rem; }
  /* anexo-linha: "Anexar" é QPushButton comum (padding:10px 16px), "Remover" é
     dangerButton (padding:9px 14px) — mesmos valores acima, sem largura fixa
     encolhida (o Qt deixa o botão respirar no tamanho do texto). */
  .anexo-linha .btn-anexar { padding: 10px 16px; font-size: .81rem; }
  .anexo-linha .btn-remover-anexo { width: auto; padding: 9px 14px; font-size: .81rem; }
  /* modal-fechar: sem equivalente direto no app.py (Qt usa o X nativo da janela);
     mantido no tamanho original, que já era confortável e nunca foi o problema. */
  #modal-fechar { width: 30px; height: 30px; font-size: 1.3rem; }
  /* Aqui, a partir de 1024px, o JS é quem manda: some/mostra a busca removendo ou
     adicionando a classe "oculto" conforme a seção atual (ver atualizarBuscaTopo). */
  /* Precisa do !important aqui: a regra de base esconde a busca com !important pra
     sumir de vez no celular, e sem !important aqui esse "mostrar de volta" nunca
     vencia a partir de 1024px. */
  .topo-busca:not(.oculto) { display: block !important; }

  /* QTabBar::tab do Mac: fundo #E5E7EB, texto #1F2937, border-radius 10, padding
     10px 18px, margin 4px, min-width 116, selecionada vira fundo azul + texto branco,
     hover #EEF4FA — valores exatos do QSS, substituindo o visual de sublinhado fino
     que eu tinha colocado antes. */
  .nav-inferior {
    /* No macOS o QTabBar nativo centraliza as abas por padrão (é o próprio estilo
       da plataforma, não algo escrito no código) — antes eu tinha alinhado à
       esquerda, que é o padrão do Windows/Linux, não do Mac. */
    grid-area: abas; position: static; max-width: none; margin: 0; left: auto; transform: none;
    border-radius: 0; box-shadow: none; border-top: none; border-bottom: none;
    justify-content: center; background: var(--fundo); flex-wrap: wrap;
    /* CAUSA REAL DO CORTE (resolvida): a regra do celular deixa "overflow-x:auto"
       (pra rolar de lado no iPhone) e isso nunca era desligado aqui — um container
       com overflow:auto vira "scroll container", e dentro de uma grade com altura
       "auto" isso fazia o navegador reservar menos altura que o necessário. */
    overflow: visible; min-height: 0; height: auto;
    /* MATEMÁTICA EXATA (documentada pra ser conferível, não "confia em mim"):
       pílula = 44px de altura (padding 12px + borda 1px dos dois lados, em cima do
       ícone de 18px) + margin --esp-1 (4px) de cada lado = 52px de "linha" do flex.
       Padding do container agora é ASSIMÉTRICO por pedido do Netto (abas mais pra
       cima, mais perto do título): --esp-2 (8px) em cima, --esp-4 (16px) embaixo.
       O padding de BAIXO é o que importa pro vão até os cartões (ver .conteudo) —
       reduzir só o de CIMA sobe a fileira sem mexer nesse vão já calculado. */
    padding: var(--esp-2) var(--esp-5) var(--esp-4);
  }
  .nav-item {
    /* Reescrito do zero pra não herdar NADA da regra do celular (flex-direction,
       line-height, max-width do texto etc.) — a mistura de "troca algumas
       propriedades, deixa outras herdadas" foi a causa real do botão aparecer
       cortado/espremido: ícone empilhado sobre o texto (herdado do celular) dentro
       de uma caixa pensada pra ícone do LADO do texto. Agora todo mundo é
       declarado aqui, sem depender de nada de fora deste bloco.
       line-height:1 EXPLÍCITO (não o padrão do navegador, que varia) — sem isso a
       altura real da pílula vira uma incógnita e qualquer conta sobre o espaço
       ao redor dela é só palpite.
       ACHADO DE AUDITORIA (mantido): o cinza #E5E7EB sozinho sobre o fundo #F4F6F8
       do cabeçalho tem contraste real de ~1.14:1 (quase imperceptível — o padrão
       mínimo do WCAG pra componentes de UI é 3:1). Escurecido o preenchimento e
       somada uma borda própria, visível mesmo se o preenchimento se aproximar do
       fundo em algum monitor/tela.
       CORREÇÃO (pedido do Netto): a "redução de 30%" da rodada anterior encolheu
       demais e ficou pior — o print de referência é o app do Mac RODANDO hoje
       (01_SISTEMA/codigo/app.py), então os números aqui agora vêm direto do QSS
       de lá (função apply_style, QTabBar::tab, linha ~3570 do app.py), não de um
       chute de porcentagem: padding:10px 18px | border-radius:10px | margin:4px |
       min-width:116px | font-size:13px (herdado de QWidget{{font-size:13px}} no
       topo do mesmo QSS, 13/16=.81rem aqui). Pílula: 10*2 (padding) + 1*2 (borda) +
       16 (ícone) = 38px de altura — com a mesma folga do .nav-inferior/.conteudo,
       o vão até o primeiro cartão fica bem maior que os 31px problemáticos de
       antes, sem exagerar como os 44px originais também exagerados. */
    display: flex; flex-direction: row; align-items: center; justify-content: center; gap: 8px;
    flex: 0 0 auto; min-width: 116px; padding: 10px 18px; font-size: .81rem; line-height: 1;
    white-space: nowrap; border-bottom: none; box-sizing: border-box;
    background: #D8DEE7; border: 1px solid #C2CCD9; border-radius: 10px; color: #1F2937; font-weight: 600;
    margin: 4px;
    transition: background-color .15s ease, border-color .15s ease, transform .1s ease, box-shadow .15s ease;
  }
  .nav-item:hover { background: #EEF4FA; border-color: #C7DAEC; box-shadow: 0 2px 8px rgba(18,61,102,.1); }
  .nav-item:active { transform: scale(.96); }
  .nav-item svg { width: 16px; height: 16px; stroke-width: 2; flex: none; display: block; }
  .nav-item span { white-space: nowrap; overflow: visible; text-overflow: clip; max-width: none; line-height: 1.2; }
  .nav-item.ativo { background: var(--primaria); border-color: var(--primaria); color: #fff; font-weight: 700; box-shadow: 0 1px 4px rgba(18,61,102,.22); }
  .nav-item.ativo svg { stroke: #fff; }
  .nav-item.ativo:hover { background: var(--primaria); border-color: var(--primaria); }

  /* O botão Relatórios da sidebar acumula as classes "sidebar-btn nav-item" (precisa de
     nav-item pra participar da troca de aba ativa em irPara/ordenarTabela etc.), mas
     isso fazia ele herdar o visual de pílula cinza do nav-item (usado na barra de
     abas embaixo), destoando dos outros botões brancos da sidebar. Selector mais
     específico que .nav-item sozinho, então vence e devolve o mesmo visual dos
     outros botões da sidebar, com o estado ativo marcado por contorno (igual
     .sidebar-btn.ativo already fazia), não por preenchimento azul. */
  .sidebar-btn.nav-item {
    /* Mesmo valor de .sidebar-btn abaixo (QPushButton#sideButton do app.py: padding
       herdado do QPushButton base 10px 16px, min-height 46 via setMinimumHeight). */
    background: #fff; color: var(--primaria); border: 1px solid #D7E0EA;
    border-radius: 12px; padding: 10px 16px; font-size: .81rem; font-weight: 700;
    min-height: 46px; min-width: 0; margin: 0 0 8px; text-align: center;
  }
  .sidebar-btn.nav-item:hover { background: #EEF4FA; }
  .sidebar-btn.nav-item.ativo { background: #fff; color: var(--primaria); outline: 2px solid var(--primaria); }
  .sidebar-btn.nav-item.ativo svg { stroke: var(--primaria); }
  .sidebar-btn.nav-item.ativo:hover { background: #EEF4FA; }

  /* #conteudo é a única área que rola nas abas sem tabela (Dashboard, Relatórios),
     igual ao QScrollArea do dashboard no Mac — min-height:0 é essencial aqui: sem
     isso o grid deixava essa área crescer além do tamanho da tela e quem acabava
     rolando era a janela inteira, não essa área. */
  .conteudo {
    grid-area: conteudo; max-width: none; width: 100%;
    /* Espaço de cima calculado, não chutado: a linha das abas termina com 4px de
       margin + 16px de padding "livres" (ver conta em .nav-inferior) antes da
       borda da grade. Somando os --esp-6 (32px) daqui, o vão total entre a borda
       visível da pílula e o topo do primeiro cartão é 4+16+32 = 52px — dá pra
       conferir com uma régua na tela que bate. */
    padding: var(--esp-6) 28px var(--esp-5);
    overflow-y: auto; min-height: 0;
    display: flex; flex-direction: column;
  }

  .vista-cartoes { display: none; }
  /* Nas abas com tabela (Lançamentos/Fornecedores/Orçamento), .vista-tabela é filha
     do #conteudo (agora flex column) e usa flex:1 — não height:100% — pra ocupar só
     o que sobra DEPOIS da busca/filtro que vem antes dela na mesma coluna, sem
     estourar o total. A barra de ferramentas fica com altura natural (flex:none) e
     .tabela-scroll (flex:1 lá dentro) absorve sozinha toda a rolagem — igual ao Mac,
     onde é só o QTableWidget que rola, nunca o painel em volta dele. */
  .vista-tabela { display: flex; flex-direction: column; flex: 1; min-height: 0; }

  /* A busca de Lançamentos/Fornecedores já existe no cabeçalho global (#busca-topo)
     a partir daqui; a versão de dentro da aba (só usada no celular) some para não
     duplicar o campo. */
  #busca-lancamentos, #busca-fornecedores { display: none; }

  /* Faixa de KPI vira uma grade sem rolagem horizontal, igual à linha única do
     sistema desktop. auto-fit/minmax em vez de "repeat(6, 1fr)" fixo: numa janela
     mais estreita (notebook, ou a janela do navegador redimensionada, não só
     tablet/celular) os cartões quebram pra próxima linha em vez de espremer os 6
     na força — isso é o que faltava pra ficar responsivo de verdade nessa faixa. */
  .tira-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); overflow: visible; }
  .tira-cards .card { flex: initial; scroll-snap-align: none; padding: 14px 12px; }
  .tira-cards .card .rotulo { font-size: .72rem; }
  .tira-cards .card .valor { font-size: 1.2rem; }
  /* Redesenho de espaçamento do Dashboard (pedido do Netto): o vão do TOPO (entre
     as abas e os cartões de orçamento) era pequeno demais, e os vãos ENTRE as
     seções de baixo (orçamento -> Top Fornecedor/Pendências -> Análise dinâmica)
     grandes demais — ficava desproporcional. As 4 classes usadas aqui
     (.tira-cards/.faixa-superior-dashboard/.cartao-grafico/.barra-progresso-principal)
     só existem dentro do Dashboard, então dá pra calibrar isso aqui sem mexer no
     espaçamento de nenhum outro módulo. Vão do topo maior (empurra tudo pra baixo,
     como pedido), vãos internos menores e uniformes (16px), melhor aproveitamento
     do espaço total. */
  .tira-cards { margin-top: 14px; margin-bottom: 16px; }

  /* Top fornecedor + as duas pendências numa única linha de 3 cartões, igual ao Mac:
     proporção exata 2:1:1 (criar_card_dashboard_info dá o mesmo peso pros 3, mas o
     Top Fornecedor ocupa 2 partes contra 1 de cada pendência) e altura fixa 172px
     (mesmo valor usado nos 3 no app.py). */
  .faixa-superior-dashboard { display: flex; gap: 14px; align-items: stretch; margin-bottom: 16px; }
  /* Ground-truth exata: criar_card_dashboard_info() usa frame.setFixedHeight(172) —
     não é uma altura MÍNIMA que cresce com o conteúdo, é uma altura TRAVADA sempre
     igual nos 3 cartões (Top Fornecedor + as 2 pendências), com addStretch(1) antes
     e depois do bloco de texto pra centralizar verticalmente. Antes eu tinha
     min-height, que deixava o cartão de Pendências financeiras crescer mais que o
     de SALIC quando a linha extra de NF/Comprovante aparecia — com height fixo +
     overflow:hidden + flex centralizado, os dois ficam sempre do mesmo tamanho,
     exatamente como no Mac. */
  .faixa-superior-dashboard .card-top {
    flex: 2; margin-bottom: 0; padding: 22px; height: 172px; overflow: hidden;
    display: flex; flex-direction: column; justify-content: center;
  }
  .faixa-superior-dashboard .linha-governanca { flex: 2; margin-bottom: 0; }
  .faixa-superior-dashboard .linha-governanca .card {
    height: 172px; overflow: hidden; display: flex; flex-direction: column; justify-content: center;
  }
  /* Cartão sem legenda agora cabe bem menor (era 118px pra caber 3 linhas de texto,
     ficaram só 2: rótulo + valor). */
  .tira-cards .card { min-height: 74px; }

  /* Revertido: a tentativa de fazer o quadro do gráfico crescer com flex:1 pra
     ocupar o vão vazio do fim do Dashboard era arriscada sem eu conseguir ver o
     resultado renderizado de verdade (Chart.js dentro de container flex-elástico
     é fonte clássica de bug de redimensionamento). Volta pro valor fixo de
     310px, que já era o comprovado — nada de "consertar" um problema chutando
     outra mudança sem confirmar visualmente antes. */
  /* Vão entre Análise dinâmica e a barra de Execução financeira: mesmo ajuste de
     redesenho de espaçamento acima (era 22px, mesmo valor exagerado das outras
     seções). */
  .cartao-grafico { margin-bottom: 16px; }

  /* Tamanho exato do QLabel#pendencyValue/pendencySub/pendencyDetail do Mac (34px/12px/
     11px) nos dois cartões de pendência, só a partir da tela larga (no celular o valor
     um pouco menor acima já cabe melhor num cartão de metade da largura). */
  .faixa-superior-dashboard .linha-governanca .card .valor { font-size: 2.125rem; margin-top: 2px; }
  .faixa-superior-dashboard .linha-governanca .card .legenda-sub { font-size: .75rem; margin-top: 2px; }
  .faixa-superior-dashboard .linha-governanca .card .legenda-detail { font-size: .6875rem; margin-top: 4px; }

  /* ---- Tabelas: réplica do QTableView/QHeaderView do Mac ----
     Cabeçalho #E8EEF5 com texto azul (não uma barra azul sólida com texto branco,
     que era o que eu tinha colocado antes), zebra de linhas (#F9FAFB), seleção
     #DBEAFE, altura de linha ~34px (defaultSectionSize do Mac). E o pedido específico
     desta rodada: a rolagem fica DENTRO da própria planilha (.tabela-scroll), não
     empurrando a página inteira — igual ao QTableWidget, que tem sua própria barra de
     rolagem interna mesmo com centenas de linhas. */
  .tabela-dados {
    /* Comparei print real do Mac com o do site lado a lado: no Mac (resizeColumnsToContents)
       a tabela NUNCA estica, ela fica do tamanho exato do conteúdo e sobra espaço vazio à
       direita antes da barra de rolagem — width:100% forçava o navegador a esticar as
       colunas pra preencher o container inteiro, mudando a proporção entre elas. Com
       width:auto (padrão de <table>) ela encolhe pro tamanho do conteúdo quando cabe, e só
       cresce além do container (ativando a rolagem horizontal do .tabela-scroll) quando as
       colunas realmente precisam de mais espaço — igual ao Mac nos dois casos. */
    /* Base font-size da Mac inteira é 13px (QWidget {{ font-size:13px }}); as
       tabelas não têm nenhum tamanho próprio no QSS, então herdam esse valor. */
    width: auto; border-collapse: collapse; background: var(--card);
    border-radius: var(--raio); font-size: 13px;
  }
  /* Envoltório que NÃO rola (ver instalarIndicadorRolagem em app.js): assume o
     flex:1/min-height que antes era da própria .tabela-scroll, e serve de
     referência fixa pras barrinhas de rolagem — .tabela-scroll continua sendo a
     única coisa que realmente rola, só que agora preenche 100% deste envoltório
     em vez de ser ela mesma o filho direto de .vista-tabela. */
  .tabela-scroll-envoltorio {
    position: relative; display: flex; flex: 1; min-height: 200px;
  }
  /* ACHADO (a barra horizontal continuava com bug, apontado pelo Netto): a tabela
     de dentro de modal (Histórico de reprogramação orçamentária, em
     abrirHistoricoOrcamento) fica dentro de .modal-caixa, que NÃO é flex — então
     o "flex:1" acima não tem efeito nenhum ali, a tabela crescia pra caber TODAS
     as linhas de uma vez, sem limite nenhum embaixo, e quem rolava era o modal
     inteiro, não a planilha. Sem um fim definido pra tabela, a barrinha
     horizontal (presa no "fim" dela) ficava lá embaixo, fora da parte visível —
     exatamente o bug relatado. Limite definido explicitamente aqui: dentro de
     modal a tabela ganha um teto próprio (max-height) e passa a rolar por
     dentro, como nas abas principais. */
  .modal-caixa .tabela-scroll-envoltorio {
    flex: none; max-height: 45vh; min-height: 160px;
  }
  .tabela-scroll {
    background: var(--card); border: 1px solid #E5E7EB; border-radius: var(--raio);
    box-shadow: var(--sombra); overflow-x: auto; overflow-y: auto;
    /* Antes isso era calc(100vh - 260px), um "chute" de altura que nem sempre batia
       com o espaço real sobrando. Agora .vista-tabela é flex column e o envoltório
       acima é flex:1 dentro dela — ocupa exatamente o que sobra depois da barra de
       ferramentas, sem cálculo aproximado, e é só ELA que rola (nunca o #conteudo
       nem a janela), igual ao viewport interno do QTableWidget no Mac. */
    flex: 1; min-width: 0;
  }
  .tabela-dados thead th {
    /* QHeaderView::section exato: font-size 12px, padding 10px 8px. */
    background: #E8EEF5; color: var(--primaria); text-align: center; font-weight: 700;
    font-size: 12px; padding: 10px 8px; white-space: nowrap; border-bottom: 1px solid var(--borda);
    position: sticky; top: 0; z-index: 1;
  }
  /* Igual ao setSortingEnabled(True) do Mac: clicar num cabeçalho ordena a tabela por
     aquela coluna (clicar de novo inverte), com uma setinha mostrando coluna e sentido
     atual — antes as tabelas daqui não tinham essa ordenação nenhuma. */
  .tabela-dados thead th.th-ordenavel { cursor: pointer; user-select: none; padding-right: 20px; }
  .tabela-dados thead th.th-ordenavel:hover { background: #DCE6F0; }
  .tabela-dados thead th.th-ordenavel.ativo { color: var(--primaria-escura); background: #DCE6F0; }
  /* Redimensionar coluna (não existe no Mac, recurso extra a pedido do Netto, igual
     ao Excel): "⋮" digita um valor exato em pixels, e a faixa fina na borda direita
     arrasta pra mudar a largura aos poucos ou recebe 2 cliques pra ajustar automático
     ao tamanho do texto (autofit). position:sticky do th já serve de referência pros
     dois ficarem grudados nele. */
  .tabela-dados thead th .rotulo-coluna { pointer-events: none; }
  .tabela-dados thead th .btn-largura-coluna {
    position: absolute; top: 3px; right: 9px; font-size: 11px; line-height: 1;
    color: var(--texto-suave); cursor: pointer; padding: 1px 3px; border-radius: 4px; opacity: .55;
  }
  .tabela-dados thead th .btn-largura-coluna:hover { opacity: 1; background: #fff; }
  .tabela-dados thead th .alca-redimensionar {
    position: absolute; top: 0; right: 0; bottom: 0; width: 7px; cursor: col-resize; z-index: 2;
  }
  .tabela-dados thead th .alca-redimensionar:hover { background: rgba(18,61,102,.3); }
  /* Altura de linha PADRÃO 34px (verticalHeader().setDefaultSectionSize(34) no Mac),
     mas não travada: o QTableView do Mac tem wordWrap ligado por padrão e roda
     resizeRowsToContents() depois de carregar os dados, então quando um nome é
     grande de mais pro espaço da coluna, o texto quebra linha e a LINHA cresce pra
     caber. Print real comparado lado a lado mostrou que min-height NÃO é respeitado
     de forma confiável em <td> pelo navegador (linhas ficavam com metade da altura
     do Mac) — height, ao contrário do que eu tinha assumido antes, funciona como um
     mínimo em células de tabela (não corta conteúdo), então é o jeito certo aqui:
     linha simples fica exatamente 34px, e ainda cresce se o texto quebrar em 2 linhas.
     Padding exato do QTableView::item (2px 6px). white-space normal por padrão:
     cada tabela abaixo trava só as colunas curtas/numéricas em nowrap. */
  .tabela-dados tbody td {
    height: 34px; box-sizing: border-box; padding: 2px 6px; text-align: center;
    border-bottom: 1px solid #EEF2F7; color: var(--texto); white-space: normal;
    word-break: break-word; vertical-align: middle;
    transition: background-color .12s ease;
    /* Sem isso, duplo clique numa palavra (ex.: "Nevton e Vilas Boas") selecionava o
       texto do navegador ANTES de abrir a edição — um clique tem que só marcar a
       célula (nosso .celula-selecionada) e dois cliques têm que abrir a edição direto,
       sem esse texto selecionado/azul no meio do caminho, igual ao QTableView do Mac
       (que nunca deixa o usuário selecionar texto solto dentro de uma célula). */
    user-select: none; -webkit-user-select: none;
  }
  /* Colunas curtas/numéricas/data não quebram linha (não faz sentido "Não" ou
     "16/12/2025" virar duas linhas) — só as colunas de texto livre quebram.
     A coluna "Item" foi removida (pedido do Netto): em vez de coluna própria só com o
     código, o vínculo com o Orçamento virou prefixo DENTRO da coluna Serviço (coluna 4
     agora, era 5) — "ORC-001 Coordenação Geral · Consultoria". Por isso as colunas
     deslocaram 1 posição pra trás a partir daqui (Data agora é 2, era 3; e assim por
     diante). */
  .tabela-lancamentos td:nth-child(1), .tabela-lancamentos td:nth-child(2),
  .tabela-lancamentos td:nth-child(7), .tabela-lancamentos td:nth-child(8),
  .tabela-lancamentos td:nth-child(9), .tabela-lancamentos td:nth-child(10),
  .tabela-lancamentos td:nth-child(11), .tabela-lancamentos td:nth-child(12) { white-space: nowrap; }
  .tabela-fornecedores td:nth-child(1), .tabela-fornecedores td:nth-child(3),
  .tabela-fornecedores td:nth-child(4), .tabela-fornecedores td:nth-child(8),
  .tabela-fornecedores td:nth-child(9) { white-space: nowrap; }
  /* Financiadores é quase igual a Fornecedores (ID, Nome, Tipo, Documento, PIX,
     Contato, Natureza), mas com DOIS documentos em vez de um: Comprovante (coluna 8,
     era "Termo") e Contrato (coluna 9, novo — pedido do Netto), o que empurra Total
     Aportado pra 10 e Observações pra 11. */
  .tabela-financiadores td:nth-child(1), .tabela-financiadores td:nth-child(3),
  .tabela-financiadores td:nth-child(4), .tabela-financiadores td:nth-child(8),
  .tabela-financiadores td:nth-child(9), .tabela-financiadores td:nth-child(10) { white-space: nowrap; }
  .tabela-orcamento td:nth-child(1), .tabela-orcamento td:nth-child(5),
  .tabela-orcamento td:nth-child(6), .tabela-orcamento td:nth-child(7),
  .tabela-orcamento td:nth-child(8), .tabela-orcamento td:nth-child(9) { white-space: nowrap; }
  /* Com width:auto (ver comentário acima), uma coluna de texto livre sem limite
     nenhum só cresce o quanto for preciso pra caber tudo numa linha só. Só max-width
     não bastava: numa tela mais estreita o algoritmo de "shrink-to-fit" da tabela
     comprime QUALQUER coluna com white-space:normal até quase a largura de uma única
     palavra (porque ela PODE quebrar mais, então o navegador prefere encolher a
     coluna inteira em vez de deixar a tabela estourar a largura da tela) — foi isso
     que fez até "Etapa" e "Grupo" virarem uma sopa de linhas de 1-2 palavras cada.
     min-width junto com max-width trava um piso: a coluna quebra linha quando o
     texto é mais longo que isso, mas nunca fica mais estreita que isso — daí, numa
     tela estreita, é a TABELA que passa da largura da tela (e o .tabela-scroll, que
     já tem overflow-x:auto, ganha a rolagem horizontal de verdade), exatamente como
     pedido: rolagem horizontal quando a proporção da tela mudar, em vez de espremer
     o texto em várias linhas curtas. */
  .tabela-lancamentos td:nth-child(3) { min-width: 160px; max-width: 200px; }
  /* "Item do Orçamento" (coluna 4, era "Serviço"): ganhou um pouco mais de largura
     que Fornecedor pra caber "ORC-001 Nome do item" sem cortar demais. */
  .tabela-lancamentos td:nth-child(4) { min-width: 200px; max-width: 280px; }
  .tabela-lancamentos td:nth-child(5) { min-width: 110px; max-width: 140px; }
  .tabela-lancamentos td:nth-child(6) { min-width: 130px; max-width: 160px; }
  .tabela-fornecedores td:nth-child(2), .tabela-fornecedores td:nth-child(7) { min-width: 160px; max-width: 200px; }
  .tabela-fornecedores td:nth-child(5) { min-width: 110px; max-width: 160px; }
  .tabela-fornecedores td:nth-child(6), .tabela-fornecedores td:nth-child(10) { min-width: 140px; max-width: 180px; }
  .tabela-financiadores td:nth-child(2), .tabela-financiadores td:nth-child(7) { min-width: 160px; max-width: 200px; }
  .tabela-financiadores td:nth-child(5) { min-width: 110px; max-width: 160px; }
  .tabela-financiadores td:nth-child(6), .tabela-financiadores td:nth-child(11) { min-width: 140px; max-width: 180px; }
  .tabela-orcamento td:nth-child(2) { min-width: 160px; max-width: 200px; }
  .tabela-orcamento td:nth-child(3) { min-width: 110px; max-width: 140px; }
  .tabela-orcamento td:nth-child(4) { min-width: 130px; max-width: 160px; }
  .tabela-dados tbody tr:nth-child(even) td { background: #F9FAFB; }
  .tabela-dados tbody tr:last-child td { border-bottom: none; }
  .tabela-dados tbody tr:hover td { background: #F7F9FB; cursor: pointer; }
  .tabela-dados tbody tr.linha-pendente-pc td { background: var(--vermelha-bg); }
  .tabela-dados tbody tr.linha-pendente-pc:hover td { background: #FCD5D5; }
  /* Célula selecionada (clique único), igual ao SelectItems do CopyableTableView no Mac
     (#DBEAFE): destaca só a célula clicada, não a linha inteira. Ctrl+C/Cmd+C copia o
     valor dela (ver keydown global em app.js). Fica assim até clicar em outra célula. */
  .tabela-dados tbody td.celula-selecionada { background: #DBEAFE !important; }
  /* Flash verde de confirmação ao copiar por clique direito (desktop) ou toque
     longo (celular) — ver copiarCelulaPorGesto em app.js. Some sozinho depois de
     meio segundo, não precisa de clique nenhum pra fechar. */
  /* .celula-copiada e .celula-whatsapp viraram regras globais (fora deste bloco de
     1024px) — ver comentário perto de .linha-lista — porque o span de WhatsApp
     também aparece no cartão do celular, não só aqui na tabela. */
  .tabela-dados td.verde { color: var(--verde); font-weight: 600; }
  .tabela-dados td.vermelha { color: var(--vermelha); font-weight: 600; }
  .tabela-dados td.laranja { color: var(--laranja); font-weight: 600; }

  /* Coluna ID voltou a rolar junto com o resto da planilha na horizontal (pedido do
     Netto: "os IDS das planilhas estão fixos e não rolam, pode deixar fluir normal").
     Antes ela ficava grudada na borda esquerda (position:sticky) ao rolar pro lado,
     igual ao Excel com a primeira coluna congelada — bom pra planilha com MUITAS
     colunas, mas não era isso que o Netto queria aqui: a rolagem inteira, ID incluso,
     deve fluir junto, sem nada fixo. Nenhuma regra própria = a coluna ID volta a se
     comportar como qualquer outra célula da tabela. */

  /* Clipe fixo à esquerda do número de NF/Comprovante/Contrato quando existe anexo,
     igual ao DocumentoNumeroDelegate do Mac (ícone sempre na mesma posição, número
     centralizado no espaço restante da coluna). */
  /* setColumnWidth exatos do Mac: Nº NF/Nº Comp. = 126px, Contrato = 86px, com
     resize mode Fixed (não mudam de tamanho conforme o conteúdo). */
  .tabela-dados td.col-documento { position: relative; width: 126px; }
  .tabela-dados td.col-contrato { width: 86px; }
  .tabela-dados .clipe-anexo {
    position: absolute; left: 8px; top: 50%; transform: translateY(-50%);
    width: 13px; height: 13px; color: var(--texto-suave);
  }
  .tabela-dados .clipe-anexo svg { width: 100%; height: 100%; display: block; }

  /* Barra de rolagem fina igual ao QScrollBar do Mac (10px, trilho cinza claro,
     alça arredondada), só dentro do container da tabela — o resto da página não
     ganha essa barra customizada. */
  .tabela-scroll::-webkit-scrollbar { width: 10px; height: 10px; }
  .tabela-scroll::-webkit-scrollbar-track { background: #F3F4F6; border-radius: 5px; }
  .tabela-scroll::-webkit-scrollbar-thumb { background: #CBD5E1; border-radius: 5px; }

  /* Indicador de rolagem próprio (ver instalarIndicadorRolagem em app.js): a
     barra ::-webkit-scrollbar acima não aparece no Safari do iPad (o toque usa
     o indicador nativo do sistema, que some sozinho ao soltar o dedo) — por
     isso essas barrinhas só ficam visíveis em aparelho de toque de verdade. No
     computador (sem dispositivo-tablet-real) elas continuam ocultas: a
     scrollbar customizada acima já resolve. Ficam dentro de
     .tabela-scroll-envoltorio (que não rola), não mais dentro da própria
     .tabela-scroll — por isso quem leva o position:relative agora é o
     envoltório (ver regra dele acima). */
  /* Visual harmônico e fluido (pedido do Netto): pílula com leve gradiente em vez
     de um bloco chapado, e transição suave também em posição/tamanho (não só
     opacidade) — a barra "desliza" acompanhando o dedo em vez de pular de
     lugar em lugar. Continua SEMPRE visível quando há conteúdo pra rolar (nunca
     opacidade 0), só muda de intensidade: mais forte durante a rolagem de
     verdade (classe "rolando", ver marcarRolagemAtiva em app.js), meio segundo
     depois volta sozinha pro repouso, mais discreta — sem nunca sumir de vez,
     que era o problema original do indicador nativo do iOS que motivou essa
     barra própria existir. */
  .indicador-rolagem-h, .indicador-rolagem-v {
    display: none; position: absolute;
    background: linear-gradient(180deg, rgba(30, 90, 150, .55), rgba(18, 61, 102, .4));
    border-radius: 999px; pointer-events: none; z-index: 3;
    box-shadow: 0 1px 3px rgba(11, 42, 73, .18);
    opacity: 0;
    transition: opacity .25s ease, left .12s ease-out, top .12s ease-out,
      width .18s ease-out, height .18s ease-out, background-color .2s ease;
  }
  .indicador-rolagem-h.visivel, .indicador-rolagem-v.visivel { opacity: .55; }
  .indicador-rolagem-h.visivel.rolando, .indicador-rolagem-v.visivel.rolando {
    opacity: .9;
    background: linear-gradient(180deg, rgba(37, 110, 180, .78), rgba(18, 61, 102, .62));
  }
  .indicador-rolagem-h { left: 0; bottom: 4px; height: 6px; }
  .indicador-rolagem-v { top: 0; right: 4px; width: 6px; }
  .indicador-rolagem-h.rolando { height: 7px; }
  .indicador-rolagem-v.rolando { width: 7px; }
  html.dispositivo-tablet-real .indicador-rolagem-h,
  html.dispositivo-tablet-real .indicador-rolagem-v { display: block; }

  /* Modal de editar/criar (LancamentoDialog/FornecedorDialog no Mac): uma janela
     centralizada de largura fixa (~700px, entre os 900px e 820px dos dois diálogos
     do Mac, adaptado pro formulário de uma coluna só da versão web) com cantos
     arredondados nos 4 lados e o próprio miolo rolando por dentro — não mais a folha
     ocupando a tela toda de baixo pra cima, que só faz sentido no celular. */
  .modal-fundo { align-items: center; justify-content: center; }
  .modal-caixa {
    width: 700px; max-width: 90vw; max-height: 82vh; border-radius: 18px; padding: 10px 26px 22px;
    box-shadow: 0 20px 60px rgba(11,42,73,.35);
  }
  .modal-alca { display: none; }

  /* Barra de ferramentas acima da tabela (Adicionar / Editar selecionado / Abrir
     anexos / Excluir selecionado), igual à faixa de botões acima das tabelas no Mac.
     Fica fora do container que rola, então não some quando a lista é longa. */
  .barra-ferramentas {
    display: flex; gap: 8px; margin-bottom: 12px; flex-wrap: wrap; flex: none;
  }
  .barra-ferramentas button {
    /* Valor exato do QPushButton genérico do app.py (Adicionar/Editar
       selecionado/Abrir anexos/Excluir selecionado são QPushButton comuns, sem
       objectName próprio): border-radius:10px, padding:10px 16px, font-weight:600,
       font-size herdado de QWidget 13px = .81rem. */
    background: var(--primaria); color: #fff; border: none; border-radius: 10px;
    padding: 10px 16px; font-size: .81rem; font-weight: 600;
    transition: background-color .15s ease, transform .1s ease, box-shadow .15s ease;
  }
  .barra-ferramentas button:hover:not(:disabled) { background: #0B2F50; box-shadow: 0 4px 12px rgba(11,42,73,.25); }
  .barra-ferramentas button:active:not(:disabled) { transform: scale(.96); }
  .barra-ferramentas button:disabled { background: #C7D2DE; cursor: not-allowed; }
  .barra-ferramentas button.perigo { background: var(--vermelha); }
  .barra-ferramentas button.perigo:hover:not(:disabled) { background: #d40000; box-shadow: 0 4px 12px rgba(251,2,7,.22); }
  .barra-ferramentas button.perigo:disabled { background: #E9B4B4; }
}

/* ---------- ALVOS DE TOQUE MAIORES (iPad em paisagem e qualquer tela "desktop"
   operada por dedo, não por mouse/trackpad) ----------
   O bloco de 1024px acima foi calibrado pixel a pixel pelo QSS do app do Mac, que é
   operado com mouse/trackpad — ponteiro fino, precisão de poucos pixels. O iPad Air
   11" M2 deitado (paisagem) mede 1180px lógicos de largura, então cai DENTRO dessa
   mesma faixa "desktop" (900-1699px) e herda esses mesmos botões pequenos, só que
   agora tocados com o dedo, não clicados com o cursor.
   Em vez de perguntar ao Netto se ele usa Magic Keyboard/trackpad no iPad (ele pode
   trocar de contexto a qualquer momento), a própria tela já informa isso: a media
   feature "pointer: coarse" é verdadeira quando o ponteiro PRINCIPAL do dispositivo
   é grosso/impreciso (dedo), e "hover: none" quando não existe like um mouse pairando
   por cima sem clicar — as duas juntas descrevem exatamente um touchscreen puro,
   sem teclado/trackpad Bluetooth conectado. Um MacBook de verdade, mesmo redimensionado
   pra uma janela estreita, nunca bate as duas condições (o trackpad é sempre
   "pointer:fine"), então esse bloco NUNCA afeta quem usa mouse/trackpad de verdade —
   só entra em ação quando o toque é o único jeito de interagir com a tela.
   Referência de tamanho mínimo confortável de toque: 44x44px (diretriz da própria
   Apple, Human Interface Guidelines, seção "Layout"). */
@media (min-width: 1024px) and (hover: none) and (pointer: coarse) {
  /* Ícones do cabeçalho (desfazer/refazer, limpar anexos, sair): 34x34 vira 44x44,
     mesma proporção de ícone por dentro (era 18/34 = 53%, mantém 20/44 = 45%, bem
     próximo, só ligeiramente mais folgado). */
  .btn-icone-topo, .btn-sair { width: 44px; height: 44px; }
  .btn-icone-topo svg, .btn-sair svg { width: 20px; height: 20px; }
  #btn-limpar-anexos-topo { width: auto; height: 44px; padding: 10px 14px; }

  /* Abas de navegação (.nav-item): a pílula de 38px de altura (10px padding + 1px
     borda + 16px ícone, ver conta detalhada lá em cima) cresce pra ~46px, folga
     extra nas laterais também pra reduzir toque errado na pílula vizinha. */
  .nav-item { padding: 14px 20px; min-width: 128px; }
  .nav-item svg { width: 18px; height: 18px; }

  /* Botões de modal/formulário (Salvar, Cancelar, Excluir dentro de diálogos): a
     redução pro tamanho do QPushButton de mouse (10px18/10px16/9px14) some aqui,
     voltando perto do valor já usado no celular (13px/12px/12px), que já nasceu
     pensado pra dedo. */
  .btn-primario { padding: 13px 20px; }
  .btn-secundario { padding: 12px 18px; }
  .btn-perigo { padding: 12px 16px; }
  .anexo-linha .btn-anexar { padding: 13px 18px; }
  .anexo-linha .btn-remover-anexo { padding: 12px 16px; }

  /* Botões da barra de ferramentas acima das tabelas (Adicionar/Editar/Abrir
     anexos/Excluir): mesmo raciocínio, um pouco mais de padding vertical. */
  .barra-ferramentas button { padding: 13px 18px; }

  /* Botão "x" de fechar modal: 30px é meio justo pro dedo mirar rápido, sobe
     pra 38px sem exagerar (o círculo continua discreto). */
  #modal-fechar { width: 38px; height: 38px; font-size: 1.4rem; }

  /* ---- Tabelas em modo toque (só aparecem aqui a partir de 1024px, ou seja, só
     o iPad DEITADO chega nelas — nenhum iPhone, nem o Pro Max deitado, chega a
     1024px de largura, então essa parte é território exclusivo do iPad/tablet
     de verdade). Dois
     controles da tabela foram desenhados para um cursor de mouse mirando 1 pixel
     exato, e ficam praticamente impossíveis de usar com o dedo: */
  /* 1) A alça de arrastar pra redimensionar coluna tem 7px de largura — beirando
     o invisível pro toque (a Apple recomenda mínimo de 44pt de alvo, ainda que a
     alça seja fina visualmente, o ALVO de toque real precisa ser bem maior). */
  .tabela-dados thead th .alca-redimensionar { width: 18px; }
  /* 2) O ícone "⋮" de digitar largura exata: 11px de fonte, padding de 1-3px, e só
     fica bem visível no :hover — que touch não dispara de forma confiável, então
     ficava praticamente escondido até a pessoa esbarrar nele sem querer. Aumentado
     e sempre visível (sem depender de hover), com respiro pra não brigar com a
     alça de redimensionar ao lado (que também cresceu). */
  .tabela-dados thead th .btn-largura-coluna {
    font-size: 14px; padding: 4px 6px; opacity: .85; right: 22px;
  }
  /* Linha da tabela: 34px é o valor exato do QTableView do Mac (alvo de mouse);
     no dedo, cada linha vira um alvo de toque próprio (1 toque seleciona a
     célula, 2 toques abre a edição) — um pouco mais de altura reduz toque na
     linha vizinha por engano. */
  .tabela-dados tbody td { height: 40px; }
}

/* ---------- IPAD DEITADO: IDÊNTICO AO MAC ----------
   BLINDAGEM PARA O CELULAR (pedido explícito do Netto): tudo daqui pra baixo,
   até o fim deste bloco de calibragem de iPad, agora vive DENTRO de um
   @media (min-width:1024px). Isso é intencional e importante: o
   html.dispositivo-tablet-real (toque real via maxTouchPoints) é verdadeiro
   tanto no iPhone quanto no iPad, então SEM essa faixa de largura essas
   regras vazariam pro iPhone também.
   CORREÇÃO DE ROTA (achado do Netto testando no celular deitado): o limiar
   era 900px, mas o iPhone Pro Max deitado chega a reportar 932px de largura
   de verdade pro CSS — não é disfarce nenhum do iPad, é a largura real desse
   aparelho específico virado de lado. Com 900px como limiar, ESSE iPhone
   sozinho entrava no bloco pensado pro iPad/Mac, enquanto iPhones menores
   deitados (abaixo de 900px) não entravam — dando o efeito de "letra menor
   num aparelho, maior em outro" que o Netto reportou, tudo dependendo do
   modelo. 1024px resolve por construção: o MAIOR iPhone deitado que existe
   (932px) fica confortavelmente abaixo, e o MENOR iPad deitado que existe
   (iPad mini, 1024px) continua alcançando o limiar — então daqui pra baixo
   é território 100% exclusivo de iPad/Mac, nunca de iPhone, em nenhuma
   orientação e em nenhum modelo. Zero risco pro celular, por construção.
   MUDANÇA DE ROTA (pedido do Netto): antes os botões do painel eram 15%
   menores só no iPad, pra caber as 7 abas numa linha só sem quebrar (o Mac
   normalmente tem largura de sobra, o iPad deitado nem sempre). Depois o
   pedido virou "iPad deitado idêntico ao Mac" — então o tamanho dos botões
   AQUI FOI REMOVIDO DE PROPÓSITO (sem regra própria = herda exatamente o
   .nav-item do Mac, pixel a pixel), e a rolagem horizontal (igual ao
   celular) entrou como rede de segurança pras 7 abas não quebrarem feio em
   2 linhas se não coubessem inteiras numa linha só.
   REMOVIDA (pedido do Netto, achado real): a barra de rolagem tinha o
   scrollbar escondido de propósito (scrollbar-width:none), então visualmente
   ela parecia a MESMA coisa que o bug antigo de botão cortado — sem nenhuma
   pista visível de "isso rola", os últimos botões apareciam cortados na
   borda direita, sem jeito óbvio de saber que dava pra arrastar pra ver o
   resto. Relatórios saiu do nav-inferior nessa mesma sessão (virou botão da
   sidebar), então agora são só 6 abas, não mais 7 — cabem com folga numa
   linha só no iPad deitado (1180px lógicos de largura, menos a sidebar de
   250px) no tamanho cheio do Mac, sem precisar de rolagem nenhuma. Sem regra
   própria aqui, o .nav-inferior volta a herdar o "flex-wrap:wrap" já
   declarado na regra base de 1024px (linha ~866) como rede de segurança: se
   algum dia sobrar pouco espaço de verdade, quebra pra 2 linhas de forma
   limpa e visível, em vez de esconder abas atrás de uma rolagem invisível. */
@media (min-width: 1024px) {
  /* CORREÇÃO (botões pequenos voltaram no iPad, pedido do Netto): o bloco de
     "pointer:coarse" lá em cima (linha ~1265) tem sua PRÓPRIA regra .nav-item, que
     só entra em ação quando o iPad está sendo usado só por toque, sem Magic
     Keyboard/trackpad Bluetooth conectado (pointer:fine some, pointer:coarse fica
     verdadeiro). Sem uma regra própria aqui, o tamanho do botão ficava dependendo
     do acessório conectado: 116px/10px18 (base do Mac) com teclado, 128px/14px20
     (aumento de acessibilidade) sem teclado — inconsistente, e o print que o Netto
     mandou (aparelho sem teclado) caía no segundo caso, menor do que ele esperava
     ver como "idêntico ao Mac". Esta regra usa 2 seletores no "html.dispositivo-
     tablet-real .nav-item" (especificidade maior que o ".nav-item" sozinho do
     bloco de pointer:coarse), travando o tamanho do Mac sempre, goste o pointer
     for coarse ou fine — sem depender de acessório. Não elimina o bloco de
     pointer:coarse pros OUTROS elementos dele (botões de modal, linhas de tabela
     etc.), só pro nav-item especificamente, que é o único que o Netto reportou. */
  html.dispositivo-tablet-real .nav-item {
    padding: 10px 18px; font-size: .81rem; min-width: 116px; gap: 8px; margin: 4px;
  }
  html.dispositivo-tablet-real .nav-item svg { width: 16px; height: 16px; }

  /* CORREÇÃO REAL da caixa Top Fornecedor cortada no iPad deitado (pedido do Netto,
     achado depois de aumentar a altura do próprio <select> e ainda assim continuar
     cortando): a causa de verdade não era o seletor, era o CARTÃO em volta dele.
     .card-top (ver regra "faixa-superior-dashboard .card-top" logo acima, fora deste
     bloco) tem height FIXO de 172px + overflow:hidden, calibrado pixel a pixel pro
     QFrame do Mac (frame.setFixedHeight(172)). O conteúdo desse cartão específico é
     bem mais alto que os outros 2 da mesma fileira (pendências): título do seletor +
     nome do fornecedor + "Recebido: X | Y%" + "Status" + "Margem até o limite" +
     valor da margem, 5 linhas de texto além do próprio seletor. No Mac a fonte nativa
     renderiza compacta o bastante pra caber nos 172px; o Safari do iPadOS renderiza
     mais espaçado (mesmo raciocínio da altura do seletor: mesma fonte, plataforma
     diferente, métrica diferente) e o overflow:hidden corta o que sobra por baixo —
     por isso aumentar só o seletor não resolveu, o corte real estava mais embaixo.
     Fix: pro iPad, troca height fixo por min-height (nunca mais baixo que 172px, mas
     cresce à vontade se o conteúdo pedir mais) e desliga o overflow:hidden. O Mac
     continua com os 172px exatos originais (a regra abaixo só entra com
     html.dispositivo-tablet-real, nunca em tela de computador de verdade). Como
     .faixa-superior-dashboard já tem align-items:stretch, os 2 cartões de pendência
     ao lado esticam sozinhos pra acompanhar a altura nova do Top Fornecedor — a
     fileira continua alinhada, só que auto-ajustável em vez de um número fixo
     chutado no CSS. */
  html.dispositivo-tablet-real .faixa-superior-dashboard .card-top,
  html.dispositivo-tablet-real .faixa-superior-dashboard .linha-governanca .card {
    height: auto; min-height: 172px; overflow: visible;
  }

  /* ---------- IPAD EM PÉ FORÇADO A RODAR IGUAL AO CELULAR ----------
     Pedido explícito do Netto: "em vertical tem que rodar exatamente como
     roda o sistema do iPhone". O motivo de isso não acontecer sozinho: o
     Safari/Chrome do iPad fingem uma largura de computador pras media
     queries do CSS (min-width:1024px em diante), então mesmo com o iPad
     literalmente em pé o navegador dizia pro CSS "essa tela tem mais de
     1024px", ativando sidebar, visão em tabela e todo o resto do bloco
     pensado pro Mac.
     html.dispositivo-tablet-real.orientacao-retrato-real só existe quando o
     próprio JS (não a media query, que é fingível) confirma toque real de
     dedo + orientação em pé pelo sensor giroscópio — combinação que o "site
     para computador" não disfarça. Cada regra abaixo desfaz, um por um, os
     overrides que o bloco de min-width:1024px aplica, devolvendo o mesmo
     shell mobile-first que o iPhone usa. */
  html.dispositivo-tablet-real.orientacao-retrato-real .sidebar-desktop { display: none; }
  html.dispositivo-tablet-real.orientacao-retrato-real,
  html.dispositivo-tablet-real.orientacao-retrato-real body { height: auto; overflow: visible; }
  html.dispositivo-tablet-real.orientacao-retrato-real .app {
    display: flex; flex-direction: column; grid-template-columns: none;
    grid-template-areas: none; height: auto; overflow: visible; padding-bottom: 74px;
  }
  html.dispositivo-tablet-real.orientacao-retrato-real .topo {
    grid-area: unset; position: sticky; grid-template-columns: auto 1fr auto;
    background: var(--primaria); color: #fff; box-shadow: 0 2px 12px rgba(11,42,73,.18);
    border-bottom: none; padding: 10px 14px; padding-top: calc(10px + env(safe-area-inset-top));
  }
  html.dispositivo-tablet-real.orientacao-retrato-real .topo-marca { display: flex; }
  html.dispositivo-tablet-real.orientacao-retrato-real .topo-titulo {
    text-align: center; justify-self: unset; font-size: .92rem; color: #fff; letter-spacing: -.01em;
  }
  html.dispositivo-tablet-real.orientacao-retrato-real .btn-icone-topo,
  html.dispositivo-tablet-real.orientacao-retrato-real .btn-sair {
    background: rgba(255,255,255,.14); color: #fff; padding: 8px;
  }
  html.dispositivo-tablet-real.orientacao-retrato-real #btn-mais-topo { display: flex; }
  html.dispositivo-tablet-real.orientacao-retrato-real #btn-limpar-anexos-topo { display: none; }
  html.dispositivo-tablet-real.orientacao-retrato-real #btn-desfazer,
  html.dispositivo-tablet-real.orientacao-retrato-real #btn-refazer { display: none; }
  html.dispositivo-tablet-real.orientacao-retrato-real .topo-busca { display: none !important; }
  html.dispositivo-tablet-real.orientacao-retrato-real .conteudo {
    grid-area: unset; max-width: none; width: auto; padding: 18px 16px; overflow-y: visible;
  }
  html.dispositivo-tablet-real.orientacao-retrato-real .nav-inferior {
    position: fixed; grid-area: unset; max-width: none; left: 0; right: 0; bottom: 0;
    transform: none; border-radius: 0; justify-content: flex-start;
    overflow-x: auto; min-height: 0; height: auto; padding: 0; flex-wrap: nowrap;
  }
  /* Reverte a pílula (a mesma classe .nav-item vira aba de computador no
     bloco de 1024px e ícone-em-cima-do-texto no mobile) de volta pro visual
     pequeno do celular — vence a redução de 15% de cima por ter mais classes
     no seletor (2 x 1), então ganha nessa combinação específica. */
  html.dispositivo-tablet-real.orientacao-retrato-real .nav-item {
    flex: 0 0 auto; min-width: 74px; padding: 10px 6px 8px; margin: 0;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
    font-size: .6rem; background: none; border: none; border-radius: 0; color: var(--texto-suave);
    font-weight: 600; line-height: 1;
  }
  html.dispositivo-tablet-real.orientacao-retrato-real .nav-item svg { width: 23px; height: 23px; }
  html.dispositivo-tablet-real.orientacao-retrato-real .nav-item.ativo {
    background: none; border-color: transparent; color: var(--primaria); font-weight: 600; box-shadow: none;
  }
  html.dispositivo-tablet-real.orientacao-retrato-real .vista-cartoes { display: block; }
  html.dispositivo-tablet-real.orientacao-retrato-real .vista-tabela { display: none; }
  html.dispositivo-tablet-real.orientacao-retrato-real .tira-cards {
    display: flex; grid-template-columns: none; overflow-x: auto;
  }
}

/* ---------- CALIBRAGEM ULTRAWIDE (monitor 2560x1080 do Netto, 21:9) ----------
   CORREÇÃO DE RUMO: a versão anterior travava o .conteudo numa largura fixa e
   centralizava — na prática isso transforma um monitor ultrawide num monitor
   comum com uma margem morta de cada lado, o oposto de "otimizar". O pedido do
   Netto é usar o espaço extra, não escondê-lo. Removida a trava de max-width:
   o .conteudo volta a ocupar 100% do espaço ao lado da sidebar (como já era
   antes de 1024px pra cima, ver linha ~792), e cada componente abaixo já é
   fluido por natureza (grid auto-fit, flex, canvas com maintainAspectRatio
   desligado) — então o espaço extra vira MAIS COLUNAS e MAIS TEXTO LEGÍVEL,
   não vão vazio. */
@media (min-width: 1700px) {
  /* tira-cards (KPIs do Dashboard): grid auto-fit já adiciona colunas sozinho
     conforme sobra espaço — só ajustei o piso mínimo do card pra não ficar uma
     fileira de 10+ cards espremidos numa tela de 2560px, cada um ganha mais
     "corpo" em vez de só multiplicar em miniatura. */
  .tira-cards { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
  /* O quadro do gráfico (Chart.js com maintainAspectRatio:false) preenche a
     largura toda do .conteudo sozinho — só a altura precisa de um valor
     explícito (Canvas não tem altura fluida própria). Num monitor largo sobra
     altura de tela real, não só largura, então ganha mais respiro vertical. */
  .cartao-grafico { height: 380px; }
  /* Tabelas: as colunas de texto mais longo (serviço, observações, endereço)
     tinham um MAX-WIDTH pensado pra caber num notebook de 1512-1728px, cortando
     o texto com reticências mais cedo do que precisava. Num monitor de 2560px
     sobra muita largura real na tabela — soltar esse teto deixa mais texto
     aparecer sem cortar, em vez de deixar aquele espaço extra vazio do lado
     direito da tabela. Os min-width (piso) continuam os mesmos; só o teto sobe. */
  .tabela-lancamentos td:nth-child(3) { max-width: 320px; }
  .tabela-lancamentos td:nth-child(4) { max-width: 400px; }
  .tabela-lancamentos td:nth-child(6) { max-width: 260px; }
  .tabela-fornecedores td:nth-child(2), .tabela-fornecedores td:nth-child(7) { max-width: 320px; }
  .tabela-fornecedores td:nth-child(6), .tabela-fornecedores td:nth-child(10) { max-width: 280px; }
  .tabela-financiadores td:nth-child(2), .tabela-financiadores td:nth-child(7) { max-width: 320px; }
  .tabela-financiadores td:nth-child(6), .tabela-financiadores td:nth-child(11) { max-width: 280px; }
  .tabela-orcamento td:nth-child(2) { max-width: 320px; }
  .tabela-orcamento td:nth-child(4) { max-width: 260px; }
}

/* ---------- ACESSIBILIDADE: navegação por teclado ----------
   Sem isso, quem navega por Tab (teclado, leitor de tela) não tinha nenhum
   indicador visual de qual elemento está focado — só aparecia o contorno feio
   padrão do navegador em alguns casos e nada em outros. Usa :focus-visible (só
   mostra o contorno quando é navegação por teclado de verdade, não em cliques de
   mouse) pra não "sujar" o visual de quem usa mouse/touch normalmente. */
button:focus-visible, a:focus-visible, input:focus-visible, select:focus-visible,
textarea:focus-visible, [tabindex]:focus-visible {
  outline: 2px solid var(--primaria-clara);
  outline-offset: 2px;
}
