/* ============================================================
   WR Timesheet — camada de aplicacao
   Depende de wrsc.css (tokens e base da marca). Aqui ficam
   apenas as classes proprias do timesheet.
   ============================================================ */

/* ---------- topo ---------- */
.topo { background: var(--topo-fundo); color: var(--topo-texto);
  border-bottom: 1px solid color-mix(in srgb, var(--topo-texto) 12%, transparent);
  position: sticky; top: 0; z-index: 40; }
.topo-in { max-width: var(--largura-max); margin: 0 auto; padding: 0 var(--e-5);
  display: flex; align-items: center; gap: var(--e-5); min-height: 58px; flex-wrap: wrap; }
.marca { display: inline-flex; align-items: center; color: var(--topo-texto); }
.marca:hover { text-decoration: none; opacity: .85; }
.marca .wr-logo { color: currentColor; }
.marca-app { font: 500 var(--t-sm)/1 var(--fonte-titulo); margin-left: var(--e-3); padding-left: var(--e-3);
  border-left: 1px solid color-mix(in srgb, var(--topo-texto) 28%, transparent);
  color: color-mix(in srgb, var(--topo-texto) 72%, transparent); letter-spacing: .01em; }

/* min-width:0 e o que impede a barra de INVADIR o bloco do usuario
   quando nao cabe: sem ele, um item flex se recusa a encolher abaixo
   do conteudo e transborda por cima do vizinho. Com ele, os itens
   quebram para a linha de baixo -- feio, mas legivel. */
.nav { display: flex; gap: 2px; flex: 1; flex-wrap: wrap; min-width: 0; }
.nav a { color: color-mix(in srgb, var(--topo-texto) 72%, transparent);
  font: 500 var(--t-sm)/1 var(--fonte-titulo); padding: 8px 12px; border-radius: var(--raio-sm);
  transition: background var(--transicao), color var(--transicao); }
.nav a:hover { background: color-mix(in srgb, var(--topo-texto) 12%, transparent); color: var(--topo-texto); text-decoration: none; }
.nav a.on { background: var(--primaria); color: #fff; font-weight: 600; }

/* flex-shrink 0: o bloco de identidade NAO encolhe.
   Sem isto, a caixa do menu (flex-basis 100%) esmagava tudo a direita
   dela mesmo numa tela de 1600 px: o nome de quem estava logado saia
   cortado ("Contat...") com meia tela de espaco sobrando ao lado, e o
   selo do cliente quebrava em duas linhas dentro da pilula, ficando
   8 px mais alto que os vizinhos. O menu tem recolhimento proprio em
   tela estreita; a identidade nao tem para onde ir. */
.usuario { display: flex; align-items: center; gap: var(--e-3); font-size: var(--t-sm);
  flex: 0 0 auto;
  /* ENCOSTA A DIREITA SEMPRE, e nao so na barra de uma linha.

     Medido: entre 901 e 1099 px a barra quebra em duas faixas de
     proposito (o menu nao cabe ao lado do bloco do usuario). Nessa
     faixa o margin-left:auto so existia dentro do @media de 1100, e
     a identidade ficava COLADA no logo com ~500 px de vazio a
     direita -- a barra parecia partida no meio, que foi a queixa.

     Aqui em cima ele vale nas tres faixas, e a quebra passa a ter
     cara de duas faixas alinhadas em vez de linha interrompida. */
  margin-left: auto;
  color: color-mix(in srgb, var(--topo-texto) 75%, transparent); }
.u-nome { max-width: 180px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sair { color: inherit; border: 1px solid color-mix(in srgb, var(--topo-texto) 28%, transparent);
  padding: 5px 11px; border-radius: var(--raio-sm); font-size: var(--t-xs); font-family: var(--fonte-titulo); font-weight: 500; }
.sair:hover { background: color-mix(in srgb, var(--topo-texto) 12%, transparent); color: var(--topo-texto); text-decoration: none; }

/* ---------- estrutura ---------- */
.conteudo { max-width: var(--largura-larga); margin: 0 auto; padding: var(--e-6) var(--e-5) var(--e-12); }

/* ============================================================
   A MEDIDA DE LEITURA
   ============================================================
   O conteiner estica; o TEXTO nao. Sem esta regra, o painel dava
   paragrafos de 229 caracteres em monitor de 2200 px, e o Sobre, 271
   -- contra os 60 a 90 que se le sem perder a linha.

   Ela pega a prosa pelo nome (`.sub`, `.dica`, `.vazio`, o passo a
   passo do boas-vindas e o paragrafo solto dentro de um cartao), e
   NAO o `p` inteiro: `p` tambem e usado como linha de rotulo ao lado
   de campo e dentro de celula estreita, onde um limite nao ajuda e
   pode atrapalhar.

   `.vazio` e centralizado, entao ganha margem automatica junto: sem
   ela a caixa de 78ch encostaria a esquerda e o texto centralizado
   dentro dela apareceria fora do centro do cartao -- pior do que
   antes. */
.conteudo p,
.conteudo li,
.conteudo .sub,
.conteudo .dica,
.conteudo .wr-aviso,
.conteudo .aviso { max-width: var(--medida); }

/* Centralizado continua centralizado. Sem a margem automatica, a
   caixa de 68ch encosta a esquerda e o texto centralizado DENTRO dela
   aparece fora do centro do cartao -- pior do que a linha longa. */
.conteudo .vazio { max-width: var(--medida); margin-inline: auto; }

/* Onde a medida NAO deve valer: dentro de campo de formulario e de
   celula estreita, um limite nao ajuda e pode espremer. */
.conteudo .campo p,
.conteudo .linha p { max-width: none; }

/* ============================================================
   PROSA EM CELULA DE TABELA
   ============================================================
   Celula IGNORA `max-width` enquanto a tabela tem `width: 100%`:
   medido, `td.dica` ficava com 1090 px e 160 caracteres por linha com
   a regra aplicada -- a regra estava la e nao fazia nada, que e o pior
   tipo de correcao.

   Com `width: auto` a tabela passa a se dimensionar pelo conteudo, e
   ai o limite da celula vale: 1090 -> 476 px, medido na mesma tela.

   `:has()` restringe isso as tabelas que TEM prosa em celula; as de
   numero continuam usando a largura toda. Navegador sem `:has()`
   ignora as duas linhas e a tabela fica como hoje -- degrada para o
   estado anterior, e nao para um estado quebrado. */
.conteudo table:has(td.dica) { width: auto; max-width: var(--largura-max); }
.conteudo td.dica { max-width: var(--medida); }
.rodape { text-align: center; color: var(--texto-3); font-size: var(--t-xs); padding: var(--e-5); }
.sub { color: var(--texto-2); font-size: var(--t-sm); margin: 0 0 var(--e-5); }
.linha { display: flex; gap: var(--e-4); flex-wrap: wrap; align-items: flex-end; }
/* ============================================================
   IRMÃOS DA MESMA LINHA TERMINAM JUNTOS
   ============================================================
   Era `align-items: start`, e isso deixava cada cartão com a altura
   do próprio conteúdo. Medido em quatro telas: 68 px de diferença
   entre cartões lado a lado em Clientes, 48 px no Painel, 17 px em
   Métricas. Ninguém sabe dizer "faltam 48 px", mas todo mundo vê que
   está torto.

   `stretch` é o padrão do grid, e é o certo para grade de cartões: a
   linha fecha reta. Um cartão com pouco conteúdo ganha espaço em
   branco embaixo — que é o preço, e é menor que o desalinho.

   Quem precisar do comportamento antigo em uma grade específica usa
   `.grid.g-topo`, logo abaixo, em vez de mexer aqui.
   ============================================================ */
.grid { display: grid; gap: var(--e-4); }
.grid.g-topo { align-items: start; }
.g2 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.g4 { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
.dir { text-align: right; } .centro { text-align: center; }
.rolar { overflow-x: auto; }
.acoes { display: flex; gap: var(--e-2); flex-wrap: wrap; align-items: center; }
/* ---------- .acoes DENTRO de tabela ---------- */
/* display:flex numa <td> tira a celula da tabela: ela deixa de ser
   table-cell, perde o vertical-align e a altura para de acompanhar a
   linha. O efeito visivel era este: numa linha alta (duas caixas de
   texto empilhadas), os botoes ficavam grudados no topo e a borda de
   baixo da coluna parava numa altura diferente da das outras -- a
   tabela inteira parecia desalinhada, e nao era a tabela, era a
   celula que tinha saido dela.

   A regra de cima continua valendo para as <div class="acoes"> que
   varias telas usam. Aqui so a celula volta a ser celula. */
td.acoes, th.acoes { display: table-cell; vertical-align: middle; }
/* Sem o flex, o espaco entre os botoes voltaria a ser o espaco em
   branco do HTML (~4px). A margem devolve o mesmo respiro do gap, e
   deixa os botoes quebrarem linha sozinhos em tela estreita.

   A margem e a MESMA em todos, e vai a direita -- nao entre um e
   outro. Com margem "entre", o botao que cai para a segunda linha
   herda o recuo do vizinho de cima e nasce deslocado alguns pixels:
   duas linhas de botao que nao se alinham, que e o desalinho que se
   estava consertando. */
td.acoes > *, th.acoes > * { vertical-align: middle; margin: 2px var(--e-2) 2px 0; }
td.acoes > *:last-child, th.acoes > *:last-child { margin-right: 0; }
.dica { color: var(--texto-3); font-size: var(--t-xs); }
.vazio { color: var(--texto-3); text-align: center; padding: var(--e-8) var(--e-4); }

.card { background: var(--superficie); border: 1px solid var(--borda); border-radius: var(--raio);
  box-shadow: var(--sombra-1); padding: var(--e-5); margin-bottom: var(--e-4); }
.card > h2 { border-bottom: 1px solid var(--borda); padding-bottom: var(--e-3); margin-bottom: var(--e-4); }

/* ---------- kpi ---------- */
/* ============================================================
   CARTÕES DA MESMA LINHA TÊM A MESMA ALTURA
   ============================================================
   Medido: os dois primeiros KPIs tinham 114 px (têm barra de
   progresso) e os dois últimos 102 px. A base ficava 12 px acima, e a
   linha inteira parecia torta — foi o que apareceu na captura.

   A causa é `.grid { align-items: start }`, que está certo para grade
   de cartões de conteúdo variável (um cartão curto não deve virar uma
   caixa alta e vazia) e errado para uma faixa de indicadores, onde a
   linha de base é o que faz a leitura funcionar.

   Por isso a correção é no .kpi, e não no .grid: mexer no .grid
   mudaria todas as grades do sistema para consertar uma.

   `align-self: stretch` iguala a altura; a coluna flexível com
   `margin-top:auto` na barra prende a barra embaixo. Resultado:
   rótulo, número e observação alinhados nos quatro, e a barra sempre
   na mesma altura — nos cartões que não têm barra, aquele espaço
   simplesmente fica vazio, que é o correto.
   ============================================================ */
.kpi { background: var(--superficie); border: 1px solid var(--borda); border-radius: var(--raio);
  padding: var(--e-4) var(--e-5); box-shadow: var(--sombra-1);
  align-self: stretch; display: flex; flex-direction: column; }
.kpi .barra { margin-top: auto; }
.kpi .rot { color: var(--texto-2); font: 700 var(--t-xs)/1.3 var(--fonte-titulo); text-transform: uppercase; letter-spacing: .06em; }
.kpi .val { font: 700 var(--t-2xl)/1.1 var(--fonte-titulo); margin-top: var(--e-1); font-variant-numeric: tabular-nums; }
.kpi .obs { color: var(--texto-3); font-size: var(--t-xs); margin-top: 2px; }

/* ---------- botoes ---------- */
.btn { display: inline-flex; align-items: center; gap: 6px; font: 600 var(--t-md)/1 var(--fonte-titulo);
  padding: 9px 16px; border-radius: var(--raio-sm); border: 1px solid var(--primaria);
  background: var(--primaria); color: var(--primaria-texto); cursor: pointer; white-space: nowrap;
  transition: background var(--transicao), border-color var(--transicao), color var(--transicao); }
.btn:hover { background: var(--primaria-hover); border-color: var(--primaria-hover); color: #fff; text-decoration: none; }
.btn-sec { background: transparent; color: var(--primaria-link); border-color: var(--borda-forte); }
.btn-sec:hover { background: var(--primaria-suave); border-color: var(--primaria); color: var(--primaria-link); }
.btn-ok { background: var(--sucesso); border-color: var(--sucesso); color: #fff; }
:root[data-theme="dark"] .btn-ok { color: var(--wr-preto); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .btn-ok { color: var(--wr-preto); } }
.btn-ok:hover { filter: brightness(1.08); background: var(--sucesso); border-color: var(--sucesso); }
.btn-perigo { background: transparent; color: var(--erro); border-color: color-mix(in srgb, var(--erro) 45%, transparent); }
.btn-perigo:hover { background: var(--erro-fundo); color: var(--erro); border-color: var(--erro); }
.btn-p { padding: 5px 10px; font-size: var(--t-sm); font-weight: 500; }

/* ---------- selos ---------- */
/* nowrap: pilula que quebra em duas linhas deixa de ser pilula.
   Aparece na barra do topo, onde o selo do cliente carrega o nome da
   empresa, e valeria em qualquer tabela estreita. */
.badge { display: inline-block; white-space: nowrap; padding: 3px 9px; border-radius: var(--raio-pill);
  font: 700 var(--t-xs)/1.4 var(--fonte-titulo); text-transform: uppercase; letter-spacing: .05em;
  background: var(--superficie-3); color: var(--texto-2); }
.b-admin     { background: var(--primaria); color: #fff; }
.b-gestor    { background: var(--selo-fundo); color: var(--selo-texto); }
.b-consultor { background: var(--superficie-3); color: var(--texto-2); }
.b-rascunho  { background: var(--superficie-3); color: var(--texto-2); }
.b-enviado   { background: var(--atencao-fundo); color: var(--atencao); }
.b-aprovado  { background: var(--sucesso-fundo); color: var(--sucesso); }
.b-rejeitado { background: var(--erro-fundo);    color: var(--erro); }
/* Devolvido para ajuste: e um pedido, nao uma recusa -- por isso usa o
   tom de atencao, nao o de erro. O contorno separa de "enviado". */
.b-em_revisao {
  background: var(--atencao-fundo);
  color: var(--atencao);
  box-shadow: inset 0 0 0 1px currentColor;
}
.b-ativo     { background: var(--sucesso-fundo); color: var(--sucesso); }
.b-pausado   { background: var(--atencao-fundo); color: var(--atencao); }
.b-encerrado { background: var(--superficie-3);  color: var(--texto-2); }
.b-inativo   { background: var(--erro-fundo);    color: var(--erro); }

/* linha de agrupamento em tabela */
td.grupo { background: var(--superficie-3); font-weight: 700; font-family: var(--fonte-titulo); }

/* ---------- avisos ---------- */
.flash { padding: 11px 15px; border-radius: var(--raio-sm); margin-bottom: var(--e-4);
  border: 1px solid var(--borda); background: var(--superficie-2); font-size: var(--t-sm); }
.f-ok    { background: var(--sucesso-fundo); border-color: color-mix(in srgb, var(--sucesso) 40%, transparent); color: var(--sucesso); }
.f-erro  { background: var(--erro-fundo);    border-color: color-mix(in srgb, var(--erro) 40%, transparent);    color: var(--erro); }
.f-aviso { background: var(--atencao-fundo); border-color: color-mix(in srgb, var(--atencao) 40%, transparent); color: var(--atencao); }
.flash a, .flash strong { color: inherit; }

/* ---------- barra ---------- */
.barra { height: 6px; border-radius: 3px; background: var(--superficie-3); overflow: hidden; margin-top: 6px; }
.barra i { display: block; height: 100%; background: var(--primaria); border-radius: 3px; transition: width var(--transicao); }
.barra i.estouro { background: var(--erro); }

/* ---------- numeros em tabela ---------- */
.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* ---------- grade semanal ---------- */
.semana { display: flex; align-items: center; justify-content: space-between; gap: var(--e-3);
  flex-wrap: wrap; margin-bottom: var(--e-4); }
.semana .titulo { font: 600 var(--t-lg)/1.2 var(--fonte-titulo); font-variant-numeric: tabular-nums; }
.grade th.dia { text-align: center; width: 78px; }
.grade th.dia small { display: block; font-weight: 400; text-transform: none; letter-spacing: 0;
  color: var(--texto-3); font-size: var(--t-xs); }
.grade th.fds, .grade td.fds { background: var(--superficie-2); }
.grade input.h { width: 66px; text-align: center; padding: 6px 4px; font-variant-numeric: tabular-nums; }
.grade input.h.preenchido { background: var(--primaria-suave); border-color: var(--primaria);
  color: var(--texto); font-weight: 600; }
.grade input.h:disabled { background: var(--superficie-2); color: var(--texto-3); border-style: dashed; }
.grade td.tot { font-weight: 700; background: var(--superficie-2); }
.tot-alerta { color: var(--atencao); }
.tot-ok { color: var(--sucesso); }
.grade tbody tr:hover { background: transparent; }

@media (max-width: 780px) {
  .nav { order: 3; width: 100%; padding-bottom: var(--e-2); }
  .conteudo { padding: var(--e-4) var(--e-3) var(--e-10); }
  /* O miolo da faixa acompanha: recuo diferente entre os dois deixava
     a borda direita da faixa 8 px fora da borda do conteúdo, e é
     justamente no celular que 8 px se veem. */
  .mf-in { padding-left: var(--e-3); padding-right: var(--e-3); }
  .grade input.h { width: 54px; }
  .u-nome { display: none; }
}
@media print {
  /* O cromo da tela nao vai para o papel. A lista aqui envelheceu uma
     vez: ela ainda citava `.topo`, a barra horizontal que deixou de
     existir quando o menu virou lateral -- e como `.nv` nao estava
     nela, TODA impressao saia com a barra lateral inteira ocupando a
     margem esquerda da folha. Regra de impressao nao aparece na tela:
     ela so e vista por quem imprime, e por isso envelhece calada. */
  .topo, .rodape, .acoes, .btn, .wr-tema,
  .nv, .nv-vidro, .mf-bt, .nvf,
  .assist-bolha, .assist-painel { display: none !important; }
  /* Sem a barra lateral, o conteudo nao pode continuar recuado por
     ela: o recuo viraria margem esquerda gigante na folha. */
  .mf, main, .conteudo { padding-left: 0 !important; margin-left: 0 !important; }
  body { background: #fff; }
  .card { box-shadow: none; border: 1px solid #bbb; break-inside: avoid; }
}

/* ============================================================
   Tela de login
   ============================================================ */
.pagina-login { min-height: 100vh; display: flex; align-items: center; justify-content: center; }
.login-fundo { position: fixed; inset: 0; z-index: -1; background: var(--wr-azul); }
.login-fundo::after {
  content: ""; position: absolute; right: 5%; bottom: 6%;
  width: 30vmin; height: 23vmin; opacity: .16;
  background-color: #fff;
  -webkit-mask: url('logo/wrsc-simbolo.svg') no-repeat center / contain;
          mask: url('logo/wrsc-simbolo.svg') no-repeat center / contain;
}
:root[data-theme="dark"] .login-fundo { background: var(--wr-preto); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .login-fundo { background: var(--wr-preto); } }

.login { display: flex; flex-direction: column; align-items: center; gap: var(--e-4); padding: var(--e-5); width: 100%; }
.login-card {
  background: var(--superficie); border: 1px solid var(--borda); border-radius: var(--raio-lg);
  box-shadow: var(--sombra-2); padding: var(--e-8) var(--e-8) var(--e-6);
  width: 100%; max-width: 400px; text-align: center;
}
.marca-login { color: var(--texto); width: 72px; height: 77px; margin-bottom: var(--e-4); }
.login-card h1 { font-size: var(--t-2xl); margin-bottom: var(--e-1); }
.login-card .sub { margin-bottom: var(--e-6); }
.btn-ms {
  display: flex; align-items: center; justify-content: center; gap: var(--e-3);
  width: 100%; padding: 12px; border: 1px solid var(--borda-forte); border-radius: var(--raio-sm);
  background: var(--superficie); color: var(--texto);
  font: 600 var(--t-md)/1 var(--fonte-titulo);
  transition: background var(--transicao), border-color var(--transicao);
}
.btn-ms:hover { background: var(--superficie-2); border-color: var(--primaria); text-decoration: none; color: var(--texto); }
.login-rod { margin: var(--e-5) 0 0; }
.login-tema { color: #fff; --topo-fundo: var(--wr-azul); }
:root[data-theme="dark"] .login-tema { --topo-fundo: var(--wr-preto); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .login-tema { --topo-fundo: var(--wr-preto); } }


/* ============================================================
   Devolucao para ajuste
   ============================================================ */

/* Aviso no topo da semana. O consultor precisa ver o motivo sem
   procurar: antes ele so existia num ramo de codigo inalcancavel. */
.aviso-devolucao {
  background: var(--atencao-fundo);
  border-left: 3px solid var(--atencao);
  border-radius: 10px;
  padding: 14px 16px;
  margin: 0 0 16px;
}
.aviso-devolucao .cabeca {
  font-family: Rubik, system-ui, sans-serif;
  font-weight: 600;
  font-size: 15px;
  color: var(--atencao);
  margin-bottom: 6px;
}
.aviso-devolucao .motivo {
  font-size: 14px;
  color: var(--texto);
  padding: 3px 0;
}

/* Mesmo motivo, agora na linha do lancamento. */
.motivo-devolucao {
  margin-top: 5px;
  padding: 6px 9px;
  border-radius: 6px;
  background: var(--atencao-fundo);
  color: var(--texto);
  font-size: 13px;
  line-height: 1.4;
}
.motivo-devolucao strong { color: var(--atencao); }

/* ============================================================
   Nota interna
   ============================================================ */

/* Marca visual para o que NAO sai para o cliente. A listra lateral
   existe para dar um sinal de relance: se esta listrado, e interno. */
.nota-interna {
  margin-top: 4px;
  padding-left: 8px;
  border-left: 2px dashed var(--borda);
  color: var(--texto-3);
  font-style: italic;
}
.campo-interno {
  border-style: dashed !important;
}
.campo-interno::placeholder { font-style: italic; }

/* Bloco de exportacoes que carregam nota interna. A borda tracejada e o
   mesmo sinal usado no campo interno: se esta tracejado, nao vai para o
   cliente. */
.grupo-interno {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px 4px 8px;
  border: 1px dashed var(--borda);
  border-radius: 8px;
  margin-left: 4px;
}
.grupo-interno .dica { white-space: nowrap; }

/* ============================================================
   Extrato de banco de horas
   ============================================================ */

/* .entre e .filtros ja eram usadas nas telas sem existirem aqui --
   funcionavam por acidente, como div comum. Definidas agora. */
.entre { display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--e-4); flex-wrap: wrap; }
.entre > h2 { margin: 0; }

.filtros { display: flex; align-items: flex-end; gap: var(--e-4); flex-wrap: wrap; margin: 0; }
.filtros .campo { margin: 0; min-width: 150px; }
.filtros .acoes { display: flex; gap: var(--e-2); }

.extrato { width: 100%; border-collapse: collapse; margin-top: var(--e-3); }
.extrato td { padding: 9px 10px; border-bottom: 1px solid var(--borda); vertical-align: baseline; }
.extrato td.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.extrato tr:last-child td { border-bottom: 0; }

/* As tres cores nao carregam sozinhas o significado: cada linha tem
   rotulo em texto ("Creditos vencidos", "Horas alem do contrato").
   A cor reforca, nao substitui -- quem nao distingue as matizes le a
   mesma informacao. */
.extrato .linha-ok td       { background: var(--sucesso-fundo); }
.extrato .linha-atencao td  { background: var(--atencao-fundo); }
.extrato .linha-erro td     { background: var(--erro-fundo); }
.extrato .linha-total td    { background: var(--primaria-suave); border-top: 2px solid var(--borda-forte);
  border-bottom: 0; font-size: var(--t-lg); padding-top: 12px; padding-bottom: 12px; }

.lista-simples { margin: var(--e-3) 0 0; padding-left: var(--e-5); line-height: 1.9; }

/* ============================================================
   Navegacao que nao quebra
   ============================================================
   Problema: a barra crescia a cada funcao nova e passava a quebrar
   em duas linhas. Duas medidas:

     1. itens de administracao entram num grupo suspenso, entao a
        barra para de crescer quando entra funcao nova;
     2. abaixo de 900px tudo colapsa num botao.

   Feito com <details>, que e sanfona nativa: funciona sem
   JavaScript, responde ao teclado e ja e anunciado como
   expansivel pelos leitores de tela. No monitor o CSS abre o
   conteudo mesmo com o <details> fechado -- e por isso que a
   regra abaixo usa !important, para vencer o estilo do proprio
   navegador. */

.nav-caixa { flex: 1 1 auto; min-width: 0; }

/* A caixa de marcacao fica fora da vista mas continua alcancavel
   pelo teclado -- por isso nao e display:none nem hidden. */
.nav-check { position: absolute; width: 1px; height: 1px; margin: -1px;
  padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.nav-abrir { display: none; }

.nav-grupo { position: relative; }
.nav-grupo > summary {
  display: inline-flex; align-items: center; gap: 6px;
  /* 8px, e não 7: com 7 o "Menu" ficava 27 px de altura contra 29 dos
     links ao lado, e o centro dele caía 1 px acima do centro deles.
     Item de menu ao lado de item de menu tem de ter o mesmo corpo. */
  padding: 8px 12px; border-radius: 8px; cursor: pointer;
  /* Mesmo corpo dos itens soltos: o grupo e um irmao deles, e nao um
     titulo acima deles. Em --t-md os tres grupos sozinhos comiam ~45 px
     a mais de barra, o que decidia se o menu cabia numa linha. */
  color: var(--topo-texto); font: 600 var(--t-sm)/1 var(--fonte-titulo);
  white-space: nowrap; list-style: none;
}
.nav-grupo > summary::-webkit-details-marker { display: none; }
.nav-grupo > summary:hover { background: rgba(255,255,255,.12); }
.nav-grupo > summary:focus-visible { outline: 2px solid var(--topo-texto); outline-offset: 2px; }
.nav-grupo > summary.on { background: var(--primaria); color: var(--primaria-texto); }
.nav-grupo .seta {
  width: 0; height: 0; border-left: 4px solid transparent; border-right: 4px solid transparent;
  border-top: 5px solid currentColor; opacity: .8;
}

@media (min-width: 901px) {
  /* Barra completa: no monitor o botao nao existe. */
  .nav-caixa > .nav { display: flex; }

  .nav-grupo[open] > summary:not(.on) { background: rgba(255,255,255,.12); }
  .nav-grupo[open] > .nav-sub {
    position: absolute; top: calc(100% + 6px); left: 0; z-index: 60;
    min-width: 210px; padding: 6px;
    background: var(--superficie); border: 1px solid var(--borda);
    border-radius: 10px; box-shadow: var(--sombra-2, 0 10px 30px rgba(0,0,0,.18));
    display: flex; flex-direction: column; gap: 2px;
  }
  .nav-grupo > .nav-sub a {
    color: var(--texto); padding: 8px 10px; border-radius: 6px; white-space: nowrap;
  }
  .nav-grupo > .nav-sub a:hover { background: var(--superficie-2); }
  .nav-grupo > .nav-sub a.on { background: var(--primaria); color: var(--primaria-texto); }
}

@media (max-width: 900px) {
  .topo-in { flex-wrap: wrap; row-gap: 8px; }
  .nav-caixa { order: 3; flex-basis: 100%; }

  .nav-abrir {
    display: inline-flex; align-items: center; gap: 8px;
    padding: 8px 12px; border-radius: 8px; cursor: pointer;
    color: var(--topo-texto); font: 600 var(--t-md)/1 var(--fonte-titulo);
    border: 1px solid rgba(255,255,255,.28);
  }
  .nav-check:focus-visible + .nav-caixa .nav-abrir {
    outline: 2px solid var(--topo-texto); outline-offset: 2px;
  }
  .nav-check:checked + .nav-caixa .nav-abrir { background: rgba(255,255,255,.14); }

  .nav-tracos { position: relative; width: 16px; height: 2px; background: currentColor; }
  .nav-tracos::before, .nav-tracos::after {
    content: ""; position: absolute; left: 0; width: 16px; height: 2px; background: currentColor;
  }
  .nav-tracos::before { top: -5px; }
  .nav-tracos::after  { top: 5px; }

  /* Sem esta linha o menu do celular fica sempre aberto: a regra
     .nav { display:flex } da folha principal vence o esconder que o
     navegador aplica ao conteudo de um <details> fechado. */
  .nav-caixa > .nav { display: none; }

  .nav-check:checked + .nav-caixa > .nav {
    display: flex; flex-direction: column; align-items: stretch; gap: 2px;
    margin-top: 8px; padding: 8px 0 4px;
    border-top: 1px solid rgba(255,255,255,.18);
  }
  .nav-caixa > .nav > a, .nav-grupo > summary { padding: 10px 12px; }
  .nav-grupo .nav-sub { display: flex; flex-direction: column; padding-left: 14px; }
  .nav-grupo > .nav-sub a { padding: 9px 12px; }
}

/* No monitor, o menu ocupa uma linha propria.

   Medido: com logo (212px) e bloco do usuario (341px), sobram ~690px
   para a barra, e os itens do Timesheet pedem ~700. Faltavam 11
   pixels -- e raspar padding para ganhar 11 seria uma correcao que a
   proxima funcao desfaz.

   Nao adianta esperar tela maior: .topo-in tem largura maxima fixa,
   entao o espaco disponivel e o mesmo em 1400 ou em 2560. A primeira
   tentativa aqui foi liberar a linha inteira so numa faixa de
   larguras -- e acima dela o bloco do usuario e que descia de linha,
   ficando pior. Uma linha propria sempre, e o resultado e estavel em
   qualquer tela. Abaixo de 900px vale o botao, que ja e outro caso. */
@media (min-width: 901px) {
  .topo-in { flex-wrap: wrap; row-gap: 4px; }
  .nav-caixa { order: 3; flex-basis: 100%; }
  /* ============================================================
     NADA DE PADDING SÓ DE UM LADO NUMA LINHA CENTRALIZADA
     ============================================================
     Havia `padding-bottom: 4px` aqui. Ele nasceu para dar respiro
     quando o menu ocupava a SEGUNDA linha da barra — layout que
     deixou de existir quando a regra de 1100px passou a proibir a
     quebra (`flex-wrap: nowrap`).

     A regra ficou, e virou dano: numa linha centralizada, 4 px só
     embaixo empurram o conteúdo 2 px para CIMA. Medido: os itens do
     menu tinham centro em y=37 enquanto a marca, o nome da pessoa e
     o botão Sair tinham centro em y=39.

     Dois pixels ninguém sabe nomear, mas a barra é o que a pessoa
     mais olha, e ela via que estava torto.

     O respiro na quebra vem do `row-gap` do .topo-in e do .nav, que
     só valem quando a quebra acontece de verdade. */
  .nav { row-gap: 4px; }
}

/* ============================================================
   Ambientes do projeto e Workspace
   ============================================================ */

/* --- cadastro na tela de projeto --- */
.amb-bloco { padding: var(--e-4) 0; border-bottom: 1px solid var(--borda); }
.amb-bloco:last-child { border-bottom: 0; }
.amb-bloco h3 { margin: 0; font-size: var(--t-md); }
.amb-bloco h3 .dica { font-weight: 400; }
.amb-bloco > .dica { margin: 2px 0 8px; }

.amb-linha { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-bottom: 6px; }
.amb-linha .amb-nome { flex: 0 1 130px; }
.amb-linha .amb-url  { flex: 2 1 280px; }
.amb-linha .amb-obs  { flex: 1 1 180px; }
.amb-vis { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap;
  font-size: var(--t-sm); color: var(--texto-2); font-weight: 400; }
.amb-vis input { width: auto; }
/* Gravar e remover sao formularios separados; o item os alinha na
   mesma linha, e a linha do formulario ocupa o espaco que sobra. */
.amb-item { display: flex; gap: 8px; align-items: flex-start; }
.amb-item .amb-linha { flex: 1 1 auto; }
.amb-remover { display: flex; align-items: center; margin-bottom: 6px; }

/* --- cards do workspace --- */
.ws-grade { display: grid; gap: var(--e-4); align-items: start;
  grid-template-columns: repeat(auto-fill, minmax(330px, 1fr)); }
.ws-card { display: flex; flex-direction: column; gap: var(--e-3); }
.ws-topo { display: flex; justify-content: space-between; gap: var(--e-3); align-items: flex-start; }
.ws-topo h2 { margin: 2px 0 0; font-size: var(--t-lg); border: 0; padding: 0; }
.ws-cliente { font: 700 var(--t-xs)/1.2 var(--fonte-titulo); text-transform: uppercase;
  letter-spacing: .06em; color: var(--texto-3); }

.ws-grupo { margin-top: 2px; }
.ws-grupo h3 { margin: 0 0 4px; font: 700 var(--t-xs)/1.2 var(--fonte-titulo);
  text-transform: uppercase; letter-spacing: .06em; color: var(--texto-3); }

/* O link inteiro e clicavel, e nao so o texto: alvo grande no toque. */
.ws-link { display: block; padding: 8px 10px; border-radius: 8px;
  border: 1px solid var(--borda); background: var(--superficie-2);
  color: var(--texto); margin-bottom: 4px; }
.ws-link:hover { border-color: var(--primaria); text-decoration: none; }
.ws-link-nome { display: block; font-weight: 600; font-size: var(--t-sm); }
/* A URL quebra em qualquer ponto: endereco de ambiente costuma ser
   uma palavra so, comprida, e sem isso estoura o card. */
.ws-link-url { display: block; font-size: var(--t-xs); color: var(--texto-2);
  word-break: break-all; }
.ws-link-obs { display: block; font-size: var(--t-xs); color: var(--texto-3); margin-top: 2px; }

.ws-acoes { display: flex; gap: 6px; flex-wrap: wrap; margin-top: auto; padding-top: var(--e-3);
  border-top: 1px solid var(--borda); }

.b-ams_bh { background: var(--selo-fundo); color: var(--selo-texto); }

/* ============================================================
   Parametros de ambiente e limpeza de dados
   ============================================================ */

/* Interruptor com explicacao ao lado (mesma marcacao do Portal). */
.param { display: flex; gap: 12px; align-items: flex-start; padding: 12px 0;
  border-bottom: 1px solid var(--borda); }
.param:last-of-type { border-bottom: 0; }
.param input { width: auto; margin-top: 3px; flex: 0 0 auto; }
.param strong { display: block; }
.param .dica { display: block; margin-top: 2px; }

/* A tarja do modo de teste aparece em toda pagina: e o que impede
   alguem de deixar o desvio ligado sem perceber. Cor de atencao, nao
   de erro -- nada esta quebrado, so precisa ser visto. */
.tarja-teste { background: var(--atencao-fundo); color: var(--atencao);
  border: 1px solid color-mix(in srgb, var(--atencao) 45%, transparent);
  border-radius: var(--raio); padding: 10px 14px; margin-bottom: var(--e-4);
  font-size: var(--t-sm); }
.tarja-teste a { color: var(--atencao); text-decoration: underline; margin-left: 6px; }

/* stretch, e nao start: os cards da mesma linha ficam da mesma
   altura e os botoes alinhados embaixo. Com alturas diferentes a
   grade fica serrilhada e o olho perde a linha. */
.limpeza-grade { display: grid; gap: var(--e-4); align-items: stretch;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); }
.limpeza-card { display: flex; flex-direction: column; gap: 6px; }
.limpeza-card h2 { margin: 0; font-size: var(--t-lg); border: 0; padding: 0; }
.limpeza-card form { margin-top: auto; padding-top: var(--e-3); }
.limpeza-num { margin: 4px 0 0; font: 700 var(--t-lg)/1.2 var(--fonte-titulo); }

/* A tela de confirmacao e a unica sem volta: a borda existe para que
   ela nao se pareca com as outras. */
.card-perigo { border: 2px solid color-mix(in srgb, var(--erro) 55%, transparent); }
.card-perigo h2 { color: var(--erro); }

.previa-limpeza { width: 100%; border-collapse: collapse; margin: 10px 0; }
.previa-limpeza th, .previa-limpeza td { padding: 6px 10px; border-bottom: 1px solid var(--borda);
  text-align: left; font-size: var(--t-sm); }
.previa-limpeza th { font: 700 var(--t-xs)/1.4 var(--fonte-titulo); text-transform: uppercase;
  letter-spacing: .05em; color: var(--texto-2); }
.previa-limpeza .num { text-align: right; font-variant-numeric: tabular-nums; }
.previa-limpeza tr.zerado td { color: var(--texto-3); }

/* Tres campos do mesmo tipo merecem a mesma largura. */
.param-emails { display: grid; gap: var(--e-4); margin-top: 14px;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.param-emails .campo { min-width: 0; }
.param-emails input { width: 100%; }

/* Campo de numero pequeno nao precisa da largura do card inteiro:
   um input largo sugere um valor longo. */
.campo-dias input { max-width: 120px; }

/* ============================================================
   Logs
   ============================================================ */

/* Os tres numeros que respondem "o e-mail saiu?" antes de qualquer
   filtro. Cor so quando ha o que ver: zero falhas fica neutro. */
.log-resumo { display: flex; gap: var(--e-4); flex-wrap: wrap; margin-bottom: var(--e-3); }
.log-kpi { flex: 0 1 200px; padding: var(--e-3) var(--e-4); border-radius: var(--raio);
  background: var(--superficie-2); border: 1px solid var(--borda); }
.log-kpi .n { display: block; font: 700 var(--t-2xl)/1 var(--fonte-titulo); }
.log-kpi .r { display: block; font-size: var(--t-sm); margin-top: 2px; }
.log-kpi .o { display: block; font-size: var(--t-xs); color: var(--texto-2); margin-top: 4px; }
.log-kpi.k-ok    { background: var(--sucesso-fundo); border-color: color-mix(in srgb, var(--sucesso) 35%, transparent); }
.log-kpi.k-ok .n { color: var(--sucesso); }
.log-kpi.k-erro  { background: var(--erro-fundo);    border-color: color-mix(in srgb, var(--erro) 35%, transparent); }
.log-kpi.k-erro .n { color: var(--erro); }
/* Meio-termo: nao esta quebrado, mas vai quebrar se ninguem olhar.
   Ex.: assinatura do webhook perto de vencer. */
.log-kpi.k-alerta  { background: var(--atencao-fundo); border-color: color-mix(in srgb, var(--atencao) 35%, transparent); }
.log-kpi.k-alerta .n { color: var(--atencao); }
.log-kpi.k-aviso { background: var(--atencao-fundo); border-color: color-mix(in srgb, var(--atencao) 35%, transparent); }
.log-kpi.k-aviso .n { color: var(--atencao); }

.log-motivos { margin: 4px 0 8px; padding-left: 20px; font-size: var(--t-sm); }
.log-motivos li { margin: 2px 0; }

.log-tabela { width: 100%; border-collapse: collapse; }
.log-tabela th, .log-tabela td { padding: 6px 10px; border-bottom: 1px solid var(--borda);
  text-align: left; font-size: var(--t-sm); vertical-align: top; }
.log-tabela th { font: 700 var(--t-xs)/1.4 var(--fonte-titulo); text-transform: uppercase;
  letter-spacing: .05em; color: var(--texto-2); white-space: nowrap; }
.log-quando { white-space: nowrap; font-variant-numeric: tabular-nums; }
/* O detalhe e onde esta a resposta (codigo HTTP, endereco, mensagem do
   Graph). Quebra em qualquer ponto para nao estourar a tabela. */
.log-detalhe { font-family: var(--fonte-mono); font-size: var(--t-xs);
  word-break: break-word; max-width: 520px; }

.log-sel { display: inline-block; padding: 2px 8px; border-radius: var(--raio-pill);
  font: 700 var(--t-xs)/1.5 var(--fonte-titulo); white-space: nowrap; }
.log-sel.s-ok    { background: var(--sucesso-fundo); color: var(--sucesso); }
.log-sel.s-erro  { background: var(--erro-fundo);    color: var(--erro); }
.log-sel.s-aviso { background: var(--atencao-fundo); color: var(--atencao); }
.log-sel.s-info  { background: var(--superficie-3);  color: var(--texto-2); }

.log-paginas { display: flex; gap: var(--e-3); align-items: center; margin-top: var(--e-3); }
.log-acoes { display: flex; gap: var(--e-4); flex-wrap: wrap; align-items: flex-start; }
.log-zerar { display: flex; gap: 6px; align-items: center; }
.log-zerar input { max-width: 130px; }
.campo-check { display: flex; align-items: flex-end; }

/* ---------- painel do agente ---------- */
/* Barra na borda e fundo distinto: o olho precisa saber num relance que
   aquele texto foi escrito por maquina, nao por uma pessoa. */
.agente-painel { border-left: 3px solid var(--primaria); }
.agente-texto { font-size: var(--t-sm); line-height: 1.55; }
.agente-texto p { margin: 0 0 10px; }
.agente-texto p:last-child { margin-bottom: 0; }

/* ---------- consumo do agente ---------- */
/* Barra em CSS puro, e nao SVG: a tela e uma lista de catorze dias,
   e um <span> com largura em porcentagem diz o mesmo sem gerador de
   grafico. Contraste e o mesmo da primaria, que ja passa em AA. */
.ag-dias { width: 100%; }
.ag-dias td { padding: 4px 8px 4px 0; border: 0; }
.ag-barra-cel { width: 55%; }
.ag-barra { display: block; height: 10px; min-width: 2px; border-radius: 5px;
  background: var(--primaria); }

/* ---------- boas-vindas ---------- */
/* O simbolo da WR bem claro atras do titulo, como na tela de login.
   Como o logo e mascara pintada com currentColor, "clarinho" e so
   baixar a opacidade -- e ele acompanha o tema escuro sozinho. */
.bv-capa { position: relative; margin-bottom: var(--e-4); padding-left: 96px; min-height: 78px; }
.bv-marca { position: absolute; left: 0; top: 0; width: 82px; height: 62px;
  color: var(--texto); opacity: .10; pointer-events: none; }
.bv-capa-texto h1 { margin: 0; }
@media (max-width: 640px) {
  .bv-capa { padding-left: 0; }
  .bv-marca { position: static; display: block; margin-bottom: var(--e-2); width: 48px; height: 36px; }
}

.bv-faixa { display: flex; flex-wrap: wrap; gap: var(--e-4);
  background: var(--superficie-2); border: 1px solid var(--borda); border-radius: var(--raio);
  padding: var(--e-3) var(--e-4); margin-bottom: var(--e-4); }
.bv-faixa-item { display: flex; align-items: baseline; gap: 8px; }
.bv-faixa-rot { font: 700 var(--t-xs)/1 var(--fonte-titulo); text-transform: uppercase;
  letter-spacing: .06em; color: var(--texto-2); }
.bv-faixa-val { font-weight: 700; font-variant-numeric: tabular-nums; }
.bv-faixa-var { font-size: var(--t-xs); color: var(--texto-3); }
/* Cor sozinha nao pode ser o unico sinal: o sinal + ou - vem junto no texto. */
.bv-faixa-var.sobe { color: var(--sucesso); }
.bv-faixa-var.desce { color: var(--erro); }

.bv-passos { list-style: none; margin: 0; padding: 0; }
.bv-passos > li { display: flex; gap: var(--e-4); padding: var(--e-4) 0;
  border-bottom: 1px solid var(--borda); }
.bv-passos > li:last-child { border-bottom: 0; padding-bottom: 0; }

/* ============================================================
   EM TELA LARGA, O ROTEIRO VAI PARA DUAS COLUNAS
   ============================================================
   Com o contêiner em 1800 px e o texto preso na medida de leitura,
   este cartão ficava com a metade direita VAZIA -- e vazio dentro de
   uma caixa branca incomoda mais do que vazio no fundo da página,
   porque a caixa promete conteúdo.

   Duas colunas usam o espaço sem esticar a linha, que era o objetivo
   dos dois lados. Abaixo de 1500 px continua em coluna única: o
   roteiro é numerado, e numeração em duas colunas estreitas obriga o
   olho a subir de volta no meio da leitura.

   `break-inside: avoid` existe porque sem ele o navegador parte um
   passo ao meio entre as colunas -- o número numa, o texto na outra. */
@media (min-width: 1500px) {
  .bv-passos { columns: 2; column-gap: var(--e-8); }
  .bv-passos > li { break-inside: avoid; }
  .bv-passos > li:last-child { border-bottom: 1px solid var(--borda); padding-bottom: var(--e-4); }
}

/* Cartão que só tem prosa não estica: sem tabela, sem grade e sem
   formulário, não há o que preencher a largura, e o cartão largo com
   texto estreito dentro é a mesma metade vazia. Quem tem qualquer um
   dos três usa a largura toda, que é o ponto da tela larga. */
.conteudo .card:not(:has(table, form, .wr-grade, .grade, .bv-passos, canvas, svg, .kpi)) {
  max-width: var(--largura-max);
}
.bv-passo-num { flex: 0 0 30px; height: 30px; border-radius: 50%;
  background: var(--primaria); color: var(--primaria-texto);
  display: flex; align-items: center; justify-content: center;
  font: 700 var(--t-sm)/1 var(--fonte-titulo); }
.bv-passo-corpo { flex: 1 1 auto; min-width: 0; }
.bv-passo-corpo h3 { margin: 2px 0 4px; font-size: var(--t-md); }
.bv-passo-corpo p { margin: 0 0 10px; color: var(--texto-2); }
.bv-print { display: block; max-width: 100%; border: 1px solid var(--borda);
  border-radius: var(--raio); margin: 0 0 10px; }
.bv-fim { margin-top: var(--e-4); border-top: 1px solid var(--borda); padding-top: var(--e-3); }
.bv-ajustes summary { cursor: pointer; }
.bv-ajustes[open] summary { margin-bottom: var(--e-2); }

/* O bloco do roteiro dentro do Painel: mesma marca-d'agua da tela de
   login, so que no canto do card. */
.bv-bloco { position: relative; }
.bv-bloco > h2 { padding-right: 70px; }
/* ============================================================
   O TRAÇO DO TÍTULO NÃO PODE CORTAR A MARCA
   ============================================================
   Medido: a borda inferior do h2 caía em y=626 e a marca ia de y=587
   a y=631. O risco atravessava o logo a 5 px da base dele — e logo
   cortado por uma linha é erro de marca, não detalhe.

   A marca desce para DEPOIS do traço, alinhada pelo topo com o texto
   que vem abaixo. Fica no mesmo canto, sem nada passando por cima.
   ============================================================ */
.bv-bloco > .bv-marca { position: absolute; right: 18px; top: 62px;
  width: 58px; height: 44px; color: var(--texto); opacity: .09; pointer-events: none; }
.bv-bloco > .sub { margin-top: -6px; }

/* ============================================================
   TOPO FLUTUANTE
   A barra preta encostada no cromo do navegador confundia: parecia
   parte da janela, nao da pagina. Agora ela flutua -- ha uma faixa
   do fundo da pagina acima dela, cantos arredondados e sombra, e
   dois degrades que fazem o conteudo aparecer e sumir suavemente
   em vez de cortar numa linha reta.

   Por que degrade e nao uma borda: com a barra flutuando, o
   conteudo rola ATRAS dela e ficaria visivel na fresta de cima. O
   degrade superior e uma faixa fixa da cor do fundo que apaga esse
   pedaco antes de ele chegar na borda da janela.
   ============================================================ */
.topo {
  position: sticky;
  top: 10px;
  z-index: 40;
  width: calc(100% - 2 * var(--e-4));
  max-width: var(--largura-max);
  margin: 10px auto 14px;
  border: 0;
  border-radius: 14px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, .20), 0 2px 6px rgba(0, 0, 0, .12);
}
.topo-in { padding: 0 var(--e-4); }

/* A faixa que apaga o conteudo antes da borda de cima da janela.
   Vai no body, e nao na barra: dentro da barra ela herdaria o
   contexto de empilhamento dela e nao cobriria nada de fora. */
body::before {
  content: '';
  position: fixed;
  left: 0; right: 0; top: 0;
  height: 12px;
  background: var(--fundo);
  z-index: 39;
  pointer-events: none;
}
/* O degrade de baixo: o conteudo emerge da barra em vez de brotar. */
.topo::after {
  content: '';
  position: absolute;
  left: 0; right: 0; top: 100%;
  height: 16px;
  background: linear-gradient(to bottom,
              color-mix(in srgb, var(--fundo) 92%, transparent), transparent);
  pointer-events: none;
}

/* Explicacao de uma linha embaixo de cada item do menu suspenso.
   Nome de tela raramente diz o que a tela faz. */
.nav-sub-nome { display: block; }
.nav-sub-dica { display: block; margin-top: 2px; font-size: var(--t-xs);
  font-weight: 400; line-height: 1.35; color: var(--texto-3); white-space: normal; }
.nav-grupo > .nav-sub a { display: block; }
.nav-grupo > .nav-sub a.on .nav-sub-dica { color: inherit; opacity: .85; }

@media (min-width: 861px) {
  /* Com a explicacao junto, o menu precisa de largura para respirar. */
  .nav-grupo > .nav-sub { min-width: 300px; }
}
@media (max-width: 860px) {
  /* No celular a barra volta a encostar nas laterais: 12 px de fresta
     de cada lado tiram espaco de quem ja tem pouco. */
  .topo { width: 100%; max-width: none; margin: 0 0 8px; top: 0; border-radius: 0; }
  body::before { display: none; }
}

/* ---------- gravacao ao sair do campo ---------- */
/* Tres estados discretos na propria celula. Nada de balao no canto da
   tela: o retorno tem de aparecer onde a pessoa esta olhando, que e o
   campo que ela acabou de deixar. */
.grade td.cel-salvando input.h { border-color: var(--borda); opacity: .7; }
.grade td.cel-salvo    input.h { border-color: var(--sucesso);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--sucesso) 22%, transparent); }
.grade td.cel-erro     input.h { border-color: var(--erro);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--erro) 25%, transparent); }
/* A cor sozinha nao pode ser o unico sinal: o title= leva o motivo, e
   a celula com erro ganha um canto marcado. */
.grade td.cel-erro { position: relative; }
.grade td.cel-erro::after {
  content: '!'; position: absolute; top: 1px; right: 3px;
  font: 700 10px/1 var(--fonte-titulo); color: var(--erro);
}

/* ---------- celula com mais de um lancamento ---------- */
/* A celula da grade e (projeto, atividade, dia) -- e ela pode ter mais
   de um lancamento. Ate a 3.15.x o segundo era invisivel: a tela
   mostrava o primeiro e o banco guardava os dois. Agora o campo mostra
   a SOMA, para de aceitar digitacao (nao ha como saber qual dos dois
   mudar) e o canto leva ao detalhe.

   O link existe em TODA celula, e nao so nas de varios: adicionar a
   segunda task do dia precisa de uma porta. Discreto por padrao --
   sete dias vezes N linhas de icone forte seria ruido em cima de quem
   so quer digitar hora. */
/* A faixa de cima da celula existe para o link morar nela sem
   encostar no campo. O total de padding vertical continua o mesmo
   (18px), so mudou de lado -- a altura da linha da grade nao muda. */
.grade td.centro { position: relative; padding-top: 14px; padding-bottom: 4px; }
.grade a.cel-abrir {
  position: absolute; top: 1px; right: 3px;
  min-width: 14px; height: 14px; padding: 0 3px;
  display: inline-flex; align-items: center; justify-content: center;
  font: 700 9px/1 var(--fonte-titulo); text-decoration: none;
  color: var(--texto-3); border-radius: 7px;
  opacity: .35; transition: opacity var(--transicao), background var(--transicao);
}
.grade td.centro:hover a.cel-abrir,
.grade a.cel-abrir:focus-visible { opacity: 1; }
.grade a.cel-abrir:hover { background: var(--primaria-suave); color: var(--primaria-link); }
/* Com dois ou mais, o canto deixa de ser afordancia e vira informacao:
   o numero diz quantos, e nao pode depender de passar o mouse. */
.grade a.cel-abrir.forte {
  opacity: 1; color: var(--primaria-texto); background: var(--primaria);
  font-size: 10px; min-width: 15px; height: 15px; border-radius: 8px;
}
.grade a.cel-abrir.forte:hover { background: var(--primaria-hover); color: var(--primaria-texto); }
/* O campo somado fica legivel, e nao com cara de desativado: ele nao
   esta travado por status, esta travado porque a edicao mora noutro
   lugar. */
.grade td.cel-varios input.h:disabled {
  background: var(--primaria-suave); color: var(--texto);
  border-style: solid; border-color: var(--primaria); font-weight: 700;
}

/* ---------- detalhe da celula ---------- */
.cel-cabeca { display: flex; flex-wrap: wrap; gap: var(--e-4);
  align-items: flex-start; justify-content: space-between; }
.cel-soma { text-align: right; }
.cel-soma strong { display: block; font: 700 var(--t-xl)/1.1 var(--fonte-titulo);
  color: var(--primaria-link); font-variant-numeric: tabular-nums; }

/* ---------- reabrir por dia ---------- */
.reabrir-dias { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px;
  margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--borda); }
.reabrir-dias label { display: inline-flex; align-items: center; gap: 5px;
  font: 500 var(--t-sm)/1 var(--fonte-titulo); padding: 5px 9px;
  border: 1px solid var(--borda); border-radius: var(--raio-sm); cursor: pointer; }
.reabrir-dias label:hover { border-color: var(--primaria); }
.reabrir-dias label input { width: auto; margin: 0; }
.reabrir-dias label.off { opacity: .5; cursor: not-allowed; text-decoration: line-through; }
.reabrir-dias label.off:hover { border-color: var(--borda); }

/* A barra em uma linha so quando ha largura para isso.
   .topo-in continua sem quebrar -- marca, menu e pessoa ficam sempre
   na mesma faixa. O MENU, nao: com `nowrap` ele nao quebrava, mas
   tambem nao encolhia, e transbordava POR CIMA do bloco do usuario
   (medido: 8 itens pedem 826 px onde ha 668). Deixar quebrar e o
   comportamento certo -- menu em duas linhas e pior do que menu numa
   linha so, e muito melhor do que menu por cima do nome da pessoa.
   Os itens tambem ficam mais justos aqui, para caber uma linha so na
   maioria dos monitores. */
@media (min-width: 1100px) {
  .topo-in { flex-wrap: nowrap; gap: var(--e-4); }
  /* Com um Menu so no lugar dos tres grupos, a barra cabe numa linha
     com folga -- e agora ela pode voltar a proibir a quebra sem risco
     de transbordar por cima do bloco do usuario. O min-width:0 do
     .nav continua sendo o que garante isso. */
  .nav { flex-wrap: nowrap; }
  .nav a, .nav-grupo > summary { padding-left: 10px; padding-right: 10px; }
}
/* O simbolo no canto do bloco de boas-vindas: o left:0 da versao de
   tela cheia continuava valendo e jogava a marca em cima do titulo. */
.bv-bloco > .bv-marca { left: auto; }

/* Ordem explicita na barra: marca, menu, pessoa. Sem isto o bloco do
   usuario aparecia entre a marca e o menu, o que embaralha a leitura
   -- quem procura "Aprovacoes" tropeça no proprio nome antes. */
@media (min-width: 1100px) {
  .topo-in > .marca { order: 1; }
  .topo-in > .nav-caixa { order: 2; }
  .topo-in > .usuario { order: 3; margin-left: auto; }
}


/* ---------- abas de area ----------
   Usadas onde uma area tem varias telas irmas (financeiro). Ficam
   dentro da pagina, e nao no topo: quem nunca entra na area nao paga
   por elas em espaco de barra. */
.abas { display: flex; flex-wrap: wrap; gap: 4px; margin: 0 0 var(--e-5);
  border-bottom: 1px solid var(--borda); padding-bottom: 8px; }
.abas .aba { color: var(--texto-2); font: 500 var(--t-sm)/1 var(--fonte-titulo);
  padding: 8px 12px; border-radius: var(--raio-sm); white-space: nowrap; }
.abas .aba:hover { background: var(--superficie-2); color: var(--texto); text-decoration: none; }
.abas .aba.on { background: var(--primaria); color: var(--primaria-texto); font-weight: 600; }

/* ------------------------------------------------------------
   O submenu do Financeiro: fileira no monitor, painel no celular

   São sete abas com rótulo longo. No telefone elas quebravam em
   quatro ou cinco linhas de etiqueta ANTES do conteúdo — meia tela
   de rolagem só para começar a ler.

   O painel é o MESMO <details class="nav-grupo"> da barra de cima,
   então assets/nav.js já cuida dele: fecha ao sair com o ponteiro,
   ao clicar fora, no Esc, e fecha os outros ao abrir um. Nenhuma
   linha de JavaScript nova, e nenhum segundo comportamento para a
   pessoa aprender.

   As cores aqui são as da PÁGINA, e não as da barra: o summary de
   .nav-grupo usa --topo-texto porque vive no topo escuro. Herdar
   aquilo aqui daria texto claro sobre fundo claro.
   ------------------------------------------------------------ */
.abas-painel { display: none; }

@media (max-width: 700px) {
  .abas-larga { display: none; }
  .abas-painel { display: block; margin: 0 0 var(--e-5); }

  .abas-painel > summary {
    display: flex; align-items: center; justify-content: space-between; gap: 8px;
    padding: 10px 12px; border-radius: var(--raio-sm); cursor: pointer;
    background: var(--superficie-2); border: 1px solid var(--borda);
    color: var(--texto); font: 600 var(--t-sm)/1.2 var(--fonte-titulo);
    list-style: none;
  }
  .abas-painel > summary::-webkit-details-marker { display: none; }
  /* A seta é do CSS, e não um caractere no HTML: assim ela gira com
     o estado e some para quem usa leitor de tela. */
  .abas-painel > summary::after {
    content: ''; flex: 0 0 auto;
    width: 0; height: 0; border-left: 5px solid transparent; border-right: 5px solid transparent;
    border-top: 6px solid currentColor; opacity: .7;
    transition: transform var(--transicao, .15s);
  }
  .abas-painel[open] > summary::after { transform: rotate(180deg); }
  .abas-painel > summary:focus-visible { outline: 2px solid var(--primaria); outline-offset: 2px; }

  .abas-lista {
    display: flex; flex-direction: column; gap: 2px; margin-top: 4px; padding: 6px;
    background: var(--superficie); border: 1px solid var(--borda);
    border-radius: var(--raio-sm); box-shadow: var(--sombra-2, 0 10px 30px rgba(0,0,0,.18));
  }
  /* Item de largura inteira: alvo de toque grande, e o rótulo longo
     cabe sem quebrar no meio de uma palavra. */
  .abas-lista .aba { display: block; padding: 10px 12px; white-space: normal; }
}

/* ---------- o painel do Menu ----------
   Um botão só na barra, e todo o resto num painel em colunas. Cresce
   para o lado, e não para baixo: é o que impede a barra de voltar a
   quebrar quando entrar a próxima tela. */
.nav-menu { margin-left: auto; }          /* encosta à direita da barra */

@media (min-width: 901px) {
  .nav-grupo.nav-menu[open] > .nav-painel {
    /* Ancorado à direita: aberto pela esquerda, um painel largo saía da
       tela em notebook. E dimensionado pelo CONTEÚDO -- com largura
       fixa, quem tem dois grupos ficava com uma coluna vazia do lado. */
    left: auto; right: 0;
    /* GRID com o número de colunas decidido no PHP (classe cols-N).
       Flex com quebra não serve aqui: num elemento posicionado, o
       navegador encolhe o painel até o menor tamanho possível e as
       colunas viram uma pilha. O número de grupos é conhecido na hora
       de desenhar a barra, então ele vem escrito na classe. */
    display: grid;
    grid-auto-rows: min-content;
    gap: 2px 24px;
    max-width: min(860px, calc(100vw - 48px));
    padding: 14px 18px 16px;
  }
  .nav-painel.cols-1 { grid-template-columns: 244px; }
  .nav-painel.cols-2 { grid-template-columns: repeat(2, 232px); }
  .nav-painel.cols-3 { grid-template-columns: repeat(3, 232px); }
  /* Quatro grupos ou mais quebram em duas fileiras de três, e não numa
     faixa que sai da tela. */
  .nav-painel.cols-4 { grid-template-columns: repeat(3, 232px); }
}
.nav-painel .nav-coluna { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.nav-painel h4 {
  margin: 6px 0 6px 10px; padding-bottom: 6px;
  border-bottom: 1px solid var(--borda);
  font: 600 var(--t-xs)/1.2 var(--fonte-titulo);
  letter-spacing: .08em; text-transform: uppercase; color: var(--texto-3);
}
.nav-painel .nav-coluna > a { display: block; }

@media (max-width: 900px) {
  /* Dentro do botão de menu do celular o painel já está aberto — ver
     assets/nav.js. O rótulo "Menu" sairia repetido, um debaixo do
     outro. */
  .nav-menu.sem-rotulo > summary { display: none; }
  .nav-menu { margin-left: 0; }
  .nav-painel h4 { margin-left: 0; }
}

/* ------------------------------------------------------------
   Cabeçalho de tabela clicável (ordenação).

   O <th> continua parecendo cabeçalho: quem ordena tabela procura
   o título da coluna, e não um botão. O que muda é o cursor e um
   sublinhado no repouso do ponteiro -- sinal suficiente, sem
   transformar o cabeçalho num campo de botões.
   ------------------------------------------------------------ */
th a.col-ord {
  color: inherit;
  text-decoration: none;
  display: inline-block;
  white-space: nowrap;
}
th a.col-ord:hover,
th a.col-ord:focus-visible { text-decoration: underline; color: var(--primaria-link); }

/* ============================================================
   Rhino Assistente (rhino.php e rhino-fila.php)
   ============================================================ */
.rhino-conversa { display: flex; flex-direction: column; gap: var(--e-3);
  margin: var(--e-4) 0; max-height: 52vh; overflow-y: auto; padding-right: 4px; }
.rhino-msg { padding: 10px 12px; border-radius: var(--raio); max-width: min(680px, 92%); }
.rhino-eu  { align-self: flex-end;   background: var(--primaria-suave); }
.rhino-ele { align-self: flex-start; background: var(--superficie-2);
             border: 1px solid var(--borda); }
.rhino-quem { color: var(--texto-3); font-size: var(--t-xs); margin-bottom: 3px; }
.rhino-hora { margin-left: 6px; }
.rhino-texto { line-height: 1.45; }
.rhino-linha { display: flex; gap: var(--e-2); align-items: center; }
.rhino-linha input[type=text] { flex: 1 1 auto; min-width: 0; }
.rhino-opcoes { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: var(--e-3); }
/* O texto cru do que a pessoa escreveu, na fila. Preserva a quebra de
   linha: e a frase dela, e nao um resumo. */
.rhino-cru { white-space: pre-wrap; background: var(--superficie-2);
  border-left: 3px solid var(--borda-forte); padding: 8px 10px;
  border-radius: 0 var(--raio) var(--raio) 0; margin: 6px 0; }

/* ============================================================
   FAIXA LATERAL — a marca nas sobras da tela
   ============================================================
   O miolo tem 1320 px. Numa janela de 1920 sobram 300 px de cada
   lado, vazios. A faixa ocupa essa sobra dizendo de que aplicação é
   a tela — o nome que saiu da barra do topo, onde parecia um item
   de menu.

   TRÊS COISAS QUE ELA NUNCA PODE FAZER
     1. atrapalhar o conteúdo  -> pointer-events:none e position:fixed
     2. aparecer quando não há sobra -> só a partir de 1560 px
     3. ser lida como informação -> aria-hidden no HTML, e a opacidade
        deixa claro que é textura. O nome de verdade está no <title>,
        no rodapé e no texto só-para-leitor da marca.

   A largura sai de calc((100vw - 1320px)/2): é a sobra real, medida,
   e não um número chutado que quebraria se --largura-max mudasse. */

/* ============================================================
   A MARCA D'AGUA LATERAL FOI REMOVIDA
   ============================================================
   Ela vivia nas sobras dos dois lados do conteudo, acima de 1560 px:
   simbolo da WRSC de um lado, nome do cliente do outro, a 12% de
   opacidade. Com o menu lateral, a sobra da esquerda virou navegacao
   e a faixa passou a disputar espaco com ela.

   O que ela fazia agora e feito em dois lugares melhores:
     - o logotipo do CLIENTE subiu para o topo da barra lateral, onde
       aparece em QUALQUER largura -- antes so num monitor de 1560 px,
       o que quer dizer: em nenhum notebook;
     - a marca da WRSC virou o FIM DA PAGINA (`.nvf`), uma faixa que
       se anima quando a pessoa chega nela.

   Ficaram para tras ~110 linhas de CSS e a funcao logo_faixa(), que
   ninguem mais chamava. Codigo morto que uma bateria ainda vigiava:
   a bateria passava, e o que ela vigiava nao existia mais na tela.
   ============================================================ */



/* ============================================================
   PAGINAÇÃO
   ============================================================
   Rolagem medida antes: a lista mais longa dava 16,6 telas. O
   controle fica DEPOIS da tabela, que é onde a pessoa chega quando
   acaba de ler — pôr acima obrigaria a rolar de volta para cima só
   para avançar.

   Os botões têm 38 px de altura: alvo de toque confortável, e o
   suficiente para o foco de teclado ter onde aparecer. */

.pag { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
       gap: var(--e-3); margin-top: var(--e-4); padding-top: var(--e-3);
       border-top: 1px solid var(--borda); }
.pag-resumo { color: var(--texto-2); font-size: var(--t-xs);
              font-variant-numeric: tabular-nums; margin: var(--e-3) 0 0; }
.pag .pag-resumo { margin: 0; }
.pag-botoes { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; }

.pag-btn { display: inline-flex; align-items: center; justify-content: center;
           min-width: 38px; height: 38px; padding: 0 10px;
           border: 1px solid var(--borda); border-radius: var(--raio);
           background: var(--superficie); color: var(--texto);
           font: 500 var(--t-xs)/1 var(--fonte-titulo);
           font-variant-numeric: tabular-nums; text-decoration: none;
           transition: background 140ms, border-color 140ms; }
a.pag-btn:hover { background: var(--superficie-2); border-color: var(--borda-forte);
                  text-decoration: none; }
a.pag-btn:focus-visible { outline: 2px solid var(--primaria); outline-offset: 2px; }

/* A página atual é <span>, não link: clicar nela não leva a lugar
   nenhum, e um link que não navega é o que gasta a confiança no resto
   da barra. Fundo cheio + peso, para não depender só da cor. */
.pag-btn.atual { background: var(--primaria); border-color: var(--primaria);
                 color: var(--primaria-texto); font-weight: 700; cursor: default; }
.pag-btn.off { opacity: .4; cursor: default; }
.pag-gap { padding: 0 2px; color: var(--texto-3); }

@media (max-width: 560px) {
  .pag { justify-content: center; }
  .pag-resumo { width: 100%; text-align: center; }
}
@media (prefers-reduced-motion: reduce) { .pag-btn { transition: none; } }
@media print { .pag-botoes { display: none; } }

/* ============================================================
   O TEMPO
   ============================================================
   Três blocos que se separam sozinhos quando a tela estreita: agora,
   hoje, e os próximos dias. Cada um some inteiro se a API não mandou
   os campos dele — não há bloco que dependa de outro. */

.clima { display: grid; gap: var(--e-4); }
@media (min-width: 900px) {
  /* auto para "agora" (é o que tem o número grande), 1fr para "hoje". */
  .clima { grid-template-columns: auto 1fr; align-items: start; }
  .clima-dias { grid-column: 1 / -1; }
}

.clima-agora { display: flex; align-items: center; gap: var(--e-4); flex-wrap: wrap; }
.clima-icone { width: 46px; height: 50px; flex: none; color: var(--primaria); }
.clima-temp { font: 700 var(--t-2xl)/1 var(--fonte-titulo);
              font-variant-numeric: tabular-nums; letter-spacing: -.02em; }
.clima-grau { font-size: var(--t-md); font-weight: 600; color: var(--texto-2); margin-left: 2px; }
.clima-desc { color: var(--texto-2); font-size: var(--t-sm); margin-top: 2px; }

/* Os pares rótulo/valor. dl porque é exatamente isso que eles são. */
.clima-nums { display: flex; flex-wrap: wrap; gap: var(--e-3) var(--e-5); margin: 0; }
.clima-nums > div { display: flex; flex-direction: column; gap: 1px; }
.clima-nums dt { font: 700 var(--t-xs)/1 var(--fonte-titulo); text-transform: uppercase;
                 letter-spacing: .06em; color: var(--texto-3); }
.clima-nums dd { margin: 0; font-weight: 600; font-variant-numeric: tabular-nums; }

.clima-hoje { display: grid; gap: var(--e-3); }
@media (min-width: 900px) {
  .clima-hoje { border-left: 1px solid var(--borda); padding-left: var(--e-5); }
}

/* O alcance térmico. A barra é decoração do intervalo; os números dos
   dois lados são o dado, e é por isso que a barra é aria-hidden —
   quem não a enxerga não perde nada. */
.clima-faixa-termica { display: flex; align-items: center; gap: var(--e-2); flex-wrap: wrap; }
.clima-min, .clima-max { font: 700 var(--t-lg)/1 var(--fonte-titulo);
                         font-variant-numeric: tabular-nums; }
.clima-min { color: var(--texto-2); }
.clima-barra { flex: 1 1 60px; min-width: 60px; height: 6px; border-radius: 3px;
               background: linear-gradient(to right,
                           color-mix(in srgb, var(--primaria) 45%, transparent),
                           var(--atencao)); }
.clima-amp { font-size: var(--t-xs); color: var(--texto-3); white-space: nowrap; }

/* Os próximos dias. Rola no próprio contêiner quando não cabe, em vez
   de empurrar a página para o lado. */
.clima-dias { list-style: none; margin: 0; padding: var(--e-3) 0 0; display: flex;
              gap: var(--e-2); border-top: 1px solid var(--borda);
              overflow-x: auto;
              /* stretch: cartões lado a lado terminam na mesma linha.
                 Chegou a ficar 'start' enquanto um deles estava inchado
                 por uma colisão de nome de classe — resolvida a colisão,
                 stretch é o certo, e é o que o auditor de alinhamento
                 cobra. */
              align-items: stretch; }
.clima-dias > li { flex: 1 1 0; min-width: 86px; display: flex; flex-direction: column;
                   align-items: center; gap: 4px; padding: var(--e-3) 4px;
                   border-radius: var(--raio); background: var(--superficie-2); }
.clima-dias .clima-icone { width: 28px; height: 30px; }
.clima-dia-rot { font: 700 var(--t-xs)/1 var(--fonte-titulo); text-transform: uppercase;
                 letter-spacing: .06em; color: var(--texto-2); }
.clima-dia-t { display: flex; align-items: baseline; gap: 5px;
               font-variant-numeric: tabular-nums; }
.clima-dia-min { color: var(--texto-3); font-size: var(--t-xs); }
.clima-dia-chuva { font-size: var(--t-xs); color: var(--primaria-link);
                   font-variant-numeric: tabular-nums; }
.clima-dia-chuva.clima-dia-sem { color: var(--texto-3); }

@media print { .clima { display: none; } }

/* Trocar a cidade do tempo. Fechado não ocupa nada; quem nunca vai
   mexer não repara que existe. */
.clima-trocar { grid-column: 1 / -1; border-top: 1px solid var(--borda); padding-top: var(--e-3); }
.clima-trocar > summary { cursor: pointer; color: var(--texto-3); font-size: var(--t-xs);
                          list-style: none; }
.clima-trocar > summary::-webkit-details-marker { display: none; }
.clima-trocar > summary::before { content: '⚙ '; }
.clima-trocar > summary:hover { color: var(--primaria-link); }
.clima-trocar[open] > summary { margin-bottom: var(--e-3); }
.clima-trocar .dica { margin-top: var(--e-2); }

/* ============================================================
   ÁREA DE DESCOMPRESSÃO
   ============================================================ */
.descomp { margin-top: var(--e-6); }
.descomp > .entre { align-items: baseline; }

/* Travada: a tarja NÃO é esmaecida junto com o que ela explica —
   aviso apagado é aviso que ninguém lê. */
.descomp-tarja { display: flex; flex-wrap: wrap; align-items: center; gap: var(--e-3);
  background: var(--atencao-fundo); border: 1px solid color-mix(in srgb, var(--atencao) 40%, transparent);
  border-radius: var(--raio); padding: var(--e-3) var(--e-4); margin: var(--e-3) 0; }
.descomp-tarja strong { color: var(--atencao); }
.descomp-tarja span { color: var(--texto-2); font-size: var(--t-sm); }
.descomp-tarja .btn { margin-left: auto; }

/* Os vultos: a moldura dos jogos sem os jogos. O HTML deles nem vai
   para a página quando está travado — esmaecer com CSS deixaria o
   jogo funcionando atrás do véu, a um F12 de distância. */
.descomp-fantasma { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--e-3); opacity: .35; filter: grayscale(1); }
.descomp-vulto { border: 1px dashed var(--borda-forte); border-radius: var(--raio);
  min-height: 96px; display: flex; align-items: center; justify-content: center;
  color: var(--texto-3); font: 600 var(--t-sm)/1 var(--fonte-titulo); }

.descomp-abas { display: flex; gap: 4px; flex-wrap: wrap; margin: var(--e-3) 0; }
.descomp-aba { font: 600 var(--t-sm)/1 var(--fonte-titulo); padding: 9px 14px;
  border: 1px solid var(--borda); border-radius: var(--raio-sm);
  background: var(--superficie); color: var(--texto-2); cursor: pointer;
  transition: background var(--transicao); }
.descomp-aba:hover { background: var(--superficie-2); }
.descomp-aba.on { background: var(--primaria); border-color: var(--primaria);
  color: var(--primaria-texto); }
.descomp-aba:focus-visible { outline: 2px solid var(--primaria); outline-offset: 2px; }

.descomp-tela { display: flex; flex-wrap: wrap; gap: var(--e-5); align-items: flex-start; }
.descomp-tela canvas { border: 1px solid var(--borda); border-radius: var(--raio);
  background: var(--superficie-2); touch-action: none; }
.descomp-tela canvas:focus-visible { outline: 2px solid var(--primaria); outline-offset: 2px; }
.descomp-lado { flex: 1 1 200px; display: flex; flex-direction: column; gap: var(--e-3);
  align-items: flex-start; }
.descomp-placar { display: flex; flex-direction: column; gap: 1px; }
.descomp-placar .rot { font: 700 var(--t-xs)/1 var(--fonte-titulo); text-transform: uppercase;
  letter-spacing: .06em; color: var(--texto-3); }
.descomp-placar strong { font: 700 var(--t-xl)/1 var(--fonte-titulo);
  font-variant-numeric: tabular-nums; }
/* A fala do jogo: pausa, motivo, fim de partida. Nasce escondida
   (hidden no HTML) e só ocupa espaço quando tem o que dizer. */
.descomp-aviso { margin: 0; font-size: var(--t-sm); line-height: 1.35;
  color: var(--texto-2); border-left: 3px solid var(--borda-forte);
  padding: 4px 0 4px 9px; }
.descomp-aviso.atento { color: var(--atencao); border-left-color: var(--atencao); }
.descomp-aviso.calmo  { color: var(--texto-3); }

/* ---- ranking ---- */
.descomp-ranking { margin-top: var(--e-5); padding-top: var(--e-4);
  border-top: 1px solid var(--borda); }
.descomp-ranking h3 { margin: 0; font-size: var(--t-lg); }
.descomp-tabelas { display: grid; gap: var(--e-4); margin-top: var(--e-3);
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.descomp-tabela h4 { margin: 0 0 var(--e-2); font-size: var(--t-sm);
  color: var(--texto-2); text-transform: uppercase; letter-spacing: .05em; }
.descomp-lista { list-style: none; margin: 0; padding: 0; }
.descomp-lista li { display: flex; align-items: baseline; gap: var(--e-2);
  padding: 5px 0; border-top: 1px solid var(--borda); }
.descomp-lista li:first-child { border-top: 0; }
.descomp-lista .pos { min-width: 26px; color: var(--texto-3);
  font: 700 var(--t-xs)/1 var(--fonte-titulo); font-variant-numeric: tabular-nums; }
.descomp-lista .quem { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.descomp-lista .pts { font-variant-numeric: tabular-nums; }
/* Cor não é o único sinal: quem é você leva o "(você)" escrito. */
.descomp-lista li.eu { background: var(--primaria-suave); border-radius: var(--raio-sm);
  padding-left: 6px; padding-right: 6px; }

.descomp-badges { margin-top: var(--e-4); }
.descomp-badges .rot { font: 700 var(--t-xs)/1 var(--fonte-titulo); text-transform: uppercase;
  letter-spacing: .06em; color: var(--texto-3); }
.descomp-badges ul { list-style: none; margin: var(--e-2) 0 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: var(--e-2); }
.descomp-badges li { background: var(--superficie-2); border: 1px solid var(--borda);
  border-radius: 999px; padding: 5px 12px; font-size: var(--t-xs); }

@media print { .descomp { display: none; } }

/* ============================================================
   CABECALHO DE LISTA COM ACAO
   ============================================================
   O <h2> da lista passou a carregar o botao "Novo ...". Fica no
   cabecalho da lista, e nao solto no topo da tela, porque e ali que a
   pessoa esta olhando quando conclui que o que ela procura ainda nao
   existe.

   `gap` cuida do espaco nos dois eixos: em tela estreita o botao cai
   para a linha de baixo sem encostar no titulo. */
.cab-lista { display: flex; align-items: center; justify-content: space-between;
             flex-wrap: wrap; gap: var(--e-2) var(--e-3); }
.cab-lista > .btn { flex: 0 0 auto; }

/* O logo no cadastro do cliente: aqui sim, fiel — cor, proporção e
   tamanho de verdade. É onde a pessoa confere se subiu o arquivo
   certo. O xadrez atrás revela PNG com fundo transparente, que é a
   armadilha clássica (logo branco em fundo branco "sumiu"). */
.logo-previa {
  display: flex; align-items: center; gap: var(--e-4);
  padding: var(--e-3); border: 1px solid var(--borda); border-radius: 8px;
  background-color: var(--superficie-2);
  background-image:
    linear-gradient(45deg, color-mix(in srgb, var(--texto) 7%, transparent) 25%, transparent 25%),
    linear-gradient(-45deg, color-mix(in srgb, var(--texto) 7%, transparent) 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, color-mix(in srgb, var(--texto) 7%, transparent) 75%),
    linear-gradient(-45deg, transparent 75%, color-mix(in srgb, var(--texto) 7%, transparent) 75%);
  background-size: 16px 16px;
  background-position: 0 0, 0 8px, 8px -8px, -8px 0;
}
.logo-previa img { max-width: 190px; max-height: 90px; object-fit: contain; }
.logo-previa .acoes { margin-left: auto; }

/* ============================================================
   Rastro do DevOps: build, release, changeset, versao por ambiente
   Tudo em tokens do tema -- claro, escuro e automatico saem de graca.
   ============================================================ */

.devops-rastro {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 10px 0 6px;
  border: 1px solid var(--borda);
  border-radius: var(--raio);
  overflow: hidden;
}

.dv-linha {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
  padding: 8px 12px;
  background: var(--superficie);
  font-size: .9rem;
}
.dv-linha + .dv-linha { border-top: 1px solid var(--borda); }

.dv-selo {
  flex: 0 0 auto;
  display: inline-block;
  padding: 2px 8px;
  border-radius: var(--raio-pill);
  font-size: .75rem;
  font-weight: 600;
  white-space: nowrap;
  background: var(--superficie-3);
  color: var(--texto-2);
}
.dv-sucesso    { background: var(--sucesso-fundo); color: var(--sucesso); }
.dv-parcial    { background: var(--atencao-fundo); color: var(--atencao); }
.dv-rodando    { background: var(--selo-fundo);    color: var(--selo-texto); }
.dv-na_fila    { background: var(--superficie-3);  color: var(--texto-2); }
.dv-falhou     { background: var(--erro-fundo);    color: var(--erro); }
.dv-cancelado  { background: var(--superficie-3);  color: var(--texto-3); }
.dv-indefinido { background: var(--superficie-3);  color: var(--texto-3); }
.dv-cs         { background: var(--superficie-2);  color: var(--texto-2); font-weight: 500; }

/* O texto e quem cede espaco quando a tela e estreita. */
.dv-texto  { flex: 1 1 180px; min-width: 0; overflow-wrap: anywhere; color: var(--texto); }
.dv-quando { flex: 0 0 auto; color: var(--texto-3); font-size: .8rem; white-space: nowrap; }

.devops-proc  { margin: 4px 0 0; font-size: .8rem; }
.devops-aviso { margin: 8px 0 0; color: var(--atencao); }

/* ---------- painel de versao por ambiente ---------- */
.dv-painel { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }

.dv-amb {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 12px;
  padding: 10px 12px;
  border: 1px solid var(--borda);
  border-radius: var(--raio);
  background: var(--superficie);
}
/* Largura FIXA, e nao auto: com auto, o numero da versao comecava
   num x diferente em cada linha, conforme o tamanho do nome do
   ambiente -- e a coluna que as pessoas leem de cima a baixo e
   justamente a dos numeros. */
.dv-amb-nome {
  flex: 0 0 230px;
  font-weight: 600; color: var(--texto);
  overflow-wrap: anywhere;
}
.dv-amb-corpo { flex: 1 1 220px; min-width: 0; }

/* A versao e o numero que as pessoas vao ler primeiro; merece
   monoespacada, para 2026.8.24.1 nao virar borrao. */
.dv-versao {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .9rem;
  color: var(--texto);
  overflow-wrap: anywhere;
}
/* A procedencia NAO e enfeite: e ela que impede alguem ler "versao em
   producao" quando o que a tela sabe e "ultima release bem-sucedida". */
.dv-proc { display: block; font-size: .78rem; color: var(--texto-3); margin-top: 2px; }
.dv-sem-mapa { color: var(--texto-3); font-size: .85rem; }

@media (max-width: 520px) {
  .dv-quando { flex: 1 1 100%; }
  .dv-amb-nome { flex: 1 1 100%; }
}

/* ---------- Central DevOps: atalhos e work items ---------- */
.dv-atalhos {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 8px;
}
.dv-atalho {
  display: block;
  padding: 10px 12px;
  border: 1px solid var(--borda);
  border-radius: var(--raio);
  background: var(--superficie);
  text-decoration: none;
  transition: border-color var(--transicao), background var(--transicao);
}
.dv-atalho:hover, .dv-atalho:focus-visible {
  border-color: var(--primaria);
  background: var(--superficie-2);
}
.dv-atalho-tipo {
  display: block; font-size: .72rem; text-transform: uppercase;
  letter-spacing: .04em; color: var(--texto-3);
}
.dv-atalho-nome {
  display: block; font-weight: 600; color: var(--texto);
  /* A linha existe mesmo vazia. Sem isso, card com rotulo
     ficava mais alto que card sem, e a grade saia torta --
     era o que se via em Producao e UAT ao lado de DEV-001. */
  min-height: 1.35em;
  overflow-wrap: anywhere;
}
.dv-atalho-url  { display: block; font-size: .8rem; color: var(--primaria-link); overflow-wrap: anywhere; }

.tbl-wi { width: 100%; }
.tbl-wi td { vertical-align: top; padding: 6px 8px 6px 0; }
.wi-num { white-space: nowrap; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }

/* O seletor de origem da versao fica recuado, para ler como detalhe
   do endereco de cima e nao como um endereco novo. */
.amb-release { margin: 4px 0 12px 16px; align-items: center; gap: 8px; }

/* ---------- abas de recorte dos work items ---------- */
.dv-abas { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 10px; }
.dv-aba {
  padding: 5px 12px;
  border: 1px solid var(--borda);
  border-radius: var(--raio-pill);
  font-size: .85rem;
  color: var(--texto-2);
  text-decoration: none;
  background: var(--superficie);
}
.dv-aba:hover { border-color: var(--borda-forte); color: var(--texto); }
.dv-aba.on {
  background: var(--primaria); border-color: var(--primaria);
  color: var(--primaria-texto); font-weight: 600;
}

/* O icone herda a cor do selo por currentColor -- nunca descasa. */
.dv-icone { vertical-align: -1px; margin-right: 5px; }

/* ---------- a atividade de cada lancamento, no detalhe da celula ---------- */
.lin-atv { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 6px; }
.lin-atv label { font-size: .78rem; color: var(--texto-3); margin: 0; }
.lin-atv select { flex: 1 1 160px; min-width: 0; }
.btn-mini { padding: 4px 10px; font-size: .8rem; }

/* o "procurar" ao lado do work item: discreto, forte no hover */
.wi-abrir { display: inline-block; margin-left: 6px; font-size: .78rem; }

/* filtro dentro de card: mais compacto que o filtro de topo de tela */
.dv-filtro { margin: 0 0 10px; padding: 0; border: 0; }
.dv-filtro .campo { margin-bottom: 0; }

/* ---------- o build, com procedencia ---------- */
.dv-build-num  { display: block; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
.dv-build-desc { display: block; color: var(--texto); overflow-wrap: anywhere; margin-top: 1px; }
.dv-linha .dv-texto .dv-proc { margin-top: 1px; }

/* ============================================================
   CENTRAL DEVOPS — passe visual
   ------------------------------------------------------------
   Tudo em token. Nenhum #hex literal aqui: se precisou de um,
   faltava um token. Vale nos tres estados de tema (claro,
   escuro e "sistema"), porque nada e definido so dentro do
   bloco escuro.

   A ideia: profundidade discreta e hierarquia forte, em vez de
   enfeite. O que salta aos olhos e o NUMERO (versao, build,
   work item) -- e o numero vem sempre com a procedencia colada
   nele, porque numero sem procedencia e como se erra sem
   perceber.
   ============================================================ */

/* ---------- faixa de indicadores ---------- */
.dv-faixa {
  display: grid;
  /* auto-FILL, e nao auto-fit: o fit colapsa as trilhas vazias, e
     dois indicadores viravam dois blocos de meia tela cada. */
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 10px;
  margin-bottom: 14px;
}
.dv-kpi {
  position: relative;
  padding: 14px 16px 14px 18px;
  border: 1px solid var(--borda);
  border-radius: var(--raio);
  background:
    linear-gradient(180deg,
      color-mix(in srgb, var(--superficie) 100%, transparent),
      color-mix(in srgb, var(--superficie-2) 55%, var(--superficie)));
  overflow: hidden;
}
/* A faixa colorida e o que diz de que AMBIENTE e o numero, sem
   precisar ler o rotulo. Producao nunca e azul: producao pede
   atencao, e atencao tem cor propria. */
.dv-kpi::before {
  content: "";
  position: absolute; inset: 0 auto 0 0; width: 3px;
  background: var(--primaria);
}
.dv-kpi-ok::before   { background: var(--sucesso); }
.dv-kpi-erro::before { background: var(--erro); }

.dv-kpi-rot {
  display: block;
  font-size: .69rem; text-transform: uppercase; letter-spacing: .06em;
  color: var(--texto-3); margin-bottom: 4px;
}
.dv-kpi-val {
  display: block;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 1.12rem; font-weight: 600; color: var(--texto);
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere; line-height: 1.25;
}
.dv-kpi-obs { display: block; font-size: .76rem; color: var(--texto-3); margin-top: 3px; }

/* ---------- atalhos de ambiente ---------- */
.dv-atalho {
  position: relative;
  padding-left: 16px;
}
.dv-atalho::before {
  content: "";
  position: absolute; inset: 0 auto 0 0; width: 3px;
  border-radius: var(--raio) 0 0 var(--raio);
  background: var(--borda-forte);
  transition: background var(--transicao);
}
.dv-atalho:hover::before, .dv-atalho:focus-visible::before { background: var(--primaria); }
.dv-a-lcs::before             { background: var(--primaria-suave); }
.dv-a-devops::before          { background: var(--primaria); }
.dv-a-producao::before        { background: var(--atencao); }
.dv-a-uat::before             { background: var(--sucesso); }
.dv-a-desenvolvimento::before { background: var(--borda-forte); }

/* O endereco vira o HOST, em mono. O caminho inteiro com GUID nao
   cabe, nao diferencia e ainda empurra o resto para fora da tela. */
.dv-atalho-url {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .76rem;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.dv-atalho:hover { transform: translateY(-1px); }
.dv-atalho { will-change: transform; }

/* ---------- versoes implantadas ---------- */
.dv-amb {
  position: relative;
  padding-left: 18px;
  align-items: center;
}
.dv-amb::before {
  content: "";
  position: absolute; inset: 0 auto 0 0; width: 3px;
  border-radius: var(--raio) 0 0 var(--raio);
  background: var(--primaria);
}
.dv-amb-producao::before        { background: var(--atencao); }
.dv-amb-uat::before             { background: var(--sucesso); }
.dv-amb-desenvolvimento::before { background: var(--borda-forte); }

.dv-versao {
  font-size: 1.05rem; font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.01em;
}

/* ---------- builds ---------- */
.dv-resumo {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 14px;
  padding: 8px 12px; margin-bottom: 10px;
  border: 1px solid var(--borda); border-radius: var(--raio);
  background: var(--superficie-2);
  font-size: .82rem; color: var(--texto-2);
}
.dv-resumo strong { color: var(--texto); font-variant-numeric: tabular-nums; }
.dv-resumo .rok   { color: var(--sucesso); }
.dv-resumo .rerro { color: var(--erro); }

.dv-build-num {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-weight: 600; font-variant-numeric: tabular-nums;
}
.dv-build-desc {
  font-size: .88rem;
  /* break-word, e NAO anywhere: 'anywhere' partia
     BD_FIS106_FiscalDocReturnFiscalReferenceLine no meio da
     palavra, e nome de classe partido ao meio deixa de ser
     procuravel. */
  overflow-wrap: break-word;
}

/* ---------- work items ---------- */
.tbl-wi tr + tr td { border-top: 1px solid var(--borda); }
.wi-num a, .wi-num {
  font-weight: 600; font-variant-numeric: tabular-nums;
  color: var(--primaria-link);
}

/* ---------- movimento ---------- */
@media (prefers-reduced-motion: reduce) {
  .dv-atalho, .dv-atalho::before { transition: none; }
  .dv-atalho:hover { transform: none; }
}

/* ---------- work item, com o que a API ja mandava ---------- */
.wi-lista { display: flex; flex-direction: column; }
.wi-item {
  padding: 10px 0;
  border-top: 1px solid var(--borda);
}
.wi-item:first-child { border-top: 0; }

.wi-topo { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px; }
.wi-num {
  flex: 0 0 auto;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-weight: 600; font-variant-numeric: tabular-nums;
  color: var(--primaria-link);
}
.wi-titulo { flex: 1 1 260px; min-width: 0; color: var(--texto); font-weight: 600; overflow-wrap: break-word; }
.wi-selos  { flex: 0 0 auto; display: flex; flex-wrap: wrap; gap: 4px; }

/* Selo se le sem ler: por isso so entra aqui o que muda a decisao de
   pegar ou nao o item. O resto vai na linha de baixo, em texto miudo. */
.wi-selo {
  display: inline-block; padding: 1px 7px;
  border-radius: var(--raio-pill);
  font-size: .7rem; font-weight: 600; white-space: nowrap;
  background: var(--superficie-2); color: var(--texto-2);
}
.wi-tipo   { background: var(--superficie-3); }
.wi-estado { background: var(--selo-fundo); color: var(--selo-texto); }
.wi-prio   { background: var(--atencao-fundo); color: var(--atencao); }
.wi-marca  { background: var(--primaria-suave); color: var(--wr-azul-900, var(--selo-texto)); }
.wi-prazo  { background: var(--superficie-2); color: var(--texto-3); }
.wi-atraso { background: var(--erro-fundo); color: var(--erro); }

.wi-resumo {
  margin-top: 3px;
  font-size: .85rem; color: var(--texto-2);
  overflow-wrap: break-word;
}
.wi-item .dv-proc { margin-top: 3px; }

@media (max-width: 560px) {
  .wi-titulo { flex: 1 1 100%; }
  .wi-selos  { flex: 1 1 100%; }
}

/* ============================================================
   SELOS DE VERSAO -- um por ambiente, do tamanho de um dado.

   A versao de cada ambiente aparecia duas vezes na mesma tela: na
   faixa do topo e num card inteiro logo abaixo, que gastava uma
   linha de altura por ambiente para mostrar um numero de onze
   caracteres. Duas copias do mesmo numero na mesma tela e convite
   para discordarem -- e quando discordam ninguem sabe em qual
   acreditar.

   Agora e um selo por lugar, e o card virou a PROCEDENCIA deles,
   recolhida logo abaixo.
   ============================================================ */
.dv-versoes {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(164px, 1fr));
  gap: 8px;
  margin-bottom: 10px;
}
.dv-vs {
  position: relative;
  display: block;
  min-width: 0;
  padding: 9px 11px 9px 15px;
  border: 1px solid var(--borda);
  border-radius: var(--raio);
  background: var(--superficie);
  color: inherit;
  text-decoration: none;
  transition: transform .12s ease, border-color .12s ease;
}
a.dv-vs:hover { transform: translateY(-1px); border-color: var(--borda-forte); }

/* A cor diz o LUGAR, nao o estado -- por isso ela e a mesma dos
   atalhos de endereco logo abaixo. Producao nunca e azul: producao
   pede atencao, e atencao tem cor propria. */
.dv-vs::before {
  content: "";
  position: absolute; inset: 0 auto 0 0; width: 3px;
  border-radius: var(--raio) 0 0 var(--raio);
  background: var(--borda-forte);
}
.dv-vs-producao::before        { background: var(--atencao); }
.dv-vs-uat::before             { background: var(--sucesso); }
.dv-vs-desenvolvimento::before { background: var(--borda-forte); }
.dv-vs-lcs::before             { background: var(--primaria-suave); }
.dv-vs-devops::before          { background: var(--primaria); }

/* O rotulo corta com reticencias; o NUMERO nunca corta. Nome de
   ambiente cortado ainda da para adivinhar, versao cortada vira
   outra versao. */
.dv-vs-rot {
  /* DUAS LINHAS, e nao reticencias.
     Com nowrap, "UAT (Tier-2 / UNO) - fusxp" e "UAT (Tier-2 / UNO) -
     So com aprovacao" cortavam os dois em "UAT (TIER-2 / UNO) - ...":
     o corte comia justamente o pedaco que DISTINGUE um do outro, que
     e o defeito que este selo existe para resolver. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-size: .67rem; text-transform: uppercase; letter-spacing: .05em;
  line-height: 1.25;
  color: var(--texto-3);
}
.dv-vs-val {
  display: block; margin-top: 2px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 1rem; font-weight: 600; color: var(--texto);
  font-variant-numeric: tabular-nums; letter-spacing: -.01em;
  line-height: 1.2; overflow-wrap: anywhere;
}
.dv-vs-obs {
  display: block; margin-top: 2px;
  font-size: .72rem; color: var(--texto-3);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* Ambiente sem release NAO some da fila: fica apagado. Fila que
   esconde os brancos nao e panorama, e a parte boa do panorama. */
.dv-vs-sem  .dv-vs-val { color: var(--texto-3); font-weight: 500; }
.dv-vs-erro .dv-vs-val { color: var(--erro); }
.dv-vs-erro::before      { background: var(--erro); }

/* ---------- o detalhe recolhido ---------- */
.dv-detalhe > summary {
  cursor: pointer;
  list-style: none;
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px;
}
.dv-detalhe > summary::-webkit-details-marker { display: none; }
.dv-detalhe > summary h2 { margin: 0; }
.dv-detalhe-dica { font-size: .78rem; color: var(--texto-3); }
.dv-detalhe > summary::after {
  content: "\25BE";
  display: inline-block; margin-left: auto;
  color: var(--texto-3); font-size: .8rem;
  transition: transform .15s ease;
}
.dv-detalhe[open] > summary::after { transform: rotate(180deg); }
.dv-detalhe > summary:focus-visible { outline: 2px solid var(--primaria); outline-offset: 3px; }
.dv-detalhe[open] > .dv-painel { margin-top: 10px; }

/* A linha que diz DE ONDE saiu a descricao do build. Fica so para
   gestor, e mostra nome de campo -- nunca valor de campo. */
.dv-proced { margin-top: -4px; }
.dv-proced code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .92em;
}

/* ============================================================
   CABECALHO QUE ORDENA, E QUANTOS POR PAGINA
   ============================================================ */
.lista-barra {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px;
  margin: 0 0 10px;
}
.pag-por { display: flex; align-items: center; gap: 8px; margin: 0; }
.pag-por label { margin: 0; font-size: var(--t-xs); color: var(--texto-2); }
.pag-por select { width: auto; padding: 5px 8px; font-size: var(--t-sm); }

/* O cabecalho inteiro e a area de clique: alvo do tamanho da
   palavra faz a pessoa errar e reordenar pela coluna do lado. */
th > a.ord {
  display: flex; align-items: center; gap: 5px;
  margin: -8px -10px; padding: 8px 10px;
  color: inherit; text-decoration: none; border-radius: var(--raio-sm);
  white-space: nowrap;
}
th.num > a.ord { justify-content: flex-end; }
th > a.ord:hover { background: color-mix(in srgb, var(--texto) 8%, transparent); text-decoration: none; }
th > a.ord:focus-visible { outline: 2px solid var(--primaria); outline-offset: -2px; }
/* A coluna ordenada fica marcada mesmo sem a seta: quem chega na
   tela precisa saber por onde ela esta ordenada antes de procurar
   o simbolo. */
th > a.ord.on { color: var(--texto); font-weight: 700; }
.ord-seta { font-size: .85em; color: var(--primaria); }

/* ============================================================
   DOCUMENTO DE ENTREGAS
   ============================================================ */

/* A linha do tempo. Barra EMPILHADA, e nao duas lado a lado: a
   pergunta e o RITMO do mes, e barras lado a lado fariam o olho
   comparar evolutivo com corretivo, que e outra pergunta. */
.ent-tempo {
  display: flex; align-items: flex-end; gap: 5px;
  height: 132px; margin: 10px 0 4px;
  overflow-x: auto;
}
.ent-mes {
  flex: 1 1 26px; min-width: 26px;
  display: flex; flex-direction: column; align-items: center; gap: 3px;
}
.ent-barra {
  width: 100%; height: 92px;
  display: flex; flex-direction: column-reverse; justify-content: flex-start;
  border-radius: 3px 3px 0 0; overflow: hidden;
  background: color-mix(in srgb, var(--texto) 6%, transparent);
}
.ent-barra i { display: block; width: 100%; }
/* Mesmas cores do resto do sistema: verde e o que deu certo, ambar
   pede atencao, cinza e o que ainda nao se sabe. */
.ent-e { background: var(--sucesso); }
.ent-c { background: var(--atencao); }
.ent-n { background: var(--borda-forte); }

.ent-num { font: 600 .72rem/1 var(--fonte-titulo); color: var(--texto-2);
  font-variant-numeric: tabular-nums; min-height: .8rem; }
.ent-rot { font-size: .66rem; color: var(--texto-3); white-space: nowrap; }

.ent-leg {
  display: inline-block; width: 10px; height: 10px; border-radius: 2px;
  margin: 0 3px 0 10px; vertical-align: -1px;
}
.ent-leg:first-child { margin-left: 0; }

/* Item tirado do documento continua na tela, apagado. Sumir esconderia
   uma decisao que alguem tomou -- e ninguem lembraria de desfazer. */
.ent-oculto > td { opacity: .5; }
.ent-oculto > td:last-child { opacity: 1; }

/* Formulario de uma celula: select e botao na mesma linha, sem o
   respiro de formulario de tela cheia. */
.ent-regra { display: flex; align-items: center; gap: 5px; margin: 0; }
.ent-regra select { width: auto; min-width: 130px; padding: 4px 7px; font-size: .82rem; }

.ent-param > summary {
  cursor: pointer; margin-top: 12px;
  font: 600 .85rem/1.4 var(--fonte-titulo); color: var(--texto-2);
}
.ent-param > summary:hover { color: var(--texto); }

/* ============================================================
   BLOCO REMOTO — o dado externo chegando, à vista
   ============================================================
   A barra é sempre visível enquanto o bloco existe: some só quando
   não há mais nada a dizer. O cronômetro é tabular para o número não
   dançar a cada décimo. */
.wr-remoto { margin: 0; }
.wr-remoto-barra {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: .8rem; color: var(--texto-2);
  padding: 6px 0 8px;
}
.wr-remoto-tempo { font-variant-numeric: tabular-nums; color: var(--texto-3); }
.wr-remoto-bt {
  font: inherit; color: var(--primaria-link); background: none;
  border: 1px solid var(--borda-forte); border-radius: var(--raio-sm);
  padding: 2px 9px; cursor: pointer; margin-left: auto;
}
.wr-remoto-bt:hover { background: var(--superficie-2); }
.wr-remoto-bt:focus-visible { outline: 2px solid var(--primaria); outline-offset: 2px; }

/* O sinal: um ponto que pulsa enquanto busca, e vira marca de estado
   quando termina. Cor sozinha não diz nada a quem não a distingue --
   por isso o texto ao lado muda junto, sempre. */
.wr-remoto-sinal {
  width: 8px; height: 8px; border-radius: 50%; flex: none;
  background: var(--texto-3);
}
.wr-remoto-buscando .wr-remoto-sinal { background: var(--primaria); animation: wr-pulso 1s ease-in-out infinite; }
.wr-remoto-pronto   .wr-remoto-sinal { background: var(--ok, #0f7a44); }
.wr-remoto-falhou   .wr-remoto-sinal { background: var(--atencao); }
.wr-remoto-falhou .wr-remoto-dizer { color: var(--atencao); }

@keyframes wr-pulso {
  0%, 100% { opacity: 1;   transform: scale(1); }
  50%      { opacity: .35; transform: scale(.7); }
}

/* O esqueleto: a forma do conteúdo antes do conteúdo. Serve para a
   página não PULAR quando o dado chega -- o salto é o que faz a
   pessoa perder o lugar onde estava lendo. */
.wr-esqueleto { display: flex; flex-direction: column; gap: 9px; padding: 4px 0 2px; }
.wr-esq-linha {
  height: 13px; border-radius: 7px; display: block;
  background: linear-gradient(90deg,
    var(--superficie-2) 0%, var(--borda) 40%, var(--superficie-2) 80%);
  background-size: 300% 100%;
  animation: wr-brilho 1.4s ease-in-out infinite;
}
@keyframes wr-brilho {
  0%   { background-position: 130% 0; }
  100% { background-position: -30% 0; }
}

/* Menos movimento: o brilho e o pulso saem, o cronômetro fica. Ele é
   informação -- tirar o número deixaria a pessoa sem saber se a
   página está viva, que é o problema original. */
:root[data-remoto-parado] .wr-esq-linha,
:root[data-remoto-parado] .wr-remoto-sinal { animation: none; }
:root[data-remoto-parado] .wr-esq-linha { background: var(--superficie-2); }
@media (prefers-reduced-motion: reduce) {
  .wr-esq-linha, .wr-remoto-sinal { animation: none; }
  .wr-esq-linha { background: var(--superficie-2); }
}
