/* Estilo base do portal.
   Cores, espacamento e tipografia num lugar so, em variaveis, para que a
   troca de tema exigida pelo item 2.7 do edital seja alteracao de valor e
   nao de codigo espalhado.

   O SISTEMA DE DESIGN (KAN-109) — as quatro regras para tela nova:

   1. COR é sempre var(--...), nunca código. O nome diz a função:
      --cor-texto / -forte / -leitura / -suave / -ajuda   (texto)
      --cor-primaria, --cor-destaque, --cor-link          (marca: o TEMA troca)
      --cor-erro / -atencao / -sucesso / -informacao (+ -fundo)
      --selo-*-fundo / --selo-*-texto                     (selos)
      --cor-superficie, --cor-fundo, --cor-borda(-forte)  (planos)
      --cor-sobre-primaria                                (texto em cima da marca)
      --sombra-cartao / -cartao-realce / -flutuante / -janela
      --veu-da-janela, --veu-sobre-foto                   (escurecidos)
      --contraste-*                                       (modo alto contraste)
   2. LETRA e ESPAÇO saem da escala: --texto-mini … --texto-manchete e
      --espaco-1 (4px) … --espaco-6 (32px). As telas antigas migram quando
      forem mexidas.
   3. UM SELETOR, UMA REGRA. Quem precisa mudar um componente muda a regra
      dele, não escreve outra igual mais abaixo.
   4. O TEMA DA PREFEITURA manda na marca: nunca escreva a cor de uma paleta
      (o verde #1d7a4c, o azul #10446f) numa regra — use a variável.

   As regras 1 e 3 são conferidas pela bateria conferir:modulo16. Os
   componentes do gerenciamento (barra do topo, barra de lista, menu Ações,
   cards de seção, janelas) estão no fim deste arquivo, cada um com o seu
   cabeçalho de comentário. */

:root {
  /* Deixa o <details> animar a altura (ver .secao-sanfona mais abaixo). */
  interpolate-size: allow-keywords;
  --cor-primaria: #10446f;
  --cor-primaria-escura: #0b304e;
  --cor-destaque: #1d7a4c;
  --cor-texto: #1f2933;
  --cor-texto-suave: #52606d;
  --cor-borda: #e2e9ee;
  --cor-erro: #a4262c;
  /* O ambar do nivel de ALERTA no relatorio de pendencias. Escuro o bastante
     para dar 5,6:1 sobre o branco — amarelo de aviso, no tom claro em que o
     olho espera ve-lo, reprova em contraste e vira letra que ninguem le. */
  --cor-atencao: #8a5a00;
  --cor-erro-fundo: #fdf3f4;
  /* Sucesso e informacao ganharam cor propria na F-10: ate entao todo recado
     do portal saia com a aparencia de erro, e "Alteracoes salvas." aparecia
     em vermelho. */
  --cor-sucesso: #1c5c31;
  --cor-sucesso-fundo: #f1f8f3;
  --cor-informacao: #10446f;
  --cor-informacao-fundo: #f3f6f8;
  --cor-fundo: #f7f8fa;
  --cor-superficie: #ffffff;
  /* Cinza para texto secundario que ainda precisa passar em 4,5:1. */
  --cor-apagado: #667085;
  /* OS OITO NIVEIS DA CARTILHA PNTP, um por cor.
     Todas escurecidas o bastante para passar em 4,5:1 sobre o branco: dourado
     e prateado como se imagina (um #d4af37, um #c0c0c0) somem no fundo claro
     e viram letra que ninguem le. Aqui eles sao a VERSAO ESCURA da mesma
     familia — o olho continua lendo "ouro" e "prata", e o texto continua
     legivel. A cor nunca anda sozinha: o desenho ao lado muda de forma. */
  --cor-nivel-diamante: #0f6e84;
  --cor-nivel-ouro: #8a6100;
  --cor-nivel-prata: #5c6670;
  --cor-nivel-elevado: #1c5c31;
  --cor-nivel-intermediario: #8a5a00;
  --cor-nivel-basico: #9a4a10;
  --cor-nivel-inicial: #a4262c;
  --cor-nivel-inexistente: #7a1c21;
  /* O SISTEMA DE DESIGN (KAN-109, 28/09): toda cor do portal é uma variável
     com o nome do que ela FAZ. Nenhuma regra abaixo escreve cor em código —
     a bateria conferir:modulo16 falha se aparecer uma. As únicas exceções,
     marcadas na própria regra, são as amostras das paletas prontas (tela
     Aparência) e a imitação do Instagram (painel de redes sociais), que
     precisam mostrar a cor de verdade de outra coisa.

     Texto. */
  --cor-texto-forte: #223;
  --cor-texto-leitura: #445;
  --cor-texto-ajuda: #667;
  /* O texto e a borda em cima da cor da marca (botão, faixa do banner,
     contador): sempre claro. */
  --cor-sobre-primaria: #ffffff;
  /* Selos e marcações: o fundo claro e o texto escuro da mesma família. */
  --selo-sucesso-fundo: #e3efe6;
  --selo-atencao-fundo: #fdf0d5;
  --selo-atencao-texto: #7a5211;
  --selo-erro-fundo: #fbe3e3;
  --selo-erro-texto: #8c2020;
  --selo-rascunho-fundo: #fdf1dd;
  --selo-rascunho-texto: #8a5a09;
  --selo-restricao-fundo: #f8e2e3;
  --cor-atencao-fundo: #fbf4e6;
  --cor-marca-texto: #fdf0c8;
  --cor-codigo-fundo: #eef1f4;
  /* Sombras, do cartão parado à janela por cima de tudo. */
  --sombra-cartao: 0 1px 2px rgba(16, 24, 40, 0.04);
  --sombra-cartao-realce: 0 4px 12px rgba(16, 24, 40, 0.08);
  --sombra-flutuante: 0 12px 32px rgba(16, 24, 40, 0.16);
  --sombra-janela: 0 20px 50px rgba(15, 23, 42, 0.25);
  /* Véus: o escurecido atrás de uma janela e por cima de foto. */
  --veu-da-janela: rgba(15, 23, 42, 0.5);
  --veu-sobre-foto: rgba(0, 0, 0, 0.72);
  --fundo-da-galeria: rgba(0, 0, 0, 0.78);
  --cor-veu-escuro: #08101c;
  --cor-video-fundo: #000000;
  /* A ESCALA DE LETRA E DE ESPAÇO (KAN-109). Tela nova usa só estes valores;
     as telas antigas migram quando forem mexidas (decisão de 28/09: não se
     reescreve o que já foi aprovado só para trocar o número pelo nome).
     Letra: */
  --texto-mini: 12px;
  --texto-pequeno: 14px;
  --texto-corpo: 1rem;
  --texto-destaque: 18px;
  --texto-titulo: 22px;
  --texto-manchete: 28px;
  /* Espaço (margem, preenchimento, vão entre itens): de 4 em 4 até 16, e
     depois 24 e 32. */
  --espaco-1: 4px;
  --espaco-2: 8px;
  --espaco-3: 12px;
  --espaco-4: 16px;
  --espaco-5: 24px;
  --espaco-6: 32px;
  /* O modo alto contraste (acessibilidade): fixo de propósito, é a promessa
     "preto, branco e amarelo" que a pessoa escolheu — o tema não mexe nele. */
  --contraste-fundo: #000000;
  --contraste-texto: #ffffff;
  --contraste-realce: #ffff00;
  /* A segunda cor de destaque dos gráficos no alto contraste (KAN-113): o
     amarelo, o branco e este ciano são as três séries — todas acima de 16:1
     sobre o preto, e distintas entre si. */
  --contraste-realce-2: #00ffff;
  /* As duas cores do anel de foco. Ver a regra :focus-visible mais abaixo. */
  --foco-interno: #ffffff;
  --foco-externo: #0b304e;
  /* Cores que o TEMA troca (KAN-24).

     ELAS EXISTEM PORQUE O TEMA NAO CHEGAVA AQUI. As telas publicas foram
     escritas com o azul digitado na mao — quatorze vezes o mesmo #10306b — e
     trocar a cor do portal deixava o cabecalho verde e os titulos das
     noticias azuis. Cor de marca digitada na mao e cor que o tema nao
     alcanca.

     Quem escreve o valor final em producao e a rota /css/tema.css, que vem
     DEPOIS deste arquivo. O que esta aqui e o padrao: o portal sem tema
     salvo, e o portal com o CSS do tema fora do ar. */

  /* A cor do link e do titulo clicavel. Era um azul proprio, #10306b, quase
     igual ao da marca mas nao igual — diferenca que ninguem enxerga e que
     obrigava a manter duas cores. Passou a ser a cor da marca. */
  --cor-link: #10446f;

  /* O texto secundario das faixas coloridas — a linha "Portal Oficial" no
     topo, o texto do rodape. O texto PRINCIPAL dessas faixas e branco e
     continua branco em qualquer tema: a conferencia de contraste da tela de
     Aparencia recusa uma cor principal em que o branco nao se leia, entao o
     branco e uma garantia e nao um chute. Este tom suave e calculado a partir
     da cor escolhida, no servidor — e nao aqui com color-mix, que navegador
     antigo nao entende e, quando nao entende uma variavel, apaga a regra
     inteira em vez de ignorar a linha. */
  --cor-sobre-primaria-suave: #cad6df;

  /* Fundo de painel levemente tingido da cor principal, e a versao um pouco
     mais forte dele. */
  --cor-realce-fundo: #f3f6f8;
  --cor-realce-fundo-forte: #e7ecf1;

  /* O cinza do espaco reservado a uma imagem que ainda nao chegou. */
  --cor-vazio: #eef2f5;

  /* Borda mais marcada que --cor-borda, para o que precisa se separar do
     fundo tingido. */
  --cor-borda-forte: #c6d2dc;

  /* OS VALORES ACIMA SAO CALCULADOS, e nao escolhidos a olho: sao exatamente
     o que src/tema/tema.js produz para a paleta Institucional. Tem que bater
     digito por digito, senao o portal fica de um jeito com o tema carregado e
     de outro sem ele — e "sem ele" acontece de verdade: no primeiro pedido
     depois de subir, e em qualquer navegador que nao alcance a rota.

     Para conferir:  node -e "..." com variaveisDoTema(PALETAS.INSTITUCIONAL)
     (a suite teste-tema.mjs faz essa conferencia sozinha). */

  /* 1160px: a medida do miolo do portal do Rio, conferida no print que a wiri
     mandou (o bloco de ladrilhos vai de 370 a 1530 numa janela de 1900). */
  --largura-maxima: 1160px;
  --raio: 8px;
}

/* A FONTE DO PORTAL — Raleway.
 *
 * POR QUE ESTA E NAO OUTRA: e a fonte de corpo do design system do gov.br,
 * entao o portal municipal fica parecido com o federal sem copiar nada.
 *
 * POR QUE NAO A RAWLINE, que o gov.br usa nos titulos: ela foi encomendada
 * pelo governo federal e nao tem licenca aberta clara para uso comercial de
 * terceiros. Este portal e LICENCIADO para prefeituras — embutir fonte de
 * licenca duvidosa num produto que se vende e risco juridico para quem
 * assinou o contrato. A Raleway e SIL Open Font License; a copia da licenca
 * vai junto, em public/fontes/LICENCA-raleway.txt, porque a OFL exige isso.
 *
 * POR QUE VEM DENTRO DO PROJETO e nao do Google Fonts:
 *   1. a politica de seguranca do portal so aceita arquivo do proprio portal;
 *   2. LGPD — fonte servida pelo Google entrega o IP de TODO cidadao que abre
 *      a pagina a uma empresa de fora, sem ninguem consentir. Num portal
 *      cujo edital tem LGPD no titulo, isso e um ponto a favor da gente.
 *
 * UM ARQUIVO SO, 48 KB, para todos os pesos: e fonte VARIAVEL. A alternativa
 * seriam quatro arquivos (leve, normal, meio-negrito, negrito) somando o
 * triplo — e portal de prefeitura se abre em celular com rede ruim.
 *
 * font-display: swap e o que garante que o TEXTO APARECE ANTES DA FONTE. Sem
 * ele o navegador esconde o texto ate a fonte chegar, e numa rede lenta a
 * pessoa olha para uma pagina em branco que ja carregou.
 */
@font-face {
  font-family: 'Raleway Variavel';
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url('/fontes/raleway-latin.woff2') format('woff2-variations');
  /* So o pedaco latino: cobre todo o portugues (acentos, cedilha, til) e
     deixa de fora cirilico e vietnamita, que ninguem aqui vai ler. */
  unicode-range:
    U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
    U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

* {
  box-sizing: border-box;
}

/*
  O tamanho de base fica no <html>, e nao no <body>.

  E o que permite ao cidadao aumentar a letra do portal INTEIRO num clique:
  todo o resto do arquivo mede em rem, que conta a partir daqui. Com o tamanho
  preso no body em pixel, como era ate esta tarefa, mudar a fonte exigiria
  mexer em cada medida do portal.

  100% e o tamanho que a pessoa escolheu na configuracao do proprio navegador,
  e nao 16px fixo. Quem ja aumentou a letra de todos os sites nao precisa
  aumentar de novo aqui.
*/
html {
  font-size: 100%;
}

html.fonte-2 {
  font-size: 115%;
}

html.fonte-3 {
  font-size: 132%;
}

/* A pagina ocupa a altura da tela no minimo, e o miolo e quem estica.
 *
 * O PROBLEMA: numa tela de conteudo curto — o painel recem-aberto, uma lista
 * vazia, a pagina de erro — o rodape ficava logo abaixo do conteudo, no meio
 * da tela, com um vazio embaixo dele. E a barra lateral, que e fixa, ia ate o
 * fim: a diferenca entre as duas alturas era o que saltava aos olhos.
 *
 * A CORRECAO: o corpo vira uma coluna de altura minima igual a da janela, e o
 * <main> recebe "flex: 1" — ou seja, ele fica com toda a sobra. Assim o rodape
 * e empurrado para baixo quando falta conteudo, e continua logo apos o
 * conteudo quando sobra. Nao e rodape "fixo": rodape fixo roubaria altura de
 * leitura em toda pagina longa, que e o contrario do que se quer.
 *
 * A barra lateral nao entra nessa conta porque e "position: fixed", e o que e
 * fixo sai do fluxo — o flex nem enxerga. */
body {
  display: flex;
  min-height: 100vh;
  flex-direction: column;
  margin: 0;
  background: var(--cor-fundo);
  color: var(--cor-texto);
  /* A pilha de reserva NAO e enfeite: ela e o que a pessoa le enquanto os
     48 KB da Raleway nao chegaram, e o que ela le para sempre se a fonte
     falhar. system-ui e a fonte que o proprio sistema ja tem carregada. */
  font-family:
    'Raleway Variavel',
    system-ui,
    -apple-system,
    'Segoe UI',
    Roboto,
    Arial,
    sans-serif;
  font-size: 1rem;
  line-height: 1.6;
}

/* O LINK SEM CLASSE usa a cor de link do tema (KAN-109). Antes não havia
 * regra para <a>, e todo link sem classe própria — o nome do registro nas
 * tabelas do gerenciamento, por exemplo — saía no azul padrão do navegador,
 * que a cor escolhida em Aparência não alcançava. */
a {
  color: var(--cor-link);
}

.container {
  width: 100%;
  max-width: var(--largura-maxima);
  margin: 0 auto;
  padding: 0 20px;
}

/* Link que aparece so quando recebe foco pelo teclado. Exigencia de
   acessibilidade: quem navega por teclado nao deve percorrer o menu inteiro
   a cada pagina. */
.pular-para-conteudo {
  position: absolute;
  left: -9999px;
  background: var(--cor-primaria);
  color: var(--cor-sobre-primaria);
  padding: 10px 16px;
}
.pular-para-conteudo:focus {
  left: 8px;
  top: 8px;
  z-index: 10;
}

/* AS DUAS ALTURAS DO TOPO saem do portal do Rio, medidas no print: a barra
   fina tem 78px e o cabeçalho tem 98px. São ALTURAS MÍNIMAS, e não fixas, de
   propósito: quem aumenta a letra pelo painel de acessibilidade precisa que a
   barra cresça junto, senão o texto sai por fora dela. Altura fixa em pixel é
   exatamente como se quebra o recurso de aumentar fonte. */
.faixa {
  background: var(--cor-primaria-escura);
  color: var(--cor-sobre-primaria-suave);
  font-size: 13px;
}
.faixa-conteudo {
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* Faixa fina (28/09): era 78px, a altura do Rio, e competia com o
     cabeçalho. Continua ALTURA MÍNIMA, não fixa, pelo motivo acima. */
  min-height: 36px;
  padding-top: 4px;
  padding-bottom: 4px;
}

.cabecalho {
  background: var(--cor-primaria);
  color: var(--cor-sobre-primaria);
}
.cabecalho-conteudo {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  align-items: center;
  justify-content: space-between;
  min-height: 98px;
  padding-top: 12px;
  padding-bottom: 12px;
}
/* A MARCA CABE NUMA COLUNA ESTREITA, e o nome quebra em duas linhas.

   No print do Rio a marca ocupa 155px, porque é uma logomarca curta. A nossa
   é o nome escrito por extenso — "Prefeitura Municipal de" mais o nome do
   município, que num nome de quatro palavras passa dos quarenta caracteres —, e
   numa linha só ela toma 419px. Com esse tamanho, marca + busca + menu não
   cabem na mesma faixa de 1120px, o menu cai para a linha de baixo e o
   cabeçalho passa de 98 para 126px: deixa de ser o topo do print.

   Então o nome quebra em duas linhas dentro de 210px. A informação continua
   inteira, o cabeçalho fecha nos 98px, e o nome do município — que é o que a
   Prefeitura quer ver ali — continua sendo a coisa maior do cabeçalho. */
.marca {
  display: flex;
  align-items: center;
  gap: 14px;
  max-width: 270px;
}
.brasao {
  width: 46px;
  height: 46px;
  border-radius: 50%;
  background: var(--cor-superficie);
  color: var(--cor-primaria);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  letter-spacing: 0.5px;
}
.marca-titulo {
  margin: 0;
  font-size: 16px;
  font-weight: 700;
  /* 1.2 para as duas linhas somadas caberem na altura do cabeçalho. Não é
     apertado demais: em 16px negrito os acentos ainda passam folgados. */
  line-height: 1.2;
}
.marca-subtitulo {
  margin: 2px 0 0;
  font-size: 13px;
  color: var(--cor-sobre-primaria-suave);
}
/* O MENU EM MAIÚSCULAS E NEGRITO, como no Rio.

   Não é enfeite: o menu do topo fica sobre a cor da marca, e texto claro sobre
   fundo colorido perde peso — em corpo normal ele parece mais apagado do que
   é. Maiúscula com negrito devolve esse peso sem precisar aumentar a letra, e
   é o que separa o menu do resto do texto do cabeçalho. */
/* O MENU DE CIMA, MEDIDO NO PORTAL DO RIO.
   Os valores abaixo nao sao gosto: sao o que o prefeitura.rio usa, lido no
   proprio site. Tres ja batiam (branco, peso 700, caixa alta); os que nao
   batiam eram o espaco entre os itens, que la e o DOBRO do que era aqui, e o
   tamanho da letra.

     la               aqui, antes        agora
     13px             14px               13px
     espaco 32px      espaco 16px        32px
     sem tracking     0,02em             sem tracking

   O ESPACO E O QUE MAIS MUDA A APARENCIA. Com 16px os itens se leem como um
   texto corrido em caixa alta, e o olho tem de separar palavra de palavra; com
   32px cada um vira um destino. Era a diferenca inteira entre o nosso topo e o
   do Rio, e ela custa 80px de largura — que cabem porque o menu tem seis
   itens, e nao sete.

   O tracking sai junto: o Rio nao usa, e com 32px de respiro entre os itens
   ele so alarga cada palavra sem separar nada. */
.menu {
  display: flex;
  flex-wrap: wrap;
  gap: 32px;
}
.menu a {
  color: var(--cor-sobre-primaria);
  text-decoration: none;
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  padding-bottom: 2px;
  border-bottom: 2px solid transparent;
}
.menu a:hover,
.menu a:focus {
  border-bottom-color: var(--cor-sobre-primaria);
}

.conteudo {
  /* Fica com toda a sobra de altura: e o que empurra o rodape para baixo em
     tela de conteudo curto. O "1 0 auto" cresce mas nao encolhe — encolher
     faria conteudo longo ser espremido. */
  flex: 1 0 auto;
  padding-top: 36px;
  padding-bottom: 56px;
}

.etiqueta {
  margin: 0 0 6px;
  text-transform: uppercase;
  letter-spacing: 1.5px;
  font-size: 12px;
  font-weight: 700;
  color: var(--cor-texto-suave);
}
.destaque h1 {
  margin: 0 0 12px;
  font-size: 34px;
  line-height: 1.2;
}
.destaque-texto {
  margin: 0;
  max-width: 62ch;
  color: var(--cor-texto-suave);
  font-size: 18px;
}

.cartoes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 16px;
  margin: 32px 0;
}
.cartao {
  background: var(--cor-superficie);
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
  padding: 18px;
}
.cartao h2 {
  margin: 0 0 6px;
  font-size: 17px;
  color: var(--cor-primaria);
}
.cartao p {
  margin: 0;
  font-size: 14px;
  color: var(--cor-texto-suave);
}

.aviso {
  background: var(--cor-superficie);
  border: 1px solid var(--cor-borda);
  border-left: 4px solid var(--cor-destaque);
  border-radius: var(--raio);
  padding: 22px;
}
.aviso h1,
.aviso h2 {
  margin: 0 0 10px;
  font-size: 20px;
}
.aviso p {
  margin: 0 0 12px;
  color: var(--cor-texto-suave);
}
.aviso-nota {
  margin: 0;
  font-size: 14px;
}
code {
  background: var(--cor-codigo-fundo);
  padding: 1px 5px;
  border-radius: 4px;
  font-size: 13px;
}

.ficha {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px;
  margin: 0 0 14px;
  padding: 0;
}
.ficha dt {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--cor-texto-suave);
}
.ficha dd {
  margin: 2px 0 0;
  font-size: 17px;
  font-weight: 600;
}

.voltar {
  color: var(--cor-primaria);
  font-weight: 600;
}

.rodape {
  background: var(--cor-primaria-escura);
  color: var(--cor-sobre-primaria-suave);
  padding: 28px 0;
  flex-shrink: 0;
}
.rodape-titulo {
  margin: 0 0 6px;
  color: var(--cor-sobre-primaria);
  font-weight: 700;
}
.rodape-texto {
  margin: 0 0 4px;
  font-size: 14px;
  max-width: 70ch;
}
.rodape-creditos {
  margin-top: 10px;
  font-size: 13px;
}

@media (max-width: 640px) {
  .destaque h1 {
    font-size: 26px;
  }
  .cabecalho-conteudo {
    align-items: flex-start;
  }
}

/* --- Formularios do ambiente de gerenciamento -------------------------- */

.formulario {
  max-width: 26rem;
}

/* O FORMULÁRIO LARGO, para as telas com campos agrupados.
   
   As 26rem acima são a largura de leitura de um formulário em coluna única, e
   elas são o padrão certo para a maioria das telas. Só que, com elas, um
   .formulario-linha de dois ou três campos NUNCA cabe lado a lado: cada campo
   pede 14rem, e dois não entram em 26rem — eles quebram, e o agrupamento que a
   tela desenhou vira uma coluna comprida de onze campos empilhados.
   
   Foi o que aconteceu com o cadastro de concurso, que agrupa número/ano/tipo,
   fase/secretaria e as duas datas de inscrição. A tela ficava com um terço da
   largura e três telas de altura.
   
   Quem usa esta classe está dizendo "aqui os grupos são para valer". */
.formulario-amplo {
  max-width: 54rem;
}

/* Dentro do formulário largo, os campos de uma linha alinham pelo TOPO.
   
   O padrão alinha pelo fim (align-items: flex-end), e ali isso está certo: numa
   linha de dois campos sem texto de ajuda, alinhar os fins alinha os campos.
   
   Aqui não. Os campos deste formulário têm ajuda embaixo, e ajudas de alturas
   diferentes — "Do jeito que sai no edital." tem uma linha, "Concurso público,
   processo seletivo, chamada pública…" tem duas. Alinhando pelo fim, o campo de
   ajuda curta SOBE, e o rótulo dele fica mais alto que o do vizinho: três
   campos lado a lado em três alturas diferentes. */
.formulario-amplo .formulario-linha {
  align-items: flex-start;
}

.campo {
  margin-bottom: 1rem;
}

.campo label {
  display: block;
  margin-bottom: 0.35rem;
  font-weight: 600;
  color: var(--cor-texto);
}

.campo input {
  width: 100%;
  padding: 0.6rem 0.7rem;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
  background: var(--cor-superficie);
  color: var(--cor-texto);
  font-family: inherit;
  font-size: 1rem;
}

/* O contorno de foco fica visivel de proposito. Retirar o outline e comum em
   sites bonitos e torna o portal inutilizavel para quem navega por teclado,
   o que a Lei de Acesso a Informacao nao permite (art. 8, par. 3, VIII). */
.campo input:focus-visible,
.botao:focus-visible {
  outline: 3px solid var(--cor-destaque);
  outline-offset: 2px;
}

.botao {
  display: inline-block;
  /* SUBLINHADO DESLIGADO. Isto conserta um defeito antigo: ".botao" nunca
     disse nada sobre sublinhado, e o navegador sublinha todo <a> por padrão.
     Resultado: <a class="botao"> saía sublinhado e <button class="botao">
     não — dois botões idênticos com aparência diferente na mesma tela.
     Apareceu de novo em Aparência, onde "Novo banner" (link) fica ao lado de
     "Salvar as cores" (botão). */
  text-decoration: none;
  padding: 0.65rem 1.4rem;
  border: 1px solid var(--cor-primaria);
  border-radius: var(--raio);
  background: var(--cor-primaria);
  color: var(--cor-sobre-primaria);
  font-family: inherit;
  font-size: 1rem;
  font-weight: 600;
  cursor: pointer;
}

.botao:hover {
  background: var(--cor-primaria-escura);
  border-color: var(--cor-primaria-escura);
}

.botao-secundario {
  background: transparent;
  color: var(--cor-primaria);
}

.botao-secundario:hover {
  background: var(--cor-primaria);
  color: var(--cor-sobre-primaria);
}

/* Erro nao se anuncia so pela cor: quem nao distingue vermelho precisa do
   texto e da borda para perceber. */
.erro-mensagem,
.mensagem-erro {
  margin: 0 0 1rem;
  padding: 0.7rem 0.9rem;
  border: 1px solid var(--cor-erro);
  border-left-width: 4px;
  border-radius: var(--raio);
  background: var(--cor-erro-fundo);
  color: var(--cor-erro);
  font-weight: 600;
}

/* --- Ambiente de gerenciamento ----------------------------------------- */

/* --- Barra lateral do gerenciamento ------------------------------------- */

/* O conteúdo se afasta por preenchimento no <body>, e não por margem em cada
 * tela: assim cabeçalho, conteúdo e rodapé se deslocam juntos, e nenhuma tela
 * nova precisa saber que a barra existe.
 *
 * A transição é curta de propósito. Recolher o menu muda a largura de tudo, e
 * sem nenhuma transição a página inteira dá um salto; longa demais, atrasa
 * quem só queria espaço. */
.com-menu-lateral {
  padding-left: 17rem;
  transition: padding-left 0.15s ease;
}

.com-menu-lateral.menu-recolhido {
  padding-left: 3.75rem;
}

/* Quem pediu ao sistema para reduzir animacao nao quer nem esta. Recolher
 * continua funcionando; a barra so troca de largura de uma vez. */
@media (prefers-reduced-motion: reduce) {
  .com-menu-lateral,
  .menu-lateral {
    transition: none;
  }
}

/* A BARRA NAO ROLA MAIS, E ISSO E O QUE PERMITE O SUBMENU.
 *
 * Ela tinha overflow-y: auto, e precisava: eram dezoito secoes numa lista so.
 * Agora sao seis linhas — o Painel e os cinco grupos —, que cabem em qualquer
 * tela sem rolagem nenhuma.
 *
 * E tinha de ser assim. Quando se pede rolagem num eixo, o CSS obriga o corte
 * no outro: "overflow-y: auto" com "overflow-x: visible" nao existe — o
 * navegador transforma o visible em auto. Ou seja, enquanto a barra rolasse,
 * qualquer coisa que vazasse para o lado seria cortada na borda dela, e o
 * submenu ficaria escondido atras da propria barra.
 *
 * O preco: se um dia a barra voltar a ter mais linhas do que cabe na tela, o
 * que passar do fim fica inalcancavel em vez de rolar. E por isso que grupo
 * novo e decisao, e nao consequencia de modulo novo. */
.menu-lateral {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  z-index: 20;
  display: flex;
  width: 17rem;
  flex-direction: column;
  overflow: visible;
  border-right: 1px solid var(--cor-borda);
  background: var(--cor-superficie);
  /* A mesma duracao do afastamento do conteudo, logo acima. As duas coisas se
   * mexem juntas quando o menu recolhe: se uma tiver transicao e a outra nao,
   * a barra e o conteudo se descolam no meio do caminho. */
  transition: width 0.15s ease;
}

.menu-recolhido .menu-lateral {
  width: 3.75rem;
}

/* Recolhida, some tudo o que é texto — mas só da vista. O texto continua no
 * documento para o leitor de tela: quem não enxerga o ícone depende dele. */
.menu-recolhido .menu-rotulo,
.menu-recolhido .menu-marca-texto,
.menu-recolhido .menu-usuario-texto {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* RECOLHIDA, A MARCA SOME INTEIRA — inclusive o brasao.
 *
 * A regra de cima escondia so o TEXTO do lado do brasao, e o brasao ficava.
 * So que ele nao cabe: a faixa recolhida tem 3,75rem, e o botao de abrir
 * (2,25rem) mais o espaco mais o brasao (2,25rem) passam de 5rem. O que
 * sobrava era uma bolinha atravessada por cima do conteudo da pagina, do lado
 * de fora da barra — foi o que apareceu na tela da Prefeitura.
 *
 * Nao se perde nada: o brasao e um atalho para o painel, e o painel e o
 * primeiro item da lista de icones logo abaixo. */
.menu-recolhido .menu-marca {
  display: none;
}

/* Recolhida, o botao de abrir fica sozinho e centrado na faixa. */
.menu-recolhido .menu-topo {
  justify-content: center;
  padding: 0.7rem 0;
}

/* MENOS DENTRO DO SUBMENU, e este "menos" e a razao de a barra recolhida
 * continuar utilizavel.
 *
 * A regra de cima esconde todo texto quando a barra esta recolhida — e ela
 * alcancava tambem os nomes dentro da lista que se abre ao lado. O resultado
 * era um submenu com sete icones e nenhuma palavra: para descobrir qual era
 * "Licitacoes" a pessoa tinha que passar o mouse em cada um e esperar o balao
 * do navegador.
 *
 * Recolhida, a barra so tem icone; a lista aberta passa a ser o UNICO lugar da
 * tela onde os nomes estao escritos. E exatamente o texto que nao pode sumir.
 *
 * Achado pelo teste de tela, e nao por leitura do codigo: escondido estava
 * certo em toda regra que eu tinha escrito. */
.menu-recolhido .menu-submenu .menu-rotulo {
  position: static;
  width: auto;
  height: auto;
  overflow: visible;
  clip-path: none;
}

.menu-topo {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.7rem 0.75rem;
  border-bottom: 1px solid var(--cor-borda);
}

/* O botão de recolher num quadrado da cor do portal: é o primeiro elemento da
 * tela, e precisa ser achado sem procurar. */
.menu-alternar {
  display: inline-flex;
  width: 2.25rem;
  height: 2.25rem;
  flex: 0 0 2.25rem;
  align-items: center;
  justify-content: center;
  border-radius: var(--raio);
  background: var(--cor-primaria);
  color: var(--cor-sobre-primaria);
  text-decoration: none;
}

.menu-alternar:hover {
  background: var(--cor-primaria-escura);
}

.menu-marca {
  display: flex;
  min-width: 0;
  align-items: center;
  gap: 0.5rem;
  color: var(--cor-texto);
  text-decoration: none;
}

.menu-brasao {
  display: inline-flex;
  width: 2.25rem;
  height: 2.25rem;
  flex: 0 0 2.25rem;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--cor-primaria);
  color: var(--cor-sobre-primaria);
  font-size: 0.75rem;
  font-weight: 700;
}

.menu-marca-texto,
.menu-usuario-texto {
  display: flex;
  min-width: 0;
  flex-direction: column;
  line-height: 1.2;
}

.menu-marca-texto strong,
.menu-usuario-texto strong {
  font-size: 0.85rem;
  /* Nome longo não empurra a barra: corta com reticências. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.menu-marca-texto small,
.menu-usuario-texto small {
  color: var(--cor-apagado);
  font-size: 0.72rem;
}

/* KAN-182 e KAN-183: os links da propria conta, embaixo do perfil. Com
 * espaco entre eles: colados, as quatro linhas (nome, perfil e os dois
 * links) viravam um bloco so, dificil de ler e de acertar o clique. */
.menu-usuario-texto .menu-usuario-senha {
  display: block;
  margin-top: 0.35rem;
  font-size: 0.72rem;
  line-height: 1.35;
}

.menu-usuario-texto .menu-usuario-senha + .menu-usuario-senha {
  margin-top: 0.2rem;
}

/* KAN-183: na tela do codigo, a explicacao fica afastada do campo. Colada
 * nele, ela parecia parte do que se digita. */
.campo-ajuda.campo-ajuda-afastada {
  margin-top: 0.75rem;
  line-height: 1.45;
}

/* KAN-183: os passos de ligar a verificacao e os codigos de recuperacao. */
.passos {
  display: grid;
  gap: 0.8rem;
  padding-left: 1.2rem;
}

.codigos-de-recuperacao {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
  gap: 0.5rem;
  padding: 0;
  list-style: none;
  font-size: 1.05rem;
}

.menu-usuario {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.7rem 0.75rem;
  border-bottom: 1px solid var(--cor-borda);
  /* Branco, como a barra do alto: nome e perfil nao precisam de outra cor. */
  background: var(--cor-superficie);
}

.menu-usuario form {
  margin: 0 0 0 auto;
}

.menu-sair {
  display: inline-flex;
  padding: 0.35rem;
  border: 0;
  border-radius: var(--raio);
  background: none;
  color: var(--cor-apagado);
  cursor: pointer;
}

.menu-sair:hover {
  background: var(--cor-fundo);
  color: var(--cor-erro);
}

/* RECOLHIDA, O BLOCO DO USUARIO SOME INTEIRO.
 *
 * Ele tinha uma bolinha com a inicial do nome, que era a unica coisa visivel
 * ali quando a barra estava estreita. A bolinha saiu (nao cabia na faixa de
 * 3,75rem e vazava por cima do conteudo), e sem ela o bloco ficou sem nada
 * para mostrar: o nome e o perfil ja eram escondidos pela regra do texto, e o
 * botao de sair por esta regra aqui. O que sobrava era uma linha de borda
 * atravessada no meio dos icones, sem nada em cima.
 *
 * Quem esta logado continua escrito na barra aberta, que e onde se le. */
.menu-recolhido .menu-usuario {
  display: none;
}

/* O RECUO DA LISTA E O QUE DA ACABAMENTO A BARRA.
 *
 * Antes o item ia de borda a borda, e o realce de "tela aberta" tambem: uma
 * faixa colorida encostada nos dois lados, com quina viva. Recuado meio
 * centimetro e com canto arredondado, o realce vira um bloco DENTRO da barra —
 * e a barra passa a ter uma margem propria, que e o que faltava para ela nao
 * parecer coluna de tabela. */
.menu-navegacao ul {
  margin: 0.5rem 0;
  list-style: none;
}

/* O RECUO E SO DA LISTA RAIZ — "> ul", e nao "ul".
 *
 * O submenu e uma lista DENTRO desta, entao toda regra escrita sem o ">"
 * alcanca os dois. Escrito solto, o recuo e a centralizacao de icone da barra
 * recolhida chegavam ate os itens do submenu, e la eles apareciam centrados,
 * cada nome comecando num lugar diferente. Visto na foto, nao no codigo. */
.menu-navegacao > ul {
  padding: 0 0.5rem;
}

.menu-navegacao li {
  display: flex;
  align-items: center;
}

.menu-navegacao > ul > li + li {
  margin-top: 0.15rem;
}

.menu-navegacao a {
  display: flex;
  min-width: 0;
  flex: 1 1 auto;
  align-items: center;
  gap: 0.7rem;
  padding: 0.62rem 0.65rem;
  border-radius: var(--raio);
  color: var(--cor-texto);
  font-weight: 600;
  text-decoration: none;
}

.menu-navegacao a:hover {
  background: var(--cor-fundo);
}

.icone-secao {
  flex: 0 0 16px;
  color: var(--cor-primaria);
}

.menu-rotulo {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* aria-current marca a tela aberta. Usar o próprio atributo como seletor
   mantém o visual e a informação para o leitor de tela sempre em acordo: não
   dá para destacar visualmente sem anunciar, nem o contrário.
   A barra à esquerda existe para o estado não depender só da cor de fundo. */
.menu-navegacao a[aria-current='page'] {
  background: var(--cor-informacao-fundo);
  color: var(--cor-primaria);
}

/* A barrinha da esquerda e sombra POR DENTRO, e nao borda: borda de verdade
 * some no canto arredondado e ainda empurra o texto 3px, desalinhando o item
 * aberto de todos os outros. So na lista raiz — dentro do submenu o realce
 * sempre foi o fundo mais o negrito, e duas barrinhas na mesma tela, uma
 * dentro da outra, seriam ruido. */
.menu-navegacao > ul > li > a[aria-current='page'] {
  box-shadow: inset 3px 0 0 var(--cor-primaria);
}

.menu-navegacao a[aria-current='page'] .icone-secao {
  color: var(--cor-primaria);
}

/* RECOLHIDA, O ITEM E SO O ICONE, E ELE FICA NO MEIO.
 *
 * Com o recuo e o preenchimento da barra aberta, o icone ficava encostado na
 * esquerda da faixa estreita, e a seta do submenu aparecia espremida do lado —
 * dois sinais disputando 3,75rem. A seta sai (o submenu continua abrindo no
 * hover, e e ele que diz que ha mais coisa ali) e o icone vai para o centro. */
.menu-recolhido .menu-navegacao > ul {
  padding: 0 0.4rem;
}

.menu-recolhido .menu-navegacao > ul > li > a {
  justify-content: center;
  padding-right: 0.3rem;
  padding-left: 0.3rem;
}

.menu-recolhido .menu-seta {
  display: none;
}

/* --- A SETA E O GRUPO ABERTO --------------------------------------------- */

.menu-seta {
  flex: 0 0 13px;
  margin-left: auto;
  color: var(--cor-texto-suave);
  opacity: 0.45;
  transition:
    opacity 0.15s ease,
    transform 0.15s ease;
}

.menu-tem-submenu:hover .menu-seta,
.menu-tem-submenu:focus-within .menu-seta {
  color: var(--cor-primaria);
  opacity: 1;
  transform: translateX(2px);
}

/* O grupo que contem a tela aberta fica marcado mesmo com o submenu fechado.
 *
 * Sem isto, quem esta em Licitacoes nao tem pista nenhuma na tela de onde
 * aquilo mora: a barra mostra so os cinco grupos, e nenhum deles se parece com
 * "Licitacoes". A pessoa perde a nocao de onde esta dentro do portal.
 *
 * Nao usa aria-current: o atributo e da TELA aberta, e a tela aberta e a
 * secao, nao o grupo. Dizer "page" nos dois faria o leitor de tela anunciar
 * duas paginas atuais. */
.menu-raiz-ativo > .menu-raiz-link {
  background: var(--cor-fundo);
  color: var(--cor-primaria);
}

.menu-raiz-ativo > .menu-raiz-link .icone-secao,
.menu-raiz-ativo > .menu-raiz-link .menu-seta {
  color: var(--cor-primaria);
  opacity: 1;
}

/* --- O SUBMENU ------------------------------------------------------------ */

/* Ele abre ao passar o mouse e ao chegar com o teclado, e fecha sozinho.
 *
 * O gatilho e o <li> INTEIRO, e nao o link: se fosse o link, o menu fecharia
 * no instante em que o mouse saisse dele para entrar na lista — que e
 * exatamente o caminho que a pessoa faz. Com o <li>, a lista e filha do
 * gatilho e o :hover continua valendo enquanto o mouse estiver nela.
 *
 * O -0.4rem no topo e a sobreposicao de 2px na esquerda existem pelo mesmo
 * motivo: o mouse atravessa o vao entre a barra e a lista, e vao com um pixel
 * de falha fecha o menu no meio do caminho.
 *
 * Nao ha JavaScript nenhum aqui, como em todo o resto do portal. */
.menu-submenu {
  position: absolute;
  z-index: 40;
  top: -0.4rem;
  left: calc(100% - 2px);
  min-width: 17rem;
  padding: 0.4rem;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
  background: var(--cor-superficie);
  box-shadow: var(--sombra-flutuante);
  opacity: 0;
  transform: translateX(-6px);
  transition:
    opacity 0.13s ease,
    transform 0.15s ease,
    visibility 0.15s;
  visibility: hidden;
}

.menu-tem-submenu {
  position: relative;
  display: block;
}

.menu-tem-submenu > .menu-raiz-link {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.menu-tem-submenu:hover > .menu-submenu,
.menu-tem-submenu:focus-within > .menu-submenu {
  opacity: 1;
  transform: translateX(0);
  visibility: visible;
}

/* O nome do grupo repetido no alto da lista.
 *
 * Parece redundante, e nao e: com o menu recolhido a barra mostra so o icone,
 * entao a lista aberta e o unico lugar da tela onde esta escrito de que grupo
 * ela e. */
.menu-submenu-titulo {
  margin: 0.15rem 0.6rem 0.4rem;
  color: var(--cor-texto-suave);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.menu-submenu ul {
  margin: 0;
}

.menu-submenu a,
.menu-submenu .menu-futuro > span {
  display: flex;
  min-width: 0;
  flex: 1 1 auto;
  align-items: center;
  gap: 0.6rem;
  padding: 0.5rem 0.6rem;
  border-radius: calc(var(--raio) - 2px);
  color: var(--cor-texto);
  font-weight: 500;
  text-decoration: none;
}

.menu-submenu a:hover {
  background: var(--cor-informacao-fundo);
  color: var(--cor-primaria);
}

.menu-submenu a[aria-current='page'] {
  border-left: 0;
  padding-left: 0.6rem;
  background: var(--cor-informacao-fundo);
  color: var(--cor-primaria);
  font-weight: 700;
}

/* --- O QUE AINDA VAI SER CONSTRUIDO -------------------------------------- */

/* Cinza, com a etiqueta do modulo, e sem ser link.
 *
 * O cinza sozinho nao serve: quem nao distingue cor ve um item normal e tenta
 * clicar. A etiqueta "M10" ao lado e o que diz, em texto, que aquilo ainda nao
 * existe — e ela esta no title tambem, por extenso. */
.menu-futuro > span,
.cartao-futuro .cartao-corpo {
  color: var(--cor-apagado);
  cursor: default;
}

.menu-futuro .icone-secao,
.cartao-futuro .cartao-selo .icone-secao {
  color: var(--cor-apagado);
}

.menu-etiqueta,
.cartao-etiqueta {
  margin: 0;
  margin-left: auto;
  padding: 0 0.4rem;
  border: 1px solid currentcolor;
  border-radius: 1rem;
  color: var(--cor-apagado);
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  white-space: nowrap;
}

/* --- A TELA DO GRUPO ----------------------------------------------------- */

.destaque-grupo {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
}

.destaque-icone {
  display: grid;
  width: 2.75rem;
  height: 2.75rem;
  flex: none;
  border-radius: var(--raio);
  background: var(--cor-informacao-fundo);
  margin-top: 0.2rem;
  place-items: center;
}

.destaque-icone .icone-secao {
  width: 22px;
  height: 22px;
  flex: none;
}

.grade-de-grupos {
  display: grid;
  margin: 0;
  padding: 0;
  gap: 1.15rem;

  /* O min() e o que impede a rolagem lateral em tela estreita.
   *
   * minmax(15rem, 1fr) sozinho diz "a coluna tem no minimo 15rem" — e 15rem,
   * com a letra no maior tamanho, sao 315px. Numa tela de 320px menos o
   * respiro, a coluna passa a ser mais larga que o lugar onde ela cabe, e a
   * pagina ganha rolagem lateral. O min(15rem, 100%) manda o minimo ceder
   * quando o espaco e menor que ele. */
  grid-template-columns: repeat(auto-fill, minmax(min(15rem, 100%), 1fr));
  list-style: none;
}

/* O CARTAO CRESCE POR CIMA DOS VIZINHOS, E NAO EMPURRANDO.
 *
 * O <li> tem altura fixa e nao muda nunca; quem cresce e a copia de dentro,
 * que e posicionada em cima dele. Assim a grade nao sabe que alguma coisa
 * cresceu, e nao se remonta.
 *
 * Empurrar seria mais simples e e pior: a cada movimento do mouse a grade
 * inteira mudaria de lugar, e um cartao que se mexe na hora de clicar e como
 * um botao que foge. */
.cartao-secao {
  position: relative;
  height: 10.5rem;
}

.cartao-secao:hover,
.cartao-secao:focus-within {
  z-index: 10;
}

.cartao-corpo {
  position: absolute;
  display: block;
  overflow: hidden;
  padding: 1rem 1.05rem;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
  background: var(--cor-superficie);
  color: var(--cor-texto);
  inset: 0;
  text-decoration: none;
  transition:
    inset 0.17s ease,
    box-shadow 0.17s ease,
    border-color 0.17s ease;
}

.cartao-secao:hover .cartao-corpo,
.cartao-secao:focus-within .cartao-corpo {
  border-color: var(--cor-borda-forte);
  box-shadow: var(--sombra-flutuante);
  inset: -1.1rem -1.2rem auto -1.2rem;
}

.cartao-selo {
  display: grid;
  width: 2.35rem;
  height: 2.35rem;
  margin-bottom: 0.7rem;
  border-radius: var(--raio);
  background: var(--cor-informacao-fundo);
  place-items: center;
}

.cartao-selo .icone-secao {
  width: 18px;
  height: 18px;
  flex: none;
}

.cartao-corpo h3 {
  margin: 0 0 0.3rem;
  font-size: 0.97rem;
  line-height: 1.3;
}

.cartao-imperativo {
  margin: 0;
  color: var(--cor-texto-suave);
  font-size: 0.85rem;
  line-height: 1.45;
}

/* As telas de dentro, e o botao, aparecem so quando o cartao cresce.
 *
 * Nada aqui e informacao unica: o nome da secao e a frase do que se faz nela
 * ficam visiveis o tempo todo, e o cartao inteiro ja e o link. Isto e reforco
 * — e por isso pode aparecer no hover sem deixar ninguem de fora.
 *
 * Nao usa display:none: o leitor de tela le tudo, e quem chega pelo teclado
 * ve, porque o :focus-within abre o mesmo cartao. */
.cartao-telas {
  display: flex;
  max-height: 0;
  margin: 0.7rem 0 0;
  padding: 0;
  flex-wrap: wrap;
  gap: 0.3rem;
  list-style: none;
  opacity: 0;
  transition:
    max-height 0.17s ease,
    opacity 0.15s ease;
}

.cartao-secao:hover .cartao-telas,
.cartao-secao:focus-within .cartao-telas {
  max-height: 8rem;
  opacity: 1;
}

.cartao-telas li {
  padding: 0.1rem 0.55rem;
  border-radius: 1rem;
  background: var(--cor-fundo);
  color: var(--cor-texto-suave);
  font-size: 0.74rem;
}

.cartao-botao {
  display: inline-block;
  max-height: 0;
  margin-top: 0.75rem;
  padding: 0 0.95rem;
  border-radius: calc(var(--raio) - 2px);
  background: var(--cor-primaria);
  color: var(--cor-sobre-primaria-suave);
  font-size: 0.82rem;
  font-weight: 700;
  opacity: 0;
  transition:
    max-height 0.17s ease,
    opacity 0.15s ease,
    padding 0.17s ease;
}

.cartao-secao:hover .cartao-botao,
.cartao-secao:focus-within .cartao-botao {
  max-height: 2.5rem;
  padding: 0.38rem 0.95rem;
  opacity: 1;
}

/* O cartao do que ainda nao existe: tracejado, e o tracejado e o que diz
 * "provisorio" para quem nao distingue o cinza. */
.cartao-futuro .cartao-corpo {
  border-style: dashed;
  background: var(--cor-fundo);
}

.cartao-futuro .cartao-selo {
  background: var(--cor-vazio);
}

.cartao-futuro .cartao-etiqueta {
  float: right;
  margin-top: -2.9rem;
}

.cartao-nota {
  max-height: 0;
  margin: 0.55rem 0 0;
  color: var(--cor-apagado);
  font-size: 0.78rem;
  line-height: 1.4;
  opacity: 0;
  transition:
    max-height 0.17s ease,
    opacity 0.15s ease;
}

.cartao-futuro:hover .cartao-nota,
.cartao-futuro:focus-within .cartao-nota {
  max-height: 6rem;
  opacity: 1;
}

/* Em tela estreita a barra vira uma faixa comum no topo: 15rem fixos ao lado
 * do conteúdo, num celular, não deixam largura para nenhum dos dois. Fixa, ela
 * ainda cobriria a tela inteira. */
@media (max-width: 60rem) {
  .com-menu-lateral,
  .com-menu-lateral.menu-recolhido {
    padding-left: 0;
  }

  .menu-lateral,
  .menu-recolhido .menu-lateral {
    position: static;
    width: auto;
    border-right: 0;
    border-bottom: 1px solid var(--cor-borda);
  }

  .menu-navegacao ul {
    display: flex;
    flex-wrap: wrap;
  }

  /* O respiro entre itens e da coluna; aqui eles ficam lado a lado. */
  .menu-navegacao > ul > li + li {
    margin-top: 0;
  }

  .menu-recolhido .menu-navegacao,
  .menu-recolhido .menu-usuario {
    display: none;
  }

  /* NO CELULAR NAO EXISTE PASSAR O MOUSE.
   *
   * Um submenu que so abre no hover seria, num toque, um item de menu que nao
   * faz nada — ou pior, que abre e fecha no primeiro toque e so navega no
   * segundo. Entao aqui ele deixa de flutuar e vira o que sempre foi na tela
   * estreita: a lista inteira, aberta, empilhada. A barra ja e uma faixa no
   * topo que rola com a pagina, entao caber nao e problema. */
  .menu-submenu {
    position: static;
    min-width: 0;
    flex-basis: 100%;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    opacity: 1;
    transform: none;
    visibility: visible;
  }

  /* E, na tela estreita, o nome LONGO tem que poder quebrar.
   *
   * A 320px com a letra no maior tamanho — que e 21px de raiz, nao 16 —
   * "Conformidade ATRICON" mais a etiqueta M14 nao cabem numa linha so. Com
   * white-space: nowrap herdado do menu-rotulo, o item empurrava a lista para
   * 367px e a pagina inteira do gerenciamento ganhava rolagem lateral, em toda
   * tela, porque a barra aparece em todas.
   *
   * min-width: 0 sozinho nao resolve: item de flex nao encolhe abaixo do
   * conteudo dele, e o conteudo e uma palavra que nao quebra. Sao as duas
   * coisas juntas. Pego pela auditoria de acessibilidade, nao pelo olho. */
  .menu-tem-submenu {
    min-width: 0;
    flex-basis: 100%;
    flex-wrap: wrap;
  }

  .menu-submenu a,
  .menu-submenu .menu-futuro > span {
    min-width: 0;
  }

  .menu-submenu .menu-rotulo {
    overflow-wrap: break-word;
    white-space: normal;
  }

  .menu-seta {
    display: none;
  }

  .cartao-secao {
    height: auto;
  }

  .cartao-corpo,
  .cartao-secao:hover .cartao-corpo,
  .cartao-secao:focus-within .cartao-corpo {
    position: static;
    box-shadow: none;
    inset: auto;
  }

  .cartao-telas,
  .cartao-botao,
  .cartao-nota {
    max-height: none;
    opacity: 1;
  }

  .cartao-botao {
    padding: 0.38rem 0.95rem;
  }
}

/* --- Respiro do conteúdo do gerenciamento -------------------------------- */

/* Dentro do gerenciamento o conteúdo usa a largura toda.
 *
 * O limite de 1100px existe para TEXTO CORRIDO: linha longa demais faz o olho
 * perder a próxima ao voltar. Só que o gerenciamento não é texto corrido — é
 * tabela, formulário e lista, onde largura é o que evita coluna espremida e
 * rolagem lateral. Manter o limite ali deixava metade da tela vazia à direita
 * enquanto a tabela apertava à esquerda, que é exatamente a bagunça que se vê.
 *
 * O texto explicativo continua com largura controlada por .destaque-texto, que
 * é onde a regra original faz sentido. */
.com-menu-lateral .conteudo {
  max-width: none;
  padding-right: 28px;
  padding-left: 28px;
}

/* Espaço entre os blocos da tela.
 *
 * Antes não havia nenhum: as telas empilhavam <section> coladas e cada página
 * resolvia por conta própria — algumas resolviam, outras não, e o resultado
 * era cada tela com um espaçamento diferente. Aqui vale para todas, inclusive
 * a próxima, e ninguém precisa lembrar. */
.conteudo > * + * {
  margin-top: 1.25rem;
}

.conteudo > .destaque {
  margin-bottom: 0.25rem;
}

/* O título da tela não precisa do tamanho de manchete do portal público: aqui
 * ele é uma etiqueta de onde a pessoa está, e o espaço vale mais para o
 * trabalho do que para a tipografia. */
.com-menu-lateral .destaque h1 {
  font-size: 28px;
}

/* Mensagem de erro é texto técnico, e vem longa. Sem limite, uma pilha inteira
 * numa célula estica a coluna e espreme todas as outras — foi o que aconteceu
 * na tela de erros. Aqui ela ocupa no máximo três linhas; o detalhe completo
 * está a um clique, na tela do erro. */
.celula-mensagem {
  display: -webkit-box;
  max-width: 44ch;
  overflow: hidden;
  /* Caminho de arquivo não tem espaço: sem isto ele não quebra e a coluna
     fica com a largura dele inteiro (KAN-168). */
  overflow-wrap: anywhere;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
}

/* --- Botão de voltar ----------------------------------------------------- */

/* PERGUNTAS FREQUENTES (PNTP 2.7 — KAN-147). */
.pergunta-frequente {
  padding: 10px 0;
  border-bottom: 1px solid var(--cor-borda);
}

.pergunta-frequente summary {
  cursor: pointer;
  font-weight: 700;
}

.pergunta-frequente p {
  max-width: 70ch;
  margin: 8px 0 0;
}

/* O ORGANOGRAMA (PNTP 2.1 e 2.2 — KAN-146): lista dentro de lista, com um
   traço à esquerda que mostra quem está abaixo de quem. */
.organograma {
  margin: 0;
  padding-left: 1.25rem;
  border-left: 2px solid var(--cor-borda-forte);
  list-style: none;
}

.organograma-raiz {
  padding-left: 0;
  border-left: 0;
}

.organograma li {
  margin: 8px 0;
}

.unidade-organograma summary {
  cursor: pointer;
}

.unidade-organograma p {
  margin: 6px 0 6px 1rem;
  max-width: 70ch;
}

/* O MAPA DO SITE (PNTP 13.5 — KAN-150): os grupos em colunas que se
   ajeitam sozinhas à largura da tela. */
.mapa-do-site {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 24px;
  align-items: start;
}

.mapa-do-site-grupo h2 {
  margin: 0 0 8px;
  font-size: 18px;
}

.mapa-do-site-grupo ul {
  margin: 0;
  padding-left: 1.1rem;
}

.mapa-do-site-grupo li {
  margin: 4px 0;
}

.mapa-do-site-grupo a {
  color: var(--cor-link);
}

/* O CAMINHO DE PÁGINAS (PNTP 13.2 — KAN-150). Letra pequena e discreta: ele
   responde "onde estou", e não compete com o título da página. O separador
   é desenhado pelo CSS, e não escrito no HTML, para o leitor de tela não
   ler "maior que" entre cada elo. */
.caminho {
  margin: 0 0 0.5rem;
  font-size: 14px;
  color: var(--cor-texto-suave);
}

.caminho ol {
  display: flex;
  flex-wrap: wrap;
  margin: 0;
  padding: 0;
  list-style: none;
}

.caminho li + li::before {
  content: '›';
  margin: 0 0.5rem;
  color: var(--cor-texto-suave);
}

.caminho a {
  color: var(--cor-link);
}

.caminho [aria-current='page'] {
  color: var(--cor-texto);
}

.barra-voltar {
  margin-bottom: 1rem;
}

.barra-voltar .voltar {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}

.formulario-linha {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 1rem;
  max-width: none;
}

/* Com texto de ajuda embaixo de um campo, alinhar pelo pé empurrava o campo
   vizinho para baixo (o "Nome" do cadastro de pessoa, nas Comissões): nessa
   linha os campos se alinham pelo alto, rótulo com rótulo. */
.formulario-linha:has(.campo-ajuda) {
  align-items: flex-start;
}

.formulario-linha .campo {
  flex: 1 1 14rem;
  margin-bottom: 0;
}

.formulario-linha .campo-estreito {
  flex: 0 1 12rem;
}

.campo select {
  width: 100%;
  padding: 0.6rem 0.7rem;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
  background: var(--cor-superficie);
  color: var(--cor-texto);
  font-family: inherit;
  font-size: 1rem;
}

.campo select:focus-visible {
  outline: 3px solid var(--cor-destaque);
  outline-offset: 2px;
}

.botao-pequeno {
  padding: 0.3rem 0.75rem;
  font-size: 0.9rem;
}

/* No celular, o botão pequeno continua com letra pequena, mas a área de
   toque sobe para 40px (pendência C2 do KAN-168): 28px é menos que a ponta
   de um dedo, e o "Remover" fica colado no "Editar". */
@media (max-width: 40rem) {
  .botao-pequeno {
    display: inline-flex;
    min-height: 40px;
    align-items: center;
  }
  .menu-de-acoes-fila button {
    min-height: 40px;
  }
}

/* Tabela larga rola dentro da propria caixa. Sem isto, a pagina inteira
   ganharia rolagem lateral no celular e o cabecalho sairia da tela. */
/*
  A tabela larga rola dentro desta caixa, e nao empurra a pagina.

  O "overflow-x: auto" sozinho NAO resolve, e isso custou tempo para
  descobrir: com ele, a tabela rola por dentro como esperado, mas o navegador
  continua contando a largura total da tabela ao decidir o tamanho da pagina —
  e o celular passa a rolar de lado tambem. Em 320px, a tela de usuarios
  empurrava a pagina para 872px.

  O "contain: paint" e o que fecha a conta: ele diz ao navegador que nada
  dentro desta caixa desenha fora dela, entao a largura da tabela para de
  contar para a pagina.

  CUIDADO ao mexer aqui: o contain tambem torna esta caixa a referencia de
  posicao para qualquer elemento com position: fixed dentro dela. Um modal
  colocado dentro de uma linha da tabela deixaria de cobrir a tela e passaria
  a ficar preso a esta caixa. Modal dentro de tabela, portanto, nao.
*/
.tabela-rolagem {
  overflow-x: auto;
  contain: paint;
}

.tabela {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.95rem;
}

.tabela th,
.tabela td {
  padding: 0.55rem 0.7rem;
  border-bottom: 1px solid var(--cor-borda);
  text-align: left;
  vertical-align: middle;
}

.tabela thead th {
  border-bottom-width: 2px;
  color: var(--cor-texto-suave);
  font-size: 0.8rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.tabela form {
  margin: 0;
}

.linha-inativa td {
  color: var(--cor-texto-suave);
}

/* Visivel para leitor de tela, invisivel na tela. Serve a legendas de tabela
   e a rotulos de coluna de acoes, que a pessoa vidente entende pelo contexto
   e a pessoa cega nao. */
.apenas-leitor {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  border: 0;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* --- Trilha de auditoria ------------------------------------------------ */

.celula-id {
  font-family: ui-monospace, 'Cascadia Mono', 'Consolas', monospace;
  font-size: 0.8rem;
  color: var(--cor-texto-suave);
}

.lista-mudancas {
  margin: 0;
  padding-left: 1.1rem;
  font-size: 0.9rem;
  /* O valor vem em JSON, às vezes um texto longo sem espaço. */
  overflow-wrap: anywhere;
}

/* O valor antigo riscado e o novo em destaque deixam a leitura imediata: nao
   e preciso comparar duas colunas para achar a diferenca. */
.valor-antigo {
  color: var(--cor-texto-suave);
  text-decoration: line-through;
}

.valor-novo {
  font-weight: 600;
}

.paginacao a {
  margin-left: 0.8rem;
  color: var(--cor-primaria);
  font-weight: 600;
}

/* --- Biblioteca de arquivos --------------------------------------------- */

.galeria {
  display: grid;
  /*
     O minmax(0, ...) do segundo argumento nao e detalhe.

     Uma coluna "1fr" vale, por baixo, "minmax(auto, 1fr)" — e esse "auto"
     manda a coluna nunca ficar menor que o maior conteudo indivisivel dela.
     Um nome de arquivo longo, que nao tem onde quebrar, virava uma coluna de
     348px dentro de um espaco de 247px, e o celular passava a rolar de lado.
     Com o minimo em zero, a coluna respeita o espaco e o nome quebra.
  */
  grid-template-columns: repeat(auto-fill, minmax(min(170px, 100%), 1fr));
  gap: 1rem;
  margin: 0 0 1rem;
  padding: 0;
  list-style: none;
}

.item-galeria {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  padding: 0.7rem;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
  background: var(--cor-superficie);
}

/* Altura fixa com o mesmo enquadramento para todos: sem isso, a grade fica
   com cartoes de alturas diferentes e a leitura vira zigue-zague. */
.item-visual {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 120px;
  overflow: hidden;
  border-radius: var(--raio);
  background: var(--cor-fundo);
}

.item-visual img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

.selo-extensao {
  color: var(--cor-primaria);
  font-size: 1.5rem;
  font-weight: 700;
  text-transform: uppercase;
}

/* Nome longo nao pode empurrar o cartao: corta com reticencias e o nome
   inteiro fica no title, ao passar o mouse. */
.item-nome {
  margin: 0;
  overflow: hidden;
  font-size: 0.85rem;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
  /* Nome de arquivo longo quebra em vez de empurrar a coluna. */
  overflow-wrap: break-word;
}

.item-dados {
  margin: 0;
  color: var(--cor-texto-suave);
  font-size: 0.75rem;
  line-height: 1.4;
}

.item-galeria form {
  margin-top: auto;
}

.campo input[type='file'] {
  padding: 0.45rem;
  background: var(--cor-fundo);
}

/* O aviso da previa: so quem esta logado ve, e ele nao pode competir com o
   conteudo que a pessoa veio conferir. */
.mensagem-previa {
  align-items: flex-start;
  font-size: 0.9rem;
}

/* Subtitulo de grupo dentro do menu lateral. Nao e clicavel: so separa.

   A cor sai das variaveis do tema, e nao de um branco transparente: a barra
   deste portal e CLARA, e branco sobre claro some. A primeira versao deste
   bloco usava "rgb(255 255 255 / 55%)" e o subtitulo ficou invisivel — existia
   no HTML, ocupava espaco e nao dava para ler. */
.menu-grupo {
  padding: 0.9rem 0.9rem 0.25rem;
  color: var(--cor-texto-suave);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* Com o menu recolhido so ha espaco para o icone, e uma palavra cortada pela
   metade seria pior do que um tracinho: o subtitulo vira uma linha divisoria,
   que continua separando os grupos sem tentar caber onde nao cabe. */
.menu-recolhido .menu-grupo {
  overflow: hidden;
  height: 1px;
  margin: 0.5rem 0.7rem;
  padding: 0;
  background: var(--cor-borda);
  text-indent: -999px;
}

/* --- Arquivos e mídias: as quatro seções -------------------------------- */

/*
  A TELA NASCE FECHADA, E A APARENCIA TEM QUE AGUENTAR ISSO.

  Quatro barras numa tela branca e, se nada mais for feito, quatro barras
  numa tela branca — a pessoa chega e nao ve o acervo dela. Por isso a barra
  fechada carrega uma AMOSTRA: quatro miniaturas pequenas, do lado da
  contagem. Fechado continua fechado, e ainda assim da para saber o que tem
  dentro sem abrir.

  O desenho e propositalmente sem sombra e sem cor: a cor da tela sao as
  fotos. Cartao colorido brigando com miniatura colorida e o que faz uma tela
  de midia parecer suja.
*/

.destaque-enxuto {
  padding-bottom: 0.75rem;
}

.midias-busca {
  margin-bottom: 1rem;
}

.midias-resumo-busca {
  margin: -0.5rem 0 1rem;
}

.midias-secoes {
  display: grid;
  gap: 0.6rem;
  margin-bottom: 1.25rem;
}

/* O bloco existe só para dar âncora ao botão de enviar, que é irmão do
   <details> e fica por cima da barra dele.

   O "min-width: 0" NÃO é enfeite. Item de grade nasce com min-width: auto, que
   quer dizer "nunca fico menor que o meu conteúdo". A prateleira tem oito
   ladrilhos em fila e rola para o lado; com min-width automático, a grade
   obedecia à fila inteira em vez de à largura da tela, e a PÁGINA passava a
   rolar na horizontal — a tela ficava 1776px de largo numa janela de 1440. */
/*
  "sanfona" E NAO "secao-midia", que era o nome ate 13/09.

  A peca nasceu na tela de Arquivos e midias, e o nome veio de la. Quando a
  tela de Aparencia precisou da mesma coisa — quatro secoes que abrem no
  clique, sem script — ou se repetia a regra inteira com outro nome, ou se
  reaproveitava um seletor chamado "midia" numa tela de cor. Nenhum dos dois
  presta: o primeiro e duas regras para corrigir, o segundo e um nome que
  mente para quem ler depois.

  O que continua chamando "secao-midia" e so o que E de midia: a amostra de
  quatro miniaturas e o botao de enviar arquivo. Eles moram DENTRO da sanfona,
  e nao sao a sanfona.
*/
.secao-sanfona-bloco {
  position: relative;
  min-width: 0;

  /*
    O "clip" e a tranca final contra rolagem lateral da PAGINA.

    O min-width acima resolve a largura do bloco; isto resolve o que escapa
    dele. O caso real: em 320px, com uma secao aberta, o lapis de um ladrilho
    de OUTRA secao — fechada — continuava aparecendo para o calculo de largura
    da pagina, e o portal inteiro passava a rolar para o lado (385px de
    conteudo numa tela de 320).
    "clip" e nao "hidden" de proposito: hidden criaria um container de
    rolagem, e a prateleira de dentro tem a rolagem dela. O clip so corta o que
    passar da borda, sem virar caixa de rolagem e sem esconder o botao de
    enviar, que fica dentro dos limites.
  */
  overflow-x: clip;
}

/*
  AS AÇÕES DA SEÇÃO — procurar e enviar — na linha do cabeçalho.

  Ficam sobre a barra em vez de dentro dela porque o cabeçalho é um <summary>,
  e o nome de um <summary> é tudo o que está escrito dentro dele — ver a nota
  na tela. A barra reserva o espaço com padding-right, então eles nunca se
  encostam, nem quando a contagem é longa.
*/
.secao-sanfona-acoes {
  position: absolute;
  top: 0.78rem;
  right: 1.1rem;
  display: flex;
  gap: 0.15rem;
  align-items: center;
}

/* Ícone, e não botão cheio: a tela inteira é de conteúdo, e quatro botões
   escuros empilhados na direita puxariam mais atenção do que as próprias
   mídias. O nome mora no title e no aria-label. */
.secao-midia-enviar {
  display: grid;
  place-items: center;
  width: 1.9rem;
  height: 1.9rem;
  border-radius: 50%;
  color: var(--cor-primaria);
}

.secao-midia-enviar:hover,
.secao-midia-enviar:focus-visible {
  background: var(--cor-fundo);
}

.secao-sanfona {
  border: 1px solid var(--cor-borda);
  border-radius: 12px;
  background: var(--cor-superficie);
  overflow: hidden;
}

/*
  A BARRA QUE ABRE A SEÇÃO.

  É um <summary>, e não um link. O navegador desenha um triângulo próprio nele
  por padrão — o "marker" —, e ele é retirado aqui porque esta tela já tem a
  sua seta, do lado direito, alinhada com o resto. São duas regras porque o
  Safari antigo só entende a segunda.
*/
.secao-sanfona-barra {
  display: flex;
  gap: 0.85rem;
  align-items: center;
  padding: 0.95rem 1.1rem;
  /* A direita reservada para as ações, que flutuam por cima. O espaço é o da
     busca ABERTA — 11rem de campo, mais o X e o enviar —, porque a caixa abre
     sem recarregar e não pode empurrar o nome da seção quando abrir. */
  padding-right: 19rem;
  color: var(--cor-texto);
  list-style: none;
  cursor: pointer;
}

.secao-sanfona-barra::-webkit-details-marker {
  display: none;
}

.secao-sanfona-barra:hover,
.secao-sanfona-barra:focus-visible {
  background: var(--cor-fundo);
}

/* O <h2> dentro do resumo é só para quem navega por cabeçalhos: visualmente
   ele é a própria barra, e não um título com peso e margem próprios. */
.secao-sanfona-titulo {
  display: flex;
  gap: 0.85rem;
  align-items: center;
  width: 100%;
  margin: 0;
  font-size: 1rem;
  font-weight: 400;
}

.secao-midia-icone {
  display: grid;
  flex: none;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 9px;
  background: var(--cor-informacao-fundo);
  color: var(--cor-primaria);
}

.secao-sanfona-nome {
  font-size: 1.05rem;
  font-weight: 700;
}

/* A amostra empurra a contagem para a direita e some quando a secao abre:
   aberta, as miniaturas de verdade estao logo abaixo, e repetir quatro delas
   no cabecalho so seria ruido. Quem some e o CSS, sem passar pelo servidor. */
.secao-midia-amostra {
  display: flex;
  gap: 0.3rem;
  margin-left: auto;
}

.secao-sanfona[open] .secao-midia-amostra {
  display: none;
}

.secao-midia-amostra img,
.secao-midia-amostra .amostra-selo {
  width: 2.1rem;
  height: 2.1rem;
  border: 1px solid var(--cor-borda);
  border-radius: 6px;
  object-fit: cover;
}

.secao-midia-amostra .amostra-selo {
  display: grid;
  place-items: center;
  background: var(--cor-fundo);
  color: var(--cor-texto-suave);
  font-size: 0.6rem;
  font-weight: 700;
}

.secao-sanfona-conta {
  margin-left: auto;
  color: var(--cor-texto-suave);
  font-size: 0.88rem;
  font-weight: 400;
}

/* Com amostra, a contagem ja nao precisa empurrar: a amostra empurrou. */
.secao-midia-amostra + .secao-sanfona-conta {
  margin-left: 0;
}

.secao-sanfona-seta {
  display: grid;
  flex: none;
  place-items: center;
  color: var(--cor-texto-suave);
}

/* A seta gira junto com a abertura, e a transicao e o que faz parecer a mesma
   coisa mudando de estado em vez de dois desenhos diferentes. */
.secao-sanfona-seta svg {
  transition: transform 0.22s ease;
}

.secao-sanfona[open] .secao-sanfona-seta svg {
  transform: rotate(180deg);
}

.secao-sanfona-corpo {
  padding: 0 1.1rem 1.1rem;
  border-top: 1px solid var(--cor-borda);
}

/*
  A SEÇÃO DESCE, EM VEZ DE APARECER DE UMA VEZ.

  ::details-content é o conteúdo do <details> visto pelo CSS. Animar altura
  até "auto" sempre foi impossível — por isso tanta gente usa JavaScript para
  medir o elemento e escrever a altura em pixels. As duas peças novas do CSS
  resolvem isso sem script:

  - interpolate-size: allow-keywords ensina o navegador a interpolar até
    "auto", que é a altura que o conteúdo tem de verdade;
  - transition-behavior: allow-discrete faz a troca de "escondido" para
    "visível" acontecer no começo da animação, e não antes dela — sem isso o
    conteúdo aparece inteiro num quadro e só depois a altura anima.

  ONDE O NAVEGADOR NÃO SOUBER, NADA QUEBRA: o <details> abre na hora, seco,
  como sempre abriu. É a definição de melhoria progressiva — o recurso novo
  enfeita, e a ausência dele não tira função nenhuma.
*/

.secao-sanfona::details-content {
  block-size: 0;
  overflow: hidden;
  transition:
    block-size 0.25s ease,
    content-visibility 0.25s allow-discrete;
  transition-behavior: allow-discrete;
}

.secao-sanfona[open]::details-content {
  block-size: auto;
}

/*
  Quem pediu menos movimento ao sistema operacional recebe menos movimento.
  Não é preferência de gosto: animação de altura é gatilho de enjoo e de
  enxaqueca para parte das pessoas, e o sistema já sabe quem são.
*/
@media (prefers-reduced-motion: reduce) {
  .secao-sanfona::details-content,
  .secao-sanfona-seta svg {
    transition: none;
  }
}

/* --- Prateleiras que rolam para o lado ---------------------------------- */

/*
  Uma prateleira por assunto: os albuns numa, os arquivos noutra.

  Ela rola na HORIZONTAL de proposito. Uma grade vertical com cem imagens
  empurraria as outras tres secoes para fora da tela, e a tela inteira existe
  para mostrar que as quatro estao ali. Quem quer ver tudo de um tipo clica em
  "ver tudo", e ai sim a secao vira grade com paginacao.

  Nao precisa de tabindex para o teclado: cada item tem link dentro, e e o
  foco passando de um para o outro que rola a prateleira.
*/
.prateleira {
  margin-top: 1.1rem;
}

.prateleira-topo {
  display: flex;
  gap: 1rem;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 0.6rem;
}

.prateleira-topo h3 {
  margin: 0;
  font-size: 0.95rem;
}

.prateleira-topo a {
  font-size: 0.88rem;
}

/* "Ver tudo" e a lupa moram juntos, na direita da prateleira — que é onde o
   olho já está quando termina de percorrer a fila para o lado. */
.prateleira-acoes {
  display: flex;
  gap: 0.75rem;
  align-items: center;
  flex: none;
}

/* --- A busca de cada seção ---------------------------------------------- */

/*
  Fechada é só a lupa; aberta é um campo pequeno e claro com um X do lado.

  QUEM ABRE: o :target do CSS, quando se clica na lupa, ou a classe "aberta",
  que o servidor põe quando já existe uma busca valendo naquela seção — depois
  de procurar o endereço não tem mais âncora, e sem isso a caixa fecharia
  justamente na tela que mostra o resultado.

  O :has() esconde a lupa enquanto a caixa está aberta. Onde ele não existir,
  a lupa fica ao lado da caixa: feio por um instante, e não quebrado.
*/
.secao-busca {
  display: inline-flex;
  align-items: center;
}

.secao-busca-lupa {
  display: grid;
  place-items: center;
  width: 1.9rem;
  height: 1.9rem;
  border-radius: 50%;
  color: var(--cor-primaria);
}

.secao-busca-lupa:hover,
.secao-busca-lupa:focus-visible {
  background: var(--cor-fundo);
}

.secao-busca-campo {
  display: none;
  align-items: center;
  gap: 0.3rem;
}

.secao-busca-campo:target,
.secao-busca-campo.aberta {
  display: flex;
}

.secao-busca:has(.secao-busca-campo:target) .secao-busca-lupa,
.secao-busca:has(.secao-busca-campo.aberta) .secao-busca-lupa {
  display: none;
}

/* Cinza e discreto, como foi pedido: é uma ferramenta, não o conteúdo. */
.secao-busca-campo input[type='search'] {
  width: 11rem;
  padding: 0.3rem 0.6rem;
  border: 1px solid var(--cor-borda);
  border-radius: 999px;
  background: var(--cor-fundo);
  font: inherit;
  font-size: 0.85rem;
}

.secao-busca-limpar {
  display: grid;
  place-items: center;
  width: 1.6rem;
  height: 1.6rem;
  border-radius: 50%;
  color: var(--cor-texto-suave);
}

.secao-busca-limpar:hover,
.secao-busca-limpar:focus-visible {
  background: var(--cor-fundo);
  color: var(--cor-texto);
}

.prateleira-itens {
  display: flex;
  gap: 0.85rem;
  margin: 0;
  padding: 0 0 0.4rem;
  overflow-x: auto;
  list-style: none;
  scroll-snap-type: x proximity;
}

.prateleira-itens > li {
  flex: none;
  width: 10.5rem;
  scroll-snap-align: start;
}

/* Em "ver tudo" a mesma lista vira grade e para de rolar para o lado. */
.prateleira-grade {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(10.5rem, 100%), 1fr));
  overflow-x: visible;
}

.prateleira-grade > li {
  width: auto;
}

/* --- O quadradinho ------------------------------------------------------ */

.ladrilho {
  position: relative;
}

.ladrilho-alvo {
  display: block;
  color: inherit;
  text-decoration: none;
}

.ladrilho-capa {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  border: 1px solid var(--cor-borda);
  border-radius: 9px;
  background: var(--cor-fundo);
  object-fit: cover;
}

.ladrilho-capa-vazia {
  display: grid;
  place-items: center;
  color: var(--cor-texto-suave);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.04em;
}

.ladrilho-nome {
  display: block;
  margin-top: 0.45rem;
  overflow: hidden;
  font-size: 0.88rem;
  font-weight: 600;
  line-height: 1.25;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.ladrilho-alvo:hover .ladrilho-nome,
.ladrilho-alvo:focus-visible .ladrilho-nome {
  text-decoration: underline;
}

.ladrilho-dados {
  display: block;
  color: var(--cor-texto-suave);
  font-size: 0.8rem;
}

/*
  O lapis fica SOBRE a capa, no canto.

  Fora dela ele viraria mais uma linha de texto embaixo de cada quadradinho, e
  doze quadradinhos com duas linhas de acao cada viram uma tela de botoes. Em
  cima da imagem ele ocupa espaco que ja existe — e ganha fundo claro proprio,
  porque foto escura engoliria um icone sem fundo.
*/
.ladrilho-editar,
.linha-midia-editar {
  display: grid;
  place-items: center;
  width: 1.9rem;
  height: 1.9rem;
  border: 1px solid var(--cor-borda);
  border-radius: 50%;
  background: color-mix(in srgb, var(--cor-sobre-primaria) 92%, transparent);
  color: var(--cor-texto);
}

.ladrilho-editar {
  position: absolute;
  top: 0.4rem;
  right: 0.4rem;
}

.ladrilho-editar:hover,
.ladrilho-editar:focus-visible,
.linha-midia-editar:hover,
.linha-midia-editar:focus-visible {
  background: var(--cor-primaria);
  color: var(--cor-superficie);
}

.ladrilho-novo > a {
  display: grid;
  width: 100%;
  aspect-ratio: 4 / 3;
  gap: 0.25rem;
  place-items: center;
  padding: 0.5rem;
  border: 2px dashed var(--cor-borda);
  border-radius: 9px;
  background: var(--cor-fundo);
  color: var(--cor-primaria);
  font-size: 0.88rem;
  font-weight: 600;
  text-align: center;
  text-decoration: none;
}

.ladrilho-novo > a:hover,
.ladrilho-novo > a:focus-visible {
  border-color: var(--cor-primaria);
}

.ladrilho-mais {
  font-size: 1.7rem;
  line-height: 1;
}

/* --- A etiqueta de situação --------------------------------------------- */

.etiqueta-estado {
  display: inline-block;
  margin-top: 0.25rem;
  padding: 0.05rem 0.45rem;
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 700;
}

.etiqueta-publicado {
  background: var(--cor-sucesso-fundo);
  color: var(--cor-sucesso);
}

.etiqueta-rascunho {
  background: var(--selo-rascunho-fundo);
  color: var(--selo-rascunho-texto);
}

.etiqueta-nenhum {
  background: var(--cor-fundo);
  color: var(--cor-texto-suave);
}

/* --- A linha (áudio e documento) ---------------------------------------- */

.lista-linhas {
  margin: 0;
  padding: 0;
  list-style: none;
}

.linha-midia {
  display: flex;
  gap: 0.85rem;
  align-items: center;
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--cor-borda);
}

.linha-midia:last-child {
  border-bottom: 0;
}

.linha-midia-selo {
  display: grid;
  flex: none;
  place-items: center;
  width: 2.9rem;
  height: 2.9rem;
  border: 1px solid var(--cor-borda);
  border-radius: 8px;
  background: var(--cor-fundo);
  color: var(--cor-texto-suave);
  font-size: 0.68rem;
  font-weight: 700;
}

.linha-midia-texto {
  display: block;
  flex: 1 1 auto;
  min-width: 0;
}

.linha-midia-nome {
  display: block;
  overflow: hidden;
  font-weight: 600;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.linha-midia .tocador {
  flex: none;
  width: 15rem;
  max-width: 40vw;
  margin: 0;
}

.linha-midia-editar {
  flex: none;
}

/* --- O modal de edição --------------------------------------------------- */

/*
  Mesma tecnica da confirmacao de exclusao: :target, sem uma linha de
  JavaScript. Ver a nota em partials/confirmar.ejs.

  O QUE ACONTECE DEPOIS DE SALVAR: o formulario e enviado, o servidor grava e
  manda de volta para o endereco da tela SEM o pedaco depois do "#". Sem
  destino, nenhum modal e alvo, e a tela volta com a secao aberta, a faixa
  verde de "salvo" no alto e a janelinha fechada. Nao ha truque nenhum nisso —
  e so o endereco de volta nao ter ancora.

  A margem zero NAO e arrumacao: o seletor ".conteudo > * + *" do alto deste
  arquivo poe margem em todo irmao dentro do conteudo, e num elemento fixo a
  margem vira deslocamento — foi o que uma vez desceu a foto ampliada e
  deixou uma faixa da pagina aparecendo por cima do fundo escuro.
*/
.midia-modal {
  display: none;
  margin: 0;
}

.midia-modal:target {
  display: flex;
  position: fixed;
  z-index: 50;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  background: var(--veu-da-janela);
  inset: 0;
}

/* A janelinha de enviar tem dois campos: na largura das outras ela ficaria
   com um campo de arquivo perdido no meio de muito branco. */
.midia-caixa-estreita {
  width: min(30rem, 100%);
}

.midia-caixa {
  width: min(43rem, 100%);
  max-height: 92vh;
  overflow-y: auto;
  border-radius: 12px;
  background: var(--cor-superficie);
  box-shadow: var(--sombra-janela);
}

.midia-caixa-topo {
  display: flex;
  gap: 1rem;
  align-items: center;
  justify-content: space-between;
  padding: 0.9rem 1.15rem;
  border-bottom: 1px solid var(--cor-borda);
}

.midia-caixa-topo h2 {
  margin: 0;
  font-size: 1.1rem;
  display: flex;
  align-items: center;
  gap: 0.1rem;
}

/* O X no alto e o terceiro jeito de fechar, e nao o unico: o Cancelar no
   rodape e o clique no fundo escuro fazem o mesmo. Tres portas porque cada
   pessoa procura a sua. */
.midia-fechar {
  display: grid;
  flex: none;
  place-items: center;
  width: 2.1rem;
  height: 2.1rem;
  border: 1px solid var(--cor-borda);
  border-radius: 50%;
  color: var(--cor-texto);
  text-decoration: none;
}

.midia-fechar:hover,
.midia-fechar:focus-visible {
  background: var(--cor-primaria);
  color: var(--cor-superficie);
}

.midia-caixa-corpo {
  display: grid;
  gap: 0.9rem;
  padding: 1.15rem;
}

.midia-previa {
  display: grid;
  place-items: center;
  padding: 0.75rem;
  border-radius: 9px;
  background: var(--cor-fundo);
}

.midia-previa img,
.midia-previa-video {
  max-width: 100%;
  max-height: 13rem;
  border-radius: 6px;
}

.midia-previa .tocador {
  margin: 0;
}

.midia-duas-colunas {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.9rem;
}

.midia-ficha {
  margin: 0;
}

.midia-caixa-rodape {
  display: flex;
  gap: 0.6rem;
  align-items: center;
  flex-wrap: wrap;
  padding: 0.9rem 1.15rem;
  border-top: 1px solid var(--cor-borda);
  background: var(--cor-fundo);
  margin: 0 -1.15rem -1.15rem;
}

/* Empurra o que vem depois para a direita: o que fica na esquerda e a acao
   perigosa, e a distancia entre ela e o Salvar e proposital. */
.midia-rodape-espaco {
  flex: 1 1 auto;
  min-width: 0;
}

/* Os botoes do rodape sao menores que os da tela.
   Sao ate quatro deles na mesma linha — a acao perigosa, o atalho, o cancelar
   e o salvar — e no tamanho normal a linha estourava a largura da janelinha e
   o "Salvar e publicar" caia sozinho numa segunda linha, parecendo outra
   coisa. */
.midia-caixa-rodape .botao {
  padding: 0.45rem 0.8rem;
  font-size: 0.92rem;
}

/* --- Tela estreita ------------------------------------------------------- */

@media (max-width: 700px) {
  /* A amostra sai: no celular ela disputaria a largura com o nome da secao, e
     o nome ganha. */
  .secao-midia-amostra {
    display: none;
  }

  /*
    No celular a barra vira duas linhas: nome e seta em cima, contagem embaixo.

    A ordem trocada e o que segura a seta na primeira linha — sem ela, a
    contagem quebrava a linha e empurrava a seta sozinha para uma TERCEIRA
    linha, e cada secao fechada ocupava a altura de tres.

    QUEM RECEBE ESTAS REGRAS E O <h2>, e nao o <summary>: desde que o titulo
    passou a morar dentro do resumo (exigencia do HTML), e ele quem alinha os
    pedacos em fila. Enderecadas ao <summary>, elas nao pegavam em nada, e o
    texto da contagem estourava a largura da tela em 320px.
  */
  .secao-sanfona-titulo {
    flex-wrap: wrap;
    gap: 0.35rem 0.6rem;
  }

  .secao-sanfona-nome {
    flex: 1 1 auto;
    min-width: 0;
  }

  .secao-sanfona-seta {
    order: 2;
  }

  .secao-sanfona-conta {
    order: 3;
    flex-basis: 100%;
    margin-left: 3.1rem;
  }

  .midia-duas-colunas {
    grid-template-columns: minmax(0, 1fr);
  }

  .linha-midia .tocador {
    display: none;
  }

  .prateleira-topo {
    flex-wrap: wrap;
    gap: 0.4rem;
  }

  /* No celular não há largura para o botão flutuar ao lado do nome: ele volta
     para o fluxo, embaixo da barra, ocupando a linha inteira. */
  .secao-sanfona-barra {
    padding-right: 1.1rem;
  }

  .secao-sanfona-acoes {
    position: static;
    justify-content: flex-end;
    margin: 0 1.1rem 0.9rem;
  }
}

/* --- Audios informativos ------------------------------------------------ */

/* O tocador nasce estreito e desalinhado do resto: o navegador desenha ele
   mesmo, com a largura que quiser. Aqui ele passa a acompanhar a coluna de
   texto, como qualquer outro bloco da pagina. */
.tocador {
  display: block;
  width: 100%;
  max-width: 32rem;
  margin-top: 0.7rem;
}

.tocador-grande {
  max-width: 40rem;
  margin-top: 1rem;
}

/* --- Galeria publica: grade de fotos e foto ampliada -------------------- */

/* A grade da galeria e a mesma .galeria da biblioteca, com duas diferencas:
   os quadros sao maiores (aqui a foto E o conteudo, nao um icone de arquivo)
   e a foto preenche o quadro em vez de caber dentro dele. */
.galeria-fotos {
  grid-template-columns: repeat(auto-fill, minmax(min(240px, 100%), 1fr));
  gap: 1.1rem;
  /* Cada cartao com a altura do proprio conteudo. Sem isto, todos na mesma
     linha esticam ate a altura do maior, e a foto sem legenda fica com uma
     tira branca embaixo, do tamanho da legenda do vizinho. */
  align-items: start;
}

.galeria-fotos .item-galeria {
  padding: 0;
  overflow: hidden;
}

.galeria-fotos .item-visual {
  height: 190px;
  border-radius: 0;
}

/* object-fit: cover corta a sobra em vez de deformar. Uma grade de fotos com
   proporcoes diferentes ou fica irregular, ou deforma o que mostra — e foto
   de pessoa esticada e o tipo de defeito que ninguem deixa passar. */
.galeria-fotos .item-visual img {
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  object-fit: cover;
  transition: transform 0.2s ease;
}

.galeria-fotos .item-visual:hover img,
.galeria-fotos .item-visual:focus img {
  transform: scale(1.04);
}

.galeria-fotos .item-nome {
  margin: 0;
  padding: 0.55rem 0.7rem;
  color: var(--cor-texto-suave);
  font-weight: 500;
  white-space: normal;
}

/* --- Galeria: a lista de albuns do gerenciamento ------------------------ */

.galeria-albuns {
  grid-template-columns: repeat(auto-fill, minmax(min(270px, 100%), 1fr));
  align-items: start;
}

.galeria-albuns .item-galeria {
  padding: 0;
  overflow: hidden;
}

.galeria-albuns .item-visual {
  height: 160px;
  border-radius: 0;
}

.galeria-albuns .item-visual img {
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  object-fit: cover;
}

/* Album sem foto ainda tem cartao: ele existe, esta sendo montado, e sumir da
   lista seria pior do que aparecer sem capa. */
.item-sem-capa {
  color: var(--cor-texto-suave);
  font-size: 0.85rem;
  font-style: italic;
}

/* Rascunho e arquivado com a capa esmaecida: da para percorrer a grade e ver
   de longe o que esta no ar e o que nao esta, sem ler selo nenhum. */
.item-inativo .item-visual img {
  opacity: 0.55;
}

.album-cartao-texto {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  padding: 0.7rem 0.7rem 0;
}

.album-cartao-nome {
  margin: 0;
  font-size: 1rem;
  line-height: 1.3;
  /* Nome longo quebra em vez de empurrar a coluna e criar rolagem lateral. */
  overflow-wrap: break-word;
}

/* Descricao longa cortada em tres linhas: o cartao serve para reconhecer o
   album, nao para ler o texto inteiro — que esta na tela do album. */
.album-cartao-descricao {
  display: -webkit-box;
  overflow: hidden;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
}

.galeria-albuns .acoes-linha {
  gap: 0.4rem;
  padding: 0.7rem;
}

/* --- Escolher a ordem fora de uma tabela -------------------------------- */

.ordenacao {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 0.9rem;
  align-items: baseline;
  margin-bottom: 1rem;
}

.ordenacao-rotulo {
  color: var(--cor-texto-suave);
  font-size: 0.85rem;
  font-weight: 600;
}

/* A lista de fotos DENTRO do gerenciamento.
   Colunas mais largas que as da biblioteca porque cada cartao carrega, alem
   da foto, um campo de legenda e quatro botoes: em 170px o campo de legenda
   fica do tamanho de tres letras e os botoes empilham um sobre o outro. */
.galeria-edicao {
  grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr));
}

.galeria-edicao .campo {
  width: 100%;
  margin: 0;
}

/* A miniatura preenche o cartao, como no portal: quem monta o album precisa
   ver o mesmo enquadramento que o cidadao vai ver. Com "contain" sobrava uma
   tira cinza dos dois lados e a foto parecia menor do que e. */
.galeria-edicao .item-visual {
  height: 150px;
  border-radius: 0;
}

.galeria-edicao .item-visual img {
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  object-fit: cover;
}

.galeria-edicao .item-galeria {
  padding: 0;
  overflow: hidden;
}

.galeria-edicao .item-dados,
.galeria-edicao > .item-galeria > form,
.galeria-edicao .acoes-linha {
  padding-right: 0.7rem;
  padding-left: 0.7rem;
}

.galeria-edicao .acoes-linha {
  padding-bottom: 0.7rem;
  gap: 0.35rem;
}

.galeria-edicao .campo label {
  font-size: 0.78rem;
}

.galeria-edicao .campo input {
  width: 100%;
  padding: 0.35rem 0.5rem;
  font-size: 0.85rem;
}

.galeria-edicao .acoes-linha form {
  margin: 0;
}

.galeria-edicao > .item-galeria > form {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  align-items: stretch;
}

.galeria-edicao > .item-galeria > form button {
  align-self: flex-start;
}

/* A foto ampliada.
   Fica escondida ate o endereco da pagina apontar para ela (#foto-xxx), e o
   :target e quem acende. Sem script nenhum: e a mesma tecnica dos avisos de
   confirmacao do gerenciamento. */
.foto-modal {
  position: fixed;
  z-index: 60;
  display: none;
  inset: 0;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  /*
     A margem ZERO nao e redundante, e a correcao de um defeito de verdade.

     A regra ".conteudo > * + *" da 20px de respiro entre as secoes de
     qualquer tela, e a foto ampliada e filha direta do conteudo. Numa caixa
     fixa com "inset: 0", esses 20px NAO viram espaco: viram deslocamento. A
     ampliacao descia 20px e a faixa do topo ficava de fora do escurecido,
     como se a tela nao estivesse mesmo esperando uma resposta.
  */
  margin: 0;
  /* Janela baixa — notebook antigo, celular deitado — rola dentro da propria
     ampliacao em vez de esconder o botao Fechar. */
  overflow: auto;
}

.foto-modal:target {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
}

/* O fundo escurecido, que tambem fecha ao ser clicado. Ele cobre a tela
   inteira por tras da foto — por isso inset: 0 e z-index menor que o da
   caixa. */
.foto-fundo {
  position: absolute;
  z-index: 0;
  inset: 0;
  background: var(--fundo-da-galeria);
}

.foto-caixa {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  max-width: min(1000px, 100%);
  margin: 0;
}

/* A foto nunca passa da tela: 80vh de altura maxima deixa espaco para a
   legenda e para os botoes, que precisam caber junto — foto que empurra o
   botao Fechar para fora da tela e foto da qual nao se sai sem o teclado. */
.foto-caixa img {
  max-width: 100%;
  max-height: 72vh;
  border-radius: var(--raio);
  object-fit: contain;
}

.foto-caixa figcaption {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  align-items: baseline;
  /* Centralizado, e nao nas duas pontas: a legenda acompanha a largura da
     caixa, que e maior que a foto quando a foto e alta e estreita. Nas pontas,
     o "3 de 12" ficava boiando longe da imagem, sem relacao visivel com ela. */
  justify-content: center;
  column-gap: 1rem;
  color: var(--cor-sobre-primaria);
  font-size: 0.95rem;
  text-align: center;
}

.foto-contagem {
  color: color-mix(in srgb, var(--cor-sobre-primaria) 75%, transparent);
  font-size: 0.85rem;
  white-space: nowrap;
}

.foto-controles {
  position: relative;
  z-index: 1;
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  justify-content: center;
}

/* O botao secundario do portal e claro com letra azul: sobre o fundo
   escurecido da ampliacao, ele praticamente some. Aqui ele inverte. */
.foto-controles .botao-secundario {
  border-color: color-mix(in srgb, var(--cor-sobre-primaria) 55%, transparent);
  background: color-mix(in srgb, var(--cor-sobre-primaria) 12%, transparent);
  color: var(--cor-sobre-primaria);
}

.foto-controles .botao-secundario:hover,
.foto-controles .botao-secundario:focus {
  border-color: var(--cor-sobre-primaria);
  background: color-mix(in srgb, var(--cor-sobre-primaria) 22%, transparent);
  color: var(--cor-sobre-primaria);
}

@media (max-width: 640px) {
  .foto-modal {
    padding: 0.8rem;
  }

  .foto-caixa img {
    max-height: 62vh;
  }

  .galeria-fotos .item-visual {
    height: 210px;
  }
}

/* Movimento reduzido: quem marcou essa preferencia no sistema operacional
   pediu para nada se mexer sozinho na tela. */
@media (prefers-reduced-motion: reduce) {
  .galeria-fotos .item-visual img {
    transition: none;
  }

  .galeria-fotos .item-visual:hover img,
  .galeria-fotos .item-visual:focus img {
    transform: none;
  }
}

/* --- Noticias: listagem publica ---------------------------------------- */

.lista-noticias {
  display: grid;
  gap: 1.25rem;
  margin-bottom: 1.5rem;
}

.cartao-noticia {
  display: grid;
  grid-template-columns: 260px 1fr;
  gap: 1.25rem;
  align-items: start;
  padding: 1.25rem;
  background: var(--cor-superficie);
  border: 1px solid var(--cor-borda);
  border-radius: 8px;
}

.cartao-noticia:has(> .cartao-noticia-texto:only-child) {
  grid-template-columns: 1fr;
}

.cartao-noticia-capa {
  display: block;
  overflow: hidden;
  border-radius: 6px;
  background: var(--cor-vazio);
}

.cartao-noticia-capa img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}

.cartao-noticia-texto h2,
.cartao-noticia-texto h3 {
  margin: 0.25rem 0 0.5rem;
  font-size: 1.25rem;
  line-height: 1.3;
}

.cartao-noticia-texto h2 a,
.cartao-noticia-texto h3 a {
  color: var(--cor-link);
  text-decoration: none;
}

.cartao-noticia-texto h2 a:hover,
.cartao-noticia-texto h2 a:focus,
.cartao-noticia-texto h3 a:hover,
.cartao-noticia-texto h3 a:focus {
  text-decoration: underline;
}

.cartao-noticia-texto p {
  margin: 0;
  color: var(--cor-texto-leitura);
  line-height: 1.55;
}

.noticia-meta {
  margin: 0;
  font-size: 0.85rem;
  color: var(--cor-texto-ajuda);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

@media (max-width: 640px) {
  .cartao-noticia {
    grid-template-columns: 1fr;
  }
}

/* --- Noticia: pagina da publicacao ------------------------------------- */

.noticia {
  max-width: 46rem;
  margin: 0 auto 2rem;
}

.noticia-cabecalho h1 {
  margin: 0.5rem 0;
  font-size: 2rem;
  line-height: 1.2;
  color: var(--cor-link);
}

.noticia-resumo {
  margin: 0;
  font-size: 1.1rem;
  color: var(--cor-texto-leitura);
  line-height: 1.55;
}

.noticia-capa {
  margin: 1.5rem 0;
}

/* A capa na pagina da noticia tem a MESMA proporcao dos cartoes da lista e
   do aplicativo: 16:9, recortada ao centro. Sem isto, foto tirada com o
   celular em pe ocupava a tela inteira antes do primeiro paragrafo (teste do
   Modulo 13, 21/09). O recorte e so na exibicao: o arquivo continua inteiro
   na biblioteca. */
.noticia-capa img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: 8px;
  background: var(--cor-vazio);
}

.noticia-corpo p {
  margin: 0 0 1rem;
  line-height: 1.7;
  color: var(--cor-texto-forte);
}

.evento {
  margin: 1.5rem 0;
  padding: 1rem 1.25rem;
  background: var(--cor-realce-fundo);
  border-left: 4px solid var(--cor-link);
  border-radius: 4px;
}

.evento h2 {
  margin: 0 0 0.5rem;
  font-size: 1rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--cor-link);
}

.midias {
  margin-top: 2rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--cor-borda);
}

.midias h2 {
  font-size: 1.1rem;
  margin: 0 0 1rem;
}

.midia {
  margin: 0 0 1.5rem;
}

.midia img,
.midia video {
  display: block;
  width: 100%;
  border-radius: 6px;
  background: var(--cor-video-fundo);
}

.midia audio {
  width: 100%;
}

.midia figcaption {
  margin-top: 0.4rem;
  font-size: 0.9rem;
  color: var(--cor-texto-ajuda);
}

.midia-documento {
  display: flex;
  gap: 0.75rem;
  align-items: center;
  padding: 0.75rem 1rem;
  border: 1px solid var(--cor-borda);
  border-radius: 6px;
  color: var(--cor-link);
  text-decoration: none;
}

.midia-documento:hover,
.midia-documento:focus {
  background: var(--cor-realce-fundo);
}

/* --- Selos e filtros ---------------------------------------------------- */

.selo {
  display: inline-block;
  padding: 0.1rem 0.45rem;
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  vertical-align: middle;
}

.selo-evento {
  background: var(--selo-sucesso-fundo);
  color: var(--cor-sucesso);
}

.selo-destaque {
  background: var(--selo-atencao-fundo);
  color: var(--selo-atencao-texto);
}

.filtros {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.75rem;
}

.filtros a {
  padding: 0.3rem 0.75rem;
  border: 1px solid var(--cor-borda);
  border-radius: 999px;
  font-size: 0.9rem;
  color: var(--cor-link);
  text-decoration: none;
}

.filtros a:hover,
.filtros a:focus {
  background: var(--cor-realce-fundo);
}

.filtros a[aria-current='page'] {
  background: var(--cor-link);
  border-color: var(--cor-link);
  color: var(--cor-sobre-primaria);
}

/* --- Formulario de conteudo -------------------------------------------- */

.campo textarea {
  width: 100%;
  padding: 0.6rem 0.7rem;
  font: inherit;
  color: var(--cor-texto-forte);
  background: var(--cor-superficie);
  border: 1px solid var(--cor-borda-forte);
  border-radius: 4px;
  resize: vertical;
}

.campo textarea:focus-visible {
  outline: 3px solid var(--cor-link);
  outline-offset: 1px;
}

/* O TEXTO DE APOIO FICA NA LINHA DE BAIXO, inclusive quando e um <span>.
 *
 * A regra tinha so margem — e margem vertical nao faz nada num elemento
 * inline. Em <p> funcionava; nos SESSENTA E QUATRO <span> espalhados por
 * dezoito telas, nao: o texto de apoio grudava no valor principal. Na lista da
 * frota a celula saia "desde 17/10/2024 2022", com a data de entrada e o ano
 * de fabricacao colados um no outro.
 *
 * O `display: block` e o que faz as duas linhas existentes passarem a valer.
 * E a mesma correcao do `.campo-marcavel`, que dizia `flex-direction` sem
 * dizer `display: flex`: regra escrita para um contexto que nunca chegou. */
.campo-ajuda {
  display: block;
  margin: 0.35rem 0 0;
  font-size: 0.85rem;
  color: var(--cor-texto-ajuda);
}

.campo-opcional {
  font-weight: 400;
  color: var(--cor-texto-ajuda);
}

/* A CAIXA DE MARCAR AO LADO DO ROTULO, e nao em cima dele.
   
   Esta regra dizia `flex-direction: row` — e `flex-direction` so faz alguma
   coisa dentro de um elemento que JA seja flex. O `.campo`, que vem sempre
   junto, e um bloco comum (so tem margem). Entao a direcao nao era aplicada, o
   `.campo label { display: block }` punha o rotulo na linha de baixo, e a
   caixinha ficava sozinha em cima — em toda tela que usa esta classe, desde
   que ela foi escrita.
   
   O `display: flex` que faltava e o que faz as outras tres linhas passarem a
   valer. */
.campo-marcavel {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 0.5rem;
}

.campo-marcavel label {
  margin: 0;
}

.campo-marcavel input {
  width: auto;
}

.bloco {
  margin: 0;
  padding: 1rem 1.25rem;
  border: 1px solid var(--cor-borda);
  border-radius: 6px;
}

/* NO GERENCIAMENTO, O BLOCO SOLTO NA TELA É UM CARTÃO COMO OS OUTROS
   (KAN-168). Doze telas (Dados institucionais, Emendas, Serviço, Sigilo…)
   usavam .bloco direto no <main>: fundo transparente e colado no bloco de
   baixo, enquanto as vizinhas usam o cartão branco com a faixa (.aviso). O
   .bloco de dentro de formulário (fieldset) continua como era. */
.conteudo-admin > section.bloco {
  padding: 22px;
  border-left: 4px solid var(--cor-destaque);
  border-radius: var(--raio);
  background: var(--cor-superficie);
}
.conteudo-admin > * + section.bloco {
  margin-top: 1.25rem;
}

.bloco legend {
  padding: 0 0.4rem;
  font-weight: 600;
  color: var(--cor-link);
}

.acoes-linha {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  align-items: center;
}

/* --- Busca --------------------------------------------------------------- */

/* BUSCA E MENU NA MESMA LINHA, como no Rio — e não um embaixo do outro.

   Empilhados, os dois somavam 74px de altura e empurravam o cabeçalho para
   110px. Lado a lado, o item mais alto do cabeçalho volta a ser a marca, e o
   topo fecha nos 98px do Rio sem apertar nada.

   Em tela estreita eles voltam a empilhar sozinhos pelo flex-wrap — ver a
   regra de 900px mais abaixo. */
.cabecalho-direita {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 0.6rem 1.5rem;
}

/* A CAIXA DE BUSCA É UMA PASTILHA BRANCA ÚNICA, com a lupa dentro.

   Antes eram dois retângulos separados — o campo e um botão escrito "Buscar".
   No print do Rio é uma peça só, de 34px de altura, com a lupa encostada na
   borda direita. O botão continua existindo e continua sendo um <button> de
   verdade: sem JavaScript, apertar Enter no campo ou clicar na lupa faz a
   mesma coisa. O que mudou foi que a palavra "Buscar" saiu da tela e ficou só
   para o leitor de tela — a lupa diz isso a quem enxerga, e o texto escondido
   diz a quem não enxerga. */
.busca-topo {
  display: flex;
  align-items: center;
  height: 34px;
  overflow: hidden;
  background: var(--cor-superficie);
  border: 1px solid var(--cor-borda-forte);
  /* PASTILHA REDONDA, como a do Rio: o canto reto fazia a busca parecer um
     campo de formulario esquecido dentro da faixa azul, e nao um atalho. O
     raio e 999px em vez de uma medida fixa para acompanhar a altura, inclusive
     quando a pessoa aumenta a letra pelo painel de acessibilidade. */
  border-radius: 999px;
}

.busca-topo input {
  width: 9.5rem;
  max-width: 100%;
  height: 100%;
  /* Com a pastilha redonda o texto precisa de mais folga a esquerda, senao a
     primeira letra encosta na curva. */
  padding: 0 0.1rem 0 1rem;
  font: inherit;
  font-size: 0.85rem;
  color: var(--cor-texto-forte);
  background: transparent;
  border: 0;
}

.busca-topo input:focus {
  outline: none;
}

.busca-topo button {
  display: grid;
  place-items: center;
  width: 2.2rem;
  height: 100%;
  padding: 0;
  color: var(--cor-link);
  background: transparent;
  border: 0;
  cursor: pointer;
}

.busca-topo button svg {
  width: 1rem;
  height: 1rem;
}

.busca-topo button:hover {
  background: var(--cor-realce-fundo);
}

/* A pastilha inteira ganha o anel de foco quando o foco está em qualquer peça
   dentro dela: com o campo sem borda própria, o anel só no <input> ficaria
   escondido atrás da pastilha. */
.busca-topo:focus-within {
  outline: 2px solid var(--cor-sobre-primaria);
  outline-offset: 2px;
}

.resultados {
  margin: 0;
  padding: 0;
  list-style: none;
}

.resultado {
  padding: 1rem 0;
  border-top: 1px solid var(--cor-borda);
}

.resultado:first-child {
  border-top: none;
}

.resultado h3 {
  margin: 0.25rem 0 0.4rem;
  font-size: 1.15rem;
  line-height: 1.3;
}

.resultado h3 a {
  color: var(--cor-link);
  text-decoration: none;
}

.resultado h3 a:hover,
.resultado h3 a:focus {
  text-decoration: underline;
}

.resultado-trecho {
  margin: 0;
  color: var(--cor-texto-leitura);
  line-height: 1.6;
}

.resultado-trecho mark {
  padding: 0 0.15rem;
  background: var(--cor-marca-texto);
  color: inherit;
  font-weight: 600;
}

.selo-fonte {
  background: var(--cor-realce-fundo-forte);
  color: var(--cor-link);
}

@media (max-width: 720px) {
  .cabecalho-direita {
    align-items: stretch;
    width: 100%;
  }

  .busca-topo input {
    width: 100%;
  }
}

/* --- Exportacao de relatorios ------------------------------------------- */

.exportar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.5rem;
  align-items: center;
  margin: 0 0 1rem;
}

.exportar-linha {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
  margin: 0;
}

.campo-embutido {
  padding: 0.3rem 0.5rem;
  font: inherit;
  font-size: 0.85rem;
  color: var(--cor-texto-forte);
  background: var(--cor-superficie);
  border: 1px solid var(--cor-borda-forte);
  border-radius: 4px;
}

.exportar-rotulo {
  font-size: 0.85rem;
  color: var(--cor-texto-ajuda);
}

/* --- Tarefas de segundo plano ------------------------------------------- */

.selo-na_fila {
  background: var(--cor-realce-fundo-forte);
  color: var(--cor-link);
}

.selo-executando {
  background: var(--selo-atencao-fundo);
  color: var(--selo-atencao-texto);
}

.selo-concluida {
  background: var(--selo-sucesso-fundo);
  color: var(--cor-sucesso);
}

.selo-falhou {
  background: var(--selo-erro-fundo);
  color: var(--selo-erro-texto);
}

/* --- Componentes do ambiente de gerenciamento (F-10, parte 2) ----------- */

/*
  A mensagem que o portal dá de volta a quem acabou de fazer alguma coisa.
  Três aparências, um formato só.

  A marca da esquerda (✓, !, i) não é enfeite: quem não distingue verde de
  vermelho precisa de algo além da cor para saber se deu certo. É o mesmo
  motivo da borda grossa à esquerda, que já existia no aviso de erro.
*/
.mensagem {
  display: flex;
  gap: 0.6rem;
  align-items: flex-start;
  margin: 0 0 1rem;
  padding: 0.7rem 0.9rem;
  border: 1px solid;
  border-left-width: 4px;
  border-radius: var(--raio);
  font-weight: 600;
}

.mensagem-marca {
  flex-shrink: 0;
  width: 1.25rem;
  height: 1.25rem;
  line-height: 1.25rem;
  font-size: 0.8rem;
  text-align: center;
  color: var(--cor-superficie);
  border-radius: 50%;
}

.mensagem-sucesso {
  border-color: var(--cor-sucesso);
  background: var(--cor-sucesso-fundo);
  color: var(--cor-sucesso);
}

.mensagem-sucesso .mensagem-marca {
  background: var(--cor-sucesso);
}

.mensagem-erro .mensagem-marca {
  background: var(--cor-erro);
}

.mensagem-informacao {
  border-color: var(--cor-informacao);
  background: var(--cor-informacao-fundo);
  color: var(--cor-informacao);
}

.mensagem-informacao .mensagem-marca {
  background: var(--cor-informacao);
}

/* --- Busca das listagens ------------------------------------------------ */

.busca-listagem {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  align-items: flex-end;
  margin: 0 0 0.75rem;
}

.busca-listagem .campo {
  flex: 1 1 18rem;
  margin: 0;
}

/* A ajuda da busca vai numa linha própria, embaixo do campo e do botão: dentro
   do campo, ela empurrava o campo para cima e o botão ficava desalinhado. E a
   busca ocupa a largura inteira mesmo dentro de uma fileira de filtros. */
.busca-listagem > .campo-ajuda {
  flex-basis: 100%;
  margin: 0;
}
.filtros > .busca-listagem {
  flex-basis: 100%;
}

/* --- Cabeçalho de coluna que ordena ------------------------------------- */

.coluna-ordenavel {
  display: inline-flex;
  gap: 0.35rem;
  align-items: center;
  color: inherit;
  text-decoration: none;
  white-space: nowrap;
}

.coluna-ordenavel:hover,
.coluna-ordenavel:focus-visible {
  text-decoration: underline;
}

/*
  A seta da coluna que não está ordenando fica apagada, mas continua na tela.
  Some-la só na coluna ativa resolveria a poluição visual e criaria outro
  problema: sem nenhuma marca, ninguém descobre que dá para clicar ali.
*/
.coluna-seta {
  font-size: 0.7rem;
  opacity: 0.35;
}

.coluna-ordenada .coluna-seta {
  opacity: 1;
}

.coluna-ordenada {
  color: var(--cor-primaria);
}

/* --- Paginação ---------------------------------------------------------- */

.paginacao {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  align-items: center;
  margin-top: 1rem;
  font-size: 0.9rem;
}

.paginacao-posicao {
  color: var(--cor-texto-suave);
}

.paginacao-total {
  color: var(--cor-texto-suave);
  font-size: 0.85rem;
}

/*
  O "Anterior" da primeira página fica visível e apagado, em vez de sumir.
  Botão que aparece e desaparece conforme a página faz o resto da linha
  dançar de lugar a cada virada — e quem clica rápido erra o alvo.
*/
.paginacao-vazio {
  padding: 0.3rem 0.7rem;
  /* Cinza que ainda passa no contraste minimo de 4,5:1. A versao anterior
     usava opacidade, e opacidade rebaixa o contraste sem avisar: a auditoria
     automatizada reprovou exatamente esta linha. */
  color: var(--cor-apagado);
  font-size: 0.85rem;
}

/* --- Confirmação de exclusão (modal sem JavaScript) --------------------- */

.botao-perigo {
  border-color: var(--cor-erro);
  color: var(--cor-erro);
}

a.botao-perigo:hover,
a.botao-perigo:focus-visible,
button.botao-perigo:hover,
button.botao-perigo:focus-visible {
  background: var(--cor-erro);
  color: var(--cor-superficie);
}

button.botao-perigo {
  background: var(--cor-erro);
  color: var(--cor-superficie);
}

/*
  O modal fica escondido ate ser o destino do endereco.

  :target e o seletor que diz "este elemento e o pedaco da pagina para onde o
  endereco aponta agora". O botao e um link para ele; o Cancelar e um link
  para lugar nenhum. E o modal inteiro, abrir e fechar, sem uma linha de
  JavaScript — o que importa porque isto guarda uma exclusao.
*/
.confirmar-modal {
  display: none;
}

.confirmar-modal:target {
  display: flex;
  position: fixed;
  inset: 0;
  z-index: 50;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  /* O fundo escurecido nao e enfeite: e o que deixa claro que o resto da tela
     esta esperando uma resposta. */
  background: var(--veu-da-janela);
}

.confirmar-caixa {
  width: min(26rem, 100%);
  padding: 1.25rem;
  text-align: left;
  background: var(--cor-superficie);
  border-top: 4px solid var(--cor-erro);
  border-radius: var(--raio);
  box-shadow: var(--sombra-janela);
}

.confirmar-pergunta {
  margin: 0 0 0.5rem;
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--cor-texto);
}

.confirmar-detalhe {
  margin: 0 0 1rem;
  font-size: 0.9rem;
  color: var(--cor-texto-suave);
}

/* --- Foco visível, um só para o portal inteiro (F-11) -------------------- */

/*
  O anel de foco tem DUAS cores, e isso não é enfeite.

  A exigência é que o indicador de foco tenha contraste de pelo menos 3:1
  contra o que está atrás dele. O problema é que o portal tem fundo branco no
  miolo e azul-escuro no cabeçalho — e não existe uma cor só que contraste bem
  com os dois. Testei laranja, roxo, verde e vinho: cada uma passa num fundo e
  falha no outro.

  A saída é um anel branco por dentro e um anel escuro por fundo. No branco,
  quem se vê é o escuro; no azul do cabeçalho, quem se vê é o branco. Um dos
  dois sempre aparece, qualquer que seja o fundo.

  :focus-visible, e não :focus: o navegador só marca quando o foco veio do
  teclado. Quem clica com o mouse não ganha um anel que não pediu.
*/
:focus-visible {
  outline: 3px solid var(--foco-interno);
  outline-offset: 0;
  box-shadow: 0 0 0 6px var(--foco-externo);
  border-radius: 2px;
}

/*
  O miolo da página recebe foco ao se usar o "Pular para o conteúdo", mas não
  entra na ordem do Tab: tabindex="-1" no HTML faz isso. Sem o anel aqui — a
  página inteira contornada de azul assusta e não informa nada.
*/
main:focus-visible {
  outline: none;
  box-shadow: none;
}

/* --- Controles de acessibilidade do cidadão ------------------------------

   O DESENHO ANTIGO FOI REMOVIDO DAQUI (15/09). Eram oito botões chapados numa
   barra no topo; viraram um painel que abre, e o painel tem o seu próprio
   bloco mais abaixo ("O painel de acessibilidade no topo").

   As regras velhas continuaram no arquivo depois da troca e seguiam valendo
   naquilo que o bloco novo não redefine — uma borda branca de 1px em cada
   item, nowrap e peso 600 de letra, tudo invisível sobre fundo branco e
   pronto para aparecer no primeiro tema escuro. Dois blocos disputando o
   mesmo nome é o jeito mais rápido de fazer um ajuste de CSS "não funcionar".

   As regras de ALTO CONTRASTE para .acessibilidade-botao seguem logo abaixo e
   continuam valendo: aquelas são do painel de hoje. */

/* --- Alto contraste ------------------------------------------------------ */

/*
  Preto e branco, com links em amarelo. Não é "o tema escuro": é o modo que
  uma pessoa com baixa visão consegue ler, e por isso todas as combinações
  ficam acima de 12:1 — muito além dos 4,5:1 exigidos.

  Está escrito como troca de VARIÁVEIS, e não como regras novas para cada
  elemento. É o que faz o modo alcançar o portal inteiro, inclusive as telas
  que ainda nem foram escritas: quem usar as variáveis, como todo o resto deste
  arquivo faz, já nasce funcionando no alto contraste.
*/
html.contraste-alto {
  --cor-primaria: var(--contraste-realce);
  --cor-primaria-escura: var(--contraste-fundo);
  --cor-destaque: var(--contraste-realce);
  --cor-texto: var(--contraste-texto);
  --cor-texto-suave: var(--contraste-texto);
  --cor-apagado: #d0d0d0;
  --cor-borda: var(--contraste-texto);
  /* Rosa-claro e não o vermelho puro: #ff8080 dava 8,6:1 sobre o preto, e o
     card pede mais de 12:1 (KAN-113). Este dá 13,5:1. */
  --cor-erro: #ffc4c4;
  --cor-erro-fundo: var(--contraste-fundo);
  --cor-sucesso: #7cff7c;
  --cor-sucesso-fundo: var(--contraste-fundo);
  --cor-informacao: var(--contraste-realce);
  --cor-informacao-fundo: var(--contraste-fundo);
  /* O trilho vazio das barras era cinza-claro: a barra amarela por cima dele
     sumia (1,05:1). Agora é o próprio fundo, e o contorno do trilho mostra
     onde ele termina (regra dos gráficos logo abaixo). */
  --cor-vazio: var(--contraste-fundo);
  --cor-fundo: var(--contraste-fundo);
  --cor-superficie: var(--contraste-fundo);
  --foco-interno: var(--contraste-fundo);
  --foco-externo: var(--contraste-realce);
}

html.contraste-alto body {
  background: var(--contraste-fundo);
  color: var(--contraste-texto);
}

/* OS GRÁFICOS NO ALTO CONTRASTE (KAN-113). As séries saíam da cor principal
   misturada ao fundo: com o amarelo sobre o preto, a série 1 virava um
   amarelo-escuro de 3:1 — o gráfico parecia um bloco escuro. Aqui cada série
   ganha uma cor própria acima de 16:1, e o trilho vazio ganha contorno. */
html.contraste-alto .grafico-serie-1 {
  --cor-marca: var(--contraste-texto);
}
html.contraste-alto .grafico-serie-2 {
  --cor-marca: var(--contraste-realce-2);
}
html.contraste-alto .grafico-serie-3 {
  --cor-marca: var(--contraste-realce);
}
html.contraste-alto .barra-trilho,
html.contraste-alto .kpi-medidor {
  outline: 1px solid var(--contraste-texto);
}
html.contraste-alto .grafico-trilho {
  stroke: var(--contraste-texto);
  stroke-width: 1;
}
/* A amostra de cor da legenda ("■ Empenhado") é um <span> com fundo, e a
   regra geral do modo pinta todo fundo de preto: a legenda ficava sem a
   marca. Aqui ela volta a mostrar a cor da série. */
html.contraste-alto .grafico-amostra {
  background-color: var(--cor-marca) !important;
}

/*
  A regra que alcança TUDO, inclusive o que ainda não foi escrito.

  A primeira versão deste modo trocava só as variáveis de cor, o que é o jeito
  elegante — e não funcionou. O portal tem dezenas de cores escritas direto na
  regra, herdadas de antes das variáveis existirem: um cinza #444455 na data
  da notícia, um #667 no rodapé do cartão. Sobre fundo preto, esse cinza dá
  contraste de 2,2:1, metade do mínimo exigido, e a auditoria automatizada
  reprovou 26 pedaços só na tela de notícias.

  Daí o !important: aqui ele não é preguiça, é a definição do recurso. Alto
  contraste é a pessoa dizendo "ignore o que o site achou bonito, eu preciso
  ler". Uma regra que pode ser vencida por outra não cumpre isso — e a cada
  tela nova alguém teria que lembrar de conferir.

  A imagem fica de fora: inverter a foto da obra não ajuda ninguém a lê-la.
*/
html.contraste-alto *:not(img):not(svg):not(path) {
  background-color: var(--contraste-fundo) !important;
  color: var(--contraste-texto) !important;
  border-color: var(--contraste-texto) !important;
  text-shadow: none !important;
}

/* Link em amarelo: é a convenção de alto contraste que o Windows usa há
   trinta anos, e quem precisa do modo já a conhece. 19,6:1 sobre o preto. */
html.contraste-alto a:not(.botao),
html.contraste-alto summary,
html.contraste-alto .coluna-ordenavel {
  color: var(--contraste-realce) !important;
}

/*
  O "a" na frente de cada seletor nao e enfeite.

  A regra de cima pinta todo link de amarelo, e o seletor dela tem peso
  "elemento + duas classes". Escrito como ".acessibilidade-ligado", este bloco
  pesava menos e perdia — o botao de alto contraste ligado ficava com fundo
  amarelo e letra amarela, ou seja, um retangulo amarelo sem texto nenhum. Com
  o "a", os dois pesam igual, e vence quem vem depois: este.
*/
html.contraste-alto a:hover,
html.contraste-alto a:focus-visible,
html.contraste-alto a[aria-current='page'],
html.contraste-alto a.acessibilidade-ligado,
html.contraste-alto .botao:hover {
  background-color: var(--contraste-realce) !important;
  color: var(--contraste-fundo) !important;
  border-color: var(--contraste-realce) !important;
}

/*
  O fundo escurecido da foto ampliada e area de clique, e nao link de leitura.

  Como e um <a>, ele caia na regra de cima — link sob o mouse fica amarelo — e
  o resultado no alto contraste era a TELA INTEIRA amarela atras da foto, que e
  exatamente o contrario do que o modo serve para fazer. Aqui ele volta a ser o
  que e: preto atras da foto, com o mouse em cima ou nao.
*/
html.contraste-alto .foto-fundo,
html.contraste-alto .foto-fundo:hover,
html.contraste-alto .foto-fundo:focus-visible {
  background-color: var(--contraste-fundo) !important;
  border-color: var(--contraste-fundo) !important;
}

/* O texto de dica dentro dos campos ("Buscar no portal") tambem precisa ser
   legivel: ele nao e alcancado pela regra geral, porque e desenhado pelo
   navegador e nao pelo HTML. */
html.contraste-alto ::placeholder {
  color: var(--cor-apagado) !important;
  opacity: 1;
}

/* O anel de foco vira amarelo sobre preto: é o par de maior contraste que
   existe, e vem depois da regra geral para não ser apagado por ela. */
html.contraste-alto :focus-visible {
  outline: 3px solid var(--contraste-realce) !important;
  box-shadow: 0 0 0 6px var(--contraste-fundo) !important;
}

/* Onde o portal escreve cor fixa em vez de variável, o alto contraste
   corrige. São poucos pontos, e cada um deles é um lugar onde valeria a pena
   usar variável desde o começo. */
html.contraste-alto .cabecalho,
html.contraste-alto .faixa,
html.contraste-alto .rodape,
html.contraste-alto .destaque,
html.contraste-alto .aviso,
html.contraste-alto .tabela,
html.contraste-alto .menu-lateral,
html.contraste-alto .confirmar-caixa,
html.contraste-alto .cartao-noticia {
  background: var(--contraste-fundo);
  color: var(--contraste-texto);
}

html.contraste-alto a,
html.contraste-alto .menu a,
html.contraste-alto .coluna-ordenavel {
  color: var(--contraste-realce);
}

html.contraste-alto .botao,
html.contraste-alto .acessibilidade-botao,
html.contraste-alto .selo,
html.contraste-alto .campo input,
html.contraste-alto .campo select,
html.contraste-alto .campo textarea {
  background: var(--contraste-fundo);
  color: var(--contraste-texto);
  border: 1px solid var(--contraste-texto);
}

html.contraste-alto .botao:hover,
html.contraste-alto .acessibilidade-ligado {
  background: var(--contraste-realce);
  color: var(--contraste-fundo);
  border-color: var(--contraste-realce);
}

html.contraste-alto .menu a[aria-current='page'],
html.contraste-alto .menu-lateral a[aria-current='page'],
html.contraste-alto .filtros a[aria-current='page'] {
  background: var(--contraste-realce);
  color: var(--contraste-fundo);
}

/* O ÍCONE DO LINK REALÇADO (KAN-113). O ícone das seções é pintado com a cor
   principal — que no alto contraste é o amarelo. No item marcado da barra
   lateral (e em qualquer link sob o mouse), o fundo também vira amarelo, e o
   ícone e a seta sumiam: amarelo sobre amarelo, 1:1. Aqui eles acompanham a
   letra, preta. */
html.contraste-alto a[aria-current='page'] svg,
html.contraste-alto a[aria-current='page'] svg *,
html.contraste-alto a:hover svg,
html.contraste-alto a:hover svg *,
html.contraste-alto a:focus-visible svg,
html.contraste-alto a:focus-visible svg *,
html.contraste-alto .botao:hover svg,
html.contraste-alto .botao:hover svg * {
  color: var(--contraste-fundo) !important;
}

/*
  A janelinha precisa de contorno no alto contraste.

  Fora dele, o que separa o modal do resto e a SOMBRA — e sombra sobre fundo
  preto nao existe. Sem esta borda, a caixa preta ficaria em cima do fundo
  preto e a pessoa veria os campos flutuando no nada, sem saber onde a
  janelinha comeca e onde termina.
*/
html.contraste-alto .midia-caixa {
  border: 2px solid var(--contraste-texto);
}

html.contraste-alto .brasao {
  background: var(--contraste-fundo);
  color: var(--contraste-realce);
  border: 2px solid var(--contraste-realce);
}

/*
  A imagem não é desligada no alto contraste, mas ganha uma borda: sobre fundo
  preto, foto escura some, e a pessoa não descobre que havia uma foto ali.
*/
html.contraste-alto img {
  border: 1px solid var(--contraste-texto);
}

/* --- Telas estreitas: o portal precisa funcionar a partir de 320px ------- */

@media (max-width: 30rem) {
  .container {
    padding: 0 12px;
  }

  .faixa-conteudo {
    flex-wrap: wrap;
    gap: 0.4rem;
    justify-content: center;
    text-align: center;
  }

  .cabecalho-conteudo,
  .cabecalho-direita {
    flex-direction: column;
    align-items: stretch;
    gap: 0.75rem;
  }

  .menu {
    flex-wrap: wrap;
    justify-content: center;
  }

  .formulario-linha {
    flex-direction: column;
    align-items: stretch;
  }

  .campo,
  .campo-estreito {
    width: 100%;
    min-width: 0;
  }

  /*
    Em 320px, um botão por linha. Botões lado a lado nessa largura ficam com
    dois caracteres cada e o texto quebra no meio da palavra.
  */
  .acoes-linha,
  .exportar,
  .exportar-linha {
    flex-direction: column;
    align-items: stretch;
  }

  .acoes-linha > *,
  .exportar-linha > * {
    width: 100%;
  }

  .galeria {
    grid-template-columns: minmax(0, 1fr);
  }

  .paginacao {
    justify-content: space-between;
  }

  /* Nenhuma palavra longa — um endereço, um e-mail — pode empurrar a página
     para o lado. Rolagem lateral é o defeito de celular mais reclamado. */
  body {
    overflow-wrap: break-word;
  }
}
/* Pilha de execucao na tela de detalhe do erro.
 *
 * Fonte de largura fixa porque pilha tem indentacao que significa alguma
 * coisa, e rolagem horizontal em vez de quebra de linha: caminho de arquivo
 * quebrado no meio deixa de ser clicavel e deixa de ser copiavel de uma vez
 * so, que sao as duas unicas coisas que se faz com ele. */
.pilha {
  margin: 0;
  padding: 1rem;
  background: var(--cor-fundo);
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
  font-family: ui-monospace, 'Cascadia Mono', 'Consolas', monospace;
  font-size: 0.85rem;
  line-height: 1.5;
  white-space: pre;
  overflow-x: auto;
  /* Mesmo motivo das tabelas: sem isto o conteudo largo aqui dentro infla a
   * largura da pagina inteira e o portal passa a rolar de lado no celular. */
  contain: paint;
}

/* Os dois caminhos de saida da tela de erro. Lado a lado no computador,
 * empilhados no celular — em tela estreita, dois botoes na mesma linha ficam
 * estreitos demais para o dedo acertar. */
.acoes-erro {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  align-items: center;
}

/* Cabeçalho enxuto dentro do gerenciamento: sem o menu do portal e sem a busca
 * do portal, ele não precisa da mesma altura. O espaço ganho vai para o
 * trabalho. */
.com-menu-lateral .cabecalho-conteudo {
  padding-top: 10px;
  padding-bottom: 10px;
}

.com-menu-lateral .marca-titulo {
  font-size: 1.05rem;
}

/* A versão no pé da barra lateral.
 *
 * margin-top: auto empurra para baixo: a barra é uma coluna flex de altura
 * inteira, então isto cola a versão no fundo da tela sem depender de quantos
 * itens o menu tem — e o menu muda conforme o perfil de quem entrou. */
.menu-versao {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: center;
  gap: 0.3rem;
  margin: auto 0 0;
  padding: 0.7rem 0.5rem;
  border-top: 1px solid var(--cor-borda);
  color: var(--cor-apagado);
  font-size: 0.75rem;
}

/* Recolhida, some a palavra e fica o número — que é a parte que o edital
 * exige ver na tela. */
.menu-recolhido .menu-versao-rotulo {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.menu-recolhido .menu-versao {
  padding-right: 0.2rem;
  padding-left: 0.2rem;
  font-size: 0.68rem;
}

.rodape-admin {
  padding-top: 14px;
  padding-bottom: 14px;
}

.rodape-admin .rodape-texto {
  margin: 0;
  font-size: 0.8rem;
}

/* A linha "números lidos às ... " com o botão de atualizar ao lado. */
.linha-atualizar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.7rem;
}

/* A mesma caixa de confirmação, sem a tarja de perigo: para perguntas que são
 * sobre uma decisão, e não sobre um estrago. */
.confirmar-caixa-neutra {
  border-top-color: var(--cor-primaria);
}

/* ==========================================================================
   APARÊNCIA DO PORTAL — a tela de cores, banners, atalhos e links (KAN-24)
   ========================================================================== */

/* Dois campos lado a lado quando cabe, um embaixo do outro quando não cabe.
   Sem @media: o "min(20rem, 100%)" já diz "20rem, ou a largura toda se ela
   for menor que isso" — e o próprio grid decide quantas colunas usar. */
.campos-lado-a-lado {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr));
  gap: 0 1.25rem;
}

.campo-ajuda-solta {
  margin: 0 0 1rem;
}

/* AS PÁGINAS DO PORTAL, NO FIM DO BLOCO DE ATALHOS.
 *
 * Separadas por uma linha e um título pequeno: são sugestão, e não cadastro.
 * Sem a separação elas se misturariam aos atalhos que já estão no ar, e a
 * pessoa não saberia quais já aparecem na home e quais são oferta. */
.sugestoes-de-atalho {
  margin-top: 1.25rem;
  padding-top: 1rem;
  border-top: 1px dashed var(--cor-borda);
}

.sugestoes-titulo {
  margin: 0 0 0.35rem;
  color: var(--cor-texto-suave);
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.acoes-separadas {
  margin-top: 1.25rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--cor-borda);
}

/* <fieldset> existe pelo agrupamento que o leitor de tela anuncia, não pela
   moldura — que aqui só brigaria com as bordas dos cartões de dentro. */
.sem-moldura {
  margin: 0 0 1.25rem;
  padding: 0;
  border: 0;
}

.rotulo-de-grupo {
  padding: 0;
  font-weight: 600;
  font-size: 1rem;
}

.lista-vazia {
  margin: 0 0 1rem;
  padding: 1.25rem;
  border: 1px dashed var(--cor-borda-forte);
  border-radius: var(--raio);
  color: var(--cor-texto-suave);
  text-align: center;
}

/* --- As paletas prontas ------------------------------------------------- */

.paletas {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(12rem, 100%), 1fr));
  gap: 0.85rem;
  margin: 0.75rem 0 0;
  padding: 0;
  list-style: none;
}

.paletas > li {
  display: grid;
  min-width: 0;
}

/* É um <label> com um <input type="radio"> escondido dentro — e não um botão.
   Assim o teclado percorre as opções com as setas, o leitor de tela anuncia
   "opção 2 de 5", e a escolha chega ao servidor sem JavaScript. */
.paleta {
  display: block;
  overflow: hidden;
  min-width: 0;
  border: 2px solid var(--cor-borda);
  border-radius: 12px;
  background: var(--cor-superficie);
  cursor: pointer;
}

.paleta-amostra {
  display: flex;
  height: 3.2rem;
}

.paleta-amostra > span {
  flex: 1;
}
.paleta-amostra-svg {
  display: block;
  width: 100%;
  height: 100%;
}

/* Formulário de um botão só (Remover, Arquivar) que fica na mesma linha do
   texto, em vez de descer para uma linha própria. */
.form-na-linha {
  display: inline;
}

.paleta-rodape {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.7rem 0.9rem;
  font-weight: 600;
  font-size: 0.95rem;
}

/* O ✓ só aparece na escolhida. Ele não é a única marca: a borda também muda,
   porque quem não distingue cor precisa de uma segunda pista — e quem usa
   leitor de tela ouve "marcado" do próprio rádio. */
.paleta-marca {
  color: var(--cor-primaria);
  visibility: hidden;
}

.paleta:has(input:checked) {
  border-color: var(--cor-primaria);
}

.paleta:has(input:checked) .paleta-marca {
  visibility: visible;
}

/* O anel de foco tem que aparecer no CARTÃO, e não no rádio escondido: o rádio
   está fora da tela, e sem isto quem navega por teclado não vê onde está. */
.paleta:has(input:focus-visible) {
  outline: 3px solid var(--cor-destaque);
  outline-offset: 2px;
}

/* --- O campo de cor e o veredito do contraste --------------------------- */

.cor-linha {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.cor-linha input[type='color'] {
  width: 3.4rem;
  height: 2.6rem;
  padding: 0.2rem;
  border: 1px solid var(--cor-borda-forte);
  border-radius: var(--raio);
  background: var(--cor-superficie);
  cursor: pointer;
}

.cor-codigo {
  color: var(--cor-texto-suave);
  font-size: 0.95rem;
  letter-spacing: 0.04em;
}

.veredito {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.75rem;
  margin: 0 0 1.25rem;
}

.selo-contraste {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.3rem 0.75rem;
  border-radius: 999px;
  font-weight: 700;
  font-size: 0.85rem;
}

.selo-passa {
  background: var(--cor-sucesso-fundo);
  color: var(--cor-sucesso);
}

.selo-reprova {
  background: var(--cor-erro-fundo);
  color: var(--cor-erro);
}

.veredito-nota {
  color: var(--cor-texto-suave);
  font-size: 0.85rem;
}

/* --- A lista que se reordena (banners, atalhos, links) ------------------ */

.lista-ordenavel {
  display: grid;
  gap: 0.6rem;
  margin: 0 0 1rem;
  padding: 0;
  list-style: none;
}

.linha-ordenavel {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.9rem;
  min-width: 0;
  padding: 0.8rem 1rem;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
  background: var(--cor-superficie);
}

/* O que está cadastrado mas não aparece no portal. Apagado, e NÃO escondido:
   quem cadastrou precisa achar o banner para entender por que ele sumiu — e a
   linha logo abaixo diz o motivo com todas as letras. */
.linha-apagada {
  background: var(--cor-realce-fundo);
}

.linha-capa {
  flex: none;
  overflow: hidden;
  width: 5.5rem;
  border-radius: 6px;
  background: var(--cor-vazio);
}

.linha-capa img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}

.linha-icone {
  display: grid;
  flex: none;
  place-items: center;
  width: 2.4rem;
  height: 2.4rem;
  border-radius: 50%;
  background: var(--cor-realce-fundo);
  color: var(--cor-primaria);
}

.linha-icone svg {
  width: 1.2rem;
  height: 1.2rem;
}

.linha-texto {
  display: grid;
  flex: 1 1 14rem;
  gap: 0.15rem;
  min-width: 0;
}

.linha-nome {
  font-weight: 600;
}

.linha-motivo {
  color: var(--cor-texto-suave);
  font-size: 0.85rem;
  font-style: italic;
}

/* Um recado da própria tela — não é erro, não é sucesso, e por isso não usa a
   faixa de mensagem que aparece depois de salvar. É uma explicação que fica
   ali o tempo todo enquanto a situação durar: "só há um banner no ar, então
   não existe giro". Fundo tingido e uma barra na cor de apoio, para separar
   do texto de ajuda sem parecer aviso de problema. */
.aviso-linha {
  margin: 0 0 1rem;
  padding: 0.7rem 0.9rem;
  border-left: 3px solid var(--cor-destaque);
  border-radius: 0 8px 8px 0;
  background: var(--cor-realce-fundo);
  color: var(--cor-texto);
  font-size: 0.9rem;
  line-height: 1.5;
}

.linha-acoes {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem;
  margin-left: auto;
}

/* Botão só de desenho, para subir e descer. Texto ao lado ocuparia a linha
   inteira numa lista de doze; o nome vai no title e no leitor de tela. */
.botao-icone {
  display: grid;
  place-items: center;
  width: 2.1rem;
  height: 2.1rem;
  padding: 0;
  border: 1px solid var(--cor-borda-forte);
  border-radius: var(--raio);
  background: var(--cor-superficie);
  color: var(--cor-primaria);
  cursor: pointer;
}

.botao-icone:hover:not(:disabled) {
  background: var(--cor-realce-fundo);
}

/* O primeiro não sobe e o último não desce. DESABILITADO e não escondido:
   botão que some faz os outros pularem de lugar a cada clique, e a pessoa
   erra o alvo. */
.botao-icone:disabled {
  opacity: 0.35;
  cursor: default;
}

/* As duas cores do tema atual, na barra fechada da seção. */
.amostra-cores {
  display: inline-flex;
  flex: none;
  overflow: hidden;
  border: 1px solid var(--cor-borda-forte);
  border-radius: 999px;
}

.amostra-cores > span {
  width: 1.4rem;
  height: 1rem;
}

@media (max-width: 40rem) {
  .linha-acoes {
    margin-left: 0;
  }
}

/* No alto contraste as amostras de cor são o único lugar do portal em que a
   cor É a informação: sem elas, as cinco paletas viram cinco caixas iguais.
   Por isso ganham moldura branca em vez de perderem o preenchimento. */
html.contraste-alto .paleta-amostra-svg,
html.contraste-alto .amostra-cores > span {
  border: 1px solid var(--contraste-texto);
}

/* A amostra do cartão "Cor livre". Arco-íris, e não as cores em uso: com as
   cores em uso, este cartão nascia idêntico ao da paleta escolhida e os dois
   pareciam a mesma opção repetida. */
.paleta-amostra-livre {
  /* Cor fixa de propósito (KAN-109): é a amostra das paletas prontas. */
  background: linear-gradient(90deg, #7c1d3f, #b45309, #1d7a4c, #0f766e, #10446f, #2f3e46);
}

/* A legenda do <fieldset> é bloco e não pode ser item de grade: sem isto ela
   vira a primeira coluna e empurra os dois campos para o lado. */
.campos-lado-a-lado > legend {
  grid-column: 1 / -1;
  margin-bottom: 0.5rem;
}

/* As duas cores do tema, ao lado do nome da paleta na barra fechada. */
.secao-sanfona-conta .amostra-cores {
  margin-right: 0.45rem;
  vertical-align: -0.15rem;
}
/* ==========================================================================
   PÁGINA INICIAL — banners rotativos, atalhos e links úteis (KAN-24)

   Sem uma linha de JavaScript. O porquê de cada peça do giro está comentado
   junto da regra; a explicação do mecanismo inteiro está em
   views/partials/faixa-de-banners.ejs.
   ========================================================================== */

/* ------------------------------------------------- faixa de destaque (banners) */

/* O TEMPO DE CADA BANNER É FIXO, e a VOLTA é que muda de tamanho.

   Antes era o contrário: a volta durava 24 s sempre, e cada banner ficava
   24 s dividido pela quantidade. Isso dava 12 s por banner quando havia dois e
   4 s quando havia seis — ou seja, cadastrar mais um banner mudava a
   velocidade de LEITURA de todos os outros. Com dois, a faixa parecia travada;
   com seis, não dava tempo de ler o título e achar o botão.

   Quantos banners existem é decisão de conteúdo. Quanto tempo se leva para ler
   um título, uma frase e alcançar um botão não é — é sempre o mesmo. Por isso
   o que fica constante é o tempo de cada um, e o `--giro` (a volta inteira)
   passa a ser esse tempo multiplicado pela quantidade.

   Os quadros da animação continuam em porcentagem da volta, então nada mais
   precisou mudar: eles se ajustam sozinhos à duração nova. */
.faixa-destaque {
  --tempo-do-banner: 5s;
  --giro: calc(var(--tempo-do-banner) * 3);
  position: relative;
  margin: 0 0 2.5rem;
  border-radius: 14px;
  overflow: hidden;
  background: var(--cor-primaria-escura);
  aspect-ratio: 1100 / 380;
}
.banner {
  position: absolute;
  inset: 0;
  opacity: 0;
  visibility: hidden;
  animation-duration: var(--giro);
  animation-iteration-count: infinite;
  animation-timing-function: linear;
}
.banner-foto {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.banner-texto {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-end;
  padding: 3rem 5rem 2.5rem;
  background: linear-gradient(
    to top,
    color-mix(in srgb, var(--cor-veu-escuro) 94%, transparent),
    color-mix(in srgb, var(--cor-veu-escuro) 70%, transparent) 40%,
    color-mix(in srgb, var(--cor-veu-escuro) 20%, transparent)
  );
  color: var(--cor-sobre-primaria);
}
.banner-etiqueta {
  display: inline-block;
  margin: 0 0 0.55rem;
  padding: 0.22rem 0.65rem;
  border-radius: 999px;
  background: var(--cor-destaque);
  color: var(--cor-sobre-primaria);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.banner-texto h2 {
  margin: 0 0 0.45rem;
  font-size: 1.9rem;
  line-height: 1.15;
  color: var(--cor-sobre-primaria);
}
.banner-texto p {
  margin: 0 0 1.1rem;
  max-width: 44rem;
  font-size: 1.02rem;
  color: color-mix(in srgb, var(--cor-sobre-primaria) 90%, transparent);
}
.banner-botao {
  display: inline-block;
  padding: 0.6rem 1.25rem;
  border-radius: var(--raio);
  background: var(--cor-superficie);
  color: var(--cor-link);
  font-weight: 700;
  text-decoration: none;
}

/* ---- o giro
   Um conjunto de quadros por quantidade de banners: a porcentagem em que cada
   um sai de cena depende de quantos sao.
   Os atrasos sao NEGATIVOS de proposito. Atraso positivo quer dizer "ainda nao
   comecou" — e ate comecar o banner fica no repouso, escondido: o primeiro
   giro teria um buraco em branco entre um banner e o seguinte.
   E 0% e um quadro VISIVEL de proposito: passar o mouse pausa o giro, e quem
   abre a pagina ja com o cursor em cima congela o giro em 0%. */
@keyframes gira-2 {
  0%,
  47% {
    opacity: 1;
    visibility: visible;
  }
  50% {
    opacity: 0;
    visibility: visible;
  }
  50.01%,
  97% {
    opacity: 0;
    visibility: hidden;
  }
  97.001% {
    opacity: 0;
    visibility: visible;
  }
  100% {
    opacity: 1;
    visibility: visible;
  }
}
@keyframes gira-3 {
  0%,
  30.333% {
    opacity: 1;
    visibility: visible;
  }
  33.333% {
    opacity: 0;
    visibility: visible;
  }
  33.343%,
  97% {
    opacity: 0;
    visibility: hidden;
  }
  97.001% {
    opacity: 0;
    visibility: visible;
  }
  100% {
    opacity: 1;
    visibility: visible;
  }
}
@keyframes gira-4 {
  0%,
  22% {
    opacity: 1;
    visibility: visible;
  }
  25% {
    opacity: 0;
    visibility: visible;
  }
  25.01%,
  97% {
    opacity: 0;
    visibility: hidden;
  }
  97.001% {
    opacity: 0;
    visibility: visible;
  }
  100% {
    opacity: 1;
    visibility: visible;
  }
}
@keyframes gira-5 {
  0%,
  17% {
    opacity: 1;
    visibility: visible;
  }
  20% {
    opacity: 0;
    visibility: visible;
  }
  20.01%,
  97% {
    opacity: 0;
    visibility: hidden;
  }
  97.001% {
    opacity: 0;
    visibility: visible;
  }
  100% {
    opacity: 1;
    visibility: visible;
  }
}
@keyframes gira-6 {
  0%,
  13.667% {
    opacity: 1;
    visibility: visible;
  }
  16.667% {
    opacity: 0;
    visibility: visible;
  }
  16.677%,
  97% {
    opacity: 0;
    visibility: hidden;
  }
  97.001% {
    opacity: 0;
    visibility: visible;
  }
  100% {
    opacity: 1;
    visibility: visible;
  }
}
.faixa-destaque[data-quantos='2'] .banner {
  animation-name: gira-2;
}
.faixa-destaque[data-quantos='2'] {
  --giro: calc(var(--tempo-do-banner) * 2);
}
.faixa-destaque[data-quantos='2'] .banner:nth-child(1) {
  animation-delay: calc(var(--giro) * -1);
}
.faixa-destaque[data-quantos='2'] .banner:nth-child(2) {
  animation-delay: calc(var(--giro) * -0.5);
}
.faixa-destaque[data-quantos='3'] .banner {
  animation-name: gira-3;
}
.faixa-destaque[data-quantos='3'] {
  --giro: calc(var(--tempo-do-banner) * 3);
}
.faixa-destaque[data-quantos='3'] .banner:nth-child(1) {
  animation-delay: calc(var(--giro) * -1);
}
.faixa-destaque[data-quantos='3'] .banner:nth-child(2) {
  animation-delay: calc(var(--giro) * -0.6667);
}
.faixa-destaque[data-quantos='3'] .banner:nth-child(3) {
  animation-delay: calc(var(--giro) * -0.3333);
}
.faixa-destaque[data-quantos='4'] .banner {
  animation-name: gira-4;
}
.faixa-destaque[data-quantos='4'] {
  --giro: calc(var(--tempo-do-banner) * 4);
}
.faixa-destaque[data-quantos='4'] .banner:nth-child(1) {
  animation-delay: calc(var(--giro) * -1);
}
.faixa-destaque[data-quantos='4'] .banner:nth-child(2) {
  animation-delay: calc(var(--giro) * -0.75);
}
.faixa-destaque[data-quantos='4'] .banner:nth-child(3) {
  animation-delay: calc(var(--giro) * -0.5);
}
.faixa-destaque[data-quantos='4'] .banner:nth-child(4) {
  animation-delay: calc(var(--giro) * -0.25);
}
.faixa-destaque[data-quantos='5'] .banner {
  animation-name: gira-5;
}
.faixa-destaque[data-quantos='5'] {
  --giro: calc(var(--tempo-do-banner) * 5);
}
.faixa-destaque[data-quantos='5'] .banner:nth-child(1) {
  animation-delay: calc(var(--giro) * -1);
}
.faixa-destaque[data-quantos='5'] .banner:nth-child(2) {
  animation-delay: calc(var(--giro) * -0.8);
}
.faixa-destaque[data-quantos='5'] .banner:nth-child(3) {
  animation-delay: calc(var(--giro) * -0.6);
}
.faixa-destaque[data-quantos='5'] .banner:nth-child(4) {
  animation-delay: calc(var(--giro) * -0.4);
}
.faixa-destaque[data-quantos='5'] .banner:nth-child(5) {
  animation-delay: calc(var(--giro) * -0.2);
}
.faixa-destaque[data-quantos='6'] .banner {
  animation-name: gira-6;
}
.faixa-destaque[data-quantos='6'] {
  --giro: calc(var(--tempo-do-banner) * 6);
}
.faixa-destaque[data-quantos='6'] .banner:nth-child(1) {
  animation-delay: calc(var(--giro) * -1);
}
.faixa-destaque[data-quantos='6'] .banner:nth-child(2) {
  animation-delay: calc(var(--giro) * -0.8333);
}
.faixa-destaque[data-quantos='6'] .banner:nth-child(3) {
  animation-delay: calc(var(--giro) * -0.6667);
}
.faixa-destaque[data-quantos='6'] .banner:nth-child(4) {
  animation-delay: calc(var(--giro) * -0.5);
}
.faixa-destaque[data-quantos='6'] .banner:nth-child(5) {
  animation-delay: calc(var(--giro) * -0.3333);
}
.faixa-destaque[data-quantos='6'] .banner:nth-child(6) {
  animation-delay: calc(var(--giro) * -0.1667);
}

/* Um banner so nao gira: fica parado. */
.faixa-destaque[data-quantos='1'] .banner {
  animation: none;
  opacity: 1;
  visibility: visible;
}

/* Pausa com o mouse em cima ou com o foco do teclado dentro. Nao e enfeite:
   a norma de acessibilidade exige um jeito de parar o que se move sozinho. */
.faixa-destaque:hover .banner,
.faixa-destaque:focus-within .banner {
  animation-play-state: paused;
}

/* Escolheu um banner na setinha: o giro para e fica o escolhido. */
.faixa-destaque:has(.banner:target) .banner {
  animation: none;
  opacity: 0;
  visibility: hidden;
}
.faixa-destaque:has(.banner:target) .banner:target {
  opacity: 1;
  visibility: visible;
}

.banner-seta {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  display: grid;
  place-items: center;
  width: 2.6rem;
  height: 2.6rem;
  border-radius: 50%;
  background: color-mix(in srgb, var(--cor-sobre-primaria) 92%, transparent);
  color: var(--cor-primaria);
  font-size: 1.1rem;
  text-decoration: none;
  opacity: 0;
  transition: opacity 0.18s ease;
}
.banner-seta-antes {
  left: 1rem;
}
.banner-seta-depois {
  right: 1rem;
}
.faixa-destaque:hover .banner-seta,
.banner-seta:focus-visible {
  opacity: 1;
}

.banner-pontos {
  position: absolute;
  right: 1.4rem;
  bottom: 1.3rem;
  z-index: 2;
  display: flex;
  gap: 0.4rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.banner-ponto {
  display: block;
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 999px;
  /* "color" num link que não mostra texto não é detalhe: sem ele o navegador
     aplica o azul padrão dele, e o texto que só o leitor de tela usa nasce
     azul-berrante por baixo do desenho. Foi a suíte do tema que apontou —
     ela procura azul de marca sobrevivente numa home verde. */
  color: var(--cor-sobre-primaria);
  background: color-mix(in srgb, var(--cor-sobre-primaria) 50%, transparent);
  position: relative;
}

/* Em celular nao existe "passar o mouse": as setinhas ficam sempre a vista,
   no canto de baixo, longe do texto. Os pontinhos ficam do outro lado. */
@media (hover: none) {
  .banner-seta {
    opacity: 1;
  }
}
@media (max-width: 48rem) {
  .faixa-destaque {
    aspect-ratio: 3 / 4;
  }
  .banner-texto {
    padding: 2rem 1.25rem 4.6rem;
  }
  .banner-texto h2 {
    font-size: 1.4rem;
  }
  .banner-texto p {
    font-size: 0.95rem;
  }
  .banner-seta {
    top: auto;
    bottom: 1rem;
    transform: none;
    width: 2.3rem;
    height: 2.3rem;
    opacity: 1;
  }
  .banner-seta-antes {
    left: 1.25rem;
  }
  .banner-seta-depois {
    left: 4.1rem;
    right: auto;
  }
  .banner-pontos {
    bottom: 1.75rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  .faixa-destaque .banner {
    animation: none;
    opacity: 0;
    visibility: hidden;
  }
  .faixa-destaque:not(:has(.banner:target)) .banner:first-child {
    opacity: 1;
    visibility: visible;
  }
  .banner-seta {
    opacity: 1;
  }
}

/* ----------------------------------------------------------- grade de atalhos */
/* O RITMO DA PÁGINA INICIAL.

   O espaço entre blocos é o que separa "uma página" de "uma pilha de coisas".
   No portal do Rio esse respiro é grande de propósito: cada bloco começa e
   termina, e o olho sabe onde está. */
.faixa-secao {
  margin: 0 0 3.5rem;
}
.faixa-titulo {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 0.5rem 1rem;
  margin: 0 0 1.5rem;
}

/* O TÍTULO EM DUAS LINHAS.

   Primeira palavra fina e pequena, o resto pesado e grande, e um risco curto
   na cor de apoio fechando embaixo. É o desenho do portal do Rio ("O QUE EU /
   PRECISO?", "DIÁRIO / OFICIAL"), e ele resolve um problema real: numa página
   longa, título todo do mesmo tamanho vira uma fileira de coisas iguais e a
   pessoa perde o lugar. O contraste entre as duas linhas dá ao olho um ponto
   de parada a cada bloco.

   É UM <h2> SÓ, com spans dentro — dois títulos dariam ao leitor de tela dois
   cabeçalhos para uma seção só. */
.titulo-secao {
  position: relative;
  margin: 0;
  padding-bottom: 0.7rem;
  /* 1.15 e não 1.05: em CAIXA ALTA os acentos sobem acima da letra, e com a
     linha mais apertada o "Ú" de ÚLTIMAS batia na linha de cima. Foi visto na
     tela, não calculado. */
  line-height: 1.15;
  text-transform: uppercase;
}

.titulo-leve {
  display: block;
  color: var(--cor-texto-suave);
  font-weight: 400;
  /* 1.45rem e 2.45rem: as duas linhas medidas no print do Rio ("O QUE EU" com
     17px de altura de caixa alta, "PRECISO?" com 28px). */
  font-size: 1.45rem;
  letter-spacing: 0.02em;
}

.titulo-forte {
  display: block;
  font-weight: 800;
  font-size: 2.45rem;
  letter-spacing: -0.01em;
}

/* O risco. Curto e embaixo da primeira letra, como no Rio — risco de ponta a
   ponta viraria uma linha divisória, que é outra coisa. */
.titulo-secao::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  /* 65px no print do Rio, 3px de altura. */
  width: 4rem;
  height: 3px;
  border-radius: 2px;
  background: var(--cor-destaque);
}
.faixa-titulo h2 {
  margin: 0;
  font-size: 1.3rem;
}
.faixa-titulo a {
  /* A cor vem do tema. Sem esta linha o navegador aplica o azul padrão dele, e
     "Todas as notícias" ficava azul numa home verde — foi assim que a suíte do
     tema pegou. */
  color: var(--cor-link);
  font-size: 0.92rem;
  font-weight: 600;
}

.grade-atalhos > li,
.lista-links > li {
  display: grid;
  min-width: 0;
}
.grade-atalhos {
  display: grid;
  /* 8 por linha em tela de escritório, como no Rio. O ladrilho menor é o que
     permite 24 atalhos sem a página virar um rolo — e prefeitura tem MUITO
     serviço para listar. */
  grid-template-columns: repeat(auto-fill, minmax(min(7.5rem, 100%), 1fr));
  gap: 0.65rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.atalho {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-width: 0;
  /* 100px, a altura do ladrilho no print do Rio — e é MÍNIMA, não fixa: um
     rótulo de duas linhas ("Carta de Serviços") precisa crescer, e altura
     travada cortaria a segunda linha. O que o mínimo garante é que o ladrilho
     de uma linha não fique mais baixo que o de duas: sem ele, a primeira
     fileira tem uma altura e a segunda tem outra, e a grade parece torta. */
  min-height: 100px;
  /* SEM BORDA, fundo levemente tingido. Vinte e quatro caixas com borda viram
     uma grade de linhas e o olho cansa; o bloco de cor chapada some e deixa o
     desenho e a palavra à frente. */
  /* 100px de altura, como no print do Rio: 20 de folga em cima, o desenho, a
     palavra, e 18 embaixo. A conta é essa e está escrita aqui porque mexer em
     qualquer uma das três partes muda a altura do ladrilho inteiro. */
  padding: 1.25rem 0.5rem 1.15rem;
  border: 0;
  border-radius: 8px;
  background: var(--cor-realce-fundo-forte);
  color: var(--cor-texto);
  font-weight: 600;
  text-align: center;
  text-decoration: none;
  transition:
    background 0.15s,
    transform 0.15s;
}
.atalho:hover {
  background: var(--cor-borda-forte);
  transform: translateY(-2px);
}

/* Quem marcou "reduzir movimento" no sistema operacional não leva o pulinho
   do ladrilho — é a mesma preferência que desliga o giro dos banners. */
@media (prefers-reduced-motion: reduce) {
  .atalho {
    transition: none;
  }

  .atalho:hover {
    transform: none;
  }
}
.atalho-icone {
  display: grid;
  place-items: center;
  width: 2.2rem;
  height: 1.9rem;
  color: var(--cor-link);
}
.atalho-icone svg {
  width: 1.9rem;
  height: 1.9rem;
}
.atalho span {
  font-size: 0.82rem;
  line-height: 1.2;
}

/* --------------------------------------------------------------- links uteis */
.lista-links {
  display: grid;
  gap: 0.6rem;
  grid-template-columns: repeat(auto-fill, minmax(min(15rem, 100%), 1fr));
  margin: 0;
  padding: 0;
  list-style: none;
}
.link-util {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  min-width: 0;
  padding: 0.85rem 1rem;
  border: 1px solid var(--cor-borda);
  border-radius: 10px;
  background: var(--cor-superficie);
  color: var(--cor-texto);
  font-size: 0.95rem;
  font-weight: 600;
  text-decoration: none;
}
.link-util:hover {
  border-color: var(--cor-primaria);
}
.link-util-seta {
  margin-left: auto;
  color: var(--cor-apagado);
}

/* --- A Prefeitura: os agentes políticos --------------------------------

   Cartões em grade, com a foto de rosto em cima e o cargo antes do nome.

   O CARGO VEM ANTES DO NOME, e é ele que está em maiúsculas pequenas. Não é
   estética: quem chega nesta página quase nunca procura uma pessoa pelo nome —
   procura "quem é o secretário de Saúde". O cargo é a chave de busca do olho,
   e o nome é a resposta. */
.grade-agentes {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(17rem, 100%), 1fr));
  gap: 1.2rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.grade-agentes > li {
  display: grid;
  min-width: 0;
}

.agente {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  height: 100%;
  padding: 1.2rem;
  border: 1px solid var(--cor-borda);
  border-radius: 12px;
  background: var(--cor-superficie);
}

/* A foto é REDONDA e de tamanho fixo.

   Fixo porque as fotos vêm de onde der — celular do assessor, digitalização de
   crachá, foto oficial — e um cartão com foto de proporção livre vira uma
   fileira de retângulos de alturas diferentes. object-fit: cover corta o que
   sobra em vez de esticar o rosto. */
.agente-foto {
  display: grid;
  place-items: center;
  overflow: hidden;
  width: 5.5rem;
  height: 5.5rem;
  border-radius: 999px;
  background: var(--cor-realce-fundo-forte);
}

.agente-foto img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Sem foto, as INICIAIS — e não uma silhueta genérica de pessoa. A inicial diz
   de quem é aquele espaço; a silhueta só ocupa lugar. Portal recém-instalado
   cadastra o Prefeito antes de alguém achar a foto oficial dele. */
.agente-iniciais {
  color: var(--cor-primaria);
  font-weight: 700;
  font-size: 1.6rem;
  letter-spacing: 0.02em;
}

.agente-texto {
  display: grid;
  gap: 0.35rem;
  min-width: 0;
}

.agente-cargo {
  margin: 0;
  color: var(--cor-texto-suave);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.agente-texto h2 {
  margin: 0;
  font-size: 1.15rem;
  line-height: 1.3;
}

.agente-pasta {
  margin: 0;
  font-weight: 600;
}

.agente-perfil {
  margin: 0.3rem 0 0;
  color: var(--cor-texto-suave);
  font-size: 0.95rem;
}

.agente-contato {
  display: grid;
  gap: 0.2rem;
  margin: 0.4rem 0 0;
  padding: 0;
  font-size: 0.95rem;
  list-style: none;
}

/* overflow-wrap: um e-mail institucional longo não pode criar rolagem lateral
   num celular de 320 pixels. "break-word" e não "anywhere": dentro de uma
   grade, "anywhere" deixa o navegador encolher a coluna e parte a palavra com
   espaço de sobra ao lado. */
.agente-contato a {
  overflow-wrap: break-word;
}

.agente-desde {
  margin: 0.4rem 0 0;
  color: var(--cor-apagado);
  font-size: 0.85rem;
}

/* A miniatura redonda da lista de gerenciamento, para bater com a página
   pública: quem cadastra reconhece na lista o que o cidadão vai ver. */
.linha-capa-redonda {
  display: grid;
  place-items: center;
  /* Quadrada, e não 16/9 como a capa de banner: foto de rosto cortada em
     paisagem corta a testa e o queixo. */
  width: 3rem;
  height: 3rem;
  border-radius: 999px;
  background: var(--cor-realce-fundo-forte);
}

.linha-capa-redonda img {
  width: 100%;
  height: 100%;
  aspect-ratio: 1;
  border-radius: 999px;
}

.linha-iniciais {
  color: var(--cor-primaria);
  font-weight: 700;
}

/* --- Cartões de destaque -------------------------------------------------

   Dois por linha. Um cartão sozinho numa faixa larga vira um banner mal feito
   e quatro numa linha viram ladrilho: dois é o tamanho em que a foto ainda se
   enxerga e o texto ainda se lê.

   Em celular vira um por linha sozinho, pelo minmax: a coluna mínima é
   min(20rem, 100%), e o 100% é o que impede a linha de ficar mais larga que a
   tela num aparelho de 320 pixels. */
.grade-cartoes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr));
  gap: 1.2rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.grade-cartoes > li {
  display: grid;
  min-width: 0;
}

.cartao-destaque {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  height: 100%;
  border: 1px solid var(--cor-borda);
  border-radius: 12px;
  background: var(--cor-superficie);
}

/* A ALTURA DA FOTO É FIXA PELA PROPORÇÃO, e não pela imagem.

   Sem isto, dois cartões lado a lado com fotos de proporções diferentes ficam
   com os títulos em alturas diferentes — e a linha inteira parece torta. O
   object-fit: cover corta o que sobra em vez de esticar. */
.cartao-destaque-foto {
  aspect-ratio: 16 / 9;
  max-width: 100%;
  background: var(--cor-vazio);
}

.cartao-destaque-foto img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.cartao-destaque-texto {
  display: flex;
  flex: 1;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.5rem;
  padding: 1.1rem 1.2rem 1.3rem;
}

.cartao-destaque-texto h3 {
  margin: 0;
  font-size: 1.15rem;
  line-height: 1.3;
}

.cartao-destaque-texto p {
  margin: 0;
  color: var(--cor-texto-suave);
  font-size: 0.95rem;
}

/* O botão desce para o pé do cartão: em dois cartões de texto desigual, os
   botões ficam alinhados em vez de cada um numa altura. */
.cartao-destaque-botao {
  margin-top: auto;
}

/* --- Amostra da galeria e dos vídeos -------------------------------------

   Os dois blocos usam a mesma grade porque são o mesmo problema: cartões
   quadrados com foto em cima e texto embaixo. Quatro por linha em tela de
   escritório, dois em tablet, um em celular. */
.grade-galeria,
.grade-videos {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(14rem, 100%), 1fr));
  gap: 1rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.grade-galeria > li,
.grade-videos > li {
  display: grid;
  min-width: 0;
}

.cartao-galeria {
  display: grid;
  gap: 0.45rem;
  height: 100%;
  color: var(--cor-texto);
  text-decoration: none;
}

.cartao-galeria-foto,
.cartao-video-capa {
  position: relative;
  display: block;
  overflow: hidden;
  aspect-ratio: 4 / 3;
  max-width: 100%;
  border-radius: 10px;
  background: var(--cor-vazio);
}

.cartao-galeria-foto img,
.cartao-video-capa img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* A contagem fica SOBRE a foto, com fundo escuro próprio.

   O fundo não é transparência sobre a imagem por acaso: uma foto clara com
   texto branco por cima deixa de se ler, e a norma pede 4,5:1. Preto a 70%
   garante o contraste em qualquer foto. */
.cartao-galeria-conta {
  position: absolute;
  right: 0.5rem;
  bottom: 0.5rem;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  background: var(--veu-sobre-foto);
  color: var(--cor-sobre-primaria);
  font-size: 0.78rem;
  font-weight: 600;
}

.cartao-galeria-nome {
  font-weight: 600;
  font-size: 0.98rem;
  line-height: 1.35;
}

.cartao-galeria:hover .cartao-galeria-nome,
.cartao-galeria:focus .cartao-galeria-nome {
  text-decoration: underline;
}

.cartao-galeria-data {
  color: var(--cor-texto-suave);
  font-size: 0.85rem;
}

/* A marca de play, no canto da capa do vídeo. Desenho e não imagem: acompanha
   o tema e continua nítido em qualquer tela. */
.cartao-video-play {
  position: absolute;
  right: 0.55rem;
  bottom: 0.55rem;
  display: grid;
  place-items: center;
  width: 2.4rem;
  height: 2.4rem;
  border-radius: 999px;
  background: var(--veu-sobre-foto);
  color: var(--cor-sobre-primaria);
}

.cartao-video h3 {
  margin: 0.5rem 0 0.2rem;
  font-size: 1rem;
  line-height: 1.35;
}

.cartao-video h3 a {
  color: var(--cor-texto);
  text-decoration: none;
}

.cartao-video h3 a:hover,
.cartao-video h3 a:focus {
  text-decoration: underline;
}

/* --- Fale conosco --------------------------------------------------------

   Fundo tingido para separar do resto: é o último bloco antes do rodapé, e
   sem a faixa ele se confunde com o rodapé que vem logo abaixo. */
.faixa-contato {
  padding: 1.6rem 1.4rem 1.8rem;
  border-radius: 14px;
  background: var(--cor-realce-fundo);
}

.grade-contato {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr));
  gap: 1rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.canal {
  display: flex;
  align-items: flex-start;
  gap: 0.7rem;
  min-width: 0;
}

.canal-icone {
  display: grid;
  flex: none;
  place-items: center;
  width: 2.4rem;
  height: 2.4rem;
  border-radius: 10px;
  background: var(--cor-realce-fundo-forte);
  color: var(--cor-primaria);
}

.canal-icone svg {
  width: 1.2rem;
  height: 1.2rem;
}

/* minmax(0, 1fr) E NÃO a coluna automática.

   Uma grade de coluna automática nunca fica mais estreita que o conteúdo
   INDIVISÍVEL dela — e "gabinete@exemplo.gov.br" é uma palavra só. Com a letra
   no maior tamanho da barra de acessibilidade, num celular de 320px, essa
   palavra mede 259px e a coluna passava a medir 259px também, empurrando a
   página para 366px de largura: rolagem lateral, que é justamente o que o
   portal não pode ter.

   O min-width: 0 do próprio .canal-texto não resolvia — ele deixa a CAIXA
   encolher, mas quem estava impondo o tamanho era a COLUNA de dentro.

   minmax(0, 1fr) tira esse piso, e aí o overflow-wrap: break-word do
   .canal-valor finalmente tem permissão para partir a palavra. Foi preferido a
   trocar break-word por "anywhere" porque anywhere também muda a conta em tela
   larga, e lá o e-mail passaria a ser partido sem necessidade. */
.canal-texto {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0.1rem;
  min-width: 0;
}

.canal-rotulo {
  color: var(--cor-texto-suave);
  font-size: 0.82rem;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

/* QUEBRA-PALAVRA, e "break-word" e não "anywhere".

   Os dois quebram uma palavra que não cabe, e é isso que impede um e-mail
   longo de criar rolagem lateral num celular de 320 pixels. A diferença
   aparece DENTRO de uma grade: "anywhere" faz o navegador calcular que a
   coluna pode ser estreitíssima, e a coluna encolhe — o e-mail saía partido
   ("...gov.b / r") numa tela larga, com espaço de sobra ao lado. Com
   "break-word" a coluna continua contando a palavra inteira e só quebra
   quando de fato não cabe. */
.canal-valor {
  font-weight: 600;
  overflow-wrap: break-word;
}

/* O canal que TEM endereço é um <a>, e <a> sem cor declarada pega o azul
   padrão do navegador — que o tema não alcança. A suíte do tema varre a home
   procurando azul de marca sobrevivente num portal verde, e foi ela que
   apontou este. É o terceiro da mesma família (o pontinho do carrossel e o
   "Todas as notícias" foram os anteriores). */
a.canal-valor {
  color: var(--cor-link);
}

.banner-ponto::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 999px;
  background: var(--cor-superficie);
  opacity: 0;
  visibility: hidden;
  animation-duration: var(--giro);
  animation-iteration-count: infinite;
  animation-timing-function: linear;
}

.faixa-destaque:hover .banner-ponto::after,
.faixa-destaque:focus-within .banner-ponto::after {
  animation-play-state: paused;
}

/* Escolheu um na mão: o giro para e acende só o escolhido. */
.faixa-destaque:has(.banner:target) .banner-ponto::after {
  animation: none;
  opacity: 0;
  visibility: hidden;
}

.faixa-destaque[data-quantos='2'] .banner-pontos li:nth-child(1) .banner-ponto::after {
  animation-name: gira-2;
  animation-delay: calc(var(--giro) * -1);
}
.faixa-destaque[data-quantos='2'] .banner-pontos li:nth-child(2) .banner-ponto::after {
  animation-name: gira-2;
  animation-delay: calc(var(--giro) * -0.5);
}
.faixa-destaque[data-quantos='3'] .banner-pontos li:nth-child(1) .banner-ponto::after {
  animation-name: gira-3;
  animation-delay: calc(var(--giro) * -1);
}
.faixa-destaque[data-quantos='3'] .banner-pontos li:nth-child(2) .banner-ponto::after {
  animation-name: gira-3;
  animation-delay: calc(var(--giro) * -0.6667);
}
.faixa-destaque[data-quantos='3'] .banner-pontos li:nth-child(3) .banner-ponto::after {
  animation-name: gira-3;
  animation-delay: calc(var(--giro) * -0.3333);
}
.faixa-destaque[data-quantos='4'] .banner-pontos li:nth-child(1) .banner-ponto::after {
  animation-name: gira-4;
  animation-delay: calc(var(--giro) * -1);
}
.faixa-destaque[data-quantos='4'] .banner-pontos li:nth-child(2) .banner-ponto::after {
  animation-name: gira-4;
  animation-delay: calc(var(--giro) * -0.75);
}
.faixa-destaque[data-quantos='4'] .banner-pontos li:nth-child(3) .banner-ponto::after {
  animation-name: gira-4;
  animation-delay: calc(var(--giro) * -0.5);
}
.faixa-destaque[data-quantos='4'] .banner-pontos li:nth-child(4) .banner-ponto::after {
  animation-name: gira-4;
  animation-delay: calc(var(--giro) * -0.25);
}
.faixa-destaque[data-quantos='5'] .banner-pontos li:nth-child(1) .banner-ponto::after {
  animation-name: gira-5;
  animation-delay: calc(var(--giro) * -1);
}
.faixa-destaque[data-quantos='5'] .banner-pontos li:nth-child(2) .banner-ponto::after {
  animation-name: gira-5;
  animation-delay: calc(var(--giro) * -0.8);
}
.faixa-destaque[data-quantos='5'] .banner-pontos li:nth-child(3) .banner-ponto::after {
  animation-name: gira-5;
  animation-delay: calc(var(--giro) * -0.6);
}
.faixa-destaque[data-quantos='5'] .banner-pontos li:nth-child(4) .banner-ponto::after {
  animation-name: gira-5;
  animation-delay: calc(var(--giro) * -0.4);
}
.faixa-destaque[data-quantos='5'] .banner-pontos li:nth-child(5) .banner-ponto::after {
  animation-name: gira-5;
  animation-delay: calc(var(--giro) * -0.2);
}
.faixa-destaque[data-quantos='6'] .banner-pontos li:nth-child(1) .banner-ponto::after {
  animation-name: gira-6;
  animation-delay: calc(var(--giro) * -1);
}
.faixa-destaque[data-quantos='6'] .banner-pontos li:nth-child(2) .banner-ponto::after {
  animation-name: gira-6;
  animation-delay: calc(var(--giro) * -0.8333);
}
.faixa-destaque[data-quantos='6'] .banner-pontos li:nth-child(3) .banner-ponto::after {
  animation-name: gira-6;
  animation-delay: calc(var(--giro) * -0.6667);
}
.faixa-destaque[data-quantos='6'] .banner-pontos li:nth-child(4) .banner-ponto::after {
  animation-name: gira-6;
  animation-delay: calc(var(--giro) * -0.5);
}
.faixa-destaque[data-quantos='6'] .banner-pontos li:nth-child(5) .banner-ponto::after {
  animation-name: gira-6;
  animation-delay: calc(var(--giro) * -0.3333);
}
.faixa-destaque[data-quantos='6'] .banner-pontos li:nth-child(6) .banner-ponto::after {
  animation-name: gira-6;
  animation-delay: calc(var(--giro) * -0.1667);
}
.faixa-destaque:has(#banner-1:target) .banner-pontos li:nth-child(1) .banner-ponto::after {
  opacity: 1;
  visibility: visible;
}
.faixa-destaque:has(#banner-2:target) .banner-pontos li:nth-child(2) .banner-ponto::after {
  opacity: 1;
  visibility: visible;
}
.faixa-destaque:has(#banner-3:target) .banner-pontos li:nth-child(3) .banner-ponto::after {
  opacity: 1;
  visibility: visible;
}
.faixa-destaque:has(#banner-4:target) .banner-pontos li:nth-child(4) .banner-ponto::after {
  opacity: 1;
  visibility: visible;
}
.faixa-destaque:has(#banner-5:target) .banner-pontos li:nth-child(5) .banner-ponto::after {
  opacity: 1;
  visibility: visible;
}
.faixa-destaque:has(#banner-6:target) .banner-pontos li:nth-child(6) .banner-ponto::after {
  opacity: 1;
  visibility: visible;
}

@media (prefers-reduced-motion: reduce) {
  .banner-ponto::after {
    animation: none;
    opacity: 0;
    visibility: hidden;
  }

  .faixa-destaque:not(:has(.banner:target)) .banner-pontos li:first-child .banner-ponto::after {
    opacity: 1;
    visibility: visible;
  }
}

/* --- A arrumação da página inicial: o quadrinho que simula a home ---------

   Ele existe porque uma LISTA DE NOMES não diz como a página fica. "Destaques,
   Acesso rápido, Últimas notícias" é uma lista de palavras: para saber o
   resultado é preciso imaginar. Aqui cada bloco tem a FORMA que ele tem na
   página — faixa larga, grade, linhas, pastilhas — dentro de uma moldura com a
   barra do portal em cima. */
.molde-home {
  overflow: hidden;
  margin: 0 0 1rem;
  border: 1px solid var(--cor-borda-forte);
  border-radius: 12px;
  background: var(--cor-fundo);
}

/* A barra do topo do portal, em miniatura: é ela que faz o quadrinho parecer
   uma página e não uma lista dentro de uma caixa. */
.molde-topo {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0;
  padding: 0.6rem 0.9rem;
  background: var(--cor-primaria);
}

.molde-brasao {
  width: 1.1rem;
  height: 1.1rem;
  border-radius: 50%;
  background: var(--cor-superficie);
}

.molde-barra {
  width: 7rem;
  height: 0.45rem;
  border-radius: 999px;
  background: var(--cor-sobre-primaria-suave);
}

.molde-blocos {
  display: grid;
  gap: 0.5rem;
  margin: 0;
  padding: 0.75rem;
  list-style: none;
}

.molde-bloco {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.9rem;
  min-width: 0;
  padding: 0.7rem 0.85rem;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
  background: var(--cor-superficie);
}

/* Bloco oculto continua APARECENDO, apagado e com a etiqueta. Sumir da tela
   faria quem ocultou "Últimas notícias" meses atrás não ter como descobrir
   por que a home está sem notícia. */
.molde-oculto {
  background: var(--cor-realce-fundo);
  opacity: 0.7;
}

.molde-desenho {
  display: grid;
  flex: none;
  place-items: center;
  width: 4.2rem;
  height: 2.6rem;
  padding: 0.3rem;
  border-radius: 5px;
  background: var(--cor-realce-fundo-forte);
}

.molde-faixa {
  width: 100%;
  height: 100%;
  border-radius: 3px;
  background: var(--cor-primaria);
}

.molde-grade {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2px;
  width: 100%;
  height: 100%;
}

.molde-grade i {
  border-radius: 2px;
  background: var(--cor-primaria);
}

.molde-lista {
  display: grid;
  gap: 3px;
  width: 100%;
}

.molde-lista i {
  height: 4px;
  border-radius: 2px;
  background: var(--cor-primaria);
}

.molde-lista i:first-child {
  width: 80%;
}

.molde-lista i:last-child {
  width: 60%;
}

.molde-pastilhas {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 3px;
  width: 100%;
}

.molde-pastilhas i {
  height: 6px;
  border-radius: 999px;
  background: var(--cor-primaria);
}

/* Dois retângulos altos: os cartões de destaque andam em pares. */
.molde-cartoes {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 3px;
  width: 100%;
  height: 100%;
}

.molde-cartoes i {
  border-radius: 2px;
  background: var(--cor-primaria);
}

/* Quatro quadrados: a amostra da galeria e a dos vídeos. Diferente da grade
   dos atalhos (três por linha, mais miúdos) porque são blocos diferentes — se
   o desenho fosse o mesmo, o quadrinho deixaria de dizer qual é qual. */
.molde-ladrilhos {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 3px;
  width: 100%;
  height: 100%;
}

.molde-ladrilhos i {
  border-radius: 2px;
  background: var(--cor-primaria);
}

/* Bolinhas: o "Fale conosco" é um desenho e um texto ao lado, repetido. Sem um
   molde próprio ele ficava igual ao dos links úteis, e o quadrinho deixava de
   dizer qual bloco é qual — que é a única razão de o quadrinho existir. */
.molde-contato {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 4px;
  width: 100%;
}

.molde-contato i {
  height: 8px;
  border-radius: 999px 4px 4px 999px;
  background: var(--cor-primaria);
}

.molde-texto {
  display: grid;
  flex: 1 1 14rem;
  gap: 0.15rem;
  min-width: 0;
}

.molde-nome {
  font-weight: 600;
}

/* O segundo formulário do modal do bloco — ocultar e mostrar — separado do
   primeiro por uma linha: são duas decisões diferentes, e um botão perdido
   embaixo de um campo de texto parece pertencer a ele. */
.secao-alternar {
  border-top: 1px solid var(--cor-borda);
}

@media (max-width: 40rem) {
  .molde-desenho {
    width: 3.2rem;
    height: 2.1rem;
  }
}

/* ==========================================================================
   OS AJUSTES DE LEITURA DO CIDADÃO (barra de acessibilidade)

   Escala de cinza, contraste negativo, links sublinhados e fonte legível.
   Todos aplicados por uma classe na etiqueta <html>, posta pelo SERVIDOR: a
   página já chega ajustada, sem o instante em que ela aparece errada e depois
   corrige — que, para quem tem baixa visão, é justamente o pior instante.

   ⚠️ O FILTRO TEM QUE FICAR NO <html>. NUNCA no <body>.

   A regra escrita do CSS diz que "filter" diferente de none faz do elemento o
   ponto de referência dos filhos com position:fixed. Se isso valesse aqui, a
   barra lateral do gerenciamento pararia de ser fixa e os modais deixariam de
   cobrir a tela — eles esticariam até a altura inteira do documento.

   MEDIDO, não suposto: no <html> o fixo CONTINUA fixo (o navegador aplica o
   filtro à tela, não ao elemento); no <body> quebra tudo — a barra lateral
   sobe junto com a rolagem e o modal vira uma caixa de 3000px. Quem for mexer
   nisto e achar mais limpo mover para o body: foi medido, e quebra.
   ========================================================================== */

html.escala-de-cinza {
  filter: grayscale(1);
}

html.contraste-negativo {
  filter: invert(1);
}

html.escala-de-cinza.contraste-negativo {
  filter: grayscale(1) invert(1);
}

/* OS GRÁFICOS NO CONTRASTE NEGATIVO (KAN-113). O modo inverte a tela inteira:
   o claro vira escuro. Os degraus claros das séries (40% e 70% da cor
   principal misturada ao branco) viravam marrom quase preto sobre o fundo
   preto, e a barra de "Empenhado" ou a fatia "Falta arrecadar" sumiam. Aqui
   os degraus se misturam ao texto (escuro) em vez do branco: depois de
   invertidos, ficam claros sobre o preto. */
html.contraste-negativo .grafico-serie-1 {
  --cor-marca: color-mix(in srgb, var(--cor-primaria) 30%, var(--cor-texto));
}
html.contraste-negativo .grafico-serie-2 {
  --cor-marca: color-mix(in srgb, var(--cor-primaria) 65%, var(--cor-texto));
}
html.contraste-negativo .grafico-serie-resto {
  --cor-marca: var(--cor-texto-suave);
}

/* Foto invertida vira negativo de filme, e aí ninguém reconhece o que está na
   imagem. O segundo "invert" desfaz o primeiro — o filtro do filho é aplicado
   antes do filtro da tela, então a foto volta ao normal enquanto o resto da
   página continua invertido. */
html.contraste-negativo img,
html.contraste-negativo video,
html.contraste-negativo .banner-foto {
  filter: invert(1);
}

html.escala-de-cinza.contraste-negativo img,
html.escala-de-cinza.contraste-negativo video,
html.escala-de-cinza.contraste-negativo .banner-foto {
  filter: invert(1) grayscale(1);
}

/* O MAIS ÚTIL DA LISTA, e o que menos parece.

   Quem não distingue cor não enxerga um link que só se diferencia por ser
   azul — e é exatamente o que o critério 1.4.1 da norma proíbe ("cor não pode
   ser o único jeito de dizer uma coisa"). Com isto ligado, todo link do
   portal ganha sublinhado, inclusive os que viraram botão. */
html.links-sublinhados a {
  text-decoration: underline;
  text-underline-offset: 0.15em;
}

/* FONTE LEGÍVEL.

   O que ajuda de verdade quem tem dislexia é o ESPAÇAMENTO — entre letras,
   entre palavras e entre linhas. "Fonte para dislexia" é assunto de estudo, e
   os estudos não sustentam o efeito que o nome promete. Por isso aqui é
   espaçamento com fonte que o computador já tem, e não mais um arquivo para
   baixar numa rede ruim.

   Os números saem da própria norma (critério 1.4.12, "espaçamento de texto"),
   que é o mínimo que uma página tem que aguentar sem quebrar. */
html.fonte-legivel body,
html.fonte-legivel input,
html.fonte-legivel select,
html.fonte-legivel textarea,
html.fonte-legivel button {
  font-family: Verdana, Tahoma, 'DejaVu Sans', sans-serif;
  letter-spacing: 0.12em;
  word-spacing: 0.16em;
}

html.fonte-legivel p,
html.fonte-legivel li,
html.fonte-legivel dd,
html.fonte-legivel .item-dados {
  line-height: 1.8;
}

/* Título com letra espaçada e apertada na altura fica ilegível justamente
   para quem ligou o ajuste. */
html.fonte-legivel h1,
html.fonte-legivel h2,
html.fonte-legivel h3 {
  line-height: 1.4;
}

/* --- O painel de acessibilidade no topo -----------------------------------

   POR QUE UM PAINEL QUE ABRE, e não oito botões na barra: oito botões lado a
   lado espremem o topo em qualquer tela menor que um monitor de escritório —
   e o topo é onde o nome da Prefeitura tem que caber. */
.acessibilidade {
  position: relative;
}

.acessibilidade-abrir {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  cursor: pointer;
  list-style: none;
}

.acessibilidade-abrir::-webkit-details-marker {
  display: none;
}

.acessibilidade-abrir:hover,
.acessibilidade-abrir:focus-visible {
  background: color-mix(in srgb, var(--cor-sobre-primaria) 15%, transparent);
}

.acessibilidade-painel {
  position: absolute;
  z-index: 40;
  top: calc(100% + 0.4rem);
  left: 0;
  min-width: 15rem;
  padding: 0.9rem 1rem 1rem;
  border: 1px solid var(--cor-borda-forte);
  border-radius: var(--raio);
  background: var(--cor-superficie);
  box-shadow: var(--sombra-flutuante);
  color: var(--cor-texto);
  text-align: left;
}

.acessibilidade-titulo {
  margin: 0 0 0.6rem;
  font-weight: 700;
  font-size: 1rem;
}

.acessibilidade-lista {
  display: grid;
  gap: 0.1rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.acessibilidade-botao {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.42rem 0.5rem;
  border-radius: 6px;
  color: var(--cor-texto);
  font-size: 0.92rem;
  text-decoration: none;
}

.acessibilidade-botao:hover {
  background: var(--cor-realce-fundo);
}

/* O ajuste LIGADO não se distingue só pela cor: ganha fundo e peso de letra.
   Cor sozinha não serve justamente para quem liga estes ajustes. */
.acessibilidade-ligado {
  background: var(--cor-realce-fundo-forte);
  color: var(--cor-link);
  font-weight: 700;
}

/* No limite do tamanho de letra o botão não some — fica apagado e continua
   sendo lido. Botão que desaparece faz os outros pularem de lugar. */
.acessibilidade-botao[aria-disabled='true'] {
  opacity: 0.45;
  pointer-events: none;
}

.acessibilidade-reiniciar {
  margin-top: 0.35rem;
  padding-top: 0.6rem;
  border-top: 1px solid var(--cor-borda);
}

.icone-acessibilidade {
  flex: none;
}

/* O painel abre para a esquerda quando não cabe à direita da tela. */
@media (max-width: 40rem) {
  .acessibilidade-painel {
    right: 0;
    left: auto;
  }
}

/* No alto contraste o painel é uma caixa branca por cima de tudo: sem moldura
   ele se dissolve no fundo preto. */
html.contraste-alto .acessibilidade-painel {
  border: 2px solid var(--contraste-texto);
}

/* --- As notícias da home, em dois níveis ---------------------------------

   Duas em destaque com foto grande, e o resto em lista com miniatura ao lado.
   Três do mesmo tamanho não dizem qual é a importante; seis do mesmo tamanho
   viram um paredão. Com os dois níveis a hierarquia está no desenho. */
.noticias-destaque {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr));
  gap: 1.75rem;
  margin: 0 0 2rem;
}

.noticia-grande {
  display: grid;
  /* "start" e não o esticar de sempre: numa dupla em que uma notícia tem foto
     e a outra não, sem isto as linhas da que não tem foto se espalham para
     ocupar a mesma altura, e o resumo fica boiando longe do título. */
  align-content: start;
  gap: 0.6rem;
  min-width: 0;
}

/* O TÍTULO VEM ANTES DA FOTO, como no Rio. Não é gosto: quem usa leitor de
   tela ouve o título primeiro e decide se continua, em vez de esperar a
   descrição de uma imagem que é só decoração. */
.noticia-grande h3 {
  margin: 0;
  font-size: 1.2rem;
  line-height: 1.3;
}

.noticia-grande h3 a {
  color: var(--cor-link);
  text-decoration: none;
}

.noticia-grande h3 a:hover,
.noticia-grande h3 a:focus {
  text-decoration: underline;
}

.noticia-grande-capa,
.noticia-linha-capa,
.cartao-video-capa {
  /* "color: inherit" NUM LINK QUE SÓ TEM IMAGEM DENTRO.

     Parece linha sem serventia e não é: um <a> sem cor declarada recebe o azul
     padrão do navegador, que o tema não alcança — e é exatamente o defeito que
     deixava o portal verde com pedaços azuis. Aqui não aparece enquanto a foto
     carrega; aparece no dia em que ela falta, e aí a moldura vem azul num
     portal verde. A suíte do tema varre a home procurando esse azul, e foi ela
     que apontou estes três. */
  color: inherit;
}

.noticia-grande-capa {
  display: block;
  overflow: hidden;
  border-radius: var(--raio);
  background: var(--cor-vazio);
}

.noticia-grande-capa img {
  display: block;
  width: 100%;
  /* O "height: auto" NÃO É ENFEITE, e custou uma foto de mil pixels de altura
     no meio da home.

     O HTML da notícia escreve width e height da imagem para o navegador
     reservar o espaço antes de ela chegar. Esses dois atributos viram CSS de
     baixa prioridade: o "width: 100%" daqui vence o primeiro, mas nada vencia
     o segundo — e altura fixa em pixel DESLIGA o aspect-ratio. Resultado: a
     capa saía no tamanho original do arquivo.

     Foi achado MEDINDO a página no navegador, e não olhando: 516 de largura
     por 1067 de altura onde a conta pedia 290. */
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}

.noticia-grande-resumo {
  margin: 0;
  color: var(--cor-texto-suave);
}

.noticias-lista {
  display: grid;
  /* DUAS COLUNAS NO MÁXIMO, e não três. Com 24rem de coluna mínima, uma tela
     de escritório comporta duas e uma de celular comporta uma. Três cabiam na
     medida anterior e ficavam estreitas demais: título de notícia quebrando em
     quatro linhas ao lado de uma miniatura de 88 pixels. */
  grid-template-columns: repeat(auto-fit, minmax(min(24rem, 100%), 1fr));
  gap: 1rem 1.75rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.noticia-linha {
  display: flex;
  gap: 0.9rem;
  align-items: flex-start;
  min-width: 0;
  padding-top: 1rem;
  border-top: 1px solid var(--cor-borda);
}

.noticia-linha-capa {
  display: block;
  flex: none;
  overflow: hidden;
  width: 5.5rem;
  border-radius: 6px;
  background: var(--cor-vazio);
}

.noticia-linha-capa img {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

.noticia-linha-texto {
  min-width: 0;
}

.noticia-linha h3 {
  margin: 0 0 0.2rem;
  font-size: 0.98rem;
  line-height: 1.3;
}

.noticia-linha h3 a {
  color: var(--cor-link);
  text-decoration: none;
}

.noticia-linha h3 a:hover,
.noticia-linha h3 a:focus {
  text-decoration: underline;
}

@media (max-width: 40rem) {
  .titulo-forte {
    font-size: 1.5rem;
  }

  .titulo-leve {
    font-size: 0.95rem;
  }
}

/* --- O rodapé em colunas -------------------------------------------------

   O menu do topo só cabe sete itens e a Prefeitura tem cinquenta destinos. O
   rodapé é onde o resto mora, agrupado por "de quem é o assunto" em vez de
   numa lista corrida. É o desenho do portal do Rio.

   Cada coluna é um <nav> com nome próprio: quem usa leitor de tela pula de
   grupo em grupo em vez de ouvir cinquenta links seguidos. */
.rodape-marca {
  display: flex;
  align-items: center;
  gap: var(--espaco-3);
  min-width: 0;
}

.rodape-brasao {
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  background: var(--cor-sobre-primaria-suave);
  color: var(--cor-primaria-escura);
  font-weight: 800;
}

/* O RODAPÉ ENXUTO (KAN-110): a marca à esquerda e os quatro grupos à direita,
   numa linha só. Cada grupo é um <details>: o título é o botão, e a lista
   desce embaixo dele quando a pessoa clica. */
.rodape-topo {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--espaco-5);
  margin: 0 0 var(--espaco-5);
}
.rodape-grupos {
  display: flex;
  flex-wrap: wrap;
  gap: var(--espaco-2);
}
.rodape-grupo-titulo {
  display: inline-flex;
  align-items: center;
  gap: var(--espaco-2);
  padding: 8px 16px;
  border: 1px solid color-mix(in srgb, var(--cor-sobre-primaria) 25%, transparent);
  border-radius: 999px;
  color: var(--cor-sobre-primaria);
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  list-style: none;
}
.rodape-grupo-titulo::-webkit-details-marker {
  display: none;
}
.rodape-grupo-titulo:hover,
.rodape-grupo-titulo:focus-visible,
.rodape-grupo[open] .rodape-grupo-titulo {
  border-color: color-mix(in srgb, var(--cor-sobre-primaria) 60%, transparent);
  background: color-mix(in srgb, var(--cor-sobre-primaria) 10%, transparent);
}
/* A seta aponta para onde a lista abre: para cima. */
.rodape-grupo-seta {
  transform: rotate(180deg);
  transition: transform 0.15s ease;
}
.rodape-grupo[open] .rodape-grupo-seta {
  transform: none;
}
/* A lista abre como um menu, por cima, em vez de empurrar os outros títulos
   para o lado. Abre PARA CIMA: o rodapé é o fim da página, e para baixo ela
   sairia do rodapé para o vazio. name="rodape-grupos" no <details> deixa um
   só aberto de cada vez, sem script. */
.rodape-grupo {
  position: relative;
}
.rodape-grupo > nav {
  position: absolute;
  z-index: 5;
  bottom: calc(100% + var(--espaco-2));
  left: 0;
  min-width: 16rem;
  max-width: calc(100vw - 2rem);
  border: 1px solid color-mix(in srgb, var(--cor-sobre-primaria) 18%, transparent);
  border-radius: var(--raio);
  background: var(--cor-primaria-escura);
  box-shadow: var(--sombra-janela);
}
.rodape-grupo:last-child > nav {
  right: 0;
  left: auto;
}
.rodape-grupo ul {
  display: grid;
  margin: 0;
  padding: var(--espaco-2) 0;
  list-style: none;
}
.rodape-grupo a {
  display: block;
  padding: 6px 16px;
  color: var(--cor-sobre-primaria-suave);
  font-size: var(--texto-pequeno);
  text-decoration: none;
}
.rodape-grupo a:hover,
.rodape-grupo a:focus {
  color: var(--cor-sobre-primaria);
  text-decoration: underline;
}
@media (prefers-reduced-motion: reduce) {
  .rodape-grupo-seta {
    transition: none;
  }
}

.rodape-legal {
  padding-top: var(--espaco-4);
  border-top: 1px solid color-mix(in srgb, var(--cor-sobre-primaria) 18%, transparent);
}

/* ---------------------------------------------------------------------------
   O BOTÃO DO RADAR DA TRANSPARÊNCIA PÚBLICA (PNTP 2.9 — KAN-145)
   ---------------------------------------------------------------------------

   Um link com cara de botão, e não a imagem da Atricon: a marca é deles.
   Duas linhas — o nome, que é o que o critério procura, e o endereço, que
   diz a quem clica que ele vai sair do portal.

   No rodapé ele herda o branco do fundo escuro. Na porta do Portal da
   Transparência (variante "titulo") vira um botão pequeno ao lado do título. */
.radar-transparencia {
  display: inline-flex;
  flex-direction: column;
  gap: 2px;
  margin: 0 0 1rem;
  padding: 10px 16px;
  border: 1px solid color-mix(in srgb, var(--cor-sobre-primaria) 45%, transparent);
  border-radius: var(--raio);
  color: var(--cor-sobre-primaria);
  text-decoration: none;
}

.radar-transparencia:hover,
.radar-transparencia:focus {
  border-color: var(--cor-sobre-primaria);
  text-decoration: underline;
}

.radar-transparencia-nome {
  font-weight: 700;
}

.radar-transparencia-onde {
  font-size: 13px;
  color: var(--cor-sobre-primaria-suave);
}

.destaque-titulo-linha {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--espaco-2) var(--espaco-3);
}

.destaque-titulo-linha h1 {
  margin: 0;
}

.destaque-titulo-linha + .destaque-texto {
  margin-top: var(--espaco-2);
}

.radar-transparencia-titulo {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  border: 1px solid var(--cor-borda-forte);
  border-radius: 999px;
  background: var(--cor-superficie);
  color: var(--cor-link);
  font-size: var(--texto-mini);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}

.radar-transparencia-titulo:hover,
.radar-transparencia-titulo:focus-visible {
  border-color: var(--cor-link);
  background: var(--cor-realce-fundo);
}

/* ---------------------------------------------------------------------------
   CONCURSOS E SELEÇÕES (TR 2.12 — KAN-26)
   ---------------------------------------------------------------------------

   Três desenhos: o bloco da página inicial, a lista pública e a lista de
   documentos para baixar.

   O QUE MANDA NOS TRÊS É A MESMA DECISÃO: o que está com inscrição aberta se
   destaca, e o resto fica neutro. Se tudo se destaca, nada se destaca — e o
   que importa aqui é a inscrição que ainda dá para fazer, porque perder o
   prazo é irreversível. */

/* O bloco da página inicial: três cartões, lado a lado. */
.grade-concursos {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(17rem, 100%), 1fr));
  gap: 1rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.grade-concursos > li {
  display: grid;
  min-width: 0;
}

.cartao-concurso-home {
  display: grid;
  align-content: start;
  gap: 0.4rem;
  height: 100%;
  padding: 1.1rem;
  border: 1px solid var(--cor-borda);
  border-radius: 10px;
  background: var(--cor-superficie);
  color: var(--cor-texto);
  text-decoration: none;
}

.cartao-concurso-home:hover,
.cartao-concurso-home:focus {
  border-color: var(--cor-borda-forte);
}

/* A faixa colorida na lateral marca o que está aberto — e é uma BORDA, e não
   só uma cor de fundo: quem enxerga pouco ou está num monitor ruim percebe a
   forma antes da cor. A palavra da fase continua escrita ali em cima, que é o
   que resolve para quem não distingue cor nenhuma. */
.cartao-concurso-home-aberto {
  border-left: 4px solid var(--cor-destaque);
}

.cartao-concurso-fase {
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--cor-texto-suave);
}

.cartao-concurso-home-aberto .cartao-concurso-fase {
  color: var(--cor-destaque);
}

.cartao-concurso-titulo {
  font-size: 1.05rem;
  font-weight: 700;
  line-height: 1.3;
  /* break-word, e não anywhere: "anywhere" encolhe a largura mínima da coluna
     e o título passa a quebrar no meio da palavra com espaço de sobra ao lado.
     Foi um defeito real desta folha, corrigido na varredura de QA. */
  overflow-wrap: break-word;
}

.cartao-concurso-numero,
.cartao-concurso-prazo,
.cartao-concurso-resumo {
  font-size: 0.88rem;
  color: var(--cor-texto-suave);
}

.cartao-concurso-prazo {
  font-weight: 600;
}

/* A lista pública: um cartão largo por concurso, empilhados. */
.lista-concursos {
  display: grid;
  gap: 1rem;
  margin: 0 0 1.5rem;
  padding: 0;
  list-style: none;
}

.cartao-concurso {
  padding: 1.25rem;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
  background: var(--cor-superficie);
}

.cartao-concurso-aberto {
  border-left: 4px solid var(--cor-destaque);
}

.cartao-concurso h2 {
  margin: 0.35rem 0 0.5rem;
  font-size: 1.25rem;
  overflow-wrap: break-word;
}

/* O link do título recebe cor explícita. Sem isso ele sai no azul padrão do
   navegador, que o tema da Prefeitura não alcança — é o defeito que reapareceu
   cinco vezes nesta folha, sempre pelo mesmo motivo. */
.cartao-concurso h2 a {
  color: var(--cor-link);
  text-decoration: none;
}

.cartao-concurso h2 a:hover,
.cartao-concurso h2 a:focus {
  text-decoration: underline;
}

.cartao-concurso p {
  margin: 0.35rem 0 0;
}

.concurso-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  font-size: 0.85rem;
  color: var(--cor-texto-suave);
}

.concurso-prazo {
  font-weight: 600;
}

.concurso-documentos {
  font-size: 0.9rem;
  color: var(--cor-texto-suave);
}

.concurso-documentos a {
  color: var(--cor-link);
}

/* A lista de documentos para baixar.

   Cada item é uma linha inteira clicável, e não um "baixar" pequeno no fim da
   frase: o alvo do dedo em celular é a linha toda, e quem usa teclado chega ao
   documento com uma tabulação por documento. */
.lista-documentos {
  display: grid;
  gap: 0;
  margin: 0;
  padding: 0;
  list-style: none;
}

.lista-documentos li + li .documento-linha {
  border-top: 1px solid var(--cor-borda);
}

.documento-linha {
  display: grid;
  gap: 0.2rem;
  padding: 0.85rem 0.5rem;
  color: var(--cor-texto);
  text-decoration: none;
}

.documento-linha:hover,
.documento-linha:focus {
  background: var(--cor-realce-fundo);
}

.documento-rotulo {
  font-weight: 700;
  color: var(--cor-link);
  overflow-wrap: break-word;
}

.documento-linha:hover .documento-rotulo,
.documento-linha:focus .documento-rotulo {
  text-decoration: underline;
}

.documento-dados {
  font-size: 0.85rem;
  color: var(--cor-texto-suave);
}

/* Os anexos na tela de gerenciamento: cada um com o próprio formulário de
   rótulo e data, e os botões de ordem embaixo. */
.lista-anexos {
  display: grid;
  gap: 0.75rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.item-anexo {
  padding: 1rem;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
  background: var(--cor-realce-fundo);
}

.item-anexo > .acoes-linha {
  margin-top: 0.5rem;
}

/* ---------------------------------------------------------------------------
   DOCUMENTOS PÚBLICOS (TR 2.11 — KAN-26)
   ---------------------------------------------------------------------------

   A página de documentos lista BIBLIOTECAS, e não arquivos soltos. O cartão
   não tem capa porque documento não tem capa: o que identifica é o nome que a
   Prefeitura deu ao conjunto e quantos arquivos há dentro.

   A lista de downloads de dentro de cada biblioteca é a mesma .lista-documentos
   da página de concursos — de propósito: é o mesmo gesto, e dois desenhos
   diferentes para o mesmo gesto seriam duas coisas para a pessoa aprender. */
.grade-bibliotecas {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(16rem, 100%), 1fr));
  gap: 1rem;
  margin: 0 0 1.5rem;
  padding: 0;
  list-style: none;
}

.grade-bibliotecas > li {
  display: grid;
  min-width: 0;
}

.cartao-biblioteca {
  display: grid;
  align-content: start;
  gap: 0.35rem;
  height: 100%;
  padding: 1.1rem;
  border: 1px solid var(--cor-borda);
  border-left: 4px solid var(--cor-primaria);
  border-radius: 10px;
  background: var(--cor-superficie);
  color: var(--cor-texto);
  text-decoration: none;
}

.cartao-biblioteca:hover,
.cartao-biblioteca:focus {
  border-color: var(--cor-borda-forte);
  border-left-color: var(--cor-primaria);
}

.cartao-biblioteca-conta {
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--cor-texto-suave);
}

.cartao-biblioteca-nome {
  font-size: 1.05rem;
  font-weight: 700;
  line-height: 1.3;
  color: var(--cor-link);
  /* break-word e não anywhere: ver a nota em .cartao-concurso-titulo. */
  overflow-wrap: break-word;
}

.cartao-biblioteca:hover .cartao-biblioteca-nome,
.cartao-biblioteca:focus .cartao-biblioteca-nome {
  text-decoration: underline;
}

.cartao-biblioteca-descricao,
.cartao-biblioteca-dados {
  font-size: 0.88rem;
  color: var(--cor-texto-suave);
}

/* ---------------------------------------------------------------------------
   REDES SOCIAIS NA PÁGINA INICIAL (TR 2.6 — KAN-26)
   ---------------------------------------------------------------------------

   Dois desenhos no mesmo bloco, porque as plataformas permitem coisas
   diferentes: quem tem quadro oficial (Facebook, YouTube, TikTok) mostra o
   feed; quem não tem (Instagram, X, LinkedIn) entra como cartão com link.

   A ALTURA DO QUADRO VEM DO HTML, do atributo height — cada rede tem a sua, e
   ela mora em src/redes/redes.js. O CSS aqui cuida só da largura e da moldura.
   Atributo de altura em pixels vira dica de estilo do navegador, e por isso
   não há altura escrita aqui: as duas brigariam. */
.grade-redes {
  display: grid;
  /* 21rem, e não menos: o quadro do Facebook é desenhado pela própria Meta
     para 420 pixels de largura, e numa coluna mais estreita que isso ele
     encolhe o texto do post em vez de quebrar a linha. */
  grid-template-columns: repeat(auto-fit, minmax(min(21rem, 100%), 1fr));
  gap: 1rem;
  margin: 0 0 1rem;
  padding: 0;
  list-style: none;

  /* CADA CARTÃO COM A PRÓPRIA ALTURA, e é aqui que estava o defeito.

     O padrão do grid é esticar todos os itens da linha até a altura do mais
     alto. O quadro do TikTok é o mais alto dos três, então o do Facebook e o
     do YouTube ganhavam um vão em branco embaixo do tamanho da diferença — e
     o bloco inteiro ficava com o dobro da altura que precisava.

     Não dá para resolver igualando as alturas: elas são diferentes de
     propósito, porque cada plataforma entrega um quadro de proporção
     diferente. O certo é o grid parar de esticar. */
  align-items: start;
}

.cartao-rede {
  display: grid;
  align-content: start;
  gap: 0.5rem;
  min-width: 0;
  /* Enxuto de propósito: o conteúdo aqui é o quadro da rede, e a moldura só
     precisa separá-lo do fundo. Preenchimento grande num cartão cujo miolo já
     tem o preenchimento da própria plataforma vira margem dentro de margem. */
  padding: 0.75rem;
  border: 1px solid var(--cor-borda);
  border-radius: 10px;
  background: var(--cor-superficie);
}

.cartao-rede-topo {
  margin: 0;
  font-size: 0.95rem;
  font-weight: 700;
}

/* Cor explícita no link: sem ela ele sai no azul padrão do navegador, que o
   tema da Prefeitura não alcança. */
.cartao-rede-topo a {
  color: var(--cor-link);
  text-decoration: none;
}

.cartao-rede-topo a:hover,
.cartao-rede-topo a:focus {
  text-decoration: underline;
}

.quadro-rede {
  display: block;
  width: 100%;
  max-width: 100%;
  /* A altura vem do atributo height do próprio <iframe>; aqui só se garante
     que ela não seja travada por nada. */
  border: 0;
  border-radius: 8px;
  background: var(--cor-vazio);
}

/* As redes que não embutem: uma faixa de cartões, menor que os quadros. */
.grade-redes-cartao {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(13rem, 100%), 1fr));
  gap: 0.75rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.grade-redes-cartao > li {
  display: grid;
  min-width: 0;
}

.cartao-rede-link {
  display: grid;
  align-content: center;
  gap: 0.2rem;
  height: 100%;
  padding: 0.9rem 1rem;
  border: 1px solid var(--cor-borda);
  border-radius: 10px;
  background: var(--cor-superficie);
  color: var(--cor-texto);
  text-decoration: none;
}

.cartao-rede-link:hover,
.cartao-rede-link:focus {
  border-color: var(--cor-borda-forte);
}

.cartao-rede-nome {
  font-weight: 700;
  color: var(--cor-link);
  overflow-wrap: break-word;
}

.cartao-rede-link:hover .cartao-rede-nome,
.cartao-rede-link:focus .cartao-rede-nome {
  text-decoration: underline;
}

.cartao-rede-dica {
  font-size: 0.85rem;
  color: var(--cor-texto-suave);
}

/* ---------------------------------------------------------------------------
   ESCOLHER DA BIBLIOTECA **OU** ENVIAR DO COMPUTADOR
   ---------------------------------------------------------------------------

   Os dois caminhos lado a lado, com um "ou" no meio que deixa claro que são
   alternativas — e não dois campos para preencher.

   O "ou" é um <p> com uma linha de cada lado, feita com pseudo-elementos. Podia
   ser só a palavra solta; a linha é o que faz o olho ler "isto OU aquilo" antes
   de ler as palavras. */
.escolher-arquivo {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: start;
  gap: 1rem;
  margin-bottom: 1rem;
}

.escolher-arquivo .campo {
  min-width: 0;
  margin-bottom: 0;
}

.escolher-arquivo-ou {
  display: grid;
  justify-items: center;
  gap: 0.35rem;
  /* Desce até a altura do campo, para o "ou" ficar na linha dos dois. */
  margin: 1.85rem 0 0;
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--cor-apagado);
}

.escolher-arquivo-ou::before,
.escolher-arquivo-ou::after {
  content: '';
  width: 1px;
  height: 0.9rem;
  background: var(--cor-borda-forte);
}

/* O campo de arquivo do navegador é feio e cada um desenha o seu. Não dá para
   trocar o botão sem JavaScript, então o que se faz é emoldurar o conjunto para
   ele não destoar dos outros campos da tela. */
.escolher-arquivo input[type='file'] {
  width: 100%;
  padding: 0.45rem 0.6rem;
  border: 1px dashed var(--cor-borda-forte);
  border-radius: var(--raio);
  background: var(--cor-realce-fundo);
  color: var(--cor-texto);
  font-family: inherit;
  font-size: 0.92rem;
}

.escolher-arquivo input[type='file']:hover {
  border-color: var(--cor-primaria);
}

/* Em celular os dois caminhos empilham, e aí o "ou" vira uma linha deitada:
   de pé, entre dois campos empilhados, ele não separaria nada. */
@media (max-width: 640px) {
  .escolher-arquivo {
    grid-template-columns: 1fr;
    gap: 0.75rem;
  }

  .escolher-arquivo-ou {
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    margin: 0;
  }

  .escolher-arquivo-ou::before,
  .escolher-arquivo-ou::after {
    width: auto;
    height: 1px;
    align-self: center;
  }
}

/* ---------------------------------------------------------------------------
   O FORMULÁRIO DE CADA REDE SOCIAL
   ---------------------------------------------------------------------------

   Um botão por rede, com o desenho dela ao lado do nome, e um formulário por
   rede atrás de cada botão. */
.acoes-linha-redes {
  flex-wrap: wrap;
  gap: 0.5rem;
}

.icone-rede {
  flex: none;
  vertical-align: -0.15em;
  margin-right: 0.4rem;
}

/* O exemplo escrito, embaixo do campo.

   Fica ali porque o placeholder some no instante em que a pessoa digita a
   primeira letra — justamente quando ela ainda está conferindo se o formato
   está certo. Escrito, ele fica. */
.campo-exemplo {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.4rem;
  margin: 0.35rem 0 0;
  font-size: 0.85rem;
}

.campo-exemplo-rotulo {
  flex: none;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--cor-apagado);
}

.campo-exemplo code {
  min-width: 0;
  padding: 0.1rem 0.4rem;
  border: 1px solid var(--cor-borda);
  border-radius: 4px;
  background: var(--cor-realce-fundo);
  color: var(--cor-texto-suave);
  /* break-word e não anywhere: um endereço longo quebra entre as barras, e não
     no meio de uma palavra com espaço de sobra ao lado. */
  overflow-wrap: break-word;
}

/* ---------------------------------------------------------------------------
   O CARTÃO DE REDE MONTADO PELO PORTAL
   ---------------------------------------------------------------------------

   Hoje só o Instagram cai aqui: ele não deixa nenhum site embutir o perfil, e
   o embed de um post avulso vira retângulo de erro no dia em que o post é
   apagado. Então o portal desenha o cartão: o @, uma foto da biblioteca e a
   data em que ela foi trocada.

   AS CORES DESTE BLOCO SÃO FIXAS, e não as do tema da Prefeitura. É o único
   lugar do portal onde isso acontece, e é de propósito: este cartão fica lado
   a lado com os quadros que o Facebook e o TikTok desenham, que vêm brancos
   com borda cinza e não obedecem a tema nenhum. Pintar só este com a cor da
   Prefeitura faria a fileira parecer quebrada.

   NÃO HÁ LOGOMARCA NENHUMA AQUI. O nome da rede aparece como texto comum, que
   é uso legítimo; a marca desenhada é de cada empresa, e o portal é vendido. */
.rede-painel {
  /* Cores fixas de propósito (KAN-109): o painel imita o Instagram, e as
     cores são as dele, não as do portal. */
  border: 1px solid #dbdbdb;
  border-radius: 8px;
  background: #fff;
  /* Segura os cantos da foto, que encosta nas bordas laterais. */
  overflow: hidden;
}

.rede-painel-arroba {
  margin: 0;
  padding: 0.7rem 0.8rem;
  font-size: 0.95rem;
  font-weight: 700;
  color: #262626;
  /* Sem isto, um @ longo empurra a largura do cartão e desmonta a fileira. */
  overflow-wrap: break-word;
}

.rede-painel-foto {
  display: block;
  background: #efefef;
}

/* A FOTO ENTRA QUADRADA, CORTADA PELO MEIO.

   aspect-ratio + object-fit é o que dá a mesma altura a todo cartão, venha a
   foto deitada, em pé ou já quadrada. O custo é que foto deitada perde as
   beiradas — decidido com a wiri em 14/09: melhor o corte do que o cartão
   mudando de tamanho a cada troca de foto.

   height: auto é OBRIGATÓRIO junto do atributo height do HTML: sem ele a
   altura em pixels vira regra de estilo e DESLIGA o aspect-ratio. Foi o
   defeito que deixou a capa da notícia com 1067px de altura. */
.rede-painel-foto img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1 / 1;
  object-fit: cover;

  /* O TETO DE ALTURA é o que mantém este cartão do tamanho dos vizinhos.

     Quadrado sozinho não basta: a largura da coluna muda com quantas redes
     estão cadastradas. Com duas redes numa tela de escritório a coluna passa
     de 580px, o quadrado vira 580 de altura, e o cartão fica com 664 contra os
     420 do quadro do Facebook ao lado — medido, não estimado.

     Com o teto, coluna estreita dá foto quadrada e coluna larga dá foto
     deitada, cortada em cima e embaixo pelo object-fit. Nos dois casos o cartão
     fecha perto dos 420 do vizinho. */
  max-height: 19rem;
}

.rede-painel-foto:hover img,
.rede-painel-foto:focus img {
  opacity: 0.9;
}

/* outline-offset negativo: o anel de foco fica DENTRO da foto. Por fora ele
   seria cortado pelo overflow: hidden do painel. */
.rede-painel-foto:focus-visible {
  outline: 3px solid var(--cor-destaque);
  outline-offset: -3px;
}

.rede-painel-pe {
  padding: 0.8rem;
}

.rede-painel-botao {
  display: block;
  padding: 0.5rem;
  border-radius: 8px;
  background: linear-gradient(45deg, #f09433, #dc2743, #bc1888);
  color: #fff;
  font-size: 0.9rem;
  font-weight: 700;
  text-align: center;
  text-decoration: none;
}

.rede-painel-botao:hover,
.rede-painel-botao:focus {
  filter: brightness(1.08);
}

.rede-painel-quando {
  margin: 0.45rem 0 0;
  font-size: 0.75rem;
  color: #737373;
  text-align: center;
}

/* ALTO CONTRASTE: o preferido do cidadão ganha das cores fixas acima.

   Quem liga o alto contraste tem dificuldade real de enxergar, e o degradê do
   botão é exatamente o que atrapalha. A regra geral do modo (lá em cima, a que
   alcança tudo) já zera a cor de fundo e a borda deste cartão — mas ela troca
   `background-color`, e degradê é `background-image`. Sem a linha abaixo o
   botão continuaria colorido no modo que existe para tirar a cor da frente.

   O !important e o prefixo `html` são para empatar em peso com aquela regra e
   vencer por vir depois. É a mesma conta explicada lá. */
html.contraste-alto .rede-painel-botao {
  background-image: none !important;
  border: 1px solid var(--contraste-texto);
}

/* ---------------------------------------------------------------------------
   O RELATÓRIO DE PENDÊNCIAS (TR 2.14)
   ---------------------------------------------------------------------------

   A tela tem duas partes com desenhos diferentes de propósito: em cima o
   placar, que responde "quanta coisa tem e quão urgente"; embaixo um bloco por
   tipo de pendência, que responde "o que é, por que importa e onde arrumar".

   O NÍVEL É COR **E** PALAVRA, nunca só cor. Quem não distingue vermelho de
   âmbar — e é uma pessoa em doze — ficaria sem a informação mais importante da
   tela. O selo escrito "Crítica" funciona em tela colorida, em impressão preto
   e branco e no leitor de tela. */
.ficha-pendencias {
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  align-items: start;
}

.pendencia-nivel {
  padding-left: 0.7rem;
  border-left: 3px solid var(--cor-borda);
}

.pendencia-nivel-critica {
  border-left-color: var(--cor-erro);
}

.pendencia-nivel-alerta {
  border-left-color: var(--cor-atencao);
}

.pendencia-nivel-aviso {
  border-left-color: var(--cor-texto-suave);
}

.pendencia-nivel dd {
  display: grid;
  gap: 0.15rem;
}

.pendencia-nivel-numero {
  font-size: 1.6rem;
  font-weight: 700;
  line-height: 1.1;
}

.pendencia-nivel-explica {
  font-size: 0.82rem;
  line-height: 1.35;
  color: var(--cor-texto-suave);
}

/* A cor da lateral do bloco diz o nível antes de a pessoa ler qualquer coisa.
   Ela sobrescreve a lateral padrão do .aviso, que é a cor de destaque do tema
   e aqui não significaria nada. */
.pendencia-grupo-critica {
  border-left-color: var(--cor-erro);
}

.pendencia-grupo-alerta {
  border-left-color: var(--cor-atencao);
}

.pendencia-grupo-aviso {
  border-left-color: var(--cor-texto-suave);
}

.pendencia-etiqueta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 0.4rem;
}

/* Selo contornado, e não preenchido: preenchido exigiria um par de cores novo
   para cada nível e outra conta de contraste. Contornado, a mesma cor serve de
   borda e de letra, e ela já passou no teste como letra. */
.pendencia-selo {
  padding: 0.1rem 0.5rem;
  border: 1px solid currentcolor;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.pendencia-selo-critica {
  color: var(--cor-erro);
}

.pendencia-selo-alerta {
  color: var(--cor-atencao);
}

.pendencia-selo-aviso {
  color: var(--cor-texto-suave);
}

.pendencia-modulo {
  font-size: 0.85rem;
  color: var(--cor-texto-suave);
}

.pendencia-porque {
  max-width: 62ch;
}

.pendencia-arrumar {
  max-width: 62ch;
}

.pendencia-quantos {
  margin: 1rem 0 0.4rem;
  font-size: 0.85rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--cor-texto-suave);
}

/* Duas colunas quando cabe: são listas de nomes curtos, e uma coluna só faria
   cinquenta arquivos órfãos ocuparem uma tela inteira de rolagem. */
.pendencia-itens {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(22rem, 100%), 1fr));
  gap: 0.3rem 1.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.pendencia-itens > li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.4rem;
  padding: 0.3rem 0;
  border-bottom: 1px solid var(--cor-borda);
  min-width: 0;
}

/* Cor explícita: sem ela o link sai no azul padrão do navegador, que o tema da
   Prefeitura não alcança. Já apareceu cinco vezes em telas diferentes. */
.pendencia-itens a {
  color: var(--cor-link);
  overflow-wrap: break-word;
}

.pendencia-detalhe {
  font-size: 0.82rem;
  color: var(--cor-texto-suave);
}

/* ---------------------------------------------------------------------------
   MÓDULO 3 — CONTRATAÇÕES
   --------------------------------------------------------------------------- */

/* As seis portas do painel do módulo.

   Cartão em vez de lista porque o número é a informação principal: a pessoa
   olha "Credores 0" e já sabe por onde começar, sem ler a linha de baixo. */
.portas-do-modulo {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(17rem, 100%), 1fr));
  gap: 1rem;
  margin: 0 0 1.25rem;
  padding: 0;
  list-style: none;
}

.portas-do-modulo > li {
  display: grid;
  min-width: 0;
}

.porta-do-modulo {
  display: grid;
  align-content: start;
  gap: 0.25rem;
  height: 100%;
  padding: 1rem 1.1rem;
  border: 1px solid var(--cor-borda);
  border-left: 4px solid var(--cor-destaque);
  border-radius: var(--raio);
  background: var(--cor-superficie);
  color: var(--cor-texto);
  text-decoration: none;
}

.porta-do-modulo:hover,
.porta-do-modulo:focus {
  border-color: var(--cor-borda-forte);
  border-left-color: var(--cor-destaque);
}

.porta-numero {
  font-size: 1.7rem;
  font-weight: 700;
  line-height: 1.1;
}

.porta-numero small {
  margin-left: 0.3rem;
  font-size: 0.78rem;
  font-weight: 400;
  color: var(--cor-texto-suave);
}

/* Cor explícita no título: sem ela o link sai no azul padrão do navegador, que
   o tema da Prefeitura não alcança. Já apareceu cinco vezes em telas
   diferentes — a cada link novo, declarar a cor. */
.porta-titulo {
  font-weight: 700;
  color: var(--cor-link);
  overflow-wrap: break-word;
}

.porta-do-modulo:hover .porta-titulo,
.porta-do-modulo:focus .porta-titulo {
  text-decoration: underline;
}

.porta-explica {
  font-size: 0.85rem;
  line-height: 1.4;
  color: var(--cor-texto-suave);
}

/* "QUANDO SE USA ISTO" — a linha que separa o que a porta É do momento em que
   ela serve.

   Mora numa linha própria, mais discreta que a explicação, porque é a resposta
   para uma pergunta diferente: a explicação diz o que tem lá dentro, esta diz
   se é agora que a pessoa precisa entrar. Sem ela, o painel do módulo ficava
   com dez portas do mesmo peso e nenhuma pista de ordem. */
.porta-quando {
  margin-top: 0.15rem;
  font-size: 0.8rem;
  font-style: italic;
  line-height: 1.35;
  color: var(--cor-texto-suave);
}

/* Cada grupo do painel do módulo respira antes do próximo, e o título do grupo
   fica maior que o das portas: é ele que organiza a leitura. */
.grupo-do-modulo > h2 {
  margin-bottom: 0.35rem;
}

/* A LINHA DO CAMINHO: "credor cadastrado → abre a licitação → …".

   Quebra em várias linhas no celular, e as setas somem do leitor de tela
   (aria-hidden no HTML) porque "seta para a direita" lido seis vezes não
   ajuda ninguém — a ordem já está na ordem das palavras. */
.caminho-do-modulo {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 0.6rem;
  margin: 0 0 0.6rem;
  padding: 0;
  list-style: none;
}

.caminho-do-modulo > span {
  padding: 0.3rem 0.6rem;
  border-radius: var(--raio);
  background: var(--cor-fundo);
  font-size: 0.85rem;
}

.caminho-do-modulo > span[aria-hidden='true'] {
  padding: 0;
  background: none;
  color: var(--cor-texto-suave);
}

/* O selo de restrição do credor.

   Vermelho E PALAVRA, nunca só cor: quem não distingue vermelho de cinza — e é
   uma pessoa em doze — ficaria sem a informação que mais importa desta tela,
   que é justamente "não assine com este". */
.selo-restricao {
  background: var(--selo-restricao-fundo);
  color: var(--cor-erro);
}

.selo-apagado {
  background: var(--cor-vazio);
  color: var(--cor-texto-suave);
}

/* O aviso de credor impedido, no alto da ficha. Mesma moldura dos outros
   avisos, com a lateral na cor de erro para separar do informativo. */
.aviso-restricao {
  border-left-color: var(--cor-erro);
}

/* Lista simples de vínculos (processos, contratos, parcerias de um credor). */
.lista-simples {
  margin: 0 0 1rem;
  padding: 0;
  list-style: none;
}

.lista-simples > li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem;
  padding: 0.35rem 0;
  border-bottom: 1px solid var(--cor-borda);
  min-width: 0;
}

.lista-simples a {
  color: var(--cor-link);
  overflow-wrap: break-word;
}

/* A ficha de uma comissão na listagem: cabeçalho, composição e o formulário de
   acrescentar, um bloco por comissão. Separadas por linha, e não por moldura
   dentro de moldura — a seção já é um cartão. */
.ficha-comissao {
  padding: 1rem 0;
  border-top: 1px solid var(--cor-borda);
}

.ficha-comissao:first-of-type {
  border-top: 0;
}

.ficha-comissao h3 {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 0.2rem;
}

.ficha-comissao h3 a {
  color: var(--cor-link);
}

/* O andamento do processo: uma linha do tempo simples, em ordem cronológica.

   <ol> e não <ul>: a ordem é a informação. Quem usa leitor de tela ouve "item
   3 de 7", e isso diz em que pé está o processo. */
.andamento {
  margin: 0 0 1rem;
  padding: 0 0 0 1.1rem;
}

.andamento > li {
  padding: 0.4rem 0;
  border-bottom: 1px solid var(--cor-borda);
}

.andamento-obs {
  display: block;
  font-size: 0.85rem;
  color: var(--cor-texto-suave);
}

/* ------------------------------------------------------------------------
   PORTAL DA TRANSPARÊNCIA (TR 3.15)

   O cartão de processo é irmão de .cartao-concurso, e não uma variante dele:
   os dois têm a mesma moldura, mas o de concurso ganha barra lateral quando as
   inscrições estão abertas, e aqui não há estado que mereça esse destaque —
   "aberto" é a situação mais comum de um processo, e destacar o comum é não
   destacar nada. Herdar um do outro amarraria duas telas que mudam por
   motivos diferentes.
   ------------------------------------------------------------------------ */

.grade-transparencia {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
  gap: 1rem;
  margin: 0 0 1.5rem;
  padding: 0;
  list-style: none;
}

.cartao-transparencia {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 1.25rem;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
  background: var(--cor-superficie);
}

/* --- MÓDULO 6: A PÁGINA DA EMERGÊNCIA ------------------------------------ */

/* OS NÚMEROS EM DESTAQUE — o gasto vinculado, os casos do boletim.
 *
 * O número vem ANTES do rótulo, e maior. É a ordem em que se lê um painel:
 * bate o olho no valor, e só depois pergunta do que ele é. Invertido, a
 * pessoa lê quatro rótulos para achar o número que procura.
 *
 * O minmax com min() é o que impede rolagem lateral em tela estreita com a
 * letra no maior tamanho: sem ele, o mínimo de 11rem vira 231px e não cabe
 * nos 320px menos o respiro. */
.cartoes-numeros {
  display: grid;
  margin: 0 0 1.25rem;
  padding: 0;
  gap: 0.75rem;
  grid-template-columns: repeat(auto-fit, minmax(min(11rem, 100%), 1fr));
  list-style: none;
}

.cartoes-numeros li {
  padding: 0.9rem 1rem;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
  background: var(--cor-superficie);
}

.cartoes-numeros strong {
  display: block;
  color: var(--cor-primaria);
  font-size: 1.4rem;
  line-height: 1.2;
}

.cartoes-numeros span {
  display: block;
  margin-top: 0.15rem;
  color: var(--cor-texto-suave);
  font-size: 0.85rem;
  line-height: 1.4;
}

/* A LISTA DE REGISTROS VINCULADOS.
 *
 * Cada item é um link para a ficha de origem, com uma linha de dados embaixo.
 * Não é tabela de propósito: são seis listas curtas de coisas de naturezas
 * diferentes, e seis tabelas com colunas diferentes na mesma página cansam
 * mais do que informam. */
.lista-vinculos {
  margin: 0 0 1rem;
  padding: 0;
  list-style: none;
}

.lista-vinculos li {
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--cor-borda);
}

.lista-vinculos li:last-child {
  border-bottom: 0;
}

.lista-vinculos a {
  color: var(--cor-link);
  font-weight: 600;
}

.lista-vinculos .item-dados {
  display: block;
  margin-top: 0.15rem;
}

/* O SELO DE "EM CURSO".
 *
 * Amarelo, e não vermelho: emergência em curso é um estado, e não um defeito.
 * O vermelho do portal é de erro, e usá-lo aqui faria toda página de
 * emergência vigente parecer uma tela quebrada.
 *
 * A borda existe para o estado não depender só da cor — quem não distingue
 * amarelo de cinza continua vendo um selo destacado. */
.selo-atencao {
  border: 1px solid var(--cor-atencao);
  background: var(--cor-realce-fundo);
  color: var(--cor-texto);
}

/* h2 E h3 na mesma regra, e isso não é preguiça de seletor.
   O nível do título depende de onde o cartão está: na porta da Transparência
   ele é o primeiro título depois do h1, e é h2; dentro de "O Município" ele
   vem embaixo de um h2 de seção ("Os lugares do município") e precisa ser h3,
   senão o índice de quem usa leitor de tela pula um nível. O cartão tem a
   mesma aparência nos dois casos porque é o mesmo cartão. */
.cartao-transparencia h2,
.cartao-transparencia h3 {
  margin: 0;
  font-size: 1.2rem;
}

/* Cor explícita no link do título: sem isso ele sai no azul padrão do
   navegador, que o tema da Prefeitura não alcança. */
.cartao-transparencia h2 a,
.cartao-transparencia h3 a {
  color: var(--cor-link);
  text-decoration: none;
}

.cartao-transparencia h2 a:hover,
.cartao-transparencia h2 a:focus,
.cartao-transparencia h3 a:hover,
.cartao-transparencia h3 a:focus {
  text-decoration: underline;
}

/* A capa do cartão de um lugar do município.
   object-fit: cover corta a sobra em vez de deformar — a mesma decisão da
   galeria de fotos. A altura fixa é o que faz os cartões de uma linha
   começarem o texto na mesma altura. */
.cartao-capa {
  /* A margem negativa faz a capa encostar nas bordas do cartão, que tem
     1.25rem de recuo de cada lado; a largura volta a caber somando os dois. */
  width: calc(100% + 2.5rem);
  height: 9rem;
  margin: -1.25rem -1.25rem 0;
  max-width: none;
  padding: 0;
  object-fit: cover;
  border-radius: var(--raio) var(--raio) 0 0;
}

/* A capa no topo da página de um lugar. Largura da coluna de leitura, altura
   limitada: uma foto vertical de celular ocuparia a tela inteira e empurraria
   o endereço e o horário para fora do primeiro olhar. */
.capa-larga {
  display: block;
  width: 100%;
  max-height: 22rem;
  margin: 0 0 1.5rem;
  object-fit: cover;
  border-radius: var(--raio);
}

.cartao-transparencia p {
  margin: 0;
}

/* O número fica por último e é empurrado para o rodapé do cartão, para os três
   cartões alinharem o número na mesma altura mesmo com textos de tamanhos
   diferentes. */
.cartao-numero {
  margin-top: auto;
  padding-top: 0.5rem;
  font-size: 0.9rem;
  color: var(--cor-texto-suave);
}

.cartao-numero strong {
  font-size: 1.35rem;
  color: var(--cor-texto);
}

.lista-processos {
  display: grid;
  gap: 1rem;
  margin: 0 0 1.5rem;
  padding: 0;
  list-style: none;
}

.cartao-processo {
  padding: 1.25rem;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
  background: var(--cor-superficie);
}

.cartao-processo h3 {
  margin: 0.35rem 0 0.5rem;
  font-size: 1.15rem;
  overflow-wrap: break-word;
}

.cartao-processo h3 a {
  color: var(--cor-link);
  text-decoration: none;
}

.cartao-processo h3 a:hover,
.cartao-processo h3 a:focus {
  text-decoration: underline;
}

.cartao-processo p {
  margin: 0.35rem 0 0;
}

.processo-meta,
.processo-dados {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  font-size: 0.85rem;
  color: var(--cor-texto-suave);
}

/* O plano de trabalho é digitado numa área de texto, com quebras de linha que
   dizem alguma coisa: metas em linhas separadas viram um parágrafo só se o
   HTML não for instruído a preservá-las. */
.texto-preservado {
  white-space: pre-wrap;
  overflow-wrap: break-word;
}

/* O OLHO DA SENHA.

   A caixa e o botao sao criados pelo /js/olho-da-senha.js, e nao pelo HTML:
   sem script eles nao existem, e o campo de senha continua sendo um campo de
   senha comum. Por isso nao ha nada aqui que precise se desfazer quando o
   script nao roda — o que estas regras pintam so chega a existir com ele. */
.campo-com-olho {
  position: relative;
  display: block;
}

/* Espaco a direita para o botao nao ficar por cima do que foi digitado. */
.campo-com-olho input {
  padding-right: 3rem;
}

.olho {
  position: absolute;
  right: 0.3rem;
  top: 50%;
  transform: translateY(-50%);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 2,4rem de lado: o alvo minimo confortavel para o dedo num celular, e o
     bastante para o botao nao encostar na borda do campo. */
  width: 2.4rem;
  height: 2.4rem;
  padding: 0;
  border: 0;
  border-radius: var(--raio);
  background: transparent;
  color: var(--cor-texto-suave);
  cursor: pointer;
}

.olho:hover {
  color: var(--cor-primaria);
  background: var(--cor-realce-fundo);
}

.olho:focus-visible {
  outline: 3px solid var(--cor-destaque);
  outline-offset: 2px;
}

.olho svg {
  width: 1.3rem;
  height: 1.3rem;
}

/* ---------------------------------------------------------------------------
   OBRAS PÚBLICAS — Módulo 10
   --------------------------------------------------------------------------- */

/* O GRÁFICO DE BARRAS É UMA TABELA, e não um desenho.
 *
 * O item 10.8 do Termo de Referência pede gráficos "bem acessíveis", e o portal
 * inteiro funciona com JavaScript desligado. As duas exigências apontam para a
 * mesma solução: uma tabela de verdade, com cabeçalho e números escritos, em
 * que a barra é só o preenchimento da célula.
 *
 * Quem enxerga vê o gráfico. Quem usa leitor de tela ouve "Em execução, 5 obras,
 * R$ 1.200.000,00" — que é mais do que qualquer gráfico em canvas entrega. E
 * quem imprime a página leva os números, não um retângulo cinza.
 *
 * A largura vem de --fatia, calculada no servidor. Largura calculada na tela é
 * largura que cada tela calcula de um jeito. */
/* A COLUNA DA BARRA PRECISA TER LARGURA PROPRIA, e esta e a linha que fazia
   o grafico inteiro nao desenhar.

   A barra e `width: var(--fatia)` — uma porcentagem. Porcentagem de que? Da
   celula que a contem. E numa tabela de layout automatico a celula tem a
   largura do CONTEUDO dela; o unico conteudo ali e a propria barra, que so
   sabe dizer a largura em porcentagem da celula. A conta e circular, o
   navegador resolve pelo minimo, e sobra o `min-width: 2px` — o tracinho.
   Oitenta por cento e vinte por cento davam o MESMO tracinho.
   
   Com `table-layout: fixed` as larguras saem da primeira linha e param de
   depender do conteudo, e a segunda coluna — que e a da barra em todos os
   graficos do portal — ganha quarenta por cento da tabela. A porcentagem passa
   a ter de que ser porcentagem.
   
   ISTO NUNCA FUNCIONOU. O item 10.8 do Termo de Referencia pede "graficos,
   estatisticas, numeros e dados bem acessiveis", e a informacao sempre esteve
   toda escrita — a tabela tem o numero e o percentual em texto, que e o que
   faz o grafico ser acessivel e imprimivel. O que faltava era o desenho, e
   nenhuma conferencia pegou: elas perguntam se a tela ABRE e se o texto esta
   certo, e uma barra de 2px abre. */
.grafico-barras {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
}

.grafico-barras th:nth-child(2),
.grafico-barras td:nth-child(2) {
  width: 40%;
}

/* A primeira coluna e o rotulo da linha ("Em manutenção", "SEMOSP"): ela pode
   quebrar em duas linhas sem prejuizo, e por isso e a que cede espaco. */
.grafico-barras th:first-child,
.grafico-barras td:first-child {
  overflow-wrap: break-word;
}

/* O titulo do grafico precisa de ar em cima: no gerenciamento ele vem logo
   depois do paragrafo que explica os numeros, e sem margem os dois se tocam. */
.grafico-barras caption {
  text-align: left;
  font-weight: 600;
  padding-top: 1rem;
  padding-bottom: 0.5rem;
}

.grafico-barras th,
.grafico-barras td {
  padding: 0.4rem 0.6rem;
  text-align: left;
  vertical-align: middle;
  border-bottom: 1px solid var(--cor-borda);
}

.grafico-barras td.numero {
  text-align: right;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.barra {
  display: block;
  min-width: 2px;
  height: 0.9rem;
  border-radius: 2px;
  background: var(--cor-destaque);
  width: var(--fatia, 0%);
}

/* Em alto contraste e em escala de cinza a cor sozinha não distingue — a barra
 * ganha contorno para continuar visível quando o preenchimento some. */
.contraste .barra,
.cinza .barra {
  outline: 1px solid currentColor;
}

/* AS FOTOS DATADAS (item 10.11).
 *
 * Grade que se ajusta sozinha, sem media query: em telefone cabe uma coluna, em
 * tela larga cabem quantas couberem. minmax(0, 1fr) tira o piso da coluna — é a
 * mesma correção do e-mail do rodapé, que criava rolagem lateral em 320px. */
.lista-de-fotos {
  list-style: none;
  margin: 1rem 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(14rem, 100%), 1fr));
  gap: 1rem;
}

.lista-de-fotos li {
  border: 1px solid var(--cor-borda);
  border-radius: 6px;
  padding: 0.6rem;
  min-width: 0;
}

.lista-de-fotos img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 4px;
  margin-bottom: 0.5rem;
}

.lista-de-fotos p {
  margin: 0.2rem 0;
}

/* OS NÚMEROS DE UM PAINEL.
 *
 * A lista curta de totais que abre um painel: "12 veículos na frota · idade
 * média 10 anos". Nasceu na tela de importação, onde contava o que o envio
 * tinha criado — daí o nome —, e hoje abre onze telas, entre elas as públicas
 * de despesas e receitas.
 *
 * Ficou sem regra até aqui, e sem regra ela caía como lista com marcador: uma
 * bolinha por número, um número por linha, ocupando meia tela para dizer duas
 * coisas. É uma faixa: os itens curtos ficam lado a lado e um item comprido,
 * como a linha de uma natureza de despesa, cai sozinho na linha seguinte
 * porque não cabe — sem media query e sem contar quantos itens são.
 *
 * O separador é uma borda à esquerda, e não um "·" escrito no HTML: caractere
 * de enfeite entra na leitura do leitor de tela, borda não. O primeiro item
 * não tem borda porque nada vem antes dele, e quem cai numa linha nova também
 * não deveria ter — isso o CSS não sabe dizer, e uma borda no começo da linha
 * é bem menos feia do que um "·" lido em voz alta. */
.numeros-do-painel {
  list-style: none;
  margin: 0 0 1rem;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1.1rem;
}

.numeros-do-painel > li {
  min-width: 0;
  padding-left: 1.1rem;
  border-left: 1px solid var(--cor-borda);
  overflow-wrap: break-word;
}

.numeros-do-painel > li:first-child {
  padding-left: 0;
  border-left: 0;
}

/* Quem aumenta a letra pelo painel de acessibilidade precisa que a faixa vire
   uma coluna antes de o texto começar a se espremer: em tela estreita cada
   número ocupa a linha inteira, e aí o separador vertical não faz sentido. */
@media (max-width: 30rem) {
  .numeros-do-painel {
    display: block;
  }

  .numeros-do-painel > li {
    padding-left: 0;
    border-left: 0;
    padding-top: 0.3rem;
  }
}

/* ==========================================================================
   AS CLASSES QUE ESTAVAM NO HTML E NÃO ESTAVAM AQUI
   ==========================================================================

   Uma varredura nova (a "classesInventadas", em scripts/varredura-de-texto.js)
   comparou todo nome de classe escrito nas telas com os nomes que este arquivo
   define, e achou trinta e três que ninguém tinha definido. Não davam erro
   nenhum: o navegador lê `class="colunas-do-quadro"`, não encontra regra, e
   desenha a caixa como desenharia sem classe alguma. A tela abre, o conteúdo
   está lá, e o teste automático fica verde — só o desenho é que não é o que a
   tela pediu. Duas colunas viram uma, um formulário que era para ser uma faixa
   vira uma pilha.

   Metade tinha nome próprio para a mesma coisa que a casa já fazia, e virou o
   nome da casa: `filtros-do-cidadao` era `busca-listagem`, `acoes` era
   `acoes-linha`, `botao-discreto` era `botao-secundario botao-pequeno`,
   `selo-na` era `selo-apagado`, e `numeros-do-envio` e `numeros-do-quadro`
   eram a mesma faixa de números com dois nomes — agora `numeros-do-painel`.
   A outra metade era desenho de verdade que faltava, e está aqui embaixo. */

/* As duas colunas do quadro funcional: por vínculo de um lado, por secretaria
   do outro. Grade que se resolve sozinha — em telefone vira uma coluna sem
   media query, porque a coluna mínima é a menor entre 22rem e a tela toda. */
.colunas-do-quadro {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(22rem, 100%), 1fr));
  gap: 1.5rem;
  align-items: start;
}

.colunas-do-quadro > div {
  min-width: 0;
}

/* O formulário de uma linha só: rótulo, campo, rótulo, campo, botão — a fonte
   de recurso dos processos de engenharia, o envio de um CSV. Não é o
   `.formulario` das fichas, que empilha campo sobre campo com rótulo em cima;
   é a faixa curta de cadastrar algo pequeno sem sair da tela.

   `align-items: flex-end` alinha tudo pela base, senão o botão sobe até o topo
   do rótulo. Os campos crescem, os rótulos não. */
.formulario-em-linha {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.5rem 0.75rem;
  margin: 0 0 1rem;
}

.formulario-em-linha label {
  font-weight: 600;
  align-self: center;
}

.formulario-em-linha input[type='text'],
.formulario-em-linha input[type='file'],
.formulario-em-linha select {
  flex: 1 1 12rem;
  min-width: 0;
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--cor-borda-forte);
  border-radius: 4px;
  font: inherit;
  color: inherit;
  background: var(--cor-superficie);
}

/* Formulário de um botão só, dentro de célula de tabela. Existe porque um
   POST precisa de <form> e um <form> é bloco: sem isto, cada botão de ação da
   linha cai numa linha própria e a célula fica com três andares. */
.acao-embutida {
  display: inline;
}

/* A lista dos arquivos que um conjunto aceita, na tela de importação. Cada
   item é um bloco com título, explicação, os botões de modelo e exportação, e
   o formulário de envio — separados por linha, e não por moldura dentro de
   moldura, que a seção já é um cartão. */
.lista-de-arquivos {
  list-style: none;
  margin: 0;
  padding: 0;
}

.lista-de-arquivos > li {
  padding: 1rem 0;
  border-top: 1px solid var(--cor-borda);
}

.lista-de-arquivos > li:first-child {
  border-top: 0;
  padding-top: 0.25rem;
}

.lista-de-arquivos h3 {
  margin: 0 0 0.35rem;
}

.acoes-do-arquivo {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0.6rem 0;
}

/* A caixa de marcar que vem dentro do próprio rótulo — "o que esta chave pode
   enviar". A ficha usa `.campo campo-marcavel`, com a caixa e o rótulo lado a
   lado; aqui o rótulo envolve a caixa, que é o que faz o texto inteiro virar
   área de clique. As duas formas valem; esta precisava de regra. */
.campo-escolha {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.2rem 0;
  font-weight: 400;
  cursor: pointer;
}

.campo-escolha input {
  width: auto;
  margin: 0;
}

/* A chave de integração recém-criada, a única vez em que ela aparece. Grande,
   com folga e quebrando onde precisar: é para ser copiada com o olho e o
   mouse, e uma sequência dessas cortada pela borda da tela é a forma mais
   certa de a pessoa copiar metade. */
.chave-em-claro {
  display: block;
  padding: 0.7rem 0.9rem;
  border: 1px dashed var(--cor-borda-forte);
  border-radius: 4px;
  background: var(--cor-realce-fundo);
  font-family: ui-monospace, 'Cascadia Mono', 'Consolas', monospace;
  font-size: 1.05rem;
  line-height: 1.5;
  overflow-wrap: anywhere;
}

/* O destaque que pede atenção, e não o destaque comum de abertura de página:
   a faixa âmbar da chave que só aparece uma vez. Cor E moldura, nunca só cor.
   Usa o âmbar que o relatório de pendências já usa, para o portal não ter dois
   amarelos de aviso diferentes. */
.destaque-atencao {
  padding: 1rem 1.25rem;
  border: 1px solid var(--cor-atencao);
  border-left-width: 5px;
  border-radius: 6px;
  background: var(--cor-realce-fundo);
}

.destaque-atencao h2 {
  margin: 0 0 0.5rem;
  color: var(--cor-atencao);
}

.destaque-atencao p {
  margin: 0 0 0.6rem;
  max-width: 70ch;
}

/* As regras gerais do leiaute de importação: termo em negrito, explicação
   abaixo. Em tela larga o termo fica à esquerda e a explicação à direita, que
   é como uma lista de definição se lê melhor; em telefone volta a empilhar. */
.regras-do-leiaute {
  margin: 0;
}

.regras-do-leiaute dt {
  font-weight: 600;
  color: var(--cor-link);
}

.regras-do-leiaute dd {
  margin: 0.2rem 0 0.9rem;
  max-width: 70ch;
}

@media (min-width: 45rem) {
  .regras-do-leiaute {
    display: grid;
    grid-template-columns: 10rem 1fr;
    gap: 0.35rem 1.25rem;
  }

  .regras-do-leiaute dt {
    grid-column: 1;
  }

  .regras-do-leiaute dd {
    grid-column: 2;
    margin: 0;
  }
}

/* O exemplo de chamada da integração. É um <pre>: as quebras de linha são o
   conteúdo, e por isso ele rola de lado em vez de reembrulhar — uma linha de
   cabeçalho HTTP quebrada no meio deixa de ser o que a pessoa vai copiar. */
.exemplo-de-chamada {
  margin: 0 0 1rem;
  padding: 0.9rem 1rem;
  border: 1px solid var(--cor-borda);
  border-radius: 6px;
  background: var(--cor-realce-fundo);
  font-family: ui-monospace, 'Cascadia Mono', 'Consolas', monospace;
  font-size: 0.92rem;
  line-height: 1.6;
  overflow-x: auto;
  contain: paint;
}

/* O ícone que diz de que tipo é o item da biblioteca — foto, áudio, documento.
   `aria-hidden` no próprio SVG: quem usa leitor de tela recebe o tipo escrito
   ao lado, e um desenho anunciado junto seria a mesma informação duas vezes. */
.icone-midia {
  flex: none;
  vertical-align: -0.15em;
  color: var(--cor-texto-suave);
}

/* O botãozinho de abrir em outra aba, ao lado do link comum. Discreto de
   propósito — não disputa com o link —, mas com área de clique de verdade:
   um alvo de 12px é um alvo que só acerta quem tem mouse e mira boa. */
.nova-aba {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.75rem;
  height: 1.75rem;
  margin-left: 0.15rem;
  border-radius: 4px;
  color: var(--cor-texto-suave);
  text-decoration: none;
  vertical-align: middle;
}

.nova-aba:hover,
.nova-aba:focus-visible {
  background: var(--cor-realce-fundo-forte);
  color: var(--cor-link);
}

/* O "ver tudo" que fecha a faixa de título de uma seção da página inicial.
   Fica na base da faixa, do lado oposto ao título, e é o único link ali — daí
   a seta do próprio texto bastar como sinal de que leva a outro lugar. */
.faixa-titulo-link {
  flex: none;
  align-self: flex-end;
  padding-bottom: 0.15rem;
  color: var(--cor-link);
  font-weight: 600;
  white-space: nowrap;
}

.faixa-titulo-link:hover,
.faixa-titulo-link:focus-visible {
  text-decoration: underline;
}

/* O nome da paleta, no rodapé do cartão de cor. Cresce para empurrar o ✓ de
   escolhida para a borda, e corta com reticências se o nome for comprido —
   sem isto o cartão se alarga e a grade de paletas perde o alinhamento. */
.paleta-nome {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* AS LARGURAS DA BARRA, UMA CLASSE POR PONTO PERCENTUAL.
 *
 * Cento e uma regras de uma linha parecem exagero até se saber por que elas
 * existem: a largura NÃO PODE vir de `style="--fatia: 38%"`.
 *
 * A política de segurança do portal é `style-src 'self'`, e isso manda o
 * navegador bloquear todo atributo `style`. Ele bloqueia calado — nenhum erro
 * na tela, só uma linha no console que ninguém abre. Era por isso que o
 * gráfico inteiro do portal nunca desenhou: toda barra caía no `min-width` e
 * saía do mesmo tamanho, oitenta por cento igual a vinte.
 *
 * E havia uma dependência escondida pior que o defeito: a política ganha
 * `unsafe-inline` quando o VLibras está ligado. O gráfico funcionava ou não
 * conforme uma opção de acessibilidade, sem relação nenhuma com ele.
 *
 * A folha de estilo é `'self'` — permitida em qualquer política, e cacheada
 * uma vez. Três quilobytes para o portal desenhar sob a regra mais restrita.
 *
 * O ponto percentual exato continua escrito em texto na célula ao lado: é ele
 * que o leitor de tela anuncia e que a impressão leva. A barra é o desenho do
 * número, e não o número. */
.barra-0 {
  width: 0%;
}
.barra-1 {
  width: 1%;
}
.barra-2 {
  width: 2%;
}
.barra-3 {
  width: 3%;
}
.barra-4 {
  width: 4%;
}
.barra-5 {
  width: 5%;
}
.barra-6 {
  width: 6%;
}
.barra-7 {
  width: 7%;
}
.barra-8 {
  width: 8%;
}
.barra-9 {
  width: 9%;
}
.barra-10 {
  width: 10%;
}
.barra-11 {
  width: 11%;
}
.barra-12 {
  width: 12%;
}
.barra-13 {
  width: 13%;
}
.barra-14 {
  width: 14%;
}
.barra-15 {
  width: 15%;
}
.barra-16 {
  width: 16%;
}
.barra-17 {
  width: 17%;
}
.barra-18 {
  width: 18%;
}
.barra-19 {
  width: 19%;
}
.barra-20 {
  width: 20%;
}
.barra-21 {
  width: 21%;
}
.barra-22 {
  width: 22%;
}
.barra-23 {
  width: 23%;
}
.barra-24 {
  width: 24%;
}
.barra-25 {
  width: 25%;
}
.barra-26 {
  width: 26%;
}
.barra-27 {
  width: 27%;
}
.barra-28 {
  width: 28%;
}
.barra-29 {
  width: 29%;
}
.barra-30 {
  width: 30%;
}
.barra-31 {
  width: 31%;
}
.barra-32 {
  width: 32%;
}
.barra-33 {
  width: 33%;
}
.barra-34 {
  width: 34%;
}
.barra-35 {
  width: 35%;
}
.barra-36 {
  width: 36%;
}
.barra-37 {
  width: 37%;
}
.barra-38 {
  width: 38%;
}
.barra-39 {
  width: 39%;
}
.barra-40 {
  width: 40%;
}
.barra-41 {
  width: 41%;
}
.barra-42 {
  width: 42%;
}
.barra-43 {
  width: 43%;
}
.barra-44 {
  width: 44%;
}
.barra-45 {
  width: 45%;
}
.barra-46 {
  width: 46%;
}
.barra-47 {
  width: 47%;
}
.barra-48 {
  width: 48%;
}
.barra-49 {
  width: 49%;
}
.barra-50 {
  width: 50%;
}
.barra-51 {
  width: 51%;
}
.barra-52 {
  width: 52%;
}
.barra-53 {
  width: 53%;
}
.barra-54 {
  width: 54%;
}
.barra-55 {
  width: 55%;
}
.barra-56 {
  width: 56%;
}
.barra-57 {
  width: 57%;
}
.barra-58 {
  width: 58%;
}
.barra-59 {
  width: 59%;
}
.barra-60 {
  width: 60%;
}
.barra-61 {
  width: 61%;
}
.barra-62 {
  width: 62%;
}
.barra-63 {
  width: 63%;
}
.barra-64 {
  width: 64%;
}
.barra-65 {
  width: 65%;
}
.barra-66 {
  width: 66%;
}
.barra-67 {
  width: 67%;
}
.barra-68 {
  width: 68%;
}
.barra-69 {
  width: 69%;
}
.barra-70 {
  width: 70%;
}
.barra-71 {
  width: 71%;
}
.barra-72 {
  width: 72%;
}
.barra-73 {
  width: 73%;
}
.barra-74 {
  width: 74%;
}
.barra-75 {
  width: 75%;
}
.barra-76 {
  width: 76%;
}
.barra-77 {
  width: 77%;
}
.barra-78 {
  width: 78%;
}
.barra-79 {
  width: 79%;
}
.barra-80 {
  width: 80%;
}
.barra-81 {
  width: 81%;
}
.barra-82 {
  width: 82%;
}
.barra-83 {
  width: 83%;
}
.barra-84 {
  width: 84%;
}
.barra-85 {
  width: 85%;
}
.barra-86 {
  width: 86%;
}
.barra-87 {
  width: 87%;
}
.barra-88 {
  width: 88%;
}
.barra-89 {
  width: 89%;
}
.barra-90 {
  width: 90%;
}
.barra-91 {
  width: 91%;
}
.barra-92 {
  width: 92%;
}
.barra-93 {
  width: 93%;
}
.barra-94 {
  width: 94%;
}
.barra-95 {
  width: 95%;
}
.barra-96 {
  width: 96%;
}
.barra-97 {
  width: 97%;
}
.barra-98 {
  width: 98%;
}
.barra-99 {
  width: 99%;
}
.barra-100 {
  width: 100%;
}

/* Imagem que não estoura o container. Era `style="max-width: 100%"` em duas
   fichas de veículo — e caía na mesma política que bloqueia estilo inline. */
.imagem-fluida {
  max-width: 100%;
  height: auto;
}

/* --- Aferição PNTP (Módulo 14) ------------------------------------------ */

/* A classificação do critério. Essencial em vermelho de propósito: é o que
 * trava o selo, e é o que a pessoa precisa achar primeiro na lista. */
.selo-pntp-essencial {
  background: var(--cor-erro-fundo);
  color: var(--cor-erro);
}

.selo-pntp-obrigatoria {
  background: var(--cor-realce-fundo-forte);
  color: var(--cor-link);
}

.selo-pntp-recomendada {
  background: var(--cor-realce-fundo);
  color: var(--cor-texto-suave);
}

/* Onde o portal responde. */
.selo-pntp-tem {
  background: var(--cor-sucesso-fundo);
  color: var(--cor-sucesso);
}

.selo-pntp-parcial {
  background: var(--selo-atencao-fundo);
  color: var(--selo-atencao-texto);
}

.selo-pntp-falta {
  background: var(--cor-erro-fundo);
  color: var(--cor-erro);
}

.selo-pntp-sem {
  background: var(--cor-realce-fundo-forte);
  color: var(--cor-texto-suave);
}

/* D A S G F: as siglas dos itens de verificação, lado a lado. */
.item-pntp {
  display: inline-block;
  min-width: 1.4rem;
  margin: 0 0.15rem 0.15rem 0;
  padding: 0.05rem 0.3rem;
  border: 1px solid var(--cor-borda);
  border-radius: 4px;
  font-size: 0.8rem;
  font-weight: 600;
  text-align: center;
  text-decoration: none;
}

.tabela-pntp th[scope='row'] {
  min-width: 16rem;
}

/* Os itens da aferição: verde o atendido, riscado o que falta. A diferença
 * não é só de cor — o risco lê igual para quem não distingue verde. */
.item-pntp-feito {
  border-color: var(--cor-sucesso);
  background: var(--cor-sucesso-fundo);
  color: var(--cor-sucesso);
}

.item-pntp-falta {
  color: var(--cor-texto-suave);
  text-decoration: line-through;
}

/* AS ETAPAS DO SERVIÇO, na ficha do gerenciamento (Módulo 15).
 *
 * É uma <ol> de propósito: a ordem é a informação. Lista sem numeração
 * obrigaria o leitor a confiar que a posição na tela é a posição de verdade —
 * e essa é justamente a coisa que o cidadão precisa conferir. */
.lista-etapas {
  margin: 0 0 1.25rem;
  padding-left: 1.25rem;
}

.lista-etapas li {
  margin-bottom: 0.9rem;
  padding-bottom: 0.9rem;
  border-bottom: 1px solid var(--cor-borda);
}

.lista-etapas li:last-child {
  border-bottom: 0;
}

/* AS ETIQUETAS DE PESQUISA DO SERVIÇO (Módulo 15).
 *
 * Em linha, e não empilhadas: são palavras curtas, e uma coluna de quinze
 * linhas com uma palavra em cada faria a tela parecer mais cheia do que o
 * conteúdo dela. */
.lista-etiquetas {
  display: flex;
  flex-wrap: wrap;
  margin: 0 0 1.25rem;
  padding: 0;
  gap: 0.5rem;
  list-style: none;
}

.lista-etiquetas li {
  display: inline-flex;
  align-items: center;
  padding: 0.3rem 0.6rem;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
  background: var(--cor-fundo);
  gap: 0.4rem;
}

/* O NÍVEL DE TRANSPARÊNCIA, COM COR PRÓPRIA E MARCADOR.
 *
 * Antes os três níveis com selo saíam todos no verde de sucesso e os cinco
 * sem selo no vermelho de erro — o que dizia "passou" ou "não passou", mas
 * não dizia QUAL nível. Cada um passou a ter a sua cor, e o desenho ao lado
 * muda de forma entre quem tem selo e quem não tem, porque em escala de
 * cinza e em alto contraste a cor deixa de existir.
 *
 * As cores são escolhidas para ler em fundo claro: o dourado e o prateado
 * puros somem no branco, então os daqui são versões escurecidas deles. */
.selo-pntp {
  display: inline-flex;
  align-items: baseline;
  gap: 0.35rem;
}

/* CUIDADO AO PÔR ESTE PARCIAL DENTRO DE UM BLOCO QUE ESTILIZA `span`.
 *
 * `.cartoes-numeros span` vale para QUALQUER span descendente — e no dia em
 * que o marcador entrou no cartão da nota, foram os dois spans dele que
 * receberam `display: block`, `font-size: 0.85rem` e a cor apagada. O nome do
 * nível saiu miúdo e cinza embaixo do desenho, no lugar de grande ao lado
 * dele. Por isso as regras abaixo têm duas classes: para vencer um seletor de
 * elemento que o parcial não controla, e devolver ao nome o tamanho e a cor
 * de onde ele estiver. */
.selo-pntp .selo-pntp-desenho {
  width: 0.95em;
  height: 0.95em;
  flex: none;
  align-self: center;
}

.selo-pntp .selo-pntp-nome {
  display: inline;
  margin: 0;
  color: inherit;
  font-weight: 700;
  font-size: inherit;
  line-height: inherit;
}

.cartoes-numeros .selo-pntp,
.tabela .selo-pntp {
  display: inline-flex;
  margin: 0;
  color: inherit;
  font-size: inherit;
  line-height: inherit;
}

.selo-pntp-diamante,
.nivel-pntp-diamante {
  --metal-claro: #d8f2f8;
  --metal-medio: #7fc6d8;
  --metal-escuro: var(--cor-nivel-diamante);

  color: var(--cor-nivel-diamante);
}

.selo-pntp-ouro,
.nivel-pntp-ouro {
  --metal-claro: #f7e3a1;
  --metal-medio: #d9ae2e;
  --metal-escuro: var(--cor-nivel-ouro);

  color: var(--cor-nivel-ouro);
}

.selo-pntp-prata,
.nivel-pntp-prata {
  --metal-claro: #edf0f2;
  --metal-medio: #b3bcc4;
  --metal-escuro: var(--cor-nivel-prata);

  color: var(--cor-nivel-prata);
}

.selo-pntp-elevado,
.nivel-pntp-elevado {
  color: var(--cor-nivel-elevado);
}

.selo-pntp-intermediario,
.nivel-pntp-intermediario {
  color: var(--cor-nivel-intermediario);
}

.selo-pntp-basico,
.nivel-pntp-basico {
  color: var(--cor-nivel-basico);
}

.selo-pntp-inicial,
.nivel-pntp-inicial {
  color: var(--cor-nivel-inicial);
}

.selo-pntp-inexistente,
.nivel-pntp-inexistente {
  color: var(--cor-nivel-inexistente);
}

.lista-pntp-perdas li {
  margin-bottom: 0.5rem;
}

.lista-pntp-perdas .item-dados {
  display: block;
}

/* ===========================================================================
   A ARVORE DA RECEITA POR NATUREZA (KAN-131, criterio 3.2 do PNTP)
   ---------------------------------------------------------------------------
   Cada no e um <details>: abre e fecha SEM JavaScript, como o resto da casa.
   O recuo vem do proprio aninhamento, e nao de uma classe por nivel — assim a
   arvore continua certa se um dia a classificacao ganhar um nivel a mais.
   =========================================================================== */

.arvore-natureza {
  list-style: none;
  margin: 0;
  padding: 0;
}

.arvore-natureza .arvore-natureza {
  margin-left: 1.25rem;
  padding-left: 0.75rem;
  border-left: 2px solid var(--cor-borda);
}

.arvore-no {
  margin: 0.35rem 0;
}

.arvore-linha {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 0.75rem;
  align-items: baseline;
  padding: 0.35rem 0.5rem;
  border-radius: 0.375rem;
  cursor: pointer;
}

.arvore-linha:hover,
.arvore-linha:focus-visible {
  background: var(--cor-fundo);
}

/* O codigo da rubrica e numero de documento: fonte de largura fixa alinha os
   niveis e deixa o olho comparar "1.7.1" com "1.7.2" sem reler. */
.arvore-codigo {
  font-family: ui-monospace, 'Cascadia Mono', 'Consolas', monospace;
  font-size: 0.875rem;
  color: var(--cor-texto-suave);
  white-space: nowrap;
}

.arvore-nome {
  font-weight: 600;
  flex: 1 1 14rem;
}

.arvore-valores {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  font-variant-numeric: tabular-nums;
}

/* A folha da arvore nao abre: ela e a rubrica em si. Sem o marcador, ninguem
   fica clicando numa linha que nunca vai responder. */
.arvore-folha .arvore-linha {
  cursor: default;
  list-style: none;
}

.arvore-folha .arvore-linha::marker {
  content: '';
}

/* ==========================================================================
   O PAINEL DO GERENCIAMENTO E OS GRÁFICOS (KAN-108)
   ==========================================================================

   AS CORES DOS GRÁFICOS SAEM DA COR PRINCIPAL DA APARÊNCIA. A Prefeitura que
   escolheu verde tem o painel verde, sem ninguém mexer aqui.

   Despesa empenhada, liquidada e paga são ETAPAS em ordem, e não três coisas
   diferentes — por isso um só tom, do claro ao escuro (40%, 70% e 100% da cor
   principal), e não três cores. Conferido com o validador de paleta da casa:
   os degraus se distinguem (ΔE 19 entre vizinhos, também para daltonismo); o
   mais claro fica abaixo de 3:1 sobre o branco, e por isso todo gráfico tem a
   legenda escrita e a tabela com os números logo abaixo.

   O vermelho aparece só onde a situação é de problema (obra paralisada) e
   sempre com o nome escrito ao lado. */

.grafico-serie-1 {
  --cor-marca: color-mix(in srgb, var(--cor-primaria) 40%, var(--cor-superficie));
}
.grafico-serie-2 {
  --cor-marca: color-mix(in srgb, var(--cor-primaria) 70%, var(--cor-superficie));
}
.grafico-serie-3 {
  --cor-marca: var(--cor-primaria);
}
.grafico-serie-resto {
  --cor-marca: var(--cor-borda-forte);
}
.grafico-status-critico {
  --cor-marca: var(--cor-erro);
}

.grafico {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
  font-family: inherit;
}
.grafico path[class^='grafico-serie'],
.grafico path[class*=' grafico-serie'],
.grafico path.grafico-status-critico {
  fill: var(--cor-marca);
}
.grafico-grade {
  stroke: var(--cor-borda);
  stroke-width: 1;
  shape-rendering: crispEdges;
}
.grafico-eixo {
  fill: var(--cor-texto-suave);
  font-size: 13px;
}
.grafico-valor {
  fill: var(--cor-texto);
  font-size: 13px;
  font-weight: 600;
}
.grafico-alvo {
  fill: transparent;
}
.grafico-link {
  cursor: pointer;
}
.grafico-link:hover .grafico-alvo,
.grafico-link:focus-visible .grafico-alvo {
  fill: var(--cor-realce-fundo-forte);
  fill-opacity: 0.6;
}
.grafico-link:focus-visible {
  outline: 3px solid var(--foco-externo);
  outline-offset: 2px;
}
.grafico-area {
  fill: var(--cor-primaria);
  fill-opacity: 0.1;
}
.grafico-linha {
  fill: none;
  stroke: var(--cor-primaria);
  stroke-width: 2;
  stroke-linejoin: round;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}
.grafico-ponto {
  fill: var(--cor-primaria);
  stroke: var(--cor-superficie);
  stroke-width: 2;
}

/* A rosca: cada fatia é um anel de traço grosso; o trilho cinza por baixo
   aparece só onde não há dado. */
.grafico-rosca {
  max-width: 200px;
  margin: 0 auto;
}
.grafico-trilho {
  fill: none;
  stroke: var(--cor-vazio);
  stroke-width: 14;
}
.grafico-fatia {
  fill: none;
  stroke: var(--cor-marca, var(--cor-primaria));
  stroke-width: 14;
}
.grafico-link:hover .grafico-fatia,
.grafico-link:focus-visible .grafico-fatia {
  stroke-width: 18;
}
.grafico-centro {
  fill: var(--cor-texto);
  font-size: 20px;
  font-weight: 700;
}
.grafico-centro-rotulo {
  fill: var(--cor-texto-suave);
  font-size: 10px;
}

/* A legenda escrita: a cor nunca anda sozinha. */
.grafico-legenda {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 18px;
  margin: 10px 0 0;
  padding: 0;
  list-style: none;
  font-size: 14px;
  color: var(--cor-texto);
}
.grafico-legenda li {
  display: flex;
  align-items: center;
  gap: 8px;
}
.grafico-legenda a {
  color: inherit;
}
.grafico-amostra {
  flex: none;
  width: 12px;
  height: 12px;
  border-radius: 3px;
  background: var(--cor-marca);
}
.grafico-legenda-valor {
  color: var(--cor-texto-suave);
  font-variant-numeric: tabular-nums;
}

/* A tabela com os números do gráfico: fechada, a um clique. */
.grafico-tabela {
  margin-top: 12px;
  font-size: 14px;
}
.grafico-tabela summary {
  cursor: pointer;
  color: var(--cor-link);
}
.grafico-tabela .tabela td,
.grafico-tabela .tabela th {
  font-variant-numeric: tabular-nums;
}
.numero-a-direita {
  text-align: right;
}

/* --- A página do painel (arrumação de 27/09) ------------------------------

   O RITMO: 8 px é a unidade. Entre faixas, 48; entre o título da faixa e os
   blocos, 16; entre blocos, 20; dentro do bloco, 24 de borda e 16 entre as
   partes. Espaço igual para coisa igual é o que faz a tela parecer arrumada
   — nenhum número aqui é "o que coube". */

.painel-topo {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--espaco-4) var(--espaco-5);
}
.painel-topo h1 {
  margin: 0 0 var(--espaco-1);
  font-size: var(--texto-manchete);
  line-height: 1.2;
}
.painel-topo-quem {
  margin: 0;
  color: var(--cor-texto-suave);
  font-size: 15px;
}
.painel-topo-hora {
  display: inline-flex;
  align-items: center;
  gap: var(--espaco-2);
  padding: 7px 12px;
  border: 1px solid var(--cor-borda-forte);
  border-radius: 999px;
  color: var(--cor-texto-suave);
  font-size: 13px;
  text-decoration: none;
  white-space: nowrap;
}
.painel-topo-hora:hover,
.painel-topo-hora:focus-visible {
  border-color: var(--cor-primaria);
  background: var(--cor-realce-fundo);
  color: var(--cor-primaria);
}

.conteudo > .painel-faixa {
  margin-top: 48px;
}
.conteudo > .painel-faixa-primeira {
  margin-top: var(--espaco-5);
}
.painel-faixa-cabeca {
  margin-bottom: var(--espaco-4);
}
.painel-faixa-cabeca h2 {
  margin: 0 0 var(--espaco-1);
  font-size: 20px;
  line-height: 1.3;
  color: var(--cor-texto);
}
.painel-faixa-cabeca p {
  margin: 0;
  max-width: 80ch;
  font-size: var(--texto-pequeno);
  color: var(--cor-texto-suave);
}
.painel-faixa-cabeca-acoes {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--espaco-3) var(--espaco-5);
}

.painel-grade {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 3fr);
  gap: 20px;
  align-items: stretch;
}
.painel-grade-meio {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.painel-grade-tres {
  grid-template-columns: minmax(0, 4fr) minmax(0, 3fr) minmax(0, 3fr);
}
@media (max-width: 1100px) {
  .painel-grade-tres {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (max-width: 900px) {
  .painel-grade,
  .painel-grade-meio,
  .painel-grade-tres {
    grid-template-columns: minmax(0, 1fr);
  }
}

.painel-bloco {
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: var(--espaco-5);
  background: var(--cor-superficie);
  border: 1px solid var(--cor-borda);
  border-radius: 12px;
  box-shadow: var(--sombra-cartao);
}
.bloco-busca {
  margin-bottom: 20px;
}
.bloco-cabeca {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--espaco-3);
  margin-bottom: var(--espaco-4);
}
.bloco-cabeca h3 {
  margin: 0;
  font-size: 16px;
  font-weight: 700;
  color: var(--cor-texto);
}
.bloco-link {
  flex: none;
  font-size: var(--texto-pequeno);
  font-weight: 600;
  text-decoration: none;
}
.bloco-link:hover,
.bloco-link:focus-visible {
  text-decoration: underline;
}
.bloco-sub {
  margin: -8px 0 var(--espaco-4);
  font-size: var(--texto-pequeno);
  color: var(--cor-texto-suave);
}
.bloco-nota {
  margin: var(--espaco-4) 0 0;
  font-size: 13px;
  color: var(--cor-texto-suave);
}
.bloco-vazio {
  margin: 0;
  padding: var(--espaco-5) var(--espaco-4);
  border-radius: 8px;
  background: var(--cor-realce-fundo);
  text-align: center;
  font-size: var(--texto-pequeno);
  color: var(--cor-texto-suave);
}
.bloco-grafico {
  margin-top: var(--espaco-2);
}
.bloco-pe {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--espaco-2) var(--espaco-4);
  margin-top: auto;
  padding-top: var(--espaco-4);
  font-size: 13px;
  color: var(--cor-texto-suave);
}
.bloco-pe > span {
  flex: 1 1 260px;
}
.bloco-pe .grafico-tabela {
  flex: 0 1 auto;
  margin: 0;
}
.bloco-pe .grafico-tabela[open] {
  flex-basis: 100%;
}
.bloco-separador {
  height: 1px;
  margin: var(--espaco-5) 0;
  background: var(--cor-borda);
}
.bloco-rosca {
  display: flex;
  justify-content: center;
  margin: 4px 0 20px;
}
.bloco-rosca .grafico-rosca {
  width: 100%;
  max-width: 190px;
}

/* Os números soltos de um bloco (empenhado, liquidado, pago...). */
.estatisticas {
  display: flex;
  flex-wrap: wrap;
  gap: var(--espaco-3) var(--espaco-6);
  margin: 0 0 var(--espaco-2);
}
.estatisticas-coluna {
  flex-direction: column;
  gap: 0;
  margin: 0;
}
.estatisticas-coluna .estatistica {
  flex-direction: row;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--espaco-3);
  padding: 10px 0;
  border-top: 1px solid var(--cor-borda);
}
.estatistica {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 0;
}
.estatistica dt {
  display: flex;
  align-items: center;
  gap: var(--espaco-2);
  font-size: 13px;
  color: var(--cor-texto-suave);
}
.estatistica dd {
  margin: 0;
  font-size: 20px;
  font-weight: 700;
  line-height: 1.25;
  color: var(--cor-texto);
  font-variant-numeric: tabular-nums;
}
.estatisticas-coluna .estatistica dd {
  font-size: 16px;
}
.estatistica-nota {
  display: block;
  font-size: var(--texto-mini);
  font-weight: 400;
  color: var(--cor-texto-suave);
}

/* --- Os cartões do alto ---------------------------------------------------

   Quatro linhas, sempre as mesmas: rótulo e selo; o número; o corpo; e o
   rodapé com a ação. A grade de linhas faz o número de um cartão ficar na
   mesma altura do número do vizinho, tenha o corpo uma linha ou três. */

.painel-cartoes {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 20px;
}
.painel-cartoes-3 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.painel-cartoes-2 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.painel-cartoes-1 {
  grid-template-columns: minmax(0, 420px);
}
@media (max-width: 1100px) {
  .painel-cartoes,
  .painel-cartoes-3 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (max-width: 560px) {
  .painel-cartoes,
  .painel-cartoes-3,
  .painel-cartoes-2 {
    grid-template-columns: minmax(0, 1fr);
  }
}
.kpi {
  position: relative;
  display: grid;
  grid-template-rows: auto auto 1fr auto;
  gap: var(--espaco-2);
  min-width: 0;
  padding: 20px 20px 16px;
  background: var(--cor-superficie);
  border: 1px solid var(--cor-borda);
  border-radius: 12px;
  box-shadow: var(--sombra-cartao);
  transition:
    border-color 0.15s ease,
    box-shadow 0.15s ease;
}
.kpi::before {
  content: '';
  position: absolute;
  top: -1px;
  left: 20px;
  right: 20px;
  height: 3px;
  border-radius: 0 0 3px 3px;
  background: var(--cor-borda-forte);
}
.kpi-bom::before {
  background: var(--cor-sucesso);
}
.kpi-atencao::before {
  background: var(--cor-atencao);
}
.kpi-critico::before {
  background: var(--cor-erro);
}
.kpi:hover {
  border-color: var(--cor-borda-forte);
  box-shadow: var(--sombra-cartao-realce);
}
.kpi-topo {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--espaco-2);
}
.kpi-rotulo {
  margin: 0;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.4;
  color: var(--cor-texto-suave);
}
.kpi-selo {
  flex: none;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: var(--texto-mini);
  font-weight: 700;
  line-height: 1.5;
  white-space: nowrap;
}
.kpi-selo-bom {
  background: var(--cor-sucesso-fundo);
  color: var(--cor-sucesso);
}
.kpi-selo-atencao {
  background: var(--cor-atencao-fundo);
  color: var(--cor-atencao);
}
.kpi-selo-critico {
  background: var(--cor-erro-fundo);
  color: var(--cor-erro);
}
.kpi-selo-neutro {
  background: var(--cor-realce-fundo);
  color: var(--cor-texto-suave);
}
.kpi-valor {
  margin: 0;
  font-size: 36px;
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.5px;
  color: var(--cor-texto);
  font-variant-numeric: tabular-nums;
}
.kpi-unidade {
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0;
  color: var(--cor-texto-suave);
}
.kpi-corpo {
  display: flex;
  flex-direction: column;
  gap: var(--espaco-1);
}
.kpi-detalhe {
  margin: 0;
  font-size: var(--texto-pequeno);
  line-height: 1.45;
  color: var(--cor-texto-suave);
}
.kpi-medidor {
  margin-bottom: var(--espaco-1);
}
.kpi-medidor svg {
  display: block;
  width: 100%;
  height: 8px;
  border-radius: 4px;
  overflow: hidden;
}
.kpi-medidor-trilho {
  fill: var(--cor-vazio);
}
.kpi-medidor-cheio {
  fill: var(--cor-primaria);
}
.kpi-medidor-bom {
  fill: var(--cor-sucesso);
}
.kpi-medidor-atencao {
  fill: var(--cor-atencao);
}
.kpi-medidor-critico {
  fill: var(--cor-erro);
}
.kpi-medidor-alvo {
  fill: var(--cor-texto);
}
.kpi-medidor-legenda {
  display: block;
  margin-top: var(--espaco-1);
  font-size: var(--texto-mini);
  text-align: right;
  color: var(--cor-apagado);
}
.kpi-rodape {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--espaco-2);
  margin-top: var(--espaco-1);
  padding-top: var(--espaco-3);
  border-top: 1px solid var(--cor-borda);
}
.kpi-meta {
  margin: var(--espaco-1) 0 0;
  font-size: var(--texto-mini);
  color: var(--cor-apagado);
}
.kpi-acao {
  flex: none;
  font-size: var(--texto-pequeno);
  font-weight: 600;
  text-decoration: none;
}
/* O cartão inteiro é clicável, mas o link de verdade é um só (o da ação):
   o ::after estica o alvo sem repetir o link para o leitor de tela. */
.kpi-acao::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 12px;
}
.kpi-acao:focus-visible {
  outline: none;
}
.kpi:has(.kpi-acao:focus-visible) {
  outline: 3px solid var(--foco-externo);
  outline-offset: 2px;
}

/* --- A agenda do que vai vencer ------------------------------------------ */

.agenda {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: 40px;
  margin: 0;
  padding: 0;
  list-style: none;
}
@media (max-width: 1000px) {
  .agenda {
    grid-template-columns: minmax(0, 1fr);
  }
}
.agenda-item {
  display: grid;
  grid-template-columns: 52px minmax(0, 1fr) auto;
  gap: var(--espaco-1) var(--espaco-4);
  align-items: center;
  padding: 14px 0;
  border-bottom: 1px solid var(--cor-borda);
}
.agenda-data {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 52px;
  border-radius: 10px;
  background: var(--cor-realce-fundo);
  line-height: 1.1;
}
.agenda-item-critico .agenda-data {
  background: var(--cor-erro-fundo);
}
.agenda-item-atencao .agenda-data {
  background: var(--cor-atencao-fundo);
}
.agenda-dia {
  font-size: 20px;
  font-weight: 700;
  color: var(--cor-texto);
}
.agenda-mes {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--cor-texto-suave);
}
.agenda-texto {
  display: flex;
  flex-direction: column;
  gap: var(--espaco-1);
  min-width: 0;
}
.agenda-texto a {
  font-weight: 600;
  line-height: 1.35;
  overflow-wrap: anywhere;
}
.agenda-oque {
  font-size: 13px;
  color: var(--cor-texto-suave);
}
.agenda-tipo {
  display: inline-block;
  margin-right: var(--espaco-1);
  padding: 0 var(--espaco-2);
  border-radius: 999px;
  background: var(--cor-realce-fundo-forte);
  font-size: var(--texto-mini);
  font-weight: 600;
  line-height: 1.6;
  color: var(--cor-texto);
}
.agenda-quando {
  font-size: 13px;
  font-weight: 700;
  white-space: nowrap;
  color: var(--cor-texto-suave);
}
.agenda-quando-atencao {
  color: var(--cor-atencao);
}
.agenda-quando-critico {
  color: var(--cor-erro);
}
@media (max-width: 560px) {
  .agenda-item {
    grid-template-columns: 48px minmax(0, 1fr);
  }
  .agenda-quando {
    grid-column: 2;
  }
}

/* --- Listas dos blocos ----------------------------------------------------- */

.lista-do-painel {
  margin: 0;
  padding: 0;
  list-style: none;
}
.lista-do-painel > li {
  display: flex;
  align-items: center;
  gap: var(--espaco-3);
  padding: var(--espaco-3) 0;
  border-top: 1px solid var(--cor-borda);
}
.lista-do-painel > li:first-child {
  border-top: 0;
  padding-top: 0;
}
.lista-principal {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  font-size: 15px;
}
.lista-principal a,
.lista-principal strong {
  font-weight: 600;
  overflow-wrap: anywhere;
}
.lista-meta {
  font-size: 13px;
  color: var(--cor-texto-suave);
}
.lista-numero {
  flex: none;
  font-size: 13px;
  text-align: right;
  color: var(--cor-texto-suave);
  font-variant-numeric: tabular-nums;
}
.lista-numero strong {
  display: block;
  font-size: 20px;
  color: var(--cor-texto);
}
.lista-em-colunas {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: 40px;
}
.lista-em-colunas > li:nth-child(2) {
  border-top: 0;
  padding-top: 0;
}
@media (max-width: 900px) {
  .lista-em-colunas {
    grid-template-columns: minmax(0, 1fr);
  }
  .lista-em-colunas > li:nth-child(2) {
    border-top: 1px solid var(--cor-borda);
    padding-top: var(--espaco-3);
  }
}
.avatar {
  display: grid;
  flex: none;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--cor-realce-fundo-forte);
  place-items: center;
  font-size: 13px;
  font-weight: 700;
  color: var(--cor-primaria);
}
.lista-de-pessoas .lista-principal strong {
  display: inline;
}
.lista-de-pessoas .marca-de-estado {
  margin-left: var(--espaco-1);
  vertical-align: 1px;
}

/* O ranking das mais lidas. */
.ranking {
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: none;
}
.ranking li {
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr) auto;
  align-items: baseline;
  gap: var(--espaco-3);
  padding: var(--espaco-3) 0;
  border-top: 1px solid var(--cor-borda);
  font-size: 15px;
}
.ranking li:first-child {
  border-top: 0;
  padding-top: 0;
}
.ranking-posicao {
  display: grid;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--cor-realce-fundo-forte);
  place-items: center;
  font-size: var(--texto-mini);
  font-weight: 700;
  color: var(--cor-primaria);
  align-self: center;
}
.ranking a {
  font-weight: 600;
  overflow-wrap: anywhere;
}
.ranking-valor {
  font-size: 13px;
  white-space: nowrap;
  color: var(--cor-texto-suave);
}

/* A rosca de obras com a legenda ao lado, e não embaixo. */
.rosca-com-legenda {
  display: grid;
  grid-template-columns: minmax(140px, 180px) minmax(0, 1fr);
  align-items: center;
  gap: var(--espaco-5);
}
.rosca-com-legenda .bloco-rosca {
  margin: 0;
}
@media (max-width: 480px) {
  .rosca-com-legenda {
    grid-template-columns: minmax(0, 1fr);
  }
}
.legenda-lista {
  margin: 0;
  padding: 0;
  list-style: none;
}
.legenda-lista li {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: var(--espaco-2) 0;
  border-top: 1px solid var(--cor-borda);
  font-size: 15px;
}
.legenda-lista li:first-child {
  border-top: 0;
}
.legenda-lista a {
  flex: 1 1 auto;
}
.legenda-lista-valor {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.marca-de-estado {
  display: inline-block;
  flex: none;
  padding: 1px 8px;
  border-radius: 999px;
  font-size: var(--texto-mini);
  font-weight: 600;
  line-height: 1.5;
}
.marca-de-estado-bom {
  background: var(--cor-sucesso-fundo);
  color: var(--cor-sucesso);
}
.marca-de-estado-atencao {
  background: var(--cor-atencao-fundo);
  color: var(--cor-atencao);
}
.marca-de-estado-critico {
  background: var(--cor-erro-fundo);
  color: var(--cor-erro);
}
.marca-de-estado-neutro {
  background: var(--cor-realce-fundo-forte);
  color: var(--cor-texto-suave);
}

/* A busca e o botão de criar, na linha do título da equipe. */
.equipe-acoes {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--espaco-3);
}
.busca-compacta {
  display: flex;
  gap: var(--espaco-2);
}
.busca-compacta input {
  width: 300px;
  max-width: 100%;
  padding: 9px 12px;
  border: 1px solid var(--cor-borda-forte);
  border-radius: 8px;
  font: inherit;
  font-size: 15px;
  background: var(--cor-superficie);
  color: var(--cor-texto);
}
@media (max-width: 640px) {
  .equipe-acoes,
  .busca-compacta {
    width: 100%;
  }
  .busca-compacta input {
    flex: 1 1 auto;
    width: auto;
  }
}

.painel-rodape {
  margin: 48px 0 0;
  padding-top: var(--espaco-4);
  border-top: 1px solid var(--cor-borda);
  font-size: 13px;
  color: var(--cor-apagado);
}

.coluna-acoes > * {
  display: inline-block;
  vertical-align: middle;
  margin: 2px 4px 2px 0;
}

/* E-mail é uma palavra só, sem espaço para quebrar: a coluna ficava com a
   largura do endereço mais comprido e a tabela passava da caixa. Aqui ele
   quebra no ponto que for preciso (KAN-168). */
.tabela .celula-email {
  overflow-wrap: anywhere;
}

/* OS BOTÕES DA ÚLTIMA COLUNA DAS LISTAS (KAN-168). A coluna encolhia até o
   texto do botão quebrar em duas linhas ("Ver a / página") e o segundo botão
   descia para baixo do primeiro. O texto do botão não quebra mais, e o
   formulário de um botão só (Arquivar, Publicar) fica na mesma linha. */
.tabela td .botao-pequeno {
  white-space: nowrap;
}
.tabela td > form:has(> .botao-pequeno) {
  display: inline-block;
  margin: 2px 0;
  vertical-align: middle;
}
.tabela td > .botao-pequeno {
  margin: 2px 4px 2px 0;
  vertical-align: middle;
}

/* --- O modal (<dialog>) ------------------------------------------------- */

.dialogo {
  width: min(560px, calc(100vw - 32px));
  max-height: calc(100vh - 48px);
  padding: 0;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
  background: var(--cor-superficie);
  color: var(--cor-texto);
  box-shadow: var(--sombra-janela);
}
.dialogo::backdrop {
  background: var(--veu-da-janela);
}
/* Sem script, o servidor desenha o dialog com `open`: ele aparece no fluxo
   da página, como um formulário comum no alto. */
.dialogo[open]:not(:modal) {
  position: static;
  margin: 0 0 var(--espaco-5);
  width: auto;
  max-width: 560px;
}
.dialogo-cabeca {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--espaco-3);
  padding: 16px 20px;
  border-bottom: 1px solid var(--cor-borda);
}
.dialogo-cabeca h2 {
  margin: 0;
  font-size: 19px;
  display: flex;
  align-items: center;
  gap: 10px;
}
.dialogo-fechar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  font-size: 24px;
  line-height: 1;
  text-decoration: none;
  color: var(--cor-texto-suave);
}
.dialogo-fechar:hover {
  background: var(--cor-realce-fundo);
  color: var(--cor-texto);
}
.dialogo .mensagem {
  margin: 16px 20px 0;
}
.dialogo .formulario-usuario {
  padding: 16px 20px 20px;
}
.formulario-usuario .campo {
  margin-bottom: 14px;
}
.formulario-usuario select,
.formulario-usuario input {
  width: 100%;
  max-width: none;
}
.formulario-acoes {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 6px;
}

/* As barras deitadas (graficos.js › barrasDeitadas): HTML, para o texto não
   encolher nas colunas estreitas. */
.barras-deitadas {
  margin: 0;
  padding: 0;
  list-style: none;
}
.barra-linha {
  display: grid;
  grid-template-columns: minmax(112px, 36%) minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  padding: 6px 4px;
  border-radius: 6px;
  color: var(--cor-texto);
  text-decoration: none;
  font-size: var(--texto-pequeno);
}
.barra-linha:hover,
.barra-linha:focus-visible {
  background: var(--cor-realce-fundo);
}
.barra-rotulo {
  color: var(--cor-texto-suave);
}
.barra-trilho {
  display: block;
  width: 100%;
  height: 14px;
}
.barra-fundo {
  fill: var(--cor-vazio);
}
.barra-cheia {
  fill: var(--cor-marca);
}
.barra-valor {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Nos títulos das listas do painel o sublinhado sai: a lista inteira é de
   links, e vinte sublinhados seguidos viram ruído. Ele volta no hover e no
   foco, que é quando a pessoa precisa saber onde está. */
.agenda-texto a,
.lista-principal a,
.ranking a,
.legenda-lista a {
  color: var(--cor-texto);
  text-decoration: none;
}
.agenda-texto a:hover,
.agenda-texto a:focus-visible,
.lista-principal a:hover,
.lista-principal a:focus-visible,
.ranking a:hover,
.ranking a:focus-visible,
.legenda-lista a:hover,
.legenda-lista a:focus-visible {
  color: var(--cor-link);
  text-decoration: underline;
}
.lista-nome {
  display: block;
  font-weight: 600;
}
.link-editar {
  flex: none;
  padding: 4px 10px;
  border-radius: 6px;
  font-size: var(--texto-pequeno);
  font-weight: 600;
  text-decoration: none;
}
.link-editar:hover,
.link-editar:focus-visible {
  background: var(--cor-realce-fundo);
  text-decoration: underline;
}
/* ==========================================================================
   SEÇÕES EM CARDS COM MODAL (KAN-111, 28/09)
   ==========================================================================

   As telas de seções (Secretarias, Arquivos, Aparência, Integrações) eram
   acordeões. Agora são uma grade de cards, e cada card abre a seção num
   modal. O bloco some da grade ("display: contents") para que card e modal
   sejam, os dois, filhos diretos dela: sem JavaScript o modal aparece aberto
   no fluxo e ocupa a linha inteira, logo abaixo dos cards. */

.secoes-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 20px;
}
.secao-bloco {
  display: contents;
}
.secao-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--espaco-1);
  min-height: 168px;
  padding: 20px;
  border: 1px solid var(--cor-borda);
  border-radius: 12px;
  background: var(--cor-superficie);
  box-shadow: var(--sombra-cartao);
  color: var(--cor-texto);
  text-decoration: none;
  transition:
    border-color 0.15s ease,
    box-shadow 0.15s ease,
    transform 0.15s ease;
}
.secao-card:hover,
.secao-card:focus-visible {
  border-color: var(--cor-borda-forte);
  box-shadow: var(--sombra-cartao-realce);
  transform: translateY(-2px);
}
@media (prefers-reduced-motion: reduce) {
  .secao-card,
  .secao-card:hover,
  .secao-card:focus-visible {
    transition: none;
    transform: none;
  }
}
.secao-card-icone {
  display: grid;
  width: 44px;
  height: 44px;
  margin-bottom: auto;
  border-radius: 12px;
  background: var(--cor-realce-fundo-forte);
  place-items: center;
  color: var(--cor-primaria);
}
.secao-card-icone .icone-secao {
  width: 20px;
  height: 20px;
}
.secao-card-selo {
  position: absolute;
  top: 20px;
  right: 20px;
}
.secao-card-nome {
  margin-top: 20px;
  font-size: 17px;
  font-weight: 700;
  line-height: 1.3;
}
.secao-card-conta {
  font-size: var(--texto-pequeno);
  color: var(--cor-texto-suave);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* O modal da seção é largo: dentro dele moram listas e formulários. A cabeça
   fica presa no alto e só o corpo rola. */
.dialogo-secao {
  width: min(1040px, calc(100vw - 32px));
  max-width: none;
}
.dialogo-secao[open] {
  display: flex;
  flex-direction: column;
}
.dialogo-secao .dialogo-cabeca {
  flex: none;
}
.dialogo-cabeca-icone {
  display: grid;
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background: var(--cor-realce-fundo-forte);
  place-items: center;
  color: var(--cor-primaria);
}
.dialogo-corpo {
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
  padding: 20px 24px 24px;
}
.dialogo-corpo > .mensagem:first-child {
  margin: 0 0 var(--espaco-4);
}
/* Sem script: o modal aberto aparece na grade, na linha inteira. */
.secoes-cards > .secao-bloco > .dialogo-secao[open]:not(:modal) {
  grid-column: 1 / -1;
  width: auto;
  max-width: none;
  max-height: none;
  margin: 0;
}

/* ==========================================================================
   A BARRA DAS TELAS DE LISTA (KAN-111, 28/09): busca · Filtros · Ações
   ========================================================================== */

.barra-lista {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--espaco-3);
  margin: 24px 0 20px;
}

/* A busca em pastilha, a mesma família da busca do topo do portal público. */
.busca-pilula {
  display: flex;
  flex: 1 1 320px;
  align-items: center;
  min-width: 0;
  height: 44px;
  padding: 0 var(--espaco-1) 0 var(--espaco-4);
  border: 1px solid var(--cor-borda-forte);
  border-radius: 999px;
  background: var(--cor-superficie);
}
.busca-pilula:focus-within {
  border-color: var(--cor-primaria);
  box-shadow: 0 0 0 3px var(--cor-realce-fundo-forte);
}
.busca-pilula-lupa {
  flex: none;
  width: 18px;
  height: 18px;
  color: var(--cor-texto-suave);
}
.busca-pilula input {
  flex: 1 1 auto;
  min-width: 0;
  height: 100%;
  padding: 0 10px;
  border: 0;
  background: transparent;
  font: inherit;
  font-size: 15px;
  color: var(--cor-texto);
}
.busca-pilula input:focus {
  outline: none;
}
.busca-pilula-limpar {
  display: grid;
  flex: none;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  place-items: center;
  font-size: 20px;
  line-height: 1;
  color: var(--cor-texto-suave);
  text-decoration: none;
}
.busca-pilula-limpar:hover {
  background: var(--cor-realce-fundo);
}
.busca-pilula-botao {
  flex: none;
  height: 36px;
  padding: 0 var(--espaco-4);
  border: 0;
  border-radius: 999px;
  background: var(--cor-realce-fundo-forte);
  font: inherit;
  font-size: var(--texto-pequeno);
  font-weight: 600;
  color: var(--cor-primaria);
  cursor: pointer;
}
.busca-pilula-botao:hover {
  background: var(--cor-borda-forte);
}
.barra-lista-nota {
  margin: -8px 0 var(--espaco-4);
  font-size: var(--texto-pequeno);
  color: var(--cor-texto-suave);
}

/* Os menus que descem. */
.menu-suspenso {
  position: relative;
  flex: none;
}
.menu-suspenso > summary {
  list-style: none;
}
.menu-suspenso > summary::-webkit-details-marker {
  display: none;
}
.menu-suspenso-botao {
  display: inline-flex;
  align-items: center;
  gap: var(--espaco-2);
  height: 44px;
  cursor: pointer;
}
.menu-suspenso-seta {
  transition: transform 0.15s ease;
}
.menu-suspenso[open] .menu-suspenso-seta {
  transform: rotate(180deg);
}
.menu-suspenso-contador {
  display: inline-grid;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: 999px;
  background: var(--cor-primaria);
  place-items: center;
  font-size: var(--texto-mini);
  font-weight: 700;
  color: var(--cor-sobre-primaria);
}
.menu-suspenso-painel {
  position: absolute;
  z-index: 30;
  top: calc(100% + 8px);
  /* Presos pela DIREITA: os dois botões ficam na ponta direita da barra, e
     um painel preso pela esquerda passaria da borda da tela. */
  right: 0;
  min-width: 260px;
  max-width: min(640px, calc(100vw - 32px));
  padding: var(--espaco-2);
  border: 1px solid var(--cor-borda);
  border-radius: 12px;
  background: var(--cor-superficie);
  box-shadow: var(--sombra-flutuante);
}
.menu-suspenso-direita .menu-suspenso-painel {
  left: auto;
  right: 0;
}
@media (max-width: 640px) {
  .menu-suspenso-painel,
  .menu-suspenso-direita .menu-suspenso-painel {
    position: fixed;
    top: auto;
    right: 16px;
    bottom: 16px;
    left: 16px;
    max-width: none;
    max-height: 70vh;
    overflow: auto;
  }
}

/* O painel de filtros: cada fileira com o nome dela em cima. O nome vem do
   aria-label que a fileira já tinha — o leitor de tela e o olho leem o mesmo. */
.painel-de-filtros {
  width: min(560px, calc(100vw - 32px));
  max-height: min(70vh, 560px);
  overflow: auto;
  padding: var(--espaco-4);
}
.painel-de-filtros .filtros {
  margin: 0 0 14px;
}
.painel-de-filtros .filtros:last-of-type {
  margin-bottom: 0;
}
.painel-de-filtros .filtros::before {
  content: attr(aria-label);
  flex-basis: 100%;
  margin-bottom: 2px;
  font-size: var(--texto-mini);
  font-weight: 700;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  color: var(--cor-texto-suave);
}
.painel-de-filtros .filtros a {
  font-size: var(--texto-pequeno);
}
.painel-de-filtros-pe {
  margin: 14px 0 0;
  padding-top: var(--espaco-3);
  border-top: 1px solid var(--cor-borda);
  font-size: var(--texto-pequeno);
}

/* O menu de ações. */
.menu-de-acoes {
  width: 300px;
}
.menu-de-acoes-item {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px 12px;
  border-radius: 8px;
  color: var(--cor-texto);
  text-decoration: none;
}
.menu-de-acoes-item:hover,
.menu-de-acoes-item:focus-visible {
  background: var(--cor-realce-fundo);
}
.menu-de-acoes-texto {
  font-size: 15px;
  font-weight: 600;
}
.menu-de-acoes-principal .menu-de-acoes-texto {
  color: var(--cor-primaria);
}
.menu-de-acoes-principal .menu-de-acoes-texto::before {
  content: '+ ';
}
.menu-de-acoes-descricao {
  font-size: 13px;
  line-height: 1.35;
  color: var(--cor-texto-suave);
}
.menu-de-acoes-separador {
  height: 1px;
  margin: var(--espaco-2) var(--espaco-1);
  background: var(--cor-borda);
}
.menu-de-acoes-titulo {
  margin: var(--espaco-1) var(--espaco-3) var(--espaco-2);
  font-size: var(--texto-mini);
  font-weight: 700;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  color: var(--cor-texto-suave);
}
.menu-de-acoes-formatos {
  display: flex;
  gap: var(--espaco-2);
  padding: 0 var(--espaco-3) var(--espaco-2);
}
.menu-de-acoes-formatos a {
  flex: 1 1 0;
  padding: var(--espaco-2) 0;
  border: 1px solid var(--cor-borda-forte);
  border-radius: 8px;
  text-align: center;
  font-size: var(--texto-pequeno);
  font-weight: 600;
  text-decoration: none;
}
.menu-de-acoes-formatos a:hover {
  background: var(--cor-realce-fundo);
}
.menu-de-acoes-fila {
  padding: 0 var(--espaco-3) var(--espaco-1);
}
.menu-de-acoes-fila button {
  padding: var(--espaco-1) 0;
  border: 0;
  background: none;
  font: inherit;
  font-size: 13px;
  color: var(--cor-link);
  text-decoration: underline;
  cursor: pointer;
}

/* O título da tela com o "?" que guarda a explicação. */
.destaque-titulo {
  display: flex;
  align-items: center;
  gap: 10px;
}
.destaque-titulo h1 {
  margin: 0;
}
.ajuda-tela {
  position: relative;
}
.ajuda-tela > summary {
  display: grid;
  width: 28px;
  height: 28px;
  border: 1px solid var(--cor-borda-forte);
  border-radius: 50%;
  place-items: center;
  font-size: var(--texto-pequeno);
  font-weight: 700;
  color: var(--cor-texto-suave);
  list-style: none;
  cursor: pointer;
}
.ajuda-tela > summary::-webkit-details-marker {
  display: none;
}
.ajuda-tela > summary:hover,
.ajuda-tela[open] > summary {
  border-color: var(--cor-primaria);
  color: var(--cor-primaria);
}
.ajuda-tela-texto {
  position: absolute;
  z-index: 30;
  top: calc(100% + 8px);
  left: 0;
  width: min(460px, calc(100vw - 48px));
  padding: var(--espaco-4);
  border: 1px solid var(--cor-borda);
  border-radius: 12px;
  background: var(--cor-superficie);
  box-shadow: var(--sombra-flutuante);
  font-size: var(--texto-pequeno);
  line-height: 1.5;
  color: var(--cor-texto-suave);
}
.ajuda-tela-texto p {
  margin: 0 0 var(--espaco-2);
}
.ajuda-tela-texto p:last-child {
  margin: 0;
}

/* A lista fica numa caixa só, sem o título solto em cima. */
.lista-caixa {
  padding: 0;
  overflow: hidden;
  border: 1px solid var(--cor-borda);
  border-radius: 12px;
  background: var(--cor-superficie);
}
.lista-caixa-cabeca {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--espaco-3);
  padding: 16px 20px;
  border-bottom: 1px solid var(--cor-borda);
}
.lista-caixa-cabeca h2 {
  margin: 0;
  font-size: 16px;
}
.lista-caixa .tabela-rolagem {
  margin: 0;
}
.lista-caixa > :not(.tabela-rolagem):not(.lista-caixa-cabeca) {
  margin: 0;
  padding: 16px 20px;
}
.lista-caixa > :not(.tabela-rolagem):not(.lista-caixa-cabeca) + :not(.tabela-rolagem) {
  padding-top: 0;
}
.destaque-resumo {
  margin: 6px 0 0;
  font-size: 15px;
  color: var(--cor-texto-suave);
}
/* Filtros que são formulário (listas de escolha), dentro do painel. */
.painel-de-filtros .filtros-formulario {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--espaco-3) var(--espaco-4);
  align-items: end;
}
.painel-de-filtros .filtros-formulario .campo {
  margin: 0;
}
.painel-de-filtros .filtros-formulario select {
  width: 100%;
}
.painel-de-filtros .filtros-formulario > button {
  grid-column: 1 / -1;
  justify-self: start;
}
@media (max-width: 560px) {
  .painel-de-filtros .filtros-formulario {
    grid-template-columns: minmax(0, 1fr);
  }
}
/* As ferramentas no alto do modal de uma seção (procurar, enviar). */
.secao-ferramentas {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: var(--espaco-3);
  margin-bottom: var(--espaco-4);
}
.dialogo-secao .secao-sanfona-corpo {
  padding: 0;
  border: 0;
}
.amostra-cores-svg {
  margin-right: 6px;
  vertical-align: -2px;
}
/* "Filtros" com algum filtro ligado: a borda na cor principal, junto do
   contador, avisa que a lista abaixo não é a lista inteira. */
.menu-suspenso-ligado {
  border-color: var(--cor-primaria);
  color: var(--cor-primaria);
}
/* Barra só com "Ações" (telas curtas, sem busca): o botão vai para a direita. */
.barra-lista-sem-busca {
  justify-content: flex-end;
}

/* O ERRO QUE TEM ENDEREÇO (KAN-111): o link do aviso até o campo recusado, e
   a marca no campo. ":target" marca o campo mesmo sem JavaScript, quando a
   pessoa segue o link; a classe vem do campo-com-erro.js. */
.mensagem-ir {
  margin-left: auto;
  font-weight: 600;
  white-space: nowrap;
}
.campo .campo-com-erro,
.formulario input:target,
.formulario select:target,
.formulario textarea:target {
  border-color: var(--cor-erro);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--cor-erro) 15%, transparent);
}
/* Com o cursor dentro, o contorno de foco continua (é acessibilidade), mas
   em vermelho: o foco verde por cima apagava a marca do erro. */
.campo .campo-com-erro:focus-visible,
.campo .campo-com-erro:focus {
  outline: 3px solid var(--cor-erro);
  outline-offset: 2px;
  border-color: var(--cor-erro);
}
/* OS BLOCOS DAS FICHAS LONGAS (KAN-111, critério "sei em que bloco estou"):
   o subtítulo do bloco gruda no alto da tela enquanto o bloco rola. */
.formulario-bloco {
  position: sticky;
  top: 0;
  z-index: 2;
  margin: var(--espaco-5) -4px var(--espaco-2);
  padding: 10px 4px 8px;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--cor-texto-suave);
  background: var(--cor-superficie);
  border-bottom: 1px solid var(--cor-borda);
}
.formulario-bloco:first-of-type {
  margin-top: var(--espaco-1);
}

/* --- A BARRA DO GERENCIAMENTO (KAN-109, 28/09) --------------------------
 *
 * No admin não há mais o cabeçalho do portal (as duas faixas azuis). O que
 * sobra é UMA barra no alto do conteúdo, e ela é montada com o que cada tela
 * já tem, sem nenhuma tela mudar:
 *
 *   [ ← voltar ]  [ SEÇÃO / Título da tela (?) ]  [ ♿ ] [ Ver o portal ↗ ]
 *
 * O <main> vira uma grade de três colunas. A primeira linha recebe o voltar
 * (.barra-voltar), o título (a .destaque da tela) e os botões
 * (.barra-admin-acoes); todo o resto ocupa as três colunas, como antes. O
 * fundo branco da barra é o ::before do <main>, também na primeira linha. */
.conteudo-admin {
  /* A conta do .menu-topo: botão de 2,25rem + 0,7rem em cima e embaixo + a
     borda de 1px. Se o topo da barra lateral mudar, muda aqui junto. */
  --altura-barra-admin: calc(2.25rem + 1.4rem + 1px);
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  /* A barra tem a mesma altura do topo da barra lateral (.menu-topo): as
     duas linhas de baixo se encontram numa linha só. */
  grid-template-rows: minmax(var(--altura-barra-admin), auto);
  column-gap: 14px;
  align-content: start;
  padding-top: 0;
}
.conteudo-admin > * {
  grid-column: 1 / -1;
}
.conteudo-admin::before {
  content: '';
  grid-row: 1;
  grid-column: 1 / -1;
  margin: 0 -28px 0;
  border-bottom: 1px solid var(--cor-borda);
  background: var(--cor-superficie);
}
.conteudo-admin > .barra-voltar,
.conteudo-admin > .barra-admin-acoes,
.conteudo-admin > .barra-admin-acoes + .destaque,
.conteudo-admin > .barra-admin-acoes + .painel-topo {
  grid-row: 1;
  margin: 0;
  padding: 6px 0;
  align-self: center;
}
.conteudo-admin > .barra-voltar {
  grid-column: 1;
}
.conteudo-admin > .barra-admin-acoes + .destaque,
.conteudo-admin > .barra-admin-acoes + .painel-topo {
  grid-column: 2;
}
.conteudo-admin > .barra-admin-acoes {
  grid-column: 3;
}
/* A segunda linha (o conteúdo da tela) começa afastada da barra. */
.conteudo-admin > .barra-admin-acoes + .destaque + *,
.conteudo-admin > .barra-admin-acoes + .painel-topo + * {
  margin-top: var(--espaco-5);
}

/* O voltar vira um botão redondo só com a seta; o texto ("Voltar para o
 * painel") continua para o leitor de tela e na dica. */
.conteudo-admin .barra-voltar .voltar {
  display: grid;
  width: 36px;
  height: 36px;
  place-items: center;
  border: 1px solid var(--cor-borda-forte);
  border-radius: 50%;
  color: var(--cor-texto-suave);
}
.conteudo-admin .barra-voltar .voltar:hover,
.conteudo-admin .barra-voltar .voltar:focus-visible {
  border-color: var(--cor-primaria);
  color: var(--cor-primaria);
}
.conteudo-admin .barra-voltar .voltar svg {
  width: 14px;
  height: 14px;
}
.conteudo-admin .voltar-texto {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* O título da tela, dentro da barra: a seção pequena em cima, o nome em
 * destaque embaixo. O texto de apoio de algumas fichas (o credor e o valor do
 * contrato, por exemplo) fica numa linha discreta logo abaixo. */
.conteudo-admin > .barra-admin-acoes + .destaque .etiqueta,
.conteudo-admin > .barra-admin-acoes + .painel-topo .etiqueta {
  margin: 0 0 2px;
  font-size: 11px;
  letter-spacing: 1.2px;
}
.conteudo-admin > .barra-admin-acoes + .destaque h1,
.conteudo-admin > .barra-admin-acoes + .painel-topo h1 {
  margin: 0;
  font-size: var(--texto-titulo);
  line-height: 1.25;
}
.conteudo-admin > .barra-admin-acoes + .destaque .destaque-previa-titulo {
  overflow: hidden;
  margin: 0;
  color: var(--cor-texto);
  font-size: var(--texto-titulo);
  font-weight: 700;
  line-height: 1.25;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.conteudo-admin > .barra-admin-acoes + .destaque .destaque-texto {
  margin-top: 2px;
  font-size: var(--texto-pequeno);
}

.barra-admin-acoes {
  display: flex;
  align-items: center;
  gap: var(--espaco-2);
}
/* A acessibilidade vira um ícone redondo, com o nome só na dica e para o
 * leitor de tela. O painel abre para a esquerda, para não sair da tela. */
.barra-admin-acoes .acessibilidade-abrir {
  display: grid;
  width: 36px;
  height: 36px;
  padding: 0;
  place-items: center;
  border: 1px solid var(--cor-borda-forte);
  color: var(--cor-texto-suave);
}
.barra-admin-acoes .acessibilidade-abrir:hover,
.barra-admin-acoes .acessibilidade-abrir:focus-visible,
.barra-admin-acoes .acessibilidade[open] .acessibilidade-abrir {
  border-color: var(--cor-primaria);
  background: var(--cor-realce-fundo);
  color: var(--cor-primaria);
}
.barra-admin-acoes .acessibilidade-abrir > span {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}
.barra-admin-acoes .acessibilidade-painel {
  right: 0;
  left: auto;
}
.barra-admin-portal {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border: 1px solid var(--cor-borda-forte);
  border-radius: 999px;
  color: var(--cor-primaria);
  font-size: var(--texto-pequeno);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}
.barra-admin-portal:hover,
.barra-admin-portal:focus-visible {
  border-color: var(--cor-primaria);
  background: var(--cor-realce-fundo);
}

/* A BARRA FICA PARADA NO ALTO; SÓ O CONTEÚDO ROLA.
 *
 * Cada peça da primeira linha (o fundo branco, o voltar, o título e os botões)
 * gruda no topo com a mesma altura, então as quatro seguem juntas como uma
 * barra só, alinhada com a linha do botão do menu. Só em tela larga: no
 * celular a barra tem duas linhas e ocuparia espaço demais parada. */
@media (min-width: 40.01rem) {
  .conteudo-admin {
    grid-template-rows: var(--altura-barra-admin);
  }
  .conteudo-admin::before,
  .conteudo-admin > .barra-voltar,
  .conteudo-admin > .barra-admin-acoes,
  .conteudo-admin > .barra-admin-acoes + .destaque,
  .conteudo-admin > .barra-admin-acoes + .painel-topo {
    position: sticky;
    /* Abaixo da barra lateral (20), para o submenu dela abrir por cima. */
    z-index: 19;
    top: 0;
    box-sizing: border-box;
    height: var(--altura-barra-admin);
    align-self: start;
  }
  .conteudo-admin::before {
    z-index: 18;
  }
  .conteudo-admin > .barra-voltar,
  .conteudo-admin > .barra-admin-acoes + .destaque,
  .conteudo-admin > .barra-admin-acoes + .painel-topo {
    display: flex;
    min-width: 0;
    flex-direction: column;
    justify-content: center;
  }
  /* O painel não tem o voltar: o título fica em linha com a hora, encostado
     à esquerda na mesma borda dos cartões (o -14px desfaz o espaço da
     coluna do voltar, que ali está vazia). */
  .conteudo-admin > .barra-admin-acoes + .painel-topo {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    margin-left: -14px;
  }
  /* Etiqueta, título e a linha de apoio cabem nos 59px da barra: linhas
     justas, e a linha de apoio menor e numa linha só (o que não couber vira
     reticências). */
  .conteudo-admin > .barra-admin-acoes + .destaque .etiqueta,
  .conteudo-admin > .barra-admin-acoes + .painel-topo .etiqueta {
    margin: 0;
    line-height: 1.2;
  }
  .conteudo-admin > .barra-admin-acoes + .destaque h1,
  .conteudo-admin > .barra-admin-acoes + .painel-topo h1 {
    line-height: 1.2;
  }
  /* A tela de grupo tem o ícone ao lado do texto: fica lado a lado. */
  .conteudo-admin > .barra-admin-acoes + .destaque-grupo {
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
  }
  .conteudo-admin > .barra-admin-acoes + .destaque-grupo .destaque-icone {
    width: 36px;
    height: 36px;
    margin-top: 0;
  }
  .conteudo-admin > .barra-admin-acoes + .destaque .destaque-texto,
  .conteudo-admin > .barra-admin-acoes + .destaque .destaque-resumo {
    overflow: hidden;
    margin-top: 1px;
    font-size: var(--texto-mini);
    line-height: 1.3;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  /* O subtítulo dos blocos das fichas gruda logo abaixo da barra, e não
     por baixo dela. */
  .conteudo-admin .formulario-bloco {
    top: var(--altura-barra-admin);
  }
  /* Centraliza acima da borda de 1px do fundo. */
  .conteudo-admin > .barra-voltar,
  .conteudo-admin > .barra-admin-acoes,
  .conteudo-admin > .barra-admin-acoes + .destaque,
  .conteudo-admin > .barra-admin-acoes + .painel-topo {
    padding: 0 0 1px;
  }
}

/* Em tela estreita, o título desce para uma linha própria, abaixo do voltar
 * e dos botões, e o "Ver o portal" fica só com o ícone. */
@media (max-width: 40rem) {
  .conteudo-admin > .barra-admin-acoes + .destaque,
  .conteudo-admin > .barra-admin-acoes + .painel-topo {
    grid-row: 2;
    grid-column: 1 / -1;
    padding-top: var(--espaco-1);
  }
  .conteudo-admin::before {
    grid-row: 1 / 3;
  }
  .conteudo-admin > .barra-admin-acoes {
    justify-self: end;
  }
  .barra-admin-portal {
    padding: 8px 10px;
    font-size: 0;
  }
  .barra-admin-portal svg {
    width: 16px;
    height: 16px;
  }
}

/* --- A PORTA DO PORTAL DA TRANSPARÊNCIA (KAN-110, 28/09) ------------------
 *
 * As quatro consultas principais (licitações, contratos, parcerias,
 * convênios) numa linha, com o mesmo peso; cada uma com o seu desenho e a sua
 * faixa de cor em cima, para se distinguir de relance. As outras consultas
 * vêm abaixo, numa grade mais compacta. Só nesta tela: as outras que usam
 * .cartao-transparencia não têm estas classes e continuam iguais. */
.grade-transparencia-principal,
.grade-transparencia-outras {
  gap: var(--espaco-4);
}
.grade-transparencia-principal {
  grid-template-columns: repeat(4, minmax(0, 1fr));
  margin-top: var(--espaco-5);
}
.grade-transparencia-outras {
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
}
.grade-transparencia-principal .cartao-transparencia,
.grade-transparencia-outras .cartao-transparencia {
  position: relative;
  transition:
    border-color 0.15s ease,
    box-shadow 0.15s ease;
}
.grade-transparencia-principal .cartao-transparencia {
  padding: var(--espaco-5);
  border-top: 4px solid var(--acento-da-consulta, var(--cor-primaria));
  box-shadow: var(--sombra-cartao);
}
.cartao-transparencia-licitacoes {
  --acento-da-consulta: var(--cor-primaria);
}
.cartao-transparencia-contratos {
  --acento-da-consulta: var(--cor-destaque);
}
.cartao-transparencia-parcerias {
  --acento-da-consulta: var(--cor-atencao);
}
.cartao-transparencia-convenios {
  --acento-da-consulta: var(--cor-nivel-diamante);
}

/* O cartão inteiro é clicável: o link do título estica por cima dele. */
.grade-transparencia-principal .cartao-transparencia :is(h2, h3) a::after,
.grade-transparencia-outras .cartao-transparencia :is(h2, h3) a::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: var(--raio);
}
.grade-transparencia-principal .cartao-transparencia:hover,
.grade-transparencia-principal .cartao-transparencia:focus-within,
.grade-transparencia-outras .cartao-transparencia:hover,
.grade-transparencia-outras .cartao-transparencia:focus-within {
  border-color: var(--cor-borda-forte);
  box-shadow: var(--sombra-cartao-realce);
}

.cartao-transparencia-icone {
  display: grid;
  width: 44px;
  height: 44px;
  place-items: center;
  border-radius: 12px;
  background: color-mix(
    in srgb,
    var(--acento-da-consulta, var(--cor-primaria)) 12%,
    var(--cor-superficie)
  );
  color: var(--acento-da-consulta, var(--cor-primaria));
}
.cartao-transparencia-icone .icone-secao {
  width: 22px;
  height: 22px;
}
.grade-transparencia-principal .cartao-transparencia h2 {
  font-size: var(--texto-titulo);
}
.grade-transparencia-principal .cartao-numero {
  margin-top: auto;
}

.grade-transparencia-titulo {
  margin: var(--espaco-6) 0 var(--espaco-3);
  font-size: var(--texto-titulo);
}
/* As outras consultas: ícone menor ao lado do título, texto em letra menor. */
.grade-transparencia-outras .cartao-transparencia {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  column-gap: var(--espaco-3);
  row-gap: var(--espaco-2);
  align-items: start;
  align-content: start;
  padding: var(--espaco-4);
}
/* O ícone e o título na mesma linha; o texto e o número ocupam a largura
   toda embaixo, para não espremer a descrição numa coluna estreita. */
.grade-transparencia-outras .cartao-transparencia > :not(.cartao-transparencia-icone) {
  grid-column: 1 / -1;
  margin: 0;
}
.grade-transparencia-outras .cartao-transparencia > :is(h2, h3):not(.cartao-transparencia-icone) {
  grid-column: 2;
  grid-row: 1;
  align-self: center;
}
.grade-transparencia-outras .cartao-transparencia-icone {
  grid-row: 1;
  grid-column: 1;
  width: 36px;
  height: 36px;
  border-radius: 10px;
}
.grade-transparencia-outras .cartao-transparencia-icone .icone-secao {
  width: 18px;
  height: 18px;
}
.grade-transparencia-outras .cartao-transparencia h3 {
  font-size: 1.05rem;
}
.grade-transparencia-outras .cartao-transparencia p {
  color: var(--cor-texto-suave);
  font-size: var(--texto-pequeno);
  line-height: 1.5;
}

@media (max-width: 64rem) {
  .grade-transparencia-principal {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (max-width: 36rem) {
  .grade-transparencia-principal {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* --- TABELAS LONGAS LEGÍVEIS (KAN-110, 28/09) -----------------------------
 *
 * 1. DINHEIRO À DIREITA, com algarismos de largura igual: a vírgula de todas
 *    as linhas cai na mesma coluna, e dá para comparar e somar de olho. As
 *    células são marcadas na tela com a classe .coluna-dinheiro (no <th> e
 *    em cada <td>).
 * 2. A LINHA EM FOCO SE DESTACA ao passar o mouse ou ao chegar nela pelo
 *    teclado (focus-within: o link da linha recebeu o foco).
 * 3. O CABEÇALHO ACOMPANHA A ROLAGEM. No portal público a tabela mora numa
 *    caixa de altura máxima com rolagem própria, e o cabeçalho gruda no alto
 *    dela. É o único jeito de o cabeçalho grudar sem criar rolagem lateral na
 *    página: a caixa já rola para o lado em tela estreita, e quem rola para
 *    o lado não deixa o sticky enxergar a janela. Tabela curta nem chega a
 *    ter rolagem: a caixa só aparece quando passa da altura. */
.tabela .coluna-dinheiro {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.tabela tbody tr:hover,
.tabela tbody tr:focus-within {
  background: var(--cor-realce-fundo);
}
body:not(.com-menu-lateral) .tabela-rolagem {
  max-height: 75vh;
  overflow: auto;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
}
body:not(.com-menu-lateral) .tabela-rolagem .tabela thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--cor-superficie);
  box-shadow: inset 0 -1px 0 var(--cor-borda-forte);
}

/* A linha de baixo do rodapé enxuto: o mapa do site e o Radar viram links de
   texto, na cor clara do rodapé. */
.rodape-legal a,
.radar-transparencia-linha {
  color: var(--cor-sobre-primaria-suave);
  text-decoration: underline;
}
.rodape-legal a:hover,
.rodape-legal a:focus {
  color: var(--cor-sobre-primaria);
}

/* --- O MENU PRINCIPAL COM AS LISTAS (KAN-110, 28/09) ----------------------
 * Passar o mouse ou chegar pelo teclado num item abre a lista das páginas
 * dele. Só CSS (:hover e :focus-within): funciona sem JavaScript. A lista
 * tem um preenchimento em cima, "ponte" entre o item e a caixa, para o mouse
 * não perder o menu no caminho. */
.menu-lista-raiz {
  display: flex;
  flex-wrap: wrap;
  /* 20, e não os 32 de antes: a setinha de cada item custou largura, e com
     32 o cabeçalho quebrava em duas fileiras (medido: 1116px de 1120). */
  gap: 20px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.menu-item {
  position: relative;
}
.menu-item > a {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.menu-item-seta {
  width: 8px;
  height: 8px;
  opacity: 0.7;
  transition: transform 0.15s ease;
}
.menu-item-com-lista:hover .menu-item-seta,
.menu-item-com-lista:focus-within .menu-item-seta {
  transform: rotate(180deg);
}
.menu-lista {
  position: absolute;
  z-index: 30;
  top: 100%;
  left: -16px;
  display: none;
  padding-top: 14px;
}
.menu-item-com-lista:last-child .menu-lista {
  right: -16px;
  left: auto;
}
.menu-item-com-lista:hover > .menu-lista,
.menu-item-com-lista:focus-within > .menu-lista {
  display: block;
}
.menu-lista ul {
  min-width: 15rem;
  margin: 0;
  padding: var(--espaco-2) 0;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
  background: var(--cor-superficie);
  box-shadow: var(--sombra-flutuante);
  list-style: none;
}
.menu .menu-lista a {
  display: block;
  padding: 8px 16px;
  border: 0;
  color: var(--cor-texto);
  font-size: var(--texto-pequeno);
  font-weight: 500;
  text-transform: none;
  white-space: nowrap;
}
.menu .menu-lista a:hover,
.menu .menu-lista a:focus {
  background: var(--cor-realce-fundo);
  color: var(--cor-link);
}
@media (prefers-reduced-motion: reduce) {
  .menu-item-seta {
    transition: none;
  }
}

/* --- OS GRÁFICOS DOS RELATÓRIOS (KAN-112) --------------------------------
 * Um <figure> por gráfico, lado a lado quando cabem dois, logo acima da
 * tabela do relatório. A segunda parte das barras empilhadas é listrada (o
 * <pattern> do SVG usa .barra-listra-fundo como fundo da listra): quem não
 * distingue os tons separa as partes pela textura. */
.graficos-do-relatorio {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(22rem, 100%), 1fr));
  gap: var(--espaco-5);
  margin: var(--espaco-4) 0 var(--espaco-5);
}
.grafico-relatorio {
  margin: 0;
  padding: var(--espaco-4);
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
  background: var(--cor-superficie);
}
.grafico-relatorio figcaption {
  margin: 0 0 var(--espaco-3);
  font-weight: 700;
  font-size: var(--texto-pequeno);
}
.grafico-relatorio-linha {
  grid-column: 1 / -1;
}
/* O texto do eixo mora dentro do SVG e cresce junto com ele: limitada a
   largura, a letra fica no tamanho da página. */
.grafico-relatorio-linha .grafico {
  display: block;
  max-width: 40rem;
}
.grafico-relatorio-vazio {
  margin: 0;
  color: var(--cor-texto-suave);
  font-size: var(--texto-pequeno);
}
.barra-listra-fundo {
  fill: var(--cor-superficie);
}
.barra-valor-segundo {
  color: var(--cor-texto-suave);
  font-weight: 400;
}
.barra-legenda {
  display: flex;
  flex-wrap: wrap;
  gap: var(--espaco-4);
  margin: 0 0 var(--espaco-2);
  color: var(--cor-texto-suave);
  font-size: var(--texto-pequeno);
}
.barra-legenda-item {
  display: inline-flex;
  align-items: center;
  gap: var(--espaco-2);
}

/*
 * SABER: O BRASAO COMO IMAGEM (F-05).
 *
 * No Portal o circulo do brasao so mostrava a sigla da UF. No Saber o
 * municipio sobe a imagem na tela Municipio, e ela ocupa o mesmo circulo,
 * inteira e sem deformar (contain), sobre fundo branco — brasao costuma ter
 * contorno escuro e some num fundo colorido.
 */
.brasao-com-imagem,
.menu-brasao-com-imagem {
  background: #fff;
  overflow: hidden;
  padding: 2px;
}

.brasao-com-imagem img,
.menu-brasao-com-imagem img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

.municipio-brasao-atual {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin: 0.5rem 0 1rem;
}

.municipio-brasao-atual img {
  width: 72px;
  height: 72px;
  object-fit: contain;
  background: #fff;
  border: 1px solid var(--cor-borda);
  border-radius: 8px;
  padding: 4px;
}

/*
 * SABER: A ESCOLHA DAS CORES NA TELA MUNICIPIO.
 *
 * Nomes com "municipio-" na frente de proposito: o style.css herdado ja tem
 * .paletas e .paleta-amostra, da tela Aparencia do Portal. Reaproveitar o
 * nome misturaria as duas regras.
 */
.municipio-paletas {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr));
  gap: 0.75rem;
  border: 0;
  padding: 0;
  margin: 0 0 1rem;
}

.municipio-paletas legend {
  font-weight: 600;
  margin-bottom: 0.5rem;
}

.municipio-paleta {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  border: 1px solid var(--cor-borda);
  border-radius: 8px;
  padding: 0.6rem 0.75rem;
  cursor: pointer;
  background: var(--cor-superficie);
}

.municipio-paleta:has(input:checked) {
  border-color: var(--cor-primaria);
  box-shadow: 0 0 0 2px var(--cor-primaria);
}

.municipio-paleta svg {
  flex: 0 0 auto;
}

/*
 * SABER: CELULA QUE NAO QUEBRA (QA de 02/10). O CPF "000.000.101-54" e a data
 * "02/10/2026, 09:51" quebravam no hifen e na virgula, e a tabela mostrava
 * meio CPF em cada linha. Numero de documento e data se leem inteiros.
 */
.tabela td.sem-quebra {
  white-space: nowrap;
}
