/* Base, listas e formulários compactos, template das páginas de registo — parte do antigo site.css (dividido por área, na mesma ordem: a cascata não muda). Ordem de carregamento nos layouts:
   site-base, site-menu-tema, site-painel-graficos, site-inicio, site-formularios. */
html {
  font-size: 14px;
}

@media (min-width: 768px) {
  html {
    font-size: 16px;
  }
}

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
  box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem var(--sgc-dourado-suave, #e3c691);
}

html {
  position: relative;
  min-height: 100%;
}

:root { --bs-body-font-family: "Work Sans", -apple-system, "Segoe UI", system-ui, sans-serif; }
body {
  margin: 0;
  font-family: var(--bs-body-font-family);
}
button, input, select, textarea, .btn, .form-control, .form-select, table { font-family: inherit; }

/* Grelha "Marcar Presença" (Presenças de Catequistas/Catequizandos) — 1
   ÚNICA linha, garantida por posição fixa em CSS Grid em vez de depender
   do embrulho automático do flexbox do Bootstrap (que reflui de forma
   diferente consoante a largura da janela, podendo criar linhas extra
   inesperadas). Cada campo tem a sua própria grid-area — não larguras que
   têm de coincidir por acaso. Em ecrãs estreitos a grelha ganha scroll
   horizontal próprio em vez de reflutir para mais linhas; os controlos
   usam as variantes "-sm" do Bootstrap para caber o máximo possível numa
   só linha mesmo em ecrãs médios. As duas páginas (Catequistas/
   Catequizandos) partilham as regras base e as grid-area de cada campo,
   diferindo só no número de colunas — Catequizandos tem mais 3 filtros
   (Fase, Catequista 1, Catequista 2) que Catequistas não tem. Botão
   "Guardar" no card-header (mesmo padrão da "Aplicar aos seleccionados"
   mais abaixo), por isso a grelha só tem os campos, sem coluna de botão. */
.grelha-marcar-presenca {
  display: grid;
  column-gap: .5rem;
  align-items: end;
  overflow-x: auto;
  padding-bottom: .25rem;
}
.grelha-marcar-presenca--catequistas {
  grid-template-columns: 5.5rem 9rem 13rem 8rem 6.5rem 5.5rem 5.5rem minmax(10rem, 1fr);
  grid-template-areas: "ano fase catequista data estado entrada saida observacao";
}
.grelha-marcar-presenca--catequizandos {
  grid-template-columns: 5.5rem 8rem 9rem 9rem 12rem 8rem 6.5rem 5.5rem 5.5rem minmax(9rem, 1fr);
  grid-template-areas: "ano fase cat1 cat2 catequizando data estado entrada saida observacao";
}
/* Presenças (Catequizandos/Catequistas) — Editar Presença: mesma grelha de
   "marcar presença" de antes, mas sem Ano/Fase/Cat1/Cat2 (passaram para o
   filtro sempre visível no topo da página, partilhado com a marcação em
   massa; ver Presencas.cshtml). */
.grelha-marcar-presenca--catequizandos-editar {
  grid-template-columns: 12rem 8rem 6.5rem 5.5rem 5.5rem minmax(9rem, 1fr);
  grid-template-areas: "catequizando data estado entrada saida observacao";
}
.grelha-marcar-presenca--catequistas-editar {
  grid-template-columns: 13rem 8rem 6.5rem 5.5rem 5.5rem minmax(10rem, 1fr);
  grid-template-areas: "catequista data estado entrada saida observacao";
}
/* Presenças — filtro sempre visível no topo (Ano/Fase/Catequista1/Catequista2 +
   Data da marcação em massa), numa só linha, mesmo raciocínio da nota acima
   (CSS Grid + scroll horizontal em vez de reflutir para mais linhas). Reaproveita
   .campo-ano/.campo-fase/.campo-cat1/.campo-cat2/.campo-data já definidos acima.
   Última coluna ("exportar") é "1fr" — ocupa o espaço restante e encosta o botão
   "Exportar Excel" à direita (pedido do utilizador), sem largura fixa própria. */
.grelha-marcar-presenca--catequizandos-filtro {
  grid-template-columns: 5.5rem 9rem 10rem 10rem 8rem 1fr;
  grid-template-areas: "ano fase cat1 cat2 data exportar";
}
.grelha-marcar-presenca--catequistas-filtro {
  grid-template-columns: 5.5rem 9rem 8rem 1fr;
  grid-template-areas: "ano fase data exportar";
}
.grelha-marcar-presenca .campo-exportar { grid-area: exportar; justify-self: end; }
/* Transferências: pedido explícito do utilizador para NÃO ficar tudo
   numa só linha (ficava com demasiadas colunas) — 2 linhas independentes,
   cada uma a sua própria grelha CSS Grid: 5 colunas (filtros de pesquisa
   do catequizando) + 5 colunas (dados da transferência a gravar). Botão
   "Guardar" no card-header (ver nota da "Aplicar aos seleccionados" mais
   abaixo), por isso nenhuma das duas linhas tem coluna de botão. */
.grelha-marcar-presenca--transferencias-linha1 {
  /* Ano com largura fixa; Fase, Catequistas e Catequizando repartem toda a largura da caixa. */
  grid-template-columns: 5.5rem minmax(8rem, 1fr) minmax(9rem, 1.2fr) minmax(9rem, 1.2fr) minmax(12rem, 2fr);
  grid-template-areas: "ano fase cat1 cat2 catequizando";
}
.grelha-marcar-presenca--transferencias-linha2 {
  grid-template-columns: 9rem minmax(16rem, 1fr) 7rem;
  grid-template-areas: "estado paroquia anotransf";
}
/* Motivo e Observação numa 3.ª linha, para o campo Paróquia ter mais largura. */
.grelha-marcar-presenca--transferencias-linha3 {
  grid-template-columns: minmax(9rem, 1fr) minmax(9rem, 1fr);
  grid-template-areas: "motivo observacao";
}
.grelha-marcar-presenca .campo-ano { grid-area: ano; }
.grelha-marcar-presenca .campo-fase { grid-area: fase; min-width: 0; }
.grelha-marcar-presenca .campo-cat1 { grid-area: cat1; min-width: 0; }
.grelha-marcar-presenca .campo-cat2 { grid-area: cat2; min-width: 0; }
.grelha-marcar-presenca .campo-catequista { grid-area: catequista; min-width: 0; }
.grelha-marcar-presenca .campo-catequizando { grid-area: catequizando; min-width: 0; }
.grelha-marcar-presenca .campo-data { grid-area: data; }
.grelha-marcar-presenca .campo-estado { grid-area: estado; }
.grelha-marcar-presenca .campo-entrada { grid-area: entrada; }
.grelha-marcar-presenca .campo-saida { grid-area: saida; }
.grelha-marcar-presenca .campo-paroquia { grid-area: paroquia; min-width: 0; }
.grelha-marcar-presenca .campo-anotransf { grid-area: anotransf; min-width: 0; }
.grelha-marcar-presenca .campo-motivo { grid-area: motivo; min-width: 0; }
.grelha-marcar-presenca .campo-observacao { grid-area: observacao; min-width: 0; }

/* Presenças — "Marcar Presença em Massa" e "Presenças já lançadas" em duas
   caixas (.card) lado a lado, com o mesmo espaçamento entre colunas já usado
   no filtro Ano/Fase/Catequista1/Catequista2 (".grelha-marcar-presenca",
   column-gap:.5rem — pedido do utilizador). Cada caixa é hoje um bloco
   normal e independente (título + corpo próprios) — muito mais simples do
   que a grelha partilhada de 4 linhas que isto já foi (com "display:contents"
   e uma linha vazia só para alinhar); os cabeçalhos das duas caixas já ficam
   à mesma altura sozinhos, por serem irmãos num "flex" com
   align-items:flex-start. A caixa da esquerda encolhe ao seu conteúdo
   (Nome tem largura própria, ver .tabela-seleccao-presencas); a da direita
   ocupa o espaço restante. Sem Model.PodeGerir, só a caixa da direita existe
   e ocupa a largura toda. */
.grade-presencas-duas-colunas {
  display: flex;
  align-items: flex-start;
  gap: .5rem;
  flex-wrap: wrap;
}
.grade-presencas-duas-colunas > .card:first-child:not(:only-child) {
  flex: 0 0 auto;
}
.grade-presencas-duas-colunas > .card:last-child {
  /* "480px" de base obrigava a quebrar para baixo da caixa da esquerda
     (pedido do utilizador: deixou de ficar lado a lado) assim que a caixa da
     esquerda cresceu com a coluna Turno adicionada depois — a soma das duas
     larguras mínimas já não cabia em ecrãs de portátil comuns (~1280px,
     menos ainda com a barra lateral aberta). "320px" dá mais margem para
     caberem as duas lado a lado; esta caixa continua a encolher à mesma
     (flex-shrink:1, min-width:0) e a própria tabela lá dentro já tem
     scroll horizontal próprio (".table-responsive") quando precisa de menos
     do que isso. */
  flex: 1 1 320px;
  min-width: 0;
}

/* Coluna Nome (lista de selecção): tamanho ajustado ao conteúdo (pedido do
   utilizador — uma largura fixa de 8cm ficava com muito espaço vazio quando
   os nomes visíveis eram curtos), com 8cm só como limite máximo para nomes
   muito longos.
   "max-width" numa CÉLULA não chega para limitar a largura da COLUNA em
   table-layout automático (confirmado: mesmo com max-width:8cm na célula, a
   coluna continuava a crescer até ao nome mais longo da lista, ~14cm, porque
   o algoritmo de auto-layout só respeita mesmo um max-width posto na TABELA
   — nunca só na célula). Por isso o limite vai na tabela; a célula só
   precisa de permitir quebra de linha ("white-space:normal", a sobrepor a
   regra site-wide ".table > :not(caption) > * > *" que põe nowrap em toda a
   parte), para a coluna poder encolher abaixo do nome mais longo quando o
   limite da tabela obriga a isso. */
.tabela-seleccao-presencas {
  /* A causa real de a coluna nunca encolher: o Bootstrap define ".table" com
     "width:100%" — uma largura EXPLÍCITA, não "auto" — por isso o
     comportamento normal de uma tabela ("shrink-to-fit" ao conteúdo quando
     width:auto) nunca chegava a entrar em jogo; a tabela tentava sempre
     preencher 100% do contentor, só travada pelo max-width (por isso ficava
     sempre exactamente no limite, mesmo com um nome de 3 letras). Repor
     "width:auto" (mesma especificidade que ".table", mas depois no ficheiro,
     por isso ganha) restaura o encolhimento normal; table-layout:auto +
     max-width fazem o resto (encolhe para nomes curtos, pára em 8cm para
     nomes longos). */
  width: auto !important;
  table-layout: auto;
  max-width: calc(3rem + 2.2rem + 8cm);
}
.tabela-seleccao-presencas .col-nome-limitada {
  white-space: normal;
  overflow-wrap: break-word;
}
/* O ".table-responsive" à volta desta tabela (Bootstrap, width:auto por
   omissão mas a preencher toda a largura disponível da célula da grelha)
   ficava mais largo do que a própria tabela agora que ela encolhe ao
   conteúdo — sobrava um espaço em branco entre a coluna Nome e a barra de
   scroll vertical, encostada à direita do wrapper em vez de à tabela.
   "width:fit-content" encolhe o wrapper à largura real da tabela, para a
   barra de scroll ficar mesmo colada à coluna Nome (pedido do utilizador).
   "margin-inline:auto" centra essa caixa (mais estreita que a caixa "Marcar
   Presença em Massa", cuja largura é ditada pela linha Turno/Horas/Observação
   acima) dentro do cartão, em vez de ficar encostada à esquerda com espaço
   vazio à direita (pedido do utilizador). */
.table-responsive:has(.tabela-seleccao-presencas) {
  width: fit-content;
  max-width: 100%;
  margin-inline: auto;
}

/* Entrada/Saída (marcação em massa): rótulos encurtados ("Entrada"/"Saída",
   ver MarcacaoEmMassaInputModel) já não precisam da largura toda de
   .form-control-sm — o campo é um <input type="time">, com o próprio ícone
   de relógio do browser (pedido do utilizador). Mesma largura já usada para
   estes dois campos na grelha de "Editar Presença" (5.5rem), para ficarem
   visualmente consistentes. */
.campo-hora-marcacao {
  max-width: 5.5rem;
}

/* "Aplicar aos seleccionados" (Passagem de Nível) — Aproveitamento,
   Observação e as contagens (Registo(s)/Aprovado(a)/Reprovado(a)/Sem
   Aproveitamento) na mesma linha, alinhados ao fundo. Flexbox em vez de
   grid de colunas fixas porque o número de "caixas" de contagem é fixo
   mas o espaço disponível varia bastante (barra lateral recolhida/expandida,
   ecrãs estreitos) — quebra para a linha seguinte nesse caso. */
.linha-aplicar-passagem {
  display: flex;
  flex-wrap: wrap;
  gap: .6rem 1rem;
  align-items: end;
}
.linha-aplicar-passagem .campo-aproveitamento { flex: 0 0 auto; min-width: 9rem; }
.linha-aplicar-passagem .campo-obs { flex: 1 1 220px; min-width: 180px; }
.contagens-passagem {
  display: flex;
  gap: .5rem;
  flex: 0 0 auto;
}
.contagens-passagem > div { min-width: 5.5rem; }
/* Registo de Sacramentos: mesma ideia, mas 5 campos (sem Aproveitamento,
   que só existe em Passagem de Nível). */
.grelha-aplicar-sacramentos {
  display: grid;
  grid-template-columns: 8rem 10rem 10rem minmax(9rem, 1fr) minmax(9rem, 1fr);
  column-gap: .5rem;
  align-items: end;
  overflow-x: auto;
  padding-bottom: .25rem;
}
/* Distribuição Catequética: 6 campos (Fase, Catequista 1/2, Grupo, Sala,
   Horário). */
.grelha-aplicar-distribuicao {
  display: grid;
  grid-template-columns: minmax(8rem, 1fr) minmax(9rem, 1fr) minmax(9rem, 1fr) 6rem 8rem 7rem;
  column-gap: .5rem;
  align-items: end;
  overflow-x: auto;
  padding-bottom: .25rem;
}

/* Tabelas com cabeçalho clicável para ordenar (ver script na própria
   página) — indicador visual de qual coluna está a ordenar e em que
   sentido. */
.tabela-ordenavel th[data-sort] {
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}
.tabela-ordenavel th[data-sort]::after {
  content: '⇅';
  margin-left: .35rem;
  opacity: .35;
  font-size: .75em;
}
.tabela-ordenavel th[data-sort].ordenado-asc::after {
  content: '▲';
  opacity: .9;
}
.tabela-ordenavel th[data-sort].ordenado-desc::after {
  content: '▼';
  opacity: .9;
}

/* Contagem de catequizandos por horário (Distribuição Catequética) — ao
   lado de Ano/Fase na mesma linha, por isso tem de ser compacta em vez
   de outro cartão grande. A própria caixa (não cada badge) replica a
   altura/moldura de .form-control/.form-select, para alinhar visualmente
   com a combobox "Fase" ao lado. */
.contagem-horarios {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .3rem;
  max-width: 26rem;
  font-size: .82rem;
  min-height: calc(1.5em + .6rem + 2px);
  padding: .3rem .55rem;
  border: 1px solid var(--bs-border-color, #dee2e6);
  border-radius: .375rem;
  background: var(--bs-body-bg, #fff);
}
.badge-horario {
  font-size: .72rem;
  line-height: 1;
  background: var(--bs-tertiary-bg, #f1f3f5);
  border-radius: .25rem;
  padding: .25rem .4rem;
  white-space: nowrap;
}
.badge-horario strong {
  margin-left: .2rem;
}

/* Botão "?" que substitui um parágrafo explicativo longo — abre um modal
   só quando alguém quer mesmo saber como a página funciona, em vez de
   ocupar sempre espaço vertical no topo da página. */
.btn-info-ajuda {
  width: 1.75rem;
  height: 1.75rem;
  padding: 0;
  line-height: 1;
  font-weight: 700;
}

/* Cartões de estatísticas (Renovação Catequética) — bem menores do que o
   fs-4/small do Bootstrap por omissão, para sobrar mais altura de ecrã
   para a tabela de catequizandos abaixo, que é a parte realmente usada
   para trabalhar. */
.linha-estatisticas-renovacao .valor {
  font-size: 1.1rem;
  font-weight: 600;
  line-height: 1.2;
}
.linha-estatisticas-renovacao .rotulo {
  font-size: .68rem;
  line-height: 1.2;
}

/* Rodapé (copyright) reduzido ao mínimo — só texto informativo, sem
   utilidade que justifique ocupar espaço vertical que a lista podia usar. */
.footer {
  flex: none;
  font-size: .68rem;
  line-height: 1.2;
  padding: .1rem 1rem;
}
/* O versículo do dia (VersiculosCatequese.DoDia()) varia de comprimento —
   sem isto, um dia com frase mais longa quebrava linha e engordava o
   rodapé, que foi deliberadamente reduzido ao mínimo. */
.rodape-assinatura {
  display: inline-flex; align-items: center; gap: .35rem;
  flex: 1 1 auto; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.rodape-cruz { width: 10px; height: 10px; flex: none; opacity: .6; }
/* Botão de Ajuda com rótulo (não só ícone) — um ícone sozinho a esta escala
   ficava demasiado discreto/pouco visível junto ao texto de copyright;
   texto + cor de destaque (vinho) garantem que se nota mesmo com a barra
   inferior baixa. */
.botao-ajuda {
  display: inline-flex; align-items: center; gap: .3rem;
  height: 21px; padding: 0 .55rem; border-radius: 20px;
  border: 1px solid var(--sgc-vinho-2); background: #fff;
  color: var(--sgc-vinho); font-size: .68rem; font-weight: 600;
  cursor: pointer; white-space: nowrap;
}
.botao-ajuda svg { width: 12px; height: 12px; stroke: currentColor; flex: none; }
.botao-ajuda:hover,
.topbar-item.aberto .botao-ajuda {
  background: var(--sgc-vinho); color: #fff; border-color: var(--sgc-vinho);
}

/* ==========================================================================
   Listas compactas — as listagens (Catequizandos, Catequistas, Distribuição,
   etc.) usavam o espaçamento largo do Bootstrap por omissão, muito mais
   "arejado" do que as grelhas densas do Desktop (DataGridView), dificultando
   a consulta de listas longas. Aplica-se a todas as páginas com uma única
   folha de estilos — são 48 páginas com "table table-striped", inviável (e
   desnecessário) reescrever tabela a tabela.
   ========================================================================== */
h1.h3, h1.h4 {
  margin-bottom: .75rem !important;
}

.content-body > p.text-muted:first-of-type,
main p.text-muted:first-of-type {
  font-size: .82rem;
  /* Sem max-width — a descrição deve ocupar toda a largura disponível da
     página em vez de quebrar em várias linhas antes de a preencher. */
}

.table {
  font-size: .8rem;
}

/* Todas as colunas dimensionam-se ao conteúdo, nunca quebram para 2
   linhas — cada coluna fica exactamente tão larga quanto precisa (a
   maior célula manda), tal como uma grelha densa do Desktop; a tabela
   como um todo pode ultrapassar a largura do ecrã, daí o
   ".table-responsive" (scroll horizontal) em cada tabela. */
.table > :not(caption) > * > * {
  padding: .12rem .5rem;
  vertical-align: middle;
  line-height: 1.3;
  white-space: nowrap;
}

.table td:last-child form {
  display: inline-block;
}

/* Coluna congelada — normalmente "Nome", para se manter visível ao
   deslocar a tabela horizontalmente (tal como fixar uma coluna numa folha
   de cálculo). Aplicar a classe "col-congelada" ao <th> e a cada <td>
   dessa coluna. Fundo sólido explícito (não "inherit") para tapar por
   completo o conteúdo de outras colunas que passa por baixo ao deslocar —
   e replica o listrado do Bootstrap (".table-striped"), que de outro modo
   não se aplicaria a uma célula com fundo próprio.
   Selector ".table td/th.col-congelada" (não só ".col-congelada") de
   propósito: o Bootstrap já define background-color nas células da
   tabela via ".table > :not(caption) > * > *" (especificidade 0,1,1) —
   uma ".col-congelada" sozinha (0,1,0) perdia contra essa regra nas
   linhas pares, ficando o fundo transparente em vez de branco. */
.table td.col-congelada,
.table th.col-congelada {
  position: sticky;
  left: 0;
  z-index: 1;
  background-color: #fff;
  white-space: nowrap;
  width: 1%;
}
.table thead th.col-congelada {
  z-index: 3;
}
.table-striped > tbody > tr:nth-of-type(odd) > .col-congelada {
  background-color: #f2f2f2;
}

/* Ordenação de linhas por arrasto (ver site.js, ligarOrdenacaoArrastar) — a
   célula do número (1ª coluna) é a "alça": cursor a indicar que se pode
   arrastar, linha(s) a arrastar semi-transparentes, e uma borda a marcar
   onde vão ficar ao largar. */
.alca-arrastar {
  cursor: grab;
  user-select: none;
}
.linha-a-arrastar {
  opacity: 0.4;
}
.linha-alvo-arrastar {
  box-shadow: inset 0 2px 0 0 var(--bs-primary, #0d6efd);
}

/* ==========================================================================
   Formulários compactos — mesmo pedido das listas ("todos os formulários
   devem ser compactos... use a mesma fonte que usou nas listas"): rótulos e
   campos mais pequenos, menos espaço morto entre campos e dentro dos
   cartões, botões menores. Aplica-se a toda a área de conteúdo (não à barra
   lateral/superior, que já têm o seu próprio dimensionamento).
   ========================================================================== */
.content-body label,
.content-body .form-label,
.content-body .form-check-label {
  font-size: .78rem;
  margin-bottom: .2rem;
  font-weight: 500;
}

.content-body .form-control,
.content-body .form-select {
  font-size: .82rem;
  padding: .3rem .55rem;
  min-height: calc(1.5em + .6rem + 2px);
}

.content-body .row.g-3 {
  --bs-gutter-y: .6rem;
}
.content-body .row.g-2 {
  --bs-gutter-y: .4rem;
}

.content-body .card-body {
  padding: .75rem .9rem;
}
.content-body .card-header {
  padding: .45rem .9rem;
  font-size: .85rem;
}

.content-body .btn {
  font-size: .82rem;
  padding: .3rem .7rem;
}

/* Formulários de registo único (Configurações, Documentos, Material, etc.)
   ficavam encostados à esquerda, com um vazio grande à direita em ecrãs
   largos — cada um já limita a sua largura por um "style=max-width:...rem"
   próprio, mas nenhum se centra sozinho. Em vez de acrescentar "mx-auto" a
   cada um dos ~20 ficheiros com este padrão, um único selector por atributo
   apanha-os todos (actuais e futuros), sem afectar os cartões largos das
   listagens (não têm "max-width" no style). Só ".card", de propósito —
   nunca as tabelas que por vezes partilham o mesmo "style=max-width" por
   engano (essas devem continuar a ocupar a largura da lista). */
.content-body .card[style*="max-width"] {
  margin-left: auto;
  margin-right: auto;
}

/* Tabelas de apoio (Anos, Bairros, Zonas, Núcleos, Tipos de Documento,
   Classificações/Categorias/Fornecedores de Material, etc.) — o Bootstrap
   dá a ".table" "width:100%" por omissão, o que forçava colunas com pouco
   conteúdo (ex.: só um ano de 4 dígitos + botões Editar/Eliminar) a esticar
   até encherem a largura toda do ecrã, com espaço vazio a mais dentro de
   cada célula. A classe "tabela-estreita" (acrescentada só nestas tabelas
   de registo simples, nunca nas listagens densas de Catequizandos/
   Catequistas/etc., que precisam mesmo da largura toda) devolve a largura
   automática — cada coluna fica só tão larga quanto o conteúdo pede — e
   centra a tabela, tal como o formulário logo acima. */
.content-body table.tabela-estreita {
  width: auto;
  max-width: 100%;
  margin-left: auto;
  margin-right: auto;
}

/* ==========================================================================
   Template das páginas de registo (Configurações, Tipos de Documento, etc.)
   --------------------------------------------------------------------------
   - Caixa de registo à ESQUERDA (campos na vertical) e lista à DIREITA, a ocupar todo o espaço que sobra; o conjunto fica centrado, com
     uma largura máxima, para não esticar demais em ecrãs enormes. Em ecrãs estreitos empilham.
   - Os dois blocos são "cartões": cantos arredondados, sombra suave e filete dourado, no estilo vinho e dourado do resto do sistema.
   - A lista é mais arejada do que as grelhas densas do resto do sistema (linhas mais altas, cabeçalho discreto, realce ao passar o rato)
     e termina com o total de registos. "Eliminar Seleccionados" fica por cima da lista, alinhado à esquerda com ela.
   Páginas com duas listas (Níveis e Fases, Horários e Salas) usam ".painel-registo" + ".lista-centrada" com o mesmo aspecto.
   ========================================================================== */
.content-body .layout-registo {
  display: grid;
  grid-template-columns: minmax(17rem, 23rem) minmax(0, 1fr);
  gap: 1.5rem;
  align-items: start;
  width: 100%;
  max-width: 1180px;
  margin: 0 auto 1.5rem;
}
.content-body .layout-registo.sem-form {
  grid-template-columns: minmax(0, 1fr);
}
/* Uma só coluna: o formulário compacto em cima, a toda a largura, e a lista por baixo (em vez de formulário à esquerda e lista à direita). */
.content-body .layout-registo.empilhado {
  grid-template-columns: minmax(0, 1fr);
  gap: .75rem;
}
.content-body .layout-registo.empilhado .layout-registo-form .card { margin: 0 !important; }
.content-body .layout-registo.sem-form > .layout-registo-form {
  display: none;
}
.content-body .layout-registo-form {
  min-width: 0;
}
.content-body .layout-registo-form .row > [class*="col-"] {
  flex: 0 0 100%;
  width: 100% !important;
  max-width: 100%;
}

/* Cartão da caixa de registo (e, em geral, todos os cartões das páginas de Configurações, para terem o mesmo aspecto) */
.content-body .layout-registo-form .card,
.content-body .painel-registo .card {
  max-width: none !important;
  margin: 0 0 1rem !important;
}
.content-body .layout-registo-form .card,
.content-body .painel-registo .card,
.content-body.secao-config .card {
  background: #fff;
  border: 1px solid var(--sgc-border);
  border-top: 3px solid var(--sgc-dourado);
  border-radius: .75rem;
  box-shadow: 0 1px 2px rgba(58, 15, 28, .05), 0 8px 22px rgba(58, 15, 28, .07);
  overflow: hidden;
}
.content-body .layout-registo-form .card-header,
.content-body .painel-registo .card-header,
.content-body.secao-config .card-header {
  background: transparent;
  border-bottom: 1px solid var(--sgc-border);
  padding: .7rem 1rem;
  font-size: .95rem;
  font-weight: 600;
}
.content-body .layout-registo-form .card-body,
.content-body .painel-registo .card-body,
.content-body.secao-config .card-body {
  padding: 1rem;
}
.content-body .layout-registo-form .form-label,
.content-body .painel-registo .form-label,
.content-body.secao-config .card .form-label {
  margin-bottom: .25rem;
  font-size: .78rem;
  font-weight: 600;
  letter-spacing: .02em;
  color: var(--sgc-text-muted);
}
.content-body .layout-registo-form .form-control,
.content-body .layout-registo-form .form-select,
.content-body .painel-registo .form-control,
.content-body .painel-registo .form-select,
.content-body.secao-config .card .form-control,
.content-body.secao-config .card .form-select {
  padding: .4rem .7rem;
  border-radius: .5rem;
}

/* Cartão da lista (linhas compactas, para listas longas) */
.content-body .layout-registo-lista,
.content-body .lista-centrada {
  min-width: 0;
  overflow-x: auto;
  counter-reset: registos;
  background: #fff;
  border: 1px solid var(--sgc-border);
  border-radius: .75rem;
  box-shadow: 0 1px 2px rgba(58, 15, 28, .05), 0 8px 22px rgba(58, 15, 28, .07);
  padding: .5rem 1rem .8rem;
}
.content-body .lista-centrada {
  width: 100%;
  margin: 0 0 1.25rem;
}
.content-body .layout-registo-lista > .mb-2,
.content-body .lista-centrada > .mb-2 {
  display: flex;
  gap: .5rem;
  padding: .1rem 0 .45rem;
  margin-bottom: 0 !important;
}
.content-body .layout-registo-lista table,
.content-body .lista-centrada table {
  width: 100%;
  margin: 0;
  font-size: .82rem;
  --bs-table-striped-bg: transparent;
}
.content-body .layout-registo-lista .table > :not(caption) > * > *,
.content-body .lista-centrada .table > :not(caption) > * > * {
  padding: .16rem .6rem;
  line-height: 1.25;
  border-bottom-color: rgba(221, 211, 194, .7);
}
.content-body .layout-registo-lista .table thead th,
.content-body .lista-centrada .table thead th {
  padding: .3rem .6rem;
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--sgc-text-muted);
  background: transparent;
  border-bottom: 2px solid var(--sgc-dourado);
}
.content-body .layout-registo-lista .table tbody tr,
.content-body .lista-centrada .table tbody tr {
  counter-increment: registos;
  transition: background-color .12s ease;
}
.content-body .layout-registo-lista .table tbody tr:hover > *,
.content-body .lista-centrada .table tbody tr:hover > * {
  background-color: rgba(193, 154, 91, .13);
}
.content-body .layout-registo-lista .table .btn-sm,
.content-body .lista-centrada .table .btn-sm {
  padding: .08rem .4rem;
  font-size: .68rem;
  line-height: 1.25;
}
.content-body .layout-registo-lista::after,
.content-body .lista-centrada::after {
  content: counter(registos) " registo(s)";
  display: block;
  margin-top: .55rem;
  font-size: .75rem;
  color: var(--sgc-text-muted);
}

@media (max-width: 991.98px) {
  .content-body .layout-registo {
    grid-template-columns: minmax(0, 1fr);
    gap: 1rem;
  }
}

/* Mais específico do que ".content-body .btn" acima (3 classes em vez de
   2), para garantir que os botões de acção por linha (Editar/Eliminar)
   ficam mesmo pequenos, independentemente da ordem no ficheiro. */
.content-body .table .btn-sm {
  padding: .15rem .45rem;
  font-size: .7rem;
}

.table thead th {
  position: sticky;
  top: 0;
  background: var(--sgc-dourado-suave);
  z-index: 2;
  white-space: nowrap;
  font-size: .74rem;
  text-transform: uppercase;
  letter-spacing: .02em;
  color: var(--sgc-text-muted, #55483d);
  border-bottom-width: 2px;
}

/* Barra de navegação vertical (e horizontal, já dada pelo table-responsive
   do Bootstrap) só aparece quando a lista é mesmo mais alta do que isto —
   mantém o formulário de filtros e os botões de acção sempre visíveis por
   cima, sem ter de percorrer a lista inteira para lá chegar. */
.table-responsive {
  max-height: 68vh;
  overflow-y: auto;
}

/* Barra de acções (Adicionar/Excluir/Actualizar/Aplicar) fixa por cima da
   lista, tal como no Desktop (sempre visível, em vez de obrigar a descer
   até ao fim de uma lista longa para a encontrar). */
.barra-accoes {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  margin-bottom: .75rem;
}


/* ==========================================================================
   Acessibilidade: foco visível ao navegar com o teclado, ligação «Saltar para o
   conteúdo» e respeito por quem pede menos movimento no sistema operativo.
   ========================================================================== */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 3px solid #1b6ec2;
  outline-offset: 2px;
  box-shadow: 0 0 0 5px rgba(255, 255, 255, .85);
}
.sidebar :where(a, button, summary):focus-visible {
  outline-color: #ffd98a;
  box-shadow: none;
}
main:focus { outline: none; }
.saltar-conteudo {
  position: absolute;
  left: .75rem;
  top: -4rem;
  z-index: 3000;
  padding: .55rem .9rem;
  background: #fff;
  color: #3a0f1c;
  font-weight: 600;
  border: 2px solid #3a0f1c;
  border-radius: .35rem;
  text-decoration: none;
}
.saltar-conteudo:focus { top: .75rem; }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

/* Lista de sugestões compacta dos campos de texto livre (ver site.js, «Lista de sugestões compacta»). */
.sgc-sugestoes {
  display: none; position: fixed; z-index: 2500;
  max-height: 14rem; overflow-y: auto;
  background: #fff; border: 1px solid var(--sgc-border, #d8cdb8); border-radius: 6px;
  box-shadow: 0 10px 24px -14px rgba(20, 10, 6, .5);
  padding: .15rem 0;
}
.sgc-sugestoes.aberto { display: block; }
.sgc-sugestao {
  padding: .22rem .6rem; font-size: .84rem; font-weight: 400; line-height: 1.25;
  color: #212529; cursor: pointer;
}
.sgc-sugestao:hover, .sgc-sugestao.activa { background: var(--sgc-surface, #f4eee2); }

/* Resultados das pesquisas por nome/local (mesmo aspecto compacto). */
.busca-resultados a { padding: .3rem .6rem; font-weight: 400; }

/* ==========================================================================
   Contraste do texto secundário: o «.text-muted» do Bootstrap 5.1 é #6c757d, que sobre a cor de fundo das páginas (#f4f1ec) fica nos 4,2:1
   (o mínimo recomendado para texto é 4,5:1). Passa a usar o castanho suave do sistema (#55483d: 8,7:1 sobre o cartão, 7,8:1 sobre o fundo).
   A área pública e o acesso têm as suas próprias regras (mais específicas) e não mudam.
   ========================================================================== */
.content-body .text-muted,
.footer.text-muted,
.footer .text-muted {
  color: var(--sgc-text-muted, #55483d) !important;
}


/* ==========================================================================
   Caixas com largura limitada (cartões, avisos, formulários e tabelas estreitas, que usam «max-width» em linha) ficam CENTRADAS na página, para
   manter a harmonia com o resto do site; o texto dentro da caixa não muda. Dentro de uma coluna da grelha (col-*), a caixa mantém o alinhamento da coluna.
   ========================================================================== */
.content-body .card[style*="max-width"],
.content-body .alert[style*="max-width"],
.content-body .row[style*="max-width"],
.content-body form[style*="max-width"],
.content-body table[style*="max-width"] {
  margin-left: auto;
  margin-right: auto;
}
.content-body [class*="col-"] .card[style*="max-width"],
.content-body [class*="col-"] .alert[style*="max-width"],
.content-body [class*="col-"] table[style*="max-width"] {
  margin-left: 0;
  margin-right: 0;
}

/* Tabelas estreitas («w-auto», por exemplo «Ver como tabela» dos gráficos e do Resumo) e os seus envoltórios em linha: centradas na caixa/página
   (o conteúdo das células não muda). Vale para a área com acesso e para a pública. */
table.w-auto {
  margin-left: auto;
  margin-right: auto;
}
.table-responsive.d-inline-block {
  display: block !important;
  width: fit-content;
  max-width: 100%;
  margin-left: auto;
  margin-right: auto;
}

/* Botão "Mostrar todas as colunas" das tabelas largas no telemóvel (ver site.js, data-colunas-essenciais) */
.botao-colunas-movel { display: none; margin-bottom: .5rem; }
@media (max-width: 767.98px) { .botao-colunas-movel { display: inline-block; } }

/* Linhas da marcação de presenças clicáveis (ver site.js); no telemóvel, linhas mais altas para tocar com o dedo */
.tabela-seleccao-presencas tbody tr { cursor: pointer; }
@media (max-width: 767.98px) {
  .tabela-seleccao-presencas td { padding-top: .5rem; padding-bottom: .5rem; }
}


/* Linha centrada de filtros/botões das páginas, com o botão «?» (descrição da página) na mesma linha. */
.barra-centrada { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: center; gap: .5rem; }
.barra-ajuda { display: flex; justify-content: center; margin-bottom: .75rem; }
.btn-ajuda { width: 1.6rem; height: 1.6rem; padding: 0; border-radius: 50%; border: 1px solid var(--sgc-border, #c9b98f); background: transparent; color: var(--sgc-vinho, #5a1a2a); font-weight: 700; font-size: .8rem; line-height: 1; cursor: pointer; }
.btn-ajuda:hover, .btn-ajuda[aria-expanded="true"] { background: var(--sgc-surface, #f4ede0); }
.ajuda-balao { position: fixed; z-index: 3000; max-width: min(24rem, 92vw); background: #fff; color: #2b2b2b; border: 1px solid var(--sgc-border, #c9b98f); border-radius: .5rem; padding: .6rem .8rem; box-shadow: 0 .4rem 1.2rem rgba(0,0,0,.22); font-size: .85rem; line-height: 1.35; }
/* Páginas da área pública abertas dentro do sistema: o título já está no cabeçalho. */
.corpo-publico-embutido h1 { display: none; }
