/* ==========================================================================
   Sovereign Layout — Sidebar + Topbar + Stage
   ========================================================================== */

.app-shell {
  min-height: 100vh;
  display: grid;
  grid-template-columns: 230px 1fr;
  /* Sem pintura própria: quem pinta o fundo é o html/body, com o degradê do
     --surface-gradient (theme.css). Aqui pintava a mesma cor chapada e, por
     estar por cima, tampava o degradê inteiro. A sidebar tem fundo próprio
     (--sidebar-surface), então o véu aparece só no palco de conteúdo. */
  background: transparent;
}
.app-shell.sidebar-collapsed {
  grid-template-columns: 56px 1fr;
}

/* -------- Sidebar -------- */
.sidebar {
  position: sticky;
  top: 0;
  align-self: start;
  height: 100vh;
  display: flex;
  flex-direction: column;
  padding: 0;
  background: var(--sidebar-surface);
  /* A rolagem NÃO fica aqui: se ficasse, a trilha da barra correria a altura
     inteira da coluna, passando ao lado da logo. Vai em .sidebar-scroll. */
  overflow: hidden;
  transition: background var(--motion-base);
  border-right: 1px solid var(--outline-variant);
}

/* Área rolável: começa abaixo da faixa da marca e ocupa o resto da coluna. */
.sidebar-scroll {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  /* Sem padding lateral: o recuo vive dentro de cada item, para que a faixa de
     hover/ativo ocupe a largura inteira da coluna. */
  padding: 0 0 1.5rem;
  overflow-y: auto;
  overflow-x: hidden;
}

/* Scrollbar discreta: some em repouso, aparece ao passar o cursor na sidebar.
   Sobrescreve a regra global de ::-webkit-scrollbar do theme.css apenas aqui.
   A largura fica reservada mesmo invisível, para não deslocar o conteúdo. */
.sidebar-scroll {
  scrollbar-width: thin;
  scrollbar-color: transparent transparent;
}
.sidebar:hover .sidebar-scroll { scrollbar-color: var(--outline-variant) transparent; }

.sidebar-scroll::-webkit-scrollbar { width: 6px; }
.sidebar-scroll::-webkit-scrollbar-track { background: transparent; }
.sidebar-scroll::-webkit-scrollbar-thumb {
  background: transparent;
  border: 0;
  border-radius: 999px;
  transition: background 160ms ease;
}
.sidebar:hover .sidebar-scroll::-webkit-scrollbar-thumb { background: var(--outline-variant); }
.sidebar:hover .sidebar-scroll::-webkit-scrollbar-thumb:hover { background: var(--on-surface-muted); }

/* A marca ocupa exatamente a faixa do frame superior, alinhada à topbar.
   É irmã fixa de .sidebar-scroll — fica fora da área rolável, então a barra
   de rolagem nunca aparece ao lado da logo. */
.sidebar-brand {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
  height: var(--topbar-h);
  flex-shrink: 0;
  padding: 0 0.75rem;
  background: var(--sidebar-surface);
  border-bottom: 1px solid var(--outline-variant);
  text-decoration: none;
  color: var(--on-surface);
  transition: padding 220ms ease;
}
.sidebar-brand:hover { color: var(--on-surface); text-decoration: none; }
.sidebar.collapsed .sidebar-brand { padding: 0; }

.sidebar-logo {
  display: block;
  width: 100%;
  /* A marca é bem mais larga que alta (2048×712), então quem limita é a
     altura; a largura só precisa dar espaço para ela crescer. */
  max-width: 190px;
  height: auto;
  max-height: calc(var(--topbar-h) - 18px);
  object-fit: contain;
  transition: width 220ms ease, opacity 220ms ease;
}
/* Colapsada: some a marca por extenso e entra o símbolo compacto */
.sidebar.collapsed .sidebar-logo { display: none; }
.sidebar-logo-mark { display: none; width: 30px; height: 30px; }

/* ── Swap automático da logo conforme o tema ─────────────────────────────── */
/* O seletor leva `img.` porque .login-logo é declarada mais abaixo neste
   arquivo e, com a mesma especificidade, venceria o display:none do par
   oculto — as duas versões apareceriam juntas na tela de login. */
/* Default (light): mostra logo escura, esconde a clara */
img.logo-dark { display: none; }
img.logo-light { display: block; }

/* Dark: mostra logo clara, esconde a escura */
[data-theme="dark"] img.logo-light { display: none; }
[data-theme="dark"] img.logo-dark { display: block; }

/* Auto: segue prefer-color-scheme do SO */
@media (prefers-color-scheme: dark) {
  [data-theme="auto"] img.logo-light { display: none; }
  [data-theme="auto"] img.logo-dark { display: block; }
}

/* Mesmo swap para o símbolo, mas só vale com a coluna recolhida. */
.sidebar.collapsed .mark-light { display: block; }
[data-theme="dark"] .sidebar.collapsed .mark-light { display: none; }
[data-theme="dark"] .sidebar.collapsed .mark-dark { display: block; }
@media (prefers-color-scheme: dark) {
  [data-theme="auto"] .sidebar.collapsed .mark-light { display: none; }
  [data-theme="auto"] .sidebar.collapsed .mark-dark { display: block; }
}

.sidebar-portal-label {
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--primary);
  font-weight: 700;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  transition: opacity 150ms ease, max-height 220ms ease;
  max-height: 40px;
  opacity: 1;
}
.sidebar.collapsed .sidebar-portal-label { opacity: 0; max-height: 0; }

.sidebar-section-label {
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--on-surface-muted);
  padding: 1.15rem 1.8rem 0.8rem 1.55rem;
  white-space: nowrap;
  transition: opacity 150ms ease;
  opacity: 1;
}
.sidebar-section-label:first-of-type { padding-top: 0.6rem; }
.sidebar.collapsed .sidebar-section-label { opacity: 0; height: 0; padding: 0; overflow: hidden; }

.sidebar-nav {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.sidebar-nav a {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  /* Recuo lateral do menu embutido no item: a faixa sangra até a borda. */
  padding: 0.68rem 1.8rem 0.68rem 1.55rem;
  border-radius: 0;
  color: var(--on-surface-muted);
  font-weight: 500;
  font-size: 0.86rem;
  letter-spacing: -0.005em;
  transition: background 150ms ease, color 150ms ease, padding 220ms ease, justify-content 220ms ease;
  text-decoration: none;
  white-space: nowrap;
  overflow: hidden;
  position: relative;
}
.sidebar.collapsed .sidebar-nav a {
  padding: 0.68rem;
  justify-content: center;
}
.sidebar.collapsed .sidebar-nav a .nav-label { display: none; }
.sidebar-nav a .nav-icon {
  font-size: 1.13rem;
  width: 20px;
  text-align: center;
  flex-shrink: 0;
  line-height: 1;
  /* Monocromático (modelo INSPINIA) — a cor por item foi removida do nav.html */
  color: var(--sidebar-icon);
  transition: color 150ms ease;
}
.sidebar-nav a:hover {
  background: var(--surface-container);
  color: var(--on-surface);
}
.sidebar-nav a:hover .nav-icon { color: var(--on-surface); }
.sidebar-nav a.active {
  background: var(--surface-container);
  color: var(--primary);
  font-weight: 700;
}
.sidebar-nav a.active .nav-icon { color: var(--primary); }


.sidebar-footer {
  margin-top: auto;
  padding-top: 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}
.sidebar-footer a {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.6rem 1.75rem 0.6rem 1.55rem;
  border-radius: 0;
  color: var(--on-surface-muted);
  font-size: 0.85rem;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  transition: background 150ms ease, color 150ms ease, padding 220ms ease;
}
.sidebar.collapsed .sidebar-footer a {
  padding: 0.6rem;
  justify-content: center;
}
.sidebar.collapsed .sidebar-footer a .nav-label { display: none; }
.sidebar-footer a:hover { background: var(--surface-container); color: var(--on-surface); }
.sidebar-footer a .nav-icon {
  font-size: 1.05rem;
  width: 18px;
  text-align: center;
  flex-shrink: 0;
  line-height: 1;
}

/* -------- Topbar (barra escura — modelo INSPINIA) -------- */
.topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 1rem;
  height: var(--topbar-h);
  padding: 0 1.25rem;
  background: var(--topbar-surface);
  border-bottom: 1px solid var(--topbar-border);
  color: var(--on-topbar);
}

.topbar-left {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 1rem;
  min-width: 0;
}

.topbar-title {
  display: none;
  font-size: 1rem;
  font-weight: 700;
  color: var(--on-topbar);
}

/* -------- Busca da tela --------------------------------------------------
   Fica ao lado do botão de recolher, como um par. Filtra ao vivo as linhas
   das tabelas da página aberta (comportamento em app.js; a linha escondida
   usa .tb-busca-off, no tables.css).

   Sobre fundo navy os controles não podem herdar o form padrão do theme.css,
   que é claro. Daí os seletores com [type="search"] e :hover/:focus explícitos:
   o `input:hover:not(:disabled):not([readonly])` do theme tem peso (0,3,1) e
   passaria na frente de um `.topbar-search input` sozinho. -------------- */
.topbar-search {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex: 0 1 420px;
  min-width: 0;
  height: 40px;
  padding: 0 0.35rem 0 0.75rem;
  border-radius: var(--radius-md);
  background: var(--topbar-hover);
  border: 1px solid transparent;
  transition: background 150ms ease, border-color 150ms ease;
}
/* O foco marca pela borda, não clareando o fundo: com o fundo mais claro o
   placeholder cai para 4.4:1, abaixo do mínimo — e é justamente no campo
   focado e ainda vazio que ele precisa ser lido. */
.topbar-search:focus-within { border-color: var(--on-topbar-muted); }

/* Tela sem tabela: a barra não muda de forma, o campo é que se apaga. Fundo
   mais discreto e cursor barrado dizem "aqui não tem o que filtrar" sem sumir
   com o controle e sem fingir que ele funciona. */
.topbar-search.sem-alvo {
  background: transparent;
  border-color: var(--topbar-border);
}
.topbar-search.sem-alvo > .ri-search-line { opacity: 0.55; }
.topbar-search.sem-alvo input[type="search"] { cursor: not-allowed; }
/* O texto do placeholder não desbota junto: é ele que diz por que o campo está
   apagado, e sem o preenchimento atrás ele lê a 7.4:1 — melhor até que no
   estado ativo. Apagá-lo apagaria justamente a explicação. */
.topbar-search > .ri-search-line {
  font-size: 1.05rem;
  line-height: 1;
  color: var(--on-topbar-muted);
  flex-shrink: 0;
}

.topbar-search input[type="search"],
.topbar-search input[type="search"]:hover,
.topbar-search input[type="search"]:focus,
.topbar-search input[type="search"]:disabled {
  flex: 1;
  width: auto;
  min-width: 0;
  height: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  outline: none;
  box-shadow: none;
  background: transparent;
  color: var(--on-topbar);
  font-family: inherit;
  font-size: 0.88rem;
}
.topbar-search input[type="search"]::placeholder { color: var(--on-topbar-muted); opacity: 1; }
/* O X é o nosso, com o contador ao lado — o nativo do WebKit sobraria. */
.topbar-search input[type="search"]::-webkit-search-cancel-button { display: none; }

.topbar-search-count {
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--on-topbar-muted);
  white-space: nowrap;
  flex-shrink: 0;
}

/* Atalho à vista: só quando o campo está ligado e ainda sem foco — ao digitar
   sai da frente do contador; na tela sem tabela não há o que atalhar. */
.topbar-search-kbd {
  font-family: inherit;
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  line-height: 1;
  padding: 0.25rem 0.4rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--topbar-border);
  color: var(--on-topbar-muted);
  white-space: nowrap;
  flex-shrink: 0;
}
.topbar-search.sem-alvo .topbar-search-kbd,
.topbar-search:focus-within .topbar-search-kbd { display: none; }
@media (max-width: 640px) { .topbar-search-kbd { display: none; } }

.topbar-search-clear {
  display: none;
  place-items: center;
  width: 26px;
  height: 26px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--on-topbar-muted);
  font-size: 1rem;
  cursor: pointer;
  flex-shrink: 0;
  overflow: visible;
}
.topbar-search-clear:hover {
  background: var(--topbar-active);
  color: var(--on-topbar);
  box-shadow: none;
  transform: none;
}
/* Desliga o state layer do botão padrão (theme.css), que aqui viraria um véu. */
.topbar-search-clear::after { content: none; }
/* Só faz sentido oferecer "limpar" quando há o que limpar. */
.topbar-search.tem-termo .topbar-search-clear { display: grid; }

.topbar-nav {
  display: flex;
  gap: 0.25rem;
  list-style: none;
  margin: 0;
  padding: 0;
  flex: 1;
}
.topbar-nav a {
  padding: 0.5rem 0.875rem;
  color: var(--on-surface-variant);
  font-size: 0.88rem;
  font-weight: 500;
  border-radius: var(--radius-md);
}
.topbar-nav a:hover { background: var(--surface-low); color: var(--on-surface); }
.topbar-nav a.active {
  color: var(--on-surface);
  font-weight: 700;
}

.topbar-right {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

/* Ajuda virou ícone puro: usa .topbar-icon-btn, igual a Administração e Tema. */

/* Tema: botão único que cicla entre os três modos. Os três ícones ficam no
   DOM e o data-state decide qual aparece — sem troca de markup pelo JS. */
.theme-cycle .theme-ico {
  display: none;
  width: 18px;
  height: 18px;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.theme-cycle[data-state="light"] .theme-ico[data-for="light"],
.theme-cycle[data-state="dark"]  .theme-ico[data-for="dark"],
.theme-cycle[data-state="auto"]  .theme-ico[data-for="auto"] { display: block; }

/* Tela cheia: mesma ideia — "entrar" em repouso, "sair" quando já está cheia. */
.fullscreen-toggle .fs-ico[data-for="exit"] { display: none; }
.fullscreen-toggle.is-full .fs-ico[data-for="enter"] { display: none; }
.fullscreen-toggle.is-full .fs-ico[data-for="exit"] { display: block; }

.topbar-icon-btn {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  padding: 0;
  display: grid;
  place-items: center;
  background: transparent;
  color: var(--on-topbar-muted);
  font-size: 1.15rem;
  border: 0;
  cursor: pointer;
  flex-shrink: 0;
  text-decoration: none;
  transition: background 150ms ease, color 150ms ease;
}
.topbar-icon-btn:hover { background: var(--topbar-hover); color: var(--on-topbar); box-shadow: none; transform: none; }
.topbar-icon-btn.active { background: var(--topbar-active); color: var(--on-topbar); }
.topbar-icon-btn::after { content: none; }
.topbar-icon-btn .icon { width: 18px; height: 18px; stroke: currentColor; fill: none; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }

.topbar-user {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  /* Avatar à esquerda: a folga maior passa para o lado do texto. */
  padding: 0.25rem 0.75rem 0.25rem 0.25rem;
  border-radius: 999px;
  /* Bloco informativo, não é botão — sem fundo e sem hover. */
  background: transparent;
  border: 0;
}

.topbar-user-meta {
  display: flex;
  flex-direction: column;
  line-height: 1.2;
  text-align: left;
}
.topbar-user-meta .cargo {
  font-size: 0.72rem;
  font-weight: 500;
  color: var(--on-topbar-muted);
}

.avatar {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--gradient-primary);
  color: #fff;
  display: grid;
  place-items: center;
  font-weight: 700;
  font-size: 0.78rem;
  letter-spacing: 0.02em;
  flex-shrink: 0;
}

/* Único elemento roxo que ficava dentro da faixa: passa para o azul da marca.
   Escopado à topbar de propósito — o mesmo .avatar aparece na lista de
   usuários (admin/users.html), sobre card branco, onde o roxo continua certo. */
.topbar-user .avatar { background: var(--topbar-avatar); }

.topbar-user .nome {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--on-topbar);
  max-width: 160px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.topbar-user .logout {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  margin-left: 0.25rem;
  color: var(--on-topbar-muted);
  font-size: 0.8rem;
  padding: 0.25rem 0.5rem;
  border-radius: var(--radius-md);
  text-decoration: none;
}
.topbar-user .logout i { font-size: 1rem; }
@media (max-width: 640px) { .topbar-user .logout span { display: none; } }
.topbar-user .logout:hover { background: var(--topbar-active); color: var(--on-topbar); }

/* -------- Main stage -------- */
.main-stage {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.container, .container-narrow {
  width: 100%;
  max-width: 100%;
  margin: 0 auto;
  padding: 1rem 1.5rem 3rem;
}
.container-narrow { max-width: 640px; }

.page-header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 1.25rem;
}

.page-header h1 {
  margin: 0;
  padding-left: 0.75rem;
  border-left: 3px solid var(--primary);
  line-height: 1.3;
}

.page-header .page-subtitle {
  display: block;
  margin-top: 0.5rem;
  /* Alinha com o texto do h1, que é empurrado pela barra de 3px mais o
     padding — sem isto o subtítulo nasce 15px à esquerda do título. */
  padding-left: calc(0.75rem + 3px);
  color: var(--on-surface-variant);
  font-size: 0.95rem;
  font-weight: 400;
  max-width: 560px;
}

.page-title-group { flex: 1; min-width: 280px; }

.page-actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

/* -------- Toggle da sidebar (agora dentro da topbar escura) --------
   Botão único: no desktop colapsa/expande; em telas ≤1024px abre o overlay. */
.sidebar-toggle {
  display: grid;
  place-items: center;
  /* Sem moldura em repouso — o realce só aparece no hover. */
  background: transparent;
  color: var(--on-topbar);
  border: 0;
  width: 42px;
  height: 42px;
  border-radius: var(--radius-md);
  padding: 0;
  cursor: pointer;
  flex-shrink: 0;
  transition: background 150ms ease;
  box-shadow: none;
}
.sidebar-toggle:hover { background: var(--topbar-active); color: var(--on-topbar); box-shadow: none; transform: none; }
.sidebar-toggle::after { content: none; }
.sidebar-toggle svg {
  width: 20px;
  height: 20px;
  stroke: currentColor;
  fill: none;
  stroke-width: 2;
  stroke-linecap: round;
}

/* Backdrop must be out-of-flow at all widths so it doesn't consume a grid cell on desktop */
.sidebar-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(25, 28, 31, 0.4);
  z-index: 40;
  display: none;
}
.sidebar-backdrop.show { display: block; }

/* -------- Tooltip para sidebar recolhida -------- */
.sidebar.collapsed .sidebar-nav a[data-tooltip],
.sidebar.collapsed .sidebar-footer a[data-tooltip] {
  position: relative;
}
.sidebar.collapsed .sidebar-nav a[data-tooltip]::after,
.sidebar.collapsed .sidebar-footer a[data-tooltip]::after {
  content: attr(data-tooltip);
  position: absolute;
  left: calc(100% + 10px);
  top: 50%;
  transform: translateY(-50%);
  background: var(--on-surface);
  color: var(--surface-lowest);
  font-size: 0.78rem;
  font-weight: 500;
  white-space: nowrap;
  padding: 0.3rem 0.65rem;
  border-radius: var(--radius-sm);
  pointer-events: none;
  opacity: 0;
  transition: opacity 150ms ease;
  z-index: 100;
}
.sidebar.collapsed .sidebar-nav a[data-tooltip]:hover::after,
.sidebar.collapsed .sidebar-footer a[data-tooltip]:hover::after {
  opacity: 1;
}

@media (max-width: 1024px) {
  .app-shell { grid-template-columns: 1fr; }
  .sidebar {
    position: fixed;
    left: -250px;
    top: 0;
    bottom: 0;
    width: 230px;
    z-index: 50;
    height: 100vh;
    transition: left 200ms ease;
    box-shadow: var(--shadow-float);
  }
  .sidebar.open { left: 0; }
  .topbar-nav { display: none; }
  .container, .container-narrow { padding: 1.5rem; }
}

@media (max-width: 640px) {
  .topbar { padding: 0.75rem 1rem; }
  .topbar-user .topbar-user-meta { display: none; }
  /* Sem espaço para os 420px fixos: a busca passa a ceder largura conforme a
     barra aperta, e o contador sai — o campo e o X é que precisam sobreviver. */
  .topbar-search { flex: 1 1 auto; gap: 0.35rem; padding-left: 0.5rem; }
  .topbar-search-count { display: none; }
  .page-header { align-items: flex-start; }
  h1 { font-size: 1.2rem; }
}

/* -------- Login (fullpage) -------- */
.login-shell {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem 1rem;
  background:
    radial-gradient(1200px 600px at 20% 10%, rgba(52, 20, 108, 0.08), transparent 60%),
    radial-gradient(800px 500px at 85% 90%, rgba(75, 46, 131, 0.08), transparent 60%),
    var(--surface);
}

.login-wrap {
  width: 100%;
  max-width: 460px;
  text-align: center;
}

.login-logo {
  display: block;
  width: 360px;
  max-width: 90%;
  height: auto;
  margin: 0 auto 1.25rem;
}
.login-system-name {
  font-size: 1.4rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  color: var(--primary);
  margin-bottom: 0.5rem;
}
.login-tagline {
  color: var(--on-surface-muted);
  font-size: 0.85rem;
  margin-bottom: 2rem;
  letter-spacing: 0.02em;
}

.login-card {
  background: var(--surface-lowest);
  border-radius: var(--radius-xl);
  padding: 2rem;
  box-shadow: var(--shadow-ambient);
  text-align: left;
}

.login-card label { margin-bottom: 0.375rem; color: var(--on-surface); font-size: 0.75rem; letter-spacing: 0.05em; text-transform: uppercase; }
.login-card .form-actions button { width: 100%; padding: 0.875rem; font-size: 0.95rem; }
/* Separador "OU" entre senha e SSO, e botão SSO com a largura do form */
.login-ou { display: flex; align-items: center; gap: 0.5rem; margin: 1rem 0; color: var(--on-surface-variant); font-size: 0.8rem; }
.login-ou span { flex: 1; height: 1px; background: var(--surface-low); }
.login-sso-btn { width: 100%; text-align: center; }

.login-meta {
  margin-top: 1rem;
  color: var(--on-surface-muted);
  font-size: 0.75rem;
  text-align: center;
  line-height: 1.6;
  padding: 0 1rem;
}

.login-footer {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  padding: 1rem 2rem;
  display: flex;
  justify-content: center;
  gap: 1rem;
  color: var(--on-surface-muted);
  font-size: 0.75rem;
  flex-wrap: wrap;
  text-align: center;
}

@media (max-width: 640px) {
  .login-footer { position: static; padding: 1rem; }
}

/* -------- Stat cards (dashboard style) -------- */
.stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1.25rem;
  margin-bottom: 2rem;
}

.stat-card {
  background: var(--surface-lowest);
  border-radius: var(--radius-lg);
  padding: 1.25rem 1.5rem;
  box-shadow: var(--shadow-card);
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.stat-card .stat-icon {
  width: 40px;
  height: 40px;
  border-radius: var(--radius-md);
  background: var(--surface-low);
  display: grid;
  place-items: center;
  color: var(--primary);
  margin-bottom: 0.5rem;
}
.stat-card .stat-icon .icon { width: 20px; height: 20px; stroke: currentColor; fill: none; stroke-width: 1.75; }
.stat-card .stat-label {
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--on-surface-muted);
  font-weight: 700;
}
.stat-card .stat-value {
  font-size: 2rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--on-surface);
  line-height: 1;
}
.stat-card .stat-hint {
  font-size: 0.8rem;
  color: var(--on-surface-variant);
}

/* Dark highlight variant (matches "Alocação por Tipo" card) */
.panel-dark {
  background: var(--gradient-primary);
  color: #fff;
  border-radius: var(--radius-lg);
  padding: 1.5rem;
  box-shadow: var(--shadow-ambient);
}
.panel-dark h2, .panel-dark h3 { color: #fff; }
.panel-dark .text-muted { color: rgba(255,255,255,0.7); }

/* -------- Aviso banner -------- */
.aviso-banner {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.65rem 1.5rem;
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1.4;
  border-bottom: 1px solid transparent;
}
.aviso-info    { background: var(--info-bg);    color: var(--info);    border-color: rgba(31,91,168,.2); }
.aviso-aviso   { background: var(--warning-bg); color: var(--warning); border-color: rgba(169,99,0,.2); }
.aviso-urgente { background: var(--danger-bg);  color: var(--danger);  border-color: rgba(179,34,54,.2); }
.aviso-sucesso { background: var(--success-bg); color: var(--success); border-color: rgba(31,122,78,.2); }
.aviso-icon { font-size: 1.15rem; line-height: 1; flex-shrink: 0; display: inline-flex; }
.aviso-body { flex: 1; min-width: 0; }
.aviso-close {
  background: transparent;
  border: none;
  font-size: 1.2rem;
  line-height: 1;
  padding: 0 0.25rem;
  cursor: pointer;
  color: inherit;
  opacity: 0.6;
  flex-shrink: 0;
  box-shadow: none;
  transform: none;
}
.aviso-close:hover { opacity: 1; background: transparent; box-shadow: none; transform: none; }
.aviso-close i { font-size: 1.1rem; }

/* -------- Expand card -------- */
.expand-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(15, 10, 30, 0.55);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  z-index: 298;
  display: none;
}
.expand-backdrop.active { display: block; }

[data-expandable].is-expanded {
  position: fixed;
  inset: 1.25rem;
  z-index: 299;
  overflow-y: auto;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-float);
  background: var(--surface-lowest);
}

.expand-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  border-radius: var(--radius-sm);
  border: 1px solid var(--outline-variant);
  background: transparent;
  color: var(--on-surface-muted);
  cursor: pointer;
  flex-shrink: 0;
  margin-left: auto;
  transition: background 150ms, color 150ms;
  font-size: 0;
}
.expand-btn:hover { background: var(--surface-container); color: var(--primary); box-shadow: none; transform: none; }
.expand-btn svg { width: 13px; height: 13px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* -------- Navbar legacy shim (older partials) -------- */
.navbar { display: none; }

/* O grupo de 3 botões de tema (.theme-toggle / .theme-toggle-btn) virou um
   botão único: ver .theme-cycle junto de .topbar-icon-btn. */

/* ── Nav Groups (collapsible sections) ───────────────────────────────────── */

.nav-group { margin-bottom: 0.15rem; }

/* Item de primeiro nível sem filhos (ex.: Tabela de Plantão, Construtor de PP).
   Herda tudo de .sidebar-nav a — só sobe o peso para igualar .nav-group-header. */
.nav-solo { margin-bottom: 0.15rem; }
.nav-item-solo { font-weight: 600; }

/* Cabeçalho de grupo tem o MESMO peso visual do item (modelo INSPINIA):
   ícone + label no tamanho normal + chevron à direita. */
.nav-group-header {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  width: 100%;
  padding: 0.68rem 1.8rem 0.68rem 1.55rem;
  background: transparent;
  border: 0;
  cursor: pointer;
  color: var(--on-surface-muted);
  font-family: inherit;
  font-size: 0.86rem;
  font-weight: 600;
  letter-spacing: -0.005em;
  text-align: left;
  border-radius: 0;
  transition: background 150ms ease, color 150ms ease;
  white-space: nowrap;
  overflow: hidden;
}
.nav-group-header:hover {
  background: var(--surface-container);
  color: var(--on-surface);
}
.nav-group-header .nav-icon {
  flex-shrink: 0;
  font-size: 1.13rem;
  width: 20px;
  text-align: center;
  line-height: 1;
  color: var(--sidebar-icon);
  transition: color 150ms ease;
}
.nav-group-header:hover .nav-icon { color: var(--on-surface); }
.nav-group-header .nav-chevron {
  margin-left: auto;
  font-size: 0.9rem;
  flex-shrink: 0;
  transition: transform 220ms ease;
  color: var(--sidebar-icon);
}
.nav-group.is-open > .nav-group-header .nav-chevron { transform: rotate(180deg); }

.nav-group-items {
  overflow: hidden;
  max-height: 0;
  transition: max-height 260ms ease;
}
.nav-group.is-open > .nav-group-items { max-height: 500px; }

/* Sub-item: só texto, recuado até alinhar com o rótulo do grupo.
   O ícone continua no DOM, escondido apenas quando a sidebar está expandida —
   é ele que identifica o item na barra colapsada, onde o rótulo some. */
.nav-group-items a {
  padding-left: 3.65rem !important;
  font-size: 0.81rem;
  font-weight: 500;
}
.sidebar:not(.collapsed) .nav-group-items a .nav-icon { display: none; }
.sidebar.collapsed .nav-group-items a .nav-icon { font-size: 1.13rem; width: 20px; }

/* Collapsed sidebar: hide group headers, show items flat without indent */
.sidebar.collapsed .nav-group-header { display: none; }
.sidebar.collapsed .nav-group-items {
  max-height: none !important;
  overflow: visible;
}
.sidebar.collapsed .nav-group-items a {
  padding: 0.6rem !important;
  justify-content: center;
}
.sidebar.collapsed .nav-group-items a .nav-label { display: none; }

/* ── Menu de Ações (padrão do projeto) ───────────────────────────────────────
   <details class="menu"> + <summary> (gatilho) + <div class="menu-list"> (painel).
   Abertura é NATIVA do <details>; o JS (app.js) só fecha ao clicar fora, ao
   escolher um item ou com Esc. Duas variantes de gatilho:
     A) toolbar  → <summary class="btn btn-secundario btn-small">Ações ▾</summary>
     B) linha de tabela (kebab) → <summary class="icon-btn"> + classe menu-row
        no <details> (alinha o painel à direita, p/ não vazar da tela).
   Cores vêm dos tokens do theme.css → claro/escuro automáticos. */
.menu { position: relative; display: inline-block; }
.menu > summary { list-style: none; cursor: pointer; }
.menu > summary::-webkit-details-marker { display: none; }

.menu-list {
  position: absolute; top: calc(100% + 0.35rem); left: 0; z-index: 60;
  min-width: 210px; padding: 0.4rem;
  background: var(--surface-lowest);
  border: 1px solid var(--outline-variant);
  /* Era 0.75rem cravado — passa a seguir o token de dropdown do design system. */
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-ambient);
  display: flex; flex-direction: column;
  animation: menu-pop 0.14s ease;
}
@keyframes menu-pop { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }

/* Menu no canto direito (page-header / célula de ações): ancora pela direita, senão
   o painel cresce para fora da tela. Vale p/ qualquer menu nesses containers. */
.page-actions .menu-list,
.row-actions .menu-list,
.actions .menu-list { right: 0; left: auto; }

/* Itens: <button> e <a> com o MESMO visual (pode misturar link e ação) */
.menu-list button, .menu-list a {
  display: flex; align-items: center; justify-content: flex-start; gap: 0.5rem;
  text-align: left; width: 100%;
  background: transparent; border: 0; border-radius: 7px;
  padding: 0.5rem 0.6rem; font: inherit; font-size: 0.85rem;
  color: var(--on-surface); text-decoration: none; cursor: pointer;
  transition: 0.16s cubic-bezier(0.4, 0, 0.2, 1);
}
.menu-list button:hover, .menu-list a:hover { background: var(--surface-low); }
/* Largura fixa no ícone: os glifos Remix têm avanços diferentes, então sem isso o
   rótulo de cada linha começa num x distinto e o menu fica visualmente desalinhado. */
.menu-list button i, .menu-list a i {
  font-size: 1rem; color: var(--on-surface-variant);
  flex: 0 0 1.15rem; width: 1.15rem; text-align: center;
}
/* Ação destrutiva: sempre por último */
.menu-list button.danger, .menu-list a.danger,
.menu-list button.danger i, .menu-list a.danger i { color: var(--danger); }
.menu-list button.danger:hover, .menu-list a.danger:hover { background: var(--danger-bg); }
.menu-sep { height: 1px; margin: 0.3rem 0.4rem; background: var(--outline-variant); }

/* Variante B: painel alinhado à direita + gatilho 30x30 */
.menu-row .menu-list { right: 0; left: auto; }
.menu-row > summary { width: 30px; height: 30px; }

/* Gatilho B — botão de ícone "fantasma" */
.icon-btn {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border: 0; background: transparent;
  color: var(--on-surface-variant);
  border-radius: 7px; cursor: pointer;
  transition: 0.16s cubic-bezier(0.4, 0, 0.2, 1);
}
.icon-btn:hover { background: var(--surface-low); color: var(--primary); }
.icon-btn .ico { width: 16px; height: 16px; }
.icon-btn i { font-size: 1.05rem; line-height: 1; }
/* Variante destrutiva (ex.: excluir) */
.icon-btn.danger { color: var(--danger); }
.icon-btn.danger:hover { background: var(--danger-bg); color: var(--danger); }
/* Funil de filtros (Contratos, PPs, Tabela de Plantão): destacado quando há filtro
   fora do padrão, com badge do nº de filtros ativos no canto. */
.icon-btn.tem-filtro { color: var(--primary); background: var(--surface-low); }
.icon-btn-badge {
  position: absolute; top: -5px; right: -5px;
  min-width: 16px; height: 16px; padding: 0 4px;
  border-radius: var(--radius-pill);
  background: var(--primary); color: var(--on-primary);
  font-size: 0.62rem; font-weight: 700; line-height: 16px; text-align: center;
  pointer-events: none;
}
.icon-btn-badge[hidden] { display: none; }
/* Funil de filtros (Contratos, PPs, Tabela de Plantão): destacado quando há filtro
   fora do padrão, com badge do nº de filtros ativos no canto. */
.icon-btn.tem-filtro { color: var(--primary); background: var(--surface-low); }
.icon-btn-badge {
  position: absolute; top: -5px; right: -5px;
  min-width: 16px; height: 16px; padding: 0 4px;
  border-radius: var(--radius-pill);
  background: var(--primary); color: var(--on-primary);
  font-size: 0.62rem; font-weight: 700; line-height: 16px; text-align: center;
  pointer-events: none;
}
.icon-btn-badge[hidden] { display: none; }

/* Agrupador na célula de ações da tabela */
.row-actions { display: inline-flex; gap: 0.25rem; justify-content: flex-end; align-items: center; }

/* ==========================================================================
   Véu de carregamento entre páginas
   Markup no base.html (#page-loader), comportamento no app.js.

   O sistema navega por links de verdade — cada tela é um documento novo vindo
   do servidor. Entre o clique e o primeiro pixel da tela nova o navegador não
   desenha nada, e a tela antiga fica parada: parece travamento, não espera.
   Este véu ocupa esse intervalo.

   z-index acima de tudo (o mais alto do sistema hoje é 9999) porque ele cobre
   inclusive sidebar, topbar e modais abertos — cobrir só o palco de conteúdo
   deixaria metade da tela viva e leria como erro de renderização.
   ========================================================================== */
.page-loader {
  position: fixed;
  inset: 0;
  z-index: 10000;
  display: grid;
  align-content: center;
  justify-items: center;
  gap: 1.1rem;
  background: var(--scrim);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  /* visibility junto do opacity: só opacity deixaria o véu invisível mas ainda
     por cima, comendo todo clique da página. O atraso na visibility é para ela
     só desligar depois que o fade terminou. */
  opacity: 0;
  visibility: hidden;
  transition: opacity 180ms ease, visibility 0s linear 180ms;
}
.page-loader.ativo {
  opacity: 1;
  visibility: visible;
  transition: opacity 180ms ease, visibility 0s;
}

/* --------------------------------------------------------------------------
   .aneis — os dois arcos girando. É o MESMO desenho em duas escalas: 104px no
   véu de página (com a marca no meio) e ~44px dentro de um card que espera a
   resposta de um fetch. Vive aqui, e não no CSS de uma feature, justamente
   porque a segunda escala é para qualquer tela usar.

   O tamanho e a espessura entram por variável; o resto é igual nos dois casos.
   -------------------------------------------------------------------------- */
.aneis {
  /* A marca entra como FUNDO, não como <img>: assim todo .aneis já nasce com o
     símbolo — o véu de página, os cards esperando um fetch e o corpo dos modais
     — sem cada template/JS ter de repetir o par de imagens. Era o que faltava
     nos anéis dos cards da Gestão Operacional, que giravam vazios. */
  --aneis-marca: url('../img/marca-actar.svg?v=1');
  display: grid;
  width: var(--aneis-tam, 104px);
  height: var(--aneis-tam, 104px);
  background: var(--aneis-marca) center / var(--aneis-logo, 52%) no-repeat;
}
/* Swap por tema, mesma lógica das regras img.logo-light / img.logo-dark lá em
   cima: o arquivo sem sufixo é o de tinta escura, para fundo claro. */
[data-theme="dark"] .aneis { --aneis-marca: url('../img/marca-actar-dark.svg?v=1'); }
@media (prefers-color-scheme: dark) {
  [data-theme="auto"] .aneis { --aneis-marca: url('../img/marca-actar-dark.svg?v=1'); }
}
/* Arcos na mesma célula do grid: é o que os mantém centrados na marca sem
   depender de position/translate. */
.aneis::before,
.aneis::after {
  grid-area: 1 / 1;
  place-self: center;
}

/* Os dois arcos são bordas — nem máscara, nem conic-gradient: além de
   funcionarem em qualquer navegador, se algo falhar eles falham para um anel
   completo, nunca para um disco tapando a logo. */
.aneis::before,
.aneis::after {
  content: '';
  border-radius: 50%;
  border-style: solid;
  border-color: transparent;
}
.aneis::before {
  width: 100%;
  height: 100%;
  border-width: var(--aneis-traco, 3px);
  border-top-color: var(--primary);
  border-right-color: var(--primary);
  animation: aneis-giro 900ms linear infinite;
}
/* O de dentro é mais fino, mais lento e ao contrário: dois arcos no mesmo
   sentido e na mesma velocidade viram um anel só, e o movimento some. */
.aneis::after {
  width: 78%;
  height: 78%;
  border-width: calc(var(--aneis-traco, 3px) * 0.66);
  border-bottom-color: var(--primary-container);
  animation: aneis-giro 1400ms linear infinite reverse;
}
@keyframes aneis-giro { to { transform: rotate(1turn); } }

.aneis-rotulo {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--on-surface-muted);
}

/* Quem pediu menos movimento continua precisando saber que algo está vindo, então
   o indicador não sai — para de girar e passa a pulsar. Os arcos viram anéis
   inteiros aqui: arco parado é um pedaço de círculo torto, que só faz sentido
   enquanto gira. */
@media (prefers-reduced-motion: reduce) {
  .aneis::before {
    border-color: var(--primary);
    animation: aneis-pulso 1.8s ease-in-out infinite;
  }
  .aneis::after {
    border-color: var(--primary-container);
    animation: aneis-pulso 1.8s ease-in-out infinite 0.9s;
  }
}
@keyframes aneis-pulso { 0%, 100% { opacity: 0.2; } 50% { opacity: 1; } }

/* --------------------------------------------------------------------------
   .carregando — o bloco que ocupa o lugar de um conteúdo que ainda está vindo
   por fetch. Trocar "Carregando…" solto por isto não é enfeite: texto estático
   e tela travada são indistinguíveis, e era exatamente essa a dúvida ("demorou
   e não apareceu"). O que gira responde à pergunta; o texto parado, não.

   Monte pelo VizCore.carregando (viz-core.js) em vez de repetir a marcação.
   -------------------------------------------------------------------------- */
.carregando {
  display: grid;
  justify-items: center;
  align-content: center;
  gap: 0.7rem;
  padding: 1.75rem 0;
}
.carregando .aneis {
  --aneis-tam: 44px;
  --aneis-traco: 2.5px;
}
.carregando .aneis-rotulo {
  font-size: 0.68rem;
  letter-spacing: 0.14em;
}
