/* ==========================================================
   COPAZA WEB - Design system
   Ajuste o bloco :root para a identidade visual oficial.
   ========================================================== */

:root {
  /* Marca */
  /*
   * Vermelho da Copaza.
   *
   * Fechado e sem alaranjar: o matiz fica em 357°, quase no
   * vermelho puro. Passar disso, na direção do laranja, é o que
   * faz a cor deixar de ler como vermelho.
   *
   * A --cor-primaria é a de trabalho — fundo de botão, item ativo,
   * dia de hoje — e por isso precisa aguentar texto branco por
   * cima: com o #b8232a isso dá 6,3:1, folgado. A --clara é meio
   * tom acima, para hover e detalhe.
   *
   * Verde continua existindo em --cor-sucesso: "salvo com sucesso"
   * é convenção, não identidade visual.
   */
  --cor-primaria: #b8232a;
  --cor-primaria-clara: #d93a41;
  --cor-primaria-escura: #8e181e;
  --cor-primaria-fraca: #fdeaeb;
  /* Anel de foco: era um rgba verde repetido em 4 arquivos */
  --cor-primaria-anel: rgba(184, 35, 42, .20);

  /*
   * A barra lateral tem cor PRÓPRIA, fora da rampa da marca.
   *
   * Ela ocupa 260px de tela o dia inteiro; em vermelho, saturado
   * ou escuro, vira o elemento mais pesado da interface e ainda
   * apaga o item ativo, que é vermelho também. Em grafite o
   * vermelho fica reservado para o que precisa ser visto — item
   * atual, botões, destaques — e aparece mais justamente por
   * aparecer menos.
   */
  --cor-sidebar: #1a1d21;
  --cor-destaque: #f0a500;

  /* Neutros */
  --cor-fundo: #f6f7f9;
  --cor-superficie: #ffffff;
  --cor-superficie-2: #fafbfc;
  --cor-borda: #e4e8ec;
  --cor-borda-forte: #cfd6dd;
  --cor-texto: #1c2530;
  --cor-texto-medio: #4b5866;
  --cor-texto-suave: #7c8896;

  /* Estado */
  --cor-sucesso: #14804a;
  --cor-sucesso-fraca: #e6f4ec;
  --cor-erro: #c02c38;
  --cor-erro-fraca: #fdecee;
  --cor-alerta: #b26a00;
  --cor-alerta-fraca: #fdf3e2;
  --cor-info: #14539a;
  --cor-info-fraca: #e8f0fa;
  --cor-neutra: #56626e;
  --cor-neutra-fraca: #eef1f4;

  /* Bordas de estado. Existem para que alertas e avisos usem variavel
     no lugar de hex fixo — era o hex que quebrava no tema escuro. */
  --cor-sucesso-borda: #bfe0cd;
  --cor-erro-borda: #f3c6ca;
  --cor-alerta-borda: #f0d9ab;
  --cor-info-borda: #c3d7ef;

  /* Layout */
  --sidebar-largura: 248px;
  --sidebar-recolhida: 62px;
  /* Largura em vigor. Topbar e conteúdo seguem esta, não a fixa —
     assim recolher o menu é trocar UMA variável, e nada fica para trás. */
  --sidebar-atual: var(--sidebar-largura);
  --topbar-altura: 60px;
  --raio: 10px;
  --raio-sm: 7px;
  --raio-lg: 14px;
  --sombra-xs: 0 1px 2px rgba(16, 24, 40, .05);
  --sombra: 0 1px 3px rgba(16, 24, 40, .08), 0 1px 2px rgba(16, 24, 40, .04);
  --sombra-md: 0 6px 20px rgba(16, 24, 40, .10);
  --sombra-lg: 0 18px 48px rgba(16, 24, 40, .18);
  --transicao: .16s ease;

  /* ------------------------- Altura dos controles -------------------------
     Um campo media 38px e o botao ao lado media 36. Dois pixels, em toda tela
     do portal que poe um botao junto de um campo — a busca com o botao de
     filtrar, o "novo item do checklist", o seletor de assunto ao lado de
     "Comentar". Ninguem decidiu isso: sao dois paddings escritos em momentos
     diferentes (9px no botao, 10px no campo) que nunca foram conferidos um
     contra o outro.

     A altura passa a vir daqui, e como `min-height` e nao como padding.
     Padding vertical faz a altura DEPENDER da fonte renderizada: com
     `line-height: normal`, a mesma regra da 38px no Windows e 37 ou 39 em
     outro sistema, e desalinha de novo no zoom. Altura declarada nao varia.

     Quem precisar de outro tamanho declara o proprio `min-height` — e ai e
     decisao, nao acidente. */
  --altura-controle: 38px;
  --altura-controle-sm: 32px;

  --fonte: 'Segoe UI', system-ui, -apple-system, Roboto, Arial, sans-serif;
  --fonte-mono: 'Cascadia Mono', Consolas, 'Courier New', monospace;
}

/* ==========================================================
   TEMA ESCURO
   Aplicado por [data-tema="escuro"] no <html> (public/js/tema.js).
   Só as variáveis mudam — nenhum componente precisa saber do tema.
   ========================================================== */
html[data-tema='escuro'] {
  /* No escuro a primária clareia: aqui ela também é cor de TEXTO
     sobre fundo escuro, e o tom fechado do tema claro sumiria */
  --cor-primaria: #e04b52;
  --cor-primaria-clara: #ec6f75;
  --cor-primaria-escura: #b8232a;
  --cor-primaria-fraca: #3a1618;
  --cor-primaria-anel: rgba(224, 75, 82, .30);

  /* No tema escuro a barra encosta no fundo da página, só um
     degrau abaixo — a divisa fica por conta da borda */
  --cor-sidebar: #12161c;

  --cor-fundo: #10151b;
  --cor-superficie: #171d26;
  --cor-superficie-2: #1d242f;
  --cor-borda: #262f3b;
  --cor-borda-forte: #35404f;
  --cor-texto: #e7ecf2;
  --cor-texto-medio: #b3becc;
  --cor-texto-suave: #8593a3;

  --cor-sucesso: #4ec08a;
  --cor-sucesso-fraca: #16332a;
  --cor-erro: #f2757f;
  --cor-erro-fraca: #3a1e23;
  --cor-alerta: #e0a94a;
  --cor-alerta-fraca: #3a2e17;
  --cor-info: #63a6f0;
  --cor-info-fraca: #16283d;
  --cor-neutra: #9aa7b5;
  --cor-neutra-fraca: #232b36;

  --cor-sucesso-borda: #245c44;
  --cor-erro-borda: #6a2f37;
  --cor-alerta-borda: #6b5326;
  --cor-info-borda: #2a4b74;

  --sombra-xs: 0 1px 2px rgba(0, 0, 0, .30);
  --sombra: 0 1px 3px rgba(0, 0, 0, .38), 0 1px 2px rgba(0, 0, 0, .24);
  --sombra-md: 0 6px 20px rgba(0, 0, 0, .45);
  --sombra-lg: 0 18px 48px rgba(0, 0, 0, .60);

  color-scheme: dark;
}

/* Densidade compacta (preferência do usuário) */
html[data-densidade='compacta'] body { font-size: 13.5px; }
html[data-densidade='compacta'] .tabela td { padding: 7px 12px; }
html[data-densidade='compacta'] .tabela th { padding: 7px 12px; }
html[data-densidade='compacta'] .cartao-corpo { padding: 14px; }
html[data-densidade='compacta'] .conteudo { padding-top: calc(var(--topbar-altura) + 16px); }

/* Evita o "piscar" branco antes do tema ser aplicado */
html { background: var(--cor-fundo); }

/* ---------------------------- Reset ---------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html, body { height: 100%; }

body {
  margin: 0;
  font-family: var(--fonte);
  font-size: 14.5px;
  line-height: 1.5;
  color: var(--cor-texto);
  background: var(--cor-fundo);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, p { margin: 0; }
a { color: var(--cor-primaria); text-decoration: none; }
a:hover { text-decoration: underline; }
img { max-width: 100%; display: block; }
button, input, select, textarea { font-family: inherit; font-size: inherit; }
:focus-visible { outline: 2px solid var(--cor-primaria-clara); outline-offset: 2px; }

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb { background: var(--cor-borda-forte); border-radius: 8px; border: 2px solid transparent; background-clip: content-box; }
::-webkit-scrollbar-thumb:hover { background: var(--cor-texto-suave); background-clip: content-box; }

/* -------------------------- Utilitarios ------------------------- */
.oculto { display: none !important; }
.text-suave { color: var(--cor-texto-suave); }
.text-medio { color: var(--cor-texto-medio); }
.text-centro { text-align: center; }
.text-direita { text-align: right; }
.text-pequeno { font-size: 12.5px; }
.mono { font-family: var(--fonte-mono); }
.negrito { font-weight: 600; }
.truncar { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.quebrar { white-space: pre-wrap; word-break: break-word; }

.linha { display: flex; align-items: center; gap: 10px; }
.linha-entre { display: flex; align-items: center; justify-content: space-between; gap: 12px; }

/*
 * No celular, o "um de cada lado" vira "um embaixo do outro".
 *
 * `.linha-entre` e o cabecalho de quase todo detalhe do portal: titulo
 * a esquerda, situacao a direita. Sem quebra, o titulo era espremido
 * ate caber ao lado das etiquetas e saia uma palavra por linha
 * ("Mudanca / do / escritorio / para o / novo / andar"). Quebrar so
 * acontece quando NAO cabe — em tela larga nada muda.
 */
@media (max-width: 640px) {
  .linha-entre { flex-wrap: wrap; }
}
/* Etiqueta nunca encolhe: com white-space:nowrap, encolher so a fazia
   vazar pela borda do cartao em cima do vizinho. Quem cede e o texto. */
.linha-entre > .badge, .linha > .badge { flex-shrink: 0; }
.linha-fim { display: flex; align-items: center; justify-content: flex-end; gap: 10px; }
.coluna { display: flex; flex-direction: column; gap: 4px; }
.espaco { flex: 1; }
.envolver { flex-wrap: wrap; }

.mt-1 { margin-top: 8px; } .mt-2 { margin-top: 16px; } .mt-3 { margin-top: 24px; }
.mb-1 { margin-bottom: 8px; } .mb-2 { margin-bottom: 16px; } .mb-3 { margin-bottom: 24px; }

/* -------------------------- Formularios ------------------------- */
.campo { margin-bottom: 16px; }
.campo:last-child { margin-bottom: 0; }

/*
 * :where(:not(.btn)) fica de fora da conta de especificidade (a regra
 * continua valendo 0,1,1), mas tira desta regra o <label class="btn">
 * que envolve <input type="file">. Sem isso o botao de anexar herdava
 * display:block, fonte de 12.5px, margem de 6px embaixo e cor de
 * rotulo — ficava mais baixo e desalinhado do botao ao lado.
 */
.campo label:where(:not(.btn)),
.rotulo {
  display: block;
  font-size: 12.5px;
  font-weight: 600;
  margin-bottom: 6px;
  color: var(--cor-texto-medio);
}

.campo .ajuda { font-size: 12px; color: var(--cor-texto-suave); margin-top: 5px; }
.obrigatorio::after { content: ' *'; color: var(--cor-erro); }

/* O estilo vale para QUALQUER campo, não só os que estão dentro de .campo.
   Painéis e formulários montados na hora (participantes, colunas, checklist)
   usam inputs e selects soltos e ficavam com a aparência crua do navegador.

   ATENÇÃO ao :where(): ele zera a especificidade dos seletores de dentro.
   Escrito como :not([type='x']):not([type='y']) a regra valia (0,3,1) e
   ganhava de qualquer classe — era isso que anulava o padding-left da
   busca e jogava a lupa por cima do texto. Com :where() a regra vale
   (0,0,1) e qualquer componente consegue ajustar o que precisar. */
input:not(:where([type='checkbox'], [type='radio'], [type='file'])),
select,
textarea {
  width: 100%;
  /* Sem padding vertical: com 10px em cima e embaixo o campo saía com
     ~41px (o texto do input usa line-height normal), 3px acima do
     botão de 38px ao lado — era o "Limpar filtros" menor em toda tela.
     A altura é a do token; o texto centraliza sozinho. */
  padding: 0 12px;
  /* textarea tem min-height propria logo abaixo e ignora esta */
  min-height: var(--altura-controle);
  font-size: 14.5px;
  color: var(--cor-texto);
  background: var(--cor-superficie);
  border: 1px solid var(--cor-borda-forte);
  border-radius: var(--raio-sm);
  outline: none;
  transition: border-color var(--transicao), box-shadow var(--transicao);
}

/*
 * Data e hora com a altura do resto.
 *
 * O Chrome desenha o campo de data com o ícone do calendário por dentro
 * e ele sai 2px mais alto que o texto ao lado (40 x 38) — na linha de
 * filtros, "De" e "Até" ficavam desalinhados da busca. Altura fixa e
 * padding vertical zero resolvem sem mexer no ícone.
 */
input:where([type='date'], [type='time'], [type='datetime-local'], [type='month']) {
  height: var(--altura-controle);
  padding-top: 0;
  padding-bottom: 0;
}
.tabela input:where([type='date'], [type='time'], [type='datetime-local'], [type='month']) { height: var(--altura-controle-sm); }

textarea { min-height: 110px; resize: vertical; line-height: 1.55; padding: 10px 12px; }
select[multiple], select[size]:not([size='1']) { padding: 6px 8px; }

/* Seta própria: a nativa não acompanha o tema escuro */
select {
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  padding-right: 32px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%237c8896' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 9px center;
  background-size: 16px;
}
select[multiple] { appearance: auto; -webkit-appearance: auto; background-image: none; padding-right: 12px; }
html[data-tema='escuro'] select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238593a3' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
}
/* As opções seguem o tema no Windows */
select option { background: var(--cor-superficie); color: var(--cor-texto); }

input:not(:where([type='checkbox'], [type='radio'])):focus,
select:focus,
textarea:focus {
  border-color: var(--cor-primaria);
  box-shadow: 0 0 0 3px var(--cor-primaria-anel);
}

input:disabled,
select:disabled,
textarea:disabled { background: var(--cor-neutra-fraca); color: var(--cor-texto-suave); cursor: not-allowed; }

input::placeholder, textarea::placeholder { color: var(--cor-texto-suave); opacity: .8; }

/*
 * Campo de arquivo.
 *
 * Precisa existir porque a regra de borda acima EXCLUI [type='file'],
 * mas a regra de :focus não excluía: o campo ficava sem borda e, ao
 * receber foco, ganhava só o anel vermelho — cara de campo com erro
 * numa tela que acabou de abrir. Só não aparecia antes porque o
 * arquivo nunca era o primeiro campo do modal, e é o primeiro que o
 * UI.modal foca sozinho.
 *
 * Em vez de tirar o file do :focus, é melhor dar a ele a mesma
 * aparência dos outros campos: aí o anel de foco passa a fazer
 * sentido, e o botão do seletor deixa de ser o desenho do sistema
 * operacional no meio do formulário — mesmo argumento do checkbox.
 */
input[type='file'] {
  width: 100%;
  min-height: var(--altura-controle);
  padding: 7px 10px;
  font-size: 13.5px;
  color: var(--cor-texto-medio);
  background: var(--cor-superficie);
  border: 1px solid var(--cor-borda-forte);
  border-radius: var(--raio-sm);
  outline: none;
  cursor: pointer;
  transition: border-color var(--transicao), box-shadow var(--transicao);
}

input[type='file']::file-selector-button {
  margin-right: 10px;
  padding: 5px 12px;
  font: inherit;
  font-weight: 600;
  color: var(--cor-texto-medio);
  background: var(--cor-neutra-fraca);
  border: 1px solid var(--cor-borda-forte);
  border-radius: var(--raio-sm);
  cursor: pointer;
  transition: background var(--transicao), color var(--transicao);
}

input[type='file']:hover::file-selector-button {
  background: var(--cor-primaria-fraca);
  color: var(--cor-primaria);
  border-color: var(--cor-primaria);
}

input[type='file']:disabled { background: var(--cor-neutra-fraca); cursor: not-allowed; }
input[type='file']:disabled::file-selector-button { cursor: not-allowed; }

/* ===================== Blindagem de permissão =====================
 *
 * Tudo que depende de permissão nasce ESCONDIDO e só aparece depois
 * que o App confere a sessão (app.js, aplicarPermissoes). O caminho
 * inverso — nascer visível e ser removido depois — deixava botões de
 * ação na tela durante a espera do /auth/me, clicáveis por quem não
 * podia usá-los.
 *
 * !important porque o alvo costuma ser botão com display próprio
 * (flex, inline-flex) declarado depois nesta mesma folha. Liberar é
 * o App REMOVER o atributo: sem ele a regra deixa de casar e o
 * elemento volta ao display que sempre teve.
 *
 * ATENÇÃO: `data-perm` é reservado para isso. Se uma tela precisar
 * guardar uma chave de permissão num elemento (o editor de perfis
 * precisa), use outro nome — ver public/js/permissoes.js.
 * ================================================================= */
[data-perm],
[data-perm-e] { display: none !important; }

/* Larguras usadas em linhas de painel (evita style inline espalhado) */
.campo-estreito { max-width: 190px; flex-shrink: 0; }
/*
 * Caixa curta, para célula de tabela e grade apertada.
 *
 * Dentro de um CAMPO de formulário ela acompanha os vizinhos: 72 px
 * fixos num campo de 330 px ficavam com 22% da coluna, ao lado de
 * campos que ocupam 100% — a caixa parecia deslocada da tela, e era.
 * A regra abaixo não alcança `<td>` nem `.etapa-grade`, onde o espaço
 * é realmente estreito e o número centralizado é o certo.
 */
.campo-numero { width: 72px; text-align: center; }
.campo > .campo-numero { width: 100%; text-align: left; }

/* Campos menores dentro de tabelas e painéis compactos */
/* Dentro da tabela tudo encolhe junto — campo, select e botao pequeno usam
   a mesma altura compacta, pelo mesmo motivo da altura cheia la em cima. */
.tabela input:not([type='checkbox']):not([type='radio']),
.tabela select { min-height: var(--altura-controle-sm); padding: 6px 9px; font-size: 13.5px; }
.tabela select { padding-right: 28px; background-position: right 7px center; background-size: 14px; }

/*
 * O espaço entre as linhas é do GRID, não da margem do campo.
 *
 * Antes era `gap: 0 16px` e cada .campo carregava margin-bottom: 16px,
 * com `.campo:last-child` zerando o último. Num grid de duas colunas
 * isso erra de duas formas, e as duas apareciam na tela de usuários:
 *
 *   - com número ÍMPAR de campos, o último ocupa a linha inteira e
 *     perde a margem, colando no fundo do bloco (Data de nascimento);
 *   - com número PAR, só o da direita perde. A coluna da esquerda fica
 *     com 16px sobrando embaixo e as duas discordam (Matrícula).
 *
 * `:last-child` é ordem no DOM, e o grid posiciona por linha e coluna —
 * os dois nunca concordaram. Com o gap cuidando das linhas, a última
 * fica sem sobra qualquer que seja a contagem de campos.
 */
/*
 * A grade se despede como um campo se despede.
 *
 * Faltava a margem de baixo: como os campos de dentro tem a propria
 * zerada, o que vinha DEPOIS da grade encostava nela — a caixa de
 * "pular fim de semana" nascia colada no campo de cima, e num
 * formulario longo isso lia como se as duas coisas fossem uma so.
 */
.grade-form { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; margin-bottom: 16px; }
.grade-form > .campo { margin-bottom: 0; }
.grade-form .campo.largura-total { grid-column: 1 / -1; }
/* Tres campos curtos numa linha so (coluna, prioridade, prazo). Sem
   ela, o terceiro descia sozinho e deixava meia linha vazia ao lado. */
.grade-form.tres { grid-template-columns: repeat(3, 1fr); }

@media (max-width: 900px) { .grade-form.tres { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px) {
  .grade-form,
  .grade-form.tres { grid-template-columns: 1fr; }
}

.campo-senha { position: relative; }
.campo-senha input { padding-right: 42px; }

.btn-olho {
  position: absolute;
  right: 5px;
  bottom: 4px;
  width: 32px;
  height: 32px;
  border: 0;
  background: transparent;
  cursor: pointer;
  color: var(--cor-texto-suave);
  border-radius: var(--raio-sm);
  display: flex;
  align-items: center;
  justify-content: center;
}
.btn-olho:hover { background: var(--cor-neutra-fraca); color: var(--cor-texto); }

/* O seletor duplo é para vencer '.campo label' logo acima, que
   vale (0,1,1) e impunha display:block em toda caixa de seleção
   dentro de um .campo — matando o alinhamento e o gap. Enquanto o
   rótulo era uma linha só de texto ninguém percebia. */
.check,
.campo .check {
  display: inline-flex;
  align-items: flex-start;
  gap: 8px;
  margin-bottom: 0;
  cursor: pointer;
  user-select: none;
  font-size: 13.5px;
  font-weight: 400;
  color: var(--cor-texto-medio);
}
.check input { margin-top: 2px; }

/* ------------------- Caixa de seleção e rádio ------------------- */

/*
 * Desenhados aqui, e não deixados para o navegador.
 *
 * 'accent-color' só pinta o preenchimento: a caixa, a borda e o
 * estado vazio continuavam sendo o desenho do sistema operacional
 * — que no tema escuro aparecia como um quadrado claro no meio do
 * formulário, e que muda de forma entre Windows, Mac e cada
 * navegador. Com appearance:none o desenho inteiro é nosso, igual
 * ao que já vale para data, hora, cor e select.
 *
 * A regra é por TIPO, sem classe: assim vale para as 29 caixas do
 * portal e para a próxima que alguém escrever, sem depender de
 * lembrar de uma classe.
 */
input[type='checkbox'],
input[type='radio'] {
  appearance: none;
  -webkit-appearance: none;
  width: 17px;
  height: 17px;
  flex: none;
  margin: 0;
  padding: 0;
  border: 1.5px solid var(--cor-borda-forte);
  border-radius: 5px;
  background-color: var(--cor-superficie);
  background-repeat: no-repeat;
  background-position: center;
  cursor: pointer;
  transition: background-color .12s ease, border-color .12s ease, box-shadow .12s ease;
}

input[type='radio'] { border-radius: 50%; }

input[type='checkbox']:hover:not(:disabled),
input[type='radio']:hover:not(:disabled) { border-color: var(--cor-texto-suave); }

input[type='checkbox']:checked,
input[type='checkbox']:indeterminate,
input[type='radio']:checked {
  background-color: var(--cor-primaria);
  border-color: var(--cor-primaria);
}

/* O "v" vai no background em SVG: desenhar com ::before esbarra
   no fato de input ser elemento vazio em alguns navegadores */
input[type='checkbox']:checked {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6L9 17l-5-5'/%3E%3C/svg%3E");
  background-size: 12px;
}

/* Estado misto: usado quando "marcar todos" tem só parte marcada */
input[type='checkbox']:indeterminate {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='3.5' stroke-linecap='round'%3E%3Cpath d='M6 12h12'/%3E%3C/svg%3E");
  background-size: 12px;
}

/* O ponto do rádio é um furo da cor da superfície, não um segundo
   elemento — acompanha o tema sozinho */
input[type='radio']:checked { box-shadow: inset 0 0 0 3.5px var(--cor-superficie); }

input[type='checkbox']:focus-visible,
input[type='radio']:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--cor-primaria-anel);
}
input[type='radio']:checked:focus-visible {
  box-shadow: inset 0 0 0 3.5px var(--cor-superficie), 0 0 0 3px var(--cor-primaria-anel);
}

input[type='checkbox']:disabled,
input[type='radio']:disabled {
  opacity: .5;
  cursor: not-allowed;
  background-color: var(--cor-neutra-fraca);
}
input[type='checkbox']:disabled:checked,
input[type='radio']:disabled:checked { background-color: var(--cor-texto-suave); border-color: var(--cor-texto-suave); }

/* ---------------------------- Botoes ---------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  /* A altura vem do token, e nao do padding vertical: e o que faz o botao
     bater com o campo ao lado. Ver --altura-controle no topo. */
  min-height: var(--altura-controle);
  padding: 0 15px;
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
  border: 1px solid transparent;
  border-radius: var(--raio-sm);
  cursor: pointer;
  transition: background var(--transicao), border-color var(--transicao), opacity var(--transicao);
}
/*
 * O CLIQUE precisa aparecer.
 *
 * Nenhum botao do portal tinha `:active`. No desktop o hover disfarcava: o
 * fundo ja estava trocado quando o dedo apertava. No toque nao existe hover
 * — a pessoa encostava e o botao nao dava sinal nenhum ate a tela mudar, o
 * que em rede lenta vira "nao funcionou" e um segundo toque. Daqui sai
 * metade das acoes duplicadas de qualquer sistema.
 *
 * O afundamento de 1px e o mesmo para todas as variantes; a cor de apertado
 * cada uma define na sua linha.
 */
.btn:active:not(:disabled) {
  transform: translateY(1px);
  /* Sem zerar a transicao, a cor de apertado leva 160ms para chegar — mais
     que o toque inteiro num celular, e o retorno visual simplesmente nao
     acontece. Soltar continua com a transicao normal. */
  transition-duration: 0s;
}
.btn:disabled { opacity: .55; cursor: not-allowed; }
.btn svg { width: 16px; height: 16px; flex-shrink: 0; }

.btn-primario { background: var(--cor-primaria); color: #fff; }
.btn-primario:hover:not(:disabled) { background: var(--cor-primaria-clara); }
.btn-primario:active:not(:disabled) { background: var(--cor-primaria-escura); }

.btn-secundario { background: var(--cor-superficie); color: var(--cor-texto); border-color: var(--cor-borda-forte); }
.btn-secundario:hover:not(:disabled) { background: var(--cor-superficie-2); border-color: var(--cor-texto-suave); }
.btn-secundario:active:not(:disabled) { background: var(--cor-neutra-fraca); }

/*
 * Com a marca em vermelho, o botão de perigo não pode mais ser
 * "o vermelho" — ele ficaria idêntico ao botão principal, e num
 * rodapé de modal a diferença entre salvar e excluir viraria
 * questão de ler com atenção.
 *
 * Ele passa a ser CONTORNADO: peso visual menor que o do botão
 * principal (que é o certo — destruir raramente é a ação
 * esperada) e inconfundível ao lado dele. Só no hover ele se
 * enche, confirmando o que vai acontecer.
 */
.btn-perigo {
  background: transparent;
  color: var(--cor-erro);
  border-color: var(--cor-erro);
  box-shadow: none;
}
.btn-perigo:hover:not(:disabled) { background: var(--cor-erro); color: #fff; }
.btn-perigo:active:not(:disabled) { background: var(--cor-erro); color: #fff; }

.btn-fantasma { background: transparent; color: var(--cor-texto-medio); }
.btn-fantasma:hover:not(:disabled) { background: var(--cor-neutra-fraca); color: var(--cor-texto); }
.btn-fantasma:active:not(:disabled) { background: var(--cor-borda); color: var(--cor-texto); }

/* `min-height` vence `height`: sem redeclarar, estes dois herdariam a altura
   cheia do .btn e o botao compacto deixaria de ser compacto. */
.btn-sm { min-height: var(--altura-controle-sm); padding: 0 11px; font-size: 13px; }
.btn-icone {
  min-height: var(--altura-controle-sm);
  padding: 7px;
  width: var(--altura-controle-sm);
  height: var(--altura-controle-sm);
}
.btn-icone svg { width: 16px; height: 16px; }
.btn-bloco { width: 100%; }

/* <a class="btn"> (paginas de erro, atalhos de icone) herdava o
   sublinhado de 'a:hover' (0,1,1), que ganha de '.btn' (0,1,0). */
a.btn,
a.btn:hover,
.alerta a.btn { text-decoration: none; }

/* --------------------------- Alertas ---------------------------- */
.alerta {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  padding: 11px 14px;
  font-size: 13.5px;
  border-radius: var(--raio-sm);
  border: 1px solid transparent;
  margin-bottom: 16px;
}
.alerta svg { width: 17px; height: 17px; flex-shrink: 0; margin-top: 1px; }
.alerta-erro    { background: var(--cor-erro-fraca);    color: var(--cor-erro);    border-color: var(--cor-erro-borda); }
.alerta-sucesso { background: var(--cor-sucesso-fraca); color: var(--cor-sucesso); border-color: var(--cor-sucesso-borda); }
.alerta-info    { background: var(--cor-info-fraca);    color: var(--cor-info);    border-color: var(--cor-info-borda); }
.alerta-alerta  { background: var(--cor-alerta-fraca);  color: var(--cor-alerta);  border-color: var(--cor-alerta-borda); }

/* O link herda a cor do alerta; so o sublinhado o diferencia */
.alerta a { color: inherit; font-weight: 600; text-decoration: underline; }
.alerta a:hover { opacity: .8; }
.alerta svg { color: inherit; }

/* ---------------------------- Cartao ---------------------------- */
.cartao {
  background: var(--cor-superficie);
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
  box-shadow: var(--sombra-xs);
}

.cartao-cabecalho {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--cor-borda);
  font-weight: 600;
  font-size: 14.5px;
}
.cartao-corpo { padding: 18px; }
.cartao-corpo.sem-espaco { padding: 0; }
.cartao-rodape { padding: 12px 18px; border-top: 1px solid var(--cor-borda); background: var(--cor-superficie-2); border-radius: 0 0 var(--raio) var(--raio); }

/* ---------------------------- Tabela ---------------------------- */
.tabela-envolucro { overflow-x: auto; }

.tabela { width: 100%; border-collapse: collapse; font-size: 13.8px; }

/*
 * No celular a coluna tem largura minima e a tabela ROLA.
 *
 * Sem isto o navegador fazia o oposto: espremia as sete colunas dentro
 * de 330 px e o nome do registro saia uma palavra por linha. A tabela
 * "cabia" na tela e ninguem conseguia ler.
 *
 * O minimo e por COLUNA, e nao um `min-width` fixo na tabela, para a
 * conta se ajustar sozinha ao numero de colunas: uma tabela de tres
 * colunas quase nao rola, a de sete rola bastante — cada uma como
 * precisa, sem lista de excecoes por tela.
 *
 * A primeira coluna ganha mais porque e sempre a identificacao do
 * registro; a de acoes fica de fora porque e botao de icone, e 96 px
 * ali so criariam um vazio que empurra o resto.
 *
 * Mesma decisao que o calendario de Reunioes ja tinha tomado: rolar e
 * melhor que espremer texto.
 */
@media (max-width: 640px) {
  .tabela th,
  .tabela td { min-width: 96px; }

  .tabela th:first-child,
  .tabela td:first-child { min-width: 150px; }

  .tabela th.acoes,
  .tabela td.acoes { min-width: 0; }
}

.tabela th {
  text-align: left;
  padding: 10px 14px;
  font-size: 11.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--cor-texto-suave);
  background: var(--cor-superficie-2);
  border-bottom: 1px solid var(--cor-borda);
  white-space: nowrap;
}

.tabela td { padding: 11px 14px; border-bottom: 1px solid var(--cor-borda); vertical-align: middle; }
.tabela tbody tr:last-child td { border-bottom: 0; }
.tabela tbody tr:hover { background: var(--cor-superficie-2); }
.tabela tr.clicavel { cursor: pointer; }
/* Cabeçalho precisa vencer o "text-align: left" de .tabela th, que tem
   especificidade maior que a classe utilitária sozinha. */
.tabela th.text-direita,
.tabela td.text-direita { text-align: right; }

/* Colunas centralizadas: o cabeçalho acompanha o conteúdo.
   .acoes = coluna de botões; .centro = qualquer outra coluna centralizada. */
.tabela th.acoes,
.tabela td.acoes,
.tabela th.centro,
.tabela td.centro { text-align: center; }

.tabela th.acoes,
.tabela td.acoes { white-space: nowrap; }
.tabela .acoes .btn { margin: 0 2px; }

/* ---------------------------- Badges ---------------------------- */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 9px;
  font-size: 11.5px;
  font-weight: 600;
  line-height: 1.6;
  border-radius: 20px;
  white-space: nowrap;
  background: var(--cor-neutra-fraca);
  color: var(--cor-neutra);
}
.badge-sucesso { background: var(--cor-sucesso-fraca); color: var(--cor-sucesso); }
.badge-erro    { background: var(--cor-erro-fraca);    color: var(--cor-erro); }
.badge-alerta  { background: var(--cor-alerta-fraca);  color: var(--cor-alerta); }
.badge-info    { background: var(--cor-info-fraca);    color: var(--cor-info); }
.badge-neutra  { background: var(--cor-neutra-fraca);  color: var(--cor-neutra); }
.badge-primaria { background: var(--cor-primaria-fraca); color: var(--cor-primaria); }
.badge .ponto { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }

/* --------------------------- Spinner ---------------------------- */
.spinner {
  width: 15px;
  height: 15px;
  border: 2px solid rgba(255, 255, 255, .4);
  border-top-color: #fff;
  border-radius: 50%;
  animation: girar .7s linear infinite;
  display: inline-block;
}
.spinner-escuro { border-color: var(--cor-borda-forte); border-top-color: var(--cor-primaria); }

/*
 * O spinner nasceu branco, para o botao primario. Em botao de fundo
 * claro — secundario, fantasma, perigo — ele ficava branco no branco:
 * o botao travava e a pessoa nao via girar nada, que e o mesmo que
 * nao ter aviso nenhum. Aqui ele passa a usar a cor do proprio texto
 * do botao, com um lado transparente para a volta aparecer.
 */
.btn-secundario .spinner,
.btn-fantasma .spinner,
.btn-perigo .spinner {
  border-color: currentColor;
  border-top-color: transparent;
  opacity: .65;
}

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

.skeleton {
  background: linear-gradient(90deg, var(--cor-neutra-fraca) 25%, var(--cor-superficie-2) 50%, var(--cor-neutra-fraca) 75%);
  background-size: 200% 100%;
  animation: brilho 1.3s ease-in-out infinite;
  border-radius: 4px;
  color: transparent !important;
}
@keyframes brilho { to { background-position: -200% 0; } }

/* ----------------------------- Logo ----------------------------- */
/* Em superfícies claras o logo preto; no tema escuro, o branco.
   Basta usar <span class="logo-tema"> com as duas imagens dentro. */
.logo-tema img { height: 100%; width: auto; }
.logo-tema .logo-escuro { display: none; }
html[data-tema='escuro'] .logo-tema .logo-claro { display: none; }
html[data-tema='escuro'] .logo-tema .logo-escuro { display: block; }

/* Sobre fundos escuros fixos (sidebar, painel do login) usa sempre o branco */
.logo-fixo-branco img { height: 100%; width: auto; }

/* ------------------------- Estado vazio ------------------------- */
.vazio {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 48px 24px;
  text-align: center;
  color: var(--cor-texto-suave);

  /*
   * Dentro de um container em GRID, o vazio ocupa a faixa inteira.
   *
   * Sem isto ele vira uma célula como outra qualquer: na aba Listas
   * dos E-mails, o "Nenhuma lista" caía numa coluna de 260px encostada
   * à esquerda, com o resto da largura vazio ao lado. Parecia defeito
   * de alinhamento, mas era o grid tratando o aviso como se fosse mais
   * um cartão da lista.
   *
   * A propriedade é ignorada quando o pai não é grid, então vale para
   * os dois casos sem precisar de classe extra — e a próxima tela em
   * grid já nasce certa.
   */
  grid-column: 1 / -1;
}
.vazio svg { width: 40px; height: 40px; color: var(--cor-borda-forte); margin-bottom: 6px; }
.vazio strong { color: var(--cor-texto-medio); font-size: 15px; }
.vazio p { font-size: 13.5px; max-width: 380px; }
