/* ============================================================
   Dot Energia — tokens do DESIGN.md aplicados à UI de Operações.

   Três regras do design system que mandam no resto deste arquivo:
   1. #00c11b é assinatura e ação: UMA por tela, menos de 5% da superfície,
      sempre com texto grafite por cima. Nunca em gráfico de consumo nem em P&L.
   2. Não existe #fff nem #000 aqui: a base é creme #f2efeb e grafite quente
      #1c1c1c. Profundidade é camada tonal, não sombra preta.
   3. Geometria redonda: input 16px, cartão 24px, botão e chip em pílula.
   ============================================================ */

@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap');

:root {
  /* cores da marca */
  --primary: #00c11b;
  --accent: #2efd54;
  --primary-deep: #00770b;
  --ink: #1c1c1c;
  --surface: #f2efeb;

  /* neutros derivados do creme e do grafite — sem cinza frio de biblioteca */
  --surface-alta: #faf8f6;
  --surface-baixa: #e7e2dc;
  --linha: #d9d3cb;
  --ink-70: #4a4642;
  --ink-45: #6b6660;

  /* Status. O verde da marca fica FORA daqui: "completo" usa um verde de
     floresta, escuro e sóbrio, para não competir com o CTA nem sugerir
     resultado financeiro positivo. */
  --ok: #2f6b3d;
  --ok-fundo: #e8efe7;
  --alerta: #8a5a00;
  --alerta-fundo: #fbf1de;
  --risco: #9e2626;
  --risco-fundo: #f8e9e7;
  --neutro: var(--ink-45);
  --neutro-fundo: var(--surface-baixa);

  /* espaçamento: escala de 8 com meio-passo de 4 */
  --xs: 4px; --sm: 8px; --md: 16px; --lg: 24px; --xl: 40px; --xxl: 64px;
  --gutter: 24px; --margem: 32px;
  /* Largura da PAGINA. Era 1200px fixos, e numa tela de 1920 isso deixava 360px
     vazios de cada lado enquanto a tabela de 19 colunas rolava na horizontal
     dentro da caixa estreita -- a tela do operador tinha espaco e a pagina nao
     usava. Agora ela cresce com o monitor e para de crescer onde a linha fica
     larga demais para o olho acompanhar da primeira a ultima coluna.
     Prosa nao segue isto: `.recorte` continua em 78ch, que e o que se le. */
  --largura: 2560px;

  /* raio hierárquico */
  --r-sm: 8px; --r-md: 16px; --r-lg: 24px; --r-xl: 32px; --r-full: 9999px;

  --fonte: Ricardo, Poppins, 'Segoe UI', system-ui, sans-serif;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--surface);
  color: var(--ink);
  font-family: var(--fonte);
  font-size: 16px;
  line-height: 1.6;
  font-weight: 400;
}

h1, h2, h3, .titulo { font-weight: 600; letter-spacing: -0.015em; margin: 0; }
h1 { font-size: 40px; line-height: 1.1; }
h2 { font-size: 30px; line-height: 1.15; letter-spacing: -0.01em; }
h3 { font-size: 22px; line-height: 1.2; letter-spacing: 0; }

/* Números do setor: tabulares, para alinharem na coluna. */
.dado, td.num, .valor, input[type="text"].pct {
  font-variant-numeric: tabular-nums lining-nums;
  font-feature-settings: 'tnum' 1, 'lnum' 1;
}

.label-caps {
  font-size: 13px; font-weight: 600; line-height: 1.3;
  letter-spacing: 0.06em; text-transform: uppercase;
}
.caption { font-size: 12px; line-height: 1.4; letter-spacing: 0.02em; color: var(--ink-45); }
.suave { color: var(--ink-45); }

/* ------------------------------------------------------------- topo */
.topo {
  background: var(--ink);
  color: var(--surface);
  padding: var(--md) var(--margem);
  /* O grafismo de pontos entra sangrando pela borda, grande e assimétrico —
     massa cheia de um lado, respiro do outro. */
  background-image:
    radial-gradient(circle at 92% -40%, rgba(46, 253, 84, 0.22), transparent 55%),
    radial-gradient(circle at 78% 130%, rgba(0, 193, 27, 0.16), transparent 50%);
}
.topo-interno {
  max-width: var(--largura); margin: 0 auto;
  display: flex; align-items: center; gap: var(--lg); flex-wrap: wrap;
}
/* A marca é o logo, não um texto imitando o logo. A versão de wordmark creme é
   a que existe para fundo escuro — sobre o grafite, o símbolo verde é o ponto
   mais alto da composição, e é dele que vem o glow do cabeçalho. */
.marca { display: flex; align-items: center; gap: var(--md); }
.marca img { height: 44px; width: auto; display: block; }
.marca .sub {
  font-weight: 400; font-size: 14px; color: var(--accent); letter-spacing: 0.02em;
  padding-left: var(--md); border-left: 1px solid rgba(242, 239, 235, 0.25);
}
@media (max-width: 620px) {
  .marca img { height: 34px; }
  .marca .sub { display: none; }
}

.abas { display: flex; gap: var(--xs); margin-left: auto; }
.abas button {
  font-family: var(--fonte); font-size: 15px; font-weight: 600;
  padding: 10px 18px; border-radius: var(--r-full);
  background: transparent; color: var(--surface);
  border: 1px solid rgba(242, 239, 235, 0.25); cursor: pointer;
}
.abas button:hover { border-color: var(--accent); color: var(--accent); }
/* Separa o caminho do fechamento das telas de consulta e cadastro. */
/* Separa uma acao de peso das vizinhas inofensivas: "Reabrir competencias"
   desfaz um encerramento, e estava encostada em "Recalcular". */
/* Celula sem valor porque a nota veio de fora e so traz o CNPJ. Marca discreta
   em vez de traco mudo: numa linha que diz "faturado", o traco le como falta
   de dado, e a razao real e outra -- nao da para atribuir aquela nota a esta
   unidade. */
.externa { font-size: 10px; color: var(--ink-45); border: 1px dashed var(--linha);
  border-radius: var(--r-full); padding: 1px 7px; white-space: nowrap; cursor: help; }

.separa-acao { align-self: center; width: 1px; height: 24px; margin: 0 var(--sm);
  background: var(--linha); flex: 0 0 auto; }
.abas-sep { align-self: center; width: 1px; height: 20px; margin: 0 var(--xs);
  background: rgba(242, 239, 235, 0.28); flex: 0 0 auto; }
.abas button.ativa { background: var(--surface); color: var(--ink); border-color: var(--surface); }

main { max-width: var(--largura); margin: 0 auto; padding: var(--lg) var(--margem) var(--xxl); }
.painel { display: none; }
.painel.ativo { display: block; }

/* ------------------------------------------------------------ cards */
.cartao {
  background: var(--surface-alta); border: 1px solid var(--linha);
  border-radius: var(--r-lg); padding: var(--lg);
}
.cartao-escuro {
  background: var(--ink); color: var(--surface);
  border-radius: var(--r-lg); padding: var(--lg);
  background-image: radial-gradient(circle at 100% 0%, rgba(46, 253, 84, 0.16), transparent 60%);
}
.hero { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: var(--md); }
/* Com oito cartoes o valor de 30px estoura a coluna em telas menores. */
@media (max-width: 1500px) { .hero .bloco .valor { font-size: 25px; } }
.hero .bloco { display: flex; flex-direction: column; gap: var(--xs); }
.hero .bloco .rotulo { font-size: 13px; font-weight: 600; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--accent); }
.hero .bloco .valor { font-size: 30px; font-weight: 600; line-height: 1.15; }
.hero .bloco .nota { font-size: 13px; color: rgba(242, 239, 235, 0.72); }
.hero .bloco .valor.negativo { color: #ff8a7a; }

.grade { display: grid; gap: var(--md); }
.grade-3 { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }

/* ------------------------------------------------------- chips/badges */
.chip, .badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 12px; border-radius: var(--r-full);
  font-size: 12px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase;
  white-space: nowrap;
}
/* Origem: chip grafite com texto verde elétrico (SCDE) e o inverso para a API,
   consistente e sem sugerir hierarquia entre as duas. */
.chip-scde { background: var(--ink); color: var(--accent); }
.chip-api { background: var(--accent); color: var(--ink); }

.status { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px;
  border-radius: var(--r-full); font-size: 12px; font-weight: 600; }
.status-completo { background: var(--ok-fundo); color: var(--ok); }
.status-faltante { background: var(--alerta-fundo); color: var(--alerta); }
.status-risco { background: var(--risco-fundo); color: var(--risco); }
.status-pendente { background: var(--neutro-fundo); color: var(--neutro); }
/* Fatura pronta, book nao: falta Angra. Nao trava o faturamento (o contrato
   nao a contempla), mas trava o fechamento da ponta de compra. */
.status-sem-book { background: var(--alerta-fundo); color: var(--alerta); }
/* Ajuste manual: a linha saiu da formula. Nao e erro, mas e a que mais precisa
   de um par de olhos antes de virar fatura -- por isso cor de destaque, nao de
   alerta nem de neutro. */
.status-ajustado { background: var(--primary); color: var(--ink); }
/* Estimativa da CCEE. `estimado` e informacao -- a linha fatura normalmente.
   `estimado-pendente` e decisao aberta: a projecao domina o mes e ninguem
   disse se vale faturar em cima dela. */
.status-estimado { background: var(--neutro-fundo); color: var(--neutro); }
.status-estimado-pendente { background: var(--alerta-fundo); color: var(--alerta);
  font-weight: 600; }

/* A linha inteira muda de tom quando a CCEE projetou horas dela -- pedido do
   operador (17/09/2026) para achar esses clientes varrendo a lista, sem ler
   coluna por coluna. Dois tons, porque os dois casos pedem acoes diferentes:

     parcial   um punhado de horas projetadas; fatura normalmente
     dominante a projecao manda no mes; a linha espera decisao

   O `:hover` da tabela e mais especifico que a classe, entao o realce precisa
   repetir no hover -- senao a linha "apaga" justamente quando o mouse para
   nela para ser lida. */
tbody tr.linha-estimada-parcial td { background: #fdf8ee; }
tbody tr.linha-estimada-parcial:hover td { background: #f8f0e0; }
tbody tr.linha-estimada td { background: var(--alerta-fundo); }
tbody tr.linha-estimada:hover td { background: #f6e8cd; }
.pct.ajustado { border-color: var(--primary); border-width: 2px; }
.sugestao.ajustado { color: var(--primary-deep); font-weight: 600; }
/* Sem medicao NENHUMA no mes: diferente de furado, e some quando a
   extracao do mes rodar. Cinza, nao ambar -- numa previa e o normal. */
.status-sem-medida { background: var(--neutro-fundo); color: var(--neutro);
  font-style: italic; }

/* ------------------------------------------------------------ botões */
button, select, input { font-family: var(--fonte); font-size: 16px; }

.btn {
  border-radius: var(--r-full); padding: 14px 24px; border: 1px solid transparent;
  font-weight: 600; font-size: 15px; cursor: pointer;
  background: var(--surface); color: var(--ink); border-color: var(--ink);
}
.btn:hover { background: var(--surface-baixa); }
/* UMA ação primária por tela. */
.btn-primario { background: var(--primary); color: var(--ink); border-color: var(--primary); }
.btn-primario:hover { background: var(--primary-deep); color: var(--surface); border-color: var(--primary-deep); }
/* Ação de CÁLCULO: não toca a CCEE, não escreve no Omie — só recalcula com o
   que já está no banco. Marcada porque o operador precisa distinguir de relance
   o que custa cota do que não custa, mas sem virar uma segunda primária, que é
   a ação que a tela quer que ele faça. */
.btn-calculo {
  border-color: var(--primary); color: var(--primary-deep); border-width: 2px;
}
.btn-calculo:hover { background: var(--primary); color: var(--ink); }
.btn:disabled, .btn-primario:disabled, .btn-calculo:disabled {
  background: var(--surface-baixa); color: var(--ink-45);
  border-color: var(--linha); border-width: 1px; cursor: not-allowed;
}

/* ------------------------------------------------------------ inputs */
.campo, select.campo, input.campo {
  background: var(--surface-alta); color: var(--ink);
  border: 1px solid var(--linha); border-radius: var(--r-md);
  padding: 12px 14px; min-height: 44px;
}
.campo:focus, select.campo:focus, input.campo:focus {
  outline: none; border-color: var(--primary);
  box-shadow: 0 0 0 2px rgba(0, 193, 27, 0.45);
}
/* Os selects usam o visual de input do design system, não o combo
   nativo: seta desenhada, raio médio, mesma altura das células. */
select.campo {
  appearance: none;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--ink-70) 50%),
    linear-gradient(135deg, var(--ink-70) 50%, transparent 50%);
  background-position: calc(100% - 18px) 50%, calc(100% - 12px) 50%;
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
  padding-right: 34px;
}
select.campo.vazio { color: var(--ink-45); }

.filtros { display: flex; flex-wrap: wrap; gap: var(--sm) var(--md);
  align-items: center; margin: var(--lg) 0 var(--md); }
.filtros label { display: inline-flex; align-items: center; gap: var(--sm);
  font-size: 14px; color: var(--ink-70); }

/* ------------------------------------------------------------ tabela */
/* A listagem roda um corpo abaixo do resto da interface (13px contra 16px). O
   design system reserva o corpo de 16px para texto que se lê; esta tabela é
   para varrer com o olho, dezenas de linhas por mês, e a densidade é o que
   deixa a carteira caber na tela sem rolagem horizontal. Os números seguem em
   `font-variant-numeric: tabular-nums`, então as colunas continuam alinhadas. */
/* Altura tambem pela tela, e nao por um numero: `min()` deixa a tabela usar o
   que sobra do monitor sem nunca ficar menor do que cabe umas dez linhas. */
.tabela-wrap { border: 1px solid var(--linha); border-radius: var(--r-lg);
  overflow: auto; background: var(--surface-alta);
  max-height: max(360px, calc(100vh - 340px)); }
/* `min-width` so para telas estreitas: acima dela a tabela ocupa a largura da
   pagina e a barra horizontal simplesmente nao aparece. */
table { border-collapse: collapse; width: 100%; min-width: 1180px; font-size: 13px; }
#tabela-horaria, #tabela-bloqueadas { min-width: 0; }
tbody td:first-child { min-width: 200px; }
thead th {
  position: sticky; top: 0; z-index: 1;
  background: var(--surface-baixa); color: var(--ink-70);
  font-size: 11px; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase;
  text-align: left; padding: 9px 10px; border-bottom: 1px solid var(--linha); white-space: nowrap;
}
tbody td { padding: 7px 10px; border-bottom: 1px solid var(--linha); vertical-align: middle; }
tbody tr:hover td { background: var(--surface); }
td.num, th.num { text-align: right; }
td.mono { font-variant-numeric: tabular-nums; font-size: 12px; color: var(--ink-70); }
/* O código do ponto embaixo do nome é referência de conferência, não leitura. */
tbody td .caption { font-size: 11px; }
tbody .status { font-size: 11px; padding: 2px 8px; }
.negativo { color: var(--risco); }
.linha-bloqueada td { opacity: 0.72; }

/* Rodapé fixo com os totais do filtro: o operador fecha o mês olhando a soma
   do que está vendo, não a soma de tudo. */
.rodape-totais {
  position: sticky; bottom: 0; margin-top: var(--md);
  background: var(--ink); color: var(--surface);
  border-radius: var(--r-lg); padding: var(--md) var(--lg);
  display: flex; flex-wrap: wrap; gap: var(--lg); align-items: center;
}
.rodape-totais .item { display: flex; flex-direction: column; }
.rodape-totais .rotulo { font-size: 11px; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--accent); }
.rodape-totais .valor { font-size: 18px; font-weight: 600; }

/* célula editável */
.pct { width: 74px; text-align: right; font-size: 13px;
  padding: 6px 8px; min-height: 32px; border-radius: var(--r-sm); }
.pct.pendente { border-style: dashed; color: var(--ink-45); }

/* ------------------------------------------------------------ avisos */
.mensagem { border-radius: var(--r-md); padding: var(--md); margin: var(--md) 0; font-size: 14px; }
.mensagem.info { background: var(--surface-baixa); }
.mensagem.aviso { background: var(--alerta-fundo); color: var(--alerta); }
.mensagem.erro { background: var(--risco-fundo); color: var(--risco); }
.mensagem ul { margin: var(--sm) 0 0; padding-left: 20px; }

/* ------------------------------------------------------------ ajuda */
/* O `?` de ajuda. Pequeno e VERDE: ele aparece em quase toda coluna, e no
   cinza antigo competia com o dado -- virava sujeira no cabecalho em vez de
   convite. Em verde ele le como affordance ("tem explicacao aqui") e some do
   caminho de quem so quer o numero. */
.ajuda-info {
  display: inline-flex; align-items: center; justify-content: center;
  width: 13px; height: 13px; border-radius: var(--r-full);
  background: transparent; color: var(--primary);
  border: 1px solid currentColor;
  font-size: 9px; font-weight: 700; line-height: 1;
  cursor: help; margin-left: 5px; vertical-align: 1px;
  opacity: 0.85; transition: opacity .12s, background-color .12s, color .12s;
}
.ajuda-info:hover {
  opacity: 1; background: var(--primary); color: var(--ink);
}
/* No cabecalho escuro (hero, nav) o verde fechado some: ali vale o claro. */
.cartao-escuro .ajuda-info, .topo .ajuda-info { color: var(--accent); }
.cartao-escuro .ajuda-info:hover, .topo .ajuda-info:hover {
  background: var(--accent); color: var(--ink);
}

/* ----------------------------------------------------------- gráfico */
.grafico { width: 100%; height: 260px; }
.grafico .barra { fill: var(--ink); }
.grafico .barra-falta { fill: var(--alerta); opacity: 0.28; }
.grafico .eixo { stroke: var(--linha); stroke-width: 1; }
.grafico .rot { font-size: 11px; fill: var(--ink-45); }
.grafico .pld { fill: none; stroke: var(--primary-deep); stroke-width: 1.5; opacity: 0.9; }

.vazio { padding: var(--xl); text-align: center; color: var(--ink-45); }

/* Em tela larga a margem encolhe: 32px de cada lado eram 64px que a tabela de
   19 colunas estava pedindo emprestado para não rolar. */
@media (min-width: 1600px) {
  main { padding-left: var(--md); padding-right: var(--md); }
  .topo { padding-left: var(--md); padding-right: var(--md); }
}

@media (max-width: 820px) {
  main { padding: var(--md); }
  .abas { width: 100%; margin-left: 0; overflow-x: auto; }
}

/* A sugestão fica ABAIXO do input, em corpo menor: ela informa, não compete com
   o valor confirmado. O botão "usar" é a única ponte entre as duas coisas. */
.sugestao { font-size: 11px; color: var(--ink-45); margin-top: 3px;
  display: flex; align-items: center; gap: 6px; justify-content: flex-end; }
.sugestao.ok { color: var(--ok); }
.sugestao.vazia { font-style: italic; }
.link-usar {
  border: 1px solid var(--linha); background: var(--surface);
  color: var(--ink); border-radius: var(--r-full);
  font-size: 11px; font-weight: 600; padding: 1px 9px; cursor: pointer;
}
.link-usar:hover { background: var(--primary); border-color: var(--primary); }

/* Recorte da carteira: diz de quem é esta tela antes de o operador somar nada. */
/* A medida de 78ch saiu a pedido do operador (25/09/2026): numa tela larga
   ela quebrava a frase deixando três palavras sozinhas na última linha, e o
   que parecia parágrafo novo era só a régua de leitura. O texto acompanha a
   tela. */
.recorte { margin: var(--md) 0 0; }
.recorte strong { color: var(--primary-deep); }

/* As caixas de componente herdaram o realce que era das chaves macro. */
.caixa-componente input, .caixa-topo input { accent-color: var(--primary); }

#angra-texto { display: block; border-radius: var(--r-sm); padding: var(--sm); }
#angra-cobertura table { min-width: 0; }


/* ---------------------------------------------- escolha da estimativa
   Botao discreto na tabela: mostra a fonte em uso e o valor dela, e a
   diferenca para a outra fica logo abaixo. O contorno marcado distingue o que
   o analista escolheu do que veio no padrao -- tres meses depois, essa e a
   diferenca entre "decidiram isso" e "ninguem olhou". */
.btn-fonte-est {
  font: inherit;
  font-variant-numeric: tabular-nums;
  padding: 3px 10px;
  border: 1px solid var(--borda, #d5d9e0);
  border-radius: 999px;
  background: var(--fundo-suave, #f6f7f9);
  color: inherit;
  cursor: pointer;
  white-space: nowrap;
}
.btn-fonte-est:hover { border-color: var(--acento, #2f6fed); }
.btn-fonte-est.escolhido {
  border-color: var(--acento, #2f6fed);
  box-shadow: inset 0 0 0 1px var(--acento, #2f6fed);
  font-weight: 600;
}


/* --------------------------------------------------- liberar para faturar
   Verbo enquanto e decisao, estado depois de tomada. A linha liberada fica
   visivelmente diferente das outras numa varredura de 50 -- e o que separa
   "ja olhei este" de "ainda nao". */
.btn-liberar {
  font: inherit;
  padding: 5px 14px;
  border: 1px solid var(--borda, #d5d9e0);
  border-radius: 6px;
  background: transparent;
  color: inherit;
  cursor: pointer;
  white-space: nowrap;
}
.btn-liberar:hover { border-color: var(--ok, #1d8a4e); }
.btn-liberar.liberado {
  border-color: var(--ok, #1d8a4e);
  background: color-mix(in srgb, var(--ok, #1d8a4e) 12%, transparent);
  color: var(--ok, #1d8a4e);
  font-weight: 600;
}

/* ------------------------------------------------------- carregando
   Duas peças, e cada uma responde a uma pergunta diferente.

   A BARRA DO TOPO responde "o sistema está fazendo alguma coisa?". Ela sobe
   com qualquer chamada em voo, some quando a última termina, e por isso vive
   no próprio `api()` — indicador que depende de alguém lembrar de acendê-lo
   fica apagado justamente na tela nova.

   O ESQUELETO responde "o que vem aqui?". Ele ocupa a forma da tabela que está
   chegando, então a página não pula quando os dados entram. Uma tabela vazia
   durante a espera é pior do que nada: ela parece resposta, e "nenhum ponto no
   mês" é uma afirmação que a gente ainda não tem como fazer.

   A barra espera 180ms antes de aparecer e fica no mínimo 320ms: sem isso, uma
   consulta rápida vira um lampejo, que cansa mais do que informa. */
#progresso {
  position: fixed; top: 0; left: 0; right: 0; height: 3px;
  z-index: 50; pointer-events: none;
  opacity: 0; transition: opacity 160ms ease-out;
  overflow: hidden;
}
/* Trilho: sem ele a barra some entre as passadas do segmento, e "parou de
   carregar" e "o brilho ainda nao voltou" viram a mesma imagem. */
#progresso.ativo { opacity: 1; background: rgba(0, 193, 27, 0.20); }
#progresso::before {
  content: ''; display: block; height: 100%; width: 38%;
  background: linear-gradient(90deg,
    transparent, var(--primary) 30%, var(--accent) 60%, transparent);
  animation: progresso-desliza 1.15s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}
@keyframes progresso-desliza {
  from { transform: translateX(-110%); }
  to   { transform: translateX(370%); }
}

/* O esqueleto imita a linha: primeira coluna larga (nome), demais estreitas. */
.esqueleto td { padding: 11px 10px; }
.esqueleto i {
  display: block; height: 10px; border-radius: 3px;
  background: linear-gradient(90deg,
    var(--surface-baixa) 25%, var(--surface) 50%, var(--surface-baixa) 75%);
  background-size: 240% 100%;
  animation: esqueleto-brilha 1.4s ease-in-out infinite;
}
.esqueleto td:first-child i { width: 70%; }
.esqueleto td.num i { margin-left: auto; width: 54%; }
@keyframes esqueleto-brilha {
  from { background-position: 140% 0; }
  to   { background-position: -40% 0; }
}

/* Botão trabalhando: o rótulo fica, e um ponto pulsa ao lado. Trocar o texto
   por "Carregando..." apagaria a informação de qual ação está em curso. */
.btn[aria-busy="true"] { position: relative; }
.btn[aria-busy="true"]::after {
  content: ''; display: inline-block; vertical-align: middle;
  width: 7px; height: 7px; margin-left: 8px; border-radius: 50%;
  background: currentColor; animation: botao-pulsa 900ms ease-in-out infinite;
}
@keyframes botao-pulsa {
  0%, 100% { opacity: 0.25; transform: scale(0.8); }
  50%      { opacity: 1;    transform: scale(1.15); }
}

/* Movimento reduzido: a informação continua, a animação não. Quem pediu menos
   movimento continua precisando saber que a tela está esperando. */
@media (prefers-reduced-motion: reduce) {
  #progresso::before,
  .esqueleto i,
  .btn[aria-busy="true"]::after { animation: none; }
  #progresso::before { width: 100%; opacity: 0.55; }
  .esqueleto i { background: var(--surface-baixa); }
  .btn[aria-busy="true"]::after { opacity: 0.6; }
}

/* ------------------------------------------------- campo gravando
   Um campo que grava em silêncio é quase tão ruim quanto um que não grava: de
   fora, as duas coisas são idênticas. O estado aparece na borda do próprio
   campo, onde o olho já está — não numa mensagem no alto da página. */
.campo.salvando { border-color: var(--alerta); background: var(--alerta-fundo); }
.campo.salvo {
  border-color: var(--ok); background: var(--ok-fundo);
  transition: border-color 400ms ease-out, background 400ms ease-out;
}
@media (prefers-reduced-motion: reduce) {
  .campo.salvo { transition: none; }
}

/* Caixa que liga um COMPONENTE ao ajuste (perdas, PROINFA, Angra, diferença).
   Fica debaixo do percentual, com o MWh que ela acrescenta ao lado: a pergunta
   que o analista faz é "quanto isso muda?", e a resposta tem de estar junto do
   controle, não num tooltip que ele precise caçar. */
.caixa-componente {
  display: flex; align-items: center; gap: 4px; justify-content: flex-end;
  margin-top: 3px; cursor: pointer; font-size: 12px;
}
.caixa-componente input { margin: 0; cursor: pointer; }
.caixa-componente input:disabled { cursor: not-allowed; }
.caixa-componente input:disabled + .caption { color: var(--ink-45); }

/* Cabeçalho ordenável. O cursor e o sublinhado pontilhado são o que diz que dá
   para clicar — sem isso a funcionalidade existe e ninguém descobre. */
#tabela-carteira thead [data-ordem] {
  cursor: pointer; user-select: none;
  text-decoration: underline dotted var(--ink-45) 1px;
  text-underline-offset: 3px;
}
#tabela-carteira thead [data-ordem]:hover { color: var(--primary-deep); }
#tabela-carteira thead [data-ordem].ordenado { color: var(--primary-deep); }
.seta-ordem { font-weight: 700; }

/* Caixa de "aplicar a todas as linhas", no cabeçalho da própria coluna. */
.caixa-topo {
  display: flex; align-items: center; gap: 4px; justify-content: flex-end;
  margin-top: 3px; cursor: pointer; font-weight: 400;
}
.caixa-topo input, .caixa-topo select { margin: 0; cursor: pointer; }

/* Data de hoje, no canto direito do topo. */
.topo-data {
  margin-left: var(--lg); text-align: right; line-height: 1.25;
  white-space: nowrap;
  color: var(--surface); opacity: 0.85; font-size: 13px;
}
.topo-data .dia { display: block; font-size: 20px; font-weight: 700; opacity: 1; }
/* A regua do setor e em dia UTIL: o 6o fecha a medicao, o 5o vence o boleto. */
.topo-data .util { display: block; color: var(--accent); opacity: 1; }

/* --------------------------------------------------- quem esta logado */
/* `margin-left: auto` tambem QUANDO QUEBRA: com nove abas a primeira linha
   enche, e sem isto o grupo comecava a segunda linha colado na esquerda, com
   cara de sobra em vez de canto. */
.topo-direita { display: flex; align-items: center; gap: var(--md); margin-left: auto; }
.topo-quem { display: flex; align-items: center; gap: var(--sm); }
.topo-quem .nome { font-size: 12px; font-weight: 600; color: var(--surface); white-space: nowrap; }
.topo-quem .sair {
  background: transparent; border: 1px solid rgba(242,239,235,.28);
  color: rgba(242,239,235,.72); border-radius: var(--r-full);
  padding: 3px 11px; font-family: inherit; font-size: 11px; cursor: pointer;
  transition: border-color .12s, color .12s;
}
.topo-quem .sair:hover { border-color: var(--accent); color: var(--accent); }
