/*
  Layout / styles / layout.css
  Breakpoints: compact < 720px · base 720–1119px · wide >= 1120px
  (mesmos valores documentados no Design System "Instrumento").

  Prompt 14 (redesign visual): estrutura passa de "sidebar de altura total
  ao lado de um header estreito" (Prompt 12) para as quatro regiões da
  seção 4 — header institucional de LARGURA TOTAL no topo, sidebar+conteúdo
  como uma faixa abaixo dele, rodapé discreto no final. `.app-shell` deixa
  de ser grid (2 colunas) e passa a ser flex em coluna: topbar (altura
  fixa) → `.shell-body` (flex-row: sidebar + conteúdo) → footer (altura
  fixa). Mantém as MESMAS classes/seletores que `shell.js`/`sidebar.js`/
  `topbar.js` já usavam onde possível — só o que a seção 2 pediu para mudar
  de fato mudou.
*/

.app-shell{
  display:flex;
  flex-direction:column;
  min-height:100vh;
}

/* ---------- header institucional ----------
   Redesign (pedido do usuário): de azul escuro pra BRANCO — `var(--surface)`
   de propósito, não `#FFFFFF` fixo: essa variável já vira superfície escura
   sozinha no tema escuro (mesmo token usado em cards/tabelas), então o
   header acompanha o tema automaticamente sem nenhuma regra extra aqui —
   só o TEXTO precisa de tratamento próprio (`--header-ink`, ver
   tokens.css), porque título/rótulo em azul-marinho fixo ficaria ilegível
   se o fundo escurecesse. Sombra trocada de `--shadow-md` (pesada, fazia
   sentido só sobre o azul escuro anterior) pra uma borda fina + sombra
   quase imperceptível — "separação muito sutil", nunca pesada. */
.topbar{
  height:var(--shell-topbar-h);
  flex:none;
  background:var(--surface);
  border-bottom:1px solid var(--border);
  box-shadow:var(--shadow-xs);
  display:flex;align-items:center;justify-content:space-between;
  padding:0 var(--space-7);
  position:sticky;top:0;z-index:50;
}
.topbar-left{display:flex;align-items:center;gap:var(--space-5);min-width:0;}
.topbar-right{display:flex;align-items:center;gap:var(--space-6);flex:none;}
.mobile-menu-btn{display:none;}

.topbar-brand{display:flex;align-items:center;gap:var(--space-5);min-width:0;position:relative;z-index:1;}
/* Logo da PMB é um lockup HORIZONTAL (marca + "PREFEITURA DE BETIM"), não um
   ícone quadrado — só a ALTURA é fixada, a largura acompanha a proporção
   natural do arquivo (`height:auto` faria o oposto e ficaria minúsculo).
   Nunca usar `object-fit:cover`/esticar: distorceria a logo. SEM caixa,
   moldura ou fundo artificial ao redor — pedido explícito do usuário: a
   logo fica direto sobre o branco do header, exatamente como já vem no
   arquivo oficial (nenhum tratamento de cor/filtro aplicado). Aumentada
   bastante (era 44/56px) — precisa de presença institucional de verdade. */
.topbar-logo{height:64px;width:auto;flex:none;}
.topbar-divider{width:2px;height:40px;background:var(--brand-accent-green);border-radius:var(--radius-full);flex:none;}
.topbar-titles{display:flex;flex-direction:column;line-height:1.3;min-width:0;gap:2px;}
/* Título — azul institucional escuro, MUITO destacado (era 21px, sobe pra
   23px) — nunca `--brand-on-primary` (branco): esse token é da SIDEBAR,
   que continua escura; o header agora é claro. `--header-ink` inverte
   sozinho no tema escuro (ver tokens.css). */
.topbar-title{font-size:23px;font-weight:700;letter-spacing:-.01em;color:var(--header-ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
/* Subtítulo em verde institucional — cor oficial da logo, mesma em
   qualquer tema (verde médio lê bem tanto sobre branco quanto sobre a
   superfície escura do tema escuro, ao contrário do azul-marinho do
   título, que precisa inverter). */
.topbar-subtitle{font-size:13px;font-weight:600;color:var(--brand-accent-green);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}

.topbar-last-update{display:flex;flex-direction:column;align-items:flex-end;line-height:1.35;gap:1px;}
.topbar-last-update-label{
  display:inline-flex;align-items:center;gap:5px;
  font-size:10.5px;letter-spacing:.05em;text-transform:uppercase;font-weight:600;color:var(--header-ink);font-family:var(--font-mono);
}
.topbar-last-update-label svg{width:11px;height:11px;flex:none;}
/* Data com bastante destaque (seção 9 — "a data deve ter maior destaque") — maior e mais pesada que o rótulo acima dela. */
.topbar-last-update-value{font-size:15px;font-weight:700;color:var(--header-ink);font-variant-numeric:tabular-nums;}
.topbar-last-update-value.is-loading{color:var(--text-tertiary);font-weight:400;}

/* botão "Atualizar dados" — verde institucional (seção 10), texto/ícone
   brancos. Não é nem `.btn-primary` (cor de AÇÃO PRIMÁRIA do resto do
   produto, `--accent`) nem `.btn-secondary` — modificador próprio, só pra
   botões que vivem DENTRO do header. Estados de sucesso/erro continuam
   usando as cores semânticas de sempre (nunca o verde institucional, que
   não é um status — ver `.refresh-btn.is-success/.is-error` abaixo,
   inalterados). */
.btn-on-brand{background:var(--brand-accent-green);border:1px solid var(--brand-accent-green);color:#fff;}
.btn-on-brand:hover{background:var(--brand-accent-green-hover);border-color:var(--brand-accent-green-hover);}
.btn-on-brand:disabled{opacity:.6;cursor:default;}
.refresh-btn{display:inline-flex;align-items:center;gap:var(--space-2);white-space:nowrap;}
.refresh-btn-icon{display:flex;}
.refresh-btn.is-loading .refresh-btn-icon svg{animation:refresh-spin var(--dur-slower) linear infinite;}
.refresh-btn.is-success{background:var(--success);border-color:var(--success);color:#fff;}
.refresh-btn.is-error{background:var(--danger);border-color:var(--danger);color:#fff;}
@keyframes refresh-spin{from{transform:rotate(0deg);}to{transform:rotate(360deg);}}
@media (prefers-reduced-motion: reduce){
  .refresh-btn.is-loading .refresh-btn-icon svg{animation:none;}
}

/* tema/menu mobile — quadrado azul institucional escuro, ícone branco (seção 11), sobre o header agora branco. */
.topbar .icon-btn{background:var(--brand-primary-dark);color:#fff;border-radius:var(--radius-md);}
.topbar .icon-btn:hover{background:var(--brand-primary);}

/* ---------- corpo: sidebar + conteúdo ---------- */
.shell-body{
  display:flex;
  flex:1;
  min-height:0;
}

/* ---------- sidebar institucional — seções 15-20 ---------- */
.sidebar{
  width:var(--shell-sidebar-w);
  flex:none;
  position:sticky;top:var(--shell-topbar-h);
  align-self:flex-start;
  height:calc(100vh - var(--shell-topbar-h));
  background:linear-gradient(180deg, var(--brand-primary) 0%, var(--brand-primary-dark) 100%);
  display:flex;flex-direction:column;
  overflow:hidden;
  z-index:40;
  transition:width var(--dur-base) var(--ease-standard);
}
.app-shell.is-collapsed .sidebar{width:var(--shell-sidebar-w-collapsed);}
/* recolher só existe a partir de 720px — abaixo disso a gaveta mobile manda, ver breakpoint compact */
@media (min-width: 720px){
  .app-shell.is-collapsed .nav-link-label,
  .app-shell.is-collapsed .sidebar-footer .nav-link-label{display:none;}
  .app-shell.is-collapsed .nav-link{justify-content:center;padding-left:0;padding-right:0;}
  .app-shell.is-collapsed .sidebar-collapse-btn{justify-content:center;padding-left:0;padding-right:0;}
  /* `.sidebar`/`.sidebar-nav` recortam (overflow:hidden/auto) pra conter o
     rótulo durante a transição de largura — mas isso também cortava o
     tooltip (`.tip-lite`) da sidebar recolhida, que precisa "vazar" pra
     fora da faixa estreita de ícones (seção 20: "estado recolhido mostra
     ícones apenas + tooltips"). Seguro liberar só no estado recolhido
     ESTÁVEL: o rótulo já some via `display:none` (não anima), então nada
     transborda durante a transição de largura em si — e os 4 itens de nav
     nunca preenchem a altura da sidebar, então abrir mão do scroll vertical
     aqui não tem custo real. */
  .app-shell.is-collapsed .sidebar{overflow:visible;}
  .app-shell.is-collapsed .sidebar-nav{overflow:visible;}
}

.sidebar-nav{padding:var(--space-6) var(--space-4);overflow-y:auto;flex:1;}
.nav-group{margin-bottom:var(--space-6);}
.nav-group-label{
  font-family:var(--font-mono);font-size:10px;letter-spacing:.08em;text-transform:uppercase;
  color:var(--brand-on-primary-muted);padding:0 var(--space-4);margin-bottom:var(--space-3);white-space:nowrap;
}
/* itens maiores e mais espaçados (seção 17) — altura confortável, ícone
   21px (era 18px), gap maior entre ícone e rótulo. */
.nav-link{
  position:relative;display:flex;align-items:center;gap:var(--space-4);
  padding:var(--space-4) var(--space-4);margin-bottom:var(--space-2);border-radius:var(--radius-md);
  color:var(--brand-on-primary-muted);font-size:14px;font-weight:500;white-space:nowrap;
  transition:background var(--dur-fast) var(--ease-standard),color var(--dur-fast),transform var(--dur-fast) var(--ease-standard);
}
.nav-link:hover{background:rgba(255,255,255,.1);color:var(--brand-on-primary);transform:translateX(2px);}
/* item ativo — destaque forte (seção 18): fundo mais claro que o resto da
   sidebar, texto/ícone brancos, sombra discreta pra "levantar" o item. */
.nav-link.is-active{background:var(--brand-primary-light);color:var(--brand-on-primary);box-shadow:var(--shadow-sm);}
.nav-link-icon{display:flex;flex:none;}
.nav-link-icon svg{width:21px;height:21px;}
.nav-link-label{overflow:hidden;}
.app-shell:not(.is-collapsed) .tip-lite{display:none;}

/* rodapé da sidebar — "Recolher menu" (seção 20) */
.sidebar-footer{flex:none;padding:var(--space-4);border-top:1px solid rgba(255,255,255,.12);}
.sidebar-collapse-btn{
  width:100%;display:flex;align-items:center;gap:var(--space-4);
  padding:var(--space-3) var(--space-4);border-radius:var(--radius-md);border:none;background:none;cursor:pointer;
  color:var(--brand-on-primary-muted);font-size:13px;font-weight:500;font-family:var(--font-ui);white-space:nowrap;
  transition:background var(--dur-fast) var(--ease-standard),color var(--dur-fast);
}
.sidebar-collapse-btn:hover{background:rgba(255,255,255,.1);color:var(--brand-on-primary);}
.sidebar-collapse-icon{display:flex;flex:none;transition:transform var(--dur-base) var(--ease-standard);}
.app-shell.is-collapsed .sidebar-collapse-icon{transform:rotate(180deg);}

/* ---------- content ---------- */
.content-outlet{padding:var(--space-7);flex:1;min-width:0;background:var(--canvas);}
.content-outlet .page{animation:page-in var(--dur-base) var(--ease-out);}
@keyframes page-in{
  from{opacity:0;transform:translateY(6px);}
  to{opacity:1;transform:translateY(0);}
}

/* ---------- rodapé discreto — seção 57 ---------- */
.shell-footer{
  flex:none;display:flex;align-items:center;justify-content:space-between;gap:var(--space-4);flex-wrap:wrap;
  padding:var(--space-4) var(--space-7);border-top:1px solid var(--border);
  background:var(--surface);font-size:11.5px;color:var(--text-tertiary);
}
.shell-footer-brand{display:inline-flex;align-items:center;gap:6px;}
.shell-footer-brand svg{width:13px;height:13px;flex:none;color:var(--text-tertiary);}

/* ---------- gaveta mobile ---------- */
.shell-backdrop{display:none;}

@media (max-width: 719px){
  .sidebar{
    position:fixed;top:0;left:0;width:var(--shell-sidebar-w);height:100vh;
    transform:translateX(-100%);
    transition:transform var(--dur-base) var(--ease-standard);
    box-shadow:var(--shadow-xl);
  }
  .app-shell.is-mobile-open .sidebar{transform:translateX(0);}
  .sidebar-footer{display:none;} /* recolher não existe no mobile — só a gaveta abre/fecha (seção 20) */
  .shell-backdrop{
    display:block;position:fixed;inset:0;background:var(--overlay);
    opacity:0;pointer-events:none;transition:opacity var(--dur-base) var(--ease-standard);z-index:60;
  }
  .app-shell.is-mobile-open .shell-backdrop{opacity:1;pointer-events:auto;}
  .mobile-menu-btn{display:inline-flex;}
  .content-outlet{padding:var(--space-6);}

  /* Header institucional no mobile (seção 43/60): prioriza logo + nome do
     sistema + ações essenciais; subtítulo e "Última atualização" saem pra
     não quebrar a linha; o botão Atualizar vira só ícone (rótulo continua
     no `aria-label` do próprio botão, nunca perde acessibilidade). */
  .topbar{height:var(--shell-topbar-h-compact);padding:0 var(--space-4);gap:var(--space-3);}
  .topbar-logo{height:32px;}
  .topbar-divider{display:none;}
  .topbar-title{font-size:15px;}
  .topbar-subtitle,.topbar-last-update{display:none;}
  .refresh-btn-label{display:none;}
  .sidebar{top:0;} /* gaveta cobre a tela inteira, inclusive atrás do header — padrão mobile comum */
  .shell-footer{padding:var(--space-4) var(--space-4);flex-direction:column;align-items:flex-start;gap:2px;}
}

@media (min-width: 720px) and (max-width: 1119px){
  .content-outlet{padding:var(--space-6);}
  .topbar{padding:0 var(--space-6);}
  .topbar-last-update{display:none;}
}
