/* =========================
   TEMA / TOKENS DE COR

   O tema claro é o padrão em :root.
   - Modo automático: sem atributo data-tema, a media query decide.
   - Modo claro forçado: data-tema="claro" bloqueia a media query.
   - Modo escuro forçado: data-tema="escuro" vence em qualquer situação.
   ========================= */

:root {
    color-scheme: light;

    --cor-fundo: #f3f4f6;
    --cor-superficie: #ffffff;
    --cor-superficie-alt: #f3f4f6;
    --cor-menu-flutuante: #ffffff;
    --cor-menu-flutuante-hover: #f3f4f6;
    --cor-sombra-menu: 0 4px 6px -2px rgba(15, 23, 42, .08), 0 12px 28px -8px rgba(15, 23, 42, .22);
    --cor-fundo-gaveta: rgba(15, 23, 42, .45);
    --cor-superficie-suave: #f9fafb;

    --cor-texto: #1f2937;
    --cor-texto-forte: #111827;
    --cor-texto-medio: #374151;
    --cor-texto-suave: #6b7280;

    --cor-borda: #e5e7eb;
    --cor-borda-forte: #d1d5db;

    --cor-menu-fundo: #111827;
    --cor-menu-item: #1f2937;
    --cor-menu-borda: #374151;
    --cor-menu-realce: #374151;
    --cor-menu-realce-hover: #4b5563;
    --cor-menu-texto: #d1d5db;
    --cor-menu-texto-forte: #ffffff;
    --cor-menu-texto-suave: #9ca3af;

    --cor-primaria: #2563eb;
    --cor-primaria-hover: #1d4ed8;
    --cor-primaria-texto: #ffffff;
    --cor-primaria-suave: #dbeafe;
    --cor-primaria-contraste: #1d4ed8;
    --cor-foco: #2563eb;
    --cor-anel-foco: rgba(37, 99, 235, 0.12);

    --cor-perigo: #dc2626;
    --cor-perigo-borda: #fecaca;
    --cor-perigo-fundo: #fef2f2;
    --cor-perigo-suave: #fee2e2;
    --cor-perigo-forte: #991b1b;

    --cor-sucesso-fundo: #dcfce7;
    --cor-sucesso-texto: #166534;

    /* Identidade por tipo de lançamento:
       despesa = vermelho, receita = verde, transferência = amarelo. */
    --cor-despesa: #dc2626;
    --cor-despesa-hover: #b91c1c;
    --cor-despesa-texto: #ffffff;
    --cor-despesa-suave: #fee2e2;
    --cor-despesa-contraste: #991b1b;

    --cor-receita: #16a34a;
    --cor-receita-hover: #15803d;
    --cor-receita-texto: #ffffff;
    --cor-receita-suave: #dcfce7;
    --cor-receita-contraste: #166534;

    --cor-transferencia: #d97706;
    --cor-transferencia-hover: #b45309;
    --cor-transferencia-texto: #ffffff;
    --cor-transferencia-suave: #fef3c7;
    --cor-transferencia-contraste: #92400e;

    /* Estado de uma linha de orçamento — não é tipo de transação, é
       "dentro do teto / perto do teto / estourou". Tokens próprios de
       propósito: a paleta de tipo fica reservada ao seu significado. */
    --cor-orcamento-ok: #16a34a;
    --cor-orcamento-alerta: #d97706;
    --cor-orcamento-estouro: #dc2626;
    --cor-orcamento-trilho: #e5e7eb;

    --cor-icone-perfil: #eef2ff;

    --cor-overlay: rgba(17, 24, 39, 0.55);
    --sombra-cartao: 0 2px 10px rgba(0, 0, 0, 0.05);
    --sombra-modal: 0 20px 50px rgba(0, 0, 0, 0.2);
    --sombra-login: 0 10px 30px rgba(0, 0, 0, 0.08);
    --sombra-painel: -12px 0 35px rgba(0, 0, 0, 0.18);
}


/* Modo automático: segue o sistema, exceto se o claro foi escolhido à mão. */
@media (prefers-color-scheme: dark) {

    :root:not([data-tema="claro"]) {
        color-scheme: dark;

        --cor-fundo: #0f172a;
        --cor-superficie: #1e293b;
        --cor-superficie-alt: #334155;
        --cor-menu-flutuante: #1e293b;
        --cor-menu-flutuante-hover: #334155;
        --cor-sombra-menu: 0 4px 6px -2px rgba(0, 0, 0, .4), 0 12px 30px -8px rgba(0, 0, 0, .65);
        --cor-fundo-gaveta: rgba(2, 6, 23, .62);
        --cor-superficie-suave: #263449;

        --cor-texto: #e2e8f0;
        --cor-texto-forte: #f8fafc;
        --cor-texto-medio: #cbd5e1;
        --cor-texto-suave: #94a3b8;

        --cor-borda: #334155;
        --cor-borda-forte: #475569;

        --cor-menu-fundo: #020617;
        --cor-menu-item: #1e293b;
        --cor-menu-borda: #334155;
        --cor-menu-realce: #334155;
        --cor-menu-realce-hover: #475569;
        --cor-menu-texto: #cbd5e1;
        --cor-menu-texto-forte: #f8fafc;
        --cor-menu-texto-suave: #94a3b8;

        --cor-primaria: #2563eb;
        --cor-primaria-hover: #1d4ed8;
        --cor-primaria-texto: #ffffff;
        --cor-primaria-suave: #1e3a8a;
        --cor-primaria-contraste: #bfdbfe;
        --cor-foco: #60a5fa;
        --cor-anel-foco: rgba(96, 165, 250, 0.25);

        --cor-perigo: #f87171;
        --cor-perigo-borda: #7f1d1d;
        --cor-perigo-fundo: #2a1212;
        --cor-perigo-suave: #7f1d1d;
        --cor-perigo-forte: #fecaca;

        --cor-sucesso-fundo: #14532d;
        --cor-sucesso-texto: #bbf7d0;

        /* Os preenchimentos mantêm o mesmo tom nos dois temas: já têm
           contraste suficiente sobre claro e sobre escuro. Só os pares
           suave/contraste dos selos precisam inverter. */
        --cor-despesa: #dc2626;
        --cor-despesa-hover: #b91c1c;
        --cor-despesa-texto: #ffffff;
        --cor-despesa-suave: #7f1d1d;
        --cor-despesa-contraste: #fecaca;

        --cor-receita: #16a34a;
        --cor-receita-hover: #15803d;
        --cor-receita-texto: #ffffff;
        --cor-receita-suave: #14532d;
        --cor-receita-contraste: #bbf7d0;

        --cor-transferencia: #d97706;
        --cor-transferencia-hover: #b45309;
        --cor-transferencia-texto: #ffffff;
        --cor-transferencia-suave: #78350f;
        --cor-transferencia-contraste: #fde68a;

        --cor-orcamento-ok: #22c55e;
        --cor-orcamento-alerta: #f59e0b;
        --cor-orcamento-estouro: #f87171;
        --cor-orcamento-trilho: #334155;

        --cor-icone-perfil: #1e3a8a;

        --cor-overlay: rgba(2, 6, 23, 0.7);
        --sombra-cartao: 0 2px 10px rgba(0, 0, 0, 0.35);
        --sombra-modal: 0 20px 50px rgba(0, 0, 0, 0.55);
        --sombra-login: 0 10px 30px rgba(0, 0, 0, 0.45);
        --sombra-painel: -12px 0 35px rgba(0, 0, 0, 0.5);
    }

}


/* Escuro escolhido à mão: vence inclusive num sistema em modo claro. */
:root[data-tema="escuro"] {
    color-scheme: dark;

    --cor-fundo: #0f172a;
    --cor-superficie: #1e293b;
    --cor-superficie-alt: #334155;
    --cor-menu-flutuante: #1e293b;
    --cor-menu-flutuante-hover: #334155;
    --cor-sombra-menu: 0 4px 6px -2px rgba(0, 0, 0, .4), 0 12px 30px -8px rgba(0, 0, 0, .65);
    --cor-fundo-gaveta: rgba(2, 6, 23, .62);
    --cor-superficie-suave: #263449;

    --cor-texto: #e2e8f0;
    --cor-texto-forte: #f8fafc;
    --cor-texto-medio: #cbd5e1;
    --cor-texto-suave: #94a3b8;

    --cor-borda: #334155;
    --cor-borda-forte: #475569;

    --cor-menu-fundo: #020617;
    --cor-menu-item: #1e293b;
    --cor-menu-borda: #334155;
    --cor-menu-realce: #334155;
    --cor-menu-realce-hover: #475569;
    --cor-menu-texto: #cbd5e1;
    --cor-menu-texto-forte: #f8fafc;
    --cor-menu-texto-suave: #94a3b8;

    --cor-primaria: #2563eb;
    --cor-primaria-hover: #1d4ed8;
    --cor-primaria-texto: #ffffff;
    --cor-primaria-suave: #1e3a8a;
    --cor-primaria-contraste: #bfdbfe;
    --cor-foco: #60a5fa;
    --cor-anel-foco: rgba(96, 165, 250, 0.25);

    --cor-perigo: #f87171;
    --cor-perigo-borda: #7f1d1d;
    --cor-perigo-fundo: #2a1212;
    --cor-perigo-suave: #7f1d1d;
    --cor-perigo-forte: #fecaca;

    --cor-sucesso-fundo: #14532d;
    --cor-sucesso-texto: #bbf7d0;

    --cor-despesa: #dc2626;
    --cor-despesa-hover: #b91c1c;
    --cor-despesa-texto: #ffffff;
    --cor-despesa-suave: #7f1d1d;
    --cor-despesa-contraste: #fecaca;

    --cor-receita: #16a34a;
    --cor-receita-hover: #15803d;
    --cor-receita-texto: #ffffff;
    --cor-receita-suave: #14532d;
    --cor-receita-contraste: #bbf7d0;

    --cor-transferencia: #d97706;
    --cor-transferencia-hover: #b45309;
    --cor-transferencia-texto: #ffffff;
    --cor-transferencia-suave: #78350f;
    --cor-transferencia-contraste: #fde68a;

    --cor-orcamento-ok: #22c55e;
    --cor-orcamento-alerta: #f59e0b;
    --cor-orcamento-estouro: #f87171;
    --cor-orcamento-trilho: #334155;

    --cor-icone-perfil: #1e3a8a;

    --cor-overlay: rgba(2, 6, 23, 0.7);
    --sombra-cartao: 0 2px 10px rgba(0, 0, 0, 0.35);
    --sombra-modal: 0 20px 50px rgba(0, 0, 0, 0.55);
    --sombra-login: 0 10px 30px rgba(0, 0, 0, 0.45);
    --sombra-painel: -12px 0 35px rgba(0, 0, 0, 0.5);
}


* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

:root {
    font-family:
        Inter,
        -apple-system,
        BlinkMacSystemFont,
        "Segoe UI",
        sans-serif;

    color: var(--cor-texto);
    background: var(--cor-fundo);
}

body {
    min-height: 100vh;

    color: var(--cor-texto);
    background: var(--cor-fundo);

    transition:
        background 0.2s,
        color 0.2s;
}

.pagina-login {
    min-height: 100vh;

    display: flex;
    align-items: center;
    justify-content: center;

    padding: 20px;
}

.cartao-login {
    width: 100%;
    max-width: 420px;

    background: var(--cor-superficie);

    border-radius: 16px;

    padding: 40px;

    box-shadow: var(--sombra-login);
}

.cabecalho-login {
    text-align: center;
    margin-bottom: 32px;
}

.logo {
    display: flex;
    justify-content: center;

    margin-bottom: 12px;
}


.logo img {
    width: 64px;
    height: 64px;
}

.cabecalho-login h1 {
    font-size: 28px;
    margin-bottom: 8px;

    color: var(--cor-texto-forte);
}

.cabecalho-login p {
    color: var(--cor-texto-suave);
    font-size: 14px;
}

.campo {
    margin-bottom: 20px;
}

/* "Manter conectado" — entre a senha e o botão Entrar. */
.campo-lembrar {
    display: flex;
    align-items: center;
    gap: 8px;

    margin-bottom: 20px;

    font-size: 14px;
    color: var(--cor-texto-suave);
    cursor: pointer;
}

.campo-lembrar input {
    width: auto;
    margin: 0;
}

.campo label {
    display: block;

    margin-bottom: 7px;

    font-size: 14px;
    font-weight: 600;
}

.campo input,
.campo select {
    width: 100%;

    padding: 12px 14px;

    border: 1px solid var(--cor-borda-forte);
    border-radius: 8px;

    background: var(--cor-superficie);
    color: var(--cor-texto);

    font-family: inherit;
    font-size: 15px;

    outline: none;

    transition:
        border-color 0.2s,
        box-shadow 0.2s;
}

.campo input:focus,
.campo select:focus {
    border-color: var(--cor-foco);

    box-shadow:
        0 0 0 3px var(--cor-anel-foco);
}

#botao-entrar,
#botao-cadastrar {
    width: 100%;

    padding: 13px;

    border: none;
    border-radius: 8px;

    background: var(--cor-primaria);
    color: var(--cor-primaria-texto);

    font-size: 15px;
    font-weight: 600;

    cursor: pointer;

    transition:
        background 0.2s,
        transform 0.1s;
}

#botao-entrar:hover,
#botao-cadastrar:hover {
    background: var(--cor-primaria-hover);
}

#botao-entrar:active,
#botao-cadastrar:active {
    transform: scale(0.99);
}

#botao-entrar:disabled,
#botao-cadastrar:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

.mensagem {
    min-height: 20px;

    margin-top: 16px;

    text-align: center;

    font-size: 14px;

    color: var(--cor-perigo);
}

/* Verde de sucesso na mesma faixa de mensagem — cadastro concluído,
   senha/e-mail trocados. Sem isso a confirmação sai vermelha, como erro. */
.mensagem.ok {
    color: var(--cor-receita, #159a46);
}

/* Login ⇄ cadastro: o link para a outra página, abaixo do botão. */
.troca-pagina-login {
    margin-top: 18px;
    text-align: center;
    font-size: 14px;
    color: var(--cor-texto-suave);
}

.troca-pagina-login a {
    color: var(--cor-primaria);
    font-weight: 600;
    text-decoration: none;
}

.troca-pagina-login a:hover {
    text-decoration: underline;
}

.layout {
    /* Altura travada, não `min-height`. Com `min-height` o layout crescia
       junto com a lista e quem rolava era o documento inteiro — a barra
       lateral ia junto, e o nome do usuário, que fica no fim dela, só
       aparecia depois de rolar a listagem toda. Travando aqui, quem rola
       passa a ser só o `.conteudo`. */
    height: 100vh;
    height: 100dvh;
    overflow: hidden;

    display: flex;

    background: var(--cor-fundo);
}


.menu-lateral {
    width: 240px;
    flex: 0 0 auto;

    display: flex;
    flex-direction: column;

    padding: 24px 16px;

    /* A barra em si não rola: se ela rolasse inteira, o bloco do usuário
       voltaria a ficar abaixo da dobra — só teria trocado "fim da lista"
       por "fim do menu". Quem rola é o `nav`, lá embaixo. */
    overflow: hidden;

    background: var(--cor-menu-fundo);
    color: var(--cor-menu-texto-forte);

    transition: width 0.18s;
}


/* ---- Menu recolhido -------------------------------------------------
   O estado vive em `data-menu` no <html>, escrito por `menu-lateral.js`
   ainda no <head> — mesmo padrão do tema. Aplicar depois faria a barra
   nascer larga e encolher na frente do usuário.

   O truque de `font-size: 0` + `::first-letter` é o mesmo que a média
   query de 768px já usava para virar só ícones: o emoji é o primeiro
   caractere do rótulo, então sobra ele. */
:root[data-menu="recolhido"] .menu-lateral {
    width: 72px;
    padding: 24px 10px;
}


:root[data-menu="recolhido"] .item-menu {
    text-align: center;
    font-size: 0;
}


:root[data-menu="recolhido"] .item-menu::first-letter {
    font-size: 20px;
}


/* A marca ficou de fora do truque do `::first-letter`: a primeira
   "letra" dela agora é uma imagem, e o seletor nem chega a casar. O
   que sobra recolhido é o próprio símbolo — que é justamente o que a
   marca é a 72px de largura. */
:root[data-menu="recolhido"] .marca {
    justify-content: center;
    padding-left: 0;
    padding-right: 0;
}


:root[data-menu="recolhido"] .marca > span {
    display: none;
}


/* O seletor de perfil é um <select> com nome de perfil: encolhido a
   72px não sobra texto legível nenhum. Some, e volta ao expandir. */
:root[data-menu="recolhido"] .seletor-perfil {
    display: none;
}


/* Do bloco do usuário sobra o avatar — que é o alvo do clique que abre
   o painel, então continua alcançável recolhido. */
:root[data-menu="recolhido"] .usuario-dados {
    display: none;
}


:root[data-menu="recolhido"] .usuario-logado {
    justify-content: center;
    padding: 10px 0;
}


.botao-recolher {
    align-self: flex-end;

    width: 30px;
    height: 30px;
    margin-bottom: 8px;
    padding: 0;

    border: 1px solid var(--cor-menu-item);
    border-radius: 8px;

    background: transparent;
    color: var(--cor-menu-texto);

    font-family: inherit;
    font-size: 15px;
    line-height: 1;

    cursor: pointer;
}


.botao-recolher:hover {
    background: var(--cor-menu-item);
    color: var(--cor-menu-texto-forte);
}


:root[data-menu="recolhido"] .botao-recolher {
    align-self: center;
}


.marca {
    display: flex;
    align-items: center;
    gap: 10px;

    padding: 0 12px 30px;

    font-size: 18px;
    font-weight: 700;
}


/* O símbolo do site (monograma "NF"). PNG de fundo transparente: quem
   pinta atrás dele é a superfície, então o mesmo arquivo serve o menu
   escuro e o cartão claro do login. */
.marca-simbolo {
    flex-shrink: 0;

    width: 30px;
    height: 30px;
}


.menu-lateral nav {
    display: flex;
    flex-direction: column;

    gap: 6px;

    /* Só a lista de telas rola, e só quando não couber. `min-height: 0`
       é obrigatório: sem ele um filho flex se recusa a encolher abaixo
       do próprio conteúdo e a rolagem nunca aparece. */
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
}


/* A marca, o seletor de perfil e o bloco do usuário são âncoras: não
   encolhem e não rolam. */
.menu-lateral > .marca,
.menu-lateral > .seletor-perfil,
.menu-lateral > .usuario-logado,
.menu-lateral > .botao-recolher {
    flex: 0 0 auto;
}


.item-menu {
    display: block;

    padding: 11px 12px;

    border-radius: 8px;

    color: var(--cor-menu-texto);

    text-decoration: none;

    font-size: 14px;

    transition:
        background 0.2s,
        color 0.2s;
}


.item-menu:hover,
.item-menu.ativo {
    background: var(--cor-menu-item);
    color: var(--cor-menu-texto-forte);
}


.botao-sair {
    margin-top: auto;

    padding: 11px 12px;

    border: none;
    border-radius: 8px;

    background: var(--cor-menu-realce);

    color: var(--cor-menu-texto-forte);

    font-size: 14px;

    cursor: pointer;
}


.botao-sair:hover {
    background: var(--cor-menu-realce-hover);
}


.conteudo {
    flex: 1;

    padding: 32px;

    overflow-y: auto;
}


/* =========================
   TOPO FIXO (item 7)
   =========================

   O cabeçalho e a barra de mês ficam fixos ao rolar. A técnica é
   estrutural, não `position: sticky`: quem tem `.tem-topo-fixo` deixa de
   ser o container que rola e vira um flex em coluna com duas partes — o
   `.cabecalho-fixo` (não rola) e o `.conteudo-rolavel` (rola).

   Uma tentativa anterior fazia o cabeçalho `sticky` DENTRO do `.conteudo`
   com margem negativa, e media a altura numa variável CSS lida pelo
   `top:` do `.dia-extrato`. As duas coisas deram regressão (conteúdo por
   trás do cabeçalho no PC; cabeçalhos de dia no meio da tela no celular).
   Tirando o cabeçalho do fluxo de rolagem, `.dia-extrato` fica intocado
   (`top: 0` já cai no topo do `.conteudo-rolavel`) e nada rola por trás.

   `.conteudo` sem a classe fica exatamente como antes — perfis, importar
   e compartilhados não são afetados. */
.conteudo.tem-topo-fixo {
    padding: 0;
    overflow: hidden;

    display: flex;
    flex-direction: column;
}

.cabecalho-fixo {
    flex: 0 0 auto;

    /* Contexto de empilhamento para o `.painel-periodo` (mês/ano, que é
       `position: absolute`) vazar por cima da lista sem ser cortado. */
    position: relative;
    z-index: 5;

    padding: 24px 32px 12px;

    background: var(--cor-fundo);
}

/* O recuo de baixo do `.cabecalho-fixo` já dá o respiro; a margem do
   header empurraria as fichas para longe demais. */
.cabecalho-fixo .cabecalho-tela {
    margin-bottom: 0;
}

.conteudo-rolavel {
    flex: 1;
    min-height: 0;

    overflow-y: auto;

    padding: 0 32px 32px;
}


/* Quando a barra de mês some (cartões com "faturas atuais", movimentações
   em busca) o cabeçalho segue fixo e no mesmo layout — só sem os meses
   (a `.barra-periodo[hidden]` some sozinha). A classe `.topo-solto`, que
   fazia o cabeçalho voltar a rolar junto, foi removida em 29/08: deixava
   o ☰ solto e o ⋮ fora de linha no celular. */


.cabecalho {
    margin-bottom: 30px;
}


.cabecalho h1 {
    margin-bottom: 5px;

    font-size: 28px;

    color: var(--cor-texto-forte);
}


.cabecalho p {
    color: var(--cor-texto-suave);
}


.resumo {
    display: grid;

    grid-template-columns:
        repeat(3, minmax(0, 1fr));

    gap: 20px;

    margin-bottom: 30px;
}


.cartao-resumo {
    padding: 24px;

    background: var(--cor-superficie);

    border-radius: 12px;

    box-shadow: var(--sombra-cartao);
}


.cartao-resumo span {
    display: block;

    margin-bottom: 10px;

    color: var(--cor-texto-suave);

    font-size: 14px;
}


.cartao-resumo strong {
    font-size: 24px;

    color: var(--cor-texto-forte);
}


.area-conteudo {
    padding: 24px;

    background: var(--cor-superficie);

    border-radius: 12px;

    box-shadow: var(--sombra-cartao);
}


.area-conteudo h2 {
    margin-bottom: 24px;

    font-size: 20px;

    color: var(--cor-texto-forte);
}


.estado-vazio {
    padding: 50px 20px;

    text-align: center;

    color: var(--cor-texto-suave);
}


.icone-vazio {
    margin-bottom: 12px;

    font-size: 40px;
}


.estado-vazio h3 {
    margin-bottom: 8px;

    color: var(--cor-texto-medio);
}


.estado-vazio p {
    font-size: 14px;
}


@media (max-width: 768px) {

    .menu-lateral {
        width: 72px;

        padding: 20px 10px;
    }


    /* Aqui o menu já é só ícone por conta da largura: recolher não teria
       o que recolher, e o botão só ocuparia espaço. */
    .botao-recolher {
        display: none;
    }


    .seletor-perfil {
        display: none;
    }


    .marca {
        justify-content: center;

        padding-left: 0;
        padding-right: 0;
    }


    .marca > span {
        display: none;
    }


    .item-menu {
        text-align: center;

        font-size: 0;
    }


    .item-menu::first-letter {
        font-size: 20px;
    }


    .botao-sair {
        font-size: 0;
    }


    .botao-sair::first-letter {
        font-size: 20px;
    }


    .seletor-perfil label {
        display: none;
    }


    .seletor-perfil select {
        padding: 8px 2px;

        font-size: 11px;

        text-align: center;
    }


    .conteudo {
        padding: 20px;
    }


    .resumo {
        grid-template-columns: 1fr;
    }

}

.seletor-perfil {
    margin-bottom: 24px;

    padding-bottom: 20px;

    border-bottom: 1px solid var(--cor-menu-item);
}

.seletor-perfil label {
    display: block;

    margin-bottom: 8px;

    font-size: 12px;

    color: var(--cor-menu-texto-suave);

    font-weight: 600;

    text-transform: uppercase;

    letter-spacing: 0.03em;
}


.seletor-perfil select {
    width: 100%;

    padding: 9px 10px;

    border: 1px solid var(--cor-menu-borda);

    border-radius: 8px;

    background: var(--cor-menu-item);

    color: var(--cor-menu-texto-forte);

    font-family: inherit;
    font-size: 14px;

    cursor: pointer;

    outline: none;
}


.seletor-perfil select:focus {
    border-color: var(--cor-foco);
}

/* =========================
   CONTAS
   ========================= */

.cabecalho-contas {
    display: flex;
    align-items: center;
    justify-content: space-between;

    gap: 20px;
}


.botao-principal {
    padding: 11px 18px;

    border: none;
    border-radius: 8px;

    background: var(--cor-primaria);
    color: var(--cor-primaria-texto);

    font-size: 14px;
    font-weight: 600;

    cursor: pointer;

    transition:
        background 0.2s,
        transform 0.1s;
}


.botao-principal:hover {
    background: var(--cor-primaria-hover);
}


.botao-principal:active {
    transform: scale(0.98);
}


.botao-principal:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}


.botao-secundario {
    /* Vale para <button> e para <a> (o link do modelo de importação):
       sem inline-block e text-decoration o âncora cai como texto
       sublinhado e a caixa some. */
    display: inline-block;

    padding: 11px 18px;

    border: 1px solid var(--cor-borda-forte);
    border-radius: 8px;

    background: var(--cor-superficie);
    color: var(--cor-texto-medio);

    font-family: inherit;
    font-size: 14px;
    font-weight: 600;
    line-height: normal;
    text-align: center;
    text-decoration: none;

    cursor: pointer;
}


.botao-secundario:hover {
    background: var(--cor-superficie-alt);
}


.lista-contas {
    display: grid;

    grid-template-columns:
        repeat(2, minmax(0, 1fr));

    /* Masonry: cada card com a altura do seu conteúdo, a fileira de baixo
       subindo para encostar. Ver js/masonry.js. `row-gap: 0` porque a
       folga entra na conta do span; o `@supports` no fim do arquivo
       troca isso pelo masonry nativo quando existir. */
    --masonry-gap: 20px;
    grid-auto-rows: 1px;
    column-gap: 20px;
    row-gap: 0;
    align-items: start;
}


.cartao-conta {
    padding: 24px;

    background: var(--cor-superficie);

    border-radius: 12px;

    box-shadow: var(--sombra-cartao);
}


.cabecalho-conta {
    display: flex;

    align-items: flex-start;
    justify-content: space-between;

    gap: 20px;

    margin-bottom: 24px;
}


.titulo-conta {
    display: flex;

    align-items: center;

    gap: 10px;
}


.titulo-conta h2 {
    font-size: 19px;

    color: var(--cor-texto-forte);
}


.numero-conta {
    margin-top: 6px;

    color: var(--cor-texto-suave);

    font-size: 13px;
}


.etiqueta-conta-padrao {
    padding: 4px 8px;

    border-radius: 999px;

    background: var(--cor-primaria-suave);
    color: var(--cor-primaria-contraste);

    font-size: 11px;
    font-weight: 700;
}


.acoes-conta {
    display: flex;

    gap: 6px;
}


/* Selo da conta ou do cartão que fica fora dos totais da tela. O registro
   continua listado com o próprio saldo — sem dizer isso no card, o total
   da tela parece errado. */
.etiqueta-ignorada {
    padding: 4px 8px;

    border-radius: 999px;

    background: var(--cor-perigo-suave);
    color: var(--cor-perigo-forte);

    font-size: 11px;
    font-weight: 700;
}


/* "Ocultar saldo": esconde os valores daquele card, para abrir o app na
   frente de alguém. É preferência do aparelho, por conta. */
.link-ocultar-saldo {
    display: block;

    margin-left: auto;

    padding: 6px 0;

    background: none;
    border: none;

    color: var(--cor-texto-suave);

    font-size: 12px;

    cursor: pointer;
}


.link-ocultar-saldo:hover {
    color: var(--cor-texto);
}


/* =========================
   VISÃO RESUMIDA (lista simples)

   A mesma tela de contas ou de cartões reduzida a um card compacto por
   registro, alternada no ⋮ e guardada como preferência do aparelho.
   Vários cards por fileira e **todos do mesmo tamanho** — o masonry
   (js/masonry.js) se abstém quando a lista tem `.lista-simples`, porque
   aqui a igualdade de tamanho é o ponto, ao contrário da visão detalhada.
   ========================= */

.lista-contas.lista-simples,
.lista-cartoes.lista-simples {
    /* `display: grid` vem da base; aqui trocamos o resto: colunas
       elásticas (~3–4 no PC, 2 no celular) e altura uniforme, anulando
       o `grid-auto-rows: 1px` / `align-items: start` do masonry. */
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
    grid-auto-rows: 1fr;
    column-gap: 12px;
    row-gap: 12px;
    align-items: stretch;
}


.cartao-simples {
    display: flex;
    flex-direction: column;
    gap: 8px;

    /* Piso de altura: cards com menos selos não ficam menores que os
       outros da fileira. */
    min-height: 122px;
    padding: 14px;

    background: var(--cor-superficie);

    border: 1px solid var(--cor-borda);
    border-radius: 12px;
}


.cartao-simples:hover {
    border-color: var(--cor-borda-forte);
}


.cartao-simples-topo {
    display: flex;
    align-items: flex-start;
    gap: 6px;
}


.cartao-simples-nome {
    flex: 1;
    min-width: 0;

    color: var(--cor-texto-forte);
    font-size: 15px;
    line-height: 1.3;

    /* Até duas linhas; daí em diante reticências, em vez de esticar o
       card e quebrar a fileira. */
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
}


.cartao-simples .botao-tres-pontos {
    flex: 0 0 auto;

    /* Encosta no canto do card sem aumentar a caixa. */
    margin: -4px -4px 0 0;
}


.cartao-simples-selos {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
}

/* Sem selos não sobra um vão de `gap` no meio do card. */
.cartao-simples-selos:empty {
    display: none;
}


/* O valor alinha a base de todos os cards da fileira. */
.cartao-simples-valor {
    margin-top: auto;

    display: flex;
    flex-direction: column;
    gap: 2px;
}


.cartao-simples-valor .valor-saldo-atual,
.cartao-simples-valor .valor-fatura {
    font-size: 18px;
    font-weight: 700;

    overflow-wrap: anywhere;
}


.cartao-simples-valor small {
    font-size: 11px;
}


/* Pagar / reabrir a fatura sem abrir o cartão. Largura total do card,
   mais baixo que o botão da visão detalhada. Anula a margem de 16px que
   `.botao-pagar-fatura` traz para o card grande. */
.cartao-simples .botao-fatura-compacto {
    width: 100%;
    margin-top: 8px;
    padding: 8px 10px;

    font-size: 13px;
    text-align: center;
}


/* No celular a faixa é estreita: 190px daria 1 coluna. 150px cabe em
   duas, que é o que "não ocupar a linha inteira" pede. */
@media (max-width: 600px) {

    .lista-contas.lista-simples,
    .lista-cartoes.lista-simples {
        grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
        column-gap: 10px;
        row-gap: 10px;
    }

    .cartao-simples-valor .valor-saldo-atual,
    .cartao-simples-valor .valor-fatura {
        font-size: 16px;
    }
}


/* Selo de estado da fatura no card do cartão, e a faixa que responde
   "quando e de onde sai o dinheiro". */
/* Os dois selos lado a lado. Flex também protege a largura deles: como
   item de flex, um filho `display: block` encolhe para o conteúdo em vez
   de esticar pela coluna. */
.linha-selo-fatura {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin-top: 6px;
}


.selo-fatura {
    font-size: 11px;
}


/* Marca de previsão (item 23). Um selo discreto na linha secundária —
   "sem poluir a interface" foi o pedido —, com contorno tracejado para
   dizer "ainda não é certo" sem competir com o valor. */
.selo-previsao {
    display: inline-block;
    padding: 0 6px;

    border: 1px dashed var(--cor-borda-forte);
    border-radius: 999px;

    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--cor-texto-suave);
    white-space: nowrap;
}


/* O estado de uma fatura são **dois eixos**, e cada um tem o seu selo:
   aberta/fechada diz o que ela ainda aceita, paga/a pagar diz o que ela
   ainda cobra. As quatro combinações existem — fechada e não paga é o
   caso comum entre o fechamento e o vencimento, e paga e não fechada é
   quem adiantou o pagamento. */
/* **Duas classes no seletor, de propósito.** Estes selos vivem dentro de
   `.dados-cartao`, cuja regra `.dados-cartao span` é mais específica que
   uma classe só — ela transformava o selo num bloco cinza da largura da
   coluna inteira, perdendo a cor que é metade da informação. */
.selo-fatura.selo-fatura-aberta,
.selo-fatura.selo-fatura-fechada,
.selo-fatura.selo-pagamento-paga,
.selo-fatura.selo-pagamento-devendo,
.selo-fatura.selo-pagamento-vazia {
    display: inline-block;

    padding: 4px 8px;
    margin-bottom: 0;

    border-radius: 999px;

    font-size: 11px;
    font-weight: 700;
    white-space: nowrap;
}

/* Fatura em aberto, em azul de propósito: a paleta de âmbar é a de
   transferência, e o estado de uma fatura não é um tipo de lançamento. */
.selo-fatura.selo-fatura-aberta {
    background: var(--cor-primaria-suave);
    color: var(--cor-primaria-contraste);
}

.selo-fatura.selo-fatura-fechada,
.selo-fatura.selo-pagamento-vazia {
    background: var(--cor-superficie-alt);
    color: var(--cor-texto-suave);
}

.selo-fatura.selo-pagamento-paga {
    background: var(--cor-receita-suave);
    color: var(--cor-receita-contraste);
}

.selo-fatura.selo-pagamento-devendo {
    background: var(--cor-despesa-suave);
    color: var(--cor-despesa-contraste);
}


/* **Dois em um**, para a linha do dashboard: o cadeado diz aberta ou
   fechada pelo desenho, e o fundo diz paga, a pagar ou sem valor pela
   cor. Dois selos ali roubariam a largura do valor, que é o dado da
   linha. */
.selo-cadeado {
    display: inline-flex;
    align-items: center;
    justify-content: center;

    width: 20px;
    height: 20px;
    margin-left: 6px;

    border-radius: 999px;

    font-size: 11px;
    line-height: 1;
    vertical-align: middle;
}

.selo-cadeado-paga {
    background: var(--cor-receita-suave);
    color: var(--cor-receita-contraste);
}

.selo-cadeado-devendo {
    background: var(--cor-despesa-suave);
    color: var(--cor-despesa-contraste);
}

.selo-cadeado-vazia {
    background: var(--cor-superficie-alt);
    color: var(--cor-texto-suave);
}


/* O cadeado desenhado. Herda `currentColor` do selo em volta, então a
   cor do tema e a do estado valem sem uma regra por combinação. */
.icone-cadeado {
    width: 11px;
    height: 10px;
    vertical-align: -1px;
}


.faixa-ciclo {
    display: grid;

    grid-template-columns: repeat(3, minmax(0, 1fr));

    gap: 10px;

    margin-top: 14px;

    padding-top: 14px;

    border-top: 1px dashed var(--cor-borda);
}


.faixa-ciclo span {
    display: block;

    color: var(--cor-texto-suave);

    font-size: 11px;
}


.faixa-ciclo strong {
    overflow: hidden;

    color: var(--cor-texto);

    font-size: 13px;

    text-overflow: ellipsis;
    white-space: nowrap;
}


.faixa-ciclo div:last-child {
    text-align: right;
}


.faixa-ciclo div:nth-child(2) {
    text-align: center;
}


.botao-acao {
    padding: 7px 10px;

    border: 1px solid var(--cor-borda-forte);
    border-radius: 7px;

    background: var(--cor-superficie);
    color: var(--cor-texto-medio);

    font-size: 12px;
    font-weight: 600;

    cursor: pointer;
}


.botao-acao:hover {
    background: var(--cor-superficie-alt);
}


.botao-perigo {
    color: var(--cor-perigo);

    border-color: var(--cor-perigo-borda);
}


.botao-perigo:hover {
    background: var(--cor-perigo-fundo);
}


.dados-conta {
    display: grid;

    grid-template-columns: 1fr 1fr;

    gap: 16px;

    padding-top: 18px;

    border-top: 1px solid var(--cor-borda);
}


.dados-conta span {
    display: block;

    margin-bottom: 5px;

    color: var(--cor-texto-suave);

    font-size: 12px;
}


.dados-conta strong {
    font-size: 18px;

    color: var(--cor-texto-forte);
}


.botao-vazio {
    margin-top: 20px;
}


/* =========================
   MODAL
   ========================= */

.modal {
    position: fixed;

    inset: 0;

    z-index: 1000;

    display: flex;

    align-items: center;
    justify-content: center;

    padding: 20px;

    background: var(--cor-overlay);
}


.modal-conteudo {
    width: 100%;

    max-width: 560px;

    max-height: 90vh;

    overflow-y: auto;

    padding: 28px;

    background: var(--cor-superficie);

    border-radius: 14px;

    box-shadow: var(--sombra-modal);
}


.modal-cabecalho {
    display: flex;

    align-items: flex-start;
    justify-content: space-between;

    gap: 20px;

    margin-bottom: 26px;
}


.modal-cabecalho h2 {
    margin-bottom: 5px;

    font-size: 21px;

    color: var(--cor-texto-forte);
}


.modal-cabecalho p {
    color: var(--cor-texto-suave);

    font-size: 13px;
}


.botao-fechar {
    width: 32px;
    height: 32px;

    border: none;
    border-radius: 7px;

    background: var(--cor-superficie-alt);
    color: var(--cor-texto-medio);

    font-size: 24px;

    line-height: 1;

    cursor: pointer;
}


.botao-fechar:hover {
    background: var(--cor-borda-forte);
}


.campo textarea {
    width: 100%;

    padding: 12px 14px;

    border: 1px solid var(--cor-borda-forte);
    border-radius: 8px;

    background: var(--cor-superficie);
    color: var(--cor-texto);

    font-family: inherit;

    font-size: 14px;

    resize: vertical;

    outline: none;
}


.campo textarea:focus {
    border-color: var(--cor-foco);

    box-shadow:
        0 0 0 3px var(--cor-anel-foco);
}


.campos-duplos {
    display: grid;

    grid-template-columns: 1fr 1fr;

    gap: 16px;
}


.opcoes-conta {
    display: flex;

    flex-direction: column;

    gap: 13px;

    margin-top: 8px;
}


.opcao-checkbox {
    display: flex;

    align-items: center;

    gap: 10px;

    color: var(--cor-texto-medio);

    font-size: 14px;

    cursor: pointer;
}


.opcao-checkbox input {
    width: 16px;
    height: 16px;

    cursor: pointer;
}


.modal-acoes {
    display: flex;

    justify-content: flex-end;

    gap: 10px;

    margin-top: 25px;

    padding-top: 20px;

    border-top: 1px solid var(--cor-borda);
}


/* Caixa de escolha (js/caixa-escolha.js): a pergunta que substituiu os
   `prompt("digite 1, 2 ou 3")`. Cada resposta é um botão largo, com
   espaço para dizer o que vai acontecer — que era o que faltava. */

.modal-estreito {
    max-width: 460px;
}


/* Fluxo "De → Para" do modal de mover transações (js/categorias.js).
   Duas pontas com quebra clara entre elas e a seta apontando o sentido. */
.fluxo-mover {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.ponta-mover {
    border: 1px solid var(--cor-borda);
    border-radius: 10px;
    padding: 12px 14px 4px;
    margin: 0;
}

.ponta-mover legend {
    padding: 0 6px;
    font-size: 12px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--cor-texto-suave);
}

.seta-mover {
    align-self: center;
    font-size: 20px;
    line-height: 1;
    color: var(--cor-texto-suave);
}


/* =========================
   LISTA ORDENÁVEL (js/ordenador-lista.js)

   A tela de "Configurar ordem". A alça é o único ponto por onde se
   arrasta: `touch-action: none` só nela deixa o resto da lista rolar
   normalmente com o dedo.
   ========================= */

.lista-ordenavel {
    display: flex;

    flex-direction: column;

    gap: 6px;

    max-height: 55vh;

    overflow-y: auto;
}


.item-ordenavel {
    display: flex;

    align-items: center;

    gap: 10px;

    padding: 10px 12px;

    background: var(--cor-superficie-suave);

    border: 1px solid var(--cor-borda);
    border-radius: 8px;
}


.item-ordenavel.sendo-arrastado {
    background: var(--cor-primaria-suave);

    border-color: var(--cor-primaria);

    /* Some a sombra do dedo: a linha em movimento precisa se distinguir
       das paradas sem mudar de tamanho, senão as vizinhas dançam. */
    box-shadow: var(--sombra-modal);
}


.alca-ordenacao {
    padding: 6px 4px;

    background: none;
    border: none;

    color: var(--cor-texto-suave);

    font-size: 18px;
    line-height: 1;

    cursor: grab;

    /* O navegador não pode interpretar o arrasto como rolagem. */
    touch-action: none;
}


.alca-ordenacao:active {
    cursor: grabbing;
}


.dados-item-ordenavel {
    display: flex;

    flex-direction: column;

    min-width: 0;
    flex: 1;
}


.dados-item-ordenavel strong {
    overflow: hidden;

    color: var(--cor-texto-forte);

    font-size: 14px;

    text-overflow: ellipsis;
    white-space: nowrap;
}


.dados-item-ordenavel small {
    font-size: 11px;
}


.setas-ordenacao {
    display: flex;

    gap: 4px;
}


.setas-ordenacao button {
    width: 30px;
    height: 30px;

    background: var(--cor-superficie);

    color: var(--cor-texto-medio);

    border: 1px solid var(--cor-borda);
    border-radius: 6px;

    cursor: pointer;
}


.setas-ordenacao button:hover {
    border-color: var(--cor-borda-forte);
}


/* Uma pergunta feita por cima de outro modal. Sem z-index próprio, quem
   vence é quem foi criado por último — e a ordem de criação depende de
   por qual tela o usuário entrou. */
.modal-acima {
    z-index: 1100;
}


/* Painel de lançamentos (js/painel-movimentacoes.js): uma consulta
   filtrada numa janela menor por cima da tela. Fica ABAIXO de .modal
   (1000, o formulário de lançamento) e de .modal-acima (1100, as caixas
   de escolha/valor) — o formulário aberto a partir do painel precisa
   vir por cima dele. */
.painel-consulta {
    z-index: 950;
}


/* Leitor de cupom fiscal (js/leitor-cupom.js): a câmera abre por cima
   do formulário de lançamento (.modal, 1000), abaixo do menu de ações
   (1200, que já fechou quando o leitor abre). */
.leitor-cupom {
    position: fixed;
    inset: 0;
    z-index: 1150;

    display: flex;
    align-items: center;
    justify-content: center;

    padding: 20px;

    background: var(--cor-overlay);
}

.leitor-cupom-conteudo {
    width: 100%;
    max-width: 460px;

    padding: 24px;

    background: var(--cor-superficie);
    border-radius: 14px;
    box-shadow: var(--sombra-modal);
}

.leitor-cupom-visor {
    position: relative;

    width: 100%;
    aspect-ratio: 4 / 3;

    overflow: hidden;

    background: #000;
    border-radius: 10px;
}

.leitor-cupom-visor video {
    width: 100%;
    height: 100%;

    object-fit: cover;
}

/* Moldura de mira sobre o vídeo — só indica onde encostar o QR. */
.leitor-cupom-mira {
    position: absolute;
    inset: 18% 22%;

    border: 2px solid rgba(255, 255, 255, 0.85);
    border-radius: 8px;

    pointer-events: none;
}

/* Lanterna e troca de câmera — só aparecem quando o aparelho oferece
   (js/leitor-cupom.js liga/desliga o [hidden]). */
.leitor-cupom-ferramentas {
    position: absolute;
    right: 10px;
    bottom: 10px;

    display: flex;
    flex-direction: column;
    gap: 8px;
}

.leitor-cupom-ferramenta {
    width: 40px;
    height: 40px;

    display: flex;
    align-items: center;
    justify-content: center;

    font-size: 18px;
    line-height: 1;

    background: rgba(0, 0, 0, 0.55);
    color: #fff;
    border: 1px solid rgba(255, 255, 255, 0.4);
    border-radius: 999px;
    cursor: pointer;
}

.leitor-cupom-ferramenta.ativo {
    background: var(--cor-primaria);
    border-color: var(--cor-primaria);
}

.leitor-cupom-status {
    margin: 14px 0 4px;

    font-size: 13px;
    text-align: center;
    color: var(--cor-texto-medio);
}

.leitor-cupom-status-erro {
    color: var(--cor-despesa);
}

.leitor-cupom-acoes {
    display: flex;
    justify-content: center;

    margin-top: 12px;
}

/* Só a lista rola; cabeçalho, barra de mês, fichas e totais ficam fixos
   (`flex-shrink: 0`) — sem isso a faixa de totais era espremida por uma
   lista longa e os valores cortavam. `overflow: visible` para o
   painelzinho de mês (.painel-periodo, position:absolute) não ser
   cortado. */
.modal-painel-consulta {
    display: flex;
    flex-direction: column;

    max-width: 520px;
    max-height: 85vh;

    overflow: visible;
}

.modal-painel-consulta > *:not(#pm-lista) {
    flex-shrink: 0;
}

.modal-painel-consulta #pm-lista {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
}

.modal-painel-consulta .barra-periodo {
    margin-bottom: 14px;
}

.modal-painel-consulta .fichas-filtro {
    margin-bottom: 14px;
}

.pm-cabecalho-acoes {
    display: flex;
    align-items: center;
    gap: 10px;
}

.pm-cabecalho-acoes .link-discreto {
    color: var(--cor-texto-suave);
    font-size: 13px;
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
}

.pm-cabecalho-acoes .link-discreto:hover {
    color: var(--cor-primaria);
}


/* A pergunta da fatura paga tem duas quebras de parágrafo (`\n\n`) no
   meio do texto — sem isto o `textContent` de `CaixaEscolha` as ignora
   e tudo vira uma linha só. */
#ce-texto {
    white-space: pre-line;
}


.lista-escolhas {
    display: flex;

    flex-direction: column;

    gap: 10px;
}


.opcao-escolha {
    display: flex;

    flex-direction: column;

    gap: 3px;

    width: 100%;

    padding: 14px 16px;

    text-align: left;

    background: var(--cor-superficie-suave);

    color: var(--cor-texto);

    border: 1px solid var(--cor-borda);
    border-radius: 10px;

    cursor: pointer;

    transition: border-color .15s, background .15s;
}


.opcao-escolha:hover {
    background: var(--cor-superficie-alt);

    border-color: var(--cor-borda-forte);
}


.opcao-escolha:focus-visible {
    outline: 2px solid var(--cor-foco);

    outline-offset: 2px;
}


.opcao-escolha strong {
    color: var(--cor-texto-forte);

    font-size: 15px;
}


.opcao-escolha small {
    font-size: 12px;

    line-height: 1.4;
}


/* A faixa lateral usa a paleta de tipo de transação, como o resto do
   app: a escolha destrutiva não fica vermelha por decoração. */
.opcao-escolha.tipo-despesa {
    border-left: 4px solid var(--cor-despesa);
}


.opcao-escolha.tipo-receita {
    border-left: 4px solid var(--cor-receita);
}


.opcao-escolha.tipo-transferencia {
    border-left: 4px solid var(--cor-transferencia);
}


/* =========================
   RESPONSIVO - CONTAS
   ========================= */

@media (max-width: 900px) {

    .lista-contas {
        grid-template-columns: 1fr;
    }

}


@media (max-width: 600px) {

    .cabecalho-contas {
        flex-direction: column;

        align-items: stretch;
    }


    .cabecalho-contas .botao-principal {
        width: 100%;
    }


    /* O cabeçalho de um card **não** empilha no celular. Ele empilhava
       porque o segundo item era uma faixa de dois ou três botões, que
       não cabia ao lado do nome; agora é o `⋮`, de 34px, e empilhá-lo
       deixaria um botão solto embaixo do nome, como se fosse conteúdo
       do card. */


    .acoes-conta {
        width: 100%;
    }


    /* As setas de mês não esticam. `.botao-acao { flex: 1 }` logo
       abaixo serve à faixa de botões de um card, onde esticar é o que
       se quer; na barra de mês ele transformava `‹` e `›` em dois
       blocos de 130px e a barra deixava de parecer uma barra. Em
       movimentações isso não acontecia por acidente de layout — lá a
       barra vive dentro de `.barra-comando`, que é coluna e a encolhe
       ao conteúdo. Agora as cinco telas ficam iguais por regra, e não
       por acidente. */
    .barra-periodo .botao-acao {
        flex: 0 0 auto;
    }


    /* Exceção: `.acoes-conta` tem dois papéis. No rodapé de um card
       (contas, cartões, categorias) ela é a faixa de botões, e esticar
       para 100% no celular é justamente o que se quer. Na linha de
       lançamento (dashboard, tela da conta, tela do cartão) ela é só a
       lixeira ao final — ali o 100% consome a linha inteira, a descrição
       colapsa para largura zero e a lixeira encosta no valor em vez de
       ir ao fim. Medido a 412px: `.dados-movimentacao` ficava com 0px e
       `.acoes-conta` com 208px. */
    .item-movimentacao .acoes-conta {
        width: auto;
        flex: 0 0 auto;
    }


    .botao-acao {
        flex: 1;
    }


    .botao-lixeira {
        flex: 0 0 auto;
    }


    .campos-duplos {
        grid-template-columns: 1fr;
    }


    .modal-conteudo {
        padding: 20px;
    }

}


/* =========================
   LISTAS AUXILIARES
   ========================= */

.item-perfil-painel,
.item-compartilhamento,
.item-inativo {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    padding: 12px;
    border: 1px solid var(--cor-borda);
    border-radius: 9px;
    margin-top: 8px;
}

.item-perfil-painel > div:first-child,
.item-compartilhamento > div:first-child,
.item-inativo > div:first-child {
    display: flex;
    flex-direction: column;
}

.item-perfil-painel small,
.item-compartilhamento small,
.item-inativo small {
    color: var(--cor-texto-suave);
}

.acoes-perfil-painel,
.acoes-inativo {
    display: flex;
    gap: 8px;
    align-items: center;
}

.acoes-cabecalho-contas {
    display: flex;
    gap: 10px;
    align-items: center;
}

/* ---- Calculadora do campo de valor ---- */

.campo-com-calculadora {
    position: relative;
    display: flex;
    align-items: center;
    gap: 8px;
}


.campo-com-calculadora > input {
    flex: 1;
    min-width: 0;
}


.botao-calculadora {
    width: 40px;
    height: 40px;
    flex: 0 0 auto;

    border: 1px solid var(--cor-borda-forte);
    border-radius: 8px;

    background: var(--cor-superficie);
    color: var(--cor-texto-medio);

    font-family: inherit;
    font-size: 14px;
    font-weight: 700;

    cursor: pointer;
}


.botao-calculadora:hover {
    background: var(--cor-superficie-alt);
    color: var(--cor-texto-forte);
}


.painel-calculadora {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    z-index: 1100;

    width: min(280px, calc(100vw - 48px));

    border: 1px solid var(--cor-borda-forte);
    border-radius: 12px;

    background: var(--cor-superficie);
    box-shadow: var(--sombra-modal);

    overflow: hidden;
}


.topo-calculadora {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 2px;

    padding: 12px 14px;

    border-bottom: 1px solid var(--cor-borda);

    background: var(--cor-superficie-alt);
}


.conta-calculadora {
    min-height: 14px;
    font-size: 12px;
    color: var(--cor-texto-suave);
}


.visor-calculadora {
    font-size: 24px;
    font-weight: 700;
    color: var(--cor-texto-forte);

    font-variant-numeric: tabular-nums;
}


.teclas-calculadora {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1px;

    background: var(--cor-borda);
}


.teclas-calculadora button {
    padding: 14px 0;

    border: 0;

    background: var(--cor-superficie);
    color: var(--cor-texto-forte);

    font-family: inherit;
    font-size: 17px;

    cursor: pointer;
}


.teclas-calculadora button:hover {
    background: var(--cor-superficie-alt);
}


.teclas-calculadora .tecla-operacao,
.teclas-calculadora .tecla-apagar {
    color: var(--cor-primaria-contraste);
    font-weight: 700;
}


.teclas-calculadora .tecla-apagar {
    font-size: 13px;
}


.teclas-calculadora .tecla-confirmar {
    /* Ocupa a linha inteira: é a tecla que encerra a conta. */
    grid-column: 1 / -1;

    background: var(--cor-primaria);
    color: var(--cor-primaria-texto);
    font-size: 14px;
    font-weight: 700;
}


.teclas-calculadora .tecla-confirmar:hover {
    background: var(--cor-primaria-hover);
}


.botao-opcoes {
    width: 42px;
    height: 42px;
    border: 1px solid var(--cor-borda-forte);
    border-radius: 8px;
    background: var(--cor-superficie);
    color: var(--cor-texto-medio);
    font-size: 24px;
    cursor: pointer;
}

.botao-opcoes:hover {
    background: var(--cor-superficie-alt);
}


/* O menu do ⋮. O container do cabeçalho precisa de `position: relative`
   para o menu ancorar nele em vez de na página. */
.acoes-cabecalho-contas {
    position: relative;
}



.opcao-menu {
    display: flex;
    align-items: flex-start;
    gap: 10px;

    padding: 12px 14px;

    border-bottom: 1px solid var(--cor-borda);

    font-size: 13px;
    line-height: 1.45;
    color: var(--cor-texto);

    cursor: pointer;
}


.opcao-menu:hover {
    background: var(--cor-superficie-alt);
}


.opcao-menu input[type="checkbox"] {
    width: 16px;
    height: 16px;
    margin-top: 2px;
    flex: 0 0 auto;
    cursor: pointer;
}


.opcao-menu small {
    display: block;
    margin-top: 4px;
    font-size: 12px;
    line-height: 1.4;
}


.botao-excluir-inativo {
    border: 0;
    border-radius: 7px;
    padding: 8px 11px;
    background: var(--cor-perigo-suave);
    color: var(--cor-perigo-forte);
    font-weight: 600;
    cursor: pointer;
}

.botao-excluir-inativo:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}


/* =========================
   USUARIO / PERFIS
   ========================= */

.usuario-logado {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    margin-top: auto;
    padding: 10px 9px;
    border: 0;
    border-radius: 10px;
    background: transparent;
    color: var(--cor-menu-texto-forte);
    font-family: inherit;
    text-align: left;
    cursor: pointer;
}

.usuario-logado:hover {
    background: var(--cor-menu-item);
}

.usuario-foto {
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: var(--cor-menu-realce);
    flex: 0 0 auto;
}

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

.usuario-dados strong,
.usuario-dados small {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.usuario-dados small {
    color: var(--cor-menu-texto-suave);
    font-size: 11px;
}

.seletor-perfil-linha {
    display: flex;
    gap: 7px;
    align-items: center;
}

.seletor-perfil-linha select {
    flex: 1;
    min-width: 0;
}

.botao-adicionar-perfil {
    width: 36px;
    height: 36px;
    border: 1px solid var(--cor-menu-borda);
    border-radius: 8px;
    background: var(--cor-menu-item);
    color: var(--cor-menu-texto-forte);
    font-size: 22px;
    line-height: 1;
    cursor: pointer;
}

.botao-adicionar-perfil:hover {
    background: var(--cor-menu-realce);
}

.painel-usuario {
    position: fixed;
    inset: 0;
    z-index: 2000;
    display: flex;
    justify-content: flex-end;
    background: var(--cor-overlay);
}

.painel-usuario-conteudo {
    width: min(420px, 94vw);
    height: 100%;
    padding: 24px;
    background: var(--cor-superficie);
    box-shadow: var(--sombra-painel);
    display: flex;
    flex-direction: column;
    overflow-y: auto;
}

.painel-usuario-cabecalho {
    display: flex;
    align-items: center;
    gap: 12px;
    padding-bottom: 22px;
    border-bottom: 1px solid var(--cor-borda);
}

.painel-usuario-cabecalho > div {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.painel-usuario-cabecalho strong {
    font-size: 20px;
    color: var(--cor-texto-forte);
}

.painel-usuario-cabecalho small {
    color: var(--cor-texto-suave);
    margin-top: 3px;
}

.painel-usuario-cabecalho .usuario-foto {
    background: var(--cor-superficie-alt);
}

.usuario-foto-grande {
    width: 52px;
    height: 52px;
}

.botao-fechar-painel {
    border: 0;
    background: transparent;
    color: var(--cor-texto-forte);
    font-size: 28px;
    line-height: 1;
    cursor: pointer;
}

.menu-usuario-opcoes {
    padding-top: 18px;
}

.opcao-menu-usuario {
    display: flex;
    align-items: center;
    gap: 13px;
    padding: 14px;
    border: 1px solid var(--cor-borda);
    border-radius: 10px;
    color: var(--cor-texto-forte);
    text-decoration: none;
}

.opcao-menu-usuario:hover {
    background: var(--cor-superficie-suave);
}

.opcao-menu-usuario > span {
    font-size: 23px;
}

.opcao-menu-usuario > div {
    flex: 1;
    display: flex;
    flex-direction: column;
}

.opcao-menu-usuario small {
    color: var(--cor-texto-suave);
    margin-top: 3px;
}

.opcao-menu-usuario > b {
    font-size: 22px;
    color: var(--cor-texto-suave);
}

/* "Segurança": linha expansível no painel do usuário, no padrão de
   accordion. A linha reusa `.opcao-menu-usuario`; só falta o reset de
   botão e o espaçamento entre os itens do menu. */
.menu-usuario-opcoes > * + * {
    margin-top: 10px;
}

.linha-seguranca {
    width: 100%;
    background: transparent;
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.corpo-seguranca {
    margin-top: 10px;
    padding: 16px;
    border: 1px solid var(--cor-borda);
    border-radius: 10px;
    background: var(--cor-superficie-suave);
}

.corpo-seguranca[hidden] {
    display: none;
}

.form-seguranca + .form-seguranca {
    margin-top: 22px;
    padding-top: 22px;
    border-top: 1px solid var(--cor-borda);
}

.form-seguranca h4 {
    margin: 0 0 12px;
    font-size: 14px;
    color: var(--cor-texto-forte);
}

.form-seguranca .campo {
    margin-bottom: 12px;
}

.aviso-seguranca {
    margin: 0 0 12px;
    padding: 10px 12px;
    border-radius: 8px;
    border: 1px solid var(--cor-transferencia, #d9a441);
    background: var(--cor-transferencia-suave, rgba(217, 164, 65, 0.12));
    color: var(--cor-texto-forte);
    font-size: 12.5px;
    line-height: 1.4;
}

.botao-seguranca {
    width: 100%;
    padding: 11px;
    border: none;
    border-radius: 8px;
    background: var(--cor-primaria);
    color: var(--cor-primaria-texto);
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
}

.botao-seguranca:hover {
    background: var(--cor-primaria-hover);
}

.botao-seguranca:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

.mensagem-seguranca {
    margin: 10px 0 0;
    min-height: 16px;
    font-size: 13px;
    color: var(--cor-perigo);
}

.mensagem-seguranca.ok {
    color: var(--cor-receita, #159a46);
}

.aviso-email-confirmar {
    margin: 0 0 10px;
    padding: 12px;
    border-radius: 10px;
    border: 1px solid var(--cor-transferencia, #d9a441);
    background: var(--cor-transferencia-suave, rgba(217, 164, 65, 0.12));
}

.aviso-email-confirmar strong {
    display: block;
    font-size: 13.5px;
    margin-bottom: 3px;
}

.aviso-email-confirmar small {
    display: block;
    font-size: 12px;
    line-height: 1.4;
    color: var(--cor-texto);
    margin-bottom: 10px;
}

.aviso-email-confirmar .botao-seguranca {
    width: auto;
    padding: 8px 16px;
    font-size: 13px;
}

/* Ponto de pendência no botão do usuário (e-mail não confirmado). */
#botao-usuario.tem-pendencia {
    position: relative;
}

#botao-usuario.tem-pendencia::after {
    content: "";
    position: absolute;
    top: 2px;
    right: 2px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--cor-transferencia, #d9a441);
    border: 1px solid var(--cor-fundo);
}

.painel-usuario-rodape {
    margin-top: auto;
    padding-top: 18px;
    border-top: 1px solid var(--cor-borda);
}

.botao-sair-painel {
    width: 100%;
    padding: 11px;
    border: 0;
    border-radius: 8px;
    background: var(--cor-menu-realce);
    color: var(--cor-menu-texto-forte);
    font-family: inherit;
    font-weight: 600;
    cursor: pointer;
}

.botao-sair-painel:hover {
    background: var(--cor-menu-realce-hover);
}


/* =========================
   SELETOR DE TEMA
   ========================= */

.bloco-tema {
    padding-top: 18px;
}

.bloco-tema > label {
    display: block;
    margin-bottom: 9px;
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--cor-texto-suave);
}

.opcoes-tema {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 6px;
    padding: 4px;
    border: 1px solid var(--cor-borda);
    border-radius: 10px;
    background: var(--cor-superficie-suave);
}

.botao-tema {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 5px;
    padding: 10px 6px;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: var(--cor-texto-medio);
    font-family: inherit;
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
}

.botao-tema span {
    font-size: 19px;
    line-height: 1;
}

.botao-tema:hover {
    background: var(--cor-superficie-alt);
}

.botao-tema.ativo {
    background: var(--cor-primaria);
    color: var(--cor-primaria-texto);
}


/* =========================
   GERENCIAMENTO DE PERFIS
   ========================= */

.lista-perfis-gerenciamento {
    display: grid;
    gap: 14px;
}

.secao-perfis-compartilhados {
    margin-top: 22px;
}

.cartao-perfil-gerenciamento {
    padding: 18px;
    border: 1px solid var(--cor-borda);
    border-radius: 12px;
    background: var(--cor-superficie);
}

.cabecalho-perfil-gerenciamento {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 15px;
}

.titulo-perfil-gerenciamento {
    display: flex;
    align-items: center;
    gap: 12px;
}

.icone-perfil {
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: var(--cor-icone-perfil);
    flex: 0 0 auto;
}

.titulo-perfil-gerenciamento h3 {
    margin: 0;
    font-size: 17px;
    color: var(--cor-texto-forte);
}

.titulo-perfil-gerenciamento small {
    display: block;
    color: var(--cor-texto-suave);
    margin-top: 4px;
}

.status-perfil {
    padding: 4px 9px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 700;
}

.status-perfil.ativo {
    background: var(--cor-sucesso-fundo);
    color: var(--cor-sucesso-texto);
}

.status-perfil.inativo {
    background: var(--cor-superficie-alt);
    color: var(--cor-texto-suave);
}

.acoes-perfil-gerenciamento {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    margin-top: 16px;
    padding-top: 14px;
    border-top: 1px solid var(--cor-borda);
}

.titulo-secao-perfis {
    margin-bottom: 16px;
}

.titulo-secao-perfis p,
.secao-perfis-compartilhados > div:first-child p {
    color: var(--cor-texto-suave);
}

.linha-email-compartilhar {
    display: flex;
    gap: 8px;
}

.linha-email-compartilhar input {
    flex: 1;
}

.item-compartilhamento-pagina {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 12px 0;
    border-bottom: 1px solid var(--cor-borda);
}

.item-compartilhamento-pagina > div:first-child {
    display: flex;
    flex-direction: column;
}

.item-compartilhamento-pagina small {
    color: var(--cor-texto-suave);
}

.acoes-compartilhamento-pagina {
    display: flex;
    gap: 6px;
}

.opcoes-permissoes {
    display: flex;
    flex-direction: column;
    gap: 13px;
    padding: 5px 0;
}

.opcoes-permissoes label {
    display: flex;
    align-items: center;
    gap: 9px;
}

.mensagem-formulario {
    color: var(--cor-perigo);
    font-size: 13px;
    min-height: 18px;
}

.texto-suave {
    color: var(--cor-texto-suave);
}


/* =========================
   IDENTIDADE POR TIPO

   Despesa = vermelho, receita = verde, transferência = amarelo.
   Aplique `tipo-despesa` / `tipo-receita` / `tipo-transferencia` junto
   com a classe base do componente (`botao-principal`, `etiqueta-tipo`).
   ========================= */

.botao-principal.tipo-despesa {
    background: var(--cor-despesa);
    color: var(--cor-despesa-texto);
}

.botao-principal.tipo-despesa:hover {
    background: var(--cor-despesa-hover);
}

.botao-principal.tipo-receita {
    background: var(--cor-receita);
    color: var(--cor-receita-texto);
}

.botao-principal.tipo-receita:hover {
    background: var(--cor-receita-hover);
}

.botao-principal.tipo-transferencia {
    background: var(--cor-transferencia);
    color: var(--cor-transferencia-texto);
}

.botao-principal.tipo-transferencia:hover {
    background: var(--cor-transferencia-hover);
}


/* Selo textual, para listas e resumos. */
.etiqueta-tipo {
    display: inline-block;
    padding: 3px 9px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 700;
}

.etiqueta-tipo.tipo-despesa {
    background: var(--cor-despesa-suave);
    color: var(--cor-despesa-contraste);
}

.etiqueta-tipo.tipo-receita {
    background: var(--cor-receita-suave);
    color: var(--cor-receita-contraste);
}

.etiqueta-tipo.tipo-transferencia {
    background: var(--cor-transferencia-suave);
    color: var(--cor-transferencia-contraste);
}


/* Faixa lateral, para cartões e itens de lista. */
.borda-tipo-despesa {
    border-left: 4px solid var(--cor-despesa);
}

.borda-tipo-receita {
    border-left: 4px solid var(--cor-receita);
}

.borda-tipo-transferencia {
    border-left: 4px solid var(--cor-transferencia);
}


/* =========================
   CARTÕES
   ========================= */

.lista-cartoes {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));

    /* Masonry — ver js/masonry.js e a nota em .lista-contas. */
    --masonry-gap: 20px;
    grid-auto-rows: 1px;
    column-gap: 20px;
    row-gap: 0;
    align-items: start;
}

.cartao-cartao {
    padding: 24px;
    background: var(--cor-superficie);
    border-radius: 12px;
    box-shadow: var(--sombra-cartao);
}

.dados-cartao {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 16px;
    padding-top: 18px;
    border-top: 1px solid var(--cor-borda);
}

/* Sem adicionais só existe o total, e três colunas deixariam-no
   espremido num terço do card. */
.dados-cartao-simples {
    grid-template-columns: minmax(0, 1fr);
}


/* Limite, em aberto, próxima e demais: contexto, não decisão. Ficam
   numa faixa de linhas pequenas abaixo do destaque. */
.contexto-fatura {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 16px;
    margin-top: 12px;
}

.contexto-fatura small {
    font-size: 12px;
}


/* `minmax(0, 1fr)` deixa a coluna encolher, mas o número ("R$ 6.781,48")
   é um token largo e vazava do card na grade estreita de 2 colunas.
   Quebra na folga do valor e, se não couber, no dígito. */
.dados-cartao > div {
    min-width: 0;
}

.dados-cartao span {
    display: block;
    margin-bottom: 5px;
    color: var(--cor-texto-suave);
    font-size: 12px;
}

.dados-cartao strong {
    font-size: 17px;
    color: var(--cor-texto-forte);
    overflow-wrap: anywhere;
}

/* Card do adicional, aninhado dentro do card do principal. */
.lista-adicionais {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin-top: 18px;
    padding-top: 18px;
    border-top: 1px solid var(--cor-borda);
}

.cartao-adicional {
    padding: 16px;
    border-radius: 10px;
    background: var(--cor-superficie-suave);
}

.cartao-adicional .titulo-conta {
    flex-wrap: wrap;
    gap: 8px;
}

.cartao-adicional .titulo-conta strong {
    font-size: 15px;
    color: var(--cor-texto-forte);
}

.cartao-adicional .cabecalho-conta {
    margin-bottom: 14px;
}

.dados-cartao-adicional {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    padding-top: 14px;
}

.dados-cartao-adicional strong {
    font-size: 15px;
}

/* O aninhamento precisa de realce próprio para o hover não confundir
   com o do card externo. */
.cartao-adicional.cartao-clicavel:hover {
    border-color: var(--cor-primaria);
    background: var(--cor-superficie-alt);
}


/* Selos do cartão: perfil vinculado e exclusão dos totais. */
.etiqueta-compartilhado,
.etiqueta-neutra {
    padding: 3px 8px;
    border-radius: 999px;
    font-size: 10px;
    font-weight: 700;
    white-space: nowrap;
}

.etiqueta-compartilhado {
    background: var(--cor-primaria-suave);
    color: var(--cor-primaria-contraste);
}

.etiqueta-neutra {
    background: var(--cor-superficie-alt);
    color: var(--cor-texto-suave);
}


/* O "i" do card, no lugar do parágrafo que ele substituiu (item 12).

   É um `<button>`, e não um `<span>`, porque a informação precisa
   continuar alcançável pelo teclado — um `title` num elemento que não
   recebe foco só existe para quem usa mouse. Do tamanho de um selo, ao
   lado do nome, para não voltar a disputar linha com o dado. */
.selo-informacao {
    width: 16px;
    height: 16px;
    padding: 0;
    border: 1px solid var(--cor-borda-forte);
    border-radius: 999px;
    background: transparent;
    color: var(--cor-texto-suave);
    font-size: 10px;
    font-weight: 700;
    line-height: 1;
    cursor: help;
    flex: none;
}

.selo-informacao:hover,
.selo-informacao:focus-visible {
    border-color: var(--cor-primaria);
    color: var(--cor-primaria);
}


/* Cartões que vieram de outro perfil, na tela "Compartilhados". */
.cartao-compartilhado {
    border: 1px dashed var(--cor-borda-forte);
    box-shadow: none;
}

.aviso-compartilhado {
    margin-top: 16px;
    padding-top: 14px;
    border-top: 1px solid var(--cor-borda);
    font-size: 12px;
}


/* A pendência não é nota de rodapé: ela pede uma ação, e some assim que
   a conta é ligada. Cor de despesa porque é uma fatura sem de onde
   sair — o mesmo vermelho que o app usa para dinheiro que falta. */
.aviso-pendencia {
    margin-top: 8px;
    padding-top: 0;
    border-top: none;
    color: var(--cor-despesa-contraste);
    font-weight: 600;
}


/* =========================
   MOVIMENTAÇÕES
   ========================= */

.barra-periodo {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    margin-bottom: 22px;
    flex-wrap: wrap;

    /* Âncora do painel de mês e ano, que abre logo abaixo do rótulo. */
    position: relative;
}


/* O `display: flex` acima venceria o `[hidden] { display: none }` do
   navegador — as duas regras têm a mesma especificidade e a do autor vem
   depois. Sem isto, esconder a barra pelo atributo não surte efeito. */
.barra-periodo[hidden] {
    display: none;
}

/* Mesmo caso: `.campos-duplos { display: grid }` venceria o
   `[hidden] { display: none }` do navegador. Sem isto, o par de datas do
   orçamento mensal não some. */
.campos-duplos[hidden] {
    display: none;
}


/* Seletor de mês e ano — ver js/navegador-periodo.js */

.rotulo-periodo-clicavel {
    cursor: pointer;
    padding: 4px 10px;
    border-radius: 8px;
    border: 1px solid transparent;

    /* Segurar para abrir o painel: sem isto o Android começa a seleção
       de texto por cima do gesto e mostra a alça azul de seleção. */
    -webkit-user-select: none;
    user-select: none;
    -webkit-touch-callout: none;

    /* O gesto usa pointermove para distinguir rolagem de clique longo.
       `touch-action: manipulation` mantém a rolagem funcionando e tira o
       atraso do duplo-toque para zoom. */
    touch-action: manipulation;
}


/* No mês vigente o clique curto não tem para onde ir. A borda pontilhada
   diz isso antes do toque, em vez de deixar o usuário achar que quebrou. */
.rotulo-periodo-clicavel.periodo-vigente {
    border-style: dashed;
    border-color: var(--cor-borda);
}

.rotulo-periodo-clicavel:hover,
.rotulo-periodo-clicavel:focus-visible {
    border-color: var(--cor-borda-forte);
    background: var(--cor-superficie);
}

.painel-periodo {
    position: absolute;
    top: calc(100% + 6px);

    /* Centralizado sobre a barra, e não colado à esquerda dela. A barra
       ocupa a largura inteira em contas, cartões e categorias, então
       `left: 0` jogava o painel para o canto da tela enquanto o rótulo
       que o abriu ficava no meio — parecia um painel de outra coisa. */
    left: 50%;
    transform: translateX(-50%);

    z-index: 30;
    min-width: 250px;
    padding: 12px;
    border: 1px solid var(--cor-borda);
    border-radius: 12px;
    background: var(--cor-superficie);
    box-shadow: var(--sombra-modal);
}

.navegador-ano {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 10px;
}

.navegador-ano strong {
    font-size: 15px;
    color: var(--cor-texto-forte);
}

.navegador-meses {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 6px;
}

.navegador-meses button {
    padding: 9px 0;
    border: 1px solid var(--cor-borda);
    border-radius: 8px;
    background: var(--cor-superficie-suave);
    color: var(--cor-texto);
    font-family: inherit;
    font-size: 13px;
    cursor: pointer;
}

.navegador-meses button:hover {
    border-color: var(--cor-primaria);
}

.navegador-meses button.mes-atual {
    background: var(--cor-primaria);
    border-color: var(--cor-primaria);
    color: var(--cor-primaria-texto);
}

.navegador-hoje {
    width: 100%;
    margin-top: 10px;
    padding: 8px 0;
    border: none;
    border-radius: 8px;
    background: transparent;
    color: var(--cor-primaria);
    font-family: inherit;
    font-size: 13px;
    cursor: pointer;
}

.navegador-hoje:hover {
    background: var(--cor-primaria-suave);
    color: var(--cor-primaria-contraste);
}


/* Fatura paga: o selo e o desfazer dividem o lugar do botão de pagar. */
.acoes-fatura-card {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}


/* Marcar o adicional na importação: a caixa e o seletor do
   principal andam juntos, e o seletor fica ao lado em vez de embaixo
   para o bloco do cartão não crescer uma linha por causa dele. */
.campo-adicional {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.campo-adicional label {
    display: flex;
    align-items: center;
    gap: 6px;
    white-space: nowrap;
}


/* Pagamentos de uma fatura. São vários porque a fatura aceita
   pagamento parcial e antecipado, e cada um precisa poder ser desfeito
   individualmente — desfazer "o pagamento" com três na lista não diz
   qual. Ocupa a linha inteira do container em flex, para a lista ficar
   abaixo dos botões em vez de ao lado deles. */
.lista-pagamentos-fatura {
    flex-basis: 100%;
    list-style: none;
    margin: 6px 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.linha-pagamento-fatura {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    padding: 8px 12px;
    border: 1px solid var(--cor-borda);
    border-radius: 8px;
    background: var(--cor-superficie-suave);
}

.linha-pagamento-fatura .valor-pagamento {
    font-weight: 600;
    color: var(--cor-texto-forte);
    font-variant-numeric: tabular-nums;
}

.linha-pagamento-fatura button {
    margin-left: auto;
}


/* Fatura em aberto no extrato da conta: previsão, não lançamento —
   por isso o traço em vez da borda cheia das linhas reais. */
.fatura-prevista {
    border-style: dashed;
    cursor: pointer;
}

.fatura-prevista:hover,
.linha-clicavel:hover {
    background: var(--cor-superficie-suave);
}

.linha-clicavel {
    cursor: pointer;
}


/* Cabeçalho que separa os grupos quando "em aberto primeiro" está
   marcado. Sem ele os dois grupos viram uma lista só e o agrupamento
   fica invisível. */
.grupo-extrato {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;

    padding: 8px 14px;

    border-bottom: 1px solid var(--cor-borda);

    background: var(--cor-superficie-alt);

    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;

    color: var(--cor-texto-medio);
}


/* Grupo de um cartão na tela de movimentações ("Agrupar despesas de
   cartões", item 2). Reusa `.cartao-expansivel` — mesmo abrir/fechar das
   telas de conta e categorias. O cabeçalho tem nome + contexto à
   esquerda e os totais da fatura à direita. */
.grupo-cartao-mov {
    margin-bottom: 10px;
}

.grupo-cartao-mov .cabecalho-expansivel {
    flex-wrap: wrap;
}

.grupo-cartao-info {
    flex: 1 1 auto;
    min-width: 0;

    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;

    padding: 0;
    border: 0;
    background: transparent;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.grupo-cartao-info strong {
    font-size: 14px;
}

.grupo-cartao-info small {
    font-size: 12px;
}

.grupo-cartao-totais {
    flex: 0 0 auto;

    font-size: 13px;
    color: var(--cor-texto-suave);
    text-align: right;
}

.grupo-cartao-mov .corpo-expansivel {
    padding: 0 8px 8px;
}

/* Item 3: o grupo por cartão da tela da fatura reusa `.grupo-cartao-mov`,
   mas com o nome/contexto num `.dados-movimentacao` simples (sem o
   `<button>` que navega — aqui já se está no cartão). Ele precisa crescer
   para empurrar o total à direita. */
#lista-fatura .grupo-cartao-mov .cabecalho-expansivel .dados-movimentacao {
    flex: 1 1 auto;
    min-width: 0;
}

/* "Agrupar despesas de cartões" na tela de conta (29/08): cada fatura do
   extrato vira um `.grupo-cartao-mov`, com o mesmo `.dados-movimentacao`
   entre o 💳 e o total — precisa crescer para empurrar o valor à direita.
   O corpo respira igual ao da tela da fatura. */
#lista-extrato .grupo-cartao-mov .cabecalho-expansivel .dados-movimentacao {
    flex: 1 1 auto;
    min-width: 0;
}

#lista-extrato .grupo-fatura-conta .corpo-expansivel .item-movimentacao {
    margin-bottom: 4px;
}


/* Relatório: cabeçalho recolhível do bloco de filtros. Ao aplicar um
   filtro salvo (clique no card ou deep link `?id=` do dashboard) os
   filtros vêm recolhidos, e o resultado fica logo abaixo sem rolagem. */
.rel-filtros-cabecalho {
    display: flex;
    align-items: center;
    gap: 10px;

    margin-bottom: 14px;
    cursor: pointer;
}

.rel-filtros-cabecalho strong {
    font-size: 15px;
    color: var(--cor-texto-forte);
}

.rel-filtros-cabecalho #rel-filtros-resumo {
    flex: 1 1 auto;
    min-width: 0;

    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;

    font-size: 13px;
}

#rel-formulario-filtro.filtros-recolhidos .rel-filtros-cabecalho {
    margin-bottom: 0;
}

#rel-filtros-corpo[hidden] {
    display: none;
}


/* Relatório: "Agrupar por" categoria/subcategoria (item novo) — mesmo
   `.cartao-expansivel` de sempre, com o rótulo crescendo para empurrar o
   subtotal à direita. */
.grupo-categoria-relatorio {
    margin-bottom: 10px;
}

.cabecalho-grupo-categoria strong {
    flex: 1 1 auto;
    min-width: 0;

    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.cabecalho-grupo-categoria span {
    flex: 0 0 auto;

    font-size: 13px;
    color: var(--cor-texto-suave);
}

.grupo-categoria-relatorio .corpo-expansivel {
    padding: 0 8px 8px;
}

.grupo-categoria-relatorio .corpo-expansivel .item-movimentacao {
    margin-bottom: 4px;
}

#lista-extrato .aviso-corpo-fatura {
    margin: 4px 6px;
    font-size: 13px;
}


/* Cabeçalho de dia. Gruda no topo do `.conteudo`, que é quem rola desde
   que a barra lateral foi travada — sem `position: sticky` aqui a data do
   bloco some assim que você entra nele.

   O total é o líquido do dia: receitas e estornos entram, despesas e
   pagamento de fatura saem, transferência não conta (é dinheiro andando
   entre contas do próprio perfil). */
.dia-extrato {
    position: sticky;
    top: 0;
    z-index: 2;

    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;

    padding: 9px 14px;

    border-bottom: 1px solid var(--cor-borda);

    background: var(--cor-superficie-alt);
}


.dia-extrato-data {
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;

    color: var(--cor-texto-medio);
}


.dia-extrato-total {
    font-size: 12px;
    font-weight: 600;
    white-space: nowrap;
}


/* Fim da lista desenhada: o observador dispara antes de ela aparecer, e
   o lote seguinte entra sem o usuário ver o vazio. */
.sentinela-lista {
    padding: 16px;

    text-align: center;

    font-size: 12.5px;
    color: var(--cor-texto-suave);
}


.grupo-extrato span:last-child {
    font-weight: 600;
    letter-spacing: 0;
    text-transform: none;
    color: var(--cor-texto-suave);
}


/* Excluir vira ícone: o card inteiro já abre a edição, então um botão
   com rótulo "Editar" ao lado seria um segundo caminho para a mesma
   ação, competindo com o clique no card. */
.botao-lixeira {
    display: flex;
    align-items: center;
    justify-content: center;

    width: 32px;
    height: 32px;
    flex: 0 0 auto;
    padding: 0;

    border: 1px solid var(--cor-perigo-borda);
    border-radius: 8px;

    background: var(--cor-superficie);
    color: var(--cor-perigo);

    font-size: 14px;
    line-height: 1;

    cursor: pointer;
}


.botao-lixeira:hover {
    background: var(--cor-superficie-alt);
}

.barra-periodo > strong {
    min-width: 160px;
    font-size: 17px;
    color: var(--cor-texto-forte);

    /* Largura mínima com texto centralizado: sem isto as setas andam
       para os lados conforme o nome do mês encolhe — "Maio de 2026"
       contra "Setembro de 2026" —, e a simetria se perde justamente ao
       navegar, que é quando ela seria notada. */
    text-align: center;
}

.item-movimentacao {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 13px 14px;
    border-bottom: 1px solid var(--cor-borda);
}

.item-movimentacao:last-child {
    border-bottom: 0;
}

.dados-movimentacao {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.dados-movimentacao strong {
    color: var(--cor-texto-forte);
}

.dados-movimentacao small {
    margin-top: 3px;
    font-size: 12px;
}

.marcador-efetivada {
    width: 26px;
    height: 26px;
    flex: 0 0 auto;
    border: 2px solid var(--cor-borda-forte);
    border-radius: 50%;
    background: transparent;
    color: transparent;
    font-size: 14px;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s;
}

.marcador-efetivada:hover {
    border-color: var(--cor-receita);
}

.marcador-efetivada.efetivada {
    border-color: var(--cor-receita);
    background: var(--cor-receita);
    color: var(--cor-receita-texto);
}

.valor-movimentacao {
    font-size: 16px;
    font-weight: 700;
    white-space: nowrap;
}

.valor-movimentacao.tipo-receita {
    color: var(--cor-receita-contraste);
}

.valor-movimentacao.tipo-despesa {
    color: var(--cor-despesa-contraste);
}

.valor-movimentacao.tipo-transferencia {
    color: var(--cor-transferencia-contraste);
}

.valor-positivo {
    color: var(--cor-receita-contraste);
}

.valor-negativo {
    color: var(--cor-despesa-contraste);
}

.aviso-parcelamento {
    grid-column: 1 / -1;
    margin-top: -6px;
    font-size: 12px;
}


/* Um campo que ocupa a linha inteira dentro de `.campos-duplos`. O
   seletor de "o valor informado é" tem rótulo e opções longos: em meia
   largura, as duas opções ficam cortadas justamente onde diferem. */
.campo-largo {
    grid-column: 1 / -1;
}


/* "Parcela 5 de 10 · compra em 05/08", no topo do formulário: a data de
   lançamento de uma parcela de cartão é a do mês dela, e sem isto não
   havia como saber quando a compra aconteceu. */
.aviso-parcela {
    margin-bottom: 14px;

    padding: 8px 12px;

    font-size: 12px;

    background: var(--cor-superficie-suave);

    border-left: 3px solid var(--cor-borda-forte);
    border-radius: 6px;
}


/* Aviso de fatura já fechada, abaixo do seletor. Amarelo de atenção
   porque é decisão, não erro — o lançamento ainda pode entrar. */
.aviso-fatura:not(:empty) {
    display: block;

    margin-top: 6px;

    color: var(--cor-transferencia-contraste);
}


/* A linha não quebra mais em duas alturas no celular: a descrição corta
   com reticências e tudo cabe numa linha só. Deixar o `flex-wrap` e o
   recuo de 40px do valor aqui espremia a descrição para ~11 caracteres
   mesmo quando havia espaço de sobra ao lado. */


/* =========================
   FATURA DO CARTÃO
   ========================= */

.link-voltar {
    display: inline-block;
    margin-bottom: 8px;
    color: var(--cor-texto-suave);
    font-size: 13px;
    font-weight: 600;
    text-decoration: none;
}

.link-voltar:hover {
    color: var(--cor-primaria);
}

.bloco-fatura {
    margin-bottom: 20px;
}

.cabecalho-fatura {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 20px;
    flex-wrap: wrap;
}

/* Os três números da fatura, no mesmo desenho da tela de cartões: o
   gasto do próprio cartão, o dos adicionais e o total — nessa ordem, que
   é a da soma. Antes a composição era uma linha de texto miúdo embaixo
   do total, e o que ela informa não se lia de relance. */
.composicao-fatura {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 28px;
}

/* Os dois primeiros blocos vivem num contêiner próprio, porque o JS os
   troca em bloco — mas `display: contents` faz esse contêiner sumir do
   layout e os filhos entrarem na **mesma** linha do total. Como flex
   aninhado ele era um item só, encolhia, e os dois quebravam numa
   coluna ao lado do total em vez de ficarem lado a lado.
   Vazio, não gera caixa nenhuma: nem o bloco, nem o vão do `gap`. */
#blocos-composicao {
    display: contents;
}

.composicao-fatura > div,
#blocos-composicao > div {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.composicao-fatura span {
    color: var(--cor-texto-suave);
    font-size: 13px;
}

/* Grandes de propósito: são as parcelas do número principal da tela, e
   em corpo de legenda voltariam a ser a linha miúda que este bloco veio
   substituir. Menores que o total, que continua sendo a resposta à
   pergunta "quanto eu pago?". */
.composicao-fatura strong {
    font-size: 24px;
    color: var(--cor-texto-forte);
}

/* O total continua sendo o número principal da tela: duas classes para
   vencer a regra acima, que é mais específica que uma classe só. */
.composicao-fatura .valor-fatura-grande {
    font-size: 30px;
}

.valor-fatura-grande {
    font-size: 30px;
    color: var(--cor-texto-forte);
}

.valor-fatura {
    color: var(--cor-despesa-contraste);
}

/* Barra de consumo do limite. Só é renderizada quando há limite. */
.bloco-limite {
    margin-top: 18px;
}

.barra-limite {
    height: 9px;
    border-radius: 999px;
    background: var(--cor-superficie-alt);
    overflow: hidden;
}

.preenchimento-limite {
    height: 100%;
    border-radius: 999px;
    transition: width 0.3s;
}

.preenchimento-limite.nivel-tranquilo {
    background: var(--cor-receita);
}

.preenchimento-limite.nivel-atencao {
    background: var(--cor-transferencia);
}

.preenchimento-limite.nivel-critico {
    background: var(--cor-despesa);
}

.rodape-limite {
    display: flex;
    justify-content: space-between;
    gap: 10px;
    margin-top: 7px;
}

.botao-pagar-fatura {
    width: 100%;
    margin-top: 16px;
}

.selo-fatura-paga {
    display: block;
    margin-top: 16px;
    text-align: center;
}

.linha-fatura-secundaria {
    display: block;
    margin-top: 3px;
    font-size: 12px;
}

/* O card inteiro abre a fatura; os botões internos seguem funcionando
   porque o handler trata `data-acao` antes de navegar. */
.cartao-clicavel {
    cursor: pointer;
    transition: border-color 0.15s, transform 0.1s;
    border: 1px solid transparent;
}

.cartao-clicavel:hover {
    border-color: var(--cor-primaria);
}

.cartao-clicavel .acoes-conta,
.cartao-clicavel .item-subcategoria,
.cartao-clicavel button {
    cursor: auto;
}

.cartao-clicavel button {
    cursor: pointer;
}


/* =========================
   BOTÃO FLUTUANTE
   ========================= */

/* FAB. Continua `position: fixed` (posição exata no canto, sem regressão
   em lista curta), mas o `acoes-flutuantes.js` agora o pendura **dentro
   da área que rola** (`.conteudo-rolavel`) em vez de no `<body>`. O
   motivo: nas telas de topo fixo quem rola é o `.conteudo-rolavel`, e um
   FAB filho do `<body>` tem como ancestral rolável só o documento — que
   ali não rola —, então o gesto de arrastar começando no botão morria.
   Filho do `.conteudo-rolavel`, o mesmo gesto rola a lista. */
.area-flutuante {
    position: fixed;
    right: 28px;
    bottom: 28px;
    z-index: 900;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 10px;

    transition: opacity 0.2s, transform 0.2s;

    /* O container é só um trilho de posicionamento e não pode capturar
       clique. Fechado, as opções continuam ocupando espaço no layout
       (elas somem por `opacity`, não por `display`), então esta caixa é
       uma faixa alta e invisível sobre a lista: sem isto ela rouba o
       clique de tudo que estiver atrás, não só embaixo do botão. Quem
       recebe clique são os filhos, e só eles. */
    pointer-events: none;
}


.botao-flutuante,
.area-flutuante.aberto .opcoes-flutuantes {
    pointer-events: auto;
}


/* Escondido ao rolar para baixo, de volta ao rolar para cima. O
   `pointer-events: none` não é enfeite: um botão invisível que continua
   interceptando cliques é pior que o problema que ele resolve. */
.area-flutuante.oculta {
    opacity: 0;
    pointer-events: none;
    transform: translateY(16px);
}


/* O `pointer-events: auto` dos filhos reativaria o clique num botão
   invisível — o container escondido não basta. Desliga nos filhos
   também, senão sobra um alvo fantasma no canto da tela. */
.area-flutuante.oculta .botao-flutuante,
.area-flutuante.oculta .opcoes-flutuantes {
    pointer-events: none;
}


/* O botão cobre o fim da lista, e é ali que ficam os registros mais
   antigos do período. Reserva espaço para o último continuar clicável:
   58px do botão + 28px até o rodapé + folga. A classe é posta pelo
   próprio componente, para as telas sem botão não ganharem o vão. */
.conteudo.com-acoes-flutuantes,
.conteudo-rolavel.com-acoes-flutuantes {
    padding-bottom: 110px;
}

.opcoes-flutuantes {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 8px;

    /* Fechado por padrão: só aparece após o primeiro clique. */
    opacity: 0;
    pointer-events: none;
    transform: translateY(8px);
    transition: opacity 0.15s, transform 0.15s;
}

.area-flutuante.aberto .opcoes-flutuantes {
    opacity: 1;
    pointer-events: auto;
    transform: translateY(0);
}

.opcao-flutuante {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 10px 16px;
    border: 0;
    border-radius: 999px;
    font-family: inherit;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    box-shadow: var(--sombra-cartao);
}

.opcao-flutuante.tipo-receita {
    background: var(--cor-receita);
    color: var(--cor-receita-texto);
}

.opcao-flutuante.tipo-despesa {
    background: var(--cor-despesa);
    color: var(--cor-despesa-texto);
}

.opcao-flutuante.tipo-transferencia {
    background: var(--cor-transferencia);
    color: var(--cor-transferencia-texto);
}

/* Ações que não são de lançamento (cadastrar conta, cartão) usam a cor
   neutra da interface, para não roubar o significado das cores de tipo. */
.opcao-flutuante.tipo-neutro {
    background: var(--cor-superficie);
    color: var(--cor-texto);
    border: 1px solid var(--cor-borda-forte);
}

.opcao-flutuante.tipo-neutro:hover {
    background: var(--cor-superficie-alt);
}

.botao-flutuante {
    width: 58px;
    height: 58px;
    border: 0;
    border-radius: 50%;
    background: var(--cor-primaria);
    color: var(--cor-primaria-texto);
    font-size: 32px;
    line-height: 1;
    cursor: pointer;
    box-shadow: var(--sombra-modal);
    transition: transform 0.2s, background 0.2s;
}

.botao-flutuante:hover {
    background: var(--cor-primaria-hover);
}

.area-flutuante.aberto .botao-flutuante {
    transform: rotate(45deg);
}

/* O seletor de tipo dentro do modal usa as mesmas abas da tela de
   categorias, já coloridas por tipo. */
.abas-tipo-modal {
    display: flex;
    width: 100%;
}

.abas-tipo-modal .aba-tipo {
    flex: 1;
    padding: 9px 10px;
    font-size: 13px;
}


/* Formulário de lançamento (js/modal-lancamento.js): no PC abre largo e
   distribui os campos em duas colunas, para caber com menos scroll.
   Abaixo de 700px volta a ser uma coluna só, como todos os modais. */
#modal-lancamento-compartilhado .modal-conteudo {
    max-width: 720px;

    /* Cabeçalho (título + tipo) fixo e só o corpo do formulário rola —
       a mesma técnica estrutural das telas com `.tem-topo-fixo` (dividir
       em dois filhos flex, não `position: sticky`), aplicada aqui num
       modal em vez de numa página inteira. Sem isso, título e tipo (e
       o botão Salvar, que mora ao lado deles) somem rolando junto do
       resto num formulário longo. */
    display: flex;
    flex-direction: column;
    padding: 0;
    overflow: hidden;
}

.ml-cabecalho-fixo {
    flex: 0 0 auto;
    padding: 28px 28px 0;
}

.ml-cabecalho-fixo #ml-campo-tipo {
    margin-bottom: 20px;
}

.ml-conteudo-rolavel {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: 0 28px 28px;
}

.ml-acoes-cabecalho {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 0 0 auto;
}

.ml-grade {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: 20px;
    align-items: start;
}

/* Por padrão cada campo ocupa a linha inteira; só os marcados com
   `.ml-par` dividem a linha ao meio (valor↔repetição, vencimento↔baixa). */
.ml-grade > * {
    grid-column: 1 / -1;
}

.ml-grade > .campo.ml-par {
    grid-column: span 1;
}

.ml-secao {
    grid-column: 1 / -1;
    margin: 0;
    padding-top: 14px;
    border-top: 1px solid var(--cor-borda);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--cor-texto-suave);
}

/* Select com o selo da categoria à esquerda ou o botão de extrato à
   direita. */
.ml-campo-selecao {
    display: flex;
    align-items: center;
    gap: 8px;
}

.ml-campo-selecao > select {
    flex: 1 1 auto;
    min-width: 0;
}

.ml-campo-selecao > .selo-categoria {
    flex: 0 0 auto;
}

.ml-botao-mini {
    flex: 0 0 auto;
    width: 42px;
    height: 44px;
    border: 1px solid var(--cor-borda-forte);
    border-radius: 8px;
    background: var(--cor-superficie);
    color: var(--cor-texto-medio);
    font-size: 16px;
    line-height: 1;
    cursor: pointer;
}

.ml-botao-mini:hover {
    background: var(--cor-superficie-alt);
    color: var(--cor-texto);
}

.ml-botao-mini:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

#ml-campo-data-efetivacao {
    margin-top: 10px;
}

#ml-campo-data-efetivacao label {
    display: block;
    margin-bottom: 7px;
    font-weight: 600;
    font-size: 14px;
    color: var(--cor-texto-medio);
}

@media (max-width: 700px) {

    #modal-lancamento-compartilhado .modal-conteudo {
        max-width: 560px;
    }

    .ml-grade {
        grid-template-columns: 1fr;
    }

    .ml-grade > .campo.ml-par {
        grid-column: 1 / -1;
    }

}


@media (max-width: 600px) {

    .area-flutuante {
        right: 18px;
        bottom: 18px;
    }

    .conteudo.com-acoes-flutuantes,
    .conteudo-rolavel.com-acoes-flutuantes {
        padding-bottom: 96px;
    }

}

/* =========================
   RESUMO DO DASHBOARD
   ========================= */

/* Extrato resumido do card de conta, no formato do app de referência. */
.resumo-conta {
    margin-top: 18px;
    padding-top: 16px;
    border-top: 1px solid var(--cor-borda);
}

.linha-resumo-conta {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    padding: 5px 0;
    font-size: 14px;
}

.linha-resumo-conta > span {
    color: var(--cor-texto-suave);
}

.linha-resumo-conta > strong {
    color: var(--cor-texto-forte);
    white-space: nowrap;
}


/* A cor do tipo tem de vencer o `color` da linha: `.linha-resumo-conta >
   strong` é mais específico que `.valor-positivo` sozinho, e por isso
   receitas e despesas apareciam pretas como o resto — a referência as
   mostra em verde e vermelho, e é o que dá para ler o card de relance. */
.linha-resumo-conta > strong.valor-positivo {
    color: var(--cor-receita-contraste);
}


.linha-resumo-conta > strong.valor-negativo {
    color: var(--cor-despesa-contraste);
}

.rodape-resumo-conta {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 15px;
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--cor-borda);
}

.rodape-resumo-conta > div {
    display: flex;
    flex-direction: column;
    gap: 3px;
}

.rodape-resumo-conta .alinhado-direita {
    text-align: right;
}

.valor-saldo-atual {
    font-size: 22px;
    color: var(--cor-texto-forte);
}

.linha-resumo-vazio {
    margin-top: 18px;
    font-size: 13px;
}

/* Lançamento de cartão não tem alternador: quem liquida é a fatura. */
.marcador-fatura {
    width: 26px;
    height: 26px;
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 15px;
    opacity: 0.65;
}

/* =========================
   IMPORTAÇÃO
   ========================= */

.trilha-etapas {
    display: flex;
    gap: 8px;
    margin-bottom: 22px;
    flex-wrap: wrap;
}

.etapa {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 9px 16px;
    border: 1px solid var(--cor-borda);
    border-radius: 999px;
    background: var(--cor-superficie);
    color: var(--cor-texto-suave);
    font-size: 13px;
    font-weight: 600;
}

.etapa span {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: var(--cor-superficie-alt);
    color: var(--cor-texto-suave);
    font-size: 11px;
}

.etapa.ativa {
    border-color: var(--cor-primaria);
    color: var(--cor-texto-forte);
}

.etapa.ativa span {
    background: var(--cor-primaria);
    color: var(--cor-primaria-texto);
}

.etapa.concluida span {
    background: var(--cor-receita);
    color: var(--cor-receita-texto);
}

.campos-arquivos {
    margin-top: 20px;
}

.campos-arquivos input[type="file"] {
    width: 100%;
    padding: 11px 14px;
    border: 1px dashed var(--cor-borda-forte);
    border-radius: 8px;
    background: var(--cor-superficie);
    color: var(--cor-texto);
    font-family: inherit;
    font-size: 13px;
    cursor: pointer;
}

.resumo-conferencia {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    margin-top: 20px;
}

.resumo-conferencia .cartao-resumo small {
    display: block;
    margin-top: 6px;
    font-size: 12px;
}

.aviso-conferencia {
    margin-top: 16px;
    padding: 13px 16px;
    border-left: 4px solid var(--cor-transferencia);
    border-radius: 8px;
    background: var(--cor-superficie-suave);
    font-size: 13px;
}

.bloco-problemas {
    margin-top: 16px;
    padding: 13px 16px;
    border: 1px solid var(--cor-borda);
    border-radius: 8px;
    background: var(--cor-superficie-suave);
}

.bloco-problemas summary {
    cursor: pointer;
    font-weight: 600;
    color: var(--cor-despesa-contraste);
}

.bloco-problemas ul {
    margin: 12px 0 0 20px;
    font-size: 13px;
    color: var(--cor-texto-suave);
}

.bloco-problemas li {
    margin-bottom: 5px;
}

.titulo-bloco {
    margin: 26px 0 12px;
    font-size: 16px;
    color: var(--cor-texto-forte);
}

.lista-detectados {
    display: flex;
    flex-direction: column;
}

.item-detectado {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 11px 0;
    border-bottom: 1px solid var(--cor-borda);
}

.item-detectado:last-child {
    border-bottom: 0;
}

.item-detectado > div {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.item-detectado small {
    margin-top: 3px;
    font-size: 12px;
}

.bloco-cartao-novo {
    margin-top: 14px;
    padding: 16px;
    border: 1px solid var(--cor-borda);
    border-radius: 10px;
    background: var(--cor-superficie-suave);
}

.campos-cartao-novo {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 14px;
    margin-top: 12px;
}

.campos-cartao-novo .campo {
    margin-bottom: 0;
}

.campo-saldo label {
    display: flex;
    align-items: baseline;
    gap: 8px;
}


@media (max-width: 900px) {

    .resumo-conferencia {
        grid-template-columns: 1fr;
    }

}


.cabecalho-secao {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 15px;
    margin-bottom: 20px;
}

.cabecalho-secao h2 {
    margin-bottom: 0;
}

.seletor-quantidade {
    padding: 7px 10px;
    border: 1px solid var(--cor-borda-forte);
    border-radius: 8px;
    background: var(--cor-superficie);
    color: var(--cor-texto);
    font-family: inherit;
    font-size: 13px;
    cursor: pointer;
    outline: none;
}

.item-saldo-conta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 15px;
    padding: 13px 0;
    border-bottom: 1px solid var(--cor-borda);
}

.item-saldo-conta:last-child {
    border-bottom: 0;
}

.item-saldo-conta > div {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.item-saldo-conta small {
    margin-top: 3px;
    font-size: 12px;
}

.valor-saldo-conta {
    font-size: 17px;
    color: var(--cor-texto-forte);
    white-space: nowrap;
}

/* Conta fora do total continua visível, mas visivelmente atenuada. */
.item-saldo-conta.conta-ignorada strong {
    color: var(--cor-texto-suave);
    font-weight: 600;
}


@media (max-width: 900px) {

    .lista-cartoes {
        grid-template-columns: 1fr;
    }

}


/* =========================
   CATEGORIAS
   ========================= */

.abas-tipo {
    display: inline-flex;
    gap: 4px;
    margin-bottom: 22px;
    padding: 4px;
    border: 1px solid var(--cor-borda);
    border-radius: 10px;
    background: var(--cor-superficie);
}

.aba-tipo {
    padding: 9px 20px;
    border: 0;
    border-radius: 7px;
    background: transparent;
    color: var(--cor-texto-medio);
    font-family: inherit;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
}

.aba-tipo:hover {
    background: var(--cor-superficie-alt);
}

/* A aba ativa assume a cor do seu tipo; as inativas ficam neutras. */
.aba-tipo.ativa[data-tipo="DESPESA"] {
    background: var(--cor-despesa);
    color: var(--cor-despesa-texto);
}

.aba-tipo.ativa[data-tipo="RECEITA"] {
    background: var(--cor-receita);
    color: var(--cor-receita-texto);
}

.aba-tipo.ativa[data-tipo="TRANSFERENCIA"] {
    background: var(--cor-transferencia);
    color: var(--cor-transferencia-texto);
}

/* Sub-abas Vigentes / Expirados dos orçamentos. Neutras de propósito —
   não são tipo de transação; só separam o que ainda vale do que já
   passou da data. Aparecem só quando há orçamento expirado. */
.sub-abas-vigencia {
    display: inline-flex;
    gap: 4px;
    margin-bottom: 16px;
    padding: 4px;
    border: 1px solid var(--cor-borda);
    border-radius: 10px;
    background: var(--cor-superficie);
}

.sub-abas-vigencia[hidden] {
    display: none;
}

.sub-aba {
    padding: 7px 16px;
    border: 0;
    border-radius: 7px;
    background: transparent;
    color: var(--cor-texto-medio);
    font-family: inherit;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
}

.sub-aba:hover {
    background: var(--cor-superficie-alt);
}

.sub-aba.ativa {
    background: var(--cor-superficie-alt);
    color: var(--cor-texto-forte);
}

.lista-categorias {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));

    /* Masonry — ver js/masonry.js e a nota em .lista-contas. Sem isto,
       expandir uma categoria deixava a do lado com um vão em branco. */
    --masonry-gap: 20px;
    grid-auto-rows: 1px;
    column-gap: 20px;
    row-gap: 0;
    align-items: start;
}

.cartao-categoria {
    padding: 24px;
    background: var(--cor-superficie);
    border-radius: 12px;
    box-shadow: var(--sombra-cartao);
}

.cartao-categoria .titulo-conta h2 {
    font-size: 19px;
    color: var(--cor-texto-forte);
}

.etiqueta-contagem {
    min-width: 24px;
    padding: 3px 8px;
    border-radius: 999px;
    background: var(--cor-primaria-suave);
    color: var(--cor-primaria-contraste);
    font-size: 11px;
    font-weight: 700;
    text-align: center;
}

.etiqueta-contagem.tipo-despesa {
    background: var(--cor-despesa-suave);
    color: var(--cor-despesa-contraste);
}

.etiqueta-contagem.tipo-receita {
    background: var(--cor-receita-suave);
    color: var(--cor-receita-contraste);
}

.etiqueta-contagem.tipo-transferencia {
    background: var(--cor-transferencia-suave);
    color: var(--cor-transferencia-contraste);
}

.subcategorias {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding-top: 16px;
    border-top: 1px solid var(--cor-borda);
}

.item-subcategoria {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 9px 12px;
    border-radius: 8px;
    background: var(--cor-superficie-suave);
    font-size: 14px;
}

.sem-subcategorias {
    padding-top: 16px;
    border-top: 1px solid var(--cor-borda);
    font-size: 13px;
}

.campo small {
    display: block;
    margin-top: 6px;
    font-size: 12px;
}


@media (max-width: 900px) {

    .lista-categorias {
        grid-template-columns: 1fr;
    }

}


/* =========================
   ORÇAMENTOS
   ========================= */

.lista-orcamentos {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));

    /* Masonry — ver js/masonry.js e a nota em .lista-contas. */
    --masonry-gap: 20px;
    grid-auto-rows: 1px;
    column-gap: 20px;
    row-gap: 0;
    align-items: start;
}

@media (max-width: 900px) {
    .lista-orcamentos {
        grid-template-columns: 1fr;
    }
}

.cartao-orcamento {
    padding: 20px 22px;
    background: var(--cor-superficie);
    border: 1px solid var(--cor-borda);
    border-radius: 14px;
}

.cabecalho-orcamento {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 16px;
}

.cabecalho-orcamento-titulo {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.cabecalho-orcamento-titulo strong {
    font-size: 16px;
    color: var(--cor-texto-forte);
}

.cabecalho-orcamento-titulo small {
    font-size: 12px;
}

.linhas-orcamento {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.linha-orcamento-topo {
    display: flex;
    justify-content: space-between;
    gap: 10px;
    font-size: 13px;
    margin-bottom: 5px;
}

.linha-orcamento-nome {
    color: var(--cor-texto);
    font-weight: 600;
}

.linha-orcamento-valores {
    white-space: nowrap;
}

.barra-progresso-orcamento {
    height: 8px;
    border-radius: 999px;
    background: var(--cor-orcamento-trilho);
    overflow: hidden;
}

.barra-progresso-orcamento-preenchimento {
    height: 100%;
    border-radius: 999px;
    background: var(--cor-orcamento-ok);
    transition: width 0.2s ease;
}

.linha-orcamento.faixa-alerta .barra-progresso-orcamento-preenchimento {
    background: var(--cor-orcamento-alerta);
}

.linha-orcamento.faixa-estouro .barra-progresso-orcamento-preenchimento {
    background: var(--cor-orcamento-estouro);
}

.linha-orcamento.faixa-andamento .barra-progresso-orcamento-preenchimento {
    background: var(--cor-primaria);
}

.linha-orcamento small {
    display: block;
    margin-top: 4px;
    font-size: 12px;
}

.resumo-orcamento {
    margin-top: 16px;
    padding-top: 12px;
    border-top: 1px solid var(--cor-borda);
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.resumo-orcamento-linha {
    display: flex;
    justify-content: space-between;
    gap: 10px;
    font-size: 13px;
}

.nota-orcamento {
    margin-top: 10px;
    font-size: 12px;
}

.grupo-linhas-orcamento {
    border: 1px solid var(--cor-borda);
    border-radius: 10px;
    padding: 14px;
    margin-top: 4px;
}

.grupo-linhas-orcamento legend {
    padding: 0 6px;
    font-size: 13px;
    font-weight: 600;
    color: var(--cor-texto-medio);
}

.linha-orcamento-form {
    padding: 12px;
    margin-bottom: 12px;
    background: var(--cor-superficie-suave, var(--cor-fundo));
    border-radius: 10px;
}

.orc-linha-incluir {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 8px 0 4px;
    font-size: 13px;
    color: var(--cor-texto-medio);
}

/* `display: flex` acima venceria o `[hidden] { display: none }`. */
.orc-linha-incluir[hidden] {
    display: none;
}

.orc-linha-incluir input {
    width: auto;
    margin: 0;
}


/* Botão que abre o seletor de categorias de uma linha (rodada C, item
   2). Parece um campo; o rótulo diz o que está escolhido. */
.orc-linha-categorias {
    width: 100%;
    text-align: left;
    padding: 9px 12px;
    border: 1px solid var(--cor-borda);
    border-radius: 8px;
    background: var(--cor-superficie, var(--cor-fundo));
    color: var(--cor-texto-suave);
    font-family: inherit;
    font-size: 14px;
    cursor: pointer;
}

.orc-linha-categorias.tem-selecao {
    color: var(--cor-texto-forte);
    border-color: var(--cor-primaria);
}


/* Checkbox opcional do formulário de orçamento — exibir no dashboard,
   somar ignoradas. */
.orc-opcao-checkbox {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 4px 0;
    font-size: 14px;
    color: var(--cor-texto-medio);
}

.orc-opcao-checkbox input {
    width: auto;
    margin: 0;
}


/* Clicar no card abre a lista dos lançamentos que o compõem. */
.cartao-orcamento {
    cursor: pointer;
}

.cartao-orcamento .botao-menu-orcamento {
    cursor: pointer;
}


/* --- Seletor de categorias em árvore (js/seletor-categorias.js) --- */
.sc-arvore {
    max-height: 55vh;
    overflow-y: auto;
    margin: 4px 0 16px;
    border: 1px solid var(--cor-borda);
    border-radius: 10px;
}

.sc-raiz {
    border-bottom: 1px solid var(--cor-borda);
}

.sc-raiz:last-child {
    border-bottom: none;
}

.sc-linha-raiz {
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 4px 10px;
}

.sc-seta {
    border: none;
    background: transparent;
    color: var(--cor-texto-suave);
    font-size: 14px;
    cursor: pointer;
    padding: 4px 6px;
    transition: transform 0.15s ease;
}

.sc-raiz.sc-aberta > .sc-linha-raiz .sc-seta {
    transform: rotate(90deg);
}

.sc-seta[disabled] {
    visibility: hidden;
}

.sc-item {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 1;
    padding: 6px 4px;
    font-size: 14px;
    cursor: pointer;
}

.sc-item input {
    width: auto;
    margin: 0;
}

.sc-subs {
    padding: 2px 10px 8px 34px;
}

.sc-subs[hidden] {
    display: none;
}

.sc-item-sub {
    padding: 4px;
    font-size: 13px;
    color: var(--cor-texto-medio);
}

.sc-vazio {
    font-size: 12px;
    padding: 2px 4px;
}


/* --- Card ORCAMENTOS do dashboard --- */

/* Dois botões de alternância lado a lado: o ativo fica cheio na cor do
   tipo, o outro só contornado. Abaixo, a lista da natureza escolhida. */
.abas-orcamento {
    display: flex;
    gap: 8px;
    margin-bottom: 14px;
}

.aba-orcamento {
    flex: 1;
    padding: 8px 4px;
    border: 2px solid;
    border-radius: 8px;
    background: transparent;
    font-family: inherit;
    font-size: 12px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
}

.aba-orcamento-despesa {
    border-color: var(--cor-despesa);
    color: var(--cor-despesa-contraste);
}

.aba-orcamento-despesa.ativa {
    background: var(--cor-despesa);
    color: var(--cor-despesa-texto);
}

.aba-orcamento-receita {
    border-color: var(--cor-receita);
    color: var(--cor-receita-contraste);
}

.aba-orcamento-receita.ativa {
    background: var(--cor-receita);
    color: var(--cor-receita-texto);
}

.lista-orcamento-dashboard {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.orcamento-secao-vazia {
    margin: 0;
    font-size: 13px;
}

.linha-orcamento-dashboard {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.linha-orcamento-dashboard + .linha-orcamento-dashboard {
    border-top: 1px solid var(--cor-borda);
    padding-top: 8px;
}

.linha-orcamento-dashboard .linha-orcamento-nome {
    font-size: 13px;
    font-weight: 600;
    color: var(--cor-texto);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* A cor da barra é a do tipo de transação, não a de uma faixa de %. O
   trilho leva a versão suave para a barra não sumir com 0% gasto. */
.secao-orcamento-despesa .barra-progresso-orcamento {
    background: var(--cor-despesa-suave);
}

.secao-orcamento-receita .barra-progresso-orcamento {
    background: var(--cor-receita-suave);
}

.secao-orcamento-despesa .barra-progresso-orcamento-preenchimento {
    background: var(--cor-despesa);
}

.secao-orcamento-receita .barra-progresso-orcamento-preenchimento {
    background: var(--cor-receita);
}

.linha-orcamento-dashboard.orc-estouro .barra-progresso-orcamento-preenchimento {
    background: repeating-linear-gradient(
        45deg,
        var(--cor-despesa) 0 6px,
        var(--cor-despesa-hover) 6px 12px
    );
}

.linha-orcamento-dashboard.orc-estouro small {
    color: var(--cor-despesa-contraste);
    font-weight: 600;
}

.linha-orcamento-dashboard small {
    display: block;
    margin: 0;
    font-size: 11px;
}


@media (max-width: 600px) {

    .abas-tipo {
        display: flex;
        width: 100%;
    }

    .aba-tipo {
        flex: 1;
    }

    .item-subcategoria {
        flex-direction: column;
        align-items: stretch;
        gap: 10px;
    }

}


/* =========================
   MENU DE TRÊS PONTINHOS
   =========================

   Ver js/menu-acoes.js. Existe para controle de configuração não ocupar
   espaço permanente na tela: ordenação, filtros e agrupamento moravam
   soltos no corpo da página e empurravam o dado para baixo. */

.botao-tres-pontos {
    display: flex;
    align-items: center;
    justify-content: center;

    width: 34px;
    height: 34px;
    flex: 0 0 auto;
    padding: 0;

    border: 1px solid transparent;
    border-radius: 8px;

    background: transparent;
    color: var(--cor-texto-suave);

    font-family: inherit;
    font-size: 18px;
    line-height: 1;

    cursor: pointer;
    transition: background 0.15s, color 0.15s, border-color 0.15s;
}


.botao-tres-pontos:hover,
.botao-tres-pontos[aria-expanded="true"] {
    background: var(--cor-superficie-alt);
    border-color: var(--cor-borda);
    color: var(--cor-texto);
}


/* Na linha da lista ele fica discreto até a linha ser tocada: uma ação
   destrutiva não pode ter o mesmo peso visual do dado, que é o problema
   que a lixeira em toda linha criava. */
.botao-tres-pontos-linha {
    width: 30px;
    height: 30px;
    font-size: 16px;
    opacity: 0.55;
}

.item-movimentacao:hover .botao-tres-pontos-linha,
.botao-tres-pontos-linha:focus-visible,
.botao-tres-pontos-linha[aria-expanded="true"] {
    opacity: 1;
}


/* Toque não tem hover: no celular o botão fica sempre legível, senão a
   única forma de descobrir a ação seria adivinhando. */
@media (hover: none) {
    .botao-tres-pontos-linha { opacity: 0.8; }
}


.menu-acoes {
    position: fixed;
    /* Acima de tudo: um menu sempre flutua sobre o conteúdo, e o painel
       de consulta (.painel-consulta, z-index 950) o deixava atrás. O
       menu já se fecha antes de qualquer modal abrir (a ação roda depois
       de `fechar()`), então não disputa com .modal / .modal-acima. */
    z-index: 1200;

    min-width: 208px;
    max-width: min(280px, calc(100vw - 16px));
    padding: 5px;

    border: 1px solid var(--cor-borda);
    border-radius: 12px;

    background: var(--cor-menu-flutuante);
    box-shadow: var(--cor-sombra-menu);
}


.menu-acoes-item {
    display: flex;
    align-items: center;
    gap: 10px;

    width: 100%;
    padding: 8px 10px;

    border: 0;
    border-radius: 8px;

    background: transparent;
    color: var(--cor-texto);

    font-family: inherit;
    font-size: 14px;
    text-align: left;

    cursor: pointer;
}


.menu-acoes-item:hover {
    background: var(--cor-menu-flutuante-hover);
}


.menu-acoes-item:focus-visible {
    outline: 2px solid var(--cor-primaria);
    outline-offset: -2px;
}


/* Largura fixa para a marca: sem ela os rótulos dançam para a direita
   conforme o ✓ aparece e some. */
.menu-acoes-marca {
    width: 16px;
    flex: 0 0 auto;

    color: var(--cor-primaria);

    font-size: 13px;
    text-align: center;
}


.menu-acoes-texto {
    flex: 1;
    min-width: 0;
}


.menu-acoes-perigo {
    color: var(--cor-perigo);
}

.menu-acoes-perigo .menu-acoes-marca {
    color: var(--cor-perigo);
}


.menu-acoes-separador {
    margin: 5px 4px 2px;
    padding-top: 6px;

    border-top: 1px solid var(--cor-borda);

    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;

    color: var(--cor-texto-suave);
}


/* O primeiro separador não precisa de risco: não há nada acima para
   separar, e o risco encostaria na borda do painel. */
.menu-acoes > .menu-acoes-separador:first-child {
    margin-top: 2px;
    padding-top: 2px;
    border-top: 0;
}


/* =========================
   TELA DE MOVIMENTAÇÕES — CABEÇALHO, FICHAS E FAIXA
   ========================= */

.cabecalho-tela {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;

    margin-bottom: 18px;
}


.cabecalho-tela-titulo {
    min-width: 0;
}


/* Quando a tela tem mais de uma ação no topo — categorias tem o ⋮ e o
   "+ Nova categoria", já que ali não há FAB de propósito. Não encolhe:
   quem cede espaço é o título, que corta. */
.acoes-cabecalho-tela {
    display: flex;
    align-items: center;
    gap: 8px;

    flex: 0 0 auto;
}


/* Categorias: as abas Despesa/Receita moram no cabeçalho, entre o
   "+ Nova categoria" e o ⋮ — compactas, sem a margem da faixa solta que
   ocupava meia tela. */
.acoes-cabecalho-tela .abas-tipo {
    margin: 0;
}

.acoes-cabecalho-tela .aba-tipo {
    padding: 7px 13px;
    font-size: 13px;
}

/* O "+" e o rótulo lado a lado — no PC o botão é "+ Nova categoria"
   (e "+ Novo orçamento"). */
#botao-nova-categoria,
#botao-novo-orcamento {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}


.cabecalho-tela h1 {
    margin: 0;

    font-size: 26px;
    letter-spacing: -0.01em;

    color: var(--cor-texto-forte);
}


.subtitulo-tela {
    margin: 2px 0 0;

    font-size: 13px;
    color: var(--cor-texto-suave);
}


/* Uma faixa só, no lugar das duas que existiam (a de período e a de
   ordenação): o navegador de mês centralizado, e as fichas de filtro
   logo abaixo, também centralizadas.

   Centralizado e não à esquerda porque o mês é o eixo da tela — tudo o
   que está abaixo pertence a ele —, e porque com as fichas do outro
   lado a faixa ficava com peso só numa ponta. */
.barra-comando {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;

    margin-bottom: 14px;
}


/* Só a margem: a centralização e o rótulo centrado vêm da regra base,
   que agora vale nas cinco telas com barra de mês. */
.barra-comando .barra-periodo {
    margin-bottom: 0;
}


/* No dashboard a barra de mês subiu para o cabeçalho, na linha do
   título: ela governa o painel e todos os cards, e ficar abaixo do
   gráfico que comanda invertia a leitura. */
.barra-periodo-cabecalho {
    margin: 0;

    /* O cabeçalho alinha os filhos pelo topo por causa do subtítulo; a
       barra fica melhor centrada com o bloco do título. */
    align-self: center;
}

/* No celular o cabeçalho já empilha; a barra ganha a linha inteira em
   vez de disputar espaço com o título. */
@media (max-width: 600px) {
    .barra-periodo-cabecalho {
        order: 3;
        width: 100%;
        margin-left: 0;
        margin-top: 10px;
    }
}


.fichas-filtro {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 7px;
}


/* Sem filtro ativo o container fica vazio; sem isto ele ainda cobraria
   o `gap` da faixa e abriria um vão que não explica nada. */
.fichas-filtro:empty {
    display: none;
}


/* Lupa de busca do cabeçalho (js/busca-tela.js). Fica sempre coladinha
   no ⋮; clicada, abre o campo de linha inteira logo abaixo do cabeçalho.
   Enquanto houver texto o campo fica à vista — é ele o estado, no lugar
   de uma ficha. */
.busca-tela-lupa.ativa {
    color: var(--cor-primaria);
    border-color: var(--cor-primaria);
}

.busca-tela-campo {
    display: block;
    box-sizing: border-box;
    width: 100%;
    margin-top: 10px;
    padding: 9px 12px;

    border: 1px solid var(--cor-borda);
    border-radius: 8px;

    background: var(--cor-superficie);
    color: var(--cor-texto-forte);

    font: inherit;
    font-size: 14px;
}

.busca-tela-campo[hidden] {
    display: none;
}

.busca-tela-campo:focus {
    outline: none;
    border-color: var(--cor-primaria);
}


/* A ficha é o que torna honesto esconder o controle no ⋮: o filtro
   continua à vista, e some no ✕. */
.ficha-filtro {
    display: inline-flex;
    align-items: center;
    gap: 6px;

    padding: 4px 6px 4px 11px;

    border: 1px solid var(--cor-borda-forte);
    border-radius: 999px;

    background: var(--cor-superficie);
    color: var(--cor-texto-medio);

    font-size: 12.5px;
    font-weight: 600;
    white-space: nowrap;
}


.ficha-filtro.tipo-receita {
    border-color: var(--cor-receita);
    color: var(--cor-receita-contraste);
}

.ficha-filtro.tipo-despesa {
    border-color: var(--cor-despesa);
    color: var(--cor-despesa-contraste);
}

.ficha-filtro.tipo-transferencia {
    border-color: var(--cor-transferencia);
    color: var(--cor-transferencia-contraste);
}


.ficha-filtro-limpar {
    display: flex;
    align-items: center;
    justify-content: center;

    width: 18px;
    height: 18px;
    padding: 0;

    border: 0;
    border-radius: 50%;

    background: var(--cor-superficie-alt);
    color: inherit;

    font-family: inherit;
    font-size: 10px;
    line-height: 1;

    cursor: pointer;
}


.ficha-filtro-limpar:hover {
    background: var(--cor-borda-forte);
}


/* Três números numa faixa, não em três cartões empilhados. No celular
   os cartões custavam cerca de 840px de rolagem para mostrar três
   valores, e o primeiro lançamento só começava a 823px de uma tela de
   915px. */
.faixa-resumo {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1px;

    margin-bottom: 14px;

    border: 1px solid var(--cor-borda);
    border-radius: 12px;

    background: var(--cor-borda);
    overflow: hidden;
}


.resumo-celula {
    display: flex;
    flex-direction: column;
    gap: 2px;

    padding: 11px 14px;

    background: var(--cor-superficie);
}


.acoes-exportar-relatorio {
    display: flex;
    gap: 8px;

    margin-bottom: 14px;
}

.botao-exportar-relatorio {
    padding: 6px 12px;

    font-size: 13px;
    color: var(--cor-texto);

    background: var(--cor-superficie);
    border: 1px solid var(--cor-borda);
    border-radius: 8px;
    cursor: pointer;
}

.botao-exportar-relatorio:hover {
    background: var(--cor-fundo);
}

.botao-exportar-relatorio:disabled {
    opacity: 0.6;
    cursor: default;
}


.resumo-rotulo {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;

    color: var(--cor-texto-suave);
}


.resumo-valor {
    font-size: 19px;
    font-weight: 700;
    line-height: 1.2;

    /* Os três valores ficam lado a lado: sem largura fixa de dígito eles
       não alinham entre si. */
    font-variant-numeric: tabular-nums;

    color: var(--cor-texto-forte);
}


.resumo-valor.tipo-receita { color: var(--cor-receita-contraste); }
.resumo-valor.tipo-despesa { color: var(--cor-despesa-contraste); }


.resumo-nota {
    font-size: 11.5px;
    line-height: 1.35;
    color: var(--cor-texto-suave);
}


/* A linha ganha densidade: a descrição corta em vez de quebrar em três
   linhas, e o valor usa dígito de largura fixa para as colunas de
   centavos alinharem. */
.item-movimentacao {
    gap: 11px;
    padding: 9px 12px;
}


.dados-movimentacao strong {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;

    font-size: 14.5px;
    font-weight: 600;
}


.dados-movimentacao small {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;

    font-size: 12px;
}


.valor-movimentacao {
    font-size: 15px;
    font-variant-numeric: tabular-nums;
}


.dia-extrato-total {
    font-variant-numeric: tabular-nums;
}


@media (max-width: 560px) {

    .faixa-resumo {
        grid-template-columns: 1fr 1fr;
    }

    /* O resultado é a conclusão dos dois de cima: ocupa a linha inteira
       em vez de virar uma terceira coluna espremida. */
    .resumo-celula:last-child {
        grid-column: 1 / -1;
        flex-direction: row;
        align-items: baseline;
        justify-content: space-between;
        gap: 10px;
    }

    .resumo-celula:last-child .resumo-nota {
        display: none;
    }

    .cabecalho-tela h1 {
        font-size: 22px;
    }

    .resumo-valor {
        font-size: 17px;
    }

}


/* =========================
   BARRA LATERAL COMO GAVETA NO CELULAR
   =========================

   Ver js/menu-lateral.js. Antes a barra ficava como um trilho de ícones
   de 72px — 17,5% da largura de uma tela de 412px, permanentemente, para
   uma navegação usada uma vez a cada tantos minutos. Fora do fluxo, o
   conteúdo ocupa a tela inteira.

   O botão e o fundo são criados pelo componente, e não no HTML de cada
   página: são sete telas, e duplicá-los garantiria que uma ficasse para
   trás numa mudança futura. */

.botao-abrir-menu,
.fundo-gaveta {
    display: none;
}


@media (max-width: 768px) {

    .menu-lateral {
        position: fixed;
        top: 0;
        left: 0;
        z-index: 50;

        width: 268px;
        height: 100%;

        padding: 20px 14px;

        transform: translateX(-100%);
        transition: transform 0.22s ease;
    }

    /* Aberta, a gaveta volta a ser o menu inteiro: nome, seletor de
       perfil e rótulos, que o trilho de ícones não tinha onde mostrar. */
    .gaveta-aberta .menu-lateral {
        transform: none;
        box-shadow: var(--cor-sombra-menu);
    }

    .gaveta-aberta .seletor-perfil {
        display: block;
    }

    .gaveta-aberta .marca,
    .gaveta-aberta .item-menu,
    .gaveta-aberta .botao-sair {
        font-size: 14px;
        text-align: left;
    }

    .gaveta-aberta .marca {
        justify-content: flex-start;

        padding-left: 12px;
        padding-right: 12px;

        font-size: 17px;
    }


    .gaveta-aberta .marca > span {
        display: inline;
    }

    /* O "menu recolhido" é preferência de desktop; no celular a gaveta é
       tudo-ou-nada. Sem isto, abrir a gaveta com a preferência ligada
       mostrava só o trilho de ícones — as regras `:root[data-menu=
       "recolhido"] …` (0,3,0) pesam mais que `.gaveta-aberta …` (0,2,0)
       e venciam mesmo dentro desta media query. Aqui elas são
       reafirmadas com o mesmo seletor e ordem posterior. */
    :root[data-menu="recolhido"] .menu-lateral {
        width: 268px;
        padding: 20px 14px;
    }

    :root[data-menu="recolhido"] .item-menu {
        text-align: left;
        font-size: 14px;
    }

    :root[data-menu="recolhido"] .item-menu::first-letter {
        font-size: inherit;
    }

    :root[data-menu="recolhido"] .marca {
        justify-content: flex-start;
        padding-left: 12px;
        padding-right: 12px;
    }

    :root[data-menu="recolhido"] .marca > span {
        display: inline;
    }

    :root[data-menu="recolhido"] .seletor-perfil {
        display: block;
    }

    :root[data-menu="recolhido"] .usuario-dados {
        display: flex;
    }

    .botao-abrir-menu {
        position: fixed;
        top: 10px;
        left: 10px;
        z-index: 40;

        display: flex;
        align-items: center;
        justify-content: center;

        width: 40px;
        height: 40px;
        padding: 0;

        border: 1px solid var(--cor-borda);
        border-radius: 10px;

        background: var(--cor-superficie);
        color: var(--cor-texto);

        font-family: inherit;
        font-size: 17px;
        line-height: 1;

        cursor: pointer;
    }

    .fundo-gaveta {
        position: fixed;
        inset: 0;
        z-index: 45;

        background: var(--cor-fundo-gaveta);

        opacity: 0;
        pointer-events: none;
        transition: opacity 0.22s ease;
    }

    .gaveta-aberta .fundo-gaveta {
        display: block;
        opacity: 1;
        pointer-events: auto;
    }

    /* A gaveta saiu do fluxo, então o conteúdo recupera a largura toda.
       O recuo no topo abre espaço para o ☰, que flutua sobre o título. */
    .conteudo {
        padding-left: 16px;
        padding-right: 16px;
        padding-top: 58px;
    }

    /* Com a gaveta aberta, rolar o fundo por baixo dela desorienta. */
    .gaveta-aberta {
        overflow: hidden;
    }


    /* --- Topo fixo no celular (item 7) ---
       Só a barra fina `☰ ‹mês› ⋮` fica fixa. Título, subtítulo e a faixa
       de totais são movidos pelo topo-fixo.js para dentro do
       `.conteudo-rolavel` e rolam com a página. */
    .conteudo.tem-topo-fixo {
        /* Sem os 58px: o ☰ deixa de flutuar e entra na barra fina. */
        padding-top: 0;
    }

    .tem-topo-fixo .cabecalho-fixo {
        padding: 8px 12px;
    }

    .tem-topo-fixo .conteudo-rolavel {
        padding: 12px 16px 20px;
    }

    /* O padding do FAB vem depois na folha e com a mesma especificidade
       da regra acima; sem este reforço o vão do último registro sumia
       no celular. */
    .tem-topo-fixo .conteudo-rolavel.com-acoes-flutuantes {
        padding-bottom: 96px;
    }

    /* A barra fina: ☰ · mês (elástico, centrado) · ⋮, tudo numa linha.
       Gap enxuto: a barra de mês precisa de toda a largura que sobrar,
       senão o › quebra para a segunda linha (telas estreitas). */
    .tem-topo-fixo .cabecalho-tela {
        flex-wrap: nowrap;
        align-items: center;
        gap: 4px;

        margin-bottom: 0;
    }

    /* Os botões da barra fina (+ , 🔍 , ⋮) encostados uns nos outros —
       cada um já tem 34px de alvo de toque, o vão entre eles é só perda
       de espaço para o mês. */
    .tem-topo-fixo .cabecalho-tela .acoes-cabecalho-tela {
        gap: 2px;
    }

    .tem-topo-fixo .cabecalho-tela .botao-abrir-menu {
        position: static;
        top: auto;
        left: auto;
        z-index: auto;

        width: 34px;
        height: 34px;

        border-color: transparent;
        background: transparent;

        flex: 0 0 auto;
    }

    .tem-topo-fixo .cabecalho-tela .barra-periodo-cabecalho {
        /* Anula o `order: 3; width: 100%` do @media 600px: aqui ela fica
           na linha, entre o ☰ e o ⋮. */
        order: 0;
        width: auto;
        margin: 0 auto;

        flex: 1 1 auto;
    }

    .tem-topo-fixo .cabecalho-tela .barra-periodo > strong {
        min-width: 0;
        font-size: 15px;
    }

    /* Categorias e Orçamentos: na barra fina o "+ Nova categoria" /
       "+ Novo orçamento" é só o "+", 34px, ao lado do ⋮. A cor
       (vermelho/verde) vem do tipo da aba, aplicada pelo JS via
       `tipo-despesa`/`tipo-receita`. */
    .tem-topo-fixo #botao-nova-categoria,
    .tem-topo-fixo #botao-novo-orcamento {
        width: 34px;
        height: 34px;
        padding: 0;

        justify-content: center;
        border-radius: 10px;

        font-size: 22px;
        line-height: 1;
    }

    .tem-topo-fixo #botao-nova-categoria .botao-rotulo,
    .tem-topo-fixo #botao-novo-orcamento .botao-rotulo {
        display: none;
    }

}


@media (prefers-reduced-motion: reduce) {

    .menu-lateral,
    .fundo-gaveta {
        transition: none;
    }

}


/* ---------------------------------------------------------------
   Cartão expansível — ver js/detalhe-expansivel.js

   O resumo fica à vista, o detalhe vem no toque. Substitui os dois
   extremos que existiam: categorias abria tudo de uma vez, perfis
   escondia o compartilhamento atrás de um modal.
   --------------------------------------------------------------- */

.cartao-expansivel {
    background: var(--cor-superficie);
    border-radius: 12px;
    box-shadow: var(--sombra-cartao);

    overflow: hidden;
}


.cabecalho-expansivel {
    display: flex;
    align-items: center;
    gap: 12px;

    padding: 13px 14px;
}


/* A seta é o alvo de toque, então tem tamanho de alvo de toque — 32px,
   como a lixeira da linha de lançamento. Girar em vez de trocar o
   caractere mantém a direção legível durante a transição. */
.seta-expansao {
    flex: 0 0 auto;

    width: 32px;
    height: 32px;

    display: flex;
    align-items: center;
    justify-content: center;

    padding: 0;

    border: 1px solid var(--cor-borda);
    border-radius: 8px;

    background: transparent;
    color: var(--cor-texto-suave);

    font-size: 15px;
    line-height: 1;
    cursor: pointer;

    transition: transform 0.15s, border-color 0.15s, color 0.15s;
}


.seta-expansao::before {
    content: "›";
}


.seta-expansao:hover {
    border-color: var(--cor-borda-forte);
    color: var(--cor-texto-forte);
}


.seta-expansao[aria-expanded="true"] {
    transform: rotate(90deg);
    color: var(--cor-texto-forte);
}


/* O total do período, entre o nome e o ⋮. `flex-shrink: 0` porque o
   número nunca deve ser o que encolhe: quem corta com reticências é o
   nome, que dá para adivinhar, e não o valor, que não dá. */
.valor-categoria {
    flex-shrink: 0;

    font-size: 14px;
    font-variant-numeric: tabular-nums;
    color: var(--cor-texto-forte);

    text-align: right;
}


.valor-categoria strong {
    font-size: 15px;
    font-weight: 700;
}


/* O critério de data mora no ⋮; esta linha é o estado dele à vista, na
   mesma ideia das fichas de filtro de movimentações. */
.aviso-totais {
    margin: 0 0 12px;
    padding: 0 2px;

    font-size: 13px;
}


/* O resumo ocupa o meio e encolhe; `min-width: 0` é o que permite o
   nome cortar com reticências em vez de empurrar as ações para fora da
   linha — mesma armadilha da linha de lançamento. */
.resumo-expansivel {
    flex: 1;
    min-width: 0;

    display: flex;
    flex-direction: column;
    gap: 2px;
}


.resumo-expansivel strong {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;

    font-size: 14.5px;
    font-weight: 600;
    color: var(--cor-texto-forte);
}


.resumo-expansivel small {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;

    font-size: 12px;
    color: var(--cor-texto-suave);
}


/* As ações do cabeçalho não esticam: aqui `.acoes-conta` não entra, de
   propósito — ela tem `width: 100%` no celular, e foi exatamente isso
   que engoliu a descrição da linha de lançamento. */
.acoes-expansivel {
    flex: 0 0 auto;

    display: flex;
    align-items: center;
    gap: 6px;
}


.corpo-expansivel {
    padding: 0 14px 12px;
    border-top: 1px solid var(--cor-borda);
}


.corpo-expansivel[hidden] {
    display: none;
}


/* Uma linha do detalhe: subcategoria, ou usuário com quem se
   compartilha. Mesma métrica da linha de lançamento, para as duas
   listas do app terem a mesma densidade. */
.linha-detalhe {
    display: flex;
    align-items: center;
    gap: 11px;

    padding: 9px 0;
    border-bottom: 1px solid var(--cor-borda);
}


.linha-detalhe:last-child {
    border-bottom: 0;
}


.linha-detalhe .resumo-expansivel strong {
    font-weight: 500;
}


.detalhe-vazio {
    padding: 12px 0 4px;

    font-size: 12.5px;
    color: var(--cor-texto-suave);
}


/* Histórico de faturas: uma linha por mês, clicável, que leva a tela
   para aquela competência. Botão e não div — é navegação, e navegação
   precisa funcionar no teclado. */
.lista-historico {
    display: flex;
    flex-direction: column;

    max-height: 60vh;
    overflow-y: auto;
}


.linha-historico {
    display: flex;
    align-items: center;
    gap: 12px;

    width: 100%;
    padding: 12px 4px;

    background: none;
    border: none;
    border-bottom: 1px solid var(--cor-borda);

    text-align: left;
    cursor: pointer;
}


.linha-historico:last-child {
    border-bottom: none;
}


.linha-historico:hover {
    background: var(--cor-menu-flutuante-hover);
}


/* =========================
   COR E ÍCONE DE CATEGORIA
   ========================= */

/* O selo redondo que representa a categoria: o ícone sobre a cor dela,
   ou a inicial do nome quando não há ícone. A cor vem do dado, e não de
   um token do tema — é a única exceção da folha, e é deliberada: ela
   pertence à categoria, não à aparência do app. */
.selo-categoria {
    display: inline-flex;
    align-items: center;
    justify-content: center;

    width: 34px;
    height: 34px;
    flex: 0 0 auto;

    border-radius: 50%;

    color: #fff;
    font-size: 16px;
    font-weight: 700;
    line-height: 1;
}


.selo-pequeno {
    width: 26px;
    height: 26px;
    font-size: 13px;
}


.amostras-cor {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}


.amostra-cor {
    width: 30px;
    height: 30px;

    border: 2px solid transparent;
    border-radius: 50%;

    cursor: pointer;
}


.amostra-cor.escolhida {
    border-color: var(--cor-texto-forte);
    box-shadow: 0 0 0 2px var(--cor-superficie) inset;
}


/* A grade de emojis rola: quarenta e oito sugestões não cabem num
   formulário sem empurrar o botão de salvar para fora da tela. */
.amostras-icone {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(40px, 1fr));
    gap: 4px;

    max-height: 132px;
    overflow-y: auto;

    padding: 6px;
    margin-bottom: 8px;

    border: 1px solid var(--cor-borda);
    border-radius: 10px;
}


.amostra-icone {
    padding: 6px 0;

    background: transparent;
    border: 2px solid transparent;
    border-radius: 8px;

    font-size: 18px;
    cursor: pointer;
}


.amostra-icone:hover {
    background: var(--cor-superficie-alt);
}


.amostra-icone.escolhida {
    border-color: var(--cor-primaria);
    background: var(--cor-primaria-suave);
}


/* =========================
   GRÁFICOS (SVG à mão)
   ========================= */

/* Grade, eixo e texto saem dos tokens do tema — é metade do motivo de
   desenhar à mão em vez de usar biblioteca. Só a cor das séries vem do
   dado: a cor de uma categoria é dela, não da aparência do app. */
.grafico {
    display: block;
    width: 100%;
    height: auto;
}


.grafico-rosca {
    max-width: 230px;
    margin: 0 auto 6px;
}


/* O fio entre fatias é a cor da superfície: separa sem inventar uma cor
   nova, e continua separando quando o tema vira. */
.fatia-grafico {
    stroke: var(--cor-superficie);
    stroke-width: 2;
}


.rotulo-fatia {
    fill: #fff;
    font-size: 11px;
    font-weight: 700;
    text-anchor: middle;

    /* A fatia clara pode engolir o branco; a sombra segura o contraste
       sem escolher uma cor de texto por fatia. */
    paint-order: stroke;
    stroke: rgba(0, 0, 0, .35);
    stroke-width: 2.5;
}


.centro-rosca-valor {
    fill: var(--cor-texto-forte);
    font-size: 17px;
    font-weight: 700;
    text-anchor: middle;
}


.centro-rosca-nota {
    fill: var(--cor-texto-suave);
    font-size: 10px;
    text-anchor: middle;
}


.rotulo-barra {
    fill: var(--cor-texto);
    font-size: 11px;
    font-weight: 600;
}


.valor-barra {
    fill: var(--cor-texto-medio);
    font-size: 11px;
    text-anchor: end;
}


.rotulo-mes {
    fill: var(--cor-texto-suave);
    font-size: 9px;
    text-anchor: middle;
}


.linha-zero {
    stroke: var(--cor-borda-forte);
    stroke-width: 1;
}


.barra-receita {
    fill: var(--cor-receita);
}


.barra-despesa {
    fill: var(--cor-despesa);
}


/* A economia é uma linha por cima das barras: ela é a diferença entre
   elas, e uma terceira barra sugeriria uma terceira medida independente. */
.linha-saldo {
    fill: none;
    stroke: var(--cor-texto-medio);
    stroke-width: 2;
    stroke-linejoin: round;
}


.ponto-saldo {
    fill: var(--cor-texto-medio);
    stroke: var(--cor-superficie);
    stroke-width: 1.5;
}


.legenda-grafico {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 4px 14px;

    margin-top: 8px;

    font-size: 12px;
    color: var(--cor-texto-medio);
}


.item-legenda {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}


.marca-legenda {
    width: 10px;
    height: 10px;
    border-radius: 3px;
    background: var(--cor-texto-medio);
}


.marca-legenda.marca-receita {
    background: var(--cor-receita);
}


.marca-legenda.marca-despesa {
    background: var(--cor-despesa);
}


/* =========================
   DASHBOARD EM CARDS
   ========================= */

/* Uma coluna no celular, duas quando há largura. O card é a unidade da
   tela: cada assunto no seu, com o ⋮ das opções dele. */
.grade-cards {
    display: grid;
    grid-template-columns: 1fr;

    /* Masonry — ver js/masonry.js e a nota em .lista-contas. */
    --masonry-gap: 16px;
    grid-auto-rows: 1px;
    column-gap: 16px;
    row-gap: 0;
    align-items: start;
}


@media (min-width: 900px) {
    .grade-cards {
        grid-template-columns: 1fr 1fr;
    }
}


/* Quando o navegador trouxer masonry nativo, o hack do js/masonry.js sai
   de cena: a folha volta ao fluxo normal de linhas e o JS se abstém
   (feature-detect no próprio arquivo). Uma regra só para as três grades. */
@supports (grid-template-rows: masonry) {
    .grade-cards,
    .lista-contas:not(.lista-simples),
    .lista-cartoes:not(.lista-simples),
    .lista-categorias,
    .lista-orcamentos {
        grid-template-rows: masonry;
        grid-auto-rows: auto;
        row-gap: var(--masonry-gap);
    }
}


.cartao-dashboard {
    padding: 18px 18px 14px;

    background: var(--cor-superficie);
    border: 1px solid var(--cor-borda);
    border-radius: 14px;
}


.cabecalho-card {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;

    margin-bottom: 6px;
}


.cabecalho-card h2 {
    margin: 0;
    font-size: 17px;
}


.acoes-card {
    display: flex;
    align-items: center;
    gap: 2px;
}


/* O `↗` abre a tela cheia do assunto — o primeiro dos dois níveis de
   clique. É um link de verdade para o toque longo e o teclado
   funcionarem como em qualquer link. */
.acoes-card a.botao-tres-pontos {
    text-decoration: none;
    font-size: 15px;
}


.corpo-card {
    display: flex;
    flex-direction: column;
}


/* A linha do card: rótulo à esquerda, valores à direita, e o previsto
   em cinza embaixo do valor. É o desenho da referência, e vale para as
   cinco linhas da visão geral, para cada conta e para cada cartão. */
.linha-visao,
.linha-card {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;

    padding: 10px 0;

    border-bottom: 1px solid var(--cor-borda);

    color: inherit;
    text-decoration: none;
}


.linha-visao:last-child,
.linha-card:last-child {
    border-bottom: none;
}


.linha-card.linha-clicavel,
a.linha-card {
    cursor: pointer;
}


.linha-card.linha-clicavel:hover,
a.linha-card:hover {
    background: var(--cor-superficie-alt);
    border-radius: 8px;
}


/* Um adicional é do principal logo acima: o recuo diz isso sem repetir
   o nome do pai em cada linha. */
.linha-adicional {
    padding-left: 14px;
}


.rotulo-visao {
    display: flex;
    flex-direction: column;
    gap: 2px;

    /* Ocupa o espaço livre: sem isto o rótulo se encolhe ao texto e
       flutua no meio da linha, longe do nome que ele descreve. */
    flex: 1 1 auto;
    min-width: 0;
}


.rotulo-visao strong {
    font-size: 14px;

    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}


.valores-visao {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 2px;

    flex: 0 0 auto;
    text-align: right;
}


.valores-visao strong {
    font-size: 15px;
}


.valores-visao.tipo-receita strong {
    color: var(--cor-receita-contraste);
}


.valores-visao.tipo-despesa strong {
    color: var(--cor-despesa-contraste);
}


/* O círculo colorido da visão geral. A cor vem do tipo de transação —
   despesa vermelha, receita verde, transferência âmbar —, que é a mesma
   paleta semântica do resto do app. */
/* Como `<span>` na linha que não lança e como `<button>` na que lança —
   o reset abaixo faz os dois ficarem idênticos. */
button.icone-visao {
    border: none;
    cursor: pointer;
    font-family: inherit;
}


.linha-visao.linha-clicavel {
    cursor: pointer;
}


.linha-visao.linha-clicavel:hover {
    background: var(--cor-superficie-alt);
    border-radius: 8px;
}


.icone-visao {
    display: flex;
    align-items: center;
    justify-content: center;

    width: 34px;
    height: 34px;
    flex: 0 0 auto;

    margin-right: 10px;

    border-radius: 50%;

    font-size: 15px;
    font-weight: 700;
    line-height: 1;
}


.icone-visao.tipo-receita {
    background: var(--cor-receita);
    color: var(--cor-receita-texto);
}


.icone-visao.tipo-despesa {
    background: var(--cor-despesa);
    color: var(--cor-despesa-texto);
}


.icone-visao.tipo-transferencia {
    background: var(--cor-transferencia);
    color: var(--cor-transferencia-texto);
}


.icone-visao.icone-neutro {
    background: var(--cor-superficie-alt);
    color: var(--cor-texto-medio);
}


.icone-visao.icone-cartao {
    background: var(--cor-primaria);
    color: var(--cor-primaria-texto);
}


/* O rodapé de total, destacado do resto: é o número que se procura de
   relance quando o card tem dez linhas. */
.total-card {
    margin-top: 6px;
    padding: 4px 12px;

    background: var(--cor-superficie-alt);
    border-radius: 10px;
}


.total-card .linha-visao {
    border-bottom: none;
}


/* O total do período nos cards de categoria. Enquanto o gráfico não
   existe (ele vem na etapa 4), é ele que responde "quanto no mês". */
.total-grafico {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;

    padding: 10px 0 14px;
}


.total-grafico strong {
    font-size: 22px;
}


/* Linha de estado dos cards de categoria (itens 9 e 10): critério ≠
   padrão, pendentes fora sob "efetivação", inclusão das não somadas. */
.nota-grafico-categoria {
    margin: 2px 0 8px;
    padding: 0 6px;

    font-size: 12px;
    text-align: center;
}


.estado-vazio-card {
    padding: 18px 6px;
}


.estado-vazio-card h3 {
    font-size: 15px;
}


/* A busca do dashboard e a barra de mês dividem a mesma faixa. No
   celular a busca ocupa a linha inteira e o mês vem embaixo. */
/* A busca ocupa a largura toda e não tem botão "Buscar": o Enter já
   envia, e o botão só roubava espaço do campo. A moldura arredondada é
   da **forma**, não do input — assim a marca à esquerda e a lupa à
   direita ficam dentro da mesma pílula. */
.forma-busca-dashboard {
    display: flex;
    align-items: center;
    gap: 8px;

    width: 100%;
    margin-bottom: 14px;
    padding: 6px 8px 6px 14px;

    border: 1px solid var(--cor-borda);
    border-radius: 999px;

    background: var(--cor-superficie);
}

/* Foco na pílula inteira, e não só no campo: o anel em volta de um
   input sem borda visível apareceria no meio da moldura. */
.forma-busca-dashboard:focus-within {
    border-color: var(--cor-primaria);
}

.marca-busca {
    flex-shrink: 0;

    width: 18px;
    height: 18px;
}

/* O campo perde a própria moldura: quem a desenha agora é a forma. */
.forma-busca-dashboard input {
    flex: 1;
    min-width: 0;

    padding: 8px 0;

    border: none;
    background: none;
    box-shadow: none;
}

.forma-busca-dashboard input:focus {
    outline: none;
    box-shadow: none;
}

/* Fundo claro de propósito: a lupa é o alvo de toque de quem não usa
   Enter, e precisa se destacar da pílula sem virar um botão cheio. */
.botao-lupa {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;

    width: 34px;
    height: 34px;
    padding: 0;

    border: 1px solid var(--cor-borda);
    border-radius: 999px;

    background: var(--cor-superficie-alt);

    font-size: 14px;
    line-height: 1;
    cursor: pointer;
}

.botao-lupa:hover {
    background: var(--cor-borda);
}


/* O checkbox de "exibir" na tela de configurar o resumo. Ordenar e
   escolher o que aparece são a mesma decisão, e por isso a mesma tela. */
.visivel-ordenavel {
    flex: 0 0 auto;
    margin: 0;
}


/* Dividir um lançamento sem sair do formulário: uma combobox com
   checkbox diz **quem**, e cada marcado vira uma linha com o valor.
   Lista de perfis empilhada não cabe num formulário que já tem quinze
   campos — era isso que empurrava a divisão para um modal à parte. */
.seletor-compartilhar {
    position: relative;

    display: flex;
    flex-direction: column;
    gap: 10px;
}


.combo-perfis {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;

    width: 100%;
    padding: 10px 12px;

    background: var(--cor-superficie);
    color: var(--cor-texto);

    border: 1px solid var(--cor-borda);
    border-radius: 10px;

    font-size: 14px;
    text-align: left;
    cursor: pointer;
}


.combo-perfis:hover {
    border-color: var(--cor-borda-forte);
}


.seta-combo {
    color: var(--cor-texto-suave);
}


.painel-perfis {
    position: absolute;
    top: 46px;
    left: 0;
    right: 0;
    z-index: 30;

    max-height: 220px;
    overflow-y: auto;

    padding: 8px;

    background: var(--cor-superficie);
    border: 1px solid var(--cor-borda);
    border-radius: 10px;
    box-shadow: 0 8px 24px var(--cor-sombra-menu);
}


.painel-perfis .opcao-checkbox {
    padding: 6px 4px;
}


.linhas-divisao {
    display: flex;
    flex-direction: column;
    gap: 10px;
}


/* Nome, valor, tipo e o ✕ numa linha só. No celular o nome fica em cima
   e os três controles embaixo: lado a lado, o seletor de tipo é um
   texto inteiro e some. */
.linha-divisao {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 8px;
    align-items: center;

    padding: 10px 12px;

    background: var(--cor-superficie-alt);
    border-radius: 10px;
}


/* No celular: o nome e o ✕ na primeira linha, o valor e o tipo embaixo.
   Os quatro lado a lado deixariam o seletor de tipo — que é um texto
   inteiro — em 60px. */
.nome-divisao {
    grid-column: 1;
    font-weight: 600;
    font-size: 14px;
}


.linha-divisao [data-remover] {
    grid-column: 2;
    grid-row: 1;
}


.linha-divisao input[data-valor],
.linha-divisao select[data-tipo],
.linha-divisao .marca-faturar,
.linha-divisao .aviso-divisao {
    grid-column: 1 / -1;
}


/* "Permitir faturar" ocupa a largura toda, abaixo dos controles: ela é
   uma frase, não um campo, e espremê-la ao lado do seletor de tipo
   deixaria as duas ilegíveis. */
.linha-divisao .marca-faturar {
    font-size: 13px;
    color: var(--cor-texto-medio);
}


@media (min-width: 560px) {

    .linha-divisao {
        grid-template-columns: 1fr 130px 140px 32px;
    }

    .nome-divisao,
    .linha-divisao input[data-valor],
    .linha-divisao select[data-tipo],
    .linha-divisao [data-remover] {
        grid-column: auto;
        grid-row: auto;
    }

    .linha-divisao .marca-faturar,
    .linha-divisao .aviso-divisao {
        grid-column: 1 / -1;
    }
}


.resumo-divisao {
    margin: 0;
}


/* O par "Valor total | Valor parcela", no padrão de duas caixas lado a
   lado: a pergunta tem exatamente duas respostas e as duas cabem na
   tela, então um select esconderia metade da informação atrás de um
   toque. */
.segmentado {
    display: grid;
    grid-template-columns: 1fr 1fr;

    border: 1px solid var(--cor-borda);
    border-radius: 10px;
    overflow: hidden;
}


.opcao-segmento {
    padding: 10px 8px;

    background: var(--cor-superficie);
    color: var(--cor-texto-medio);

    border: none;

    font-size: 14px;
    cursor: pointer;
}


.opcao-segmento + .opcao-segmento {
    border-left: 1px solid var(--cor-borda);
}


.opcao-segmento.ativo {
    background: var(--cor-primaria-suave);
    color: var(--cor-primaria-contraste);
    font-weight: 600;
}


/* Dividir um lançamento: uma linha por perfil, com o valor livre e a
   calculadora anexada. O valor não é uma fração calculada — dividir uma
   conta raramente cai em metades exatas. */
.lista-compartilhar {
    display: flex;
    flex-direction: column;
    gap: 14px;

    max-height: 50vh;
    overflow-y: auto;
}


.linha-compartilhar {
    display: flex;
    flex-direction: column;
    gap: 8px;

    padding-bottom: 12px;
    border-bottom: 1px solid var(--cor-borda);
}


.linha-compartilhar:last-child {
    border-bottom: none;
    padding-bottom: 0;
}


/* O campo de valor traz a calculadora anexada, e o seletor de tipo é
   um texto inteiro: lado a lado, os três ficam ilegíveis na largura de
   um celular. Empilha por padrão e só abre em duas colunas quando há
   espaço de verdade. */
.campos-compartilhar {
    display: grid;
    grid-template-columns: 1fr;
    gap: 8px;
}


@media (min-width: 560px) {
    .campos-compartilhar {
        grid-template-columns: 1fr 1fr;
    }
}


.texto-erro {
    color: var(--cor-despesa);
}


/* Tela "Compartilhados". */
.totais-compartilhados {
    display: flex;
    justify-content: space-between;

    margin-bottom: 20px;
    padding: 14px 16px;

    background: var(--cor-superficie);
    border: 1px solid var(--cor-borda);
    border-radius: 12px;
}


.totais-compartilhados strong {
    display: block;
    font-size: 18px;
    font-weight: 700;
}


.aviso-compartilhados {
    margin: 0 0 16px;
    padding: 12px 14px;

    background: var(--cor-superficie);
    border: 1px solid var(--cor-borda);
    border-left: 3px solid var(--cor-transferencia);
    border-radius: 8px;

    font-size: 13.5px;
}


.titulo-secao {
    margin: 22px 0 10px;
    font-size: 14px;
    font-weight: 600;
    color: var(--cor-texto-suave);
    text-transform: uppercase;
    letter-spacing: .04em;
}


.lista-compartilhados {
    display: flex;
    flex-direction: column;
    gap: 10px;
}


.cartao-compartilhado {
    display: flex;
    align-items: center;
    gap: 12px;

    padding: 13px 14px;

    background: var(--cor-superficie);
    border: 1px solid var(--cor-borda);
    border-radius: 12px;
}


/* ------------------------------------------------ painel do topo

   Os três números do saldo e o gráfico do dia a dia, acima da busca. O
   saldo do meio é o número da tela; os laterais são contexto e ficam
   menores, com o mesmo peso um do outro para nenhum dos dois puxar a
   leitura. */
.painel-saldo:empty {
    display: none;
}

.painel-saldo {
    margin-bottom: 16px;
    padding: 18px 20px;

    border: 1px solid var(--cor-borda);
    border-radius: 14px;

    background: var(--cor-superficie);
}

.numeros-saldo {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 12px;
}

.numero-saldo {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
}

.numero-saldo-lateral {
    align-items: center;
}

/* O saldo no centro, e os laterais alinhados às bordas: é o desenho que
   diz "de onde veio, onde está, para onde vai" sem precisar de rótulo
   explicando a ordem. */
.numero-saldo-centro {
    align-items: center;
    padding: 0 8px;
}

.numero-saldo span {
    color: var(--cor-texto-suave);
    font-size: 12px;
    white-space: nowrap;
}

.numero-saldo strong {
    font-size: 15px;
    color: var(--cor-texto-forte);
    white-space: nowrap;
}

.numero-saldo-centro strong {
    font-size: 26px;
}

.grafico-do-painel {
    margin-top: 14px;
}

/* Sem `width: 100%`: o viewBox já vem na largura medida do contêiner,
   então esticar de novo desfaria justamente o que essa medição resolve. */
.grafico-linha {
    display: block;
    max-width: 100%;
    height: auto;
    margin: 0 auto;
}

.area-linha {
    fill: var(--cor-primaria);
    opacity: 0.14;
}

.traco-linha {
    stroke: var(--cor-primaria);
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.ponto-linha {
    fill: var(--cor-primaria);
    stroke: var(--cor-superficie);
    stroke-width: 1.5;
}

.marca-eixo {
    fill: var(--cor-texto-suave);
    font-size: 9px;
    text-anchor: middle;
}

.marca-eixo-y,
.marca-eixo-fim {
    text-anchor: end;
}

.marca-eixo-inicio {
    text-anchor: start;
}

.nota-painel {
    margin-top: 8px;
    color: var(--cor-texto-suave);
    font-size: 12px;
    text-align: center;
}


/* Abaixo de 480px os três números não cabem lado a lado sem espremer o
   central, que é o que se vem ver. Os laterais descem para uma linha
   própria, dividindo a largura. */
@media (max-width: 480px) {
    .numeros-saldo {
        grid-template-columns: 1fr 1fr;
        gap: 10px 12px;
    }

    .numero-saldo-centro {
        grid-column: 1 / -1;
        order: -1;
    }
}


/* --------------------------------- cor de fundo do painel do topo */

.grade-cores-painel {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(44px, 1fr));
    gap: 10px;

    margin-bottom: 18px;
}

.opcao-cor-painel {
    width: 100%;
    aspect-ratio: 1;

    border: 2px solid transparent;
    border-radius: 10px;

    cursor: pointer;
}

/* O anel de escolhido vem por fora, com a cor da superfície entre ele e
   a amostra — assim ele se lê tanto sobre uma cor clara quanto escura. */
.opcao-cor-painel.escolhida {
    border-color: var(--cor-texto-forte);
    box-shadow: inset 0 0 0 2px var(--cor-superficie);
}

.opcao-cor-painel.sem-cor {
    background: var(--cor-superficie-alt);
    color: var(--cor-texto-suave);
    font-size: 18px;
    font-weight: 700;
}

.campo-cor-automatica {
    padding-top: 14px;
    border-top: 1px solid var(--cor-borda);
}

/* Duas classes: `.campo label` é mais específico que uma classe só, e
   punha o checkbox numa linha e o texto na de baixo. */
.campo label.rotulo-com-ajuda {
    display: flex;
    align-items: center;
    gap: 8px;

    margin-bottom: 0;
    cursor: pointer;
}

.campo label.rotulo-com-ajuda input {
    width: auto;
    margin: 0;
}

/* O "?" das opções que precisam de explicação. Redondo e discreto: ele
   não compete com o controle, mas é um alvo de toque de verdade. */
.botao-ajuda {
    display: inline-flex;
    align-items: center;
    justify-content: center;

    width: 20px;
    height: 20px;
    padding: 0;

    border: 1px solid var(--cor-borda);
    border-radius: 999px;

    background: var(--cor-superficie-alt);
    color: var(--cor-texto-suave);

    font-size: 12px;
    font-weight: 700;
    line-height: 1;
    cursor: help;
}

.botao-ajuda:hover {
    color: var(--cor-texto-forte);
    border-color: var(--cor-primaria);
}

.nota-cor-automatica {
    margin: 6px 0 10px 28px;
    font-size: 12px;
}
