/* =========================================================================
   Tema "Circuito de aprovação" — camada sobre o Bootstrap 5.3.
   Identidade: documento de controlo + carimbo (tinta de carimbo violeta).
   Aplica-se a toda a app (cores/tipografia); o ecrã "A minha mesa" (.mesa)
   leva o tratamento completo. Ver plan.md / CLAUDE.md.
   ========================================================================= */

:root {
  --paper:        #E7E7E0; /* papel/betão frio — fundo da página            */
  --surface:      #FCFCF9; /* branco de documento — cartões                 */
  --surface-2:    #F3F3EC; /* faixa sutil                                   */
  --ink:          #1A1D24; /* tinta grafite (quase preto, frio)             */
  --ink-2:        #5A5F68; /* tinta fraca — texto secundário                */
  --linha:        #D6D6CC; /* fio de pauta (betão)                          */
  --carimbo:      #4B39A7; /* tinta de carimbo — marca + ação primária      */
  --carimbo-tinta:#2E2170; /* tinta de carimbo profunda — moldura do selo   */
  --carimbo-suave:rgba(75, 57, 167, .10);
  --alerta:       #BE4319; /* laranja de segurança — fundo/borda de urgência */
  --alerta-suave: rgba(190, 67, 25, .12);
  --alerta-texto: #9E330E; /* laranja escurecido — texto sobre fundo suave (AA) */
  --ok:           #2E7157; /* confirmação (só isso — nunca é a marca)        */
  --ok-suave:     rgba(46, 113, 87, .12);
  --raio:    3px;          /* cartões, botões, inputs                        */
  --raio-sm: 2px;          /* etiquetas, chips                               */
}

/* ---- Base ---------------------------------------------------------------- */
body {
  font-family: 'IBM Plex Sans', system-ui, sans-serif;
  background: var(--paper);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 {
  font-family: 'Space Grotesk', system-ui, sans-serif;
  letter-spacing: -.012em;
  color: var(--ink);
}
a { color: var(--carimbo); text-underline-offset: 2px; }
a:hover { color: var(--carimbo-tinta); }
hr { border-color: var(--linha); }

/* Foco visível e coerente em todo o lado (piso de qualidade). */
:focus-visible {
  outline: 2px solid var(--carimbo);
  outline-offset: 2px;
}

/* Saltar a navegação: invisível até receber foco por teclado. Fora do ecrã por
   posição (não `display:none`), senão o leitor de ecrã também não lhe chegava. */
.link-saltar {
  position: absolute;
  top: 0;
  left: -9999px;
  z-index: 100;
  padding: .6rem 1rem;
  background: var(--carimbo);
  color: #fff;
  font-weight: 600;
  text-decoration: none;
  border-radius: 0 0 var(--raio) 0;
}
.link-saltar:focus { left: 0; }

/* ---- Barra de navegação -------------------------------------------------- */
.navbar.bg-dark {
  background-color: var(--ink) !important;
  border-bottom: 1px solid #000;
}
.navbar .navbar-brand {
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 700;
  letter-spacing: .005em;
  display: inline-flex;
  align-items: center;
}
/* Losango antes do nome da aplicação. Chegou a sair em 2026-09-09, quando o
   logótipo da Opero entrou ao lado; o cliente pediu-o de volta no mesmo dia
   (D49) — é a marca da aplicação, e o logótipo é o da empresa. */
.navbar .navbar-brand::before {
  content: "";
  width: .72em; height: .72em;
  margin-right: .5em;
  border: 2px solid var(--carimbo);
  border-radius: var(--raio-sm);
  transform: rotate(-8deg);
}

/* Contagem no menu ("Por imputar 4"). Monocromática: sobre a barra escura, o
   contraste vem do claro contra o escuro e não de cor nova (D32). Números em
   mono e tabulares para o crachá não mudar de largura de 9 para 10. */
.nav-conta {
  display: inline-block;
  min-width: 1.4em;
  margin-left: .35em;
  padding: 0 .35em;
  border-radius: 999px;
  background: var(--paper);
  color: var(--ink);
  font-family: 'IBM Plex Mono', monospace;
  font-variant-numeric: tabular-nums;
  font-size: .78em;
  font-weight: 600;
  line-height: 1.5;
  text-align: center;
}
/* Dentro de um `btn-outline-light`, o hover inverte o botão: sem isto o crachá
   ficava claro sobre claro e desaparecia. */
.btn-outline-light:hover .nav-conta {
  background: var(--ink);
  color: var(--paper);
}

/* ---- Botões (recolorir via variáveis do Bootstrap) ----------------------- */
.btn { --bs-btn-border-radius: var(--raio); font-weight: 500; }
.btn-primary {
  --bs-btn-bg: var(--carimbo);
  --bs-btn-border-color: var(--carimbo);
  --bs-btn-hover-bg: var(--carimbo-tinta);
  --bs-btn-hover-border-color: var(--carimbo-tinta);
  --bs-btn-active-bg: var(--carimbo-tinta);
  --bs-btn-active-border-color: var(--carimbo-tinta);
  --bs-btn-disabled-bg: var(--carimbo);
  --bs-btn-disabled-border-color: var(--carimbo);
  --bs-btn-focus-shadow-rgb: 75, 57, 167;
}
.btn-success {
  --bs-btn-bg: var(--ok); --bs-btn-border-color: var(--ok);
  --bs-btn-hover-bg: #245c46; --bs-btn-hover-border-color: #245c46;
  --bs-btn-active-bg: #245c46; --bs-btn-active-border-color: #245c46;
}
.btn-outline-danger {
  --bs-btn-color: var(--alerta); --bs-btn-border-color: var(--alerta);
  --bs-btn-hover-bg: var(--alerta); --bs-btn-hover-border-color: var(--alerta);
}
.btn-dark { --bs-btn-bg: var(--ink); --bs-btn-border-color: var(--ink); }

/* ---- Superfícies genéricas (cartões, alertas, tabelas) ------------------- */
.card {
  --bs-card-bg: var(--surface);
  --bs-card-border-color: var(--linha);
  --bs-card-border-radius: var(--raio);
}
.card-header { background: var(--surface-2); font-family: 'Space Grotesk', sans-serif; }
.alert { --bs-alert-border-radius: var(--raio); border-width: 1px 1px 1px 3px; }
.table { --bs-table-bg: var(--surface); }
.form-control, .form-select { border-color: var(--linha); border-radius: var(--raio); }
.form-control:focus, .form-select:focus {
  border-color: var(--carimbo);
  box-shadow: 0 0 0 .2rem var(--carimbo-suave);
}

/* ---- Barra de filtros (relatórios de aprovação) --------------------------
   Era um cartão com sete campos de tamanho normal em grelha de quatro colunas,
   e duas caixas de ajuda de alturas diferentes que desencontravam as linhas de
   base da fila. Passa a uma barra: sem cartão, campos `sm`, rótulos na mesma
   pauta das etiquetas da aplicação (maiúsculas espaçadas, tinta fraca) e uma
   nota só, no fim. A grelha é `auto-fit` em vez de colunas fixas — reflui
   sozinha e deixa de sobrar meia fila vazia. */
.filtros {
  border: 1px solid var(--linha);
  border-radius: var(--raio);
  background: var(--surface);
  padding: .9rem 1rem .75rem;
  margin-bottom: 1.5rem;
}
.filtros__grelha {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
  gap: .75rem .9rem;
  align-items: end;
}
/* O par de datas ocupa duas colunas: são dois campos no espaço de um rótulo. */
.filtro--datas { grid-column: span 2; }
@media (max-width: 34rem) {
  .filtro--datas { grid-column: span 1; }
}
.filtro { min-width: 0; }
.filtro__rotulo {
  display: block;
  font-size: .75rem;  /* mesmo piso de legibilidade das etiquetas da mesa */
  text-transform: uppercase;
  letter-spacing: .08em;
  font-weight: 600;
  color: var(--ink-2);
  margin-bottom: .25rem;
}
.filtro__par {
  display: flex;
  align-items: center;
  gap: .35rem;
}
.filtro__par .form-control { min-width: 0; }
.filtro__ate {
  color: var(--ink-2);
  font-family: 'IBM Plex Mono', monospace;
  flex: none;
}
/* Os botões são mais uma célula da grelha: assim acompanham o refluxo em vez
   de ficarem numa fila própria sempre que a largura muda. */
.filtros__acoes {
  display: flex;
  align-items: center;
  gap: .4rem;
  flex-wrap: wrap;
}
.filtros__limpar {
  --bs-btn-color: var(--ink-2);
  --bs-btn-hover-color: var(--carimbo);
  text-decoration: none;
  padding-left: .25rem;
  padding-right: .25rem;
}
.filtros__nota {
  font-size: .8rem;
  color: var(--ink-2);
  margin: .7rem 0 0;
}

/* ---- Campo com lista de caixas (escolher vários) -------------------------
   Substituiu o `<select multiple>` dos aprovadores de uma obra: num select
   nativo nada indica que se pode escolher mais do que um, e quem escolhia o
   segundo perdia o primeiro sem perceber porquê — daí a instrução "Ctrl/Cmd"
   que lá estava. Caixas dispensam a instrução e funcionam no telemóvel, onde
   essas teclas não existem.

   A marcação é a que o Django gera (`<div>` por opção, `<input>` dentro do
   `<label>`), que não encaixa no `.form-check` do Bootstrap — o aspeto vem
   todo daqui. */
.campo-caixas {
  border: 0;
  padding: 0;
  margin: 0;
  min-width: 0; /* um <fieldset> não encolhe por omissão; sem isto estoira grelhas */
}
/* O Bootstrap põe o <legend> a ~20px e em `float: left`; aqui é um rótulo de
   campo como os outros. */
.campo-caixas > legend {
  float: none;
  width: auto;
  font-size: inherit;
  line-height: inherit;
  margin-bottom: .5rem;
}
/* O contentor que o Django desenha à volta das opções. */
.campo-caixas > div {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
  gap: .1rem .5rem;
  /* Com muitos utilizadores a lista crescia sem fim e empurrava o resto do
     formulário. Rola a partir daí, como o histórico da fatura. */
  max-height: 14rem;
  overflow-y: auto;
  overscroll-behavior: contain;
  border: 1px solid var(--linha);
  border-radius: var(--raio);
  background: var(--surface);
  padding: .35rem .5rem;
  scrollbar-width: thin;
  scrollbar-color: var(--linha) transparent;
}
.campo-caixas > div::-webkit-scrollbar { width: 8px; }
.campo-caixas > div::-webkit-scrollbar-track { background: transparent; }
.campo-caixas > div::-webkit-scrollbar-thumb {
  background: var(--linha);
  border-radius: 4px;
}
.campo-caixas label {
  display: flex;
  align-items: center;
  gap: .5rem;
  /* A linha toda é alvo de toque, não só a caixa: em obra, com luvas, acertar
     num quadrado de 14px é o que falha. */
  padding: .35rem .3rem;
  border-radius: var(--raio-sm);
  cursor: pointer;
  margin: 0;
}
.campo-caixas label:hover { background: var(--surface-2); }
.campo-caixas input[type="checkbox"] {
  /* `accent-color` recolore a caixa nativa sem lhe substituir o comportamento
     nem a marcação — o contrário do que o Bootstrap faz. */
  accent-color: var(--carimbo);
  width: 1rem;
  height: 1rem;
  flex: none;
  margin: 0;
}
.campo-caixas input[type="checkbox"]:focus-visible {
  outline: 2px solid var(--carimbo);
  outline-offset: 2px;
}
@media (pointer: coarse) {
  .campo-caixas label { min-height: 44px; }
}

/* Navbar: marca da empresa · nome da aplicação (este é que é o link). */
.marca {
  display: flex;
  align-items: center;
  gap: .75rem;
  min-width: 0;
}
.marca__logo {
  height: 30px;
  width: auto;
  flex: none;
}
.marca__sep {
  color: rgba(255, 255, 255, .35);
  line-height: 1;
  user-select: none;
}
.marca__app { margin-right: 0; }

/* =========================================================================
   Carimbo — o elemento-assinatura. Impressão de selo de borracha.
   ========================================================================= */
.carimbo {
  font-family: 'Space Grotesk', sans-serif;
  text-transform: uppercase;
  color: var(--carimbo-tinta);
  border: 4px double var(--carimbo-tinta);
  border-radius: 7px;
  padding: .4rem .95rem .5rem;
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  line-height: 1;
  transform: rotate(-5deg);
  opacity: .9;
  mix-blend-mode: multiply; /* assenta a tinta no papel */
  /* Ligeiro desalinhamento de tinta — como um carimbo pressionado duas vezes. */
  box-shadow: 1.5px 1.5px 0 var(--carimbo-suave);
  text-shadow: .5px .5px 0 rgba(46, 33, 112, .18);
  user-select: none;
}
.carimbo--pendente .carimbo__linha1 {
  font-size: .7rem; font-weight: 600; letter-spacing: .2em;
}
.carimbo--pendente .carimbo__n {
  font-size: 1.75rem; font-weight: 700; letter-spacing: .02em; margin-top: .12em;
}
.carimbo--limpa {
  color: var(--ok);
  border-color: var(--ok);
  font-size: clamp(1.5rem, 6vw, 2.2rem);
  font-weight: 700;
  letter-spacing: .12em;
  padding: .6rem 1.5rem .7rem;
  transform: rotate(-4deg);
  box-shadow: 1.5px 1.5px 0 var(--ok-suave);
  text-shadow: .5px .5px 0 rgba(46, 113, 87, .18);
}

/* =========================================================================
   "Os meus Centros de Custo" — registo de faturas em conferência.
   ========================================================================= */
.mesa { max-width: 62rem; margin-inline: auto; }

/* ---- Cabeçalho / hero ---------------------------------------------------- */
.mesa__cabecalho { margin-bottom: 1.75rem; }
.mesa__sobre {
  font-family: 'IBM Plex Mono', monospace;
  text-transform: uppercase;
  letter-spacing: .18em;
  font-size: .72rem;
  color: var(--ink-2);
  margin: 0 0 .35rem;
}
.mesa__topo {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}
.mesa__titulo {
  font-size: clamp(2rem, 6vw, 3.1rem);
  font-weight: 700;
  margin: 0;
}

/* ---- Faixa de estatísticas (dados reais) --------------------------------- */
.mesa__stats {
  display: flex;
  flex-wrap: wrap;
  gap: 0;
  margin: 1.35rem 0 0;
  border: 1px solid var(--linha);
  border-radius: var(--raio);
  background: var(--surface);
  overflow: hidden;
}
.mesa__stats .stat {
  flex: 1 1 8rem;
  padding: .8rem 1.1rem;
  border-left: 1px solid var(--linha);
}
.mesa__stats .stat:first-child { border-left: 0; }
.mesa__stats dt {
  font-size: .75rem;  /* piso de legibilidade: 12px (era .68rem ≈ 10,9px) */
  text-transform: uppercase;
  letter-spacing: .12em;
  color: var(--ink-2);
  font-weight: 600;
}
.mesa__stats dd {
  font-family: 'IBM Plex Mono', monospace;
  font-variant-numeric: tabular-nums;
  font-size: 1.5rem;
  font-weight: 600;
  margin: .15rem 0 0;
  color: var(--ink);
}
.mesa__stats dd .stat__u { font-size: .9rem; color: var(--ink-2); margin-left: .1em; }
.mesa__stats .stat--alerta dd { color: var(--alerta); }

/* ---- Registo (lista de processos) ---------------------------------------- */
.registo {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: .8rem;
}
.processo {
  display: grid;
  grid-template-columns: 1fr minmax(11rem, 15rem);
  gap: clamp(1rem, 3vw, 2rem);
  background: var(--surface);
  border: 1px solid var(--linha);
  /* A barra à esquerda codifica URGÊNCIA, não a marca: neutra por defeito,
     laranja quando o vencimento aperta. O violeta fica reservado ao selo e à ação. */
  border-left: 3px solid var(--linha);
  border-radius: var(--raio);
  padding: 1.05rem 1.25rem 1.15rem;
}
/* Sem hover-lift: o cartão não é clicável — só o botão de ação é. */
.processo > * { min-width: 0; }
.processo--proxima { border-left-color: var(--alerta); }
.processo--vencida {
  border-left-color: var(--alerta);
  border-left-width: 4px;
  background: linear-gradient(0deg, var(--alerta-suave), var(--alerta-suave)), var(--surface);
}

.processo__cabecalho {
  display: flex;
  align-items: baseline;
  gap: .75rem;
  flex-wrap: wrap;
  margin-bottom: .55rem;
}
.processo__ref {
  font-family: 'IBM Plex Mono', monospace;
  font-weight: 600;
  font-size: .82rem;
  letter-spacing: .02em;
  color: var(--ink);
}
.processo__prova {
  font-family: 'IBM Plex Mono', monospace;
  font-size: .75rem;  /* piso de legibilidade: 12px (era .68rem ≈ 10,9px) */
  text-transform: uppercase;
  letter-spacing: .1em;
  color: var(--ink-2);
}
.processo__fornecedor {
  font-family: 'Space Grotesk', sans-serif;
  font-size: 1.32rem;
  font-weight: 600;
  line-height: 1.15;
  margin: 0;
  overflow-wrap: anywhere; /* nomes de fornecedor longos não transbordam */
}
.processo__obra { color: var(--ink-2); margin: .2rem 0 0; font-size: .92rem; }
.processo__routing {
  margin: .7rem 0 0;
  font-size: .82rem;
  color: var(--ink-2);
  display: flex;
  align-items: center;
  gap: .5rem;
  flex-wrap: wrap;
}

/* Etiquetas de encaminhamento — codificam POR QUE a fatura está nesta mesa. */
.tag {
  font-family: 'IBM Plex Mono', monospace;
  font-weight: 600;
  font-size: .7rem;
  text-transform: uppercase;
  letter-spacing: .07em;
  padding: .3em .6em;
  border: 1px solid;
  border-radius: var(--raio-sm);
  white-space: nowrap;
}
.tag--obra   { color: var(--carimbo-tinta); border-color: var(--carimbo); background: var(--carimbo-suave); }

/* ---- Coluna direita: valor, vencimento, ação ----------------------------- */
.processo__rail {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  text-align: right;
  gap: .55rem;
}
.processo__total {
  font-family: 'IBM Plex Mono', monospace;
  font-size: clamp(1.15rem, 4.5vw, 1.55rem); /* encolhe para totais grandes */
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  line-height: 1;
  margin: 0;
  color: var(--ink);
}
.processo__moeda { font-size: .82rem; color: var(--ink-2); margin-left: .25em; }
.venc {
  font-family: 'IBM Plex Mono', monospace;
  font-size: .74rem;
  margin: 0;
  padding: .28em .55em;
  border-radius: var(--raio-sm);
  color: var(--ink-2);
  background: var(--surface-2);
}
.venc--proxima { color: var(--alerta-texto); background: var(--alerta-suave); font-weight: 600; }
.venc--vencida { color: #fff; background: var(--alerta); font-weight: 600; }

/* Aviso chamativo: fatura vencida sem decisão final (histórico de obra). */
tr.linha-alerta { background: var(--alerta-suave); }
tr.linha-alerta:hover { background: var(--alerta-suave); }
.aviso-vencida {
  display: inline-flex;
  align-items: center;
  gap: .35em;
  margin-top: .35em;
  padding: .3em .6em;
  border-radius: var(--raio-sm);
  color: #fff;
  background: var(--alerta);
  font-weight: 700;
  font-size: .72rem;
  text-transform: uppercase;
  letter-spacing: .02em;
}

/* ---- Separadores de arquivo (organização pessoal por obra) ---------------
   Metáfora: os separadores de cartolina de um arquivador. O separador aberto
   "parte" a régua por baixo e liga-se à lista que se segue — é isso que torna
   óbvio que a tabela mostra o conteúdo daquele separador.
   Monocromático de propósito: a cor tem significado reservado neste sistema
   (carimbo = ação, laranja = urgência) e isto é arrumação privada, não estado
   do documento. */
.arquivo { margin-top: 2rem; }
.arquivo__topo {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: .5rem;
}
.arquivo__rotulo {
  font-family: 'IBM Plex Mono', monospace;
  font-size: .7rem;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--ink-2);
  margin: 0;
}
.arquivo__rotulo span { text-transform: none; letter-spacing: 0; opacity: .8; }

/* A tira rola na horizontal em vez de partir para várias linhas: com wrap, as
   abas da 2.ª linha perderiam a ligação visual à régua. */
.arquivo__tira {
  display: flex;
  align-items: stretch;
  gap: .15rem;
  padding: 0 .15rem;
  overflow-x: auto;
  scrollbar-width: thin;
  border-bottom: 1px solid var(--linha);
}
.separador {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: .5em;
  padding: .5rem .8rem;
  border: 0;
  border-top: 2px solid transparent;   /* espaço reservado: o ativo pinta-o */
  border-radius: var(--raio-sm) var(--raio-sm) 0 0;
  background: transparent;
  color: var(--ink-2);
  font-size: .84rem;
  line-height: 1.2;
  text-decoration: none;
  white-space: nowrap;
  transition: background .12s ease, color .12s ease;
}
.separador:hover { background: var(--surface-2); color: var(--ink); }
.separador__n {
  font-family: 'IBM Plex Mono', monospace;
  font-variant-numeric: tabular-nums;
  font-size: .72rem;
  opacity: .6;
}
/* O separador aberto toma a cor de papel da tabela que se segue — é isso que o
   liga visualmente à lista. Marcador a 2px no topo para não deixar dúvidas.
   Filetes laterais por `inset` (não por border) para não mexer no layout. */
.separador--ativo {
  background: var(--surface);
  color: var(--ink);
  font-weight: 600;
  border-top-color: var(--ink);
  box-shadow: inset 1px 0 0 var(--linha), inset -1px 0 0 var(--linha);
}
.separador--ativo:hover { background: var(--surface); }
.separador--ativo .separador__n { opacity: .75; }
.separador__apagar {
  border: 0;
  background: none;
  color: var(--ink-2);
  font-size: 1.05rem;
  line-height: 1;
  padding: 0 .1em;
  margin-left: .15em;
  cursor: pointer;
}
.separador__apagar:hover { color: var(--alerta); }

/* Criar: fechado por omissão (<details>) para a tira ficar limpa em repouso. */
.arquivo__novo { flex: 0 0 auto; }
.arquivo__novo > summary {
  list-style: none;
  cursor: pointer;
  font-size: .8rem;
  color: var(--ink-2);
  padding: .3rem .6rem;
  border: 1px dashed var(--linha);
  border-radius: var(--raio-sm);
  white-space: nowrap;
}
.arquivo__novo > summary::-webkit-details-marker { display: none; }
.arquivo__novo > summary:hover { color: var(--ink); border-color: var(--ink-2); }
.arquivo__novo[open] > summary { color: var(--ink); border-style: solid; }
.arquivo__form { display: flex; gap: .3rem; margin-top: .4rem; }
.arquivo__form input { max-width: 12rem; }

.arquivo__vazio {
  padding: .9rem 1rem;
  border: 1px dashed var(--linha);
  border-radius: var(--raio);
  background: var(--surface-2);
  color: var(--ink-2);
  font-size: .85rem;
  /* Sem separadores não há tira a que a tabela se "ligue" — recupera o respiro. */
  margin: 0 0 1.25rem;
}

/* Filtrar por situação, dentro do separador aberto — mesma família dos separadores.
   Mesmos materiais: monocromático (a cor tem significado reservado neste sistema,
   ver D32), contagem em mono, mesmo corpo de letra, mesma tira que rola em vez de
   partir para duas linhas. Distingue-se pela **direção da marca**: o separador é
   uma aba que se levanta (marca em cima, toma o papel da tabela); a situação é uma
   linha de índice **sobre** esse papel (marca em baixo, assente no próprio fio que
   a separa da lista). Assim lêem-se como o mesmo sistema sem se confundirem. */
.filtro-situacao {
  display: flex;
  align-items: stretch;
  gap: .15rem;
  padding: .4rem .65rem 0;
  background: var(--surface);
  box-shadow: inset 1px 0 0 var(--linha), inset -1px 0 0 var(--linha);
  border-bottom: 1px solid var(--linha);
  overflow-x: auto;
  scrollbar-width: thin;
}
.filtro-situacao__rotulo {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  font-family: 'IBM Plex Mono', monospace;
  font-size: .7rem;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--ink-2);
  opacity: .7;
  padding-bottom: .4rem;
  margin-right: .45rem;
}
.filtro-situacao__opcao {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: .5em;
  padding: .3rem .7rem;
  border: 0;
  border-bottom: 2px solid transparent;  /* espaço reservado: a ativa pinta-o */
  border-radius: var(--raio-sm) var(--raio-sm) 0 0;
  background: transparent;
  color: var(--ink-2);
  font-size: .84rem;
  line-height: 1.2;
  text-decoration: none;
  white-space: nowrap;
}
.filtro-situacao__opcao:hover { background: var(--surface-2); color: var(--ink); }
.filtro-situacao__n {
  font-family: 'IBM Plex Mono', monospace;
  font-variant-numeric: tabular-nums;
  font-size: .72rem;
  opacity: .6;
}
.filtro-situacao__opcao--ativa {
  color: var(--ink);
  font-weight: 600;
  border-bottom-color: var(--ink);
}
.filtro-situacao__opcao--ativa:hover { background: transparent; }
.filtro-situacao__opcao--ativa .filtro-situacao__n { opacity: .75; }

/* Escolher o separador de uma fatura, dentro da tabela: silencioso em repouso,
   revela-se ao passar o rato — não deve competir com o estado da fatura. */
.sep-escolha {
  max-width: 11rem;
  padding: .2rem .3rem;
  border: 1px solid transparent;
  border-radius: var(--raio-sm);
  background: transparent;
  color: var(--ink-2);
  font-family: inherit;
  font-size: .8rem;
  cursor: pointer;
}
.sep-escolha:hover { border-color: var(--linha); background: var(--surface-2); color: var(--ink); }
.sep-escolha:focus-visible { border-color: var(--ink); background: var(--surface); color: var(--ink); }
.sep-escolha--arrumada { color: var(--ink); }
.processo__acao {
  margin-top: auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px; /* alvo de toque confortável (obra/telemóvel) */
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 600;
  font-size: .9rem;
  text-decoration: none;
  color: #fff;
  background: var(--carimbo);
  padding: .5rem .95rem;
  border-radius: var(--raio);
  transition: background .15s ease;
  white-space: nowrap;
}
.processo__acao:hover { background: var(--carimbo-tinta); color: #fff; }

/* ---- Mesa limpa (estado vazio) ------------------------------------------- */
.mesa-limpa {
  text-align: center;
  padding: clamp(2.5rem, 10vw, 5rem) 1rem;
  border: 1px dashed var(--linha);
  border-radius: var(--raio);
  background: var(--surface);
}
.mesa-limpa__texto { color: var(--ink-2); margin: 1.25rem 0 0; }

/* ---- Responsivo ---------------------------------------------------------- */
@media (max-width: 40rem) {
  /* O carimbo do hero passa para baixo do título (evita clipping à direita). */
  .mesa__topo { flex-direction: column; align-items: flex-start; gap: .9rem; }
}

@media (max-width: 34rem) {
  .processo {
    grid-template-columns: 1fr;
    gap: 1rem;
  }
  /* Rail em movel: total + vencimento na 1ª linha; ação ocupa a largura toda. */
  .processo__rail {
    flex-flow: row wrap;
    align-items: center;
    justify-content: space-between;
    gap: .5rem .75rem;
    text-align: left;
    border-top: 1px solid var(--linha);
    padding-top: .85rem;
  }
  .processo__total { order: 1; }
  .venc { order: 2; }
  .processo__acao { order: 3; flex-basis: 100%; text-align: center; margin-top: .1rem; }
  /* Os números ficam lado a lado no telemóvel, em vez de empilhados: assim a
     faixa ocupa uma linha e não meio ecrã antes de se chegar à primeira
     fatura. `flex: 1 1 0` com `min-width: 0` é o que impede a quebra — sem o
     `min-width`, o conteúdo impõe a largura mínima e as caixas voltam a
     partir para baixo. O corpo do rótulo mantém-se nos 12px (piso de
     legibilidade); o que cede é o `letter-spacing`, que é o que não cabe em
     três colunas de telemóvel, e o tamanho do número. */
  .mesa__stats .stat {
    flex: 1 1 0;
    min-width: 0;
    padding: .6rem .4rem;
  }
  /* A coluna do valor é a única de comprimento variável — as contagens nunca
     passam de dois dígitos. Sem lhe dar mais largura, um total de seis dígitos
     transbordava a caixa (medido: 150.000,00 € já não cabia em três colunas
     iguais a 390px, e os dados de demonstração — 822,90 € — escondiam-no). */
  .mesa__stats .stat--valor { flex: 1.7 1 0; }
  .mesa__stats dt {
    letter-spacing: .02em;
    line-height: 1.15;
    /* Rede de segurança: um rótulo de palavra única e longa ("CONDICIONAIS")
       não cabe numa quarta coluna — parte-se em vez de transbordar a caixa. */
    overflow-wrap: break-word;
  }
  /* `min()` em vez de tamanho fixo: encolhe nos ecrãs mais estreitos em vez de
     partir o número ao meio, que num valor em euros se lê mal ("1.234.5" numa
     linha e "67,89" na seguinte). Medido: 1,05rem chega até 360px. */
  .mesa__stats dd { font-size: min(1.05rem, 4.6vw); }
  .mesa__stats dd .stat__u { font-size: .7rem; }
}

/* Ecrãs táteis: a ação principal do processo já tinha 44px, mas os `btn-sm` da
   navegação e das tabelas ("Abrir", "Editar", "Sair") ficavam nos ~31px. Em obra,
   com luvas e ao sol, é onde se falha o toque. Só em ponteiro grosseiro — no rato
   estes botões devem continuar discretos. */
@media (pointer: coarse) {
  .btn-sm {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  /* Espaço entre alvos vizinhos (mínimo 8px) na tira de ações da navegação. */
  .navbar-nav { gap: .6rem !important; }
  .seta-comentario {
    min-width: 44px;
    min-height: 44px;
  }
}

/* ---- Movimento reduzido -------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
  .processo:hover { transform: none; }
}

/* =========================================================================
   Componentes partilhados pelos restantes ecrãs — mesma linguagem da "mesa".
   ========================================================================= */

/* Eyebrow / sobrescrito reutilizável (igual ao da mesa). */
.eyebrow {
  font-family: 'IBM Plex Mono', monospace;
  text-transform: uppercase;
  letter-spacing: .18em;
  font-size: .72rem;
  color: var(--ink-2);
  margin: 0 0 .35rem;
}

/* Cabeçalho de página (título + ação/retorno à direita). */
.page-head { margin-bottom: 1.6rem; }
.page-head__row {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: .75rem 1rem;
  flex-wrap: wrap;
}
.page-head__title {
  font-family: 'Space Grotesk', sans-serif;
  font-size: clamp(1.7rem, 4vw, 2.4rem);
  font-weight: 700;
  letter-spacing: -.015em;
  margin: 0;
}
.page-head__lead { color: var(--ink-2); margin: .5rem 0 0; max-width: 62ch; }

/* Tabelas como registo/documento de controlo. */
.table { --bs-table-bg: var(--surface); --bs-table-border-color: var(--linha); }
.table thead th {
  font-family: 'IBM Plex Mono', monospace;
  text-transform: uppercase;
  letter-spacing: .07em;
  font-size: .75rem;  /* piso de legibilidade: 12px (era .68rem ≈ 10,9px) */
  font-weight: 600;
  color: var(--ink-2);
}
.table td { vertical-align: middle; }
.num, td.num, th.num {
  font-family: 'IBM Plex Mono', monospace;
  font-variant-numeric: tabular-nums;
}

/* Distintivos coerentes com a paleta. */
.badge.text-bg-primary   { background-color: var(--carimbo) !important; }
.badge.text-bg-secondary { background-color: var(--ink-2)   !important; }
.badge.text-bg-dark      { background-color: var(--ink)     !important; }

/* Chip de estado (fatura / aprovação). */
.chip-estado {
  display: inline-block;
  font-family: 'IBM Plex Mono', monospace;
  text-transform: uppercase;
  letter-spacing: .06em;
  font-size: .75rem;  /* piso de legibilidade: 12px (era .68rem ≈ 10,9px) */
  font-weight: 600;
  padding: .3em .6em;
  border-radius: var(--raio-sm);
  border: 1px solid var(--linha);
  color: var(--ink-2);
  background: var(--surface-2);
}
.chip-estado--ok    { color: var(--ok);            border-color: var(--ok);      background: var(--ok-suave); }
.chip-estado--aviso { color: var(--alerta-texto);  border-color: var(--alerta);  background: var(--alerta-suave); }
.chip-estado--acao  { color: var(--carimbo-tinta); border-color: var(--carimbo); background: var(--carimbo-suave); }

/* Comentário de uma aprovação: fica **aberto** por omissão — foi escrito para
   ser lido — e a seta a seguir ao estado esconde-o para quem só quer a lista.
   Monocromático de propósito: a cor está reservada ao estado (D32), e o
   comentário é a nota à margem, não o carimbo. */
.seta-comentario {
  border: 0;
  background: none;
  padding: 0 .25rem;
  line-height: 1;
  color: var(--ink-2);
}
.seta-comentario:hover { color: var(--ink); }
.seta-comentario__icone {
  display: inline-block;
  font-size: .85rem;
  transition: transform .15s ease;
}
/* Fechado: a seta aponta para o lado, como uma pasta por abrir. */
.seta-comentario[aria-expanded="false"] .seta-comentario__icone {
  transform: rotate(-90deg);
}
.comentario-aprovacao {
  margin: .4rem 0 0;
  padding-left: .7rem;
  border-left: 2px solid var(--linha);
  color: var(--ink-2);
  font-size: .9rem;
  white-space: pre-line;  /* respeita as quebras de linha de quem escreveu */
}

/* ---- Aprovada condicionalmente (D42) ------------------------------------
   Não é uma decisão — é uma espera declarada. Fica **monocromática** (D32:
   a cor está reservada ao carimbo e à urgência) e usa o **tracejado** como
   código próprio: a linha interrompida lê-se como "por fechar", sem gastar
   uma cor nova nem competir com o verde do aprovado ou o laranja do vencido. */
.chip-estado--condicional {
  color: var(--ink-2);
  border-color: var(--ink-2);
  border-style: dashed;
  background: var(--surface-2);
}
.tag--condicional {
  color: var(--ink-2);
  border-color: var(--ink-2);
  border-style: dashed;
  background: var(--surface-2);
}
.comentario-aprovacao--condicional { border-left-style: dashed; }
.comentario-aprovacao__rotulo,
.processo__condicional-rotulo {
  font-family: 'IBM Plex Mono', monospace;
  text-transform: uppercase;
  letter-spacing: .06em;
  font-size: .75rem;
  font-weight: 600;
  color: var(--ink);
}
.processo__condicional {
  margin: .35rem 0 0;
  padding-left: .7rem;
  border-left: 2px dashed var(--linha);
  color: var(--ink-2);
  font-size: .9rem;
  white-space: pre-line;
}
/* O que já está marcado, no cartão da decisão: lembra a quem volta ao ecrã o
   que ficou pendente da última vez. */
.nota-condicional {
  padding: .6rem .75rem;
  border: 1px dashed var(--ink-2);
  border-radius: var(--raio);
  background: var(--surface-2);
}
.nota-condicional__titulo {
  margin: 0 0 .25rem;
  font-family: 'IBM Plex Mono', monospace;
  font-size: .75rem;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--ink);
}
.nota-condicional__texto {
  color: var(--ink-2);
  font-size: .9rem;
  white-space: pre-line;
}
/* Três ações na mesma linha: quebram para baixo em ecrã estreito em vez de
   encolherem abaixo do alvo tátil de 44px. */
.decisao-botoes {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
}
.btn-condicional {
  --bs-btn-color: var(--ink);
  --bs-btn-border-color: var(--ink-2);
  --bs-btn-hover-bg: var(--ink);
  --bs-btn-hover-border-color: var(--ink);
  --bs-btn-active-bg: var(--ink);
  --bs-btn-active-border-color: var(--ink);
  border-style: dashed;
}
/* Aviso de comentário em falta (D48): só aparece depois de alguém tentar
   rejeitar ou marcar como condicional sem escrever nada. Usa o laranja de
   urgência já reservado por D32 — não entra cor nova por causa disto. */
.decisao-erro {
  color: var(--alerta-texto);
  font-size: .92rem;
  font-weight: 600;
}
/* Classe própria em vez do `.is-invalid` do Bootstrap: aquele traz um ícone
   de fundo que não pertence a esta identidade. */
.campo--falta {
  border-color: var(--alerta);
  box-shadow: 0 0 0 .2rem var(--alerta-suave);
}

/* Painéis do centro de gestão (contagem em destaque). */
.hub-card__n {
  font-family: 'IBM Plex Mono', monospace;
  font-variant-numeric: tabular-nums;
  font-size: 2rem;
  font-weight: 600;
  line-height: 1;
  color: var(--ink);
}
.hub-card__rotulo {
  font-family: 'IBM Plex Mono', monospace;
  text-transform: uppercase;
  letter-spacing: .1em;
  font-size: .75rem;  /* piso de legibilidade: 12px (era .68rem ≈ 10,9px) */
  color: var(--ink-2);
}

/* Detalhe da fatura. */
.doc-visor {
  border: 1px solid var(--linha);
  background: var(--surface);
  border-radius: var(--raio);
}
/* O visor antes de o `visor.js` lhe meter o documento — e, no telemóvel, para
   sempre. Sem `ratio`: uma caixa quadrada e vazia com um botão ao meio seria
   pior do que não ter caixa nenhuma (D70). */
.doc-visor--ligacao { padding: 1.5rem; text-align: center; }
.doc-visor__titulo {
  font-family: 'IBM Plex Mono', monospace;
  text-transform: uppercase;
  letter-spacing: .18em;
  font-size: .72rem;
  color: var(--ink-2);
  margin: 0 0 .9rem;
}
.doc-visor__nota {
  font-size: .85rem;
  color: var(--ink-2);
  margin: .9rem 0 0;
}
.doc-dl dt { color: var(--ink-2); font-weight: 500; }
.doc-dl dd { font-family: 'IBM Plex Mono', monospace; font-variant-numeric: tabular-nums; }

/* Entrar (login) — primeiro contacto com a identidade. */
.login { max-width: 24rem; margin: clamp(1.5rem, 6vw, 4rem) auto 0; }
.login__marca {
  display: flex;
  align-items: center;
  gap: .5rem;
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--ink);
  margin-bottom: 1.5rem;
}
.login__selo {
  width: .8em;
  height: .8em;
  border: 2px solid var(--carimbo);
  border-radius: var(--raio-sm);
  transform: rotate(-8deg);
}
.login__titulo {
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 700;
  font-size: 2rem;
  margin: 0 0 1.25rem;
}
.login__cartao {
  background: var(--surface);
  border: 1px solid var(--linha);
  border-top: 3px solid var(--carimbo);
  border-radius: var(--raio);
  padding: 1.5rem;
}
.login__cartao .btn-primary { width: 100%; }

/* =========================================================================
   Obras adjudicadas — cartões na Mesa que levam ao histórico da obra.
   ========================================================================= */
.obras { margin-top: 2.5rem; }
.obras__cabecalho { margin-bottom: 1rem; }
.obras__titulo {
  font-family: 'Space Grotesk', sans-serif;
  font-size: clamp(1.3rem, 3.5vw, 1.7rem);
  font-weight: 700;
  margin: 0;
}
.obras__sub {
  color: var(--ink-2);
  margin: .35rem 0 0;
  max-width: 62ch;
  font-size: .92rem;
}
.obras__lista {
  list-style: none;
  margin: 1.1rem 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: .8rem;
}
.obra-card { min-width: 0; }
.obra-card__link {
  display: flex;
  flex-direction: column;
  gap: .7rem;
  height: 100%;
  min-height: 44px; /* alvo de toque confortável */
  padding: 1rem 1.1rem;
  background: var(--surface);
  border: 1px solid var(--linha);
  /* Barra à esquerda = tinta de carimbo: a obra é navegável (leva ao histórico). */
  border-left: 3px solid var(--carimbo);
  border-radius: var(--raio);
  text-decoration: none;
  color: var(--ink);
  transition: border-color .15s ease, box-shadow .15s ease;
}
.obra-card__link:hover {
  color: var(--ink);
  border-color: var(--carimbo);
  box-shadow: 0 2px 0 var(--carimbo-suave);
}
.obra-card__ref { display: flex; flex-direction: column; gap: .1rem; min-width: 0; }
.obra-card__codigo {
  font-family: 'IBM Plex Mono', monospace;
  font-weight: 600;
  font-size: .74rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--carimbo-tinta);
}
.obra-card__nome {
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 600;
  font-size: 1.1rem;
  line-height: 1.15;
  overflow-wrap: anywhere; /* nomes de obra longos não transbordam */
}
.obra-card__metricas {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: .4rem .7rem;
  margin-top: auto;
}
.obra-card__metrica {
  font-family: 'IBM Plex Mono', monospace;
  font-size: .74rem;
  color: var(--ink-2);
}
.obra-card__metrica b { color: var(--ink); font-variant-numeric: tabular-nums; }
.obra-card__metrica--aviso, .obra-card__metrica--aviso b { color: var(--alerta-texto); }
.obra-card__seta { margin-left: auto; color: var(--carimbo); font-weight: 700; }

/* ---- Tabelas ordenáveis e filtráveis (Fase 22) ---------------------------
   O cabeçalho passa a botão (feito em JS — ver `tabela.js`), por isso tem de
   parecer cabeçalho e não botão do Bootstrap. Monocromático: a cor continua
   reservada ao estado e à ação (D32); aqui a seta e o traço bastam. */
/* Rótulo + seta de ordenação + menu de valores, sempre na mesma linha. Sem
   isto o menu quebrava para baixo do cabeçalho assim que a coluna apertava. */
.th-cabecalho {
  display: inline-flex;
  align-items: center;
  gap: .15rem;
  white-space: nowrap;
}

.th-ordenar {
  display: inline-flex;
  align-items: center;
  gap: .35em;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: inherit;
  cursor: pointer;
}
.th-ordenar:hover { color: var(--carimbo); }
.th-ordenar__seta::after {
  content: '↕';
  font-size: .8em;
  opacity: .35;
}
[aria-sort='ascending'] .th-ordenar__seta::after { content: '↑'; opacity: 1; }
[aria-sort='descending'] .th-ordenar__seta::after { content: '↓'; opacity: 1; }

.th-filtro { display: inline-block; }
.th-filtro__botao {
  /* 24x24 é o mínimo para um alvo de ponteiro (WCAG 2.5.8); a seta sozinha
     dava 11x10 e falhava-se o clique. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 24px;
  min-height: 24px;
  padding: 0 .25em;
  border: 0;
  background: none;
  color: var(--ink-2);
  font-size: .85em;
  line-height: 1;
  opacity: .45;
  cursor: pointer;
}
.th-filtro__botao:hover { opacity: 1; color: var(--carimbo); }
/* Coluna com filtro por aplicar: tem de se ver que a lista está incompleta. */
.th-filtro__botao--ativo {
  opacity: 1;
  color: var(--carimbo);
  background: var(--carimbo-suave);
  border-radius: var(--raio-sm);
}
.th-filtro__menu {
  max-height: 18rem;
  overflow-y: auto;
  padding: .35rem;
  /* O menu está dentro de um `<th>` e herdava dele o versalete e o espaçamento
     do cabeçalho: os valores liam-se "BETÃO" em vez de "Betão". Aqui mostram-se
     os dados como eles são. */
  font-family: 'IBM Plex Sans', system-ui, sans-serif;
  text-transform: none;
  letter-spacing: normal;
  font-weight: 400;
  font-size: .85rem;
  color: var(--ink);
}
.th-filtro__acoes {
  display: flex;
  gap: .5rem;
  padding: 0 .35rem .35rem;
  border-bottom: 1px solid var(--linha);
  margin-bottom: .35rem;
}
.th-filtro__acao {
  padding: 0;
  border: 0;
  background: none;
  color: var(--carimbo);
  font-size: .78rem;
  text-decoration: underline;
  cursor: pointer;
}
.th-filtro__opcao {
  display: block;
  padding: .18rem .35rem;
  white-space: nowrap;
  cursor: pointer;
}
.th-filtro__opcao:hover { background: var(--surface-2); }

.tabela-ferramentas {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
  flex-wrap: wrap;
  margin: .75rem 0 .35rem;
}
.tabela-ferramentas__campo { max-width: 22rem; flex: 1 1 12rem; }
.tabela-ferramentas__contagem {
  margin: 0;
  font-family: 'IBM Plex Mono', monospace;
  font-size: .74rem;
  color: var(--ink-2);
  opacity: .8;
}

/* Linha escondida pelo filtro — classe (e não `hidden`) para não colidir com
   o `display` que o Bootstrap dá às linhas da tabela. */
.linha-filtrada { display: none; }

@media (pointer: coarse) {
  .th-ordenar, .th-filtro__botao { min-height: 44px; }
  .th-filtro__opcao { padding: .5rem .35rem; }
}

/* Observações de uma fatura: uma nota por linha, com autor e data. Mesma
   linguagem do comentário de uma aprovação — nota à margem, não carimbo. */
.observacao__meta {
  font-family: 'IBM Plex Mono', monospace;
  font-size: .72rem;
  color: var(--ink-2);
  opacity: .85;
}
.observacao__texto {
  white-space: pre-line;
  color: var(--ink);
}
.observacao__apagar {
  min-width: 24px;
  min-height: 24px;
  padding: 0 .3rem;
  border: 0;
  background: none;
  color: var(--ink-2);
  line-height: 1;
  opacity: .5;
  cursor: pointer;
}
.observacao__apagar:hover { opacity: 1; color: var(--alerta-texto); }

@media (pointer: coarse) {
  .observacao__apagar { min-width: 44px; min-height: 44px; }
}

/* ---- Histórico da fatura (D44) ------------------------------------------
   O rasto de auditoria, finalmente com ecrã. Lê-se de cima para baixo como uma
   folha de processo: o que aconteceu, quando e por quem. Monocromático (D32),
   com uma barra à esquerda a marcar as duas ações que mudam o rumo da fatura —
   aprovada e rejeitada — para se encontrarem de relance numa lista longa. */
/* Numa fatura com muitas passagens o rasto crescia sem fim e empurrava tudo o
   que vem depois para fora do ecrã. A lista passa a ter caixa própria com
   rolamento: mostra cerca de cinco registos e o resto rola lá dentro. O
   `tabindex="0"` no HTML é o que permite a quem navega por teclado rolar a
   caixa; sem ele o conteúdo escondido ficava inalcançável. */
.historico-caixa {
  max-height: 22rem;
  overflow-y: auto;
  overscroll-behavior: contain;
  /* Barra de rolagem discreta, dentro da pauta monocromática (D32). */
  scrollbar-width: thin;
  scrollbar-color: var(--linha) transparent;
}
.historico-caixa:focus-visible { outline-offset: -2px; }
.historico-caixa::-webkit-scrollbar { width: 8px; }
.historico-caixa::-webkit-scrollbar-track { background: transparent; }
.historico-caixa::-webkit-scrollbar-thumb {
  background: var(--linha);
  border-radius: 4px;
}
.historico-caixa::-webkit-scrollbar-thumb:hover { background: var(--ink-2); }

.historico__linha { border-left: 3px solid transparent; }
.historico__linha--aprovada  { border-left-color: var(--ok); }
.historico__linha--rejeitada { border-left-color: var(--alerta); }
.historico__topo {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: .5rem;
}
.historico__acao {
  font-family: 'IBM Plex Mono', monospace;
  text-transform: uppercase;
  letter-spacing: .06em;
  font-size: .75rem;
  font-weight: 600;
  color: var(--ink);
}
.historico__quando {
  font-family: 'IBM Plex Mono', monospace;
  font-variant-numeric: tabular-nums;
  font-size: .75rem;
  color: var(--ink-2);
  white-space: nowrap;
}
.historico__quem { font-size: .85rem; color: var(--ink-2); }
.historico__detalhe {
  margin-top: .3rem;
  padding-left: .7rem;
  border-left: 2px solid var(--linha);
  font-size: .9rem;
  color: var(--ink-2);
  white-space: pre-line;
}

/* =========================================================================
   Páginas de erro (403 / 404 / 500) — a mesma pauta da entrada.
   Sem cor nova: o código do erro leva o laranja de segurança porque é um
   aviso, e o resto é monocromático (D32). A página do 500 não usa esta folha
   (ver `500.html`), por ter de funcionar mesmo quando os estáticos não servem.
   ========================================================================= */
.erro { max-width: 32rem; margin: clamp(1.5rem, 6vw, 4rem) auto 0; }
.erro__codigo {
  font-family: 'IBM Plex Mono', monospace;
  font-variant-numeric: tabular-nums;
  font-size: .72rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--alerta-texto);
  margin: 0 0 .35rem;
}
.erro__titulo {
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 700;
  font-size: 2rem;
  margin: 0 0 1.25rem;
}
.erro__cartao {
  background: var(--surface);
  border: 1px solid var(--linha);
  border-top: 3px solid var(--alerta);
  border-radius: var(--raio);
  padding: 1.5rem;
}
.erro__cartao p:last-child { margin-bottom: 0; }
