/* ══════════════════════════════════════════════════════════════════════════════
   comum.css — Componentes que as duas superfícies compartilham
   ──────────────────────────────────────────────────────────────────────────────
   O sistema tem duas folhas de componente: style.css (console, que é operado) e
   documento.css (painel, dossiê e laudos, que são lidos e impressos). Elas são
   separadas de propósito — colidem em .card, .badge e body.

   Três componentes, porém, precisam existir nas duas: o cabeçalho, o diálogo e
   o painel de sessão expirada. Enquanto não havia esta folha, o painel de
   sessão estava escrito duas vezes, uma em cada lugar, e os dois já começavam a
   divergir: o véu era var(--surface-trans) numa e um rgba literal na outra.
   Duas definições do mesmo componente um dia discordam — foi exatamente por
   isso que as cinco declarações de variável concorrentes viraram tokens.css.

   Ordem de carregamento, em todo template:

     <link rel="stylesheet" href="/static/css/tokens.css">
     <link rel="stylesheet" href="/static/css/comum.css">
     <link rel="stylesheet" href="/static/css/style.css">   ← ou documento.css

   Toda cor vem de tokens.css. Nenhum literal aqui.
   ══════════════════════════════════════════════════════════════════════════════ */

/* ══════════════════════════════════════════════════════════════════════════════
   SÓ PARA O LEITOR DE TELA
   ──────────────────────────────────────────────────────────────────────────────
   Texto que existe na árvore de acessibilidade e não ocupa espaço na página.

   Serve para o que a tela já diz por outros meios a quem enxerga, e não diz a
   quem não enxerga: o nome da tela no console, onde a marca do cabeçalho é um
   link e não um título; e o rótulo de uma área que só se distingue pela
   posição.

   Não use `display: none` nem `visibility: hidden` para isso — os dois tiram o
   elemento da árvore de acessibilidade também, e aí o texto não existe para
   ninguém. O recorte de 1px é o único jeito que continua sendo lido.

   `white-space: nowrap` está aqui porque sem ele o texto quebra dentro do
   quadro de 1px e alguns leitores de tela o anunciam letra a letra.
   ══════════════════════════════════════════════════════════════════════════════ */

/* ══════════════════════════════════════════════════════════════════════════════
   O ATRIBUTO `hidden` PRECISA ESCONDER
   ──────────────────────────────────────────────────────────────────────────────
   O navegador implementa `hidden` como `[hidden] { display: none }` na folha
   dele, que é a de menor precedência: qualquer `display` declarado numa regra
   de componente ganha, e o elemento continua na tela com o atributo posto.

   Não é hipótese. `#header-btn-caso` nasce com `hidden` no console e só recebe
   `href` quando a URL traz `?case=`. Como `.topo-btn` declara `display: flex`,
   ele aparecia mesmo assim — 129px de botão, com `href` nulo, levando a lugar
   nenhum em toda abertura do console sem caso na URL. O mesmo valia para o
   bloco da conta, que nasce oculto até o servidor responder.

   O `!important` é o que faz a regra valer contra o `display` do componente,
   que é justamente quem ela precisa vencer. Vale globalmente porque `hidden`
   significa a mesma coisa em toda parte, e quatro regras `[hidden]` por classe
   — que era o que havia — deixam de fora a quinta classe que alguém escrever.
   ══════════════════════════════════════════════════════════════════════════════ */

[hidden] { display: none !important; }

.so-leitor {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ══════════════════════════════════════════════════════════════════════════════
   PULAR PARA O CONTEÚDO
   ──────────────────────────────────────────────────────────────────────────────
   Primeiro elemento focável de toda tela. Fica fora da vista até receber foco,
   e então aparece no canto superior esquerdo.

   Existe porque o cabeçalho montado por cabecalho.js tem entre seis e nove
   controles — voltar, console, os destinos do perfil, o seletor de organização,
   o tema e o sair —, e sem este link quem navega por teclado atravessa todos
   eles em cada tela, a cada visita. Numa tela de leitura como o dossiê isso é
   incômodo; no painel do caso, onde se alterna entre a tabela e o formulário de
   convite, é o que faz a pessoa desistir do teclado.

   Não usa .so-leitor: precisa ser invisível *e* voltar a ocupar espaço quando
   focado, e o recorte de 1px não volta atrás. -100px acima do topo resolve as
   duas coisas.
   ══════════════════════════════════════════════════════════════════════════════ */

.pular-para-conteudo {
  position: absolute;
  top: -100px;
  left: var(--esp-3);
  z-index: var(--z-sessao);
  padding: var(--esp-2) var(--esp-4);
  border-radius: var(--radius-sm);
  background: var(--color-primary);
  color: var(--hero-text);
  font-family: var(--fonte-marca);
  font-size: var(--texto-corpo);
  font-weight: 700;
  text-decoration: none;
  transition: top 0.15s ease;
}
.pular-para-conteudo:focus {
  top: var(--esp-3);
}

/* Região que o JS repinta sozinha. Não tem aparência própria: existe para que
   o `aria-live` fique num lugar previsível do markup, e para que se possa
   procurar por ela. */
.regiao-viva {
  display: contents;
}

/* ══════════════════════════════════════════════════════════════════════════════
   CABEÇALHO
   ──────────────────────────────────────────────────────────────────────────────
   Montado por cabecalho.js dentro de <header id="topo-mno" class="topo">.
   Antes, só o console tinha cabeçalho: o painel, o dossiê e os três laudos
   abrem em aba nova e terminavam sem caminho de volta, sem alternador de tema e
   sem sair — quem chegasse ali por um link só saía digitando URL.

   Duas linhas, e a divisão é declarada, não deixada ao flex-wrap: em cima quem
   sou e onde estou; embaixo o que faço. Com a barra de abas na própria linha,
   as cinco abas do console cabem inteiras bem abaixo de 1280px, e a rolagem
   horizontal volta a ser exceção em vez de regra.
   ══════════════════════════════════════════════════════════════════════════════ */

.topo {
  position: sticky;
  top: 0;
  z-index: var(--z-cabecalho);
  background: var(--surface-trans);
  backdrop-filter: blur(16px);
  border-bottom: 1px solid var(--card-border);
}

/* O recuo lateral acompanha o dos contêineres de conteúdo — .app-container no
   console e .container nos documentos, ambos 20px e 14px no telefone. A marca
   é o ponto fixo que o olho usa para se situar; desalinhada do texto abaixo,
   a tela parece de outro sistema. */
/* A faixa acompanha a largura da folha de cada superfície. O padrão é a do
   console; quem tem folha mais estreita declara a própria largura — é o caso
   dos documentos, em documento.css. Com uma largura fixa para todos, a marca
   do laudo pré-matriz ficava 120px à esquerda do próprio texto, e a página
   parecia de outro sistema. */
.topo-linha {
  max-width: var(--topo-largura, 1280px);
  margin: 0 auto;
  padding: 10px 20px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  /* A fila de ações desce para uma segunda faixa quando não cabe, em vez de
     comprimir a marca. Sem isto, o admin numa tela de laudo — nove itens, e a
     faixa mais estreita do sistema (900px) — espremia "SISTEMA MYELINFY MNO"
     até a caixa ter a largura de uma letra, e o nome quebrava em vertical,
     um caractere por linha. */
  flex-wrap: wrap;
}

/* Fio entre as duas linhas: sem ele a marca e as abas leem como um bloco só. */
.topo-linha + .topo-linha {
  border-top: 1px solid var(--card-border);
}

/* ── Linha 1: marca e conta ── */

/* A marca é o ponto fixo que o olho usa para se situar; ela não cede espaço.
   Quem cede é `.topo-acoes`, logo abaixo — o contrário do que era, e a inversão
   era o defeito: a marca tinha `min-width: 0` e encolhia até zero enquanto as
   ações tinham `flex-shrink: 0` e nunca encolhiam. */
.topo-marca {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-shrink: 0;
  text-decoration: none;
  color: var(--text-main);
  border-radius: var(--radius-sm);
}
.topo-sigla {
  flex-shrink: 0;
  width: 38px;
  height: 38px;
  border-radius: 10px;
  background: linear-gradient(135deg, var(--hero-from), var(--color-primary));
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--hero-text);
  font-family: 'Outfit', sans-serif;
  font-weight: 800;
  font-size: 18px;
  box-shadow: var(--shadow-sm);
}
.topo-nome {
  display: flex;
  flex-direction: column;
  min-width: 0;
  /* Teto para o subtítulo, que é o nome da tela e pode ser longo ("Laudo
     executivo do caso MYF-CASE-001"). Sem ele, a marca — que agora não encolhe
     — ficaria tão larga quanto o texto mais comprido que passasse por ali. */
  max-width: 32ch;
}
.topo-nome strong {
  font-family: 'Outfit', sans-serif;
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.15;
  color: var(--text-strong);
  /* O nome do sistema é uma unidade: ou cabe inteiro, ou a faixa quebra. Ele
     nunca se parte no meio. */
  white-space: nowrap;
}
.topo-nome span {
  font-size: 11px;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.topo-acoes {
  display: flex;
  align-items: center;
  gap: 10px;
  /* Cede espaço e quebra internamente antes de a faixa inteira quebrar. */
  flex: 1 1 auto;
  min-width: 0;
  flex-wrap: wrap;
  justify-content: flex-end;
}

.topo-btn {
  background: var(--card-bg);
  border: 1px solid var(--card-border);
  color: var(--text-main);
  padding: 8px 12px;
  border-radius: 10px;
  font-family: 'Outfit', sans-serif;
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1.2;
  cursor: pointer;
  transition: var(--transition);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
  text-decoration: none;
}
.topo-btn:hover {
  border-color: var(--color-primary);
  color: var(--color-primary);
}
.topo-btn-sair:hover {
  border-color: var(--color-danger);
  color: var(--color-danger);
}

/* ── Navegação por perfil e identidade ──
   Preenchidas por cabecalho.js a partir de `/api/auth/estado`. Nascem `hidden`
   e só aparecem quando o servidor diz que há o que mostrar: um cabeçalho que
   abre com espaços vazios e depois se preenche pula na tela. */
.topo-perfil {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}

/* O destino atual é o único item preenchido: quem está numa área não precisa
   de um botão que a ofereça, precisa saber que já chegou. */
.topo-btn-atual {
  background: var(--tone-accent-bg);
  border-color: var(--color-primary);
  color: var(--tone-accent-fg);
}
.topo-btn-atual:hover {
  color: var(--tone-accent-fg);
}

/* ── Onde estou: organização ativa, à esquerda, colada na marca ──────────────
   O seletor já esteve à direita, no meio dos botões. Ele responde "onde estou",
   e não "para onde vou" — e um campo de formulário entre botões de navegação
   era o elemento visualmente mais pesado do cabeçalho, disputando a primeira
   leitura com a marca. Junto da marca ele lê como parte da resposta "que
   sistema é este, e de quem é o dado que estou vendo", que é a pergunta que a
   regra da casa manda responder em toda tela autenticada. */
.topo-onde {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  /* A linha é `space-between` com dois filhos. Com três, o do meio flutuaria;
     o `auto` aqui devolve marca e organização à esquerda e empurra as ações
     para a direita, sem que a linha precise saber quantos filhos tem. */
  margin-right: auto;
  padding-left: 12px;
  border-left: 1px solid var(--card-border);
}

.topo-org-fixa {
  font-size: 12px;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 22ch;
}

.topo-org {
  background: var(--input-bg);
  border: 1px solid var(--card-border);
  color: var(--input-color);
  border-radius: 9px;
  padding: 6px 9px;
  font-family: 'Inter', sans-serif;
  font-size: 12px;
  max-width: 26ch;
  cursor: pointer;
}
.topo-org:hover { border-color: var(--color-primary); }

/* ══════════════════════════════════════════════════════════════════════════════
   MENU DE CONTA
   ──────────────────────────────────────────────────────────────────────────────
   Um avatar com as iniciais, e atrás dele o que diz respeito à própria conta:
   quem sou, em que papel e organização, minha conta, tema e sair.

   Existe porque a barra tinha os cinco itens abertos, lado a lado com a
   navegação. Medido com a conta de administração — cinco destinos e 276
   organizações —, o cabeçalho chegava a dez controles, quebrava em duas linhas
   já aos 791px de largura e ficava com 143px de altura. E a degradação para
   tela estreita piorava em vez de melhorar: abaixo de 560px o rótulo de cada
   botão some (regra mais abaixo) e sobrava uma fileira de emoji sem texto —
   🗂 👥 📊 ⚙ 🔑 🌤 🔓 —, sete alvos que só quem já sabia o que eram conseguia
   distinguir. O `aria-label` salvava quem usa leitor de tela e não salvava
   ninguém que enxerga.

   Agora a navegação some abaixo de 640px e reaparece DENTRO do menu, e o avatar
   cresce para 44px. Nada vira ícone mudo: some com um lugar para reaparecer.

   Duas perguntas, dois lugares: `nav-perfil` é "para onde vou", este bloco é "o
   que faço com a minha conta". Enquanto estavam na mesma fila, procurar "Sair"
   e procurar "Painel" era a mesma busca visual.
   ══════════════════════════════════════════════════════════════════════════════ */

.conta-bloco {
  position: relative;
  display: inline-flex;
}

.conta-avatar {
  width: 36px;
  height: 36px;
  padding: 0;
  border-radius: 50%;
  cursor: pointer;
  border: 1px solid var(--card-border);
  background: var(--tone-accent-bg);
  color: var(--tone-accent-fg);
  font-family: var(--fonte-marca);
  font-size: var(--texto-mini);
  font-weight: 700;
  letter-spacing: .02em;
}
.conta-avatar:hover { border-color: var(--color-primary); }

/* ── O painel, compartilhado pelos dois menus ──
   O cabeçalho tem dois menus suspensos: Gestão, que guarda os destinos, e a
   conta. Eles são o mesmo componente — mesma moldura, mesma sombra, mesma
   linha de item — e por isso a aparência mora aqui, uma vez só. Escrever o
   segundo painel copiando o primeiro é o começo da divergência que este
   sistema já pagou cinco vezes, uma por declaração de variáveis concorrente —
   as que viraram tokens.css. O que muda entre os dois menus é de onde o painel
   se ancora e o que entra dentro. */
.menu-suspenso {
  position: absolute;
  top: calc(100% + 9px);
  min-width: 232px;
  z-index: var(--z-cabecalho);
  padding: 6px;
  border: 1px solid var(--card-border);
  border-radius: var(--radius-md);
  background: var(--surface-solid);
  box-shadow: var(--shadow-md);
}

.menu-suspenso button,
.menu-suspenso a {
  display: flex;
  width: 100%;
  align-items: center;
  gap: 9px;
  padding: 9px 11px;
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--text-body);
  font-family: var(--fonte-texto);
  font-size: var(--texto-corpo);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}
.menu-suspenso button:hover,
.menu-suspenso a:hover {
  background: var(--realce-sutil);
  color: var(--text-strong);
}
/* O destino atual não vira item clicável do menu — ele sai da lista. Esta
   regra é para quando ele estiver lá assim mesmo, marcado com aria-current. */
.menu-suspenso [aria-current="page"] {
  color: var(--tone-accent-fg);
  font-weight: 600;
}

/* ── Menu de Gestão: os destinos, atrás de um botão só ──
   Os destinos eram um botão cada, abertos na barra. Para a conta de
   administração isso dava quatro botões seguidos, e a barra virava uma fila
   de coisas do mesmo peso visual onde nada se destacava.

   Agora são um item de menu cada, atrás de "Gestão". O que se perde é um
   clique; o que se ganha é que a barra passa a ter três coisas — onde estou,
   para onde vou, quem sou — em vez de sete.

   Ancorado à esquerda, e não à direita como o da conta, porque o botão dele
   fica no meio da barra: alinhado à direita, o painel escaparia da tela em
   janela estreita. */
.menu-gestao-bloco {
  position: relative;
  display: inline-flex;
}
.menu-gestao { left: 0; }

/* A seta é o que diz que o botão abre alguma coisa em vez de levar a algum
   lugar — sem ela, "Gestão" lê como mais um destino da barra. */
.menu-gestao-seta {
  /* `inline-block` porque `transform` não se aplica a elemento inline não
     substituído. */
  display: inline-block;
  font-size: 9px;
  opacity: .7;
}
/* Sem `transition` aqui, de propósito. Com ela, a rotação não chegava a
   acontecer: a regra casava, o atributo mudava e o valor computado ficava
   parado na identidade. Uma animação de 150ms num glifo de 9px não paga o
   preço de um comportamento que não se consegue verificar. */
[aria-expanded="true"] .menu-gestao-seta { transform: rotate(180deg); }

/* ── Menu da conta ── */
.conta-menu { right: 0; }

.conta-menu-topo {
  padding: 9px 11px 11px;
  margin-bottom: 5px;
  border-bottom: 1px solid var(--card-border);
}
.conta-menu-nome {
  font-family: var(--fonte-marca);
  font-size: 13.5px;
  font-weight: 700;
  color: var(--text-strong);
}
/* Papel e organização na mesma linha: "titular · Meridiano Log". É a resposta
   curta de "quem sou eu aqui", e ela precisa caber sem empurrar o menu. */
.conta-menu-onde {
  font-size: var(--texto-rotulo);
  color: var(--text-muted);
  margin-top: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Sair é o único item do menu que encerra alguma coisa. Vermelho aqui não é
   alarme: é o que impede o clique distraído em cima de "Tema claro". */
.conta-menu .conta-sair { color: var(--color-danger); }
.conta-menu .conta-sair:hover { background: var(--tone-danger-bg); }

/* Separador entre a navegação e a conta. Só entra quando há o que separar —
   na área de quem apenas responde, o cabeçalho é a marca e o avatar. */
.cabecalho-sep {
  width: 1px;
  height: 24px;
  flex: none;
  background: var(--card-border);
}

/* Âmbar, e não vermelho: simular papel não é erro nem perigo, é um estado que
   precisa ser notado. Vermelho aqui ensinaria a ignorar o vermelho. */
.topo-simulando {
  background: var(--tone-warning-bg);
  border: 1px solid var(--color-warning);
  color: var(--tone-warning-fg);
  border-radius: 999px;
  padding: 5px 11px;
  font-family: 'Outfit', sans-serif;
  font-size: 11.5px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}
.topo-simulando:hover {
  background: var(--color-warning);
  color: var(--surface-solid);
}

/* ── Linha 2: as abas e a ação de contexto ── */
/*
   A ação de contexto cede a linha antes das abas. Com os dois lado a lado e
   sem quebra, as cinco abas só cabiam inteiras acima de 1204px — pouco abaixo
   dos 1280px que esta fase queria destravar. Deixando a ação descer sozinha
   quando aperta, as abas ficam com a linha inteira e a rolagem horizontal só
   volta abaixo de 1062px. Medido no console real:

     ≥ 1204px   abas e ação na mesma linha, nada rola
     1204–1062  a ação desce, as cinco abas continuam inteiras
     < 1062px   a barra de abas rola em si mesma (o recurso, não a regra)

   `flex: 0 1 auto` (e não `1 1`) é o que mantém isso: sem crescer, a barra
   ocupa o tamanho natural e a ação fica encostada à direita; a quebra é
   decidida por esse tamanho natural. O `min-width: 0` só entra depois da
   quebra, para a barra poder encolher e rolar quando nem a linha toda basta.
*/
.topo-linha-abas {
  gap: 12px;
  flex-wrap: wrap;
  row-gap: 8px;
}
.topo-linha-abas > :first-child {
  flex: 0 1 auto;
  min-width: 0;
}

/* ── Estreito ── */

@media (max-width: 860px) {
  .topo-linha { padding: 9px 20px; }
  .topo-nome strong { font-size: 15px; }
  .topo-nome span { display: none; }
  .topo-acoes { gap: 6px; }
  .topo-btn { padding: 7px 10px; font-size: 12px; }
  .topo-onde { padding-left: 8px; }
}

@media (max-width: 640px) {
  .topo-linha { padding: 9px 14px; }
  .topo-org, .topo-org-fixa { max-width: 14ch; }

  /* No telefone os dois menus ganham alvo de toque maior. A navegação NÃO
     precisa mais mudar de lugar aqui: ela já está atrás do botão "Gestão", que
     é um alvo só em qualquer largura. Enquanto os destinos eram um botão cada
     na barra, esta media query os escondia e uma cópia deles aparecia dentro
     do menu de conta — duas listas do mesmo conteúdo, mantidas à mão. */
  .conta-menu,
  .menu-gestao { right: -4px; min-width: 236px; }
  .menu-gestao { right: auto; left: -4px; }
  .menu-suspenso button,
  .menu-suspenso a { padding: 12px; font-size: var(--texto-leitura); }
  .conta-avatar { width: 44px; height: 44px; font-size: var(--texto-corpo); }
  .menu-gestao-btn { min-height: 44px; }
}

@media (max-width: 560px) {
  /* Rótulo some, ícone fica. A regra continua valendo para os botões que
     sobraram na barra — Voltar e Console —, que são dois e têm ícone
     reconhecível. Os destinos do perfil não passam mais por aqui: eles saem da
     barra 80px antes, em 640px, e reaparecem escritos por extenso dentro do
     menu. Enquanto todos os sete passavam por esta regra, a tela estreita
     mostrava uma fileira de emoji e o aria-label era a única coisa que ainda
     dizia o que cada um fazia — o que resolve para quem usa leitor de tela e
     não resolve para quem enxerga. */
  .topo-btn .topo-btn-rotulo { display: none; }
  .topo-btn { padding: 8px 10px; }
  /* "Gestão" mantém o rótulo aqui, ao contrário dos outros botões da barra.
     Um ⚙ com uma seta ao lado não diz que ali estão as áreas do acesso — e
     esconder o rótulo dele desfaria justamente o que o menu veio resolver, que
     era a barra virar uma fileira de ícones sem nome. Cabe porque, com os
     destinos recolhidos, sobraram três ou quatro itens na barra em vez de
     sete. */
  .menu-gestao-btn .topo-btn-rotulo { display: inline; }
  /* A simulação continua visível de propósito, mesmo aqui: é o único item que,
     escondido, faz o administrador concluir que perdeu acesso. */
  .topo-simulando { padding: 5px 9px; font-size: 11px; }
}

/* O cabeçalho é navegação: não vai para o papel junto com o laudo. */
@media print {
  .topo { display: none !important; }
}

/* ══════════════════════════════════════════════════════════════════════════════
   DIÁLOGOS
   ──────────────────────────────────────────────────────────────────────────────
   <dialog> nativo: fechar com Esc, retenção de foco e camada superior vêm do
   navegador, sem JS. Antes eram <div> posicionados só com atributos style, com
   véu preto fixo que ignorava o tema.

   As variantes .dialogo-aviso são montadas por dialogo.js e substituem as
   caixas do navegador, que não têm tema, não têm estilo, travam a aba inteira
   e — no caso da caixa de pergunta — faziam a pessoa reescrever a palavra de
   uma célula da Matriz num campo do sistema operacional, no meio de um fluxo
   de 36 células.
   ══════════════════════════════════════════════════════════════════════════════ */

.dialogo {
  /* O `margin: auto` é o que centra o <dialog>, e precisa estar escrito aqui.
     As duas folhas de componente abrem com `* { margin: 0 }`, que é regra de
     autor e por isso vence a folha do navegador: sem esta linha, todo diálogo
     do sistema encostava no canto superior esquerdo da tela, com o `left: 0` e
     o `right: 0` herdados e nenhuma margem para distribuir. */
  margin: auto;
  border: none;
  padding: 0;
  background: transparent;
  max-width: min(500px, calc(100vw - 32px));
  width: 100%;
  color: var(--text-main);
  overflow: visible;
}
.dialogo::backdrop {
  background: var(--surface-trans);
  backdrop-filter: blur(6px);
}
.dialogo-corpo {
  background: var(--surface-solid);
  border: 1px solid var(--card-border);
  border-radius: var(--radius-lg);
  padding: 28px;
  box-shadow: var(--shadow-lg);
  max-height: calc(100vh - 48px);
  overflow-y: auto;
}
.dialogo-largo { max-width: 520px; }

.dialogo-titulo {
  margin: 0 0 18px;
  color: var(--text-strong);
  font-family: 'Outfit', sans-serif;
  font-size: 18px;
  font-weight: 700;
}
.dialogo-rotulo {
  display: block;
  font-size: 12.5px;
  margin-bottom: 6px;
  font-weight: 600;
  color: var(--text-muted);
}
.dialogo-campo {
  width: 100%;
  padding: 10px 14px;
  border-radius: var(--radius-sm);
  background: var(--input-bg);
  color: var(--input-color);
  border: 1px solid var(--input-border);
  font-family: inherit;
  font-size: 14px;
}
.dialogo-campo:focus {
  outline: none;
  border-color: var(--input-focus-border);
  box-shadow: 0 0 0 3px var(--color-primary-glow);
}
.dialogo-acoes {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 22px;
  flex-wrap: wrap;
}
.dialogo-fechar {
  background: none;
  border: none;
  color: var(--text-muted);
  font-size: 20px;
  line-height: 1;
  padding: 4px 6px;
  cursor: pointer;
  border-radius: var(--radius-sm);
}
.dialogo-fechar:hover { color: var(--text-main); background: var(--tone-accent-bg); }

/* ── Aviso, confirmação e pergunta ── */

.dialogo-aviso .dialogo-corpo {
  border-left: 3px solid var(--color-primary);
}
.dialogo-aviso.tom-erro .dialogo-corpo { border-left-color: var(--color-danger); }
.dialogo-aviso.tom-alerta .dialogo-corpo { border-left-color: var(--color-warning); }
.dialogo-aviso.tom-sucesso .dialogo-corpo { border-left-color: var(--color-success); }

.dialogo-aviso .dialogo-titulo { margin-bottom: 10px; }

/* pre-line: as mensagens herdadas trazem quebra de linha própria — o texto da
   autorização que faltou marcar vem numa linha separada da instrução. */
.dialogo-mensagem {
  margin: 0;
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--text-body);
  white-space: pre-line;
}
.dialogo-aviso .dialogo-rotulo { margin-top: 18px; }

@media (max-width: 640px) {
  .dialogo-corpo { padding: 22px 18px; }
  .dialogo-acoes { flex-direction: column-reverse; }
  .dialogo-acoes .btn { width: 100%; justify-content: center; }
}

/* ══════════════════════════════════════════════════════════════════════════════
   PAINEL DE SESSÃO EXPIRADA
   ──────────────────────────────────────────────────────────────────────────────
   Montado por sessao.js quando alguma chamada devolve 401. Fica por cima de
   tudo, mas não apaga a tela: o que estava sendo digitado continua legível
   atrás, para dar chance de copiar antes de entrar de novo.
   ══════════════════════════════════════════════════════════════════════════════ */

.sessao-fundo {
  position: fixed;
  inset: 0;
  z-index: var(--z-sessao);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: var(--surface-trans);
  backdrop-filter: blur(6px);
}
.sessao-caixa {
  background: var(--surface-solid);
  border: 1px solid var(--card-border);
  border-left: 3px solid var(--color-warning);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: 28px;
  max-width: min(460px, calc(100vw - 40px));
}
.sessao-caixa h2 {
  font-family: 'Outfit', sans-serif;
  font-size: 19px;
  font-weight: 700;
  color: var(--text-strong);
  margin-bottom: 10px;
}
.sessao-caixa p {
  font-size: 14.5px;
  color: var(--text-body);
  line-height: 1.6;
  margin-bottom: 22px;
}
.sessao-acoes {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  flex-wrap: wrap;
}
@media (max-width: 640px) {
  .sessao-acoes { flex-direction: column-reverse; }
  .sessao-acoes .btn { width: 100%; justify-content: center; }
}

/* Foco sempre visível nos três componentes, sem depender da lista de seletores
   que cada folha mantém por conta própria. */
.topo :focus-visible,
.dialogo :focus-visible,
.sessao-fundo :focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

/* ══════════════════════════════════════════════════════════════════════════════
   ADMINISTRAÇÃO DA PLATAFORMA
   ──────────────────────────────────────────────────────────────────────────────
   Roxo, e não o azul das demais telas. A cor tem significado neste sistema:
   azul é o caminho normal dentro de uma organização, e /admin é a única tela
   que está acima de todas elas. Num sistema multi-cliente, confundir "estou
   dentro do inquilino" com "estou acima dele" é o tipo de engano que termina
   com o dossiê de uma empresa aberto sob o nome de outra — então a diferença
   ganha cor, e não só um título.
   ══════════════════════════════════════════════════════════════════════════════ */

/* Os dois nomes de classe são deliberados, e não redundância: comum.css carrega
   ANTES de documento.css e style.css, então uma regra de classe única aqui
   perde para `.brand-badge` e `.badge` de lá — mesma especificidade, e vence
   quem vem depois. O selo saía branco sobre transparente nos dois temas, que é
   o modo silencioso de falhar que este projeto já conhece. Nomear o que se
   sobrepõe deixa a intenção escrita em vez de dependente da ordem. */
.badge.selo-plataforma,
.brand-badge.selo-plataforma {
  background: var(--tone-plataforma-bg);
  color: var(--tone-plataforma-fg);
  border: 1px solid var(--tone-plataforma-borda);
}

/* ── Abas ────────────────────────────────────────────────────────────────────
   Uma implementação, duas cores. A forma (a fileira, o botão, o painel que
   some) é a mesma em toda tela com abas; só a cor do selecionado muda, porque
   neste sistema cor é significado e não decoração: azul é o caminho normal,
   roxo é a plataforma acima das organizações. O `/admin` acrescenta
   `.abas-admin` sobre a base e ganha o roxo; qualquer outra tela usa só a base
   e fica azul.

   A base nasceu do `/admin`, onde era `.abas-admin` e mais nada. Generalizá-la
   no dia em que a segunda tela precisou de abas foi mais barato que a
   alternativa de sempre: um segundo conjunto de classes com a mesma forma e
   uma diferença de 1px que ninguém consegue explicar depois. */
.abas {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin: 18px 0 8px;
}

.aba-btn {
  background: var(--card-bg);
  border: 1px solid var(--card-border);
  color: var(--text-main);
  font-family: 'Outfit', sans-serif;
  font-size: 13px;
  font-weight: 600;
  padding: 8px 14px;
  border-radius: 10px;
  cursor: pointer;
  transition: var(--transition);
}
.aba-btn:hover { border-color: var(--color-primary); }
.aba-btn[aria-selected="true"] {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: var(--hero-text);
}

.aba-btn-admin:hover { border-color: var(--color-purple); }
.aba-btn-admin[aria-selected="true"] {
  background: var(--color-purple);
  border-color: var(--color-purple);
  color: var(--sobre-roxo);
}

/* Abas escondidas, e não desabilitadas: o painel que não está em foco sai da
   árvore visual inteira, em vez de ficar cinza atrás do que está. */
.aba { display: none; }
.aba.ativa { display: block; }

/* Assentos e piso, editáveis dentro da tabela de organizações. Estreito de
   propósito: são números de dois dígitos, e um campo de largura total
   empurraria as demais colunas para fora da tela. */
.campo-contrato {
  width: 5.5em;
  padding: 5px 8px;
  border: 1px solid var(--input-border);
  background: var(--input-bg);
  color: var(--input-color);
  border-radius: var(--radius-sm);
  font-family: inherit;
  font-size: 12.5px;
  font-variant-numeric: tabular-nums;
}
.campo-contrato:focus {
  outline: none;
  border-color: var(--input-focus-border);
  box-shadow: 0 0 0 3px var(--color-primary-glow);
}

/* Prompt, resposta e erro do provedor, no diagnóstico de uma chamada de IA.
   Rolagem própria porque um prompt de M·04 tem milhares de caracteres, e sem
   teto o diálogo cresce até passar da tela. */
.bloco-diagnostico {
  margin-top: 6px;
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--input-border);
  background: var(--input-bg);
  color: var(--text-main);
  font-family: 'Consolas', 'Courier New', monospace;
  font-size: 12px;
  line-height: 1.55;
  max-height: 240px;
  overflow: auto;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* ══════════════════════════════════════════════════════════════════════════════
   BANNER DE SIMULAÇÃO DE PAPEL
   ──────────────────────────────────────────────────────────────────────────────
   Fixo no topo, e não um selo discreto no cabeçalho. Um administrador que
   esquece a simulação ligada conclui que perdeu acesso — e passa a investigar um
   defeito que não existe. O banner é a única coisa do sistema que se impõe
   assim, e é porque ele descreve um estado em que TODAS as demais telas mentem
   sobre o que a pessoa pode.

   Não usa `position: fixed` de propósito: no topo do fluxo ele empurra a página
   para baixo, o que é exatamente o efeito desejado — a tela inteira fica
   deslocada enquanto a simulação durar, e isso é mais um lembrete.
   ══════════════════════════════════════════════════════════════════════════════ */
.banner-simulacao {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  flex-wrap: wrap;
  padding: 10px 18px;
  background: var(--tone-plataforma-bg);
  border-bottom: 1px solid var(--tone-plataforma-borda);
  color: var(--tone-plataforma-fg);
  font-family: 'Outfit', system-ui, sans-serif;
  font-size: 13px;
  font-weight: 600;
  text-align: center;
}
.banner-simulacao strong { color: var(--tone-plataforma-fg); }
.banner-simulacao button {
  padding: 5px 12px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--tone-plataforma-borda);
  background: transparent;
  color: var(--tone-plataforma-fg);
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
}
.banner-simulacao button:hover { border-color: var(--color-purple); }
.banner-simulacao button:focus-visible {
  outline: 2px solid var(--color-purple);
  outline-offset: 2px;
}

/* ══════════════════════════════════════════════════════════════════════════════
   PASTA DA ORGANIZAÇÃO — ÁRVORE E LEITOR
   ──────────────────────────────────────────────────────────────────────────────
   Quarto componente das duas superfícies, e ele chegou aqui pelo mesmo motivo
   dos três primeiros: passou a existir em duas telas. A Pasta vivia só na aba de
   Organizações do console; com a aba restrita ao administrador de plataforma, o
   operador — que é quem de fato lê os laudos do caso — ficaria sem ela. Ela
   agora também abre no painel do caso, que é onde ele trabalha.

   A marcação inteira é montada por `static/js/pasta.js`, em DOM. Nenhuma classe
   daqui aparece escrita num template, e é por isso que elas estão na lista de
   classes críticas de `testes/t_integridade_frontend.py`: sem regra, o JS segue
   funcionando e a árvore sai como texto empilhado.
   ══════════════════════════════════════════════════════════════════════════════ */

/* "Consultando o banco…" e a falha de consulta. Eram <p> com `style=` escrito
   dentro do JavaScript, e por isso saíam com a cor do tema escuro em cima do
   papel branco do tema claro. */
.pasta-aviso {
  margin: 0;
  padding: 8px 0;
  font-size: 13px;
  color: var(--text-muted);
}
.pasta-aviso-erro { color: var(--color-danger); }

/* A faixa de exportação. Tom de atenção, e não de ação neutra: o que sai daqui
   é o material nominal inteiro, e é o único ponto da pasta em que um clique
   tira dado do sistema. O botão fica à direita do aviso, nunca antes dele. */
.aviso-exportacao {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 16px;
  padding: 12px 14px;
  border: 1px solid var(--tone-warning-fg);
  border-left-width: 3px;
  border-radius: var(--radius-md);
  background: var(--tone-warning-bg);
}

.aviso-exportacao strong {
  display: block;
  font-size: 14px;
  color: var(--text-strong);
  margin-bottom: 2px;
}

.aviso-exportacao span {
  display: block;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--text-body);
  max-width: 62ch;
}

.aviso-exportacao .btn { flex: 0 0 auto; white-space: nowrap; }

.pasta-tree-box {
  background: var(--input-bg);
  border: 1px solid var(--card-border);
  border-radius: var(--radius-md);
  padding: 16px;
  max-height: 320px;
  overflow: auto;
  font-family: 'Inter', monospace;
  font-size: 13px;
  color: var(--text-body);
}

/* ── Árvore da pasta ──
   Diretório e arquivo são <button>: antes eram <div onclick>, fora do alcance
   do teclado, e o cabeçalho de pasta tinha `cursor: pointer` sem dobrar nada. */
.pasta-dir-row,
.pasta-file-row {
  width: 100%;
  font: inherit;
  text-align: left;
  appearance: none;
  background: none;
  border: none;
}

.pasta-dir-row {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 6px;
  border-radius: 6px;
  cursor: pointer;
  color: var(--color-warning);
  font-weight: 700;
  min-width: 0;
}
.pasta-dir-row:hover { background: var(--tone-warning-bg); }
.pasta-dir-seta {
  flex-shrink: 0;
  font-size: 10px;
  width: 10px;
  color: var(--text-muted);
}
.pasta-dir-nome {
  min-width: 0;
  overflow-wrap: anywhere;
}
.pasta-dir-conta {
  flex-shrink: 0;
  margin-left: auto;
  font-size: 11px;
  font-weight: 600;
  color: var(--text-muted);
}
.pasta-dir-filhos {
  border-left: 1px dashed var(--card-border);
  margin-left: 7px;
  padding-left: 10px;
}
.pasta-vazia {
  color: var(--text-muted);
  font-size: 11px;
  padding: 2px 0;
}

.pasta-file-nome {
  flex: 1;
  min-width: 0;
  overflow-wrap: anywhere;
  color: var(--text-main);
}
.pasta-file-tamanho {
  flex-shrink: 0;
  color: var(--text-muted);
  font-size: 11px;
}
.pasta-file-selo {
  flex-shrink: 0;
  font-size: 9px;
  font-weight: 700;
  padding: 1px 5px;
  border-radius: var(--radius-full);
  letter-spacing: 0.04em;
}
.pasta-file-selo-laudo {
  background: var(--tone-accent-bg);
  color: var(--tone-accent-fg);
}
.pasta-file-selo-ia {
  background: var(--ia-bg);
  color: var(--ia-text);
}

.pasta-file-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  border-radius: 6px;
  cursor: pointer;
  transition: var(--transition);
  margin-top: 2px;
  /* Nome de arquivo é longo e vem do banco (`QA Bot_MYF-PERSON-038.json`).
     Sem poder encolher, a linha vira o piso de largura da coluna inteira. */
  min-width: 0;
}
.pasta-file-row > span { min-width: 0; overflow-wrap: anywhere; }

.pasta-file-row:hover {
  background: var(--tone-accent-bg);
  color: var(--color-primary);
}

.pasta-file-row.active {
  background: var(--tone-accent-bg);
  font-weight: 600;
  color: var(--color-primary);
}
.pasta-file-row.active .pasta-file-nome { color: var(--color-primary); }

/* Foco visível em tudo que virou botão na árvore. */
.pasta-dir-row:focus-visible,
.pasta-file-row:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

.pasta-viewer-container {
  background: var(--surface-solid);
  border: 1px solid var(--card-border);
  border-radius: var(--radius-md);
  padding: 18px;
  margin-top: 16px;
}

.pasta-viewer-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
  flex-wrap: wrap;
  gap: 10px;
  border-bottom: 1px solid var(--card-border);
  padding-bottom: 12px;
}

.pasta-viewer-code {
  background: var(--input-bg);
  border: 1px solid var(--card-border);
  border-radius: var(--radius-sm);
  padding: 16px;
  font-family: 'Consolas', 'Courier New', monospace;
  font-size: 12.5px;
  line-height: 1.6;
  max-height: 400px;
  overflow: auto;
  color: var(--text-main);
  white-space: pre-wrap;
}

.report-preview-banner {
  background: linear-gradient(135deg, var(--ia-bg), var(--tone-accent-bg));
  border: 1px solid var(--ia-border);
  border-radius: var(--radius-md);
  padding: 18px;
  margin-bottom: 16px;
}


/* ══════════════════════════════════════════════════════════════════════════════
   MOVIMENTO REDUZIDO
   ──────────────────────────────────────────────────────────────────────────────
   style.css e documento.css já têm o bloco deles, e como todo template carrega
   uma das duas, o seletor `*` de lá acabava alcançando os componentes desta
   folha também. Funcionava por cascata, não por decisão — e as duas
   formulações já divergiam: uma zera a duração, a outra remove a transição.

   O cabeçalho, o diálogo e o painel de sessão são desta folha, e é o diálogo
   que mais importa aqui: ele entra em cena com transformação, e é justamente o
   que aparece de repente no meio da leitura.
   ══════════════════════════════════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  .topo *,
  .dialogo,
  .dialogo *,
  .sessao-fundo,
  .sessao-fundo *,
  .banner-simulacao,
  .pular-para-conteudo {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
