@charset "UTF-8";
/* ==========================================================================
   sgm-shell.css — moldura da aplicação: topo, navegação e área de trabalho
   --------------------------------------------------------------------------
   A navegação tem três formas, escolhidas pela largura e pelo usuário:

     data-nav="open"    barra lateral inteira, 264px   (desktop)
     data-nav="mini"    só ícones, 68px, submenu em flyout (desktop/tablet)
     data-nav="drawer"  fora da tela, entra por cima    (mobile)

   A responsividade é estrutural — a barra muda de forma. A tipografia não
   encolhe: o operador fica em DPI constante e texto fluido só atrapalha.
   ========================================================================== */

/* minmax(0,1fr) e não 1fr: uma trilha 1fr tem min-width:auto e cresce com o
   conteúdo mais largo, o que põe a página inteira em rolagem horizontal
   quando um nome de entidade é comprido. */
.sgm-app {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-rows: var(--sgm-topbar-h) 1fr;
  grid-template-areas:
    "aside topbar"
    "aside main";
  min-height: 100vh;
  min-height: 100dvh;
}

/* --------------------------------------------------------------------------
   0. Moldura fixa — só o miolo rola
   --------------------------------------------------------------------------
   A classe entra por JS (sgm-telas.js, em montarApp), e não no markup: o
   mesmo app.html abre no protótipo e sob uniGUI, e lá o <html> é montado
   pelo ExtJS.

   Antes disso a página inteira rolava: descer até o quarto quadro levava o
   menu junto para fora da tela — parecia que os módulos tinham sumido — e o
   scrollIntoView do submenu piorava, porque rolava a janela. Agora a altura
   é a da tela, a barra e o topo ficam parados, e a rolagem é do .sgm-main.
   O menu já tinha a própria rolagem em .sgm-aside__nav.

   Sem !important e sem tocar em nenhum elemento do ExtJS: 100dvh é a
   viewport, não uma medida que o ExtJS tenha calculado em px. Forçar
   percentual por cima do que ele mede é o que deixou a tela em branco uma
   vez (§6a do Retorno_SGM).

   Isto DEPENDE de o TUniHTMLFrame ocupar a janela inteira. Por isso o
   `hApp` do Main.dfm ganhou `LayoutConfig.Height/Width = '100%'` junto do
   Align = alClient — o mesmo par que foi medido em 1280x720 no hLogin. Se
   o painel do ExtJS ficar menor que a janela, o fim do conteúdo é recortado
   em vez de rolar, e o sintoma é a última linha do card sumindo.
   -------------------------------------------------------------------------- */

.sgm-shell-fixo,
.sgm-shell-fixo body {
  height: 100%;
  overflow: hidden;
}

.sgm-shell-fixo .sgm-app {
  height: 100vh;
  height: 100dvh;
  min-height: 0;
  overflow: hidden;
}

/* min-height:0 nas duas: numa trilha de grid o padrão é auto, e o filho
   com overflow cresceria até caber o conteúdo em vez de rolar. */
.sgm-shell-fixo .sgm-aside { min-height: 0; }

/* O miolo não rola: quem rola é o painel da aba ativa (sgm-components §9).
   Uma rolagem só por vez, e no lugar certo — a barra de abas e o cabeçalho
   da tela ficam parados, e a grid rola por dentro. Antes, a página inteira
   rolava e levava embora as abas e o rodapé de totais da grid. */
.sgm-shell-fixo .sgm-main {
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* --------------------------------------------------------------------------
   1. Barra superior
   -------------------------------------------------------------------------- */

.sgm-topbar {
  grid-area: topbar;
  position: sticky;
  top: 0;
  z-index: var(--sgm-z-topbar);
  display: flex;
  align-items: center;
  gap: var(--sgm-3);
  height: var(--sgm-topbar-h);
  padding: 0 var(--sgm-4);
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-outline);
}

.sgm-topbar__entidade {
  display: flex;
  align-items: center;
  gap: var(--sgm-3);
  min-width: 0;
}

/* o bloco de texto precisa poder encolher, e o nome precisa ser block —
   text-overflow não age sobre um span inline */
.sgm-topbar__entidade > span { min-width: 0; display: block; }

.sgm-brasao {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 34px; height: 34px;
  border-radius: var(--sgm-r-sm);
  overflow: hidden;
}

/* Com brasão a moldura some: o brasão é a identidade, não precisa de caixa
   colorida em volta. A imagem usa o espaço todo. */
.sgm-brasao img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

/* Sem brasão cadastrado, o ícone assume — com a caixa e um corpo que preenche
   o quadrado, em vez de boiar pequeno no meio dele. */
.sgm-brasao[data-sem-brasao] {
  background: var(--color-primary-50);
  border: 1px solid var(--color-primary-100);
  color: var(--color-primary-500);
  font-size: 19px;
}

.sgm-topbar__nome {
  display: block;
  font-size: var(--sgm-t-base);
  font-weight: 650;
  color: var(--color-on-surface);
  letter-spacing: -.01em;
}

.sgm-topbar__sub {
  font-size: var(--sgm-t-xs);
  color: var(--color-on-surface-variant);
  margin-top: 1px;
}

.sgm-topbar__spacer { flex: 1 1 auto; }

.sgm-topbar__busca {
  position: relative;
  flex: 0 1 340px;
  min-width: 0;
}
.sgm-topbar__busca .sgm-input {
  min-height: 34px;
  background: var(--color-surface-sunken);
  border-color: transparent;
}
.sgm-topbar__busca .sgm-input:hover { background: #f1f5f9; }
.sgm-topbar__busca .sgm-input:focus { background: var(--color-surface); border-color: var(--color-primary-500); }

.sgm-topbar__acoes { display: flex; align-items: center; gap: var(--sgm-1); }

/* Ações do topo em disco, como no header-actions do modelo Angular:
   2,5rem, redondo, fundo só no hover. */
.sgm-topbar__acoes .sgm-btn--icon {
  width: 2.5rem;
  min-height: 2.5rem;
  border-radius: var(--sgm-r-pill);
  color: var(--app-header-fg);
}
.sgm-topbar__acoes .sgm-btn--icon:hover:not(:disabled) {
  background: var(--app-header-hover);
  border-color: transparent;
  transform: none;
  box-shadow: none;
}

/* Contador sobre o ícone. O vermelho vivo é o do modelo (#ef4444) e não o
   --color-error: aqui ele não comunica erro, chama atenção. */
.sgm-badge-dot {
  position: absolute;
  top: 0.25rem; right: 0.25rem;
  min-width: 1rem; height: 1rem;
  padding: 0 0.25rem;
  display: grid; place-items: center;
  background: #ef4444;
  color: #fff;
  font-size: 0.625rem;
  font-weight: 700;
  line-height: 1;
  border-radius: var(--sgm-r-pill);
  border: 2px solid var(--color-surface);
}

.sgm-user {
  display: flex;
  align-items: center;
  gap: var(--sgm-2);
  padding: 4px 10px 4px 4px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--sgm-r-pill);
  cursor: pointer;
  transition: background-color var(--sgm-fast) var(--sgm-ease),
              border-color var(--sgm-fast) var(--sgm-ease);
}
.sgm-user:hover { background: var(--color-surface-sunken); border-color: var(--color-outline); }

.sgm-avatar {
  flex: 0 0 auto;
  display: grid; place-items: center;
  width: 30px; height: 30px;
  border-radius: 50%;
  background: var(--color-primary-500);
  color: #fff;
  font-size: var(--sgm-t-sm);
  font-weight: 700;
  letter-spacing: .02em;
}

.sgm-user__nome {
  font-size: var(--sgm-t-sm);
  font-weight: 600;
  color: var(--color-on-surface);
  max-width: 150px;
}

/* --------------------------------------------------------------------------
   2. Barra lateral
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   🥇 RAIL + PAINEL — a estrutura do ModeloPadrao (2026-08-14)

   O menu deixou de ser uma coluna com submenus e passou a ter duas partes,
   como o `lyt-sidenav` do @fiorilli/template que o modelo usa:

     .sgm-rail   64px, um ÍCONE por módulo — a navegação de primeiro nível,
                 e a razão de ela existir é caber inteira sem rolar
     .sgm-navp   o painel do módulo ATIVO: título + os quadros dele

   ⚠️ `data-nav="mini"` esconde o PAINEL e mantém o rail — antes ele encolhia
   a coluna inteira para 68px. É a mesma tecla («), com outro significado:
   agora ela troca "rail + painel" por "só o rail".
   -------------------------------------------------------------------------- */

.sgm-aside {
  grid-area: aside;
  position: relative;
  z-index: var(--sgm-z-drawer);
  display: flex;
  flex-direction: row;          /* rail | painel */
  width: var(--sgm-sidebar-w);
  background: var(--app-sidebar-bg);
  color: var(--app-sidebar-fg);
  transition: width var(--sgm-normal) var(--sgm-ease),
              transform var(--sgm-normal) var(--sgm-ease);
}

.sgm-rail {
  flex: 0 0 var(--sgm-rail-w, 64px);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sgm-1);
  padding: 0 0 var(--sgm-3);
  background: var(--app-rail-bg, rgb(0 0 0 / .16));
}

.sgm-rail__nav {
  flex: 1 1 auto;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: var(--sgm-2) 0;
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-width: none;
}
.sgm-rail__nav::-webkit-scrollbar { width: 0; }

.sgm-rail__pe { flex: 0 0 auto; }

.sgm-rail__item {
  display: grid;
  place-items: center;
  width: 42px; height: 42px;
  border: 0;
  border-radius: var(--sgm-r-sm);
  background: none;
  color: var(--app-sidebar-fg);
  font-size: 16px;
  cursor: pointer;
  opacity: .72;
  transition: background var(--sgm-fast) var(--sgm-ease),
              opacity var(--sgm-fast) var(--sgm-ease);
}

.sgm-rail__item:hover { background: var(--app-sidebar-hover); color: #fff; opacity: 1; }
.sgm-rail__item:focus-visible { outline: 2px solid var(--sgm-ring); outline-offset: 2px; }

/* o módulo ativo: fundo cheio e a barrinha à esquerda, como o item ativo do
   painel — é o mesmo estado, em dois lugares */
.sgm-rail__item[aria-current="page"] {
  background: var(--color-primary-500);
  color: #fff;
  opacity: 1;
}

.sgm-rail__sep {
  width: 28px; height: 1px;
  margin: var(--sgm-2) 0;
  background: var(--app-sidebar-outline);
}

.sgm-navp {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.sgm-navp__topo {
  display: flex;
  align-items: center;
  height: var(--sgm-topbar-h);
  padding: 0 var(--sgm-4);
  border-bottom: 1px solid var(--app-sidebar-outline);
  flex: 0 0 auto;
  color: #fff;
  font-size: var(--sgm-t-md);
  font-weight: 700;
  letter-spacing: -.02em;
}

/* o nome do módulo que o painel está mostrando — é ele que responde "os
   quadros de quê", agora que o painel mostra um módulo por vez */
.sgm-navp__titulo {
  margin: 0;
  padding: var(--sgm-4) var(--sgm-4) var(--sgm-2);
  font-size: var(--sgm-t-xs);
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--app-sidebar-fg);
  opacity: .6;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* O rótulo de ENTIDADE dentro do painel do Meu painel — o mesmo quadro pode
   estar marcado em duas, e ali são dois cards com números diferentes. Sem o
   rótulo, o menu mostraria duas linhas iguais. */
.sgm-navp__grupo {
  margin: var(--sgm-3) 0 var(--sgm-1);
  padding: 0 var(--sgm-4);
  font-size: var(--sgm-t-xs);
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--app-sidebar-fg);
  opacity: .55;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.sgm-navp__grupo:first-child { margin-top: 0; }

.sgm-navp__vazio {
  margin: 0;
  padding: var(--sgm-2) var(--sgm-4);
  font-size: var(--sgm-t-sm);
  color: var(--app-sidebar-fg);
  opacity: .6;
}

.sgm-logo {
  display: flex;
  align-items: center;
  gap: var(--sgm-2);
  min-width: 0;
  color: #fff;
  font-size: var(--sgm-t-md);
  font-weight: 700;
  letter-spacing: -.02em;
}

.sgm-logo__marca {
  flex: 0 0 auto;
  display: grid; place-items: center;
  width: 30px; height: 30px;
  border-radius: var(--sgm-r-sm);
  background: var(--color-primary-500);
  color: #fff;
  font-size: 13px;
}

.sgm-logo__txt { white-space: nowrap; }

.sgm-aside__nav {
  flex: 1 1 auto;
  overflow-y: auto;
  overflow-x: hidden;
  padding: var(--sgm-3) var(--sgm-2);
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, .18) transparent;
}
.sgm-aside__nav::-webkit-scrollbar { width: 8px; }
.sgm-aside__nav::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, .16);
  border-radius: var(--sgm-r-pill);
}

.sgm-nav-grupo {
  margin: var(--sgm-4) 0 var(--sgm-1);
  padding: 0 var(--sgm-3);
  font-size: var(--sgm-t-xs);
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--app-sidebar-fg-muted);
  opacity: .75;
}
.sgm-nav-grupo:first-child { margin-top: 0; }

/* ⚠️ A GEOMETRIA DO MENU SAI DAQUI, E DE UM LUGAR SÓ.

   O recuo do submenu e o filete vertical dele estavam escritos em pixels
   soltos (47px e 26px) calculados à mão a partir da caixa do ícone. Bastou
   mexer no tamanho do ícone para os três desalinharem — e o sintoma é o texto
   do submenu fora de prumo com o do módulo, que ninguém liga à causa.

   Agora os três saem da mesma conta: recuo = padding + caixa + gap, e o
   filete no centro da caixa. Mudar o ícone move o resto junto.

   ⚠️ O FLYOUT SAIU da lista em 2026-08-14, com o próprio flyout: recolhido, o
   ícone do rail abre o dashboard direto (sgm-shell.js, `botaoRail`). Ficava
   aqui porque era `position: fixed` e filho do `<body>` — fora do
   `.sgm-aside`, e uma variável declarada só ali não resolveria nele. */
.sgm-aside {
  --nav-pad-x: var(--sgm-3);   /* recuo lateral do item      */
  --nav-ico: 24px;             /* caixa do ícone             */
  --nav-gap: var(--sgm-3);     /* entre o ícone e o rótulo   */
}

.sgm-nav-item {
  display: flex;
  align-items: center;
  gap: var(--nav-gap);
  width: 100%;
  padding: 10px var(--nav-pad-x);
  margin-bottom: 3px;
  background: transparent;
  border: 0;
  border-radius: var(--sgm-r-sm);
  color: var(--app-sidebar-fg);
  font: inherit;
  font-size: var(--sgm-t-base);
  font-weight: 550;
  text-align: left;
  cursor: pointer;
  position: relative;
  transition: background-color var(--sgm-fast) var(--sgm-ease),
              color var(--sgm-fast) var(--sgm-ease);
}

.sgm-nav-item:hover { background: var(--app-sidebar-hover); color: #fff; }

/* O ÍCONE — pedido do Rodrigo em 2026-08-10: "parece que estão condensados".

   Estava em 14px numa caixa de 20, com 82% de opacidade, ao lado de um rótulo
   de 15px. Três coisas somadas: menor que o texto, apagado e sem folga em
   volta — o olho lia a lista como um bloco de palavras com uma mancha à
   esquerda, em vez de uma lista de módulos com marca própria.

   16px numa caixa de 24 põe o ícone no mesmo peso visual do rótulo, e a caixa
   maior é o que dá o respiro sem precisar afastar o texto (o que roubaria
   largura de rótulo, e os do submenu já truncam). */
.sgm-nav-item__ico {
  flex: 0 0 auto;
  width: var(--nav-ico);
  text-align: center;
  font-size: 16px;
  line-height: 1;
  opacity: .92;
}

/* passar o mouse acende o ícone junto do item: sem isso, o rótulo clareia e o
   ícone fica para trás, que é o que fazia a linha parecer meio apagada */
.sgm-nav-item:hover .sgm-nav-item__ico { opacity: 1; }

.sgm-nav-item__txt { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.sgm-nav-item__seta {
  flex: 0 0 auto;
  font-size: 10px;
  opacity: .55;
  transition: transform var(--sgm-normal) var(--sgm-ease);
}
.sgm-nav-item[aria-expanded="true"] .sgm-nav-item__seta { transform: rotate(90deg); }

/* item ativo: fundo do acento + filete de 3px, o único traço colorido do sistema */
.sgm-nav-item[aria-current="page"] {
  background: var(--color-primary-500);
  color: #fff;
  font-weight: 650;
}
.sgm-nav-item[aria-current="page"] .sgm-nav-item__ico { opacity: 1; }

/* contador de itens do módulo */
.sgm-nav-item__tag {
  flex: 0 0 auto;
  padding: 1px 7px;
  border-radius: var(--sgm-r-pill);
  background: rgba(255, 255, 255, .14);
  font-size: 10px;
  font-weight: 700;
  line-height: 1.6;
}

/* Submenu. Anima grid-template-rows 0fr→1fr em vez de max-height: a altura
   sai do conteúdo real, sem teto arbitrário que corta um módulo com muitos
   itens, e sem o salto do final quando o conteúdo é mais baixo que o teto. */
.sgm-nav-sub {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--sgm-slow) var(--sgm-ease);
}
.sgm-nav-sub[data-open="true"] { grid-template-rows: 1fr; }

.sgm-nav-sub > * { min-height: 0; }

.sgm-nav-sub__int { overflow: hidden; }

/* o rótulo do submenu começa onde começa o do módulo — a conta é a mesma,
   e é por isso que ela mora nas variáveis e não em pixels digitados */
.sgm-nav-sub .sgm-nav-item {
  padding-left: calc(var(--nav-pad-x) + var(--nav-ico) + var(--nav-gap));
  font-size: var(--sgm-t-sm);
  font-weight: 500;
  color: var(--app-sidebar-fg-muted);
}
.sgm-nav-sub .sgm-nav-item::before {
  content: "";
  position: absolute;
  /* no CENTRO da caixa do ícone, que é de onde o submenu "desce" */
  left: calc(var(--nav-pad-x) + var(--nav-ico) / 2);
  top: 0; bottom: 0;
  width: 1px;
  background: var(--app-sidebar-outline);
}
.sgm-nav-sub .sgm-nav-item:hover { color: #fff; }
.sgm-nav-sub .sgm-nav-item[aria-current="page"] {
  background: var(--app-sidebar-hover);
  color: #fff;
}
.sgm-nav-sub .sgm-nav-item[aria-current="page"]::before {
  background: var(--color-primary-500);
  width: 2px;
  left: calc(var(--nav-pad-x) + var(--nav-ico) / 2);
}

.sgm-aside__pe {
  flex: 0 0 auto;
  padding: var(--sgm-3);
  border-top: 1px solid var(--app-sidebar-outline);
}

.sgm-aside__pe .sgm-nav-item { margin: 0; }

/* --------------------------------------------------------------------------
   3. Forma "mini": só ícones
   -------------------------------------------------------------------------- */

/* ⚠️ O MINI MUDOU DE SIGNIFICADO em 2026-08-14, com o rail: antes ele
   encolhia a coluna inteira para 68px e escondia os rótulos; agora ele
   esconde o PAINEL e deixa o rail, que já é só ícone. A tecla («) é a mesma,
   e o resultado é o que o modelo mostra quando o painel está recolhido. */
[data-nav="mini"] .sgm-aside { width: var(--sgm-rail-w, 64px); }
[data-nav="mini"] .sgm-navp { display: none; }

/* ⚠️ AQUI FICAVA O `.sgm-flyout` — a camada que o ícone do rail abria com os
   quadros do módulo, posicionada por JS em position:fixed. Saiu em
   2026-08-14: recolhido, o ícone abre o dashboard direto, e estilo sem
   elemento é peso que ninguém sabe mais por que existe. */

/* --------------------------------------------------------------------------
   4. Forma "drawer": mobile
   -------------------------------------------------------------------------- */

.sgm-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--sgm-z-overlay);
  background: rgba(11, 25, 33, .48);
  backdrop-filter: blur(2px);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--sgm-normal) var(--sgm-ease);
}

[data-nav="drawer"][data-drawer="open"] .sgm-overlay { opacity: 1; pointer-events: auto; }

[data-nav="drawer"] .sgm-app {
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas: "topbar" "main";
}

[data-nav="drawer"] .sgm-aside {
  position: fixed;
  top: 0; left: 0; bottom: 0;
  width: min(84vw, var(--sgm-sidebar-w));
  transform: translateX(-100%);
  box-shadow: var(--sgm-sh-4);
}

[data-nav="drawer"][data-drawer="open"] .sgm-aside { transform: translateX(0); }

/* --------------------------------------------------------------------------
   4b. Forma "fab": botão flutuante com leque radial (telefone)
   --------------------------------------------------------------------------
   Em tela pequena a barra lateral não paga o espaço que ocupa. O acesso vira
   um botão no canto inferior direito — polegar alcança sem reposicionar a mão.

   O leque mostra os atalhos frequentes; o último item abre a gaveta com os
   14 módulos. Um leque com 14 itens seria ilegível, então ele não tenta.
   -------------------------------------------------------------------------- */

.sgm-fab {
  position: fixed;
  right: var(--sgm-4);
  bottom: var(--sgm-4);
  z-index: var(--sgm-z-drawer);
  display: none;
  padding-bottom: env(safe-area-inset-bottom, 0);
}

[data-nav="fab"] .sgm-fab { display: block; }

/* o disco que cresce por trás e escurece a tela */
.sgm-fab::after {
  content: "";
  position: absolute;
  right: 0; bottom: 0;
  width: 56px; height: 56px;
  border-radius: 50%;
  background: var(--app-sidebar-bg);
  z-index: -2;
  transform: scale(1);
  opacity: 0;
  transition: transform var(--sgm-slow) var(--sgm-ease),
              opacity var(--sgm-normal) var(--sgm-ease);
}

/* O disco tem 56px, logo 28px de raio. O ícone mais distante fica a 184px do
   centro e tem 18px de raio: 202px de alcance. A escala leva o fundo a 218px —
   dezesseis pixels de margem acima do último ícone, e nada além disso. Escalas
   maiores escureciam meia tela sem motivo.

   A ESCALA VEM DO JS, e o 7.8 aqui é só o valor de três arcos cheios.

   O menu é montado a partir do que o perfil libera. Com poucos módulos o arco
   externo fica vazio, e uma mancha dimensionada para 184px escureceria meia
   tela em volta de nada. `montarFab` (uJsShell.pas) mede o último arco que
   recebeu item e grava --sgm-fab-escala. Mesmo motivo pelo qual a posição dos
   itens também é calculada lá: o CSS não sabe quantos atalhos existem. */
.sgm-fab[data-open="true"]::after {
  opacity: .97;
  transform: scale(var(--sgm-fab-escala, 7.8));
  transition-timing-function: cubic-bezier(.68, 1.55, .265, 1);
}

.sgm-fab__btn {
  position: relative;
  display: grid;
  place-items: center;
  width: 56px; height: 56px;
  border: 0;
  border-radius: 50%;
  background: var(--color-primary-500);
  color: #fff;
  font-size: 19px;
  cursor: pointer;
  box-shadow: 0 4px 8px rgba(16, 24, 40, .16), 0 10px 24px rgba(15, 118, 110, .30);
  transition: transform var(--sgm-normal) var(--sgm-ease),
              box-shadow var(--sgm-normal) var(--sgm-ease);
}

.sgm-fab__btn:active { transform: scale(.94); }

.sgm-fab__btn i { transition: transform var(--sgm-normal) var(--sgm-ease); }
.sgm-fab[data-open="true"] .sgm-fab__btn i { transform: rotate(135deg); }

.sgm-fab[data-open="true"] .sgm-fab__btn {
  background: var(--app-sidebar-hover);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .18);
}

.sgm-fab__itens { position: absolute; right: 8px; bottom: 8px; }

/* Item do leque: só o ícone. O rótulo escrito cobria o conteúdo da página e,
   com muitos módulos, virava uma parede de texto sobre o gráfico. O nome vive
   no aria-label e no title — leitor de tela e toque longo continuam tendo.
   A posição nos dois arcos é calculada em JS: o número de módulos que o
   perfil libera é variável. */
.sgm-fab__item {
  position: absolute;
  right: 0; bottom: 0;
  display: grid;
  place-items: center;
  width: 36px; height: 36px;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, .22);
  border-radius: 50%;
  background: rgba(255, 255, 255, .14);
  color: #fff;
  font-size: 14px;
  cursor: pointer;
  opacity: 0;
  transform: translate3d(0, 0, 0) scale(.3);
  pointer-events: none;
  transition: transform var(--sgm-slow) var(--sgm-ease),
              opacity var(--sgm-normal) var(--sgm-ease),
              background-color var(--sgm-fast) var(--sgm-ease);
}

.sgm-fab[data-open="true"] .sgm-fab__item {
  opacity: 1;
  pointer-events: auto;
  transition-timing-function: cubic-bezier(.175, .885, .32, 1.275);
}

.sgm-fab__item:active { background: rgba(255, 255, 255, .34); }

.sgm-fab__item[aria-current="page"] {
  background: var(--color-primary-500);
  border-color: var(--color-primary-500);
}

/* alvo de toque de 42px sem empurrar o vizinho — o arco mais apertado deixa
   40px entre centros, então o excedente se sobrepõe só 2px */
.sgm-fab__item::before {
  content: "";
  position: absolute;
  inset: -3px;
  border-radius: 50%;
}

/* na forma fab a gaveta ainda existe: é o "Todos os módulos" do leque */
[data-nav="fab"] .sgm-app {
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas: "topbar" "main";
}

[data-nav="fab"] .sgm-aside {
  position: fixed;
  top: 0; left: 0; bottom: 0;
  width: min(84vw, var(--sgm-sidebar-w));
  transform: translateX(-100%);
  box-shadow: var(--sgm-sh-4);
}

[data-nav="fab"][data-drawer="open"] .sgm-aside { transform: translateX(0); }
[data-nav="fab"][data-drawer="open"] .sgm-overlay { opacity: 1; pointer-events: auto; }

/* espaço para o botão não cobrir o fim do conteúdo */
[data-nav="fab"] .sgm-main { padding-bottom: 88px; }

/* --------------------------------------------------------------------------
   5. Área de trabalho
   -------------------------------------------------------------------------- */

.sgm-main {
  grid-area: main;
  min-width: 0;
  padding: var(--sgm-5);
  overflow-x: hidden;
}

.sgm-page-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--sgm-4);
  flex-wrap: wrap;
  margin-bottom: var(--sgm-5);
}

/* 💎 `--color-on-surface-variant`, E NÃO `--color-on-surface-muted` —
   2026-08-20, pelo mesmo motivo de `.sgm-hint` (sgm-base.css): o muted
   (#6b7c8f) dá 4,28:1 sobre a superfície branca e a WCAG AA pede 4,5:1 para
   texto normal; 13px é texto normal. É esta regra que desenha o subtítulo de
   TODA tela — "Pesquisa da pessoa nos oito sistemas do município." e as
   irmãs. O variant (#46586b) dá 7,32:1. */
.sgm-page-head__sub {
  margin-top: var(--sgm-1);
  font-size: var(--sgm-t-base);
  color: var(--color-on-surface-variant);
}

.sgm-page-head__acoes { display: flex; align-items: center; gap: var(--sgm-2); flex-wrap: wrap; }

/* barra de filtros: uma linha, acima do conteúdo que ela recorta */
.sgm-filtros {
  display: flex;
  align-items: flex-end;
  gap: var(--sgm-3);
  flex-wrap: wrap;
  padding: var(--sgm-3) var(--sgm-4);
  margin-bottom: var(--sgm-4);
  background: var(--color-surface);
  border: 1px solid var(--color-outline);
  border-radius: var(--sgm-r);
  box-shadow: var(--sgm-sh-1);
}
.sgm-filtros .sgm-field { flex: 0 1 190px; }

/* A entidade CRESCE com o espaço que sobra; os outros campos não.
   "3 - INSTITUTO DE PREVIDÊNCIA DOS SERVIDORES MUNICIPAIS" não cabe em
   190px, e a barra tinha meia largura vazia à direita — apontado pelo
   Rodrigo em 2026-08-10.

   O teto existe para o combo não engolir a linha inteira quando o nome é
   curto: um <select> de 900px para "1 - PREFEITURA" é o defeito oposto.

   ⚠️ OS TRÊS SELETORES SÃO ARITMÉTICA, não estilo. A regra acima é
   `.sgm-filtros .sgm-field` — DUAS classes, (0,2,0). Uma classe sozinha
   (0,1,0) perderia e esta linha não faria nada, sem erro e sem aviso: o
   defeito que já custou quatro correções neste projeto. Com `.sgm-field`
   junto são (0,3,0), e não há empate para a ordem dos arquivos desempatar. */
.sgm-filtros .sgm-field.sgm-filtros__entidade { flex: 1 1 340px; max-width: 560px; }

/* 💎 OS DOIS CAMPOS DA PESQUISA DO CONTRIBUINTE — 2026-08-20.

   Estas larguras viviam em `style` inline dentro de sgm-telas.js. Inline vence
   qualquer regra de autor, media query inclusive: a redeclaração de 100% do
   bloco de 767px abaixo não fazia efeito nenhum, e podia ser apagada sem que
   nada na tela mudasse — o pior tipo de regra morta, a que parece viva.

   A aritmética é a mesma do `__entidade` logo acima, e pelo mesmo motivo:
   `.sgm-filtros .sgm-field` sozinho é (0,2,0), então a classe do campo entra
   junto e faz (0,3,0). Uma classe solta (0,1,0) perderia, sem erro e sem
   aviso — o defeito que já custou quatro correções neste projeto.

   As bases: o Nome cresce (é o filtro principal, e nome é longo); o CPF/CNPJ
   não cresce e reserva 230px, que é o que a máscara de CNPJ pede a 13px. */
.sgm-filtros .sgm-field.sgm-filtros__nome { flex: 1 1 320px; }
.sgm-filtros .sgm-field.sgm-filtros__doc  { flex: 0 1 230px; }

/* A busca do detalhamento (a barra que abre pelo botão de lupa da tela de
   detalhe). Mesma história, mesmo conserto: era `style: 'flex:1 1 260px'`. */
.sgm-filtros .sgm-field.sgm-filtros__busca { flex: 1 1 260px; }

/* 💎 A FAIXA DE APOIO — e por que ela SAI DO FLUXO. Print do Rodrigo,
   2026-08-20: na pesquisa do Contribuinte o campo CPF/CNPJ aparecia UM DEGRAU
   ACIMA do campo Nome, e a dica dele descia por cima da linha do vizinho.

   A causa é a de cima, na própria `.sgm-filtros`: `align-items: flex-end`
   alinha as colunas pela BASE, e isso só alinha os controles enquanto todas as
   colunas tiverem a mesma estrutura. A coluna do documento tinha três filhos
   (rótulo, campo, apoio) contra dois do Nome — então a base que coincidia era
   a do TEXTO DE APOIO, e o campo subia exatamente a altura dele. Com a frase
   quebrando em duas linhas nos 230px da coluna, o degrau era de duas linhas.

   ⚠️ NÃO SE CONSERTA ISSO ENCURTANDO A FRASE. Uma frase mais curta só encolhe
   o degrau até o dia em que a mensagem de erro for maior que ela — e o erro é
   escrito por quem digitou, não por nós. Enquanto o apoio ocupar espaço no
   fluxo da coluna, a barra inteira se move quando ele aparece ou muda.

   Aqui o apoio é ABSOLUTO e o lugar dele é RESERVADO no `padding-bottom` das
   colunas E do bloco do botão. Com isso: as três estruturas voltam a ser
   iguais e a base volta a alinhar os controles; o erro entra e sai sem mover
   um pixel; e o botão Localizar fica na linha dos campos, não na do apoio.

   A reserva é derivada dos tokens, não medida na tela: o `gap` do `.sgm-field`
   mais uma linha de `--sgm-t-sm`.

   ⚠️ ARITMÉTICA. `.sgm-filtros .sgm-field` é (0,2,0); um empate aqui deixaria
   a reserva à mercê da ordem dos arquivos, que é o defeito que já custou
   quatro correções neste projeto. Por isso a barra entra DUAS vezes no
   seletor — `.sgm-filtros.sgm-filtros--apoio` —, o que faz (0,3,0) nas
   colunas e (0,3,0) no `__fim`, acima de qualquer regra de uma ou duas
   classes.

   E o apoio propriamente dito é `.sgm-filtros .sgm-filtros__apoio` (0,2,0),
   acima de `.sgm-hint` e de `.sgm-error` (0,1,0) — as duas classes que se
   revezam nele conforme o estado. Sem isso, a classe do estado poderia
   devolver o apoio ao fluxo na hora do erro, que é justamente quando ele não
   pode se mexer. */
.sgm-filtros.sgm-filtros--apoio .sgm-field,
.sgm-filtros.sgm-filtros--apoio .sgm-filtros__fim {
  padding-bottom: calc(var(--sgm-1) + var(--sgm-t-sm) * var(--sgm-lh));
}
.sgm-filtros.sgm-filtros--apoio .sgm-field { position: relative; }
.sgm-filtros .sgm-filtros__apoio {
  position: absolute;
  left: 0;
  bottom: 0;
  max-width: 100%;
}

.sgm-filtros__fim { margin-left: auto; display: flex; align-items: center; gap: var(--sgm-2); }

/* --------------------------------------------------------------------------
   6. Pontos de quebra
   -------------------------------------------------------------------------- */

@media (max-width: 1180px) {
  .sgm-topbar__busca { flex-basis: 220px; }
}

@media (max-width: 900px) {
  .sgm-topbar__busca { display: none; }
  .sgm-user__nome    { display: none; }
  .sgm-user          { padding: 4px; }
}

@media (max-width: 767px) {
  .sgm-main { padding: var(--sgm-3); }

  .sgm-topbar { padding: 0 var(--sgm-3); gap: var(--sgm-2); }
  .sgm-topbar__sub { display: none; }

  .sgm-page-head { margin-bottom: var(--sgm-4); }
  .sgm-page-head__acoes { width: 100%; }
  .sgm-page-head__acoes .sgm-btn { flex: 1 1 auto; }

  .sgm-filtros { padding: var(--sgm-3); }
  .sgm-filtros .sgm-field { flex: 1 1 100%; }
  /* No telefone TODO campo ocupa a linha, inclusive a entidade. Media query
     não soma especificidade, então a regra de (0,3,0) lá de cima venceria
     aqui e deixaria o combo com 340px numa tela de 342px — sem esta linha o
     ajuste do desktop quebraria o celular. */
  .sgm-filtros .sgm-field.sgm-filtros__entidade { flex: 1 1 100%; max-width: none; }
  /* Os dois campos da pesquisa do contribuinte, pelo mesmo motivo e com a
     mesma aritmética (0,3,0). Sem estas duas linhas o CPF/CNPJ fica em ~138px
     no telefone e a máscara de CNPJ não cabe no campo. */
  .sgm-filtros .sgm-field.sgm-filtros__nome { flex: 1 1 100%; }
  .sgm-filtros .sgm-field.sgm-filtros__doc  { flex: 1 1 100%; }
  .sgm-filtros .sgm-field.sgm-filtros__busca { flex: 1 1 100%; }
  .sgm-filtros__fim { margin-left: 0; width: 100%; }
  .sgm-filtros__fim .sgm-btn { flex: 1 1 auto; }
  /* No telefone cada campo ocupa a linha inteira e o botão desce para a dele:
     não há mais nada ao lado para alinhar, e a reserva do apoio no bloco do
     botão viraria só um vão. Ela sai daqui — e SÓ daqui: nas colunas a reserva
     continua, porque é ela que impede a lista de resultados de saltar quando a
     mensagem de erro entra. */
  .sgm-filtros.sgm-filtros--apoio .sgm-filtros__fim { padding-bottom: 0; }
}

/* Quem comanda a navegação depende da forma, não da largura solta:
   open/mini → botão de recolher na topbar;
   fab       → o botão flutuante manda, e a topbar não repete o controle;
   drawer    → hambúrguer. */
.sgm-only-mobile,
.sgm-only-desktop { display: none; }

[data-nav="open"] .sgm-only-desktop,
[data-nav="mini"] .sgm-only-desktop { display: inline-flex; }

[data-nav="drawer"] .sgm-only-mobile { display: inline-flex; }

/* --------------------------------------------------------------------------
   🥇 A DICA DO RAIL — 2026-08-19, do modelo em C:\Sistemas\Modelos\Angular

   O modelo trocou o `title` nativo por uma dica própria (item 17 do MUDANCAS
   dele: a `lytTooltip` passou a adotar o `title` e a aceitar posição). Aqui
   vale pelo mesmo motivo: com a barra recolhida o rail é SÓ ícone, e o nome do
   módulo não está escrito em lugar nenhum.

   ⚠️ VIVE NO <body>, em position:fixed — `.sgm-rail__nav` tem
   `overflow-x: hidden`, e um balão desenhado dentro do botão seria cortado na
   borda da barra. É o mesmo motivo pelo qual o flyout antigo saía do fluxo.

   ⚠️ `pointer-events: none` NÃO É DETALHE: o balão nasce a 10px do ícone, e
   sem isso ele roubaria o `mouseleave` do próprio botão que o abriu — a dica
   piscaria ao aproximar o cursor dela.
   -------------------------------------------------------------------------- */

.sgm-dica {
  position: fixed;
  z-index: var(--sgm-z-popover);
  max-width: 260px;
  padding: 6px 10px;
  border-radius: var(--sgm-r-sm);
  background: var(--app-sidebar-bg);
  color: #fff;
  font-size: var(--sgm-t-sm);
  font-weight: 500;
  line-height: 1.35;
  white-space: nowrap;
  box-shadow: var(--sgm-sh-3);
  opacity: 0;
  transform: translateX(-4px);
  pointer-events: none;
  transition: opacity var(--sgm-fast) var(--sgm-ease),
              transform var(--sgm-fast) var(--sgm-ease);
}

.sgm-dica[data-open="true"] { opacity: 1; transform: translateX(0); }

/* a setinha que ancora o balão no ícone — sem ela ele parece solto na tela */
.sgm-dica::before {
  content: '';
  position: absolute;
  top: 50%;
  left: -4px;
  width: 8px; height: 8px;
  transform: translateY(-50%) rotate(45deg);
  background: var(--app-sidebar-bg);
}

/* ⚠️ NO TELEFONE A DICA NÃO EXISTE. Lá a barra é gaveta, o item mostra o
   rótulo escrito, e um balão preso ao toque ficaria pendurado sem nada que o
   feche — o `mouseleave` nunca chega num dispositivo sem cursor. */
@media (hover: none) {
  .sgm-dica { display: none; }
}

/* ==========================================================================
   🥇 SÓ O TRILHO, COM O NOME SOB O ÍCONE — remodelagem de 2026-10-15
   --------------------------------------------------------------------------
   Pedido do Rodrigo, com o print do painel riscado: *"a barra de menu com os
   atalhos pode remover ela, pois só está ocupando espaço"*.

   O PAINEL SAIU (`.sgm-navp`, a coluna de 200px com os quadros do módulo).
   Os quadros não ficaram inalcançáveis: eles são os CARDS do dashboard que o
   ícone abre, e a busca do topo ("Buscar quadro ou módulo") leva a qualquer
   um deles pelo nome. O painel era atalho de rolagem, e cobrava 200px de toda
   tela para isso.

   O TRILHO GANHOU O NOME DO MÓDULO SOB O ÍCONE, que é a forma do modelo novo
   (`rotulosNoTrilho: true` no `app.config.ts`, core 22.32 / template 22.12):
   ~11 letras por linha, duas linhas no máximo. Nome comprido usa o rótulo
   curto (`railTitle` lá, `Shell.rotuloRail` aqui) — e o nome inteiro
   continua no `aria-label` e na dica.

   A TECLA « CONTINUA, COM O SENTIDO DO MODELO: liga e desliga os nomes ("Nomes
   no menu" do painel de acessibilidade dele). Sem nomes o trilho volta aos
   64px só de ícone, e a dica diz o nome. A escolha fica no NAVEGADOR, como lá
   — é aparência, não dado.

   ⚠️ TUDO AQUI SOBREPÕE as seções 2 e 3 deste arquivo em vez de reescrevê-las:
      essas linhas são citadas por ponteiro (`confere-ponteiros.js`), e a
      cascata resolve pela ordem — estas regras vêm depois e têm a mesma ou
      maior especificidade.
   ========================================================================== */

/* o painel não existe mais no app.html; a regra fica para a página que ainda
   o traga (um demo antigo, uma cópia em cache) não abrir a coluna vazia */
.sgm-navp { display: none; }

[data-nav="open"] { --sgm-rail-w: 84px; }

[data-nav="open"] .sgm-aside { width: var(--sgm-rail-w); }

/* sem o painel, o trilho É a barra: o tom mais escuro que o separava da
   coluna ao lado viraria uma faixa sem motivo */
.sgm-rail { background: none; }

.sgm-rail__rot { display: none; }

/* --- com os nomes ------------------------------------------------------- */

[data-nav="open"] .sgm-rail__nav {
  gap: 4px;
  padding: var(--sgm-2) 0;
  /* ⚠️ COM NOMES, 18 MÓDULOS NÃO CABEM numa tela de notebook — e o trilho
     rola. A barra fina aparece de propósito: escondida, o fim da lista
     parecia o fim dos módulos. */
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, .18) transparent;
}

/* ⚠️ `flex: 0 0 auto` NÃO É DETALHE — medido em 2026-10-15: o `.sgm-rail__nav`
   é coluna flex e, com a lista maior que a tela, ENCOLHE os filhos até o
   `min-height`. Os itens de nome comprido perdiam a segunda linha (26px de
   texto numa caixa de 17), e o trilho parecia ter nomes cortados ao meio. */
[data-nav="open"] .sgm-rail__item {
  flex: 0 0 auto;
  width: 76px;
  height: auto;
  min-height: 48px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 7px 3px 6px;
  border-radius: var(--sgm-r);
}

[data-nav="open"] .sgm-rail__item i { font-size: 17px; line-height: 1; }

[data-nav="open"] .sgm-rail__rot {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  max-width: 100%;
  font-size: 0.65625rem;   /* 10,5px — o corpo do rótulo de trilho do modelo */
  font-weight: 550;
  line-height: 1.2;
  letter-spacing: 0;
  text-align: center;
  /* nunca parte palavra no meio ("Contabili-dade"): quem não cabe usa o
     rótulo curto, que é escolhido em Shell.rotuloRail */
  overflow-wrap: normal;
  word-break: normal;
}

[data-nav="open"] .sgm-rail__sep { flex: 0 0 1px; width: 40px; margin: var(--sgm-1) 0; }   /* 1px que a rolagem não encolhe a zero */

/* --- telefone: a gaveta do leque ----------------------------------------
   Na gaveta o trilho deita: ícone e nome na mesma linha, a lista inteira à
   mão do polegar. É o "Todos os módulos" do botão flutuante. */

[data-nav="fab"] .sgm-aside { width: min(84vw, 248px); }

[data-nav="fab"] .sgm-rail { flex: 1 1 auto; width: 100%; align-items: stretch; }

[data-nav="fab"] .sgm-rail__nav { align-items: stretch; padding: var(--sgm-3) var(--sgm-2); }

[data-nav="fab"] .sgm-rail__pe { padding: 0 var(--sgm-2); }

[data-nav="fab"] .sgm-rail__item {
  flex: 0 0 auto;   /* o mesmo encolhimento do trilho aberto — ver a nota lá em cima */
  width: 100%;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: var(--sgm-3);
  padding: 0 var(--sgm-3);
  opacity: .85;
}

[data-nav="fab"] .sgm-rail__item i { flex: 0 0 22px; text-align: center; }

[data-nav="fab"] .sgm-rail__rot {
  display: block;
  min-width: 0;
  font-size: var(--sgm-t-base);
  font-weight: 550;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

[data-nav="fab"] .sgm-rail__sep { flex: 0 0 1px; width: auto; margin: var(--sgm-1) var(--sgm-3); }
