/* Intranet COPPEAD — direção visual (2026-07-17, revisão 2)

   Conceito: a sidebar de setores como o quadro de sinalização de um saguão
   institucional — divisórias finas (hairline), rótulos em versalete
   espaçado, contadores em monoespaçada como numeração de sala. O restante
   da interface é editorial/acadêmico: serifada nos títulos (letterhead),
   sans neutra no corpo e nos controles. */

:root {
    /* Cor (2026-08-26, pedido do Felipe: tokens atualizados pro Design
       System oficial da marca COPPEAD, "COPPEAD UFRJ - Design System.pdf" --
       supersede a extração ad-hoc do CSS ao vivo do site institucional
       (2026-08-19/21, ver histórico do vault). Só valores trocados, mesmos
       nomes de variável -- nenhum uso em nenhum arquivo precisou mudar.
       Contraste verificado (fórmula de luminância relativa, mesma usada
       nas rodadas anteriores): --navy-600 novo 11.1:1 contra branco,
       --navy-600-hover 7.4:1, --urgente 5.5:1, --sucesso 5.3:1, todos AA
       (e a maioria AAA) pra texto normal. --navy-tenue/claro/tenue-forte
       (texto sobre o gradiente) seguem passando (6.2:1 contra o ponto mais
       claro do gradiente novo, que ficou mais escuro que o antigo) --
       não precisaram mudar. Escopo desta rodada é só cor -- tipografia
       (Design System pede NeueHaasGroteskDisp W02; Felipe confirmou que a
       fonte real usada pela marca é Inter) e componentes ficam pra
       decisão futura, não mexidos aqui. */
    --tinta: #1B1731; /* Preto Texto */
    --tinta-suave: #4A4A6A; /* Cinza Secundário */
    --linha: #DDD9F0; /* Cinza Borda */
    --linha-forte: #8C8CAA; /* Cinza Texto, usado como borda mais forte */
    --papel: #F0EDFB; /* Cinza Claro */
    --superficie: #ffffff; /* Branco -- já batia */
    --navy-950: #1B1731; /* Preto Texto -- mesmo tom do --tinta, papel estrutural */
    --navy-800: #3B2A8A; /* sem 4º tom oficial -- reusa Roxo Profundo */
    --navy-600: #3B2A8A; /* Roxo Profundo -- cor de marca primária */
    --navy-600-hover: #6B3FA0; /* Violeta -- 2ª cor de marca, ponto claro do gradiente */
    --navy-100: #F0EDFB; /* Cinza Claro */
    /* --terracota* (nível "importante") DECIDIDO por Felipe em
       2026-08-26, pergunta direta respondida em chat: "Deve ser usado
       exatamete o que é especificado no documento" -- Design System só
       define Sucesso/Erro, então usa Violeta (--navy-600-hover), sem tom
       novo inventado. NÃO É resolução unilateral de sessão anterior --
       é instrução explícita do Felipe. Não reverter sem nova instrução
       dele. Mesma escolha aplicada no app mobile. */
    --terracota: #6B3FA0;
    --terracota-100: #F0EDFB;
    --terracota-texto: #3B2A8A;
    --urgente: #C0392B; /* Vermelho Erro */
    --urgente-100: #fbe0dc; /* tinta clara derivada do Vermelho Erro */
    /* 2026-08-27: --urgente-escuro passa a ser OBRIGATORIO como cor de
       TEXTO sempre que o fundo for --urgente-100. Medido (luminancia
       relativa WCAG): --urgente #C0392B sobre --urgente-100 #fbe0dc =
       4.35:1 -- reprova o minimo AA de 4.5:1 pra texto normal (e todos os
       usos sao texto pequeno: selo, badge, pill, faixa de erro).
       --urgente-escuro #9a2e22 sobre #fbe0dc = 6.03:1 (AA folgado, quase
       AAA). A auditoria sugeriu #a8291c (5.60:1); mantido o token que ja
       existia, que e melhor -- menos um tom vermelho no sistema.
       --urgente continua valido sobre branco (5.44:1) e como cor de
       PREENCHIMENTO (borda, faixa, fundo de botao). */
    --urgente-escuro: #9a2e22; /* tinta escura derivada do Vermelho Erro */
    --sucesso: #1D7A5F; /* Verde Sucesso */
    /* 2026-08-28 (auditoria): aqui havia --lido: #FF6656, enviado pela
       Comunicacao para o estado "lido" do card de aviso -- e usado em ZERO
       regras deste arquivo. O estado nunca foi implementado com ele: quem
       comunica "lido" hoje e' .aviso-card.lido (titulo/texto em tom apagado),
       que funciona e passa contraste. Token removido em vez de mantido como
       promessa nao cumprida. Se a Comunicacao quiser mesmo a faixa #FF6656,
       ela precisa antes de uma decisao de contraste: 2,88:1 sobre o card
       branco reprova o minimo de 3:1 de WCAG 1.4.11 para indicador nao
       textual. Nao reintroduzir sem essa decisao. */

    /* Gradiente institucional (2026-09-01, pedido da Comunicação: trocar o
       roxo do Design System pelas duas cores da marca que eles enviaram,
       #5D4988 → #8F5A9F). Era "#3B2A8A → #6B3FA0".

       Hex literal em vez de var() DE PROPÓSITO: --navy-600/--navy-600-hover
       continuam sendo cor de TEXTO e de borda sobre fundo branco em dezenas
       de regras deste arquivo (11,1:1 e 7,4:1 verificados) -- repintar os
       tokens arrastaria a interface inteira junto, quando o pedido é só
       sobre o gradiente. Estas duas cores pintam SÓ superfície. */
    --gradiente-marca: linear-gradient(135deg, #5D4988 0%, #8F5A9F 100%);
    /* 2026-09-04, pedido do Felipe: painel de métricas do setor volta a ser
       gradiente (revoga a decisão editorial de 21/07 -- ver DESIGN.md).
       Mesmas 3 cores já oficiais (--navy-600 + os dois extremos do
       gradiente institucional acima), só um terceiro stop pra dar
       profundidade; nenhum tom novo. */
    --gradiente-painel-setor: linear-gradient(135deg, #3B2A8A 0%, #5D4988 50%, #8F5A9F 100%);

    /* Texto sobre o gradiente. 2026-09-01: recalculado para as cores novas.
       O ponto CLARO agora é #8F5A9F (luminância 0,157 contra 0,092 do
       #6B3FA0 antigo), então o fundo ficou mais claro e o texto precisou
       acompanhar: #f7f2fb caía para 4,25:1, abaixo do mínimo AA de 4,5:1.
       #faf7fd dá 4,79:1.

       ⚠️ TETO INERENTE À COR DA MARCA: sobre #8F5A9F nem BRANCO PURO passa
       de 5,08:1. Não existe escolha de texto que alcance AAA (7:1) aqui --
       é consequência de #8F5A9F ser claro, não de má escolha de token. Se
       um dia AAA for exigido, o que muda é o gradiente, não este valor.

       --navy-tenue NÃO subiu junto: apesar do nome, ele hoje é sobretudo
       cor de FUNDO em superfície branca (5 regras: .post-card-link:hover,
       .avatares-cluster:hover, etc.), e clareá-lo apagaria esses estados.
       Os 2 usos dele como texto sobre o gradiente (.sidebar-vazio e
       .login-rodape) foram trocados para --navy-claro. */
    --navy-tenue: #f0e8f5;
    --navy-claro: #faf7fd;
    --navy-tenue-forte: #faf7fd;

    /* Tipografia
       2026-08-27 (CORREÇÃO DE COMENTÁRIO FALSO): o texto que ficava aqui
       dizia que "static/fonts/ está vazio de propósito" e que os arquivos
       licenciados "ainda não chegaram". ISSO É FALSO desde que os arquivos
       foram enviados: os 5 .woff2 (Light/Regular/Medium/Bold/Black) ESTÃO
       em static/fonts/ e coletados em staticfiles/fonts/ -- verificado no
       disco do servidor em 2026-08-27. O comentário errado já induziu uma
       auditoria a concluir que a fonte da marca era impossível de usar.
       Não reintroduzir.
       Consequência: --grotesk deixa de ser um token de nicho (usado em ~8
       seletores) e vira a FAMÍLIA PRINCIPAL da interface -- body + todos os
       títulos -- que é o que o Design System oficial manda
       (NeueHaasGroteskDisp W02). --serifada (Georgia) e --sans (system-ui)
       foram REMOVIDOS: com a promoção, ficaram órfãos. Não recriar sem
       decisão de design explícita. */
    --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
    --grotesk: "NeueHaasGroteskDisp", "Helvetica Neue", Helvetica, Arial, sans-serif;

    /* Forma (2026-08-28, auditoria: o arquivo tinha 12 valores distintos de
       border-radius -- 4, 6, 7, 8, 10, 16px, 50%, 999px -- contra 2 tokens.
       Cada tela lia como montada numa sessao diferente, porque foi. Escala
       unica, toda em multiplos de 4px como manda a escala de espacamento do
       Design System oficial ("4 8 12 16 24 32 48 64 80 96 128 160"). NENHUMA
       COR MUDOU nesta rodada -- so' forma e elevacao (instrucao explicita do
       Felipe: "a cor nao quero que altere, a identidade visual da marca deve
       ser mantida"). */
    --radius-sm: 4px;   /* chips, selos, inputs pequenos (era 4px e 6px) */
    --radius: 8px;      /* cards, botoes, paineis (era 6, 7, 8 e 10px) */
    --radius-lg: 16px;  /* dialogos e cards de aviso com capa */
    --radius-pill: 999px;
    --radius-circulo: 50%;

    /* Elevacao (2026-08-28, auditoria: 37 box-shadow no arquivo contra 1
       token -- ~36 sombras ad-hoc. Mesma logica da forma: 4 degraus nomeados,
       nenhum valor novo inventado, sao exatamente as sombras que ja' estavam
       em uso, agora com nome. --sombra mantem o nome antigo de proposito:
       19 usos que nao precisam mudar. */
    --sombra: 0 1px 2px rgba(27, 23, 49, 0.05), 0 8px 24px rgba(27, 23, 49, 0.045);
    --sombra-hover: 0 4px 10px rgba(27, 23, 49, 0.09), 0 12px 28px rgba(27, 23, 49, 0.08);
    --sombra-alta: 0 14px 28px rgba(27, 23, 49, 0.14), var(--sombra);
    /* 2026-08-31 (auditoria): rgba(2,12,27) e' o quase-preto AZULADO do navy
   antigo, nao o --tinta (#1B1731 = 27,23,49) da marca. Rebaseado; a
   diferenca e' de matiz na sombra, nao de intensidade. */
    --sombra-modal: 0 12px 40px rgba(27, 23, 49, 0.45), 0 2px 8px rgba(27, 23, 49, 0.3);
    --foco-anel: 0 0 0 3px rgba(59, 42, 138, 0.55);

    /* Botoes (2026-08-28, rodada "botoes", referencia: Geist/Vercel e Linear).
       Sub-familia propria de elevacao -- nao cabe em --sombra/--sombra-hover,
       que sao de card. O que faz um botao ler como peca solida e iluminada em
       vez de retangulo chapado e' o realce INTERNO de 1px no topo, e card
       nenhum tem isso. Sombra tingida com o proprio --navy-600 (59,42,138) em
       vez de cinza neutro: mesma tecnica que --foco-anel ja usa. Nenhum tom
       fora da paleta oficial -- so branco, --tinta, --navy-600 e --urgente
       em alpha. */
    --sombra-botao: 0 1px 2px rgba(27, 23, 49, 0.16), inset 0 1px 0 rgba(255, 255, 255, 0.14);
    --sombra-botao-hover: 0 2px 4px rgba(27, 23, 49, 0.14), 0 6px 16px rgba(59, 42, 138, 0.24), inset 0 1px 0 rgba(255, 255, 255, 0.18);
    --sombra-botao-perigo-hover: 0 2px 4px rgba(27, 23, 49, 0.14), 0 6px 16px rgba(192, 57, 43, 0.28), inset 0 1px 0 rgba(255, 255, 255, 0.18);
    --sombra-botao-leve: 0 1px 2px rgba(27, 23, 49, 0.07);

    /* Anel de foco para superficie ESCURA. O --foco-anel e' roxo a 55%; sobre
       o preenchimento roxo do botao primario ele simplesmente nao aparece
       (mesma familia de defeito dos acentos sobre o gradiente, achado na
       auditoria de hoje). Ring branco interno separa o halo do preenchimento. */
    --foco-anel-solido: inset 0 0 0 2px var(--superficie), 0 0 0 3px rgba(59, 42, 138, 0.55);

    /* Alturas do Design System oficial do COPPEAD: Small 32 / Default 40 /
       Large 48. O portal usava 2.65rem = 42.4px, que nao e' nenhuma das tres
       e nao cai na grade de 4px. */
    --altura-botao: 40px;
    --altura-botao-sm: 32px;
    --altura-botao-lg: 48px;

    /* Curva de saida (ease-out-quint). Token proprio em vez de reusar
       --transicao porque --transicao JA CARREGA a palavra `ease` dentro:
       `box-shadow var(--transicao) var(--ease)` expandiria para
       "140ms ease cubic-bezier(...)", declaracao invalida, e a transicao
       inteira seria descartada em silencio. */
    --transicao-botao: 160ms cubic-bezier(0.22, 1, 0.36, 1);

    /* Espacamento (2026-08-31, auditoria: o arquivo tinha 35 valores rem
       distintos em padding/margin/gap e ZERO tokens -- 60% deles fora da
       escala oficial do Design System ("4 8 12 16 24 32 48 64 80 96 128
       160"). O mais usado de todos, 1.25rem = 20px em 51 lugares, nao existe
       na escala. Nome = multiplo de 4, entao a lacuna do 5 (=20px) fica
       visivel: se um dia alguem procurar --e-5, o proprio nome diz que o DS
       nao define esse degrau.
       Empates de arredondamento (20px, 40px) sobem, decisao do Felipe: o app
       ja estava apertado (densidade 7/10 na auditoria) e o gutter do DS e'
       24px. */
    --e-1: 4px;
    --e-2: 8px;
    --e-3: 12px;
    --e-4: 16px;
    --e-6: 24px;
    --e-8: 32px;
    --e-12: 48px;
    --e-16: 64px;
    --e-20: 80px;
    --e-24: 96px;
    --e-32: 128px;
    --e-40: 160px;

    /* Tipografia -- os 11 niveis do Design System oficial (2026-08-31,
       auditoria: 125 declaracoes de font-size, 33 valores distintos, de 9,6 a
       30,4px, e ZERO tokens; 14,0 / 14,1 / 14,2 / 14,4 / 14,7px conviviam sem
       diferenca visivel). Felipe escolheu os 11 niveis exatos, sem inventar
       degrau: o de 14px foi oferecido e recusado. Consequencia aceita: meta,
       caption e rotulo de controle que estavam entre 12,5 e 14,4px caem para
       Caption 13px. Os pesos que o DS casa com cada nivel estao no comentario
       de cada linha -- font-size e' token, peso continua explicito na regra. */
    /* Display 80/900, H1 56/700 e H2 40/700 existem no DS e NAO estao aqui:
       nenhuma superficie da intranet tem texto desse tamanho (sao do site
       institucional). Mesma politica que removeu --lido em 28/08 -- token sem
       uso e' promessa, nao sistema. Se aparecer a superficie, reintroduzir
       pelo NIVEL do DS, nunca inventando o tamanho. */
    --t-h3: 32px;         /* 500 */
    --t-h4: 24px;         /* 500 */
    --t-h5: 20px;         /* 400 */
    --t-body-lg: 18px;    /* 300 */
    --t-body: 16px;       /* 300 */
    --t-caption: 13px;    /* 400 */
    --t-label: 11px;      /* 500 */
    --t-overline: 10px;   /* 400 */

    --transicao: 140ms ease;
}

@media (prefers-reduced-motion: reduce) {
    :root { --transicao: 0ms; --transicao-botao: 0ms; }
}

/* NeueHaasGroteskDisp (2026-08-26, pedido da Comunicação): fonte
   comercial licenciada. 5 pesos pra cobrir a escala do Design System
   (Display/Black 900, H1-H2/Bold 700, H3-H4/Medium 500,
   H5/Caption/Overline/Regular 400, BodyLarge/Body/Light 300).
   2026-08-27: os 5 arquivos JÁ ESTÃO no disco (static/fonts/ e
   staticfiles/fonts/) -- estes @font-face carregam de verdade, não são
   mais 404 silencioso. Só existem estes 5 pesos: qualquer
   `font-weight: 600` no arquivo seria SINTETIZADO pelo navegador
   (falso-negrito, espaçamento errado). Por isso, na mesma data, todo 600
   foi migrado pra 500 (Medium) ou 700 (Bold). Não reintroduzir 600 sem
   antes adicionar um @font-face SemiBold aqui. */
@font-face {
    font-family: "NeueHaasGroteskDisp";
    src: url("/static/fonts/NeueHaasGroteskDisp-Light.6fe202f17588.woff2") format("woff2");
    font-weight: 300;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: "NeueHaasGroteskDisp";
    src: url("/static/fonts/NeueHaasGroteskDisp-Regular.be0bbad58d0e.woff2") format("woff2");
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: "NeueHaasGroteskDisp";
    src: url("/static/fonts/NeueHaasGroteskDisp-Medium.8f96a0df06ca.woff2") format("woff2");
    font-weight: 500;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: "NeueHaasGroteskDisp";
    src: url("/static/fonts/NeueHaasGroteskDisp-Bold.b3358c1ce70c.woff2") format("woff2");
    font-weight: 700;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: "NeueHaasGroteskDisp";
    src: url("/static/fonts/NeueHaasGroteskDisp-Black.9ecb8fb29cee.woff2") format("woff2");
    font-weight: 900;
    font-style: normal;
    font-display: swap;
}

* { box-sizing: border-box; }

/* 2026-08-27: não havia NENHUMA regra global de imagem no arquivo. Toda
   imagem enviada pelo usuário (capa de banner, foto de perfil, anexo de
   post -- upload de até 5MB) renderizava em tamanho natural e estourava o
   container, sendo cortada pelo overflow:hidden do card ou empurrando a
   página na horizontal. Reset padrão, uma linha, resolve na raiz em vez
   de um max-width por componente. Componentes que precisam de dimensão
   fixa (.brand-logo, .avatar-leitura) usam classe -- especificidade maior,
   continuam ganhando. */
img { max-width: 100%; height: auto; }

body {
    margin: 0;
    font-family: var(--grotesk);
    color: var(--tinta);
    background: var(--papel);
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
    /* 2026-08-29 (auditoria visual): .layout ficava fora do fluxo de altura
       do body -- .sidebar pedia 100vh inteiros mesmo abaixo do .site-header,
       entao a pagina sempre passava de uma tela pela altura do header,
       forcando um scrollbar nativo residual ao lado do scrollbar proprio da
       sidebar/feed. Corpo em coluna flex faz .layout ocupar so' o espaco que
       sobra do header. */
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

a { color: var(--navy-600); text-decoration: none; }
a:hover { text-decoration: underline; }

:focus-visible {
    outline: 2px solid var(--navy-600);
    outline-offset: 2px;
}

/* ===== Cabeçalho institucional ===== */
.site-header {
    background: var(--gradiente-marca);
    color: var(--superficie);
    padding: var(--e-4) var(--e-8);
    display: flex;
    align-items: center;
    justify-content: space-between;
    /* 2026-08-28 (auditoria): era var(--terracota), que apos o remap de
       26/08 vale #6B3FA0 -- exatamente o tom final do --gradiente-marca.
       A regua ficava com contraste 1,00:1 contra o proprio cabecalho na
       ponta direita: invisivel. --linha (#DDD9F0, Cinza Borda do Design
       System oficial) e' visivel sobre os dois extremos do gradiente e
       ainda separa do --papel da pagina. Nenhum tom novo. */
    border-bottom: 3px solid var(--linha);
}

.site-header .brand-linha {
    display: flex;
    align-items: center;
    gap: var(--e-3);
}

.site-header .brand a {
    font-family: var(--grotesk);
    font-size: var(--t-h5);
    font-weight: 700;
    letter-spacing: 0.01em;
    color: var(--superficie);
    text-decoration: none;
    transition: opacity var(--transicao);
}
.site-header .brand a:hover { opacity: 0.85; text-decoration: none; }
.site-header .brand a span { color: var(--navy-claro); }

/* Logo real da marca (2026-08-26, pedido do Felipe: substitui o
   lockup em texto "Intranet COPPEAD" pela logo oficial que a
   Comunicação mandou -- variante clara, pra cima do gradiente do
   cabeçalho). Altura fixa que cabe na faixa do cabeçalho sem esticar o
   header (padding do .site-header não mudou); largura segue a
   proporção real do arquivo (415×126). */
.brand-logo-link { display: inline-flex; align-items: center; }
.brand-logo { display: block; height: 2.2rem; width: auto; }

/* .botao-home REMOVIDO em 2026-09-01 a pedido da Comunicação ("remover o
   ícone de casa, deixar no lugar apenas o logo do COPPEAD"). Existia desde
   2026-07-20 porque o Felipe reportou que ninguém achava como voltar ao
   início -- o pedido de agora reverte aquele.

   Nenhuma rota foi perdida: a própria logo é <a href="/"> com
   aria-label="Intranet COPPEAD — página inicial" (base.html), então o
   caminho para a home continua existindo, clicável e anunciado por leitor
   de tela. O que sumiu foi o segundo link para o MESMO destino.

   Se a queixa de 07/20 voltar, a resposta NÃO é ressuscitar o ícone (a
   Comunicação decidiu contra) -- é tornar a logo mais evidentemente
   clicável. */

.site-header .brand small {
    display: block;
    font-family: var(--mono);
    font-size: var(--t-label);
    font-weight: 400;
    letter-spacing: 0.06em;
    color: var(--navy-tenue);
    margin-top: var(--e-1);
}

.site-header nav {
    display: flex;
    align-items: center;
    gap: var(--e-4);
}

/* Maiúsculo padronizado no menu superior (2026-07-20, pedido do Felipe:
   reforçar leitura de conformidade institucional) — mesmo tratamento do
   nome de setor na sidebar. Sublinhado animado + foco de alto contraste
   adicionados em 2026-08-13 (Felipe achou o menu "simples demais"; o
   :focus-visible global usa --navy-600, que quase não aparece sobre o
   navy-950 do cabeçalho — folha de estilo escura precisa do próprio
   contraste de foco). Mesmo tratamento estendido ao botão "Sair", que é
   um <button> disfarçado, não um <a>, então fica fora do seletor "nav a". */
.site-header nav a,
.logout-form .link-button {
    position: relative;
    padding-bottom: var(--e-1);
    color: var(--navy-claro);
    font-size: var(--t-caption);
    text-transform: uppercase;
    letter-spacing: 0.02em;
    transition: color var(--transicao);
}
.site-header nav a::after,
.logout-form .link-button::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 2px;
    /* 2026-08-28 (auditoria): era var(--terracota) = #6B3FA0, o mesmo tom
       do fim do gradiente -- e o menu fica justamente a DIREITA, na parte
       violeta. O sublinhado existia e nunca apareceu (1,00:1). Branco da
       7,38:1 no ponto mais claro do gradiente e 11,15:1 no mais escuro,
       e casa com a cor que o texto ja assume no hover. */
    background: var(--superficie);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform var(--transicao);
}
.site-header nav a:hover,
.site-header nav a:focus-visible,
.logout-form .link-button:hover,
.logout-form .link-button:focus-visible {
    color: var(--superficie);
}
.site-header nav a:hover::after,
.site-header nav a:focus-visible::after,
.logout-form .link-button:hover::after,
.logout-form .link-button:focus-visible::after {
    transform: scaleX(1);
}
.site-header nav a:focus-visible,
.logout-form .link-button:focus-visible {
    outline: 2px solid var(--superficie);
    outline-offset: 3px;
}

.usuario-atual { color: var(--navy-claro); font-size: var(--t-caption); text-transform: uppercase; letter-spacing: 0.02em; }

/* ===== Layout com sidebar de setores =====
   A sidebar é um painel navy sólido, colado ao cabeçalho (mesma cor) — as
   duas peças formam um "L" de chrome institucional inconfundível, contra o
   conteúdo claro. Sem isso (fundo branco solto, borda fina) a sidebar lia
   como um bloco de texto qualquer, não como menu (2026-07-17, feedback
   direto do Felipe: "o fundo branco está dando impressão de texto"). */
/* Sem max-width/centralização aqui de propósito: a sidebar precisa
   encostar na borda real da janela (2026-07-17, Felipe: a faixa branca à
   esquerda dela quebrava a leitura de "isto é um menu"). Quem centraliza
   é o .container, dentro do espaço que sobra. */
.layout {
    display: flex;
    align-items: stretch;
    width: 100%;
    flex: 1;
    min-height: 0;
}

.sidebar {
    width: 248px;
    flex-shrink: 0;
    background: var(--gradiente-marca);
    padding: var(--e-8) var(--e-4);
    position: sticky;
    top: 0;
    align-self: stretch;
    max-height: 100vh;
    overflow-y: auto;
    /* 2026-08-31 (auditoria): rgba(77,66,141,.1) nao e' nenhum tom oficial.
   --navy-600 (#3B2A8A = 59,42,138) na mesma opacidade -- a mesma tecnica
   que --foco-anel ja usa. */
    box-shadow: 2px 0 0 rgba(59, 42, 138, 0.1);
}

.sidebar-titulo {
    font-family: var(--mono);
    font-size: var(--t-label);
    font-weight: 500;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--navy-tenue-forte);
    margin: var(--e-1) var(--e-2) var(--e-4);
}
/* .sidebar-titulo e' reaproveitada em 2 fundos bem diferentes: a sidebar
   escura (".sidebar", onde --navy-tenue-forte foi calibrada essa sessao
   pro gradiente da marca) e o painel claro ".contexto" ("Meu espaco",
   home.html) -- o mesmo tom quase-branco fica ilegivel sobre fundo claro
   (2026-08-21, achado do Felipe). --tinta-suave ja passa AA sobre --papel. */
.contexto .sidebar-titulo {
    color: var(--tinta-suave);
}

.sidebar-nav {
    display: flex;
    flex-direction: column;
    gap: var(--e-1);
}

.sidebar-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--e-2);
    padding: var(--e-2) var(--e-3);
    border-radius: var(--radius);
    color: var(--navy-claro);
    font-size: var(--t-caption);
    font-weight: 500;
    transition: background var(--transicao), color var(--transicao);
}

.sidebar-item:hover,
.sidebar-item:focus-visible {
    background: rgba(255, 255, 255, 0.09);
    color: var(--superficie);
    text-decoration: none;
}

.sidebar-item.ativo {
    background: var(--superficie);
    color: var(--navy-950);
    font-weight: 700;
}
.sidebar-item.ativo .sidebar-badge { background: var(--terracota); color: var(--superficie); }

.sidebar-item-nome {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    /* Maiúsculo padronizado com os demais rótulos institucionais da
       sidebar/cabeçalho (2026-07-20, pedido do Felipe: reforçar leitura de
       conformidade). Tracking mais folgado que .sidebar-titulo pois aqui é
       nome de setor, não legenda mono. */
    text-transform: uppercase;
    letter-spacing: 0.02em;
}

/* 2026-08-28 (auditoria): fundo era var(--terracota) = #6B3FA0 sobre a
   sidebar, que E' o gradiente terminando em #6B3FA0 -- pilula invisivel
   (1,00:1), reprovando WCAG 1.4.11. Invertido: pilula branca com numero
   em Roxo Profundo. Mesma dupla de cores ja usada por .sidebar-item.ativo
   logo acima -- nenhum tom novo, e agora o contador finalmente aparece. */
.sidebar-badge {
    font-family: var(--mono);
    background: var(--superficie);
    color: var(--navy-600);
    font-size: var(--t-label);
    font-weight: 700;
    line-height: 1;
    padding: var(--e-1) var(--e-2);
    border-radius: var(--radius-pill);
    min-width: 1.4rem;
    text-align: center;
    flex-shrink: 0;
}

.sidebar-vazio {
    font-size: var(--t-caption);
    /* 2026-09-01: era --navy-tenue, que sobre o gradiente novo dá 4,25:1
       (reprova AA). Este texto cai no PÉ da sidebar, que é justamente o
       ponto claro do gradiente de 135deg. */
    color: var(--navy-claro);
    padding: 0 var(--e-2);
}

/* ===== Sidebar recolhível (2026-08-28, pedido do Felipe) =====
   A escolha é por pessoa e por navegador (localStorage), não por conta: é
   preferência de tela, não dado do sistema -- não merece ida ao servidor a
   cada clique nem uma coluna no banco. */
.sidebar-topo {
    display: flex;
    align-items: center;
    gap: var(--e-2);
    margin-bottom: var(--e-4);
}
/* O título já trazia a margem inferior que agora é do .sidebar-topo; deixá-la
   aqui somaria duas margens e desalinharia o botão em relação ao texto. */
.sidebar-topo .sidebar-titulo { margin: 0 0 0 var(--e-2); }
/* 02/09: "Setores" virou link pro indice /setores/ (achado UX navegacao --
   ninguem alcancava a busca por descricao sem digitar a URL). min-height
   e' alvo de toque (WCAG 2.5.8) sem crescer a linha; outline em
   --superficie copia .sidebar-recolher:focus-visible ao lado, porque o
   :focus-visible global pinta --navy-600, o inicio do proprio gradiente
   -- anel invisivel aqui. html.sidebar-recolhida some com o link junto
   com a lista (main.css ~626), sem ficar focavel fora da tela. */
a.sidebar-titulo { display: inline-flex; align-items: center; min-height: 1.5rem; }
a.sidebar-titulo:hover, a.sidebar-titulo:focus-visible { color: var(--superficie); }
a.sidebar-titulo:focus-visible { outline: 2px solid var(--superficie); outline-offset: 2px; }

.sidebar-recolher {
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    /* 2.25rem = alvo de toque mínimo de 24px com folga (WCAG 2.5.8). O
       `min-height: 0` é obrigatório: a regra base de `button` impõe um
       min-height que transformaria este quadrado num retângulo -- a mesma
       causa raiz já documentada em .btn-icone. */
    width: 2.25rem;
    height: 2.25rem;
    min-height: 0;
    padding: 0;
    background: transparent;
    border: 1px solid rgba(255, 255, 255, 0.22);
    border-radius: var(--radius);
    color: var(--navy-claro);
    cursor: pointer;
    box-shadow: none;
    transition: background var(--transicao), color var(--transicao);
}
.sidebar-recolher svg { width: 1.05rem; height: 1.05rem; }
.sidebar-recolher:hover, .sidebar-recolher:focus-visible {
    background: rgba(255, 255, 255, 0.12);
    color: var(--superficie);
    transform: none;
    box-shadow: none;
}
.sidebar-recolher:focus-visible { outline: 2px solid var(--superficie); outline-offset: 2px; }

@media (min-width: 901px) {
    html.sidebar-recolhida .sidebar {
        width: 3.35rem;
        padding-left: var(--e-2);
        padding-right: var(--e-2);
    }
    /* `display: none`, não opacidade nem largura zero: link invisível que
       continua focável é armadilha de teclado -- a pessoa tabula para dentro
       de uma lista que não está na tela e perde o cursor. */
    html.sidebar-recolhida .sidebar-titulo,
    html.sidebar-recolhida .sidebar-nav,
    html.sidebar-recolhida .sidebar-vazio { display: none; }
    html.sidebar-recolhida .sidebar-topo { margin-bottom: 0; }
    html.sidebar-recolhida .sidebar-recolher { margin-left: 0; }
    /* A seta é a mesma; o CSS a espelha. Trocar o SVG no JS seria manter dois
       ícones sincronizados à mão para desenhar exatamente a mesma forma. */
    html.sidebar-recolhida .sidebar-recolher svg { transform: scaleX(-1); }
}

/* Abaixo de 900px a sidebar já vira gaveta pelo #menu-movel-toggle: recolher
   uma gaveta não significa nada, e o botão só ocuparia espaço. */
@media (max-width: 900px) {
    .sidebar-recolher { display: none; }
}



@media (max-width: 900px) {
    .layout { flex-direction: column; }
    .sidebar {
        width: 100%;
        position: static;
        height: auto;
        max-height: none;
        padding: var(--e-4) var(--e-6);
        box-shadow: none;
    }
    .sidebar-titulo { margin: 0 0 var(--e-2) var(--e-1); }
    .sidebar-nav { flex-direction: row; flex-wrap: wrap; gap: var(--e-1); }
    .sidebar-item { flex: 0 1 auto; }
}

/* ===== Rede de seguranca de quebra de texto (2026-08-28) =====
   Palavra longa sem espaco -- nome de arquivo, e-mail, URL -- nao tem onde
   quebrar e escapa de QUALQUER caixa, por melhor dimensionado que o container
   esteja. Era a causa dos titulos vazando dos cards de informativo e da lista
   de alertas.

   2026-08-28, MESMO DIA, CORRECAO (achado do Felipe, com screenshot: nos
   paineis "Favoritos" e "Acessados recentemente" o nome do setor aparecia
   como "T / I", "VD / RI", "Bibliot / eca", "Centro de Pesquis / a").
   A versao original usava `anywhere` de proposito, com esta justificativa:
   "alem de quebrar a palavra, ele REDUZ o min-content do elemento, que e'
   justamente o que impede o item de empurrar a coluna do grid/flex pra fora
   da tela. So' age quando nao existe outro ponto de quebra possivel, entao
   nao muda nada em texto normal."

   O mecanismo estava descrito certo; a ultima frase e' que estava errada.
   `anywhere` reduz o min-content SEMPRE, nao so' quando falta ponto de
   quebra -- e aplicado a TODO span/a do documento, o min-content de
   qualquer texto vira 1 CARACTERE. Em qualquer coluna estreita (a
   .contexto tem 240-280px) o item entao encolhe abaixo da maior palavra e
   o texto desmonta letra a letra em vez de quebrar no espaco.

   `break-word` mantem o objetivo original -- palavra longa sem espaco
   (nome de arquivo, e-mail, URL) continua quebrando em vez de escapar da
   caixa -- e NAO mexe no min-content, entao texto normal volta a se medir
   pela maior palavra. Verificado: "Relatorio_Anual_Consolidado_2026_
   versao_final.pdf" segue quebrando; "Centro de Pesquisa" nao.

   Pra "nao empurrar a coluna do grid/flex pra fora da tela" a ferramenta
   certa e' `min-width: 0` no proprio item, que este arquivo ja usa em
   .container, .aviso-card-corpo, .aviso-card-stats e outros. Medido na home
   real de producao em 1440/1280/1180/1024/900/768/640/430/360/320px:
   zero estouro horizontal com `break-word`, igual ao que dava com
   `anywhere`. :where() mantem especificidade zero -- nao atrapalha nenhuma
   regra existente. */
:where(p, h1, h2, h3, h4, h5, h6, li, dd, dt, td, th, strong, em, small,
       a, span, label, summary, figcaption, blockquote, button) {
    overflow-wrap: break-word;
}

/* Wrapper geral */
.container {
    flex: 1;
    min-width: 0;
    max-width: 1080px;
    /* 2026-09-01 (pedido da Comunicação: "alinhar o título e os cards mais
       à esquerda"). Era `margin: 0 auto`, que num item flex faz as DUAS
       margens automáticas engolirem a sobra em partes iguais: a 1920px
       sobravam 592px e o conteúdo nascia 296px à direita da sidebar --
       um vão morto entre o menu e o texto que crescia com o monitor.
       A 1180px a sobra é zero e o alinhamento já era o pedido: o defeito
       só aparecia em tela larga, que é onde a Comunicação olhou.

       `auto` só à DIREITA: a sobra inteira vai para lá, o conteúdo encosta
       na sidebar e a coluna .contexto continua indo para a borda direita
       (com `margin: 0` ela viria junto e deixaria o buraco do outro lado).
       max-width segue mandando na medida da linha; só a posição mudou. */
    margin: 0 auto 0 0;
    padding: var(--e-8) var(--e-8) var(--e-16);
}

/* Coluna de contexto (Lince: coluna direita de busca/filtros/contexto do
   modulo, 2026-08-19). So a home usa hoje (paineis "Meu espaco", movidos
   pra ca a partir da area central); outras paginas simplesmente nao
   preenchem {% block contexto %} e a coluna some sozinha via :has(),
   mesmo truque nativo ja usado no Alcance do formulario de aviso (sem JS). */
.contexto {
    width: 280px;
    flex-shrink: 0;
    padding: var(--e-8) var(--e-8) var(--e-16) 0;
    display: flex;
    flex-direction: column;
    gap: var(--e-4);
}
.contexto:not(:has(*)) { display: none; }

@media (max-width: 1180px) {
    .contexto { width: 240px; }
}

@media (max-width: 900px) {
    .contexto { width: 100%; padding: 0 var(--e-6) var(--e-8); }
}

/* Blocos da home configuraveis via admin (Lince: home montavel por JSON,
   secoes -> blocos {tipo, tamanho, link, imagem} em grade de 12 colunas,
   liga/desliga sem deploy). Ver core.models.BlocoHome. */
.blocos-home {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    gap: var(--e-4);
}
.bloco-home-item { position: relative; }
.bloco-home-item a, .bloco-home-item .bloco-home-sem-link {
    display: block;
    border-radius: var(--radius);
    overflow: hidden;
    box-shadow: var(--sombra);
    line-height: 0;
}
.blocos-home img { width: 100%; height: auto; display: block; }

/* Classes fixas em vez de style= inline (2026-08-19, corrige bug de CSP: o
   header Content-Security-Policy do projeto e' style-src 'self', sem
   unsafe-inline/nonce -- style="grid-column: span N" era bloqueado pelo
   navegador e nunca aplicava). BlocoHome.colunas so' aceita 3/4/6/12
   (choices fechado), entao 4 classes cobrem todo caso possivel. */
.bloco-home-col-3 { grid-column: span 3; }
.bloco-home-col-4 { grid-column: span 4; }
.bloco-home-col-6 { grid-column: span 6; }
.bloco-home-col-12 { grid-column: span 12; }

@media (max-width: 900px) {
    .bloco-home-col-3, .bloco-home-col-4, .bloco-home-col-6, .bloco-home-col-12 {
        grid-column: span 12;
    }
}

/* 02/09 (achado UX media): resumo de erro dos formularios longos (aviso,
   documento). Faixa no topo em vez de borda lateral -- mesmo idioma de
   .mensagens li e .perfil-aviso-ad, abaixo. --urgente-escuro sobre
   --urgente-100 de proposito: --urgente cheio da 4,35:1, ja reprovado
   em 27/08 (ver .mensagens li.mensagem-error). */
.form-erros {
    background: var(--urgente-100);
    border-top: 3px solid var(--urgente);
    border-radius: var(--radius);
    padding: var(--e-3) var(--e-4);
    margin: 0 0 var(--e-6);
    color: var(--urgente-escuro);
    font-size: var(--t-caption);
}
.form-erros p { margin: 0 0 var(--e-2); font-weight: 500; }
.form-erros ul { list-style: none; margin: 0; padding: 0; }
.form-erros a,
.form-erros .errorlist { color: var(--urgente-escuro); }

/* Mensagens do sistema (Django messages) */
.mensagens { list-style: none; margin: 0 0 var(--e-6); padding: 0; }
.mensagens li {
    background: var(--navy-100);
    /* Barra no topo em vez de lateral (2026-07-20, auditoria: borda lateral
       colorida como único sinal de estado é anti-padrão) — mesmo idioma de
       "faixa de card" já usado em .banner-card/.confirmacao-card. */
    border-top: 3px solid var(--navy-600);
    padding: var(--e-3) var(--e-4);
    border-radius: var(--radius);
    margin-bottom: var(--e-2);
    font-size: var(--t-caption);
}
/* 02/09 (achado UX estados): erro/aviso e sucesso saiam pixel a pixel
   identicos -- a caixa de "aviso expirou, cancelado" (error/warning) lia
   como a mesma confirmacao roxa de sempre. success fica so' com a faixa
   verde (fundo ja e' --navy-100 == --papel na regra-base, DESIGN.md
   registra o alias). error/warning usam --urgente-escuro, nao --urgente
   cheio: sobre --urgente-100 o tom cheio da 4,35:1, ja reprovado em
   27/08. info/debug ficam na regra-base (roxo institucional neutro). */
.mensagens li.mensagem-success { border-top-color: var(--sucesso); }
.mensagens li.mensagem-error,
.mensagens li.mensagem-warning {
    background: var(--urgente-100);
    border-top-color: var(--urgente-escuro);
    color: var(--urgente-escuro);
}

/* ===== HERO — mural de avisos ===== */
.hero { margin-bottom: var(--e-12); }

.hero-cabecalho {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    margin-bottom: var(--e-4);
}

.hero-cabecalho-acoes { display: flex; align-items: baseline; gap: var(--e-4); }
.restaurar-ordem-form { margin: 0; }
.restaurar-ordem-form button {
    background: none;
    border: none;
    padding: 0;
    font-size: var(--t-caption);
    color: var(--navy-600);
    text-decoration: underline;
    cursor: pointer;
    /* Disfarcado de link: nao pode receber a elevacao do botao de verdade. */
    min-height: 0;
    box-shadow: none;
}
/* Precisa repetir background:none aqui, nao so' no seletor base
   (2026-08-21, achado do Felipe: botao virava um bloco roxo ilegivel
   no hover). Empate de especificidade com o "button:hover" generico
   mais abaixo no arquivo -- os dois tem 1 classe/pseudo + 1 tag, quem
   vinha por ultimo no arquivo ganhava o "background", pintando o botao
   inteiro na mesma cor do texto (invisivel). */
.restaurar-ordem-form button:hover,
.restaurar-ordem-form button:focus-visible {
    color: var(--navy-600-hover);
    background: none;
    box-shadow: none;
    transform: none;
}
/* `button:focus-visible` (0,1,1) sobrepoe a regra global `:focus-visible`
   (0,1,0) e zera o outline -- sem esta linha, um botao-fantasma que tambem
   zera a box-shadow ficaria sem NENHUM indicador de foco. */
.restaurar-ordem-form button:focus-visible {
    outline: 2px solid var(--navy-600);
    outline-offset: 2px;
}

/* Cards moveis (2026-08-19, Trilha 2 do redesenho: personalizacao por
   usuario). draggable="true" nos itens + botoes subir/descer -- os dois
   caminhos chamam o mesmo endpoint no fim (POST /preferencias/...). Botao
   sempre visivel e funcional sem JS nenhum (link/form comum); o cursor
   de arrasto e' so affordance visual extra pra quem usa mouse. */
[draggable="true"] { cursor: grab; }
[draggable="true"].arrastando { cursor: grabbing; opacity: 0.5; }

/* Controle de mover, redesenhado (2026-08-19, achado do Felipe: dois
   circulos grandes flutuando sobre o card, um cheio outro contorno, sem
   coesao nenhuma). Vira um unico pill discreto -- as duas metades tem
   exatamente o mesmo peso visual em repouso, so a interacao (hover/foco)
   muda; a divisoria interna substitui gap+circulo por segmentacao real. */
.card-mover {
    display: inline-flex;
    align-items: stretch;
    border: 1px solid var(--linha-forte);
    border-radius: var(--radius-pill);
    background: var(--superficie);
    overflow: hidden;
    line-height: 0;
}
.card-mover form { margin: 0; }
.card-mover form:first-child button { border-right: 1px solid var(--linha-forte); }
.card-mover button {
    width: 28px;
    height: 24px;
    min-height: 0;
    box-shadow: none;
    border: none;
    background: none;
    color: var(--tinta-suave);
    cursor: pointer;
    font-size: var(--t-label);
    line-height: 1;
    transition: background var(--transicao), color var(--transicao);
}
.card-mover button:hover, .card-mover button:focus-visible {
    background: var(--navy-100);
    color: var(--navy-600);
    box-shadow: none;
    transform: none;
}
/* Mesma causa do .restaurar-ordem-form: sem outline explicito, o foco aqui
   seria so' a troca de fundo -- indicador fraco demais pra 2.4.11/2.4.13.
   offset negativo porque o pill tem overflow:hidden e um outline pra fora
   seria recortado. */
.card-mover button:focus-visible {
    outline: 2px solid var(--navy-600);
    outline-offset: -2px;
}

/* Sobre imagem (blocos da home) o pill claro sumiria -- pill escuro
   translucido com blur, mesma forma e comportamento. */
.bloco-home-item .card-mover {
    position: absolute;
    top: 0.5rem;
    right: 0.5rem;
    border-color: transparent;
    background: rgba(27, 23, 49, 0.55);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
}
.bloco-home-item .card-mover form:first-child button { border-right-color: rgba(255, 255, 255, 0.25); }
.bloco-home-item .card-mover button { color: var(--superficie); }
.bloco-home-item .card-mover button:hover, .bloco-home-item .card-mover button:focus-visible {
    background: rgba(255, 255, 255, 0.22);
    color: var(--superficie);
}
.feed-avisos.arrastando-sobre .post-card,
.blocos-home.arrastando-sobre .bloco-home-item {
    transition: transform var(--transicao);
}

/* 2026-08-27 -- CAUSA RAIZ DO "h1 da home e' o menor texto da pagina":
   a regra que da tamanho de verdade a titulo de pagina tem seletor
   `.container > h1` (ver ~"Revisao sistemica de UX/UI" mais abaixo), mas o
   <h1> da home mora dentro de <section class="hero"> -- filho de .hero, nao
   filho direto de .container. A regra NUNCA aplicava, e o <h1> caia em
   .hero-titulo, que e' um rotulo mono/versalete de 0.7rem (11px). Um <h1>
   de 11px maiusculo e' o menor texto da tela.
   CORRECAO: .hero-titulo continua existindo, mas so' como OVERLINE de
   secao (que e' o papel visual que ele sempre teve de fato). O <h1> real
   passa a usar a classe NOVA .hero-titulo-pagina, definida logo abaixo.
   O template core/templates/core/home.html precisa separar os dois
   elementos (outro agente esta fazendo isso na mesma data).
   Nao acrescentei `.hero > h1` ao grupo de titulos: enquanto o template
   antigo ainda estiver no ar com <h1 class="hero-titulo">, esse seletor
   ganharia do .hero-titulo e explodiria o overline pra 2rem. A classe
   explicita evita a janela de inconsistencia. */
.hero-titulo-pagina {
    margin: 0 0 var(--e-3);
    font-family: var(--grotesk);
    font-weight: 700;
    font-size: var(--t-h3); /* 30px -- degrau 32 do DS, com folga pro mobile */
    line-height: 1.16;
    letter-spacing: -0.018em;
    color: var(--navy-950);
    text-transform: none;
}

.hero-titulo {
    font-family: var(--mono);
    font-size: var(--t-label);
    font-weight: 500;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--tinta-suave);
    margin: 0;
}

.ver-informativos { font-size: var(--t-caption); }

/* Sem carrossel automatico (2026-07-20, julgamento do tribunal: carrossel
   dificulta descoberta e raramente tem os controles de acessibilidade
   recomendados pela W3C; Confluence usa 1 banner ativo por vez) -- vale
   pra esta grade tambem, nao so pro .hero-destaque antigo que ela substituiu. */
/* Grade de cards de avisos (2026-08-19, teste a pedido do Felipe: layout
   "como no Lince University" -- referencia de repertorio para o mecanismo
   (grade de cards uniformes), nao para a paleta Vuetify do Lince. Reaproveita
   a linguagem visual ja validada do antigo .hero-destaque (faixa de cor por
   importancia, selo mono, titulo serifado) em vez de inventar um componente
   novo -- so muda de "1 destaque + lista" pra "todos em grade". */
/* 2026-08-31 (auditoria): removidas daqui ~140 linhas de .hero-cards e
   .banner-card* (a grade "bento" de avisos que saiu da interface) e, mais
   abaixo, .contador-avisos. Nenhum template os renderiza, e
   setores/tests.py:164-165 trava a volta da marcacao com assertNotContains.
   NAO confundir com .feed-avisos/.feed-post logo adiante: aquilo e' a mini
   rede social DESATIVADA DE PROPOSITO (core/urls.py preserva views/models e
   documenta como reativar), entao fica onde esta. */

/* ===== Grade de avisos da home (2026-08-24/26, pedido do Paulo via
   Felipe: substitui a mini rede social, que não agradou). Passou por
   carrossel de 1 por vez, depois lista empilhada em coluna única --
   Felipe achou que exigia rolar demais ("objetivo dos avisos é ser
   enxuto mas informativo") e voltou pra grade lado a lado, agora com
   paginação de verdade em vez de corte fixo (ver core/views.py::home,
   Paginator). Card: branco, faixa colorida no topo (importância),
   avatar circular do setor, selo de importância, botão "Saiba mais". */
.avisos-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(17.5rem, 1fr));
    gap: var(--e-6);
    margin-bottom: var(--e-4);
}

/* ===== Avisos da home: lista com rolagem própria (2026-08-29) =====
   A faixa de urgente no topo foi desfeita -- com 3 urgentes publicados ela
   comia a dobra inteira. Urgente volta para a lista, e a LISTA ganha altura
   fixa com rolagem, que rola sozinha e volta ao topo (ideia do Paulo).
   Diferente do carrossel de 28/08, isto não esconde: a lista inteira está no
   DOM e na página, a rolagem só passeia por ela. */
.avisos-rolagem-bloco { position: relative; margin-bottom: var(--e-4); }
.avisos-rolagem {
    /* Altura em rem, não em vh: o bloco não pode encolher a ponto de caber
       meio card quando a janela é baixa. ~2,5 cards, o suficiente para o
       movimento ser percebido sem empurrar o resto da home para fora. */
    max-height: 40rem;
    overflow-y: auto;
    /* 02/09: era "contain" e travava a rolagem da PÁGINA quando a lista
       chegava ao fim -- em notebook 1366x768 o bloco é mais alto que a
       viewport útil e o resto da home ficava inalcançável até mover o
       mouse pra fora da coluna. "auto" devolve o encadeamento padrão em
       qualquer altura de janela, sem mexer na altura fixa do DESIGN.md. */
    overscroll-behavior: auto;
    display: flex;
    flex-direction: column;
    gap: var(--e-4);
    padding: var(--e-1) var(--e-2) var(--e-6) var(--e-1);  /* 2px para o anel de foco do card não ser cortado */
    /* 2026-09-01 (pedido da Comunicação: "alinhar os cards na mesma margem
       que o título"). O padding acima é o que sobrava: ele empurrava o card
       4px à direita do <h1>, e a diferença aparece porque as duas bordas
       verticais ficam uma sob a outra. Puxar a CAIXA 4px para a esquerda
       devolve o alinhamento sem tirar do anel de foco o espaço que ele
       precisa -- zerar o padding cortaria o anel, que foi por que ele
       existe. Os controles ("Passa sozinho...") são irmãos, não filhos:
       não andam junto e continuam alinhados ao título. */
    margin-left: calc(-1 * var(--e-1));
    scrollbar-width: thin;
    scrollbar-color: var(--linha-forte) transparent;
}
.avisos-rolagem:focus-visible { outline: 2px solid var(--navy-600); outline-offset: 4px; border-radius: var(--radius); }
.avisos-rolagem::-webkit-scrollbar { width: 8px; }
.avisos-rolagem::-webkit-scrollbar-thumb { background: var(--linha-forte); border-radius: var(--radius-pill); }
.avisos-rolagem::-webkit-scrollbar-track { background: transparent; }
/* Esmaecimento na base: diz "tem mais abaixo" sem gastar uma linha de texto.
   aria-hidden por natureza (é ::after) e não intercepta clique. */
.avisos-rolagem-bloco::after {
    content: "";
    position: absolute;
    /* Acompanha o margin-left negativo de .avisos-rolagem: sem isto sobrava
       uma tira de 4px de card sem esmaecer na quina inferior esquerda. */
    left: calc(-1 * var(--e-1));
    right: 0;
    bottom: 0;
    height: 2.5rem;
    background: linear-gradient(to bottom, transparent, var(--papel));
    pointer-events: none;
}
.avisos-rolagem .aviso-card { flex-shrink: 0; }   /* nunca espremer card para caber */
.avisos-rolagem .aviso-card-corpo { padding: var(--e-6) var(--e-6); }
.avisos-rolagem .aviso-card-titulo { font-size: var(--t-h5); }
.avisos-rolagem .aviso-card-texto {
    font-size: var(--t-caption);
    -webkit-line-clamp: 2;
    max-width: 78ch;
    flex-grow: 0;
    margin-bottom: var(--e-4);
}

.avisos-rolagem-controles {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--e-2);
    margin-top: var(--e-2);
}
.avisos-rolagem-dica { font-family: var(--mono); font-size: var(--t-label); letter-spacing: 0.04em; color: var(--tinta-suave); }
.avisos-rolagem-acoes { display: flex; gap: 0.5rem; }

/* ===== Modo TV (2026-08-31) =====
   Tela cheia e' a Fullscreen API nativa do navegador: nenhuma biblioteca,
   nenhuma rota nova, nenhum segundo layout para manter. O MESMO bloco que ja'
   rola sozinho na home vira a tela inteira -- e por isso a maquina de rolagem,
   o Pausar e a degradacao sem JS continuam valendo sem uma linha a mais.
   Sair e' Esc (nativo) ou o proprio botao. */
.avisos-rolagem-bloco:fullscreen {
    background: var(--papel);
    padding: 3rem 4rem 1rem;
    display: flex;
    flex-direction: column;
}
.avisos-rolagem-bloco:fullscreen .avisos-rolagem { max-height: none; flex: 1; }
.avisos-rolagem-bloco:fullscreen .aviso-card-titulo { font-size: 1.75rem; }
.avisos-rolagem-bloco:fullscreen .aviso-card-texto { font-size: 1.1rem; -webkit-line-clamp: 3; }
.avisos-rolagem-bloco:fullscreen .avisos-rolagem-controles { margin-top: 1rem; }
/* o esmaecimento da base sobe para nao velar os controles em tela cheia */
.avisos-rolagem-bloco:fullscreen::after { bottom: 3rem; }

.avisos-rolagem-pausa {
    min-height: 0;
    padding: var(--e-1) var(--e-3);
    font-size: var(--t-caption);
    background: var(--superficie);
    color: var(--navy-600);
    border: 1px solid var(--linha-forte);
    border-radius: var(--radius-pill);
    box-shadow: none;
    cursor: pointer;
    /* Largura mínima: "Pausar" e "Retomar" têm tamanhos diferentes e o botão
       pularia de posição a cada clique. */
    min-width: 5.5rem;
}
.avisos-rolagem-pausa:hover { background: var(--navy-100); border-color: var(--navy-600); transform: none; }
.avisos-rolagem-pausa:focus-visible { outline: none; box-shadow: var(--foco-anel); border-color: var(--navy-600); }

/* ===== O X que fecha o aviso na home (ideia do Paulo, 2026-08-29) =====

   ⚠️ O `position: relative; z-index: 1` do FORM não é enfeite: o card inteiro
   é um stretched link (`.aviso-card-botao::after` com `inset: 0`), e sem
   vencer essa camada o X aparece, recebe foco por teclado e **não responde
   ao clique** -- foi exatamente o defeito relatado pelo Felipe. O z-index vai
   no form e não no `.aviso-card-topo` que o envolve: se o pai comum criasse
   contexto de empilhamento, o ::after do botão passaria a se posicionar em
   relação a ele. Mesmo motivo e mesma solução de `.aviso-card-desmarcar-form`
   -- se um terceiro controle entrar no card, ele precisa disto também. */
.aviso-card-fechar-form {
    display: flex;
    margin: 0 0 0 var(--e-2);
    position: relative;
    z-index: 1;
}
.aviso-card-fechar {
    /* 28px de alvo (WCAG 2.5.8 pede 24) com o glifo desenhado dentro. */
    width: 28px;
    height: 28px;
    min-height: 0;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid transparent;
    border-radius: var(--radius-circulo);
    background: transparent;
    box-shadow: none;
    cursor: pointer;
    /* Presente mas quieto: é ação secundária e não pode competir com "Saiba
       mais", que é o que a pessoa veio fazer. Ganha corpo quando o ponteiro
       entra no card -- e fica sempre cheio onde não existe hover, senão o
       controle nasceria apagado no celular.
       0.55 sobre a cor que de fato renderiza (--tinta-suave, herdada de
       .btn-icone -- a `color: var(--linha-forte)` que estava aqui era
       codigo morto, .btn-icone vence por ordem no arquivo) dava 1,80:1
       contra o card branco, abaixo do minimo de 3:1 de WCAG 1.4.11 pra
       controle so' de icone. 0.65 compoe 3,42:1 (achado UX 02/09). */
    opacity: 0.65;
    transition: opacity var(--transicao), color var(--transicao),
                background var(--transicao), border-color var(--transicao),
                transform var(--transicao), box-shadow var(--transicao);
}
.aviso-card:hover .aviso-card-fechar,
.aviso-card:focus-within .aviso-card-fechar { opacity: 1; }
@media (hover: none) { .aviso-card-fechar { opacity: 1; } }

.aviso-card-fechar svg { width: 15px; height: 15px; display: block; }

/* Fechar tira conteúdo da vista da pessoa, então o hover fala a língua da
   ação destrutiva -- mas em tom claro, porque é reversível (o aviso continua
   no perfil do setor) e não é exclusão. */
.aviso-card-fechar:hover {
    opacity: 1;
    background: var(--urgente-100);
    border-color: var(--urgente);
    color: var(--urgente-escuro);
    /* transform explícito: o hover global de button levanta 1px, e aqui o
       movimento certo é crescer no lugar, não subir. */
    transform: scale(1.08);
    box-shadow: none;
}
.aviso-card-fechar:active { transform: scale(0.94); }
.aviso-card-fechar:focus-visible {
    outline: none;
    opacity: 1;
    border-color: var(--navy-600);
    box-shadow: var(--foco-anel);
    transform: none;
}
@media (prefers-reduced-motion: reduce) {
    .aviso-card-fechar:hover, .aviso-card-fechar:active { transform: none; }
}

.avisos-divisor {
    border: none;
    border-top: 2px solid var(--linha-forte);
    margin: var(--e-1) 0;
    flex-shrink: 0;
}

/* O caminho para os avisos que não entraram na lista. É a garantia de
   "nenhum aviso fica inalcançável" (pedido do Felipe, 26/08) -- não é
   decoração e não pode sumir numa próxima rodada de limpeza. */
.avisos-mais { margin: 0 0 var(--e-4); font-size: var(--t-caption); }

/* Estado "em dia". Não repete o conteúdo já lido (a regra de 28/08 diz que
   aviso lido sai da home) -- afirma a recência em uma linha. */
.avisos-em-dia {
    font-size: var(--t-caption);
    color: var(--tinta-suave);
    margin: var(--e-3) 0 var(--e-4);
}

@media (max-width: 640px) { .avisos-rolagem { max-height: 28rem; } }

/* Cartão redesenhado (2026-08-26, pedido do Felipe: seguir o modelo de
   card da Escola Virtual/Fundação Bradesco -- ev.org.br/trilhas-de-
   conhecimento/aprimoramento-profissional, "mais clean e bonito" --
   mantendo a paleta oficial da marca COPPEAD. Estrutura adaptada, não
   clonada: card branco sem faixa de borda, distintivo circular
   flutuante (sobrepõe o canto do card em vez de uma cor de borda),
   rodapé com par de estatísticas (padrão "Duração/Nível" do site de
   referência) + botão de ação. */
.aviso-card {
    position: relative;
    display: flex;
    flex-direction: column;
    background: var(--superficie);
    border-radius: var(--radius-lg);
    /* 2026-08-28: contorno de 1px além da sombra. O card branco sobre --papel
       (#F0EDFB) tem quase a mesma luminância do fundo -- a aresta da caixa
       era desenhada SÓ pela sombra difusa, e sumia em tela clara ou com
       brilho baixo. A hairline usa --linha, o mesmo token que já separa o
       rodapé por dentro do card: nenhum tom novo, e a caixa passa a ter
       limite em qualquer condição de tela. */
    border: 1px solid var(--linha);
    box-shadow: var(--sombra);
    transition: transform var(--transicao), box-shadow var(--transicao);
}
.aviso-card:hover, .aviso-card:focus-within {
    transform: translateY(-3px);
    box-shadow: var(--sombra-alta);
}

/* ===== Card inteiro clicável (2026-08-28) =====
   A referência que o Felipe deu para este componente foi o card de notícia
   (estilo G1). Nesse modelo a CAIXA é a área de clique -- aqui só o título e
   o botão eram, e num card de 3 colunas isso é um alvo pequeno cercado de
   área morta. O <a> do título projeta uma camada invisível sobre o card
   inteiro: continua existindo UM único link, um destino só para o leitor de
   tela, e nada de div com onclick (que a CSP deste projeto bloquearia).

   Trade-off assumido, não esquecido: com a camada por cima, arrastar para
   selecionar o texto do card deixa de funcionar. Num card de resumo -- texto
   já truncado em 3 linhas, íntegro na página de detalhe -- clicar vale mais
   que selecionar. Se algum dia o card virar conteúdo final em vez de
   chamada, esta é a primeira regra a remover. */
/* Quem estica é o BOTÃO, não o link do título -- e a diferença não é
   estilística. `.aviso-card-titulo` tem `overflow: hidden` por causa do
   line-clamp de 2 linhas, e overflow recorta o ::after de qualquer
   descendente: a camada nasceria limitada à altura do título, cobrindo
   duas linhas de texto em vez do card. O botão não tem nenhum ancestral
   com overflow, e "abrir o aviso" já é literalmente a função dele. */
.aviso-card-botao::after {
    content: "";
    position: absolute;
    inset: 0;
}
/* Sobe acima da camada: é o único controle do card que faz outra coisa que
   não "abrir o aviso". Sem isto, "marcar como não visualizado" ficaria
   inalcançável no clique. O z-index vai no FORM e não no `.aviso-card-acoes`
   que os envolve -- se o pai comum criasse contexto de empilhamento, o
   ::after do botão passaria a se posicionar em relação a ele e cobriria
   apenas o próprio rodapé. */
.aviso-card-desmarcar-form { display: flex; margin: 0; position: relative; z-index: 1; }

/* O anel de foco pertence ao CARD: o alvo de clique agora é a caixa
   inteira, então um anel em volta de um pedaço descreveria mal o que está
   focado. Vale para os dois links do card -- o título continua focável por
   teclado mesmo estando sob a camada. `:has()` já é usado neste arquivo. */
.aviso-card:has(.aviso-card-botao:focus-visible),
.aviso-card:has(.aviso-card-titulo a:focus-visible) {
    outline: 2px solid var(--navy-600);
    outline-offset: 3px;
}
/* Passar o mouse em qualquer ponto do card sublinha o título -- é o que diz
   "isto aqui é clicável inteiro", sem precisar de moldura ou rótulo extra. */
.aviso-card:hover .aviso-card-titulo a { text-decoration: underline; }
/* 2026-08-28, pedido do Felipe: "leve sombreado vermelho para os de caráter
   urgente, assim os avisos importantes ficam evidentes". Sombra, e não fundo
   ou borda colorida: o card urgente já carrega o selo vermelho, e pintar a
   caixa inteira brigaria com a paleta institucional que o Felipe pediu para
   preservar. A sombra neutra continua na frente da declaração -- sem ela o
   card urgente perderia a elevação dos vizinhos e pareceria afundado.
   Sombra não é texto: não entra no cálculo de contraste da WCAG, e quem não
   distingue a cor continua tendo o selo escrito "Urgente" como sinal real --
   isto é reforço, nunca o único indicador. color-mix mantém o vermelho
   amarrado ao token --urgente, em vez de um rgba() solto que sairia de
   sincronia no dia em que a marca mudar. */
.aviso-card.importancia-urgente {
    box-shadow: var(--sombra), 0 4px 16px color-mix(in srgb, var(--urgente) 26%, transparent);
}
.aviso-card.importancia-urgente:hover,
.aviso-card.importancia-urgente:focus-within {
    box-shadow: var(--sombra-alta), 0 8px 22px color-mix(in srgb, var(--urgente) 34%, transparent);
}
.aviso-card-capa {
    margin: 0;
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    overflow: hidden;
    background: var(--navy-100);
}
.aviso-card-capa img {
    width: 100%;
    max-height: 9rem;
    /* 02/09 (achado UX responsivo/consistencia/performance): vivia num
       style="aspect-ratio" inline no template, que a CSP (style-src
       'self') descartava sem aviso -- a reserva de espaco nunca
       funcionou de fato. So' age abaixo de ~560px: a variante lado-a-
       lado (main.css, height:100% + width:100%) define os dois eixos
       e o aspect-ratio e' ignorado, entao o desktop nao muda. */
    aspect-ratio: 16 / 9;
    object-fit: cover;
    display: block;
    /* 2026-09-03 (polimento): contorno neutro sutil, pra imagem de capa
       enviada por qualquer setor não se fundir com o fundo do card em
       fotos muito claras. Preto/branco em alpha -- nunca a cor de marca. */
    outline: 1px solid rgba(27, 23, 49, .08);
    outline-offset: -1px;
    /* Duração própria, mais lenta que --transicao (140ms): um zoom de imagem
       na velocidade de um botão lê como falha de renderização, não como
       movimento. A capa já tem overflow:hidden, então nada vaza. */
    transition: transform 320ms ease;
}
.aviso-card:hover .aviso-card-capa img,
.aviso-card:focus-within .aviso-card-capa img {
    transform: scale(1.045);
}
/* O projeto zera --transicao em prefers-reduced-motion, o que aqui deixaria
   o zoom INSTANTÂNEO em vez de ausente -- um salto seco da imagem, pior que
   a animação. Quem pediu menos movimento não recebe movimento nenhum. */
@media (prefers-reduced-motion: reduce) {
    .aviso-card-capa img { transition: none; }
    .aviso-card:hover .aviso-card-capa img,
    .aviso-card:focus-within .aviso-card-capa img { transform: none; }
}
/* Imagem à esquerda / texto à direita quando o aviso tem capa (2026-08-27,
   pedido do Felipe: modelo de card de notícia -- "quando tiver [imagem] a
   esquerda e o texto a direita da imagem, fica informativo e permite ver a
   imagem"). Sem capa, o card continua como já era (só texto, coluna única).
   Abaixo de 560px volta a empilhar -- card de notícia em coluna estreita
   junto com título+rodapé espreme demais pra caber ao lado da imagem. */
.aviso-card:has(.aviso-card-capa) {
    flex-direction: row;
    align-items: stretch;
}
.aviso-card:has(.aviso-card-capa) .aviso-card-capa {
    flex: 0 0 clamp(8.5rem, 32%, 12.5rem);
    border-radius: var(--radius-lg) 0 0 var(--radius-lg);
}
.aviso-card:has(.aviso-card-capa) .aviso-card-capa img {
    height: 100%;
    max-height: none;
}
@media (max-width: 560px) {
    .aviso-card:has(.aviso-card-capa) {
        flex-direction: column;
    }
    .aviso-card:has(.aviso-card-capa) .aviso-card-capa {
        flex: none;
        border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    }
    .aviso-card:has(.aviso-card-capa) .aviso-card-capa img {
        height: auto;
        max-height: 9rem;
    }
}
/* Linha própria pro badge, acima do título (2026-08-26, achado do
   Felipe: badge posicionado absoluto sobrepunha o título quando o
   texto quebrava em 2 linhas). Fluxo normal, nunca sobrepõe nada. */
/* 2026-08-27 (2 correcoes):
   1) justify-content era flex-end -- o badge era o UNICO elemento do card
      alinhado a direita, contra titulo/texto/rodape todos a esquerda.
      Passa a flex-start, mesma margem otica do resto.
   2) min-height reserva a linha SEMPRE. Antes, o template so' renderiza a
      linha do badge quando importancia != normal, entao cards vizinhos na
      grade comecavam o titulo em alturas diferentes -- a grade parecia
      desalinhada. Agora a caixa existe mesmo vazia e todos os titulos
      comecam na mesma linha de base. 1.5rem = altura real do badge
      (0.62rem de fonte + 0.22rem de padding vertical x2). */
.aviso-card-topo {
    display: flex;
    align-items: center;
    /* 2026-08-28: a data mudou de lugar (era rotulo "Publicado" no rodape) e
       divide esta linha com o selo. gap garante respiro quando os dois
       existem; o margin-left:auto da data ancora ela a direita mesmo quando
       o selo NAO existe (importancia normal), que era o caso em que ela
       escorregava pro canto esquerdo. */
    gap: var(--e-3);
    min-height: 1.5rem;
    margin-bottom: var(--e-2);
}
.aviso-card-data-topo {
    margin-left: auto;
    flex-shrink: 0;
    font-family: var(--mono);
    font-size: var(--t-label);
    letter-spacing: 0.04em;
    color: var(--tinta-suave);
}
.aviso-card-badge,
.badge-importancia {
    display: inline-block;
    font-family: var(--grotesk);
    font-size: var(--t-overline);
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    padding: var(--e-1) var(--e-2);
    border-radius: var(--radius-pill);
    background: var(--terracota-100);
    color: var(--terracota-texto);
    /* 2026-08-28 (auditoria): --terracota-100 vale #F0EDFB, que e' o mesmo
       Cinza Claro do --papel. Sobre o card branco a pilula tinha 1,09:1 de
       contraste -- a FORMA de pilula nao existia, sobrava so o texto, num
       roxo identico ao de link. "Importante" nao lia como nivel, lia como
       link. Contorno de 1px na propria cor do nivel devolve a pilula
       (7,38:1 contra o card) sem inventar tom nenhum. */
    border: 1px solid var(--terracota);
}
.aviso-card.importancia-urgente .aviso-card-badge { background: var(--urgente-100); color: var(--urgente-escuro); border-color: var(--urgente); } /* 2026-08-27: era var(--urgente) (4.35:1 sobre --urgente-100, reprova AA); --urgente-escuro da 6.03:1. */

.aviso-card-corpo {
    /* 2026-08-28: `position: relative` REMOVIDO daqui de propósito. Ele
       sobrou da época do badge posicionado absoluto (que voltou ao fluxo
       normal em 2026-08-26) e, mantido, seria o ancestral posicionado mais
       próximo do ::after do título -- a camada de clique cobriria só o
       corpo, deixando a capa da esquerda morta justamente nos cards com
       imagem. Sem ele, o ancestral é o .aviso-card, que é o certo. */
    display: flex;
    flex-direction: column;
    flex-grow: 1;
    /* 2026-08-28: SEM min-width:0 o corpo nunca encolhia abaixo do proprio
       min-content, entao o card empurrava a coluna do grid e a pagina inteira
       ganhava barra horizontal (medido: 98px de estouro entre 1280 e 1440px).
       Item flex tem min-width:auto por default -- este e' o antidoto padrao. */
    min-width: 0;
    padding: var(--e-6) var(--e-6) var(--e-6);
}

/* Já lido: card inteiro fica com tom apagado (2026-08-26, achado do
   Felipe: "remova os ícones... apenas os textos devem ser mostrados" --
   sem o distintivo circular que antes carregava a cor de "lido", o
   sinal migrou pro card inteiro. Mesmo tratamento já usado em
   .banner-card.lido no perfil de setor -- não inventa linguagem nova). */
.aviso-card.lido .aviso-card-titulo a,
.aviso-card.lido .aviso-card-texto,
.aviso-card.lido .aviso-card-stat-valor {
    color: var(--tinta-suave);
    opacity: 0.85;
}
.aviso-card.lido .aviso-card-titulo a { font-weight: 400; }

.aviso-card-titulo {
    /* Pesos variados dentro do mesmo card (2026-08-26, pedido do Felipe:
       "quando for várias entre tipo e avisos, variar entre os pesos
       dessa fonte") -- título Bold, corpo Light, estatísticas/botão
       Bold, seguindo a escala do próprio Design System. */
    /* 2026-08-27: 0.92rem (~14.7px) deixava o TITULO menor que o valor
       das estatisticas do rodape em peso otico -- hierarquia invertida.
       1.05rem (~16.8px) recoloca o titulo como o elemento mais forte do
       card, coerente com a escala do DS (16/18px de corpo forte). */
    margin: 0 0 var(--e-1);
    font-family: var(--grotesk);
    font-weight: 700;
    font-size: var(--t-body);
    line-height: 1.35;
    /* 2026-09-03 (polimento): título curto de até 2 linhas -- balance
       evita a primeira linha cheia e a segunda com 1-2 palavras soltas. */
    text-wrap: balance;
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    /* A propriedade padronizada, ao lado da -webkit-: os navegadores que já
       a implementam param de depender de um prefixo de fornecedor. */
    line-clamp: 2;
    -webkit-box-orient: vertical;
}
.aviso-card-titulo a { color: var(--tinta); text-decoration: none; }
.aviso-card-titulo a:hover, .aviso-card-titulo a:focus-visible { text-decoration: underline; }
.aviso-card-texto {
    margin: 0 0 var(--e-4);
    font-family: var(--grotesk);
    font-weight: 300;
    line-height: 1.5;
    font-size: var(--t-caption);
    color: var(--tinta-suave);
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    flex-grow: 1;
}

/* 2026-08-28 (achado do Felipe, com screenshot: botao "Saiba mais"
   desenhado por CIMA da data "26/08/2026" no card com imagem, dentro do
   grid de 3 colunas da home -- coluna de texto mais estreita do que
   qualquer contexto testado antes). flex-wrap:wrap e' rede de seguranca
   ESTRUTURAL: se o rotulo/valor + botao nao couberem numa linha, o
   botao desce pra linha de baixo -- nunca mais sobrepoe, em NENHUMA
   largura de card, presente ou futura. */
.aviso-card-rodape {
    /* grid de 2 colunas FIXAS no lugar de flex+wrap (2026-08-28). O wrap era
       uma rede de seguranca legitima contra sobreposicao, mas tornava o
       layout dependente do comprimento do conteudo: "TI" cabia na linha e o
       botao ficava a direita; "Gerencia Administrativa" nao cabia e o botao
       descia. Resultado: cada card da grade diferente do vizinho, e a linha
       divisoria em alturas diferentes (rodape de 2 linhas empurra o
       margin-top:auto). minmax(0,1fr) deixa a coluna do setor encolher e
       truncar em vez de empurrar; a coluna `auto` do botao nunca quebra. */
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: var(--e-4);
    margin-top: auto;
    padding-top: var(--e-4);
    border-top: 1px solid var(--linha);
}
.aviso-card-setor {
    min-width: 0;
    font-family: var(--grotesk);
    font-size: var(--t-caption);
    font-weight: 500;
    color: var(--tinta-suave);
    /* Rede de seguranca: nome muito longo trunca em vez de empurrar o botao.
       O template poe o nome completo no `title`, entao nada se perde. */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* 2026-08-28: .aviso-card-stats/-stat/-stat-rotulo/-stat-valor removidos
   junto com o markup que os usava (rodape "Setor | Publicado"). Eram usados
   SO' em core/_aviso_card.html -- confirmado por grep antes de apagar. */

/* 2026-08-27 (2 correcoes):
   1) HIERARQUIA: era peso 700 em var(--navy-600) -- o nome do setor e a
      data, que sao metadado, carregavam a unica cor de destaque do card e
      pesavam mais que o titulo. Passa a --tinta-suave / peso 500: continua
      legivel (--tinta-suave #4A4A6A sobre branco = 8.6:1) sem competir com
      o titulo.
   2) TRUNCAMENTO: max-width de 8rem (~128px) cortava nome de setor comum
      ("Secretaria Academica") no meio. Sobe pra 11rem; o pai
      (.aviso-card-stat) ja tem min-width:0, entao o flex ainda encolhe
      quando a largura do card exige. */
.aviso-card-stat-valor {
    font-family: var(--grotesk);
    font-weight: 500;
    font-size: var(--t-caption);
    color: var(--tinta-suave);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 11rem;
}
/* 2026-08-27: modificador pro valor de DATA. Data tem formato fixo
   (26/08/2026, 10 caracteres) e nunca precisa truncar -- ganhava
   reticencias a toa por herdar a mesma regra do nome do setor (max-width
   de 11rem pensado pro nome do SETOR, comprimento bem maior que uma data).
   2026-08-28 (achado do Felipe, com screenshot): a 1a versao usava
   max-width:none + overflow:visible -- "nunca trunca" virou "pode crescer
   sem limite", e no card estreito com imagem (grid de 3 colunas da home)
   a data invadia visualmente o botao "Saiba mais" ao lado. Fix: max-width
   FIXO, calculado pra uma data (10 caracteres, "26/08/2026") sempre caber
   inteira em qualquer fonte/zoom razoavel -- nunca precisa truncar na
   pratica, mas tem um teto real. overflow/text-overflow voltam a herdar
   hidden/ellipsis da regra base (.aviso-card-stat-valor) como rede de
   seguranca: se algum dia o teto for insuficiente (fonte custom maior,
   locale com formato de data diferente), o pior caso vira "..." -- nunca
   mais sobreposicao visual, em nenhuma largura de card. */
.aviso-card-stat-valor--data {
    max-width: 5.5rem;
}

/* Ghost/outline em vez de preenchido (2026-08-26, achado do Felipe: "o
   botão Saiba mais deve estar menos destacável") -- mesma linguagem já
   usada em .btn-secundario no resto do site (contorno que preenche no
   hover), não inventa estilo novo. */
.aviso-card-botao {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    padding: var(--e-2) var(--e-3);
    border-radius: var(--radius);
    background: transparent;
    border: 1px solid var(--linha-forte);
    color: var(--navy-600);
    font-family: var(--grotesk);
    font-weight: 700;
    font-size: var(--t-caption);
    text-decoration: none;
    /* `color` entra na transição: sem ela, borda e fundo deslizavam enquanto
       o texto trocava de tom num salto -- o botão se movia em duas
       velocidades. */
    transition: background var(--transicao), border-color var(--transicao),
                color var(--transicao);
}
.aviso-card-botao:hover, .aviso-card-botao:focus-visible {
    background: var(--navy-100);
    border-color: var(--navy-600);
}

/* 2026-08-28: "marcar como não visualizado" no card (aviso lido saiu da home,
   este é o caminho de volta). Os dois controles dividem UMA célula do grid do
   rodapé -- acrescentar uma terceira coluna reabriria o defeito de layout
   dependente do conteúdo que a variante C fechou. O .btn-icone padrão é 2.25rem
   e cresceria o rodapé só nos cards lidos, deixando a grade desalinhada; aqui
   ele desce pra altura exata do .aviso-card-botao (0.4rem+0.4rem de padding
   sobre uma linha de 0.78rem), então card com e sem ícone medem igual. */
.aviso-card-acoes { display: flex; align-items: center; gap: var(--e-1); flex-shrink: 0; }
/* .aviso-card-desmarcar-form é declarada junto do stretched link, mais acima
   neste arquivo: o `z-index` dela só faz sentido lido ao lado da camada de
   clique que ela precisa vencer. */
.aviso-card-desmarcar { width: 1.9rem; height: 1.9rem; }
.aviso-card-desmarcar svg { width: 1rem; height: 1rem; }

/* Feed de avisos da home (2026-08-24, pedido do Felipe: só a home vira
   feed de posts estilo rede social, coluna única igual Instagram/
   LinkedIn). Reusa .post-card inteiro (mesma classe do detalhe do aviso)
   -- só acrescenta o que é específico do feed (fechar, reordenar,
   opacidade de lido). */
.feed-avisos {
    display: flex;
    flex-direction: column;
    gap: var(--e-6);
    max-width: 40rem;
    margin: 0 auto var(--e-4);
}

.feed-post {
    transition: transform var(--transicao), box-shadow var(--transicao);
}
.feed-post:hover, .feed-post:focus-within {
    transform: translateY(-2px);
    box-shadow: var(--sombra-hover);
}
.feed-post.importancia-importante { background: var(--terracota-100); }
.feed-post.importancia-urgente { background: var(--urgente-100); }
.feed-post.lido { opacity: 0.82; }

.post-card-cabecalho .banner-fechar-form { margin-left: auto; }

.feed-expira {
    font-family: var(--mono);
    font-size: var(--t-label);
    color: var(--tinta-suave);
    margin-left: auto;
}

.post-card .card-mover { margin: 0 var(--e-6) var(--e-4); align-self: flex-start; }

.hero-vazio {
    background: var(--superficie);
    border: 1px dashed var(--linha-forte);
    border-radius: var(--radius);
    padding: var(--e-12);
    text-align: center;
    color: var(--tinta-suave);
}

/* Botão fechar (X) do aviso no Hero — some só pro usuário; aviso segue
   ativo no perfil do setor até expirar. */
.banner-fechar-form { margin: 0; flex-shrink: 0; }

.banner-fechar {
    background: transparent;
    border: none;
    color: var(--tinta-suave);
    font-size: var(--t-body);
    line-height: 1;
    /* Alvo de toque >=44px (WCAG 2.5.5); glifo continua pequeno, centralizado
       via flex (2026-07-20, auditoria de acessibilidade — 24px era pequeno
       demais pra toque em mobile). */
    width: 2.75rem;
    height: 2.75rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-pill);
    cursor: pointer;
    padding: 0;
    transition: background var(--transicao), color var(--transicao);
}
.banner-fechar:hover { background: var(--papel); color: var(--tinta); }

/* Badge de importância: fundido com .aviso-card-badge em 02/09 (achado UX
   consistencia) -- as duas classes repetiam a mesma declaracao linha a
   linha, e a divergencia (font-family: var(--grotesk), so' na outra)
   fazia a pilula do mesmo aviso trocar de tipografia entre a home e o
   detalhe. Regra base fica em .aviso-card-badge, acima. */
.badge-importancia--urgente { background: var(--urgente-100); color: var(--urgente-escuro); border-color: var(--urgente); } /* 2026-08-27: era var(--urgente) (4.35:1 sobre --urgente-100, reprova AA); --urgente-escuro da 6.03:1. */

/* Selo de setor — mesmo padrão mono/versalete usado em .banner-card-selo,
   pra telas (como Informativos) que mostram o setor fora de uma lista de
   linhas. */
.setor-badge {
    font-family: var(--mono);
    font-size: var(--t-label);
    font-weight: 500;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--tinta-suave);
    flex-shrink: 0;
}

.badge-novo {
    display: inline-block;
    background: var(--navy-600);
    color: var(--superficie);
    font-size: var(--t-overline);
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    padding: var(--e-1) var(--e-2);
    border-radius: var(--radius-pill);
}


/* ===== Estado de carregamento (2026-08-31, auditoria: o sistema nao tinha
   NENHUM -- zero spinner/skeleton no arquivo. Upload de documento e de aviso
   aceitam ate 5MB de imagem numa rede interna: quem clica em "Publicar" fica
   sem resposta ate a pagina trocar, e o reflexo e' clicar de novo. Escopo
   deliberadamente pequeno: so' o botao que submeteu um formulario de upload,
   nada de overlay de pagina nem skeleton de lista.) */
button[data-carregando] {
    /* `color: transparent` em vez de trocar o texto: o rotulo continua no
       fluxo, entao o botao NAO muda de largura e a barra de acoes nao pula --
       e nada precisa tocar em element.style, que a convencao do projeto
       proibe por causa da CSP (ver o bloco de cards moveis em main.js). */
    position: relative;
    color: transparent !important;
    pointer-events: none;
}
button[data-carregando]::after {
    content: "";
    position: absolute;
    inset: 0;
    margin: auto;
    width: 1rem;
    height: 1rem;
    border: 2px solid currentColor;
    border-top-color: transparent;
    border-radius: var(--radius-circulo);
    /* currentColor e' transparente na regra acima; o anel usa a cor real do
       texto do botao, que o navegador ainda resolve em ::after via `color`. */
    color: var(--superficie);
    animation: girando 620ms linear infinite;
}
.btn-secundario[data-carregando]::after { color: var(--navy-600); }

@keyframes girando { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
    /* Sem giro: o anel vira um tracinho parado. O sinal de "esta' acontecendo"
       nao pode depender do movimento -- mesma regra do Hero. */
    button[data-carregando]::after { animation: none; border-top-color: currentColor; opacity: 0.55; }
}

/* ===== Setores / perfil ===== */
.setores-titulo {
    font-family: var(--mono);
    font-size: var(--t-label);
    font-weight: 500;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--tinta-suave);
    margin: var(--e-8) 0 var(--e-4);
}
.container > .setores-titulo:first-child,
.hero > .setores-titulo:first-child { margin-top: 0; }

.perfil-setor-cabecalho {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--e-3);
    margin-bottom: var(--e-6);
    padding-bottom: var(--e-6);
    border-bottom: 2px solid var(--navy-950);
}
.perfil-setor-cabecalho h1 { margin: 0; font-family: var(--grotesk); font-size: var(--t-h3); }
.setor-acoes { display: flex; gap: var(--e-4); align-items: center; margin: var(--e-4) 0 0; }
.perfil-setor-cabecalho .setor-acoes { gap: var(--e-4); font-size: var(--t-caption); margin: 0; }
/* Descricao do setor, logo abaixo do nome (2026-09-08, pedido do Felipe:
   visitante que nao e' do setor precisa ver do que se trata assim que
   abre a pagina -- antes so' aparecia la embaixo, depois do painel e da
   lista de documentos). Empilhada com o h1 num bloco a parte pra
   .perfil-setor-cabecalho continuar "titulo+descricao" de um lado,
   botoes de acao do outro, sem entrar na mesma linha flex do h1. */
.perfil-setor-titulo-bloco { display: flex; flex-direction: column; gap: var(--e-2); }
.perfil-setor-descricao-topo { margin: 0; color: var(--tinta-suave); max-width: 60ch; }

/* Usadas so' em setores/detalhe_painel.html (2026-08-21, auditoria: pagina
   nunca tinha recebido regra propria, saia com HTML cru do navegador).
   Reaproveita a mesma linguagem mono/versalete de .hero-titulo pro rotulo
   de trilha, e a mesma estrutura de cabecalho de .perfil-setor-cabecalho. */
.breadcrumb {
    font-family: var(--mono);
    font-size: var(--t-label);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--tinta-suave);
    margin-bottom: var(--e-6);
}
.breadcrumb a { color: var(--navy-600); }

.pagina-cabecalho {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--e-3);
    margin-bottom: var(--e-6);
    padding-bottom: var(--e-6);
    border-bottom: 2px solid var(--navy-950);
}
.pagina-cabecalho h1 { margin: 0 0 var(--e-2); font-family: var(--grotesk); font-size: var(--t-h3); }
.pagina-cabecalho p { margin: 0; color: var(--tinta-suave); }

.perfil-setor-descricao {
    background: var(--superficie);
    border-radius: var(--radius);
    box-shadow: var(--sombra);
    padding: var(--e-6) var(--e-6);
    margin-bottom: var(--e-6);
    color: var(--tinta);
}

.setores-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: var(--e-4);
    margin-top: var(--e-6);
}

.setor-card {
    background: var(--superficie);
    border-radius: var(--radius);
    box-shadow: var(--sombra);
    padding: var(--e-4) var(--e-6);
    border-top: 4px solid var(--navy-600);
    /* Unifica com o motion ja validado no .banner-card (2026-08-19,
       achado do Felipe: home ficou vivida, resto do sistema continuou
       plano) -- mesma receita de elevacao no hover/foco, sem inventar
       linguagem nova por tela. */
    transition: transform var(--transicao), box-shadow var(--transicao);
    /* 2026-09-03 (achado QA): so' o TI tem "Descricao" preenchida hoje, e
       sem isso o card dele ficava bem mais alto que os vizinhos na mesma
       linha da grade -- ragged em vez de alinhado. Flex + acoes empurrado
       pro rodape deixa a altura desigual (o grid ja estica os cards) sem
       feio visual, e continua certo quando mais setores preencherem a
       propria descricao. */
    display: flex;
    flex-direction: column;
}
.setor-card:hover, .setor-card:focus-within {
    transform: translateY(-3px);
    box-shadow: var(--sombra-hover);
}
.setor-card h2 { margin: 0 0 var(--e-2); font-family: var(--grotesk); font-size: var(--t-body-lg); }
.setor-card .setor-acoes { display: flex; gap: var(--e-4); font-size: var(--t-caption); margin-top: auto; padding-top: var(--e-4); }

/* ===== Documentos do setor — visual deliberadamente distinto dos avisos
   (2026-07-17, pedido do Felipe): sem cor por importância/urgência, é
   arquivo estático, não notícia. Selo cinza "PDF" no lugar do selo
   colorido de setor/importância do Hero. */
.lista-documentos {
    list-style: none;
    margin: 0;
    padding: 0;
    background: var(--superficie);
    border-radius: var(--radius);
    box-shadow: var(--sombra);
    overflow: hidden;
}

/* 2026-08-27 (achado do Felipe, screenshot de /documentos/buscar/):
   align-items:baseline alinhava cada <li> pela linha de base do TEXTO --
   como o bloco da direita (.lista-documentos-info) tem altura variável
   (1 selo vs 2, com/sem status de revisão), a baseline de cada linha
   caía em alturas diferentes e o selo "pulava" verticalmente de linha
   pra linha, mesmo já tendo largura fixa (14rem, ver comentário
   histórico abaixo). flex-start alinha todo mundo pelo topo -- selo
   sempre no mesmo Y que a primeira linha do título. */
.lista-documentos li {
    display: flex;
    align-items: flex-start;
    gap: var(--e-4);
    padding: var(--e-3) var(--e-4);
    border-bottom: 1px solid var(--linha);
    transition: background var(--transicao);
}
.lista-documentos li:last-child { border-bottom: none; }
.lista-documentos li:hover { background: var(--papel); }

.documento-selo {
    font-family: var(--mono);
    font-size: var(--t-overline);
    font-weight: 700;
    letter-spacing: 0.06em;
    color: var(--navy-600);
    background: var(--papel);
    border: 1px solid var(--linha);
    border-radius: var(--radius-sm);
    padding: var(--e-1) var(--e-2);
    flex-shrink: 0;
}

/* 2026-08-27: cor do texto era var(--urgente) sobre var(--urgente-100)
   = 4.35:1, reprova o minimo AA de 4.5:1 (texto pequeno, 0.64rem).
   var(--urgente-escuro) sobre o mesmo fundo = 6.03:1. */
.documento-selo-sigiloso {
    color: var(--urgente-escuro);
    background: var(--urgente-100);
    border-color: transparent;
}

.lista-documentos-titulo {
    font-family: var(--grotesk);
    font-weight: 700;
    font-size: var(--t-body);
    color: var(--tinta);
    flex: 1 1 auto;
    /* 2026-08-28: `min-width: 140px` era um piso ABSOLUTO -- em tela de 320px
       com selo e meta ao lado, nao havia como caber. min() mantem os 140px de
       conforto onde ha espaco e cede quando nao ha. */
    min-width: min(140px, 100%);
}
.lista-documentos-titulo:hover { text-decoration: underline; }

/* 2026-08-29 (pedido do Paulo via Felipe): diferenciar documento de aviso
   só em "Destaques do setor" (setores/templates/setores/perfil.html) --
   clipe pra documento, balao de conversa pra aviso. Decorativo (aria-hidden
   no svg), herda a cor do link (--tinta) via currentColor, sem token novo. */
.destaque-icone {
    display: inline-block;
    vertical-align: -2px;
    margin-right: var(--e-1);
}

/* Título de documento sempre em caixa alta (2026-08-26, achado do Felipe:
   documentos entram com capitalização inconsistente -- CAIXA ALTA vs
   Title Case, dependendo de quem fez o upload -- e ele quer um padrão
   único visualmente). Combina classe + prefixo de href (2026-08-26,
   correção: o seletor original era só por href, e "Enviar documento"
   -- botão em setores/perfil.html, URL /documentos/setor/<slug>/enviar/
   -- também começa com "/documentos/", então virava CAIXA ALTA junto
   com os títulos de verdade, sem ninguém pedir isso -- achado pelo
   próprio Felipe comparando com "Editar perfil"/"Criar aviso" ao lado,
   que ficaram em case normal). Exigir a classe .lista-documentos-titulo
   também restringe pros links que são de fato título de documento (só
   documento usa essa classe com href de /documentos/ — aviso/pessoa/
   atalho reusam a mesma classe mas linkam pra outro path, então nunca
   batem aqui de qualquer forma). Documento novo já nasce conforme, sem
   precisar lembrar do padrão na hora do upload. */
a.lista-documentos-titulo[href^="/documentos/"] { text-transform: uppercase; }
.documento-detalhe-cabecalho h1 { text-transform: uppercase; }

/* Divisória sutil antes de Ver/Baixar (2026-08-13, Felipe: metadados,
   status e ações ficavam colados, lendo como um bloco só de texto em vez
   de três grupos distintos — autor/data, status de revisão, ações). */
.lista-documentos-acoes {
    display: flex;
    gap: var(--e-4);
    font-size: var(--t-caption);
    flex-shrink: 0;
    margin-left: auto;
    padding-left: var(--e-4);
    border-left: 1px solid var(--linha);
}
/* Ícone SVG em vez de texto "Ver"/"Baixar" (mockup do Felipe, refinamento
   "emoji/texto -> ícone de traço"). aria-label já nomeia a ação por
   documento -- o <svg> é puramente decorativo (aria-hidden). */
.lista-documentos-acoes a {
    display: inline-flex;
    align-items: center;
    color: var(--navy-600);
}
.lista-documentos-acoes a:hover { color: var(--navy-600-hover); }

/* Data (ou contagem) no final de .lista-documentos-meta, destacada do
   resto do texto -- mesma ideia de .corpo-badge-postagens acima. */
.lista-documentos-numero {
    color: var(--linha-forte);
    font-variant-numeric: tabular-nums;
}

/* 2026-08-26, achado do Felipe: o selo de categoria aparecia em posicoes
   diferentes de linha pra linha ("alguns mais pra esquerda, outros mais
   pra direita"). Causa: .lista-documentos-titulo tem flex:1 1 auto, entao
   ele cresce e consome todo o espaco sobrando depois de descontar os
   irmaos -- como a largura do selo varia por linha (Norma vs Formulario
   vs Calendario), o titulo terminava em X diferente por linha, o que
   flexbox nao alinha entre linhas (cada <li> e um container independente).
   Fix: agrupa selo(s)+meta(+revisao) num filho de largura FIXA -- o titulo
   sempre cresce ate o mesmo ponto, e o bloco da direita fica sempre no
   mesmo lugar em toda linha. */
.lista-documentos-info {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--e-1);
    flex: 0 0 auto;
    width: 14rem;
}
/* 2026-08-27: linha própria pros selos (tipo/sigiloso/status), sempre no
   topo do bloco -- antes selo(s) e meta viviam soltos no mesmo flex row
   e quebravam linha de formas diferentes dependendo de quantos selos a
   linha tinha. Agora o selo nunca compete de posição com o metadado.
   2026-08-28 (achado do Felipe): alinhado à direita fazia o selo e o
   metadado começarem em X diferentes -- cada um tem comprimento próprio
   (largura do selo varia por categoria, texto do metadado varia por
   nome/setor), então "alinhar à direita" só alinhava o FIM dos dois, não
   o início. Como a coluna já tem largura fixa (14rem), alinhar à
   ESQUERDA garante que o selo comece exatamente na mesma posição que o
   metadado logo abaixo, sempre -- é isso que "Norma em cima de TI" pede. */
.lista-documentos-selos {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-start;
    align-items: center;
    gap: var(--e-2);
}
.lista-documentos-info-ampla { width: 19.5rem; }
/* 2026-09-08, pedido do Felipe: Postagens do perfil (core/perfil.html) --
   selo e data encostados na borda direita da linha, nao soltos com vao
   vazio quando o setor e' curto (ex. "TI") vs longo (ex. "Secretaria
   Academica"). Contraria de proposito o achado de 2026-08-28 logo acima
   (que preferiu ESQUERDA pra selo/metadado comecarem no mesmo X) --
   pedido explicito, so' pra esta lista (classe extra, nao mexe no padrao
   default usado em Documentos do setor). */
.lista-documentos-info--direita { align-items: flex-end; text-align: right; }

.lista-documentos li.lido .lista-documentos-titulo {
    font-weight: 400;
    color: var(--tinta-suave);
}
.lista-documentos li.lido .documento-selo {
    opacity: 0.65;
}

.corpo-badge-postagens {
    font-family: var(--mono);
    background: var(--navy-600);
    color: var(--superficie);
    font-size: var(--t-label);
    font-weight: 700;
    line-height: 1;
    padding: var(--e-1) var(--e-2);
    border-radius: var(--radius-pill);
    min-width: 1.4rem;
    text-align: center;
    flex-shrink: 0;
    /* 2026-09-03 (polimento): contador de postagens -- mesmo motivo do
       .paginacao-atual, evita o badge "respirar" ao trocar de dígito. */
    font-variant-numeric: tabular-nums;
}
.corpo-badge-postagens:hover { text-decoration: none; filter: brightness(1.1); }

/* ===== Formulários ===== */
form p { margin: 0 0 var(--e-4); }
label { display: block; font-size: var(--t-caption); font-weight: 500; margin-bottom: var(--e-1); color: var(--tinta); }
input, textarea, select {
    width: 100%;
    min-height: 2.75rem;
    padding: var(--e-3) var(--e-3);
    border: 1px solid var(--linha-forte);
    border-radius: var(--radius);
    font-family: inherit;
    font-size: var(--t-body);
    background: var(--superficie);
    color: var(--tinta);
}
/* 2026-09-03 (polimento): select nativo destoava dos inputs/botões ao
   redor -- seta do sistema operacional, sem relação com o resto do
   Design System. Seta própria (mesmo --linha-forte #8C8CAA já usado como
   contorno neutro em todo o arquivo, nenhuma cor nova) + appearance:none
   pra tirar a seta padrão do navegador. */
select {
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none'%3E%3Cpath d='M6 9l6 6 6-6' stroke='%238C8CAA' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right var(--e-3) center;
    background-size: 16px;
    padding-right: calc(var(--e-3) + 22px);
}
/* Checkbox/radio não devem esticar pra 100% de largura como os campos de
   texto (2026-07-17: ficavam quebrados nas telas de confirmação/escolha). */
input[type="checkbox"], input[type="radio"] {
    width: auto;
    padding: 0;
    margin: 0 var(--e-2) 0 0;
    vertical-align: middle;
    /* 2026-08-31 (Felipe: "o quadrado fica todo desforme"): a regra acima
       impunha min-height 2.75rem, border e background a TODO input -- o
       checkbox virava uma caixa de 14x44px com borda propria, e o anel de
       foco seguia essa caixa, nao o glifo. Zerar os tres devolve o
       controle nativo, que ja desenha quadrado. flex-shrink impede que ele
       seja espremido quando o label e' flex e o texto e' longo. */
    min-height: 0;
    flex-shrink: 0;
    border: none;
    background: none;
    accent-color: var(--navy-600);
}

/* Grupo de rádio do Django (RadioSelect) — lista sem marcador, uma opção
   por linha, com respiro. */
form ul:has(input[type="radio"]) {
    list-style: none;
    margin: 0;
    padding: 0;
}
form ul:has(input[type="radio"]) li { margin-bottom: var(--e-2); font-size: var(--t-body); }
form ul:has(input[type="radio"]) label { display: inline; font-weight: 400; }

/* 2026-08-27: o halo de foco usava var(--navy-100) (#F0EDFB), que da
   1.15:1 contra o branco do campo -- na pratica invisivel, e o `outline:
   none` logo acima tinha tirado o indicador nativo (falha WCAG 2.4.7).
   Trocado por --navy-600 a 55% sobre branco = #938abf, 3.17:1, que passa
   o minimo de 3:1 de 2.4.11 (contraste de componente nao-textual).
   Testado tambem 25% (#cecae2, 1.59:1) e 45% (#a79fca, 2.48:1): ambos
   ainda reprovam, por isso 55% e nao os 25% sugeridos pela auditoria. */
input:focus, textarea:focus, select:focus {
    border-color: var(--navy-600);
    outline: none;
    box-shadow: var(--foco-anel);
}
button, .btn {
    /* display:flex real (2026-08-26, achado do Felipe: texto do botão
       desalinhado) -- sem isso, o `justify-content: center` mais abaixo
       no arquivo (perto de .documentos-filtros) não fazia nada: a
       propriedade só tem efeito em container flex/grid, e <button> puro
       nunca foi um. Texto ficava alinhado ao padrão do navegador em vez
       de centralizado de verdade. */
    display: inline-flex;
    align-items: center;
    background: var(--navy-600);
    color: var(--superficie);
    border: none;
    /* 40px = "Default" do Design System oficial (era 42.4px, fora da escala). */
    min-height: var(--altura-botao);
    padding: var(--e-2) var(--e-6);
    border-radius: var(--radius);
    /* 700 -> 500. So' existem os pesos 300/400/500/700/900 na NeueHaas, entao
       600 estaria fora de questao de qualquer forma; 500 com tracking positivo
       minimo e' o peso que Geist, Linear e o primario do Stripe usam. 700 em
       0.9rem sobre preenchimento cheio le como aviso, nao como acao. */
    font-size: var(--t-caption);
    font-weight: 500;
    letter-spacing: 0.01em;
    cursor: pointer;
    box-shadow: var(--sombra-botao);
    transition: background var(--transicao-botao), box-shadow var(--transicao-botao), transform var(--transicao-botao);
}
button:hover {
    background: var(--navy-600-hover);
    box-shadow: var(--sombra-botao-hover);
    transform: translateY(-1px);
}
/* O --foco-anel roxo sobre preenchimento roxo e' invisivel. */
button:focus-visible {
    outline: none;
    box-shadow: var(--foco-anel-solido);
}
/* Estado exigido pelo Design System ("Estados: Disabled, With Icon, Loading")
   e que nao existia em nenhuma das 3560 linhas: um botao desabilitado ficava
   pixel a pixel identico a um habilitado. */
button:disabled,
.btn[aria-disabled="true"] {
    opacity: 0.45;
    cursor: not-allowed;
    box-shadow: none;
    transform: none;
}
button:disabled:hover,
.btn[aria-disabled="true"]:hover {
    background: var(--navy-600);
    box-shadow: none;
    transform: none;
}
/* Botao primario de acao destrutiva (ex.: "Excluir definitivamente") -
   vermelho em vez do navy padrao, sinalizando a consequencia antes do
   clique (2026-07-18). */
button.perigo { background: var(--urgente); }
button.perigo:hover { background: var(--urgente-escuro); box-shadow: var(--sombra-botao-perigo-hover); }
a.btn { display: inline-flex; align-items: center; color: var(--superficie); }
a.btn:hover {
    color: var(--superficie);
    text-decoration: none;
    background: var(--navy-600-hover);
    box-shadow: var(--sombra-botao-hover);
    transform: translateY(-1px);
}
a.btn:focus-visible { outline: none; box-shadow: var(--foco-anel-solido); }

/* Cards de formulario e confirmacao (2026-07-18, pesquisa: formulario
   deve ser um card fechado, nao ficar solto na pagina; confirmacao de
   acao destrutiva precisa de peso visual, nao so texto corrido). */
.container h1, .container h2 { font-family: var(--grotesk); }

.form-card {
    background: var(--superficie);
    border-radius: var(--radius);
    box-shadow: var(--sombra);
    padding: var(--e-8) var(--e-8);
    max-width: 640px;
}
.form-card h1 { margin-top: 0; }
/* 2026-09-08, pedido do Felipe: "Postagens" no perfil (core/perfil.html)
   ficava espremida no max-width de formulario -- titulo longo quebrava
   linha colado no selo/data. So' esta instancia, os outros .form-card
   (login, criar aviso etc.) continuam no mesmo limite de sempre. */
.form-card--largo { max-width: 60rem; }

/* 2026-08-27: .imagem-capa-preview e' usada em banners/criar.html:27 e
   banners/editar.html:26 pro preview da capa, mas NUNCA existiu no CSS.
   Sem regra nenhuma, a imagem renderizava em tamanho natural (upload
   permite ate' 5MB, entao facilmente 3000px de largura) e era cortada
   pelo overflow:hidden do .form-card -- o usuario via uma tira do canto
   superior esquerdo da propria foto e nao entendia o que era.
   O `img { max-width: 100% }` global (topo do arquivo) ja impede o
   estouro; esta classe limita tambem a ALTURA, senao uma foto retrato de
   3000px de altura empurraria o botao de salvar pra fora da tela. */
.imagem-capa-preview {
    display: block;
    max-width: 100%;
    height: auto;
    max-height: 12rem;
    object-fit: cover;
    border-radius: var(--radius);
}
/* 2026-09-03 (achado QA, bug que eu mesmo introduzi): o atributo `hidden`
   tem a MESMA especificidade de uma classe -- sem isto, `display: block`
   acima vencia o `display: none` do hidden por vir depois na cascata, e
   o <img id="preview-imagem-aviso"> sem src aparecia como icone de imagem
   quebrada em Criar aviso antes do usuario escolher um arquivo. */
.imagem-capa-preview[hidden] { display: none; }
.form-card > p:first-of-type { color: var(--tinta-suave); font-size: var(--t-body); }

.form-acoes {
    display: flex;
    gap: var(--e-4);
    align-items: center;
    margin-top: var(--e-6);
}

.confirmacao-card {
    background: var(--superficie);
    border-radius: var(--radius);
    box-shadow: var(--sombra);
    padding: var(--e-8) var(--e-8);
    max-width: 560px;
    /* Faixa no topo, não lateral (2026-07-20, auditoria: anti-padrão). */
    border-top: 4px solid var(--navy-600);
}
.confirmacao-card.perigo { border-top-color: var(--urgente); }
.confirmacao-card h1 { margin-top: 0; }
.confirmacao-card p { color: var(--tinta-suave); }
.confirmacao-card label {
    display: flex;
    align-items: center;
    gap: var(--e-2);
    font-weight: 500;
    font-size: var(--t-body);
    background: var(--papel);
    padding: var(--e-3) var(--e-4);
    border-radius: var(--radius);
    margin: var(--e-4) 0;
    color: var(--tinta);
}
.confirmacao-card.perigo label { background: var(--urgente-100); }

/* Aprovação por gestor (2026-09-01, pedido do Felipe). Aqui e não no fim do
   arquivo de propósito: o fim é o bloco @media (max-width: 640px), e o
   DESIGN.md proíbe regra-base depois dos overrides de mobile. */
.confirmacao-nota {
    background: var(--papel);
    border-left: 3px solid var(--navy-600);
    padding: var(--e-3) var(--e-4);
    border-radius: var(--radius);
    margin: var(--e-4) 0;
    font-size: var(--t-caption);
    /* min-width: 0 porque motivo de recusa é texto livre: sem isto uma URL
       ou nome de arquivo sem espaço empurra a coluna e a página ganha barra
       horizontal (invariante de layout do DESIGN.md). */
    min-width: 0;
}
.confirmacao-nota.atencao { border-left-color: var(--urgente); }
.confirmacao-recusa {
    margin-top: var(--e-6);
    padding-top: var(--e-6);
    border-top: 1px solid var(--linha);
}
.confirmacao-recusa textarea {
    width: 100%;
    min-width: 0;
    margin-top: var(--e-2);
}

/* ===== Perfil de usuário (Redesenhado 2026-07-20) ===== */
.perfil-grid {
    display: grid;
    grid-template-columns: 280px minmax(0, 1fr);
    gap: var(--e-8);
    align-items: start;
    margin-top: var(--e-6);
}

.perfil-sidebar {
    display: flex;
    flex-direction: column;
    gap: var(--e-6);
}

.perfil-card-identidade {
    background: var(--superficie);
    border-radius: var(--radius);
    box-shadow: var(--sombra);
    padding: var(--e-8) var(--e-8);
    text-align: center;
    /* --navy-950 era o unico card do sistema ainda com essa cor -- todos os
       outros (banner-card, setor-card, form-card, painel-gestao,
       documento-detalhe-cabecalho) usam --navy-600 (2026-08-21, achado no
       audit: pagina de perfil inconsistente com o resto). */
    border-top: 4px solid var(--navy-600);
}

.perfil-card-avatar-wrapper {
    position: relative;
    width: 110px;
    height: 110px;
    margin: 0 auto var(--e-6);
}

.perfil-avatar,
.perfil-avatar-vazio {
    width: 110px;
    height: 110px;
    border-radius: var(--radius-circulo);
    display: block;
    box-shadow: var(--sombra);
}

.perfil-avatar {
    object-fit: cover;
    background: var(--papel);
}

.perfil-avatar-vazio {
    display: flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: 1px dashed var(--linha-forte);
    color: var(--linha-forte);
}

.perfil-card-nome {
    font-family: var(--grotesk);
    font-size: var(--t-h4);
    font-weight: 700;
    color: var(--tinta);
    margin: 0 0 var(--e-1);
    line-height: 1.2;
}

.perfil-card-username {
    font-family: var(--mono);
    font-size: var(--t-caption);
    color: var(--tinta-suave);
    margin: 0 0 var(--e-6);
}

.perfil-card-meta-lista {
    list-style: none;
    padding: 0;
    margin: var(--e-6) 0 0;
    border-top: 1px solid var(--linha);
    text-align: left;
}

.perfil-card-meta-item {
    padding: var(--e-3) 0;
    border-bottom: 1px solid var(--linha);
    display: flex;
    flex-direction: column;
    gap: var(--e-1);
}

.perfil-card-meta-item:last-child {
    border-bottom: none;
}

.perfil-card-meta-rotulo {
    font-family: var(--mono);
    font-size: var(--t-overline);
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--tinta-suave);
}

.perfil-card-meta-valor {
    font-size: var(--t-caption);
    color: var(--tinta);
    /* 2026-08-28: aqui tinha `word-break: break-all`, que quebra QUALQUER
       palavra em QUALQUER caractere pra preencher a linha -- e esta classe
       carrega setor, cargo e funcao, nao so' e-mail. Em coluna estreita
       "Tecnico de Redes" virava "Tecni/co", exatamente o defeito que o
       Felipe declarou inaceitavel. Nao foi trocado por outra regra porque
       nao precisa: o :where(...span...) la' em cima ja' da
       `overflow-wrap: break-word`, que quebra o e-mail longo (palavra unica
       que nao cabe sozinha na linha) e deixa a prosa em paz. */
}

.perfil-status-pill {
    font-family: var(--mono);
    font-size: var(--t-label);
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    padding: var(--e-1) var(--e-2);
    border-radius: var(--radius-sm);
    background: var(--navy-100);
    color: var(--navy-800);
    display: inline-block;
}
/* 2026-08-27: texto era var(--urgente) sobre var(--urgente-100) = 4.35:1
   (reprova AA); var(--urgente-escuro) = 6.03:1. */
.perfil-status-pill.inativo {
    background: var(--urgente-100);
    color: var(--urgente-escuro);
}

/* Controles de foto estilo "cartao de perfil" -- 2 botoes-icone sobre o
   proprio avatar em vez de bloco de botao retangular + texto + checkbox
   (2026-08-21, achado do Felipe: a caixa antiga lia como formulario de RH,
   nao como perfil pessoal). Trocar (camera) sempre visivel; remover (lixeira)
   so' aparece quando ja existe foto -- mesma logica condicional de antes. */
.perfil-avatar-imagem {
    display: block;
}

.perfil-avatar-acao {
    position: absolute;
    width: 28px;
    height: 28px;
    border-radius: var(--radius-pill);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--navy-600);
    color: var(--superficie);
    border: 2px solid var(--superficie);
    box-shadow: var(--sombra);
    cursor: pointer;
    transition: background var(--transicao), transform 100ms ease;
}
.perfil-avatar-acao:hover { background: var(--navy-600-hover); }
.perfil-avatar-acao:active { transform: translateY(1px); }
.perfil-avatar-acao svg { pointer-events: none; }

/* Os dois na base do circulo, um em cada lado (2026-08-21, pedido do
   Felipe: lixeira na esquerda, camera na direita, ambos na base). Offset
   negativo (-6px) pra ficarem majoritariamente FORA do circulo -- so' a
   metade de cima de cada botao toca a borda da foto. */
.perfil-avatar-acao--trocar { bottom: -6px; right: -6px; }

.perfil-avatar-acao--remover {
    bottom: -6px;
    left: -6px;
    background: var(--urgente);
}
.perfil-avatar-acao--remover:hover { background: var(--urgente-escuro); }
.perfil-avatar-acao--remover:has(.perfil-avatar-remover-checkbox:checked) {
    background: var(--urgente-escuro);
}

/* Input real continua clipado a 1x1px (padrão de acessibilidade pra
   esconder visualmente sem tirar do tab order, 2026-07-20) -- mas isso
   também clipa o :focus-visible padrão, deixando quem navega por teclado
   sem indicação de foco. :has() repassa o estado de foco pro botão-ícone
   visível que acompanha cada input (mesmo achado de antes, adaptado pro
   novo formato de botão redondo). */
.perfil-upload-input,
.perfil-avatar-remover-checkbox {
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    padding: 0 !important;
    margin: -1px !important;
    overflow: hidden !important;
    clip: rect(0, 0, 0, 0) !important;
    border: 0 !important;
    opacity: 0 !important;
}
.perfil-upload-input { pointer-events: none !important; }
.perfil-card-avatar-wrapper:has(.perfil-upload-input:focus-visible) .perfil-avatar-acao--trocar,
.perfil-avatar-acao--remover:has(.perfil-avatar-remover-checkbox:focus-visible) {
    outline: 2px solid var(--navy-950);
    outline-offset: 2px;
}

.perfil-upload-status {
    min-height: 1.1rem;
    margin: 0 0 var(--e-6);
    font-size: var(--t-caption);
    color: var(--navy-600);
    font-weight: 500;
}

.perfil-avatar-salvar {
    margin: 0 0 var(--e-6);
}

/* Aviso "dados vem do AD" (2026-08-21, pedido do Felipe: nada alem da
   foto e' editavel, precisa avisar de onde vem o resto e como corrigir).
   Mesma faixa-no-topo de .mensagens li, cor institucional neutra (nao e'
   erro nem sucesso, so' informativo). */
.perfil-aviso-ad {
    display: flex;
    align-items: flex-start;
    gap: var(--e-3);
    background: var(--navy-100);
    border-top: 3px solid var(--navy-600);
    border-radius: var(--radius);
    padding: var(--e-4) var(--e-4);
    margin: 0 0 var(--e-6);
    font-size: var(--t-caption);
    color: var(--tinta);
}
.perfil-aviso-ad svg {
    flex-shrink: 0;
    margin-top: var(--e-1);
    color: var(--navy-600);
}
.perfil-aviso-ad p {
    margin: 0;
}

.perfil-foto-erro {
    color: var(--urgente);
    font-size: var(--t-caption);
    margin-top: var(--e-2);
}

/* Edit form cards styling */
.perfil-secao-titulo {
    font-family: var(--grotesk);
    font-size: var(--t-h5);
    font-weight: 700;
    color: var(--navy-950);
    margin: var(--e-6) 0 var(--e-4);
    padding-bottom: var(--e-2);
    border-bottom: 1px solid var(--linha);
}
/* Substitui o style="margin-top: 2rem" inline que a CSP do projeto
   bloqueava silenciosamente (2026-08-21, auditoria: style-src 'self',
   sem unsafe-inline -- mesma classe de bug ja corrigida no BlocoHome). */
.perfil-secao-titulo--espacada { margin-top: var(--e-8); }

.perfil-secao-titulo:first-of-type {
    margin-top: 0;
}

.perfil-form-linha {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--e-6);
}

.perfil-form-linha p {
    margin: 0 0 var(--e-4);
}

/* Funcao entrou na mesma grade de Nome/Sobrenome pra nao ter secao propria
   so' pra 1 campo (2026-08-21, achado do Felipe: "Função" repetido como
   titulo de secao e rotulo de campo, layout ruim). 3o item numa grade de
   2 colunas sobraria sozinho numa linha pela metade -- ocupa a linha
   inteira em vez disso. */
.perfil-form-linha-larga {
    grid-column: 1 / -1;
}

.perfil-form-linha p label,
.form-card p label {
    display: block;
    font-size: var(--t-caption);
    font-weight: 500;
    color: var(--tinta);
    margin-bottom: var(--e-2);
}

.perfil-campo-erro {
    color: var(--urgente);
    font-size: var(--t-caption);
    display: block;
    margin-top: var(--e-1);
}

/* Erro de campo do Django (form.as_p) — sem isso, .errorlist saía sem
   nenhum estilo do sistema (2026-07-21, auditoria). Mesmo tratamento de
   .perfil-campo-erro, já validado no perfil de usuário. */
.errorlist {
    list-style: none;
    margin: var(--e-1) 0 0;
    padding: 0;
    color: var(--urgente);
    font-size: var(--t-caption);
}
.errorlist li { margin: 0; }

/* View other profile details styling */
.perfil-info-lista {
    list-style: none;
    margin: 0 0 var(--e-6);
    padding: 0;
    background: var(--superficie);
    border-radius: var(--radius);
}

.perfil-info-lista li {
    padding: var(--e-3) var(--e-4);
    border-bottom: 1px solid var(--linha);
    font-size: var(--t-body);
    color: var(--tinta);
}

.perfil-info-lista li:last-child {
    border-bottom: none;
}

.perfil-info-lista li strong {
    font-weight: 500;
    color: var(--tinta-suave);
    margin-right: var(--e-2);
    font-family: var(--grotesk);
}

.perfil-bio {
    background: var(--papel);
    border-radius: var(--radius-sm);
    padding: var(--e-6) var(--e-6);
    color: var(--tinta);
    line-height: 1.6;
    font-size: var(--t-body);
}

.perfil-vazio-texto {
    color: var(--tinta-suave);
    font-style: italic;
    font-size: var(--t-caption);
}

/* Feedback tátil no clique — todo botão "afunda" um pouco (2026-07-17). */
button:active, .btn:active {
    transform: translateY(0);
    box-shadow: var(--sombra-botao);
}

/* Botão secundário: contorno que preenche no hover, "marca o quadrado"
   (2026-07-17, pedido do Felipe para as ações de Enviar documento/Criar
   aviso — hoje eram links soltos, sem affordance de botão). */
.btn-secundario {
    display: inline-flex;
    align-items: center;
    background: transparent;
    color: var(--navy-600);
    /* --linha-forte (#8C8CAA) da 3.03:1 sobre branco e e' o minimo de
       1.4.11 pro contorno do componente. --linha (#DDD9F0) seria mais bonito
       e da 1.28:1: reprova. Nao trocar. */
    border: 1px solid var(--linha-forte);
    /* Sem min-height proprio, um <button class="btn-secundario"> herdava a
       altura da regra base e um <a class="btn-secundario"> nao herdava nada:
       lado a lado, alturas diferentes (42.4 x ~38px). */
    min-height: var(--altura-botao);
    padding: var(--e-2) var(--e-4);
    border-radius: var(--radius);
    font-size: var(--t-caption);
    font-weight: 500;
    letter-spacing: 0.01em;
    cursor: pointer;
    box-shadow: var(--sombra-botao-leve);
    transition: background var(--transicao-botao), border-color var(--transicao-botao), box-shadow var(--transicao-botao), transform var(--transicao-botao);
}
.btn-secundario:hover {
    background: var(--navy-100);
    border-color: var(--navy-600);
    text-decoration: none;
    box-shadow: var(--sombra-botao);
    transform: translateY(-1px);
}
/* Fundo claro: aqui o anel roxo normal aparece, o solido (ring branco
   interno) sumiria contra o proprio botao. */
.btn-secundario:focus-visible {
    outline: none;
    border-color: var(--navy-600);
    box-shadow: var(--foco-anel);
}
.btn-secundario:active { transform: translateY(0); box-shadow: var(--sombra-botao-leve); }

/* Variante de perigo — ações destrutivas (excluir) marcam vermelho no
   hover em vez de navy, sinalizando a consequência antes do clique. */
/* 2026-08-27: mesmo par reprovado (4.35:1) achado fora da lista da
   auditoria -- corrigido junto, e' a mesma causa raiz. Borda segue
   --urgente cheio (preenchimento, nao texto). */
.btn-secundario.btn-perigo:hover {
    background: var(--urgente-100);
    border-color: var(--urgente);
    color: var(--urgente-escuro);
}

.site-footer {
    text-align: center;
    color: var(--tinta-suave);
    font-size: var(--t-caption);
    padding: var(--e-8);
}

/* Botão de logout no cabeçalho, disfarçado de link — resets de <button>
   só; cor/hover/foco/sublinhado vêm do seletor compartilhado com
   ".site-header nav a" lá em cima. Virou so' icone (2026-08-21, pedido
   do Felipe: texto "SAIR" desalinhado dos outros itens do menu) --
   causa raiz do desalinhamento era o <button> manter o padding padrao
   do navegador (nunca zerado aqui), deixando a caixa mais alta que a
   de um <a> vizinho no mesmo flex; padding:0 + inline-flex centralizado
   resolve por igual pro texto (quando tinha) e pro icone agora. */
.logout-form { display: inline; margin: 0; padding: 0; }
.logout-form .link-button {
    display: inline-flex;
    align-items: center;
    background: none;
    border: none;
    margin: 0;
    padding: 0;
    min-height: 0;
    box-shadow: none;
    line-height: 1;
    font-family: inherit;
    cursor: pointer;
    text-decoration: none;
}

/* Barra de filtros de documentos (2026-07-17, revisão — pills simples não
   davam pra ordenar por data/publicador; virou uma barra de busca + selects). */
.documentos-filtros {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--e-2);
    margin-bottom: var(--e-4);
}
.documentos-filtros-busca { flex: 1 1 220px; min-width: 180px; }
.documentos-filtros select { width: auto; flex: 0 0 auto; }
.documentos-filtros button { flex-shrink: 0; }
.documentos-filtros-limpar {
    font-size: var(--t-caption);
    color: var(--tinta-suave);
}

.lista-documentos-meta {
    font-family: var(--mono);
    font-size: var(--t-label);
    color: var(--tinta-suave);
    /* 2026-08-24, achado em revisao de UX: flex item de texto sem
       min-width:0 recusa encolher abaixo do proprio conteudo (default
       min-width:auto do flexbox) -- linha inteira da home estourava a
       largura da viewport e forcava scroll horizontal na pagina toda. */
    min-width: 0;
}

/* ===== Página Informativos ===== */
.filtro-informativos {
    display: flex;
    gap: var(--e-2);
    margin-bottom: var(--e-6);
}
.filtro-informativos a {
    padding: var(--e-2) var(--e-4);
    border-radius: var(--radius-pill);
    background: var(--superficie);
    border: 1px solid var(--linha-forte);
    color: var(--tinta-suave);
    font-size: var(--t-caption);
}
.filtro-informativos a.filtro-ativo {
    background: var(--navy-600);
    border-color: var(--navy-600);
    color: var(--superficie);
}

.lista-informativos {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--e-2);
}
.lista-informativos li {
    background: var(--superficie);
    border-radius: var(--radius);
    box-shadow: var(--sombra);
    padding: var(--e-4) var(--e-4);
    display: flex;
    /* 2026-08-28: mesma falha de `.alerta-item` -- linha rigida de 4+ itens
       (setor, "NOVO", titulo, validade) sem permissao de quebrar. Em telas
       estreitas o titulo empurrava a validade pra fora do cartao e os dois se
       sobrepunham. Quebra antes de espremer. */
    flex-wrap: wrap;
    align-items: center;
    gap: var(--e-2);
    row-gap: var(--e-2);
    /* Faixa no topo, não lateral (2026-07-20, auditoria: anti-padrão) —
       mesmo idioma de .banner-card, que já usava border-top. */
    border-top: 3px solid var(--terracota);
}
.lista-informativos li.lido {
    border-top-color: var(--linha-forte);
    opacity: 0.75;
}

/* ===== Telas pré-login — páginas independentes, sem sidebar/cabeçalho do
   resto do sistema (2026-07-17, pedido do Felipe: "quero algo bonito").

   ⚠️ ESTE BLOCO SERVE QUATRO TELAS: login, confirmar_login, 404 e 500.
   `.login-shell`, `.login-card`, `.login-marca`, `.login-marca-legenda` e
   `.login-rodape` são de todas. **Antes de mexer em qualquer `.login-*`,
   rodar `grep -rn 'login-' --include=*.html`.** O que é só do login mora
   sob `.login-slab` — nenhuma das outras três o emite, então nada vaza.
   (Em 29/08 uma regra `.login-marca p` (0,1,1) chegou a vencer
   `.login-marca-legenda` (0,1,0) por especificidade e repintou o selo das
   três; pego pelo harness antes de publicar. Não repetir o padrão.)

   Redesenho 2026-08-29, 2ª rodada. Felipe: *"ainda achei o layout confuso
   e não vivo. Os textos escritos podem ficar contidos em um 'i' que ao
   passar o mouse traga a informação."* Uma resposta pra cada:

   CONFUSO -> o card único misturava três trabalhos (dizer o que é o
   sistema, explicar a credencial, receber usuário e senha) numa coluna
   só, e por isso lia como uma pilha de parágrafos com dois campos no
   meio. Virou LÂMINA de duas metades: a esquerda é institucional (marca
   + o que é o sistema), a direita é a tarefa (título, dois campos,
   botão). Cada metade tem um trabalho. Abaixo de 900px empilha, e a
   metade institucional vira o topo da mesma lâmina.

   NÃO VIVO -> o card branco flutuava num campo roxo sem nenhuma outra
   massa de cor: a tela inteira era branco contra roxo claro, dois
   valores próximos. Agora a lâmina é near-black contra branco, sobre o
   roxo iluminado — três valores bem separados. **Nenhum tom novo:** o
   painel usa `--navy-950` (#1B1731, "Preto Texto" do Design System
   oficial, que o DESIGN.md já registra como papel estrutural). A regra
   permanente do Felipe ("a cor não quero que altere") continua valendo —
   o diff de tokens deste arquivo segue vazio.

   TEXTOS EM "i" -> reusa `.info-tip`, o componente que o projeto já tem
   (gatilho de 24×24 por WCAG 2.5.8, balão alcançável pelo ponteiro por
   1.4.13, `aria-label` próprio por 4.1.2). Não foi criado um segundo
   tooltip. ⚠️ Por causa dele a lâmina **não** pode usar `overflow:
   hidden` pros cantos: em 28/08 um balão foi recortado exatamente assim
   dentro de um card arredondado. O raio vai nas duas metades. */
body.pagina-login {
    /* Duas camadas de LUZ sobre o gradiente, que continua idêntico na
       base (última da pilha). Nenhum tom novo: só branco e --navy-600
       em alpha — a mesma técnica que --foco-anel e --sombra-botao-hover
       já usam neste arquivo, e por isso escritos em rgba() literal com o
       valor comentado, não em var() (rgba não aceita custom property).

       1. Halo branco atrás da lâmina (a "fonte de luz"): é o que separa
          uma superfície iluminada de tinta chapada.
       2. Base no ponto ESCURO do próprio gradiente a 55%: assenta o rodapé
          e dá profundidade. Não é vinheta decorativa — é a cor escura da
          marca reforçando o próprio sentido do gradiente.
          2026-09-01: era rgba(59,42,138) = #3B2A8A, que ERA o ponto escuro
          do gradiente antigo. Com a troca pedida pela Comunicação esse tom
          deixou de existir no gradiente, e mantê-lo teria introduzido um
          terceiro roxo na tela. Agora é #5D4988, o novo ponto escuro. */
    background:
        radial-gradient(ellipse 62% 66% at 50% 44%,
            rgba(255, 255, 255, 0.17) 0%, rgba(255, 255, 255, 0) 64%),
        radial-gradient(ellipse 120% 60% at 50% 118%,
            rgba(93, 73, 136, 0.55) 0%, rgba(93, 73, 136, 0) 70%),
        var(--gradiente-marca);
    min-height: 100vh;
}

.login-shell {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: var(--e-12) var(--e-6);
}

/* Logo oficial da marca (2026-08-28, auditoria: login/404/500 eram as
   únicas telas sem ela). Só existe a variante CLARA — por isso ela nunca
   vai sobre o card branco: no login mora no painel escuro da lâmina, nas
   outras três continua sobre o gradiente. */
.login-logo {
    margin: 0 0 var(--e-6);
    line-height: 0;
    animation: login-surge 400ms cubic-bezier(0.22, 1, 0.36, 1) both;
}
.login-logo img {
    height: 2.9rem;
    width: auto;
    display: block;
}

.login-card {
    width: 100%;
    max-width: 400px;
    background: var(--superficie);
    border-radius: var(--radius-lg);
    box-shadow: var(--sombra-modal);
    padding: var(--e-8) var(--e-8) var(--e-8);
    animation: login-surge 480ms cubic-bezier(0.22, 1, 0.36, 1) 80ms both;
}

/* Cabeçalho das telas irmãs ("ERRO 404", "ERRO 500", "CONFIRME SUA
   CONTA"). O login não usa nenhum dos dois: tem `.login-titulo`. */
.login-marca {
    text-align: center;
    margin-bottom: var(--e-8);
    padding-bottom: var(--e-6);
    border-bottom: 1px solid var(--linha);
}
.login-marca-legenda {
    margin: var(--e-1) 0 0;
    font-family: var(--mono);
    font-size: var(--t-label);
    font-weight: 500;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--tinta-suave);
}

/* ===== Só do login: a lâmina de duas metades ===== */

.login-slab {
    width: 100%;
    max-width: 860px;
    display: grid;
    /* A sombra e a animação são da LÂMINA, não das metades: card dentro
       de card é sempre erro, e duas metades animando em separado deixam
       ver o fundo pela junta. */
    box-shadow: var(--sombra-modal);
    animation: login-surge 520ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

.login-painel {
    /* "Preto Texto" (#1B1731) do Design System oficial, aqui como
       superfície. É o que dá à tela um terceiro valor: near-black,
       branco e o roxo iluminado atrás. Sem ele o painel seria roxo
       sobre roxo e a lâmina perderia a metade esquerda. */
    background: var(--navy-950);
    color: var(--superficie);
    padding: var(--e-12) var(--e-8);
    display: flex;
    flex-direction: column;
    /* Empilhado (< 900px): a metade institucional é o TOPO da lâmina. */
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}
.login-painel .login-logo {
    margin: 0 0 var(--e-6);
    animation: none; /* quem entra é a lâmina inteira */
}
.login-painel .login-logo img { height: 3.2rem; }

.login-painel-frase {
    margin: 0;
    font-size: var(--t-h5);
    font-weight: 400;
    line-height: 1.4;
    letter-spacing: -0.01em;
    color: var(--navy-claro);
    text-wrap: pretty;
    max-width: 22ch;
}
/* Saída pública, no painel e não no card: quem chega aqui sem conta
   (aluno, ex-aluno, visitante) precisa de um caminho, e o LDAP nunca vai
   ter conta pra essas pessoas. Link em branco cheio sobre o painel
   near-black = 17,3:1; o `--navy-tenue` da nota abaixo dá 15,7:1. */
.login-painel-publico {
    margin: var(--e-8) 0 0;
    display: flex;
    flex-direction: column;
    gap: var(--e-1);
    font-size: var(--t-caption);
}
.login-painel-publico a {
    color: var(--superficie);
    font-weight: 500;
    text-decoration: underline;
    text-underline-offset: 3px;
    /* O sublinhado já marca o link; o hover muda a espessura em vez da cor,
       porque não existe um segundo branco na paleta. */
    text-decoration-thickness: 1px;
    transition: text-decoration-thickness var(--transicao);
}
.login-painel-publico a:hover,
.login-painel-publico a:focus-visible { text-decoration-thickness: 2px; }
.login-painel-publico a:focus-visible { outline: 2px solid var(--superficie); outline-offset: 3px; }
.login-painel-publico-nota {
    color: var(--navy-tenue);
    font-size: var(--t-caption);
}

/* Assinatura institucional no pé do painel. Empurrada pro fundo por
   margin-top:auto — só tem efeito quando a coluna tem altura sobrando,
   que é exatamente o caso de 900px pra cima. */
.login-painel-rodape {
    margin: var(--e-8) 0 0;
    font-family: var(--mono);
    font-size: var(--t-label);
    font-weight: 500;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--navy-tenue);
    opacity: 0.75;
}

/* A metade branca é o `.login-card`, sem a moldura própria: a lâmina já
   tem sombra e raio. */
.login-slab .login-card {
    max-width: none;
    box-shadow: none;
    animation: none;
    border-radius: 0 0 var(--radius-lg) var(--radius-lg);
    padding: var(--e-8) var(--e-8) var(--e-8);
    display: flex;
    flex-direction: column;
    justify-content: center;
}

/* 2026-08-31 (auditoria): era min-width:900px, que casa NO MESMO pixel que
   os 7 blocos `max-width: 900px` do arquivo -- a 900px exatos o login
   recebia grade desktop com o resto do app em modo mobile. 901px alinha
   com o divisor estrutural ja usado em .sidebar (linha ~553). */
@media (min-width: 901px) {
    .login-slab { grid-template-columns: minmax(0, 0.82fr) minmax(0, 1fr); }
    .login-painel {
        padding: var(--e-12) var(--e-12);
        border-radius: var(--radius-lg) 0 0 var(--radius-lg);
    }
    /* 2026-09-01 (pedido da Comunicação: mover a logo e a massa de texto do
       topo do painel para o miolo). Duas margens automáticas na MESMA
       coluna flex repartem a sobra em partes iguais: uma acima da logo,
       outra acima da assinatura. Resultado: o grupo logo + frase + link
       desce para o meio e "COPPEAD / UFRJ" continua colado no pé.

       Só dentro deste @media de propósito: empilhado (<901px) o painel é o
       topo da lâmina e não tem altura sobrando -- `auto` viraria zero e a
       regra seria ruído. */
    .login-painel .login-logo { margin-top: auto; }
    .login-painel-rodape { margin-top: auto; }
    .login-slab .login-card {
        border-radius: 0 var(--radius-lg) var(--radius-lg) 0;
        padding: var(--e-12) var(--e-12);
    }
}

.login-titulo {
    margin: 0 0 var(--e-8);
    font-size: var(--t-h4);
    font-weight: 700;
    letter-spacing: -0.01em;
    line-height: 1.2;
    color: var(--tinta);
}

/* `.campo` existe por dois motivos: o :focus-within abaixo, e trocar o
   empilhamento por margin (que precisava da exceção
   `label:first-of-type`) por um grid com gap único. */
.login-form {
    display: grid;
    gap: var(--e-4);
}
/* Rótulo e o "i" na mesma linha. `gap: 2px` porque o gatilho já tem
   24px de alvo com o glifo de 14px centralizado dentro: um gap maior
   afastaria o ícone do rótulo que ele explica. */
.campo-cabecalho {
    display: flex;
    align-items: center;
    gap: var(--e-1);
    margin-bottom: var(--e-2);
}
.campo-cabecalho label {
    margin-bottom: 0;
    transition: color var(--transicao);
}
/* Feedback de estado, não enfeite: o rótulo do campo em foco assume a
   cor de marca junto com o anel do input. */
.login-form .campo:focus-within .campo-cabecalho label { color: var(--navy-600); }

/* O balão do componente é `position:absolute` ancorado no `.info-tip`,
   que tem 24px de largura. Isso produz dois defeitos aqui, os dois pegos
   no harness:

     1. sem largura própria, o shrink-to-fit dentro de um containing block
        de 24px encolhe o balão até o min-content e o texto sai UMA
        PALAVRA POR LINHA -- o defeito de quebra que o Felipe pediu para
        nunca mais acontecer (regra permanente, 28/08);
     2. dando `width: max-content; max-width: 260px`, resolve no desktop e
        ESTOURA a viewport em 360px e 320px (medido: +45px e +85px), porque
        o gatilho já começa a ~120px da borda.

   Largura fixa não resolve os dois: qualquer valor grande o bastante para
   o texto respirar é grande demais para 320px. A saída é o balão parar de
   se ancorar no ícone e passar a se ancorar na LINHA (o cabeçalho do campo
   ou o rodapé de ajuda), que tem exatamente a largura do card. `left` e
   `right` em 0 e o balão mede sempre o card: nunca estoura, nunca quebra,
   em nenhuma largura. Para isso o `.info-tip` precisa sair de
   `position: relative` -- é o que o torna containing block. */
.login-card .campo-cabecalho,
.login-card .login-ajuda { position: relative; }
.login-card .info-tip { position: static; }
.login-card .info-tip-balao {
    left: 0;
    right: 0;
    width: auto;
    max-width: none;
    transform: translateY(4px);
}
.login-card .info-tip:hover .info-tip-balao,
.login-card .info-tip:focus-within .info-tip-balao {
    transform: translateY(0);
}

/* Mesmo defeito e mesma saida do .login-card acima, agora nos radios de
   Alcance/Visibilidade (banners/criar.html, banners/editar.html,
   documentos/upload.html, documentos/editar.html): o .info-tip ali
   envolve so' o botao de 24px, o balao encolhia no shrink-to-fit e o
   texto saia uma palavra por linha (achado UX 02/09). Ancora no <label>
   do radio, que tem a largura do campo. */
.form-card .campo-widget > div > div > label { position: relative; }
.form-card .campo-widget .info-tip { position: static; }
.form-card .campo-widget .info-tip-balao {
    left: 0;
    right: 0;
    width: auto;
    max-width: none;
    transform: translateY(4px);
}
.form-card .campo-widget .info-tip:hover .info-tip-balao,
.form-card .campo-widget .info-tip:focus-within .info-tip-balao {
    transform: translateY(0);
}

/* Texto de ajuda de formulário. Não é mais usado no login (virou balão de
   `.info-tip`), mas `banners/criar.html` e `banners/editar.html` usam —
   e lá também estava sem regra nenhuma, herdando --tinta cheia e pesando
   mais que o próprio <label>. A regra fica: corrige as duas telas. */
.campo-ajuda {
    display: block;
    margin-top: var(--e-2);
    font-size: var(--t-caption);
    line-height: 1.45;
    color: var(--tinta-suave);
    text-wrap: pretty;
}

/* ⚠️ `>` obrigatório, não é estilo. Escrito como `.login-form button` esta
   regra também pegava o `.info-tip-trigger`, que agora vive DENTRO do form:
   o gatilho do "i" ia a 38x48px esticado em vez dos 24x24 do componente,
   reprovando WCAG 2.5.8 justamente na peça criada pra cumpri-lo. Medido no
   harness antes de publicar. O botão de submit é filho direto; o gatilho
   não. */
.login-form > button {
    width: 100%;
    /* `button` base é inline-flex sem justify-content; num botão de
       largura total isso deixa o rótulo à esquerda. */
    justify-content: center;
    margin-top: var(--e-1);
    /* Ação única e principal da página -> tamanho "Large" do Design System. */
    min-height: var(--altura-botao-lg);
    padding: var(--e-3);
    font-size: var(--t-body);
}

/* 2026-08-27: texto era var(--urgente) sobre var(--urgente-100) = 4.35:1
   (reprova AA) -- justamente a mensagem que o usuario MAIS precisa ler.
   var(--urgente-escuro) = 6.03:1. A faixa/borda continua --urgente cheio
   (cor de preenchimento nao e' texto, nao entra na regra 4.5:1). */
.login-erro {
    background: var(--urgente-100);
    color: var(--urgente-escuro);
    /* Faixa no topo, não lateral (2026-07-20, auditoria: anti-padrão). */
    border-top: 3px solid var(--urgente);
    border-radius: var(--radius-sm);
    padding: var(--e-2) var(--e-3);
    font-size: var(--t-caption);
    margin: 0 0 var(--e-6);
}

/* Rodapé DENTRO do card branco. Existe separado de `.login-rodape`
   porque aquele usa --navy-tenue (#f0e8f5), certo sobre o gradiente
   (6,2:1) e **1,2:1 aqui**: até 29/08 este texto estava ao vivo e
   invisível. --tinta-suave dá 8,5:1. */
.login-ajuda {
    display: flex;
    align-items: center;
    gap: var(--e-1);
    margin: var(--e-8) 0 0;
    padding-top: var(--e-6);
    border-top: 1px solid var(--linha);
    font-size: var(--t-caption);
    color: var(--tinta-suave);
}

/* FORA do card, sobre o gradiente — só as três telas irmãs usam. */
.login-rodape {
    margin-top: var(--e-8);
    font-size: var(--t-caption);
    /* 2026-09-01: era --navy-tenue (4,25:1 sobre o gradiente novo, reprova
       AA). Único texto destas telas que fica direto sobre o fundo. */
    color: var(--navy-claro);
    text-align: center;
}

@keyframes login-surge {
    from { opacity: 0; transform: translateY(12px); }
    to   { opacity: 1; transform: none; }
}
/* O conteúdo é visível por padrão: o `opacity: 0` só existe DENTRO do
   keyframe. Tirar a animação devolve o estado natural do elemento —
   nunca uma tela em branco (armadilha do reveal preso em opacity 0). */
@media (prefers-reduced-motion: reduce) {
    .login-logo,
    .login-card,
    .login-slab { animation: none; }
}
.lista-informativos li .banner-expira { margin-left: auto; flex-shrink: 0; }
/* Mesma causa raiz do .lista-documentos-meta acima: o titulo (link sem
   classe propria) e' o unico item que deveria crescer/encolher na linha;
   sem min-width:0 ele forcava overflow horizontal em titulos longos. */
.lista-informativos li a { flex: 1 1 auto; min-width: 0; }

/* Paginação redesenhada (2026-08-26, pedido do Felipe: "os botões do
   sistema estão simples demais... algo bonito e fluido, visual
   moderno"). Links viram pílulas com contorno (mesma linguagem ghost já
   usada em .aviso-card-botao/.btn-secundario -- elevação sutil no
   hover, não inventa um terceiro estilo de botão) e a página atual vira
   um selo preenchido na cor de marca, em vez de texto solto mono. */
.paginacao {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--e-3);
    margin-top: var(--e-8);
    padding-top: var(--e-6);
    border-top: 1px solid var(--linha);
    font-size: var(--t-caption);
}
.paginacao a {
    display: inline-flex;
    align-items: center;
    gap: var(--e-2);
    padding: var(--e-2) var(--e-4);
    border-radius: var(--radius-pill);
    border: 1px solid var(--linha-forte);
    background: var(--superficie);
    color: var(--navy-600);
    font-family: var(--grotesk);
    font-weight: 700;
    font-size: var(--t-caption);
    text-decoration: none;
    box-shadow: var(--sombra);
    transition: background var(--transicao), border-color var(--transicao), transform var(--transicao), box-shadow var(--transicao);
}
.paginacao a:hover, .paginacao a:focus-visible {
    background: var(--navy-100);
    border-color: var(--navy-600);
    transform: translateY(-1px);
    box-shadow: var(--sombra-hover);
}
.paginacao a:active { transform: translateY(0); }
.paginacao-atual {
    display: inline-flex;
    align-items: center;
    padding: var(--e-2) var(--e-4);
    border-radius: var(--radius-pill);
    background: var(--navy-600);
    color: var(--superficie);
    font-family: var(--grotesk);
    font-weight: 700;
    font-size: var(--t-caption);
    white-space: nowrap;
    /* 2026-09-03 (polimento): "Página X de Y" -- sem isto, o pill muda de
       largura a cada troca de dígito (9 -> 10) e o botão "Próxima" pula. */
    font-variant-numeric: tabular-nums;
}
@media (max-width: 480px) {
    .paginacao { flex-wrap: wrap; gap: var(--e-2); }
}

/* ===== Evolução do MVP — produtividade, governança e mobile (2026-07-20) ===== */
.pular-conteudo {
    position: fixed;
    z-index: 2000;
    top: 0.5rem;
    left: 0.5rem;
    transform: translateY(-150%);
    background: var(--superficie);
    color: var(--navy-950);
    padding: var(--e-3) var(--e-4);
    border-radius: var(--radius-sm);
    box-shadow: var(--sombra);
}
.pular-conteudo:focus { transform: translateY(0); }

.menu-movel-toggle, .sidebar-overlay { display: none; }
.secao-cabecalho {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--e-4);
    margin-bottom: var(--e-4);
}
.secao-cabecalho h2 { margin: 0; }
.secao-cabecalho > span { color: var(--tinta-suave); font-size: var(--t-caption); }
.home-pessoal, .painel-gestao { margin: 0 0 var(--e-12); }
.home-pessoal-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--e-4); }
.painel-compacto, .documento-detalhe, .painel-gestao {
    background: var(--superficie);
    border-radius: var(--radius);
    box-shadow: var(--sombra);
}
.painel-compacto { padding: var(--e-4) var(--e-6); }
.painel-compacto h3 { margin: 0 0 var(--e-3); font-size: var(--t-caption); font-family: var(--mono); text-transform: uppercase; letter-spacing: 0.06em; }
/* Estrela no card de Favoritos (2026-08-26, pedido do Felipe: sinal
   visual pra identificar o painel de longe, sem precisar ler o título).
   Só o painel de Favoritos ganha o ícone -- Acessados recentemente/
   Atalhos do setor continuam sem, reusando o mesmo .painel-compacto. */
.painel-compacto--favoritos { position: relative; }
.painel-favoritos-estrela {
    position: absolute;
    top: 0.9rem;
    right: 1rem;
    color: var(--navy-600);
}
.lista-links-compacta { list-style: none; margin: 0; padding: 0; }
/* 2026-08-28: titulo e setor disputavam a mesma linha numa coluna de
   240-280px (.contexto). Mesmo com o min-content de volta ao normal, um
   titulo longo ao lado de "Gerencia Administrativa" nao cabe -- o layout
   dependia do comprimento do conteudo, que e' a mesma familia de defeito do
   rodape do card de aviso. Setor vai pra linha propria: nunca quebra, nunca
   trunca, funciona em qualquer largura e com qualquer nome de setor.
   Versalete mono segue a linguagem ja usada nos rotulos do sistema. */
.lista-links-compacta li { display: block; padding: var(--e-2) 0; border-bottom: 1px solid var(--linha); }
.lista-links-compacta li:last-child { border-bottom: 0; }
.lista-links-compacta span {
    display: block;
    margin-top: var(--e-1);
    font-family: var(--mono);
    font-size: var(--t-label);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--tinta-suave);
}

/* Calendário na home logada (2026-09-04, mockup do Felipe + pedido de
   04/09: mais respiro visual e dias clicáveis, ver core.models.Evento e
   core/views.py::_dados_calendario_home). Mesmo cartão .painel-compacto
   já usado por Favoritos/Acessados/Atalhos -- reaproveita cor e tipo. */
/* 2026-09-08 (achado de QA): usava var(--e-5), token que o DESIGN.md
   declara ausente de propósito ("a lacuna do --e-5 é intencional") --
   var() com custom property indefinida invalida o shorthand INTEIRO, não
   só o lado com o valor ruim. O card inteiro vivia com padding:0 nos 4
   lados (confirmado via getComputedStyle), inclusive o bottom que usava
   --e-6 válido. Troquei pelo token vizinho mais próximo, mantendo menos
   padding lateral que o .painel-compacto padrão de propósito (não comer
   largura da grade de 7 colunas). */
.painel-compacto--calendario { padding: var(--e-4) var(--e-4) var(--e-6); }
.painel-compacto--calendario h3 { margin-bottom: var(--e-4); }
.calendario-nav { display: flex; gap: var(--e-2); margin-bottom: var(--e-4); }
.calendario-nav-seta, .calendario-mes-atual {
    flex: 1;
    height: 2.25rem;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-sm);
    font: 500 var(--t-caption) var(--grotesk);
    color: var(--tinta);
}
.calendario-nav-seta { border: 1px solid var(--linha); background: var(--superficie); text-decoration: none; }
.calendario-nav-seta:hover { background: var(--papel); }
.calendario-mes-atual { background: var(--linha); text-transform: capitalize; font-weight: 600; }
.calendario-cabecalho-semana, .calendario-grade { display: grid; grid-template-columns: repeat(7, 1fr); gap: var(--e-2); }
.calendario-cabecalho-semana { margin-bottom: var(--e-2); text-align: center; }
.calendario-cabecalho-semana span { font: 600 var(--t-label) var(--grotesk); color: var(--tinta-suave); }
.calendario-dia {
    position: relative;
    aspect-ratio: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--linha);
    border-radius: var(--radius-sm);
    background: var(--superficie);
    color: var(--tinta-suave);
    font: 500 var(--t-caption) var(--grotesk);
}
button.calendario-dia {
    /* Reset só de box-model do `button, .btn` global (main.css ~2148):
       min-height:40px e padding:e-2 e-6 quebrariam o quadrado do dia numa
       grade de 7 colunas. Cor/fundo NÃO entram aqui de propósito -- ficam
       a cargo de .calendario-dia/-com-itens/-urgente, que já vencem o
       seletor `button` puro por especificidade de classe. */
    width: 100%;
    min-height: 0;
    padding: 0;
    cursor: pointer;
    transition-property: background, border-color, color;
    transition-duration: var(--transicao);
}
.calendario-dia-vazio { border-color: transparent; background: transparent; }
.calendario-dia-hoje { color: var(--tinta); font-weight: 700; }
.calendario-dia-com-itens {
    border-color: var(--navy-600);
    color: var(--navy-600);
    font-weight: 700;
}
.calendario-dia-com-itens:hover, .calendario-dia-com-itens:focus-visible { background: var(--papel); }
.calendario-dia-urgente { border-width: 2px; border-color: var(--urgente); background: var(--urgente-100); color: var(--urgente-escuro); }
.calendario-dia-urgente:hover, .calendario-dia-urgente:focus-visible { background: var(--urgente-100); filter: brightness(0.97); }

/* Popover nativo por dia (mesmo padrão de .lancador-painel em base.html):
   um dia pode ter aviso + revisão de documento juntos, então é uma lista,
   não um <a href> só. Centralizado (margin:auto do UA) em vez de ancorado
   no botão -- a coluna de 280px não tem espaço pra um popover ancorado
   sem estourar a viewport. */
.calendario-dia-popover {
    /* display:none + :popover-open (mesmo padrão de .lancador-painel):
       num navegador sem Popover API, :popover-open é seletor inválido e
       a regra inteira cai -- o painel fica escondido de vez em vez de
       aparecer solto, sem estilo, no fluxo da página. */
    display: none;
    margin: auto;
    width: min(22rem, calc(100vw - 2rem));
    /* 2026-09-08 (achado de QA): era var(--e-5), token inexistente (ver
       nota em .painel-compacto--calendario acima) -- o popover inteiro
       vivia com padding:0. .lancador-painel, citado no comentário acima
       como o mesmo padrão, usa var(--e-4); repetido aqui por igual. */
    padding: var(--e-4);
    background: var(--superficie);
    color: var(--tinta);
    border: 1px solid var(--linha);
    border-radius: var(--radius);
    box-shadow: var(--sombra-alta);
}
.calendario-dia-popover:popover-open { display: block; }
.calendario-dia-popover::backdrop { background: rgba(27, 23, 49, 0.45); }
.calendario-dia-popover-titulo {
    margin: 0 0 var(--e-3);
    font: 600 var(--t-caption) var(--grotesk);
    text-transform: capitalize;
    color: var(--tinta-suave);
}
.calendario-dia-popover-lista { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--e-3); }
.calendario-dia-popover-lista li { padding-top: var(--e-3); border-top: 1px solid var(--linha); }
.calendario-dia-popover-lista li:first-child { padding-top: 0; border-top: 0; }
.calendario-dia-popover-tipo {
    display: block;
    margin-bottom: var(--e-1);
    font: 600 var(--t-overline) var(--mono);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--navy-600);
}
.calendario-dia-popover-tipo-urgente { color: var(--urgente); }
.calendario-dia-popover-lista a,
.calendario-dia-popover-titulo-item { font-size: var(--t-body); color: var(--tinta); }
.calendario-proximos-titulo { margin: var(--e-3) 0 var(--e-2); font: 500 var(--t-label) var(--grotesk); color: var(--tinta); }
.calendario-proximos-lista { list-style: none; margin: 0; padding: 0; }
.calendario-proximos-lista li { display: flex; align-items: baseline; gap: var(--e-1); padding: var(--e-1) 0; border-bottom: 1px solid var(--linha); font-size: var(--t-overline); }
.calendario-proximos-lista li:last-child { border-bottom: 0; }
.calendario-proximos-bolinha { color: var(--navy-600); font-size: 8px; }
.calendario-proximos-bolinha-urgente { color: var(--urgente); }
.calendario-proximos-nome { color: var(--tinta); flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.calendario-proximos-data { color: var(--tinta-suave); font-family: var(--mono); flex-shrink: 0; }

/* Atalhos "Direcionamento" na home anônima (2026-09-04, mockup do Felipe). */
.direcionamento-grade { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--e-3); }
.direcionamento-item {
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--superficie);
    border: 1px solid var(--linha);
    border-radius: var(--radius);
    padding: var(--e-4);
    text-decoration: none;
    color: var(--tinta);
    font: 600 var(--t-caption) var(--grotesk);
    text-transform: uppercase;
    letter-spacing: 0.03em;
    text-align: center;
    transition-property: border-color, color, box-shadow;
    transition-duration: var(--transicao);
}
.direcionamento-item:hover { border-color: var(--navy-600); color: var(--navy-600); box-shadow: var(--sombra-hover); }
@media (max-width: 640px) {
    .direcionamento-grade { grid-template-columns: 1fr; }
}

.documento-detalhe { overflow: hidden; margin-bottom: var(--e-4); }
/* Prévia do PDF embutida na página (mockup do Felipe: painel "Preview"
   dentro do card do documento). O iframe aponta pra ver_documento (mesma
   origem, inline, sem download) -- zoom/paginação são os nativos do
   visualizador de PDF do navegador, nenhuma lib nova. */
.documento-preview {
    margin: 0 var(--e-8) var(--e-6);
    border: 1px solid var(--linha);
    border-radius: var(--radius);
    overflow: hidden;
}
.documento-preview iframe {
    display: block;
    width: 100%;
    height: 70vh;
    min-height: 420px;
    border: 0;
}
.documento-detalhe-cabecalho { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--e-6); padding: var(--e-8) var(--e-8); border-top: 4px solid var(--navy-600); }
.banner-detalhe.importancia-importante .documento-detalhe-cabecalho { border-top-color: var(--terracota); }
.banner-detalhe.importancia-urgente .documento-detalhe-cabecalho { border-top-color: var(--urgente); }
.documento-detalhe-cabecalho h1 { margin: var(--e-2) 0; }
.documento-detalhe-cabecalho p { margin-bottom: 0; color: var(--tinta-suave); }
/* 2026-08-28 (pedido do Felipe): "marcar como não lido" saiu da barra
   de ações no rodapé e foi pro lado de "Adicionar aos favoritos", como
   ícone discreto (reusa .btn-icone/.info-tip já existentes) em vez do
   botão com texto que tinha lá embaixo. */
.documento-detalhe-acoes { display: flex; align-items: center; gap: var(--e-2); flex-shrink: 0; }
.documento-metadados { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); margin: 0; border-top: 1px solid var(--linha); }
.documento-metadados > div { padding: var(--e-4) var(--e-6); border-right: 1px solid var(--linha); border-bottom: 1px solid var(--linha); }
.documento-metadados dt { font: 500 var(--t-label) var(--mono); text-transform: uppercase; letter-spacing: 0.06em; color: var(--tinta-suave); }
.documento-metadados dd { margin: var(--e-1) 0 0; }
.barra-acoes-documento { position: sticky; bottom: 0.75rem; z-index: 10; display: flex; flex-wrap: wrap; gap: var(--e-3); align-items: center; width: fit-content; padding: var(--e-3); background: color-mix(in srgb, var(--superficie) 92%, transparent); backdrop-filter: blur(8px); border-radius: var(--radius); box-shadow: var(--sombra); }

.status-revisao { display: inline-block; font: 500 var(--t-overline) var(--mono); text-transform: uppercase; letter-spacing: 0.04em; }
.status-atualizado { color: var(--sucesso); }
.status-revisao_proxima { color: var(--terracota-texto); }
.status-desatualizado { color: var(--urgente); }
.status-sem_data { color: var(--tinta-suave); }

.painel-gestao { padding: var(--e-6); border-top: 4px solid var(--navy-600); }
/* 2026-09-04, pedido do Felipe: volta a ser painel gradiente com números
   grandes, como no mockup -- revoga a decisão editorial de 21/07 (linha
   acima descrevia o motivo daquela escolha; ver DESIGN.md pra o registro
   histórico). Só a seção de MÉTRICAS troca de cartão branco pro gradiente
   -- "Destaques do setor" reusa a mesma classe .painel-gestao e continua
   branca, por isso o cartão em si migrou pra .metricas-painel (dentro da
   section), não para .painel-gestao--metricas (a section vira só
   moldura: sem fundo/sombra/borda próprios). */
.painel-gestao--metricas { padding: 0; border-top: 0; background: none; box-shadow: none; }
.metricas-painel {
    background: var(--gradiente-painel-setor);
    border-radius: var(--radius-lg);
    box-shadow: 0 8px 24px rgba(59, 42, 138, 0.25);
    overflow: hidden;
}
.metricas-lista { display: grid; grid-template-columns: repeat(5, 1fr); list-style: none; margin: 0; padding: 0; }
/* 2026-09-08 (achado de QA): var(--e-5) invalidava o padding lateral
   inteiro (token inexistente de propósito, ver nota acima em
   .painel-compacto--calendario). --e-4 é o vizinho mais próximo, e
   mantém menos espaço lateral que --e-6 de propósito -- são 5 colunas
   nesta grade, não pode comer largura. */
.metricas-lista li { position: relative; padding: var(--e-6) var(--e-4); }
.metricas-lista li:not(:last-child)::after {
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: 1px;
    background: rgba(255, 255, 255, 0.18);
}
.metricas-lista a { display: block; text-decoration: none; color: inherit; }
.metricas-lista a:focus-visible { outline: 2px solid var(--superficie); outline-offset: -2px; }
.metricas-lista-rotulo { display: flex; align-items: center; gap: var(--e-2); margin-bottom: var(--e-3); }
.metricas-lista-bolinha { width: 8px; height: 8px; border-radius: var(--radius-circulo); background: var(--superficie); flex-shrink: 0; }
.metricas-lista-rotulo span {
    font: 600 9.5px var(--grotesk);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: rgba(250, 247, 253, 0.7);
}
.metricas-lista strong { display: block; font: 700 34px/1 var(--mono); color: var(--superficie); }
.metricas-lista .metrica-atencao .metricas-lista-bolinha { background: var(--urgente-100); }
.metricas-lista .metrica-atencao strong { color: var(--urgente-100); }
@media (max-width: 900px) {
    .metricas-lista { grid-template-columns: repeat(3, 1fr); }
    .metricas-lista li::after { display: none; }
    .metricas-lista li { border-bottom: 1px solid rgba(255, 255, 255, 0.18); }
}
@media (max-width: 640px) {
    .metricas-lista { grid-template-columns: repeat(2, 1fr); }
    .metricas-lista strong { font-size: 26px; }
}
.pesquisas-vazias { margin-top: var(--e-6); }
.pesquisas-vazias h3 { font-size: var(--t-caption); text-transform: uppercase; font-family: var(--mono); }
.pesquisas-vazias ul { list-style: none; padding: 0; margin: 0; }
.pesquisas-vazias li { display: flex; justify-content: space-between; padding: var(--e-2) 0; border-bottom: 1px solid var(--linha); }

@media (max-width: 900px) {
    .menu-movel-toggle { display: inline-flex; align-items: center; gap: var(--e-2); min-height: 2.75rem; }
    .sidebar {
        position: fixed;
        z-index: 1001;
        inset: 0 auto 0 0;
        width: min(82vw, 320px);
        transform: translateX(-105%);
        /* Abaixo de 900px a gaveta so' escondia por transform: os links de
           setor continuavam focaveis e audiveis fora da tela (achado UX
           02/09, acessibilidade+responsivo). visibility tira do tab order
           e da arvore de acessibilidade sem tocar no JS. NAO usar
           var(--transicao) como atraso de visibility: o token carrega
           `ease` (main.css ~225) e um valor com ease num slot de delay
           invalida a declaracao inteira -- por isso a regra de abertura
           abaixo zera o atraso em vez de reusar o token ali. */
        visibility: hidden;
        transition: transform var(--transicao), visibility var(--transicao);
        overflow-y: auto;
        padding-top: var(--e-6);
    }
    .sidebar.sidebar-aberta {
        transform: translateX(0);
        visibility: visible;
        transition: transform var(--transicao), visibility 0s;
    }
    .sidebar .sidebar-nav { flex-direction: column; flex-wrap: nowrap; }
    .sidebar .sidebar-item { width: 100%; }
    .sidebar-overlay { position: fixed; z-index: 1000; inset: 0; width: 100%; height: 100%; border: 0; border-radius: 0; background: rgba(27, 23, 49, 0.62); }
    .menu-movel-aberto .sidebar-overlay { display: block; }
    .menu-movel-aberto { overflow: hidden; }
    .metricas-lista { gap: var(--e-2) var(--e-6); }
}

@media (max-width: 640px) {
    /* 2026-08-27: padding mobile do .container -- vinha do bloco @media
       640 la' de cima, onde era regra morta (ver comentario la'). Aqui
       depois da regra base, aplica. */
    .container { padding: var(--e-6) var(--e-4) var(--e-12); }

    /* 02/09: `.site-header { flex-wrap: wrap; gap: var(--e-3); }` removida
       daqui -- flex-wrap e' inerte (o cabecalho e' grid abaixo de 900px)
       e o gap migrou pro bloco do fim do arquivo, que e' o que vence a
       cascata (achado UX consistencia). */

    /* 2026-08-27: o menu superior rola na horizontal no celular e nao
       dava NENHUMA pista disso -- "SETORES / CORPO / BUSCAR / OLA, fulano
       / sino / sair" em caixa alta nao cabe em 360px e o conteudo cortado
       simplesmente sumia na borda, num publico majoritariamente mobile.
       Duas correcoes CSS puras (sem JS, sem redesenhar a navegacao):
       1) mask-image esmaece os ultimos 2.5rem, sinal visual classico de
          "continua pra la'". Degrada em silencio onde nao ha suporte: o
          menu volta a ser exatamente o que era.
       2) tira o CAIXA ALTA e o letter-spacing no breakpoint movel e baixa
          1 degrau de corpo -- "Setores" ocupa ~15% menos que "SETORES",
          entao boa parte dos casos passa a caber sem rolagem nenhuma.
       A barra de rolagem nativa foi mantida de proposito: onde o SO a
       desenha, e' mais um indicador. */
    .site-header nav {
        width: 100%;
        overflow-x: auto;
        padding-bottom: var(--e-1);
        -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 2.5rem), transparent 100%);
        mask-image: linear-gradient(to right, #000 calc(100% - 2.5rem), transparent 100%);
    }
    .site-header nav a,
    .logout-form .link-button,
    .usuario-atual {
        text-transform: none;
        letter-spacing: 0;
        font-size: var(--t-caption);
    }
    .documento-detalhe-cabecalho { flex-direction: column; padding: var(--e-6); }
    .documento-metadados { grid-template-columns: 1fr; }
    .documento-metadados > div { border-right: 0; }
    .barra-acoes-documento { width: 100%; bottom: 0; border-radius: var(--radius-sm) var(--radius-sm) 0 0; }
    .secao-cabecalho { display: block; }
    .secao-cabecalho > span { display: block; margin-top: var(--e-1); }
}

/* ===== Revisão sistêmica de UX/UI — 2026-07-23 =====
   Direção: "caderno institucional azul". A régua superior identifica
   documentos/ações; superfícies e tipografia ficam deliberadamente
   contidas para o conteúdo institucional continuar sendo o protagonista. */

.container > h1,
h1.post-card-legenda,     /* h1 do detalhe de aviso: 3 niveis abaixo do
                              .container, o combinador filho acima nunca
                              casava e o titulo caia nos 16px do body
                              (achado UX 02/09, mesma causa raiz ja corrigida
                              pro h1 da home em 27/08 -- main.css ~910). */
.perfil-setor-cabecalho h1,
.documento-detalhe-cabecalho h1,
.form-card h1,
.confirmacao-card h1 {
    color: var(--navy-950);
    font-size: clamp(var(--t-h4), 2.2vw, var(--t-h3));
    line-height: 1.16;
    letter-spacing: -0.018em;
}

.container h2:not(.hero-titulo, .setores-titulo, .aviso-card-titulo, .perfil-secao-titulo) {
    color: var(--navy-950);
    font-size: clamp(var(--t-body-lg), 1.6vw, var(--t-h5));
    line-height: 1.25;
}

.lista-documentos,
.setor-card,
.form-card,
.confirmacao-card,
.perfil-setor-descricao,
.painel-compacto,
.documento-detalhe,
.painel-gestao {
    border: 1px solid var(--linha);
}

.form-card,
.confirmacao-card,
.painel-gestao {
    border-top-width: 3px;
}
/* As duas regras acima (border/border-top-width) miram .painel-gestao
   genérico e vêm DEPOIS de .painel-gestao--metricas no arquivo -- sem
   este reset, ganhariam da cascata (mesma especificidade, ordem de
   arquivo) e devolveriam a borda no painel de métricas gradiente. */
.painel-gestao--metricas { border: none; }

.setores-titulo,
.hero-titulo {
    color: var(--navy-800);
    font-size: var(--t-label);
    letter-spacing: 0.12em;
}

.form-card {
    max-width: 720px;
    padding: 0;
    overflow: hidden;
    border-top: 3px solid var(--navy-600);
}

/* Wrapper de espacamento uniforme (2026-08-21, achado do Felipe: campos
   dentro do form-card do perfil com distancias diferentes da borda --
   raiz do problema era ".form-card > h1, .form-card > p" so' pegar os
   <p> soltos tipo Localizacao/Sobre, deixando .perfil-secao-titulo e
   .perfil-form-linha sem o mesmo respiro). Todo conteudo de um form-card
   sem cabecalho/form proprios (perfil.html) entra aqui em vez de ficar
   solto direto no card. */
.form-card-corpo {
    padding: var(--e-6) var(--e-8) var(--e-8);
}

.form-card-cabecalho {
    padding: var(--e-6) var(--e-8) var(--e-6);
    background: linear-gradient(180deg, var(--navy-100), var(--superficie));
    border-bottom: 1px solid var(--linha);
}

.form-card-cabecalho h1 {
    margin: var(--e-1) 0 var(--e-2);
}

.form-card-cabecalho p {
    max-width: 58ch;
    margin: 0;
    color: var(--tinta-suave);
    font-size: var(--t-body);
}

.form-card-tipo,
.confirmacao-tipo {
    display: block;
    font: 700 var(--t-label) var(--mono);
    color: var(--navy-600);
    letter-spacing: 0.11em;
    text-transform: uppercase;
}

.form-card > form {
    padding: var(--e-6) var(--e-8) var(--e-8);
}

.form-card > h1,
.form-card > p {
    margin-right: var(--e-8);
    margin-left: var(--e-8);
}

.form-card > h1:first-child {
    margin-top: var(--e-6);
}

.confirmacao-opcao {
    display: flex;
    align-items: flex-start;
    gap: var(--e-3);
    padding: var(--e-3) var(--e-4);
    border: 1px solid var(--linha);
    border-radius: var(--radius-sm);
    background: var(--papel);
    color: var(--tinta);
    font-size: var(--t-caption);
    /* 2026-08-28 (auditoria): era 550. So' existem @font-face 300/400/500/
       700/900 -- 550 e' sintetizado pelo navegador (falso-negrito, metricas
       erradas), exatamente o que a regra de 27/08 no topo do arquivo proibe
       pro 600. Medium (500) e' o peso real mais proximo. */
    font-weight: 500;
    cursor: pointer;
}

.confirmacao-opcao:hover {
    border-color: var(--navy-600);
    background: var(--navy-100);
}

.confirmacao-opcao input {
    margin-top: var(--e-1);
    accent-color: var(--navy-600);
}

/* Opção única "publicar direto" em criar.html/upload.html — a mesma casca
   de cartão do .confirmacao-opcao (feita pra telas de confirmação com peso
   de decisão) ficava pesada demais pra um único checkbox dentro de um
   formulário já longo (2026-08-13, Felipe achou "estranho"). Vira uma
   linha leve, sem borda, encostada nos botões de ação. */
.opcao-confirmacao {
    /* 2026-09-03 (polimento): a label esticava pra 100% da largura do
       form-card, e o anel de foco (abaixo) virava uma barra inteira em vez
       de contornar só o controle. inline-flex sozinho não bastou em teste
       isolado (suspeita: blockifica de volta pra flex se o pai for
       grid/flex, CSS Display Level 3) -- width:fit-content força o encolhe
       independente disso. Sem afetar layout dos vizinhos (mesma margem/gap). */
    display: inline-flex;
    width: fit-content;
    align-items: center;
    gap: var(--e-2);
    margin: var(--e-2) 0 0;
    color: var(--tinta-suave);
    font-size: var(--t-caption);
    font-weight: 500;
    cursor: pointer;
    transition: color var(--transicao);
}

.opcao-confirmacao:hover,
.opcao-confirmacao:focus-within {
    color: var(--navy-600);
}

.opcao-confirmacao input {
    accent-color: var(--navy-600);
}

.form-acoes {
    justify-content: flex-end;
    padding-top: var(--e-4);
    border-top: 1px solid var(--linha);
}

.confirmacao-card {
    max-width: 620px;
    padding: 0;
    overflow: hidden;
}

.confirmacao-cabecalho {
    padding: var(--e-6) var(--e-8) var(--e-6);
    background: linear-gradient(180deg, var(--navy-100), var(--superficie));
    border-bottom: 1px solid var(--linha);
}

.confirmacao-card.perigo .confirmacao-cabecalho {
    background: linear-gradient(180deg, var(--urgente-100), var(--superficie));
}

/* 2026-08-27: idem -- este texto fica sobre o topo do gradiente, que e'
   exatamente --urgente-100 (4.35:1 com --urgente). */
.confirmacao-card.perigo .confirmacao-tipo {
    color: var(--urgente-escuro);
}

.confirmacao-cabecalho h1 {
    margin: var(--e-1) 0 var(--e-2);
}

.confirmacao-cabecalho p {
    max-width: 52ch;
    margin: 0;
    color: var(--tinta-suave);
}

.confirmacao-cabecalho strong {
    color: var(--tinta);
}

.confirmacao-card form {
    padding: var(--e-6) var(--e-8) var(--e-6);
}

.confirmacao-card label.confirmacao-opcao {
    margin: 0 0 var(--e-4);
    background: var(--papel);
}

.confirmacao-card.perigo label.confirmacao-opcao {
    background: var(--urgente-100);
    border-color: color-mix(in srgb, var(--urgente) 28%, var(--linha));
}

.confirmacao-card .form-acoes {
    margin-top: 0;
}

/* CheckboxSelectMultiple do form.as_p (setores_destino/documentos em
   Aviso e Documento) saía como <ul> crua, sem nenhuma casca do sistema —
   mesma lacuna que o .errorlist tinha antes de ser corrigido (2026-08-13,
   pedido do Felipe: melhorar a tela de criar aviso). Reaproveita a mesma
   linguagem visual de .opcao-confirmacao em vez de inventar um padrão novo.
   Grade em vez de lista vertical (2026-08-13, Felipe: com 12 setores a
   lista ficava alta demais, exigindo scroll) — colunas se ajustam sozinhas
   à largura do cartão, sem precisar contar quantos setores existem hoje. */
/* Correção 2026-08-13 (mesmo dia): o seletor acima era baseado em
   <ul>/<li>, mas o Django 5.2 renderiza RadioSelect/CheckboxSelectMultiple
   como <div id="id_campo"><div><label>...</label></div></div> — nunca
   bateu com nada, é por isso que nada disso aparecia estilizado nem o
   :has() de revelação funcionava direito (o <div> do widget ficava
   dentro de um <p>, HTML inválido, o navegador fechava o <p> sozinho no
   meio). Corrigido: os templates passaram a envolver esses campos em
   <div class="campo-widget"> em vez de <p>, e o seletor abaixo mira a
   estrutura real. */
.form-card .campo-widget > div {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: var(--e-2);
    margin: var(--e-2) 0 var(--e-4);
}

.form-card .campo-widget > div > div {
    margin: 0;
}

.form-card .campo-widget > div > div > label {
    /* height:100% faz o cartao esticar ate a altura da linha da grade —
       sem isso, quem esticava era o <div> em volta (item de grid, stretch
       por padrao), mas a borda fica no <label>, que so cresce pelo texto
       (2026-08-13, Felipe: cartoes com tamanhos diferentes na mesma
       linha). box-sizing: border-box ja vem do reset global (* {...}). */
    display: flex;
    /* center, não flex-start (2026-08-26, achado do Felipe: bullet/radio
       desalinhado do texto) -- flex-start jogava a bolinha pro topo do
       cartão esticado pela grade, enquanto o texto de uma linha só ficava
       "flutuando" abaixo dela em vez de ao lado, alinhado. */
    align-items: center;
    height: 100%;
    gap: var(--e-2);
    padding: var(--e-2) var(--e-3);
    border: 1px solid var(--linha);
    border-radius: var(--radius-sm);
    background: var(--papel);
    color: var(--tinta);
    font-size: var(--t-caption);
    font-weight: 500;
    text-wrap: pretty;
    cursor: pointer;
    transition: background var(--transicao), border-color var(--transicao);
}

.form-card .campo-widget > div > div > label:hover,
.form-card .campo-widget > div > div > label:focus-within {
    border-color: var(--navy-600);
    background: var(--navy-100);
}

.form-card .campo-widget > div > div > label input {
    accent-color: var(--navy-600);
    flex-shrink: 0;
}

/* Anel de foco padrão do navegador na caixinha em si ficava um quadrado
   solto e desalinhado (2026-08-13, Felipe: "parece um retângulo"). O
   label já muda de cor com :focus-within (ver .opcao-confirmacao) — isso
   já é indicação de foco suficiente, então tira o quadrado redundante. */
.opcao-confirmacao input:focus-visible {
    outline: none;
}
/* 2026-08-27: 2o `outline: none` sem substituto real. O comentario acima
   diz que o :focus-within do label ja indica o foco, mas medindo: o label
   sai de `background: var(--papel)` (#F0EDFB) pra `background:
   var(--navy-100)` -- que E' EXATAMENTE #F0EDFB, o mesmo valor. Nao ha
   mudanca de fundo nenhuma; sobrava so' 1px de borda mudando de cor.
   Devolvo o indicador como anel no proprio label (nao no checkbox), o que
   preserva a decisao do Felipe de 2026-08-13 ("nao quero o retangulo solto
   na caixinha") e ainda assim passa 2.4.7/2.4.11. */
.opcao-confirmacao:focus-within {
    box-shadow: var(--foco-anel);
    /* 2026-08-31: o anel existia, mas em canto vivo e encostado no texto --
       lia como retangulo solto. Raio + respiro; a margem negativa devolve
       o alinhamento a esquerda, entao nada se desloca na tela. Compensacao
       valida so' AQUI: .opcao-confirmacao nao tem padding proprio, entao
       o par se cancela. */
    /* 2026-09-03 (Felipe achou "feia"): --radius (8px) numa caixa curta de
       uma linha só vira pílula/oval, pesada. --radius-sm (4px) é o mesmo
       token que a classe irmã .form-card .campo-widget label já usa pro
       mesmo tipo de controle (chip/checkbox pequeno) -- alinha as duas. */
    border-radius: var(--radius-sm);
    padding: 2px var(--e-1);
    margin-left: calc(var(--e-1) * -1);
}
/* 02/09 (achado UX): a regra acima, compartilhada com este seletor, somava
   a mesma margem negativa a um <label> que JA tem padding proprio
   (var(--e-2) var(--e-3), acima) -- a margem alargava a caixa 8px pra
   esquerda em vez de deslocar, e o cartao focado invadia o vizinho no
   grid. O anel sozinho basta: o cartao ja troca border-color no foco. */
.form-card .campo-widget > div > div > label:focus-within {
    box-shadow: var(--foco-anel);
}

/* help_text do Django (ex.: em documentos.help_text) também não tinha
   estilo próprio. */
.form-card .helptext {
    display: block;
    margin: calc(var(--e-3) * -1) 0 var(--e-4);
    color: var(--tinta-suave);
    font-size: var(--t-caption);
}

/* Alcance (Toda a COPPEAD vs Setores específicos) e Documentos vinculados
   (2026-08-13, Felipe: "toda a COPPEAD" era o resultado implícito de
   esvaziar as caixinhas — virou escolha explícita; documentos vinculados
   virou opt-in com busca). Revelação via :has() nativo, sem JS pra
   mostrar/esconder — só a busca de documentos precisa de script. */
.alcance-setores-lista,
.documentos-revelados {
    display: none;
}

.alcance-wrapper:has(input[name="alcance"][value="especificos"]:checked) .alcance-setores-lista {
    display: block;
}

/* Somente gestores (2026-09-10): não faz sentido com alcance "Público" --
   quem não tem login não pode ser identificado como gestor. Esconder aqui
   só reforça visualmente o que BannerForm.clean()/DocumentoForm.clean() já
   garantem no servidor. */
.alcance-wrapper:has(input[name="alcance"][value="publico"]:checked) .alcance-apenas-gestores {
    display: none;
}

/* 2026-09-10 (achado do Felipe: caixa "com foco" parecia fora do padrao):
   os radios de Alcance/Visibilidade vizinhos nunca mostram o aro nativo do
   navegador -- so' o :focus-within do label (linha ~4013) muda a borda.
   Este checkbox usa o MESMO label, mas nao tinha a mesma supressao (so'
   existia pra .opcao-confirmacao, ver linha ~4028) -- resultado: o aro
   nativo do quadradinho aparecia JUNTO com a borda do label ao clicar,
   dobrando o contorno so' aqui. Mesmo racional/comentario da regra de
   2026-08-27 logo abaixo. */
.alcance-apenas-gestores input:focus-visible {
    outline: none;
}

/* 2026-09-10 (achado do Felipe, 3a rodada): virou círculo pra bater com
   os radios de Alcance (ver histórico git), mas aí ficava indistinguível
   de um radio de verdade -- "Toda a COPPEAD" + "Somente gestores" cheios
   ao mesmo tempo parecia bug (dois "radios" marcados), quando na
   verdade é o comportamento certo: a caixa COMPÕE com o alcance
   escolhido, não substitui (ver banners/forms.py, documentos/forms.py).
   Quadrado nativo devolvido de propósito -- é a convenção padrão (quadrado
   = independente, círculo = escolha única) que sinaliza isso sem precisar
   de texto extra. Caixa/borda/fundo/hover do label continuam iguais aos
   dos radios; só o glifo volta a ser o nativo do checkbox. */

.documentos-toggle-wrapper:has(.opcao-confirmacao input:checked) .documentos-revelados {
    display: block;
}

/* E-mail manual (2026-09-08): mesmo padrão de revelação via :has() usado
   acima em Documentos vinculados -- "Setores que recebem o e-mail" só
   aparece depois de marcar "Avisar por e-mail". */
.email-toggle-wrapper .email-setores-lista {
    display: none;
}

.email-toggle-wrapper:has(.opcao-confirmacao input:checked) .email-setores-lista {
    display: block;
}

/* 2026-08-31 (pedido do Felipe): "Este documento não precisa de revisão"
   -- inverso do padrão acima (aqui o campo já é visível por padrão, some
   quando marcado, em vez de aparecer quando marcado). */
.revisao-toggle-wrapper:has(.opcao-confirmacao input:checked) .revisao-data {
    display: none;
}

.documentos-busca-form {
    margin-bottom: var(--e-2);
}

/* Documento escondido pela busca em static/js/main.js — display:none via
   atributo em vez de classe, pra não competir com o display:grid do
   .campo-widget (checkbox card por trás continua no DOM, só oculto). */
.form-card .campo-widget > div > div[hidden] {
    display: none;
}

.btn-secundario,
button,
.btn {
    justify-content: center;
    line-height: 1.2;
}

.documentos-filtros {
    padding: var(--e-3);
    border: 1px solid var(--linha);
    border-radius: var(--radius);
    background: var(--superficie);
}

.documentos-filtros input,
.documentos-filtros select {
    background-color: var(--papel);
}

.lista-documentos li {
    padding-top: var(--e-3);
    padding-bottom: var(--e-3);
}

.lista-documentos-titulo {
    line-height: 1.3;
}

.perfil-setor-cabecalho {
    border-bottom-width: 1px;
}

@media (max-width: 900px) {
    .site-header {
        display: grid;
        grid-template-columns: minmax(0, 1fr) auto;
        gap: var(--e-3) var(--e-4);
    }

    .site-header nav {
        grid-column: 1 / -1;
        width: 100%;
    }

    .menu-movel-toggle {
        white-space: nowrap;
    }

    .container {
        width: 100%;
    }
}

@media (max-width: 640px) {
    /* 02/09 (achado UX consistencia): `.site-header { padding: var(--e-3)
       var(--e-4); }` era regra morta -- mesma especificidade (0,1,0) do
       bloco do fim do arquivo, que vem depois e sempre ganhava. O padding
       real ficou consolidado la'; ver comentario no bloco vencedor. */

    .site-header .brand a {
        font-size: var(--t-body-lg);
    }

    .brand-logo {
        height: 1.8rem;
    }

    .site-header .brand small {
        font-size: var(--t-overline);
    }

    .container {
        padding: var(--e-6) var(--e-4) var(--e-12);
    }

    .hero {
        margin-bottom: var(--e-8);
    }

    .lista-documentos li {
        padding: var(--e-4) var(--e-4);
    }

    .lista-documentos-titulo,
    .lista-documentos-meta,
    .lista-documentos-acoes {
        /* 2026-08-28: era `flex: none` (= 0 0 auto), ou seja "nunca encolha".
           Funcionava na lista de documentos, que empilha em COLUNA no mobile --
           mas a pagina de Alertas reusa estas mesmas classes numa LINHA com
           wrap, e ali o titulo simplesmente nao cabia: 441px de texto numa
           caixa de 293px, 155px de barra horizontal na pagina. Com shrink
           zerado o item nunca e' constrangido, entao nem `overflow-wrap`
           conseguia quebrar a palavra. `0 1 auto` mantem a intencao original
           (nao crescer) e devolve a capacidade de encolher. */
        flex: 0 1 auto;
        min-width: 0;
    }

    .lista-documentos-info,
    .lista-documentos-info-ampla {
        width: 100%;
        align-items: flex-start;
    }

    .lista-documentos-selos {
        justify-content: flex-start;
    }

    /* Linha empilha em coluna aqui (.lista-documentos li, regra acima) —
       divisória vira horizontal em vez de vertical. */
    .lista-documentos-acoes {
        margin-left: 0;
        padding-left: 0;
        padding-top: var(--e-2);
        border-left: none;
        border-top: 1px solid var(--linha);
        width: 100%;
    }

    .documentos-filtros {
        align-items: stretch;
    }

    .documentos-filtros-busca,
    .documentos-filtros select,
    .documentos-filtros button {
        width: 100%;
        flex: 1 1 auto;
    }

    .form-card-cabecalho,
    .form-card > form,
    .confirmacao-cabecalho,
    .confirmacao-card form {
        padding-right: var(--e-4);
        padding-left: var(--e-4);
    }

    .form-acoes {
        align-items: stretch;
        flex-direction: column-reverse;
        gap: var(--e-3);
    }

    .form-acoes > * {
        width: 100%;
    }
}

/* ===== Dropzone de upload de documento (2026-08-24, achado em revisao de
   UX: upload era so' um <input type=file> nu, sem area de arrastar). Input
   nativo continua visivel dentro da zona -- nao usar display:none, pra nao
   tirar do fluxo de tab/leitor de tela; o arrastar e' so' um atalho por
   cima do que ja funciona por clique/teclado. */
.dropzone-arquivo {
    border: 2px dashed var(--linha-forte);
    border-radius: var(--radius);
    padding: var(--e-6);
    text-align: center;
    transition: background var(--transicao), border-color var(--transicao);
}
.dropzone-arquivo.arrastando-sobre {
    border-color: var(--navy-600);
    background: var(--navy-tenue);
}
.dropzone-arquivo-texto {
    margin: 0 0 var(--e-2);
    color: var(--tinta-suave);
    font-size: var(--t-caption);
}
.dropzone-arquivo-link {
    color: var(--navy-600);
    text-decoration: underline;
    cursor: pointer;
}
.dropzone-arquivo-nome {
    margin: 0 0 var(--e-2);
    font-weight: 700;
    color: var(--tinta);
}
/* 02/09 (achado UX formularios): mesmo elemento passou a mostrar recusa
   (nao so' sucesso) -- sem isto, "arquivo.docx" em negrito e' lido como
   aceite. Par ja' medido no DESIGN.md (--urgente-escuro sobre
   --urgente-100 da 6,03:1, AA folgado). */
.dropzone-arquivo-nome-erro { color: var(--urgente-escuro); }

/* ===== Post de aviso estilo rede social (2026-08-24, pedido do Felipe:
   curtir/comentar/quem-leu com a mesma linguagem visual do
   Instagram/LinkedIn/Facebook -- capa, legenda, icones, avatares
   empilhados com modal de nomes). */
.post-card {
    background: var(--superficie);
    border-radius: var(--radius);
    box-shadow: var(--sombra);
    border-top: 4px solid var(--navy-600);
    overflow: hidden;
}
.post-card.importancia-importante { border-top-color: var(--terracota); }
.post-card.importancia-urgente { border-top-color: var(--urgente); }

.post-card-cabecalho {
    display: flex;
    align-items: center;
    gap: var(--e-3);
    padding: var(--e-4) var(--e-6);
}
.post-card-avatar { flex-shrink: 0; }
.post-card-identidade { display: flex; flex-direction: column; min-width: 0; }
/* Grotesk, não a serifada/sans padrão do resto do site (2026-08-26,
   achado do Felipe: "ainda tem textos com fontes diferentes da padrão
   do sistema" -- essa página de detalhe nunca tinha recebido a fonte
   oficial da marca aplicada nos cards da grade, mesmo sendo a página
   que o "Saiba mais" da grade abre). */
.post-card-setor { font-family: var(--grotesk); font-weight: 700; }
.post-card-data {
    font-family: var(--mono);
    font-size: var(--t-label);
    color: var(--tinta-suave);
}
.post-card-cabecalho .setor-badge { margin-left: auto; }

.post-card-capa {
    display: block;
    background: var(--navy-100);
}
.post-card-capa img {
    width: 100%;
    max-height: 26rem;
    /* 02/09: mesma correcao de .aviso-card-capa img acima -- aqui e' onde
       esta' o ganho real, nada sobrescreve a altura, entao passa a
       reservar espaco em qualquer largura e mata ate' 416px de shift
       na pagina do aviso. */
    aspect-ratio: 16 / 9;
    object-fit: cover;
    display: block;
}

.post-card-corpo { padding: var(--e-4) var(--e-6) 0; }
.post-card-legenda { margin: 0; line-height: 1.5; font-family: var(--grotesk); font-size: var(--t-body); font-weight: 700; }
/* 02/09 (achado UX consistencia): a classe nao tinha NENHUMA regra --
   grep zero. Herdava 16px/400 do body, mesmo tamanho do titulo (que ja'
   cresceu via h1.post-card-legenda acima). Espelha .aviso-card-texto
   (~1440) sem o clamp de 3 linhas: aqui e' pagina de leitura completa. */
.post-card-texto {
    margin: var(--e-2) 0 0;
    font-weight: 300;
    font-size: var(--t-body);
    line-height: 1.55;
    color: var(--tinta-suave);
    max-width: 68ch;
    text-wrap: pretty;
}

.post-card-reacoes {
    display: flex;
    align-items: center;
    gap: var(--e-2);
    padding: var(--e-3) var(--e-4) var(--e-1);
}
.btn-icone {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    /* CAUSA RAIZ do "curtir tem forma diferente do vizinho": .btn-icone
       (0,1,0) nunca declarou min-height, entao um <button class="btn-icone">
       herdava o min-height da regra base `button` e virava uma caixa de
       36x42.4px -- com border-radius:50% isso e' uma ELIPSE. O mesmo
       .btn-icone num <a> nao casa com `button`, nao herdava nada, e ficava
       36x36 redondo. Os dois conviviam lado a lado na barra de reacoes. */
    min-height: 0;
    border-radius: var(--radius-circulo);
    border: none;
    background: transparent;
    color: var(--tinta-suave);
    cursor: pointer;
    transition: background var(--transicao), color var(--transicao);
}
a.btn-icone { text-decoration: none; }
/* Sem isso, o <svg> dentro de um <button> (curtir) some -- alguns motores
   nao dao ao svg um tamanho intrinseco dentro de flex, so o height do
   atributo HTML sobrevive, o width cai pra 0 (achado do QA, 2026-08-26,
   comparado com o mesmo icone dentro de <a>, que funcionava sem isso). */
.btn-icone svg { width: 1.375rem; height: 1.375rem; flex-shrink: 0; }
.btn-icone:hover, .btn-icone:focus-visible {
    background: var(--navy-tenue);
    color: var(--navy-600);
    box-shadow: none;
    transform: none;
}
.btn-icone:focus-visible { outline: 2px solid var(--navy-600); outline-offset: 2px; }
.btn-icone.curtir-ativo { color: var(--terracota); }
.btn-icone.favorito-ativo { color: var(--navy-600); }

.post-card-contadores {
    display: flex;
    align-items: center;
    gap: var(--e-2);
    padding: 0 var(--e-6) var(--e-3);
    font-size: var(--t-caption);
    color: var(--tinta-suave);
}
.post-card-contador-comentarios { color: inherit; }

/* Desmarcar leitura (2026-08-26, pedido do Felipe). 2026-09-08: virou
   ícone-só (olho riscado) + tooltip no hover, mesma linha de curtir/
   comentar em banners/detalhe.html e do favorito em documentos/detalhe.html
   -- o botão-pílula com texto que existia aqui foi substituído por
   `.btn-icone` dentro de `.info-tip` (ver aquele bloco mais abaixo),
   então não sobra mais nenhuma regra própria de botão. */
.desmarcar-leitura-form { display: inline-block; }
/* 02/09 (achado UX responsivo): .barra-acoes-documento e' sticky (~3303) e
   funciona em documentos/detalhe.html, onde e' irma do <article>. Aqui ela
   fica DENTRO do .post-card, que tem overflow:hidden (~3891) -- ancestral
   com overflow != visible vira o container de rolagem do sticky, e como
   o post-card nunca rola, o sticky se comporta como position:relative:
   nunca gruda. position:static acaba com a promessa nao cumprida. */
.post-card > .barra-acoes-documento { position: static; width: auto; margin: 0 var(--e-6) var(--e-4); }

.post-card-quem-leu {
    display: flex;
    align-items: center;
    gap: var(--e-2);
    padding: 0 var(--e-6) var(--e-4);
    flex-wrap: wrap;
}
.post-card-quem-leu-titulo { font-size: var(--t-caption); color: var(--tinta-suave); }

/* Cluster de avatares empilhados + modal (reusado curtidas/quem-leu). */
.avatares-cluster {
    display: inline-flex;
    align-items: center;
    gap: var(--e-2);
    border: none;
    background: transparent;
    cursor: pointer;
    padding: var(--e-1) var(--e-1) var(--e-1) var(--e-1);
    border-radius: var(--radius-pill);
}
.avatares-cluster:hover, .avatares-cluster:focus-visible { background: var(--navy-tenue); }
.avatares-empilhados { display: flex; }
.avatares-empilhados .avatar-leitura {
    width: 1.6rem;
    height: 1.6rem;
    font-size: var(--t-label);
    border: 2px solid var(--superficie);
    margin-left: calc(var(--e-2) * -1);
}
.avatares-empilhados .avatar-leitura:first-child { margin-left: 0; }
.avatar-leitura-mais { background: var(--tinta-suave); }
.avatares-rotulo { font-size: var(--t-caption); font-weight: 500; }

/* Dialogo de confirmacao de acao destrutiva (2026-08-28, auditoria:
   substitui window.confirm). Mesma linguagem de superficie do
   .confirmacao-card das paginas de confirmacao dedicadas -- card branco,
   raio e elevacao dos tokens, verbo especifico no botao. Nenhum tom novo. */
.dialogo-confirmar {
    border: none;
    border-radius: var(--radius);
    box-shadow: var(--sombra-alta);
    padding: var(--e-6);
    width: min(26rem, 92vw);
    color: var(--tinta);
    background: var(--superficie);
}
.dialogo-confirmar::backdrop { background: rgba(27, 23, 49, 0.45); }
.dialogo-confirmar h2 {
    margin: 0 0 var(--e-2);
    font-size: var(--t-body-lg);
}
.dialogo-confirmar p {
    margin: 0 0 var(--e-6);
    color: var(--tinta-suave);
    font-size: var(--t-body);
}
.dialogo-confirmar-acoes {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: var(--e-3);
}

.modal-pessoas {
    border: none;
    border-radius: var(--radius);
    box-shadow: var(--sombra-alta);
    padding: 0;
    width: min(22rem, 90vw);
}
.modal-pessoas::backdrop { background: rgba(27, 23, 49, 0.45); }
.modal-pessoas-cabecalho {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--e-4) var(--e-6);
    /* 2026-08-27: era var(--borda), que NUNCA foi definida no :root -- a
       declaracao inteira era invalida e o cabecalho do modal ficava sem
       divisoria. Token real: --linha (#DDD9F0, Cinza Borda do DS). */
    border-bottom: 1px solid var(--linha);
    margin: 0;
}
.modal-pessoas-cabecalho h2 { margin: 0; font-size: var(--t-body); }
.modal-fechar {
    border: none;
    background: transparent;
    color: var(--tinta-suave);
    cursor: pointer;
    padding: var(--e-1);
}
.lista-pessoas-modal {
    list-style: none;
    margin: 0;
    padding: var(--e-2) var(--e-6) var(--e-6);
    max-height: 20rem;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: var(--e-3);
}
.lista-pessoas-modal li { display: flex; align-items: center; gap: var(--e-3); }

/* display:contents aqui fazia o <button> perder a largura (bug do
   Chrome com controles de formulario dentro de display:contents) --
   o coracao/curtir ficava invisivel, so a area de hover aparecia
   (achado do QA, 2026-08-26). inline-flex evita o bug e ocupa a
   mesma area de antes dentro do row .post-card-reacoes. */
.curtir-form { display: inline-flex; }

.post-card-comentarios { margin-top: var(--e-6); }
/* Comentarios do aviso (banners/detalhe.html) so' abrem ao clicar no
   icone/contador de comentarios (2026-09-08, pedido do Felipe) -- os dois
   linkam pra #comentarios, e :target revela sem precisar de JS (a CSP do
   projeto e' script-src 'self' sem inline). Selector por ID, nao pela
   classe: o feed da home (_hero_publicacoes.html) reusa a MESMA classe
   .post-card-comentarios pros comentarios sempre visiveis do post, sem
   id -- esconder por classe escondia isso tambem. */
#comentarios { display: none; }
#comentarios:target { display: block; }
.lista-comentarios {
    list-style: none;
    margin: 0 0 var(--e-6);
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--e-2);
}
.lista-comentarios li {
    display: flex;
    align-items: flex-start;
    gap: var(--e-3);
    background: var(--superficie);
    border-radius: var(--radius);
    box-shadow: var(--sombra);
    padding: var(--e-3) var(--e-4);
}
.comentario-corpo { flex-grow: 1; min-width: 0; }
.comentario-corpo p { margin: 0; }
.comentario-cabecalho {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--e-2);
    margin-bottom: var(--e-1);
}
.comentario-excluir-btn { flex-shrink: 0; width: 1.8rem; height: 1.8rem; }
.comentario-form {
    display: flex;
    align-items: flex-start;
    gap: var(--e-3);
}
.comentario-form textarea {
    flex-grow: 1;
    resize: vertical;
    margin: 0;
}

/* ===== Mini rede social da home — composer, vídeo, link, comentário
   inline (2026-08-24/26, pedido do Felipe). Reusa .post-card/.btn-icone/
   .comentario-form já existentes; só o que é específico do feed de
   publicações entra aqui. */
.publicacao-composer { padding: var(--e-4) var(--e-6) var(--e-4); }
.publicacao-composer-topo {
    display: flex;
    align-items: flex-start;
    gap: var(--e-3);
}
.publicacao-composer-topo textarea {
    flex-grow: 1;
    resize: vertical;
    margin: 0;
    min-height: 2.6rem;
}
.publicacao-composer-anexos {
    display: flex;
    align-items: center;
    gap: var(--e-2);
    margin-top: var(--e-3);
    flex-wrap: wrap;
}
.publicacao-anexo-botao {
    display: inline-flex;
    align-items: center;
    gap: var(--e-2);
    color: var(--tinta-suave);
    font-size: var(--t-caption);
    font-weight: 700;
    border: 1px solid var(--linha-forte);
    border-radius: var(--radius);
    padding: var(--e-2) var(--e-3);
    cursor: pointer;
    transition: background var(--transicao), color var(--transicao), border-color var(--transicao);
}
.publicacao-anexo-botao:hover, .publicacao-anexo-botao:focus-within {
    background: var(--navy-tenue);
    color: var(--navy-600);
    border-color: var(--navy-600);
}
.publicacao-anexo-botao input[type="file"] {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}
.publicacao-link-campo {
    display: inline-flex;
    align-items: center;
    gap: var(--e-2);
    flex-grow: 1;
    min-width: 10rem;
    border: 1px solid var(--linha-forte);
    border-radius: var(--radius);
    padding: var(--e-1) var(--e-3);
    color: var(--tinta-suave);
}
.publicacao-link-campo input {
    flex-grow: 1;
    border: none;
    margin: 0;
    padding: var(--e-1) 0;
    background: transparent;
}
/* 2026-08-27: o `outline: none` aqui nao tinha NENHUM substituto -- o
   input nao tem borda propria (a borda e' do wrapper), entao focar o campo
   nao produzia mudanca visual alguma (falha WCAG 2.4.7). Em vez de
   devolver o outline no input (que desenharia um retangulo solto dentro da
   pilula do wrapper), o indicador vai pro wrapper via :has() -- mesmo
   truque nativo ja usado no Alcance do formulario de aviso. Mesmo anel de
   3px/3.17:1 dos campos normais. */
.publicacao-link-campo input:focus { outline: none; }
.publicacao-link-campo:has(input:focus) {
    border-color: var(--navy-600);
    box-shadow: var(--foco-anel);
}
.publicacao-composer-anexos .btn { margin-left: auto; }

.post-card-video video {
    width: 100%;
    max-height: 26rem;
    display: block;
    background: #000;
}

.post-card-link {
    display: flex;
    align-items: center;
    gap: var(--e-2);
    margin: 0 var(--e-6) var(--e-4);
    padding: var(--e-3) var(--e-4);
    border: 1px solid var(--linha-forte);
    border-radius: var(--radius);
    color: var(--navy-600);
    text-decoration: none;
    overflow: hidden;
}
.post-card-link:hover, .post-card-link:focus-visible { background: var(--navy-tenue); }
.post-card-link span {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.post-card-comentarios .comentario-linha {
    display: flex;
    align-items: flex-start;
    gap: var(--e-3);
    /* 2026-08-27: era var(--fundo), token inexistente -- o balao do
       comentario ficava transparente sobre o card branco, sem separacao
       visual nenhuma. Token real: --papel (#F0EDFB, Cinza Claro do DS). */
    background: var(--papel);
    border-radius: var(--radius);
    padding: var(--e-3) var(--e-4);
    margin: 0 var(--e-6) var(--e-2);
}
.post-card-comentarios .comentario-form { margin: var(--e-3) var(--e-6) var(--e-4); }

.marcar-todos-lidos-form { margin: var(--e-2) 0 var(--e-3); }

/* ===== Confirmacao formal de ciencia (2026-08-24, pedido do Felipe). */
/* "Quem abriu" o documento (2026-08-24, pedido do Felipe: abrir/baixar
   ja e' o validador de leitura -- substitui o antigo botao de confirmacao
   explicita). So visivel pro setor dono do documento. Icones pequenos
   (iniciais em circulo), mesma linguagem visual de "visto por" de redes
   sociais, sem precisar de foto/avatar real. */
.quem-abriu {
    background: var(--navy-100);
    border-top: 3px solid var(--navy-600);
    border-radius: var(--radius);
    padding: var(--e-4) var(--e-4);
    margin: var(--e-4) 0;
}
.quem-abriu-titulo {
    margin: 0 0 var(--e-2);
    font-weight: 700;
    color: var(--tinta);
}
.avatares-leitura {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: var(--e-2);
}
.avatar-leitura {
    width: 2rem;
    height: 2rem;
    border-radius: var(--radius-circulo);
    background: var(--navy-600);
    color: var(--superficie);
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: var(--grotesk);
    font-weight: 700;
    font-size: var(--t-caption);
    cursor: default;
    /* 2026-09-09: overflow:hidden recorta a foto de perfil (quando existe,
       ver core/_avatar_conteudo.html) no circulo -- inofensivo pra quem
       so tem a inicial, que nunca ultrapassa a caixa. */
    overflow: hidden;
}
.avatar-leitura img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* ===== Central de ajuda / FAQ (2026-08-24, achado em revisao de UX: heuristica
   "Ajuda e Documentacao" pontuou 1/4 -- sistema nao tinha nenhuma ajuda
   contextual). */
.lista-faq {
    display: flex;
    flex-direction: column;
    gap: var(--e-2);
}
.faq-item {
    background: var(--superficie);
    border-radius: var(--radius);
    box-shadow: var(--sombra);
    padding: var(--e-4) var(--e-4);
}
.faq-item summary {
    cursor: pointer;
    font-family: var(--grotesk);
    font-weight: 700;
    font-size: var(--t-body);
}
.faq-item p { margin: var(--e-2) 0 0; }

/* ===== Central de alertas (2026-08-24, pedido do Felipe). */
.lista-alertas {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--e-2);
}
.alerta-item {
    background: var(--superficie);
    border-radius: var(--radius);
    box-shadow: var(--sombra);
    padding: var(--e-4) var(--e-4);
    display: flex;
    /* 2026-08-28: linha rigida de 3 itens (selo + titulo + descricao) onde o
       titulo tem piso de min-width:140px -- em 320px nao cabe, e a pagina
       inteira ganhava 304px de barra horizontal. A regra que empilha no mobile
       mirava `.lista-documentos li`, e esta pagina reusa so' as CLASSES dos
       filhos, nunca aquele container -- entao nunca recebeu tratamento mobile
       nenhum. Quebrar a linha resolve nas 13 larguras sem media query nova. */
    flex-wrap: wrap;
    row-gap: var(--e-2);
    align-items: center;
    gap: var(--e-2);
    border-top: 3px solid var(--linha-forte);
}
.alerta-item.alerta-aviso_urgente { border-top-color: var(--urgente); }
.alerta-item.alerta-ciencia_pendente { border-top-color: var(--navy-600); }
/* 2026-08-27 (achado de QA): mesmo componente visual do badge de
   importância do card de aviso (.aviso-card-badge) -- eram duas
   linguagens diferentes pro mesmo conceito ("urgente"), uma pill
   colorida no feed, uma caixa monoespaçada aqui. Mesma pill, mesmas
   variantes de cor. */
.alerta-rotulo {
    display: inline-block;
    font-family: var(--grotesk);
    font-size: var(--t-overline);
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    padding: var(--e-1) var(--e-2);
    border-radius: var(--radius-pill);
    background: var(--terracota-100);
    color: var(--terracota-texto);
    border: 1px solid var(--terracota); /* 2026-08-28: ver .aviso-card-badge */
    flex-shrink: 0;
}
.alerta-item.alerta-aviso_urgente .alerta-rotulo { background: var(--urgente-100); color: var(--urgente-escuro); border-color: var(--urgente); }

/* Sino de alertas no cabecalho */
.sino-alertas {
    position: relative;
    display: inline-flex;
    align-items: center;
    color: inherit;
}
/* 2026-08-28: area de clique minima de 24x24 (WCAG 2.5.8, nivel AA).
   Medido no viewport real de 360px: o sino dava 18x23 e o "Sair" 16x16.
   Overlay centrado -- nao muda tamanho, posicao nem espacamento de nada;
   so' aumenta o que o dedo acerta. Os segmentos do carrossel (12x24)
   ficam de fora de proposito: caem na excecao "Equivalente" do criterio,
   porque as setas fazem a mesma navegacao em 34x34. */
.sino-alertas::before,
.logout-form .link-button::before {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: 24px;
    height: 24px;
    transform: translate(-50%, -50%);
}
/* 2026-08-28 (auditoria): mesmo defeito de .sidebar-badge -- pilula
   #6B3FA0 sobre o gradiente que termina em #6B3FA0. Mesma inversao. */
.sino-alertas .badge-alertas {
    position: absolute;
    top: -0.4rem;
    right: -0.5rem;
    background: var(--superficie);
    color: var(--navy-600);
    font-family: var(--mono);
    font-size: var(--t-overline);
    font-weight: 700;
    line-height: 1;
    padding: var(--e-1) var(--e-1);
    border-radius: var(--radius-pill);
    min-width: 1.1rem;
    text-align: center;
}

/* Agrupa sino de alertas + sair, com espacamento maior entre eles
   (2026-08-24, pedido do Felipe: sino ficava perto demais do botao de
   sair, risco de clique errado). */
.cabecalho-acoes-usuario {
    display: flex;
    align-items: center;
    gap: var(--e-6);
    padding-left: var(--e-6);
    margin-left: var(--e-1);
    border-left: 1px solid rgba(255, 255, 255, 0.25);
}

/* Lançador de sistemas — a "grade de pontinhos" do cabeçalho (2026-08-31,
   pedido do Paulo via Felipe: "um menu igual ao do Gmail, mas para os
   sistemas internos do COPPEAD"). Popover nativo, sem JS nenhum. */
.lancador { display: inline-flex; }

.lancador-botao {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    min-height: 0;
    padding: 0;
    border: none;
    border-radius: var(--radius);
    background: none;
    color: var(--superficie);
    cursor: pointer;
    transition: background var(--transicao);
}
.lancador-botao:hover { background: rgba(255, 255, 255, 0.16); }
.lancador-botao:focus-visible {
    /* Cabeçalho é superfície escura: o --foco-anel roxo some contra o
       gradiente. Mesma razão que já levou o menu superior ao anel sólido. */
    outline: none;
    box-shadow: var(--foco-anel-solido);
}

/* display:none no estado base + :popover-open para abrir. Num navegador sem
   Popover API o seletor :popover-open é inválido, a regra inteira é
   descartada e o painel fica escondido para sempre — o botão vira inerte.
   Degradar para "atalho ausente" é aceitável; degradar para "painel colado
   na tela em toda página" não seria.
   O UA aplica `position:fixed; inset:0; margin:auto` em [popover] — daí o
   `inset` e o `margin` explícitos abaixo, senão o painel centraliza na tela.

   ⚠️ 2026-08-31, defeito real corrigido (Felipe: "nada acontece quando clico"):
   elemento na camada superior resolve `position:absolute` contra o **viewport**,
   NÃO contra o ancestral posicionado. A primeira versão usava
   `position:absolute; top: calc(100% + 0.9rem)` contando com um `.lancador`
   com `position:relative` — mas `100%` virou a altura da JANELA, e o painel
   abria ~14px abaixo da dobra. Ele sempre abriu; ninguém via.
   Como o contentor é o viewport de qualquer jeito, `fixed` é honesto: o topo
   é a altura do cabeçalho (66px) mais uma folga, e a direita acompanha o
   padding de 2rem do `.site-header`, alinhando o painel à borda do conteúdo.
   Só dá para abrir com o cabeçalho na tela (é onde o botão está), então
   ancorar na janela não desgruda na prática.
   ponytail: números fixos amarrados à altura do cabeçalho; se ele mudar de
   altura, ajustar o `top` aqui — ou migrar para CSS anchor positioning
   (`anchor-name`/`position-area`), que ainda não é suportado fora do Chromium. */
.lancador-painel {
    display: none;
    position: fixed;
    inset: auto 2rem auto auto;
    top: 4.6rem;
    margin: 0;
    width: min(20rem, calc(100vw - 2rem));
    padding: var(--e-4);
    background: var(--superficie);
    color: var(--tinta);
    border: 1px solid var(--linha);
    border-radius: var(--radius);
    box-shadow: 0 12px 32px rgba(27, 23, 49, 0.22);
    overflow: visible;
}
.lancador-painel:popover-open { display: block; }

/* ============================================================
   2026-08-31 (auditoria): quatro ajustes medidos no navegador, em producao.
   ============================================================ */

/* 1. O painel do lancador abria 74px a DIREITA do proprio botao (medido:
      botao termina em x=1415, painel em x=1489). `inset: auto 2rem auto auto`
      ancora na JANELA, e o botao nao e' o ultimo item do cabecalho -- sino e
      "Sair" vem depois dele, entao o painel alinhava com o "Sair".
      Numero fixo nao resolve: a largura daqueles dois muda com o badge de
      alertas. Ancoragem CSS resolve de verdade; o @supports mantem o
      comportamento de hoje (funcional, so' torto) onde ela ainda nao existe. */
.lancador-botao { anchor-name: --ancora-lancador; }
@supports (anchor-name: --x) {
    .lancador-painel {
        position-anchor: --ancora-lancador;
        top: calc(anchor(bottom) + var(--e-2, 0.5rem));
        right: anchor(right);
        left: auto;
        bottom: auto;
    }
}

/* 2. Tres controles vizinhos, tres tratamentos: o lancador entrou hoje como
      32x32 com raio e fundo no hover, e sino e "Sair" continuaram icone nu --
      e ainda herdavam de `.site-header nav a` o sublinhado animado e o
      `padding-bottom`, que era de onde saiam os 23px de altura do sino.
      Mesma caixa pros tres. O overlay ::before de 24x24 de 28/08 fica onde
      esta: agora e' menor que a caixa, nao atrapalha, e volta a valer sozinho
      se alguem reduzir o botao um dia. */
.site-header .sino-alertas,
.site-header .logout-form .link-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    min-height: 0;
    padding: 0;
    border-radius: var(--radius);
    transition: background var(--transicao);
}
.site-header .sino-alertas::after,
.site-header .logout-form .link-button::after { content: none; }
.site-header .sino-alertas:hover,
.site-header .logout-form .link-button:hover { background: rgba(255, 255, 255, 0.16); }

/* 3. WCAG 2.2 2.5.8: `.ver-informativos` media 185x21 e o link do rodape
      30x14. Mesma tecnica de overlay ja usada no sino desde 28/08 -- nao muda
      tamanho, posicao nem espacamento de nada, so' aumenta o que o dedo
      acerta. `width: 100%` cobre o link inteiro; `min-width` so' age no link
      curto do rodape. */
.ver-informativos,
.site-footer a { position: relative; }
.ver-informativos::before,
.site-footer a::before {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: 100%;
    min-width: 24px;
    height: 24px;
    transform: translate(-50%, -50%);
}

/* 4. `color-scheme: light` declarado. Isto NAO e' modo escuro -- e' dizer ao
      navegador qual e' o unico tema que existe aqui. Sem a declaracao, quem
      usa o SO em modo escuro recebe controle de formulario, scrollbar e
      autofill pintados pelo tema do sistema em cima de uma pagina que e'
      clara por decisao do Design System oficial. */
:root { color-scheme: light; }

/* Selo de gestor na "Equipe do setor" (2026-08-31, pedido do Paulo via Felipe).
   Estrela + palavra, nunca a estrela sozinha: aqui estrela ja' significa
   "favorito" (.painel-favoritos-estrela), e o DESIGN.md e' explicito pra badge --
   "nunca cor sozinha sem texto". */
.selo-gestor {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    flex-shrink: 0;
    color: var(--navy-600);
    font-family: var(--mono);
    font-size: var(--t-overline, 0.68rem);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    white-space: nowrap;
}
.selo-gestor svg { width: 0.85rem; height: 0.85rem; display: block; }



.lancador-titulo {
    margin: 0 0 var(--e-3);
    font-family: var(--mono);
    font-size: var(--t-label);
    font-weight: 400;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--tinta-suave);
}

.lancador-grade {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--e-1);
}

/* Seletor escopado no `.site-header nav` de propósito, não por capricho: o
   lançador mora dentro do <nav> do cabeçalho, então cada item é também um
   `.site-header nav a` e herdava dali cor lilás-clara (--navy-claro, feita
   para fundo escuro e ilegível sobre o painel branco), CAIXA ALTA,
   `padding-bottom: 0.3rem` e uma barra `::after` de sublinhado animado.
   2026-08-31: foi exatamente assim que os 6 nomes saíram lavados e cortados
   na primeira versão publicada. `.site-header nav .lancador-item` (0,2,1)
   vence `.site-header nav a` (0,1,2) por contagem de classe.
   Se o lançador um dia sair do cabeçalho, este escopo tem que sair junto. */
.site-header nav .lancador-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--e-2);
    min-width: 0;
    padding: var(--e-3) var(--e-1);
    border-radius: var(--radius);
    color: var(--tinta);
    font-size: var(--t-caption);
    text-align: center;
    text-transform: none;
    letter-spacing: normal;
    text-decoration: none;
    transition: background var(--transicao);
}
/* Mata a barra de sublinhado animado do menu superior. */
.site-header nav .lancador-item::after { content: none; }
.site-header nav .lancador-item:hover,
.site-header nav .lancador-item:focus-visible {
    background: var(--navy-100);
    color: var(--tinta);
    text-decoration: none;
}
.site-header nav .lancador-item:focus-visible {
    /* O :focus-visible do menu superior usa contorno BRANCO (superfície
       escura). Aqui o fundo é branco: volta o anel roxo padrão. */
    outline: none;
    box-shadow: var(--foco-anel);
}

/* O sprite não é para ser visto: só guarda os <symbol> que os ladrilhos
   referenciam. `width/height: 0` + `position: absolute` em vez de
   `display: none` — a técnica de sprite consagrada, que não depende de o
   navegador resolver <use> a partir de uma árvore não renderizada. */
.lancador-sprite {
    position: absolute;
    width: 0;
    height: 0;
    overflow: hidden;
}

.lancador-ladrilho {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 2.5rem;
    height: 2.5rem;
    border-radius: 50%;
    background: var(--gradiente-marca);
    color: var(--superficie);
}
.lancador-ladrilho svg {
    /* currentColor no <symbol> herda daqui: um só desenho, e a cor é
       decidida pelo ladrilho. */
    width: 1.25rem;
    height: 1.25rem;
    display: block;
}

.lancador-nome {
    min-width: 0;
    font-size: var(--t-caption);
    line-height: 1.2;
    overflow-wrap: break-word;
}

/* "(abre em nova aba)" — invisível na tela, lido pelo leitor de tela: todo
   item do lançador sai do sistema em aba nova, e isso precisa ser anunciado. */
.lancador-nova-aba {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* Interações "vivas" (2026-08-27, achado de QA/pedido do Felipe: curtir e
   comentar recarregavam a página inteira sem nenhuma resposta visual
   imediata, "sensação de sistema morto"). Sem mudar o contrato do
   backend (continua form POST clássico com reload) -- micro-interações
   que dão feedback ANTES do reload acontecer. Ver static/js/main.js. */
@keyframes curtir-pulso-anim {
    0%   { transform: scale(1); }
    40%  { transform: scale(1.25); }
    100% { transform: scale(1); }
}
.curtir-pulso svg { animation: curtir-pulso-anim 220ms ease-out; }

.comentario-form textarea {
    resize: none;
    overflow: hidden;
}

@media (prefers-reduced-motion: reduce) {
    .curtir-pulso svg { animation: none; }
}

/* Tooltip de ajuda ("i") -- só onde o rótulo sozinho não deixa claro o
   que a ação faz (ex.: "Marcar como não lido" em banners/detalhe.html).
   Trigger é <button>, não <span onmouseover>: funciona por teclado/foco
   (:focus-visible), não só hover -- importante em uso por tablet/toque. */
.info-tip { position: relative; display: inline-flex; align-items: center; gap: var(--e-1); }
/* 2026-08-28 (auditoria): o gatilho era um <button> de 14x14px com
   padding:0 -- reprova WCAG 2.2 SC 2.5.8, que exige alvo minimo de
   24x24 CSS px. O glifo continua com 14px; quem cresce e' a area
   clicavel, centralizada por flex (mesma solucao ja usada em
   .banner-fechar). `cursor: help` num <button>: trocado por pointer,
   que e' o que a peca realmente e'. */
.info-tip-trigger {
    background: none;
    border: none;
    width: 24px;
    height: 24px;
    /* 2026-08-29: `button, .btn` acima define `min-height: var(--altura-botao)`
       (40px), que vence o `height: 24px` daqui -- o gatilho media 24x40 e o
       anel de foco, com border-radius 50%, saia ELIPTICO. Nao era regressao do
       login: valia em todas as telas que usam .info-tip desde que o componente
       existe. Pego medindo o alvo no harness (24x40 em vez de 24x24). */
    min-height: 0;
    padding: 0;
    cursor: pointer;
    color: inherit;
    opacity: 0.6;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-circulo);
    flex-shrink: 0;
}
.info-tip-trigger:hover, .info-tip-trigger:focus-visible { opacity: 1; }
.info-tip-balao {
    position: absolute;
    bottom: calc(100% + 6px);
    left: 50%;
    transform: translateX(-50%) translateY(4px);
    background: var(--tinta);
    color: var(--superficie);
    font-family: var(--grotesk);
    font-size: var(--t-caption);
    line-height: 1.4;
    padding: var(--e-2) var(--e-3);
    border-radius: var(--radius);
    max-width: 240px;
    white-space: normal;
    opacity: 0;
    /* opacity/pointer-events escondiam o balao na tela mas nao da arvore
       de acessibilidade -- leitor de tela sempre lia o texto, e em varios
       lugares o balao vive DENTRO do <h1> ou do <label> do campo (achado
       UX 02/09). visibility com atraso na saida tira do leitor sem cortar
       o fade: some so' depois da transicao terminar. */
    visibility: hidden;
    pointer-events: none;
    transition: opacity 150ms ease-out, transform 150ms ease-out, visibility 0s linear 150ms;
    z-index: 10;
}
/* 2026-08-28 (auditoria): o balao so' abria no :hover do GATILHO, entao
   levar o mouse ate' o proprio balao o fechava -- reprova WCAG 2.2
   SC 1.4.13 (Content on Hover or Focus), criterio "Hoverable": o conteudo
   precisa continuar visivel com o ponteiro em cima dele. Ancorando o
   hover no wrapper .info-tip (que contem gatilho + balao) o balao fica
   alcancavel. `pointer-events` volta a auto so' quando visivel, senao um
   balao invisivel capturaria cliques do que estiver embaixo.
   O :focus-within cobre o teclado; o Esc continua tratado no main.js. */
.info-tip:hover .info-tip-balao,
.info-tip:focus-within .info-tip-balao {
    opacity: 1;
    visibility: visible;
    transition-delay: 0s;
    pointer-events: auto;
    transform: translateX(-50%) translateY(0);
}
/* 2026-08-28 (achado do Felipe, com screenshot): balao padrao abre pra
   CIMA e centralizado -- nos icones do cabecalho de documento (favorito/
   marcar como nao lido), que ficam colados no canto superior direito do
   card, isso jogava o balao pra fora do card por cima E pela direita; o
   card tem overflow:hidden (pros cantos arredondados), entao o texto
   saia cortado em vez de simplesmente aparecer fora de lugar. Modificador
   só pros gatilhos que ficam no topo/borda: abre pra BAIXO (sempre tem o
   corpo do card embaixo) e gruda a borda direita do balao na borda
   direita do gatilho em vez de centralizar, então também não escapa pela
   lateral. */
.info-tip--cabecalho .info-tip-balao {
    bottom: auto;
    top: calc(100% + 6px);
    left: auto;
    right: -6px;
    transform: translateY(-4px);
}
.info-tip--cabecalho:hover .info-tip-balao,
.info-tip--cabecalho:focus-within .info-tip-balao {
    transform: translateY(0);
}
/* 2026-08-31 (achado do Felipe): mesmo defeito de 28/08 (balão abre pra
   cima, perto do topo do card, sai cortado) reapareceu no "i" dos
   cabeçalhos de tela (form-card-cabecalho, ex. "Enviar documento") porque
   o modificador --cabecalho não foi aplicado ali -- exigia lembrar de
   adicionar a classe toda vez que um "i" novo entrasse perto do topo.
   Regra por CONTEXTO em vez de classe manual: qualquer .info-tip dentro
   de .form-card-cabecalho herda o comportamento "abre pra baixo"
   automaticamente, não depende de ninguém lembrar. */
/* 02/09 (achado UX): o .info-tip do cabecalho envolve so' o botao de
   24px -- sem largura propria, o balao encolhia no shrink-to-fit e o
   texto saia uma palavra por linha, empilhado alem do topo do cartao.
   Mesma tecnica do .login-card (~3030): ancora no <h1>, que tem a
   largura do card, em vez de no botao. */
.form-card-cabecalho h1 { position: relative; }
.form-card-cabecalho .info-tip { position: static; }
.form-card-cabecalho .info-tip-balao {
    bottom: auto;
    top: calc(100% + 6px);
    left: 0;
    right: 0;
    width: auto;
    max-width: none;
    transform: translateY(-4px);
}
.form-card-cabecalho .info-tip:hover .info-tip-balao,
.form-card-cabecalho .info-tip:focus-within .info-tip-balao {
    transform: translateY(0);
}
@media (prefers-reduced-motion: reduce) {
    .info-tip-balao { transition: none; }
}

/* ===== Overrides de mobile — realocados para o fim do arquivo (2026-08-28) =====
   Este bloco @media (max-width: 640px) vivia perto do TOPO do arquivo. Todas as
   regras-base que ele tenta sobrescrever (.perfil-grid, .perfil-form-linha,
   .lista-documentos li, .lista-documentos-acoes, .setor-acoes) sao declaradas
   DEPOIS dele, com a mesma especificidade (0,1,0) -- entao a base ganhava
   sempre e o celular nunca recebia override nenhum. Era REGRA MORTA, exatamente
   o mesmo defeito que ja' tinha sido diagnosticado e corrigido para .container
   em 2026-08-27; o resto do bloco ficou para tras. Efeito medido: o perfil
   mantinha a coluna fixa de 280px em tela de 320px (71px de barra horizontal) e
   as linhas de documento nunca empilhavam. Mover para o fim e' o menor conserto
   possivel -- nenhuma declaracao mudou, so' a posicao na cascata. */
@media (max-width: 640px) {
    /* 2026-08-27: aqui existia `.container { padding: 1.5rem 1rem 3rem; }`
       -- REGRA MORTA. A regra base `.container { padding: 2.25rem 2rem
       4rem; }` esta DEPOIS neste mesmo arquivo e tem a mesma
       especificidade (0,1,0), entao ganhava sempre e o celular nunca
       recebia o padding reduzido. Movida pro bloco @media (max-width:
       640px) do fim do arquivo, que vem depois da regra base e portanto
       aplica de verdade. Nao inverti a ordem das regras aqui pra nao mexer
       na cascata de tudo o mais que esse bloco define. */

    /* 02/09 (achado UX consistencia): .site-header era declarado 3x neste
       breakpoint (aqui, e mais dois blocos acima, ambos regra morta por
       especificidade igual e ordem no arquivo) -- padding e gap
       divergentes entre eles, e so' este bloco (o ultimo) vencia. `gap`
       reproduz o par row/column que ja renderizava (8px/12px) sem
       depender de heranca entre blocos; `padding` cai de 24px pra 16px,
       batendo com o `.container` (var(--e-6) var(--e-4)) -- unica
       consequencia visual real desta consolidacao. flex-wrap saiu: nao
       faz nada num container grid. */
    .site-header {
        gap: var(--e-2) var(--e-3);
        padding: var(--e-3) var(--e-4);
    }
    .site-header nav {
        flex-wrap: wrap;
        row-gap: var(--e-2);
    }

    /* Linhas de aviso/documento: em vez de espremer tudo numa linha so
       (setor, titulo, data, acoes), empilha verticalmente abaixo de ~640px
       (2026-07-18: risco real de overflow horizontal em tela de celular,
       nunca testado ao vivo ate agora). */
    .lista-documentos li {
        flex-direction: column;
        align-items: flex-start;
        gap: var(--e-2);
    }
    .lista-documentos-acoes {
        margin-left: 0;
        width: 100%;
        justify-content: space-between;
    }

    .setor-acoes { flex-wrap: wrap; }

    /* Perfil de usuário: grid fixo de 2 colunas (280px + 1fr) não cabe
       numa tela de celular — empilha o cartão de identidade acima do
       conteúdo (2026-07-20, achado na revisão: não havia override mobile
       nenhum pro layout novo em duas colunas). */
    .perfil-grid { grid-template-columns: 1fr; }
    .perfil-form-linha { grid-template-columns: 1fr; }
}

/* 02/09 (achado UX navegacao/baixa): o menu do cabecalho nunca marcava a
   pagina atual -- so' o :hover/:focus-visible acendia o sublinhado, entao
   quem navega por teclado via o sublinhado como "onde meu cursor esta",
   nunca "onde eu estou". aria-current="page" e' posto pelo base.html via
   {% with rota=... %}. Fica no FIM do arquivo de proposito: a regra do
   sino empata em especificidade (0,3,2) com .sino-alertas:hover (~4644)
   e so' vence por ordem. */
.site-header nav a[aria-current="page"] { color: var(--superficie); }
.site-header nav a[aria-current="page"]::after { transform: scaleX(1); }
.site-header .sino-alertas[aria-current="page"] { background: rgba(255, 255, 255, 0.16); }
