/* =====================================================================
   SISTEMA DE TREINAMENTOS — folha de estilo única.

   DECISÕES DE DESIGN E O MOTIVO DE CADA UMA
   -----------------------------------------
   1. SEM FRAMEWORK (Bootstrap, Tailwind). O sistema tem ~15 telas e um visual
      simples. Um framework traria centenas de KB e um vocabulário de classes
      a aprender, para economizar pouca coisa. Menos dependência também
      significa menos atualização de segurança para acompanhar.

   2. VARIÁVEIS CSS (custom properties) no :root. Trocar a cor institucional da
      empresa é editar UMA linha. Sem elas, seria caçar o mesmo código
      hexadecimal em cinquenta lugares.

   3. UNIDADES RELATIVAS (rem) em vez de pixels fixos. Quem aumenta a fonte do
      navegador — comum entre pessoas com baixa visão — vê o layout inteiro
      acompanhar, em vez de textos gigantes dentro de caixas pequenas.

   4. MODO ESCURO via prefers-color-scheme. Só redefinimos as variáveis; nenhum
      componente precisa ser reescrito. É o retorno da decisão nº 2.

   5. CONTRASTE. As combinações de texto e fundo seguem a razão mínima de 4.5:1
      recomendada pela norma de acessibilidade WCAG. Num sistema de uso
      obrigatório, ninguém pode ficar de fora por não conseguir ler.
   ===================================================================== */

:root {
  /* Cor institucional: azul sóbrio. Trocar aqui muda o sistema inteiro. */
  --cor-primaria: #1c4f8b;
  --cor-primaria-escura: #16406f;
  --cor-primaria-clara: #e8f0f9;

  /* Cores de estado. Verde/âmbar/vermelho são convenção cultural forte;
     mas nunca usamos SÓ a cor — sempre acompanhada de texto. */
  --cor-ok: #1f7a4d;
  --cor-ok-fundo: #e6f4ec;
  --cor-atencao: #8a5300;
  --cor-atencao-fundo: #fdf3e2;
  --cor-perigo: #a32020;
  --cor-perigo-fundo: #fbeaea;

  --cor-texto: #1a1f26;
  --cor-texto-suave: #5a6472;
  --cor-fundo: #f4f6f9;
  --cor-superficie: #ffffff;
  --cor-borda: #d8dee7;

  --raio: 8px;
  --raio-grande: 14px;
  --largura-maxima: 1200px;

  /* ESCALA DE PROFUNDIDADE
     Três níveis, não cinco. A sombra comunica DISTÂNCIA do fundo: repouso,
     interativo-sob-o-cursor, e flutuante (diálogo). Mais níveis que isso
     ninguém distingue, e cada um vira uma decisão a mais para tomar errado.
     Sombras em duas camadas — uma curta e densa, uma longa e difusa — porque é
     assim que a luz real cai; uma camada só parece adesivo. */
  --sombra: 0 1px 2px rgba(16, 24, 40, .06), 0 1px 3px rgba(16, 24, 40, .04);
  --sombra-media: 0 2px 4px rgba(16, 24, 40, .06), 0 8px 20px rgba(16, 24, 40, .08);
  --sombra-alta: 0 8px 16px rgba(16, 24, 40, .10), 0 24px 48px rgba(16, 24, 40, .16);

  /* MOVIMENTO
     Duas durações e uma curva, usadas em tudo. É a consistência que faz uma
     interface parecer projetada em vez de montada — animações com tempos
     diferentes a cada componente dão a sensação de coisa remendada.

     120ms para RESPOSTA (hover, clique): abaixo disso o olho não percebe
     transição, acima começa a parecer atraso entre o dedo e a tela.
     260ms para ENTRADA (conteúdo chegando): tempo de acompanhar o movimento
     sem esperar por ele.

     A curva é ease-out — rápida no começo, suave no fim. É o oposto de
     `linear`, que parece mecânico, e de `ease-in`, que parece que a interface
     hesitou antes de obedecer. */
  --tempo-resposta: 120ms;
  --tempo-entrada: 260ms;
  --curva: cubic-bezier(.22, .61, .36, 1);
}

@media (prefers-color-scheme: dark) {
  :root {
    --cor-primaria: #6ea8e6;
    --cor-primaria-escura: #8bbcf0;
    --cor-primaria-clara: #16283d;
    --cor-ok: #6fd39b;
    --cor-ok-fundo: #14301f;
    --cor-atencao: #e5b562;
    --cor-atencao-fundo: #33260f;
    --cor-perigo: #f08a8a;
    --cor-perigo-fundo: #351717;
    --cor-texto: #e8ecf2;
    --cor-texto-suave: #a3adba;
    --cor-fundo: #10151c;
    --cor-superficie: #1a222c;
    --cor-borda: #2c3744;

    /* Sombras precisam ser MAIS densas no escuro, não menos. Sombra é ausência
       de luz; sobre fundo escuro ela quase não aparece, e os cartões perdem a
       separação do fundo. Compensamos com opacidade maior e uma borda de topo
       clara que simula luz vindo de cima. */
    --sombra: 0 1px 2px rgba(0, 0, 0, .40), 0 1px 3px rgba(0, 0, 0, .30);
    --sombra-media: 0 2px 4px rgba(0, 0, 0, .40), 0 8px 20px rgba(0, 0, 0, .45);
    --sombra-alta: 0 8px 16px rgba(0, 0, 0, .45), 0 24px 48px rgba(0, 0, 0, .55);
  }
}

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  /* Pilha de fontes do sistema: usa a fonte nativa de cada plataforma.
     Carrega instantaneamente (nada a baixar) e parece nativo em todo lugar. */
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
               "Helvetica Neue", Arial, sans-serif;
  font-size: 1rem;
  line-height: 1.55;
  color: var(--cor-texto);
  background: var(--cor-fundo);
  display: flex;
  flex-direction: column;

  /* 100vh MENTE no celular: a unidade considera a janela SEM a barra de
     endereço, então um rodapé "no fim da tela" fica escondido atrás dela até a
     pessoa rolar. `dvh` (dynamic viewport height) acompanha a barra aparecendo
     e sumindo. A linha com vh fica antes como retaguarda para navegadores que
     não conhecem dvh — eles simplesmente ignoram a segunda declaração. */
  min-height: 100vh;
  min-height: 100dvh;

  /* Impede o Safari do iPhone de aumentar a fonte por conta própria ao girar
     o aparelho para a horizontal — o layout "cresce" sozinho sem isto. */
  -webkit-text-size-adjust: 100%;

  /* Um título longo sem espaços (nome de arquivo, URL colada pelo admin) não
     pode esticar a página e criar rolagem horizontal no corpo inteiro. */
  overflow-wrap: break-word;
}

/* Título grande pede entrelinha e espaçamento MENORES, não maiores. Em corpo de
   texto o espaço entre letras ajuda a ler; em títulos ele afrouxa a palavra e
   tira o peso. `-.015em` é sutil o bastante para ninguém notar como escolha e
   suficiente para o título parecer sólido. */
h1 { font-size: 1.6rem; margin: 0 0 .25rem; letter-spacing: -.015em; line-height: 1.25; }
h2 { font-size: 1.15rem; margin: 0 0 .5rem; }
h3 { font-size: 1rem; margin: 0; }
p  { margin: .35rem 0; }
a  { color: var(--cor-primaria); text-decoration: none; }
a:hover { text-decoration: underline; }
code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .9em;
  background: var(--cor-primaria-clara);
  padding: .1rem .3rem;
  border-radius: 4px;
}

/* Foco visível: ESSENCIAL. Quem navega por teclado (ou não usa mouse por
   limitação motora) precisa ver onde está. Remover o contorno de foco é um
   dos erros de acessibilidade mais comuns em CSS. */
:focus-visible {
  outline: 3px solid var(--cor-primaria);
  outline-offset: 2px;
}

/* ---------------------------------------------------------------- TOPO */
/* Altura aproximada do cabeçalho, para quem precisa grudar ABAIXO dele (a coluna
   do PDF na revisão de avaliação). Não é o cabeçalho que a usa — ele é
   dimensionado pelo próprio conteúdo; é a medida de quem tem de descontá-la. */
:root { --altura-topo: 4.2rem; }

.topo {
  background: var(--cor-superficie);
  border-bottom: 1px solid var(--cor-borda);
  box-shadow: var(--sombra);

  /* O cabeçalho ACOMPANHA a rolagem. Numa tabela de 80 documentos, voltar ao
     topo para trocar de tela era uma rolagem inteira de volta. `sticky` (e não
     `fixed`) mantém o elemento no fluxo, então o conteúdo não precisa de
     compensação de margem — que é como esse recurso costuma quebrar. */
  position: sticky;
  top: 0;
  z-index: 20;
}

/* Fio da cor institucional no topo da página. Um detalhe de 3px que faz o
   sistema parecer da empresa, e não um formulário genérico. O gradiente clareia
   para a direita para não virar uma barra chapada. */
.topo::before {
  content: "";
  display: block;
  height: 3px;
  background: linear-gradient(90deg, var(--cor-primaria), var(--cor-primaria-escura) 55%, var(--cor-primaria));
}
.topo-conteudo {
  max-width: var(--largura-maxima);
  margin: 0 auto;
  padding: .75rem 1.25rem;
  display: flex;
  align-items: center;
  gap: 1.5rem;
  flex-wrap: wrap;
}
.marca {
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--cor-texto);
  white-space: nowrap;
}
.marca:hover { text-decoration: none; }
.marca-leve { color: var(--cor-texto-suave); font-weight: 400; margin-left: .3rem; }

.menu { display: flex; gap: .25rem; flex-wrap: wrap; flex: 1; }
.menu a {
  padding: .4rem .7rem;
  border-radius: var(--raio);
  color: var(--cor-texto-suave);
  font-size: .95rem;
}
.menu a:hover { background: var(--cor-primaria-clara); text-decoration: none; }
/* O item ativo tem cor E peso diferentes: se a pessoa não distingue as cores,
   o negrito ainda comunica onde ela está. */
.menu a.ativo { background: var(--cor-primaria-clara); color: var(--cor-primaria); font-weight: 600; }

.usuario { display: flex; align-items: center; gap: .75rem; }
.usuario-nome { display: flex; flex-direction: column; font-size: .9rem; line-height: 1.2; }
.usuario-perfil { color: var(--cor-texto-suave); font-size: .78rem; }

/* ------------------------------------------------------------ CONTEÚDO */
.conteudo {
  flex: 1;
  width: 100%;
  max-width: var(--largura-maxima);
  margin: 0 auto;
  padding: 1.5rem 1.25rem 3rem;
}
.conteudo--centralizado {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  max-width: 460px;
}

.cabecalho-pagina {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 1.25rem;
}
.subtitulo { color: var(--cor-texto-suave); margin: 0; }

.rodape {
  border-top: 1px solid var(--cor-borda);
  padding: 1rem 1.25rem;
  text-align: center;
  color: var(--cor-texto-suave);
  font-size: .85rem;
}

/* -------------------------------------------------------------- AVISOS */
.avisos { display: grid; gap: .5rem; margin-bottom: 1.25rem; }
.aviso {
  padding: .7rem .9rem;
  border-radius: var(--raio);
  border-left: 4px solid;
  font-size: .95rem;
}
.aviso--sucesso { background: var(--cor-ok-fundo); border-color: var(--cor-ok); color: var(--cor-ok); }
.aviso--erro    { background: var(--cor-perigo-fundo); border-color: var(--cor-perigo); color: var(--cor-perigo); }
.aviso--aviso   { background: var(--cor-atencao-fundo); border-color: var(--cor-atencao); color: var(--cor-atencao); }
.aviso--info    { background: var(--cor-primaria-clara); border-color: var(--cor-primaria); color: var(--cor-primaria); }

/* -------------------------------------------------------------- BOTÕES */
.botao {
  display: inline-block;
  padding: .5rem .9rem;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
  background: var(--cor-superficie);
  color: var(--cor-texto);
  font-size: .93rem;
  font-family: inherit;
  cursor: pointer;
  text-align: center;
  /* Área de toque confortável no celular (recomendação: ~44px). */
  min-height: 2.4rem;
}
.botao:hover { background: var(--cor-primaria-clara); text-decoration: none; }
.botao--principal {
  background: var(--cor-primaria);
  border-color: var(--cor-primaria);
  color: #fff;
  font-weight: 600;
}
.botao--principal:hover { background: var(--cor-primaria-escura); }
.botao--perigo { color: var(--cor-perigo); border-color: var(--cor-perigo); background: transparent; }
.botao--perigo:hover { background: var(--cor-perigo-fundo); }
.botao--discreto { background: transparent; border-color: transparent; color: var(--cor-texto-suave); }
.botao--discreto:hover { background: var(--cor-primaria-clara); }
.botao--pequeno { padding: .3rem .6rem; font-size: .85rem; min-height: 2rem; }
.botao--largo { width: 100%; }
.botao--enviando { opacity: .6; cursor: progress; }
.botao:disabled { opacity: .6; cursor: not-allowed; }

/* Botão quadrado só com símbolo (zoom do visualizador). O lado mínimo de
   2.75rem = 44px é a recomendação de alvo de toque da Apple e do Google: abaixo
   disso, o erro de toque com o polegar cresce muito. */
.botao--icone {
  min-width: 2.75rem;
  min-height: 2.75rem;
  padding: .4rem;
  font-size: 1.15rem;
  line-height: 1;
  font-weight: 700;
}

/* Estado do "declarar ciência" antes de a leitura chegar ao fim. Mantemos o
   botão VISÍVEL e apenas apagado — escondê-lo faria a pessoa procurar por algo
   que ela não sabe que existe. */
.botao--bloqueado { opacity: .55; }

.acoes { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; }
.form-inline { display: inline; }

/* --------------------------------------------------------- FORMULÁRIOS */
.campo { margin-bottom: 1rem; }
.campo label {
  display: block;
  font-weight: 600;
  font-size: .9rem;
  margin-bottom: .25rem;
}
.entrada {
  width: 100%;
  padding: .55rem .7rem;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
  background: var(--cor-superficie);
  color: var(--cor-texto);
  /* 1rem = 16px evita o zoom automático do Safari no iOS ao focar o campo. */
  font-size: 1rem;
  font-family: inherit;
}
.entrada:focus { border-color: var(--cor-primaria); }
.campo--erro .entrada { border-color: var(--cor-perigo); }
.mensagem-erro { color: var(--cor-perigo); font-size: .85rem; margin: .25rem 0 0; }
.ajuda { color: var(--cor-texto-suave); font-size: .85rem; margin: .25rem 0 0; }

.campo--checkbox { margin-bottom: 1rem; }
.rotulo-checkbox { display: flex; align-items: center; gap: .5rem; font-weight: 400; }
.rotulo-checkbox input { width: 1.05rem; height: 1.05rem; }

fieldset {
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
  padding: 1rem 1.1rem .5rem;
  margin: 0 0 1.25rem;
}
legend { font-weight: 600; padding: 0 .4rem; font-size: .95rem; }

.cartao-form {
  background: var(--cor-superficie);
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
  padding: 1.5rem;
  box-shadow: var(--sombra);
  max-width: 640px;
}
.info-arquivo {
  background: var(--cor-primaria-clara);
  border-radius: var(--raio);
  padding: .75rem .9rem;
  margin-bottom: 1rem;
  font-size: .9rem;
}

/* Formulários horizontais (vincular documento, filtros). O grid com
   auto-fit reflui sozinho no celular, sem media query. */
.form-linha, .barra-filtros {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 1rem;
  align-items: end;
}
.barra-filtros {
  background: var(--cor-superficie);
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
  padding: 1rem;
  margin-bottom: 1.25rem;
}
.campo--acoes { display: flex; gap: .5rem; margin-bottom: 1rem; }

.barra-busca { display: flex; gap: .5rem; margin-bottom: 1.25rem; flex-wrap: wrap; }
.barra-busca .entrada { flex: 1; min-width: 200px; }

/* --------------------------------------------------------------- LOGIN */
.cartao-login {
  background: var(--cor-superficie);
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
  padding: 2rem;
  box-shadow: var(--sombra);
  width: 100%;
  margin-top: 3rem;
}
.titulo-login { font-size: 1.35rem; margin-bottom: .25rem; }
.subtitulo-login { color: var(--cor-texto-suave); margin-bottom: 1.5rem; }
.rodape-login {
  margin-top: 1.5rem;
  padding-top: 1rem;
  border-top: 1px solid var(--cor-borda);
  color: var(--cor-texto-suave);
  font-size: .85rem;
  text-align: center;
}

/* ----------------------------------------------------------- PAINÉIS */
.painel {
  background: var(--cor-superficie);
  border: 1px solid var(--cor-borda);
  /* Raio maior nos blocos grandes e menor nos pequenos (botões, selos). Raio
     único em tudo é o que faz uma interface parecer "de template": um cartão de
     300px com o mesmo canto de um botão de 30px parece proporcionalmente mais
     quadrado que ele. */
  border-radius: var(--raio-grande);
  padding: 1.25rem;
  margin-bottom: 1.5rem;
  box-shadow: var(--sombra);
}
.painel--alerta { border-left: 4px solid var(--cor-atencao); }
.painel--perigo { border-left: 4px solid var(--cor-perigo); }
.painel-descricao { color: var(--cor-texto-suave); font-size: .9rem; margin-bottom: 1rem; }
.cabecalho-painel {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
}

/* ------------------------------------------------------- INDICADORES */
.indicadores {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 1rem;
  margin-bottom: 1.5rem;
}
.indicador {
  background: var(--cor-superficie);
  border: 1px solid var(--cor-borda);
  border-left: 4px solid var(--cor-primaria);
  border-radius: var(--raio-grande);
  padding: 1rem;
  display: flex;
  flex-direction: column;
  gap: .15rem;
  color: var(--cor-texto);
  box-shadow: var(--sombra);
}
.indicador:hover { text-decoration: none; border-color: var(--cor-primaria); }
.indicador--atencao { border-left-color: var(--cor-atencao); }
.indicador--ok { border-left-color: var(--cor-ok); }
.indicador--neutro { border-left-color: var(--cor-texto-suave); }
.indicador-valor { font-size: 2rem; font-weight: 700; line-height: 1.1; }
.indicador-rotulo { font-size: .9rem; font-weight: 600; }
.indicador-extra { font-size: .8rem; color: var(--cor-texto-suave); }

/* ----------------------------------------------------------- TABELAS */
/* O contêiner rolável evita que uma tabela larga estique a página inteira e
   crie rolagem horizontal no corpo — o problema clássico de tabela no
   celular. A rolagem fica dentro da tabela, onde ela pertence. */
.tabela-rolavel { overflow-x: auto; }
.tabela {
  width: 100%;
  border-collapse: collapse;
  font-size: .93rem;
}
.tabela th, .tabela td {
  padding: .65rem .75rem;
  text-align: left;
  border-bottom: 1px solid var(--cor-borda);
  vertical-align: top;
}
.tabela th {
  font-size: .82rem;
  text-transform: uppercase;
  letter-spacing: .03em;
  color: var(--cor-texto-suave);
  border-bottom: 2px solid var(--cor-borda);
  white-space: nowrap;
}
.tabela tbody tr:hover { background: var(--cor-primaria-clara); }
.col-acoes { white-space: nowrap; }
.col-acoes .botao, .col-acoes form { display: inline-block; margin-right: .25rem; }
.celula-secundaria { color: var(--cor-texto-suave); font-size: .82rem; margin: .15rem 0 0; }
.alerta-inline { color: var(--cor-atencao); font-weight: 600; }

.lista-dados {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 1rem;
  margin: 0;
}
.lista-dados dt { font-size: .82rem; color: var(--cor-texto-suave); text-transform: uppercase; }
.lista-dados dd { margin: .15rem 0 0; font-weight: 500; }
.lista-simples { margin: .5rem 0 0; padding-left: 1.25rem; }
.lista-simples li { margin-bottom: .3rem; }

/* -------------------------------------------------------------- SELOS */
.selo {
  display: inline-block;
  padding: .15rem .5rem;
  border-radius: 999px;
  font-size: .78rem;
  font-weight: 600;
  white-space: nowrap;
}
.selo--ok { background: var(--cor-ok-fundo); color: var(--cor-ok); }
.selo--pendente { background: var(--cor-atencao-fundo); color: var(--cor-atencao); }
.selo--expirado { background: var(--cor-perigo-fundo); color: var(--cor-perigo); }
.selo--inativo { background: var(--cor-fundo); color: var(--cor-texto-suave); }
.selo--categoria { background: var(--cor-primaria-clara); color: var(--cor-primaria-escura); }
.selo--individual { background: var(--cor-primaria-clara); color: var(--cor-primaria-escura); margin-left: .35rem; }

/* ------------------------------------------------- ORGANIZAÇÃO: TAGS */
.etiquetas { display: inline-flex; flex-wrap: wrap; gap: .25rem; margin-top: .3rem; }
.etiqueta {
  display: inline-block;
  padding: .1rem .45rem;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
  font-size: .75rem;
  color: var(--cor-texto-suave);
  white-space: nowrap;
}

/* ------------------------------------------------------------ FILTROS */
/* `flex-wrap` em vez de grid de colunas fixas: no celular os campos empilham
   sozinhos, sem media query e sem largura mínima que force rolagem lateral. */
.filtros {
  display: flex;
  flex-wrap: wrap;
  gap: .75rem;
  align-items: flex-end;
  padding: 1rem;
  margin-bottom: 1.25rem;
  background: var(--cor-fundo);
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
}
.filtros__campo { display: flex; flex-direction: column; gap: .25rem; min-width: 150px; }
.filtros__campo--largo { flex: 1; min-width: 220px; }
.filtros__campo label { font-size: .82rem; color: var(--cor-texto-suave); }
.filtros__acoes { display: flex; gap: .5rem; }

/* -------------------------------------------------- SEÇÕES DE FORMULÁRIO */
.secao-form {
  margin: 1.25rem 0;
  padding: 1rem;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
}
.secao-form legend { padding: 0 .4rem; font-weight: 600; font-size: .9rem; }
.secao-form--destaque { border-color: var(--cor-primaria); background: var(--cor-primaria-clara); }

/* Painel "o cargo já atribui isto sozinho", na tela de funcionário.
   Preenchido por app.js; sem JavaScript ele permanece com o atributo `hidden`
   e a lista completa de documentos continua servindo. */
.painel-cargo {
  margin-bottom: 1rem;
  padding: 0.75rem 1rem;
  border-left: 3px solid var(--cor-primaria);
  background: var(--cor-primaria-clara);
  border-radius: var(--raio);
}

.painel-cargo__titulo {
  margin: 0 0 0.5rem;
  font-weight: 600;
}

/* Lista de caixas de seleção. Colunas automáticas: com 3 cargos ocupa uma
   linha, com 40 documentos vira várias colunas em vez de uma lista quilométrica.
   `auto-fill` com largura mínima resolve os dois casos sem media query. */
.lista-caixas { display: grid; gap: .25rem; max-height: 320px; overflow-y: auto; padding: .25rem; }
.lista-caixas--colunas { grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); }
.rotulo-grupo { display: block; font-weight: 500; margin-bottom: .3rem; }
.vazio--linha { padding: .6rem; font-size: .9rem; }

/*
   ALVO DE TOQUE DA CAIXA DE SELEÇÃO.

   O checkbox padrão do navegador tem cerca de 16px — menos de metade dos 44px
   que o resto do sistema respeita. A correção não é só aumentar o quadradinho:
   é fazer a LINHA INTEIRA ser clicável, com altura mínima. Assim o alvo passa a
   ser o nome do cargo/documento, que é o que a pessoa está de fato mirando.
*/
.lista-caixas .rotulo-checkbox {
  display: flex;
  align-items: center;
  gap: .55rem;
  min-height: 2.75rem;
  padding: .25rem .5rem;
  border-radius: var(--raio);
  cursor: pointer;
}
.lista-caixas .rotulo-checkbox:hover { background: var(--cor-fundo); }
.lista-caixas input[type="checkbox"] { width: 1.15rem; height: 1.15rem; flex-shrink: 0; }

/* A caixa da tabela também: ali o alvo é só o quadradinho, então ele cresce e a
   célula ganha respiro em volta. */
.col-selecao input[type="checkbox"] { width: 1.15rem; height: 1.15rem; }

/* Só aparece no celular, onde as colunas de apoio somem. */
.so-celular { display: none; }

/* --------------------------------------------------- AÇÃO EM LOTE */
.barra-lote {
  margin-top: 1rem;
  padding: 1rem;
  background: var(--cor-fundo);
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
}
.barra-lote__titulo { margin: 0 0 .6rem; font-weight: 600; }
.barra-lote__campos { display: flex; flex-wrap: wrap; gap: .75rem; align-items: flex-end; }
.col-selecao { width: 2.5rem; text-align: center; }

/* Segunda linha da barra de ações em lote: situação e exclusão.
   Separada por uma borda porque são ações de natureza diferente das de
   categoria/tags — uma organiza, a outra tira do ar. */
.barra-lote__acoes-situacao {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin-top: 1rem;
  padding-top: 1rem;
  border-top: 1px solid var(--cor-borda);
}

.barra-lote__acoes-situacao .ajuda {
  flex-basis: 100%;
  margin: 0;
}

/* Formulário dentro de célula de tabela (edição de prazo no lugar). */
.form-embutido { display: flex; align-items: center; gap: .35rem; flex-wrap: wrap; }
.entrada--curta { width: 5.5rem; }

.grupo-botoes { display: flex; flex-wrap: wrap; gap: .5rem; }
.ajuda--atencao {
  padding: .6rem .75rem;
  background: var(--cor-atencao-fundo);
  color: var(--cor-atencao);
  border-radius: var(--raio);
}
.cartao-form--atencao { border-left: 4px solid var(--cor-atencao); }
.destaque-numero { margin: 0; font-size: 2.5rem; font-weight: 700; color: var(--cor-atencao); line-height: 1; }
.destaque-texto { margin: .25rem 0 1rem; font-size: 1.05rem; }
.mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; word-break: break-all; }

.prazo { display: block; font-size: .9rem; }
.prazo--urgente { color: var(--cor-atencao); font-weight: 600; }
.prazo--vencido { color: var(--cor-perigo); font-weight: 600; }
.prazo-data { display: block; font-size: .8rem; color: var(--cor-texto-suave); }

/* ---------------------------------------------------------------- ABAS */
.abas { display: flex; gap: .25rem; flex-wrap: wrap; margin-bottom: 1.25rem; border-bottom: 1px solid var(--cor-borda); }
.aba {
  padding: .55rem .9rem;
  color: var(--cor-texto-suave);
  border-bottom: 3px solid transparent;
  font-size: .93rem;
}
.aba:hover { text-decoration: none; color: var(--cor-primaria); }
.aba--ativa { color: var(--cor-primaria); border-bottom-color: var(--cor-primaria); font-weight: 600; }

/* --------------------------------------------------------- PAGINAÇÃO */
.paginacao { display: flex; gap: 1rem; align-items: center; justify-content: center; margin-top: 1.25rem; flex-wrap: wrap; }
.paginacao-info { color: var(--cor-texto-suave); font-size: .88rem; text-align: center; margin-top: 1rem; }

/* -------------------------------------------------- PORTAL / CARTÕES */
.cartoes { list-style: none; padding: 0; margin: 0; display: grid; gap: 1rem;
           grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.cartao-treinamento {
  border: 1px solid var(--cor-borda);
  border-left: 4px solid var(--cor-primaria);
  border-radius: var(--raio-grande);
  padding: 1.1rem;
  background: var(--cor-superficie);
  box-shadow: var(--sombra);
  /* Coluna flexível para o botão poder ser empurrado ao pé — ver `.cartao-acoes`. */
  display: flex;
  flex-direction: column;
}
.cartao-treinamento--inativo { border-left-color: var(--cor-texto-suave); opacity: .75; }
.cartao-cabecalho { display: flex; justify-content: space-between; gap: .5rem; align-items: flex-start; margin-bottom: .5rem; }
.cartao-descricao { font-size: .9rem; color: var(--cor-texto-suave); }
/* Categoria como sobretítulo discreto: informa sem competir com o título do
   treinamento, que é o que a pessoa veio ler. */
.cartao-categoria {
  margin: -.25rem 0 .35rem;
  font-size: .78rem;
  font-weight: 600;
  letter-spacing: .02em;
  text-transform: uppercase;
  color: var(--cor-primaria);
}
.cartao-prazo { margin-top: .5rem; }

/*
   BARRA DE PROGRESSO.

   O <progress> sem estilo herda a aparência do sistema operacional — no modo
   escuro vira um traço cinza que parece um campo desabilitado. `appearance:
   none` desliga o desenho nativo e nos deixa pintar os dois pedaços: a calha
   (o elemento) e o preenchimento (o pseudo-elemento), que infelizmente tem
   nome diferente em cada motor. Por isso a regra aparece duas vezes.

   O elemento continua sendo <progress> de verdade: leitor de tela anuncia o
   valor sozinho, e é isso que uma <div> pintada nunca dá de graça.
*/
.progresso progress {
  width: 100%;
  height: .7rem;
  appearance: none;
  -webkit-appearance: none;
  border: none;
  border-radius: 999px;
  background: var(--cor-borda);
  overflow: hidden;
}
.progresso progress::-webkit-progress-bar { background: var(--cor-borda); border-radius: 999px; }
.progresso progress::-webkit-progress-value {
  border-radius: 999px;
  background: linear-gradient(90deg, var(--cor-primaria), var(--cor-ok));
}
.progresso progress::-moz-progress-bar {
  border-radius: 999px;
  background: linear-gradient(90deg, var(--cor-primaria), var(--cor-ok));
}

/* --------------------------------------------------------------- ERRO */
.cartao-erro {
  background: var(--cor-superficie);
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
  padding: 2.5rem 2rem;
  text-align: center;
  box-shadow: var(--sombra);
  margin-top: 3rem;
}
.erro-codigo { font-size: 3rem; font-weight: 700; color: var(--cor-texto-suave); margin: 0; line-height: 1; }
.cartao-erro .botao { margin-top: 1.25rem; }

.vazio {
  padding: 1.5rem;
  text-align: center;
  color: var(--cor-texto-suave);
  background: var(--cor-fundo);
  border: 1px dashed var(--cor-borda);
  border-radius: var(--raio);
}

/* --------------------------------------------- CAMPO DE SENHA COM "MOSTRAR" */
/*
   O botão fica DENTRO da moldura do campo, e não ao lado: ao lado ele encurtaria
   a caixa de texto e desalinharia este campo em relação aos outros do formulário.

   `display: none` por padrão — o app.js acrescenta a classe na raiz do documento
   e só então o botão aparece. Sem JavaScript ele não teria efeito nenhum, e um
   botão inerte na tela é pior que a ausência dele.
*/
.botao-mostrar-senha { display: none; }
.js-senha-visivel-disponivel .botao-mostrar-senha { display: block; }

.entrada-com-acao {
  position: relative;
  display: flex;
  align-items: stretch;
}
/* O recuo à direita reserva o espaço do botão, para o texto digitado nunca
   passar por baixo dele. */
.entrada-com-acao .entrada { padding-right: 5.5rem; }

.js-senha-visivel-disponivel .botao-mostrar-senha {
  position: absolute;
  top: 1px;
  right: 1px;
  bottom: 1px;
  padding: 0 .75rem;
  border: none;
  /* Encostado na borda arredondada do campo: o raio de 1px menos que o da
     entrada evita a linha clara que aparece no canto quando os dois são iguais. */
  border-radius: 0 calc(var(--raio) - 1px) calc(var(--raio) - 1px) 0;
  background: transparent;
  color: var(--cor-primaria);
  font: inherit;
  font-size: .88rem;
  font-weight: 600;
  cursor: pointer;
}
.js-senha-visivel-disponivel .botao-mostrar-senha:hover { text-decoration: underline; }
/* O foco precisa ficar visível: o botão é alcançável pelo teclado, e sem
   contorno quem navega por Tab não sabe onde está. */
.js-senha-visivel-disponivel .botao-mostrar-senha:focus-visible {
  outline: 2px solid var(--cor-primaria);
  outline-offset: -2px;
}

/* Esconde visualmente mas mantém para leitores de tela. Usado em rótulos que
   seriam redundantes na tela, mas são obrigatórios para quem usa leitor —
   `display: none` os removeria também da leitura. */
.oculto-visualmente {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/*
   IMPRESSÃO DA TELA DE LEITURA.

   "Imprimir" no navegador inclui "Salvar como PDF" — é um caminho de download do
   documento que não passa por nenhuma das outras defesas, e ele sai com as
   páginas já renderizadas. Aqui as folhas saem do papel e entra uma linha
   explicando por quê, para a pessoa não achar que a impressora falhou.

   Vale a ressalva de sempre: quem quiser burlar imprime a captura de tela. O que
   isto remove é o Ctrl+P que funciona sem nenhum esforço.
*/
@media print {
  .leitor-paginas,
  .leitor-barra,
  .leitor-retaguarda { display: none !important; }

  .leitor::after {
    content: "Este documento é interno e não pode ser impresso ou salvo. "
             "Consulte-o pelo sistema.";
    display: block;
    padding: 1rem;
    border: 1px solid #999;
    font-size: .95rem;
  }
}

/* --------------------------------------------- VISUALIZADOR DE PDF */
/*
   O leitor NÃO tem altura fixa nem rolagem interna vertical, e isso é
   deliberado. Um painel com rolagem própria dentro de uma página que também
   rola ("scroll aninhado") é uma das piores experiências em celular: o dedo
   nunca sabe qual dos dois vai se mover, e chegar ao fim do documento exige
   acertar a área certa da tela. Aqui as páginas entram no fluxo normal e quem
   rola é o documento inteiro — o gesto natural do aparelho.

   A rolagem HORIZONTAL, sim, fica contida: ela só existe quando a pessoa dá
   zoom além da largura da tela, e aí é esperado que role dentro do leitor.
*/
.leitor {
  margin-bottom: 1.5rem;
}

/* A barra acompanha a rolagem para que zoom e contador estejam sempre à mão
   num documento de 40 páginas. */
.leitor-barra {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .5rem;
  flex-wrap: wrap;
  padding: .5rem .75rem;
  background: var(--cor-superficie);
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio) var(--raio) 0 0;
  box-shadow: var(--sombra);
}
.leitor-barra-grupo { display: flex; gap: .4rem; align-items: center; }
.leitor-contador {
  font-size: .9rem;
  font-weight: 600;
  color: var(--cor-texto-suave);
  font-variant-numeric: tabular-nums; /* o número não "dança" ao trocar de página */
}

.leitor-paginas {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .75rem;
  padding: .75rem;
  background: var(--cor-fundo);
  border: 1px solid var(--cor-borda);
  border-top: none;
  border-radius: 0 0 var(--raio) var(--raio);
  overflow-x: auto;   /* só entra em ação com zoom acima de 100% */
  overscroll-behavior-x: contain;
  /* Tira o arrastar-a-imagem e a seleção acidental da folha. Acompanha o
     bloqueio do menu de contexto em visualizador.js — e vale a mesma ressalva:
     é o caminho fácil que está sendo fechado, não uma barreira real. */
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;  /* iOS: o toque longo não abre "Salvar imagem" */
}
.leitor-paginas img,
.leitor-paginas canvas { -webkit-user-drag: none; }

/* Moldura da página: existe desde o início, com a proporção correta, para a
   barra de rolagem já nascer do tamanho final. Sem isso a página "pula"
   enquanto cada folha é medida e ler vira uma luta. */
/*
   A FOLHA É BRANCA NOS DOIS TEMAS — e isto conserta um defeito visível.

   Antes, a moldura usava var(--cor-superficie). No modo escuro essa variável é
   #1a222c (quase preto), e o resultado aparecia como BARRAS PRETAS sobre o
   documento em duas situações:

     * ao dar zoom no navegador, quando todas as páginas voltam ao estado de
       "moldura vazia" antes de serem redesenhadas — as folhas viravam
       retângulos escuros, e as que ficam fora da janela de renderização
       CONTINUAVAM escuras;
     * em qualquer diferença de arredondamento de um ou dois pixels entre a
       moldura e o canvas, que abria uma faixa escura na borda da página.

   Uma folha de papel é branca independente do tema do sistema: o conteúdo do
   PDF é branco, e pintar a moldura de escuro nunca teve como combinar com ele.
   O fundo AO REDOR das páginas (.leitor-paginas) segue o tema — é a mesa, não o
   papel.

   Sem `border`, de propósito: com `box-sizing: border-box`, uma borda de 1px
   encolhe a caixa de conteúdo em 2px e o canvas passa a não caber exatamente na
   moldura, que é a origem da faixa na borda. O contorno da folha fica por conta
   do box-shadow, que não ocupa espaço no layout.
*/
.leitor-pagina {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  background: #ffffff;
  box-shadow: var(--sombra), 0 0 0 1px rgba(0, 0, 0, .18);
  /* O rótulo "3 / 40" da moldura vazia fica sobre branco nos dois temas, então
     precisa de uma cor própria — var(--cor-texto-suave) é clara no escuro e
     desapareceria. */
  color: #5a6472;
  font-size: .85rem;
}
.leitor-pagina canvas { display: block; max-width: none; }
/* Cor fixa, e não var(--cor-perigo): a moldura é branca nos dois temas, e o
   vermelho claro do modo escuro (#f08a8a) sobre branco fica ilegível. */
.leitor-pagina--erro { color: #a12a2a; padding: 1rem; text-align: center; }
.leitor-pagina-rotulo { opacity: .6; }

.leitor-status {
  padding: .75rem .9rem;
  margin: 0;
  background: var(--cor-primaria-clara);
  color: var(--cor-primaria);
  border: 1px solid var(--cor-borda);
  border-top: none;
  font-size: .9rem;
  text-align: center;
}
.leitor-status--erro { background: var(--cor-perigo-fundo); color: var(--cor-perigo); }

.leitor-retaguarda {
  padding: 1rem;
  text-align: center;
  border: 1px solid var(--cor-borda);
  border-top: none;
  border-radius: 0 0 var(--raio) var(--raio);
  background: var(--cor-superficie);
}
.leitor-retaguarda .ajuda { margin-bottom: .75rem; }
.leitor-aviso--pendente { color: var(--cor-atencao); }

/* ==========================================================================
   REVISÃO DA AVALIAÇÃO — questões à esquerda, PDF à direita

   As duas colunas são o ponto da tela: conferir meio milhar de questões contra
   o documento, trocando de aba a cada uma, é o que faz a revisão ser abandonada
   na metade. A coluna do documento acompanha a rolagem (sticky) porque a lista
   de questões é sempre mais alta que a tela.

   `minmax(0, ...)` nas duas faixas, e não `1fr` puro: o conteúdo do leitor tem
   largura mínima própria (o canvas da página), e sem o mínimo zero o grid estoura
   para a direita em vez de encolher a coluna.
   ========================================================================== */
.revisao {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 1.5rem;
  align-items: start;
}
/*
   A COLUNA DO DOCUMENTO ROLA POR DENTRO, e é isso que faz a tela valer.

   Com as duas colunas rolando juntas, chegar na última questão levava o PDF
   junto — e o revisor voltava a caçar a página, que é o trabalho que esta tela
   existe para eliminar. Dando altura de tela à coluna e rolagem própria ao
   documento, as questões correm de um lado e o PDF fica onde foi deixado.

   O `sticky` só passa a ter efeito por causa do `max-height`: enquanto o
   elemento era mais alto que a janela, não havia o que grudar.

   O lazy-render do visualizador continua funcionando: o IntersectionObserver
   considera o recorte dos ancestrais, então a página que sai da área rolável
   conta como fora de vista, exatamente como quando saía da janela.
*/
/*
   A coluna do PDF gruda ABAIXO do cabeçalho, não no topo da janela.

   O `.topo` também é `position: sticky` (em `top: 0`, com `z-index: 20`), então
   grudar esta coluna em `1rem` a fazia deslizar POR BAIXO dele: os primeiros
   ~50px do leitor ficavam cobertos e os botões de zoom, inalcançáveis enquanto
   o revisor rolava as questões — que é justamente quando ele precisa deles.

   `--altura-topo` existe para as duas medidas não divergirem. Se o cabeçalho
   mudar de altura, é um número só a acertar.
*/
.revisao-documento {
  position: sticky;
  top: calc(var(--altura-topo) + 1rem);
}
.revisao-documento .leitor { margin-bottom: 0; }
.revisao-documento .leitor-paginas {
  /* Desconta o cabeçalho, o respiro de 1rem acima, a barra de ferramentas do
     leitor e um respiro igual abaixo — senão a folha passa do fim da janela e o
     revisor rola a página inteira para ver o pé do documento. */
  max-height: calc(100vh - var(--altura-topo) - 6.5rem);
  /*
     `scroll` e não `auto`: o visualizador mede `clientWidth` UMA vez, antes de
     inserir as molduras — ou seja, antes de a barra vertical existir. Com `auto`
     ele media 15px a mais que o espaço real e cada folha ficava larga demais,
     produzindo uma barra horizontal permanente. Reservando a calha desde o
     início, a medida nasce certa.
  */
  overflow-y: scroll;
}

/*
   Formulário de geração: rótulo, número e botão na mesma linha.

   `flex-wrap` e não uma largura fixa no campo: em telas estreitas o botão desce
   para a linha de baixo em vez de o número virar uma caixa de dois caracteres.
   O `.form-inline` existente serve para formulário de um botão só (é
   `display: inline`) e aqui produziria três elementos disputando a mesma linha.
*/
.form-gerar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: .5rem;
}
.form-gerar input[type="number"] { width: 5rem; }
/* O painel de ações empilha formulários independentes; sem isto eles colam. */
.painel form + form { margin-top: .5rem; }

/* ---------------------------------------------------------------------------
   A PROVA DO FUNCIONÁRIO
   --------------------------------------------------------------------------- */

/*
   O prazo fica no cabeçalho da página, junto do título, porque é a informação
   que a pessoa consulta com mais frequência durante a prova.
*/
.prova-prazo { margin: 0; text-align: right; }
.prova-prazo-rotulo { display: block; font-size: .8rem; color: var(--cor-texto-suave); }
.prova-cronometro { display: block; font-variant-numeric: tabular-nums; }
/* Nos últimos cinco minutos o cronômetro muda de cor. Cor NÃO é o único sinal:
   o texto continua dizendo os minutos restantes, para quem não distingue as
   duas cores. */
.prova-cronometro--atencao { color: var(--cor-atencao); font-weight: 600; }
.prova-cronometro--fim { color: var(--cor-perigo); font-weight: 600; }

/* `fieldset` traz borda e padding próprios do navegador; aqui o cartão da
   questão já é a moldura. */
.questao-grupo { border: 0; margin: 0; padding: 0; }
.questoes--prova .questao-enunciado { padding: 0; }

/*
   Sem o marcador da lista nesta tela: o número já está DENTRO do enunciado
   ("1. Antes de iniciar…"), porque ali ele faz parte do texto que o leitor de
   tela anuncia junto com a pergunta. Mantendo os dois, o número aparecia duas
   vezes — uma fora do cartão, à esquerda, e outra no começo da frase.
*/
.questoes--prova,
.questoes--resultado { list-style: none; padding-left: 0; }

.alternativas { list-style: none; margin: .75rem 0 0; padding: 0; display: grid; gap: .25rem; }

/*
   A área clicável é o RÓTULO INTEIRO, não só o círculo do radio: numa prova de
   dez questões com cinco alternativas, acertar um alvo de 13px cinquenta vezes é
   um convite ao erro — e no celular é pior.
*/
.alternativa-opcao {
  display: flex;
  align-items: baseline;
  gap: .5rem;
  padding: .5rem;
  border-radius: var(--raio);
  cursor: pointer;
}
.alternativa-opcao:hover { background: var(--cor-primaria-clara); }
/* O foco fica no rótulo quando o radio dentro dele é focado: navegando por
   teclado, é preciso VER onde se está. */
.alternativa-opcao:focus-within { outline: 2px solid var(--cor-primaria); outline-offset: 1px; }
.alternativa-letra { font-weight: 600; min-width: 1.2rem; }

.prova-entrega { margin-top: 1.5rem; }

/* Resultado: o selo carrega o veredito, e o texto ao lado repete em palavras —
   nenhuma informação depende só de cor. */
.resultado-linha { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; margin: .5rem 0 0; }

/* Bloco da prova dentro do cartão de treinamento no portal. */
.cartao-prova {
  margin: .75rem 0 0;
  padding-top: .75rem;
  border-top: 1px dashed var(--cor-borda);
  display: flex;
  align-items: center;
  gap: .5rem;
  flex-wrap: wrap;
}

.questoes { margin: 0; padding-left: 1.5rem; display: grid; gap: 1rem; }
.questao {
  background: var(--cor-superficie);
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
  padding: 1rem;
}
.questao-enunciado { font-weight: 600; margin: 0 0 .75rem; }

.alternativas { list-style: none; margin: 0; padding: 0; display: grid; gap: .3rem; }
.alternativa { display: flex; gap: .5rem; align-items: baseline; }
.alternativa-letra {
  font-weight: 700;
  min-width: 1.3rem;
  color: var(--cor-texto-suave);
}
/* A alternativa correta é marcada por COR E PESO, nunca só por cor: quem não
   distingue verde de cinza precisa de outro sinal, e o gabarito por extenso
   logo abaixo é o terceiro. */
.alternativa--correta { color: var(--cor-ok); font-weight: 600; }
.alternativa--correta .alternativa-letra { color: var(--cor-ok); }

/* ESPELHO DE UMA TENTATIVA (tela do administrador).

   A alternativa que a pessoa marcou usa FUNDO, e não cor de texto, porque ela
   pode coincidir com a correta — que já usa cor e peso. Dois sinais na mesma
   propriedade se sobrescreveriam, e a linha mais importante do espelho (marcou E
   acertou) ficaria indistinguível de "só acertou". */
.alternativa--escolhida {
  background: var(--cor-primaria-clara);
  border-radius: var(--raio);
  padding: .15rem .35rem;
  margin: -.15rem -.35rem;
}
/* As palavras "marcou" e "gabarito" ao lado da alternativa. São a razão pela qual
   o espelho continua legível sem enxergar cor nenhuma. */
.alternativa-marca {
  font-size: .72rem;
  text-transform: uppercase;
  letter-spacing: .03em;
  font-weight: 700;
  color: var(--cor-texto-suave);
  white-space: nowrap;
}

.questao-gabarito {
  margin: .75rem 0 0;
  font-size: .88rem;
  font-weight: 600;
  color: var(--cor-ok);
}
/* No espelho a mesma linha diz "acertou", "errou" ou "deixou em branco". Verde
   para todos os três faria a frase e a cor discordarem — e é a frase que alguém
   lê quando contesta a nota. */
.questao-gabarito--erro { color: var(--cor-perigo); }
.questao-gabarito--branco { color: var(--cor-texto-suave); }
.questao-referencia { margin: .25rem 0 0; font-size: .85rem; color: var(--cor-texto-suave); }
.questao-referencia--ausente { color: var(--cor-atencao); }

.painel--declaracao { border-left: 4px solid var(--cor-primaria); }
.voltar { margin: 0 0 .5rem; font-size: .93rem; }
.documento-meta { color: var(--cor-texto-suave); font-size: .88rem; }
/*
   O BOTÃO FICA COLADO NO PÉ DO CARTÃO.

   Sem isto, o botão flutua logo abaixo do último parágrafo — e como um título
   quebra em duas linhas e o vizinho não, os botões da fileira ficam em alturas
   diferentes. É um desalinho pequeno que faz a tela inteira parecer descuidada,
   e some quando o cartão vira coluna flexível e a ação é empurrada para baixo
   com `margin-top: auto`.

   Os cartões já têm a mesma altura (é o padrão do grid); o que faltava era
   distribuir o espaço sobrando DENTRO deles.
*/
.cartao-acoes { margin-top: auto; padding-top: .9rem; margin-bottom: 0; }

/* -------------------------------------------------- AVISO DE VENCIMENTO */
/*
   UM BLOCO, DOIS PAPÉIS.

   O mesmo <dialog> é janela modal quando o JavaScript roda e faixa no topo da
   página quando não roda. Quem decide é o atributo [open], que só existe
   depois de `showModal()`.

   Isso resolve o conflito entre "o aviso precisa interromper" e a regra do
   projeto de funcionar sem JavaScript: em vez de escolher um dos dois, o
   navegador sem suporte recebe a versão que ele consegue mostrar. O texto é
   o mesmo nos dois casos, porque vem do servidor.
*/
.aviso-vencimento {
  width: min(34rem, calc(100vw - 2rem));
  padding: 1.25rem;
  border: 1px solid var(--cor-atencao);
  border-left: 4px solid var(--cor-atencao);
  border-radius: var(--raio);
  background: var(--cor-superficie);
  color: var(--cor-texto);
  box-shadow: var(--sombra);
}

/* Sem [open]: o navegador esconderia o elemento. Trazemos de volta como faixa
   no fluxo normal da página, logo acima do título. */
.aviso-vencimento:not([open]) {
  display: block;
  position: static;
  width: auto;
  margin: 0 0 1.25rem;
}
/* O botão "Entendi" só fecha um diálogo ABERTO. Fora do modo modal ele seria
   um botão inerte — melhor não existir. */
.aviso-vencimento:not([open]) .aviso-vencimento-acoes { display: none; }

/* O escurecido atrás do modal. Pertence ao navegador, não a uma <div> nossa. */
.aviso-vencimento::backdrop { background: rgba(16, 24, 40, .55); }

.aviso-vencimento h2 {
  margin-top: 0;
  color: var(--cor-atencao);
  font-size: 1.1rem;
}
.aviso-vencimento-lista {
  display: grid;
  gap: .6rem;
  margin: .9rem 0;
  padding-left: 1.1rem;
}
.aviso-vencimento-lista a { font-weight: 600; }
.aviso-vencimento-acoes { margin: 0; text-align: right; }

/* ------------------------------------------------------------- CELULAR */
/*
   O sistema é usado no telefone tanto quanto no computador, então o celular não
   é um caso degradado — é o caso principal do portal do funcionário. As regras
   abaixo tratam quatro coisas que quebram nessa tela e em nenhuma outra:
   espaço vertical, alvo de toque, recorte do aparelho e tabela larga.
*/
@media (max-width: 720px) {
  /*
     REVISÃO EM UMA COLUNA.
     Lado a lado em 380px não caberia nem a questão nem a página do PDF. O
     documento vai para baixo das questões, e o `sticky` é desligado: numa coluna
     só ele grudaria no topo cobrindo a leitura.
  */
  .revisao { grid-template-columns: 1fr; gap: 1rem; }
  .revisao-documento { position: static; }
  /* Rolagem dentro de rolagem numa tela pequena é armadilha de toque: o dedo
     não sabe qual das duas vai se mover. Numa coluna só, a página rola inteira. */
  .revisao-documento .leitor-paginas { max-height: none; overflow-y: visible; }

  /*
     CABEÇALHO EM GRADE.
     Empilhar os três blocos em coluna (o que o flex fazia) consumia três
     linhas de altura antes de o conteúdo começar. Em grade, marca e usuário
     dividem a primeira linha e o menu ocupa a segunda inteira — uma linha a
     menos, de graça, em toda tela do sistema.
  */
  .topo-conteudo {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "marca usuario"
      "menu  menu";
    align-items: center;
    gap: .5rem .75rem;
    padding: .6rem .9rem;
  }
  .marca   { grid-area: marca; font-size: 1rem; }
  .usuario { grid-area: usuario; gap: .5rem; }
  .menu    { grid-area: menu; }
  /* No celular o nome completo rouba a largura do menu; o perfil já identifica
     quem está logado, e o nome continua acessível na própria tela do portal. */
  .usuario-nome { font-size: .82rem; max-width: 40vw; }

  /*
     MENU EM FAIXA ROLÁVEL.
     Seis itens não cabem em 360px. As alternativas seriam um menu sanfonado
     (que exigiria JavaScript, contra a regra do projeto de funcionar sem ele)
     ou reduzir a fonte até ficar ilegível. A faixa horizontal mantém todos os
     itens alcançáveis com um gesto que o usuário de celular já conhece.
     `scroll-snap` faz cada item parar alinhado em vez de meio cortado.
  */
  .menu {
    flex-wrap: nowrap;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    scrollbar-width: none;          /* Firefox */
    -ms-overflow-style: none;
    margin: 0 -.9rem;               /* sangra até a borda da tela... */
    padding: 0 .9rem;               /* ...sem colar o primeiro item nela */
  }
  .menu::-webkit-scrollbar { display: none; }  /* Safari/Chrome */
  .menu a {
    scroll-snap-align: start;
    white-space: nowrap;
    padding: .55rem .8rem;
    min-height: 2.75rem;            /* 44px: alvo de toque confortável */
    display: flex;
    align-items: center;
  }

  /*
     ALVO DE TOQUE.
     No desktop um botão de 32px é clicável com precisão de mouse. No celular,
     o polegar tem cerca de 9mm de área de contato — abaixo de 44px o erro de
     toque cresce muito, e errar um botão de "excluir" é caro.
  */
  .botao { min-height: 2.75rem; padding: .6rem 1rem; }
  .botao--pequeno { min-height: 2.5rem; padding: .5rem .8rem; font-size: .9rem; }
  .acoes { gap: .6rem; }
  .col-acoes .botao { margin-bottom: .25rem; }

  /* Respeita o recorte da tela (notch/ilha dinâmica) e as bordas curvas.
     `max()` mantém o respiro normal em aparelhos sem recorte. */
  .topo-conteudo,
  .conteudo,
  .rodape {
    padding-left: max(.9rem, env(safe-area-inset-left));
    padding-right: max(.9rem, env(safe-area-inset-right));
  }
  .conteudo { padding-top: 1rem; padding-bottom: 2rem; }
  .rodape { padding-bottom: max(1rem, env(safe-area-inset-bottom)); }

  .cabecalho-pagina { flex-direction: column; gap: .5rem; }
  h1 { font-size: 1.3rem; }
  h2 { font-size: 1.08rem; }
  .indicador-valor { font-size: 1.7rem; }
  .painel { padding: 1rem; }
  .cartao-form, .cartao-login { padding: 1.15rem; }
  .cartao-login { margin-top: 1.5rem; }

  /* Cartões do portal em coluna única: dois cartões lado a lado num celular
     deixam o título quebrado em quatro linhas. */
  .cartoes { grid-template-columns: 1fr; }
  .indicadores { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: .75rem; }

  /*
     TABELA: a primeira coluna fica fixa ao rolar para o lado.
     Sem isso, ao arrastar a tabela para ver a última coluna a pessoa perde de
     vista DE QUEM é aquela linha, e precisa voltar para conferir. Fixando a
     coluna de identificação, o contexto nunca some.
  */
  .tabela th:first-child,
  .tabela td:first-child {
    position: sticky;
    left: 0;
    background: var(--cor-superficie);
    border-right: 1px solid var(--cor-borda);
  }
  .tabela th, .tabela td { padding: .55rem .6rem; }

  /*
     SELEÇÃO EM LOTE É TAREFA DE COMPUTADOR — e some no celular.

     Marcar 40 documentos para trocar a categoria de todos é trabalho de carga
     inicial, feito sentado. No telefone essa coluna custava caro duas vezes:
     roubava largura de uma tabela que já tem oito colunas, e — pior — passava a
     ser a PRIMEIRA, então a regra acima fixava um checkbox no lugar do nome do
     documento. A pessoa rolava para o lado e via uma coluna de caixinhas sem
     saber a que linha pertenciam.

     Escondendo a coluna, o nome do documento volta a ser o que fica fixo.
     Como `display:none` tira o elemento do fluxo mas NÃO muda o `:first-child`,
     a regra acima deixa de ter efeito visível e precisamos fixar a segunda.
  */
  .tabela--selecionavel th:nth-child(2),
  .tabela--selecionavel td:nth-child(2) {
    position: sticky;
    left: 0;
    background: var(--cor-superficie);
    border-right: 1px solid var(--cor-borda);
  }
  .col-selecao,
  .barra-lote { display: none; }

  /*
     COLUNAS DE APOIO SOMEM; A INFORMAÇÃO NÃO.

     Nome do arquivo, tamanho, hash e as duas contagens são úteis no computador
     e viram rolagem lateral no telefone. Em vez de simplesmente cortá-las, as
     contagens reaparecem como linha secundária dentro da célula do documento
     (`.so-celular`), que é onde a pessoa já está olhando. Esconder é aceitável;
     perder, não.
  */
  .col-apoio { display: none; }
  .so-celular { display: block; }

  /* Filtros em duas colunas: a busca ocupa a linha inteira, os três seletores
     dividem o resto. Empilhados, os quatro campos empurravam a lista para fora
     da primeira tela. */
  .filtros { display: grid; grid-template-columns: 1fr 1fr; gap: .6rem; padding: .8rem; }
  .filtros__campo { min-width: 0; }
  .filtros__campo--largo { grid-column: 1 / -1; }
  .filtros__acoes { grid-column: 1 / -1; }
  .filtros__acoes .botao { flex: 1; }

  /*
     LISTA DE CAIXAS SEM ROLAGEM PRÓPRIA.

     No computador, limitar a altura evita uma lista de 40 documentos empurrar o
     botão de salvar para fora da tela. No celular a mesma limitação cria uma
     área que rola dentro de uma página que também rola — o dedo entra na caixa,
     a página trava, e a pessoa acha que a tela travou. Deixamos a lista crescer
     e a página rolar inteira, que é o gesto esperado.
  */
  .lista-caixas { max-height: none; overflow-y: visible; grid-template-columns: 1fr; }

  /* Edição de prazo dentro da célula: o campo e o botão empilham em vez de
     espremer, e ambos ganham altura de toque. */
  .form-embutido { gap: .4rem; }
  .form-embutido .entrada--curta { min-height: 2.75rem; width: 4.5rem; }
  .form-embutido .botao { min-height: 2.75rem; }

  /* A barra de ação em lote some, mas a de confirmação de vínculos não pode:
     ela é justamente a tela que evita um erro caro. */
  .destaque-numero { font-size: 2.1rem; }
  .grupo-botoes .botao { flex: 1 1 auto; justify-content: center; }

  /* Barra do leitor mais compacta, e o contador vai para a direita. */
  .leitor-paginas { padding: .5rem; gap: .5rem; }
  .leitor-barra { padding: .45rem .6rem; }
}

/*
   AFFORDANCE DE ROLAGEM NA TABELA (todas as larguras).

   Uma tabela que rola para o lado sem nenhum sinal visual simplesmente parece
   uma tabela com colunas faltando — a pessoa não descobre que há mais conteúdo.
   Este truque puramente em CSS resolve: as duas sombras internas aparecem
   apenas quando existe conteúdo escondido daquele lado, porque as camadas
   brancas (`local`) rolam junto com o conteúdo e cobrem as sombras (`scroll`)
   quando se chega ao fim. Nenhum JavaScript, nenhuma alteração de template.
*/
.tabela-rolavel {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  background:
    linear-gradient(to right, var(--cor-superficie) 30%, transparent) left center / 2.5rem 100% no-repeat local,
    linear-gradient(to left,  var(--cor-superficie) 30%, transparent) right center / 2.5rem 100% no-repeat local,
    radial-gradient(farthest-side at 0    50%, rgba(16,24,40,.16), transparent) left center / .9rem 100% no-repeat scroll,
    radial-gradient(farthest-side at 100% 50%, rgba(16,24,40,.16), transparent) right center / .9rem 100% no-repeat scroll;
}

/* =====================================================================
   MOVIMENTO

   TRÊS REGRAS QUE VALEM PARA TUDO AQUI
   ------------------------------------
   1. TODA ANIMAÇÃO TEM UMA FUNÇÃO. Ou confirma que a interface recebeu o
      toque, ou explica de onde um elemento veio, ou chama atenção para algo
      que mudou sozinho. Movimento decorativo é a diferença entre um sistema
      que parece bem feito e um que parece brinquedo — e este é usado todo dia
      por quem tem outra coisa para fazer.

   2. SÓ `transform` E `opacity`. São as duas únicas propriedades que o
      navegador anima na placa de vídeo, sem recalcular layout. Animar
      `width`, `top` ou `margin` obriga o navegador a refazer as contas a cada
      quadro — no celular de entrada da fábrica isso vira animação travada,
      que é pior que nenhuma.

   3. NADA É ESSENCIAL. Quem desligou animações no sistema operacional recebe
      a interface inteira, imediatamente, sem transição. A regra
      `prefers-reduced-motion` no fim deste arquivo garante isso, e é por isso
      que nenhuma informação chega SÓ por movimento.
   ===================================================================== */

/*
   TRANSIÇÃO ENTRE PÁGINAS, SEM UMA LINHA DE JAVASCRIPT.

   Este sistema é multipágina: cada clique recarrega o documento, e o
   navegador pisca em branco entre um e outro. `@view-transition` faz o
   navegador cruzar as duas páginas com um fundido — o mesmo efeito pelo qual
   aplicativos de página única carregam megabytes de framework.

   `navigation: auto` só vale para navegação do próprio usuário e de mesma
   origem: clique em link e botão voltar. Formulário com POST não entra, o que
   é bom — ali a mudança de estado deve ser percebida.

   Onde o navegador não suporta (Firefox ainda atrás de flag), simplesmente
   não acontece nada. Melhoria progressiva de verdade: zero risco, zero
   retaguarda para escrever.
*/
@view-transition { navigation: auto; }

::view-transition-old(root) { animation: sair-fundido 90ms ease-in both; }
::view-transition-new(root) { animation: entrar-fundido 180ms var(--curva) both; }

@keyframes entrar-fundido { from { opacity: 0; } }
@keyframes sair-fundido   { to   { opacity: 0; } }

/*
   ENTRADA DO CONTEÚDO.

   Um deslocamento de 8px, não de 40px. O objetivo é dar a sensação de que a
   página assentou, não fazer o texto voar pela tela — deslocamento grande
   obriga o olho a perseguir a linha até ela parar, e atrasa a leitura.
*/
@keyframes surgir {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}

.conteudo > * {
  animation: surgir var(--tempo-entrada) var(--curva) both;
}

/*
   ENTRADA EM CASCATA DOS CARTÕES.

   Cada cartão entra 40ms depois do anterior. O atraso faz o olho ler a lista
   como uma sequência — primeiro item, segundo, terceiro — em vez de um bloco
   que aparece de uma vez. Paramos no sexto: a partir daí o último cartão
   demoraria mais de um quarto de segundo para aparecer, e a cascata deixa de
   ser elegante para virar espera.
*/
.cartoes > *,
.indicadores > * {
  animation: surgir var(--tempo-entrada) var(--curva) both;
}
.cartoes > *:nth-child(1), .indicadores > *:nth-child(1) { animation-delay: 0ms; }
.cartoes > *:nth-child(2), .indicadores > *:nth-child(2) { animation-delay: 40ms; }
.cartoes > *:nth-child(3), .indicadores > *:nth-child(3) { animation-delay: 80ms; }
.cartoes > *:nth-child(4), .indicadores > *:nth-child(4) { animation-delay: 120ms; }
.cartoes > *:nth-child(5), .indicadores > *:nth-child(5) { animation-delay: 160ms; }
.cartoes > *:nth-child(n + 6), .indicadores > *:nth-child(n + 6) { animation-delay: 200ms; }

/*
   AVISOS (flash) ENTRAM DESLIZANDO DE CIMA.

   Aqui o movimento carrega significado: a mensagem apareceu AGORA, em
   resposta ao que a pessoa acabou de fazer. Sem o deslize, ela se confunde
   com o conteúdo que já estava na tela, e some da atenção justamente quando
   diz "documento excluído".
*/
@keyframes descer {
  from { opacity: 0; transform: translateY(-10px); }
  to   { opacity: 1; transform: none; }
}
.aviso { animation: descer 300ms var(--curva) both; }
.avisos > .aviso:nth-child(2) { animation-delay: 60ms; }
.avisos > .aviso:nth-child(3) { animation-delay: 120ms; }
.avisos > .aviso:nth-child(n + 4) { animation-delay: 180ms; }

/* =====================================================================
   RESPOSTA AO TOQUE

   O intervalo entre tocar e ver algo acontecer é o que faz uma interface
   parecer rápida ou morta — mais até que o tempo real de carregamento.
   ===================================================================== */

.botao {
  transition:
    background-color var(--tempo-resposta) var(--curva),
    border-color var(--tempo-resposta) var(--curva),
    box-shadow var(--tempo-resposta) var(--curva),
    transform var(--tempo-resposta) var(--curva);
}
.botao:hover { transform: translateY(-1px); box-shadow: var(--sombra-media); }
/* O botão AFUNDA ao ser pressionado. É a metáfora física do objeto sendo
   empurrado, e resolve um problema concreto do celular: o dedo cobre o botão,
   então a confirmação precisa aparecer na borda que ainda se vê. */
.botao:active { transform: translateY(1px) scale(.985); box-shadow: none; }
.botao--principal:hover { box-shadow: 0 4px 12px rgba(28, 79, 139, .28); }

/*
   ANEL DE FOCO.

   `:focus-visible`, e não `:focus`: o anel aparece para quem navega por
   teclado e não para quem clicou com o mouse — que é o comportamento que as
   pessoas esperam, e o motivo pelo qual tanta gente removia o contorno padrão
   e quebrava a navegação por teclado de todo mundo.
*/
:focus-visible {
  outline: 2px solid var(--cor-primaria);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Cartões e painéis sobem de leve sob o cursor. O deslocamento é mínimo (2px)
   porque a informação vem da SOMBRA crescendo; o movimento só reforça. */
.cartao-treinamento,
.painel,
.indicador {
  transition:
    box-shadow var(--tempo-resposta) var(--curva),
    transform var(--tempo-resposta) var(--curva),
    border-color var(--tempo-resposta) var(--curva);
}
.indicador:hover { transform: translateY(-2px); box-shadow: var(--sombra-media); }
.cartao-treinamento:hover {
  transform: translateY(-2px);
  box-shadow: var(--sombra-media);
  border-color: var(--cor-primaria);
}
/* Expirado não sobe: ele não é acionável, e um cartão que reage ao cursor
   promete um clique que não existe. */
.cartao-treinamento--inativo:hover { transform: none; box-shadow: var(--sombra); border-color: var(--cor-borda); }

.tabela tbody tr { transition: background-color var(--tempo-resposta) var(--curva); }

/* Etiquetas e caixas de seleção também respondem, para a lista não parecer
   uma imagem estática. */
.etiqueta { transition: border-color var(--tempo-resposta) var(--curva), color var(--tempo-resposta) var(--curva); }
.lista-caixas .rotulo-checkbox { transition: background-color var(--tempo-resposta) var(--curva); }
.entrada {
  transition: border-color var(--tempo-resposta) var(--curva),
              box-shadow var(--tempo-resposta) var(--curva);
}
.entrada:focus {
  box-shadow: 0 0 0 3px var(--cor-primaria-clara);
}

/*
   BARRA DE PROGRESSO QUE PREENCHE.

   O portal mostra "3 de 7 treinamentos". Animar o preenchimento faz a pessoa
   ver o quanto já andou, em vez de encontrar uma barra parada. `transform`
   com origem à esquerda em vez de `width`, pela regra 2 lá em cima.
*/
@keyframes preencher {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}
.progresso progress::-webkit-progress-value {
  transform-origin: left center;
  animation: preencher 700ms var(--curva) both;
}
.progresso progress::-moz-progress-bar {
  transform-origin: left center;
  animation: preencher 700ms var(--curva) both;
}

/*
   DIÁLOGO DE AVISO DE VENCIMENTO.

   Entra com escala, e não deslizando: escala comunica "isto surgiu por cima
   de tudo", que é exatamente o papel de um modal. O fundo escurece junto —
   sem isso o diálogo parece colado na página em vez de flutuando sobre ela.
*/
@keyframes surgir-modal {
  from { opacity: 0; transform: translateY(12px) scale(.96); }
  to   { opacity: 1; transform: none; }
}
.aviso-vencimento[open] {
  animation: surgir-modal 240ms var(--curva) both;
  box-shadow: var(--sombra-alta);
}
.aviso-vencimento[open]::backdrop {
  animation: entrar-fundido 240ms var(--curva) both;
  background: rgba(16, 24, 40, .45);
  backdrop-filter: blur(2px);
}

/*
   PRAZO VENCENDO: PULSO LENTO E DISCRETO.

   Quatro segundos por ciclo e variação mínima de opacidade. Um pulso rápido
   viraria alarme e a pessoa aprenderia a ignorá-lo — que é o oposto do
   objetivo. E, como manda a regra 3, a informação NÃO está no movimento: o
   texto já diz "vence em 3 dias" e a cor já mudou.
*/
@keyframes pulsar {
  0%, 100% { opacity: 1; }
  50%      { opacity: .72; }
}
.prazo--urgente { animation: pulsar 4s ease-in-out infinite; }

/* Respeita quem configurou o sistema para reduzir animações (enjoo por
   movimento, distúrbios vestibulares).

   `animation: none` cancela também as animações de ENTRADA — e como elas usam
   `both`, o elemento ficaria preso no estado inicial (invisível, deslocado) se
   não devolvêssemos opacidade e posição explicitamente. Um sistema que some
   para quem tem distúrbio vestibular seria uma falha bem pior que a original. */
@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
  .conteudo > *,
  .cartoes > *,
  .indicadores > *,
  .aviso,
  .aviso-vencimento[open] { opacity: 1 !important; transform: none !important; }
  ::view-transition-old(root),
  ::view-transition-new(root) { animation: none !important; }
}
