/* ============================================================
   Navegação principal — sem framework
   ============================================================
   Uma barra para as três superfícies: site público, painel admin e painel do
   gestor. Escrita em CSS próprio sobre `tokens.css`, sem classe de Bootstrap e
   sem utilidade de Tailwind, porque ela precisa servir tanto a página já
   migrada quanto a que ainda não foi. Componente de navegação não precisa de
   framework para existir, e este sobrevive à migração inteira sem reescrita.

   Veio do `gestor-nav-app`, que morava em `frontend-planejai/src/index.css` e
   era renderizado por um componente React já morto: o elemento que ele
   procurava saiu dos templates em `a2f831f`, então as duzentas linhas viajavam
   em todo carregamento do painel sem desenhar nada.

   O menu chega do servidor aberto. Só depois de o `navbar.js` marcar a barra
   com `pnav--js` é que as regras abaixo podem escondê-lo, e é por isso que a
   ocultação está toda atrás dessa classe: sem ela, sem JavaScript, o menu fica
   visível.
   ============================================================ */

/* O `position` e o `z-index` aqui não são enfeite: são o que mantém o painel
   suspenso por cima do conteúdo.

   O `view-transition-name` que esta folha dá à `.pnav` mais abaixo CRIA um
   contexto de empilhamento. Com ele, o `z-index: 30` do `.pnav__itens` passou a
   valer só dentro da `.pnav`, e a `.pnav` sendo estática pintava na ordem do
   documento, antes do `.gestor-container`. O menu aberto no celular ficava atrás
   do cartão da página, meio visível, meio coberto.

   Qualquer propriedade que crie contexto de empilhamento na `.pnav` (transform,
   filter, opacity abaixo de 1, contain) tem o mesmo efeito. Ao acrescentar uma,
   conferir se o painel continua por cima em largura de celular. */
.pnav {
  position: relative;
  z-index: 100;
  width: 100%;
  font-family: var(--bs-font-sans-serif);
}

/* Largura e recuo da barra. Antes vinha do `container` do Bootstrap, que as
   telas migradas não carregam mais: a marca encostava na borda esquerda e a
   pílula de itens ia para o canto direito. */
.pnav__area {
  width: 100%;
  /* Cada superfície declara a sua no próprio CSS, porque cada uma tem uma
     largura de conteúdo diferente. Barra mais estreita que o conteúdo abaixo
     dela é o deslocamento que se vê na tela. O 1140 de antes vinha do
     `container` do Bootstrap e não correspondia a nenhuma das três. */
  max-width: var(--pnav-largura, 1140px);
  margin: 0 auto;
  padding: 0 var(--espaco-3);
}

/* O painel admin tem nove itens de menu e precisa de mais espaço. */
.pnav__area--largo {
  --pnav-largura: 1560px;
}

.pnav__barra {
  position: relative;
  display: flex;
  /* Não quebrar é o que permite medir a falta de espaço: com `wrap`, o
     conteúdo que não cabe desce de linha e `scrollWidth` nunca passa de
     `clientWidth`, então não há sinal nenhum de que faltou espaço. Foi assim
     que a barra virou três andares em 21/08/2026 sem nada acusar. Agora ela
     transborda, o `navbar.js` mede o transbordo e recolhe. */
  flex-wrap: nowrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--espaco-5);
  width: 100%;
  padding: var(--espaco-2) 0;
}

/* ── Marca ── */

.pnav__marca {
  display: inline-flex;
  flex-direction: column;
  text-decoration: none;
}

/* A marca é um SVG servido como imagem, não texto estilizado. O arquivo já traz
   o símbolo e o nome, com o "AI" em laranja, então a folha só cuida do tamanho.
   `width: auto` com `height` fixa preserva a proporção 961×168 do viewBox, e os
   atributos `width`/`height` no `<img>` reservam o espaço antes de o arquivo
   chegar, para a barra não pular.

   O viewBox foi apertado até a caixa do desenho (era 1080×300, com 44% de folga
   em volta). Com a folga, `height: 2.25rem` rendia 20 pixels de letra e o
   subtítulo passava a mandar no bloco. */
.pnav__marca-logo {
  display: block;
  height: 1.75rem;
  width: auto;
}

.pnav__marca-sub {
  margin-top: 0.22rem;
  color: rgba(243, 236, 223, 0.55);
  font-size: 0.76rem;
  font-weight: 800;
  letter-spacing: 0.26em;
  text-transform: uppercase;
}

/* ── Itens ── */

/* O `<details>` é quem empurra os itens para a direita no desktop; os itens
   dentro dele só se organizam. */
.pnav__menu {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-left: auto;
}

/* Pílula dos itens que permanecem na barra quando o espaço aperta.
   Vive fora de `.pnav__itens`, que é o que vira painel suspenso, e por isso não
   é alcançada pelas regras do estado recolhido. */
.pnav__lista--fixa {
  flex-shrink: 0;
}

/* Item de flex encolhe abaixo do conteúdo por padrão, e foi isso que escondeu a
   falta de espaço: em vez de transbordar, os blocos se comprimiam, o texto
   quebrava dentro do próprio link e a barra só ficava mais alta. Do lado do
   JavaScript nada acusava, porque `scrollWidth` nunca passava de `clientWidth`.
   Com `flex-shrink: 0` a falta vira transbordo, e transbordo é mensurável. */
.pnav__marca,
.pnav__lista,
.pnav__meta {
  flex-shrink: 0;
}

.pnav__link,
.pnav__sair,
.pnav__usuario {
  white-space: nowrap;
}

.pnav__itens {
  display: flex;
  align-items: center;
  /* Antes daqui saía `flex-wrap: wrap`, posto para o "Sair" do painel admin não
     ficar fora da tela em 1440px. Ele resolvia o corte criando a quebra: a
     decisão de Q-029, preservar as listas como estão, continua valendo, mas
     quem cede agora é o estado da barra, que recolhe, e não o alinhamento. */
  flex-wrap: nowrap;
  justify-content: flex-end;
  gap: 1.15rem;
}

.pnav__lista {
  display: flex;
  align-items: center;
  /* A pílula também não quebra. Enquanto ela quebrava por dentro, a faixa nunca
     transbordava, a medição do `navbar.js` não via falta de espaço nenhuma e o
     recolhimento jamais entrava: o resultado era a barra de dois andares que
     este trabalho veio corrigir. Quem quebra é o estado recolhido, que empilha
     em coluna, e o caminho sem JavaScript no celular. */
  flex-wrap: nowrap;
  justify-content: center;
  gap: 0.55rem;
  padding: 0.42rem;
  border: var(--borda-sutil);
  border-radius: var(--raio-pilula);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.055), rgba(255, 255, 255, 0.02));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.03);
  list-style: none;
  margin: 0;
}

.pnav__link,
.pnav__sair {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 44px de alvo de toque, que é o mínimo da WCAG 2.5.8 e não desce daqui. */
  min-height: 2.75rem;
  padding: 0.62rem 1.05rem;
  border: 0;
  border-radius: var(--raio-pilula);
  background: none;
  color: rgba(243, 236, 223, 0.76);
  font-family: inherit;
  font-size: 0.96rem;
  font-weight: 800;
  text-decoration: none;
  cursor: pointer;
  transition:
    background var(--transicao-curta),
    color var(--transicao-curta),
    transform var(--transicao-curta),
    box-shadow var(--transicao-curta);
}

.pnav__link:hover,
.pnav__sair:hover {
  color: #fff6ea;
  transform: translateY(-1px);
  box-shadow: 0 12px 24px rgba(0, 0, 0, 0.18);
}

/* Sair é a única ação da barra que desfaz o que se estava fazendo, e até aqui
   ela se parecia com um item de menu qualquer no hover. O vermelho avisa antes
   do clique. Só cor e fundo: o `translateY` e a sombra vêm da regra acima e
   continuam valendo, então o gesto é o mesmo dos outros, só que em vermelho.

   `#ff8f8f` sobre `rgba(255,90,90,.14)` dá 7,1:1, folgado para 1.4.3. O tom é
   o mesmo que `site.css` já usa em erro, para vermelho significar uma coisa só
   no produto inteiro.

   O hover em si vive no fim do arquivo: ele precisa da `@media (hover: hover)`,
   e nenhuma `@media` pode vir antes do `.pnav--compacta` sem derrubar o AC-085.
   No teclado o aviso vale igual, e `:focus-visible` não passa pelo `hover`, por
   isso esta metade fica aqui. */
.pnav__sair:focus-visible {
  color: #ff8f8f;
  background: rgba(255, 90, 90, 0.14);
}

/* Estado ativo marcado por contorno e cor de texto, não por preenchimento.
   O laranja preenchido está reservado para AÇÃO, e na landing isso é o botão de
   cadastro do hero. Medido na captura: com os dois preenchidos, o item de menu
   competia com o único caminho de entrada da página e AC-049 deixava de valer. */
.pnav__link[aria-current='page'] {
  border: 1px solid rgba(239, 143, 29, 0.55);
  background: rgba(239, 143, 29, 0.12);
  color: #ffb765;
}

.pnav__meta {
  display: flex;
  align-items: center;
  gap: 0.8rem;
}

/* Era uma pílula preenchida, com 40 pixels de recheio horizontal e peso 800.
   Quem tem ação recebe forma de botão; o nome de quem está logado é
   identificação, e estava competindo por largura com os cinco destinos e com o
   "Sair", que são os elementos acionáveis da barra. Sem o recheio e com peso
   normal ele continua legível e devolve espaço para a navegação. */
.pnav__usuario {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 3rem;
  color: #cbf2ea;
  font-size: 0.9rem;
  font-weight: 600;
}

/* O nome é o único conteúdo da barra de tamanho imprevisível, e desde que o
   bloco do usuário deixou de ir para o painel suspenso ele fica na barra em
   toda largura. Sem teto, "Maria Aparecida da Conceição Nascimento Rodrigues"
   empurrava a barra para fora da área: com `flex-shrink: 0` no `.pnav__meta`,
   que é o que torna a falta de espaço mensurável, quem tem de ceder é o texto.

   Reticências e não quebra: o nome inteiro continua alcançável no `title`, e a
   altura da barra não depende de quem está logado. */
.pnav__usuario-nome {
  display: block;
  max-width: 11rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.pnav__usuario-email {
  color: rgba(203, 242, 234, 0.7);
  font-size: 0.78rem;
  font-weight: 600;
}

.pnav__sair {
  border: 1px solid rgba(239, 143, 29, 0.28);
}

/* ── Botão do menu no celular ──
   É o `<summary>` do `<details>`. `display:block` remove o triângulo do
   navegador; `list-style:none` faz o mesmo no Safari, que usa outro mecanismo. */

.pnav__abrir {
  display: none;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 3rem;
  border: var(--borda-controle);
  border-radius: var(--raio-pilula);
  background: rgba(255, 255, 255, 0.04);
  cursor: pointer;
  list-style: none;
}

.pnav__abrir::-webkit-details-marker {
  display: none;
}

.pnav__abrir-tracos {
  display: flex;
  flex-direction: column;
  gap: 0.28rem;
}

.pnav__abrir-tracos span {
  display: block;
  width: 1.1rem;
  height: 2px;
  border-radius: var(--raio-pilula);
  background: #fff1dc;
}

.pnav__abrir:focus-visible,
.pnav__link:focus-visible,
.pnav__sair:focus-visible {
  outline: 3px solid rgba(120, 209, 192, 0.95);
  outline-offset: 3px;
}

/* ── Estado recolhido ──

   Antes isto valia dentro de `@media (max-width: 991.98px)`, e essa era a
   falha: 992px é uma largura fixa, e as três superfícies servem listas de
   tamanhos diferentes. Três itens no site público cabem folgados em 992. Cinco
   no painel do gestor pedem cerca de 1.230 pixels com o bloco do usuário
   junto. Nove no painel admin pedem mais ainda. Uma largura só não podia
   atender às três, e quem não cabia quebrava em linhas.

   Agora o recolhimento é medido: o `navbar.js` compara o que a barra pede com
   o espaço que ela tem e aplica `pnav--compacta` quando falta. A regra passa a
   ser "recolhe quando não cabe", que vale para qualquer superfície e para
   qualquer lista, inclusive as que ainda não existem.

   A classe continua sendo posta só por JavaScript, e o aprimoramento
   progressivo não muda: sem script, nada recolhe e a barra chega inteira. */

.pnav--compacta .pnav__abrir {
  display: inline-flex;
}

.pnav--compacta .pnav__itens[data-aberto='false'] {
  display: none;
}

/* Painel suspenso ancorado no botão que o abre, e não na barra inteira.

   Ancorava nas duas pontas, com `left: 0; right: 0`, e por isso ocupava toda a
   largura da área da navbar: 1280 pixels no painel do gestor, para quatro itens
   de menu. Menu suspenso pertence ao controle que o abriu; esticado de ponta a
   ponta ele não se lê como menu, e sim como a página tendo mudado.

   A largura agora sai do conteúdo, entre um mínimo que evita item apertado e um
   máximo que respeita a tela. O `calc` reserva a margem lateral para o painel
   não encostar na borda em janela estreita. */
.pnav--compacta .pnav__itens {
  position: absolute;
  left: auto;
  right: 0;
  top: calc(100% + 0.65rem);
  min-width: 15rem;
  max-width: min(21rem, calc(100vw - 2rem));
  flex-direction: column;
  align-items: stretch;
  margin-left: 0;
  padding: var(--espaco-2);
  border: var(--borda-sutil);
  border-radius: 1.1rem;
  background: rgba(12, 19, 24, 0.98);
  box-shadow: 0 24px 44px rgba(0, 0, 0, 0.34);
  z-index: 30;
}

.pnav--compacta .pnav__itens .pnav__lista {
  flex-direction: column;
  align-items: stretch;
  width: 100%;
}

/* Dentro do painel a lista deixa de ser pílula.

   Ela é desenhada para FLUTUAR na barra: tem borda, raio de pílula, gradiente e
   sombra interna, e é isso que a separa do fundo lá em cima. Dentro de um painel
   que já tem borda, fundo e sombra, esse mesmo contorno vira moldura sobre moldura
   — foi o que produziu o efeito de caixa dentro de caixa que o usuário
   relatou.

   Aqui ela volta a ser o que é neste contexto: um grupo de linhas. Quem separa
   um grupo do outro é o espaço, e uma linha fina entre eles, não outra borda. */
.pnav--compacta .pnav__itens .pnav__lista {
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
  gap: 0.15rem;
}

/* Separa os grupos sem empilhar bordas: só entre irmãos, nunca no primeiro. */
.pnav--compacta .pnav__itens > * + * {
  margin-top: 0.35rem;
  padding-top: 0.35rem;
  border-top: 1px solid rgba(255, 255, 255, 0.07);
}

.pnav--compacta .pnav__itens .pnav__link {
  width: 100%;
  justify-content: flex-start;
  border-radius: 0.9rem;
}

/* ── Celular ──

   O que sobra aqui é o caminho sem JavaScript, e só ele. Sem script não há
   `pnav--compacta`, então a barra precisa poder empilhar em vez de transbordar
   para fora da tela: a quebra volta, e nessa situação ela é o comportamento
   correto, não o defeito. */

@media (max-width: 991.98px) {
  /* `:not(.pnav--js)` é o que restringe isto ao caminho sem script. Sem a
     ressalva, a quebra volta a valer também com JavaScript presente, a barra
     deixa de transbordar e o recolhimento nunca entra no telefone, que é
     justamente onde ele sempre foi necessário. */
  .pnav:not(.pnav--js) .pnav__barra,
  .pnav:not(.pnav--js) .pnav__itens,
  .pnav:not(.pnav--js) .pnav__lista {
    flex-wrap: wrap;
  }

  .pnav:not(.pnav--js) .pnav__itens {
    justify-content: flex-start;
  }

  .pnav__marca-logo {
    height: 1.5rem;
  }
}

/* O bloco `@media (min-width: 992px)` que existia aqui forçava
   `.pnav__itens { display: flex }` no desktop, para o estado fechado do celular
   não vazar para telas largas. Ele saiu porque agora atrapalha: em tela larga
   que não comporta a lista, é justamente o estado recolhido que precisa valer,
   e essa regra o venceria por especificidade de media query. O que ela
   protegia passou a ser garantido na origem, porque `pnav--compacta` só existe
   quando a medição diz que falta espaço. */

/* Duas regras que precisam de `@media` e por isso vivem aqui embaixo, longe da
   propriedade que ajustam: no topo elas passariam na frente do `.pnav--compacta`
   e derrubariam o AC-085. A razão está na NOTA DE POSIÇÃO, mais adiante.

   O vermelho do Sair, gastado apenas em ponteiro fino: no toque o `:hover`
   dispara sozinho ao encostar, e o aviso perderia o sentido. */
@media (hover: hover) and (pointer: fine) {
  .pnav__sair:hover {
    color: #ff8f8f;
    background: rgba(255, 90, 90, 0.14);
  }
}

/* E na tela estreita a barra é só marca, usuário e o botão do menu: o nome cede
   mais, senão empurra o botão para fora. */
@media (max-width: 575.98px) {
  .pnav__usuario-nome {
    max-width: 7rem;
  }
}

/* Movimento é enfeite: quem pediu menos movimento não perde informação nenhuma
   ao perder as transições. O pulso da marca saiu junto com o texto estilizado —
   o SVG não anima. */
@media (prefers-reduced-motion: reduce) {
  .pnav__link,
  .pnav__sair {
    transition: none;
  }

  .pnav__link:hover,
  .pnav__sair:hover {
    transform: none;
  }
}


/* NOTA DE POSIÇÃO: este bloco vive no FIM do arquivo de propósito.
   `test_navbar_contrato.py::test_o_estado_recolhido_vale_por_classe_e_nao_por_largura_fixa`
   (AC-085) exige que `.pnav--compacta` apareça antes da primeira `@media` da
   folha, para garantir que o estado recolhido não volte a depender de largura
   fixa. O opt-out de movimento reduzido aqui é uma `@media`, e no topo ela
   passaria na frente e derrubaria a guarda sem violar a intenção dela. */

/* ============================================================
   TRAVESSIA ENTRE TELAS
   ============================================================
   Vive aqui porque `navbar.css` é a única folha que as TRÊS superfícies
   carregam: site público, painel do gestor e painel admin. O site já usava
   `@view-transition` pelo `site.css`; os painéis usavam um truque de
   JavaScript no `main.js` que interceptava todo clique em link interno,
   segurava 140 ms e só então navegava. Os 140 ms compravam `opacity:.94`,
   `translateY(4px)` e `blur(.2px)` — praticamente invisível. Custo real,
   benefício nenhum.

   Aqui quem faz é o navegador. Sem atraso, sem interceptar clique, e onde
   não houver suporte o link simplesmente navega, que já é melhor do que
   esperar 140 ms por um fade de 6%.

   `ease-out` e não `ease`: quem entra e quem sai pede curva que começa
   rápido. `ease` é `ease-in-out` disfarçado e segura o começo do movimento,
   justo no instante em que se está olhando. */
@view-transition{
  navigation: auto;
}
::view-transition-old(root){
  animation-duration:.22s;
  animation-timing-function:cubic-bezier(.2,.6,.2,1);
}
::view-transition-new(root){
  animation-duration:.22s;
  animation-timing-function:cubic-bezier(.2,.6,.2,1);
}

/* A barra é a mesma nas três superfícies e continua sendo a mesma entre uma
   tela e outra. Nomeada, ela ATRAVESSA a travessia em vez de piscar junto
   com o conteúdo. O nome precisa ser único no documento, e só existe uma
   navbar por página. */
.pnav{
  view-transition-name: navbar-do-site;
}

@media (prefers-reduced-motion: reduce){
  @view-transition{
    navigation: none;
  }
}

