/*
 * Sistema visual da aplicação.
 *
 * Cor: neutros com viés levemente frio (azul-esverdeado), acento petróleo.
 * Verde e vermelho são reservados ao significado contábil — entrada e saída —
 * e nunca usados como decoração, para que a cor continue querendo dizer algo.
 *
 * Dois temas, claro e escuro, escolhidos em "Minha conta" e resolvidos aqui:
 * o `<html>` chega com `data-theme` valendo `light` ou `dark`, e o claro é o
 * padrão. Nada disso passa por JavaScript — o tema certo já vem no primeiro
 * paint, sem piscar o outro.
 *
 * O escuro não é o claro invertido: os neutros escurecem, mas o acento e as
 * cores contábeis *clareiam*, senão petróleo e vinho somem no fundo escuro. Só
 * as variáveis mudam; nenhuma regra abaixo sabe em que tema está.
 *
 * Forma: painel de trabalho com navegação lateral fixa e uma faixa de contexto
 * no topo da coluna de conteúdo. O conteúdo vive em cartões claros sobre um
 * fundo levemente mais escuro; a separação vem da sombra rasa e da borda fina,
 * nunca de mais uma cor.
 */

:root {
  color-scheme: light;

  --ground:        #F4F6F6;
  --surface:       #FFFFFF;
  --surface-alt:   #EDF1F1;
  --line:          #D3DBDA;
  --line-forte:    #B6C2C1;

  --ink:           #10201E;
  --ink-medio:     #43514F;
  --ink-fraco:     #6C7A78;

  --acento:        #0B5D53;
  --acento-forte:  #084A42;
  --acento-fraco:  #DCEAE7;
  --acento-texto:  #FFFFFF;

  --entrada:       #16794A;
  --entrada-fundo: #DFF1E7;
  --saida:         #A8322A;
  --saida-fundo:   #FAE3E1;
  --aviso:         #8A5A06;
  --aviso-fundo:   #FBEED6;

  --foco:          #1F8C7C;

  /* Vermelho de fundo cheio pede texto claro por cima; no escuro o `--saida` é
     que fica claro, e o texto inverte junto. */
  --saida-texto:   #FFFFFF;
  --saida-forte:   #8E2A23;

  /* Contorno da amostra de cor e véu por trás da gaveta: são preto e branco
     diluídos, e trocam de lado com o tema. */
  --contorno-amostra: rgb(0 0 0 / 12%);
  --cortina:          rgb(16 32 30 / 38%);

  /* Qual das duas marcas aparece. A regra fica em `.brand__logo`; aqui só se
     diz qual tema mostra qual. */
  --logo-claro:  block;
  --logo-escuro: none;

  --raio:      8px;
  --raio-caixa: 14px;
  /* Duas sombras: a rasa desgruda o cartão do fundo, a larga e bem diluída dá
     a profundidade sem escurecer a borda. */
  --sombra:      0 1px 2px rgb(16 32 30 / 5%), 0 10px 24px -14px rgb(16 32 30 / 18%);
  --sombra-alta: 0 2px 4px rgb(16 32 30 / 6%), 0 18px 40px -20px rgb(16 32 30 / 26%);

  --fonte-titulo: "Bricolage Grotesque", "Public Sans", ui-sans-serif, system-ui, sans-serif;
  --fonte-corpo:  "Public Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;

  --largura: 68rem;
  /* A coluna do painel já perde a lateral de largura: o teto sobe para as
     grades de indicadores continuarem cabendo quatro a quatro. O site
     deslogado fica na medida de leitura de sempre. */
  --largura-painel: 78rem;
  --lateral: 16rem;

  /* ---------- Valores do tema escuro ----------
     Moram aqui, num lugar só, e o mapeamento do escuro logo abaixo aponta
     para elas: é o que mantém cada cor escrita uma vez. */

  --escuro-ground:      #0C1614;
  --escuro-surface:     #14201E;
  --escuro-surface-alt: #1D2B29;
  --escuro-line:        #2A3937;
  --escuro-line-forte:  #3D4E4B;

  --escuro-ink:         #E7EDEB;
  --escuro-ink-medio:   #B4C1BF;
  --escuro-ink-fraco:   #8A9997;

  /* Petróleo #0B5D53 tem contraste 1,4 sobre o fundo escuro: como acento, some.
     O escuro sobe o mesmo tom até a faixa legível e inverte a direção do
     hover — no claro o acento escurece ao passar o mouse, aqui ele clareia. */
  --escuro-acento:       #4FBFA9;
  --escuro-acento-forte: #74D5C1;
  --escuro-acento-fraco: #16332F;
  --escuro-acento-texto: #06201C;

  --escuro-entrada:       #57C98E;
  --escuro-entrada-fundo: #123125;
  --escuro-saida:         #F08A80;
  --escuro-saida-fundo:   #3A1C19;
  --escuro-saida-texto:   #26100D;
  --escuro-saida-forte:   #F6A79E;
  --escuro-aviso:         #E0B25E;
  --escuro-aviso-fundo:   #342610;

  --escuro-foco: #56D0B8;

  --escuro-contorno-amostra: rgb(255 255 255 / 20%);
  --escuro-cortina:          rgb(0 0 0 / 62%);

  /* No claro a sombra escurece o fundo e desgruda o cartão. Sobre fundo escuro
     não há o que escurecer: a sombra vira quase preta e serve só de assento,
     e quem separa o cartão do fundo é a borda. */
  --escuro-sombra:      0 1px 2px rgb(0 0 0 / 40%), 0 10px 24px -14px rgb(0 0 0 / 70%);
  --escuro-sombra-alta: 0 2px 4px rgb(0 0 0 / 45%), 0 18px 40px -20px rgb(0 0 0 / 80%);
}

/* O mapeamento do escuro: só as variáveis mudam. */
:root[data-theme="dark"] {
  color-scheme: dark;

  --ground:        var(--escuro-ground);
  --surface:       var(--escuro-surface);
  --surface-alt:   var(--escuro-surface-alt);
  --line:          var(--escuro-line);
  --line-forte:    var(--escuro-line-forte);

  --ink:           var(--escuro-ink);
  --ink-medio:     var(--escuro-ink-medio);
  --ink-fraco:     var(--escuro-ink-fraco);

  --acento:        var(--escuro-acento);
  --acento-forte:  var(--escuro-acento-forte);
  --acento-fraco:  var(--escuro-acento-fraco);
  --acento-texto:  var(--escuro-acento-texto);

  --entrada:       var(--escuro-entrada);
  --entrada-fundo: var(--escuro-entrada-fundo);
  --saida:         var(--escuro-saida);
  --saida-fundo:   var(--escuro-saida-fundo);
  --saida-texto:   var(--escuro-saida-texto);
  --saida-forte:   var(--escuro-saida-forte);
  --aviso:         var(--escuro-aviso);
  --aviso-fundo:   var(--escuro-aviso-fundo);

  --foco:          var(--escuro-foco);

  --contorno-amostra: var(--escuro-contorno-amostra);
  --cortina:          var(--escuro-cortina);

  --sombra:      var(--escuro-sombra);
  --sombra-alta: var(--escuro-sombra-alta);

  --logo-claro:  none;
  --logo-escuro: block;
}

*, *::before, *::after { box-sizing: border-box; }

img, svg, video, canvas { max-width: 100%; }

/* O atributo `hidden` precisa vencer qualquer `display` de classe. Sem isto,
   uma regra como `.lote { display: flex }` deixa o elemento visível mesmo
   marcado como oculto. */
[hidden] { display: none !important; }

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--fonte-corpo);
  font-size: 1rem;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
  font-family: var(--fonte-titulo);
  font-weight: 600;
  line-height: 1.2;
  text-wrap: balance;
  margin: 0;
}

a { color: var(--acento); text-underline-offset: 2px; }
a:hover { color: var(--acento-forte); }

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

.container {
  width: min(100% - 2rem, var(--largura));
  margin-inline: auto;
}

/* ================================================== casca do painel ==
 * Lateral fixa com a navegação, coluna de conteúdo à direita e uma faixa de
 * contexto no topo dela. A lateral é a única navegação do app: espalhar os
 * mesmos links entre topo e lateral obriga a escolher onde olhar.
 * ==================================================================== */

.app {
  display: grid;
  grid-template-columns: var(--lateral) minmax(0, 1fr);
  min-height: 100dvh;
}

.app__principal {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

/* ---------- Navegação lateral ---------- */

.lateral {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  flex-direction: column;
  height: 100dvh;
  padding: 1rem .75rem 1.15rem;
  background: var(--surface);
  border-right: 1px solid var(--line);
  overflow-y: auto;
  overscroll-behavior: contain;
}

.lateral__marca {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .3rem .5rem 1.1rem;
}

.lateral__grupo { display: flex; flex-direction: column; gap: .15rem; }

.lateral__rotulo {
  padding: 1rem .8rem .35rem;
  font-size: .68rem;
  text-transform: uppercase;
  letter-spacing: .09em;
  font-weight: 600;
  color: var(--ink-fraco);
}

.lateral__link {
  display: flex;
  align-items: center;
  gap: .7rem;
  padding: .6rem .8rem;
  border-radius: var(--raio);
  color: var(--ink-medio);
  text-decoration: none;
  font-size: .94rem;
  font-weight: 500;
}

.lateral__link .icone { flex: none; color: var(--ink-fraco); }

.lateral__link:hover { background: var(--surface-alt); color: var(--ink); }
.lateral__link:hover .icone { color: var(--ink-medio); }

/* A página em que se está é dita pelo `aria-current` — o estilo segue o
   atributo em vez de uma classe própria, para não haver como pintar uma e
   esquecer a outra. */
.lateral__link[aria-current] {
  background: var(--acento-fraco);
  color: var(--acento);
  font-weight: 600;
}
.lateral__link[aria-current] .icone { color: var(--acento); }

.lateral__rodape {
  margin-top: auto;
  padding-top: .9rem;
  border-top: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: .15rem;
}

.lateral__rodape form { margin: 0; }

.lateral__link--botao {
  width: 100%;
  background: none;
  border: 0;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
}

.lateral__usuario {
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: .3rem .8rem .55rem;
  min-width: 0;
}

.lateral__inicial {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 2rem;
  height: 2rem;
  border-radius: 999px;
  background: var(--acento-fraco);
  color: var(--acento);
  font-family: var(--fonte-titulo);
  font-weight: 700;
  font-size: .85rem;
}

.lateral__nome {
  min-width: 0;
  font-size: .875rem;
  font-weight: 600;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---------- Faixa de contexto ---------- */

.topbar {
  position: sticky;
  top: 0;
  z-index: 15;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
}

.topbar__inner {
  display: flex;
  align-items: center;
  gap: 1rem;
  min-height: 4rem;
}

/* A faixa do painel acompanha a coluna inteira; a do site, deslogado, fica
   presa à mesma medida do conteúdo. */
.topbar__inner--largo { padding-inline: clamp(1rem, 3vw, 2rem); }

.topbar__titulo {
  font-family: var(--fonte-titulo);
  font-size: 1rem;
  font-weight: 600;
  color: var(--ink);
}

/* O sino: ícone só, com a contagem colada no canto. Sem contagem ele não
   chama atenção nenhuma, que é o certo — a maior parte dos dias não tem aviso,
   e um sino que brilha sempre não avisa nada. */
.sino {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 999px;
  color: var(--ink-medio);
}

.sino:hover { background: var(--surface-alt); color: var(--ink); }
.sino:focus-visible { outline: 2px solid var(--foco); outline-offset: 2px; }

.sino__contagem {
  position: absolute;
  top: .1rem;
  right: .05rem;
  min-width: 1.05rem;
  padding: 0 .2rem;
  border-radius: 999px;
  background: var(--saida);
  color: #fff;
  font-size: .68rem;
  font-weight: 600;
  line-height: 1.05rem;
  text-align: center;
}

/* O "ou" entre a senha e o Google: um fio com a palavra no meio, que é como o
   olho lê "há um segundo caminho" sem precisar de uma frase. */
.autenticacao__ou {
  display: flex;
  align-items: center;
  gap: .75rem;
  margin: 1.25rem 0;
  color: var(--ink-fraco);
  font-size: .85rem;
}

.autenticacao__ou::before,
.autenticacao__ou::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--line);
}

.google { display: inline-flex; align-items: center; justify-content: center; gap: .6rem; }

/* ---------- Primeiros passos ---------- */

.primeiros-passos { margin-bottom: 1.75rem; }

.passos { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }

.passo {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: .85rem;
  padding: .85rem 0;
  border-top: 1px solid var(--line);
}

.passo:first-child { border-top: 0; }

/* O círculo vazio é o passo que falta; o cheio, o que já foi. A marca repete o
   que o botão ao lado já diz — cor e forma sozinhas não são informação. */
.passo__marca {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.5rem;
  height: 1.5rem;
  border: 2px solid var(--line-forte);
  border-radius: 999px;
  color: transparent;
  flex: none;
}

.passo--feito .passo__marca {
  border-color: var(--entrada);
  background: var(--entrada);
  color: #fff;
}

.passo__texto { display: flex; flex-direction: column; gap: .15rem; min-width: 0; }

.passo__descricao { font-size: .85rem; color: var(--ink-fraco); }

.passo--feito .passo__texto strong { color: var(--ink-fraco); }

@media (max-width: 40rem) {
  .passo { grid-template-columns: auto minmax(0, 1fr); }
  .passo .botao { grid-column: 2; justify-self: start; }
}

/* O campo único da barra. Estreito de propósito: ele é um atalho, não o
   formulário — quem precisa dos dez campos clica no botão ao lado. */
.rapido { display: flex; align-items: center; gap: .25rem; margin: 0; }

.rapido__campo {
  width: clamp(9rem, 22vw, 16rem);
  padding: .45rem .7rem;
  border: 1px solid var(--line-forte);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-size: .875rem;
}

.rapido__campo:focus-visible { outline: 2px solid var(--foco); outline-offset: 1px; }

.rapido__enviar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--ink-medio);
  cursor: pointer;
}

.rapido__enviar:hover { background: var(--surface-alt); color: var(--ink); }

/* No celular a barra já está apertada entre a gaveta e o seletor de perfil. */
@media (max-width: 40rem) { .rapido { display: none; } }

.topbar__acoes {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: .35rem;
  flex-wrap: wrap;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: .55rem;
  font-family: var(--fonte-titulo);
  font-weight: 700;
  color: var(--ink);
  text-decoration: none;
  letter-spacing: -.01em;
}

/* A altura fixa evita que a barra pule enquanto o SVG carrega. */
.brand__logo { height: 2.375rem; width: auto; }

/* As duas marcas vêm sempre no HTML; o tema decide qual delas ocupa espaço. A
   escura é a mesma arte em branco, para não sumir no fundo escuro. */
.brand__logo--clara  { display: var(--logo-claro); }
.brand__logo--escura { display: var(--logo-escuro); }

.brand__mark__nome__admin {
  color: white;
  background: linear-gradient(29deg, rgb(0 25 255), #d000ff);
  padding: 1px 11px;
  border-radius: 25px;
  font-size: .75rem;
  letter-spacing: .02em;
}

/* ---------- Navegação em linha (páginas sem sessão) ---------- */

.nav { display: flex; align-items: center; gap: .35rem; flex-wrap: wrap; }

.nav__link {
  padding: .4rem .7rem;
  border-radius: var(--raio);
  color: var(--ink-medio);
  text-decoration: none;
  font-size: .925rem;
  font-weight: 500;
}
.nav__link:hover { background: var(--surface-alt); color: var(--ink); }

/* ---------- Blocos de página ---------- */

main.container { padding-block: 2rem 4rem; }

/* Dentro da casca a medida já é a da coluna: o respiro lateral vem do padding
   e cresce com a tela, em vez de sobrar margem dos dois lados. */
.app main.container { width: min(100% - clamp(2rem, 6vw, 4rem), var(--largura-painel)); }

.pagina__cabecalho {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: .75rem;
  margin-bottom: 1.75rem;
}

.pagina__titulo { font-size: clamp(1.6rem, 1.2rem + 1.4vw, 2.1rem); letter-spacing: -.025em; }
.pagina__subtitulo { color: var(--ink-fraco); margin: .25rem 0 0; }

/* Quem gerou o relatório e quando. Fica na tela, e não só no arquivo, porque
   relatório circula tanto como captura de tela e impressão quanto como CSV — e
   nessas duas formas a pergunta "de quando é isto, e quem tirou?" fica sem
   resposta. Menor que o subtítulo de propósito: é procedência, não conteúdo. */
.pagina__assinatura { color: var(--ink-fraco); font-size: .8125rem; margin: .35rem 0 0; }

/* O período que a página está mostrando, à direita do título. Era uma frase no
   subtítulo, onde duas datas no meio do texto se liam como texto; em pastilha,
   lêem-se como o filtro que são. */
.pagina__periodo {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  padding: .45rem .8rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
  box-shadow: var(--sombra);
  font-size: .82rem;
  font-weight: 600;
  color: var(--ink-medio);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.pagina__periodo svg { color: var(--ink-fraco); flex: none; }

/* ---------- Gaveta do período ----------
   A pastilha acima é o `summary` deste `<details>`: o que se lê é o recorte
   que está valendo, e clicar nele abre por onde trocá-lo. */

.periodo { position: relative; }

/* O triângulo que o navegador põe no `summary` sairia dentro da pastilha, ao
   lado do ícone de calendário — dois enfeites disputando a mesma ponta. */
.periodo > summary { cursor: pointer; list-style: none; }
.periodo > summary::-webkit-details-marker { display: none; }
.periodo > summary:hover { border-color: var(--line-forte); color: var(--ink); }
.periodo > summary:focus-visible { outline: 2px solid var(--foco); outline-offset: 2px; }

/* A seta gira ao abrir. É o que diz que a pastilha é um controle e não um
   rótulo — sem ela, ninguém descobre que dá para clicar. */
.periodo__seta {
  width: .42rem;
  height: .42rem;
  border-right: 2px solid var(--ink-fraco);
  border-bottom: 2px solid var(--ink-fraco);
  transform: translateY(-2px) rotate(45deg);
  transition: transform .15s ease;
}

.periodo[open] .periodo__seta { transform: translateY(1px) rotate(-135deg); }

/* A gaveta flutua sobre a página. Empurrar o conteúdo para baixo faria o
   painel inteiro pular a cada abertura, e o que se quer ver ao escolher o
   período são justamente os números que estão logo abaixo. */
.periodo__gaveta {
  position: absolute;
  right: 0;
  z-index: 20;
  margin-top: .5rem;
  min-width: 18rem;
  padding: .9rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--raio-caixa);
  box-shadow: var(--sombra-alta);
}

/* Dois por dois: os quatro rótulos não cabem numa linha só na largura da
   gaveta, e uma coluna de quatro deixaria o formulário longe do alcance. */
.periodo__atalhos {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: .35rem;
  padding-bottom: .85rem;
  margin-bottom: .85rem;
  border-bottom: 1px solid var(--line);
}

.periodo__atalho {
  padding: .4rem .6rem;
  border: 1px solid var(--line);
  border-radius: var(--raio);
  background: var(--surface-alt);
  font-size: .8rem;
  font-weight: 600;
  color: var(--ink-medio);
  text-decoration: none;
  text-align: center;
  white-space: nowrap;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}

.periodo__atalho:hover { color: var(--ink); border-color: var(--line-forte); }

/* O atalho que descreve o que está na tela fica aceso. Quando as datas foram
   digitadas à mão nenhum acende, que é a resposta certa: não é nenhum deles. */
.periodo__atalho[aria-current] {
  background: var(--acento-fraco);
  border-color: var(--acento);
  color: var(--acento);
}

.periodo__atalho:focus-visible { outline: 2px solid var(--foco); outline-offset: 2px; }

.periodo__form {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: .6rem;
  align-items: end;
}

.periodo__form .botao { grid-column: 1 / -1; }

/* O título da seção e o seletor na mesma linha, no painel do perfil — lá o
   período não fica no cabeçalho da página, que já é dos botões do perfil. */
.secao__cabecalho {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
}

/* ---------- Página inicial ----------
   A tela pública é a única do sistema que precisa convencer antes de explicar,
   e o que convence aqui é parecer o que é: um painel de dinheiro. O painel ao
   lado do texto é montado em HTML — não pesa no carregamento, não desatualiza
   em relação à tela real e usa as mesmas cores contábeis do produto. */

.hero {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  gap: 3.5rem;
  align-items: center;
  padding-block: 4rem 3rem;
}

.hero__coluna {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1.35rem;
  max-width: 30rem;
}

.hero__selo {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  margin: 0;
  padding: .3rem .8rem .3rem .6rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink-medio);
  font-size: .8125rem;
  font-weight: 500;
}

.hero__selo-ponto {
  width: .45rem;
  height: .45rem;
  border-radius: 999px;
  background: var(--acento);
}

.hero__titulo {
  font-size: clamp(2.2rem, 1.2rem + 3.8vw, 3.75rem);
  line-height: 1.03;
  letter-spacing: -.04em;
  font-weight: 700;
  margin: 0;
}

.hero__texto { font-size: 1.125rem; color: var(--ink-medio); margin: 0; }
.hero__acoes { display: flex; gap: .75rem; flex-wrap: wrap; }

/* ---------- Painel de demonstração ---------- */

.painel-previa {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: calc(var(--raio-caixa) + 4px);
  box-shadow: var(--sombra-alta);
  padding: 1.15rem 1.3rem 1.05rem;
  font-variant-numeric: tabular-nums;
}

.painel-previa__topo {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding-bottom: .9rem;
  border-bottom: 1px solid var(--line);
}

.painel-previa__nome { font-family: var(--fonte-titulo); font-weight: 700; }

.painel-previa__periodo {
  margin-left: auto;
  font-size: .8125rem;
  color: var(--ink-fraco);
}

.painel-previa__numeros {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--line);
  border-bottom: 1px solid var(--line);
}

.painel-previa__numeros > div {
  background: var(--surface);
  padding: .85rem .1rem .95rem;
  display: flex;
  flex-direction: column;
  gap: .15rem;
}

.painel-previa__rotulo {
  font-size: .6875rem;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--ink-fraco);
}

.painel-previa__cifra { font-size: 1.0625rem; font-weight: 700; letter-spacing: -.01em; }

.painel-previa__grafico {
  display: flex;
  align-items: flex-end;
  gap: .6rem;
  height: 6.5rem;
  padding-block: 1.1rem 1rem;
  border-bottom: 1px solid var(--line);
  margin-bottom: .35rem;
}

/* Entrada e saída lado a lado, um par por mês: é o gráfico do painel de
   verdade, reduzido ao que cabe aqui. */
.barra-dupla {
  flex: 1;
  align-self: stretch;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: 2px;
}

.barra-dupla > span {
  width: .45rem;
  height: var(--h, 10%);
  border-radius: 2px 2px 0 0;
}

.barra-dupla__entrada { background: var(--entrada); }
.barra-dupla__saida   { background: var(--saida); }

.painel-previa__linha {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: center;
  gap: .6rem;
  padding: .55rem .45rem;
  border-radius: var(--raio);
  font-size: .875rem;
}

.painel-previa__linha--foco { background: var(--surface-alt); }

.painel-previa__texto {
  color: var(--ink-medio);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.painel-previa__valor { font-weight: 600; }

.painel-previa__rodape {
  display: flex;
  align-items: center;
  gap: .75rem;
  padding-top: .9rem;
  margin-top: .4rem;
  border-top: 1px solid var(--line);
}

.painel-previa__progresso {
  flex: 1;
  height: .375rem;
  border-radius: 999px;
  background: var(--surface-alt);
  border: 1px solid var(--line);
  overflow: hidden;
}

.painel-previa__progresso span {
  display: block;
  width: var(--pct, 0%);
  height: 100%;
  background: var(--acento);
}

.painel-previa__legenda { font-size: .75rem; color: var(--ink-fraco); white-space: nowrap; }

/* ---------- Seções da página inicial ---------- */

.secao-marketing { padding-block: 2.5rem; }

.secao-marketing__titulo {
  font-size: clamp(1.4rem, 1.1rem + 1.2vw, 1.9rem);
  letter-spacing: -.03em;
  margin: 0 0 1.5rem;
}

.recursos {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr));
  gap: 1rem;
}

.recurso { display: flex; flex-direction: column; gap: .55rem; padding: 1.25rem 1.35rem; }

.recurso__glifo {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.375rem;
  height: 2.375rem;
  border-radius: var(--raio);
  background: var(--acento-fraco);
  color: var(--acento);
}

.recurso__titulo {
  margin: 0;
  font-size: 1rem;
  font-family: var(--fonte-titulo);
  letter-spacing: -.015em;
}

.recurso__texto { margin: 0; color: var(--ink-medio); font-size: .9rem; }

.fecho {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 1.25rem;
  margin-block: 1.5rem 4rem;
  padding: 2rem 2.25rem;
  border-radius: calc(var(--raio-caixa) + 4px);
  background: var(--acento);
  color: var(--acento-texto);
}

.fecho__titulo {
  margin: 0;
  font-size: clamp(1.3rem, 1.05rem + 1.1vw, 1.8rem);
  letter-spacing: -.03em;
  color: inherit;
}

.fecho__botao { background: var(--acento-texto); color: var(--acento); border-color: transparent; }
.fecho__botao:hover { background: var(--surface-alt); color: var(--acento-forte); }

@media (max-width: 60rem) {
  .hero { grid-template-columns: minmax(0, 1fr); gap: 2.25rem; padding-block: 2.25rem 1.5rem; }
  .fecho { padding: 1.75rem; }
}

.vazio {
  border: 1px dashed var(--line-forte);
  border-radius: var(--raio-caixa);
  padding: 2.5rem 1.5rem;
  text-align: center;
  color: var(--ink-fraco);
  background: var(--surface);
}
.vazio p { margin: 0; }

.cartao {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--raio-caixa);
  padding: 1.35rem 1.5rem;
  box-shadow: var(--sombra);
}

/* O cartão que leva a algum lugar reage ao mouse; o que só mostra número, não.
   Sem isso, tudo parece clicável e nada parece clicável. */
a.cartao { transition: box-shadow .15s ease, border-color .15s ease, transform .15s ease; }
a.cartao:hover { border-color: var(--line-forte); box-shadow: var(--sombra-alta); transform: translateY(-1px); }

/* Cabeçalho dentro do cartão. Nasceu nos gráficos do painel: o título solto
   acima da caixa deixava cada bloco com duas alturas para o olho seguir — a do
   texto e a do cartão. Dentro, o gráfico e o nome dele são uma coisa só. */
.cartao__cabecalho {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: .5rem 1rem;
  margin-bottom: 1.15rem;
}

.cartao__titulo {
  font-family: var(--fonte-titulo);
  font-size: 1rem;
  letter-spacing: -.01em;
  line-height: 1.25;
  margin: 0;
}

.cartao__apoio {
  margin: .2rem 0 0;
  font-size: .8rem;
  color: var(--ink-fraco);
  max-width: 42ch;
}

/* Tabela encostada nas bordas do cartão: a moldura já é a do cartão, e a da
   `.tabela-rolagem` por dentro dela seria uma segunda linha a 1px da primeira. */
.cartao--tabela { padding: 0; overflow: hidden; }
.cartao--tabela .cartao__cabecalho { margin: 0; padding: 1.2rem 1.35rem .95rem; }
.cartao--tabela .tabela-rolagem { border: 0; border-radius: 0; }
.cartao--tabela .tabela th { background: transparent; border-top: 1px solid var(--line); }
.cartao--tabela .vazio { border: 0; margin: 0; }

/* ---------- Botões ---------- */

.botao {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .4rem;
  padding: .5rem 1rem;
  border-radius: var(--raio);
  border: 1px solid transparent;
  font-family: inherit;
  font-size: .95rem;
  font-weight: 600;
  line-height: 1.4;
  text-decoration: none;
  cursor: pointer;
}

.botao--primario { background: var(--acento); color: var(--acento-texto); }
.botao--primario:hover { background: var(--acento-forte); color: var(--acento-texto); }

.botao--vazado { background: transparent; border-color: var(--line-forte); color: var(--ink); }
.botao--vazado:hover { background: var(--surface-alt); color: var(--ink); }

.botao--grande { padding: .7rem 1.4rem; font-size: 1rem; }

/* Botão desligado precisa parecer desligado. Sem isto, o que não responde ao
   clique tem a mesma cara do que responde, e quem clica conclui que o sistema
   travou. */
.botao:disabled {
  opacity: .45;
  cursor: not-allowed;
  box-shadow: none;
}

/* ---------- Formulários ---------- */

/* O formulário é uma grade que se ajusta à largura que tem: duas ou três
   colunas num monitor, uma no celular. Antes era uma coluna fixa de 26rem — uma
   tira estreita no meio de uma tela de 1400px, com o rodapé de ações longe do
   primeiro campo.

   `minmax(min(100%, 22rem), 1fr)` é o que faz a mesma regra servir aos dois
   casos: onde há espaço, cabem colunas de 22rem; onde o formulário vive numa
   coluna estreita, como o cartão de login, a largura disponível vira o mínimo
   e sobra uma coluna só. */
.form {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr));
  align-items: start;
  gap: 1.15rem 1.25rem;
  max-width: 56rem;
}

/* Só campo curto divide a linha. Tudo o mais — o bloco de erros, o grupo de
   opções, a caixa de texto, o par de campos e as ações — ocupa a linha inteira:
   são coisas que perdem sentido cortadas ao meio.
   
   O par (`.campo-duplo`) ocupa a linha e se divide por dentro, com a grade
   dele. Mandá-lo ocupar duas colunas da grade de fora obrigaria a grade a ter
   duas colunas mesmo no celular — foi assim que um campo apareceu cortado na
   borda direita da tela de 430px. */
.form > * { grid-column: 1 / -1; }
.form > .campo { grid-column: auto; }
.form > .campo--largo,
.form > .campo--opcoes,
.form > .campo:has(textarea) { grid-column: 1 / -1; }

/* Formulário de assunto grande — lançamento, recorrência, conta bancária —
   cresce até onde a coluna de conteúdo permitir. */
.form--larga { max-width: none; }

.campo { display: flex; flex-direction: column; gap: .3rem; }

.campo label { font-size: .875rem; font-weight: 600; color: var(--ink-medio); }

.campo input[type="text"],
.campo input[type="email"],
.campo input[type="password"],
.campo input[type="date"],
.campo input[type="month"],
.campo input[type="number"],
.campo input[type="search"],
.campo input[type="tel"],
.campo select,
.campo textarea {
  padding: .55rem .7rem;
  border: 1px solid var(--line-forte);
  border-radius: var(--raio);
  background: var(--surface);
  color: var(--ink);
  font-family: inherit;
  font-size: 1rem;
  width: 100%;
}

.campo__dica { font-size: .8125rem; color: var(--ink-fraco); }
.campo__erro { font-size: .8125rem; color: var(--saida); font-weight: 500; }

.form__acoes { display: flex; gap: .6rem; align-items: center; flex-wrap: wrap; }

.form__erros {
  border: 1px solid var(--saida);
  background: var(--saida-fundo);
  color: var(--saida);
  border-radius: var(--raio);
  padding: .85rem 1rem;
}
.form__erros h2 { font-size: .95rem; margin-bottom: .35rem; }
.form__erros ul { margin: 0; padding-left: 1.1rem; }

/* ---------- Avisos ---------- */

.flash-stack { display: flex; flex-direction: column; gap: .6rem; margin-bottom: 1.5rem; }

.flash {
  display: flex;
  align-items: flex-start;
  gap: .75rem;
  padding: .7rem 1rem;
  border-radius: var(--raio);
  border: 1px solid;
  font-size: .95rem;
}

.flash__texto { flex: 1; }

/* Herda a cor do aviso: o ✕ de um erro é vermelho, o de uma confirmação é
   verde. Um cinza fixo brigaria com os dois. */
.flash__fechar {
  flex-shrink: 0;
  display: inline-flex;
  padding: .15rem;
  border: 0;
  border-radius: var(--raio);
  color: inherit;
  background: transparent;
  cursor: pointer;
  opacity: .7;
}
.flash__fechar:hover { opacity: 1; background: rgb(0 0 0 / 6%); }
.flash--ok     { background: var(--entrada-fundo); border-color: var(--entrada); color: var(--entrada); }
.flash--alerta { background: var(--aviso-fundo);   border-color: var(--aviso);   color: var(--aviso); }

/* ---------- Tabelas de dados ---------- */

.tabela-rolagem { overflow-x: auto; border-radius: var(--raio-caixa); border: 1px solid var(--line); }

.tabela {
  width: 100%;
  border-collapse: collapse;
  background: var(--surface);
  font-size: .95rem;
}

.tabela th, .tabela td { padding: .8rem 1rem; text-align: left; border-bottom: 1px solid var(--line); }

.tabela th {
  font-size: .75rem;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--ink-fraco);
  font-weight: 600;
  background: var(--surface-alt);
  white-space: nowrap;
}

.tabela tbody tr:last-child td { border-bottom: 0; }
.tabela tbody tr:hover { background: var(--surface-alt); }

.tabela .numero { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* ---------- Etiquetas de estado ---------- */

.etiqueta {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  padding: .15rem .5rem;
  border-radius: 999px;
  font-size: .75rem;
  font-weight: 600;
  border: 1px solid;
  white-space: nowrap;
}

.etiqueta--neutra   { background: var(--surface-alt);   border-color: var(--line-forte); color: var(--ink-medio); }
.etiqueta--acento   { background: var(--acento-fraco);  border-color: var(--acento);     color: var(--acento); }
.etiqueta--entrada  { background: var(--entrada-fundo); border-color: var(--entrada);    color: var(--entrada); }
.etiqueta--saida    { background: var(--saida-fundo);   border-color: var(--saida);      color: var(--saida); }
.etiqueta--aviso    { background: var(--aviso-fundo);   border-color: var(--aviso);      color: var(--aviso); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
  }
}

/* ---------- Indicadores e listas de dados ---------- */

.indicadores {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
  gap: 1rem;
  margin-bottom: 2.25rem;
}

/* O indicador é uma grade de uma coluna com uma segunda reservada à marca — o
   ícone no canto. Todo filho cai na primeira coluna de propósito: as telas que
   não têm marca (totais de lançamentos, fecho de caixa) continuam empilhando
   rótulo, valor e dica sem saber que a segunda coluna existe. */
.indicador {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-content: start;
  gap: .3rem 1rem;
  padding: 1.15rem 1.3rem 1.25rem;
  overflow: hidden;
}

.indicador > * { grid-column: 1; }

/* Um véu da cor do indicador saindo do canto da marca. É o que diferencia
   "entrou" de "saiu" antes de ler o número — e some sozinho nas telas sem
   modificador, onde `--fundo-indicador` não existe. */
.indicador {
  background-image:
    radial-gradient(115% 130% at 100% 0, var(--fundo-indicador, transparent) 0%, transparent 62%);
}

.indicador--entrada { --cor-indicador: var(--entrada); --fundo-indicador: var(--entrada-fundo); }
.indicador--saida   { --cor-indicador: var(--saida);   --fundo-indicador: var(--saida-fundo); }
.indicador--acento  { --cor-indicador: var(--acento);  --fundo-indicador: var(--acento-fraco); }
.indicador--aviso   { --cor-indicador: var(--aviso);   --fundo-indicador: var(--aviso-fundo); }

.indicador__rotulo {
  align-self: center;
  font-size: .75rem;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--ink-fraco);
  font-weight: 600;
}

/* O valor ocupa a linha inteira, por baixo da marca. Dividir a linha com ela
   tirava uns quarenta pixels de largura, e "R$ 14.000,00" quebrava em duas
   linhas no cartão de sempre — quatro deles lado a lado numa tela de 1400px. */
.indicador__valor {
  grid-column: 1 / -1;
  font-family: var(--fonte-titulo);
  font-size: 1.85rem;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.02em;
  line-height: 1.1;
}

.indicador__marca {
  grid-column: 2;
  grid-row: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.15rem;
  height: 2.15rem;
  border-radius: 11px;
  background: var(--fundo-indicador, var(--surface-alt));
  color: var(--cor-indicador, var(--ink-medio));
}

/* O que vem depois do número: a variação contra o período anterior, o link
   para as contas. Linha de apoio, nunca outro número grande. */
.indicador__rodape {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: .1rem .5rem;
  margin-top: .2rem;
  font-size: .8rem;
  color: var(--ink-fraco);
}

.indicador__rodape a { color: var(--ink-medio); }

.secao__titulo {
  font-size: 1.1rem;
  letter-spacing: -.01em;
  margin: 2.25rem 0 .9rem;
}
.secao__titulo--primeiro { margin-top: 0; }

.lista-dados {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
  gap: 1.1rem;
  margin: 0;
}
.lista-dados dt {
  font-size: .75rem;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--ink-fraco);
  font-weight: 600;
}
.lista-dados dd { margin: .2rem 0 0; font-variant-numeric: tabular-nums; }

.acoes-admin { display: flex; flex-wrap: wrap; gap: .6rem; }
.acoes-admin form { margin: 0; }

.busca { display: flex; gap: .5rem; flex-wrap: wrap; }
.busca input[type="search"] {
  padding: .45rem .7rem;
  border: 1px solid var(--line-forte);
  border-radius: var(--raio);
  background: var(--surface);
  color: var(--ink);
  font-family: inherit;
  font-size: 1rem;
  flex: 1 1 15rem;
  min-width: 0;
}

.texto-apoio { color: var(--ink-medio); font-size: .95rem; max-width: 46rem; }

/* Em linha, o texto de apoio vem sempre depois de outra coisa — o nome da
   categoria depois do lançamento, o valor depois da ligação. O ERB come a
   quebra de linha entre os dois e as palavras saem coladas. */
span.texto-apoio { margin-left: .35rem; }

.cartao--atencao { border-left: 3px solid var(--aviso); margin-top: 1.5rem; }

/* .cartao + .cartao { margin-top: 1.25rem; } */

/* ---------- Telas de conta ---------- */

/* ---------- Telas de entrada ----------
   Todas as seis telas do Devise usam este cartão: entrar, criar conta,
   recuperar e definir senha, reenviar confirmação e desbloqueio. O tratamento
   é do contêiner, e não de cada view, para que continuem parecendo a mesma
   porta. */

.autenticacao {
  position: relative;
  max-width: 27rem;
  margin-inline: auto;
  margin-block: 2.5rem 3.5rem;
  padding: 2.25rem 2.25rem 1.75rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: calc(var(--raio-caixa) + 4px);
  box-shadow: var(--sombra-alta);
  display: flex;
  flex-direction: column;
  gap: 1.35rem;
}

/* O brilho de fundo pertence ao próprio cartão, e não ao <body>: o layout é o
   mesmo de todas as páginas, e marcar o corpo pediria uma classe que só estas
   seis telas usariam. */
.autenticacao::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(58rem 30rem at 50% -14%, var(--acento-fraco), transparent 68%);
}

.autenticacao__cabecalho { display: flex; flex-direction: column; gap: .3rem; }

.autenticacao__titulo {
  margin: 0;
  font-size: 1.75rem;
  font-family: var(--fonte-titulo);
  font-weight: 700;
  letter-spacing: -.025em;
}

.autenticacao__subtitulo { margin: 0; color: var(--ink-medio); font-size: .9375rem; }

/* Dentro do cartão o formulário ocupa a largura toda: o teto de 26rem existe
   para o formulário solto no meio de uma página larga. */
.autenticacao .form { max-width: none; gap: 1.1rem; }

/* Um caminho adiante por tela: o botão ocupa a linha inteira, como o "Entrar".
   Numa tela de entrada não há ação secundária a disputar espaço com ele. */
.autenticacao .form__acoes { display: flex; }
.autenticacao .form__acoes .botao { flex: 1; padding-block: .65rem; }

.autenticacao__chamada {
  margin: 0;
  padding-top: 1.1rem;
  border-top: 1px solid var(--line);
  font-size: .9375rem;
  color: var(--ink-medio);
  text-align: center;
}

.autenticacao__links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: .3rem 1rem;
  font-size: .8125rem;
}

/* Nas outras telas o `_links` do Devise é o único rodapé e vem logo depois do
   formulário: só lá ele precisa da própria linha de separação. Depois da
   chamada de criar conta, que já traz a sua, uma segunda linha seria ruído. */
.form + .autenticacao__links {
  padding-top: 1.1rem;
  border-top: 1px solid var(--line);
  font-size: .9rem;
}

/* Rótulo à esquerda, atalho à direita: "esqueci minha senha" é lido no momento
   em que a senha é digitada, não no fim da página. */
.campo__topo { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; }
.campo__atalho { font-size: .8125rem; }

.campo-senha { position: relative; display: flex; }
.campo-senha input { flex: 1; padding-right: 2.9rem; }

.campo-senha__olho {
  position: absolute;
  inset-block: 1px;
  right: 1px;
  width: 2.75rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 0 var(--raio) var(--raio) 0;
  background: transparent;
  color: var(--ink-fraco);
  cursor: pointer;
}

.campo-senha__olho:hover { color: var(--ink); }

/* Um olho por vez, escolhido pelo mesmo atributo que o leitor de tela lê. */
.campo-senha__icone--ocultar { display: none; }
.campo-senha__olho[aria-pressed="true"] .campo-senha__icone--ver { display: none; }
.campo-senha__olho[aria-pressed="true"] .campo-senha__icone--ocultar { display: block; }

.botao--bloco { width: 100%; padding-block: .65rem; }

@media (max-width: 30rem) {
  .autenticacao { padding: 1.75rem 1.35rem 1.5rem; margin-block: 1.5rem 2.5rem; }
}

.campo-inline { display: flex; align-items: center; gap: .5rem; }
.rotulo-inline { font-weight: 400; color: var(--ink-medio); font-size: .925rem; }

/* O que mudou em cada evento da auditoria: uma linha por campo, com o valor de
   antes apagado e o de agora em destaque — a leitura é sempre da esquerda para
   a direita, e é o lado direito que vale hoje. */
.alteracoes { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .2rem; }
.alteracoes__item { font-size: .85rem; line-height: 1.4; }
.alteracoes__campo { color: var(--ink-fraco); }
.alteracoes__campo::after { content: ":"; }
.alteracoes__antes { text-decoration: line-through; color: var(--ink-fraco); }
.alteracoes__seta { color: var(--ink-fraco); }
.alteracoes__depois { font-weight: 600; }

/* ---------- Perfis ---------- */

.cartoes {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr));
  gap: 1rem;
}

.cartao-perfil {
  display: flex;
  flex-direction: column;
  gap: .6rem;
  border-top: 3px solid var(--cor, var(--acento));
}

.cartao-perfil__topo {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: .75rem;
}

.cartao-perfil__nome { font-size: 1.1rem; }
.cartao-perfil__nome a { color: var(--ink); text-decoration: none; }
.cartao-perfil__nome a:hover { color: var(--acento); }

.cartao-perfil__doc {
  margin: 0;
  font-variant-numeric: tabular-nums;
  color: var(--ink-fraco);
  font-size: .9rem;
}

.cartao-perfil__desc { margin: 0; color: var(--ink-medio); font-size: .925rem; }
.cartao-perfil__acoes { margin-top: auto; padding-top: .5rem; }
.cartao-perfil__acoes form { margin: 0; }

.ponto-cor {
  display: inline-block;
  width: .6em;
  height: .6em;
  border-radius: 3px;
  background: var(--cor, var(--acento));
  vertical-align: baseline;
  margin-right: .1em;
}

/* ---------- Escolha de tipo e de cor ---------- */

.campo--opcoes { border: 0; padding: 0; margin: 0; }
.campo--opcoes legend { font-size: .875rem; font-weight: 600; color: var(--ink-medio); padding: 0; }

.opcao {
  display: flex;
  align-items: flex-start;
  gap: .55rem;
  padding: .6rem .75rem;
  border: 1px solid var(--line-forte);
  border-radius: var(--raio);
  cursor: pointer;
  background: var(--surface);
}
.opcao + .opcao { margin-top: .5rem; }
.opcao:has(input:checked) { border-color: var(--acento); background: var(--acento-fraco); }
.opcao > span { display: flex; flex-direction: column; }
.opcao__dica { font-size: .8125rem; color: var(--ink-fraco); }

.paleta { display: flex; flex-wrap: wrap; gap: .5rem; }

.paleta__opcao { cursor: pointer; line-height: 0; }
.paleta__opcao input { position: absolute; opacity: 0; pointer-events: none; }

.paleta__amostra {
  display: block;
  width: 2rem;
  height: 2rem;
  border-radius: var(--raio);
  background: var(--cor);
  box-shadow: inset 0 0 0 1px var(--contorno-amostra);
}

.paleta__opcao input:checked + .paleta__amostra {
  box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--cor);
}
.paleta__opcao input:focus-visible + .paleta__amostra {
  outline: 2px solid var(--foco);
  outline-offset: 3px;
}

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

/* ---------- Atalhos de relatório salvos ---------- */

/* Coluna mais larga que a dos cartões fixos: aqui o nome é escrito por uma
   pessoa, e "Fechamento do trimestre passado" não cabe em 14rem. */
.atalhos-salvos {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 18rem), 1fr));
  gap: 1rem;
  margin-bottom: 1.5rem;
}

.atalho-salvo { display: flex; flex-direction: column; gap: .6rem; }
.atalho-salvo:hover { border-color: var(--acento); }

.atalho-salvo__alvo {
  display: flex;
  flex-direction: column;
  gap: .35rem;
  color: inherit;
  text-decoration: none;
}

/* O nome que a pessoa deu é o protagonista do cartão. O `.atalho__titulo` dos
   cartões fixos é um rótulo miúdo em caixa alta — desenho para o cartão em que
   o número é o que se lê, e que apagava o nome aqui. */
.atalho-salvo__nome {
  margin: 0;
  font-family: var(--fonte-titulo);
  font-size: 1.0625rem;
  line-height: 1.25;
  font-weight: 700;
  color: var(--ink);
  overflow-wrap: anywhere;
}

.atalho-salvo__meta {
  margin: 0;
  font-size: .8125rem;
  color: var(--ink-fraco);
}

.atalho-salvo__recorte {
  display: flex;
  flex-wrap: wrap;
  gap: .3rem;
  margin: .15rem 0 0;
}

/* As ações vivem no rodapé do cartão, e não num menu sobreposto: a gaveta
   flutuante cobria o próprio nome do atalho que ela vinha ajustar. */
/* `flex-start` e não `center`: com "Renomear" aberto, o rodapé cresce e o
   "Apagar" centralizado ia parar no meio da altura nova, longe do irmão com
   quem ele forma um par. */
.atalho-salvo__acoes {
  display: flex;
  align-items: flex-start;
  gap: .5rem;
  margin-top: auto;
  padding-top: .6rem;
  border-top: 1px solid var(--line);
}

.atalho-salvo__apagar { margin: 0; margin-left: auto; }

/* Apagar é a única ação sem volta do cartão, e a cor diz isso antes da
   confirmação. Discreta em repouso: ela avisa, não ameaça. */
.link-acao--perigo:hover { color: var(--saida); background: var(--saida-fundo); }

/* Renomear abre para baixo, empurrando o cartão em vez de cobri-lo. */
.renomear > summary {
  cursor: pointer;
  list-style: none;
  display: inline-block;
}
.renomear > summary::-webkit-details-marker { display: none; }
.renomear > summary::marker { content: ""; }

.renomear__form {
  display: flex;
  gap: .4rem;
  margin-top: .5rem;
}
.renomear__form input[type="text"] { min-width: 0; flex: 1; }

/* ---------- Salvar o recorte como atalho ---------- */

.salvar-atalho {
  margin-top: 1.75rem;
  padding-top: 1rem;
  border-top: 1px solid var(--line);
}

.salvar-atalho > summary {
  cursor: pointer;
  width: fit-content;
  font-size: .875rem;
  font-weight: 600;
  color: var(--acento);
}
.salvar-atalho > summary:hover { color: var(--acento-forte); }

.salvar-atalho > p { margin: .6rem 0 1rem; }

/* Grid e não `.form-linha`: naquela, a nota do período crescia dentro da coluna
   dele, esticava a caixa e deixava os dois rótulos em alturas diferentes. Aqui
   os campos dividem a linha em proporção fixa, o botão fecha a linha e a nota
   ocupa a largura inteira embaixo — onde texto longo não empurra nada. */
.salvar-atalho__form {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) auto;
  align-items: end;
  gap: .75rem 1rem;
}

.salvar-atalho__form .campo { min-width: 0; }

.salvar-atalho__nota {
  grid-column: 1 / -1;
  margin: 0;
  font-size: .8125rem;
  color: var(--ink-fraco);
}

/* No estreito cada campo ocupa a linha inteira, e o botão vira largura total:
   três colunas em 22rem de tela viram três colunas ilegíveis. */
@media (max-width: 46rem) {
  .salvar-atalho__form { grid-template-columns: 1fr; }
  .salvar-atalho__form .botao { width: 100%; }
}

/* ---------- Atalhos de filtro da lista ---------- */

.atalhos-de-filtro {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  margin-bottom: 1rem;
}

.atalho-de-filtro {
  padding: .4rem .85rem;
  border: 1px solid var(--line-forte);
  border-radius: 999px;
  font-size: .875rem;
  font-weight: 500;
  color: var(--ink-medio);
  text-decoration: none;
  background: var(--surface);
}
.atalho-de-filtro:hover { background: var(--surface-alt); color: var(--ink); }

/* O atalho aceso é o que descreve a lista que está na tela. */
.atalho-de-filtro[aria-current="true"] {
  border-color: var(--acento);
  color: var(--surface);
  background: var(--acento);
}

/* A grade inteira de filtros, guardada atrás de uma linha. */
.filtros__caixa { margin-bottom: 1.5rem; }

.filtros__caixa > summary {
  cursor: pointer;
  width: fit-content;
  margin-bottom: .85rem;
  font-size: .875rem;
  font-weight: 600;
  color: var(--acento);
}
.filtros__caixa > summary:hover { color: var(--acento-forte); }

/* ---------- Gaveta de campos opcionais no formulário ---------- */

/* Irmã de `.filtros__mais`, para o formulário: o que quase sempre fica vazio
   sai da frente sem sair da tela. */
.campo__gaveta {
  border-top: 1px solid var(--line);
  padding-top: .85rem;
}

.campo__gaveta > summary {
  cursor: pointer;
  width: fit-content;
  margin-bottom: .85rem;
  font-size: .875rem;
  font-weight: 600;
  color: var(--acento);
}
.campo__gaveta > summary:hover { color: var(--acento-forte); }

/* ---------- Erro no próprio campo ---------- */

/* O Rails exige que a marca de erro *envolva* o campo. `display: contents` faz
   o embrulho sumir da caixa de layout: o `input` continua sendo filho direto
   de `.campo` para todo efeito de espaçamento e largura. */
.campo__invalido { display: contents; }

.campo__invalido input,
.campo__invalido select,
.campo__invalido textarea {
  border-color: var(--saida);
  background: var(--saida-fundo);
}

.campo__invalido input:focus,
.campo__invalido select:focus,
.campo__invalido textarea:focus { outline-color: var(--saida); }

/* A frase fica logo abaixo do campo. Com `display: contents` no embrulho, ela é
   filha do mesmo flex de `.campo` e cai naturalmente entre o campo e a dica —
   que é a ordem em que as duas precisam ser lidas. */
.campo__erro {
  font-size: .82rem;
  font-weight: 500;
  color: var(--saida);
}

/* ---------- Seletor de perfil na barra ---------- */

.seletor-perfil { display: flex; align-items: center; gap: .4rem; }

.seletor-perfil__atual {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  padding: .35rem .65rem;
  border: 1px solid var(--line-forte);
  border-radius: var(--raio);
  font-size: .9rem;
  font-weight: 500;
  color: var(--ink);
  text-decoration: none;
  background: var(--surface);
}
.seletor-perfil__atual:hover { background: var(--surface-alt); color: var(--ink); }

/* Com dois ou mais perfis o seletor é um `<details>`: o `summary` vira o botão
   e a gaveta cai por baixo dele. O triângulo padrão do navegador sai de cena —
   a seta desenhada ao lado do nome diz a mesma coisa e segue a cor do tema. */
details.seletor-perfil { display: block; position: relative; }

.seletor-perfil > summary { cursor: pointer; list-style: none; }
.seletor-perfil > summary::-webkit-details-marker { display: none; }
.seletor-perfil > summary::marker { content: ""; }

.seletor-perfil__nome {
  max-width: 12rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.seletor-perfil__seta { color: var(--ink-fraco); transition: transform .15s ease; }
.seletor-perfil[open] .seletor-perfil__seta { transform: rotate(180deg); }

/* `position: absolute` tira a gaveta do fluxo — e com ela sai também do
   esconderijo do `<details>` fechado: o navegador continuava desenhando a
   lista inteira por cima da tela, aberta ou não. Fechar é dito aqui, à mão. */
.seletor-perfil:not([open]) .seletor-perfil__gaveta { display: none; }

.seletor-perfil__gaveta {
  position: absolute;
  z-index: 30;
  top: calc(100% + .35rem);
  left: 0;
  min-width: 15rem;
  max-width: min(20rem, calc(100vw - 2rem));
  padding: .35rem;
  border: 1px solid var(--line);
  border-radius: var(--raio-caixa);
  background: var(--surface);
  box-shadow: var(--sombra-alta);
}

.seletor-perfil__rotulo {
  margin: 0;
  padding: .4rem .6rem .3rem;
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--ink-fraco);
}

/* O `button_to` embrulha cada troca num `<form>`. Ele não é a linha do menu —
   a linha é o botão dentro dele —, e por isso não ganha espaçamento nenhum. */
.seletor-perfil__forma { margin: 0; display: block; }

.seletor-perfil__item {
  display: flex;
  align-items: center;
  gap: .5rem;
  width: 100%;
  padding: .5rem .6rem;
  border: 0;
  border-radius: var(--raio);
  font: inherit;
  font-size: .9rem;
  text-align: left;
  color: var(--ink);
  text-decoration: none;
  background: transparent;
  cursor: pointer;
}

.seletor-perfil__item:hover,
.seletor-perfil__item:focus-visible { background: var(--surface-alt); color: var(--ink); }

/* O perfil aberto não é um botão: clicar nele não levaria a lugar nenhum. É
   texto, com o ✓ dizendo por que ele não responde ao toque. */
.seletor-perfil__item--atual { cursor: default; font-weight: 600; }
.seletor-perfil__item--atual:hover { background: transparent; }

.seletor-perfil__item-nome {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.seletor-perfil__dono, .seletor-perfil__marca { font-size: .78rem; color: var(--ink-fraco); }

.seletor-perfil__rodape {
  display: block;
  margin-top: .3rem;
  padding: .5rem .6rem;
  border-top: 1px solid var(--line);
  font-size: .82rem;
  color: var(--ink-fraco);
  text-decoration: none;
}
.seletor-perfil__rodape:hover { color: var(--ink); }

/* ---------- Árvore de categorias ---------- */

.colunas-tipos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
  gap: 1.75rem;
  align-items: start;
}

.coluna-tipo__cabecalho {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
  margin-bottom: .75rem;
}

.coluna-tipo__titulo { font-size: 1rem; margin: 0; }

.arvore { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .5rem; }

.arvore__item {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--raio-caixa);
  padding: .7rem .85rem;
}
.arvore__item--arrastando { opacity: .4; }

.arvore__raiz { display: flex; align-items: center; gap: .55rem; flex-wrap: wrap; }

.arvore__nome { color: var(--ink); text-decoration: none; font-weight: 500; }
.arvore__nome:hover { color: var(--acento); text-decoration: underline; }

.arvore__acoes {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: .1rem;
  flex-wrap: wrap;
  opacity: .55;
}
.arvore__item:hover .arvore__acoes,
.arvore__item:focus-within .arvore__acoes { opacity: 1; }
.arvore__acoes form { margin: 0; }

.arvore__filhas {
  list-style: none;
  margin: .55rem 0 0;
  padding: .5rem 0 0 1.7rem;
  border-top: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: .3rem;
}

.arvore__filha { display: flex; align-items: center; gap: .5rem; font-size: .925rem; }

.categoria__marca {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.85rem;
  height: 1.85rem;
  border-radius: var(--raio);
  color: var(--cor, var(--acento));
  background: color-mix(in srgb, var(--cor, var(--acento)) 14%, transparent);
  flex: none;
}

.link-acao {
  font-size: .8125rem;
  color: var(--ink-fraco);
  text-decoration: none;
  padding: .15rem .35rem;
  border-radius: 4px;
}
.link-acao:hover { color: var(--acento); background: var(--surface-alt); }

.link-acao--botao { background: none; border: 0; font-family: inherit; cursor: pointer; }

.lista-simples {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: .5rem;
}
.lista-simples li {
  display: flex;
  align-items: center;
  gap: .55rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--raio);
  padding: .55rem .75rem;
}
.lista-simples form { margin: 0 0 0 auto; }

/* ---------- Grade de ícones ---------- */

.icones__busca {
  padding: .5rem .7rem;
  border: 1px solid var(--line-forte);
  border-radius: var(--raio);
  background: var(--surface);
  color: var(--ink);
  font-family: inherit;
  width: 100%;
  margin-bottom: .6rem;
}

.icones {
  max-height: 20rem;
  overflow-y: auto;
  border: 1px solid var(--line);
  border-radius: var(--raio);
  padding: .75rem;
  background: var(--surface);
}

.icones__grupo + .icones__grupo { margin-top: .9rem; }

.icones__rotulo {
  font-size: .7rem;
  text-transform: uppercase;
  letter-spacing: .07em;
  color: var(--ink-fraco);
  margin: 0 0 .4rem;
}

.icones__grade { display: flex; flex-wrap: wrap; gap: .35rem; }

.icones__opcao { cursor: pointer; }
.icones__opcao input { position: absolute; opacity: 0; pointer-events: none; }

.icones__amostra {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.4rem;
  height: 2.4rem;
  border: 1px solid var(--line);
  border-radius: var(--raio);
  color: var(--ink-medio);
}
.icones__opcao:hover .icones__amostra { border-color: var(--line-forte); color: var(--ink); }

.icones__opcao input:checked + .icones__amostra {
  border-color: var(--acento);
  background: var(--acento-fraco);
  color: var(--acento);
}
.icones__opcao input:focus-visible + .icones__amostra { outline: 2px solid var(--foco); outline-offset: 2px; }

.icones__vazio { color: var(--ink-fraco); font-size: .9rem; }

.form-linha {
  display: flex;
  gap: .75rem;
  align-items: flex-end;
  flex-wrap: wrap;
  margin-top: 1rem;
}
.form-linha .campo { flex: 1 1 12rem; }

.botao--mini { padding: .25rem .6rem; font-size: .8125rem; }
.acoes-admin--centro { justify-content: center; }

/* ---------- Atalhos do perfil ---------- */

.atalhos {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 14rem), 1fr));
  gap: 1rem;
  margin-bottom: 1.5rem;
}

.atalho {
  display: flex;
  flex-direction: column;
  gap: .2rem;
  text-decoration: none;
  color: var(--ink);
}
.atalho:hover { border-color: var(--acento); color: var(--ink); }

.atalho__titulo {
  font-size: .75rem;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--ink-fraco);
  font-weight: 600;
}
.atalho__valor {
  font-family: var(--fonte-titulo);
  font-size: 1.8rem;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
.atalho__dica { font-size: .8125rem; color: var(--ink-fraco); }

/* ---------- Lançamentos ---------- */

.valor { font-variant-numeric: tabular-nums; font-weight: 600; }
.valor--income, .indicador__valor.valor--income { color: var(--entrada); }
.valor--expense, .indicador__valor.valor--expense { color: var(--saida); }
.tabela td.valor--income { color: var(--entrada); font-weight: 600; }
.tabela td.valor--expense { color: var(--saida); font-weight: 600; }

.indicadores--totais { margin-bottom: 1.5rem; }

.linha--cancelada td { opacity: .5; text-decoration: line-through; }
.linha--cancelada td:last-child { text-decoration: none; }

.filtros {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 9.5rem), 1fr));
  gap: .85rem;
  align-items: end;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--raio-caixa);
  padding: 1rem;
  margin-bottom: 1.5rem;
}
.filtros .campo--largo { grid-column: span 2; }
.filtros__acoes { display: flex; align-items: center; gap: .75rem; }

/* A gaveta dos filtros que não se usa todo dia. Ocupa a faixa inteira porque é
   uma seção, não mais um campo ao lado dos outros. */
.filtros__mais {
  grid-column: 1 / -1;
  border-top: 1px solid var(--line);
  padding-top: .85rem;
}

.filtros__mais > summary {
  cursor: pointer;
  font-size: .875rem;
  font-weight: 600;
  color: var(--acento);
  width: fit-content;
}
.filtros__mais > summary:hover { color: var(--acento-forte); }

.filtros__gaveta {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 9.5rem), 1fr));
  gap: .85rem;
  align-items: end;
  margin-top: .85rem;
}

.campo-duplo {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
  gap: 1.15rem;
}

.lote {
  display: flex;
  align-items: center;
  gap: .6rem;
  flex-wrap: wrap;
  background: var(--acento-fraco);
  border: 1px solid var(--acento);
  border-radius: var(--raio-caixa);
  padding: .7rem .9rem;
  margin-bottom: .75rem;
}

.lote__contagem { font-weight: 600; font-size: .9rem; color: var(--acento); }

.lote__campo {
  padding: .35rem .55rem;
  border: 1px solid var(--line-forte);
  border-radius: var(--raio);
  background: var(--surface);
  color: var(--ink);
  font-family: inherit;
  font-size: .875rem;
}

.coluna-selecao { width: 2.5rem; }

/* --- O envio do arquivo OFX ------------------------------------------------
   A área que recebe o arquivo arrastado. É moldura, e não botão: o controle de
   verdade continua sendo o `input` que mora dentro dela, para que a tela siga
   funcionando de teclado e sem JavaScript. */

.soltura {
  display: flex;
  flex-direction: column;
  gap: .6rem;
  align-items: flex-start;
  padding: 1.1rem;
  border: 2px dashed var(--line-forte);
  border-radius: var(--raio-caixa);
  background: var(--surface-alt);
  transition: border-color .12s ease, background .12s ease;
}

/* O arquivo está por cima da área, ainda não solto. */
.soltura--ativa {
  border-color: var(--acento);
  background: var(--acento-fraco);
}

.soltura--recusada { border-color: var(--saida); background: var(--saida-fundo); }

/* Enquanto o arquivo sobe, a moldura para de convidar a soltar: tracejado é o
   desenho de "solte aqui", e o gesto já foi feito. */
.soltura--enviando { border-style: solid; border-color: var(--acento); }

.soltura__dica { margin: 0; font-size: .875rem; color: var(--ink-fraco); }

/* O nome do arquivo escolhido, para conferir antes de enviar que é mesmo o
   extrato certo — o campo de arquivo sozinho corta o nome no meio. */
.soltura__escolhido {
  margin: 0;
  font-weight: 600;
  color: var(--acento);
  word-break: break-all;
}

/* --- Conferência do extrato antes de importar ------------------------------
   A revisão é uma tabela longa que se lê de cima para baixo e uma barra de
   resumo que precisa acompanhar a rolagem: sem ela, decidir a linha duzentos
   significaria voltar ao topo para ver quanto já está marcado. */

.revisao__barra {
  position: sticky;
  top: 0;
  z-index: 3;
  justify-content: space-between;
}

.revisao__soma {
  font-size: .875rem;
  color: var(--ink-medio);
  font-variant-numeric: tabular-nums;
}

/* A barra de filtros da conferência. Nasce escondida no HTML e o Stimulus a
   revela: sem JavaScript, filtrar seria um controle que não faz nada. */
.revisao__filtros {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 1rem;
  padding: .8rem .9rem;
  margin-bottom: .75rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--raio-caixa);
}

.revisao__busca { flex: 1 1 16rem; min-width: 0; }
.revisao__busca input[type="search"] {
  padding: .45rem .7rem;
  border: 1px solid var(--line-forte);
  border-radius: var(--raio);
  background: var(--surface);
  color: var(--ink);
  font-family: inherit;
  font-size: .95rem;
  width: 100%;
}

.revisao__grupo-filtro {
  display: flex;
  flex-wrap: wrap;
  gap: .35rem;
  border: 0;
  padding: 0;
  margin: 0;
}

.revisao__legenda-filtro {
  width: 100%;
  padding: 0;
  margin-bottom: .3rem;
  font-size: .75rem;
  text-transform: uppercase;
  letter-spacing: .06em;
  font-weight: 600;
  color: var(--ink-fraco);
}

/* O rádio continua sendo o controle — é ele que o teclado e o leitor de tela
   alcançam, e é dele o estado. O que se vê é o rótulo. */
.filtro-chip { cursor: pointer; }

/* Escondido do olho, presente para o resto: continua sendo um rádio de
   verdade, que o teclado alcança e o leitor de tela anuncia. `opacity: 0` com
   tamanho zero o tiraria da árvore de acessibilidade e do alcance do ponteiro. */
.filtro-chip input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.filtro-chip span {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  padding: .3rem .7rem;
  border: 1px solid var(--line-forte);
  border-radius: 999px;
  font-size: .85rem;
  color: var(--ink-medio);
  white-space: nowrap;
}

.filtro-chip:hover span { background: var(--surface-alt); }

.filtro-chip input:checked + span {
  background: var(--acento);
  border-color: var(--acento);
  color: var(--surface);
  font-weight: 600;
}

/* O foco do teclado precisa aparecer no rótulo: o rádio que o recebe é
   invisível. */
.filtro-chip input:focus-visible + span { outline: 2px solid var(--acento); outline-offset: 2px; }

.filtro-chip__conta { font-variant-numeric: tabular-nums; opacity: .75; }

.filtro-chip input:checked + span .filtro-chip__conta { opacity: .9; }

/* Escondida pelo filtro — e não removida: o formulário continua enviando o que
   está marcado, e marcar é decisão, enquanto o filtro é só uma lente.

   Qualificada por `.tabela` de propósito. Em tela estreita a tabela vira fichas
   com `.tabela tr { display: block }`, que tem especificidade maior que uma
   classe sozinha — e o filtro deixava de esconder qualquer coisa no celular,
   em silêncio, com o contador dizendo que só dezesseis linhas estavam à vista. */
.tabela .linha--filtrada { display: none; }

.revisao__sem-resultado { margin-top: .75rem; }

/* A barra de decisão em lote, embaixo da de resumo. */
.revisao__lote { margin-top: -.25rem; }

/* "Isto vai ser importado e você não está vendo." O tom de aviso é de
   propósito: é a diferença entre importar dezesseis linhas e sessenta e quatro. */
.revisao__escondidas {
  font-size: .875rem;
  font-weight: 600;
  color: var(--aviso);
  font-variant-numeric: tabular-nums;
}

.revisao__resumo {
  font-size: .875rem;
  font-weight: 600;
  color: var(--acento);
}

.revisao__coluna-historico { min-width: 22rem; }
.revisao__coluna-decisao { min-width: 18rem; }

.revisao__decisao { width: 100%; max-width: 26rem; }

/* O seletor que virou campo de busca. */
.combo { max-width: 26rem; }

/* Dentro de um campo de formulário o combo é o campo, e ocupa a coluna inteira
   como o `select` que ele substitui — o teto de 26rem é da tabela da revisão do
   extrato, onde a coluna é larga e o seletor não precisa acompanhar. */
.campo > .combo { max-width: none; }

/* Nas linhas de controles — a barra de lote, o teto do orçamento — quem dava a
   largura era o `select`, pelo nome mais comprido da lista. Escondido, ele não
   dá mais: sem um piso sobraria a caixa de texto no tamanho de fábrica, estreita
   demais para caber "Educação › Escola do filho". */
.lote .combo,
.form-linha--compacta .combo { min-width: 14rem; }

.combo__campo { width: 100%; }
.combo__campo::placeholder { color: var(--ink-fraco); }

/* A lista flutua por cima, sem alargar a linha da tabela ao abrir. `fixed` e
   não `absolute`: a tabela rola dentro de `.tabela-rolagem`, e o que é
   posicionado em relação a ela é recortado pela borda da caixa. Quem coloca no
   lugar é o `combo_controller`, que sabe onde o campo está na tela. */
.combo__lista {
  position: fixed;
  z-index: 25;
  list-style: none;
  margin: 0;
  padding: .25rem;
  max-height: 15rem;
  overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--line-forte);
  border-radius: var(--raio);
  box-shadow: var(--sombra-alta);
}

.combo__grupo {
  padding: .4rem .5rem .2rem;
  font-size: .7rem;
  text-transform: uppercase;
  letter-spacing: .06em;
  font-weight: 600;
  color: var(--ink-fraco);
}

.combo__item {
  padding: .35rem .5rem;
  border-radius: var(--raio);
  font-size: .85rem;
  cursor: pointer;
}
.combo__item:hover,
.combo__item--marcada { background: var(--acento-fraco); }
.combo__item[aria-selected="true"] { font-weight: 600; color: var(--acento); }

.combo__vazio { padding: .4rem .5rem; font-size: .85rem; color: var(--ink-fraco); }

/* O histórico do banco se corrige na conferência, e é o único campo de texto
   de uma tabela que se lê de cima para baixo: parece texto até o ponteiro
   passar por cima, para não virar duzentas caixas empilhadas. */
.revisao__historico {
  width: 100%;
  /* Sem isto o campo não encolhe abaixo da largura intrínseca do `input`, e a
     ficha do celular estoura para o lado. A largura confortável de leitura vem
     da coluna, não do campo. */
  min-width: 0;
  padding: .3rem .4rem;
  border: 1px solid transparent;
  border-radius: var(--raio);
  background: transparent;
  color: inherit;
  font-family: inherit;
  font-size: inherit;
}
.revisao__historico:hover { border-color: var(--line); background: var(--surface); }
.revisao__historico:focus { border-color: var(--acento); background: var(--surface); }

/* Editado e ainda não gravado: sem a marca, não há como rever o que se mexeu
   antes de confirmar a importação inteira. */
.revisao__historico--alterado {
  border-color: var(--acento);
  background: var(--acento-fraco);
  font-weight: 600;
}

/* A busca que recorta uma lista já na tela, encostada nela e não numa barra de
   filtros: não há botão para apertar, o resultado acompanha a digitação. */
.busca--embutida { margin-bottom: .75rem; }
.busca--embutida input[type="search"] { flex: 1 1 100%; font-size: .9rem; }

/* O rótulo de uma escolha com explicação embaixo: o texto de apoio fica sob o
   título da opção, não ao lado do botão. */
.campo--escolha { border: 0; padding: 0; margin: 0; }

.campo--escolha .campo-inline { align-items: flex-start; margin-bottom: .6rem; }

.campo--escolha .rotulo-inline { display: flex; flex-direction: column; gap: .15rem; }

.campo__legenda {
  padding: 0;
  margin-bottom: .5rem;
  font-size: .875rem;
  font-weight: 600;
  color: var(--ink-medio);
}

.paginacao { margin-top: 1.5rem; }
.paginacao .pagy { display: flex; gap: .25rem; flex-wrap: wrap; }
.paginacao .pagy a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.1rem;
  padding: .3rem .55rem;
  border: 1px solid var(--line);
  border-radius: var(--raio);
  background: var(--surface);
  color: var(--ink-medio);
  text-decoration: none;
  font-size: .9rem;
  font-variant-numeric: tabular-nums;
}
.paginacao .pagy a:hover { border-color: var(--line-forte); color: var(--ink); }
.paginacao .pagy a[aria-current="page"] {
  background: var(--acento);
  border-color: var(--acento);
  color: var(--acento-texto);
  font-weight: 600;
}
.paginacao .pagy a[aria-disabled="true"] { opacity: .45; pointer-events: none; }

/* ---------- Recorrências ---------- */

.cartao-serie {
  display: flex;
  flex-direction: column;
  gap: .45rem;
  border-left: 3px solid var(--cor, var(--acento));
}

.cartao-serie__valor {
  margin: 0;
  font-family: var(--fonte-titulo);
  font-size: 1.35rem;
  font-variant-numeric: tabular-nums;
}

.cartao-serie__frequencia {
  font-family: var(--fonte-corpo);
  font-size: .85rem;
  font-weight: 400;
  color: var(--ink-fraco);
}

.cartao-serie__proxima {
  margin: auto 0 0;
  padding-top: .4rem;
  font-size: .8125rem;
  color: var(--ink-fraco);
}

.acoes-serie {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  align-items: flex-end;
}
.acoes-serie form { margin: 0; }
.acoes-serie .form-linha { margin-top: 0; }

.previa { margin-top: 1.25rem; }
.previa .tabela-rolagem { max-height: 24rem; overflow-y: auto; }

.cartao-serie__proxima--atrasada { color: var(--saida); font-weight: 500; }

/* ---------- Contas bancárias ---------- */

.cartao-conta {
  display: flex;
  flex-direction: column;
  gap: .45rem;
  border-top: 3px solid var(--cor, var(--acento));
}

.cartao-conta__banco { margin: 0; font-size: .9rem; color: var(--ink-medio); }

.cartao-conta__saldo {
  margin: .2rem 0 0;
  font-family: var(--fonte-titulo);
  font-size: 1.5rem;
  font-variant-numeric: tabular-nums;
}

.cartao-conta__perfis {
  margin: auto 0 0;
  padding-top: .5rem;
  display: flex;
  flex-wrap: wrap;
  gap: .35rem;
}

/* O cartão inteiro leva à conta. O nome sozinho não parecia clicável — e uma
   linha de texto é alvo pequeno demais no celular. */
.cartao-conta {
  position: relative;
  transition: box-shadow .15s ease, border-color .15s ease, transform .15s ease;
}

/* Só as bordas laterais e de baixo reagem: a de cima carrega a cor do banco. */
.cartao-conta:hover {
  border-inline-color: var(--line-forte);
  border-bottom-color: var(--line-forte);
  box-shadow: var(--sombra-alta);
  transform: translateY(-1px);
}
.cartao-conta:hover .cartao-perfil__nome a { color: var(--acento); }

/* Quem chega pelo teclado vê o cartão inteiro responder, não só o nome. */
.cartao-conta:focus-within {
  border-inline-color: var(--line-forte);
  border-bottom-color: var(--line-forte);
  box-shadow: var(--sombra-alta);
}

/* A âncora do nome se estica sobre o cartão: um link só, área de clique toda. */
.cartao-conta__link::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--raio-caixa);
}

.cartao-conta__abrir {
  margin: 0;
  padding-top: .6rem;
  border-top: 1px solid var(--line);
  display: flex;
  align-items: center;
  gap: .3rem;
  font-size: .875rem;
  font-weight: 600;
  color: var(--acento);
}
.cartao-conta__abrir svg { transition: transform .15s ease; }
.cartao-conta:hover .cartao-conta__abrir svg { transform: translateX(3px); }

/* Blocos empilhados sem título entre eles precisam de respiro próprio. */
.lista-simples + .vazio,
.cartoes + .vazio,
.tabela-rolagem + .vazio,
.lista-simples + .cartao,
.tabela-rolagem + .cartao { margin-top: 1.25rem; }

/* ---------- Extrato e importação ---------- */

.erro-importacao {
  background: var(--saida-fundo);
  border-left: 3px solid var(--saida);
  padding: .75rem 1rem;
  border-radius: var(--raio);
  color: var(--saida);
}

/* ---------- Mesa de conciliação ---------- */

.progresso {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 1.5rem;
  flex-wrap: wrap;
}

.progresso__barra {
  flex: 1 1 16rem;
  height: .55rem;
  background: var(--surface-alt);
  border: 1px solid var(--line);
  border-radius: 999px;
  overflow: hidden;
}

.progresso__preenchido {
  display: block;
  width: var(--pct, 0%);
  height: 100%;
  background: var(--acento);
}

.progresso__texto { margin: 0; font-size: .9rem; color: var(--ink-medio); }

/* A barra do orçamento muda de cor antes de acabar: âmbar aos 85%, vermelho
   quando passou. Aos 85% ainda dá tempo de fazer alguma coisa, que é o que
   separa um aviso de um obituário. */
.progresso__preenchido--apertado  { background: var(--aviso); }
.progresso__preenchido--estourado { background: var(--saida); }

/* A meta cumprida fica verde de entrada: aqui a barra cheia é boa notícia, e
   usar o mesmo vermelho do teto estourado diria o contrário do que aconteceu.
   Enquanto não chegou, ela veste a cor da própria meta, posta na marcação. */
.progresso__preenchido--atingida { background: var(--entrada); }

.mesa {
  display: grid;
  grid-template-columns: minmax(18rem, 2fr) minmax(20rem, 3fr);
  gap: 1.75rem;
  align-items: start;
}

@media (max-width: 60rem) {
  .mesa { grid-template-columns: minmax(0, 1fr); }
}

.mesa__titulo { font-size: 1rem; margin: 0 0 .75rem; }
.mesa__titulo--foco { font-size: 1.15rem; }

.mesa__lista {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: .35rem;
  max-height: 40rem;
  overflow-y: auto;
}

.mesa__linha {
  border: 1px solid var(--line);
  border-radius: var(--raio);
  background: var(--surface);
}
.mesa__linha--ativa { border-color: var(--acento); box-shadow: inset 3px 0 0 var(--acento); }

.mesa__link {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: .3rem .7rem;
  align-items: baseline;
  padding: .25rem .15rem;
  color: var(--ink);
  text-decoration: none;
}
.mesa__link:hover { background: var(--surface-alt); color: var(--ink); }

.mesa__data { font-variant-numeric: tabular-nums; color: var(--ink-fraco); font-size: .85rem; }
.mesa__descricao { font-size: .9rem; min-width: 0; overflow-wrap: anywhere; }
.mesa__valor {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  white-space: nowrap;
  justify-self: end;
}
.mesa__link .etiqueta { grid-column: 1 / -1; justify-self: start; }

.mesa__foco { border-left: 3px solid var(--acento); }

/* A barra de lote da mesa fica na coluna estreita: os botões quebram em mais de
   uma linha e é assim mesmo — esconder algum deles atrás de um menu seria
   esconder a metade do que a tela passou a saber fazer. */
.lote--mesa { gap: .45rem; padding: .55rem .6rem; }
.lote__todos { display: flex; align-items: center; gap: .4rem; font-size: .85rem; font-weight: 600; }
.lote--mesa .botao[disabled] { opacity: .5; cursor: not-allowed; }

.mesa__dica { font-size: .8125rem; margin: 0 0 .75rem; }

.mesa__cabecalho { display: flex; align-items: center; gap: .5rem; padding: .5rem .6rem 0; }
.mesa__cabecalho .mesa__link { flex: 1; }

.mesa__historico {
  /* Sem isto o campo não encolhe abaixo da largura intrínseca do `input`, e a
     coluna estoura para o lado. */
  min-width: 0;
  width: calc(100% - 1.2rem);
  margin: .1rem .6rem .5rem;
  padding: .25rem .35rem;
  border: 1px solid transparent;
  border-radius: var(--raio);
  background: transparent;
  color: inherit;
  font-family: inherit;
  font-size: .9rem;
}
.mesa__historico:hover { border-color: var(--line); background: var(--surface-alt); }
.mesa__historico:focus { border-color: var(--acento); background: var(--surface); }

/* Mexido e ainda não gravado. A marca é o que separa "digitei" de "está
   salvo" — sem ela, essa diferença só existe na memória de quem digitou. */
.mesa__historico--alterado {
  border-color: var(--acento);
  background: var(--acento-fraco);
  font-weight: 600;
}

.sugestoes {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: .75rem;
}

.sugestao { display: flex; flex-direction: column; gap: .35rem; }
.sugestao--alta { border-left: 3px solid var(--entrada); }
.sugestao--media { border-left: 3px solid var(--acento); }
.sugestao--baixa { border-left: 3px solid var(--line-forte); }

.sugestao__topo {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
}

.sugestao__valor { font-variant-numeric: tabular-nums; font-weight: 600; }
.sugestao__descricao { margin: 0; font-weight: 500; }
.sugestao__motivos { margin: 0; font-size: .8125rem; color: var(--ink-fraco); }
.sugestao form { margin-top: .35rem; }

.campo__dica--atencao { color: var(--aviso); }
/* O palpite de categoria: a cor de acento é a mesma da etiqueta "Pela sua
   escolha anterior" da conferência de extrato — é o mesmo aprendizado
   falando, e ele se anuncia igual nos dois lugares. */
.campo__dica--palpite { color: var(--acento); }

/* Dica que precisa ficar sempre em linha própria, e não só quando o texto
   acima é comprido o bastante para quebrar. */
.campo__dica--bloco { display: block; }

.form-linha--compacta { gap: .4rem; margin-top: 0; }
.form-linha--compacta .campo { flex: 0 1 auto; }

/* ---------------------------------------------------------------- gráficos */
/* Desenhados como SVG no servidor: herdam o tema pelas variáveis, aparecem
   sem JavaScript e não custam nada no bundle. */

.grafico { margin: 0; display: flex; flex-direction: column; gap: .75rem; }

.grafico__svg {
  width: 100%;
  height: 12.5rem;
  display: block;
  /* O corte é estrutural, não higiene. O `ChartsHelper` desenha cada barra um
     raio mais comprida do que ela mede justamente para que os dois cantos
     redondos de baixo caiam aqui fora e a base saia quadrada, apoiada na linha
     do zero. */
  overflow: hidden;
  /* A linha do zero é eixo, não régua: fica um tom acima da grade, que é quem
     tem de recuar. */
  border-bottom: 1px solid var(--line-forte);
}

/* Réguas em 25/50/75/100% do teto: dão escala à barra sem números soltos no
   desenho. Traço contínuo e de um tom só acima do fundo — pontilhado soma
   ruído e se lê como projeção ou limite, que não é o que uma régua diz. */
.grafico__grade {
  stroke: var(--line);
  stroke-width: 1;
}

/* Cor chapada, uma por série. O degradê que havia aqui era por barra — cada
   uma com a sua própria escala —, então a mesma série saía num tom em janeiro
   e noutro em fevereiro, e a cor, que só devia dizer "entrada" ou "saída",
   passava a vazar magnitude. */
.grafico__barra--entrada { fill: var(--entrada); }
.grafico__barra--saida   { fill: var(--saida); }

/* Parar o mouse numa barra recua as outras. Junto com o `<title>` que o helper
   põe em cada uma, é o valor exato de um mês sem uma linha de JavaScript — o
   que antes só o Chart.js dava.

   O gatilho é `:has(.grafico__barra:hover)`, e não `.grafico__svg:hover`, que
   era o de antes: aquele disparava com o ponteiro em qualquer canto do quadro,
   então atravessar o cartão apagava o gráfico inteiro sem nada em foco. */
.grafico__barra { transition: opacity .18s ease; }
.grafico__svg:has(.grafico__barra:hover) .grafico__barra { opacity: .32; }
.grafico__svg .grafico__barra:hover { opacity: 1; }

.grafico__legenda { display: flex; flex-wrap: wrap; gap: .4rem; }

.grafico__chave {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  padding: .2rem .6rem .25rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface-alt);
  font-size: .75rem;
  font-weight: 600;
  color: var(--ink-medio);
}

.grafico__chave::before {
  content: "";
  width: .5rem; height: .5rem;
  border-radius: 999px;
}

.grafico__chave--entrada::before { background: var(--entrada); }
.grafico__chave--saida::before   { background: var(--saida); }

/* ---------------------------------------------------------------- roscas */
/* A rosca responde ao que a barra não responde: participação no total. O furo
   do meio não é enfeite — é onde o total mora, e é o que faz as fatias
   somarem um número visível em vez de somarem "tudo". */

.grafico--rosca { align-items: stretch; }

.grafico__tela--rosca {
  height: 13.5rem;
  display: grid;
  place-items: center;
}

.grafico__tela--rosca > canvas { grid-area: 1 / 1; }

/* Sobreposto ao canvas, e não desenhado nele: assim herda fonte, cor e tema do
   resto da página, e não precisa ser repintado quando o tema muda. */
.grafico__centro {
  grid-area: 1 / 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .1rem;
  text-align: center;
  pointer-events: none;
}

.grafico__centro-rotulo {
  font-size: .68rem;
  text-transform: uppercase;
  letter-spacing: .07em;
  font-weight: 600;
  color: var(--ink-fraco);
}

.grafico__centro-valor {
  font-family: var(--fonte-titulo);
  font-size: 1.15rem;
  letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
}

/* A legenda traz os números. É por isso que ela é HTML do servidor e não a do
   Chart.js: aparece na impressão, é lida por leitor de tela e dispensa a
   tabela escondida que os outros gráficos precisam ter. */
.rosca-legenda { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }

.rosca-legenda__item {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center;
  gap: .55rem;
  padding: .4rem .15rem;
  border-top: 1px solid var(--line);
  font-size: .85rem;
}

.rosca-legenda__item:first-child { border-top: 0; }

.rosca-legenda__cor {
  width: .6rem;
  height: .6rem;
  border-radius: 3px;
  background: var(--cor, var(--line-forte));
  box-shadow: inset 0 0 0 1px var(--contorno-amostra);
}

.rosca-legenda__nome { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.rosca-legenda__valor { font-variant-numeric: tabular-nums; font-weight: 600; }

.rosca-legenda__fatia {
  min-width: 3.2rem;
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: var(--ink-fraco);
}

/* Duas roscas lado a lado — de onde veio e para onde foi. Empilham sozinhas
   quando a coluna encolhe. */
.roscas {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
  gap: 1.75rem;
}

.roscas__uma { display: flex; flex-direction: column; gap: .75rem; min-width: 0; }

.roscas__titulo {
  margin: 0;
  font-size: .75rem;
  text-transform: uppercase;
  letter-spacing: .06em;
  font-weight: 600;
  color: var(--ink-fraco);
}

/* Gaveta de detalhe: a leitura completa continua na página, mas fechada. Aberta
   sempre, ela empurrava o resto do painel para baixo da dobra. */
.detalhamento { margin-top: 1.25rem; border-top: 1px solid var(--line); padding-top: .9rem; }

.detalhamento__abrir {
  cursor: pointer;
  font-size: .82rem;
  font-weight: 600;
  color: var(--acento);
  list-style: none;
  display: inline-flex;
  align-items: center;
  gap: .4rem;
}

.detalhamento__abrir::-webkit-details-marker { display: none; }

.detalhamento__abrir::before {
  content: "▸";
  transition: transform .15s ease;
}

.detalhamento[open] .detalhamento__abrir::before { transform: rotate(90deg); }

.detalhamento__abrir:focus-visible { outline: 2px solid var(--foco); outline-offset: 3px; }

.detalhamento > :not(summary) { margin-top: 1rem; }

/* ------------------------------------------------------- seletor de janela */
/* Dia, semana, mês, ano. São links: a escolha vai para a URL, o gráfico
   continua desenhado no servidor e o endereço pode ser guardado. */

.segmentado {
  display: inline-flex;
  gap: .15rem;
  padding: .2rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface-alt);
}

.segmentado__item {
  padding: .3rem .8rem;
  border-radius: 999px;
  font-size: .8rem;
  font-weight: 600;
  color: var(--ink-medio);
  text-decoration: none;
  white-space: nowrap;
  transition: background .15s ease, color .15s ease;
}

.segmentado__item:hover { color: var(--ink); background: var(--surface); }

.segmentado__item[aria-current] {
  background: var(--surface);
  color: var(--acento);
  box-shadow: var(--sombra);
}

.segmentado__item:focus-visible { outline: 2px solid var(--foco); outline-offset: 2px; }

/* O quadro do Turbo é `inline` por padrão, e um cartão dentro dele encolhia
   até o tamanho do texto quando a coluna era flex. */
turbo-frame { display: block; }

/* Sem movimento não há gráfico, mas ainda há um lugar onde ele vai ficar. A
   moldura tracejada diz isso; um parágrafo solto no meio do cartão parecia
   erro de carregamento. */
.grafico__vazio {
  margin: 0;
  padding: 2.75rem 1rem;
  text-align: center;
  border: 1px dashed var(--line-forte);
  border-radius: var(--raio-caixa);
  background: var(--surface-alt);
}

/* O canvas do Chart.js precisa de uma caixa com altura própria: ele mede o pai
   para se dimensionar, e um pai que se dimensiona pelo filho deixa os dois sem
   referência — o gráfico cresce a cada `resize`, alguns pixels por vez, até a
   página inteira ser um canvas. A altura fixa aqui é o que corta esse laço. */
.grafico__tela {
  position: relative;
  height: 18rem;
}

/* ------------------------------------------------------------- pendências */
/* A cor da faixa é a severidade. Ela repete o que o texto já diz, porque cor
   sozinha não é informação para quem não a distingue. */

/* Em duas colunas quando a tela deixa: três pendências empilhadas ocupavam
   meia página de altura para dizer três frases curtas. */
.pendencias {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 21rem), 1fr));
  gap: .6rem;
}

.pendencia {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: .85rem;
  padding: .85rem 1.05rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-left: 3px solid var(--cor-severidade, var(--line-forte));
  border-radius: var(--raio-caixa);
  box-shadow: var(--sombra);
  color: inherit;
  text-decoration: none;
}

/* Só a pendência que leva a algum lugar reage ao mouse. O painel administrativo
   usa a mesma caixa como aviso em `<p>`, e aviso não é clicável. */
a.pendencia { transition: box-shadow .15s ease, border-color .15s ease, transform .15s ease; }
a.pendencia:hover { box-shadow: var(--sombra-alta); transform: translateY(-1px); }
a.pendencia:hover .pendencia__seta { transform: translateX(3px); color: var(--acento); }

.pendencia:focus-visible { outline: 2px solid var(--foco); outline-offset: 2px; }

.pendencia--saida   { --cor-severidade: var(--saida);      --fundo-severidade: var(--saida-fundo); }
.pendencia--aviso   { --cor-severidade: var(--aviso);      --fundo-severidade: var(--aviso-fundo); }
.pendencia--acento  { --cor-severidade: var(--acento);     --fundo-severidade: var(--acento-fraco); }
.pendencia--neutra  { --cor-severidade: var(--line-forte); --fundo-severidade: var(--surface-alt); }

/* O ponto repete a cor da faixa lateral num tamanho que o olho pega de longe.
   Cor sozinha não é informação: o texto ao lado continua dizendo o mesmo. */
.pendencia__marca {
  width: .55rem;
  height: .55rem;
  border-radius: 999px;
  background: var(--cor-severidade, var(--line-forte));
  box-shadow: 0 0 0 4px var(--fundo-severidade, var(--surface-alt));
  flex: none;
}

.pendencia__texto { display: flex; flex-direction: column; gap: .15rem; min-width: 0; }

.pendencia__titulo { font-weight: 600; }

.pendencia__descricao { font-size: .85rem; color: var(--ink-fraco); }

.pendencia__seta {
  color: var(--ink-fraco);
  flex: none;
  transition: transform .15s ease, color .15s ease;
}

/* --------------------------------------------------------- linhas de perfil */

/* As linhas moram dentro de um cartão: quem separa uma da outra é o fio, não
   uma borda inteira em volta de cada. Caixa dentro de caixa dobrava a moldura
   e fazia a lista parecer mais pesada do que a tabela ao lado. */
.linhas-de-perfil { display: flex; flex-direction: column; }

.linha-de-perfil {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: .8rem .4rem;
  border-top: 1px solid var(--line);
  border-radius: var(--raio);
  color: inherit;
  text-decoration: none;
  transition: background .15s ease;
}

.linha-de-perfil:first-child { border-top: 0; }

.linha-de-perfil:hover { background: var(--surface-alt); }

.linha-de-perfil:focus-visible { outline: 2px solid var(--foco); outline-offset: 2px; }

/* Nome, barra e detalhe empilhados numa coluna só. Empilhar por flex, e não
   por linhas da grade, é o que deixa a barra ser opcional: no perfil sem
   movimento ela simplesmente não vem, e nada abaixo se desloca. */
.linha-de-perfil__texto {
  display: flex;
  flex-direction: column;
  gap: .3rem;
  min-width: 0;
  flex: 1 1 auto;
}

.linha-de-perfil__nome { font-weight: 600; display: flex; align-items: center; gap: .45rem; }

.linha-de-perfil__detalhe { font-size: .82rem; color: var(--ink-fraco); }

.linha-de-perfil__resultado {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  white-space: nowrap;
  flex: none;
}

/* Quanto do movimento do perfil foi entrada. Diz de relance o que os dois
   números da linha de baixo dizem por extenso — e some no perfil parado, onde
   não há proporção nenhuma a mostrar. */
.linha-de-perfil__barra {
  height: .3rem;
  border-radius: 999px;
  background: var(--saida);
  overflow: hidden;
}

.linha-de-perfil__barra > span {
  display: block;
  height: 100%;
  width: var(--parte, 0%);
  border-radius: 999px;
  background: var(--entrada);
}

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

/* ------------------------------------------------------------------ seções */

.painel-colunas {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
  gap: 1.35rem;
  align-items: start;
}

/* Uma pilha de cartões dentro de uma coluna do painel. */
.painel-pilha { display: flex; flex-direction: column; gap: 1.35rem; }

.variacao { font-size: .78rem; font-weight: 500; }
.variacao--sobe { color: var(--entrada); }
.variacao--desce { color: var(--saida); }

/* ------------------------------------------------- rollup por categoria */

.rollup { display: flex; flex-direction: column; gap: 1.1rem; }

.rollup__grupo { display: flex; flex-direction: column; gap: .35rem; }

.rollup__raiz {
  display: grid;
  grid-template-columns: 1fr auto auto;
  gap: .8rem;
  align-items: baseline;
  font-weight: 600;
}

.rollup__nome { display: flex; align-items: center; gap: .45rem; min-width: 0; }

.rollup__valor { font-variant-numeric: tabular-nums; white-space: nowrap; }

.rollup__fatia {
  font-variant-numeric: tabular-nums;
  color: var(--ink-fraco);
  font-weight: 500;
  min-width: 3.5rem;
  text-align: right;
}

.rollup__barra {
  height: 6px;
  border-radius: 3px;
  background: var(--surface-alt);
  overflow: hidden;
}

.rollup__barra span { display: block; height: 100%; background: var(--cor, var(--acento)); }

.rollup__filhas {
  list-style: none;
  margin: .2rem 0 0;
  padding: 0 0 0 1.1rem;
  border-left: 2px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: .25rem;
  font-size: .88rem;
}

.rollup__filhas li {
  display: grid;
  grid-template-columns: 1fr auto auto;
  gap: .8rem;
  align-items: baseline;
  color: var(--ink-medio);
}

/* Lançado direto na raiz, sem subcategoria: é uma linha de verdade do
   detalhamento, não um rótulo — mas não é uma subcategoria que exista. */
.rollup__direta { font-style: italic; color: var(--ink-fraco); }

.grafico__barra--acento { fill: var(--acento); }

/* --------------------------------------------------------- lista de dados */

.lista-de-dados {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: .5rem 1rem;
  margin: 0;
}

.lista-de-dados dt { color: var(--ink-medio); }

.lista-de-dados dd {
  margin: 0;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  text-align: right;
}

.lista-simples { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .2rem; }

/* Rótulos do eixo: uma coluna por ponto, alinhada com as barras do SVG acima. */
.grafico__eixo {
  display: grid;
  grid-auto-flow: column;
  /* `1fr` não deixa a coluna encolher abaixo do rótulo, e doze meses empurram
     a página inteira para o lado num celular. `minmax(0, 1fr)` deixa. */
  grid-auto-columns: minmax(0, 1fr);
  font-size: .7rem;
  color: var(--ink-fraco);
  font-variant-numeric: tabular-nums;
}

.grafico__eixo span { text-align: center; white-space: nowrap; }

/* A régua rareia conforme enche. Trinta rótulos de "01/09" não cabem em 720px
   e viram uma tira contínua de dígitos — foi o que aconteceu quando a janela
   de dias entrou. `visibility` em vez de `display` porque a coluna precisa
   continuar existindo: é ela que alinha o rótulo com a barra lá em cima.
   As faixas são cumulativas e a mais estreita vem por último, para vencer. */
.grafico__eixo:has(span:nth-child(14)) span:nth-child(even) { visibility: hidden; }

.grafico__eixo:has(span:nth-child(20)) span { visibility: hidden; }
.grafico__eixo:has(span:nth-child(20)) span:nth-child(3n + 1) { visibility: visible; }

/* Trinta colunas em 1000px dão 33px por rótulo, e "01/09" mede 31 na fonte
   cheia: sobrava um pixel de cada lado e o último dígito raspava no vizinho. */
.grafico__eixo:has(span:nth-child(20)) { font-size: .66rem; }

/* Ação destrutiva e irreversível. Só a exclusão de conta usa: se todo botão
   perigoso for vermelho, nenhum é. */
.botao--perigo { background: var(--saida); color: var(--saida-texto); border-color: var(--saida); }
.botao--perigo:hover { background: var(--saida-forte); color: var(--saida-texto); }

/* ================================================ telas estreitas ==
 * O layout base já é fluido — as grades usam auto-fit e as tabelas rolam
 * dentro da própria caixa. O que não cabe de jeito nenhum lado a lado num
 * aparelho é a lateral e a tabela larga: a primeira vira gaveta, a segunda
 * vira ficha. O resto aqui é respiro menor e alvo de toque maior.
 * ================================================================= */

/* O botão da gaveta só existe abaixo do ponto de quebra; acima dele a lateral
   está sempre aberta e o botão sairia sobrando. */
.menu-alternar { display: none; }

.app__cortina { display: none; }

/* A lateral cabe até aqui. Abaixo disso ela rouba a coluna de conteúdo, e uma
   tabela de lançamentos precisa de cada pixel de largura. */
@media (max-width: 64rem) {
  .app { grid-template-columns: minmax(0, 1fr); }

  /* Sai do fluxo e vira gaveta sobreposta: empurrar o conteúdo para o lado
     reflui a página inteira a cada toque no botão. */
  .lateral {
    position: fixed;
    inset: 0 auto 0 0;
    z-index: 40;
    width: min(17.5rem, 84vw);
    transform: translateX(-100%);
    /* Fora da tela e fora do alcance: só o `transform` deixaria os links
       tabuláveis do lado de fora, e o foco sumiria da página. */
    visibility: hidden;
    transition: transform .22s ease, visibility .22s;
    box-shadow: var(--sombra-alta);
  }

  .lateral--aberta { transform: none; visibility: visible; }

  .app__cortina {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 30;
    background: var(--cortina);
    opacity: 0;
    pointer-events: none;
    transition: opacity .22s ease;
  }

  /* A cortina vem depois da lateral no HTML só por causa desta regra: é o que
     permite acendê-la sem uma classe a mais no JavaScript. */
  .lateral--aberta ~ .app__cortina { opacity: 1; pointer-events: auto; }

  .menu-alternar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    margin-left: -.5rem;
    padding: 0;
    border: 0;
    border-radius: var(--raio);
    background: none;
    color: var(--ink-medio);
    cursor: pointer;
  }
  .menu-alternar:hover { background: var(--surface-alt); color: var(--ink); }

  .menu-alternar__icone--fechar { display: none; }
  .menu-alternar[aria-expanded="true"] .menu-alternar__icone--abrir  { display: none; }
  .menu-alternar[aria-expanded="true"] .menu-alternar__icone--fechar { display: block; }
}

/* Enquanto a gaveta está aberta a página de trás não rola: rolar o fundo por
   baixo de um painel aberto é como perder o lugar da leitura. */
.sem-rolagem { overflow: hidden; }

@media (max-width: 48rem) {
  .container { width: min(100% - 1.5rem, var(--largura)); }
  main.container { padding-block: 1.5rem 3rem; }
  .app main.container { width: min(100% - 1.5rem, var(--largura-painel)); }

  .topbar__inner { min-height: 3.5rem; gap: .6rem; }
  .topbar__inner--largo { padding-inline: .75rem; }
  .brand__logo { height: 2rem; }
  .lateral__marca { padding-bottom: .9rem; }

  /* Na faixa estreita sobra espaço para o perfil em foco e o botão, nada mais:
     o resto dos atalhos já está na gaveta. */
  .topbar__acoes .botao { padding-inline: .8rem; }

  /* ---------- cabeçalho de página ---------- */

  .pagina__cabecalho {
    flex-direction: column;
    align-items: stretch;
    margin-bottom: 1.25rem;
  }
  .pagina__cabecalho .acoes-admin .botao { flex: 1 1 8rem; }

  .hero { padding-block: 1.5rem .5rem; }
  .hero__acoes { width: 100%; }
  .hero__acoes .botao { flex: 1 1 11rem; }

  /* ---------- tabelas viram fichas ---------- */
  /* Rolagem horizontal em tela de dedo esconde metade das colunas. Cada linha
     vira uma ficha e cada célula carrega o próprio rótulo, tirado do `thead`
     pelo atributo `data-rotulo`. */

  .tabela-rolagem { border: 0; border-radius: 0; overflow: visible; }

  .tabela { display: block; background: none; font-size: 1rem; }
  .tabela thead { display: none; }
  .tabela tbody, .tabela tfoot { display: block; }

  .tabela tr {
    display: block;
    padding: .7rem .9rem;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--raio-caixa);
  }
  .tabela tr + tr { margin-top: .5rem; }
  .tabela tfoot tr { background: var(--surface-alt); font-weight: 600; }

  /* Rótulo e valor são duas células de uma tabelinha de uma linha só. Com
     `grid` cada filho da célula viraria um item — o pontinho de cor iria para
     uma linha e o nome da categoria para outra. Aqui o conteúdo todo, texto
     solto incluído, cai numa célula anônima só, e o valor comprido quebra
     dentro da própria coluna em vez de por baixo do rótulo. */
  .tabela td {
    display: table;
    width: 100%;
    padding: .12rem 0;
    border: 0;
  }

  .tabela td::before {
    content: attr(data-rotulo);
    display: table-cell;
    width: 6.5rem;
    padding-right: .75rem;
    font-size: .7rem;
    text-transform: uppercase;
    letter-spacing: .06em;
    font-weight: 600;
    color: var(--ink-fraco);
  }

  /* Célula sem rótulo — seleção, ações — ocupa a ficha inteira. */
  .tabela td:not([data-rotulo]) { display: block; padding-block: .25rem; }
  .tabela td:not([data-rotulo])::before { content: none; }

  /* Onde a linha tem cabeçalho próprio (`th scope="row"`), ele vira o título
     da ficha em vez de mais uma célula rotulada. */
  .tabela tbody th[scope="row"],
  .tabela tfoot th[scope="row"] {
    display: block;
    padding: 0 0 .35rem;
    border: 0;
    background: none;
    color: var(--ink);
    font-size: 1rem;
    font-weight: 600;
    text-transform: none;
    letter-spacing: normal;
    white-space: normal;
  }

  .tabela td.numero { text-align: left; }
  .tabela tbody tr:last-child td { border-bottom: 0; }

  .coluna-selecao { width: auto; }

  /* ---------- densidade e alvos de toque ---------- */

  .cartao { padding: 1.15rem; }

  .indicadores {
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 8.5rem), 1fr));
    gap: .6rem;
    margin-bottom: 1.5rem;
  }
  .indicador__valor { font-size: 1.3rem; }
  .indicador { padding: .95rem 1rem 1rem; }
  .indicador__marca { width: 1.85rem; height: 1.85rem; border-radius: 10px; }
  .indicador__marca svg { width: 16px; height: 16px; }

  .atalhos {
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 8.5rem), 1fr));
    gap: .6rem;
  }
  .atalho__valor { font-size: 1.4rem; }

  .filtros { padding: .85rem; gap: .7rem; }
  .filtros .campo--largo { grid-column: 1 / -1; }
  .filtros .campo-inline { grid-column: 1 / -1; }
  .filtros__acoes { grid-column: 1 / -1; }
  .filtros__acoes .botao { flex: 1 1 auto; }

  /* Fonte menor que 16px faz o iOS dar zoom ao focar o campo, e a página nunca
     volta ao lugar. Botões ficam de fora: não recebem foco de digitação. */
  input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]),
  select,
  textarea { font-size: 1rem; }

  input[type="checkbox"], input[type="radio"] { width: 1.15rem; height: 1.15rem; }

  .link-acao { padding: .45rem .55rem; font-size: .875rem; }

  /* Etiqueta que conta uma frase inteira não cabe numa linha de 320px. */
  .etiqueta { white-space: normal; }

  .paginacao .pagy a { min-width: 2.5rem; min-height: 2.5rem; padding: .45rem .6rem; }

  .icones { max-height: 14rem; }

  .mesa__lista { max-height: none; }

  .grafico__svg { height: 9.5rem; }
  .grafico__eixo { font-size: .62rem; }
  .grafico__tela { height: 15rem; }
  .grafico__tela--rosca { height: 12rem; }
  .roscas { gap: 1.5rem; }
  .segmentado { width: 100%; justify-content: space-between; }
  .segmentado__item { flex: 1; text-align: center; padding: .4rem .3rem; }
  .grafico__vazio { padding: 1.75rem .75rem; }

  /* Na tela estreita a régua rareia antes: cabe menos da metade dos rótulos que
     cabem no computador, e as mesmas faixas aplicadas aqui deixariam as datas
     se atropelando de novo. */
  .grafico__eixo:has(span:nth-child(7)) span:nth-child(even) { visibility: hidden; }

  .grafico__eixo:has(span:nth-child(11)) span { visibility: hidden; }
  .grafico__eixo:has(span:nth-child(11)) span:nth-child(4n + 1) { visibility: visible; }

  .grafico__eixo:has(span:nth-child(20)) span:nth-child(4n + 1) { visibility: hidden; }
  .grafico__eixo:has(span:nth-child(20)) span:nth-child(7n + 1) { visibility: visible; }

  .autenticacao { padding-block: 1rem; }
}

@media (max-width: 30rem) {
  /* Duas colunas de botão em 320px dão dois botões ilegíveis. */
  .form__acoes { flex-direction: column; align-items: stretch; }
  .form__acoes .botao { width: 100%; }

  .rollup__fatia { min-width: 2.8rem; }
  .rollup__raiz, .rollup__filhas li { gap: .5rem; }
}

/* Sem cursor não existe hover: o que só aparecia ao passar o mouse precisa
   estar visível o tempo todo em tela de toque. */
@media (hover: none) {
  .arvore__acoes { opacity: 1; }
}

/* Recorte da tela (notch) em paisagem: o conteúdo não pode ficar embaixo dele. */
@supports (padding: max(0px)) {
  .container {
    padding-left: env(safe-area-inset-left);
    padding-right: env(safe-area-inset-right);
  }
}
