/* ============================================================
   CADERNINHO PRO — TEMA V2 (reskin rodada 1: Dashboard + Lançamentos)
   Spec: referencia/rodada-01/ (protótipo Claude Design + AVALIACAO.md)
   Regras: TUDO escopado em body.v2 — sem a classe, este arquivo é
   inerte e o visual atual permanece intacto. Zero mudança de lógica.
   Fonte: Inter em tudo (Newsreader foi vetada — hierarquia por peso).
   ============================================================ */

/* ---------- utilitária .only-v2 (ÚNICA regra fora do escopo body.v2,
   de propósito: precisa valer nos dois lados para esconder por padrão
   e só revelar quando body.v2 estiver presente) ---------- */
.only-v2{display:none !important;}
body.v2 .only-v2{display:flex !important;}

/* ---------- fundo e clima ---------- */
body.v2::before{
  background:
    radial-gradient(ellipse 70% 45% at 50% 0%, rgba(59,130,246,.06) 0%, transparent 65%),
    radial-gradient(ellipse 45% 35% at 90% 100%, rgba(59,130,246,.04) 0%, transparent 60%);
}
body.v2.light::before{
  background:
    radial-gradient(ellipse 70% 45% at 50% 0%, rgba(37,99,235,.05) 0%, transparent 65%),
    radial-gradient(ellipse 45% 35% at 90% 100%, rgba(16,185,129,.03) 0%, transparent 60%);
}

/* ---------- navegação ---------- */
body.v2 nav{padding:14px 26px;border-bottom-color:transparent;}
body.v2 .ntab{border-radius:12px;padding:7px 12px;font-weight:700;}
body.v2 .ntab.on{box-shadow:0 6px 18px var(--ob);}

/* ---------- cabeçalho de página ---------- */
body.v2 .ph-title{font-size:24px;letter-spacing:-0.01em;}
body.v2 .ph-title::after{content:none;}   /* respiro > sublinhado */

/* ---------- strip de meses (coração da navegação temporal) ---------- */
body.v2 .mstrip{gap:8px;padding:8px 4px 12px;}
body.v2 .mbtn.month-btn{
  display:inline-flex;flex-direction:column;align-items:center;gap:3px;
  min-width:52px;padding:9px 10px;border-radius:16px;
  font-size:12px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;
  border:1px solid var(--b2);color:var(--t3);background:transparent;
}
body.v2 .mbtn.month-btn small{
  font-size:8px;font-weight:900;letter-spacing:.06em;text-transform:uppercase;
  color:var(--orange);opacity:.85;
}
body.v2 .mbtn.month-btn.past-month{opacity:.55;}
body.v2 .mbtn.month-btn.on{
  background:var(--orange);border-color:var(--orange);color:#fff;opacity:1;
  transform:scale(1.06);box-shadow:0 6px 18px var(--ob);
  padding:10px 12px 12px;min-width:58px;
}
body.v2 .mbtn.month-btn.on small{color:rgba(255,255,255,.9);}
body.v2 .mbtn.month-btn:hover:not(.on){border-color:var(--b3);color:var(--tx);transform:scale(1.04);}
body.v2 .myr-btn{border-radius:8px;}

/* ---------- dashboard: saldo como manchete (hero unificado) ---------- */
/* os 2 KPIs pequenos (entradas/saídas) somem: a sub-linha ▲/▼ dentro do
   hero (.v2-hero-sub, only-v2) os substitui */
body.v2 #dash-kpi-section .kpi-ok,
body.v2 #dash-kpi-section .kpi-o{display:none;}
body.v2 #dash-kpi-section .kpi-grid{grid-template-columns:1fr !important;gap:12px;}
body.v2 #dash-kpi-section #dash-bal-card{grid-column:1 / -1;order:-1;padding:26px 24px 30px;border-radius:22px;}
body.v2 #dash-kpi-section #dash-bal-card .kpi-value{font-size:42px;font-weight:800;letter-spacing:-0.02em;line-height:1.05;}
body.v2 .kpi{border-radius:18px;padding:18px;}
body.v2 .kpi-label{font-size:11px;font-weight:800;letter-spacing:.08em;}
body.v2 .kpi-value{font-size:24px;font-weight:800;letter-spacing:-0.02em;}
/* sub-linha ▲entradas/▼saídas dentro do hero (spec: heroSubRow/heroSubIn/heroSubOut) */
body.v2 .v2-hero-sub{gap:16px;margin-top:4px;align-items:center;}
body.v2 .v2-hero-in,
body.v2 .v2-hero-out{display:flex;align-items:center;gap:4px;font-size:13px;font-weight:700;}
body.v2 .v2-hero-in{color:var(--ok);}
body.v2 .v2-hero-out{color:var(--t2);}
/* modo individual: hero unificado ocupa a linha toda, sem 2ª linha de KPIs */
body.v2.modo-individual #dash-kpi-section .kpi-grid{grid-template-columns:1fr !important;}

/* ---------- cartões de pessoa (chico/dieni/casal) ---------- */
body.v2 .scard{border-radius:18px;}
body.v2 .sc-amt{font-size:34px;font-weight:800;letter-spacing:-0.02em;}
body.v2 .sc-av{font-size:23px;}
body.v2 .sc-name{letter-spacing:.04em;}
body.v2 .sc-sub{font-size:10px;}

/* ---------- cards e títulos de seção ---------- */
body.v2 .card{border-radius:18px;padding:22px;}
body.v2 .ct{font-size:12px;font-weight:800;letter-spacing:.06em;text-transform:uppercase;color:var(--t2);}
body.v2 .fc{border-radius:18px;}

/* ---------- lembretes (borda de status já existe; só refinar) ---------- */
body.v2 .rem-item{border-radius:12px;padding:11px 12px;border-left-width:3px;}

/* ---------- dashboard: "Por categoria" vira barras (donut some no v2) ---------- */
body.v2 #dash-cat-charts .card:first-child .cw,
body.v2 #dash-cat-charts .card:first-child .leg{display:none;}
/* #cat-bars-v2 é um container block (linhas empilhadas), não flex —
   sobrescreve a utilitária .only-v2 (que liga display:flex) */
body.v2 #cat-bars-v2{display:block !important;}
body.v2 .cat-bar-row{display:flex;align-items:center;gap:10px;margin-bottom:12px;}
body.v2 .cat-bar-row:last-child{margin-bottom:0;}
body.v2 .cat-bar-emoji{font-size:16px;flex-shrink:0;width:20px;text-align:center;}
body.v2 .cat-bar-wrap{flex:1;display:flex;flex-direction:column;gap:5px;min-width:0;}
body.v2 .cat-bar-track{height:7px;border-radius:4px;background:var(--s3);overflow:hidden;}
body.v2 .cat-bar-fill{height:100%;border-radius:5px;transition:width .5s;}
body.v2 .cat-bar-name-row{display:flex;justify-content:space-between;gap:8px;}
body.v2 .cat-bar-name{font-size:12px;color:var(--t2);font-weight:600;}
body.v2 .cat-bar-amt{font-size:12px;color:var(--tx);font-weight:700;white-space:nowrap;}

/* ---------- lançamentos: filtros como chips ---------- */
body.v2 .fbtn{padding:8px 15px;font-size:12px;font-weight:700;border-radius:20px;}
body.v2 .fseg{border-radius:20px;background:transparent;border-color:var(--b1);}
body.v2 #fSearch{border-radius:14px!important;background:var(--s2);border:1px solid var(--b2);padding:9px 14px;height:auto!important;}

/* ---------- barra de seleção em massa ---------- */
body.v2 .stb{background:var(--ob);border-color:var(--obr);border-radius:14px;box-shadow:0 10px 30px rgba(0,0,0,.35);}
body.v2 .stb-cnt{color:var(--orange);font-weight:800;}
body.v2 .sbtn{border-radius:10px;}

/* ---------- tabela com cara de lista ---------- */
body.v2 .tw{border-radius:18px;}
body.v2 thead th{background:transparent;font-size:10.5px;letter-spacing:.1em;padding:12px;}
body.v2 tbody td{padding:12px;}
body.v2 tbody tr:hover td{background:rgba(59,130,246,.04);}

/* linha-pai da fatura do cartão: superfície própria, não um bloco de acento */
body.v2 tbody tr.cc-parent-row{background:var(--s2) !important;}
body.v2 tbody tr.cc-parent-row td{border-top:1px solid var(--b2) !important;padding:14px 12px;}
body.v2 tbody tr.cc-child-row{background:color-mix(in srgb, var(--s1) 55%, transparent);}
body.v2 tbody tr.cc-child-row td:nth-child(2){padding-left:34px !important;}

/* parcelas projetadas: visivelmente "ainda não aconteceu" */
body.v2 tbody tr:has(.iproj){opacity:.62;}
body.v2 tbody tr:has(.iproj):hover{opacity:.85;}
body.v2 .iproj{
  padding:2px 7px;border-radius:5px;font-size:0;font-weight:800;
  letter-spacing:.03em;text-transform:uppercase;
  background:transparent;border:1px dashed rgba(168,85,247,.5);
}
/* esconde o conteúdo original (🔮/🔮 Previsto) e injeta o texto v2 */
body.v2 .iproj::after{content:'projetada';font-size:9px;font-weight:800;letter-spacing:.03em;text-transform:uppercase;}
body.v2 .intb{padding:2px 6px;border-radius:5px;font-weight:800;letter-spacing:.03em;text-transform:uppercase;}

/* ---------- botões ---------- */
body.v2 .btn{border-radius:12px;}
body.v2 .btn-p{box-shadow:0 6px 18px var(--ob);}

/* ---------- estados vazios ---------- */
body.v2 .empty{padding:40px 16px;}
body.v2 .empty-t{font-weight:800;color:var(--tx);}

/* ---------- modais viram bottom sheet no celular ---------- */
@media (max-width:640px){
  body.v2 .modal-bg{align-items:flex-end;}
  body.v2 .modal-card{
    max-width:100%;border-radius:26px 26px 0 0;border-bottom:none;
    padding-top:14px;
    animation:v2SheetUp .28s cubic-bezier(.22,.68,0,1.1);
  }
  body.v2 .modal-card::before{
    content:'';display:block;width:36px;height:4px;border-radius:2px;
    background:var(--b2);margin:0 auto 12px;
  }
}
@keyframes v2SheetUp{from{transform:translateY(100%);}to{transform:translateY(0);}}

/* ---------- lançamentos: FAB mobile + form manual vira bottom sheet ----------
   Fora do breakpoint mobile o form (.fc) continua inline no desktop; o FAB fica
   oculto (sobrescrevendo o display:flex da utilitária .only-v2 com !important). */
body.v2 #fab-add-v2{display:none !important;}
body.v2 #fc-sheet-bg-v2{display:none !important;}

@media (max-width:640px){
  body.v2 #fab-add-v2{
    display:flex !important;position:fixed;bottom:20px;right:18px;
    width:52px;height:52px;border-radius:50%;align-items:center;justify-content:center;
    border:none;background:var(--orange);color:#fff;cursor:pointer;
    box-shadow:0 10px 24px var(--ob);z-index:950;
  }
  /* sem o sheet aberto, o form some da página — o FAB é o acesso */
  body.v2:not(.fc-sheet-open) #page-lancamentos .fc{display:none;}
  body.v2.fc-sheet-open #fc-sheet-bg-v2{
    display:block !important;position:fixed;inset:0;
    background:rgba(0,0,0,.5);z-index:998;
  }
  body.v2.fc-sheet-open #page-lancamentos .fc{
    position:fixed;left:0;right:0;bottom:0;z-index:999;
    border-radius:26px 26px 0 0;max-height:85vh;overflow-y:auto;
    animation:v2SheetUp .28s cubic-bezier(.22,.68,0,1.1);
  }
  body.v2.fc-sheet-open #page-lancamentos .fc::before{
    content:'';display:block;width:36px;height:4px;border-radius:2px;
    background:var(--b2);margin:0 auto 12px;
  }
}

@media (prefers-reduced-motion: reduce){
  body.v2 .modal-card{animation:none;}
  body.v2 .mbtn.month-btn.on{transform:none;}
  body.v2.fc-sheet-open #page-lancamentos .fc{animation:none;}
}

/* ---------- importar: stepper de 4 passos (etapa 3) ---------- */
/* .only-v2 já liga display:flex — aqui só ajustamos alinhamento/espaçamento */
body.v2 #imp-stepper-v2{align-items:flex-start;justify-content:center;gap:0;margin-bottom:20px;}
body.v2 .imp-step{
  display:flex;flex-direction:column;align-items:center;gap:6px;
  position:relative;flex:1;max-width:130px;
}
body.v2 .imp-step-dot{
  width:8px;height:8px;border-radius:50%;background:var(--b2);
  position:relative;z-index:1;transition:width .2s,height .2s,background .2s,box-shadow .2s;
}
/* linha conectora entre bolinhas — desenhada por trás (z-index 0) */
body.v2 .imp-step:not(:last-child)::after{
  content:'';position:absolute;top:3px;left:50%;width:100%;height:1px;
  background:var(--b2);z-index:0;
}
body.v2 .imp-step.done:not(:last-child)::after{background:var(--orange);}
body.v2 .imp-step.done .imp-step-dot{background:var(--orange);}
body.v2 .imp-step.active .imp-step-dot{
  width:12px;height:12px;background:var(--orange);box-shadow:0 0 0 4px var(--ob);
}
body.v2 .imp-step-label{
  font-size:10px;font-weight:800;letter-spacing:.05em;text-transform:uppercase;color:var(--t3);
}
body.v2 .imp-step.active .imp-step-label,
body.v2 .imp-step.done .imp-step-label{color:var(--tx);}

/* ---------- importar: totalizador "bate ao centavo" (etapa 3) ---------- */
/* card em coluna — sobrescreve o display:flex (row) da utilitária .only-v2 */
body.v2 #imp-totalizer-v2{
  display:flex !important;flex-direction:column;gap:8px;
  background:var(--s2);border:1px solid var(--b1);border-radius:14px;
  padding:14px;margin-top:14px;
}
body.v2 .imp-tot-row{display:flex;justify-content:space-between;align-items:center;gap:10px;font-size:12px;}
body.v2 .imp-tot-label{color:var(--t3);white-space:nowrap;}
body.v2 .imp-tot-value{font-weight:800;color:var(--tx);}
body.v2 .imp-tot-row input#imp-expected-v2{max-width:130px;width:auto;text-align:right;}
body.v2 .imp-tot-match{font-size:13px;font-weight:800;margin-top:2px;min-height:16px;}
body.v2 .imp-tot-match.ok{color:var(--ok);}
body.v2 .imp-tot-match.bad{color:var(--danger);}

@media (prefers-reduced-motion: reduce){
  body.v2 .imp-step-dot{transition:none;}
}

/* ---------- parcelas: visão em cards (etapa 4) ---------- */
/* listagem/tabela atual (#parc-content) some no v2 — só dentro de #page-parcelas */
body.v2 #page-parcelas #parc-content{display:none;}
/* #parcelas-cards-v2 empilha os cards em coluna — a utilitária .only-v2 já liga
   display:flex, aqui só fixamos a direção e o espaçamento entre cards */
body.v2 #parcelas-cards-v2{flex-direction:column;gap:12px;}
body.v2 .pz-card-v2{
  background:var(--s1);border:1px solid var(--b1);border-radius:18px;padding:16px;
  display:flex;flex-direction:column;gap:10px;
}
body.v2 .pz-card-v2-quitada{border-color:rgba(74,222,128,.35);}
body.v2 .pz-top-v2{display:flex;align-items:flex-start;gap:10px;}
body.v2 .pz-emoji-v2{font-size:22px;flex-shrink:0;}
body.v2 .pz-textwrap-v2{flex:1;min-width:0;}
body.v2 .pz-desc-v2{font-size:14px;font-weight:800;color:var(--tx);}
body.v2 .pz-sub-v2{font-size:11px;color:var(--t3);margin-top:2px;}
body.v2 .pz-amounts-v2{text-align:right;flex-shrink:0;}
body.v2 .pz-parcela-v2{font-size:14px;font-weight:800;color:var(--tx);white-space:nowrap;}
body.v2 .pz-total-v2{font-size:10px;color:var(--t3);margin-top:1px;white-space:nowrap;}
body.v2 .pz-bar-track-v2{height:7px;border-radius:4px;background:var(--s3);overflow:hidden;}
body.v2 .pz-bar-fill-v2{height:100%;border-radius:5px;transition:width .5s;}
body.v2 .pz-bar-c-v2{background:linear-gradient(90deg, var(--chico), color-mix(in srgb, var(--chico) 60%, white));}
body.v2 .pz-bar-d-v2{background:linear-gradient(90deg, var(--dieni), color-mix(in srgb, var(--dieni) 60%, white));}
body.v2 .pz-bar-ca-v2{background:linear-gradient(90deg, var(--casal), color-mix(in srgb, var(--casal) 60%, white));}
body.v2 .pz-bar-quitada-v2{background:linear-gradient(90deg,#4ade80,#22c55e);}
body.v2 .pz-bottom-v2{display:flex;justify-content:space-between;align-items:center;}
body.v2 .pz-progress-v2{font-size:11px;font-weight:700;color:var(--t2);}
body.v2 .pz-remaining-v2{font-size:11px;color:var(--t3);}

/* ---------- rendas: hero verde do total do mês (etapa 5) ---------- */
/* #rendas-hero-v2 é um bloco empilhado (label + valor), não flex —
   sobrescreve a utilitária .only-v2 (que liga display:flex) */
body.v2 #rendas-hero-v2{
  display:block !important;
  background:var(--s1);border:1px solid var(--b1);border-radius:18px;
  padding:20px;margin-bottom:14px;
}
body.v2 .rendas-hero-label-v2{
  font-size:11px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:var(--t3);
}
body.v2 .rendas-hero-value-v2{
  font-size:34px;font-weight:800;letter-spacing:-0.02em;color:var(--ok);margin-top:6px;
}

/* ---------- relatórios: ranking de categorias com posição (etapa 5) ---------- */
/* substitui visualmente o gráfico de rosca dentro do mesmo card — esconde só
   o canvas e a legenda (não o card inteiro, que também abriga #rel-rank-v2).
   Chart.js seta style="display:block" inline no canvas, por isso !important;
   o wrapper (div sem id/classe, só "position:relative;height:240px") é
   selecionado via :has() para não sobrar um vão vazio de 240px no v2. */
body.v2 #page-relatorios div:has(> #rel-chart-cat){display:none !important;}
body.v2 #rel-leg-cat{display:none !important;}
/* #rel-rank-v2 é um bloco empilhado (linhas), não flex —
   sobrescreve a utilitária .only-v2 (que liga display:flex) */
body.v2 #rel-rank-v2{display:block !important;}
body.v2 .rel-rank-row-v2{display:flex;align-items:center;gap:10px;margin-bottom:12px;}
body.v2 .rel-rank-row-v2:last-child{margin-bottom:0;}
body.v2 .rel-rank-pos-v2{font-size:11px;font-weight:800;color:var(--t4);width:24px;flex-shrink:0;}
body.v2 .rel-rank-emoji-v2{font-size:16px;flex-shrink:0;width:20px;text-align:center;}
body.v2 .rel-rank-wrap-v2{flex:1;display:flex;flex-direction:column;gap:5px;min-width:0;}
body.v2 .rel-rank-track-v2{height:7px;border-radius:4px;background:var(--s3);overflow:hidden;}
body.v2 .rel-rank-fill-v2{height:100%;border-radius:5px;transition:width .5s;}
body.v2 .rel-rank-name-row-v2{display:flex;justify-content:space-between;gap:8px;}
body.v2 .rel-rank-name-v2{font-size:12px;color:var(--t2);font-weight:600;}
body.v2 .rel-rank-amt-v2{font-size:12px;color:var(--tx);font-weight:700;white-space:nowrap;}
body.v2 .pz-quitada-v2{display:flex;align-items:center;gap:4px;font-size:11px;font-weight:800;color:var(--ok);}

/* ---------- metas: cards de progresso (etapa 6) ---------- */
/* listagem/grid atual (#meta-grid) some no v2 — só dentro de #page-metas;
   os cards do v2 reusam os componentes .pz-* já criados na etapa 4 (parcelas).
   #meta-grid tem "display:grid" inline no index.html, por isso !important
   (mesmo caso do #rel-chart-cat na etapa 5). */
body.v2 #page-metas #meta-grid{display:none !important;}
/* #metas-cards-v2 empilha os cards em coluna — a utilitária .only-v2 já liga
   display:flex, aqui só fixamos a direção e o espaçamento entre cards */
body.v2 #metas-cards-v2{flex-direction:column;gap:12px;}
body.v2 .pz-bar-meta-v2{background:var(--orange);}
body.v2 .pz-aporte-btn-v2{
  flex-shrink:0;border:none;border-radius:99px;padding:6px 12px;
  font-size:12px;font-weight:800;color:#fff;background:var(--orange);cursor:pointer;
}
body.v2 .pz-aporte-btn-v2:active{opacity:.85;}

/* ---------- config: seções colapsáveis (etapa 7) ----------
   5 grupos da spec (Perfis/Categorias/Cartões/Aparência/Conta) + "Avançado"
   para cards sem correspondência clara. DOM não foi reordenado: os cards de
   um grupo podem aparecer em mais de um trecho não-contíguo da página
   (ex.: Aparência e Conta têm 2 cabeçalhos cada, um por trecho) — todos os
   cabeçalhos do mesmo grupo alternam a MESMA classe no body, então abrir/
   fechar em qualquer um deles afeta todos os cards do grupo em uníssono.
   Estado inicial: tudo aberto (nenhuma classe cfg-close-*-v2 no body). */
body.v2 .cfg-sec-hd-v2{
  grid-column:1 / -1;
  justify-content:space-between;align-items:center;
  padding:12px 0;margin-top:18px;
  border-bottom:1px solid var(--b1);
  cursor:pointer;
}
body.v2 .cfg-sec-hd-v2:first-child{margin-top:0;}
body.v2 .cfg-sec-hd-title-v2{
  display:flex;align-items:center;gap:7px;
  font-size:13px;font-weight:800;letter-spacing:.06em;text-transform:uppercase;color:var(--t2);
}
body.v2 .cfg-sec-hd-chevron-v2{
  display:flex;align-items:center;color:var(--t3);transition:transform .2s;
}
@media (prefers-reduced-motion: reduce){
  body.v2 .cfg-sec-hd-chevron-v2{transition:none;}
}

/* cada cabeçalho gira o próprio chevron via a classe que ele mesmo alterna
   no body (rotaciona TODOS os cabeçalhos do mesmo grupo, mesmo os de
   trechos não-contíguos, mantendo-os em sincronia) */
body.v2.cfg-close-perfis-v2 [data-sec="perfis"] .cfg-sec-hd-chevron-v2,
body.v2.cfg-close-categorias-v2 [data-sec="categorias"] .cfg-sec-hd-chevron-v2,
body.v2.cfg-close-cartoes-v2 [data-sec="cartoes"] .cfg-sec-hd-chevron-v2,
body.v2.cfg-close-aparencia-v2 [data-sec="aparencia"] .cfg-sec-hd-chevron-v2,
body.v2.cfg-close-conta-v2 [data-sec="conta"] .cfg-sec-hd-chevron-v2,
body.v2.cfg-close-avancado-v2 [data-sec="avancado"] .cfg-sec-hd-chevron-v2{
  transform:rotate(-90deg);
}

/* esconde os cards do grupo fechado — cada card existente recebeu só uma
   classe adicional no atributo class (nenhuma outra mudança no markup);
   #cfg-profiles-row (perfis) já tinha id próprio, então nem precisou de
   classe nova, o seletor de id abaixo já resolve */
/* !important: alguns cards têm display inline (ex.: #cfg-profiles-row é
   "display:grid", o card "Salvar Configurações" é "display:flex") que, sem
   isso, venceria a regra externa por especificidade */
body.v2.cfg-close-perfis-v2 .cfg-sec-perfis-v2,
body.v2.cfg-close-perfis-v2 #cfg-profiles-row{display:none !important;}
body.v2.cfg-close-categorias-v2 .cfg-sec-categorias-v2{display:none !important;}
body.v2.cfg-close-cartoes-v2 .cfg-sec-cartoes-v2{display:none !important;}
body.v2.cfg-close-aparencia-v2 .cfg-sec-aparencia-v2{display:none !important;}
body.v2.cfg-close-conta-v2 .cfg-sec-conta-v2{display:none !important;}
body.v2.cfg-close-avancado-v2 .cfg-sec-avancado-v2{display:none !important;}

/* ---------- modal pagar/conciliar: contas com saldo + card antes/depois (etapa 8) ----------
   #pay-accounts-v2 e #pay-totalizer-v2 são containers only-v2; conteúdo 100%
   gerado via JS em renderPayAccountsV2()/renderPayTotalizerV2() (app.js), a
   partir do mesmo <select id="pay-account-id"> e getPayableAmount()/
   getPayDirection() que confirmPay() já usa — nenhuma decisão nova, só leitura
   e sincronização do próprio <select>. #pay-totalizer-v2 fica vazio (sem o
   card .pay-tot-card-v2) enquanto nenhuma conta foi escolhida — controlado por
   innerHTML condicional, não por display, para não brigar com a utilitária
   .only-v2 (que força display:flex sob body.v2). */
body.v2 #pay-accounts-v2{display:flex !important;flex-direction:column;gap:8px;margin-bottom:12px;}
body.v2 .pay-acc-row-v2{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:12px 14px;border-radius:12px;border:1px solid var(--b2);
  background:var(--s2);color:var(--tx);font-family:var(--font);font-size:13px;font-weight:700;
  cursor:pointer;text-align:left;
}
body.v2 .pay-acc-row-v2:hover{border-color:var(--b3);}
body.v2 .pay-acc-row-v2.sel{border-color:var(--orange);background:var(--ob);}
body.v2 .pay-acc-row-v2-saldo{font-size:12px;font-weight:700;color:var(--t3);}
body.v2 .pay-tot-card-v2{
  display:flex;flex-direction:column;gap:8px;background:var(--s2);border:1px solid var(--b1);
  border-radius:14px;padding:14px;margin-bottom:16px;
}
body.v2 .pay-tot-row-v2{display:flex;justify-content:space-between;align-items:center;gap:10px;font-size:12px;}
body.v2 .pay-tot-label-v2{color:var(--t3);}
body.v2 .pay-tot-value-v2{font-weight:800;color:var(--tx);}
body.v2 .pay-tot-warn-v2{
  display:flex;align-items:center;gap:6px;font-size:12px;font-weight:700;color:var(--danger);
  margin-top:2px;
}
body.v2 .pay-tot-warn-v2 svg{flex-shrink:0;}

/* ---------- modal editar lançamento: aviso de parcela projetada (etapa 8) ----------
   #eim-proj-banner-v2 é um container only-v2 vazio por padrão; renderEditProjBannerV2()
   (app.js) só injeta o card .eim-proj-banner-v2-card quando o item aberto é
   projetado (isProj lido de mItems(), a mesma fonte do 🔮/"Previsto" na
   tabela) — nenhuma decisão nova, só leitura. */
body.v2 .eim-proj-banner-v2-card{
  display:flex;align-items:flex-start;gap:8px;
  background:color-mix(in srgb, var(--warn) 15%, transparent);
  border:1px solid color-mix(in srgb, var(--warn) 40%, transparent);
  border-radius:12px;padding:10px 12px;margin-bottom:16px;
  color:var(--warn);font-size:12px;font-weight:600;line-height:1.4;
}
body.v2 .eim-proj-banner-v2-card svg{flex-shrink:0;margin-top:1px;}

/* ================================================================
   DESKTOP (etapa 9) — largura confortável + dashboard em 2 colunas.
   Spec: rodada-04-final `isDesktopMode` + AVALIACAO.md (Modo DESKTOP).
   A tabela de Lançamentos NÃO muda de formato — ela já É o desktop
   (no v2 mobile ela vira lista em etapa futura); aqui só garantimos
   que nenhuma regra v2 deixe a leitura apertada em telas grandes.
   ================================================================ */

/* A) largura do conteúdo: max-width generoso e centrado em telas grandes
   (o v1 já usa .page{margin:0 auto}; só reduzimos o teto e respiramos
   as laterais — sem tocar em padding-top/bottom já definidos) */
@media (min-width:1200px){
  body.v2 .page{max-width:1240px;padding-left:32px;padding-right:32px;}
}

/* B) dashboard em 2 colunas ≥1024px — grid nos filhos diretos de
   #page-dashboard, sem tocar no HTML. Regra genérica primeiro (largura
   total, linha automática), exceções de coluna depois: qualquer bloco
   futuro que eu não tenha mapeado cai automaticamente na largura total
   em vez de sumir numa coluna errada.
   #page-dashboard.on (não só #page-dashboard): goPage() alterna a
   classe "on" pra mostrar/esconder páginas (base: .page{display:none};
   .page.on{display:block}) — as regras abaixo só valem com a página
   realmente aberta.
   POR QUE LINHA EXPLÍCITA (E NÃO SÓ grid-column + linha automática):
   testei primeiro só com grid-column (linha automática pra tudo) e deu
   dois problemas diferentes:
   1. Grid auto-flow: itens de alturas bem desiguais acabando na MESMA
      linha (ex.: #dash-scards-section, ~350px, ao lado de #dash-rem-
      cat-row, ~680px) esticam a linha inteira pro maior — sobra um vão
      vazio embaixo do item curto antes do próximo da mesma coluna.
   2. Float com clear:left/right (tentativa alternativa) resolveria o
      vão, mas float tem uma regra própria (CSS2.1 §9.5.1): nenhum
      float pode subir mais alto que o topo de um float/bloco anterior
      no DOM, DE QUALQUER DIREÇÃO. #dash-accounts-section vem DEPOIS de
      #dash-daily-cf no HTML (ordem real: kpi, scards, cc-casal,
      month-end, saldo, daily-cf, [modais], accounts, rem-cat-row) —
      com float, a coluna direita inteira seria empurrada pra baixo do
      #dash-daily-cf, bem pior que o vão do grid.
   Solução: grid com `grid-row` explícito só nos 7 blocos mapeados —
   cada um ganha a PRÓPRIA linha (linha 3 a 7), então nenhuma linha da
   coluna esquerda é compartilhada com um item desproporcionalmente alto
   da direita (zero vão no meio). #dash-rem-cat-row (o item mais alto
   da direita) recebe `grid-row:4 / 8`, cobrindo o espaço de scards +
   cc-casal + saldo + daily-cf combinados — como ele é mais baixo que
   essa soma, a coluna direita só termina mais cedo que a esquerda
   (vão no FINAL da seção, antes do próximo divisor de largura total,
   que é o comportamento normal/esperado de um dashboard em 2 colunas,
   não um vão no meio do conteúdo).
   #dash-cc-casal-section e #dash-saldo-section podem estar
   display:none (modo individual ou sem dado de saldo) — nesse caso não
   geram caixa e a própria linha reservada simplesmente fica sem
   conteúdo na coluna esquerda (não sobra vão porque não há nada depois
   dependendo dela: #dash-daily-cf tem linha própria fixa, não flutua).
   #fx-warning e #dash-month-end-banner ficam em `grid-row:auto`
   (regra genérica) — são avisos raros e condicionais; quando visíveis,
   a linha automática os insere em largura total sem conflitar com as
   linhas 3-7 (reservadas só nas colunas 1/2, nunca em 1/-1).
   Os 3 modais internos (#saldo-entry-modal/#saldo-pay-modal/
   #saldo-hist-modal) são position:fixed — o containing block deles é a
   viewport, não o grid, então não são afetados (confirmado no harness).
   Divs vazias com display:none (linhas 386-387 do index.html) não
   participam do grid (elemento display:none não gera caixa). */
@media (min-width:1024px){
  body.v2 #page-dashboard.on{
    display:grid;
    grid-template-columns:1.2fr 1fr;
    gap:16px;
    align-items:start;
  }
  body.v2 #page-dashboard.on > *{grid-column:1 / -1;grid-row:auto;}

  body.v2 #page-dashboard.on > #dash-kpi-section{grid-column:1;grid-row:3;}
  body.v2 #page-dashboard.on > #dash-scards-section{grid-column:1;grid-row:4;}
  body.v2 #page-dashboard.on > #dash-cc-casal-section{grid-column:1;grid-row:5;}
  body.v2 #page-dashboard.on > #dash-saldo-section{grid-column:1;grid-row:6;}
  body.v2 #page-dashboard.on > #dash-daily-cf{grid-column:1;grid-row:7;}

  body.v2 #page-dashboard.on > #dash-accounts-section{grid-column:2;grid-row:3;}
  body.v2 #page-dashboard.on > #dash-rem-cat-row{grid-column:2;grid-row:4 / 8;}
}

/* C) tabela de lançamentos: leitura confortável em telas grandes.
   Conferido: o v2 já usa padding 12px em thead th/tbody td (igual ou
   maior que o padding do v1, 10px 12px) — nenhuma regra v2 aperta a
   tabela em nenhuma largura hoje. Reforça explicitamente no desktop
   pra essa garantia não depender de nenhuma regra futura de mobile. */
@media (min-width:1024px){
  body.v2 thead th{padding:12px 14px;}
  body.v2 tbody td{padding:12px 14px;}
}
