/* =========================================================
   Smart Assets — tema Smart Compass Omni / SmartPrecision
   Paleta e métricas extraídas de omni.smartcompass.com.br
   ========================================================= */
:root{
  /* neutros (zinc) */
  --bg:#fafafa; --card:#ffffff;
  --n50:#fafafa; --n100:#f4f4f5; --n200:#e4e4e7; --n300:#d4d4d8;
  --n400:#a1a1aa; --n500:#71717a; --n600:#52525b; --n700:#3f3f46; --n900:#18181b;
  --line:#e4e4e7; --line2:#f4f4f5;
  --txt:#11181c; --txt-strong:#18181b; --muted:#71717a; --muted2:#a1a1aa;

  /* primária */
  /* Primária DOURADA, a mesma da marca nos relatórios (#C9A84C).
     A escala não é a tradução direta da azul, e o motivo é contraste: o
     dourado é uma cor CLARA. Onde o azul era fundo com letra branca, o
     dourado é fundo com letra preta; e `--pri600`, que aqui é usado quase
     sempre como TEXTO (link, item ativo da lateral, aba ativa), vira o
     dourado escurecido, porque #C9A84C sobre branco não tem contraste.
     `--pri-hover` existe separado porque `--pri600` deixou de servir como
     fundo de hover no momento em que virou tinta de texto. */
  --pri50:#FBF6E6; --pri100:#F3E9CC; --pri200:#E3CE92; --pri:#C9A84C; --pri600:#7D6113; --pri700:#5B460E;
  --pri-hover:#B4923C;
  /* Tinta sobre o dourado cheio. O design system manda o botão primário ter
     fundo dourado e texto na cor do fundo escuro da marca. */
  --sobre-pri:#0A0A0A;
  /* secundária */
  --sec100:#e4d4f4; --sec:#7828c8; --sec600:#6020a0;
  /* semânticas */
  --ok100:#d1f4e0; --ok:#17c964; --ok600:#12a150; --ok700:#0e793c;
  --wr100:#fdedd3; --wr:#f5a524; --wr700:#936316;
  --dg50:#fee7ef; --dg100:#fdd0df; --dg200:#faa0bf; --dg:#f31260; --dg600:#c20e4d; --dg700:#920b3a;

  /* compat com nomes antigos usados em estilos inline do app.js */
  --navy:#18181b; --navy2:#27272a; --blue:#C9A84C; --teal:#7828c8;
  --green:#12a150; --red:#f31260; --amber:#936316;

  --radius:14px; --radius-sm:10px; --radius-xs:8px; --radius-ctl:12px; --pill:9999px;
  --shadow:0 1px 2px rgba(0,0,0,.04);
  --shadow-lg:0 12px 34px rgba(0,0,0,.14);
  --ring:0 0 0 2px rgba(201,168,76,.50);
  /* o painel abriga o rótulo mais longo ("Oportunidades Verificadas") com a
     setinha do submenu ao lado, em uma linha só */
  --rail:50px; --sidew:236px;
  --alto-relevo:#ffffff;        /* superfície que "sobe" sobre um campo preenchido */
  --toast-bg:#18181b; --toast-txt:#ffffff;
  /* ícones desenhados em SVG (não dá para usar var() dentro de url(), então a
     imagem inteira vira uma variável e o tema escuro a substitui) */
  --img-chevron:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2371717a' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  --img-calendario:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2371717a' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 2v4'/%3E%3Cpath d='M16 2v4'/%3E%3Crect width='18' height='18' x='3' y='4' rx='2'/%3E%3Cpath d='M3 10h18'/%3E%3C/svg%3E");
  --login-fundo:#0b1b33;        /* base do degrade da tela de acesso */
  --login-card:#ffffff;
  --login-borda:#e4e4e7;
  --login-txt:#52525b;
  /* O botao e o anel de foco do login passam a ser o azul do sistema. Como
     sao var() da primaria, o tema escuro os acerta sozinho e nao precisa
     redeclarar nada. */
  --login-btn:var(--pri);
  --login-btn-hover:var(--pri-hover);
  color-scheme:light;
}

/* ===== Tema escuro (paleta escura do HeroUI) ===== */
:root[data-tema="escuro"]{
  --bg:#000000; --card:#18181b;
  --n50:#18181b; --n100:#27272a; --n200:#3f3f46; --n300:#52525b;
  --n400:#71717a; --n500:#a1a1aa; --n600:#d4d4d8; --n700:#e4e4e7; --n900:#fafafa;
  --line:#27272a; --line2:#232326;
  --txt:#ecedee; --txt-strong:#fafafa; --muted:#a1a1aa; --muted2:#71717a;

  /* No escuro o texto dourado clareia em vez de escurecer — é a mesma lógica
     do azul que ele substitui, onde `--pri600` já era o tom mais claro. */
  --pri50:#241D08; --pri100:#3A2F10; --pri200:#5B460E; --pri:#C9A84C; --pri600:#E5C875; --pri700:#F0DEAE;
  --pri-hover:#D8BA63;
  --sec100:#3b0764; --sec:#9353d3; --sec600:#d8b4fe;
  --ok100:#052814; --ok:#17c964; --ok600:#45d483; --ok700:#74dfa2;
  --wr100:#312107; --wr:#f5a524; --wr700:#f9c97c;
  --dg50:#310413; --dg100:#610726; --dg200:#920b3a; --dg:#f31260; --dg600:#f871a0; --dg700:#faa0bf;

  --navy:#fafafa; --navy2:#27272a; --blue:#C9A84C; --teal:#9353d3;
  --green:#45d483; --red:#f31260; --amber:#f9c97c;

  --shadow:0 1px 2px rgba(0,0,0,.5);
  --shadow-lg:0 12px 34px rgba(0,0,0,.7);
  --alto-relevo:#3f3f46;
  --toast-bg:#e4e4e7; --toast-txt:#18181b;
  --img-chevron:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23a1a1aa' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  --img-calendario:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23a1a1aa' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 2v4'/%3E%3Cpath d='M16 2v4'/%3E%3Crect width='18' height='18' x='3' y='4' rx='2'/%3E%3Cpath d='M3 10h18'/%3E%3C/svg%3E");
  --login-fundo:#05070d;
  --login-card:#18181b;
  --login-borda:#3f3f46;
  --login-txt:#a1a1aa;
  color-scheme:dark;
}
/* No escuro, --ok700 vira verde claro: texto branco por cima ficaria ilegível */
:root[data-tema="escuro"] .badge.Encerrado{background:var(--ok700);color:#052814}
/* o favicon tem fundo branco; no escuro ele viraria um quadrado aceso no trilho */
:root[data-tema="escuro"] .rail-logo img{filter:invert(1) hue-rotate(180deg)}
*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{font-family:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  background:var(--bg);color:var(--txt);font-size:14px;line-height:1.45;
  -webkit-font-smoothing:antialiased}
button{font-family:inherit;cursor:pointer}
a{color:var(--pri600);text-decoration:none}
a:hover{text-decoration:underline}
.hidden{display:none !important}

/* ícones SVG inline — herdam a cor do texto e nunca encolhem no flex */
.ico{flex:0 0 auto;display:inline-block;vertical-align:-.18em}

/* =========================================================
   Shell: trilho de ícones + painel de navegação + conteúdo
   ========================================================= */
.shell{display:flex;min-height:100vh;align-items:stretch}

.rail{width:var(--rail);flex:0 0 var(--rail);border-right:1px solid var(--line);
  background:var(--bg);display:flex;flex-direction:column;align-items:center;
  gap:6px;padding:12px 0;position:sticky;top:0;height:100vh;z-index:60}
.rail-logo{width:30px;height:30px;border-radius:9px;overflow:hidden;display:grid;place-items:center;
  margin-bottom:10px;user-select:none}
.rail-logo img{width:30px;height:30px;display:block;object-fit:contain}
.rail-btn{width:34px;height:34px;border:none;background:transparent;border-radius:var(--radius-xs);
  display:grid;place-items:center;font-size:15px;color:var(--n600);line-height:1}
.rail-btn:hover{background:var(--n100);color:var(--txt)}
.rail-btn.active{background:var(--pri100);color:var(--pri600)}
.rail-spacer{flex:1}
.rail .avatar{width:26px;height:26px;border-radius:var(--pill);background:var(--sec);color:#fff;
  display:grid;place-items:center;font-size:12px;font-weight:600;
  border:none;font-family:inherit;padding:0;transition:box-shadow .12s}
.rail .avatar:hover{box-shadow:0 0 0 3px var(--sec100)}
.rail .avatar[aria-expanded="true"]{box-shadow:0 0 0 3px var(--sec100)}

/* menu da conta, aberto ao clicar no avatar */
.conta-pop{position:fixed;z-index:3200;min-width:230px;max-width:280px;background:var(--card);
  border-radius:var(--radius);padding:6px;
  box-shadow:0 0 15px rgba(0,0,0,.03),0 2px 30px rgba(0,0,0,.12),0 0 1px rgba(0,0,0,.3)}
.conta-cab{padding:10px 10px 12px;border-bottom:1px solid var(--line2);margin-bottom:6px}
.conta-nome{font-size:14px;font-weight:600;color:var(--txt-strong);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.conta-email{font-size:12px;color:var(--muted);margin:2px 0 8px;
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.conta-item{display:flex;align-items:center;gap:9px;width:100%;text-align:left;border:none;
  background:transparent;border-radius:var(--radius-xs);padding:8px 10px;
  font-family:inherit;font-size:14px;color:var(--txt)}
.conta-item:hover{background:var(--n100)}
.conta-item:disabled{opacity:.6;cursor:not-allowed}
.conta-item .ico{color:var(--muted)}

.side{width:var(--sidew);flex:0 0 var(--sidew);border-right:1px solid var(--line);
  background:var(--bg);padding:14px 12px;position:sticky;top:0;height:100vh;
  overflow-y:auto;display:flex;flex-direction:column;gap:18px;z-index:50}
.side-brand{display:flex;flex-direction:column;gap:6px;font-size:15px;font-weight:600;
  color:var(--txt-strong);padding:0 6px;letter-spacing:-.01em}
.side-nav{display:flex;flex-direction:column;gap:18px}
.side-group{display:flex;flex-direction:column;gap:2px}
.side-cap{font-size:11px;font-weight:600;color:var(--muted);text-transform:uppercase;
  letter-spacing:.6px;padding:0 6px 6px}
/* Subsecao dentro de um grupo da lateral. Menor e mais apagada que o
   `.side-cap` do grupo: ela divide, nao compete com o titulo. O espaco em cima
   e o que separa uma subsecao da lista anterior -- a primeira nao precisa
   dele, por isso o `:first-of-type`. */
.side-sub{font-size:10px;font-weight:600;color:var(--muted2);text-transform:uppercase;
  letter-spacing:.5px;padding:14px 6px 4px}
.side-group .side-sub:first-of-type{padding-top:2px}
.side-item{display:flex;align-items:center;gap:8px;width:100%;text-align:left;
  background:transparent;border:none;border-radius:var(--radius-xs);
  padding:6px 8px;font-size:14px;line-height:20px;color:var(--n600)}
.side-item:hover{background:var(--n100);color:var(--txt)}
.side-item.active{background:var(--pri100);color:var(--pri600);font-weight:500}

/* Gaveta de recortes dentro de um item da lateral (hoje, os fundos do
   Portfólio). O item e a seta são botões irmãos: clicar no nome leva à tela,
   clicar na seta só abre a lista. O submenu tinha sido retirado deste front
   quando "Análises de Matrículas" virou aba; volta aqui com outro papel —
   antes era outra tela, agora é um recorte da mesma. */
.side-linha{display:flex;align-items:center;gap:2px}
.side-linha .side-item{flex:1;min-width:0}
.side-seta{flex:0 0 auto;width:22px;height:28px;display:grid;place-items:center;
  border:none;background:transparent;color:var(--muted2);
  border-radius:var(--radius-xs)}
.side-seta:hover{background:var(--n100);color:var(--txt)}
/* O traço à esquerda amarra os recortes ao item que os abriu: sem ele a lista
   fica solta e parece mais um grupo da lateral, não um detalhe do Portfólio. */
.side-sublista{display:flex;flex-direction:column;gap:2px;margin:2px 0 2px 10px;
  padding-left:9px;border-left:1px solid var(--line)}
.side-sublista .side-item{font-size:13px;line-height:18px;padding:5px 8px;color:var(--muted)}
.side-sublista .side-item:hover{color:var(--txt)}
/* O menu não tem mais submenu: "Análises de Matrículas" era o único, e virou
   aba dentro do caso. Os estilos de submenu saíram junto. */
.side-foot{margin-top:auto;font-size:11px;color:var(--muted2);padding:0 6px}

.main{flex:1;min-width:0;display:flex;flex-direction:column}

/* cabeçalho da página: título + trilha */
.page-head{padding:20px 28px 0}
.page-head h1{margin:0;font-size:20px;line-height:28px;font-weight:600;color:var(--txt-strong)}
.crumb{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--muted);
  margin-top:6px;min-height:18px;flex-wrap:wrap}
.crumb i{font-style:normal;color:var(--n300)}
.crumb b{color:var(--txt-strong);font-weight:500}
.crumb a{color:var(--muted)}
.crumb a:hover{color:var(--txt)}

/* Teto de largura de TODAS as telas: o conteudo cresce com a janela ate aqui e
   para. Era 1560px, e em monitor largo sobrava uma faixa morta a direita do
   mapa e das grades — o .wrap e alinhado a esquerda, entao o que sobra fica
   todo de um lado so. 1800px enche a tela em 1920 sem deixar a linha de texto
   longa demais nas telas que sao texto. */
.wrap{padding:18px 28px 40px;max-width:1800px;width:100%}

/* =========================================================
   Botões
   ========================================================= */
.btn{border:1px solid var(--line);background:var(--card);color:var(--txt);padding:0 14px;height:36px;
  border-radius:var(--radius-sm);font-size:13px;font-weight:500;
  display:inline-flex;align-items:center;gap:7px;transition:background .12s,border-color .12s}
.btn:hover{background:var(--n100);border-color:var(--n300)}
.btn.primary{background:var(--pri);border-color:var(--pri);color:var(--sobre-pri)}
.btn.primary:hover{background:var(--pri-hover);border-color:var(--pri-hover)}
.btn.teal{background:var(--sec);border-color:var(--sec);color:#fff}
.btn.teal:hover{background:var(--sec600);border-color:var(--sec600)}
.btn.ghost{background:transparent;border-color:transparent;color:var(--muted)}
.btn.ghost:hover{background:var(--n100);color:var(--txt)}
.btn.danger{color:var(--dg600);border-color:var(--dg200);background:var(--card)}
.btn.danger:hover{background:var(--dg50);border-color:var(--dg)}
.btn.sm{height:28px;padding:0 9px;font-size:12px;border-radius:var(--radius-xs)}
/* ação só com ícone: quadrado, sem o padding lateral que o texto pedia. É o que
   permite a coluna de ações caber sem empurrar a tabela para fora da tela. */
.btn.icon{padding:0;gap:0;justify-content:center;width:30px}
.btn.sm.icon{width:28px}
.btn:disabled{opacity:.5;cursor:not-allowed}
/* Botao desabilitado em que o VERMELHO e a informacao, nao um aviso de erro: a
   praca nao tem imovel nosso, e nao ha tela para abrir. Opacidade cheia de
   proposito -- clareado a 50% pelo :disabled acima, o vermelho deixaria de ser
   legivel e a cor perderia a funcao. */
.btn.sem-imovel:disabled{opacity:1;color:var(--dg700);border-color:var(--dg200);
  background:var(--dg50);cursor:not-allowed}
.btn:focus-visible{outline:none;box-shadow:var(--ring)}

/* =========================================================
   Cards e títulos de seção
   ========================================================= */
.card{background:var(--card);border:none;border-radius:var(--radius);box-shadow:var(--shadow)}
.section-title{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;margin:0 0 16px}
.section-title h2{margin:0;font-size:18px;line-height:26px;font-weight:600;color:var(--txt-strong);letter-spacing:-.01em}
.section-title .desc{color:var(--muted);font-size:13px;font-weight:400;margin-top:2px}

/* =========================================================
   Portfólio: KPIs e tabela
   ========================================================= */
.totals{display:grid;grid-template-columns:repeat(6,1fr);gap:12px;margin-bottom:18px}
.stat{background:var(--card);border:none;border-radius:var(--radius);padding:14px 16px;box-shadow:var(--shadow)}
.stat .label{color:var(--muted);font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.5px}
.stat .value{font-size:20px;font-weight:600;margin-top:6px;color:var(--txt-strong);
  font-variant-numeric:tabular-nums;letter-spacing:-.01em}
.stat .value.sm{font-size:16px}
.stat.accent{background:var(--pri);color:var(--sobre-pri)}
.stat.accent .label{color:rgba(10,10,10,.70)}
.stat.accent .value{color:var(--sobre-pri)}

table.grid{width:100%;border-collapse:separate;border-spacing:0;font-size:14px}
table.grid th{text-align:right;padding:8px 9px;height:36px;color:var(--muted);font-weight:600;
  font-size:12px;line-height:16px;text-transform:uppercase;letter-spacing:.2px;white-space:nowrap;
  background:var(--n100);border:none;position:sticky;top:0;z-index:2}
table.grid thead th:first-child{border-radius:var(--radius-xs) 0 0 var(--radius-xs)}
table.grid thead th:last-child{border-radius:0 var(--radius-xs) var(--radius-xs) 0}
table.grid th.l,table.grid td.l{text-align:left}
table.grid td{padding:8px 9px;border-bottom:1px solid var(--line2);text-align:right;white-space:nowrap;
  font-size:14px;line-height:20px}
table.grid tbody tr{cursor:pointer}
table.grid tbody tr:hover td{background:var(--n50)}
table.grid tbody tr:last-child td{border-bottom:none}
table.grid tfoot td{font-weight:600;border-top:1px solid var(--line);border-bottom:none;background:var(--n50)}
.num{font-variant-numeric:tabular-nums;font-feature-settings:"tnum"}
.pos{color:var(--ok600)} .neg{color:var(--dg600)}

/* Grades largas (Portfólio, Verificadas, Descartados): 13 a 16 colunas.
   O padding lateral de 12px custava 24px por coluna — só nele iam ~336px.
   Reduzido para 6px, devolve ~190px de largura útil.

   6px é o piso que adianta: medido no Portfólio com 16 colunas, a tabela sai de
   1588px para 1548px, e abaixo de 6px ela não encolhe mais — o que manda ali
   passa a ser o conteúdo das células e a linha de filtros, não o espaçamento.
   Diminuir a fonte não muda nada nesse ponto, pelo mesmo motivo. */
table.grid.compact th,table.grid.compact td{padding-left:6px;padding-right:6px}

/* Trunca o texto da célula com reticências, respeitando o max-width que a
   especificação da coluna define em JS. Sem isto, um nome longo estica a coluna
   e joga a tabela inteira para fora da tela (medido: 1807px de largura exigida
   contra 1504px disponíveis numa janela de 1920). O valor completo continua
   acessível no title da célula. */
.trunc{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Alternativa à truncagem: o texto ocupa mais de uma linha dentro do mesmo
   limite de largura. A coluna continua sem esticar a tabela, e o nome inteiro
   fica visível — reticências escondiam justamente o fim do nome, que é onde
   costuma estar o que distingue um lote do outro. */
.quebra{display:inline-block;vertical-align:middle;white-space:normal;
  overflow-wrap:anywhere;line-height:1.3}
/* fora da caixa de largura, para não ser recortado com o texto */
.link-anuncio{display:inline-flex;vertical-align:middle;margin-left:6px}

/* Linha de filtros, logo abaixo do cabeçalho. O cabeçalho é sticky no topo;
   esta segunda linha gruda logo abaixo dele, por isso o top deslocado.
   Controles no padrão Omni: fundo zinc-100, sem borda, foco com anel azul. */
table.grid tr.filtros th{padding:7px 6px 9px;height:auto;top:36px;
  background:var(--card);border-bottom:1px solid var(--line);
  text-transform:none;letter-spacing:normal;font-weight:400}
.filtro-campo{position:relative;display:block}
.filtro-ico{position:absolute;left:8px;top:50%;transform:translateY(-50%);
  display:flex;align-items:center;color:var(--muted2);pointer-events:none;
  font-size:12px;line-height:1}
/* `.filtro-barra` é a mesma linha de filtros fora de uma tabela — as telas de
   cadastro são listas, não grades, e sem ela o filtro ali teria a cara de um
   formulário no meio de uma tela de leitura. As regras são compartilhadas com a
   linha da grade de propósito: dois blocos iguais divergiriam no primeiro
   ajuste, e o filtro passaria a ter duas aparências no mesmo sistema. */
table.grid tr.filtros input,
.filtro-barra .filtro-campo input{width:100%;min-width:0;height:30px;
  padding:0 8px 0 27px;font-size:12.5px;font-family:inherit;color:var(--txt);
  background-color:var(--n100);border:1px solid transparent;
  border-radius:var(--radius-sm);
  transition:background-color .12s,border-color .12s}
table.grid tr.filtros input::placeholder,
.filtro-barra .filtro-campo input::placeholder{color:var(--muted2)}
table.grid tr.filtros input:hover,
.filtro-barra .filtro-campo input:hover{background-color:var(--n200)}
table.grid tr.filtros input:focus,
.filtro-barra .filtro-campo input:focus{outline:none;background-color:var(--card);
  border-color:var(--pri);box-shadow:var(--ring)}
table.grid tr.filtros .csel{width:100%}
table.grid tr.filtros .csel-trigger,
.filtro-barra .csel-trigger{height:30px;padding:0 6px 0 10px;font-size:12.5px;
  border-radius:var(--radius-sm)}
/* A barra alinha os controles e dá a largura de cada um: a busca ocupa o que
   sobra, o recorte por lista fica no tamanho do rótulo mais longo. */
.filtro-barra{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:14px}
.filtro-barra .filtro-campo{flex:1 1 260px;max-width:340px}
.filtro-barra .csel{min-width:190px}
/* Filtro preenchido fica evidente — uma lista curta sem sinal visível parece
   defeito, e não resultado de filtro. */
.filtro-campo.ativo input{background-color:var(--pri100);border-color:var(--pri);
  color:var(--pri600);font-weight:500}
.filtro-campo.ativo .filtro-ico{color:var(--pri600)}
table.grid tr.filtros .csel.ativo .csel-trigger,
.filtro-barra .csel.ativo .csel-trigger{background-color:var(--pri100);
  border-color:var(--pri);color:var(--pri600);font-weight:500}
table.grid tr.filtros .csel.ativo .csel-trigger .ico,
.filtro-barra .csel.ativo .csel-trigger .ico{color:var(--pri600)}

/* Cabeçalho clicável (coluna ID do Portfólio, que ordena). Herda a aparência do
   próprio cabeçalho para não parecer um controle solto; a setinha é o que
   avisa que dá para clicar. */
.th-filtro{display:inline-flex;align-items:center;gap:4px;padding:2px 6px;
  margin:-2px -6px;border:none;background:transparent;cursor:pointer;
  font:inherit;color:inherit;text-transform:inherit;letter-spacing:inherit;
  border-radius:var(--radius-xs);transition:background-color .12s}
.th-filtro:hover{background:var(--n200)}
.th-filtro:focus-visible{outline:none;box-shadow:var(--ring)}
.th-filtro.ativo{background:var(--pri100);color:var(--pri600)}

/* Estrela de favorito (Portfólio): na célula da grade e no botão que filtra
   pelos favoritos, na linha de filtros. Sem fundo em repouso — uma coluna
   inteira de botões desenhados brigaria com o ID logo ao lado, e a estrela
   sozinha já diz que dá para clicar. Marcada, ela é preenchida: só o contorno
   mudando de cor não se distingue de longe numa lista de vinte linhas. */
.fav{display:inline-flex;align-items:center;justify-content:center;
  padding:3px;border:none;background:transparent;cursor:pointer;
  color:var(--muted2);border-radius:var(--radius-xs);
  transition:color .12s,background-color .12s}
.fav:hover{background:var(--n200);color:var(--amber)}
.fav:focus-visible{outline:none;box-shadow:var(--ring)}
.fav:disabled{cursor:default;opacity:.5}
.fav.ativo{color:var(--amber)}
.fav.ativo .ico{fill:currentColor}
/* Fora do <button>, no relatório e em qualquer lugar que só exiba o estado. */
span.fav{cursor:default}
span.fav:hover{background:transparent;color:var(--muted2)}
span.fav.ativo:hover{color:var(--amber)}

/* Selo de status clicável (Descartados): o badge vira gatilho de menu. */
.badge-btn{display:inline-flex;align-items:center;gap:3px;padding:2px 4px 2px 0;
  border:none;background:transparent;cursor:pointer;border-radius:var(--pill);
  color:var(--muted);transition:background-color .12s}
.badge-btn:hover{background:var(--n100)}
.badge-btn:focus-visible{outline:none;box-shadow:var(--ring)}
.badge-btn .ico{color:var(--muted2)}

/* Coluna de ações: ocupa só o necessário (width:1% + nowrap) para que as colunas
   de dado fiquem com toda a largura restante. */
table.grid th.acoes,table.grid td.acoes{width:1%;white-space:nowrap;text-align:right}
/* espaçamento por margem, e não flex: o <td> precisa continuar table-cell para
   não sair do alinhamento das colunas */
table.grid td.acoes .btn{vertical-align:middle}
table.grid td.acoes .btn+.btn{margin-left:4px}

/* Check de matrícula anexada, ao lado da lupa na grade de ativos. A versão
   .vazio ocupa a mesma largura para os botões não deslocarem entre as linhas. */
.mat-ok{display:inline-flex;align-items:center;justify-content:center;
  width:22px;height:28px;color:var(--ok600);flex:0 0 22px}
.mat-ok.vazio{color:transparent}

/* Rodapé de páginas */
.pager{display:flex;align-items:center;justify-content:space-between;gap:12px;
  flex-wrap:wrap;padding:10px 4px 2px}
.pager-info{font-size:12px;color:var(--muted)}
.pager-btns{display:flex;gap:4px;flex-wrap:wrap}
/* "..." das paginas puladas: nao e botao, e nao pode parecer um. Mesma altura dos
   botoes para a fileira nao ficar torta. */
.pager-gap{display:inline-flex;align-items:center;height:28px;padding:0 2px;
  font-size:12px;color:var(--muted2);user-select:none}
.btn.sm.pg{min-width:28px;padding:0 8px;justify-content:center}

/* =========================================================
   Badges (chips flat, no padrão HeroUI)
   ========================================================= */
.badge{display:inline-flex;align-items:center;height:24px;padding:0 8px;border-radius:var(--pill);
  font-size:12px;line-height:16px;font-weight:500;white-space:nowrap}
/* Status da oportunidade. "Pipeline" e "Portfólio" substituíram "Prospecção" e
   "Aprovado" — as regras antigas ficam porque os mesmos nomes ainda servem de
   classe para a etapa do ativo e para o parecer da matrícula. */
.badge.Pipeline{background:var(--wr);color:#3d2a06;font-weight:600}
.badge.Portfólio{background:var(--ok100);color:var(--ok700);font-weight:600}
.badge.Prospecção{background:var(--n100);color:var(--n600)}
.badge.Análise{background:var(--wr100);color:var(--wr700)}
/* "Proposta enviada" — a classe é o status sem o espaço (ver PORT_COLS em
   app.js). Azul primário para não se confundir com nenhum outro status do
   portfólio: o amarelo é de quem ainda está sendo analisado e o verde de quem já
   entrou. Aqui a proposta saiu e a resposta do cedente não voltou. */
/* Azul FIXO, e nao a primaria. O azul foi escolhido pelo motivo do
   comentario acima — nao colidir com nenhum outro selo —, e quando a
   primaria virou dourada este selo veio junto e passou a disputar com o
   Pipeline (ambar) e o Analise (ambar claro), que e exatamente a confusao
   que se queria evitar. Por isso ele deixa de seguir a primaria.
   Os dois tons sao os que a escala azul tinha: #cce3fd/#005bc4 no claro e
   #002e62/#66aaf9 no escuro. Os mesmos valem no relatorio impresso. */
.badge.Propostaenviada{background:#cce3fd;color:#005bc4;font-weight:600}
:root[data-tema="escuro"] .badge.Propostaenviada{background:#002e62;color:#66aaf9}
.badge.Aprovado{background:var(--ok100);color:var(--ok700)}
.badge.Emexecução,.badge.Em.execução{background:var(--sec100);color:var(--sec600)}
.badge.Encerrado{background:var(--ok700);color:#fff}
/* On Hold — a classe é o status sem o espaço, como nos demais. Cinza, porque o
   caso saiu do movimento; mas um cinza mais firme que o de "Descartado", que é o
   mais apagado da grade de propósito. A diferença entre os dois tem de ser
   visível na mesma tela: um está parado e volta, o outro acabou. Cor cheia do
   funil aqui diria que o caso está andando. */
.badge.OnHold{background:var(--n200);color:var(--n700);font-weight:600}
.badge.Descartado{background:var(--n100);color:var(--muted2)}
.badge.dot{background:var(--ok100);color:var(--ok700)}
/* Em Análise é o elegível que alguém pegou para estudar: azul, não verde — o
   verde já é o selo de "passou nos hurdles", e os dois precisam se distinguir
   na mesma coluna. Classe sem acento (emanalise) porque `.badge.Análise` já
   existe para o parecer da matrícula, que é âmbar. */
.badge.emanalise{background:var(--pri100);color:var(--pri600);font-weight:600}
/* SIGNOFF é decisão assumida em cima de uma reprovação: âmbar, não verde — o
   verde diria que a conta fechou, e ela não fechou. */
.badge.signoff{background:var(--wr100);color:var(--wr700);font-weight:600;
  letter-spacing:.3px}
.badge.etp{background:var(--pri100);color:var(--pri600);border:none}
/* Arquivo cujo conteúdo se perdeu no servidor: âmbar, o mesmo tom de "precisa
   de ação" usado em Análise — não vermelho, porque o registro está íntegro; o
   que falta é reenviar o arquivo. */
.badge.ausente{background:var(--wr100);color:var(--wr700);font-weight:600}
.asset-table td.l select{min-width:96px}

/* =========================================================
   Abas
   ========================================================= */
.tabs{display:flex;gap:4px;border-bottom:1px solid var(--line);margin-bottom:18px;flex-wrap:wrap}
.tabs button{background:transparent;border:none;padding:10px 14px;font-size:14px;font-weight:500;
  color:var(--muted);border-bottom:2px solid transparent;margin-bottom:-1px}
.tabs button:hover{color:var(--txt)}
.tabs button.active{color:var(--pri600);border-bottom-color:var(--pri)}

/* Variante segmentada (abas da oportunidade, no padrão Omni): a aba ativa é a
   que "sobe" sobre o trilho cinza, em vez de ser sublinhada. Rola na horizontal
   em tela estreita para nenhuma aba ficar inalcançável. */
.tabs.pill{gap:2px;border-bottom:none;padding:4px;background:var(--n100);
  border-radius:var(--radius-ctl);width:fit-content;max-width:100%;
  flex-wrap:nowrap;overflow-x:auto}
.tabs.pill button{padding:7px 14px;border-bottom:none;margin:0;
  border-radius:var(--radius-xs);white-space:nowrap;transition:background-color .12s,color .12s}
.tabs.pill button:hover{color:var(--txt)}
.tabs.pill button.active{background:var(--card);color:var(--txt-strong);box-shadow:var(--shadow)}
/* no escuro a sombra não separa a aba ativa do trilho (os dois são escuros):
   o contorno de 1px é o que faz o destaque aparecer */
:root[data-tema="escuro"] .tabs.pill button.active{box-shadow:0 0 0 1px var(--n200)}

/* =========================================================
   Formulários
   ========================================================= */
.form-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px 18px}
.field{display:flex;flex-direction:column;gap:5px;min-width:0}
.field label{font-size:12px;font-weight:500;color:var(--muted)}
.field .hint{font-size:11px;color:var(--muted2);font-weight:400}
/* Controles no padrão Omni: fundo zinc-100, sem borda, raio 12px, altura 40px.
   Os <select> usam chevron próprio (a seta nativa do SO é suprimida). */
input,select,textarea{font-family:inherit}
select{
  -webkit-appearance:none;appearance:none;
  background-color:var(--n100);
  background-image:var(--img-chevron);
  background-repeat:no-repeat;background-position:right 10px center;background-size:16px 16px;
  border:1px solid transparent;border-radius:var(--radius-ctl);
  height:40px;padding:0 34px 0 12px;font-size:14px;color:var(--txt);
  transition:background-color .12s,border-color .12s}
select:hover{background-color:var(--n200)}
select:focus{outline:none;background-color:var(--card);border-color:var(--pri);box-shadow:var(--ring)}
select::-ms-expand{display:none}
/* variante compacta (barra de upload de documentos) */
select.sel-sm{height:32px;padding:0 28px 0 10px;font-size:13px;
  background-size:14px 14px;background-position:right 8px center}

/* --- Select customizado: o popup nativo é do sistema operacional e não aceita
   CSS, então o <select> fica oculto e este componente o substitui visualmente. --- */
.csel{position:relative;display:inline-block;vertical-align:middle;min-width:0}
.csel>select{display:none}
.field .csel,.asset-table .csel{width:100%}
.csel-trigger{display:flex;align-items:center;justify-content:space-between;gap:8px;width:100%;
  height:40px;padding:0 10px 0 12px;border:1px solid transparent;border-radius:var(--radius-ctl);
  background-color:var(--n100);color:var(--txt);font-family:inherit;font-size:14px;text-align:left;
  transition:background-color .12s,border-color .12s}
.csel-trigger:hover{background-color:var(--n200)}
.csel-trigger.open,.csel-trigger:focus-visible{outline:none;background-color:var(--card);
  border-color:var(--pri);box-shadow:var(--ring)}
.csel-trigger:disabled{opacity:.5;cursor:not-allowed}
.csel-trigger .ico{color:var(--muted)}
.csel-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.csel-label.ph{color:var(--muted2)}

.csel-pop{position:fixed;z-index:3200;background:var(--card);border-radius:var(--radius);padding:4px;
  overflow-y:auto;box-shadow:0 0 15px rgba(0,0,0,.03),0 2px 30px rgba(0,0,0,.08),0 0 1px rgba(0,0,0,.3)}
.csel-opt{display:flex;align-items:center;justify-content:space-between;gap:10px;min-height:32px;
  padding:6px 8px;border-radius:var(--radius-xs);font-size:14px;line-height:20px;
  color:var(--txt);cursor:pointer}
.csel-opt-txt{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.csel-opt:hover{background:var(--n100)}
.csel-opt.sel{background:var(--pri100);color:var(--pri600)}

/* variantes compactas */
.csel.sel-sm .csel-trigger{height:32px;padding:0 8px 0 10px;font-size:13px}
.asset-table .csel-trigger{height:auto;min-height:28px;padding:5px 4px 5px 6px;font-size:13px;
  background-color:transparent;border-radius:var(--radius-xs)}
.asset-table .csel-trigger:hover{background-color:var(--n100)}
.asset-table .csel-trigger.open{background-color:var(--card)}

.field select{width:100%;max-width:100%;min-width:0}
.field input,.field textarea{width:100%;max-width:100%;min-width:0;
  padding:9px 12px;border:1px solid transparent;border-radius:var(--radius-ctl);
  font-size:14px;background-color:var(--n100);color:var(--txt);transition:background-color .12s,border-color .12s}
.field input:not([type=file]){height:40px;padding:0 12px}
/* Botao que ocupa uma celula do formulario (Analisar, Localizar, Panorama
   Imobiliario, + Lancar) fica na mesma linha da grade que um campo, e a base
   dos dois tem de fechar: o controle tem 40px (o input acima, e o
   .csel-trigger que substitui o <select>) contra os 36px do .btn padrao.
   Filho DIRETO, e sem .sm/.icon, de proposito: botao pequeno ou de icone
   posto ao lado do campo dentro de um flex -- o ↻ do nome da oportunidade, o
   lapis da referencia de mercado -- mantem o tamanho dele. */
.field > .btn:not(.sm):not(.icon){height:40px}
.field input:hover,.field textarea:hover{background-color:var(--n200)}
.field input:focus,.field textarea:focus{outline:none;background-color:var(--card);
  border-color:var(--pri);box-shadow:var(--ring)}

/* Campo de data: ícone de calendário próprio no lugar do indicador nativo.
   O indicador continua existindo, invisível e sobreposto ao ícone, para
   preservar o seletor de data nativo do navegador. */
input[type="date"],.field input[type="date"]{
  -webkit-appearance:none;appearance:none;
  background-color:var(--n100);
  background-image:var(--img-calendario);
  background-repeat:no-repeat;background-position:right 11px center;background-size:16px 16px;
  border:1px solid transparent;border-radius:var(--radius-ctl);
  height:40px;padding:0 36px 0 12px;font-size:14px;color:var(--txt)}
input[type="date"]:hover{background-color:var(--n200)}
input[type="date"]:focus{outline:none;background-color:var(--card);border-color:var(--pri);box-shadow:var(--ring)}
input[type="date"]::-webkit-calendar-picker-indicator{
  opacity:0;cursor:pointer;width:22px;height:22px;margin:0 -6px 0 0;padding:0}
input[type="date"]::-webkit-datetime-edit{color:var(--txt)}
input[type="date"]::-webkit-datetime-edit-fields-wrapper{padding:0}

/* Seletor de arquivo: o controle nativo não é estilizável, então o input fica
   oculto e este contêiner reproduz o padrão de controle do Omni. */
.filepicker{display:inline-flex;align-items:center;gap:10px;min-width:0;max-width:340px;
  height:40px;padding:0 12px 0 6px;background-color:var(--n100);border-radius:var(--radius-ctl)}
.filepicker input[type="file"]{display:none}
.filepicker .fp-btn{display:inline-flex;align-items:center;gap:6px;flex:0 0 auto;
  height:28px;padding:0 10px;border:none;border-radius:var(--radius-xs);
  background:var(--alto-relevo);color:var(--txt);font-family:inherit;font-size:13px;font-weight:500;
  box-shadow:var(--shadow);transition:background .12s}
.filepicker .fp-btn:hover{background:var(--n200)}
.filepicker .fp-name{font-size:13px;color:var(--muted2);min-width:0;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.filepicker .fp-name.has{color:var(--txt)}
.filepicker.sm{height:32px;max-width:280px}
.filepicker.sm .fp-btn{height:24px;padding:0 8px;font-size:12px}
.filepicker.sm .fp-name{font-size:12px}
.field input::placeholder,.field textarea::placeholder{color:var(--muted2)}
.input-suffix input{width:100%}
.form-grid>*{min-width:0}
.field.span2{grid-column:span 2}
.field.span3{grid-column:span 3}
/* Coluna FIXA (1 ou 3), para o par do Simulador que divide uma linha e deixa o
   meio vazio de proposito: "Venda e locacao" na primeira coluna e "Categoria de
   uso" na terceira, logo abaixo do botao do Panorama Imobiliario.
   So dentro do grid de TRES colunas: abaixo de 1081px o .form-grid vira duas
   (ver a media query no fim do arquivo), e pedir a coluna 3 ali criaria uma
   terceira coluna implicita -- a linha ficaria mais larga que o formulario.
   Sem a regra, os dois caem lado a lado, que e o certo com duas colunas. */
@media(min-width:1081px){
  .field.col1{grid-column:1}
  .field.col3{grid-column:3}
}
.group-title{grid-column:1/-1;font-size:11px;font-weight:600;color:var(--muted);text-transform:uppercase;
  letter-spacing:.6px;padding:10px 0 4px;border-bottom:1px solid var(--line2);margin-top:6px}
/* Título que abre e fecha a seção logo abaixo dele. É um <button> para funcionar
   por teclado e ser anunciado como controle; a seta gira ao abrir. Genérico de
   propósito: quem usa hoje é o nome de cada frente das Observações do ativo. */
.toggle{display:flex;align-items:center;gap:8px;width:100%;text-align:left;
  background:none;border:none;font-family:inherit;color:inherit;cursor:pointer}
.toggle:focus-visible{outline:none;box-shadow:var(--ring);border-radius:6px}
.toggle .chev{display:flex;flex:none;transition:transform .15s}
.toggle[aria-expanded="true"] .chev{transform:rotate(90deg)}
/* Quantos campos da seção estão preenchidos. À direita, em peso e cor menores:
   é dado e não rótulo. */
.toggle .conta{margin-left:auto;flex:none;font-size:12px;font-weight:400;color:var(--muted2)}

/* Bloco de uma frente da diligencia (Regulatorio, Comercial, Ambiental, Geral):
   o nome, que abre e fecha, as perguntas dela e a caixa de texto. O divisor entre
   blocos e o que deixa claro a qual frente cada pergunta pertence — sem ele as
   perguntas ficavam soltas acima de uma caixa chamada "Regulatorio". */
.obs-frente{display:flex;flex-direction:column;gap:12px;padding:12px 0}
.obs-frente+.obs-frente{border-top:1px solid var(--line2)}
/* Sem mudanca de cor no hover: o nome da frente fica na cor do texto, clicado ou
   nao. O `cursor:pointer` do .toggle e a seta ja dizem que a linha abre. */
.obs-frente-nome{font-size:14.5px;font-weight:600;color:var(--txt);padding:3px 0}
.obs-frente-corpo{display:flex;flex-direction:column;gap:12px}
/* O aviso de que a Geral e a unica que o cedente ve tem de ser legivel, nao
   letra miuda de contrato. */
.obs-frente .hint{font-size:12px}

/* Linha de questionário (perguntas de diligência do ativo): enunciado à
   esquerda, resposta à direita. Enunciado longo com resposta curta — empilhar,
   como nos outros campos, gastaria a linha inteira com duas palavras. */
.field.pergunta{flex-direction:row;align-items:center;gap:16px}
.field.pergunta>label{flex:1;min-width:0;color:var(--txt);font-weight:400;
  font-size:13.5px;line-height:1.4}
/* Quem estreita e o .csel, nao o `select`: a pagina troca todo select nativo
   pelo componente proprio (botao + select escondido, ver enhanceSelect). Mirar em
   `select` pega o no invisivel e deixa o controle real com os 100% de
   `.field .csel`, que esmagam o enunciado ate uma letra por linha. */
.field.pergunta>.csel{width:210px;flex:none}
/* Numa tela estreita a resposta nao cabe ao lado: volta a empilhar. */
@media (max-width:900px){
  .field.pergunta{flex-direction:column;align-items:stretch;gap:6px}
  .field.pergunta>.csel{width:100%}
}
/* Semáforo de risco regulatório e ambiental, no título da seção Observações.
   Herda o .badge do portfólio (mesma pílula, mesma altura) e só troca as cores.
   As cores saem das variáveis de tema, e não de valores fixos: a página tem modo
   escuro, e um #hex cravado aqui viraria texto ilegível lá. */
.risco{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.badge.risco-baixo{background:var(--ok100);color:var(--ok700);font-weight:600}
.badge.risco-moderado{background:var(--wr100);color:var(--wr700);font-weight:600}
.badge.risco-alto{background:var(--dg100);color:var(--dg700);font-weight:600}
/* Crítico é o único em cor cheia: nas quatro faixas em tom pastel ele se perdia
   no meio, e é justamente o que não pode passar despercebido. */
.badge.risco-critico{background:var(--dg);color:#fff;font-weight:700}
/* Os dois estados que não são faixa de risco — ninguém respondeu, ou respondeu
   pouco demais para o índice valer. Cinza de propósito: verde ali seria lido
   como "está tudo bem", que é exatamente o que não se sabe. */
.badge.risco-sem_dados,.badge.risco-parcial{background:var(--n100);color:var(--n600);
  font-weight:600}
/* Índice e cobertura ao lado da pílula. A cobertura vem no MESMO tamanho do
   índice: ela é a ressalva que qualifica o número, e ressalva em corpo menor
   não é lida junto com o que ela qualifica. */
.risco .num,.risco .nota{font-size:12.5px;color:var(--muted);
  font-variant-numeric:tabular-nums}
.risco .num b{color:var(--txt);font-weight:600}
/* Vazia na maioria dos ativos: sem isto o `gap` do flex abriria um buraco ao
   lado do número toda vez que não houvesse ressalva a dar. */
.risco .nota:empty{display:none}
.input-suffix{position:relative}
.input-suffix span{position:absolute;right:10px;top:50%;transform:translateY(-50%);color:var(--muted2);font-size:12px}

/* =========================================================
   Painel de KPIs
   ========================================================= */
.kpis{display:grid;grid-template-columns:repeat(4,1fr);gap:12px}
.kpi{background:var(--card);border:none;border-radius:var(--radius);padding:14px 16px;box-shadow:var(--shadow)}
.kpi .k{color:var(--muted);font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.5px}
.kpi .v{font-size:22px;font-weight:600;margin-top:6px;color:var(--txt-strong);
  font-variant-numeric:tabular-nums;letter-spacing:-.01em}
.kpi .s{font-size:11.5px;color:var(--muted2);margin-top:2px}
.kpi.hl{box-shadow:0 0 0 1px var(--pri200),var(--shadow)}
.kpi.hl .v{color:var(--pri600)}

/* =========================================================
   Tabela editável de ativos
   ========================================================= */
.asset-table{width:100%;border-collapse:separate;border-spacing:0;font-size:13px}
.asset-table th{background:var(--n100);color:var(--muted);font-size:11px;font-weight:600;
  text-transform:uppercase;letter-spacing:.2px;padding:8px 7px;border:none;text-align:right;white-space:nowrap}
.asset-table thead th:first-child{border-radius:var(--radius-xs) 0 0 var(--radius-xs)}
.asset-table thead th:last-child{border-radius:0 var(--radius-xs) var(--radius-xs) 0}
.asset-table th.l{text-align:left}
.asset-table td{padding:4px 5px;border-bottom:1px solid var(--line2);text-align:right;white-space:nowrap}
.asset-table td.l{text-align:left}
.asset-table input,.asset-table select{width:100%;border:1px solid transparent;background-color:transparent;
  padding:6px;border-radius:var(--radius-xs);font-size:13px;font-family:inherit;text-align:right;
  font-variant-numeric:tabular-nums;color:var(--txt)}
/* selects da grade ficam compactos, mas mantêm o chevron do padrão Omni */
.asset-table select{height:auto;padding:6px 20px 6px 6px;
  background-position:right 3px center;background-size:13px 13px}
.asset-table input[inputmode="decimal"]{min-width:80px}
.asset-table td.l input,.asset-table select{text-align:left}
.asset-table input:hover,.asset-table select:hover{background-color:var(--n100)}
.asset-table input:focus,.asset-table select:focus{outline:none;border-color:var(--pri);
  background-color:var(--card);box-shadow:var(--ring)}
.asset-table .calc{color:var(--muted);font-variant-numeric:tabular-nums;padding-right:8px}
.asset-table tfoot td{font-weight:600;background:var(--n50);border-top:1px solid var(--line)}

/* =========================================================
   Matriz de fluxo de caixa
   ========================================================= */
.matrix-wrap{overflow-x:auto;border:none;border-radius:var(--radius);background:var(--card);box-shadow:var(--shadow)}
table.matrix{border-collapse:separate;border-spacing:0;font-size:12.5px;min-width:100%}
table.matrix th,table.matrix td{padding:7px 10px;text-align:right;white-space:nowrap;font-variant-numeric:tabular-nums}
table.matrix thead th{background:var(--n100);color:var(--muted);position:sticky;top:0;
  font-weight:600;font-size:11px;text-transform:uppercase;letter-spacing:.2px;z-index:2}
table.matrix th.rowh,table.matrix td.rowh{position:sticky;left:0;background:var(--card);text-align:left;
  font-weight:500;box-shadow:1px 0 0 var(--line);z-index:3;min-width:170px}
table.matrix thead th.rowh{background:var(--n100);z-index:4}
table.matrix tbody td{border-bottom:1px solid var(--line2)}
table.matrix tbody tr:nth-child(even) td{background:var(--n50)}
table.matrix tbody tr:nth-child(even) td.rowh{background:var(--n50)}
table.matrix tr.total td{font-weight:600;border-top:1px solid var(--line);background:var(--pri50) !important}
table.matrix td.zero{color:var(--n300)}
table.matrix .miss{color:var(--muted2)}
/* Modo de edição da matriz de realizado. O tracejado é o que diz que a célula
   aceita clique: sem ele, um número igual a todos os outros não convida a nada e
   a pessoa procura o campo de edição em outro lugar. */
table.matrix td.edit{cursor:pointer;box-shadow:inset 0 0 0 1px var(--line)}
table.matrix td.edit:hover{background:var(--pri50) !important;color:var(--pri600)}
table.matrix td.edit.copiado{border-bottom:2px dashed var(--amber)}
table.matrix td.travada{cursor:not-allowed;color:var(--muted2)}
table.matrix td input{width:100%;min-width:80px;text-align:right;border:1px solid var(--pri);
  border-radius:4px;padding:3px 5px;font-size:12.5px;font-family:inherit;
  background:var(--card);color:var(--txt);font-variant-numeric:tabular-nums}
/* Selo do lançamento que ainda é a cópia do orçado, não apuração. */
.selo-orcado{display:inline-block;font-size:10px;font-weight:600;letter-spacing:.3px;
  text-transform:uppercase;padding:1px 6px;border-radius:6px;
  background:var(--n100);color:var(--amber);border:1px solid var(--line)}
/* Faixa de aviso da aba Orçado × Realizado. Desvio zero por cópia não é o mesmo
   que desvio zero por resultado, e a tabela sozinha não distingue os dois. */
.aviso-copia{display:flex;gap:9px;align-items:flex-start;padding:10px 12px;
  border-radius:var(--radius);font-size:12.5px;line-height:1.45;
  background:var(--n100);color:var(--txt);border:1px solid var(--line);margin-bottom:16px}
.aviso-copia .ico{color:var(--amber);flex:none;margin-top:1px}
.nao-apurado{color:var(--muted2)}

/* =========================================================
   Realizado / gráficos
   ========================================================= */
/* alinhado pelo topo: o campo Categoria tem uma linha de dica a mais, e com
   align-items:end essa altura extra desalinhava rótulo e controle da linha */
.rz-form{display:grid;grid-template-columns:90px 1.4fr 1fr 1fr auto;gap:10px;align-items:start}
/* A aba Custos usa o mesmo formulário em linha, mas com quatro campos em vez dos
   cinco do realizado. Sem esta variante a Data cai na coluna de 90px que existe
   para o Mês — larga demais para um número, estreita demais para uma data, que
   aparece cortada em "dd/" — e o botão herda a coluna de 1fr da Data, ficando do
   tamanho de um campo. */
.rz-form.custos{grid-template-columns:150px 1.4fr 1fr auto}
.rz-form .btn{height:40px}
.chart-box{background:var(--card);border:none;border-radius:var(--radius);padding:16px;box-shadow:var(--shadow)}
.chart-box h3{margin:0 0 4px;font-size:15px;font-weight:600;color:var(--txt-strong)}
.chart-box .csub{color:var(--muted);font-size:12px;margin-bottom:10px}
.legend{display:flex;gap:16px;font-size:12px;color:var(--muted);margin-top:8px;flex-wrap:wrap}
.legend .li{display:flex;align-items:center;gap:6px}
.legend .sw{width:10px;height:10px;border-radius:3px}

/* =========================================================
   Modal / toast
   ========================================================= */
.modal-bg{position:fixed;inset:0;background:rgba(0,0,0,.5);display:grid;place-items:center;z-index:2000;
  backdrop-filter:blur(2px)}
.modal{background:var(--card);border-radius:var(--radius);padding:22px;max-width:440px;width:92%;box-shadow:var(--shadow-lg)}
.modal h3{margin:0 0 8px;font-size:18px;font-weight:600;color:var(--txt-strong)}
.modal p{color:var(--muted);margin:0 0 18px}
.modal .row{display:flex;justify-content:flex-end;gap:10px}
.modal.wide{max-width:860px;width:96%;max-height:92vh;overflow:auto}
.sim-status{display:inline-flex;align-items:center;gap:8px;font-size:15px;font-weight:600;
  padding:6px 16px;border-radius:var(--pill)}
.sim-status.ok{background:var(--ok100);color:var(--ok700)}
.sim-status.no{background:var(--dg100);color:var(--dg700)}
.sim-kpis{display:grid;grid-template-columns:repeat(6,1fr);gap:8px;margin-top:12px}
.sim-note{border-radius:var(--radius-sm);padding:11px 14px;font-size:13px}
.sim-note.ok{background:var(--ok100);color:var(--ok700)}
.sim-note.no{background:var(--dg50);color:var(--dg700);border:1px solid var(--dg100)}
.sim-note div{margin:2px 0}
@media(max-width:820px){.sim-kpis{grid-template-columns:repeat(3,1fr)}}

/* Leitura automática da matrícula (aba Matrículas). O rótulo em caixa alta e a
   caixa do parecer copiam o painel de matrículas que a equipe já usa: a mesma
   ficha, lida do mesmo jeito, para ninguém ter de reaprender onde olhar. */
.rot-ia{font-size:11px;letter-spacing:.06em;text-transform:uppercase;
        color:var(--muted2);font-weight:600}
.caixa-ia{border:1px solid var(--line);border-radius:var(--radius-sm);
          padding:12px 14px;background:var(--n50)}
.caixa-ia ul{margin:6px 0 0;padding-left:18px;font-size:13px;line-height:1.6}

/* ---- lote de ativos do simulador ---- */
/* Cada linha é um imóvel da oportunidade. O rótulo repete em toda linha (em vez
   de virar cabeçalho de tabela) porque as linhas quebram em coluna no celular,
   onde um cabeçalho fixo lá em cima deixaria de dizer a que campo se refere. */
.sim-ativos{display:flex;flex-direction:column;gap:8px}
.sim-ativo{display:grid;gap:8px;align-items:end;
  grid-template-columns:22px repeat(4,minmax(96px,1fr)) 78px 78px 32px;
  padding:9px 10px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--n50)}
.sim-ativo-n{font-size:12px;color:var(--muted2);padding-bottom:9px;text-align:right}
.sim-ativo-cel{display:flex;flex-direction:column;gap:3px;min-width:0}
.sim-ativo-cel label{font-size:11px;color:var(--muted);white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.sim-ativo-cel input{width:100%;min-width:0}
.sim-ativo-x{padding:6px;color:var(--muted2)}
.sim-ativo-x:hover{color:var(--dg700)}
/* Segunda linha do ativo: o cadastro do imovel (bairro, areas, aluguel), que
   alimenta a base de precos por cidade. Linha propria porque, ao lado dos
   valores, cinco campos a mais deixariam cada um com menos de 60px. O filete
   separa o que e premissa de calculo do que e cadastro do imovel. */
.sim-ativo-cad{grid-column:1/-1;display:grid;gap:8px;align-items:end;
  grid-template-columns:minmax(120px,1.5fr) minmax(88px,1fr) minmax(88px,1fr)
                        72px minmax(100px,1fr);
  padding-top:9px;margin-top:3px;border-top:1px dashed var(--line)}
/* Terra Nua troca DUAS celulas por duas outras, e sao sempre cinco visiveis:
   urbano  = Bairro | Area constr. | Area terreno | Unid. | Aluguel
   terra   = Bairro | Terra nua    | Agricultura  | Pastagem | Aluguel
   Celula escondida sai do fluxo do grid (display:none), entao a contagem fecha —
   mas a quarta coluna vale 72px, largura pensada para o seletor de unidade. Sem
   este template, "Pastagem (ha)" cairia naqueles 72px. */
.sim-ativo-cad.terra{grid-template-columns:minmax(120px,1.5fr) minmax(88px,1fr)
                     minmax(88px,1fr) minmax(88px,1fr) minmax(100px,1fr)}
/* o <select> vira `.csel` em runtime e precisa acompanhar a largura da celula */
.sim-ativo-cel .csel{width:100%}
/* aviso da linha de cadastro: o que estes campos alimentam e, quando falta a
   cidade, que o imovel nao vai entrar na base de precos */
.sim-ativo-cad-nota{grid-column:1/-1;font-size:11.5px;color:var(--muted);
  margin-top:2px}
.sim-ativo-cad-nota.falta{color:var(--wr700)}
/* a conta do leiloeiro ocupa a linha inteira, abaixo dos campos */
.sim-ativo-conta{grid-column:1/-1;font-size:11.5px;color:var(--muted)}
/* Memoria de calculo do leilao: uma LINHA POR ITEM, rotulo a esquerda e valor
   a direita. Duas colunas so para o valor alinhar — sem borda e sem fundo, que
   e o que separa uma lista conferivel de uma tabela dentro do formulario. A
   coluna do valor nao encolhe: numero quebrado em duas linhas nao se confere. */
.conta-leilao{display:grid;grid-template-columns:1fr auto;gap:1px 16px;
  align-items:baseline;max-width:420px;margin-top:4px}
.conta-leilao .conta-val{text-align:right;white-space:nowrap;
  font-variant-numeric:tabular-nums}
/* Os tres marcos da conta — o que sai no ato e o total — em peso maior: sao as
   linhas que a pessoa procura, o resto e a decomposicao delas. */
.conta-leilao .forte{font-weight:600;color:var(--txt)}
.sim-ativos-total{font-size:12px;color:var(--muted)}
/* "em [ 30 ] x mensais", ao lado do botao Comprar parcelado. Fica na mesma
   linha do botao no simulador e logo abaixo dele na tela da oportunidade */
.sim-parcelas{display:inline-flex;align-items:center;gap:6px;
  font-size:12px;color:var(--muted)}
.sim-parcelas input{width:72px}
@media(max-width:820px){
  .sim-ativo{grid-template-columns:repeat(2,1fr)}
  .sim-ativo-cad{grid-template-columns:repeat(2,1fr)}
  .sim-ativo-n{text-align:left;padding-bottom:0}
}

#toast{position:fixed;bottom:24px;left:50%;transform:translateX(-50%);background:var(--toast-bg);color:var(--toast-txt);
  padding:11px 20px;border-radius:var(--radius-sm);font-size:13.5px;box-shadow:var(--shadow-lg);
  opacity:0;transition:opacity .25s,transform .25s;pointer-events:none;z-index:3000}
#toast.show{opacity:1;transform:translateX(-50%) translateY(-4px)}
#toast.err{background:var(--dg)}

/* =========================================================
   Utilitários
   ========================================================= */
.empty{text-align:center;padding:60px 20px;color:var(--muted)}
.empty .big{display:flex;justify-content:center;margin-bottom:14px;color:var(--n300)}
.empty .big .ico{stroke-width:1.5}
.two-col{display:grid;grid-template-columns:1fr 1fr;gap:16px}
.mt16{margin-top:16px}.mt24{margin-top:24px}
.rowflex{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.pill{display:inline-flex;align-items:center;gap:6px;background:var(--n100);border-radius:var(--radius-xs);
  padding:4px 10px;font-size:12px;color:var(--muted);font-weight:500}
.sim-status .ico{stroke-width:2.5}

/* =========================================================
   Usuários
   ========================================================= */
.user-row{display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding:14px 20px}
.user-row.sep{border-top:1px solid var(--line2)}
.user-row:hover{background:var(--n50)}
.user-nome{display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  font-size:15px;font-weight:600;color:var(--txt-strong)}
.user-email{font-size:13px;color:var(--muted);margin-top:2px;
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
.user-tag{display:inline-flex;align-items:center;height:19px;padding:0 7px;border-radius:5px;
  font-size:10.5px;font-weight:600;letter-spacing:.05em;
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  background:var(--n100);color:var(--muted)}
.user-tag.adm{background:var(--ok100);color:var(--ok700)}
/* Pessoa física × jurídica no cadastro de clientes: azul e roxo. Duas cores
   porque a distinção mudou de peso — ela decide o documento esperado e se
   existe pessoa de contato —, e os tokens seguem os dois temas. */
.user-tag.pf{background:var(--pri100);color:var(--pri600)}
.user-tag.pj{background:var(--sec100);color:var(--sec600)}
.user-tag.voce{background:var(--pri100);color:var(--pri600)}
.btn.ghost.off{opacity:.4;cursor:not-allowed}
.btn.ghost.off:hover{background:transparent;color:var(--muted)}

/* =========================================================
   Configurações — listas de cadastro (Cedentes)
   Mesma linha da lista de usuários; a segunda linha é texto comum, e não
   monoespaçado, porque aqui ela é uma frase ("em 3 registros") e não um e-mail.
   ========================================================= */
.cad-row{display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding:14px 20px}
.cad-row.sep{border-top:1px solid var(--line2)}
.cad-row:hover{background:var(--n50)}
.cad-nome{display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  font-size:15px;font-weight:600;color:var(--txt-strong)}
.cad-sub{font-size:13px;color:var(--muted);margin-top:2px}

/* ---------------------------------------------------------
   Editor das respostas de uma pergunta de diligência
   (Configurações › Perguntas)

   Grid, e não uma fila flex: o cabeçalho e as linhas compartilham a MESMA
   definição de colunas, então "Pontos" fica em cima da caixa de pontos e a
   marca de "fora do cálculo" em cima do botão dela. Com flex, cada linha
   calculava a própria largura e o cabeçalho descolava do conteúdo.
   --------------------------------------------------------- */
.op-grid{display:grid;grid-template-columns:1fr 84px 132px 32px;gap:8px;
  align-items:center}
.op-cab{font-size:11px;font-weight:500;color:var(--muted2);
  padding-bottom:2px}
/* A coluna de pontos e a da marca são estreitas: o rótulo centralizado sobre
   elas é o que deixa claro a qual campo pertence. */
.op-cab.meio{text-align:center}

/* Botão de duas posições no lugar de uma caixa de marcar: a tela não tem
   checkbox em lugar nenhum (ver `simNao`), e inventar um só aqui destoaria.
   Desligado é discreto; ligado acende, porque ligar muda o que a resposta faz
   no cálculo e isso precisa ser visível ao passar o olho na lista. */
.op-flag{display:flex;align-items:center;justify-content:center;gap:6px;
  width:100%;padding:8px 10px;font-size:12px;font-weight:500;
  border:1px solid var(--line);border-radius:var(--radius-xs);
  background:transparent;color:var(--muted);white-space:nowrap;
  font-family:inherit;transition:background-color .12s,color .12s,border-color .12s}
.op-flag:hover{color:var(--txt);border-color:var(--n300)}
.op-flag .ponto{width:7px;height:7px;border-radius:var(--pill);
  background:var(--n300);flex:0 0 auto;transition:background-color .12s}
.op-flag[aria-pressed="true"]{background:var(--pri100);color:var(--pri600);
  border-color:var(--pri200)}
.op-flag[aria-pressed="true"] .ponto{background:var(--pri)}
/* Pontos de uma resposta marcada como "fora do cálculo" não são editáveis — ela
   existe justamente para tirar a pergunta da conta. O campo continua à vista,
   apagado, em vez de sumir: um controle que desaparece ao clicar no vizinho faz
   a linha pular e parece defeito. */
.op-grid input:disabled{opacity:.45}

/* =========================================================
   Tela de acesso
   ========================================================= */
/* O fundo é composto em CSS, sem arquivo de imagem: dois brilhos radiais
   que dão volume aos cantos sobre um degradê azul-marinho. A CSP da
   página é `default-src 'self'`, e esta é justamente a tela que não pode
   depender de recurso externo para ficar apresentável. */
.login-body{min-height:100vh;display:grid;place-items:center;padding:24px;
  background-color:var(--login-fundo);
  background-image:
    radial-gradient(820px 560px at 14% 10%,rgba(0,111,238,.30),transparent 62%),
    radial-gradient(620px 480px at 86% 88%,rgba(120,40,200,.18),transparent 62%),
    linear-gradient(160deg,#0b1b33 0%,#12294a 46%,#163a66 100%)}
:root[data-tema="escuro"] .login-body{
  background-image:
    radial-gradient(820px 560px at 14% 10%,rgba(0,111,238,.20),transparent 62%),
    radial-gradient(620px 480px at 86% 88%,rgba(120,40,200,.14),transparent 62%),
    linear-gradient(160deg,#05070d 0%,#0a1220 50%,#0e1c30 100%)}

/* O fio de marca no topo é um FUNDO do próprio cartão, não um
   pseudo-elemento: fundo é recortado pelo `border-radius`, e a faixa
   acompanha a curva do canto em vez de atravessar reta por cima dela.
   `overflow:hidden` resolveria o mesmo, mas recortaria junto a sombra
   colorida do botão Acessar. */
.login-card{position:relative;width:100%;max-width:440px;
  background-color:var(--login-card);
  /* Um tom só. O fio era primária -> secundária, e com a primária dourada
     virou dourado -> roxo, que não é combinação de lugar nenhum do
     sistema. O roxo continua existindo, mas não encostado no dourado. */
  background-image:linear-gradient(90deg,var(--pri),var(--pri700));
  background-repeat:no-repeat;background-size:100% 3px;background-position:top left;
  border:1px solid var(--login-borda);border-radius:20px;padding:38px 36px 36px;
  box-shadow:0 1px 2px rgba(0,0,0,.10),0 12px 28px rgba(0,0,0,.22),
             0 40px 80px rgba(0,0,0,.28);
  animation:fx-subir .38s var(--ease) both}

.login-marca{display:flex;align-items:center;justify-content:center;
  padding-bottom:22px;margin-bottom:24px;border-bottom:1px solid var(--login-borda)}
/* a logo é a arte oficial (mesmo arquivo do Omni); altura fixa e largura livre
   para preservar a proporção 1280x450 */
.login-logo{height:54px;width:auto;display:block}
/* O wordmark é preto e some no cartão escuro — invertido, vira branco. */
:root[data-tema="escuro"] .login-logo{filter:invert(1)}

.login-titulo{margin:0 0 22px;font-size:20px;line-height:28px;font-weight:600;
  color:var(--txt-strong);text-align:center;letter-spacing:-.01em}
.login-sub{margin:-16px 0 22px;font-size:13px;color:var(--muted);
  line-height:1.55;text-align:center}
.login-sub code{text-align:left}

.login-campo{position:relative;margin-bottom:14px}
.login-campo input{width:100%;height:56px;padding:20px 14px 6px 44px;
  border:1px solid var(--login-borda);border-radius:12px;
  background:var(--login-card);color:var(--txt);font-size:15px;font-family:inherit;
  transition:border-color var(--t-rapido) var(--ease),
             box-shadow var(--t-rapido) var(--ease)}
.login-campo input:hover:not(:focus){border-color:var(--n300)}
.login-campo input:focus{outline:none;border-color:var(--pri);
  box-shadow:0 0 0 3px rgba(0,111,238,.18)}
/* Só o campo que tem o botão do olho abre espaço à direita. Uma regra por
   `input[type=password]` erraria duas vezes: encolheria o texto dos campos
   de troca de senha, que não têm botão, e o espaço sumiria no campo da
   senha justamente quando o olho é acionado e o tipo vira `text`. */
.login-campo.com-olho input{padding-right:46px}
.login-campo label{position:absolute;left:44px;top:50%;transform:translateY(-50%);
  color:var(--muted);font-size:15px;pointer-events:none;
  transition:top var(--t-rapido) var(--ease),font-size var(--t-rapido) var(--ease),
             color var(--t-rapido) var(--ease)}
.login-campo input:focus + label,
.login-campo input:not(:placeholder-shown) + label{top:16px;font-size:11px;color:var(--muted2)}
.login-campo input:focus + label{color:var(--pri)}
.login-campo .req{color:var(--dg)}
/* O ícone vem DEPOIS do rótulo no HTML de propósito: entre o input e o
   rótulo ele quebraria o seletor de irmão adjacente que faz o rótulo
   flutuar. */
.login-ico{position:absolute;left:15px;top:50%;transform:translateY(-50%);
  display:flex;color:var(--muted2);pointer-events:none;
  transition:color var(--t-rapido) var(--ease)}
.login-campo:focus-within .login-ico{color:var(--pri)}

.login-olho{position:absolute;right:9px;top:50%;transform:translateY(-50%);width:32px;height:32px;
  display:grid;place-items:center;border:none;background:transparent;color:var(--muted);
  border-radius:var(--pill);
  transition:background-color var(--t-rapido) var(--ease),color var(--t-rapido) var(--ease)}
.login-olho:hover{background:var(--n100);color:var(--txt)}
.login-olho:focus-visible{outline:none;box-shadow:var(--ring)}

.login-btn{width:100%;height:52px;margin-top:8px;border:none;border-radius:12px;
  background:var(--login-btn);color:var(--sobre-pri);font-size:15px;font-weight:600;font-family:inherit;
  display:flex;align-items:center;justify-content:center;gap:9px;
  box-shadow:0 2px 10px rgba(0,111,238,.35);
  transition:background var(--t-rapido) var(--ease),
             box-shadow var(--t-rapido) var(--ease),
             transform var(--t-rapido) var(--ease)}
.login-btn:hover:not(:disabled){background:var(--login-btn-hover);
  transform:translateY(-1px);box-shadow:0 6px 18px rgba(0,111,238,.42)}
.login-btn:active:not(:disabled){transform:translateY(0) scale(.99);
  box-shadow:0 2px 8px rgba(0,111,238,.30);transition-duration:.06s}
.login-btn:focus-visible{outline:none;box-shadow:var(--ring),0 6px 18px rgba(0,111,238,.42)}
.login-btn:disabled{opacity:.6;cursor:not-allowed;box-shadow:none;transform:none}

.login-erro{margin:2px 0 12px;padding:11px 13px;border-radius:12px;font-size:13px;
  background:var(--dg50);color:var(--dg700);border:1px solid var(--dg100);
  animation:fx-surgir var(--t-medio) var(--ease) both}
.login-sub code{display:block;margin:8px 0;padding:8px 10px;border-radius:8px;
  background:var(--n100);color:var(--txt);border:1px solid var(--login-borda);
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12.5px}

/* barra de rolagem discreta, como no Omni */
*::-webkit-scrollbar{width:10px;height:10px}
*::-webkit-scrollbar-track{background:transparent}
*::-webkit-scrollbar-thumb{background:var(--n200);border-radius:var(--pill);border:2px solid var(--bg)}
*::-webkit-scrollbar-thumb:hover{background:var(--n300)}

@media(max-width:1280px){
  .totals{grid-template-columns:repeat(3,1fr)}
  .kpis{grid-template-columns:repeat(2,1fr)}
}
@media(max-width:1080px){
  .form-grid{grid-template-columns:repeat(2,1fr)}
  .two-col{grid-template-columns:1fr}
}
@media(max-width:900px){
  .rail{display:none}
  .side{position:fixed;left:0;top:0;transform:translateX(-100%);transition:transform .2s;
    box-shadow:var(--shadow-lg);background:var(--card)}
  .side.open{transform:none}
  .page-head{padding:16px 16px 0}
  .wrap{padding:14px 16px 32px}
  .totals{grid-template-columns:repeat(2,1fr)}
}


/* =========================================================
   Agenda de Leilões
   A leitura é por data: cada praça é uma linha, agrupada pelo mês. Os estilos
   daqui servem também às colunas "Praças" das grades do Portfólio e de
   Verificadas, onde as duas datas dividem uma célula.
   ========================================================= */
/* rótulo "1ª"/"2ª" antes da data, na célula compartilhada das grades */
.praca-n{display:inline-block;min-width:15px;margin-right:5px;font-size:11px;
  font-weight:600;color:var(--muted2)}

.agenda-controles{display:flex;align-items:center;justify-content:space-between;
  gap:12px;flex-wrap:wrap;margin-bottom:12px}
/* Mesmo campo de busca da linha de filtros das grades, que só tem estilo dentro
   de tr.filtros — aqui ele vive fora da tabela. */
.agenda-busca,.radar-busca{min-width:290px}
/* Mesmo campo, medida menor: o teto de preço é um número curto e não precisa da
   largura da busca. O prefixo é "R$" no lugar da lupa. */
.radar-valor{width:150px;flex:0 0 auto}
.radar-valor .filtro-ico{font-size:11.5px;font-weight:600}
/* Cidade e deságio, na mesma família: o nome da cidade precisa de mais espaço
   que o número de duas casas do deságio. */
.radar-cidade{width:180px;flex:0 0 auto}
.radar-desagio{width:132px;flex:0 0 auto}
.radar-desagio .filtro-ico{font-size:11.5px;font-weight:600}
.agenda-busca input,.radar-busca input,.radar-valor input,
.radar-cidade input,.radar-desagio input{width:100%;height:34px;
  padding:0 10px 0 30px;font-size:13px;
  font-family:inherit;color:var(--txt);background-color:var(--n100);
  border:1px solid transparent;border-radius:var(--radius-sm);
  transition:background-color .12s,border-color .12s}
.agenda-busca input::placeholder,.radar-busca input::placeholder,
.radar-valor input::placeholder,.radar-cidade input::placeholder,
.radar-desagio input::placeholder{color:var(--muted2)}
.agenda-busca input:hover,.radar-busca input:hover,
.radar-valor input:hover,.radar-cidade input:hover,
.radar-desagio input:hover{background-color:var(--n200)}
.agenda-busca input:focus,.radar-busca input:focus,
.radar-valor input:focus,.radar-cidade input:focus,
.radar-desagio input:focus{outline:none;background-color:var(--card);
  border-color:var(--pri);box-shadow:var(--ring)}
/* A seta nativa da sugestão é um triângulo azul chapado do navegador, fora da
   linguagem dos outros controles da linha (que usam o nosso chevron). Sai por
   opacidade, e não por display: a área de clique continua ali e a lista abre
   igual, ao clicar ou ao digitar. */
.radar-cidade input::-webkit-calendar-picker-indicator{opacity:0}

/* Cidade e estado dividem a coluna Cidade/UF, deitados. A cidade toma o espaço
   que sobra; o estado é sigla, e sigla não precisa de largura. */
.radar-cidade-uf{display:flex;align-items:center;gap:6px;min-width:0}
.radar-cidade-uf .radar-cidade{flex:1 1 auto;width:auto;min-width:0}
.radar-cidade-uf .csel{flex:0 0 78px;width:78px}

/* Período: um controle com a cara de seletor, e as duas datas no que ele abre. */
.radar-periodo{min-width:0}
.periodo-pop{min-width:212px}
.pop-sep{height:1px;margin:4px 6px;background:var(--line)}
.periodo-datas{display:flex;flex-direction:column;gap:6px;padding:4px 8px 6px}
.periodo-datas label{display:flex;align-items:center;gap:8px;font-size:12.5px;
  color:var(--muted)}
.periodo-datas input[type="date"]{flex:1 1 auto;min-width:0;height:32px;
  font-size:13px;padding:0 28px 0 10px;border-radius:var(--radius-sm)}
/* "de" e "até" têm larguras diferentes; alinhar os dois campos exige fixar a
   coluna do rótulo. */
.periodo-datas label span{flex:0 0 26px;white-space:nowrap}

/* Barra de filtros do Radar no modo Quadros, onde não há cabeçalho de coluna
   para pendurá-los. São os mesmos controles, reaproveitados. */
.radar-filtros{display:flex;flex-wrap:wrap;gap:10px;align-items:center;
  margin-bottom:12px}
.radar-filtros .radar-periodo{width:170px}
.radar-filtros .radar-cidade-uf{width:290px}
/* Fora da grade os controles voltam ao tamanho de formulário (40px) e o rótulo
   à fonte de 14px — aqui eles têm de casar com os campos de texto da barra, que
   são de filtro. Sem isto o "Todos" do estado sai truncado ("To…"). */
.radar-filtros .csel-trigger{height:34px;font-size:13px}
.radar-filtros .radar-cidade-uf .csel{flex:0 0 92px;width:92px}

/* O que o anúncio escreveu no lugar do preço. No portal é curto ("Lances com
   deságio"); na hasta é o ônus do edital, um parágrafo — e a célula não quebra
   linha. O texto inteiro fica no title. */
.radar-obs{max-width:130px;margin-left:auto}

/* O nome da fonte é endereço de site ou nome de tribunal: pode quebrar entre
   palavras, nunca no meio ("portalzuk.c / om.br"). O `anywhere` do .quebra
   deixa a coluna encolher abaixo do texto quando a linha de filtros aperta a
   tabela; `break-word` mantém a palavra inteira como largura mínima. */
.radar-fonte{overflow-wrap:break-word}

/* Dentro da linha de filtros da grade os campos seguem a coluna, e não a
   largura própria que têm na barra; a altura e a fonte já vêm de tr.filtros. */
table.grid tr.filtros .filtro-campo{width:auto;min-width:0}

/* Linha de filtros do Radar: seis controles lado a lado, um por coluna. Com o
   preenchimento cinza em todos eles a linha pesava mais que o cabeçalho, e a
   primeira coisa que a tela mostrava era um formulário, não a lista — então o
   fundo só aparece no mouse, no foco e quando o filtro está valendo. É o mesmo
   tratamento que a tabela de ativos já dá aos seletores dela.
   As quatro regras vêm juntas de propósito: base, mouse, foco e preenchido
   empatam em especificidade com as de `tr.filtros`, e quem vem depois vence. */
table.grid.radar-grid tr.filtros th{padding:5px 6px 7px}
table.grid.radar-grid tr.filtros input,
table.grid.radar-grid tr.filtros .csel-trigger{background-color:transparent;
  border-color:transparent}
table.grid.radar-grid tr.filtros input:hover,
table.grid.radar-grid tr.filtros .csel-trigger:hover{background-color:var(--n100)}
table.grid.radar-grid tr.filtros input:focus,
table.grid.radar-grid tr.filtros .csel-trigger.open,
table.grid.radar-grid tr.filtros .csel-trigger:focus-visible{
  background-color:var(--card);border-color:var(--pri);box-shadow:var(--ring)}
table.grid.radar-grid tr.filtros .filtro-campo.ativo input,
table.grid.radar-grid tr.filtros .csel.ativo .csel-trigger{
  background-color:var(--pri100);border-color:var(--pri)}

/* Separador de mês: é rótulo, não compromisso — nada de cursor de clique nem de
   realce ao passar o mouse. */
table.grid tbody tr.agenda-mes{cursor:default}
table.grid tbody tr.agenda-mes td,
table.grid tbody tr.agenda-mes:hover td{background:var(--n100)}
table.grid tbody tr.agenda-mes td{padding-top:9px;padding-bottom:9px;
  font-size:12px;font-weight:600;text-transform:uppercase;letter-spacing:.4px;
  color:var(--muted);border-bottom:1px solid var(--line)}
.agenda-mes-n{float:right;text-transform:none;letter-spacing:normal;
  font-weight:500;color:var(--muted2)}

/* Célula da data: dia da semana embaixo e, ao lado, quanto falta. */
.agenda-dia{font-size:11px;color:var(--muted2);
  line-height:15px}
.agenda-prazo{display:inline-flex;align-items:center;height:19px;padding:0 7px;
  margin-top:3px;border-radius:var(--pill);background:var(--n100);
  color:var(--muted);font-size:11px;font-weight:500;white-space:nowrap}
/* Hoje é a única data que não dá para remarcar: vermelho. Dentro de sete dias,
   âmbar — ainda há o que preparar. O que passou fica cinza. */
.agenda-prazo.hoje{background:var(--dg100);color:var(--dg600);font-weight:600}
.agenda-prazo.perto{background:var(--wr100);color:var(--wr700);font-weight:600}
.agenda-prazo.passado{background:transparent;color:var(--muted2);padding-left:0}
/* Praça já realizada continua na agenda (é histórico), mas recuada: o que ainda
   vai acontecer tem de saltar aos olhos primeiro. */
table.grid tbody tr.passada td{opacity:.62}
/* A 2ª praça é a que costuma decidir a compra, e é ela que ganha o destaque. A
   3ª só aparece em edital que a preveja e fica com a leitura discreta da 1ª —
   dar destaque às duas tiraria o destaque de qualquer uma. */
.badge.praca1,.badge.praca3{background:var(--n100);color:var(--n600)}
.badge.praca2{background:var(--pri100);color:var(--pri600);font-weight:600}


/* Lápis do motivo do descarte: com motivo escrito, o ícone fica no amarelo da
   marca — dá para varrer a coluna e ver quais linhas já foram justificadas. */
.btn.sm.icon.com-motivo{color:var(--wr700);background:var(--wr100)}
.btn.sm.icon.com-motivo:hover{background:var(--wr)}

/* =========================================================
   Calendário da Agenda de Leilões
   É a visão padrão do módulo: um mês por vez, com as praças dentro do dia.
   ========================================================= */
.cal-card{padding:14px 16px 12px}
.cal-nav{display:flex;align-items:center;gap:8px;margin-bottom:12px}
.cal-mes{font-size:15px;font-weight:700;color:var(--txt-strong);
  min-width:170px;text-align:center;text-transform:capitalize}
.cal-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:6px}
.cal-cab{font-size:10.5px;font-weight:700;letter-spacing:.6px;text-transform:uppercase;
  color:var(--muted2);text-align:center;padding-bottom:2px}
/* altura mínima em vez de fixa: um dia com três praças cresce, e a semana
   acompanha — melhor do que cortar compromisso para manter a grade quadrada */
.cal-dia{min-height:86px;border:1px solid var(--line);border-radius:var(--radius-xs);
  padding:5px 6px;display:flex;flex-direction:column;gap:3px;background:var(--card)}
.cal-dia.vazio{border-color:transparent;background:transparent}
.cal-dia .cal-n{font-size:12px;font-weight:600;color:var(--muted)}
.cal-dia.tem{border-color:var(--n300)}
.cal-dia.tem:hover{border-color:var(--pri);box-shadow:var(--shadow)}
/* hoje: anel, não preenchimento — o preenchimento competia com o dia selecionado */
.cal-dia.hoje{box-shadow:0 0 0 2px var(--pri) inset}
.cal-dia.hoje .cal-n{color:var(--pri600)}
.cal-dia.sel{border-color:var(--pri);background:var(--pri50)}
/* dia que já passou fica recuado, mas continua legível: é histórico da carteira */
.cal-dia.passado{background:var(--n50)}
.cal-dia.passado .cal-chip{opacity:.6}
.cal-chip{font-size:10.5px;line-height:1.25;padding:2px 5px;border-radius:5px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:pointer}
.cal-chip.praca1,.cal-chip.praca3{background:var(--n100);color:var(--n600)}
.cal-chip.praca2{background:var(--pri100);color:var(--pri600);font-weight:600}
/* a 3ª ganha só um contorno: distingue da 1ª no mesmo dia sem competir com a 2ª */
.cal-chip.praca3{box-shadow:inset 0 0 0 1px var(--n300)}
.cal-mais{font-size:10px;color:var(--muted2);font-weight:600;padding-left:5px}
.cal-legenda{display:flex;align-items:center;gap:14px;margin-top:12px;
  padding-top:10px;border-top:1px solid var(--line2);font-size:11.5px;color:var(--muted)}
.cal-legenda span{display:inline-flex;align-items:center;gap:6px}
.cal-pt{width:9px;height:9px;border-radius:3px;display:inline-block}
.cal-pt.praca1{background:var(--n300)}
.cal-pt.praca2{background:var(--pri)}
.cal-pt.praca3{background:var(--n100);box-shadow:inset 0 0 0 1px var(--n300)}
/* linha do detalhe do dia: mesma leitura da grade, sem virar tabela */
.cal-item{display:grid;grid-template-columns:88px 92px 1fr 130px 120px 108px;
  align-items:center;gap:10px;padding:9px 4px;border-top:1px solid var(--line2);
  font-size:13px}
/* visão do mês: a data abre a linha, porque ali as praças são de dias diferentes */
.cal-item.com-data{grid-template-columns:62px 88px 92px 1fr 130px 120px 108px}
.cal-item-data{display:flex;flex-direction:column;line-height:1.15}
.cal-item-data i{font-style:normal;font-size:10px;color:var(--muted2)}
.cal-item:hover{background:var(--n50)}
.cal-item-id{color:var(--muted);font-variant-numeric:tabular-nums}
.cal-item-nome{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cal-item-loc{color:var(--muted)}
.cal-item-val{text-align:right;font-variant-numeric:tabular-nums}

/* =========================================================
   Radar de Leilões
   Botão que liga/desliga um recorte ("Só com data marcada"). Usa a mesma
   linguagem de "filtro ativo" da linha de filtros das grades — fundo claro da
   primária, e não cor cheia: cor cheia numa tela de garimpo competiria com a
   leitura da lista, que é o que interessa ali.
   ========================================================= */
.btn.on{background:var(--pri100);border-color:var(--pri);color:var(--pri600);
  font-weight:600}
.btn.on:hover{background:var(--pri100);border-color:var(--pri600)}
/* Linha sem anúncio para abrir não finge ser clicável (a grade dá cursor de
   mão a toda linha por padrão) */
table.grid tbody tr.sem-link{cursor:default}
/* A célula do imóvel recebe desde o título curto do portal ("Apartamento 59 m²")
   até o parágrafo inteiro do edital de hasta. Duas linhas de corte igualam as
   alturas e mantêm a lista folheável; o texto completo fica no title. */
/* Miniatura do anúncio, na primeira coluna: é por ela que se descarta um imóvel
   em meio segundo. 4:3 recortado no centro (`cover`) porque as fotos chegam em
   proporções diferentes de cada portal e uma coluna de alturas irregulares
   destroi a leitura da grade. */
td.radar-foto{width:1%;padding:6px 10px 6px 12px}
.radar-mini{width:64px;height:48px;border-radius:var(--radius-xs);object-fit:cover;
  background:var(--n100);display:block}
/* No quadro a foto é a capa: ocupa a largura inteira, com proporção fixa para
   que cartões vizinhos não fiquem em alturas diferentes. */
.radar-capa{width:100%;aspect-ratio:4/3;object-fit:cover;background:var(--n100);
  display:block}
.radar-sem-foto{display:flex;align-items:center;justify-content:center;
  color:var(--muted2)}

/* Quadros: a mesma consulta da lista, com a foto no tamanho de quem decide por
   ela. `auto-fill` deixa a grade se acomodar à largura da janela em vez de
   fixar um número de colunas. */
.radar-cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(236px,1fr));
  gap:14px;align-items:start}
.radar-cards>.card{grid-column:1/-1}      /* aviso de vazio atravessa a grade */
.radar-card{background:var(--card);border:1px solid var(--line);
  border-radius:var(--radius);overflow:hidden;display:flex;flex-direction:column;
  cursor:pointer;transition:border-color .12s,box-shadow .12s}
.radar-card:hover{border-color:var(--n300);box-shadow:var(--shadow)}
.radar-card.sem-link{cursor:default}
.radar-card-corpo{padding:10px 12px 12px;display:flex;flex-direction:column;gap:5px;
  flex:1}
.radar-card-topo{display:flex;align-items:center;justify-content:space-between;gap:8px}
/* Duas linhas fixas: título curto de portal e parágrafo de edital ocupam o
   mesmo espaço, e a linha de preço fica na mesma altura em todos os cartões. */
.radar-card-titulo{font-weight:600;font-size:13px;line-height:1.35;min-height:35px;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.radar-card-rodape{margin-top:auto;padding-top:8px;display:flex;gap:10px;
  justify-content:space-between;align-items:flex-end;border-top:1px solid var(--line2)}
.radar-card-preco{font-size:15px;font-weight:600;color:var(--txt-strong);
  font-variant-numeric:tabular-nums}
.radar-card-data{text-align:right;font-size:12px;font-variant-numeric:tabular-nums;
  white-space:nowrap}
/* A ação fecha o cartão, largura inteira: no quadro não há coluna de ações como
   na lista, e um ícone solto num canto passaria despercebido. */
.radar-card-acao{width:100%;justify-content:center;margin-top:10px}
.radar-card-rodape .hint{white-space:nowrap}
.radar-off{font-size:11px;font-weight:700;color:var(--muted);white-space:nowrap}
.radar-off.pos{color:var(--ok600)}
/* 340px é o que deixa a coluna de deságio caber na tela sem rolagem lateral
   num monitor de 1366 — é ela que responde a pergunta da tela. */
.radar-imovel{max-width:340px;white-space:normal}
.radar-titulo{font-weight:600;line-height:1.3;display:-webkit-box;
  -webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.radar-1linha{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* =========================================================
   Panorama Imobiliário
   Design da casa: paleta Smart Compass, cartões e tipografia do sistema, e o tema
   claro/escuro do usuário respeitado.

   A proporção é a decisão central desta tela. O Brasil é um desenho quase
   quadrado: se o cartão do mapa fica largo, o país encolhe no meio dele e a tela
   parece inacabada. Por isso a coluna do mapa tem largura fixa próxima da altura
   do conjunto (780 × 720), e não uma fração da tela — assim o desenho preenche o
   cartão e a ficha ao lado fica com uma largura de leitura confortável.

   As cores do mapa são lidas do CSS em tempo de desenho (ver panPaleta() em
   panorama.js), porque o Leaflet põe cor em atributo de SVG, onde var() não é
   resolvido.
   ========================================================= */
/* segmento (residencial / comercial) e a data do último dado disponível: a
   primeira coisa da tela, porque tudo abaixo depende das duas escolhas */
.pan-topo{display:flex;align-items:center;justify-content:space-between;gap:16px;
  flex-wrap:wrap;margin-bottom:16px}
.pan-seg{margin-bottom:0}
.pan-ref{display:flex;align-items:center;gap:7px;font-size:12px;color:var(--muted)}
.pan-ref .ico{color:var(--muted2)}

/* linha única de controles: voltar ao país e ir direto à cidade. A trilha e os
   cartões de média saíram — o painel ao lado do mapa nomeia o recorte e mostra os
   números dele. */
.pan-controles{display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  margin-bottom:16px}

/* Mapa e ficha lado a lado, da mesma altura. A coluna do mapa tem largura fixa
   próxima da altura do conjunto porque o Brasil é um desenho quase quadrado — se
   ela virasse fração da tela, o país encolheria no meio do cartão. */
.pan-wrap{display:grid;grid-template-columns:880px minmax(400px,1fr);
  gap:18px;align-items:stretch;max-width:1760px;height:min(84vh,860px)}
.pan-mapcard{padding:14px;display:flex;flex-direction:column;height:100%}
.pan-mapcab{display:flex;align-items:center;justify-content:space-between;
  gap:14px;flex-wrap:wrap;padding:2px 4px 12px}
.pan-mapcab h3{margin:0;font-size:15px;font-weight:600;color:var(--txt-strong);
  display:flex;align-items:center;gap:8px}
.pan-mapcab h3 .ico{color:var(--muted)}
.pan-mapcab .legend{margin-top:0;gap:14px;font-size:12px}
.pan-mapcab .legend .sw{width:10px;height:10px;border-radius:3px}
/* o que fazer neste nível ("escolha o estado") */
.pan-nivel{font-size:10.5px;font-weight:700;text-transform:uppercase;
  letter-spacing:.5px;color:var(--pri600);background:var(--pri100);
  border-radius:var(--pill);padding:3px 9px;margin-left:2px}
.pan-erro{color:var(--dg600);font-size:12px}

/* Sem tile de rua: só o contorno oficial do IBGE sobre uma superfície neutra do
   tema. O mapa preenche o cartão — com altura própria, sobrava faixa branca
   embaixo dele quando a ficha ao lado era mais alta. */
/* fundo na cor do cartão: o mapa é um desenho de contorno sobre a folha, e um
   fundo cinza atrás dele criava um retângulo visível dentro do cartão */
.pan-mapa{flex:1;min-height:0;width:100%;border-radius:var(--radius-sm);
  overflow:hidden;background:var(--card);position:relative}
.pan-mapa .leaflet-container{background:var(--card)}
.pan-mapa .leaflet-interactive{cursor:pointer;outline:none;
  transition:fill .15s,fill-opacity .15s,stroke .15s,stroke-width .15s}
.pan-mapa .leaflet-control-zoom{border:none;box-shadow:var(--shadow)}
.pan-mapa .leaflet-control-zoom a{background:var(--card);color:var(--txt);
  border-color:var(--line);width:28px;height:28px;line-height:28px;font-size:16px}
.pan-mapa .leaflet-control-zoom a:hover{background:var(--n100)}
.pan-mapa .leaflet-tooltip{background:var(--card);color:var(--txt);
  border:1px solid var(--line);box-shadow:var(--shadow-lg);font-size:12px;
  font-weight:600;padding:5px 10px;border-radius:var(--radius-xs)}
.pan-mapa .leaflet-tooltip-top:before{border-top-color:var(--line)}
/* o Leaflet cria um pane de tiles vazio; escondê-lo evita faixa cinza */
.pan-mapa .leaflet-tile-pane{display:none}

/* a malha do estado chega por fetch; sem aviso, o clique parecia não ter efeito */
.pan-carregando{position:absolute;inset:0;z-index:600;display:none;
  flex-direction:column;align-items:center;justify-content:center;gap:12px;
  background:var(--card)}
.pan-mapa.carregando .pan-carregando{display:flex}
.pan-carregando .anel{width:32px;height:32px;border-radius:50%;
  border:2px solid var(--n200);border-top-color:var(--pri);
  animation:pan-girar 1s linear infinite}
.pan-carregando span{font-size:12px;font-weight:600;color:var(--muted)}
@keyframes pan-girar{to{transform:rotate(360deg)}}

/* sigla do estado escrita no centro do território, sem caixa: a etiqueta com nome
   e preço tapava o desenho e repetia o que a ficha já diz */
.pan-sigla-wrap{width:0;height:0}
/* azul escuro sobre o azul claro do mapa: quem tem dado vem no tom mais forte */
.pan-sigla{position:absolute;transform:translate(-50%,-50%);white-space:nowrap;
  cursor:pointer;font-size:11.5px;font-weight:700;letter-spacing:.04em;
  line-height:1;color:var(--pri700)}
.pan-sigla.off{color:var(--pri600);font-weight:600;opacity:.75;cursor:default}

/* ---- ficha / lista da direita ---- */
.pan-panel{padding:22px;display:flex;flex-direction:column;overflow:hidden;height:100%}
/* Dentro do estado não há mapa: a ficha ocupa a largura da tela. Sem altura
   travada — quem rola aqui é a página, não uma caixa interna. */
.pan-solo{max-width:1760px;height:auto;overflow:visible;padding:28px 30px;
  min-height:min(78vh,780px)}
.pan-solo .pan-conteudo{overflow:visible;max-height:none;padding:0;margin:0}
.pan-solo .pan-ficha-cab h3{font-size:28px}
.pan-solo .pan-sub{font-size:14px}
.pan-solo .pan-mini{grid-template-columns:repeat(4,1fr);max-width:1000px;gap:14px}
/* ficha com três números (a rural, sem o preço em dólar) */
.pan-solo .pan-mini.tres{grid-template-columns:repeat(3,1fr);max-width:760px}
.pan-solo .pan-mini-item{padding:14px 16px}
.pan-solo .pan-mini-item .v{font-size:21px}
.pan-solo .pan-rank{max-height:none}
.pan-solo .pan-rank-item{font-size:14.5px;padding:12px 12px}
.pan-solo .pan-rank-item .v{font-size:15px}
.pan-solo .pan-linha{font-size:14px;padding:9px 0}
/* campo de busca da cidade: caixa própria, com lupa, botão de limpar e realce no
   foco. A `.filtro-campo` do Radar é feita para a linha de filtros de uma grade e,
   solta aqui, saía sem ícone e com metade da altura. */
.pan-busca{display:flex;align-items:center;gap:9px;height:40px;padding:0 13px;
  max-width:380px;margin-bottom:14px;background:var(--n50);
  border:1px solid var(--line);border-radius:var(--radius-ctl);
  transition:border-color .12s,box-shadow .12s,background .12s}
.pan-busca:focus-within{background:var(--card);border-color:var(--pri);
  box-shadow:0 0 0 3px var(--pri100)}
.pan-busca.ativo{border-color:var(--pri200)}
.pan-busca>.ico{color:var(--muted2);flex:0 0 auto}
.pan-busca:focus-within>.ico{color:var(--pri)}
.pan-busca input{flex:1;min-width:0;border:none;background:transparent;outline:none;
  font:inherit;font-size:14px;color:var(--txt)}
.pan-busca input::placeholder{color:var(--muted2)}
.pan-busca-x{border:none;background:transparent;padding:2px;display:grid;
  place-items:center;color:var(--muted2);border-radius:var(--pill);flex:0 0 auto}
.pan-busca-x:hover{background:var(--n200);color:var(--txt)}
/* padding-right dá folga para a barra de rolagem não encostar nos números */
.pan-conteudo{flex:1;min-height:0;overflow-y:auto;margin:-4px;padding:4px 10px 4px 4px;
  scrollbar-width:thin;scrollbar-color:var(--n300) transparent}
.pan-conteudo::-webkit-scrollbar{width:6px}
.pan-conteudo::-webkit-scrollbar-track{background:transparent}
.pan-conteudo::-webkit-scrollbar-thumb{background:var(--n300);border-radius:3px}
/* nome da praca a esquerda, botao dos nossos imoveis a direita */
.pan-ficha-cab{display:flex;align-items:flex-start;justify-content:space-between;
  gap:14px;flex-wrap:wrap}
.pan-ficha-cab h3{margin:0;font-size:23px;font-weight:600;color:var(--txt-strong);
  letter-spacing:-.015em;line-height:1.2}
.pan-sub{color:var(--muted);font-size:13.5px;margin-top:3px}

/* Troca de fonte dentro da ficha rural: VTN da Receita x pesquisa da Scot.
   Nao ocupa a largura toda como as abas de segmento — sao dois botoes, e
   esticados ate a borda pareceriam navegacao de tela, nao um filtro da ficha. */
.pan-fonte{margin-top:16px;margin-bottom:0;width:fit-content;max-width:100%}

/* Os nossos imoveis da praca em modal. Sobrou para UM caso: o Panorama aberto
   dentro do modal do Simulador, onde nao se pode trocar de rota. Na pagina, a lista
   abre em tela cheia (ver .pan-imoveis-card, mais abaixo). */
.nossos-modal{max-width:none;width:min(780px,96vw);max-height:88vh;
  display:flex;flex-direction:column}
.nossos-corpo{flex:1;min-height:0;overflow:auto;margin-top:6px}

/* Uma linha por imovel: identificacao a esquerda, os dois precos a direita. */
.pan-nossos{display:flex;flex-direction:column;margin-top:14px}
.pan-nossos-item{display:flex;align-items:flex-start;justify-content:space-between;
  gap:14px;padding:12px 0;border-bottom:1px solid var(--line2);font-size:13px}
.pan-nossos-item:last-child{border-bottom:none}
.pan-nossos-item .n{min-width:0}
/* Tipo e bairro sao a IDENTIDADE do imovel numa base de precos ("Casa · Centro"),
   e por isso vem em primeiro plano; o codigo do caso desceu para a linha de baixo. */
.pan-nossos-item .ident{font-size:15px;font-weight:600;color:var(--txt-strong);
  line-height:1.3}
.pan-nossos-item .ident .sep{color:var(--muted2);margin:0 6px;font-weight:400}
.pan-nossos-item .ident .vago{color:var(--muted2);font-weight:400;font-size:13.5px}
.pan-nossos-item .meta{display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  margin-top:5px;font-size:12px;color:var(--muted)}
/* de onde o imovel veio: portfolio ou simulacao ainda no backlog */
.pan-nossos-item .org{font-size:10.5px;color:var(--muted2);
  border:1px solid var(--line);border-radius:var(--pill);padding:1px 7px}
.pan-nossos-item .anuncio{display:inline-flex;align-items:center;gap:3px;
  color:var(--pri600);text-decoration:none}
.pan-nossos-item .anuncio:hover{text-decoration:underline}
.pan-nossos-item .end{color:var(--muted2);overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;max-width:100%}
.pan-nossos-item .sub{font-size:11.5px;color:var(--muted2);margin-top:3px}
.pan-nossos-item .v{text-align:right;flex:0 0 auto;color:var(--muted);
  font-variant-numeric:tabular-nums}
.pan-nossos-item .v b{color:var(--txt-strong)}
.pan-nossos-item .v .sem{color:var(--muted2)}
/* quem ainda nao tem area nao tem R$/m2, e a linha diz isso em vez de sumir */
.pan-nossos-item .falta{flex:0 0 auto;font-size:11.5px;color:var(--wr700);
  background:var(--wr100);border-radius:var(--pill);padding:2px 9px}

/* Tela cheia dos nossos imoveis da praca (#/panorama/imoveis/<UF>/<cidade>): a
   mesma lista, com as duas saidas por linha — o imovel no caso dele e o anuncio no
   site de origem. Sao TRES blocos na linha, e por isso ela pode quebrar: em tela
   estreita as acoes descem, em vez de comprimir os precos. */
.pan-imoveis-card{padding:6px 18px}
.pan-nossos.com-acoes{margin-top:0}
.pan-nossos.com-acoes .pan-nossos-item{flex-wrap:wrap;padding:14px 0}
.pan-nossos.com-acoes .pan-nossos-item .n{flex:1 1 300px}
/* As duas saidas empilhadas, "Abrir imovel" (azul) em cima do anuncio: a de dentro
   do sistema vem primeiro, e lado a lado elas disputavam a mesma leitura. Largura
   igual para as duas (stretch), senao a de baixo fica torta embaixo da de cima. */
.pan-nossos-acoes{display:flex;flex-direction:column;align-items:stretch;gap:6px;
  flex:0 0 auto}
/* imovel cujo caso nao tem "Link do anuncio": em vez de um botao morto, o lugar do
   anuncio diz que ele falta — e o title diz onde se preenche */
.pan-sem-anuncio{font-size:11.5px;color:var(--muted2);white-space:nowrap;
  text-align:center;border:1px dashed var(--line);border-radius:var(--pill);
  padding:4px 9px}

/* quatro números da cidade, em dois pares */
.pan-mini{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:18px}
.pan-mini-item{background:var(--n50);border-radius:var(--radius-sm);padding:12px 14px}
.pan-mini-item .k{color:var(--muted);font-size:10.5px;font-weight:600;
  text-transform:uppercase;letter-spacing:.5px}
.pan-mini-item .v{font-size:19px;font-weight:600;margin-top:5px;
  color:var(--txt-strong);font-variant-numeric:tabular-nums;line-height:1.2}
/* a variação em 12 meses é o único número do bloco com leitura de bom/ruim, e a
   cor dela precisa vencer o color do .v */
.pan-mini-item .v.pos{color:var(--ok600)}
.pan-mini-item .v.neg{color:var(--dg600)}
/* Terceira linha do indicador: a variacao frente ao exercicio anterior, do
   jeito que a fonte publica — abaixo do valor, pequena. */
.pan-mini-item .ks{color:var(--muted2);font-size:11px;margin-top:2px;
  font-variant-numeric:tabular-nums}
.pan-mini-sub{font-size:10.5px;color:var(--muted2);margin-top:1px}

.pan-bloco{margin-top:24px}
.pan-cap{color:var(--muted);font-size:10.5px;font-weight:700;
  text-transform:uppercase;letter-spacing:.7px;display:flex;align-items:center;
  gap:6px;margin-bottom:11px}
.pan-cap .ico{color:var(--pri)}
/* Legenda de grupo DENTRO da lista de ranking. Existe para o rural, onde a lista
   do estado tem dois tipos de item que nao se comparam: as regioes pesquisadas
   pela Scot e os municipios, que herdam a media do estado. O primeiro grupo cola
   no topo; os seguintes ganham respiro para a quebra ser visivel. */
.pan-cap-grupo{margin-top:18px;margin-bottom:8px}
.pan-cap-grupo:first-child{margin-top:0}
.pan-linha{display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:8px 0;border-bottom:1px solid var(--line2);font-size:13.5px}
.pan-linha:last-child{border-bottom:none}
.pan-linha b{font-variant-numeric:tabular-nums;color:var(--txt-strong)}
.pan-barra{height:6px;background:var(--n100);border-radius:var(--pill);
  overflow:hidden;margin-top:7px}
.pan-barra i{display:block;height:100%;background:var(--pri);border-radius:var(--pill)}
.pan-nota{color:var(--muted2);font-size:12px;margin-top:8px}

/* "Mais procurado" é a única caixa com fundo da primária: é o que a pessoa leva
   anotado da tela */
.pan-destaque{margin-top:24px;background:var(--pri50);border-radius:var(--radius-sm);
  padding:14px 16px;font-size:13.5px;font-weight:600;color:var(--txt-strong);
  line-height:1.45}
.pan-destaque .pan-cap{color:var(--pri600);margin-bottom:7px}

/* A lista é clicável: é por ela que se troca de estado ou de cidade sem ter de
   achar a área no mapa. Botão, e não div com listener, para o teclado alcançar. */
.pan-rank{display:flex;flex-direction:column}
.pan-rank-item{display:flex;align-items:center;justify-content:space-between;
  gap:10px;padding:10px 8px;border:none;background:transparent;font-family:inherit;
  border-radius:var(--radius-xs);text-align:left;color:var(--txt);font-size:13.5px;
  border-bottom:1px solid var(--line2);transition:background .12s}
.pan-rank-item:last-child{border-bottom:none}
.pan-rank-item:hover{background:var(--n50)}
.pan-rank-item:focus-visible{outline:none;box-shadow:var(--ring)}
.pan-rank-item .n{display:flex;flex-direction:column;gap:2px;line-height:1.25;min-width:0}
.pan-rank-item .n i{font-style:normal;font-size:11px;color:var(--muted2);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pan-rank-item .v{font-weight:600;font-variant-numeric:tabular-nums;
  color:var(--txt-strong);white-space:nowrap}

.pan-voltar{margin-bottom:14px;padding-left:4px}

/* Seletor de referencia de mercado do Simulador: e a PROPRIA tela do Panorama
   montada dentro de um modal (ver abrirSeletorDeMercado em panorama.js). Modal
   largo porque o mapa (880px) e a ficha ao lado so cabem lado a lado assim;
   abaixo de 1400px de janela a media query do modulo ja empilha os dois. */
.pan-modal{max-width:none;width:min(980px,96vw);max-height:92vh;
  display:flex;flex-direction:column}
/* Modal: uma coluna, o mapa centralizado, sem a ficha ao lado (que ali nem e
   construida -- ver `soMapa` em renderPanorama). A largura do cartao acompanha
   os 880px que o desenho do Brasil pede, e encolhe junto em janela estreita. */
.pan-wrap-solo{grid-template-columns:minmax(0,1fr);justify-items:center}
.pan-wrap-solo .pan-mapcard{width:min(100%,880px)}
/* O corpo rola e o rodape com o botao de confirmar fica sempre visivel: sem
   isso, escolher uma cidade no fim de uma lista longa esconderia o botao. */
.pan-modal-corpo{flex:1;min-height:0;overflow:auto}
/* A altura do conjunto tem de descontar cabecalho e rodape do modal. Os 84vh do
   modulo sao para a tela inteira e estourariam daqui. */
.pan-modal .pan-wrap{height:min(62vh,700px);max-width:none}
.pan-modal-rodape{display:flex;align-items:center;justify-content:space-between;
  gap:16px;flex-wrap:wrap;flex:0 0 auto;
  padding-top:14px;margin-top:14px;border-top:1px solid var(--line)}
/* O resumo da praca escolhida. `min-width:0` para ele encurtar em vez de
   empurrar os botoes para fora quando o nome da regiao e longo. */
.pan-modal-resumo{font-size:13px;color:var(--muted);min-width:0}

/* o mapa ocupa 880px; abaixo disso + a ficha, os dois não caem lado a lado */
@media(max-width:1400px){
  .pan-wrap{grid-template-columns:1fr;height:auto}
  .pan-mapa{flex:none;height:min(68vh,620px)}
  .pan-panel{height:auto;overflow:visible}
  .pan-conteudo{overflow:visible}
}

@media(max-width:1100px){
  .cal-dia{min-height:74px}
  .cal-chip{font-size:9.5px}
  .cal-item{grid-template-columns:80px 1fr 110px;row-gap:2px}
  .cal-item.com-data{grid-template-columns:56px 80px 1fr 110px}
  .cal-item-loc,.cal-item-val{display:none}
}

/* ---------- Caixa de selecao ----------
   O checkbox nativo e desenhado pelo sistema operacional: nao aceita cor, nao
   aceita raio, e sai de um tamanho diferente em cada maquina. Aqui ele e
   redesenhado do zero (`appearance:none`) para caber no resto da tela.

   Continua sendo um <input type=checkbox> de verdade — teclado, leitor de tela
   e o evento `change` seguem funcionando. So a pintura muda.

   18px porque 13px (o padrao do Windows) e alvo pequeno demais para uma coluna
   que se clica muitas vezes seguidas, marcando linha a linha. */
.cxsel{
  appearance:none;-webkit-appearance:none;
  width:18px;height:18px;margin:0;flex:0 0 auto;
  border:1.5px solid var(--n300);border-radius:6px;
  background:var(--card);
  display:inline-grid;place-content:center;
  cursor:pointer;vertical-align:middle;
  transition:background-color .12s ease,border-color .12s ease,box-shadow .12s ease;
}
.cxsel:hover{border-color:var(--pri200);background:var(--pri50)}
/* O "check" e um pseudo-elemento em escala 0 que cresce ao marcar: sem a
   transicao a marca aparece seca, e numa coluna que se percorre marcando varias
   linhas o movimento e o que confirma o clique sem precisar reler a tela. */
.cxsel::after{
  content:"";width:10px;height:10px;
  transform:scale(0);transition:transform .12s ease;
  background:var(--sobre-pri);
  clip-path:polygon(14% 44%,0 60%,39% 100%,100% 18%,84% 4%,39% 68%);
}
.cxsel:checked{background:var(--pri);border-color:var(--pri)}
.cxsel:checked::after{transform:scale(1)}
.cxsel:checked:hover{background:var(--pri-hover);border-color:var(--pri-hover)}
/* Foco visivel, e so no foco por TECLADO (`:focus-visible`): o anel a cada
   clique de mouse polui uma coluna inteira de caixas. */
.cxsel:focus-visible{outline:none;box-shadow:var(--ring)}
.cxsel:disabled{opacity:.45;cursor:not-allowed}

/* Na grade a celula fica estreita e centrada, e a linha inteira e clicavel
   (abre a ficha) — o cursor de texto no meio dela confundiria. */
.grid td .cxsel,.grid th .cxsel{display:grid}
.grid th .cxsel{margin:0 auto}

/* Tabela de Emolumentos (Configuracoes) --------------------------------------
   A lista dos 27 estados com as duas tabelas de cada um. O `.user-row` de base
   e flex com `space-between`, que serviria para duas pontas; aqui sao quatro
   colunas de largura fixa, entao a linha vira grade. */
/* Cada estado e uma linha que LEVA a tabela: sigla, resumo e a seta a direita.
   Deixou de ser acordeao quando a troca entre Notas e Registro passou para
   dentro da tela, na barra de tipos — o primeiro clique nao mostrava nada que
   a linha fechada ja nao dissesse. */
.emol-estado{border-top:1px solid var(--line2)}
.emol-estado:first-child{border-top:none}
.emol-cab-uf{padding:13px 20px;gap:12px}
.emol-cab-uf:hover{background:var(--n50)}
.emol-uf{font-weight:600;min-width:34px}
.emol-resumo{font-size:13px;color:var(--muted)}
/* A linha inteira e um botao, entao precisa parecer uma linha e nao um botao:
   sem fundo, sem borda, largura toda e conteudo alinhado como o do acordeao
   que estava aqui antes. A seta fica encostada a direita. */
.emol-cab-link{display:flex;align-items:center;width:100%;text-align:left;
  background:none;border:none;color:inherit;font:inherit;cursor:pointer}
.emol-cab-link .emol-resumo{flex:1;min-width:0}
.emol-ir{display:inline-flex;color:var(--muted2);flex:none}
.emol-cab-link:hover .emol-ir{color:var(--txt)}
/* Troca de tabela dentro do estado (Notas, Registro e a de cidade onde houver).
   Mesmo `tabs pill` do Panorama; so ganha a margem que o separa do titulo. */
.emol-tipos{margin-top:4px;margin-bottom:18px}
/* Tipo que o estado ainda nao tem: fica visivel e apagado, porque o botao ainda
   serve — ele CRIA a tabela. Escondê-lo faria o estado parecer ter so uma. */
.tabs.pill button.emol-tipo-vazio{color:var(--muted2);font-style:italic}
/* Estado incompleto ganha uma marca na borda, nao fundo vermelho: sao 27
   linhas e a maioria comeca incompleta — fundo colorido em quase tudo deixa
   de sinalizar qualquer coisa. */
.emol-falta{box-shadow:inset 3px 0 0 var(--red)}
/* Coletado e esperando conferencia: ambar. Duas filas de trabalho, duas cores. */
.emol-pendente{box-shadow:inset 3px 0 0 var(--wr)}
/* Sem tabela e o vermelho que a tela existe para mostrar. */
.badge.emol-ausente{background:var(--dg100);color:var(--red);font-weight:600}
/* A conferir: ambar, o mesmo peso de "esta esperando uma pessoa" usado no
   restante do sistema. Nao pode parecer com vigente. */
.badge.emol-conferir{background:var(--wr100);color:var(--wr700);font-weight:600}
.badge.emol-vigente{background:var(--ok100);color:var(--ok700);font-weight:600}

/* ---------------------------------------------------------------------------
   Faixas de valor: a grade editavel da tabela de emolumentos
   ---------------------------------------------------------------------------
   Aparencia de planilha, e nao de formulario, porque a tarefa e de planilha:
   conferir uma coluna de trinta numeros contra um PDF aberto do lado. Campos
   arredondados e espacados — o padrao do resto do sistema — quebram a leitura
   vertical justamente onde ela e o trabalho.

   Grid e nao <table>: as celulas sao inputs e precisam de largura previsivel.
   Numa <table> a coluna se ajusta ao conteudo e a grade "pula" enquanto se
   digita, que e o momento em que a pessoa esta comparando tela e documento. */
.fx-grade{margin-top:14px;border:1px solid var(--line);border-radius:6px;
  overflow:auto;max-height:560px}
.fx-linha{display:grid;grid-template-columns:46px 1fr 1fr 1fr 0.9fr 38px;
  align-items:stretch}
.fx-linha + .fx-linha{border-top:1px solid var(--line2)}

/* Cabecalho preso no topo: rolando trinta faixas, saber qual coluna e qual
   deixa de ser obvio na decima linha. */
.fx-cab{position:sticky;top:0;z-index:2;background:var(--n100);
  font-size:11px;text-transform:uppercase;letter-spacing:.04em;color:var(--muted);
  border-bottom:1px solid var(--line)}
.fx-cab > div{padding:8px 10px;display:flex;align-items:center;
  border-right:1px solid var(--line2)}
.fx-cab > div:last-child{border-right:none}

/* A coluna dos numeros, como a do Excel: fundo proprio, para o olho saber onde
   a tabela comeca. */
.fx-num{display:flex;align-items:center;justify-content:center;
  background:var(--n100);color:var(--muted2);font-size:11px;
  font-variant-numeric:tabular-nums;border-right:1px solid var(--line2)}

/* Celula: o input ocupa a celula inteira, sem borda propria nem cantos. A
   separacao vem da grade, nao do campo — e assim as colunas leem como colunas. */
.fx-cel{width:100%;height:100%;border:none;border-right:1px solid var(--line2);
  border-radius:0;background:transparent;padding:7px 10px;
  text-align:right;font-variant-numeric:tabular-nums;font-size:13px;
  color:var(--txt)}
.fx-cel:hover{background:var(--n100)}
/* Celula ativa com contorno por dentro: o de fora seria cortado pela celula
   vizinha, porque nao ha espaco entre elas. */
.fx-cel:focus{outline:none;box-shadow:inset 0 0 0 2px var(--pri);
  background:var(--card)}
/* A linha inteira se marca quando alguma celula dela esta ativa — e o que
   responde "em que faixa eu estou" sem tirar o olho da coluna. */
.fx-linha:focus-within .fx-num{background:var(--pri);color:var(--sobre-pri);font-weight:600}

.fx-del{display:flex;align-items:center;justify-content:center;background:none;
  border:none;color:var(--muted2);cursor:pointer;padding:0}
.fx-del:hover{color:var(--red)}
.fx-del:disabled{opacity:.35;cursor:default}

/* Os tres passos ate o calculo. Lista e nao cards lado a lado: a ordem importa
   (sem documento nao ha faixa) e uma fila horizontal sugere alternativas. */
.passos{display:flex;flex-direction:column;gap:2px}
.passo{display:grid;grid-template-columns:26px 190px 1fr;align-items:center;
  gap:10px;padding:7px 0;font-size:13px;color:var(--muted)}
.passo-n{display:flex;align-items:center;justify-content:center;width:22px;
  height:22px;border-radius:50%;background:var(--n100);color:var(--muted2);
  font-size:12px;font-weight:600}
.passo.ok .passo-n{background:var(--ok100);color:var(--ok700)}
.passo-t{color:var(--txt);font-weight:500}
.passo.ok .passo-t{font-weight:600}
.passo-d{font-size:12px}
.passo-fim{margin-top:12px;padding-top:12px;border-top:1px solid var(--line2);
  font-size:13px;color:var(--muted)}
.passo-fim.ok{color:var(--ok700);font-weight:500}

/* Bloco dobravel: o cadastro que se faz uma vez sai do caminho do trabalho
   diario, sem sumir. O marcador padrao do <details> e pequeno demais para
   parecer clicavel numa tela com cards grandes. */
.dobravel > summary{list-style:none;cursor:pointer;padding:16px 20px;
  font-size:16px;font-weight:600;color:var(--txt);display:flex;
  align-items:baseline;gap:12px}
.dobravel > summary::-webkit-details-marker{display:none}
.dobravel > summary::before{content:'▸';color:var(--muted2);font-size:12px}
.dobravel[open] > summary::before{content:'▾'}
.dobra-resumo{font-size:12px;font-weight:400;color:var(--muted);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* =========================================================
   Movimento e estados
   Micro-interações apenas: nada aqui muda cor, tamanho ou posição em
   REPOUSO. O que existia continua com a mesma aparência parada; o que muda
   é como a interface responde ao cursor, ao clique e ao teclado. Tudo o
   que se move passa pelo interruptor de `prefers-reduced-motion` no fim
   deste bloco.

   A paleta não é tocada de propósito: o tema azul do Omni continua sendo o
   padrão visual deste sistema.
   ========================================================= */
:root{
  /* Desacelera no fim: entra rápido e assenta devagar. É a curva que faz um
     deslocamento de 2px parecer peso, e não um pulo. */
  --ease:cubic-bezier(.2,.8,.2,1);
  --t-rapido:.14s;   /* troca de cor, realce de linha */
  --t-medio:.2s;     /* elevação, entrada de menu */
  --t-lento:.28s;    /* entrada de modal e de estado vazio */
  --shadow-md:0 4px 14px rgba(0,0,0,.10);
  --lift:-2px;
}
/* No escuro a sombra precisa ser mais densa: o fundo é quase preto e uma
   sombra de 10% de opacidade simplesmente não aparece. */
:root[data-tema="escuro"]{ --shadow-md:0 4px 14px rgba(0,0,0,.6); }

/* ---------- Cartões de indicador ----------
   Só o `.stat` recebe deslocamento. O `.card` genérico NÃO pode receber:
   ele envolve tabelas e campos cujo menu suspenso é `position:fixed`
   (`.csel-pop`, `.conta-pop`), e um `transform` no ancestral passa a ser o
   bloco que posiciona esse menu — o popup saltaria de lugar enquanto o
   cursor estivesse sobre o cartão. A sombra sozinha não tem esse efeito,
   mas num cartão que ocupa a largura da tela ela também não informa nada,
   então o `.card` fica como está. */
.stat{transition:transform var(--t-medio) var(--ease),
                 box-shadow var(--t-medio) var(--ease)}
.stat:hover{transform:translateY(var(--lift));box-shadow:var(--shadow-lg)}

/* ---------- Botões ----------
   Sobem 1px sob o cursor e afundam no clique. O afundamento é mais rápido
   que a subida de propósito: o retorno tátil tem de chegar junto com o
   clique, não depois dele. */
.btn{transition:background var(--t-rapido) var(--ease),
                border-color var(--t-rapido) var(--ease),
                box-shadow var(--t-rapido) var(--ease),
                transform var(--t-rapido) var(--ease)}
.btn:hover:not(:disabled){transform:translateY(-1px);box-shadow:var(--shadow-md)}
.btn:active:not(:disabled){transform:translateY(0) scale(.985);box-shadow:none;
  transition-duration:.06s}
.btn:disabled{transform:none;box-shadow:none}

/* ---------- Trilho, lateral e listas de menu ---------- */
.rail-btn,.side-item,.conta-item,.csel-opt{
  transition:background-color var(--t-rapido) var(--ease),
             color var(--t-rapido) var(--ease),
             box-shadow var(--t-rapido) var(--ease),
             transform var(--t-rapido) var(--ease)}
/* A barra lateral marca o item ativo sem depender só do fundo azul-claro,
   que em tema escuro fica discreto demais. `inset` não ocupa espaço, então
   nenhum item muda de tamanho ao ficar ativo. */
.side-item.active,.rail-btn.active{box-shadow:inset 2px 0 0 var(--pri)}
.rail-btn:active,.side-item:active,.conta-item:active{transform:scale(.97)}

/* ---------- Gaveta dos recortes na lateral ---------- */
.side-seta{transition:background-color var(--t-rapido) var(--ease),
                      color var(--t-rapido) var(--ease),
                      box-shadow var(--t-rapido) var(--ease)}
.side-seta svg{transition:transform var(--t-medio) var(--ease)}
.side-seta[aria-expanded="true"] svg{transform:rotate(90deg)}
.side-seta:focus-visible{outline:none;box-shadow:var(--ring)}

/* ---------- Abas ---------- */
.tabs button{transition:color var(--t-rapido) var(--ease),
                        border-bottom-color var(--t-medio) var(--ease)}
.tabs.pill button{transition:background-color var(--t-rapido) var(--ease),
                             color var(--t-rapido) var(--ease),
                             box-shadow var(--t-rapido) var(--ease)}

/* ---------- Linhas de grade ----------
   A linha sob o cursor ganha um fio azul na primeira célula. Numa grade de
   16 colunas o fundo cinza-claro sozinho se perde na largura; o fio marca
   onde a linha começa. `inset` de novo: não empurra a coluna. */
table.grid tbody tr td{transition:background-color var(--t-rapido) var(--ease),
                                  box-shadow var(--t-rapido) var(--ease)}
table.grid tbody tr:hover td:first-child{box-shadow:inset 2px 0 0 var(--pri)}
table.grid tbody tr:active td{background:var(--n100)}

/* ---------- Entradas ----------
   Modal, menu suspenso e estado vazio aparecem por evento, nunca a cada
   tecla digitada num filtro, então animar a entrada deles não pisca.
   `abrirPopover()` mede o menu com offsetWidth/offsetHeight logo depois de
   inserir — medidas de layout, que o `transform` não altera —, então a
   animação não desloca o cálculo de posição. */
@keyframes fx-surgir{from{opacity:0}to{opacity:1}}
@keyframes fx-subir{from{opacity:0;transform:translateY(8px) scale(.985)}
                    to{opacity:1;transform:none}}
@keyframes fx-popover{from{opacity:0;transform:translateY(-4px)}
                      to{opacity:1;transform:none}}
.modal-bg{animation:fx-surgir var(--t-medio) var(--ease) both}
.modal{animation:fx-subir var(--t-lento) var(--ease) both}
.csel-pop,.conta-pop{animation:fx-popover var(--t-rapido) var(--ease) both}
.empty{animation:fx-surgir var(--t-lento) var(--ease) both}

/* ---------- Foco pelo teclado ----------
   O `.btn` já tinha anel de foco; o resto dos controles não tinha nenhum, e
   quem navega por Tab ficava sem saber onde estava. Mesmo anel do botão,
   para o sistema não ganhar duas aparências de foco. */
.rail-btn:focus-visible,.side-item:focus-visible,.conta-item:focus-visible,
.tabs button:focus-visible,.csel-trigger:focus-visible,.toggle:focus-visible,
.csel-opt:focus-visible,.dobravel > summary:focus-visible{
  outline:none;box-shadow:var(--ring)}
/* O item ativo tem de manter a barra lateral enquanto está em foco: uma
   segunda declaração de box-shadow substitui a primeira inteira. */
.side-item.active:focus-visible,.rail-btn.active:focus-visible{
  box-shadow:var(--ring),inset 2px 0 0 var(--pri)}

/* ---------- Aviso flutuante ----------
   Curva com leve excesso na subida: o toast passa do lugar e volta. Só a
   transição muda; o `translateX(-50%)` que centraliza continua onde
   estava. */
#toast{transition:opacity var(--t-medio) var(--ease),
                  transform var(--t-medio) cubic-bezier(.2,1.2,.3,1)}

/* ---------- Bloco dobrável ----------
   O marcador gira em vez de trocar de desenho. A troca de `content` não
   anima; manter o mesmo glifo nos dois estados e girar 90 graus, sim. */
.dobravel > summary::before{transition:transform var(--t-medio) var(--ease)}
.dobravel[open] > summary::before{content:'\25B8';transform:rotate(90deg)}

/* ---------- Interruptor geral ----------
   Quem pediu menos movimento no sistema operacional recebe a interface
   inteira parada, inclusive o que já existia antes deste bloco (o giro do
   Panorama e o deslizar da lateral no celular). Não é preferência de
   estilo: movimento involuntário dispara enxaqueca e vertigem em parte das
   pessoas, e o navegador já sabe quem são. */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.001ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
    scroll-behavior:auto !important}
  .stat:hover,.btn:hover:not(:disabled),.btn:active:not(:disabled),
  .rail-btn:active,.side-item:active,.conta-item:active{transform:none}
}

/* =========================================================
   Mapa dobrável no Portfólio
   ========================================================= */
/* O cabeçalho do mapa é um botão inteiro, e não uma setinha de 14px: o alvo de
   clique é o título junto com o ícone. */
/* `flex:0 0 auto` e `nowrap` porque o botão divide a linha com a legenda das
   etapas, que é longa: sem eles o título quebrava em duas linhas e o cabeçalho
   do cartão crescia. Quem cede espaço é a legenda, que quebra sem prejuízo. */
.mapa-cab{display:flex;align-items:center;gap:8px;flex:0 0 auto;white-space:nowrap;
  background:none;border:none;
  padding:3px 6px;margin:-3px -6px;font-family:inherit;color:var(--txt-strong);
  text-align:left;border-radius:var(--radius-xs);
  transition:background-color var(--t-rapido) var(--ease)}
.mapa-cab:hover{background:var(--n100)}
.mapa-cab:focus-visible{outline:none;box-shadow:var(--ring)}
.mapa-seta{display:flex;color:var(--muted)}
.mapa-seta svg{transition:transform var(--t-medio) var(--ease)}
.mapa-card.fechado .mapa-seta svg{transform:rotate(-90deg)}
.mapa-card.fechado #portfolioMap{display:none}
/* Recolhido, o cartão vira uma faixa: o respiro que sobrava embaixo do mapa
   deixa de existir junto com ele. */
.mapa-card.fechado{padding-bottom:10px}

