/* ==========================================================================
   Gastos — folha unica.
   Principio: a cor so aparece quando significa alguma coisa. O resto e
   preto, branco e espaco. Tema segue o sistema do iOS automaticamente.
   ========================================================================== */

:root {
    /* Neutros — light */
    --fundo:        #ffffff;
    --fundo-sutil:  #f7f7f8;
    --tinta:        #09090b;
    --tinta-media:  #52525b;
    --tinta-fraca:  #a1a1aa;
    --linha:        #e4e4e7;
    --linha-forte:  #d4d4d8;

    /* Semanticas — usadas so no indicador de ritmo */
    --folga:   #15803d;
    --aperto:  #b45309;
    --estouro: #b91c1c;

    /* Escala tipografica: poucos degraus, muito contraste */
    --t-saldo:   clamp(3.75rem, 19vw, 5.5rem);
    --t-titulo:  1.0625rem;
    --t-corpo:   0.9375rem;
    --t-micro:   0.6875rem;

    --gap:    1.5rem;
    --raio:   14px;
    --borda:  0.5px;

    --transicao: 160ms cubic-bezier(0.32, 0.72, 0, 1);
}

@media (prefers-color-scheme: dark) {
    :root {
        --fundo:        #000000;
        --fundo-sutil:  #0c0c0e;
        --tinta:        #fafafa;
        --tinta-media:  #a1a1aa;
        --tinta-fraca:  #52525b;
        --linha:        #1c1c1f;
        --linha-forte:  #2a2a2e;

        --folga:   #4ade80;
        --aperto:  #fbbf24;
        --estouro: #f87171;
    }
}

* { margin: 0; padding: 0; box-sizing: border-box; }

/* O `hidden` do HTML vale `display: none` na folha do navegador, que perde
   para QUALQUER classe que defina display. Sem esta linha `el.hidden = true`
   nao esconde nada: era o caso do botao de ditado (`.entrada__acao` e grid) e
   da foto colada. */
[hidden] { display: none !important; }

html {
    -webkit-text-size-adjust: 100%;
    background: var(--fundo);
}

body {
    font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", system-ui, sans-serif;
    font-size: var(--t-corpo);
    line-height: 1.45;
    color: var(--tinta);
    background: var(--fundo);
    -webkit-font-smoothing: antialiased;
    min-height: 100dvh;
}

/* ==========================================================================
   Layout do app: coluna da altura da tela
   ==========================================================================
   Estrutura no molde do PokerWeb: uma div com a altura da tela, coluna flex,
   miolo rolando por dentro e a barra como ultimo item. Nada de
   `position: fixed` — nao existe "colar embaixo" para dar errado.

   Qual unidade de altura usar esta explicado na regra `.casca` abaixo. */

/* UMA fonte de verdade para a altura: a `.casca`, e so ela.
   Antes html e body tinham `height: 100%` competindo com o `100svh` daqui —
   quando os dois discordavam, o `overflow: hidden` do body cortava o fim da
   coluna e a barra saia da tela. O PokerWeb nao poe altura nenhuma no
   html/body, so `overscroll-behavior`, e e por isso que funciona. */

html.app,
body.app {
    overscroll-behavior: none;
}

/* O `min-height` do body base tambem competia com a casca */
body.app {
    min-height: 0;
}

/* Medido no iPhone do Rodopoulos, app instalado (17/08/2026):
       100vh  = 852 px  <- a tela inteira, correto
       100lvh = 852 px  <- idem
       100svh = 793 px  <- ERRADO
       100dvh = 793 px  <- ERRADO
   No PWA standalone o WebKit calcula svh/dvh descontando uma barra de
   navegador que nao existe, e sobra faixa morta embaixo. Por isso aqui o
   app instalado usa `vh`, que e a tela toda.

   No navegador comum vale o contrario: as barras existem de verdade e `dvh`
   e quem acompanha, enquanto `vh` passaria por baixo delas. */

.casca {
    height: 100vh;
    height: 100dvh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.standalone .casca {
    height: 100vh;
}

/* Nada de highlight cinza ao tocar — o app tem que parecer nativo */
a, button, input, textarea, [role="button"] {
    -webkit-tap-highlight-color: transparent;
}

:focus-visible {
    outline: 2px solid var(--tinta);
    outline-offset: 3px;
    border-radius: 4px;
}

.env {
    max-width: 34rem;
    margin: 0 auto;
    padding: 1.25rem 1.375rem 6.5rem;
}

/* ==========================================================================
   Casca: topo, abas e gaveta
   ========================================================================== */

.topo {
    flex: 0 0 auto;
    z-index: 20;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.875rem 1.375rem;
    /* Solido: nada passa por tras dele agora que o scroll e do .conteudo */
    background: var(--fundo);
    border-bottom: var(--borda) solid var(--linha);
}

/* So o app instalado passa por baixo da status bar. No Safari comum este
   padding empurraria o cabecalho para baixo sem motivo. */
.standalone .topo {
    padding-top: calc(0.875rem + env(safe-area-inset-top));
}

.topo__titulo {
    font-size: 1.0625rem;
    font-weight: 600;
    letter-spacing: -0.01em;
}

.topo__menu {
    display: grid;
    place-items: center;
    width: 2.25rem;
    height: 2.25rem;
    margin-right: -0.375rem;
    border: none;
    background: transparent;
    color: var(--tinta);
    cursor: pointer;
    border-radius: 8px;
}

.topo__menu svg { width: 1.25rem; height: 1.25rem; }
.topo__menu:active { background: var(--fundo-sutil); }

/* Barra de rolagem fora: no Windows ela e um bloco cinza que corta o layout.
   O conteudo continua rolando normalmente, de roda, dedo ou teclado. */
.conteudo,
.abas,
.gaveta__painel {
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.conteudo::-webkit-scrollbar,
.abas::-webkit-scrollbar,
.gaveta__painel::-webkit-scrollbar {
    width: 0;
    height: 0;
}

/* O unico pedaco que rola. Como a barra inferior vem depois dele no fluxo,
   nao ha nada tapando o fim da lista — sem reservar espaco por baixo. */
.conteudo {
    flex: 1 1 auto;
    /* Flex item nao encolhe abaixo do conteudo sem isto, e ai a barra seria
       empurrada para fora da tela */
    min-height: 0;
    overflow-y: auto;
    /* `contain` para o arrasto morrer aqui e nao virar bounce da tela toda */
    overscroll-behavior-y: contain;
    -webkit-overflow-scrolling: touch;
    width: 100%;
    max-width: 34rem;
    margin: 0 auto;
    padding: 1.25rem 1.375rem 2rem;
}

/* Coluna do conteudo: o que se le mais o campo de chat.
   A navegacao fica de fora de proposito — no desktop ela vira a coluna da
   esquerda e o campo precisa continuar colado ao conteudo. */
.principal {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
}

/* Barra de abas: embaixo no celular, porque o topo do iPhone esta fora do
   alcance do polegar. No desktop vira coluna lateral (ver o media query). */
.abas {
    flex: 0 0 auto;
    z-index: 20;
    display: flex;
    background: var(--fundo);
    border-top: var(--borda) solid var(--linha);
    padding-bottom: env(safe-area-inset-bottom);
}

/* Com o teclado aberto quem manda no rodape e ele: a navegacao sai e o campo
   de texto fica encostado no teclado, como em qualquer app de conversa.

   Some junto o problema dos 34px de safe-area, que o iPhone continua
   reportando com o teclado na frente e viravam uma faixa morta entre os
   icones e o teclado.

   A classe vem do ajuste de altura no app.js, que ja sabe quando o teclado
   esta aberto. So no celular — no desktop a `.abas` e a coluna da esquerda. */
@media (max-width: 59.9375rem) {
    .teclado .abas { display: none; }
}

/* Atalhos do menu: no celular vivem na gaveta do canto */
.abas__extra { display: none; }

.abas__item {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.1875rem;
    padding: 0.5rem 0.25rem 0.4375rem;
    color: var(--tinta-fraca);
    text-decoration: none;
    font-size: 0.625rem;
    letter-spacing: 0.01em;
    transition: color var(--transicao);
}

.abas__item svg { width: 1.375rem; height: 1.375rem; }
.abas__item--ativo { color: var(--tinta); }
.abas__item:active { opacity: 0.6; }

.gaveta {
    position: fixed;
    inset: 0;
    z-index: 40;
    background: rgba(0, 0, 0, 0.35);
}

.gaveta__painel {
    position: absolute;
    top: 0;
    right: 0;
    width: min(17rem, 82vw);
    height: 100%;
    background: var(--fundo);
    border-left: var(--borda) solid var(--linha);
    padding: 1rem 0;
    display: flex;
    flex-direction: column;
}

/* A gaveta cobre a tela inteira, entao passa por baixo da status bar
   pelo mesmo criterio do cabecalho */
.standalone .gaveta__painel {
    padding-top: calc(1rem + env(safe-area-inset-top));
    padding-bottom: calc(1rem + env(safe-area-inset-bottom));
}

.gaveta__item {
    padding: 0.9375rem 1.375rem;
    color: var(--tinta);
    text-decoration: none;
    border-bottom: var(--borda) solid var(--linha);
}

.gaveta__item:active { background: var(--fundo-sutil); }
.gaveta__item--fim {
    margin-top: auto;
    border-bottom: none;
    border-top: var(--borda) solid var(--linha);
    color: var(--estouro);
}

/* ==========================================================================
   Saldo — o unico numero que importa ao abrir o app
   ========================================================================== */

.saldo {
    padding: 2.5rem 0 0.5rem;
}

.saldo__cifra {
    display: block;
    font-size: var(--t-micro);
    font-weight: 500;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--tinta-fraca);
    margin-bottom: 0.625rem;
}

.saldo__valor {
    display: block;
    font-size: var(--t-saldo);
    font-weight: 200;
    letter-spacing: -0.045em;
    line-height: 0.92;
    font-variant-numeric: tabular-nums;
    color: var(--tinta);
}

.saldo__valor sup {
    font-size: 0.36em;
    font-weight: 400;
    letter-spacing: 0;
    vertical-align: top;
    position: relative;
    top: 0.55em;
    margin-left: 0.1em;
    color: var(--tinta-media);
}

.saldo__nota {
    margin-top: 0.875rem;
    font-size: var(--t-corpo);
    color: var(--tinta-media);
    font-variant-numeric: tabular-nums;
}

.saldo--estouro .saldo__valor { color: var(--estouro); }

/* ==========================================================================
   Regua do ciclo — o elemento de assinatura.
   Duas grandezas na mesma linha: quanto do dinheiro foi (preenchimento)
   e quanto do tempo passou (marcador). Se o preenchimento passa o
   marcador, o ritmo esta acima do previsto.
   ========================================================================== */

.regua {
    margin: 1.75rem 0 0;
}

.regua__trilho {
    position: relative;
    height: 3px;
    background: var(--linha);
    border-radius: 999px;
}

.regua__gasto {
    position: absolute;
    inset: 0 auto 0 0;
    border-radius: 999px;
    background: var(--folga);
    transition: width var(--transicao), background-color var(--transicao);
}

.regua--aperto  .regua__gasto { background: var(--aperto); }
.regua--estouro .regua__gasto { background: var(--estouro); }

/* Marcador do dia de hoje dentro do ciclo */
.regua__hoje {
    position: absolute;
    top: -4px;
    bottom: -4px;
    width: 1.5px;
    background: var(--tinta);
    transform: translateX(-50%);
}

.regua__legenda {
    display: flex;
    justify-content: space-between;
    margin-top: 0.6875rem;
    font-size: var(--t-micro);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--tinta-fraca);
    font-variant-numeric: tabular-nums;
}

.regua__ritmo { color: var(--tinta-media); }
.regua--aperto  .regua__ritmo { color: var(--aperto); }
.regua--estouro .regua__ritmo { color: var(--estouro); }

/* ---- fatura fechada ----
   Passado: nao aceita mais lancamento. A barra fica vermelha, o marcador de
   "hoje" some (nao ha ritmo a acompanhar) e o trilho ganha um risco por cima
   para dizer, sem texto, que aquilo esta encerrado. */
.regua--fechada .regua__gasto { background: var(--estouro) !important; }
.regua--fechada .regua__hoje  { display: none; }

.regua--fechada .regua__trilho {
    opacity: 0.75;
    border: var(--borda) solid var(--estouro);
}

.regua--fechada .regua__ritmo {
    color: var(--estouro);
    font-weight: 500;
}

/* O saldo de uma fatura fechada e numero de arquivo: perde o peso visual
   de "quanto ainda posso gastar" e ganha uma tarja discreta. */
.saldo--fechada .saldo__valor { color: var(--tinta-media); }

.saldo--fechada .saldo__cifra {
    color: var(--estouro);
}

.saldo--fechada .saldo__cifra::after {
    content: " · encerrada";
    color: var(--tinta-fraca);
}

/* ==========================================================================
   Entrada — o gesto principal do app
   ========================================================================== */

/* Ultimo item da coluna de conteudo, logo abaixo do que se esta lendo. */
.entrada {
    flex: 0 0 auto;
    padding: 0.625rem 1.375rem;
    background: var(--fundo);
    border-top: var(--borda) solid var(--linha);
}

.entrada__caixa {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    max-width: 34rem;
    margin: 0 auto;
}

/* Foto colada esperando o envio. Fica acima do campo, com a miniatura do que
   foi colado — colar as cegas e o jeito mais facil de mandar a imagem errada. */
.entrada__anexo {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    max-width: 34rem;
    margin: 0 auto 0.5rem;
    padding: 0.5rem 0.625rem;
    border: var(--borda) solid var(--linha);
    border-radius: var(--raio);
    background: var(--fundo-sutil);
}

.entrada__anexo-mini {
    flex-shrink: 0;
    width: 2.5rem;
    height: 2.5rem;
    object-fit: cover;
    border-radius: 8px;
    background: var(--linha);
}

.entrada__anexo-texto {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.0625rem;
}

.entrada__anexo-titulo {
    font-size: var(--t-corpo);
    color: var(--tinta);
}

.entrada__anexo-nota {
    font-size: var(--t-micro);
    color: var(--tinta-media);
}

.entrada__anexo-tirar {
    flex-shrink: 0;
    width: 2rem;
    height: 2rem;
    display: grid;
    place-items: center;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: var(--tinta-media);
    cursor: pointer;
}

.entrada__anexo-tirar:hover { color: var(--tinta); background: var(--linha); }
.entrada__anexo-tirar svg   { width: 1rem; height: 1rem; }

/* Gravando audio, a foto em espera sai da frente junto com o campo */
.entrada--gravando .entrada__anexo { display: none; }

.entrada__campo {
    flex: 1;
    min-width: 0;
    font: inherit;
    font-size: 1rem; /* 16px: abaixo disso o iOS dá zoom ao focar */
    color: var(--tinta);
    background: var(--fundo-sutil);
    border: var(--borda) solid var(--linha);
    border-radius: var(--raio);
    padding: 0.8125rem 0.9375rem;
    transition: border-color var(--transicao);
}

.entrada__campo::placeholder { color: var(--tinta-fraca); }
.entrada__campo:focus {
    outline: none;
    border-color: var(--linha-forte);
}

.entrada__acao {
    flex-shrink: 0;
    width: 2.875rem;
    height: 2.875rem;
    display: grid;
    place-items: center;
    border: none;
    border-radius: 50%;
    background: var(--tinta);
    color: var(--fundo);
    cursor: pointer;
    transition: opacity var(--transicao), transform var(--transicao);
}

.entrada__acao:disabled { opacity: 0.35; }
.entrada__acao:active:not(:disabled) { transform: scale(0.93); }
.entrada__acao svg { width: 1.125rem; height: 1.125rem; }

/* Gravar e acao secundaria: o ditado do teclado resolve na maioria das vezes */
.entrada__acao--quieto {
    background: transparent;
    color: var(--tinta-media);
    border: var(--borda) solid var(--linha);
}

/* ==========================================================================
   Gravacao no estilo WhatsApp: some o campo, aparecem cancelar e enviar
   com o cronometro no meio. Sem ambiguidade sobre o que cada botao faz.
   ========================================================================== */

.gravando {
    display: none;
    align-items: center;
    gap: 0.75rem;
    max-width: 34rem;
    margin: 0 auto;
}

.entrada--gravando .entrada__caixa { display: none; }
.entrada--gravando .gravando       { display: flex; }

.gravando__cancelar,
.gravando__enviar {
    flex-shrink: 0;
    width: 2.875rem;
    height: 2.875rem;
    display: grid;
    place-items: center;
    border: none;
    border-radius: 50%;
    cursor: pointer;
    transition: transform var(--transicao);
}

.gravando__cancelar {
    background: transparent;
    color: var(--tinta-media);
    border: var(--borda) solid var(--linha-forte);
}

.gravando__enviar {
    background: var(--folga);
    color: #fff;
}

.gravando__cancelar:active,
.gravando__enviar:active { transform: scale(0.93); }

.gravando__cancelar svg,
.gravando__enviar svg { width: 1.125rem; height: 1.125rem; }

.gravando__estado {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    color: var(--tinta-media);
    font-variant-numeric: tabular-nums;
}

.gravando__ponto {
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 50%;
    background: var(--estouro);
    animation: pulsar 1.4s ease-in-out infinite;
}

@keyframes pulsar {
    0%, 100% { opacity: 1; }
    50%      { opacity: 0.3; }
}

.entrada__aviso {
    max-width: 34rem;
    margin: 0.5rem auto 0;
    font-size: var(--t-micro);
    color: var(--tinta-media);
    min-height: 1em;
}

/* ==========================================================================
   Listas
   ========================================================================== */

.secao {
    margin-top: 2.5rem;
}

.secao__titulo {
    font-size: var(--t-micro);
    font-weight: 500;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--tinta-fraca);
    margin-bottom: 0.25rem;
}

/* Corte por dia: numa fatura corrida e a data que orienta a leitura */
.dia {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    margin: 1.75rem 0 0.375rem;
    padding-bottom: 0.375rem;
    border-bottom: var(--borda) solid var(--linha);
}

.dia:first-child { margin-top: 0.75rem; }

.dia__nome {
    font-size: var(--t-micro);
    font-weight: 500;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--tinta-media);
}

.dia__total {
    font-size: var(--t-micro);
    color: var(--tinta-fraca);
    font-variant-numeric: tabular-nums;
}

.lancamento {
    display: flex;
    align-items: baseline;
    gap: 0.875rem;
    padding: 0.8125rem 0;
    border-bottom: var(--borda) solid var(--linha);
}

.lancamento:last-child { border-bottom: none; }

/* Valor a direita, tamanho de leitura: e o dado que se procura na lista */
.lancamento__valor {
    margin-left: auto;
    font-size: 1.0625rem;
    font-variant-numeric: tabular-nums;
    font-weight: 500;
    white-space: nowrap;
}

.lancamento__nome {
    flex: 1;
    min-width: 0;
    font-size: 1rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.lancamento__tag {
    flex-shrink: 0;
    padding: 0.0625rem 0.375rem;
    border-radius: 5px;
    background: var(--fundo-sutil);
    border: var(--borda) solid var(--linha);
    font-size: 0.6875rem;
    color: var(--tinta-media);
}

.lancamento__nome--vago {
    color: var(--tinta-media);
    font-style: italic;
}

.lancamento__quando {
    font-size: var(--t-micro);
    color: var(--tinta-fraca);
    font-variant-numeric: tabular-nums;
}

/* Pendencia: a unica coisa que pede acao, entao e a unica com moldura */
.pendencia {
    border: var(--borda) solid var(--linha-forte);
    border-radius: var(--raio);
    padding: 0.9375rem 1rem;
    margin-top: 0.75rem;
}

.pendencia__pergunta {
    color: var(--tinta);
    margin-bottom: 0.75rem;
}

.pendencia__form {
    display: flex;
    gap: 0.5rem;
}

.pendencia__campo {
    flex: 1;
    min-width: 0;
    font: inherit;
    font-size: 1rem;
    color: var(--tinta);
    background: var(--fundo);
    border: var(--borda) solid var(--linha);
    border-radius: 10px;
    padding: 0.5625rem 0.75rem;
    text-transform: uppercase;
}

.pendencia__campo:focus { outline: none; border-color: var(--linha-forte); }

.botao {
    font: inherit;
    font-size: var(--t-corpo);
    font-weight: 500;
    color: var(--fundo);
    background: var(--tinta);
    border: none;
    border-radius: 10px;
    padding: 0.5625rem 1rem;
    cursor: pointer;
    transition: opacity var(--transicao);
}

.botao:disabled { opacity: 0.35; }
.botao--quieto {
    background: transparent;
    color: var(--tinta-media);
    border: var(--borda) solid var(--linha);
}

.vazio {
    padding: 2rem 0;
    color: var(--tinta-fraca);
}

/* ==========================================================================
   Comercios, filtros e formularios
   ========================================================================== */

.ajuda {
    color: var(--tinta-media);
    margin-bottom: 1.25rem;
    line-height: 1.5;
}

.ajuda strong { color: var(--tinta); font-weight: 600; }


.novo {
    border: var(--borda) solid var(--linha);
    border-radius: var(--raio);
    margin-bottom: 1.25rem;
    overflow: hidden;
}

.novo__abrir {
    padding: 0.875rem 1rem;
    cursor: pointer;
    font-weight: 500;
    list-style: none;
}

.novo__abrir::-webkit-details-marker { display: none; }
.novo__abrir::before { content: "+ "; color: var(--tinta-fraca); }
.novo[open] .novo__abrir::before { content: "− "; }

.novo__form {
    padding: 0 1rem 1rem;
    border-top: var(--borda) solid var(--linha);
}

.comercio {
    border-bottom: var(--borda) solid var(--linha);
}

.comercio__cab {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.8125rem 0;
    cursor: pointer;
    list-style: none;
}

.comercio__cab::-webkit-details-marker { display: none; }

.comercio__nome {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.comercio__meta {
    flex-shrink: 0;
    font-size: var(--t-micro);
    color: var(--tinta-fraca);
    font-variant-numeric: tabular-nums;
}

/* Busca e ordem lado a lado quando cabe */
.filtros {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    align-items: flex-end;
}

.filtros__busca { flex: 1 1 12rem; min-width: 0; margin: 0; }
.filtros__ordem { flex: 0 1 14rem; min-width: 0; margin: 0; }
.filtros__ordem .seletor__caixa { max-width: none; }
.filtros + #listaComercios { margin-top: 1.25rem; }

/* A lista de comercios nao vai para duas colunas: os cartoes abrem e crescem,
   e em multi-coluna o que cresce empurra o resto para a coluna seguinte —
   o item aberto ficava espremido em meia largura e a lista dancava a cada
   clique. Uma coluna so, acompanhando a largura do campo de busca. */
.lista-cartoes {
    width: 100%;
}

/* ---- cartao aberto ----
   Fechado, e so uma linha de lista. Aberto, vira um painel com fundo e
   moldura proprios: sem isso os campos de um comercio encostavam no nome do
   proximo e nao dava para saber onde um terminava. */
.comercio[open] {
    margin: 0.5rem 0 1.25rem;
    border: var(--borda) solid var(--linha-forte);
    border-radius: var(--raio);
    background: var(--fundo-sutil);
    border-bottom: var(--borda) solid var(--linha-forte);
}

.comercio[open] .comercio__cab {
    padding: 0.875rem 1rem;
    border-bottom: var(--borda) solid var(--linha);
}

.comercio[open] .comercio__nome { font-weight: 600; }

.comercio__corpo { padding: 0; }

/* Um assunto por bloco, separados por linha */
.bloco {
    padding: 1rem;
    border-bottom: var(--borda) solid var(--linha);
}

.bloco:last-child { border-bottom: none; }

.bloco__titulo {
    margin-bottom: 0.625rem;
    font-size: var(--t-micro);
    font-weight: 500;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--tinta-fraca);
}

/* Recado do proprio cartao. O aviso geral fica no topo da pagina e, com a
   lista rolada, o usuario nunca via a resposta do que tinha acabado de fazer. */
.comercio__aviso {
    margin-top: 0.5rem;
    font-size: var(--t-micro);
    color: var(--tinta-media);
    min-height: 1.2em;
}

.comercio__aviso--erro { color: var(--estouro); }

/* Mesclar e acao rara e sem volta: fica por ultimo e discreta */
.comercio__mesclar {
    margin-top: 0.75rem;
    padding-top: 0.75rem;
    border-top: var(--borda) solid var(--linha);
}

/* Nome do extrato: fica embaixo do campo de edicao, apagado. Serve para
   conferir de onde veio o lancamento, nao para ser lido no dia a dia. */
.comercio__fatura {
    font-size: var(--t-micro);
    letter-spacing: 0.04em;
    color: var(--tinta-fraca);
    margin: 0.625rem 0 0;
    overflow-wrap: anywhere;
}

/* Edicao do nome do lugar e da categoria */
.editar {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.5rem;
    padding-top: 0.25rem;
}

.editar__campo {
    flex: 1 1 11rem;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.editar__campo--curto { flex: 0 1 8.5rem; }

.editar .campo__entrada { padding: 0.5rem 0.6875rem; }
.editar .botao { flex: 0 0 auto; }

/* A caixa do seletor precisa preencher a coluna e a seta encolhe junto */
.editar .seletor__caixa { max-width: none; }
.editar .seletor__campo { padding-right: 2rem; }
.editar .seletor__seta  { right: 0.625rem; width: 1rem; height: 1rem; }

.chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.375rem;
    margin-bottom: 0.75rem;
}

.chip {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.25rem 0.5rem 0.25rem 0.625rem;
    background: var(--fundo-sutil);
    border: var(--borda) solid var(--linha);
    border-radius: 999px;
    font-size: 0.8125rem;
}

/* Nome do extrato: fonte de largura fixa e tom apagado, porque e texto de
   maquina — serve para conferir, nao para ler. Um comercio mesclado acumula
   varios, e e por eles que a IA sabe onde lancar. */
.chip--fatura {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.6875rem;
    letter-spacing: 0;
    color: var(--tinta-media);
    background: transparent;
    border-style: dashed;
}

.chip__x {
    border: none;
    background: transparent;
    color: var(--tinta-fraca);
    font-size: 1rem;
    line-height: 1;
    padding: 0 0.125rem;
    cursor: pointer;
}

.chip__x:active { color: var(--estouro); }

/* ==========================================================================
   Chat
   ========================================================================== */

/* Sem padding-bottom aqui.
   Havia 3.5rem "para o campo de entrada", de quando ele era `position: fixed`
   e cobria o fim da conversa. Hoje a entrada é irmã do `.conteudo` na coluna e
   ocupa espaço próprio, então aquilo virou folga sobre nada: somado ao padding
   do `.conteudo` dava 96px de vazio depois da última mensagem, e rolar até o
   fim empurrava o texto para fora da tela. Quem afasta a última bolha da borda
   é o padding do `.conteudo`. */
.conversa {
    display: flex;
    flex-direction: column;
    gap: 0.625rem;
}

.fala {
    max-width: 82%;
    padding: 0.625rem 0.875rem;
    border-radius: 18px;
    line-height: 1.4;
    overflow-wrap: anywhere;
    /* A confirmacao vem em linhas: o que entrou, como ficou a fatura, o
       comentario. `pre-line` respeita as quebras sem virar bloco de codigo. */
    white-space: pre-line;
}

.fala--eu {
    align-self: flex-end;
    background: var(--tinta);
    color: var(--fundo);
    border-bottom-right-radius: 5px;
}

.fala--ia {
    align-self: flex-start;
    background: var(--fundo-sutil);
    border: var(--borda) solid var(--linha);
    border-bottom-left-radius: 5px;
}

.fala__hora {
    display: block;
    margin-top: 0.25rem;
    font-size: 0.625rem;
    opacity: 0.55;
    font-variant-numeric: tabular-nums;
}

/* ==========================================================================
   Cartao de resposta
   ==========================================================================
   Confirmacao de gasto em forma de painel: o valor que entrou fica sozinho no
   topo, as metricas do ciclo em celulas separadas e o acumulado do lugar como
   nota. Antes era tudo um paragrafo so, e dava para confundir o total do
   comercio com o gasto recem-lancado. */

.fala--cartao {
    max-width: 100%;
    width: 100%;
    padding: 0;
    background: transparent;
    border: none;
}

.resposta {
    padding: 0.9375rem 1rem 1rem;
    border: var(--borda) solid var(--linha);
    border-radius: var(--raio);
    background: var(--fundo-sutil);
}

.resposta__topo {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 0.875rem;
}

.resposta__valor {
    font-size: 1.75rem;
    font-weight: 600;
    letter-spacing: -0.03em;
    font-variant-numeric: tabular-nums;
    line-height: 1.1;
}

.resposta__sub {
    color: var(--tinta-media);
    font-size: var(--t-corpo);
}

.resposta__tag {
    padding: 0.0625rem 0.4375rem;
    border-radius: 5px;
    background: var(--fundo);
    border: var(--borda) solid var(--linha-forte);
    font-size: var(--t-micro);
    color: var(--tinta-media);
}

/* Antes -> depois: quanto a fatura tinha e quanto ficou. Sem isso o cartao
   so mostrava o acumulado, e nao dava para ver o peso deste lancamento. */
.antesdepois {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 0.875rem;
    font-variant-numeric: tabular-nums;
}

.antesdepois__antes {
    color: var(--tinta-fraca);
    text-decoration: line-through;
    text-decoration-thickness: 1px;
}

.antesdepois__seta {
    width: 0.9375rem;
    height: 0.9375rem;
    flex-shrink: 0;
    color: var(--tinta-fraca);
}

.antesdepois__depois { font-weight: 500; }

.antesdepois__delta {
    padding: 0.0625rem 0.4375rem;
    border-radius: 5px;
    background: var(--fundo);
    border: var(--borda) solid var(--linha-forte);
    font-size: var(--t-micro);
    color: var(--tinta-media);
}

.resposta__grade {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.75rem 1rem;
    padding: 0.875rem 0;
    border-top: var(--borda) solid var(--linha);
    border-bottom: var(--borda) solid var(--linha);
}

.resposta__cel {
    display: flex;
    flex-direction: column;
    gap: 0.0625rem;
    min-width: 0;
}

.resposta__cel-valor {
    font-size: 1.0625rem;
    font-weight: 500;
    font-variant-numeric: tabular-nums;
}

.resposta__cel-rotulo {
    font-size: var(--t-micro);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--tinta-fraca);
}

.resposta__trilho {
    height: 4px;
    margin-top: 0.875rem;
    border-radius: 999px;
    background: var(--linha);
    overflow: hidden;
}

.resposta__preenche {
    height: 100%;
    border-radius: 999px;
    transition: width var(--transicao);
}

.resposta__preenche--folga   { background: var(--folga); }
.resposta__preenche--aperto  { background: var(--aperto); }
.resposta__preenche--estouro { background: var(--estouro); }

.resposta__legenda {
    margin-top: 0.375rem;
    font-size: var(--t-micro);
    color: var(--tinta-fraca);
    font-variant-numeric: tabular-nums;
}

.resposta__linha {
    margin-top: 0.625rem;
    color: var(--tinta-media);
    line-height: 1.4;
}

.resposta__linha--aviso { color: var(--aperto); }

@media (min-width: 60rem) {
    .resposta__grade { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* --------------------------------------------------------------------------
   Cartao montado pela IA

   Nos outros cartoes o formato e fixo e o CSS pode contar com a ordem. Aqui
   nao: a IA escolhe quais blocos entram e em que sequencia. Por isso o
   espacamento e o separador ficam na relacao entre blocos vizinhos, e nao
   dentro de cada um — assim qualquer combinacao fecha certo.
   -------------------------------------------------------------------------- */

.resposta__topo--livre {
    margin-bottom: 0;
    padding-bottom: 0.8125rem;
    border-bottom: var(--borda) solid var(--linha);
}

.resposta__titulo {
    font-size: 1.0625rem;
    font-weight: 600;
    letter-spacing: -0.01em;
}

.resposta--livre .resposta__bloco { margin-top: 0.875rem; }
.resposta--livre .resposta__bloco:first-child { margin-top: 0; }

.resposta--livre .resposta__bloco + .resposta__bloco {
    padding-top: 0.875rem;
    border-top: var(--borda) solid var(--linha);
}

/* As bordas da grade sairiam em cima das do bloco vizinho.
   As colunas ficam as mesmas do resto do app — 2 no celular, 4 no desktop.
   Cheguei a tentar `auto-fit`, que se ajusta a quantidade de numeros, mas com
   4 itens numa tela media dava 3 em cima e 1 sobrando embaixo. */
.resposta--livre .resposta__grade {
    padding: 0;
    border-top: 0;
    border-bottom: 0;
}

/* Estes tres ja trazem margem propria, pensada para o cartao de formato fixo */
.resposta--livre .resposta__linha,
.resposta--livre .resposta__trilho { margin-top: 0; }

.resposta__lista .barra:first-child { padding-top: 0; }
.resposta__lista .barra:last-child  { padding-bottom: 0; }

/* ==========================================================================
   Conferencia da fatura lida por foto
   ==========================================================================
   Leitura de imagem erra e a fatura repete o que ja foi lancado no dia a dia,
   entao nada entra sozinho: cada linha e marcada ou nao antes de virar gasto.
   O que ja esta na conta vem desmarcado e com aviso. */

.revisao__titulo {
    margin-bottom: 0.75rem;
    line-height: 1.4;
}

.revisao {
    border: var(--borda) solid var(--linha);
    border-radius: var(--raio);
    background: var(--fundo-sutil);
    overflow: hidden;
}

/* Em que fatura o grupo de linhas cai. A fatura fecha dia 26, entao uma foto
   tirada no comeco do mes tem compras dos dois lados do corte — sem este
   cabecalho o gasto lancado parece sumido, e so estava na outra fatura. */
.revisao__fatura {
    padding: 0.5rem 0.875rem 0.4375rem;
    border-bottom: var(--borda) solid var(--linha);
    background: var(--fundo);
    font-size: var(--t-micro);
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    /* --tinta-media, e nao --tinta-fraca: no tema escuro o fraco da 2,8:1
       contra o preto. Este rotulo existe justamente para ser lido. */
    color: var(--tinta-media);
}

.revisao__item {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.6875rem 0.875rem;
    border-bottom: var(--borda) solid var(--linha);
    cursor: pointer;
    -webkit-user-select: none;
    user-select: none;
}

.revisao__item:last-child { border-bottom: none; }
.revisao__item--repetido { opacity: 0.6; }
.revisao__item--fora     { opacity: 0.45; text-decoration: line-through; }
.revisao__item--feito    { opacity: 0.75; }

/* O "pode ser repetido" NAO fica apagado: ele entra marcado e vai ser lancado,
   entao precisa puxar o olho em vez de sumir. Tarja em vez de transparencia. */
.revisao__item--suspeito {
    border-left: 3px solid var(--aviso, #d9911f);
    padding-left: 0.55rem;
    background: color-mix(in srgb, var(--aviso, #d9911f) 7%, transparent);
    border-radius: 0 8px 8px 0;
}

/* A frase que explica o casamento. Fica abaixo do nome e do valor, menor, e
   quebra em varias linhas se precisar — e texto para ler, nao rotulo. */
.revisao__pista {
    display: block;
    margin-top: 0.15rem;
    font-size: 0.72rem;
    line-height: 1.35;
    color: var(--aviso, #d9911f);
    opacity: 0.9;
}
.revisao__item--repetido .revisao__pista { color: var(--txt3, #8a8a99); }

/* Mesma caixa do "confiar neste aparelho": o checkbox do sistema nao aceita
   cor e no tema escuro fica branco no branco. */
.revisao__item input {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

.revisao__caixa {
    flex-shrink: 0;
    width: 1.25rem;
    height: 1.25rem;
    display: grid;
    place-items: center;
    border: 1.5px solid var(--linha-forte);
    border-radius: 6px;
    background: transparent;
    color: var(--fundo);
    transition: background var(--transicao), border-color var(--transicao);
}

.revisao__caixa svg {
    width: 0.8125rem;
    height: 0.8125rem;
    opacity: 0;
    transition: opacity var(--transicao);
}

.revisao__item input:checked + .revisao__caixa {
    background: var(--tinta);
    border-color: var(--tinta);
}

.revisao__item input:checked + .revisao__caixa svg { opacity: 1; }
.revisao__item input:disabled + .revisao__caixa { opacity: 0.4; }

.revisao__item input:focus-visible + .revisao__caixa {
    outline: 2px solid var(--tinta);
    outline-offset: 2px;
}

.revisao__texto {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.0625rem;
}

.revisao__nome {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.revisao__meta {
    font-size: var(--t-micro);
    color: var(--tinta-fraca);
}

.revisao__valor {
    flex-shrink: 0;
    font-weight: 500;
    font-variant-numeric: tabular-nums;
}

/* "dar nome" na linha do lugar que a fatura trouxe e o app nao conhece.
   O padding com margem negativa engorda o alvo do dedo para ~28px sem
   empurrar a linha: no tamanho natural o texto tem 15px de altura. */
.revisao__acao {
    padding: 0.375rem 0.25rem;
    margin: -0.375rem -0.25rem;
    border: none;
    background: none;
    font: inherit;
    color: var(--tinta);
    text-decoration: underline;
    text-underline-offset: 2px;
    cursor: pointer;
}

/* Painel que abre logo abaixo da linha. Nao e um modal de proposito: some o
   contexto se a lista sair da tela para o nome ser digitado. */
.revisao__nomear {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 0.75rem 0.875rem 0.875rem;
    border-bottom: var(--borda) solid var(--linha);
    background: var(--fundo);
}

.revisao__lista > :last-child { border-bottom: none; }

.revisao__nomear-cru {
    font-size: 0.72rem;
    line-height: 1.35;
    color: var(--tinta-fraca);
    word-break: break-word;
}

.revisao__nomear-linha {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.revisao__nomear-ou {
    flex-shrink: 0;
    font-size: var(--t-micro);
    color: var(--tinta-media);
}

.revisao__campo {
    flex: 1;
    min-width: 0;
    font: inherit;
    /* 16px: abaixo disso o iOS da zoom sozinho ao focar o campo */
    font-size: 1rem;
    color: var(--tinta);
    background: var(--fundo-sutil);
    border: var(--borda) solid var(--linha-forte);
    border-radius: 10px;
    padding: 0.5rem 0.625rem;
    transition: border-color var(--transicao);
}

.revisao__campo:focus {
    outline: none;
    border-color: var(--tinta);
}

.revisao__campo:disabled { opacity: 0.5; }

.botao--mini {
    flex-shrink: 0;
    font-size: var(--t-micro);
    padding: 0.5rem 0.75rem;
    border-radius: 10px;
}

/* Marcar/desmarcar tudo, acima da lista */
.revisao__barra {
    display: flex;
    gap: 1rem;
    padding: 0.625rem 0.875rem;
    border-bottom: var(--borda) solid var(--linha);
    background: var(--fundo);
}

.revisao__link {
    padding: 0;
    border: none;
    background: none;
    color: var(--tinta-media);
    font: inherit;
    font-size: var(--t-micro);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    cursor: pointer;
}

.revisao__link:hover { color: var(--tinta); }

.revisao__rodape {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.625rem;
    padding: 0.875rem;
    border-top: var(--borda) solid var(--linha);
    background: var(--fundo);
}

.revisao__recado {
    font-size: var(--t-micro);
    color: var(--tinta-media);
}

/* Foto da fatura no chat: miniatura que abre num modal sobre a tela */
.fala--foto { padding: 0.25rem; max-width: 14rem; }

.foto {
    display: block;
    width: 100%;
    padding: 0;
    border: none;
    background: none;
    border-radius: 14px;
    overflow: hidden;
    line-height: 0;
    cursor: zoom-in;
}

.foto img {
    width: 100%;
    height: auto;
    max-height: 15rem;
    object-fit: cover;
    transition: opacity var(--transicao);
}

.foto:hover img { opacity: 0.85; }

/* ---- modal da foto ----
   Fica sobre o app em vez de abrir outra aba: no PWA instalado sair para o
   navegador tira a pessoa do app, e voltar exige a bandeja do sistema.
   `position: fixed` aqui e seguro — cobre a tela inteira, nao depende de o
   WebKit acertar onde e o fundo (ver o comentario da `.casca`). */
.lupa {
    position: fixed;
    inset: 0;
    z-index: 60;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: calc(1rem + env(safe-area-inset-top)) 1rem calc(1rem + env(safe-area-inset-bottom));
    /* Sem backdrop-filter aqui, de proposito.
       No PWA em iOS, blur de fundo em position:fixed com animacao entrando
       junto faz o WebKit compor a camada errada: o modal virava um retangulo
       PRETO por cima de tudo, sem imagem e sem o X, e so saia fechando o app.
       O fundo ja e quase opaco, entao o blur nao fazia falta nenhuma. */
    background: rgba(0, 0, 0, 0.92);
    animation: aparecer 140ms ease-out;
}

@keyframes aparecer {
    from { opacity: 0; }
    to   { opacity: 1; }
}

.lupa__img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    border-radius: 10px;
    /* O fundo branco da fatura precisa de borda para nao sangrar no preto */
    box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.12);
}

/* Recado de imagem que nao carregou: sem ele a lupa ficava preta e muda */
.lupa__erro {
    max-width: 18rem;
    margin: 0;
    color: rgba(255, 255, 255, 0.86);
    font-size: 0.9375rem;
    line-height: 1.5;
    text-align: center;
}

.lupa__fechar {
    position: absolute;
    top: calc(0.75rem + env(safe-area-inset-top));
    right: 0.75rem;
    display: grid;
    place-items: center;
    width: 2.5rem;
    height: 2.5rem;
    border: none;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.14);
    color: #fff;
    cursor: pointer;
}

.lupa__fechar svg { width: 1.125rem; height: 1.125rem; }
.lupa__fechar:hover { background: rgba(255, 255, 255, 0.24); }

/* Linha de espera: os pontinhos com o cancelar ao lado */
.esperando {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    align-self: flex-start;
}

.esperando__cancelar {
    padding: 0.3125rem 0.625rem;
    border: var(--borda) solid var(--linha-forte);
    border-radius: 999px;
    background: transparent;
    color: var(--tinta-media);
    font: inherit;
    font-size: var(--t-micro);
    letter-spacing: 0.03em;
    text-transform: uppercase;
    cursor: pointer;
    transition: color var(--transicao), border-color var(--transicao);
}

.esperando__cancelar:hover:not(:disabled) {
    color: var(--estouro);
    border-color: var(--estouro);
}

.esperando__cancelar:disabled { opacity: 0.5; cursor: default; }

/* Os tres pontos enquanto a IA pensa. Ela leva de 3 a 25 segundos, entao a
   tela precisa mostrar que esta viva — sem isso parece travada. */
.pensando {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.875rem;
}

.pensando span {
    width: 0.4375rem;
    height: 0.4375rem;
    border-radius: 50%;
    background: var(--tinta-media);
    animation: pontinho 1.2s ease-in-out infinite;
}

.pensando span:nth-child(2) { animation-delay: 0.15s; }
.pensando span:nth-child(3) { animation-delay: 0.3s; }

@keyframes pontinho {
    0%, 60%, 100% { opacity: 0.25; transform: translateY(0); }
    30%           { opacity: 1;    transform: translateY(-0.1875rem); }
}

/* ==========================================================================
   Estatisticas
   ========================================================================== */

/* A regra do `.cartao` esta uma so, mais abaixo, na secao do painel de
   inicio. Havia duas: esta trazia um `margin-bottom` que somava ao gap do
   grid e abria um vao a mais entre as linhas de cartoes. */

.barra {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 0.25rem 0.75rem;
    align-items: baseline;
    padding: 0.5rem 0;
}

.barra__nome {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.barra__valor {
    font-variant-numeric: tabular-nums;
    font-weight: 500;
}

.barra__trilho {
    grid-column: 1 / -1;
    height: 4px;
    background: var(--linha);
    border-radius: 999px;
    overflow: hidden;
}

.barra__preenche {
    height: 100%;
    background: var(--tinta);
    border-radius: 999px;
}

.numeros {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr));
    gap: 0.75rem;
    margin-bottom: 0.75rem;
}

.numero__valor {
    display: block;
    font-size: 1.5rem;
    font-weight: 300;
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
}

.numero__rotulo {
    display: block;
    margin-top: 0.125rem;
    font-size: var(--t-micro);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--tinta-fraca);
}

/* ==========================================================================
   Login
   ========================================================================== */

.portao {
    min-height: 100dvh;
    display: grid;
    place-items: center;
    padding: 1.5rem;
}

/* O card existe para dar chao ao formulario. Sem ele os campos ficam
   soltos no meio da tela e a pagina parece inacabada. */
.portao__caixa {
    width: 100%;
    max-width: 21rem;
    background: var(--fundo-sutil);
    border: var(--borda) solid var(--linha);
    border-radius: 20px;
    padding: 2rem 1.75rem 1.75rem;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04),
                0 12px 32px -12px rgba(0, 0, 0, 0.12);
}

@media (prefers-color-scheme: dark) {
    .portao__caixa {
        background: #0c0c0e;
        box-shadow: 0 1px 2px rgba(0, 0, 0, 0.5),
                    0 16px 40px -16px rgba(0, 0, 0, 0.9);
    }
}

.portao__marca {
    font-size: 1.375rem;
    font-weight: 600;
    letter-spacing: -0.02em;
    color: var(--tinta);
    margin-bottom: 0.25rem;
}

.portao__sub {
    font-size: var(--t-corpo);
    color: var(--tinta-media);
    margin-bottom: 1.75rem;
}

.campo { margin-bottom: 0.875rem; }

.campo__rotulo {
    display: block;
    font-size: var(--t-micro);
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--tinta-fraca);
    margin-bottom: 0.4375rem;
}

/* Dentro do card, o campo precisa ser mais claro que o fundo para nao sumir */
.campo__entrada {
    width: 100%;
    font: inherit;
    font-size: 1rem;
    color: var(--tinta);
    background: var(--fundo);
    border: var(--borda) solid var(--linha-forte);
    border-radius: 12px;
    padding: 0.8125rem 0.875rem;
    transition: border-color var(--transicao), box-shadow var(--transicao);
}

.campo__entrada:focus {
    outline: none;
    border-color: var(--tinta);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--tinta) 8%, transparent);
}

.campo__entrada--codigo {
    text-align: center;
    font-size: 1.5rem;
    letter-spacing: 0.4em;
    font-variant-numeric: tabular-nums;
    padding-left: 0.4em;
}

.portao__botao {
    width: 100%;
    margin-top: 1rem;
    padding: 0.8125rem;
}

.portao__erro {
    margin-top: 0.875rem;
    font-size: var(--t-corpo);
    color: var(--estouro);
    min-height: 1.4em;
}

.lembrar {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    margin-top: 0.875rem;
    font-size: var(--t-corpo);
    color: var(--tinta-media);
    cursor: pointer;
    -webkit-user-select: none;
    user-select: none;
}

/* Caixa propria em vez do checkbox do sistema.
   Com `accent-color: var(--tinta)` o Safari pintava o quadrado da cor do
   texto (branco no tema escuro) e desenhava o certinho igualmente claro em
   cima — marcava, mas nao dava para ver. Aqui o fundo e a tinta e o certinho
   e a cor de fundo, entao o contraste existe nos dois temas. */

.lembrar input {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

.lembrar__caixa {
    flex-shrink: 0;
    width: 1.25rem;
    height: 1.25rem;
    display: grid;
    place-items: center;
    border: 1.5px solid var(--linha-forte);
    border-radius: 6px;
    background: transparent;
    color: var(--fundo);
    transition: background var(--transicao), border-color var(--transicao);
}

.lembrar__caixa svg {
    width: 0.8125rem;
    height: 0.8125rem;
    opacity: 0;
    transition: opacity var(--transicao);
}

.lembrar input:checked + .lembrar__caixa {
    background: var(--tinta);
    border-color: var(--tinta);
}

.lembrar input:checked + .lembrar__caixa svg { opacity: 1; }

.lembrar input:focus-visible + .lembrar__caixa {
    outline: 2px solid var(--tinta);
    outline-offset: 3px;
}

/* ==========================================================================
   Rodape
   ========================================================================== */

.rodape {
    margin-top: 3rem;
    padding-top: 1.25rem;
    border-top: var(--borda) solid var(--linha);
    display: flex;
    gap: 1.25rem;
    font-size: var(--t-micro);
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.rodape a { color: var(--tinta-fraca); text-decoration: none; }
.rodape a:active { color: var(--tinta); }

/* ==========================================================================
   Seletor de fatura
   ==========================================================================
   O `select` do sistema traz uma seta propria, diferente em cada navegador e
   sempre destoando do resto. `appearance: none` tira a seta e o desenho de
   caixa; o chevron abaixo e nosso, igual em todo lugar. */

.seletor { margin-bottom: 1.25rem; }

.seletor__caixa {
    position: relative;
    display: block;
    max-width: 20rem;
}

.seletor__campo {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    width: 100%;
    padding-right: 2.5rem;
    cursor: pointer;
}

/* Some tambem a seta do Internet Explorer/Edge legado */
.seletor__campo::-ms-expand { display: none; }

.seletor__seta {
    position: absolute;
    top: 50%;
    right: 0.875rem;
    width: 1.125rem;
    height: 1.125rem;
    transform: translateY(-50%);
    color: var(--tinta-media);
    pointer-events: none;   /* o clique atravessa e abre o select */
}

/* ==========================================================================
   Abertura da fatura
   ==========================================================================
   Aparece quando o mes vira: a fatura ja existe, mas com o teto padrao e
   esperando confirmacao. Chama atencao de proposito — e a unica coisa da tela
   que pede uma decisao. */

.abertura {
    padding: 1.125rem 1.25rem 1.25rem;
    margin-bottom: 1.5rem;
    border: var(--borda) solid var(--folga);
    border-radius: var(--raio);
    background: color-mix(in srgb, var(--folga) 7%, var(--fundo));
}

.abertura__selo {
    font-size: var(--t-micro);
    font-weight: 500;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--folga);
}

.abertura__titulo {
    margin-top: 0.25rem;
    font-size: 1.375rem;
    font-weight: 600;
    letter-spacing: -0.02em;
}

.abertura__quando {
    margin-top: 0.125rem;
    font-size: var(--t-micro);
    color: var(--tinta-media);
    font-variant-numeric: tabular-nums;
}

.abertura__linha {
    display: flex;
    align-items: flex-end;
    flex-wrap: wrap;
    gap: 0.625rem;
    margin-top: 1rem;
}

.abertura__campo {
    flex: 1 1 9rem;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.abertura__campo .campo__entrada {
    font-size: 1.0625rem;
    font-variant-numeric: tabular-nums;
}

/* O dia cabe em dois digitos, mas o rotulo ("Outubro foi até o dia") e mais
   largo: a coluna acompanha o rotulo e o campo fica do tamanho do numero. */
.abertura__campo--dia {
    flex: 0 0 auto;
}

.abertura__campo--dia .campo__entrada {
    width: 5.5rem;
    text-align: center;
}

.abertura__virada {
    margin-top: 0.625rem;
    font-size: var(--t-micro);
    color: var(--tinta);
}

.abertura__nota {
    margin-top: 0.75rem;
    font-size: var(--t-micro);
    color: var(--tinta-media);
}

/* ==========================================================================
   Painel de inicio
   ========================================================================== */

/* Coluna por dentro: assim o "ver todos" desce para o rodape do cartao
   quando ele e esticado ao lado de um vizinho mais alto. */
.cartao {
    display: flex;
    flex-direction: column;
    padding: 1.125rem 1.25rem 1.25rem;
    border: var(--borda) solid var(--linha);
    border-radius: var(--raio);
    background: var(--fundo-sutil);
}

.painel .cartao { margin-top: 1rem; }

.secao__link {
    display: inline-block;
    align-self: flex-start;
    margin-top: auto;      /* empurra para o fim do cartao */
    padding-top: 0.875rem;
    font-size: var(--t-micro);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--tinta-media);
    text-decoration: none;
}

.secao__link:hover { color: var(--tinta); }

/* O saldo no chat e informacao de canto, nao o assunto da tela */
.saldo--fita { margin-bottom: 1.25rem; }
.saldo--fita .saldo__valor { font-size: clamp(2rem, 9vw, 2.75rem); }

/* ---- rosca de categorias ---- */

.rosca {
    position: relative;
    width: min(13.5rem, 62%);
    margin: 0.5rem auto 1.25rem;
}

.rosca__svg {
    width: 100%;
    height: auto;
    transform: rotate(-90deg);   /* comeca no topo */
}

.rosca__fatia {
    transition: opacity var(--transicao), stroke-width var(--transicao);
    cursor: pointer;
}

.rosca__fatia:hover,
.rosca__fatia:focus-visible { stroke-width: 6.5; outline: none; }
.rosca__fatia--apagada { opacity: 0.25; }

.rosca__centro {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.125rem;
    text-align: center;
    pointer-events: none;
}

.rosca__centro strong {
    font-size: 1.25rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.02em;
}

.rosca__centro span {
    font-size: var(--t-micro);
    color: var(--tinta-media);
}

.legenda {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    padding: 0.4375rem 0;
    cursor: default;
}

.legenda__ponto {
    flex-shrink: 0;
    width: 0.625rem;
    height: 0.625rem;
    border-radius: 3px;
}

.legenda__nome {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.legenda__valor { font-variant-numeric: tabular-nums; }

.legenda__pct {
    min-width: 2.5rem;
    text-align: right;
    font-size: var(--t-micro);
    color: var(--tinta-fraca);
    font-variant-numeric: tabular-nums;
}

/* ---- colunas das faturas ---- */

/* Cresce com o cartao quando ele e esticado ao lado de um vizinho mais alto,
   mas nunca fica baixa demais para as barras se distinguirem. */
.colunas {
    display: flex;
    align-items: flex-end;
    gap: 0.375rem;
    flex: 1;
    min-height: 9rem;
    margin-top: 0.5rem;
}

.coluna {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.375rem;
    height: 100%;
    padding: 0;
    border: none;
    background: transparent;
    cursor: pointer;
}

.coluna__trilho {
    flex: 1;
    display: flex;
    align-items: flex-end;
    width: 100%;
    min-height: 0;
}

.coluna__barra {
    width: 100%;
    min-height: 2px;
    border-radius: 4px 4px 2px 2px;
    background: var(--linha-forte);
    transition: background var(--transicao), opacity var(--transicao);
}

.coluna:hover .coluna__barra { opacity: 0.75; }
.coluna__barra--atual   { background: var(--folga); }
.coluna__barra--estouro { background: var(--estouro); }

.coluna__rotulo {
    font-size: 0.625rem;
    letter-spacing: 0.02em;
    color: var(--tinta-fraca);
    font-variant-numeric: tabular-nums;
}

/* A nota da comparacao fecha o cartao, colada embaixo */
#colunasNota { margin-top: 0.75rem; }

/* ==========================================================================
   Diagnostico de tela
   ========================================================================== */

.diag__linha {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.6875rem 0;
    border-bottom: var(--borda) solid var(--linha);
}

.diag__rotulo {
    color: var(--tinta-media);
    font-size: var(--t-micro);
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.diag__valor {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-variant-numeric: tabular-nums;
    text-align: right;
}

.diag__valor--ok    { color: var(--folga); }
.diag__valor--erro  { color: var(--estouro); }
.diag__valor--aviso { color: var(--tinta-media); }

/* ==========================================================================
   Desktop
   ==========================================================================
   No PC a barra de abas embaixo nao faz sentido: o mouse chega em qualquer
   lugar e sobra largura. A navegacao vira coluna fixa a esquerda, com os
   atalhos do menu ja abertos, e o conteudo ganha espaco para listas.

   A marca ".lado__marca" e o titulo da coluna; no celular ela nao existe. */

.lado__marca { display: none; }

@media (min-width: 60rem) {

    /* ======================================================================
       O DOCUMENTO NÃO ROLA. Quem rola é o miolo (`.conteudo`).

       Sem isto sobrava uma barra de rolagem do navegador ATRÁS do app: você
       rolava e a casca inteira subia, deixando um vão preto do tamanho da
       tela embaixo da barra de entrada — parecia um rodapé gigante. É o
       documento que rola, não o chat, e por isso mexer no chat não resolvia.

       Basta uma extensão do navegador injetar um elemento no body para criar
       esse excedente, e é por isso que só aparecia no desktop.

       `overflow: hidden` sozinho não segura — medido: ainda rolava 500px por
       propagação. O que trava é a altura fixa junto.

       Só aqui, e não no celular: `height: 100%` em html/body já competiu com
       a altura da `.casca` no PWA do iPhone e cortou o fim da coluna.
       ====================================================================== */
    html.app,
    body.app {
        height: 100%;
        overflow: hidden;
    }

    /* A coluna lateral rola sozinha quando não cabe, mas o arrasto morre nela */
    .abas { overscroll-behavior: contain; }

    .casca {
        display: grid;
        grid-template-columns: 15rem minmax(0, 1fr);
        grid-template-rows: auto auto minmax(0, 1fr);
        grid-template-areas:
            "marca  topo"
            "nav    principal"
            "nav    principal";
    }

    .lado__marca {
        grid-area: marca;
        display: block;
        padding: 1.25rem 1.25rem 0.75rem;
        font-size: 1.0625rem;
        font-weight: 600;
        letter-spacing: -0.01em;
        border-right: var(--borda) solid var(--linha);
    }

    .topo { grid-area: topo; }
    .principal { grid-area: principal; min-width: 0; }

    /* O menu do canto perde a razao de existir: tudo esta na coluna */
    .topo__menu { display: none; }

    .abas {
        grid-area: nav;
        flex-direction: column;
        align-items: stretch;
        gap: 0.125rem;
        padding: 0.5rem 0.625rem;
        border-top: none;
        border-right: var(--borda) solid var(--linha);
        overflow-y: auto;
    }

    .abas__item {
        flex: 0 0 auto;
        flex-direction: row;
        align-items: center;
        justify-content: flex-start;
        gap: 0.6875rem;
        padding: 0.625rem 0.75rem;
        border-radius: 9px;
        font-size: var(--t-corpo);
        letter-spacing: 0;
        text-transform: none;
    }

    .abas__item:hover { background: var(--fundo-sutil); }

    .abas__item--ativo {
        background: var(--fundo-sutil);
        font-weight: 500;
    }

    .abas__extra {
        display: block;
        margin-top: 0.75rem;
        padding-top: 0.75rem;
        border-top: var(--borda) solid var(--linha);
    }

    /* Mesmo tamanho e mesma caixa dos itens de cima: e tudo navegacao, e a
       coluna fica ilegivel se metade dela for texto miudo. */
    .abas__link {
        display: block;
        padding: 0.625rem 0.75rem;
        border-radius: 9px;
        color: var(--tinta-media);
        text-decoration: none;
        font-size: var(--t-corpo);
    }

    .abas__link:hover { background: var(--fundo-sutil); color: var(--tinta); }
    .abas__link--fim { margin-top: 0.25rem; color: var(--tinta-fraca); }

    /* Largura e o motivo de usar o PC: as telas de dado ocupam o que tem */
    .conteudo {
        max-width: 76rem;
        padding: 1.75rem 2.5rem 2.5rem;
    }

    /* O campo de gasto tem a mesma largura do conteudo e o mesmo alinhamento:
       antes parava em 44rem colado a esquerda e a barra parecia cortada no
       meio da tela. Quem limita o comprimento do texto sao as bolhas da
       conversa (`.fala`), nao o campo. */
    .entrada { padding: 0.875rem 2.5rem; }
    .entrada__caixa,
    .gravando,
    .entrada__aviso { max-width: 76rem; margin-left: auto; margin-right: auto; }

    /* Bolha de conversa nao acompanha: linha de 1200 px e ilegivel */
    .fala { max-width: min(82%, 38rem); }

    /* Alvos de toque viram alvos de mouse: podem encolher */
    .lancamento { padding: 0.6875rem 0; }

    /* ---- listas em duas colunas ----
       `columns` e nao grid: a leitura segue a coluna da esquerda inteira e
       so entao passa para a direita, que e como se le uma lista ordenada.
       Em grid a ordem viraria zigue-zague e a data deixaria de fazer sentido. */
    .lista-dupla {
        columns: 2;
        column-gap: 3.5rem;
    }

    .lista-dupla > * {
        break-inside: avoid;
        page-break-inside: avoid;
    }

    /* Titulo da lista nao entra na divisao em colunas */
    .lista-dupla > .secao__titulo {
        column-span: all;
        margin-bottom: 0.5rem;
    }

    /* ---- painel de inicio: cartoes lado a lado ---- */
    .painel {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 1.25rem;
        /* `stretch` e nao `start`: com `start` cada cartao ficava com a altura
           do proprio conteudo, mas a linha reservava a altura do maior — e
           sobrava um vao embaixo do menor. Esticando, a linha fecha certinho. */
        align-items: stretch;
    }

    /* No grid quem separa e o gap; a margem de cada cartao ficaria dobrada */
    .painel .cartao { margin-top: 0; }
}

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        transition-duration: 0.01ms !important;
    }
}
