:root {
  --fundo: #f5f6fa;
  --superficie: #ffffff;
  --superficie-2: #f0f2f7;
  --borda: #e2e5ee;
  --texto: #1b1f2a;
  --texto-fraco: #6b7385;
  --primaria: #4f7cff;
  --primaria-contraste: #ffffff;
  --entrada: #16a34a;
  --saida: #e0603c;
  --alerta: #b45309;
  --erro: #dc2626;
  --sombra: 0 1px 2px rgba(16, 24, 40, .06), 0 8px 24px rgba(16, 24, 40, .06);
  --raio: 12px;
  /* Temperatura de uma semana no quadro em tabela: do tranquilo (azul) ao
     estourado (vermelho cheio). Não são as cores das categorias — aqui a cor
     diz o quanto do limite da semana já foi usado. */
  --semana-0-fundo: var(--superficie-2); --semana-0-texto: var(--texto-fraco);
  --semana-1-fundo: #e3ecff; --semana-1-texto: #1d3f8f;
  --semana-2-fundo: #fdeacd; --semana-2-texto: #7a4a06;
  --semana-3-fundo: #fbdcd6; --semana-3-texto: #a52c14;
  --semana-4-fundo: #e8483c; --semana-4-texto: #ffffff;
}

[data-tema="escuro"] {
  --fundo: #11141c;
  --superficie: #191d28;
  --superficie-2: #212736;
  --borda: #2c3242;
  --texto: #e8eaf2;
  --texto-fraco: #98a0b5;
  --primaria: #6b93ff;
  --entrada: #35c07a;
  --saida: #f0805c;
  --alerta: #f0b45c;
  --erro: #f87171;
  --sombra: 0 1px 2px rgba(0, 0, 0, .3), 0 8px 24px rgba(0, 0, 0, .28);
  --semana-1-fundo: #1e2c4d; --semana-1-texto: #a9c3ff;
  --semana-2-fundo: #3a2e14; --semana-2-texto: #f0c377;
  --semana-3-fundo: #4a2318; --semana-3-texto: #f4a48d;
  --semana-4-fundo: #a52c14; --semana-4-texto: #ffe9e4;
}

* { box-sizing: border-box; }

/* Barra de rolagem fina e discreta em toda a tela, no lugar do padrão
   grosso do navegador — que, em algumas plataformas, flutua por cima do
   texto nas listas roláveis (legenda dos gráficos, Maiores gastos etc.)
   em vez de reservar o próprio espaço. */
* { scrollbar-width: thin; scrollbar-color: var(--borda) transparent; }
*::-webkit-scrollbar { width: 8px; height: 8px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb { background: var(--borda); border-radius: 99px; }
*::-webkit-scrollbar-thumb:hover { background: var(--texto-fraco); }

body {
  margin: 0;
  background: var(--fundo);
  color: var(--texto);
  font: 15px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { margin: 0; font-weight: 650; letter-spacing: -.01em; }
h1 { font-size: 1.15rem; }
h2 { font-size: 1rem; }

/* ------------------------------------------------------------------ topo */
.topo {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  align-items: center;
  justify-content: space-between;
  padding: 14px 24px;
  background: var(--superficie);
  border-bottom: 1px solid var(--borda);
  position: sticky;
  top: 0;
  z-index: 20;
}

.topo-marca { display: flex; align-items: center; gap: 12px; }
.topo-logo { font-size: 1.7rem; }
.topo-sub { margin: 0; color: var(--texto-fraco); font-size: .82rem; }
.topo-filtros { display: flex; gap: 12px; align-items: flex-end; flex-wrap: wrap; }
/* Todo controle da fileira com a mesma altura: assim texto e ícone de cada um
   ficam na mesma linha e centralizados entre si, em vez de só encostarem por
   baixo (a legenda oculta acima já garante o encosto — ver .legenda-oculta). */
.topo-filtros input,
.topo-filtros select,
.topo-filtros .btn-tema,
.topo-filtros .usuario-logado {
  height: 38px;
  box-sizing: border-box;
}
.topo-filtros .btn-tema { display: inline-flex; align-items: center; justify-content: center; }

/* ------------------------------------------------------------------ abas */
.abas {
  display: flex;
  gap: 4px;
  padding: 0 24px;
  background: var(--superficie);
  border-bottom: 1px solid var(--borda);
  overflow-x: auto;
  position: sticky;
  /* Preenchido via JS com a altura real do cabeçalho — que muda de tamanho
     quando os filtros quebram linha numa tela estreita. */
  top: var(--altura-topo, 64px);
  z-index: 19;
}

.aba {
  border: 0;
  background: none;
  color: var(--texto-fraco);
  padding: 11px 14px;
  font: inherit;
  font-weight: 550;
  cursor: pointer;
  border-bottom: 2px solid transparent;
  white-space: nowrap;
}

.aba:hover { color: var(--texto); }
.aba.ativa { color: var(--primaria); border-bottom-color: var(--primaria); }

/* min() em vez de um valor fixo: em monitor comum, o conteúdo acompanha a
   largura real da tela em vez de parar cedo e sobrar margem vazia; o teto
   de 2200px só entra em telas realmente enormes, pra não esticar demais. */
main { padding: 22px 24px 16px; max-width: min(96vw, 2200px); margin: 0 auto; }

.painel-secao { display: none; }
.painel-secao.ativa { display: grid; gap: 18px; }

/* Lançamentos: o formulário "Novo lançamento" e o cabeçalho da lista (título,
   busca/filtros, paginação) ficam sempre visíveis — só a tabela em si rola,
   dentro de uma altura que ocupa o resto da tela. */
#secao-lancamentos.ativa {
  display: flex;
  flex-direction: column;
  height: calc(100vh - var(--altura-fixa, 130px));
  min-height: 320px;
}
#secao-lancamentos > .painel:first-child { flex: none; }
.painel-lancamentos-lista {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.painel-lancamentos-lista .painel-cabecalho { flex: none; flex-wrap: wrap; }
/* scrollbar-gutter reserva o espaço da barra de rolagem vertical mesmo
   quando ela não aparece (poucos lançamentos) — sem isso, as colunas da
   tabela ficam alinhadas diferente dependendo de o mês ter barra ou não. */
.lancamentos-rolagem { flex: 1; overflow-y: auto; min-height: 0; scrollbar-gutter: stable; }
.painel-lancamentos-lista > .paginacao { flex: none; }

/* Importar: mesma ideia de Lançamentos — o formulário de escolher o
   arquivo e a lista de "Arquivos importados" ficam do tamanho natural
   deles, e só a tabela dentro de "Conferir antes de importar" ocupa o
   resto da tela e rola por dentro. */
#secao-importar.ativa {
  display: flex;
  flex-direction: column;
  height: calc(100vh - var(--altura-fixa, 130px));
  min-height: 480px;
}
#secao-importar.ativa > article { flex: none; }
#secao-importar.ativa > #painel-previa[hidden] { display: none; }
#secao-importar.ativa > #painel-previa {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
}
#painel-previa > .painel-cabecalho,
#painel-previa > #fila-previa,
#painel-previa > #resumo-previa,
#painel-previa > #avisos-previa,
#painel-previa > #mapeamento-csv,
#painel-previa > .form-acoes {
  flex: none;
}
#painel-previa > .tabela-rolagem {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}
/* "Arquivos importados" tem tamanho fixo pra não crescer sem limite e
   empurrar a página inteira pra rolagem — a lista dele rola por dentro. */
#secao-importar.ativa > article:last-child #lista-importacoes {
  max-height: 220px;
  overflow-y: auto;
  padding-right: 6px;
}
.paginacao-topo { margin: 4px 0 14px; }

/* -------------------------------------------------------------- campos */
.campo { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
/* [hidden] sozinho perde pra "display: flex" acima (regra de autor sempre
   vence regra do navegador, mesmo com o atributo presente) — sem isto o
   campo continuaria visível depois de escondido. */
.campo[hidden] { display: none; }
/* O checkbox de "Período" e o botão de tema não têm uma legenda de verdade
   em cima, como Mês e Pessoa têm — sem uma legenda oculta do mesmo tamanho
   ali, o controle deles fica um pouco mais alto que os outros na fileira de
   filtros. A legenda oculta faz as quatro caixas terem a mesma forma, e
   `align-items: flex-end` (herdado de .topo-filtros) alinha o resto. */
.legenda-oculta { visibility: hidden; }
.campo-checkbox-controle {
  display: flex; align-items: center; gap: 6px; height: 38px;
  font-size: .82rem; color: var(--texto-fraco); white-space: nowrap;
}
.campo-checkbox-controle input { margin: 0; }
/* Fica dentro da barra de abas, por cima dela (position: absolute — não
   participa do fluxo, então nunca aumenta a altura da barra, mesmo quando
   o texto quebra em duas linhas) — assim toda página (Painel incluída) tem
   a mesma distância entre a barra e o conteúdo, com ou sem aviso.
   Em telas largas (>=1600px) fica centralizado na página de verdade; abaixo
   disso não cabe centralizado sem sobrepor as abas, então volta a ocupar só
   o espaço livre ao lado delas. */
.aviso-mes-aberto {
  margin: 0; display: flex; align-items: center; justify-content: center;
  pointer-events: none;
}
.aviso-mes-aberto[hidden] { display: none; }
.aviso-mes-aberto span {
  font-size: .74rem; line-height: 1.2; color: var(--alerta); text-align: center;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
@media (max-width: 1599px) {
  .aviso-mes-aberto { position: static; flex: 1; padding: 0 16px; }
}
@media (min-width: 1600px) {
  .aviso-mes-aberto {
    position: absolute; left: 50%; top: 0; bottom: 0; transform: translateX(-50%);
    max-width: min(560px, 40vw);
  }
}
.aviso-atualizacao {
  display: flex; align-items: center; justify-content: center; gap: 12px;
  margin: 0; padding: 8px 24px; font-size: .85rem; text-align: center;
  background: color-mix(in srgb, var(--primaria) 12%, var(--superficie));
  border-bottom: 1px solid var(--borda);
}
/* [hidden] sozinho perde pra "display: flex" acima (regra de autor sempre
   vence a regra do navegador, mesmo com o atributo presente). */
.aviso-atualizacao[hidden] { display: none; }
.orcamento-global {
  padding: 4px 0 14px; margin-bottom: 8px; border-bottom: 2px solid var(--borda);
}
.orcamento-global .orcamento-topo { font-weight: 700; }
.campo > span { font-size: .74rem; color: var(--texto-fraco); font-weight: 600; text-transform: uppercase; letter-spacing: .04em; }
.campo-largo { grid-column: span 2; }

input, select, button, textarea { font: inherit; color: inherit; }

input[type="text"], input[type="search"], input[type="number"], input[type="date"],
input[type="month"], input[type="password"], input[type="file"], select, textarea {
  background: var(--superficie);
  border: 1px solid var(--borda);
  border-radius: 9px;
  padding: 8px 10px;
  min-width: 0;
  transition: border-color .15s, box-shadow .15s;
}

input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--primaria);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--primaria) 22%, transparent);
}

input[type="color"] {
  width: 40px; height: 38px; padding: 3px;
  border: 1px solid var(--borda); border-radius: 9px;
  background: var(--superficie); cursor: pointer;
}

.btn {
  background: var(--superficie);
  border: 1px solid var(--borda);
  border-radius: 9px;
  padding: 8px 14px;
  font-weight: 550;
  cursor: pointer;
  transition: background .15s, border-color .15s, transform .05s;
}

.btn:hover { background: var(--superficie-2); }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: .55; cursor: not-allowed; }

.btn-primario {
  background: var(--primaria);
  border-color: var(--primaria);
  color: var(--primaria-contraste);
}
.btn-primario:hover { filter: brightness(1.07); background: var(--primaria); }

.btn-tema { padding: 8px 11px; }

.btn-icone {
  background: none; border: 0; cursor: pointer; padding: 4px 6px;
  border-radius: 7px; color: var(--texto-fraco); font-size: .95rem;
  text-decoration: none; display: inline-block;
}
.btn-icone:hover { background: var(--superficie-2); color: var(--erro); }
/* Ação neutra (baixar), não destrutiva — sem o vermelho do hover padrão. */
.btn-icone-neutro:hover { color: var(--primaria); }

/* -------------------------------------------------------------- painéis */
.painel {
  background: var(--superficie);
  border: 1px solid var(--borda);
  border-radius: var(--raio);
  padding: 18px;
  box-shadow: var(--sombra);
  min-width: 0;
}

.painel-cabecalho {
  display: flex; flex-wrap: wrap; gap: 12px;
  align-items: center; justify-content: space-between; margin-bottom: 14px;
}

.ajuda { color: var(--texto-fraco); font-size: .85rem; margin: 6px 0 12px; }
.vazio { color: var(--texto-fraco); font-size: .88rem; text-align: center; padding: 18px 0; margin: 0; }

/* ----------------------------------------------------------------- KPIs */
.cartoes-kpi {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 14px;
}

.kpi {
  background: var(--superficie);
  border: 1px solid var(--borda);
  border-left: 3px solid var(--borda);
  border-radius: var(--raio);
  padding: 15px 17px;
  box-shadow: var(--sombra);
  display: grid;
  gap: 3px;
}

.kpi-rotulo { font-size: .76rem; color: var(--texto-fraco); font-weight: 600; text-transform: uppercase; letter-spacing: .04em; }
.kpi-valor { font-size: 1.5rem; font-weight: 680; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.kpi-nota { font-size: .8rem; color: var(--texto-fraco); }
.kpi-entrada { border-left-color: var(--entrada); }
.kpi-entrada .kpi-valor { color: var(--entrada); }
.kpi-saida { border-left-color: var(--saida); }
.kpi-saida .kpi-valor { color: var(--saida); }
.kpi-saldo { border-left-color: var(--primaria); }

.positivo { color: var(--entrada); }
.negativo { color: var(--saida); }

/* -------------------------------------------------------------- gráficos */
.grade-graficos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
  gap: 18px;
}

/* Em tela larga, 2x2 fecha a grade certinho — com 3 colunas sobra um buraco.
   Numa tela bem larga (>=1400px), 3 colunas voltam a fechar certinho (os
   6 cards em 2 linhas) e aproveitam o espaço extra em vez de só esticar
   cada card. */
@media (min-width: 760px) {
  .grade-graficos { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1400px) {
  .grade-graficos { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* Os 6 cards (gráficos e listas) têm sempre a mesma altura entre si — sem
   isso, cada um cresce só até onde o próprio conteúdo pede, e a grade fica
   toda desalinhada. O conteúdo de cada um rola por dentro se não couber. */
.grade-graficos > article {
  display: flex;
  flex-direction: column;
  height: 320px;
}

/* Em tela bem larga (>=1400px, 3 colunas x 2 linhas) a seção inteira vira
   uma altura fixa (o que sobra da tela depois do cabeçalho/abas/rodapé, via
   --altura-fixa) e a grade preenche esse espaço em vez de usar uma altura
   de card fixa e "chutada" — 320px só cabia certinho na conta de quando foi
   medido; qualquer mudança no aviso do mês em aberto, no cabeçalho, ou no
   navegador real do usuário (barra de tarefas, zoom) sobrava ou faltava
   espaço e a página inteira ganhava rolagem. Com isso os cards sempre se
   ajustam ao que realmente sobra na tela. */
@media (min-width: 1400px) {
  #secao-painel.ativa {
    display: flex;
    flex-direction: column;
    height: calc(100vh - var(--altura-fixa, 130px));
    min-height: 480px;
  }
  #secao-painel.ativa > .cartoes-kpi {
    flex: none;
  }
  #secao-painel.ativa > .grade-graficos {
    flex: 1;
    min-height: 0;
    grid-auto-rows: 1fr;
  }
  #secao-painel.ativa > .grade-graficos > article {
    height: auto;
    min-height: 0;
  }
}
.grade-graficos > article > h2 {
  flex: none;
}
.area-grafico { position: relative; height: 290px; margin-top: 8px; }
.area-grafico-baixa { height: 230px; }
.grade-graficos .area-grafico {
  flex: 1;
  height: auto;
  min-height: 0;
}
.grade-graficos #lista-orcamentos,
.grade-graficos #lista-orcamentos-semana {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  /* Sem isso, "overflow-y: auto" sozinho faz o navegador tratar o eixo x
     como "auto" também (regra do CSS) — aí qualquer conteúdo passando 1px
     da largura do card abre rolagem lateral. Esses cards nunca devem ter. */
  overflow-x: hidden;
  margin-top: 8px;
  padding-right: 6px;
}

/* Legenda em lista de coluna única, ao lado do gráfico de rosca (em vez da
   legenda padrão do Chart.js, que quebra em duas colunas quando não cabe).
   O Chart.js define width/height como estilo inline no canvas a cada
   resize, medindo o PAI direto dele — um aspect-ratio no canvas em si não
   adianta nada, porque esse estilo inline vence qualquer CSS externo. Por
   isso o canvas mora dentro de um wrapper próprio (.area-grafico-canvas)
   que É quadrado de verdade: o Chart.js mede esse wrapper e o buffer já
   nasce quadrado.

   O wrapper ocupa a altura toda de propósito: por dentro, o gráfico ainda
   reserva uma folga do tamanho do salto da fatia no hover (ver SALTO_FATIA
   em app.js), então o anel desenhado fica do mesmo tamanho de antes — a
   diferença é que agora a fatia destacada cresce pra dentro dessa folga,
   em vez de ser cortada pela borda do canvas. A largura segue limitada
   (max-width) pra legenda ao lado não ficar espremida. */
.area-grafico-com-legenda { display: flex; gap: 14px; align-items: center; }
.area-grafico-canvas {
  position: relative;
  flex: 0 0 auto;
  height: 100%;
  aspect-ratio: 1 / 1;
  min-width: 0;
  max-width: 55%;
}
.legenda-grafico {
  flex: 1 1 140px; min-width: 140px; overflow-y: auto; align-self: stretch;
  display: flex; flex-direction: column; gap: 1px; padding-right: 6px;
}
.legenda-item {
  display: flex; align-items: center; gap: 7px; padding: 5px 6px; border-radius: 7px;
  cursor: pointer; border: 0; background: none; font: inherit; text-align: left; width: 100%;
  color: var(--texto); transition: background .12s;
}
.legenda-item:hover, .legenda-item.legenda-destacada { background: var(--superficie-2); }
.legenda-item.legenda-item-oculto { opacity: .4; }
.legenda-item.legenda-item-oculto .legenda-texto { text-decoration: line-through; }
.legenda-ponto { width: 10px; height: 10px; border-radius: 99px; flex: none; }
.legenda-texto {
  flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: .82rem;
}
.legenda-valor {
  flex: none; font-size: .76rem; color: var(--texto-fraco); font-variant-numeric: tabular-nums;
  min-width: 74px; text-align: right;
}
.legenda-valores {
  flex: none; font-size: .76rem; color: var(--texto-fraco); font-variant-numeric: tabular-nums;
  min-width: 44px; text-align: right;
}

/* Balão dos gráficos, em HTML de verdade (ver `tooltipExterno` no app.js) —
   fixo na tela, por cima de tudo, pra nunca sair cortado pela borda do
   próprio canvas do gráfico (pequeno demais pra caber o balão desenhado
   dentro dele, do jeito nativo do Chart.js). */
.tooltip-grafico {
  position: fixed;
  z-index: 60;
  pointer-events: none;
  background: var(--superficie-2);
  border: 1px solid var(--borda);
  color: var(--texto);
  padding: 8px 11px;
  border-radius: 8px;
  font-size: .8rem;
  line-height: 1.5;
  box-shadow: var(--sombra);
  opacity: 0;
  transition: opacity .08s;
  max-width: 260px;
}
.tooltip-grafico-titulo { font-weight: 650; margin-bottom: 2px; }
.tooltip-grafico-nota { color: var(--texto-fraco); font-size: .74rem; margin-top: 2px; }

/* -------------------------------------------- meta de entradas (4 estilos)
   Percentual da previsão (meta) de uma categoria de Entrada, ao lado do
   percentual normal da fatia — são contas diferentes (fatia do total x meta
   batida) e o estilo de exibição é escolhido em Preferências (⚙️ no topo). */
.legenda-meta {
  flex: none; font-size: .68rem; color: var(--texto-fraco); opacity: .8;
  font-variant-numeric: tabular-nums; min-width: 40px; text-align: right;
}
.legenda-item-empilhado { flex-direction: column; align-items: stretch; gap: 2px; }
.legenda-item-linha1 { display: flex; align-items: center; gap: 7px; width: 100%; }
.legenda-item-linha2 {
  padding-left: 17px; font-size: .68rem; color: var(--texto-fraco); opacity: .85; text-align: left;
}
.legenda-meta-barra {
  flex: none; width: 46px; height: 6px; border-radius: 99px; background: var(--borda); overflow: hidden;
}
.legenda-meta-barra-preenchimento { display: block; height: 100%; background: #facc15; }
.legenda-meta-barra-pct {
  flex: none; font-size: .68rem; color: var(--texto-fraco); min-width: 28px; text-align: right;
}
.legenda-valor-com-meta small { opacity: .75; }

/* ------------------------------------------------------------- preferências */
.menu-preferencias { position: relative; }
.menu-preferencias-painel {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 25;
  background: var(--superficie); border: 1px solid var(--borda); border-radius: 10px;
  box-shadow: var(--sombra); padding: 10px; min-width: 220px;
}
.menu-preferencias-titulo {
  font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  color: var(--texto-fraco); margin-bottom: 6px;
}
.menu-preferencias-opcao {
  display: flex; align-items: center; gap: 7px; padding: 5px 4px; border-radius: 6px;
  font-size: .84rem; cursor: pointer;
}
.menu-preferencias-opcao:hover { background: var(--superficie-2); }

.campo-usuario-logado .usuario-logado {
  display: flex; align-items: center; gap: 4px; font-size: .84rem; color: var(--texto-fraco);
  text-transform: none; letter-spacing: normal;
}
/* Um nome por linha, do que entrou primeiro em diante — quando o casal está
   junto no sistema, os dois aparecem, um sobre o outro. */
/* Fonte um pouco menor e linhas mais juntas pra que dois nomes empilhados
   ainda caibam na mesma altura dos outros controles da fileira. */
#usuarios-logados { display: flex; flex-direction: column; font-size: .78rem; line-height: 1.2; }
.usuario-nome { white-space: nowrap; }
.usuario-nome-eu { font-weight: 650; color: var(--texto); }

.titulo-arrastavel { display: flex; align-items: center; gap: 6px; cursor: grab; user-select: none; }
.titulo-arrastavel:active { cursor: grabbing; }
.alca-arrastar { color: var(--texto-fraco); font-size: .9rem; }
.grade-graficos > article.arrastando { opacity: .4; }
.grade-graficos > article.alvo-de-arraste { outline: 2px dashed var(--primaria); outline-offset: 4px; }

/* ----------------------------------------------------------- orçamentos */
.orcamento { padding: 10px 0; border-bottom: 1px solid var(--borda); }
.orcamento:last-child { border-bottom: 0; }
.orcamento-topo { display: flex; justify-content: space-between; gap: 10px; font-size: .9rem; margin-bottom: 7px; }
.orcamento-valores { color: var(--texto-fraco); font-variant-numeric: tabular-nums; }

/* Só no card "Orçamento por semana": o texto é mais longo (mostra o
   disponível e, entre parênteses, o orçado e o reservado), então cabe numa
   linha só com fonte menor e as duas "colunas invisíveis" alinhadas —
   nome com largura fixa, valores ocupando o resto — em vez do nome
   empurrando o valor pra um ponto diferente em cada linha. */
.orcamento-topo-semana {
  justify-content: flex-start; flex-wrap: nowrap; font-size: .7rem; gap: 8px;
}
.orcamento-topo-semana > span:first-child {
  flex: 0 0 108px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.orcamento-topo-semana .orcamento-valores {
  flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.orcamento-topo-semana .orcamento-valores small { font-size: .9em; opacity: .85; }

/* Clica pra ir direto ajustar o orçamento em Cadastros (ver irParaAjusteOrcamento).
   Sem margem negativa: isso empurrava o card pra precisar de rolagem horizontal
   (overflow-y:auto no contêiner força o eixo x a virar "auto" também). */
.orcamento-clicavel { cursor: pointer; padding: 10px 0; border-radius: 8px; }
.orcamento-clicavel:hover { background: var(--superficie-2); }

.barra { position: relative; height: 8px; background: var(--superficie-2); border-radius: 99px; overflow: hidden; }
.barra > div { height: 100%; border-radius: 99px; transition: width .3s; }
/* :first-child pra pegar só a barra de gasto — sem isso, também pegava o
   .bloco-bloqueado (reservado), que também é um <div> filho direto, e
   sobrescrevia o hachurado dele com uma cor sólida. */
.barra-estourada > div:first-child { background: var(--erro) !important; }
.barra-atencao > div:first-child { background: var(--alerta) !important; }

/* Trecho reservado pelas parcelas do mês, logo depois do que já foi gasto
   (ver barraMes em app.js) — listras diagonais neutras, pra não competir
   com as cores de progresso: não é gasto de verdade, é compromisso já
   assumido. border-radius:0 porque fica no meio da barra, não na ponta —
   o arredondamento de sobra fica por conta do overflow:hidden do .barra. */
.bloco-bloqueado {
  position: absolute; top: 0; bottom: 0; border-radius: 0 !important;
  background: repeating-linear-gradient(
    45deg, var(--texto-fraco) 0 3px, transparent 3px 7px
  );
  opacity: .5;
  cursor: help;
}
/* "Orçamento por semana": o reservado fica sempre do mesmo tamanho, no fim
   da barra/coluna — quando o gasto já passou do disponível e está
   avançando sobre esse trecho, ele continua tracejado, só que na cor do
   estouro, pra avisar que aquele dinheiro reservado já está sendo usado.
   As listras ficam opacas (vermelho + um tom claro, em vez de transparente)
   porque o gasto embaixo costuma já estar vermelho também — listra
   transparente sobre fundo vermelho não apareceria. */
.segmento-semana.barra-estourada .bloco-bloqueado,
.barra-clicavel.barra-estourada .bloco-bloqueado,
.coluna-semana.barra-estourada .coluna-reservada {
  background: repeating-linear-gradient(
    45deg, var(--erro) 0 3px, rgba(255, 255, 255, .6) 3px 7px
  );
  opacity: 1;
}

/* Uma faixa por semana (ritmo da semana), no card "Orçamento por semana" —
   separado do card "Orçamentos do mês", que tem só a barra de sempre com o
   total (ver renderizarOrcamentos/segmentosDeSemana em app.js). overflow:
   hidden porque a soma das larguras (%) + os "gap" entre os segmentos passa
   de 100% em uns poucos pixels — sem isso, o último segmento vazava um
   pouquinho pra fora do card. */
/* O fundo aparece nas frestas entre os blocos: sem ele, uma semana colava
   na outra e a barra parecia contínua em vez de setorizada por semana. */
.barra-semanas {
  display: flex; gap: 2px; height: 8px; overflow: hidden;
  background: var(--borda); border-radius: 99px;
}

/* Régua com o intervalo de dias de cada semana, alinhada aos blocos (mesmas
   larguras e mesmo "gap"). Fica grudada no topo do card ao rolar a lista,
   pra não perder a referência das datas. */
.regua-semanas {
  display: flex; gap: 2px;
  position: sticky; top: 0; z-index: 1;
  padding: 2px 0 4px;
  background: var(--superficie);
  font-size: .64rem; color: var(--texto-fraco);
}
.regua-semanas > div {
  flex: 0 0 auto; text-align: center;
  overflow: hidden; white-space: nowrap;
}

/* Explicação curta do card, entre o título e o conteúdo. */
.nota-card {
  margin: 2px 0 0; font-size: .7rem; line-height: 1.35;
  color: var(--texto-fraco);
}

/* Quanto do orçamento já está reservado pelas parcelas, escrito ao lado dos
   valores — o hachurado sozinho não diz de quanto se trata. */
.orcamento-bloqueado-nota { color: var(--texto-fraco); }

/* Cada segmento é a semana inteira (largura proporcional aos dias dela) já
   como trilho; o preenchido de dentro é só a fração gasta — se passar de
   100% do orçamento daquela semana, vira aviso/estouro como a barra de
   baixo (mesmas classes .barra-atencao/.barra-estourada). Clicável: abre a
   lista de lançamentos daquela semana (ver abrirDrilldownSemana em app.js);
   por isso o cursor de ponteiro, não de "ajuda" como um tooltip comum. */
.segmento-semana {
  position: relative; flex: 0 0 auto; height: 100%;
  background: var(--superficie-2); border-radius: 2px; overflow: hidden;
  cursor: pointer;
}
.segmento-semana:hover { filter: brightness(1.15); }
.segmento-semana > div { height: 100%; border-radius: 2px; transition: width .3s; }

/* Não é gasto nem alerta — é espaço do teto Global sem categoria dona, daí
   a cor neutra e tracejada em vez das cores de progresso normais. */
.orcamento-nao-alocado .orcamento-topo { color: var(--texto-fraco); font-weight: 500; }
.barra-nao-alocada { border: 1px dashed var(--borda); background: none; }
.barra-nao-alocada > div { background: var(--texto-fraco); opacity: .5; }

/* Alerta de orçamento (50/75/90/95/100% do teto) ao lado do percentual. */
.orcamento-alerta {
  display: inline-block; font-weight: 650; padding: 1px 7px; border-radius: 99px;
  font-size: .78rem; margin-left: 4px;
}
.orcamento-alerta-atencao {
  color: var(--alerta); background: color-mix(in srgb, var(--alerta) 16%, transparent);
}
.orcamento-alerta-cheio {
  color: var(--erro); background: color-mix(in srgb, var(--erro) 16%, transparent);
}

/* --------------------------------------------------------------- tabelas */
.tabela-rolagem { overflow-x: auto; }

.tabela { width: 100%; border-collapse: collapse; font-size: .9rem; }
.tabela th {
  text-align: left; font-size: .72rem; text-transform: uppercase; letter-spacing: .04em;
  color: var(--texto-fraco); font-weight: 650; padding: 9px 10px;
  border-bottom: 1px solid var(--borda); white-space: nowrap;
}
.tabela td { padding: 9px 10px; border-bottom: 1px solid var(--borda); vertical-align: middle; }
.tabela tbody tr:hover { background: var(--superficie-2); }
.tabela .direita { text-align: right; }
.tabela td.valor { text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; white-space: nowrap; }
.tabela select { padding: 5px 7px; font-size: .85rem; max-width: 190px; }
.linha-duplicada { opacity: .55; }
/* Vem marcada pra importar (a fatura prevalece) — sem opacidade reduzida
   como .linha-duplicada, que fica de fora; só um fundo discreto de alerta
   pra chamar atenção de que isso vai apagar um lançamento manual. */
.linha-duplicada-manual { background: color-mix(in srgb, var(--alerta) 8%, transparent); }
.linha-dividida { border-left: 3px solid var(--primaria); }

/* Larguras fixas por coluna: sem isso (table-layout: auto, o padrão), o
   navegador redistribui a largura de cada coluna conforme o conteúdo da
   página atual — um mês com descrições longas ou poucas linhas alinha as
   colunas num x diferente do que um mês com descrições curtas ou muitas
   linhas, mesmo sendo a mesma tabela. */
#tabela-lancamentos { table-layout: fixed; }
#tabela-lancamentos th:nth-child(1) { width: 9%; }
#tabela-lancamentos th:nth-child(2) { width: 32%; }
#tabela-lancamentos th:nth-child(3) { width: 21%; }
#tabela-lancamentos th:nth-child(4) { width: 15%; }
#tabela-lancamentos th:nth-child(5) { width: 16%; }
#tabela-lancamentos th:nth-child(6) { width: 7%; }
#tabela-lancamentos td:nth-child(2) { overflow-wrap: break-word; }
.valor-divisao {
  width: 100px; text-align: right; padding: 5px 7px; font-size: .88rem;
  font-variant-numeric: tabular-nums;
}

.etiqueta {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 9px; border-radius: 99px; font-size: .78rem; font-weight: 550;
  border: 1px solid transparent; white-space: nowrap;
}

.marca-competencia {
  display: block;
  color: var(--primaria);
  font-size: .74rem;
  font-weight: 600;
  white-space: nowrap;
}
.btn-icone-mini {
  background: none; border: 0; cursor: pointer; padding: 1px 4px;
  border-radius: 5px; color: var(--texto-fraco); font-size: .74rem;
  margin-top: 2px;
}
.btn-icone-mini:hover { background: var(--superficie-2); color: var(--texto); }
.campo-competencia-inline { display: block; margin-top: 4px; width: 9.5rem; }

.marca-parcela { color: var(--texto-fraco); font-size: .8rem; margin-left: 6px; }
.marca-origem { color: var(--texto-fraco); font-size: .74rem; margin-left: 6px; }
.marca-origem-manual { color: var(--alerta); }
/* Lançamento de despesa fixa cujo valor ainda é a média (boleto não
   chegou) — mesma cor de alerta do restante, pra chamar a atenção de que
   ainda precisa ser conferido. */
.marca-estimado {
  color: var(--alerta); font-size: .74rem; margin-left: 6px; font-weight: 600;
  cursor: help;
}
.titular-ok { color: var(--texto-fraco); font-size: .85rem; }
.titular-sem-cartao { color: var(--alerta); font-size: .85rem; font-weight: 600; }
.btn-inline { background: none; border: none; cursor: pointer; color: var(--primaria);
  font-weight: 700; padding: 0 4px; font-size: .95rem; }
.previa-descricao-texto { cursor: text; border-bottom: 1px dashed transparent; }
.previa-descricao-texto:hover { border-bottom-color: var(--texto-fraco); }
.previa-descricao-input { width: 100%; padding: 3px 5px; }

.modal-drilldown {
  width: min(920px, 94vw); max-height: 82vh; padding: 0; border: none; border-radius: 12px;
  background: var(--superficie); color: var(--texto);
  box-shadow: 0 20px 50px rgba(0, 0, 0, .35);
}
.modal-drilldown::backdrop { background: rgba(0, 0, 0, .5); }
.modal-cabecalho {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 18px; border-bottom: 1px solid var(--borda);
}
.modal-cabecalho h3 { margin: 0; font-size: 1rem; }
.modal-drilldown-lista {
  padding: 8px 18px 18px; overflow: auto; max-height: calc(82vh - 56px);
}
.grafico-clicavel { cursor: pointer; }

/* ------------------------------------------------------------ formulários */
.form-grade {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(165px, 1fr));
  gap: 12px;
  align-items: end;
}

.form-linha { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: 14px; }
.form-linha input[type="text"], .form-linha input[type="search"] { flex: 1 1 130px; }
.form-linha input.estreito { flex: 0 0 auto; width: 5.5rem; }
.form-linha input.estreito-icone { flex: 0 0 auto; width: 3.5rem; text-align: center; }
.form-linha input.medio { flex: 0 0 auto; width: 7.5rem; }

/* No formulário de Cartões, Apelido e Banco encolhem para caber junto com
   Final, Fecha dia e Vence dia numa única linha. */
#form-cartao input[name="apelido"] { flex: 1 1 110px; }
#form-cartao input[name="banco"] { flex: 1 1 70px; }

.form-acoes { display: flex; gap: 10px; align-items: end; }
.form-acoes-fim { justify-content: flex-end; margin-top: 16px; }

.filtros-linha { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }

.paginacao {
  display: flex; align-items: center; justify-content: center;
  gap: 14px; margin-top: 14px; color: var(--texto-fraco); font-size: .87rem;
}

/* --------------------------------------------------------------- prévia */
.resumo-previa {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px; padding: 14px; margin-bottom: 14px;
  background: var(--superficie-2); border-radius: 10px;
}
.resumo-previa div { display: grid; gap: 2px; }
.resumo-previa span { font-size: .74rem; color: var(--texto-fraco); text-transform: uppercase; letter-spacing: .04em; font-weight: 600; }
.resumo-previa strong { font-size: 1rem; font-variant-numeric: tabular-nums; }

.mapeamento {
  padding: 15px;
  margin-bottom: 16px;
  border: 1px dashed var(--borda);
  border-radius: 10px;
  background: var(--superficie-2);
}
.mapeamento h3 { font-size: .92rem; margin-bottom: 2px; }
.mapeamento .form-grade { margin-top: 12px; }
.mapeamento .form-acoes { margin-top: 14px; }

.aviso-caixa {
  padding: 10px 13px; border-radius: 9px; margin-bottom: 10px; font-size: .87rem;
  background: color-mix(in srgb, var(--alerta) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--alerta) 40%, transparent);
  color: var(--texto);
}

/* ------------------------------------------------------------- cadastros */
/* Pessoas e Cartões, lado a lado, num grid só deles — antes dividiam um
   grid "auto-fit" com Categorias e Regras (que ocupam a largura toda via
   grid-column:1/-1); esse span nas linhas de baixo impedia o auto-fit de
   colapsar as colunas vazias da linha de cima, deixando Pessoas e Cartões
   presos no tamanho mínimo mesmo com a tela bem larga. Cartões recebe uma
   fração maior (tem mais campos e agora mostra a lista ao lado). */
.grade-cadastros-topo {
  display: grid;
  grid-template-columns: minmax(300px, 1fr) minmax(420px, 1.7fr);
  gap: 18px;
}
@media (max-width: 760px) {
  .grade-cadastros-topo { grid-template-columns: 1fr; }
}

.grade-cadastros-baixo {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 18px;
}
@media (max-width: 1100px) {
  .grade-cadastros-baixo { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 760px) {
  .grade-cadastros-baixo { grid-template-columns: 1fr; }
}

/* A seção inteira ocupa o que sobra da janela (mesma ideia de Lançamentos
   e do Painel, via --altura-fixa) — Pessoas/Cartões ficam do tamanho
   natural deles, e a linha de baixo (Categorias/Regras) estica pra
   preencher o resto de verdade, em vez de uma altura fixa "chutada" que só
   cabia certinho numa janela de um tamanho específico e sobrava vazio (ou
   faltava espaço) em qualquer outra. */
#secao-cadastros.ativa {
  display: flex;
  flex-direction: column;
  height: calc(100vh - var(--altura-fixa, 130px));
  min-height: 480px;
}
#secao-cadastros.ativa > .grade-cadastros-topo {
  flex: none;
}
#secao-cadastros.ativa > .grade-cadastros-baixo {
  flex: 1;
  min-height: 0;
  grid-auto-rows: 1fr;
}

/* Categorias e Regras têm uma quantidade diferente de texto/formulário
   acima da lista — sem a mesma altura pros dois cards e a lista esticando
   pra preencher o resto (flex:1), o card com menos coisa em cima sobra
   vazio embaixo e a barra de rolagem da lista para no meio do quadro, bem
   antes da borda inferior. */
.grade-cadastros-baixo > article {
  display: flex;
  flex-direction: column;
  height: auto;
  min-height: 0;
}
.grade-cadastros-baixo > article > h2,
.grade-cadastros-baixo > article > form,
.grade-cadastros-baixo > article > p.ajuda,
.grade-cadastros-baixo > article > .filtros-linha {
  flex: none;
}
.grade-cadastros-baixo .lista-rolagem {
  flex: 1;
  min-height: 0;
  max-height: none;
}

/* Cartões: formulário à esquerda, lista dos cartões cadastrados à direita
   (em vez de embaixo) — com o espaço extra que o card ganhou acima. */
.cartoes-layout { display: flex; gap: 22px; align-items: flex-start; }
.cartoes-form { flex: 1 1 260px; min-width: 240px; }
.cartoes-lista {
  flex: 1 1 220px; min-width: 200px; align-self: stretch;
  max-height: 380px; overflow-y: auto; padding-right: 8px;
  border-left: 1px solid var(--borda); padding-left: 20px;
}
@media (max-width: 760px) {
  .cartoes-layout { flex-direction: column; }
  .cartoes-lista { border-left: 0; padding-left: 0; border-top: 1px solid var(--borda); padding-top: 12px; }
}

/* Sem um teto de largura, o nome (flex:1) empurra os botões de editar/
   remover lá pro fim da linha — numa tela larga, isso deixa um vão vazio
   enorme entre o texto e os botões. */
.item-lista {
  display: flex; align-items: center; gap: 10px; max-width: 640px;
  padding: 9px 0; border-bottom: 1px solid var(--borda);
}
.item-lista:last-child { border-bottom: 0; }
.item-lista-nome { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.item-lista-info { color: var(--texto-fraco); font-size: .83rem; }
.info-icone { color: var(--texto-fraco); cursor: help; font-size: .8rem; }
.ponto-cor { width: 11px; height: 11px; border-radius: 99px; flex: none; }

.item-lista-edicao {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center; max-width: 640px;
  padding: 4px 0 12px 4px; border-bottom: 1px solid var(--borda);
}
/* [hidden] sozinho perde pra "display: flex" acima — mesma pegadinha do
   .campo[hidden] mais abaixo. */
.item-lista-edicao[hidden] { display: none; }
/* Só os filhos diretos (Cartão/Orçamento/Categoria/Regra) — os campos de
   Lançamento moram dentro de .campo (coluna), que já cuida do próprio
   tamanho logo abaixo; se essa regra os alcançasse, o 130px viraria
   altura em vez de largura (eixo principal do .campo é vertical). */
.item-lista-edicao > input, .item-lista-edicao > select { flex: 1 1 130px; }
.item-lista-edicao .campo-estreito { flex: 0 0 auto; width: 6rem; }
/* Controle deslizante do orçamento por categoria — o máximo dele já vem
   limitado ao que ainda sobra dentro do Orçamento Global (ver
   renderizarCategorias), então arrastar até o fim nunca estoura o teto. */
.campo-slider-orcamento { flex: 1 1 160px; accent-color: var(--primaria); }

/* Categorias e Regras moram em cartões bem largos (lado a lado com o
   vizinho) — a linha deve ocupar a caixa toda, sem teto, pra não sobrar
   vão vazio e os botões ficarem coladinhos na borda direita. */
#lista-categorias .item-lista, #lista-categorias .item-lista-edicao,
#lista-regras .item-lista, #lista-regras .item-lista-edicao {
  max-width: none;
}

.lista-rolagem { max-height: 235px; overflow-y: auto; padding-right: 6px; }

/* -------------------------------------------------- edição inline em listas */
.campo-inline {
  background: transparent; border: 1px solid transparent; border-radius: 6px;
  padding: 4px 6px; color: var(--texto); font: inherit; width: 100%;
}
.campo-inline:hover { border-color: var(--borda); }
.campo-inline:focus { border-color: var(--primaria); outline: none; background: var(--superficie-2); }
.campo-estreito { width: 80px; }

/* Painel de edição de um lançamento (linha extra da tabela) — os campos
   levam legenda em cima, como no formulário de "Novo lançamento". */
.item-lista-edicao .campo { flex: 0 1 150px; }
.item-lista-edicao .campo.campo-largo { flex: 1 1 220px; }
.linha-edicao-lancamento td { padding-top: 4px; padding-bottom: 12px; border-bottom: 1px solid var(--borda); }
.acoes-lancamento { white-space: nowrap; }
.campo-cor-inline {
  width: 26px; height: 26px; padding: 0; border: none; border-radius: 99px;
  background: none; cursor: pointer; flex: none;
}
.campo-checkbox-tabela {
  display: flex; align-items: center; gap: 5px; font-size: .78rem;
  color: var(--texto-fraco); white-space: nowrap;
}

.rodape {
  text-align: center;
  padding: 8px 24px 12px;
  color: var(--texto-fraco);
  font-size: .8rem;
}
.rodape strong { font-variant-numeric: tabular-nums; color: var(--texto); }

/* ---------------------------------------------------------------- avisos */
.avisos { position: fixed; right: 18px; bottom: 18px; display: grid; gap: 8px; z-index: 50; max-width: min(400px, calc(100vw - 36px)); }

.toast {
  background: var(--superficie); border: 1px solid var(--borda); border-left: 3px solid var(--primaria);
  border-radius: 10px; padding: 11px 15px; box-shadow: var(--sombra); font-size: .89rem;
  animation: surgir .2s ease-out;
}
.toast-erro { border-left-color: var(--erro); }
.toast-ok { border-left-color: var(--entrada); }

@keyframes surgir { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

@media (max-width: 620px) {
  main { padding: 16px 14px 50px; }
  .topo, .abas { padding-left: 14px; padding-right: 14px; }
  .campo-largo { grid-column: span 1; }
}

/* ------------------------------------------- quadro semanal: 5 desenhos */
/* O mesmo dado (quanto de cada semana já foi gasto do limite daquela semana)
   desenhado de cinco jeitos — quem escolhe é o seletor no cabeçalho do card,
   e a escolha fica salva no navegador. Em todos os modelos, o elemento de
   uma semana carrega data-semana-* : é assim que o hover monta o balão e o
   clique abre a lista de compras da semana (ver os listeners em app.js). */
.cabecalho-semana {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; flex-wrap: wrap;
}
#modelo-semana { padding: 4px 8px; font-size: .78rem; border-radius: 8px; }

/* Barra normal que também é clicável (modelo "uma semana por vez"). */
.barra-clicavel { cursor: pointer; }
.barra-clicavel:hover { filter: brightness(1.1); }

/* --- colunas por semana: altura = quanto do limite da semana foi usado.
   A escala vai até 140%, então o tracejado do limite (100%) fica a 100/140
   da altura — daí o 28.6% de cima. */
.colunas-semana {
  position: relative; display: flex; gap: 6px;
  align-items: flex-end; height: 64px;
}
.colunas-semana::before {
  content: ""; position: absolute; left: 0; right: 0; top: 28.6%;
  border-top: 1px dashed var(--texto-fraco); opacity: .55;
}
.coluna-semana {
  position: relative; flex: 1; min-width: 0; height: 100%;
  display: flex; flex-direction: column; justify-content: flex-end;
  cursor: pointer;
}
.coluna-semana:hover { filter: brightness(1.1); }
/* Só um pedaço por vez (semana escolhida, ou o mês inteiro): a coluna fica
   com largura fixa, não esticada pra ocupar o card inteiro. */
.colunas-semana-unica { justify-content: flex-start; }
.colunas-semana-unica .coluna-semana { flex: 0 0 72px; }
.coluna-semana > b {
  font-size: .6rem; font-weight: 600; color: var(--texto-fraco);
  text-align: center; line-height: 1.1; margin-bottom: 2px;
}
.coluna-semana > i { display: block; border-radius: 3px 3px 0 0; transition: height .3s; }
.coluna-semana.barra-atencao > i { background: var(--alerta) !important; }
.coluna-semana.barra-estourada > i { background: var(--erro) !important; }
/* Reservado pelas parcelas: empilhado logo acima do que já foi gasto. */
.coluna-reservada {
  display: block; border-radius: 3px 3px 0 0;
  background: repeating-linear-gradient(
    45deg, var(--texto-fraco) 0 3px, transparent 3px 7px
  );
  opacity: .5;
}
/* --- tabela colorida: os números exatos do pedaço escolhido, sem precisar
   passar o mouse em nada. Só uma coluna de dado por vez — nunca precisa de
   rolagem lateral. */
.tabela-semanas { border-collapse: separate; border-spacing: 3px; width: auto; font-size: .74rem; }
.tabela-semanas thead th {
  font-weight: 600; color: var(--texto-fraco); font-size: .66rem;
  text-align: center; padding: 0 2px; white-space: nowrap;
}
.tabela-semanas tbody th {
  text-align: left; font-weight: 500; font-size: .8rem;
  white-space: nowrap; padding-right: 4px;
}
.tabela-semanas tbody tr { cursor: pointer; }
.celula-semana {
  text-align: center; border-radius: 6px; padding: 5px 4px;
  font-variant-numeric: tabular-nums; white-space: nowrap;
  background: var(--semana-0-fundo); color: var(--semana-0-texto);
  /* Largura fixa — sempre do mesmo tamanho, dê R$ 1 ou R$ 12.345, pra não
     ficar pulando de tamanho ao trocar de semana. Cabe até 5 dígitos. */
  width: 78px; box-sizing: border-box;
}
.celula-semana small { display: block; font-size: .86em; opacity: .8; }
.celula-semana[data-semana-inicio] { cursor: pointer; }
.celula-semana[data-semana-inicio]:hover { filter: brightness(1.06); }
.nivel-1 { background: var(--semana-1-fundo); color: var(--semana-1-texto); }
.nivel-2 { background: var(--semana-2-fundo); color: var(--semana-2-texto); }
.nivel-3 { background: var(--semana-3-fundo); color: var(--semana-3-texto); }
.nivel-4 { background: var(--semana-4-fundo); color: var(--semana-4-texto); font-weight: 700; }
.celula-reservada {
  text-align: right; color: var(--texto-fraco);
  font-variant-numeric: tabular-nums; white-space: nowrap; padding-left: 6px;
}

/* --- uma semana por vez: abas no alto e as barras de sempre embaixo. */
.abas-semana { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 4px; }
.aba-semana {
  font-size: .72rem; padding: 3px 10px; border-radius: 99px; cursor: pointer;
  border: 1px solid var(--borda); background: var(--superficie-2); color: var(--texto-fraco);
  /* Largura fixa — todas as semanas do mesmo tamanho, dê "1-2" ou "27-30",
     em vez de pular de tamanho conforme o rótulo. */
  width: 58px; box-sizing: border-box; text-align: center;
}
.aba-semana:hover { border-color: var(--primaria); }
.aba-semana.ativa {
  background: var(--primaria); border-color: var(--primaria);
  color: var(--primaria-contraste); font-weight: 600;
}
/* Botão do mês inteiro, sempre o último da fileira — uma linha separando
   ele das semanas, pra ficar claro que é um pedaço diferente (o total).
   Largura pro maior nome de mês em português ("Fevereiro"), senão ele
   mudaria de tamanho mês a mês. */
.aba-mes {
  width: 98px; margin-left: 6px; padding-left: 12px; border-left: 1px solid var(--borda);
}

/* Seletor de semana/mês do card "Orçamento por semana" — mesma fileira de
   botões nos modelos tabela, colunas e abas, sempre logo abaixo da nota. */
#filtro-semana { margin: 6px 0 10px; }
#filtro-semana[hidden] { display: none; }
