/* Fontes reais empacotadas em static/fonts/ (ver README.md ali) - sem isso o
 * navegador escolhia um fallback do sistema por conta propria, e o zero
 * daquele fallback não era o do Design.md. */
@font-face { font-family: "Inter"; font-weight: 400; src: url("/static/fonts/Inter-Regular.woff2") format("woff2"); font-display: swap; }
@font-face { font-family: "Inter"; font-weight: 600; src: url("/static/fonts/Inter-SemiBold.woff2") format("woff2"); font-display: swap; }
@font-face { font-family: "JetBrains Mono"; font-weight: 450; src: url("/static/fonts/JetBrainsMono-Regular.woff2") format("woff2"); font-display: swap; }

/* ============================================================================
 * Painel OCLE - Gestão de Obras. A folha ÚNICA do painel, desde 05/09/2026.
 *
 * Ate aqui eram DUAS, e elas discordavam: `app.css` vestia 10 telas no verde do
 * Design.md, e `ocle.css` vestia so a Visao Geral numa paleta ardosia/esmeralda
 * (`--canvas-bg: #f8fafc`). O resultado e' que a tela de abertura parecia outro
 * produto, e nenhuma das duas parecia os prints. Os prints novos de 05/09 -
 * entregues em CODIGO, em `frontend-referencia/codigo/` - decidem a discussao:
 * fundo verde-claro `#e9f3d9`, sidebar `#17512c` sob laje `#0f3b1f`, e uma
 * escala tipografica bem maior que a que estava aqui.
 *
 * Esta folha e' o `app.css` retonalizado para esses tokens, e nao uma reescrita
 * a partir do prototipo. A razao e' de risco: o prototipo e' um mockup de tres
 * telas com dado inventado, e o que esta escrito aqui e' a mecanica que as ONZE
 * telas exigem - o sticky de <thead> que so funciona sem `overflow` na tabela,
 * o <tfoot> grudado por celula, o chevron do acordeao, as tres regras de
 * impressao, o indicador do htmx. Trocar valor de token nao arrisca nada disso;
 * comecar do zero arriscaria tudo, e de novo.
 *
 * O que veio do prototipo alem dos tokens: as variantes de KPI, as abas em
 * pilula, a tabela com grade completa, a celula de prazo de fundo cheio e a
 * agenda semanal da Programacao - todas no fim, em COMPONENTES DO PROTOTIPO.
 * Mais as pilulas de alerta da Visao Geral, que ficam junto do dashboard.
 *
 * O controle segmentado do print NAO virou componente novo: e' o `.vistas` que
 * ja existia para `?colunas=` em Material e RMDs, e que o Controle Operacional
 * passou a usar no lugar do texto corrido. O comentario de `.vistas` ja o
 * apontava como o proximo candidato - foi so cobrar a promessa.
 *
 * A laje escura continua na NAVEGACAO, nao nas tabelas - a decisao de 04/09
 * segue de pe e pelo mesmo motivo: com a sidebar verde-profunda, uma tabela de
 * cabecalho escuro empilha lajes e pesa. So o <tfoot> segue escuro, porque ali
 * a laje significa "total".
 *
 * Cor reservada para SEMANTICA (verde ok / ambar aviso / vermelho negativo /
 * cinza neutro), separada do acento. O `--info` passou de teal a AZUL: e a cor
 * que os prints dao a "Unica" e a PLV, e ela precisa distinguir-se do verde de
 * "Final" a um metro de distancia.
 *
 * Sistema claro, de propósito: o fundo é pintado explicitamente para não pegar o
 * tema do host. Inter no texto E no número; a tabularidade vem do
 * `font-variant-numeric: tabular-nums` em `.num`, nunca da mono. A JetBrains
 * Mono continua empacotada e declarada: voltar é trocar `--f-num`, uma linha.
 * ========================================================================== */

:root {
  /* superfícies - os verdes claros dos prints (protótipo, seção 1) */
  --surface: #e9f3d9;         /* fundo da página */
  --panel: #ffffff;
  --panel-2: #f3f8ea;         /* zebra, cabeçalho de tabela, trilho de barra */
  /* Duas bordas, nao uma. O prototipo separa a borda do CARTAO (`--borda`) da
   * divisoria INTERNA (`--borda-2`), e a diferenca importa numa tela de 200
   * linhas: com a borda de cartao em toda linha, a tabela vira grade. */
  --line: #d2e2ba;            /* borda de cartão, de tabela, de filtro */
  --line-2: #e6eeda;          /* divisória entre linhas de tabela */
  --line-forte: #bcd39a;

  /* tinta */
  --ink: #14331f;
  --ink-medio: #3a5a45;
  --muted: #4c6b57;
  --muted-claro: #82997f;
  /* o travessao de ausencia tem cor propria: --muted-claro nao passa em AA,
   * e este e o glifo que carrega a regra 1 (`NULL` != 0) na tela. */
  --nulo: #5f7f6a;
  /* a tinta de TODO titulo - pagina, painel, cartao. Separada do `--primary`,
   * que e acento de link e de estado ativo: nos prints o titulo e verde
   * profundo e o link e verde medio, e fundi-los apagaria a hierarquia. */
  --titulo: #0f3b1f;

  /* marca / acento */
  --primary: #1c6b38;         /* link de projeto (protótipo --verde-700) */
  --primary-forte: #217a3f;   /* barra de progresso, estado OK (--verde-600) */
  --primary-suave: #eef3e4;   /* pílula do item ativo, fundo verde muito claro */
  --on-primary: #ffffff;

  /* semântica (separada do acento) */
  --ok: #217a3f;        --ok-bg: #e2f0d9;
  --aviso: #b98900;     --aviso-bg: #fbf1cd;
  --erro: #b3261e;      --erro-bg: #fdeceb;
  --neutro: #56635b;    --neutro-bg: #e7eae6;
  --info: #2563eb;      --info-bg: #e4edfe;
  --indigo: #4b4a9e;    --indigo-bg: #e5e4f7;

  /* faixa sólida escura: hoje só o <tfoot> de totais. É o verde profundo do
   * logotipo, o mesmo da laje da sidebar - uma tinta escura só no painel. */
  --faixa: #0f3b1f;
  --faixa-2: #17512c;         /* linha de agrupamento do cabeçalho, um tom acima */
  --faixa-ink: #eaf3ee;
  --faixa-ink-fraca: #a9c7b6;

  /* navegacao: corpo `--verde-800` sob a laje `--verde-900` do logotipo, e o
   * filete de acento `#62c33f` no item ativo - os tres do protótipo. */
  --sidebar-bg: #17512c;
  --sidebar-topo: #0f3b1f;
  --sidebar-ink: #ffffff;
  --sidebar-ink-fraca: #a9d3a4;
  --sidebar-acento: #62c33f;
  --sidebar-ativo-bg: #0f3b1f;
  --sidebar-linha: rgba(255, 255, 255, 0.10);

  --sidebar-w: 248px;
  --sidebar-w-recolhida: 72px;
  --linha-h: 40px;
  --linha-h-densa: 36px;
  --r: 14px;
  --r-md: 10px;
  --r-sm: 8px;
  --r-pill: 999px;
  --sombra: 0 1px 2px rgba(15, 59, 31, 0.05), 0 1px 3px rgba(15, 59, 31, 0.04);
  --sombra-2: 0 2px 6px rgba(15, 59, 31, 0.08);

  --f-texto: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --f-num: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  /* Escala de espacamento. Ate 04/09 o arquivo nao tinha nenhuma: `16px 18px`,
   * `14px 16px`, `11px 16px`, `13px 15px` e `10px 14px` eram valores digitados a
   * mao em componentes diferentes, e nenhum deles errado sozinho. O problema e
   * que sem escala "padronizar as telas" nao e verificavel - nao ha contra o que
   * conferir. Os componentes tocados na refatoracao passam a usar estas. */
  --e-1: 4px;
  --e-2: 8px;
  --e-3: 12px;
  --e-4: 16px;
  --e-5: 24px;
  --e-6: 32px;
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

/* 13,5px ate 04/09. Os prints leem-se de longe - e a maior diferenca entre o
 * painel de ontem e eles nao e cor, e ESCALA. O protótipo declara 15px/1.45 no
 * corpo, e toda a hierarquia daqui para baixo foi remedida a partir disso. */
body {
  margin: 0;
  background: var(--surface);
  color: var(--ink);
  font-family: var(--f-texto);
  font-size: 15px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

a { color: inherit; }

/* números: sans-serif, tabular, alinhados à direita quando em coluna. O
 * `tabular-nums` é obrigatório aqui: sem mono, é ele que mantém a coluna
 * alinhada. O `letter-spacing` negativo compensava a largura da mono e saiu. */
.num {
  font-family: var(--f-num);
  font-variant-numeric: tabular-nums;
  font-size: 14px;
  white-space: nowrap;
}
.nulo { color: var(--nulo); }
/* quantidade em destaque - conferencia do romaneio (Mudanca 6): e o numero
 * que se confere fisicamente, e precisa ler-se de longe. */
.num.num-grande { font-size: 16px; font-weight: 600; }
/* saldo/valor negativo. A macro `num_sinal` decide pelo `bruto`, nunca pelo
 * texto pt-BR - depender do formato de exibicao para escolher cor seria
 * parsear a propria saida. */
.num.negativo { color: var(--erro); font-weight: 600; }

/* ============================================================ shell */
.app {
  display: grid;
  grid-template-columns: var(--sidebar-w) 1fr;
  min-height: 100vh;
}
/* A sidebar recolhida (o chevron do topo dos prints). A classe mora no <html>,
 * posta a partir do `localStorage` pelo script curto do <head> de `base.html`
 * - e nao pelo `painel.js`, que e `defer` e rodava depois da primeira pintura:
 * ate 01/10/2026 a barra "piscava" larga e encolhia a cada navegacao. */
:root.sidebar-recolhida .app { grid-template-columns: var(--sidebar-w-recolhida) 1fr; }
:root.sidebar-recolhida .marca-txt,
:root.sidebar-recolhida .item .rotulo,
:root.sidebar-recolhida .menu.rodape,
:root.sidebar-recolhida .versao-no-ar { display: none; }
:root.sidebar-recolhida .marca-linha { justify-content: center; padding: 0 var(--e-2); }
:root.sidebar-recolhida .item { justify-content: center; padding: 13px 0; border-left-width: 0; }
:root.sidebar-recolhida .item.ativo { border-left-width: 0; box-shadow: inset 0 -3px 0 var(--sidebar-acento); }
:root.sidebar-recolhida .recolher svg { transform: rotate(180deg); }

/* A barra como GAVETA, so na lista do Controle Operacional (29/09/2026, dono
 * do produto: "quando abre essa barra lateral os projetos dao uma encolhida
 * horizontalmente e ficam um pouco cortados", e a tela congelava ao abrir e ao
 * fechar). Empurrar a lista tirava 176px dela e obrigava as 3 mil celulas a
 * recalcular a largura das colunas: 60-107ms por clique, medido com a regua -
 * no /rmds, com mais celulas, 15ms. Aqui a coluna da grade fica sempre na
 * largura recolhida e a barra aberta flutua por cima, com sombra: a lista nao
 * muda de tamanho, e nao ha o que recalcular. Desde 01/10/2026 a tela segue a
 * preferencia das outras (chega aberta, por cima, se estava aberta), e fechar
 * aqui grava. A classe e `gaveta-ativa`, posta pelo script do <head>: sem
 * JavaScript nao ha botao para fechar a gaveta, e a barra volta a empurrar a
 * lista como nas outras telas. */
@media (min-width: 901px) {
  :root.gaveta-ativa .app { grid-template-columns: var(--sidebar-w-recolhida) 1fr; }
  :root.gaveta-ativa .app > .painel { grid-column: 2; }
  :root.gaveta-ativa:not(.sidebar-recolhida) .sidebar {
    position: fixed; left: 0; top: 0; width: var(--sidebar-w); z-index: 20;
    box-shadow: 6px 0 24px rgba(8, 30, 16, 0.35);
  }
}

/* ---- sidebar ESCURA (04/09), em duas lajes (05/09) ----
 * O protótipo põe o logotipo numa laje MAIS escura (`--verde-900`) sobre o
 * corpo (`--verde-800`), e é isso que dá à marca o peso que ela tem nos prints.
 * Por isso a `.marca-linha` sangra até a borda com margem negativa: o padding
 * lateral da barra vale para os itens, não para a laje. */
.sidebar {
  background: var(--sidebar-bg);
  border-right: none;
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
  padding: 0 0 var(--e-3);
}

.marca-linha {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--e-2);
  background: var(--sidebar-topo);
  padding: 0 var(--e-4);
  min-height: 92px;
  margin-bottom: var(--e-2);
}
/* O botao de recolher. Nasce `hidden` no HTML e e' revelado por `painel.js`:
 * sem JavaScript ele nao aparece, em vez de aparecer inerte. */
.recolher {
  flex: none; display: grid; place-items: center;
  width: 30px; height: 30px; padding: 0;
  background: rgba(255, 255, 255, 0.08); color: var(--sidebar-ink-fraca);
  border: none; border-radius: var(--r-sm); cursor: pointer;
}
.recolher:hover { background: rgba(255, 255, 255, 0.16); color: var(--sidebar-ink); }
.recolher svg { width: 17px; height: 17px; transition: transform .15s; }

.marca {
  display: flex;
  align-items: center;
  gap: var(--e-2);
  padding: 0;
  text-decoration: none;
  color: var(--sidebar-ink);
}
.marca-ico {
  width: 32px; height: 32px;
  border-radius: var(--r-sm);
  background: var(--sidebar-ink);
  color: var(--sidebar-bg);
  display: grid; place-items: center;
  font-weight: 800; font-size: 19px;
}
.marca-txt { display: flex; flex-direction: column; line-height: 1.05; }
.marca-txt strong { font-size: 32px; font-weight: 900; letter-spacing: -0.03em; }
/* o "!" do logotipo, em verde de acento sobre a laje escura */
.marca-txt strong i { font-style: normal; color: var(--sidebar-acento); }
.marca-txt small {
  font-size: 10px; letter-spacing: 0.16em; color: var(--sidebar-ink-fraca);
  text-transform: uppercase; margin-top: 3px;
}

.menu { display: flex; flex-direction: column; gap: 0; }
.menu.rodape { margin-top: auto; padding-top: var(--e-2); border-top: 1px solid var(--sidebar-linha); }
/* O numero da versao no ar, no canto inferior esquerdo: discreto, alinhado com
 * os itens, sem rotulo - o detalhe (data, alteracao sem commit) fica no title. */
.versao-no-ar {
  /* +4px: o filete de `border-left` dos itens, para alinhar com os icones */
  display: block; padding: var(--e-3) var(--e-4) 0 calc(var(--e-4) + 4px);
  font-size: 11px; line-height: 1; letter-spacing: 0.04em;
  font-variant-numeric: tabular-nums;
  color: var(--sidebar-ink-fraca); opacity: 0.6;
}

/* O item do protótipo: sem pílula arredondada, sangrando de borda a borda, com
 * o estado ativo marcado por uma laje mais escura MAIS o filete de acento. É a
 * leitura dos prints - a barra é uma coluna contínua, não uma lista de botões. */
.item {
  display: flex; align-items: center; gap: 13px;
  padding: 13px var(--e-4);
  border-radius: 0;
  color: var(--sidebar-ink-fraca);
  text-decoration: none;
  font-size: 16px; font-weight: 500;
  border-left: 4px solid transparent;
}
.item .ico { width: 21px; height: 21px; flex-shrink: 0; color: currentColor; opacity: 0.9; }
.item:hover { background: rgba(255, 255, 255, 0.06); color: var(--sidebar-ink); }
.item.ativo {
  background: var(--sidebar-ativo-bg);
  color: var(--sidebar-ink);
  font-weight: 600;
  border-left-color: var(--sidebar-acento);
}
.item.ativo .ico { opacity: 1; }
/* `Usuarios` e os dois do rodape. Esmaecido o bastante para nao convidar o
 * clique, opaco o bastante para o rotulo continuar legivel - ele explica, pelo
 * `title`, por que esta ali sem levar a lugar nenhum. */
.item.inativo { color: rgba(169, 211, 164, 0.5); cursor: default; }
.item.inativo:hover { background: none; color: rgba(169, 211, 164, 0.5); }
.sidebar :focus-visible { outline-color: var(--sidebar-ink); }

/* ---- painel / topbar ---- */
.painel { display: flex; flex-direction: column; min-width: 0; }

.topbar {
  position: sticky; top: 0; z-index: 5;
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  backdrop-filter: blur(8px);
  display: flex; align-items: flex-start; justify-content: space-between; gap: var(--e-5);
  padding: var(--e-5) var(--e-6) var(--e-4);
}
/* 19px e peso 650 faziam do titulo da pagina um rotulo. Nos prints ele e' a
 * primeira coisa que se le, em verde profundo - e o resto da hierarquia se
 * mede a partir dele. */
.topbar-titulo h1 {
  margin: 0; font-size: 29px; font-weight: 800;
  letter-spacing: -0.02em; color: var(--titulo); line-height: 1.15;
}
.topbar-titulo .sub { margin: var(--e-1) 0 0; color: var(--muted); font-size: 15px; }
/* Coluna, nao linha (05/09). Os seis prints poem a pilula de contrato, o sino e
 * o avatar na primeira linha, e os chips da tela (declaracao do portal, data da
 * planilha, exportar) na SEGUNDA, alinhados a direita. Em linha unica os chips
 * de tela competiam com o contrato pela mesma altura e empurravam o titulo. */
.topbar-dir { display: flex; flex-direction: column; align-items: flex-end;
  gap: var(--e-2); flex-shrink: 0; }
.topbar-dir .linha-topo,
.topbar-dir .linha-meta { display: flex; align-items: center; gap: var(--e-2);
  flex-wrap: wrap; justify-content: flex-end; }
.topbar-dir .linha-meta:empty { display: none; }

/* Sino e avatar: presentes nos seis prints, e inertes de propósito - não há
 * notificação nem sessão de usuário neste painel. Ficam como `aria-hidden`,
 * sem `<button>`: um botão anunciaria uma ação que não existe. */
.avatar-topo {
  width: 36px; height: 36px; border-radius: var(--r-pill);
  background: var(--primary-forte); color: var(--on-primary);
  display: grid; place-items: center; flex: none;
}
.avatar-topo svg { width: 22px; height: 22px; }
.sino-topo { color: var(--titulo); display: grid; place-items: center; flex: none; }
.sino-topo svg { width: 21px; height: 21px; }

/* A pilula de contrato do topo. Contornada e nao preenchida: ela declara o
 * escopo da tela, nao um estado - preencher a poria competindo com os chips
 * semanticos, que sao os que querem ser vistos. */
/* Retangular arredondado, nao pilula (05/09): e' a forma nos prints, e ela
 * distingue o chip de ESCOPO (o contrato, a data da fonte) do chip semantico,
 * que continua pilula. */
.chip-contrato {
  display: inline-flex; align-items: center; gap: var(--e-1);
  font-size: 15px; color: var(--ink);
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--r-sm); padding: 8px var(--e-4); white-space: nowrap;
}
.chip-contrato b { font-family: var(--f-num); font-weight: 650; color: var(--titulo); }

.meta-chip {
  display: inline-flex; align-items: center; gap: var(--e-2);
  font-size: 13.5px; color: var(--muted);
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--r-sm); padding: 7px var(--e-3);
}
.meta-chip b { font-family: var(--f-num); font-size: 14px; color: var(--titulo); }

.conteudo { padding: var(--e-2) var(--e-5) 40px; max-width: 1600px; width: 100%; }

/* ============================================================ cartões */
/* QUATRO colunas iguais, nao `auto-fit` (05/09). Com `auto-fit`, uma tela de 4
 * cartoes e outra de 5 davam larguras diferentes ao mesmo componente, e nos
 * prints a fileira e sempre uma grade regular. O `minmax(0, 1fr)` e o que
 * impede um numero longo de estourar a coluna. */
.kpis {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--e-4);
}
.kpis > * { min-height: 118px; }
@media (max-width: 1400px) { .kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: var(--e-5);
  box-shadow: var(--sombra);
}
/* Os prints dao ao KPI um rotulo de 20px/800 - MAIOR que o <h2> de secao - e um
 * numero de 38px/800. Nao e exagero: a fileira de KPI e a unica coisa da tela
 * feita para ser lida em pe, de longe, sem foco. */
.card .rot {
  font-size: 20px; font-weight: 800; letter-spacing: -0.01em;
  color: var(--titulo); line-height: 1.25;
}
.card .big {
  font-family: var(--f-num); font-size: 38px; font-weight: 800;
  letter-spacing: -0.03em; margin-top: var(--e-1); color: var(--ink);
  line-height: 1.1;
}
.card .pe { font-size: 14.5px; color: var(--muted); margin-top: var(--e-1); line-height: 1.35; }
/* A base de toda tile (06/10/2026, macro `tile`): a que nao se sabe sai escrita,
 * esmaecida e em italico - nunca omitida. */
.card .tile-base.desconhecida { font-style: italic; color: var(--nulo); }
/* O numero de destaque quase sempre chega dentro de um `<span class="num">` -
 * e' a macro `num()`/`pct()` que o embrulha, para carregar o `title` com o
 * bruto e o travessao de ausencia. Sem esta linha o `.num` (14px) vence o
 * `.big` (38px) por ser o elemento mais interno, e TODO numero-manchete do
 * painel sai no tamanho de celula de tabela. O `font-size` shorthand nao serve
 * aqui: ele zeraria o `font-variant-numeric`, que e o que alinha a coluna. */
.card .big .num, .rodape-saude b .num, .agenda-cab b .num {
  font-size: inherit; font-weight: inherit; letter-spacing: inherit;
}
/* Centrado, como nos prints. A fileira de KPI e' feita para ser lida de longe e
 * de uma vez - nao e' tabela, e nao ha coluna a alinhar. Tabela continua com o
 * numero a direita, que e o oposto e esta certo la. */
.kpis .card {
  text-align: center;
  display: flex; flex-direction: column; justify-content: center; gap: 2px;
}
/* `width: 100%` porque a margem automatica no eixo cruzado do flex encolhe a
 * caixa ao conteudo, e o medidor virava um risco (regua, 06/10/2026). */
.kpis .card .medidor { margin-left: auto; margin-right: auto; max-width: 220px; width: 100%; }

/* As variantes de KPI do protótipo. Cada uma existe num print, e cada uma diz
 * uma coisa diferente sobre o MESMO número:
 *   destaque/atencao  - há trabalho aqui (borda âmbar, fundo creme)
 *   perigo            - o número em si é ruim (só ele em vermelho)
 *   ok                - o número está bom (borda verde)
 *   solido-vermelho   - a única do painel que inverte o cartão inteiro, e por
 *                       isso vale para UM cartão por tela, nunca dois. */
.card.destaque, .card.kpi-atencao { border-color: #e6c463; border-width: 2px; background: #fdf6dc; }
.card.destaque .rot, .card.kpi-atencao .rot { color: #7a5406; }
.card.destaque .pe, .card.kpi-atencao .pe { color: #8a6508; }
.card.kpi-perigo .big { color: var(--erro); }
/* titulo-vermelho - pinta so o rotulo, e o cartao fica branco. E a variante que
 * o print de Material usa no "Saldo negativo": o `destaque` (fundo ambar, borda
 * de 2px) grita mais alto que o numero que ele anuncia. */
.card.kpi-titulo-vermelho .rot { color: var(--erro); }
/* A irma ambar, para o cartao de Excedente em Material. Ele era vermelho quando
 * se chamava "Saldo negativo"; unificado o nome em 22/09/2026, unificou-se
 * tambem o tom, que na Visao Geral e no Controle Operacional sempre foi aviso -
 * a mesma coisa nao pode ser urgente numa tela e atencao na outra. */
.card.kpi-titulo-aviso .rot { color: var(--aviso); }
.card.kpi-ok { border-color: var(--primary-forte); border-width: 2px; background: #eef7e6; }
.card.kpi-solido {
  background: #a72721; border-color: #8e1f1a; border-width: 2px; color: var(--on-primary);
}
.card.kpi-solido .rot, .card.kpi-solido .big { color: var(--on-primary); }
.card.kpi-solido .pe { color: rgba(255, 255, 255, 0.85); }
.card.kpi-solido .num.nulo { color: rgba(255, 255, 255, 0.6); }
a.card-link { display: block; text-decoration: none; transition: border-color .15s, box-shadow .15s; }
a.card-link:hover { border-color: var(--primary); box-shadow: 0 2px 10px rgba(20, 40, 28, 0.12); }

.secao { margin-top: var(--e-6); }
.secao > h2, .secao-cabeca > h2 {
  font-size: 21px; font-weight: 800; letter-spacing: -0.015em;
  color: var(--titulo); margin: 0 0 var(--e-3);
}
/* Titulo de secao com um link a direita ("Ver todos os BMDs faturados de
 * outubro/2026", 05/10/2026). */
.secao-cabeca {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--e-2) var(--e-4); flex-wrap: wrap;
}
.link-secao { font-size: 14.5px; font-weight: 650; color: var(--primary-forte); text-decoration: none; }
.link-secao:hover { text-decoration: underline; }
/* Icone de informacao ao lado do titulo: carrega no `title` uma explicacao ou
 * reconciliacao (regra 5 - nunca some em silencio) que antes ficava em texto
 * fixo sob o grafico, empurrando os paineis da Visao Geral para alturas
 * diferentes (regua, 22/09/2026). */
.info-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; margin-left: 6px; vertical-align: middle;
  border: 1px solid var(--line-forte); border-radius: 50%;
  font-size: 11px; font-weight: 700; line-height: 1;
  color: var(--muted); cursor: help;
}
.painel-branco {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--r); box-shadow: var(--sombra); overflow: hidden;
}

/* ============================================================ filtros */
.filtros {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--e-4);
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r);
  box-shadow: var(--sombra); padding: var(--e-4); margin-bottom: var(--e-4);
}.filtros .campo { display: flex; flex-direction: column; gap: 5px; }
.filtros .campo label {
  font-size: 12px; font-weight: 650; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--muted);
}
.filtros .campo-check label {
  font-size: 15px; color: var(--ink); text-transform: none; letter-spacing: 0;
  font-weight: 600; display: flex; align-items: center; gap: 8px;
}
/* Cantos de 9px, nao pilula (05/09): o print mostra campos retangulares, e a
 * pilula num <select> de 200px de largura desperdicava 20px de cada ponta. */
/* O campo de data entrou na mesma regra em 09/10/2026: fora dela o navegador o
 * desenhava em monospace de 13px, de canto reto, ao lado de selects em Inter 15px. */
.filtros input[type="text"], .filtros input[type="date"], .filtros select {
  font: inherit; font-size: 15px; color: var(--ink);
  border: 1px solid var(--line); border-radius: 9px;
  padding: 9px 12px; background: var(--panel); min-height: 42px;
}
.filtros input[type="date"] { font-variant-numeric: tabular-nums; }
.filtros input[type="text"] { min-width: 220px; }
.filtros input[type="text"]::placeholder { color: var(--muted-claro); }
.filtros input[type="text"]:focus, .filtros input[type="date"]:focus, .filtros select:focus {
  outline: 2px solid var(--primary); outline-offset: 1px; border-color: var(--primary);
}
.filtros input[type="checkbox"] { width: 18px; height: 18px; accent-color: var(--primary-forte); }
.botao-primario {
  font: inherit; font-size: 16px; font-weight: 700; color: var(--on-primary);
  background: var(--sidebar-bg); border: none; border-radius: 9px;
  padding: 0 26px; min-height: 42px; cursor: pointer;
}
.botao-primario:hover { background: var(--primary); }
.link-limpar { font-size: 14px; color: var(--muted); align-self: center; }
.link-limpar:hover { color: var(--ink-medio); text-decoration: underline; }

/* ============================================================ tabelas */
.tabela-wrap { overflow-x: auto; overflow-y: auto; max-height: 70vh; border-radius: var(--r); }
/* Sem `overflow` aqui, de proposito. `overflow` na propria tabela faz dela um
 * container de rolagem que nunca rola, e o `position: sticky` do <thead>
 * abaixo passa a grudar NELE - ou seja, nao gruda em lugar nenhum. Quem
 * arredonda o canto e a .tabela-wrap, que ja tem overflow + border-radius. */
.tabela {
  width: 100%; border-collapse: collapse;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--r); box-shadow: var(--sombra);
}
/* Cabecalho em CAIXA NORMAL e verde profundo (05/09), nao em versalete cinza de
 * 10,5px. Nos prints o <th> le-se como titulo de coluna, no mesmo tamanho do
 * dado; o versalete minusculo vinha do sistema anterior e sumia numa tela de 15
 * colunas - que e justamente onde o rotulo mais importa. */
.tabela th {
  font-size: 14px; font-weight: 700; letter-spacing: 0;
  color: var(--titulo); text-align: left; padding: var(--e-2) var(--e-3);
  border-bottom: 1px solid var(--line); background: var(--panel-2);
  white-space: nowrap;
  position: sticky; top: 0; z-index: 1;
}
.tabela th.n, .tabela td.n { text-align: right; }
.tabela td {
  padding: 0 var(--e-3); height: var(--linha-h);
  border-bottom: 1px solid var(--line-2); vertical-align: middle;
}
.tabela tbody tr:last-child td { border-bottom: none; }
.tabela tbody tr:hover { background: var(--panel-2); }
.tabela a { color: var(--primary); text-decoration: underline; text-underline-offset: 2px;
  font-weight: 600; }
.tabela a:hover { color: var(--titulo); }
.tabela .cod { font-family: var(--f-num); font-size: 14px; }
/* Chave composta sem espaco (`DEBITO:1647386:I250506603`) e uma palavra so, e
 * sem ponto de quebra ela alargava a tabela de Documentos em 38px - medido pela
 * regua em 10/09/2026. Quebra em qualquer ponto so quando nao cabe. */
.tabela td.chaves { overflow-wrap: anywhere; }
.tabela .desc { color: var(--ink-medio); }

tr.orfa td { color: var(--muted); font-style: italic; background: var(--panel-2); }

.rodape-nota {
  font-size: 13px; color: var(--muted); margin-top: 10px; line-height: 1.55;
}
.rodape-nota em { color: var(--ink-medio); font-style: normal; font-weight: 600; }

/* linha de grupo (Detalhe/Material) */
.grupo-linha td {
  background: var(--panel-2); font-weight: 600; font-size: 14px; color: var(--ink-medio);
}
/* o tamanho do grupo de etapa (Controle Operacional, 28/09/2026): legenda, nao titulo */
.grupo-linha .grupo-conta { font-weight: 400; color: var(--muted); }

/* ================================================ acordeão de obra (Obras)
 * Estrutura das telas de Materiais e PDE/PLV do portal: sigla → projeto →
 * tabela. Feito com <details>/<summary> nativos: o painel não tem JavaScript,
 * e a única alternativa sem ele seria não agrupar. */
.grupo-obra {
  margin-top: 14px;
  border-radius: var(--r);
  border: 1px solid var(--line);
  background: var(--panel);
  box-shadow: var(--sombra);
  overflow: hidden;
}
/* Variante de AGRUPAMENTO da `.faixa-summary`: so a cor. A mecanica do chevron,
 * o `list-style: none` e o marcador nativo moram na base - eram tres copias
 * antes de RMDs precisar da quarta.
 *
 * Era escura (`--faixa`) ate 04/09. Clareou junto com o <thead>, e pela mesma
 * razao: com a sidebar assumindo o verde profundo, Material empilhava sidebar +
 * faixa de obra + faixa de projeto + cabecalho de tabela, quatro lajes escuras
 * numa tela so. O filete verde a esquerda e o que sobrou da laje - basta para
 * marcar "isto e um cabecalho de grupo", sem pesar. */
.obra-faixa {
  background: var(--panel-2); color: var(--ink);
  border-bottom: 1px solid var(--line);
  box-shadow: inset 3px 0 0 var(--primary);
}
.obra-faixa:hover { background: var(--primary-suave); }
.obra-faixa:focus-visible { outline: 2px solid var(--primary); outline-offset: -3px; }
details[open] > .obra-faixa { border-bottom-color: var(--line-forte); }
.obra-sigla {
  font-family: var(--f-num); font-size: 13.5px; font-weight: 600;
  letter-spacing: -0.01em; white-space: nowrap;
}
.obra-chips { display: flex; flex-wrap: wrap; gap: 6px; flex: 1; }
.obra-base { flex: none; width: 190px; }
.obra-base .pct-mini { color: var(--muted); }
.obra-base .trilho { background: var(--panel); border: 1px solid var(--line); }

/* pilula sobre a faixa de grupo - o equivalente das do portal. Era branca
 * translucida, para a laje escura; com a faixa clara passa aos tons neutros. */
.tag {
  display: inline-flex; align-items: center;
  padding: 2px var(--e-2); border-radius: var(--r-pill);
  background: var(--panel); border: 1px solid var(--line); color: var(--ink-medio);
  font-size: 12.5px; font-weight: 600; white-space: nowrap;
}
.tag.t-erro   { background: var(--erro-bg);   border-color: transparent; color: var(--erro); }
.tag.t-aviso  { background: var(--aviso-bg);  border-color: transparent; color: var(--aviso); }

.barra-acoes {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 16px; margin-top: 18px;
}

/* ============================================ tabela densa com topo escuro */
.tabela.densa td { height: var(--linha-h-densa); padding: 0 var(--e-3); font-size: 13.5px; }
.tabela.densa th { padding: 6px var(--e-3); font-size: 13px; }
.tabela.densa .num, .tabela.densa .cod { font-size: 13px; }
.grupo-obra .tabela { border: none; border-radius: 0; box-shadow: none; }
.grupo-obra .tabela-wrap { border-radius: 0; max-height: none; }

/* O nivel de DENTRO do acordeao de Material (`.grupo-projeto`) saiu em
 * 08/09/2026: Material achatou para um nivel e passou a `.cascata`, mais abaixo.
 * `.grupo-obra` e `.obra-faixa` ficam - Programacao e a conferencia de romaneio
 * tambem as usam. */

.tabela thead.escuro th {
  background: var(--panel-2); color: var(--muted);
  border-bottom: 1px solid var(--line-forte);
}
/* a linha de agrupamento do cabeçalho separa os blocos por TINTA, nunca por
 * régua vertical - o Design.md proíbe linhas verticais em tabela. */
.tabela thead.escuro tr.grupo-col th {
  background: var(--primary-suave); color: var(--titulo);
  border-bottom: 1px solid var(--line);
  font-size: 13.5px; font-weight: 800; text-align: center;
  height: 28px; padding: 0 11px;
}
.tabela thead.escuro tr.grupo-col th.col-projeto { text-align: left; }
/* O deslocamento do sticky tem de casar com a altura da linha de cima. Era
 * `27px` cravado, e so batia enquanto TODA tabela de dois niveis fosse `.densa`;
 * a vista essencial de Material nao e. Por isso a linha de agrupamento passou a
 * ter `height` fixa acima - o numero deixou de depender do padding herdado.
 *
 * E o seletor era `tr:last-child`, que so acertava porque toda tabela de dois
 * niveis tinha exatamente duas linhas. Na vista essencial ha UMA, e ali
 * `last-child` e a primeira - que ganharia 26px de deslocamento e descolaria do
 * topo. `nth-child(2)` diz a posicao, que e o que a regra sempre quis dizer. */
.tabela thead.escuro tr:nth-child(2) th { top: 28px; }

/* o projeto não some no scroll horizontal */
.tabela .col-projeto { position: sticky; left: 0; z-index: 2; }
.tabela thead .col-projeto { z-index: 3; }
.tabela tbody .col-projeto { background: var(--panel); }
.tabela tbody tr:hover .col-projeto { background: var(--panel-2); }
.tabela td.cod .sub {
  display: block; font-size: 12px; color: var(--muted); font-weight: 400;
  margin-top: -3px;
}
/* a descricao de material sob o codigo. `.texto-curto` nao serve aqui: ela e'
 * `inline-block` e brigaria com o `display: block` da `.sub`. */
.tabela td.cod .sub.corta {
  max-width: 340px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-family: var(--f-texto);
}
.tabela td.pilha { display: table-cell; white-space: nowrap; }
/* a segunda linha de uma celula que nao e codigo: o 'N de M materiais' e o estagio do processo em /faltantes#sem-orcamento (25/09/2026). */
.tabela td .nota-linha, .lista-citacoes .nota-linha { display: block; font-size: 12px; color: var(--muted); margin-top: 2px; }
.tabela td.pilha .chip { margin-right: 4px; }
.tabela td.diverge { color: var(--erro); font-weight: 600; }
.tabela td.venceu .num { color: var(--erro); font-weight: 600; }

/* tinta de criticidade na linha inteira, como na aba Prazo & Atraso do portal */
/* `:not(.cel-prazo)` (29/09/2026): a celula de prazo tem a cor dela, e o
 * `:hover` da linha, mais especifico que `td.cel-prazo.p-vencido`, a pintava de
 * claro por baixo do texto branco - o quadrado vermelho sumia sob o mouse. */
.tabela tbody tr.vencido td:not(.cel-prazo):not(.prog-passou) { background: color-mix(in srgb, var(--erro-bg) 40%, var(--panel)); }
.tabela tbody tr.critico td:not(.cel-prazo):not(.prog-passou) { background: color-mix(in srgb, var(--aviso-bg) 45%, var(--panel)); }
.tabela tbody tr.vencido:hover td:not(.cel-prazo):not(.prog-passou), .tabela tbody tr.critico:hover td:not(.cel-prazo):not(.prog-passou) {
  background: var(--panel-2);
}

/* ================================================= barra de progresso em célula */
.barra-inline { display: inline-flex; align-items: center; gap: 8px; width: 100%; }
.barra-inline .trilho {
  flex: 1; min-width: 42px; height: 5px; border-radius: 3px;
  background: var(--panel-2); overflow: hidden;
}
.barra-inline .fill { display: block; height: 100%; border-radius: 3px; }
.barra-inline .fill.b-alto  { background: var(--ok); }
.barra-inline .fill.b-medio { background: var(--aviso); }
.barra-inline .fill.b-baixo { background: var(--erro); }
.barra-inline .pct-mini { font-size: 13px; min-width: 46px; text-align: right; }

/* `kpis-compacto` comprimia o cartao a `13px 15px` com o numero em 22px, e e'
 * o modificador que Material, RMDs, Documentos, Programacao, Operacional,
 * Projeto, Romaneio e Faltantes usam - ou seja, quase todo o painel lia a
 * variante apertada, e a `.card` folgada quase nunca aparecia. Em 04/09 a
 * diferenca entre os dois virou pequena de proposito: o compacto continua
 * existindo (uma fileira de 4 cartoes nao pode empurrar a tabela para fora da
 * primeira tela), mas deixou de ser aperto. */
.kpis.kpis-compacto .card { padding: var(--e-3) var(--e-4); }
.kpis.kpis-compacto .card .rot { font-size: 17px; }
.kpis.kpis-compacto .card .big { font-size: 32px; margin-top: var(--e-1); }
.kpis.kpis-compacto .card .pe { font-size: 13px; margin-top: var(--e-1); }

/* ================================================== seletor de vista de coluna
 * Material tem 13 colunas e o item de RMD tem 10, e as duas telas eram as mais
 * densas do painel. A saida NAO foi esconder campo: e' dar dois niveis a mesma
 * tabela, com a vista essencial no que se le todo dia e um clique para o resto.
 * Links com querystring (`?colunas=`), montados com `url_com` - o mesmo gesto
 * do `?vista=` do Controle Operacional, que hoje sai como texto corrido em
 * `.barra-acoes` e e o proximo candidato a adotar este componente.
 *
 * Nao e a `.abas`: em RMDs as abas ja significam OUTRA coisa (a natureza da
 * devolucao, que troca o universo de linhas). Duas listas de links com a mesma
 * aparencia e significados diferentes na mesma tela seria pior que uma classe a
 * mais - por isso a vista e pilula agrupada, e a aba continua sublinhada. */
.vistas {
  display: inline-flex; align-items: center; gap: var(--e-1);
  background: var(--panel-2); border: 1px solid var(--line);
  border-radius: var(--r-pill); padding: 3px;
}
.vistas > .rot {
  font-size: 12px; font-weight: 650; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--muted); padding: 0 var(--e-2) 0 var(--e-3);
}
.vistas a, .vistas b {
  padding: 5px var(--e-3); border-radius: var(--r-pill);
  font-size: 14px; font-weight: 600; text-decoration: none; white-space: nowrap;
}
.vistas a { color: var(--muted); }
.vistas a:hover { background: var(--panel); color: var(--ink-medio); }
.vistas b {
  background: var(--primary); color: var(--on-primary);
  box-shadow: 0 1px 2px rgba(20, 40, 28, 0.18);
}

/* ============================================ "como ler esta tela", recolhido
 * Material tinha TRES paragrafos de prosa densa no rodape e RMDs tinha dois
 * mais um aviso - texto que explica regra de leitura (a barra conta linhas, os
 * agregados vem do filtro inteiro, travessao nao e zero) e que precisa
 * continuar existindo, porque e' o que impede o numero de ser mal lido. Mas
 * aberto por padrao ele ocupava meia tela abaixo da tabela.
 *
 * `<details>` nativo, fechado. O texto nao se perde - deixa de competir com o
 * dado pela mesma altura de tela. Na impressao a regra geral esconde todo
 * `<summary>`, e aqui isso esta certo: o corpo continua sendo impresso. */
.como-ler { margin-top: var(--e-5); }
.como-ler > summary {
  display: inline-flex; align-items: center; gap: var(--e-2);
  cursor: pointer; list-style: none;
  font-size: 12.5px; font-weight: 650; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--muted); padding: var(--e-2) 0;
}
.como-ler > summary::-webkit-details-marker { display: none; }
.como-ler > summary::after {
  content: ""; width: 0; height: 0;
  border-left: 5px solid currentColor;
  border-top: 4px solid transparent; border-bottom: 4px solid transparent;
  transition: transform .15s;
}
.como-ler[open] > summary::after { transform: rotate(90deg); }
.como-ler > summary:hover { color: var(--ink-medio); }
.como-ler .corpo {
  border-left: 2px solid var(--line);
  padding: var(--e-1) 0 var(--e-1) var(--e-4);
}
.como-ler .rodape-nota:first-child { margin-top: 0; }

/* ============================================================ chips */
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 12px; border-radius: var(--r-pill);
  font-size: 13px; font-weight: 600; line-height: 1.5; white-space: nowrap;
}
.chip.ok      { background: var(--ok-bg);     color: var(--ok); }
.chip.aviso   { background: var(--aviso-bg);  color: var(--aviso); }
.chip.erro    { background: var(--erro-bg);   color: var(--erro); }
.chip.neutro  { background: var(--neutro-bg); color: var(--neutro); }
.chip.info    { background: var(--info-bg);   color: var(--info); }
.chip.indigo  { background: var(--indigo-bg); color: var(--indigo); }
/* badge de RMD/negativo: contorno vermelho, como no print */
.chip.contorno-erro {
  background: transparent; color: var(--erro);
  border: 1px solid color-mix(in srgb, var(--erro) 45%, transparent);
}
.chip.contorno-aviso {
  background: transparent; color: var(--aviso);
  border: 1px solid color-mix(in srgb, var(--aviso) 45%, transparent);
}
.chip.zero { background: transparent; color: var(--muted-claro); font-family: var(--f-num); }
/* Dentro da celula do orcado, ao lado do numero: nomeia a MDM complementar que
   fez aquele orcado crescer. Coluna propria empurraria /pep, /material e
   /projeto de uma vez, por um caso que e de 204 escopos. */
.chip.chip-orcado { margin-left: 6px; font-size: 10px; padding: 1px 5px; vertical-align: 1px; }

/* ============================================================ documentos que faltam
   O resumo de /faltantes na Visao Geral (13/10/2026), no lugar do *Material por
   situacao*: uma linha por documento a pedir, o numero grande a esquerda e o
   que ele destrava embaixo do nome. Duas colunas onde cabe, para as oito
   linhas lerem de uma olhada; o zero fica, apagado. */
.faltam-lista { list-style: none; margin: 0; padding: 0; display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px var(--e-4); }
@media (max-width: 1100px) { .faltam-lista { grid-template-columns: minmax(0, 1fr); } }
.faltam-linha { display: flex; align-items: center; gap: var(--e-3); padding: 8px 12px;
  border-radius: var(--r); border: 1px solid var(--line); border-left: 4px solid var(--aviso);
  background: var(--panel); color: var(--ink); text-decoration: none; min-width: 0; }
.faltam-linha:hover { background: var(--panel-2); }
.faltam-linha:hover .faltam-doc { text-decoration: underline; }
.faltam-qt { font-family: var(--f-num); font-size: 20px; font-weight: 800; min-width: 2.5ch;
  text-align: right; flex-shrink: 0; color: var(--ink); }
.faltam-doc { font-weight: 650; min-width: 0; overflow-wrap: anywhere; }
.faltam-detalhe { display: block; font-weight: 400; font-size: 12.5px; color: var(--muted); }
.faltam-linha.zero { border-left-color: var(--line); color: var(--muted); }
.faltam-linha.zero .faltam-qt { color: var(--muted-claro); }
.faltam-pe { margin: var(--e-3) 0 0; font-size: 13px; }

/* *Ultimas medicoes* em 1024px rolava de lado (regua, 13/10/2026: 829px de
 * tabela numa caixa de 728, e 829 em 805 a 1101px). Nove colunas cabem com o
 * respiro e a letra menores; acima de 1200px nada muda. */
@media (max-width: 1200px) {
  .tabela.ultimas-medicoes th, .tabela.ultimas-medicoes td { padding-left: 6px; padding-right: 6px; font-size: 13px; }
  .tabela.ultimas-medicoes .chip { padding-left: 6px; padding-right: 6px; }
}

/* medidor de cobertura dentro do card */
.medidor { height: 6px; background: var(--panel-2); border: 1px solid var(--line);
  border-radius: var(--r-pill); overflow: hidden; margin-top: 10px; }
.medidor > span { display: block; height: 100%; background: var(--primary-forte); }

/* ============================================================ dashboard (Visao Geral) */
.kpi-hero { padding: 18px 20px; }
/* `.kpis .card` centraliza o bloco (rot+big+pe) na vertical - certo quando os
 * quatro cartoes tem o mesmo tanto de texto, errado aqui: o `.pe` de baixo tem
 * tamanho diferente em cada um ("autorizada no AES e ainda nao medida..." e
 * bem mais longo que "so etapas em aberto..."), entao o bloco inteiro tinha
 * altura diferente por cartao e centralizar jogava o `.big` para uma linha
 * diferente em cada um - so alinhar o `.rot` (abaixo) nao bastava (regua,
 * 22/09/2026, duas rodadas: "os numeros nao estao alinhados na mesma altura" e
 * depois "ainda nao estao na mesma faixa"). Ancorado no topo, o `.big` cai
 * sempre na mesma linha - o que sobra de `.pe` mais curto vira espaco embaixo,
 * nunca deslocamento em cima. */
.kpis .kpi-hero { justify-content: flex-start; }
/* Coluna, nao linha: o selo "mes em andamento" e a SEGUNDA LINHA do rotulo nos
 * prints (o `kpi__rotulo-2` do protótipo), nao um adorno ao lado dele. Ao lado,
 * ele empurrava "US medida no mês" para duas linhas e desalinhava a fileira.
 * `min-height` reserva a altura do selo mesmo nos dois cartoes que nao o tem
 * ("US aguardando medicao", "Saldo a medir"), para o `.big` comecar na mesma
 * linha com ou sem selo. */
.kpi-hero .rot { display: flex; flex-direction: column; align-items: center; gap: var(--e-1); min-height: 48px; justify-content: flex-start; }
/* Tamanho unico para os quatro herois: dinheiro de sete digitos ("R$
 * 1.237.700,24") estourava a 38px (regua, 11/09/2026), e o remedio de entao -
 * encolher so o numero comprido - deixava os quatro em dois tamanhos
 * diferentes lado a lado, que e' o que a regua seguinte cobrou (22/09/2026).
 * 31px cabe o mais longo e os outros tres acompanham, sempre. */
.kpi-hero .big { font-size: 31px; margin-top: var(--e-1); }
.selo {
  display: inline-flex; align-items: center; font-size: 12px; font-weight: 650;
  letter-spacing: 0.04em; text-transform: uppercase; color: var(--aviso);
  background: var(--aviso-bg); border-radius: var(--r-pill); padding: 2px 9px;
}
.tendencia { font-size: 13.5px; margin-top: 6px; }
.tendencia.alta { color: var(--ok); }
.tendencia.baixa { color: var(--erro); }

.linha-dashboard {
  display: grid; grid-template-columns: 2fr 1fr; gap: 16px; align-items: stretch;
  margin-top: var(--e-4);
}
.linha-dashboard > .secao { margin-top: 0; }
/* `par`: a linha unica da Visao Geral, com a pizza de um lado e a coluna do
 * grafico mensal + Atencao do outro. Era 1fr/1fr ate 22/09/2026 - a regua
 * pediu uma pizza maior com a legenda sempre ao lado (nunca embaixo), e 3fr/2fr
 * da a esse lado a largura que falta, sobrando para a outra coluna porque o
 * grafico mensal apertou o espaco entre as barras para caber 6. Em 05/10/2026,
 * com a linha de variacao, o grafico mensal ganhou largura (4fr/5fr, e 5fr/8fr
 * abaixo de 1400px): cada barra precisa de ~92px para o valor exato
 * ("R$ 1.759.095,84") nao encavalar no vizinho de altura parecida.
 *
 * 13/10/2026: meia linha para cada lado. A curva desceu para baixo da pizza, as
 * duas colunas passaram a ter dois cartoes cada, e a de 4fr ficava com a legenda
 * da pizza empilhada - a mais alta das duas, abrindo um vao no faturado ao lado. */
.linha-dashboard.par { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
/* `.par` tem duas classes e venceria uma regra de uma so: sem cita-la aqui, o
 * empilhado nunca chega e a linha fica com duas colunas espremidas - foi o que
 * a regua mostrou em 1100px (a legenda da pizza caindo para baixo do donut). */
@media (max-width: 1100px) {
  .linha-dashboard, .linha-dashboard.par { grid-template-columns: 1fr; }
}
/* Desde 13/10/2026 os dois lados da linha sao `.coluna-dashboard`: a pizza com
 * a curva embaixo, e o faturado por mes com a Atencao embaixo. A pizza e o
 * primeiro cartao do lado dela, e por isso e ela que cresce ate a linha fechar
 * nivelada - a regra que esticava o `.secao` solto da pizza (22/09/2026, "nao
 * quero o espaco vazio ali") virou a regra geral da coluna, logo abaixo. */

/* Coluna do dashboard: empilha dois cartoes onde o outro lado tem um so. Quem
 * absorve a folga e o PRIMEIRO cartao - o grafico cresce ate a linha fechar
 * nivelada nas duas colunas. Empurrar o ultimo para baixo (`margin-top: auto`)
 * tambem nivelava, mas abria um vao de branco no meio da coluna, que e
 * exatamente a assimetria que esta linha veio desfazer. */
.coluna-dashboard { display: flex; flex-direction: column; gap: var(--e-4); }
.coluna-dashboard > .secao { margin-top: 0; }
.coluna-dashboard > .secao:first-child { flex: 1; display: flex; flex-direction: column; }
/* `justify-content:center`: o card ainda estica ate fechar a linha com a
 * pizza (`flex:1`), mas o grafico de dentro parou de esticar junto - virou
 * bastante alto com a pizza grande, e barra fina e alta com numero minusculo
 * "de espremido" (regua, 22/09/2026). O card agora centraliza um grafico de
 * altura fixa, sobrando espaco em cima/embaixo em vez de esticar a barra. */
.coluna-dashboard > .secao:first-child > .painel-branco {
  flex: 1; display: flex; flex-direction: column; justify-content: center;
}
.coluna-dashboard .chart-mensal { height: 240px; flex: none; }

/* pizza de US orcada por situacao. O SVG desenha a fatia como arco de um
 * circulo unico: raio 15.9155 (circunferencia 100), stroke-width 31.831 = 2r,
 * o que fecha o furo e faz do anel uma pizza cheia. As cores sao `stroke` aqui
 * e `background` na legenda - as duas listas usam as MESMAS classes de cor,
 * para nunca divergirem. */
.pizza-bloco { display: flex; align-items: center; gap: 32px; flex-wrap: wrap; justify-content: center; }
/* 400px (era 220px, depois 260px, depois 320px): o card da pizza passou a
 * esticar ate a altura da coluna do grafico+Atencao ao lado (`.linha-dashboard
 * .par > .secao:first-child`), e o disco cresceu ate preencher esse espaco -
 * 320px ainda deixava um vao branco embaixo da legenda (regua, 22/09/2026:
 * "ficou um quadrado branco enorme"). 320px desde 05/10/2026: a linha deu
 * largura ao grafico mensal, e o gestor pediu a pizza "um pouco" menor. */
.pizza { width: 320px; height: 320px; flex-shrink: 0; }
/* 13/10/2026: com a curva embaixo dela, a pizza divide a coluna e nao precisa
 * mais esticar ate a altura do grafico mensal + Atencao. Menor, a legenda volta
 * para o lado do disco na coluna de meia linha - empilhada, ela fazia a coluna
 * da esquerda alta e abria um vao no card do faturado ao lado. */
.coluna-dashboard .pizza-bloco { gap: 24px; }
.coluna-dashboard .pizza { width: 200px; height: 200px; }
.coluna-dashboard .pizza-legenda { min-width: 220px; font-size: 14px; }
.coluna-dashboard .pizza-legenda li { padding: 6px 0; gap: 10px; }
/* ROSCA, nao pizza cheia (05/09). `stroke-width: 31.831` e 2r, e fechava o furo
 * - era a leitura do print anterior. O print novo traz um anel, e o anel e' o
 * melhor grafico dos dois aqui: o furo dá onde pousar o olho, e a espessura
 * constante compara arcos sem a distorcao de area que a fatia cheia introduz. */
.pizza circle { fill: none; stroke-width: 10; }
.pizza .pizza-vazia { stroke: var(--panel-2); }
.pizza .pizza-fatia { stroke-linecap: butt; }
.pizza .pizza-fatia.ok           { stroke: var(--primary-forte); }
.pizza .pizza-fatia.info         { stroke: var(--info); }
.pizza .pizza-fatia.aviso        { stroke: var(--aviso); }
.pizza .pizza-fatia.indigo       { stroke: var(--indigo); }
.pizza .pizza-fatia.neutro       { stroke: var(--muted-claro); }
.pizza .pizza-fatia.neutro-forte { stroke: var(--muted); }

.pizza-legenda {
  list-style: none; margin: 0; padding: 0; flex: 1; min-width: 260px;
  font-size: 15px; color: var(--ink-medio);
}
.pizza-legenda li {
  display: grid; grid-template-columns: 26px 1fr auto auto;
  align-items: center; gap: 12px;
  padding: 9px 0; border-bottom: 1px solid var(--line);
}
.pizza-legenda li:last-child { border-bottom: 0; }
/* Badge redondo colorido com o icone da etapa dentro, no lugar da bolinha lisa
 * - mesma cor de sempre (`.funil-seg.*`), so com forma reconhecivel. */
.pizza-legenda .legenda-icone {
  width: 26px; height: 26px; border-radius: 50%; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
}
.pizza-legenda .val { color: var(--ink); font-weight: 650; }
.pizza-legenda .pc { min-width: 54px; text-align: right; color: var(--muted); }

/* pastilhas de cor da legenda - compartilhadas com qualquer outra serie */
.funil-seg.ok       { background: var(--primary-forte); }
.funil-seg.info     { background: var(--info); }
.funil-seg.aviso    { background: var(--aviso); }
.funil-seg.indigo   { background: var(--indigo); }
.funil-seg.neutro   { background: var(--muted-claro); }
.funil-seg.neutro-forte { background: var(--muted); }

/* alertas */
.alertas-lista { display: flex; flex-direction: column; }
.alerta-item {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 10px 0; border-bottom: 1px solid var(--line);
  text-decoration: none; color: inherit;
}
.alerta-item:last-child { border-bottom: none; }
.alerta-item:hover .rotulo { text-decoration: underline; }
.alerta-item .rotulo { font-size: 14px; color: var(--ink-medio); }
.alerta-item .badge {
  font-family: var(--f-num); font-size: 13.5px; font-weight: 650; color: var(--on-primary);
  background: var(--erro); border-radius: var(--r-pill); min-width: 22px; text-align: center;
  padding: 2px 7px; flex-shrink: 0;
}
.alerta-item .badge.zero { background: var(--neutro-bg); color: var(--muted); }

/* Linhas de alerta da Visão Geral. Solidas e coloridas desde 05/09 (liam "de
 * longe" melhor que texto+contador) - eram uma fileira horizontal ate
 * 22/09/2026, quando a régua pediu ícone e leitura de cima para baixo, como a
 * referência de estilo trazida pelo usuário. A cor solida por linha inteira
 * fica, que era o ganho original; só a orientação virou coluna. Cada uma é
 * <a>, para o alerta levar onde ele se resolve. */
.alertas-lista-cor { display: flex; flex-direction: column; gap: 6px; padding: var(--e-3); }
.alerta-linha {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 14px; border-radius: var(--r-md);
  font-size: 14px; font-weight: 650; line-height: 1.3; text-decoration: none;
}
.alerta-linha:hover { filter: brightness(1.08); text-decoration: underline; }
.alerta-icone { display: inline-flex; flex-shrink: 0; }
.alerta-rot { flex: 1; }
.alerta-qt { font-family: var(--f-num); font-size: 15px; font-weight: 800; flex-shrink: 0; }
.alerta-linha.erro   { background: var(--erro);  color: var(--on-primary); }
.alerta-linha.aviso  { background: #e8891a;      color: #3d2102; }
.alerta-linha.escuro { background: #23302a;      color: var(--on-primary); }
.alerta-linha.ok     { background: var(--ok);    color: var(--on-primary); }
/* zero mantém a linha e perde a cor - ver o comentário em `visao_geral.html` */
.alerta-linha.zero {
  background: var(--panel-2); color: var(--muted); border: 1px solid var(--line);
  font-weight: 600;
}

/* grafico mensal (barras verticais). Largura das barras ajustada em
 * 22/09/2026 para caber ate 6 (janela rolante), sem depender de altura extra
 * para compensar - a altura do grafico e fixa (`.coluna-dashboard .chart-
 * mensal`), entao a largura e' o unico grau de liberdade aqui. */
/* A linha de variacao (05/10/2026) liga o topo das barras: a `.trilho-mes` de cada
 * mes e a caixa onde a altura da coluna e exata, e o svg cobre as mesmas
 * caixas - mesmo topo (`--topo`), mesmo pe (`--rotulos`) e barras de largura
 * igual, sem `gap` (o respiro e o padding da barra), para o centro da barra
 * N cair em (N + 0,5) / total da largura, que e onde o svg poe o ponto. */
.chart-mensal {
  --topo: 22px; --rotulos: 36px;
  position: relative; display: flex; align-items: flex-end; height: 150px;
  padding: var(--topo) 6px 0;
}
.barra-mes { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column;
  align-items: center; height: 100%; padding: 0 5px; }
.barra-mes .trilho-mes { flex: none; width: 100%; height: calc(100% - var(--rotulos));
  display: flex; align-items: flex-end; justify-content: center; }
.barra-mes .coluna {
  width: 100%; max-width: 32px; background: var(--primary-forte); border-radius: 4px 4px 0 0;
  min-height: 2px; position: relative;
}
.linha-variacao {
  position: absolute; left: 6px; right: 6px; top: var(--topo);
  height: calc(100% - var(--topo) - var(--rotulos)); width: calc(100% - 12px);
  overflow: visible; pointer-events: none; z-index: 1;
}
.linha-variacao line { stroke: var(--ink-medio); stroke-width: 2; stroke-linecap: round; }
.linha-variacao line.ressalva { stroke: var(--muted); stroke-dasharray: 4 4; }
.barra-mes .coluna.com-ponto::after {
  content: ""; position: absolute; top: -4px; left: 50%; width: 8px; height: 8px;
  margin-left: -4px; border-radius: 50%; background: var(--panel);
  border: 2px solid var(--ink-medio); box-sizing: border-box; z-index: 2;
}
.barra-mes .variacao { font-family: var(--f-num); font-size: 11px; line-height: 14px;
  height: 14px; white-space: nowrap; color: var(--muted); }
.barra-mes .variacao.sobe { color: var(--ok); }
.barra-mes .variacao.desce { color: var(--erro); }
.barra-mes .variacao.ressalva { color: var(--muted); }
.barra-mes.parcial .coluna {
  background: repeating-linear-gradient(135deg, var(--primary-suave), var(--primary-suave) 4px,
    var(--panel-2) 4px, var(--panel-2) 8px);
  border: 1px dashed var(--primary-forte);
}
/* Mes futuro: nunca tem `pct_altura` (sem nota, sem numero para desenhar), so
 * um traco baixo e pontilhado que marca o lugar no eixo sem fingir ser dado -
 * a diferenca de `.parcial` (mes corrente, com nota parcial de verdade). */
.barra-mes.futuro .coluna {
  height: 6% !important; max-width: 20px;
  background: transparent; border: 1px dashed var(--line-forte);
}
/* `nowrap`: com 6 barras a coluna apertou e "R$ 1.737.732,13" quebrava em
 * duas linhas (regua, 22/09/2026) - o numero flutua sobre o gap das barras
 * vizinhas, que sao mais estreitas que o texto de proposito. 11px (nao 10px):
 * a altura fixa do grafico (200px) deixou de comprimir tudo, e o numero
 * minusculo lia como "espremido" mesmo com espaco de sobra (regua, mesma
 * data, segunda rodada). */
.barra-mes .valor {
  font-family: var(--f-num); font-size: 11px; color: var(--ink-medio);
  white-space: nowrap;
  /* Sobre o topo da coluna, e acima da linha: o fundo do painel apaga o
   * trecho da linha que cruzaria o numero. */
  position: absolute; bottom: calc(100% + 7px); left: 50%; transform: translateX(-50%);
  background: var(--panel); padding: 0 3px; border-radius: 3px; z-index: 3;
  line-height: 14px;
}
.barra-mes.futuro .valor { color: var(--muted); }
/* A vizinha de altura parecida (13/10/2026, `api/json._producao_mensal_json`):
 * o rotulo sobe uma linha para nao encavalar. O `--topo` da coluna da Visao
 * Geral cresce na mesma medida, para o rotulo da barra mais alta caber. */
.barra-mes .valor.sobe { bottom: calc(100% + 23px); }
.coluna-dashboard .chart-mensal { --topo: 38px; }
/* A barra com nota e link para os BMDs do mes (05/10/2026). */
a.barra-mes { text-decoration: none; border-radius: var(--r-sm); }
a.barra-mes:hover { background: var(--panel-2); }
a.barra-mes:hover .mes { color: var(--primary-forte); }
.barra-mes .mes { font-size: 12px; line-height: 16px; margin-top: 6px; color: var(--muted);
  text-transform: uppercase; }

/* A curva acumulada (06/10/2026), sob as barras e no mesmo eixo: o mesmo
 * respiro lateral de 6px e um mes por coluna de largura igual, para o ponto do
 * mes N cair embaixo da barra do mes N. As tres cores sao tokens semanticos -
 * autorizado azul (o contrato), medido verde (o servico, a cor das barras) e
 * faturado ambar (a nota). */
.curva-legenda { list-style: none; margin: 0 0 var(--e-3); padding: 0; display: flex;
  flex-wrap: wrap; gap: var(--e-2) var(--e-5); font-size: 12px; color: var(--muted); }
.curva-legenda li { display: flex; align-items: center; gap: 6px; }
.curva-legenda strong { font-family: var(--f-num); font-weight: 600; color: var(--ink); }
.curva-chave { width: 14px; height: 3px; border-radius: 2px; background: currentColor; }
.curva-legenda .curva-autorizado .curva-chave { color: var(--info); }
.curva-legenda .curva-medido .curva-chave { color: var(--primary-forte); }
.curva-legenda .curva-faturado .curva-chave { color: var(--aviso); }
/* As duas distancias entre as linhas (13/10/2026): o que a curva responde, dito
 * em numero, porque so o desenho nao dizia. */
.curva-distancias { list-style: none; margin: 0 0 var(--e-3); padding: 0; display: flex;
  flex-wrap: wrap; gap: var(--e-2) var(--e-5); font-size: 13px; color: var(--ink-medio); }
.curva-distancias li { padding: 4px 10px; border-radius: var(--r); background: var(--panel-2);
  border: 1px solid var(--line); }
.curva-distancias strong { font-family: var(--f-num); font-weight: 700; color: var(--ink); }
/* O sinal invertido (medido acima do autorizado, faturado acima do medido) nao
 * e alarme: e a cobertura do AES e a nota que paga BMD antigo. Tom de aviso. */
.curva-distancias li.passou { border-color: var(--aviso); }
.chart-curva { height: 150px; padding: 8px 6px; }
.chart-curva svg { width: 100%; height: 100%; overflow: visible; display: block; }
.chart-curva line { stroke-width: 2; stroke-linecap: round; fill: none; }
.chart-curva line.ressalva { stroke-dasharray: 4 4; opacity: .7; }
.chart-curva line.marca { stroke-width: 8; }
.chart-curva .curva-autorizado line { stroke: var(--info); }
.chart-curva .curva-medido line { stroke: var(--primary-forte); }
.chart-curva .curva-faturado line { stroke: var(--aviso); }
.curva-meses { display: flex; padding: 0 6px; }
.curva-meses span { flex: 1 1 0; text-align: center; font-size: 12px; line-height: 16px;
  color: var(--muted); }
.curva-meses span.futuro { color: var(--muted-claro); }
.curva-pe { margin: var(--e-3) 0 0; font-size: 12px; color: var(--muted); }
/* O segmentado `.vistas` no cabecalho de secao (o "Agrupar os AES" de /faltantes). */
.secao-cabeca .vistas { margin-right: auto; }
/* A ordem por vencimento no Controle Operacional (07/10/2026): a lista sem as faixas. */
.op-ordem { margin: 0 0 var(--e-2); font-size: 14px; color: var(--muted); }
.op-ordem b { color: var(--titulo); }
/* A fila de AES por fiscal em /faltantes (06/10/2026): um bloco por fiscal,
 * a lista pronta para mandar a cada um. */
.grupo-fiscal { margin: 0 0 var(--e-3); }
.grupo-fiscal h3 { margin: 0 0 var(--e-1); font-size: 16px; color: var(--titulo); }
.grupo-fiscal ul { margin: 0; padding-left: 20px; font-size: 14px; }
.grupo-fiscal li { margin: 2px 0; }

/* rodape de saude da base */
.rodape-saude {
  display: flex; flex-wrap: wrap; gap: var(--e-5) var(--e-6); align-items: center;
  padding: var(--e-4) var(--e-5); margin-top: var(--e-2); font-size: 13px;
  color: var(--ink-medio);
}
.rodape-saude .item { display: flex; align-items: center; gap: 7px; }
.rodape-saude .ponto { width: 8px; height: 8px; border-radius: 50%; }
.rodape-saude .ponto.ok { background: var(--ok); }
.rodape-saude .ponto.aviso { background: var(--aviso); }
.rodape-saude .ponto.erro { background: var(--erro); }
.rodape-saude .ponto.neutro { background: var(--muted-claro); }
.rodape-saude b { font-family: var(--f-num); font-size: 19px; font-weight: 700;
  color: var(--titulo); }

/* ============================================================ estados */
.vazio, .erro-box {
  background: var(--panel); border: 1px dashed var(--line-forte);
  border-radius: var(--r); padding: 40px 32px; text-align: center; color: var(--muted);
}
.vazio code { background: var(--panel-2); padding: 2px 7px; border-radius: 5px;
  font-family: var(--f-num); color: var(--ink-medio); }

.alerta {
  background: var(--erro-bg); color: var(--erro); font-weight: 600;
  border: 1px solid color-mix(in srgb, var(--erro) 30%, transparent);
  border-radius: var(--r); padding: 12px 16px; margin-bottom: 18px;
}

/* grupos de pendência */
.grupo-pend { margin-bottom: 22px; }
.grupo-pend > h3 { display: flex; align-items: center; gap: 10px; margin: 0 0 9px;
  font-size: 14px; font-weight: 650; }
.grupo-pend .cont { font-family: var(--f-num); background: var(--neutro-bg);
  color: var(--neutro); padding: 1px 9px; border-radius: var(--r-pill); font-size: 13.5px; }

/* meta grid do Detalhe do PEP */
.meta-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 16px 24px; padding: 16px 18px; background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--r); box-shadow: var(--sombra); }
.meta-grid .rot { font-size: 12px; font-weight: 650; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--muted); }
.meta-grid .val { margin-top: 3px; font-size: 13.5px; }

:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; border-radius: 4px; }

/* ======================================================= acessibilidade
 * Duas ausencias que doiam com 9 itens de menu antes do conteudo e com tabelas
 * de 14 colunas que rolam na horizontal. */
.pular {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--primary); color: var(--on-primary);
  padding: 10px 16px; border-radius: 0 0 var(--r-sm) 0; font-weight: 650;
}
.pular:focus { left: 0; }

.sr-apenas {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* A tabela que rola na horizontal precisa ser focavel, senao as colunas da
 * direita ficam inalcancaveis pelo teclado. */
.tabela-wrap[tabindex]:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

/* ============================================== conteudo largo (Operacional)
 * 14 colunas + coluna sticky passam de 1400px; so essa tela abre mao do teto. */
.conteudo.largo { max-width: none; }

/* ============================================================ abas (RMDs, Projeto)
 * Links com querystring, nunca estado em JavaScript. */
.abas {
  display: flex; gap: 4px; align-items: flex-end;
  border-bottom: 1px solid var(--line); margin-bottom: 16px;
}
.abas a {
  padding: var(--e-3) var(--e-4); text-decoration: none; font-size: 14.5px; font-weight: 650;
  color: var(--muted); border-bottom: 3px solid transparent; margin-bottom: -1px;
}
.abas a:hover { color: var(--ink-medio); background: var(--panel-2); }
.abas a[aria-current="page"] { color: var(--titulo); border-bottom-color: var(--primary); }
.abas .cont {
  font-family: var(--f-num); font-size: 12.5px; color: var(--muted);
  background: var(--neutro-bg); border-radius: var(--r-pill); padding: 1px 7px; margin-left: 6px;
}

/* ============================================================ paginacao
 * Borda desabilitada e <span>, nunca <a>: link que nao vai a lugar nenhum e
 * armadilha de teclado. */
.paginacao {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  margin-top: 16px; font-size: 14px;
}
.paginacao a, .paginacao span {
  padding: 6px 11px; border-radius: var(--r-sm); border: 1px solid var(--line);
  background: var(--panel); text-decoration: none; color: var(--ink-medio);
}
.paginacao a:hover { border-color: var(--primary); color: var(--primary); }
.paginacao span.inativo { color: var(--muted-claro); background: var(--panel-2); }
.paginacao .posicao { border: none; background: none; font-family: var(--f-num); color: var(--muted); }

/* ============================================================ aviso de origem
 * Faixa que declara de onde o dado veio e o que NAO esta ali. Informativa -
 * `.alerta` (vermelho) continua reservado para defeito do motor. */
.aviso-info {
  background: var(--panel); color: var(--ink-medio);
  border: 1px solid var(--line);
  border-left: 4px solid var(--info);
  border-radius: var(--r); box-shadow: var(--sombra);
  padding: var(--e-4) var(--e-5); margin-bottom: var(--e-4);
  font-size: 13.5px; line-height: 1.6;
}
.aviso-info b { color: var(--titulo); }

/* ================================================ rodape de totais grudado
 * Sticky nas CELULAS, nao no <tfoot>: o suporte a sticky no elemento tfoot e
 * recente. Se falhar, a linha continua sendo a ultima da tabela e continua
 * correta - nunca precisa de JavaScript.
 *
 * Planos de z-index nas tabelas: thead 1 (3 na col-projeto) . col-projeto 2 .
 * tfoot 4 (5 na col-projeto) . topbar 5. */
.tabela-wrap.rolagem { max-height: calc(100vh - 300px); }
.tabela tfoot td, .tabela tfoot th {
  position: sticky; bottom: 0; z-index: 4;
  background: var(--faixa); color: var(--faixa-ink);
  border-top: 1px solid var(--faixa-2); border-bottom: none;
  font-weight: 650; height: var(--linha-h-densa);
}
.tabela tfoot .col-projeto { left: 0; z-index: 5; background: var(--faixa); }
.tabela tfoot .nota {
  font-weight: 400; font-size: 12.5px; color: var(--faixa-ink-fraca); text-align: left;
}
.tabela tfoot .num { color: var(--faixa-ink); }
.tabela tfoot .nulo { color: var(--faixa-ink-fraca); }

/* texto longo em coluna estreita (Municipio, Fiscal, Descricao) */
.texto-curto {
  display: inline-block; max-width: 180px; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom;
}
/* a descricao de material, que e' o texto mais longo do painel e o que mais
 * doia escondido - 130px cortavam `POLIMERICO 15KV RD COMPACTA` no meio */
.texto-curto.largo { max-width: 340px; }
/* A tabela de material do PEP tem doze colunas desde o saldo unico (Fonte e
 * Fechamento entraram), e a descricao a 180px deixava a Causa 11px fora do
 * envelope em 1600px (regua, 11/09/2026). O texto inteiro segue no `title`. */
.texto-curto.estreito { max-width: 160px; }

/* hash de arquivo (Documentos) */
.hash {
  font-family: var(--f-num); font-size: 13px; color: var(--muted);
  background: var(--panel-2); border-radius: 4px; padding: 1px 6px;
}

/* chip cinza forte - o sexto tom, para CANCELADA e afins */
.chip.neutro-forte { background: var(--neutro-bg); color: var(--ink-medio); }

/* ============================================ barra de consumo (Material)
 * NAO e a `.barra-inline`: aquela e faixa 80/50 onde alto = bom. Consumo e o
 * inverso - 403% e o pior caso da tela. Verde ate 100, vermelho no que passa. */
.barra-consumo { display: inline-flex; align-items: center; gap: 8px; width: 100%; }
.barra-consumo .trilho {
  flex: 1; min-width: 42px; height: 5px; border-radius: 3px;
  background: var(--panel-2); overflow: hidden; display: flex;
}
.barra-consumo .dentro { height: 100%; background: var(--ok); }
.barra-consumo .excedeu { height: 100%; background: var(--erro); }
.barra-consumo .pct-mini { font-size: 13px; min-width: 46px; text-align: right; }
.barra-consumo.estourou .pct-mini { color: var(--erro); font-weight: 600; }

/* faixa de grupo sem orcamento (Material) */
.tabela tbody tr.grupo-linha.aviso td {
  background: var(--aviso-bg); color: var(--aviso); font-weight: 600; font-size: 13.5px;
}

/* ==================================== acordeao: a mecanica do chevron, uma vez
 * `.obra-faixa` (Obras/Material/Programacao) e `.rmd-faixa` (RMDs) sao
 * modificadores desta base. Sem isso seria a terceira copia. As duas sao
 * claras desde 04/09 - so o <tfoot> e a sidebar seguem escuros. */
.faixa-summary {
  display: flex; align-items: center; gap: var(--e-4);
  padding: var(--e-3) var(--e-4); cursor: pointer; user-select: none;
  list-style: none;
}
.faixa-summary::-webkit-details-marker { display: none; }
.faixa-summary::before {
  content: ""; flex: none;
  width: 0; height: 0;
  border-left: 5px solid currentColor;
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
  transition: transform .15s;
}
details[open] > .faixa-summary::before { transform: rotate(90deg); }

.tabela tbody tr.atencao td { background: color-mix(in srgb, var(--aviso-bg) 45%, var(--panel)); }
.tabela tbody tr.atencao:hover td { background: var(--panel-2); }

/* ======================================== CASCATA - telas Material e RMDs
 * Coluna unica: um projeto (Material) ou um RMD embaixo do outro, com bastante
 * respiro. Substitui o acordeao de dois niveis de Material (`.grupo-projeto`,
 * que saiu) e a pilha de `.cartao-rmd` de RMDs (idem), e e o que o codigo de
 * referencia entregue em 08/09/2026 desenha.
 *
 * O que a referencia chama `.tabela--ar` chama-se aqui `.tabela.arejada`: nesta
 * folha os modificadores de tabela sao classes (`.densa`, `.grade`,
 * `.com-totais`), e um `--` solto seria a unica excecao.
 *
 * A referencia tambem pagina DENTRO de cada bloco. Aqui nao: a paginacao
 * continua sendo uma so, do conjunto filtrado, no fim da lista. Paginar por
 * bloco faria o rodape de cada grupo depender de quanto foi desenhado, que e o
 * corte `?limite=` ja recusado em Obras. */

/* Envelope da tela arejada. So Material e RMDs o vestem - as outras nove telas
 * ficam onde estavam, e e por isso que ele existe como classe em vez de mudar
 * `.kpis`/`.card` para todo mundo. */
.tela-ar { display: flex; flex-direction: column; gap: var(--e-5); }
/* O ritmo da coluna e o `gap`, e mais nada. Tres dos seis filhos trazem margem
 * propria - `.barra-acoes` 18px, `.paginacao` 16px, `.como-ler` var(--e-5) -
 * porque nas outras nove telas nao existe envelope nenhum e a margem e que os
 * separa. Aqui ela SOMA com o gap, e a coluna saia 24/24/42/40/48. Quem
 * introduz um envelope de `gap` assume a margem de quem entra nele. */
.tela-ar > * { margin-top: 0; margin-bottom: 0; }
.tela-ar .kpis { gap: 20px; }
.tela-ar .kpis .card { min-height: 132px; padding: 20px 18px 22px; gap: 4px; }
/* O medidor de 6px serve num cartao compacto; num de 132px com numero de 38px
 * ele vira um fio, e o trilho `--panel-2` sobre branco quase nao se ve. O print
 * traz 9px. Escopado, porque `.medidor` tambem veste Documentos, PEP e
 * Detalhe da Obra, que nao mudam nesta rodada. */
.tela-ar .kpis .medidor { height: 9px; }
/* `.filtros` nao e filho direto - mora dentro do cartao -, entao a regra de
 * cima nao o alcanca. */
.tela-ar .filtros { margin: 0; }

/* A barra de filtros/abas como o print a mostra: uma faixa branca de uma linha
 * so, sem rotulo em versalete acima de cada campo. Vai NO `.card`, sobrescrevendo
 * o padding dele - o `.filtros` de dentro perde o proprio cartao para nao
 * empilhar dois.
 *
 * A medida e a que a referencia RENDERIZA, nao a que ela declara: la o
 * `.barra-ferramentas { padding: 18px 22px }` e vencido por
 * `.tela-ar .card__corpo { padding: 20px 24px 22px }`, que tem duas classes. E
 * os 24px laterais sao o que alinha esta barra com o `--e-5` de
 * `.bloco__cabeca`, tres elementos abaixo. */
.barra-ferramentas { padding: 20px var(--e-5) 22px; }
.barra-ferramentas .filtros {
  align-items: center; gap: 14px;
  background: none; border: none; box-shadow: none; padding: 0; margin: 0;
}
/* O rotulo continua no HTML, e continua sendo lido em voz alta: quem carrega o
 * sentido na tela e o `placeholder`, mas um `<select>` sem rotulo acessivel nao
 * se navega. `.sr-apenas` e a mesma classe que os `<caption>` das tabelas usam. */
.filtros.compacta .campo { flex-direction: row; align-items: center; gap: var(--e-2); }
.filtros.compacta .campo > label {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}
.filtros.compacta .campo .pe { display: none; }
.filtros.compacta .campo-check { gap: 18px; }
.filtros.compacta .campo-check label { font-size: 14.5px; }
/* O `.campo-check` e a EXCECAO da regra de cima: ali o <label> nao e etiqueta
 * acima do campo, e o proprio controle - o texto ao lado da caixinha. Escondido
 * por `.sr-apenas`, os tres filtros de Material desapareciam da tela sem
 * deixar rastro, e sobrava um botao "Filtrar" sozinho. */
.filtros.compacta .campo-check > label {
  position: static; width: auto; height: auto;
  overflow: visible; clip-path: none;
}
/* Checkboxes, botao e "limpar" viajam JUNTOS. Como itens soltos do flex eles
 * quebram um a um, e a segunda linha saia com o botao sozinho a esquerda; o
 * print poe o grupo inteiro na segunda linha, encostado a direita. E o
 * `<span class="linha empurra">` que a referencia usa. */
.filtros.compacta .acoes {
  display: flex; align-items: center; gap: 18px; margin-left: auto;
}
.filtros.compacta .empurra { margin-left: auto; }
.filtros.compacta select { min-width: 150px; }
/* O print poe a busca ocupando perto de metade da barra, com os seletores
 * encostados a direita. E o `.campo--flex` da referencia, so que aqui o
 * `.campo` e o <div> que embrulha rotulo + campo - entao quem cresce e ele, e o
 * <input> de dentro precisa acompanhar. */
.filtros.compacta .campo-busca { flex: 1 1 240px; }
.filtros.compacta .campo-busca input[type="text"] { width: 100%; }
/* Dentro de `.linha-barra` a busca NAO cresce: a barra divide a linha com as
 * abas, e uma busca elastica come o espaco do botao, que quebra para baixo. E a
 * mesma distincao que a referencia faz entre `.campo--flex` (Material, cresce)
 * e `.campo--largo` (RMDs, largura fixa). */
.linha-barra .filtros.compacta .campo-busca { flex: 0 1 280px; }
/* E o formulario inteiro nao quebra por dentro: quem quebra e a `.linha-barra`,
 * poendo o filtro abaixo das abas. Sem isto, busca + situacao + botao estouram
 * a largura de conteudo por ~1px e o botao cai sozinho para a linha de baixo,
 * a esquerda - o oposto do print, que os traz os tres na mesma linha. */
.linha-barra .filtros.compacta { flex-wrap: nowrap; }
/* Abas a esquerda e filtro a direita na mesma barra, como no print de RMDs.
 * Quebra numa tela estreita em vez de comprimir o campo de busca. */
.linha-barra { display: flex; align-items: center; gap: var(--e-4); flex-wrap: wrap; }
.linha-barra .empurra { margin-left: auto; }
.linha-barra .abas { margin: 0; }

/* A pilha de blocos */
.cascata { display: flex; flex-direction: column; gap: 20px; }

.bloco {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r);
  box-shadow: var(--sombra);
  overflow: hidden;
}
/* `.bloco__cabeca` NAO reusa `.faixa-summary`: aquela e uma faixa de 40px com o
 * chevron em `::before`, e aqui o cabecalho tem 21px de titulo, chips e barra de
 * progresso, com a seta na ponta direita. Sao dois componentes, nao dois tons do
 * mesmo. O `list-style`/`::-webkit-details-marker` repete-se porque nenhuma das
 * duas herda da outra. */
.bloco > summary { list-style: none; cursor: pointer; }
.bloco > summary::-webkit-details-marker { display: none; }
/* `--primary-suave` e o verde das abas em pilula: sobre um cabecalho de 21px
 * com chips e barra ele pinta a faixa inteira. O print pede quase branco. */
.bloco > summary:hover {
  background: color-mix(in srgb, var(--panel-2) 50%, var(--panel));
}
.bloco > summary:focus-visible { outline: 2px solid var(--primary); outline-offset: -3px; }

.bloco__cabeca {
  display: flex; align-items: center; gap: var(--e-4);
  padding: 20px var(--e-5); flex-wrap: wrap;
}
.bloco[open] > .bloco__cabeca { padding-bottom: var(--e-4); }
.bloco__titulo {
  font-size: 21px; font-weight: 800; letter-spacing: -0.015em;
  color: var(--titulo); margin: 0;
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
}
.bloco__titulo .ponto { color: var(--muted-claro); font-weight: 700; }
.bloco__titulo .sigla {
  font-family: var(--f-num); font-weight: 700; color: var(--primary);
}
.bloco__chips { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.bloco__chips .tag { font-size: 14px; padding: 3px var(--e-3); }
/* "N negativos" / "N em aberto" e o sinal mais forte do cabecalho, e no print e
 * vermelho SOLIDO. O tinto palido de `.tag.t-erro` serve numa celula de tabela,
 * onde ele nao compete com nada; ao lado de um titulo de 21px ele desaparece. */
.bloco__chips .tag.t-erro {
  background: var(--erro); border-color: transparent; color: var(--on-primary);
}
.bloco__dir { margin-left: auto; display: flex; align-items: center; gap: 18px; }
.bloco__barra { flex: none; width: 220px; }
/* O `m.barra()` desenha o trilho de 5px que serve dentro de uma celula. No
 * cabecalho do bloco o print traz 9px e o valor em 14px/700. */
.bloco__barra .trilho { height: 9px; border-radius: var(--r-pill); }
.bloco__barra .pct-mini { font-size: 14px; font-weight: 700; color: var(--ink); }
.bloco__seta {
  flex: none; color: var(--titulo); display: grid; place-items: center;
  transition: transform .15s ease;
}
.bloco__seta svg { width: 22px; height: 22px; display: block; }
.bloco[open] > summary .bloco__seta { transform: rotate(180deg); }

/* Faixa interna: nomeia a secao e traz a segunda medida do bloco a direita. */
.bloco__faixa {
  display: flex; align-items: center; gap: var(--e-3); flex-wrap: wrap;
  padding: 14px var(--e-5); background: var(--panel-2);
  border-top: 1px solid var(--line-2); border-bottom: 1px solid var(--line-2);
  font-size: 16px; font-weight: 700; color: var(--titulo);
}
.bloco__faixa .dir {
  margin-left: auto; display: flex; align-items: center; gap: 10px;
  font-size: 15px; font-weight: 600; color: var(--muted);
}

/* Metadados discretos, abaixo da faixa */
.bloco__nota {
  display: flex; gap: 28px; flex-wrap: wrap; align-items: center;
  padding: var(--e-3) var(--e-5); background: #fbfaf1;
  border-bottom: 1px solid var(--line-2);
  font-size: 14.5px; color: var(--muted);
}
.bloco__nota b { color: var(--ink); font-weight: 700; }

/* A referencia fecha o bloco com 18px (`.bloco__rodape` 10 + `.paginacao` 8).
 * Aqui nao ha rodape de bloco - a paginacao e uma so, no fim da lista -, entao
 * o respiro de baixo tem de sair daqui. */
.bloco__corpo { padding: var(--e-1) var(--e-3) var(--e-3); }
/* Nao existe `.bloco__rodape`: a paginacao por bloco da referencia nao entrou
 * (ver o comentario no topo desta secao), e uma classe sem consumidor e a
 * mesma divida que `.grupo-projeto` e `.cartao-rmd` acabaram de pagar. */
/* Dentro do bloco a tabela ja esta num cartao: sem borda, sem sombra e sem
 * canto proprio - a mesma correcao que `.grupo-obra .tabela` faz. */
/* RMDs agrupadas por projeto (13/10/2026): o bloco do projeto leva as RMDs dele
 * como sub-blocos. Dentro do cartao o sub-bloco nao e outro cartao - sem sombra
 * nem canto, separado por um fio -, e o titulo desce de 21 para 17px, para o
 * projeto continuar sendo o que se le primeiro. A seta e o respiro do bloco
 * aberto valem so para o proprio bloco (`> summary`): sem isso o projeto aberto
 * girava a seta de toda RMD recolhida dentro dele. */
.rmds-do-projeto { display: flex; flex-direction: column; }
.bloco.bloco-rmd {
  border: none; border-top: 1px solid var(--line); border-radius: 0; box-shadow: none;
  margin-left: var(--e-4); border-left: 3px solid var(--line-2);
}
.bloco.bloco-rmd > .bloco__cabeca { padding: 14px var(--e-5) 14px var(--e-4); }
.bloco.bloco-rmd .bloco__titulo { font-size: 17px; }
.bloco.bloco-rmd .bloco__chips .tag { font-size: 13.5px; }
.bloco.bloco-rmd .bloco__barra { width: 180px; }
/* A tabela de itens da RMD rolava de lado (regua de 13/10/2026: 178px a 1024 na
 * essencial, 59px a 1366 na completa - antes do agrupamento, ja). Quem a
 * alargava era a descricao numa linha so, ate 340px: aqui ela dobra em ate duas
 * linhas (o texto inteiro fica no title), e abaixo de 1.400px o respiro lateral
 * das celulas encolhe e o cabecalho pode dobrar. */
.bloco-rmd .tabela td.cod .sub.corta {
  max-width: none; white-space: normal; overflow: hidden; overflow-wrap: anywhere;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2;
}
@media (max-width: 1400px) {
  .bloco-rmd .tabela.densa th, .bloco-rmd .tabela.densa td {
    padding-left: 5px; padding-right: 5px; font-size: 12.5px;
  }
  .bloco-rmd .tabela.arejada th, .bloco-rmd .tabela.arejada td { padding-left: 8px; padding-right: 8px; }
  .bloco-rmd .tabela th { white-space: normal; }
}
/* A mesma cura em `/material` (regua de 14/10/2026): a 1024 px a tabela do bloco
 * rolava 196 px de lado, com ou sem os chips de reposicao e de sobra, porque a
 * descricao numa linha so levava a coluna Material a 326 px. Dobra em ate duas
 * linhas, com o texto inteiro no title, e abaixo de 1.400 px o respiro encolhe. */
.cascata .tabela td.cod .sub.corta {
  max-width: none; white-space: normal; overflow: hidden; overflow-wrap: anywhere;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2;
}
@media (max-width: 1400px) {
  .cascata .tabela.arejada th, .cascata .tabela.arejada td { padding-left: 8px; padding-right: 8px; }
  .cascata .tabela th { white-space: normal; }
  /* Os chips do % fornecido (reposicao, sobra que voltou) descem para baixo da
   * barra em vez de ficar ao lado dela: lado a lado eles alargavam a coluna. */
  .cascata .tabela .chip.chip-acima {
    display: block; width: fit-content; max-width: 100%; margin: 3px 0 0 auto;
    white-space: normal; text-align: right;
  }
  .cascata .tabela.densa th, .cascata .tabela.densa td { padding-left: 5px; padding-right: 5px; }
}
/* A janela de ~1.100 px (notebook a 125%): as vistas de 10 e 12 colunas so cabem
 * com letra e respiro menores, e a barra do % fornecido mais curta. */
@media (max-width: 1100px) {
  .cascata .tabela.densa th, .cascata .tabela.densa td,
  .cascata .tabela.densa .num, .cascata .tabela.densa .cod {
    padding-left: 2px; padding-right: 2px; font-size: 11.5px;
  }
  .cascata .tabela.densa td.cod .sub { font-size: 10.5px; }
  .cascata .tabela.densa .chip { font-size: 10px; padding: 1px 4px; }
  .cascata .tabela.densa .chip.chip-orcado {
    display: block; width: fit-content; max-width: 100%; margin: 2px 0 0 auto;
    white-space: normal; overflow-wrap: anywhere;
  }
  .cascata .tabela.densa .barra-consumo { gap: 4px; }
  .cascata .tabela.densa .barra-consumo .trilho { min-width: 24px; }
  .cascata .tabela.densa .barra-consumo .pct-mini { min-width: 0; font-size: 11.5px; }
}
.bloco .tabela { border: none; border-radius: 0; box-shadow: none; }
.bloco .tabela-wrap { border-radius: 0; max-height: none; }
/* Dentro do bloco o `<thead class="escuro">` se apaga: o print traz cabecalho
 * branco com texto verde-escuro em negrito, e o fundo `--panel-2` do `.escuro`
 * repetia a `.bloco__faixa` que esta dois elementos acima - duas faixas do
 * mesmo tom encostadas. O `.escuro` continua no HTML porque a vista larga
 * desenha `tr.grupo-col`, que depende dele. */
.bloco .tabela.arejada thead th {
  background: var(--panel); color: var(--titulo);
  border-bottom: 1px solid var(--line);
}

/* Tabela arejada: linhas mais altas e respiro lateral. E o oposto da `.densa`,
 * e as duas nunca convivem - a cascata e a tela que tem espaco. */
.tabela.arejada th { padding: var(--e-3) 14px; font-size: 14.5px; }
/* Altura pela `height` e padding vertical em ZERO - a disciplina de
 * `.tabela td` e de `.densa`. A referencia usa `padding: 13px 14px` sem altura
 * porque o dado de exemplo dela nao tem celula de duas linhas; aqui a coluna de
 * material carrega `.cod` + `.sub`, e os dois juntos davam 48px numa linha e
 * ~58 na vizinha, na mesma tabela. Declarar os dois nunca da o maior: da um
 * valor por linha. */
.tabela.arejada td { padding: 0 14px; height: 48px; }

/* Item de RMD ainda em aberto: a linha INTEIRA pintada, como no print. Era o
 * creme discreto de `tr.atencao`, e numa tabela de 50 linhas ele nao se via.
 * O texto vai a branco, e por isso a regra de impressao no fim do arquivo
 * precisa alcancar esta classe tambem. */
.tabela tbody tr.destaque-vermelho td {
  background: #f0736d; color: #2a0806; font-weight: 600;
  border-bottom-color: #e05f58;
}
.tabela tbody tr.destaque-vermelho:hover td { background: #ea6159; }
.tabela tbody tr.destaque-vermelho .nulo,
.tabela tbody tr.destaque-vermelho .sub { color: #4a1310; }

/* Nas duas telas da cascata o rodape de notas e um cartao de largura inteira,
 * com titulo de 19px e a seta na ponta - e como a referencia o desenha. Ao lado
 * de blocos de 21px, o versalete cinza de 12,5px que serve as outras nove telas
 * nao lia como secao. Escopado em `.tela-ar`, e reusando o triangulo `::after`
 * que `.como-ler` ja tem: o chevron continua com uma implementacao so, e
 * nenhum template muda. */
.tela-ar .como-ler {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--r); box-shadow: var(--sombra); overflow: hidden;
}
.tela-ar .como-ler > summary {
  display: flex; padding: 18px var(--e-5);
  font-size: 19px; font-weight: 800; letter-spacing: -0.015em;
  text-transform: none; color: var(--titulo);
}
.tela-ar .como-ler > summary::after {
  margin-left: auto;
  border-left-width: 7px; border-top-width: 6px; border-bottom-width: 6px;
}
.tela-ar .como-ler .corpo { border-left: none; padding: 0 var(--e-5) 20px; }

/* A procedencia, no aviso do topo. `.chip` e nao `.tag`: a tag e branca
 * translucida, feita para a faixa escura da obra, e sumiria no fundo claro. */
.fontes-linha { display: inline-flex; flex-wrap: wrap; gap: 6px; margin-left: 6px; }

/* ================================================== timeline de marcos (Projeto)
 * Quatro estados, nao dois. `pendente` (da para provar que nao aconteceu) e
 * `sem_dado` (nao fomos informados) PRECISAM parecer diferentes: com dois
 * estados, 480 projetos sem data de termino apareceriam como atrasados. E a
 * regra 1 num componente visual. */
.timeline {
  display: flex; align-items: flex-start; gap: 0;
  padding: 20px 16px 14px; overflow-x: auto;
}
.marco { flex: 1; min-width: 96px; text-align: center; position: relative; }
.marco::before {
  content: ""; position: absolute; top: 8px; left: -50%; width: 100%; height: 2px;
  background: var(--line); z-index: 0;
}
.marco:first-child::before { display: none; }
.marco .ponto {
  position: relative; z-index: 1; display: block; width: 18px; height: 18px;
  margin: 0 auto 8px; border-radius: 50%; background: var(--panel);
  border: 2px solid var(--line);
}
.marco.feito .ponto { background: var(--primary-forte); border-color: var(--primary-forte); }
.marco.feito::before { background: var(--primary-forte); }
.marco.parcial .ponto { background: var(--panel); border-color: var(--aviso); border-width: 4px; }
.marco.pendente .ponto { background: var(--panel); border-color: var(--muted-claro); }
.marco.sem-dado .ponto { background: var(--panel); border-style: dashed; border-color: var(--nulo); }
.marco .rot { display: block; font-size: 12.5px; font-weight: 600; color: var(--ink-medio); }
.marco .quando { display: block; font-family: var(--f-num); font-size: 12.5px; color: var(--muted); }
.marco.sem-dado .rot, .marco.sem-dado .quando { color: var(--nulo); font-weight: 500; }
.marco.parcial .quando { color: var(--aviso); }

/* seccoes do Detalhe da Obra */
.secao-proj { margin-top: 22px; }
.secao-proj > summary {
  font-size: 13.5px; font-weight: 650; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--ink-medio); padding: 10px 14px; background: var(--panel-2);
  border: 1px solid var(--line); border-radius: var(--r);
}
.secao-proj[open] > summary { border-radius: var(--r) var(--r) 0 0; }
.secao-proj > summary .cont {
  font-family: var(--f-num); font-size: 12.5px; color: var(--muted);
  background: var(--panel); border-radius: var(--r-pill); padding: 1px 8px; margin-left: 8px;
}
.secao-proj .corpo {
  border: 1px solid var(--line); border-top: none;
  border-radius: 0 0 var(--r) var(--r); padding: 14px 16px; background: var(--panel);
}

/* ==================================================== htmx: o que ele troca
 * Ver static/VENDOR.md para versao e procedencia. A regiao `#tela` e o pedaco
 * que a troca de vista, o filtro e a paginacao substituem - a pagina inteira de
 * Material na vista completa sao 240 KB, e o fragmento e' ~12 KB.
 *
 * Todo alvo e' um <a href> ou <form> que FUNCIONA sem htmx: com JavaScript
 * desligado o link recarrega a pagina e a tela continua correta, so mais lenta.
 * E por isso que os testes continuam valendo - eles pedem a URL inteira. */
#tela { position: relative; }
/* O htmx poe `htmx-request` no elemento durante o pedido. Esmaecer sem mexer no
 * layout: qualquer coisa que mude altura faria a tabela saltar a cada clique. */
#tela.htmx-request { opacity: 0.55; transition: opacity .12s; }
#tela.htmx-request::after {
  content: "carregando…";
  position: absolute; top: var(--e-4); right: var(--e-4);
  background: var(--titulo); color: var(--on-primary);
  font-size: 13px; font-weight: 650; letter-spacing: 0.04em;
  padding: 5px var(--e-3); border-radius: var(--r-pill);
}
@media (prefers-reduced-motion: reduce) {
  #tela.htmx-request { transition: none; }
  .recolher svg { transition: none; }
}

/* ============================================================ impressao
 * O controller imprime. Sem isto, o sticky esconde linha no PDF. */
@media print {
  .sidebar, .filtros, .pular, .paginacao, .abas { display: none !important; }
  .app { grid-template-columns: 1fr; }
  .topbar { position: static !important; }
  .tabela-wrap { max-height: none !important; overflow: visible !important; }
  .tabela th, .tabela td, .tabela tfoot td, .tabela tfoot th,
  .tabela .col-projeto { position: static !important; }
  details > summary { display: none; }
  .card, .painel-branco, .tabela { box-shadow: none; }
}

/* impressao da conferencia do romaneio (Mudanca 6): a regra geral acima
 * esconde TODO `<summary>` - certo para as outras telas, onde o cabecalho de
 * grupo e so navegacao. Aqui o cabecalho de PEP e conteudo (e' o que organiza
 * a conferencia fisica por destino), entao esta pagina restaura so o dela,
 * com `!important` porque a regra geral tambem usa. O resto da regra geral
 * (sidebar/nav fora, tabela sem scroll) continua valendo. */
@media print {
  .pagina-romaneio details.grupo-obra > summary { display: flex !important; }
}

/* impressao das duas telas refeitas em 04/09.
 *
 * `.vistas` e navegacao, como `.abas`: um seletor de coluna em pilula nao se
 * clica no papel. `.como-ler` e prosa sobre como ler a TELA, e some inteira -
 * esconder so o `<summary>` dela deixaria o texto orfao do proprio titulo.
 *
 * O `<summary>` do cartao de RMD, ao contrario, e CONTEUDO: e o numero do
 * documento, mais projeto, PEP, emissao e a barra de certificacao. A regra
 * geral o escondia desde sempre, e isso nao se notava porque a abertura padrao
 * (`d.abertos and t.rmds <= 6`) nao abria nenhum cartao com 14 RMDs na base -
 * a pagina impressa saia vazia. Com 3 abertos, sairiam tres tabelas de itens
 * sem dizer de qual RMD cada uma e. Mesma excecao do romaneio, pela mesma
 * razao: aqui o cabecalho de grupo nao e navegacao. */
@media print {
  .vistas, .como-ler { display: none !important; }
  details.cartao-rmd > summary { display: flex !important; }
}

@media (max-width: 900px) {
  .app, :root.sidebar-recolhida .app { grid-template-columns: 1fr; }
  .recolher { display: none; }
  :root.sidebar-recolhida .marca-txt, :root.sidebar-recolhida .item .rotulo { display: revert; }
  .sidebar { position: static; height: auto; flex-direction: row; flex-wrap: wrap;
    align-items: center; border-right: none; border-bottom: 1px solid var(--sidebar-bg); }
  .sidebar .menu { flex-direction: row; flex-wrap: wrap; }
  .sidebar .menu.rodape, .versao-no-ar { display: none; }
  .item { border-left: none; }
  .item.ativo { border-left: none; }
  .barra { grid-template-columns: 1fr 2fr 44px; }
  .barra .qt-nota { grid-column: 1 / -1; text-align: left; }
}

/* ==========================================================================
   COMPONENTES DO PROTÓTIPO (05/09/2026)

   O que veio de `frontend-referencia/codigo/` e não existia aqui. Cada um está
   num print e nenhum foi inventado para preencher a folha. As cores de estado
   reusam o vocabulário semântico que já existe (`ok`/`aviso`/`erro`/`info`/
   `indigo`/`neutro`) em vez de trazer os cinco nomes de cor do protótipo - é o
   mesmo mapa que `_macros.html::_COR_ESTADO_PDE` já aplica aos chips, e assim
   um documento APROVADO tem a mesma tinta no chip e no bloco da agenda.
   ========================================================================== */

/* ---------------------------------------------------- abas em pílula (RMDs)
 * Variante da `.abas` sublinhada. Nos prints as abas de RMD são pílulas dentro
 * de uma caixa branca; a sublinhada continua existindo para o Detalhe da Obra,
 * onde ela convive com o `.vistas` na mesma tela e precisa distinguir-se dele. */
.abas.pilula {
  border-bottom: none; gap: 6px; padding: 5px;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--r-md); display: inline-flex; width: auto;
}
.abas.pilula a {
  border-bottom: none; margin-bottom: 0; border-radius: var(--r-sm);
  padding: 6px var(--e-4); font-size: 17px; font-weight: 600; color: var(--muted);
}
.abas.pilula a:hover { background: var(--panel-2); color: var(--ink); }
.abas.pilula a[aria-current="page"] {
  background: var(--primary-suave); color: var(--titulo);
  border: 1px solid var(--line-forte); padding: 5px 15px;
}

/* ------------------------------------------------- tabela com grade completa
 * Só o Controle Operacional. O Design.md proíbe régua vertical em tabela, e a
 * proibição continua certa para uma lista de leitura. Esta tela é outra coisa:
 * são 15 colunas em dois níveis de cabeçalho, e sem a grade o olho perde a
 * linha entre "Autorizado" e "Fim Operacional". O print confirma a exceção. */
.tabela.grade th, .tabela.grade td { border: 1px solid var(--line-2); }
.tabela.grade thead th { text-align: center; }
.tabela.grade thead th.col-projeto { text-align: left; }

/* -------------------------------------------- célula de prazo de fundo cheio
 * Nos prints o prazo não é chip: é a célula inteira pintada, e é o que faz uma
 * tela de 200 linhas mostrar o atraso sem que se leia coluna nenhuma.
 *
 * Os QUATRO estados são os do relatório, e o quarto não é decorativo:
 * `p-sem-dado` é prazo NÃO DECLARADO, e precisa parecer diferente de "no
 * prazo". Pintá-lo de verde afirmaria que está tudo bem com os projetos sobre
 * os quais a fonte não diz nada - a regra 1 numa célula de tabela. */
.tabela td.cel-prazo { text-align: center; font-weight: 600; font-size: 14px; }
.tabela td.cel-prazo.p-vencido  { background: #c53f36; color: #fff; }
/* Laranja, e nao mais o amarelo (09/10/2026, dono do produto: *"quando estiver
 * chegando perto do vencimento altere a cor para um laranja para diferenciar"*):
 * o amarelo passou a ser a programacao vencida (`td.cel-prog.prog-passou`), e as
 * duas celulas ficam lado a lado na mesma linha. */
.tabela td.cel-prazo.p-critico  { background: #f0a050; color: #3d2102; }
/* O zero da coluna Falta (09/10/2026): quadradinho verde com o certo, para a obra
 * sem nada a fornecer ou devolver se ler sem ler numero. */
.tabela .falta-ok {
  display: inline-grid; place-items: center; width: 20px; height: 20px;
  border-radius: 4px; background: var(--ok); color: var(--on-primary);
  font-size: 13px; font-weight: 800; line-height: 1;
}
.tabela td.cel-prazo.p-no-prazo { background: #2f8a48; color: #fff; }
.tabela td.cel-prazo.p-sem-dado { background: var(--panel-2); color: var(--muted); }
.tabela td.cel-prazo .num { color: inherit; }
.tabela td.cel-prazo .num.nulo { color: inherit; opacity: 0.75; }
.tabela td.cel-prazo .chip { background: rgba(255, 255, 255, 0.85); color: inherit; }

/* ================================== CONTROLE OPERACIONAL (maquete 23/09/2026)
 * Tres blocos com titulo, cartao com icone e selo, filtros numa faixa so e
 * cabecalho escuro. Tudo escopado em classes proprias (`op-*`, `kpis-op`): as
 * outras telas nao mudam. As cores sao as do sistema - o marrom e o vermelho
 * da maquete viram `--faixa` e `--erro`. */
/* A lista de projetos e o assunto da tela; cartoes e filtros sao a moldura
 * dela, e por isso sao baixos e os titulos de bloco sao pequenos (23/09/2026:
 * "a parte de projetos precisa ocupar uma area maior da tela"). */
.op-bloco + .op-bloco { margin-top: var(--e-4); }
.op-bloco > h2, .op-cab > h2 {
  font-size: 18px; font-weight: 800; letter-spacing: -0.015em;
  color: var(--titulo); margin: 0 0 var(--e-2);
}
.op-cab {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--e-4); flex-wrap: wrap; margin-bottom: var(--e-3);
}
.op-cab > h2 { margin: 0; font-size: 24px; }
.op-cab__acoes { display: flex; align-items: center; gap: var(--e-4); }

/* O cartao vira grade: rotulo e selo em cima, icone a esquerda, numero e
 * legenda a direita. `.rot`/`.big` continuam filhos diretos do cartao - e o que
 * o teste do topo sem prosa confere. */
.kpis.kpis-op .card {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-areas: "rot rot selo" "ico big big" "ico leg leg";
  align-items: center; column-gap: var(--e-3); row-gap: 0;
  text-align: left; padding: 12px 16px; min-height: 0;
}
/* Cinco cartoes numa fileira so (09/10/2026, dono do produto: "os KPIs ficaram
 * para baixo da tela, ficou esquisito"): a previsao de caixa de 08/10 era o 5o
 * cartao numa grade de 4, e caia sozinho na fileira de baixo - abaixo de 1400px,
 * em 3 fileiras de 2. A grade agora e de 5 em toda largura, e o cartao encolhe. */
.kpis.kpis-op { grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 12px; }
.kpis.kpis-op .card .rot { grid-area: rot; font-size: 15px; margin-bottom: 6px; align-self: start; }
.kpis.kpis-op .kpi-selo { grid-area: selo; justify-self: end; align-self: start; }
/* 25.750,582 a 40px estourava o cartao de 1/4 de tela (regua, 23/09/2026). */
.kpis.kpis-op .card .big {
  grid-area: big; align-self: end; margin: 0; font-size: clamp(24px, 1.9vw, 30px);
  white-space: nowrap;
}
@media (max-width: 1700px) { .kpis.kpis-op .card .big { font-size: clamp(19px, 1.6vw, 26px); } }
.kpis.kpis-op .kpi-leg {
  grid-area: leg; align-self: start; font-size: 12.5px; color: var(--muted); line-height: 1.25;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* A base da tile (06/10/2026) quebra a linha: cortada em reticencias ela some
 * justamente na parte que diz o que ficou fora da conta (regua: as quatro
 * cortavam em 1440px). */
.kpis.kpis-op .kpi-leg.tile-base { white-space: normal; overflow: visible; }
.kpis.kpis-op .kpi-ico {
  grid-area: ico; width: 46px; height: 46px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
}
.kpis.kpis-op .kpi-ico .ico { width: 22px; height: 22px; }
.kpis.kpis-op .kpi-ico.ok     { background: var(--ok-bg);     color: var(--ok); }
.kpis.kpis-op .kpi-ico.erro   { background: var(--erro-bg);   color: var(--erro); }
.kpis.kpis-op .kpi-ico.neutro { background: var(--neutro-bg); color: var(--neutro); }
.kpis.kpis-op .card.kpi-solido .kpi-ico { background: rgba(255, 255, 255, 0.16); color: var(--on-primary); }
.kpis.kpis-op .card.kpi-solido .kpi-leg { color: rgba(255, 255, 255, 0.88); }
/* O anel da base do orcado: o mesmo truque da pizza da Visao Geral - raio de
 * 15,9155 da circunferencia 100, e o `dasharray` recebe o percentual cru. */
.kpi-anel { width: 46px; height: 46px; }
.kpi-anel circle { fill: none; stroke-width: 4.2; }
.kpi-anel .trilho { stroke: var(--line-2); }
.kpi-anel .arco { stroke-linecap: round; }
.kpi-anel .arco.ok    { stroke: var(--ok); }
.kpi-anel .arco.aviso { stroke: var(--aviso); }
.kpi-anel .arco.erro  { stroke: var(--erro); }
/* O cartao que e link (Divergencias, Prazo vencido - 01/10/2026). A grade de
 * cima vence o `display: block` de `a.card-link` pela especificidade; daqui
 * vem so o que o link acrescenta: o foco do teclado e o estado "filtrando",
 * com o filtro dele ligado e o clique que o desliga. */
.kpis.kpis-op a.card-link:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.kpis.kpis-op .card.kpi-ativo { border-color: var(--primary); box-shadow: inset 0 0 0 1px var(--primary); }
.kpis.kpis-op .card.kpi-solido.kpi-ativo { box-shadow: inset 0 0 0 2px var(--on-primary); }
/* O cartao estreito da fileira de 5 (ver `.kpis.kpis-op`): depois das regras
 * dele, para ganhar pela ordem. */
@media (max-width: 1400px) {
  .kpis.kpis-op .card { padding: 10px 12px; column-gap: 10px; }
  .kpis.kpis-op .card .rot { font-size: 14px; }
  .kpis.kpis-op .kpi-ico { width: 36px; height: 36px; }
  .kpis.kpis-op .kpi-ico .ico { width: 18px; height: 18px; }
  .kpis.kpis-op .kpi-leg { white-space: normal; font-size: 12px; }
}
@media (max-width: 1150px) {
  .kpis.kpis-op .kpi-ico { display: none; }
  .kpis.kpis-op .card { grid-template-areas: "rot rot selo" "big big big" "leg leg leg"; }
}

/* Filtros numa linha so: cada select divide a faixa, a busca pega o dobro. */
.card.barra-ferramentas:has(.op-filtros) { padding: 10px var(--e-3); }
.op-filtros input[type="text"], .op-filtros select, .op-filtros .botao-primario,
.mais-filtros > summary { min-height: 38px; }
.op-filtros input[type="text"], .op-filtros select { padding-top: 7px; padding-bottom: 7px; }
/* A tabela ocupa a janela quase inteira: rolada a pagina, o cabecalho da lista
 * encosta no topo e sobram so os 110px do titulo da tela. Era 100vh - 300px. */
.tabela-wrap.rolagem:has(.op-lista) { max-height: calc(100vh - 110px); }
.op-filtros { flex-wrap: nowrap; gap: 10px; }
.op-filtros .campo { flex: 1 1 110px; min-width: 0; }
.op-filtros .campo-busca { flex: 2 1 220px; }
.op-filtros .campo:has(#f-mes) { flex-basis: 140px; }
.filtros.compacta.op-filtros select { min-width: 0; width: 100%; }
.op-filtros .botao-primario { flex: none; }
.op-filtros .link-limpar { flex: none; }
@media (max-width: 1300px) { .op-filtros { flex-wrap: wrap; } }
.mais-filtros { position: relative; flex: none; }
.mais-filtros > summary {
  list-style: none; cursor: pointer; white-space: nowrap;
  font-size: 15px; font-weight: 600; color: var(--ink-medio);
  border: 1px solid var(--line); border-radius: 9px;
  padding: 9px 12px; min-height: 42px; display: flex; align-items: center; gap: 6px;
}
.mais-filtros > summary::-webkit-details-marker { display: none; }
.mais-filtros > summary::after { content: "▾"; font-size: 12px; color: var(--muted); }
.mais-filtros[open] > summary { border-color: var(--primary); }
/* filtro ligado com a caixa fechada: o resumo fala por ela (02/10/2026) */
.mais-filtros--ativo > summary { border-color: var(--primary); color: var(--primary-forte); font-weight: 650; background: var(--ok-bg); }
.mais-filtros__caixa {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 10;
  flex-direction: column; align-items: flex-start; gap: 10px;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-md);
  box-shadow: var(--sombra-2); padding: var(--e-3) var(--e-4); white-space: nowrap;
}

/* Cabecalho escuro, como o <tfoot> de totais que ja fecha a tabela: a mesma
 * tinta, e a laje sobe para o topo so nesta tela. */
.tabela.op-lista thead.escuro th {
  background: var(--faixa-2); color: var(--faixa-ink);
  border-color: rgba(255, 255, 255, 0.12);
}
.tabela.op-lista thead.escuro tr.grupo-col th {
  background: var(--faixa); color: var(--faixa-ink);
  border-color: rgba(255, 255, 255, 0.12);
  height: 36px; font-size: 15px;
}
/* O titulo de coluna dobra em duas linhas em vez de ser cortado ("Local ·
 * Fiscal", "Data prog." - 09/10/2026, regua a 1.093px). */
.tabela.op-lista thead.escuro tr.grupo-col th[rowspan] { white-space: normal; line-height: 1.2; }
@media (max-width: 1279px) {
  .tabela.op-lista.densa thead.escuro tr.grupo-col th { font-size: 12.5px; padding-left: 3px; padding-right: 3px; }
  .tabela.op-lista.densa thead tr:nth-child(2) th:has(.th-sub) { white-space: normal; }
}
@media (max-width: 1079px) {
  .tabela.op-lista.densa thead.escuro tr:nth-child(2) th { font-size: 9.5px; padding-left: 2px; padding-right: 2px; }
  .tabela.op-lista.densa thead.escuro tr.grupo-col th { font-size: 11.5px; }
}
/* A lista deixa de ser `densa` no tamanho, e continua na marcacao: letra de
 * leitura e linha de 46px. O deslocamento da segunda linha do cabecalho acompanha
 * a primeira (36px), senao o sticky descola. */
.tabela.op-lista thead.escuro tr:nth-child(2) th { top: 36px; }
.tabela.op-lista thead.escuro th { font-size: 14.5px; padding: 9px var(--e-3); }
.tabela.op-lista.densa td { height: 46px; font-size: 15px; }
.tabela.op-lista.densa .num, .tabela.op-lista.densa .cod { font-size: 15px; }
.tabela.op-lista td.cod .sub { font-size: 12.5px; }
.tabela.op-lista .chip { font-size: 13px; }
.tabela.op-lista tfoot td { font-size: 15px; }
/* Caber sem rolar de lado (23/09/2026, a vista completa media 2.341px numa
 * janela de 1.304). Tres alavancas, nenhuma encolhendo a letra: rotulo de coluna
 * quebra em duas linhas em vez de ditar a largura (`Diverge do FF` era mais
 * largo que qualquer numero embaixo dele), o respiro lateral cai de 12 para
 * 8px, e os selos da Etapa empilham em vez de enfileirar. */
.tabela.op-lista th, .tabela.op-lista td { padding-left: var(--e-2); padding-right: var(--e-2); }
/* Larguras fixas (02/10/2026): a coluna nao muda quando o filtro troca as
 * linhas, e o navegador pinta sem medir a tabela inteira. Em **porcentagem** da
 * largura da tela, e nao em px: em px a vista completa somava 1.510px e, abaixo de
 * ~1.600px de janela, a pagina rolava de lado e cortava as ultimas colunas. As
 * proporcoes sao as que a vista completa media sozinha a 1.600px; nas vistas de
 * menos colunas a soma fica abaixo de 100% e a sobra se divide na mesma proporcao. */
.tabela.op-lista { table-layout: fixed; width: 100%; }
/* Local · Fiscal e Regiao (05/10/2026): as outras cederam na mesma proporcao,
 * para a vista completa continuar cabendo sem rolar de lado. De novo em
 * 08/10/2026, para a Programacao e a Previsao R$ entrarem, e em 09/10/2026, quando
 * Escopos e Base sairam: os 9,1% deles foram para as colunas que a regua mediu
 * estourando a 1.366px (Regiao, Prazo, Etapa, Saldo R$). E de novo no mesmo dia,
 * quando a Previsao R$ virou "% exec.": os 2,5% que ela soltou foram para os
 * dois saldos, onde o total em milhoes nao cabia. */
.tabela.op-lista col.c-projeto { width: 8.1%; }
.tabela.op-lista col.c-local   { width: 6.6%; }
.tabela.op-lista col.c-regiao  { width: 5.7%; }
.tabela.op-lista col.c-etapa   { width: 8.9%; }
.tabela.op-lista col.c-prazo   { width: 8.2%; }
.tabela.op-lista col.c-prog    { width: 7.9%; }
.tabela.op-lista col.c-falta   { width: 5.2%; }
.tabela.op-lista col.c-med     { width: 5.0%; }
.tabela.op-lista col.c-us      { width: 7.0%; }
.tabela.op-lista col.c-saldo   { width: 8.7%; }
.tabela.op-lista col.c-reais   { width: 8.1%; }
.tabela.op-lista col.c-saldo-rs { width: 10.0%; }
.tabela.op-lista col.c-exec    { width: 5.5%; }
/* "% exec." (09/10/2026): 100% em cinza e o padrao, que ninguem informou; o
 * digitado sai em preto, e o "passou" avisa que o faturado ja o ultrapassou. */
.tabela.op-lista .cel-exec .exec-padrao { color: var(--muted-claro); font-weight: 400; }
/* Abaixo de 1.500px o "fat." sai: o cabecalho e o title ja dizem que o numero de
 * baixo e o faturado. */
@media (max-width: 1500px) { .tabela.op-lista .cel-exec .fat-rot { display: none; } }
.tabela.op-lista .cel-exec .exec-passou { display: inline-block; margin-top: 2px; font-size: 10.5px; padding: 0 5px; }
/* Abaixo de 1.500px a letra da lista desce um ponto (09/10/2026): a soma do que
 * cada coluna precisa a 15px (regua, 1.366px) passava a largura da janela, e
 * o que nao cabe ou fura a vizinha ou rola a pagina de lado. */
@media (max-width: 1500px) {
  .tabela.op-lista.densa td, .tabela.op-lista.densa .num, .tabela.op-lista.densa .cod { font-size: 14px; }
  .tabela.op-lista.densa td.cod .sub { font-size: 11.5px; }
}
/* E abaixo de 1.300px os selos da Etapa e da Regiao ("Medição parcial", "SFZCBN"). */
@media (max-width: 1300px) {
  .tabela.op-lista.densa td.pilha .chip, .tabela.op-lista.densa .chip.regiao { font-size: 11px; padding: 1px 5px; }
  .tabela.op-lista.densa .prazo-dias { font-size: 11px; }
  .tabela.op-lista.densa td.cod .sub { font-size: 11px; letter-spacing: -0.01em; }
}
/* Abaixo de 1.280px (notebook com escala de 125%, janela pela metade): letra de
 * 12,5px, respiro de 3px, o "R$" sai das celulas - o cabecalho da coluna ja o diz
 * - e o selo da etapa pode dobrar. Sem isso a vista completa rolava de lado a
 * 1.024 e 1.100px (regua, 09/10/2026). */
@media (max-width: 1279px) {
  .tabela.op-lista .moeda { display: none; }
  .tabela.op-lista.densa th, .tabela.op-lista.densa td { padding-left: 3px; padding-right: 3px; }
  .tabela.op-lista.densa td, .tabela.op-lista.densa .num, .tabela.op-lista.densa .cod { font-size: 12.5px; }
  .tabela.op-lista.densa thead.escuro th { font-size: 12px; }
  .tabela.op-lista.densa thead tr:nth-child(2) th { font-size: 11.5px; }
  .tabela.op-lista.densa td.par .par-sub, .tabela.op-lista.densa td.par .par-sub .num { font-size: 11.5px; }
  .tabela.op-lista.densa td.cod .sub { font-size: 10.5px; letter-spacing: -0.02em; }
  .tabela.op-lista.densa td.pilha .chip, .tabela.op-lista.densa .chip.regiao { font-size: 10.5px; padding: 1px 4px; }
  .tabela.op-lista.densa td.pilha > .chip { white-space: normal; line-height: 1.25; }
  .tabela.op-lista.densa .prazo-dias { font-size: 10.5px; }
  .tabela.op-lista.densa td.pilha { min-width: 0; }
  .tabela.op-lista.densa td.cel-prazo { white-space: normal; }
  .tabela.op-lista.densa thead tr:nth-child(2) th { font-size: 10.5px; }
  /* As proporcoes do que cada coluna precisa nesta letra, medidas a 1.024px (e de
   * novo em 09/10/2026, quando o total em milhoes do par US e R$ ficou numa
   * linha so: Etapa e Saldo R$ cederam para eles; a 1.024px, Projeto e Saldo US). */
  .tabela.op-lista col.c-projeto { width: 8.9%; }
  .tabela.op-lista col.c-local   { width: 5.0%; }
  .tabela.op-lista col.c-regiao  { width: 6.5%; }
  .tabela.op-lista col.c-etapa   { width: 7.2%; }
  .tabela.op-lista col.c-prazo   { width: 8.4%; }
  .tabela.op-lista col.c-prog    { width: 8.2%; }
  .tabela.op-lista col.c-falta   { width: 5.2%; }
  .tabela.op-lista col.c-med     { width: 4.8%; }
  .tabela.op-lista col.c-us      { width: 7.7%; }
  .tabela.op-lista col.c-saldo   { width: 8.8%; }
  .tabela.op-lista col.c-reais   { width: 8.4%; }
  .tabela.op-lista col.c-saldo-rs { width: 9.8%; }
  .tabela.op-lista col.c-exec    { width: 5.5%; }
}
/* E abaixo de 1.080px (a janela de 1.024) mais um ponto a menos. */
@media (max-width: 1079px) {
  .tabela.op-lista col.c-projeto { width: 8.9%; }
  .tabela.op-lista col.c-etapa   { width: 7.1%; }
  .tabela.op-lista col.c-saldo   { width: 8.6%; }
  .tabela.op-lista col.c-exec    { width: 5.0%; }
  .tabela.op-lista col.c-reais   { width: 9.2%; }
  .tabela.op-lista.densa td, .tabela.op-lista.densa .num, .tabela.op-lista.densa .cod { font-size: 11.5px; }
  .tabela.op-lista.densa td.par .par-sub, .tabela.op-lista.densa td.par .par-sub .num { font-size: 10.5px; }
  .tabela.op-lista.densa td.cod .sub, .tabela.op-lista.densa .prazo-dias { font-size: 10px; }
}
/* O que vai sob o numero do projeto ("ANLC328942022 · sem AES") dobra entre as
 * partes, e nao no meio do codigo da obra. */
.tabela.op-lista td.col-projeto .sub { white-space: normal; overflow-wrap: normal; }
/* O selo "FF conf." da coluna Med. dobra em duas linhas em vez de furar a coluna. */
.tabela.op-lista td.cel-med .chip { white-space: normal; line-height: 1.2; }
.tabela.op-lista col.c-debito  { width: 7.2%; }
.tabela.op-lista td.cel-prog { overflow-wrap: normal; white-space: nowrap; }
/* "material entregue" (13/10/2026; era o "esperando prog." de 09/10): a obra
 * em Nao iniciado com o material na rua e programacao nenhuma. Pode dobrar em
 * duas linhas - a data ao lado nunca dobra. Cinza, e nao o indigo da etapa
 * Programada, que ela deixou de ser; o amarelo continua so da data que ja
 * passou, e as regras de linha (zebra, hover, vencido) nao a pintam. */
.tabela.op-lista td.cel-prog .material-entregue { display: inline-block; white-space: normal; line-height: 1.2; font-size: 12px; color: var(--muted); font-weight: 600; }
.tabela.op-lista td.cel-prog.prog-passou { background: #f7dfa5; color: #4a3a05; font-weight: 600; }
/* A sigla da regiao cabe inteira na coluna (09/10/2026): o chip estourava em
 * todas as linhas a 1.366px. Menor so aqui, sem cortar a sigla. */
.tabela.op-lista .chip.regiao { font-size: 12px; padding: 1px 6px; letter-spacing: 0; }
/* A faixa de datas de programacao na barra de filtros (08/10/2026). Com ela a
 * barra nao cabe numa linha abaixo de 1.700px sem espremer os selects ("Eta",
 * "Pra" - regua, 1.366px), entao ela quebra em duas antes disso. Desde 09/10/2026
 * os dois campos sao um grupo so, que quebra inteiro. */
/* E o grupo mora numa linha propria, embaixo dos outros filtros (09/10/2026, dono
 * do produto: "o filtro de datas saiu da tela, pode deixar na parte de baixo, mas
 * os dois quadrados"): acima de 1.700px a barra nao quebra, e o grupo de ~400px
 * era empurrado para fora do cartao. `order` o leva para depois do botao, e a
 * base de 100% abre a linha so para ele. */
.op-filtros { flex-wrap: wrap; }
/* A quebra de linha antes do grupo: um item vazio de base 100%, que fica sozinho
 * numa linha de altura zero. Na linha de baixo vao as datas, o Filtrar e o limpar. */
.op-filtros::before { content: ""; order: 97; flex: 0 0 100%; height: 0; margin-top: -10px; }
.op-filtros .campo-faixa { order: 98; flex: none; display: flex; align-items: center; gap: 8px; }
.op-filtros .botao-primario { order: 99; }
.op-filtros > .link-limpar { order: 100; }
.op-filtros .campo-faixa .faixa-rot { font-size: 14.5px; color: var(--muted); white-space: nowrap; }
.op-filtros input[type="date"] { min-height: 38px; width: 150px; padding-top: 7px; padding-bottom: 7px; }
/* O Excel e o que o gestor leva para a apresentacao (09/10/2026, dono do produto:
 * "um botao verde de exportar excel, um negocio simples e bonito", e depois
 * "parecido do botao de adicionar obra da tela de programacao"): a mesma pastilha
 * do "+ Adicionar programacao" (`.botao-primario` + `.adicionar > summary`), com o
 * icone no lugar do "+", e nao o link cinza do JSON ao lado. */
.botao-exportar {
  display: inline-flex; align-items: center; gap: 7px; align-self: center;
  min-height: 36px; padding: 0 16px; border-radius: var(--r-sm); border: none;
  background: var(--sidebar-bg); color: var(--on-primary);
  font: inherit; font-size: 14px; font-weight: 700; text-decoration: none; white-space: nowrap;
}
.botao-exportar:hover { background: var(--primary); color: var(--on-primary); text-decoration: none; }
.botao-exportar:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.botao-exportar .ico { width: 16px; height: 16px; }
@media (max-width: 1700px) { .op-filtros { flex-wrap: wrap; } .op-filtros .campo { min-width: 120px; } }
/* Quando a barra quebra, o campo nao cresce para encher a linha (09/10/2026):
 * Municipio e Faturado em viravam selects de 425px a 1.093px e de 1.020px a
 * 1.280px (regua). So abaixo de 1.366px, onde ela quebra no meio dos selects -
 * acima, a primeira linha cabe inteira e crescer e o que a alinha. O grupo de
 * datas fica fora: encolhido a 150px, o Filtrar caia em cima dele. */
@media (max-width: 1365px) {
  .op-filtros .campo:not(.campo-faixa) { flex: 0 1 150px; }
  .op-filtros .campo.campo-busca { flex: 0 1 250px; }
}
/* Com obra fechada na lista a coluna Debito entra, e a tabela tem uma coluna a
 * mais para dividir: o modo compacto comeca antes, em 1.600px (09/10/2026). */
@media (max-width: 1599px) {
  .tabela.op-lista.com-debito .moeda { display: none; }
  .tabela.op-lista.densa.com-debito th, .tabela.op-lista.densa.com-debito td { padding-left: 3px; padding-right: 3px; }
  .tabela.op-lista.densa.com-debito td, .tabela.op-lista.densa.com-debito .num,
  .tabela.op-lista.densa.com-debito .cod { font-size: 12.5px; }
  .tabela.op-lista.densa.com-debito td.par .par-sub,
  .tabela.op-lista.densa.com-debito td.par .par-sub .num { font-size: 11.5px; }
  .tabela.op-lista.densa.com-debito td.cod .sub { font-size: 10.5px; letter-spacing: -0.02em; }
  .tabela.op-lista.densa.com-debito td.n .chip-bloco,
  .tabela.op-lista.densa.com-debito td.n .chip { font-size: 10.5px; padding: 1px 3px; }
  .tabela.op-lista.densa.com-debito .chip-bloco .chip-sub { font-size: 10px; }
  .tabela.op-lista.densa.com-debito td.pilha .chip, .tabela.op-lista.densa.com-debito .chip.regiao { font-size: 10.5px; padding: 1px 4px; }
  .tabela.op-lista.densa.com-debito td.pilha > .chip { white-space: normal; line-height: 1.25; }
  .tabela.op-lista.densa.com-debito td.cel-prazo { white-space: normal; }
  .tabela.op-lista.densa.com-debito .prazo-dias { font-size: 10.5px; }
}
@media (max-width: 1279px) {
  .tabela.op-lista.densa.com-debito td, .tabela.op-lista.densa.com-debito .num,
  .tabela.op-lista.densa.com-debito .cod { font-size: 11px; }
  .tabela.op-lista.densa.com-debito td.par .par-sub,
  .tabela.op-lista.densa.com-debito td.par .par-sub .num { font-size: 10px; }
  .tabela.op-lista.densa.com-debito td.cod .sub, .tabela.op-lista.densa.com-debito .prazo-dias,
  .tabela.op-lista.densa.com-debito td.n .chip-bloco, .tabela.op-lista.densa.com-debito td.n .chip { font-size: 9.5px; }
  .tabela.op-lista.densa.com-debito th, .tabela.op-lista.densa.com-debito td { padding-left: 2px; padding-right: 2px; }
  /* O selo "falta romaneio" da obra fechada pede a coluna Falta mais larga; o
   * Local, que ja termina em reticencias, cede. */
  .tabela.op-lista.com-debito col.c-local   { width: 4.6%; }
  .tabela.op-lista.com-debito col.c-falta   { width: 5.8%; }
  .tabela.op-lista.com-debito col.c-projeto { width: 9.4%; }
}
/* Local na primeira linha, fiscal na segunda, menor: os dois nomes se leem
 * juntos sem dobrar a altura da linha. */
.tabela.op-lista td.col-local { line-height: 1.25; overflow-wrap: normal; }
.tabela.op-lista td.col-local .local-linha { display: block; font-size: 13.5px; }
.tabela.op-lista td.col-local .sub { display: block; font-size: 12px; }
/* O nome longo ("FERNANDO CAUS HAMMERSCHMIDT") termina em reticencias em vez de
 * furar a coluna ao lado (09/10/2026); o nome inteiro fica no title. */
.tabela.op-lista td.col-local .local-linha, .tabela.op-lista td.col-local .sub {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tabela.op-lista td { overflow-wrap: anywhere; }
.tabela.op-lista td.n, .tabela.op-lista td.par, .tabela.op-lista td.cel-prazo { overflow-wrap: normal; }
/* O selo que responde no lugar do numero ("faturada" + NF, "falta romaneio" +
 * itens) e um bloco de duas linhas de canto pouco arredondado: quebrado dentro da
 * pilula redonda ele virava uma bola de tres linhas ("faturada / · NF / 1650"). */
.tabela.op-lista td.n .chip { max-width: 100%; }
/* O codigo da obra sob o projeto ("ANLS330552024") e um nome so: com a coluna
 * em porcentagem ele quebrava no meio. Um ponto menor cabe inteiro a 1.280px. */
.tabela.op-lista td.col-projeto .sub { overflow-wrap: normal; word-break: normal; font-size: 11.5px; }
.tabela.op-lista td.n .chip-bloco {
  display: inline-block; white-space: normal; text-align: center;
  padding: 2px 5px; border-radius: 6px; line-height: 1.2; font-size: 12px;
}
.tabela.op-lista td.n:has(.chip-bloco) { padding-left: 3px; padding-right: 3px; }
.tabela.op-lista .debito-valor { white-space: normal; }
.tabela.op-lista .chip-bloco .chip-sub {
  display: block; white-space: nowrap; font-size: 11.5px; font-weight: 500; opacity: 0.85;
}
/* A barra da Base cede antes do numero: com o trilho de 42px o "100,00%" furava
 * a coluna abaixo de 1.440px de janela. */
/* O total em milhoes (faixa de etapa e rodape, "R$ -2.941.770,25") desce o "R$"
 * para a linha de cima quando a coluna aperta, em vez de furar a vizinha. */
.tabela.op-lista td.n .num { white-space: normal; }
.tabela.op-lista .barra-inline { gap: 5px; }
.tabela.op-lista .barra-inline .trilho { min-width: 14px; }
.tabela.op-lista thead tr:nth-child(2) th { white-space: normal; line-height: 1.2; }
/* O rotulo de uma palavra so ("Escopos", "Fornecer", "Devolver") nao quebra:
 * a coluna estreita o cortava. Um ponto menor e respiro de 4px cabem a 1.280px. */
.tabela.op-lista thead tr:nth-child(2) th { font-size: 12.5px; padding-left: 4px; padding-right: 4px; }
.tabela.op-lista td.pilha {
  white-space: normal; min-width: 150px; max-width: 200px;
  padding-top: 5px; padding-bottom: 5px; line-height: 1.9;
}
.tabela.op-lista td.cel-prazo { white-space: nowrap; line-height: 1.2; }
.tabela.op-lista .prazo-dias { display: block; font-size: 12px; font-weight: 500; opacity: 0.9; }
/* O prazo herdado de projeto ligado (29/09/2026): a data nao e deste projeto, e
 * a marca diz de quem - em italico, abaixo dos dias, sem competir com eles. */
.tabela.op-lista .prazo-herdado { display: block; font-size: 11.5px; font-style: italic; opacity: 0.85; }
/* Par medido / autorizado numa celula: o medido em cima, no tamanho da tabela,
 * e o autorizado embaixo, menor e apagado - como o `.sub` da obra sob o projeto. */
.tabela.op-lista td.par { line-height: 1.2; white-space: nowrap; }
.tabela.op-lista td.par .par-sub { display: block; font-size: 12.5px; color: var(--muted); }
.tabela.op-lista td.par .par-sub .num { font-size: 12.5px; color: inherit; }
/* O total geral de US (30/09/2026) mora no rodape escuro: o autorizado embaixo
 * troca o cinza da tabela pela tinta fraca da faixa, senao some no verde. */
.tabela.op-lista tfoot td.par .par-sub { color: var(--faixa-ink-fraca); }
.tabela.op-lista tfoot td.par .par-sub .num { color: inherit; }
.tabela.op-lista th .th-sub {
  display: block; font-size: 12px; font-weight: 600; color: var(--faixa-ink-fraca);
}
.tabela.op-lista .barra-inline .pct-mini { font-size: 13px; }
.tabela.op-lista th, .tabela.op-lista td { padding-left: 6px; padding-right: 6px; }
.tabela.op-lista thead.escuro th { font-size: 13.5px; }
.tabela.op-lista td.pilha { min-width: 120px; }
/* Selos da Etapa um tico menores, para os dois de material ("1 ação",
 * "1 exced.") caberem lado a lado sob o da etapa - empilhados um por linha, a
 * linha do projeto triplicava. */
.tabela.op-lista td.pilha .chip { font-size: 12px; padding: 1px 6px; margin-right: 0; }
/* Os selos de material dobram para a linha de baixo quando nao cabem lado a lado
 * (09/10/2026): em nowrap "1 diverg. 2 repos." furava a coluna em 102 linhas a
 * 1.366px. Cada selo continua inteiro. */
.tabela.op-lista td.pilha .pilha-par { white-space: normal; }
.tabela.op-lista td.cod .sub .sem-material { color: var(--aviso); font-weight: 600; }
.tabela.op-lista thead tr:nth-child(2) th:has(.th-sub) { white-space: nowrap; }
.tabela.op-lista td.col-projeto { padding-right: 4px; }
/* Zebra, que a maquete traz e que numa tabela de 18 colunas segura o olho na
 * linha. Nao pinta a linha vencida nem a celula de prazo: as duas ja falam por
 * cor, e a zebra por cima apagaria o sinal. */
.tabela.op-lista tbody tr:nth-child(even):not(.vencido):not(:hover):not(.grupo-linha) > td:not(.cel-prazo):not(.prog-passou) {
  background: var(--panel-2);
}
/* A faixa de etapa (02/10/2026, dono do produto: "deixe mais destacado as
 * divisoes das etapas"). Ate aqui era o mesmo --panel-2 da zebra, e numa lista
 * zebrada a divisao virava mais uma linha par. Agora leva a cor da etapa - os
 * tons do chip e da pizza -, um filete grosso em cima e a esquerda, o icone e
 * o nome em destaque. */
.tabela.op-lista tr.grupo-etapa { --faixa-cor: var(--muted-claro); --faixa-bg: var(--neutro-bg); }
.tabela.op-lista tr.grupo-etapa.tom-indigo { --faixa-cor: var(--indigo); --faixa-bg: var(--indigo-bg); }
.tabela.op-lista tr.grupo-etapa.tom-aviso  { --faixa-cor: var(--aviso);  --faixa-bg: var(--aviso-bg); }
.tabela.op-lista tr.grupo-etapa.tom-info   { --faixa-cor: var(--info);   --faixa-bg: var(--info-bg); }
.tabela.op-lista tr.grupo-etapa.tom-ok     { --faixa-cor: var(--primary-forte); --faixa-bg: var(--ok-bg); }
.tabela.op-lista tr.grupo-etapa.tom-neutro-forte { --faixa-cor: var(--muted); --faixa-bg: var(--neutro-bg); }
.tabela.op-lista.densa tr.grupo-etapa > td {
  background: var(--faixa-bg); color: var(--ink);
  border-top: 4px solid var(--faixa-cor); border-bottom: 1px solid var(--faixa-cor);
  height: 52px; font-size: 15px;
}
.tabela.op-lista tr.grupo-etapa > td:first-child { box-shadow: inset 6px 0 0 var(--faixa-cor); padding-left: 14px; }
/* Nos totais (faixa de etapa e rodape) o "R$" dobrava para cima do numero e
   punha o Saldo R$ uma linha abaixo do Saldo US (09/10/2026). O cabecalho ja
   diz R$; o numero fica numa linha so, na altura dos vizinhos. */
.tabela.op-lista tr.grupo-etapa .moeda,
.tabela.op-lista tfoot .moeda { display: none; }
.tabela.op-lista tr.grupo-etapa td.n .num,
.tabela.op-lista tfoot td.n .num { white-space: nowrap; }
/* Numa linha so, o total em milhoes (-3.106.408,74) passava da celula abaixo de
 * 1366px: a letra encolhe ate caber (regua). */
@media (max-width: 1365px) {
  .tabela.op-lista.densa tr.grupo-etapa td.n .num,
  .tabela.op-lista.densa tfoot td.n .num { font-size: 12.5px; }
}
@media (max-width: 1279px) {
  .tabela.op-lista.densa tr.grupo-etapa td.n .num,
  .tabela.op-lista.densa tfoot td.n .num { font-size: 11px; letter-spacing: -0.2px; }
}
.tabela.op-lista tr.grupo-etapa .etapa-icone {
  width: 24px; height: 24px; border-radius: 50%; margin-right: 8px; vertical-align: middle;
  display: inline-flex; align-items: center; justify-content: center;
}
.tabela.op-lista tr.grupo-etapa .etapa-nome {
  font-size: 17px; font-weight: 750; letter-spacing: 0.01em; vertical-align: middle;
}
.tabela.op-lista tr.grupo-etapa .grupo-conta { color: var(--ink-medio); }

/* A lista em TELA CHEIA (29/09/2026, dono do produto: "desfaca esse bloco dentro
 * da tela, deixe os projetos, as linhas, como se fosse em tela cheia"). Ate aqui
 * a tabela morava numa caixa de rolagem propria - 790px de altura, barra de
 * rolagem dos dois lados, o rodape "N projetos" preso no fundo da caixa - e a
 * pagina rolava por fora dela: duas rolagens aninhadas.
 *
 * Agora a pagina e a unica rolagem. A caixa perde a altura maxima e o
 * `overflow` (sem ele ela deixa de ser container, e o `sticky` do cabecalho
 * passa a grudar na JANELA); a barra do topo sobe com a pagina nesta tela, para
 * o cabecalho escuro grudar no topo sem conta de altura nenhuma; e o rodape de
 * total volta a ser a ultima linha, em vez de uma faixa fixa no pe da tela. */
.tabela-wrap.rolagem:has(.op-lista) { max-height: none; overflow: visible; }
.painel:has(.op-lista) .topbar { position: static; }
.tabela.op-lista tfoot td { position: static; }
/* Largura toda: o limite de 1600px e a margem de 24px valem para as telas de
 * leitura; aqui a tabela e o assunto. */
.conteudo:has(.op-lista) { max-width: none; padding-left: var(--e-3); padding-right: var(--e-3); }

/* E caber de lado sem rolar, medido com a regua em 1600x900 (vista completa: a
 * tabela tinha 1.583px numa janela de 1.304). A coluna Projeto sozinha tinha
 * 357px, porque a linha de baixo ("orcado nos projetos 1663364, 1634216 e mais
 * 13") nao quebrava: agora quebra, e a coluna fica no tamanho do numero. */
.tabela.op-lista td.col-projeto { white-space: normal; min-width: 120px; max-width: 190px; }
.tabela.op-lista td.col-projeto .sub { display: block; white-space: normal; line-height: 1.25; }
.tabela.op-lista th, .tabela.op-lista td { padding-left: 5px; padding-right: 5px; }
.tabela.op-lista tbody tr:hover > td:not(.cel-prazo):not(.prog-passou) { background: var(--primary-suave); }
/* O selo "sem material" ao lado do numero, e nao embaixo: embaixo ele dobrava
 * a altura da linha, e metade da lista ficava com o dobro da altura. */
.tabela.op-lista td.col-projeto { white-space: nowrap; }
.tabela.op-lista td.col-projeto .chip { margin-left: var(--e-1); vertical-align: 1px; }

.notas-rodape { margin-top: var(--e-3); }
.notas-rodape > summary {
  cursor: pointer; font-size: 13px; font-weight: 600; color: var(--muted);
}
.notas-rodape > summary:hover { color: var(--ink-medio); }

/* ============================================ AGENDA SEMANAL (Programação)
 * Duas pistas por dia, e a razão é medida, não estética: das entradas de
 * programação da base, 192 vêm do portal e declaram **só o dia** - nenhuma tem
 * hora. As 4 que trazem janela são os PDFs do SOD.
 *
 * Uma grade só de hora posicionaria 4 documentos e esconderia 192. Um dia
 * inteiro sem grade jogaria fora a única informação de janela que existe. Por
 * isso a coluna do dia tem uma FAIXA DE DIA INTEIRO no topo, para quem só
 * declara data, e a grade 8h-18h abaixo, para quem declara janela. Nada é
 * inventado (nenhum documento ganha hora que não tem) e nada some. */
/* A agenda ocupa a largura toda desde 05/10/2026 ("aumente o tamanho de tela da
 * programação"): o painel de avisos que ficava ao lado desceu para o fim da
 * página, fechado, e a página usa a gaveta do Controle Operacional - a barra
 * lateral aberta flutua por cima em vez de tirar 176px das sete colunas. */
.agenda-layout { margin-top: var(--e-3); }
.prog-filtros { margin-top: var(--e-3); }

.agenda-barra {
  display: flex; align-items: center; gap: var(--e-4); flex-wrap: wrap;
  padding: var(--e-3) var(--e-4); border-bottom: 1px solid var(--line);
}
.agenda-periodo { font-size: 17px; font-weight: 700; color: var(--titulo); }
.nav-periodo { display: inline-flex; align-items: center; gap: var(--e-2); margin-left: auto; }
.nav-periodo a, .nav-periodo span.inativo {
  display: grid; place-items: center; min-width: 36px; height: 36px; padding: 0 12px;
  border: 1px solid var(--line); background: var(--panel); border-radius: var(--r-sm);
  color: var(--primary); text-decoration: none; font-size: 14px; font-weight: 600;
}
.nav-periodo a:hover { background: var(--primary-suave); border-color: var(--line-forte); }
.nav-periodo span.inativo { color: var(--muted-claro); background: var(--panel-2); }

/* A AGENDA, em cartões empilhados (09/09/2026).
 *
 * Sete colunas iguais, e nenhuma delas se reparte. A versão anterior era uma
 * grade de horas com blocos em `position: absolute` e uma faixa por
 * sobreposição; a largura do dia crescia em frações para compensar. Não
 * escalava: a semana tem largura fixa, e na semana de 07/09 quatro dias
 * pediram 3fr ao mesmo tempo — todos voltaram a ~30px, e `2920-2026` saiu um
 * algarismo por linha.
 *
 * O mínimo de 124px é o piso de legibilidade, e ele foi MEDIDO na tela:
 * `4267-2026` em 13px negrito ocupa 71,4px, e com as bordas e os dois paddings
 * (cartão e pilha) isso fecha em ~100px; 124px deixa a folga do `10:15–17:15`,
 * que é a linha mais larga do cartão. Abaixo disso a semana passa a ROLAR na
 * horizontal em vez de espremer - a coluna estreita é o defeito que esta tela
 * existe para não ter, e uma barra de rolagem é o preço menor. Nas larguras
 * medidas (1280 a 1920) nenhuma rola: o dia fica entre 140px e 186px. */
.agenda { display: grid; grid-template-columns: repeat(7, minmax(124px, 1fr)); overflow-x: auto; }
.agenda-col { border-right: 1px solid var(--line-2); min-width: 0; }
.agenda-col:last-child { border-right: 0; }
.agenda-col.hoje { background: var(--primary-suave); }
.agenda-cab {
  padding: 10px 4px; text-align: center; font-size: 13px; color: var(--muted);
  border-bottom: 1px solid var(--line);
  text-transform: uppercase; letter-spacing: 0.03em;
}
.agenda-cab b { display: block; font-size: 17px; color: var(--titulo); font-weight: 700; }
.agenda-col.hoje .agenda-cab b { color: var(--primary); }
/* Quantos documentos o dia tem. Fica no cabeçalho porque a pilha pode passar
 * da dobra: sem o número, um dia de 9 leria-se como um dia de 5. */
.agenda-cab .conta {
  display: inline-block; margin-top: 3px; padding: 0 6px; border-radius: 9px;
  background: var(--line); color: var(--ink-medio); font-size: 11.5px; font-weight: 700;
}

/* A coluna do dia vai ate o pe da janela: a semana se le como uma folha de
 * agenda, e nao como uma faixa no meio da tela com metade da altura vazia. */
.agenda-pilha {
  padding: 6px; display: flex; flex-direction: column; gap: 6px;
  min-height: max(260px, calc(100vh - 470px));
}

/* O cartão. Empilha, não posiciona — a altura é o conteúdo, e a hora é texto.
 *
 * A COR é do bloco inteiro, e isso não é enfeite. Na grade de horas o documento
 * era um retângulo pintado, e a semana se lia pela cor antes de se ler número
 * nenhum. A primeira versão empilhada trocou o retângulo por um filete de 3px na
 * borda esquerda: legível e cinza — "a alteração veio de uma forma nada visual",
 * disse o dono do produto, e estava certo. A tinta volta aqui pelos três lugares
 * que o bloco antigo usava (faixa cheia, contorno de 2px e fundo claro), sobre a
 * pilha que resolveu a legibilidade. As duas coisas nunca competiram; faltava a
 * segunda.
 *
 * As cores continuam sendo o vocabulário semântico (`ok`/`aviso`/`erro`/`info`/
 * `indigo`/`neutro`), o mesmo mapa do chip - um documento APROVADO tem a mesma
 * tinta na agenda e na lista. */
.cartao {
  display: block; border-radius: var(--r-sm); overflow: hidden;
  background: var(--panel); border: 2px solid var(--neutro);
  font-size: 12.5px; line-height: 1.3; text-decoration: none; min-width: 0;
  box-shadow: var(--sombra);
  transition: box-shadow .08s ease, transform .08s ease;
}
/* A faixa cheia do topo, herdeira do `.evento-cab`: é ela que faz a cor virar
 * BLOCO e não filete. Carrega os dois rótulos (tipo e selo); o dado - número,
 * hora, obra - fica no corpo, sobre fundo claro, que é onde se lê. */
.cartao-topo {
  display: flex; align-items: center; gap: 5px; justify-content: space-between;
  padding: 3px 7px; background: var(--neutro); color: var(--on-primary);
}
.cartao-corpo { display: block; padding: 6px 8px 7px; }
/* Interativo: o cartão inteiro é `<a>`, e o hover LEVANTA o bloco em vez de só
 * trocar o fundo. Numa pilha de cinco cartões coloridos, clarear um fundo já
 * claro não diz qual está sob o cursor. `focus-visible` porque a agenda imprime
 * e também se navega por teclado. */
.cartao:hover { box-shadow: 0 3px 8px rgba(15, 59, 31, 0.22); transform: translateY(-1px); }
.cartao:focus-visible { outline: 3px solid var(--primary); outline-offset: 1px; }
.cartao-tipo {
  font-size: 11.5px; font-weight: 700; letter-spacing: 0.04em;
  text-transform: uppercase; color: inherit;
}
/* Numero e hora com os algarismos da tabela (`tabular-nums`), como o `.num` do
 * resto do painel; um ponto maiores desde que a agenda ganhou a largura toda. */
.cartao-num {
  display: block; font-weight: 700; color: var(--ink); font-size: 14px;
  overflow-wrap: anywhere; font-variant-numeric: tabular-nums;
}
.cartao-num.sem { font-weight: 400; font-style: italic; color: var(--muted); }
.cartao-hora { display: block; font-weight: 700; color: var(--ink-medio); font-size: 13px; font-variant-numeric: tabular-nums; }
.cartao-sub { display: block; color: var(--muted); font-size: 12.5px; overflow-wrap: anywhere; }
.cartao.cancelado .cartao-num { text-decoration: line-through; color: var(--muted); }
/* Cancelado esmaece a faixa em vez de perder a cor: o estado continua valendo
 * (um cancelado APROVADO não é um cancelado RECUSADO), mas o bloco não pode
 * disputar o olho com o que ainda vai acontecer. */
.cartao.cancelado { box-shadow: none; }
.cartao.cancelado .cartao-topo { opacity: .5; }

/* Contorno + faixa + fundo, por estado. O fundo é a versão `-bg` da mesma cor,
 * a mesma que o `.chip` usa - é o que faz o cartão ser um quadrado colorido
 * visto de longe, e não um cartão branco com detalhe. */
.cartao.ok     { border-color: var(--ok);     background: var(--ok-bg); }
.cartao.aviso  { border-color: var(--aviso);  background: var(--aviso-bg); }
.cartao.erro   { border-color: var(--erro);   background: var(--erro-bg); }
.cartao.info   { border-color: var(--info);   background: var(--info-bg); }
.cartao.indigo { border-color: var(--indigo); background: var(--indigo-bg); }
.cartao.neutro { border-color: var(--neutro); background: var(--neutro-bg); }
.cartao.neutro-forte { border-color: var(--ink-medio); background: var(--neutro-bg); }
.cartao.ok     .cartao-topo { background: var(--ok); }
.cartao.aviso  .cartao-topo { background: var(--aviso); }
.cartao.erro   .cartao-topo { background: var(--erro); }
.cartao.info   .cartao-topo { background: var(--info); }
.cartao.indigo .cartao-topo { background: var(--indigo); }
.cartao.neutro .cartao-topo { background: var(--neutro); }
.cartao.neutro-forte .cartao-topo { background: var(--ink-medio); }

/* O selo da autorização. Existe SÓ onde a pergunta existe: um PLV sem `✓` não
 * está esperando nada — nenhuma das 93 OMBs do corpus cita um PLV. Por isso ele
 * não reserva espaço (não é um slot vazio), aparece só quando há AUT.
 *
 * Dentro da faixa ele inverte: pastilha branca sobre a tinta do estado. Verde
 * sobre verde sumiria justamente no caso mais comum, o do PDE aprovado. */
.selo-aut {
  flex: none; display: inline-flex; align-items: center; gap: 1px;
  padding: 0 5px; border-radius: 9px; font-size: 11px; font-weight: 700;
  background: var(--ok); color: var(--on-primary);
}
.cartao-topo .selo-aut { background: var(--panel); color: var(--ink); }

.agenda-vazia { padding: 26px 20px; text-align: center; color: var(--muted); font-size: 15px; }

/* Tirar da programacao (14/10/2026): cancelada ou nao realizada. Fica logo
 * abaixo do cartao, fora dele (o cartao e um <a>), pequeno e cinza - e a acao
 * rara da agenda, e nao pode disputar o olho com o que vai acontecer. Aberto,
 * o formulario empilha na largura da coluna, que tem 124 px no minimo. */
.cartao-acao { margin-top: -3px; font-size: 11.5px; }
.cartao-acao > summary {
  cursor: pointer; color: var(--muted); padding: 1px 4px; list-style: none;
  text-align: right;
}
.cartao-acao > summary::-webkit-details-marker { display: none; }
.cartao-acao > summary:hover { color: var(--ink); text-decoration: underline; }
.cartao-acao.sugerida > summary { color: var(--ink-medio); font-weight: 700; }
.cartao-acao form {
  display: flex; flex-direction: column; gap: 4px; padding: 6px;
  border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--panel);
}
.cartao-acao select, .cartao-acao input, .cartao-acao button {
  width: 100%; min-width: 0; box-sizing: border-box; font-size: 12px;
}
.cartao-acao button { padding: 4px 6px; }
.cartao-saida { font-weight: 700; color: var(--ink-medio); }
/* A sugestao de reprogramacao: um "?" na faixa, como o selo da AUT. */
.selo-reprog {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  min-width: 16px; padding: 0 4px; border-radius: 9px; font-size: 11px; font-weight: 800;
  background: var(--aviso); color: var(--on-primary);
}
.cartao-topo .selo-reprog { background: var(--panel); color: var(--aviso); }
.agenda-retiradas { margin: 0; padding: 8px 16px 0; }

/* ------------------------------------------------- painel Avisos e Pendências
 * O lateral do print. Alimentado SÓ por sinais que a tela já calcula
 * (divergência de estado, pedido órfão, atrasado, sem PDE) - nenhum número
 * novo, e cada linha leva ao lugar onde o sinal se resolve. */
.avisos { overflow: hidden; }
.avisos-prog .avisos-lista { padding: var(--e-3) 0 0; max-width: 720px; }
.avisos-cabeca {
  background: var(--titulo); color: var(--on-primary);
  font-size: 17px; font-weight: 800; padding: 12px var(--e-4);
}
.avisos-lista { padding: var(--e-3); display: flex; flex-direction: column; gap: var(--e-3); }
.aviso-cartao {
  border: 1px solid var(--line); border-left: 4px solid var(--info);
  border-radius: var(--r-sm); background: var(--panel);
  padding: 10px 12px; font-size: 14px; line-height: 1.4;
  text-decoration: none; color: var(--ink-medio); display: block;
}
.aviso-cartao:hover { background: var(--panel-2); }
.aviso-cartao b { display: block; color: var(--titulo); font-size: 15px; }
.aviso-cartao.alerta-erro { border-left-color: var(--erro); }
.aviso-cartao.alerta-aviso { border-left-color: var(--aviso); }

/* ------------------------------------------------------------------ impressão
 * A agenda imprime: é a folha que vai para o campo. O que sai é a navegação de
 * semana; as sete colunas e os cartões ficam.
 *
 * Desde 09/09/2026 não há mais `position: absolute` a preservar - a hora é
 * texto dentro do cartão, e texto imprime sem truque. Foi o efeito colateral
 * mais barato da mudança: a folha impressa passou a carregar a mesma informação
 * que a tela, em vez de depender de a impressora respeitar posicionamento. */
@media print {
  .agenda-barra, .nav-periodo, .avisos, .avisos-prog { display: none !important; }
  .agenda-pilha { min-height: 0; }
  .cartao { box-shadow: none; transform: none; }
}

/* ---------------------------------------- texto claro sobre fundo colorido
 * O navegador descarta cor de fundo ao imprimir, por padrão. Nos componentes
 * abaixo o fundo NÃO é enfeite - ele carrega o significado, e o texto por cima
 * é branco. Sem esta regra a célula de prazo vencido imprime branco no branco:
 * some da folha justamente a linha que alguém foi conferir no papel.
 *
 * `print-color-adjust: exact` pede a tinta de volta. Onde a impressora recusar,
 * o pior caso continua sendo perda de cor - nunca perda de texto -, porque a
 * segunda regra devolve tinta escura a quem estava em branco. */
@media print {
  .tabela td.cel-prazo, .card.kpi-solido, .selo-aut, .avisos-cabeca,
  .tabela tfoot td, .tabela tfoot th, .chip, .tag, .badge,
  /* A faixa do cartao e o fundo dele. Na folha que vai para o campo a cor do
   * estado e o que se le primeiro; sem a tinta, sete colunas de cartoes ficam
   * todas iguais e a agenda impressa perde o que a de tela tem. */
  .cartao, .cartao-topo,
  /* A linha de item de RMD em aberto: sem a tinta, a folha impressa nao
   * distingue o que falta devolver do que ja foi certificado. O texto dela e
   * ESCURO de proposito - se a impressora recusar o fundo, o pior caso e uma
   * linha sem cor, nunca uma linha ilegivel. */
  .tabela tbody tr.destaque-vermelho td {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
}
@media print and (monochrome) {
  /* Sem cor, a faixa vira uma tarja clara com regua embaixo: o cartao continua
   * sendo um bloco, e o tipo continua legivel. Perde-se o estado, nunca texto. */
  .cartao { background: transparent !important; border-color: var(--line-forte) !important; }
  .cartao-topo {
    background: var(--panel-2) !important; color: var(--ink) !important;
    border-bottom: 1px solid var(--line-forte);
  }
  .tabela td.cel-prazo, .card.kpi-solido, .selo-aut, .avisos-cabeca {
    background: transparent !important;
    color: var(--ink) !important;
    border: 1px solid var(--line-forte);
  }
  .card.kpi-solido .rot, .card.kpi-solido .big, .card.kpi-solido .pe {
    color: var(--ink) !important;
  }
}

/* Observacao do BMD organizada (25/09/2026): um cartao por boletim, fora da
   tabela; em cada um, a etiqueta do poste a esquerda e o que a Copel escreveu a
   direita. ``pre-line`` guarda a quebra que junta a continuacao ao item. */
.tabela tr.bmd-detalhe td { border-top: 0; padding-top: 0; color: var(--muted); font-size: 13px; }
.obs-link { margin-left: var(--e-2); font-size: 13px; }
.obs-titulo { font-size: 15px; margin: var(--e-5) 0 var(--e-3); color: var(--titulo); }
.obs-lista { display: flex; flex-direction: column; gap: var(--e-3); }
.obs-cartao { background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-md);
  padding: var(--e-3) var(--e-4); }
.lista-citacoes .obs-cartao { margin-top: var(--e-1); }
.obs-cab { display: flex; flex-wrap: wrap; align-items: center; gap: var(--e-2);
  padding-bottom: var(--e-2); margin-bottom: var(--e-2); border-bottom: 1px solid var(--line); }
.obs-data { color: var(--ink-medio); font-size: 14px; }
.obs-tema { font-weight: 600; color: var(--ink); font-size: 14px; }
.obs-conta { margin-left: auto; color: var(--muted); font-size: 13px; }
.obs-igual { margin: 0; color: var(--muted); font-size: 14px; }
.obs-secao { margin: var(--e-3) 0 var(--e-1); font-size: 12px; text-transform: uppercase;
  letter-spacing: .05em; color: var(--ink-medio); }
.obs-itens { list-style: none; margin: 0; padding: 0; display: grid;
  grid-template-columns: 9.5rem minmax(0, 1fr); column-gap: var(--e-3); row-gap: 8px; }
.obs-itens li { display: contents; }
.obs-rotulo { text-align: right; }
.obs-rotulo .chip { white-space: normal; text-align: center; }
.obs-ponto { color: var(--muted-claro); padding-right: 4px; }
.obs-texto { white-space: pre-line; font-size: 14px; line-height: 1.45; color: var(--ink); overflow-wrap: anywhere; }
.obs-itens li.destaque .obs-texto { font-weight: 600; }
@media (max-width: 640px) {
  .obs-itens { grid-template-columns: 4.75rem minmax(0, 1fr); column-gap: var(--e-2); }
  .obs-cartao { padding: var(--e-2) var(--e-3); }
  .obs-conta { margin-left: 0; }
}
.lista-citacoes { margin: 0; padding-left: var(--e-4); display: flex; flex-direction: column; gap: var(--e-2); }
/* Janela estreita (1.280px): o total geral do rodape, o unico numero que ainda
 * furava a coluna por poucos px, desce um ponto. */
@media (max-width: 1400px) {
  .tabela.op-lista th, .tabela.op-lista td { padding-left: 4px; padding-right: 4px; }
  .tabela.op-lista tfoot td { font-size: 13.5px; }
  .tabela.op-lista tfoot td.n { padding-left: 3px; padding-right: 3px; }
  .tabela.op-lista td.col-projeto { font-size: 13.5px; }
  .tabela.op-lista td.cod.col-projeto { white-space: normal; }
  .tabela.op-lista td.n .chip { padding-left: 8px; padding-right: 8px; }
  .tabela.op-lista .barra-inline { gap: 4px; }
  .tabela.op-lista .barra-inline .trilho { min-width: 6px; }
}

/* Regiao da obra: a sigla do orgao emissor (05/10/2026). Um chip so para todas
   - a sigla ja diz o setor, e cor por sigla seria legenda para decorar. */
.chip.regiao { background: var(--indigo-bg); color: var(--indigo); font-variant-numeric: tabular-nums; letter-spacing: 0.02em; }

/* Valor escolhido entre documentos que discordam: o do mais recente, com a
   marca e o outro nome no title (services/local_fiscal). */
.escolhido.diverge { text-decoration: underline dotted var(--aviso); text-underline-offset: 3px; cursor: help; }
.marca-diverge { color: var(--aviso); font-weight: 700; }

/* Login e cadastro de usuarios (05/10/2026). A tela de entrada nao tem sidebar:
 * uma caixa no meio da pagina, com o logotipo escrito, como o da barra. */
body.tela-login { min-height: 100vh; display: grid; place-items: center; background: var(--surface); }
.login-caixa { width: min(380px, calc(100vw - 32px)); background: var(--panel); border-radius: 12px;
  padding: var(--e-5) var(--e-5); box-shadow: 0 6px 24px rgba(0, 0, 0, 0.08); }
.login-caixa h1 { font-size: 20px; margin: var(--e-3) 0 var(--e-4); }
.login-marca strong { font-size: 26px; }
.login-marca small { display: block; letter-spacing: 0.12em; font-size: 11px; }
.login-form { display: grid; gap: 6px; }
.login-form input { padding: 9px 10px; font-size: 15px; border: 1px solid var(--line); border-radius: 8px; }
.login-form button { margin-top: var(--e-3); }
.login-pe { margin-top: var(--e-4); font-size: 13px; color: var(--ink-medio); }
.aviso-erro { background: var(--erro-bg); color: var(--erro); padding: 10px 14px; border-radius: 8px; }
.form-cadastro { display: flex; flex-wrap: wrap; gap: var(--e-3); align-items: flex-end; padding: var(--e-4); }
.form-cadastro .campo { display: grid; gap: 4px; }
/* `font: inherit` nos campos e botoes (05/10/2026): controle de formulario nao
 * herda a fonte, e os campos e o Salvar/Excluir saiam na letra padrao do
 * navegador, diferente da Inter do resto. Os algarismos sao os tabulares do
 * `.num`, para data e hora alinharem como na tabela. */
.form-cadastro input, .form-cadastro select { padding: 7px 9px; border: 1px solid var(--line); border-radius: 6px; font: inherit; font-variant-numeric: tabular-nums; }
.form-linha { display: inline-flex; gap: 6px; align-items: center; margin-right: var(--e-3); }
.form-linha input { padding: 5px 8px; border: 1px solid var(--line); border-radius: 6px; width: 140px; font: inherit; font-size: 14px; font-variant-numeric: tabular-nums; }
.form-linha input.hora { width: 96px; }
.botao-secundario { padding: 5px 10px; border: 1px solid var(--line); border-radius: 6px; background: transparent; cursor: pointer; font: inherit; font-size: 14px; }
.form-sair { margin: 0; }
/* So a familia herda: `font: inherit` e `color: inherit` desfaziam o tamanho e a
 * cor do `.item`, e o Sair saia apagado ao lado do nome do usuario. */
.form-sair button.item { width: 100%; background: none; border: 0; border-left: 4px solid transparent; font-family: inherit; cursor: pointer; text-align: left; }
.titulo-secao { margin-top: var(--e-5); }

/* Programacao adicionada a mao, o cartao OL (05/10/2026). O mesmo formato do
 * PDE - faixa, linha forte, hora, sub -, em VERDE (dono do produto: "deixe como
 * a cor verde o quadradinho lancado manualmente"), com a faixa "OL" e o selo
 * "manual" para ninguem o tomar por documento da Copel. O verde e o do `ok`,
 * que nenhum documento usa: o PDF nunca diz "Executado". */
.cartao.ol { border-color: var(--ok); background: var(--ok-bg); }
.cartao.ol .cartao-topo { background: var(--ok); }
.selo-manual {
  font-size: 10px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
  padding: 0 5px; border-radius: 3px; background: rgba(255, 255, 255, 0.25);
}
.cartao-obs { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.selo-ol {
  display: inline-block; padding: 0 5px; border-radius: 3px; background: var(--ok);
  color: var(--on-primary); font-size: 10.5px; font-weight: 700;
}

/* O botao "+ Adicionar programacao", ao lado das setas da semana. E o <summary>
 * de um <details>: o painel abre POR CIMA da agenda, na largura da barra, sem
 * JavaScript. */
.agenda-barra { position: relative; }
.adicionar > summary { list-style: none; display: inline-grid; place-items: center; min-height: 36px; padding: 0 16px; font-size: 14px; border-radius: var(--r-sm); }
.adicionar > summary::-webkit-details-marker { display: none; }
.adicionar[open] > summary { background: var(--primary); }
.adicionar-painel {
  position: absolute; left: 0; right: 0; top: 100%; z-index: 30;
  background: var(--panel); border: 1px solid var(--line-forte); border-top: 3px solid var(--ok);
  box-shadow: 0 10px 28px rgba(15, 59, 31, 0.22); padding: var(--e-4);
}
/* O X do painel (09/10/2026, dono do produto: "um x para fechar caso tenha
 * apertado por engano", e depois "pequeno no canto superior esquerdo em
 * vermelho, nao uma faixa" e "em formato quadrado"): um quadrado vermelho de
 * 24px, de canto levemente arredondado, no canto de cima a
 * esquerda; o painel desce o conteudo o bastante para ele nao cobrir o 1o campo. */
/* O painel mora dentro de `.nav-periodo`, e `.nav-periodo a` (o botao das setas)
 * dava ao X 36px, borda e padding - a "faixa" que o dono do produto viu. */
.nav-periodo .adicionar-painel .painel-fechar {
  min-width: 0; padding: 0; border: none;
  position: absolute; top: 8px; left: 8px; z-index: 1; width: 24px; height: 24px;
  display: inline-grid; place-items: center; border-radius: 4px;
  background: var(--erro); color: var(--on-primary);
  font-size: 17px; font-weight: 700; line-height: 1; text-decoration: none;
}
.nav-periodo .adicionar-painel .painel-fechar:hover { background: var(--erro); border: none; filter: brightness(0.88); color: var(--on-primary); text-decoration: none; }
.adicionar-painel .painel-fechar:focus-visible { outline: 2px solid var(--erro); outline-offset: 2px; }
.adicionar-painel { padding-top: calc(var(--e-4) + 22px); }
.adicionar-grade { display: grid; grid-template-columns: minmax(0, 1fr) 260px; gap: var(--e-5); align-items: start; }
@media (max-width: 900px) { .adicionar-grade { grid-template-columns: 1fr; } }
.form-adicionar { padding: 0; }
.form-adicionar .campo-largo input { width: 300px; }
.form-adicionar .aviso-erro { flex-basis: 100%; margin: 0; }
.form-adicionar label { font-size: 13px; font-weight: 600; color: var(--ink-medio); display: inline-flex; gap: 6px; align-items: center; }
.campo-fixo { padding: 7px 0; font-weight: 600; color: var(--ok); }
.par-horas { display: inline-flex; gap: 6px; align-items: center; color: var(--muted); }
.nota-campo { font-size: 12px; font-weight: 400; color: var(--muted); }
/* O numero da area: o mesmo no rotulo do campo e no cartao-modelo. */
.area {
  display: inline-grid; place-items: center; width: 17px; height: 17px; flex: none;
  border-radius: 50%; background: var(--titulo); color: var(--on-primary);
  font-size: 10.5px; font-weight: 700; font-variant-numeric: tabular-nums;
}
.modelo-cartao { margin: 0; }
.modelo-cartao figcaption { font-size: 13px; font-weight: 600; color: var(--ink-medio); margin-bottom: var(--e-2); }
.cartao-modelo { pointer-events: none; }
.cartao-modelo:hover { box-shadow: none; transform: none; }
.cartao-modelo .cartao-topo .area { margin-left: auto; background: rgba(255, 255, 255, 0.3); }
.linha-modelo { display: flex; gap: 6px; align-items: center; justify-content: space-between; }
.linha-modelo > :first-child { min-width: 0; }
.agenda-aviso { margin: var(--e-2) var(--e-4) 0; }

.adicionadas .historico summary { cursor: pointer; font-size: 12px; }
.adicionadas .historico ul { margin: 4px 0 0; padding-left: 16px; font-size: 12px; }
.adicionadas .tabela-wrap { margin-top: var(--e-3); }
/* O formulario de alterar mora numa celula: em linha ele somava ~650 px e a tabela
 * passava de 1.500 px, rolando de lado ate em 1920 (pego pela regua do gestor
 * simulado, 15/10/2026). Aqui ele dobra dentro da celula. */
.adicionadas .form-linha { display: flex; flex-wrap: wrap; max-width: 236px; margin-right: 0; }
.adicionadas .form-linha input { width: 112px; }
.adicionadas .form-linha input.hora { width: 80px; }
/* Titulo e observacao tambem estao nos campos do formulario de alterar: na janela
 * estreita (o notebook a 125% tem ~1.100 px) a coluna repetida sai. */
@media (max-width: 1100px) { .adicionadas .col-repetida { display: none; } }

/* % fornecido (05/10/2026): o selo de alerta ao lado da barra, quando o
 * certificado passou do orcado ou chegou sem item orcado. */
.chip.chip-acima { margin-left: 6px; font-size: 10.5px; padding: 1px 6px; vertical-align: 1px; }

/* RMD em aberto em obra faturada (05/10/2026): uma RMD por linha da celula. */
.rmd-aberta { display: flex; flex-wrap: wrap; gap: 6px; align-items: baseline; }
.rmd-aberta + .rmd-aberta { margin-top: 4px; }
.rmd-aberta .sub { font-size: 12px; color: var(--muted); white-space: nowrap; }
/* Uma linha menor sob o valor da celula (a multa, a hora do lancamento). */
.linha-sub { margin-top: 2px; font-size: 12px; color: var(--muted); white-space: nowrap; }
