/* =========================================================================
   Investimentos — extrato impresso, em tela.
   Estrutura por fios de 1px; dinheiro em serifa transicional com numerais
   tabulares; cor reservada para sinal (alta/baixa) e ação primária.
   ========================================================================= */

:root {
  --paper: #f7f7f3;
  --raised: #ffffff;
  --sunken: #f1f1ec;
  --ink: #14181c;
  --ink-soft: #565d65;
  --ink-faint: #878d94;
  --rule: #e2e2da;
  --rule-strong: #c8c8bd;
  --pine: #1e4b44;
  --pine-deep: #163833;
  --pine-wash: #e8efec;
  --up: #17654a;
  --down: #a33528;
  /* Azul do "no azul": positivo no resumo do incremento diário. Pesa quase o
     mesmo que o vermelho contra o papel (6,0 contra 6,3 de contraste), para
     nenhum dos dois gritar mais alto que o outro, e ΔE 20 de distância do
     vermelho na pior visão de cor simulada. */
  --blue: #1f5fa8;
  --amber: #7d6218;
  --amber-wash: #f6f1e0;

  --serif: "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua", Georgia, serif;
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  /* Largura fixa, para o que se lê caractere a caractere: o segredo do segundo
     fator, que alguém vai copiar à mão para o telefone. Em fonte proporcional,
     o I maiúsculo e o l minúsculo têm o mesmo desenho. */
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;

  --shell: 74rem;
  --shell-wide: 120rem;
  --r-sm: 3px;
  --r-md: 5px;
  --r-lg: 8px;
}

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 1rem;
  line-height: 1.55;
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { font-family: var(--serif); font-weight: 600; letter-spacing: -0.01em; margin: 0; }
h1 { font-size: 1.75rem; line-height: 1.2; }
h2 { font-size: 1.3125rem; line-height: 1.25; }
h3 { font-size: 1.0625rem; }
p { margin: 0; }

a { color: var(--pine); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--pine-deep); }

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

.shell { width: min(var(--shell), 100% - 2.5rem); margin-inline: auto; }

/* Texto corrido continua estreito, porque linha longa cansa de ler. Já uma
   tabela de dados quer largura: com o contêiner travado, dar zoom out só
   aumentava a margem e a tabela rolava do mesmo jeito. Assim, sobrando espaço
   na tela — inclusive por zoom out —, mais colunas aparecem sem rolagem. */
.shell-wide { width: min(var(--shell-wide), 100% - 2.5rem); margin-inline: auto; }

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 50;
  background: var(--pine); color: #fff; padding: .625rem 1rem; border-radius: 0 0 var(--r-md) 0;
}
.skip:focus { left: 0; }

.muted { color: var(--ink-soft); }
.faint { color: var(--ink-faint); }
.num { font-family: var(--serif); font-variant-numeric: tabular-nums; }
.up { color: var(--up); }
.down { color: var(--down); }
.flat { color: var(--ink-soft); }

/* ---------------------------------------------------------------- cabeçalho */
.masthead { border-bottom: 1px solid var(--rule); background: var(--raised); }
.masthead-inner {
  display: flex; align-items: center; gap: 1.75rem;
  min-height: 4rem;
}
/* ------------------------------------------------------------------ a marca
   Duas linhas: o nome e a assinatura, **alinhadas pela direita** — a última
   letra de "by Salas" termina onde termina a de "Investimentos". Alinhadas
   pela esquerda, as duas viravam um bloco de texto; penduradas na mesma
   margem direita, a de baixo lê-se como assinatura do que está acima.

   O tamanho está em `em`, não em `rem`: a marca aparece em dois tamanhos
   (cabeçalho e porta de entrada), e em `rem` a assinatura ficaria
   desproporcional num dos dois. */
.wordmark {
  /* O ícone acompanha o **nome**, não o bloco. "by Salas" é subtítulo: com o
     alinhamento no centro das duas linhas, o ícone descia para o meio e ficava
     entre elas, parecendo pertencer às duas — ou a nenhuma. */
  display: inline-flex; align-items: flex-start; gap: .5rem;
  font-family: var(--serif); font-size: 1.1875rem; font-weight: 600;
  color: var(--ink); text-decoration: none; letter-spacing: -0.015em;
}
.wordmark-nome { display: grid; }
/* Linha travada: é o que mantém a marca de duas linhas na mesma altura de
   cabeçalho que a de uma linha tinha, sem empurrar o menu para baixo.

   A margem cancela o espaçamento **negativo** que a marca aplica entre letras
   e que sai também depois da última: sem ela, a caixa do nome termina uma
   fração antes da própria letra, e é essa caixa que a linha de baixo usa como
   referência. */
.wordmark-app { line-height: 1.05; margin-right: .015em; }
.wordmark-autor {
  font-family: var(--sans);
  font-size: .5em; font-weight: 500; line-height: 1;
  letter-spacing: .06em;
  color: var(--ink-faint);
  justify-self: end; margin-top: .15em;
  /* O mesmo cancelamento do lado de cá, com o sinal trocado: aqui o
     espaçamento é positivo, então a última letra pararia essa fração antes do
     fim da caixa. Com os dois cancelamentos, as duas letras finais terminam
     exatamente na mesma vertical — perto o bastante para ninguém saber dizer o
     que está errado, longe o bastante para o alinhamento não parecer
     alinhamento. */
  margin-right: -.06em;
}
/* Em `em`, para a conta do alinhamento valer nos dois tamanhos da marca: a
   margem é a metade do que sobra entre a altura da linha do nome (1.05em) e a
   do ícone, e é ela que põe o centro do ícone no centro da primeira linha. */
.mark {
  width: .95em; height: .95em; margin-top: .05em;
  color: var(--pine); flex: none;
}

/* Na porta de entrada e no "Sobre" a marca cresce e a assinatura vem junto. */
.wordmark-grande { font-size: 1.75rem; }
/* O ícone já é relativo ao nome; a marca grande não precisa redimensioná-lo. */
/* A marca é o título do diálogo, e precisa de ar antes da primeira linha de
   dados: colada, "by Salas" e "VERSÃO" se leem como um par. */
.sobre-marca {
  margin-bottom: 1.25rem; padding-bottom: 1rem;
  border-bottom: 1px solid var(--rule);
}

.nav { display: flex; gap: 1.5rem; margin-right: auto; }
.nav a {
  color: var(--ink-soft); text-decoration: none; font-size: .9375rem;
  padding: 1.25rem 0; border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.nav a:hover { color: var(--ink); }
.nav a[aria-current="page"] { color: var(--ink); border-bottom-color: var(--pine); }

/* Submenu de Metas: alocação e patrimônio.

   Abre no passar do mouse e no foco do teclado — `focus-within` cobre quem
   navega por tabulação, que de outro jeito passaria batido pelos dois itens.
   A ponte invisível no topo evita que o menu feche quando o ponteiro atravessa
   o vão entre o item e a lista. */
.nav-com-submenu { position: relative; display: inline-flex; }
.nav-com-submenu > .submenu {
  position: absolute; top: 100%; left: 0; z-index: 30;
  display: none; flex-direction: column; min-width: 11rem;
  padding: .375rem; margin-top: .25rem;
  background: var(--raised, #fff); border: 1px solid var(--rule, #e2e8e5);
  border-radius: var(--r-md, 10px);
  box-shadow: 0 8px 24px rgba(20, 40, 35, .12);
}
.nav-com-submenu > .submenu::before {
  content: ""; position: absolute; left: 0; right: 0; top: -.35rem; height: .35rem;
}
.nav-com-submenu:hover > .submenu,
.nav-com-submenu:focus-within > .submenu { display: flex; }
.nav-com-submenu > .submenu a {
  padding: .5rem .625rem; border-bottom: 0; border-radius: 6px;
  white-space: nowrap; font-size: .9375rem;
}
.nav-com-submenu > .submenu a:hover { background: var(--pine-wash, #eef4f1); }
.nav-com-submenu > .submenu a[aria-current="page"] { color: var(--pine-deep, #1e4b44); }

/* Sem passar o mouse não há submenu. Em tela estreita os dois itens ficam à
   mostra, em vez de um menu que nunca abre. */
/* Sem mouse, quem abre o submenu é o toque.

   Achatar os dois itens na barra resolvia o alcance e criava outro problema: a
   barra passava a mostrar "Alocação  Patrimônio" onde as outras telas mostram
   um nome só, e o nome "Metas" sumia. Aqui o item continua sendo "Metas", e o
   toque abre a lista — que é o gesto que a pessoa tenta.

   `:hover` não é desligado por este bloco, mas num aparelho de toque ele nunca
   dispara; o que abre é a marca posta pelo script. */
/* A barra rola na horizontal, e rolagem recorta.

   `overflow-x: auto` não corta só nos lados: ele recorta tudo que passa da
   borda de baixo, e o submenu aberto aparecia decepado na altura do cabeçalho.
   Posição fixa escapa do recorte — mas então as coordenadas precisam ser
   medidas na abertura, porque `fixed` não herda a posição do ancestral. */
@media (hover: none) {
  .nav-com-submenu[data-aberto="1"] > .submenu { position: fixed; }
}

@media (hover: none) {
  /* `focus-within` também precisa sair de cena aqui.
     Ele existe para quem navega por tabulação, mas tocar num link também dá
     foco — então o submenu abria no primeiro toque e não fechava no segundo:
     o atributo saía e o foco segurava a lista aberta. */
  .nav-com-submenu:hover > .submenu,
  .nav-com-submenu:focus-within > .submenu { display: none; }
  .nav-com-submenu[data-aberto="1"] > .submenu { display: flex; }
}

.masthead-actions { display: flex; align-items: center; gap: .75rem; }

/* Rótulos que trocam com a largura. O padrão é o longo; o curto só aparece
   onde o longo não cabe. */
.so-estreito { display: none; }
.so-largo { display: inline; }

.menu { position: relative; }
.menu summary { list-style: none; cursor: pointer; }
.menu summary::-webkit-details-marker { display: none; }
.avatar {
  display: grid; place-items: center; width: 2rem; height: 2rem;
  border-radius: 50%; background: var(--pine-wash); color: var(--pine-deep);
  font-size: .8125rem; font-weight: 600; border: 1px solid var(--rule);
}
.menu-panel {
  position: absolute; right: 0; top: calc(100% + .625rem); z-index: 20;
  min-width: 15rem; background: var(--raised);
  border: 1px solid var(--rule); border-radius: var(--r-md);
  box-shadow: 0 12px 28px -18px rgba(20, 24, 28, .45);
  padding: .375rem;
}
.menu-id {
  font-size: .8125rem; color: var(--ink-faint);
  padding: .5rem .625rem; border-bottom: 1px solid var(--rule); margin-bottom: .25rem;
  overflow-wrap: anywhere;
}
.menu-panel a, .menu-panel button {
  display: block; width: 100%; text-align: left;
  padding: .5rem .625rem; border: 0; border-radius: var(--r-sm);
  background: none; color: var(--ink); font: inherit; font-size: .9375rem;
  text-decoration: none; cursor: pointer;
}
.menu-panel a:hover, .menu-panel button:hover { background: var(--sunken); }

/* ------------------------------------------------------------ personificação */
.impersonation {
  display: flex; align-items: center; justify-content: center;
  gap: 1rem; flex-wrap: wrap;
  background: var(--amber-wash); border-bottom: 1px solid #e4dcc0;
  padding: .5rem 1.25rem; font-size: .875rem; color: var(--amber);
}
.impersonation strong { color: #5f4a10; }

/* -------------------------------------------------------------------- flashes */
.flash-stack { margin-top: 1.25rem; display: grid; gap: .5rem; }
.flash {
  border: 1px solid var(--rule); border-left: 3px solid var(--pine);
  background: var(--raised); border-radius: var(--r-sm);
  padding: .6875rem .875rem; font-size: .9375rem;
}
.flash-error { border-left-color: var(--down); }
.flash-warning { border-left-color: var(--amber); }

/* -------------------------------------------------------------------- botões */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .4375rem;
  font: inherit; font-size: .9375rem; line-height: 1;
  padding: .625rem 1rem; border-radius: var(--r-md);
  border: 1px solid var(--rule-strong); background: var(--raised); color: var(--ink);
  cursor: pointer; text-decoration: none; white-space: nowrap;
}
.btn:hover { background: var(--sunken); color: var(--ink); }
.btn-sm { padding: .4375rem .75rem; font-size: .875rem; }
.btn-primary { background: var(--pine); border-color: var(--pine); color: #fff; }
.btn-primary:hover { background: var(--pine-deep); border-color: var(--pine-deep); color: #fff; }
.btn-ghost { background: transparent; border-color: currentColor; color: inherit; }
.btn-ghost:hover { background: rgba(20, 24, 28, .06); color: inherit; }
.btn-danger { color: var(--down); border-color: #e0c5c0; }
.btn-danger:hover { background: #fbf0ee; }

/* --------------------------------------------------------------- data picker */
.timeline {
  display: flex; align-items: flex-end; gap: .75rem; flex-wrap: wrap;
}
.timeline label { font-size: .8125rem; color: var(--ink-soft); display: block; margin-bottom: .3125rem; }
input[type="date"] {
  font: inherit; font-size: .9375rem; color: var(--ink);
  padding: .5rem .625rem; border: 1px solid var(--rule-strong);
  border-radius: var(--r-md); background: var(--raised);
}

/* ================================================================== POSIÇÃO */
.statement { padding: 3rem 0 1rem; }

.statement-head {
  display: flex; justify-content: space-between; align-items: flex-end;
  gap: 1.5rem; flex-wrap: wrap; margin-bottom: 1.5rem;
}
.statement-head p { color: var(--ink-soft); font-size: .9375rem; }

.balance { border-top: 2px solid var(--ink); padding-top: 1.25rem; }
.balance-label { font-size: .875rem; color: var(--ink-soft); margin-bottom: .25rem; }
.balance-figure {
  font-family: var(--serif); font-weight: 600;
  font-size: clamp(2.5rem, 7.5vw, 4.25rem); line-height: 1.02;
  letter-spacing: -0.03em; margin: 0;
}
.balance-note { margin-top: .75rem; color: var(--ink-soft); font-size: .9375rem; max-width: 46ch; }
.balance-note .num { font-size: 1rem; }

.ledger-strip {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  border-top: 1px solid var(--rule); margin-top: 2rem;
}
.ledger-cell {
  padding: 1.125rem 1.25rem 1.125rem 0;
  border-right: 1px solid var(--rule);
}
/* Abrindo um cartão, a tira não precisa da linha nem do respiro de cima: a
   borda do cartão já faz a separação, e as duas juntas desenham um risco solto
   acima do primeiro conteúdo. */
.form-card > .ledger-strip:first-child { margin-top: 0; border-top: 0; }
.form-card > .ledger-strip:first-child .ledger-cell { padding-top: 0; }
.ledger-cell:last-child { border-right: 0; }
.ledger-cell + .ledger-cell { padding-left: 1.25rem; }
.ledger-cell dt { font-size: .8125rem; color: var(--ink-soft); margin-bottom: .25rem; }
.ledger-cell dd { margin: 0; font-family: var(--serif); font-size: 1.5rem; font-weight: 600; letter-spacing: -0.015em; }
.ledger-cell small { display: block; font-family: var(--sans); font-size: .8125rem; color: var(--ink-faint); font-weight: 400; letter-spacing: 0; margin-top: .125rem; }

.toggle-figure {
  border: 0; background: none; padding: 0; margin: 0; cursor: pointer;
  font: inherit; color: inherit; text-align: left;
  display: inline-flex; align-items: baseline; gap: .5rem;
  border-bottom: 1px dashed var(--rule-strong);
}
.toggle-figure:hover { border-bottom-color: var(--ink-soft); }
.toggle-hint { font-family: var(--sans); font-size: .75rem; color: var(--ink-faint); font-weight: 400; letter-spacing: 0; }

/* ---------------------------------------------------------------- seções */
.section { padding: 2.5rem 0; }
.section-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
  border-bottom: 1px solid var(--rule); padding-bottom: .625rem; margin-bottom: 1.25rem;
}
.section-head p { color: var(--ink-soft); font-size: .875rem; }

.split { display: grid; gap: 2.5rem; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
@media (max-width: 62rem) { .split { grid-template-columns: 1fr; } }

/* barras de composição */
.allocation { display: grid; gap: 1rem; }
.allocation-row { display: grid; gap: .375rem; }
.allocation-top { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; font-size: .9375rem; }
.allocation-top strong { font-weight: 500; }
.allocation-value { font-family: var(--serif); font-size: 1.0625rem; }
.track { height: .5rem; background: var(--sunken); border-radius: 999px; overflow: hidden; }
.track span { display: block; height: 100%; background: var(--pine); border-radius: 999px; width: 0; }
.track span[data-tone="2"] { background: #4c7c6f; }
.track span[data-tone="3"] { background: #7fa397; }
.track span[data-tone="4"] { background: #a9c2b9; }
.track span[data-tone="5"] { background: #c8d6d0; }
.track span[data-tone="6"] { background: #7d6218; }
.track span[data-tone="7"] { background: #b19246; }
.track span[data-tone="8"] { background: #a33528; }
.track span[data-tone="9"] { background: #c4746a; }

/* =================================================================== TABELAS */
.table-wrap {
  background: var(--raised); border: 1px solid var(--rule); border-radius: var(--r-md);
  overflow-x: auto;
}
table { width: 100%; border-collapse: collapse; font-size: .9375rem; }
thead th {
  text-align: left; font-weight: 500; font-size: .8125rem; color: var(--ink-soft);
  padding: .75rem .875rem; border-bottom: 1px solid var(--rule-strong);
  background: var(--raised); white-space: nowrap; position: sticky; top: 0;
}
tbody td { padding: .8125rem .875rem; border-bottom: 1px solid var(--rule); vertical-align: middle; }
tbody tr:last-child td { border-bottom: 0; }
.numeric { text-align: right; font-family: var(--serif); font-variant-numeric: tabular-nums; white-space: nowrap; }
th.numeric { font-family: var(--sans); }

th[data-sort] { cursor: pointer; user-select: none; }
th[data-sort]:hover { color: var(--ink); }
th[data-sort]::after { content: "↕"; margin-left: .375rem; opacity: .3; font-size: .75rem; }
th[data-sort][aria-sort="ascending"]::after { content: "↑"; opacity: 1; }
th[data-sort][aria-sort="descending"]::after { content: "↓"; opacity: 1; }

/* linha agregada expansível */
.position-row > td { background: var(--raised); }
.position-row.is-open > td { background: var(--sunken); }
.disclosure {
  display: inline-flex; align-items: center; gap: .5rem;
  background: none; border: 0; padding: 0; font: inherit; color: var(--ink);
  cursor: pointer; text-align: left;
}
.disclosure .chevron {
  width: .5rem; height: .5rem; border-right: 1.5px solid var(--ink-faint);
  border-bottom: 1.5px solid var(--ink-faint); transform: rotate(-45deg);
  transition: transform .18s ease; flex: none;
}
.position-row.is-open .chevron { transform: rotate(45deg); }
.ticker { font-family: var(--serif); font-size: 1rem; font-weight: 600; letter-spacing: .01em; }
.sub { display: block; font-size: .78125rem; color: var(--ink-faint); font-family: var(--sans); font-weight: 400; }

.entries-row > td { padding: 0; background: var(--sunken); }
.entries { padding: .25rem 0 .75rem 2.25rem; }
.entries table { font-size: .875rem; }
.entries thead th { background: transparent; border-bottom: 1px solid var(--rule); position: static; }
.entries tbody td { border-bottom: 1px dotted var(--rule); }
.entries tbody tr:last-child td { border-bottom: 0; }

.pill {
  display: inline-block; padding: .125rem .5rem; border-radius: 999px;
  font-size: .75rem; border: 1px solid var(--rule-strong); color: var(--ink-soft);
  white-space: nowrap;
}
.pill-fixed { background: var(--pine-wash); border-color: #cfdfd9; color: var(--pine-deep); }
.pill-soon { background: #f6ece9; border-color: #e5c9c3; color: var(--down); }

.filters { display: flex; gap: .5rem; flex-wrap: wrap; align-items: flex-end; }
.filters select {
  font: inherit; font-size: .9375rem; padding: .5rem .625rem;
  border: 1px solid var(--rule-strong); border-radius: var(--r-md); background: var(--raised); color: var(--ink);
}
.filters label { display: block; font-size: .8125rem; color: var(--ink-soft); margin-bottom: .3125rem; }

/* ==================================================================== VAZIO */
.empty {
  border: 1px dashed var(--rule-strong); border-radius: var(--r-md);
  background: var(--raised); padding: 2.5rem 2rem; text-align: center;
}
.empty h2 { margin-bottom: .5rem; }
.empty p { color: var(--ink-soft); max-width: 44ch; margin: 0 auto 1.25rem; }

.notice {
  border: 1px solid #e4dcc0; background: var(--amber-wash); color: var(--amber);
  border-radius: var(--r-sm); padding: .625rem .875rem; font-size: .875rem;
}

/* ================================================================ FORMULÁRIO */
.form-page { padding: 2.5rem 0 4rem; }
.form-card {
  background: var(--raised); border: 1px solid var(--rule); border-radius: var(--r-lg);
  padding: 1.75rem;
}
.fieldset { border: 0; padding: 0; margin: 0 0 1.75rem; }
.fieldset:last-of-type { margin-bottom: 1rem; }
.fieldset legend {
  font-family: var(--serif); font-size: 1.0625rem; font-weight: 600;
  padding: 0 0 .625rem; margin-bottom: 1rem; width: 100%;
  border-bottom: 1px solid var(--rule);
}
.grid { display: grid; gap: 1rem 1.25rem; grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr)); }
.field { display: grid; gap: .375rem; align-content: start; }
.field label { font-size: .875rem; color: var(--ink-soft); }
.field input[type="text"], .field input[type="email"], .field input[type="password"],
.field input[type="number"], .field input[type="date"], .field select, .field textarea {
  font: inherit; font-size: .9375rem; color: var(--ink); width: 100%;
  padding: .5625rem .6875rem; background: var(--raised);
  border: 1px solid var(--rule-strong); border-radius: var(--r-md);
}
.field input:focus, .field select:focus { border-color: var(--pine); }
.field .help { font-size: .8125rem; color: var(--ink-faint); }
.field .error { font-size: .8125rem; color: var(--down); }
.field.has-error input, .field.has-error select { border-color: var(--down); }
.check { display: flex; align-items: flex-start; gap: .5rem; }
.check input { margin-top: .25rem; accent-color: var(--pine); }
.check label { color: var(--ink); font-size: .9375rem; }
.form-actions { display: flex; gap: .75rem; flex-wrap: wrap; align-items: center; padding-top: .5rem; }
.form-actions .spacer { margin-left: auto; }
[hidden] { display: none !important; }

/* =================================================================== ACESSO */
.gate {
  min-height: 100dvh; display: grid; grid-template-columns: 1.05fr .95fr;
}
@media (max-width: 56rem) { .gate { grid-template-columns: 1fr; } }

.gate-aside {
  background: var(--pine-deep); color: #e9efec;
  padding: 3.5rem clamp(2rem, 5vw, 4rem);
  display: flex; flex-direction: column; justify-content: space-between; gap: 3rem;
}
@media (max-width: 56rem) { .gate-aside { display: none; } }
.gate-aside .wordmark { color: #fff; }
.gate-aside .mark { color: #8fc4b0; }
/* Sobre o verde escuro, o cinza da assinatura sumiria: aqui ela usa o mesmo
   tom dos rótulos da coluna, que já foi escolhido para esse fundo. */
.gate-aside .wordmark-autor { color: #9db8ae; }
.gate-quote { font-family: var(--serif); font-size: clamp(1.5rem, 2.6vw, 2.125rem); line-height: 1.25; letter-spacing: -0.02em; max-width: 20ch; color: #fff; }
.gate-aside dl { display: grid; gap: 1.25rem; margin: 0; }
.gate-aside dt { font-size: .8125rem; color: #9db8ae; margin-bottom: .125rem; }
.gate-aside dd { margin: 0; font-size: .9375rem; color: #dfeae5; max-width: 34ch; }

.gate-main {
  display: grid; place-items: center; padding: 3rem 1.5rem;
}
.gate-form { width: min(24rem, 100%); }
.gate-form h1 { font-size: 1.875rem; margin-bottom: .375rem; }
.gate-form > p { color: var(--ink-soft); margin-bottom: 1.75rem; }
.gate-form .field + .field { margin-top: 1rem; }
.gate-form .btn { width: 100%; margin-top: 1.5rem; padding-block: .75rem; }
.gate-alt { margin-top: 1.5rem; font-size: .9375rem; color: var(--ink-soft); text-align: center; }
.form-error {
  border: 1px solid #e0c5c0; background: #fbf0ee; color: var(--down);
  border-radius: var(--r-sm); padding: .625rem .75rem; font-size: .875rem; margin-bottom: 1.25rem;
}

/* ================================================================= GRÁFICOS */
.charts {
  display: grid; gap: 1.5rem;
  grid-template-columns: repeat(auto-fit, minmax(23rem, 1fr));
  /* Todos os cartões da linha com a mesma altura.

     Havia aqui `align-items: start`, para o cartão de três legendas não ficar
     com um vazio embaixo. O vazio se resolve do outro lado: a rosca cresce e
     o ocupa (`igualarRoscas`, em charts.js). Cartões de alturas diferentes
     fazem a leitura virar sobre o tamanho deles em vez do que dizem. */
  align-items: stretch;
}
/* Modo de medição, ligado pelo script por um instante e desligado na mesma
   passada.

   A altura da linha é a do cartão mais alto pela **altura natural** dele.
   Medir com os cartões já esticados mediria o próprio estica: a folga sairia
   de onde ela já foi ocupada, e a rosca cresceria mais um tanto a cada
   chamada — e `renderCharts` é chamado de novo a cada troca de valores. */
.charts.medindo-alturas { align-items: start; }

.chart-card {
  background: var(--raised); border: 1px solid var(--rule); border-radius: var(--r-md);
  padding: 1.25rem 1.375rem 1.375rem;
}
/* Só os cartões estreitos da grade de cima: o corpo recebe a folga da linha, e
   é dentro dele que a rosca cresce.

   Os largos — papel a papel, liquidez, vencimentos — ficam como estão: cada um
   ocupa a linha inteira, então não há vizinho mais alto nem folga a
   distribuir. Por isso a regra é escoada em `.charts >` e exclui
   `.chart-wide`: o cartão de evolução vive fora desta grade e não pode ser
   alcançado por ela. */
.charts > .chart-card:not(.chart-wide) { display: flex; flex-direction: column; }

/* O corpo empilha sempre: rosca em cima, legenda embaixo.

   Lado a lado — o que acontecia sozinho em duas colunas, onde sobrava largura
   para a legenda caber ao lado — a rosca não tem para onde crescer. Ela é
   quadrada: ganhar altura é ganhar largura, e ali a largura é da legenda.
   Tomá-la faria o texto da lista reembrulhar mais alto, e o cartão cresceria
   em vez de encolher — a altura se retroalimentando. Medido a 1100px, a folga
   de "Por modalidade" era de 144px e a rosca só podia crescer 38.

   Empilhado, a largura do cartão inteiro é da rosca, a folga da linha se
   resolve, e o arranjo é o mesmo em toda largura de tela — que é o que a grade
   uniforme promete. O papel a papel continua lado a lado: é a exceção
   declarada, e lá a rosca já é maior por conta própria. */
.charts > .chart-card:not(.chart-wide) > .chart-body {
  flex: 1 1 auto;
  flex-direction: column;
  align-items: center;
  /* A folga que a rosca não alcançar fica dividida em cima e embaixo, não
     toda embaixo: vazio repartido lê como cartão centrado, não como cartão
     quebrado. */
  justify-content: center;
}
/* Em coluna, `flex: 1 1 13rem` passaria a valer na vertical e esticaria a
   lista. A altura dela é a do conteúdo; a largura, a do cartão. */
.charts > .chart-card:not(.chart-wide) > .chart-body > .legend {
  flex: 0 0 auto; width: 100%;
}

.chart-card h3 { margin-bottom: .125rem; }
.chart-card .chart-sub { font-size: .8125rem; color: var(--ink-faint); margin-bottom: 1rem; }
.chart-body { display: flex; align-items: center; justify-content: center; gap: 1.25rem; flex-wrap: wrap; }
/* O desenho é vetorial: deixar que encolha evita que ele empurre a legenda
   para fora numa tela estreita, e o total no furo acompanha. */
.chart-body svg { flex: none; max-width: 100%; height: auto; }
/* A legenda precisa de largura para o nome caber numa linha. Quando não
   sobra espaço ao lado da rosca, ela quebra para baixo e usa o cartão todo. */
.legend {
  display: grid; gap: .4375rem; font-size: .8125rem;
  flex: 1 1 13rem; min-width: 13rem;
}
.legend-item {
  display: grid; grid-template-columns: auto 1fr auto;
  align-items: start; gap: .5rem;
}
.swatch { width: .625rem; height: .625rem; border-radius: 2px; flex: none; margin-top: .25rem; }
/* Nome de categoria nunca é cortado: "ETF Nacional · renda fixa" e
   "ETF Nacional · renda variável" viram a mesma coisa com reticências. */
.legend-name { color: var(--ink-soft); overflow-wrap: anywhere; }
.legend-share { font-family: var(--serif); color: var(--ink); }
.chart-empty { color: var(--ink-faint); font-size: .875rem; padding: 1.5rem 0; }

/* A barra de escala, na frente do título de Privacidade.

   Discreta por decisão, não por descuido: ela não tem rótulo nem legenda, e o
   desenho acompanha — fio fino, cursor pequeno, cor da casa. Quem a vê é quem
   a colocou ali. Só o administrador a recebe no HTML. */
.titulo-com-escala { display: flex; align-items: center; gap: .75rem; min-width: 0; }
.escala-form { display: flex; align-items: center; gap: .5rem; }
/* 9rem para dez paradas dão quase um centímetro cada: arrastar acerta a parada
   sem depender do teclado. Mais larga que isso a barra deixa de passar por
   enfeite ao lado do título, que é metade do que ela precisa ser. */
.escala {
  -webkit-appearance: none; appearance: none;
  width: 9rem; height: 1rem; background: none; cursor: pointer; margin: 0;
}
.escala::-webkit-slider-runnable-track {
  height: 2px; background: var(--rule-strong); border-radius: 1px;
}
.escala::-moz-range-track {
  height: 2px; background: var(--rule-strong); border-radius: 1px;
}
.escala::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: .625rem; height: .625rem; margin-top: -.3125rem;
  border-radius: 50%; background: var(--pine); border: 0;
}
.escala::-moz-range-thumb {
  width: .625rem; height: .625rem; border: 0; border-radius: 50%;
  background: var(--pine);
}
.escala:focus-visible { outline: 2px solid var(--pine); outline-offset: 3px; }

/* O eco do percentual. Ocupa o lugar dele sempre — largura fixa e visibilidade,
   não `display` — para o título não dar um pulo lateral no instante em que o
   número aparece. Tabular para "20%" e "100%" não mudarem de largura enquanto
   a barra corre. */
.escala-eco {
  visibility: hidden;
  min-width: 3ch;
  font-size: .8125rem;
  font-variant-numeric: tabular-nums;
  color: var(--ink-soft);
}
.escala-eco.visivel { visibility: visible; }

/* ==================================================================== RODAPÉ */
.footer { border-top: 1px solid var(--rule); margin-top: 3rem; padding: 1.75rem 0 2.5rem; }
/* Empilhado e centralizado: as duas frases são uma só mensagem, e lado a lado
   elas se leriam como dois avisos sem relação. */
.footer-inner {
  display: grid; justify-items: center; gap: .375rem; text-align: center;
}
/* Sem teto de largura: cada frase cabe numa linha na tela cheia, e em tela
   estreita quebra sozinha. Com o teto, a primeira quebrava já no desktop e as
   duas frases viravam três linhas sem motivo. */
.footer p { font-size: .8125rem; color: var(--ink-faint); }

/* ================================================================ LISTA ADMIN */
.people { display: grid; gap: .5rem; }
.person {
  display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;
  background: var(--raised); border: 1px solid var(--rule); border-radius: var(--r-md);
  padding: .875rem 1rem;
}
.person .who { margin-right: auto; }
.person .who strong { font-weight: 500; }
.person .who span { display: block; font-size: .8125rem; color: var(--ink-faint); }
/* O e-mail de quem convidou é um link dentro de uma linha apagada: sem a cor
   própria ele herdaria o cinza das outras e deixaria de parecer clicável. */
.convite-origem a { color: var(--pine); }
.convite-origem a:hover { color: var(--pine-deep); }

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

@media (max-width: 46rem) {
  .nav { gap: 1rem; font-size: .875rem; overflow-x: auto; }
  .nav a { padding: 1rem 0; }
  .masthead-inner { gap: 1rem; }
  .ledger-cell, .ledger-cell + .ledger-cell { padding-left: 0; border-right: 0; border-bottom: 1px solid var(--rule); }
  .ledger-strip { border-top: 1px solid var(--rule); }
}

@media print {
  .masthead, .footer, .timeline, .btn, .filters { display: none; }
  body { background: #fff; }
}

/* ------------------------------------------------- ajustes finos de tabela */
/* Largura da coluna do papel — de novo, só a tabela de fora: aplicá-la à
   tabela aninhada esticaria a célula do menu de ações para 15rem. */
#positions-table > tbody > tr:not(.entries-row) > td:first-child,
#positions-table > thead > tr > th:first-child { min-width: 15rem; }
#positions-table td:nth-child(2),
#analysis-table td:nth-child(4) { white-space: nowrap; }

.table-dense td, .table-dense th { white-space: nowrap; }
.table-dense td:first-child { min-width: 10rem; white-space: normal; }

tfoot td {
  border-top: 1px solid var(--rule-strong); background: var(--raised);
  padding: .8125rem .875rem;
}
tfoot strong { font-weight: 600; }
tfoot .numeric { font-family: var(--serif); }

.subhead { margin-top: 2rem; }
.subhead h3 { font-size: 1rem; }
.allocation + .subhead { margin-top: 2.25rem; }

/* -------------------------------------------------- aviso com ação embutida */
.callout {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1.5rem; flex-wrap: wrap;
  background: var(--raised); border: 1px solid var(--rule);
  border-left: 3px solid var(--pine); border-radius: var(--r-md);
  padding: 1.125rem 1.25rem; margin: 1.75rem 0 0;
}
.callout h3 { font-size: 1rem; margin-bottom: .1875rem; }
.callout p { font-size: .875rem; color: var(--ink-soft); max-width: 58ch; }
.callout form { flex: none; }
.callout-quiet { border-left-color: var(--amber); }

/* ---------------------------------------------------- autocompletar simples */
.field { position: relative; }
.suggest {
  position: absolute; top: 100%; left: 0; right: 0; z-index: 30;
  margin: .25rem 0 0; padding: .25rem; list-style: none;
  background: var(--raised); border: 1px solid var(--rule-strong);
  border-radius: var(--r-md);
  box-shadow: 0 12px 28px -18px rgba(20, 24, 28, .5);
  max-height: 14rem; overflow-y: auto;
}
.suggest li {
  padding: .4375rem .625rem; border-radius: var(--r-sm);
  font-size: .875rem; cursor: pointer;
}
.suggest li:hover, .suggest li.is-active { background: var(--pine-wash); }

/* ------------------------------------------------------ saídas do lançamento */
.danger-zone {
  margin-top: 2rem; background: var(--raised);
  border: 1px solid var(--rule); border-radius: var(--r-lg); padding: 1.5rem 1.75rem;
}
.danger-zone h2 { font-size: 1.125rem; }
.danger-zone > p { font-size: .875rem; margin-bottom: 1.25rem; }
.danger-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1.5rem; flex-wrap: wrap;
  padding: 1rem 0; border-top: 1px solid var(--rule);
}
.danger-row p { font-size: .875rem; max-width: 56ch; margin-top: .125rem; }
.danger-row form { flex: none; }

/* ----------------------------------------------------------- linha arquivada */
.archived-row td { color: var(--ink-faint); background: var(--sunken); }
.archived-row .ticker { color: var(--ink-soft); }
.pill-archived { background: var(--sunken); border-color: var(--rule-strong); }

/* --------------------------------------------------------- saldo em dólar */
.balance-usd {
  margin-top: .5rem; font-size: .875rem; color: var(--ink-soft);
}
.balance-usd .num { font-family: var(--serif); font-size: 1.0625rem; color: var(--ink); }

.cur-tag {
  display: inline-block; margin-left: .3125rem; font-family: var(--sans);
  font-size: .6875rem; color: var(--ink-faint); vertical-align: .05em;
}

/* ------------------------------------------- barras empilhadas por prazo */
.chart-wide { grid-column: 1 / -1; }
.chart-body-block { display: block; }
.legend-inline {
  display: flex; flex-wrap: wrap; gap: .5rem 1rem;
  margin-top: .75rem; min-width: 0;
}
.legend-chip {
  display: inline-flex; align-items: center; gap: .375rem;
  font-size: .8125rem; color: var(--ink-soft);
}

/* Papel fixo ao rolar a tabela larga na horizontal.

   Só as células de dados da tabela de fora. A linha de lançamentos tem uma
   célula só, que também é `first-child`: grudá-la criaria um contexto de
   empilhamento em volta da tabela aninhada, e qualquer menu aberto lá dentro
   ficaria preso abaixo das linhas seguintes. */
#positions-table > tbody > tr:not(.entries-row) > td:first-child,
#positions-table > thead > tr > th:first-child,
#positions-table > tfoot > tr > td:first-child {
  position: sticky; left: 0; z-index: 2;
  background: var(--raised); border-right: 1px solid var(--rule);
}
#positions-table > thead > tr > th:first-child { z-index: 3; }
#positions-table .position-row.is-open td:first-child { background: var(--sunken); }
#positions-table tfoot td:first-child { background: var(--raised); }

/* ------------------------------------------ aviso de coleta em andamento */
.live-bar {
  position: fixed; left: 50%; bottom: 1.5rem; transform: translateX(-50%);
  z-index: 60; display: flex; align-items: center; gap: .625rem;
  background: var(--ink); color: #f2f4f3;
  padding: .625rem 1rem; border-radius: 999px;
  font-size: .875rem; box-shadow: 0 14px 34px -18px rgba(20, 24, 28, .75);
  max-width: calc(100% - 2rem);
}
.live-bar.is-done { background: var(--pine-deep); }
.live-bar.is-idle { background: var(--amber); }
.live-bar.is-leaving { opacity: 0; transition: opacity .35s ease; }

.live-spinner {
  width: .875rem; height: .875rem; flex: none;
  border: 2px solid rgba(255, 255, 255, .3);
  border-top-color: #fff; border-radius: 50%;
  animation: live-spin .7s linear infinite;
}
@keyframes live-spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  .live-spinner { animation: none; border-top-color: rgba(255, 255, 255, .8); }
}

/* ------------------------------------------- cotação a caminho, por papel */
.fetching {
  display: inline-flex; align-items: center; gap: .375rem;
  font-family: var(--sans); font-size: .8125rem; color: var(--ink-faint);
  white-space: nowrap;
}
.fetching-dot {
  width: .4375rem; height: .4375rem; border-radius: 50%;
  background: var(--pine); flex: none;
  animation: fetch-pulse 1.1s ease-in-out infinite;
}
@keyframes fetch-pulse {
  0%, 100% { opacity: .25; transform: scale(.75); }
  50%      { opacity: 1;   transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .fetching-dot { animation: none; opacity: .7; }
}

/* =========================================================================
   Celular: tabelas viram fichas.
   Uma tabela de 12 colunas não cabe em 390px, e rolar na horizontal esconde
   justamente os números. Cada linha vira uma ficha com rótulo à esquerda e
   valor à direita — a mesma informação, na vertical.
   ========================================================================= */
@media (max-width: 52rem) {
  .table-wrap { border: 0; background: none; overflow-x: visible; }

  .table-wrap table,
  .table-wrap tbody,
  .table-wrap tfoot,
  .table-wrap tr,
  .table-wrap td { display: block; width: auto; }

  .table-wrap thead { display: none; }

  .table-wrap tbody tr:not(.entries-row) {
    background: var(--raised); border: 1px solid var(--rule);
    border-radius: var(--r-md); padding: .25rem .875rem .5rem;
    margin-bottom: .625rem;
  }

  .table-wrap tbody td {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 1rem; padding: .4375rem 0; border-bottom: 1px solid var(--rule);
    text-align: left;
  }
  .table-wrap tbody td:last-child { border-bottom: 0; }

  /* Vale para o corpo e para o rodapé: empilhado, o total sem rótulo vira
     quatro números seguidos sem dizer qual é qual. */
  .table-wrap tbody td[data-label]::before,
  .table-wrap tfoot td[data-label]::before {
    content: attr(data-label);
    font-family: var(--sans); font-size: .8125rem; color: var(--ink-soft);
    font-weight: 400; flex: none;
  }

  /* A primeira célula é o título da ficha: sem rótulo, largura toda. */
  .table-wrap tbody td:first-child {
    display: block; padding: .625rem 0 .5rem;
    border-bottom: 1px solid var(--rule-strong);
  }
  .table-wrap tbody td:first-child::before { content: none; }

  .table-wrap .numeric { text-align: right; white-space: normal; }
  /* No corpo da ficha o detalhe fica ao lado do número; no título da ficha
     ele desce para a linha de baixo. */
  .table-wrap tbody td .sub { display: inline; margin-left: .375rem; }
  .table-wrap tbody td:first-child .sub { display: block; margin-left: 0; }
  .table-wrap tbody td:first-child .disclosure { width: 100%; align-items: flex-start; }
  .table-wrap tbody td:first-child .chevron { margin-top: .375rem; }

  /* A primeira coluna deixa de ser fixa: não há rolagem horizontal. */
  #positions-table > tbody > tr > td:first-child,
  #positions-table > thead > tr > th:first-child { position: static; border-right: 0; }

  /* Lançamentos individuais, dentro da ficha. */
  .entries-row > td { padding: 0; background: none; }
  .entries { padding: 0 0 .5rem; }
  .entries table, .entries tbody, .entries tr, .entries td { display: block; }
  .entries thead { display: none; }
  .entries tbody tr {
    border: 1px dashed var(--rule-strong); border-radius: var(--r-sm);
    padding: .25rem .625rem; margin-top: .5rem; background: var(--raised);
  }
  .entries tbody td {
    display: flex; justify-content: space-between; gap: 1rem;
    padding: .3125rem 0; border-bottom: 1px dotted var(--rule);
  }
  .entries tbody td::before {
    content: attr(data-label); color: var(--ink-faint); font-size: .78125rem;
  }

  .table-wrap tfoot tr {
    background: var(--sunken); border: 1px solid var(--rule-strong);
    border-radius: var(--r-md); padding: .25rem .875rem .5rem;
  }
  .table-wrap tfoot td:empty { display: none; }
  .table-wrap tfoot td[data-label] { display: flex; justify-content: space-between; }
  .table-wrap tfoot td:first-child { border-bottom: 1px solid var(--rule-strong); }

  /* A tabela da análise tem 16 colunas: continua rolando, com aviso. */
  #analysis-table { display: table; }
  #analysis-table thead { display: table-header-group; }
  #analysis-table tbody { display: table-row-group; }
  #analysis-table tfoot { display: table-footer-group; }
  #analysis-table tr { display: table-row; }
  #analysis-table td, #analysis-table th { display: table-cell; }
  #analysis-table td::before { content: none; }
  .table-wrap:has(#analysis-table) {
    overflow-x: auto; border: 1px solid var(--rule);
    background: var(--raised); border-radius: var(--r-md);
  }
}

/* Cabeçalho e filtros em telas estreitas */
@media (max-width: 46rem) {
  .shell, .shell-wide { width: min(var(--shell), 100% - 1.75rem); }
  .masthead-inner { flex-wrap: wrap; gap: .5rem .75rem; padding-block: .625rem; }
  /* A marca acompanha a largura da tela.

     Os ícones da direita têm largura fixa, e o que sobra para a marca encolhe
     junto com o aparelho. Em corpo fixo ela deixava de caber e caía para uma
     linha só dela, empurrando os ícones para outra — duas faixas onde cabia
     uma. O corpo variável tira isso do acaso: a conta é o espaço que sobra
     dividido pelo que a marca ocupa em `em`, e o `clamp` guarda os extremos —
     nunca maior que no computador, nunca menor que o legível.

     `vw` em vez do tamanho do container porque a largura da marca **é** o que
     se está calculando: medi-la a partir da caixa que ela mesma estica seria
     perguntar o resultado para chegar nele. */
  .masthead .wordmark {
    order: 1; flex: 0 1 auto; min-width: 0;
    font-size: clamp(.8125rem, calc((100vw - 14.625rem) / 7.4), 1.1875rem);
  }
  /* A assinatura é metade do nome, e com o nome pequeno ela chegaria a seis
     pixels. Aqui ela ganha um piso próprio em `rem` — continua mais estreita
     que o nome, que é o que mantém as duas últimas letras alinhadas. */
  .masthead .wordmark-autor { font-size: max(.5em, .5625rem); }
  .masthead-actions { order: 2; margin-left: auto; flex: none; gap: .5rem; }

  /* Em tela estreita o botão usa o rótulo curto: com o longo, a marca era
     empurrada para uma linha só dela e deixava de parecer um item de menu. */
  .so-largo { display: none; }
  .so-estreito { display: inline; }
  .nav {
    order: 3; width: 100%; margin: 0; gap: 1.25rem;
    border-top: 1px solid var(--rule);
  }
  .nav a { padding: .625rem 0; font-size: .9375rem; }

  .statement { padding: 1.75rem 0 .5rem; }
  .statement-head { gap: 1rem; }
  .timeline, .filters { width: 100%; }
  .filters > div { flex: 1 1 9rem; }
  .filters .btn, .timeline .btn { flex: none; }
  input[type="date"], .filters select { width: 100%; }

  .section { padding: 1.75rem 0; }
  .form-card { padding: 1.125rem; }
  .danger-zone { padding: 1.125rem; }
  .danger-row { align-items: flex-start; }
  .callout { flex-direction: column; align-items: flex-start; gap: .875rem; }
  .callout form, .callout .btn { width: 100%; }
  .chart-body { justify-content: center; }
  .live-bar { left: 1rem; right: 1rem; transform: none; justify-content: center; }
}

.callout h3 .fetching-dot { display: inline-block; margin-right: .4375rem; }

/* ==================================================== metas de alocação */
.verdict {
  display: inline-block; margin-top: .3125rem;
  padding: .0625rem .4375rem; border-radius: 999px;
  font-family: var(--sans); font-size: .6875rem; font-weight: 500;
  border: 1px solid transparent; white-space: nowrap;
}
.verdict-buy    { background: var(--pine-wash); color: var(--pine-deep); border-color: #cfdfd9; }
.verdict-reduce { background: #f6ece9; color: var(--down); border-color: #e5c9c3; }
.verdict-hold   { background: var(--sunken); color: var(--ink-soft); border-color: var(--rule-strong); }
.verdict-none   { background: transparent; color: var(--ink-faint); border-color: var(--rule); }

.verdict-panel {
  background: var(--raised); border: 1px solid var(--rule);
  border-left: 3px solid var(--pine); border-radius: var(--r-md);
  padding: 1.25rem 1.375rem; margin-bottom: 1.5rem;
}
.verdict-panel.is-aligned { border-left-color: var(--rule-strong); }
.verdict-panel h2 { font-size: 1.0625rem; margin-bottom: .1875rem; }
.verdict-panel > p { font-size: .875rem; }

.buy-list { list-style: none; margin: 1rem 0 .75rem; padding: 0; display: grid; gap: .5rem; }
.buy-list li {
  display: grid; grid-template-columns: minmax(6rem, auto) 1fr auto;
  align-items: baseline; gap: .75rem;
  padding-bottom: .5rem; border-bottom: 1px solid var(--rule);
}
.buy-list li:last-child { border-bottom: 0; padding-bottom: 0; }
.buy-name { font-family: var(--serif); font-size: 1rem; font-weight: 600; }
.buy-gap { font-size: .8125rem; color: var(--ink-soft); }
.buy-amount { font-size: 1.0625rem; }

.tree-label { display: block; }
/* A árvore da calculadora tem um nível a mais que a de metas, por causa do
   desdobramento do ETF. Faltando uma classe, a linha volta para a margem e
   parece estar no topo da hierarquia. */
.indent-0 { padding-left: 0; }
.indent-1 { padding-left: 1.25rem; }
.indent-2 { padding-left: 2.5rem; }
.indent-3 { padding-left: 3.75rem; }
.indent-4 { padding-left: 5rem; }

.target-row.level-1 td { background: var(--sunken); }
.target-row.level-1 .tree-label { font-family: var(--serif); font-weight: 600; }
.target-row.level-3 .tree-label,
.target-row.level-4 .tree-label { color: var(--ink-soft); }

/* Um fio ligando a linha ao grupo que a contém, para a profundidade ficar
   legível mesmo quando o recuo é pequeno. */
.tree-label[class*="indent-"]:not(.indent-0) { position: relative; }
.indent-1::before, .indent-2::before,
.indent-3::before, .indent-4::before {
  content: ""; position: absolute; top: -.4rem; bottom: -.4rem;
  border-left: 1px solid var(--rule);
}
.indent-1::before { left: .375rem; }
.indent-2::before { left: 1.625rem; }
.indent-3::before { left: 2.875rem; }
.indent-4::before { left: 4.125rem; }

.weight-input {
  font: inherit; font-size: .875rem; width: 5.5rem; text-align: right;
  padding: .3125rem .5rem; border: 1px solid var(--rule-strong);
  border-radius: var(--r-sm); background: var(--raised); color: var(--ink);
}
.weight-input:focus { border-color: var(--pine); }

@media (max-width: 52rem) {
  .indent-1, .indent-2, .indent-3, .indent-4 { padding-left: 0; }
  .indent-1::before, .indent-2::before,
  .indent-3::before, .indent-4::before { display: none; }
  .target-row.level-2 td:first-child::after { content: " · tipo"; color: var(--ink-faint); font-size: .75rem; }
  .target-row.level-3 td:first-child::after { content: " · papel"; color: var(--ink-faint); font-size: .75rem; }
  .target-row.level-4 td:first-child::after { content: " · papel"; color: var(--ink-faint); font-size: .75rem; }
  .weight-input { width: 6.5rem; }
  .buy-list li { grid-template-columns: 1fr auto; }
  .buy-gap { grid-column: 1 / -1; }
}

/* ------------------------------------------ legenda da escala de desvio */
.color-key {
  display: flex; align-items: center; gap: .75rem 1.25rem; flex-wrap: wrap;
  background: var(--raised); border: 1px solid var(--rule);
  border-radius: var(--r-md); padding: .75rem 1rem; margin-bottom: 1.25rem;
  font-size: .8125rem; color: var(--ink-soft);
}
.color-key ul {
  display: flex; gap: 1rem; flex-wrap: wrap;
  list-style: none; margin: 0; padding: 0;
}
.color-key li { display: inline-flex; align-items: center; gap: .375rem; }
.key-dot { width: .75rem; height: .75rem; border-radius: 2px; flex: none; }
.key-below { background: rgb(27, 107, 74); }
.key-on    { background: rgb(201, 162, 39); }
.key-above { background: rgb(163, 53, 40); }

.legend-target {
  display: block; font-size: .6875rem; color: var(--ink-faint);
}

/* =========================================================================
   Modo privado: o olho do cabeçalho borra os valores.
   Só números e dinheiro entram no borrão — rótulos, papéis e navegação
   continuam legíveis, senão a tela vira uma mancha e perde a utilidade.
   ========================================================================= */
.icon-btn {
  display: grid; place-items: center; width: 2rem; height: 2rem;
  padding: 0; border: 1px solid var(--rule); border-radius: 50%;
  background: var(--raised); color: var(--ink-soft); cursor: pointer;
}
.icon-btn:hover { color: var(--ink); background: var(--sunken); }
.icon-btn svg { width: 1.0625rem; height: 1.0625rem; }
.icon-btn .eye-closed { display: none; }
body.is-private .icon-btn { color: var(--pine-deep); border-color: #cfdfd9; background: var(--pine-wash); }
body.is-private .icon-btn .eye-open { display: none; }
body.is-private .icon-btn .eye-closed { display: block; }

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

body.is-private .balance-figure,
body.is-private .balance-usd,
body.is-private .balance-note .num,
body.is-private .ledger-cell dd,
body.is-private .allocation-value,
body.is-private .track,
body.is-private td.numeric,
body.is-private tfoot td,
body.is-private .legend-share,
body.is-private .legend-target,
body.is-private .buy-amount,
body.is-private .buy-gap,
body.is-private .verdict-panel h2,
body.is-private .chart-body svg text,
body.is-private .statement-head p .num,
body.is-private [data-private] {
  /* Apagar o texto e pintar só a sombra dele.
     Borrar mantém os contornos dos algarismos: de perto, ou num navegador que
     desenha a máscara com menos força, dá para ler o número por baixo. Com a
     cor transparente não há contorno nenhum — o que aparece é a sombra
     espalhada, e ela não se remonta.
     O borrão continua por cima, agora só para desmanchar o que sobrou. */
  color: transparent !important;
  text-shadow: 0 0 .55em var(--ink-soft, #5b6b66);
  filter: blur(.35em);
  transition: filter .12s ease;
  user-select: none;
  pointer-events: none;
}

/* Fatia de rosca fica cinza: a proporção some junto com o número. */
body.is-private .chart-body svg path,
body.is-private .chart-body svg rect,
body.is-private .swatch,
body.is-private .key-dot {
  filter: grayscale(1) opacity(.35);
}

@media (prefers-reduced-motion: reduce) {
  body.is-private [data-private] { transition: none; }
}

@media print {
  body.is-private * { filter: none !important; }
}

/* ------------------------------------------------ navegação pela análise */
.crumbs {
  display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
  margin-bottom: 1.25rem; font-size: .875rem;
}
.crumb {
  display: inline-flex; flex-direction: column; line-height: 1.2;
  padding: .3125rem .625rem; border-radius: var(--r-sm);
  border: 1px solid var(--rule); background: var(--raised);
  color: var(--ink); text-decoration: none;
}
.crumb small { font-size: .6875rem; color: var(--ink-faint); }
.crumb:hover { background: var(--sunken); color: var(--ink); }
.crumb.is-current { background: var(--pine-wash); border-color: #cfdfd9; color: var(--pine-deep); }
.crumb.is-current small { color: #6d8d83; }
.crumb-sep { color: var(--ink-faint); }

.drill-hint { font-size: .8125rem; color: var(--ink-faint); margin-bottom: 1rem; }

.slice-link { cursor: pointer; }
.slice-link:hover path { opacity: .82; }
.legend-item.is-link { text-decoration: none; color: inherit; cursor: pointer; }
.legend-item.is-link:hover .legend-name { color: var(--ink); text-decoration: underline; }
a.ticker { color: var(--ink); text-decoration: none; }
a.ticker:hover { color: var(--pine); text-decoration: underline; }

/* ------------------------------------------------- calculadora de aporte */
#calculator-table .check { align-items: center; gap: .5rem; }
#calculator-table .check label { cursor: pointer; }
#calculator-table .check .sub { display: inline; margin-left: .375rem; }
#calculator-table input[type="checkbox"] { margin-top: 0; }

/* Espaçador entre o aviso e a árvore da calculadora */
.section-head-spacer { height: .25rem; }

/* Botão em trabalho, enquanto a requisição vai à rede */
.btn-spinner {
  width: .8125rem; height: .8125rem; flex: none; margin-right: .4375rem;
  border: 2px solid rgba(255, 255, 255, .35);
  border-top-color: #fff; border-radius: 50%;
  animation: live-spin .7s linear infinite;
}
.btn:disabled { opacity: .85; cursor: progress; }
@media (prefers-reduced-motion: reduce) {
  .btn-spinner { animation: none; border-top-color: rgba(255, 255, 255, .9); }
}

/* Percentual clicável: alterna entre porcentagem e valor */
.legend-share {
  font-family: var(--serif); color: var(--ink);
  background: none; border: 0; padding: 0; margin: 0;
  font-size: .8125rem; cursor: pointer; white-space: nowrap;
  border-bottom: 1px dashed var(--rule-strong);
}
.legend-share:hover { border-bottom-color: var(--ink-soft); }
.legend-name.is-link { cursor: pointer; }
.legend-name.is-link:hover { color: var(--ink); text-decoration: underline; }
.legend[data-unit="abs"] .legend-share { font-size: .78125rem; }

/* O botão de alternância guarda os dois percentuais; só o rótulo navega. */
.legend-share {
  display: flex; flex-direction: column; align-items: flex-end; gap: .0625rem;
  text-align: right;
}
.legend-now { font-family: var(--serif); }
.legend-item .legend-target { display: block; }

/* -------------------------------- composição: ETF aberto em subcategorias */
.allocation-row[data-level="1"] { padding-left: 1rem; }
.allocation-row[data-level="2"] { padding-left: 2rem; }
.allocation-row[data-level="1"] .allocation-top strong,
.allocation-row[data-level="2"] .allocation-top strong {
  font-weight: 400; color: var(--ink-soft);
}
.allocation-row[data-level="1"] .allocation-value,
.allocation-row[data-level="2"] .allocation-value { font-size: .9375rem; }
.allocation-row[data-level="1"] .track,
.allocation-row[data-level="2"] .track { height: .3125rem; }

/* Um fio vertical liga o filho ao tipo que o contém. */
.allocation-row[data-level="1"],
.allocation-row[data-level="2"] { position: relative; }
.allocation-row[data-level="1"]::before,
.allocation-row[data-level="2"]::before {
  content: ""; position: absolute; left: .375rem; top: 0; bottom: 0;
  border-left: 1px solid var(--rule);
}
.allocation-row[data-level="2"]::before { left: 1.375rem; }

.of-parent { color: var(--ink-faint); font-family: var(--sans); font-size: .75rem; }

/* Tipo que se subdivide vira um botão de abrir e fechar */
.allocation-toggle {
  display: inline-flex; align-items: center; gap: .4375rem;
  background: none; border: 0; padding: 0; margin: 0;
  font: inherit; color: inherit; cursor: pointer; text-align: left;
}
.allocation-toggle .chevron {
  width: .4375rem; height: .4375rem; flex: none;
  border-right: 1.5px solid var(--ink-faint);
  border-bottom: 1.5px solid var(--ink-faint);
  transform: rotate(-45deg); transition: transform .18s ease;
}
.allocation-toggle[aria-expanded="true"] .chevron { transform: rotate(45deg); }
.allocation-toggle:hover .chevron { border-color: var(--ink); }

/* Resumo abaixo da curva de liquidez */
.liquidity-note {
  margin-top: .75rem; font-size: .875rem; color: var(--ink-soft);
}
.liquidity-note .num { font-family: var(--serif); color: var(--ink); }

/* ---------------------------------------- categorias na listagem de ativos */
.group-row td {
  background: var(--sunken); border-bottom: 1px solid var(--rule-strong);
  padding-top: .625rem; padding-bottom: .625rem;
}
.group-name {
  font-family: var(--serif); font-size: 1rem; font-weight: 600; letter-spacing: -.005em;
}
.rate-avg { white-space: nowrap; }
.group-row .sub { display: inline; margin-left: .5rem; }
.group-row.level-1 .group-name { font-size: .9375rem; font-weight: 500; color: var(--ink-soft); }
.group-row.level-1 td { background: var(--raised); }
.group-body + .group-body .group-row td { border-top: 1px solid var(--rule); }

@media (max-width: 52rem) {
  .table-wrap tbody.group-body { display: block; }
  .table-wrap .group-row {
    background: none; border: 0; border-radius: 0;
    padding: 1rem 0 .375rem; margin: 0;
  }
  .table-wrap .group-row td { background: none; border-bottom: 0; padding: 0; }
  .table-wrap .group-row td:first-child { border-bottom: 1px solid var(--rule-strong); }
  .table-wrap .group-row td[data-label] { display: flex; padding: .25rem 0; }
  .table-wrap .group-row td:empty { display: none; }

  /* Pai aberto cede a vez aos filhos, aqui também — mas somem de vez.
     No computador as células ficam invisíveis e continuam ocupando o lugar,
     para as colunas não mudarem de largura a cada clique. Empilhada, cada
     célula é uma linha inteira: guardar o espaço vira um vão em branco do
     tamanho do grupo. Não há coluna nenhuma para preservar aqui. */
  .table-wrap .group-row:has(.group-toggle[aria-expanded="true"]) > td.numeric {
    display: none;
  }
}

/* ------------------------------ categoria expansível na listagem de ativos */
.group-toggle {
  display: inline-flex; align-items: baseline; gap: .5rem;
  background: none; border: 0; padding: 0; margin: 0;
  font: inherit; color: inherit; cursor: pointer; text-align: left;
}
.group-toggle .chevron {
  width: .4375rem; height: .4375rem; flex: none; align-self: center;
  border-right: 1.5px solid var(--ink-faint);
  border-bottom: 1.5px solid var(--ink-faint);
  transform: rotate(45deg); transition: transform .18s ease;
}
.group-toggle[aria-expanded="false"] .chevron { transform: rotate(-45deg); }
.group-toggle:hover .chevron { border-color: var(--ink); }

/* Os papéis de uma subcategoria ficam recuados em relação a ela, e um fio
   vertical marca a que grupo pertencem. */
/* A hierarquia é marcada por margem num elemento interno, nunca pelo padding
   da célula: padding é ajustado por outras regras — a compactação em telas
   médias, por exemplo — e como aquelas usam seletor de ID, venciam estas e a
   indentação sumia sem deixar rastro.

   A escada é de um degrau por nível, uniforme: um papel dentro de "Ação" fica
   no mesmo recuo de "ETF Internacional" dentro de "ETF", porque estão na mesma
   profundidade da árvore. */
.group-body .position-row td:first-child .disclosure { margin-left: 1.25rem; }
.group-body[data-level="1"] .group-row .group-toggle { margin-left: 1.25rem; }
.group-body[data-level="1"] .position-row td:first-child .disclosure {
  margin-left: 2.5rem;
}

.group-body .position-row td:first-child .disclosure,
.group-body[data-level="1"] .group-row .group-toggle { position: relative; }
.group-body .position-row td:first-child .disclosure::before,
.group-body[data-level="1"] .group-row .group-toggle::before {
  content: ""; position: absolute; left: -.75rem; top: -.5rem; bottom: -.5rem;
  border-left: 1px solid var(--rule);
}
.entries-row > td { padding-left: 1.25rem; }
.group-body[data-level="1"] .entries-row > td { padding-left: 2.5rem; }

@media (max-width: 52rem) {
  /* Em ficha, a linha já é um bloco separado: o recuo só rouba largura. */
  .group-body .position-row td:first-child .disclosure,
  .group-body[data-level="1"] .group-row .group-toggle,
  .group-body[data-level="1"] .position-row td:first-child .disclosure {
    margin-left: 0;
  }
  .group-body .position-row td:first-child .disclosure::before,
  .group-body[data-level="1"] .group-row .group-toggle::before { display: none; }
  .entries-row > td,
  .group-body[data-level="1"] .entries-row > td { padding-left: 0; }
}

/* ------------------------------------------------- filtro pelo cabeçalho */
thead th[data-filter] { position: relative; padding-right: 2rem; }

.filter-toggle {
  position: absolute; right: .4375rem; top: 50%; transform: translateY(-50%);
  display: grid; place-items: center; width: 1.125rem; height: 1.125rem;
  padding: 0; border: 0; border-radius: 3px;
  background: none; color: var(--ink-faint); cursor: pointer;
}
.filter-toggle svg { width: .6875rem; height: .6875rem; }
.filter-toggle:hover { color: var(--ink); background: var(--sunken); }
.filter-toggle.is-active { color: var(--pine); background: var(--pine-wash); }

.filter-panel {
  position: absolute; z-index: 30; right: 0; top: calc(100% + .25rem);
  min-width: 11rem; max-width: 20rem; max-height: 17rem; overflow-y: auto;
  display: grid; gap: 1px; padding: .25rem;
  background: var(--raised); border: 1px solid var(--rule-strong);
  border-radius: var(--r-md); box-shadow: 0 6px 20px rgba(20, 24, 28, .12);
}
.filter-option {
  text-align: left; font: inherit; font-weight: 400; font-size: .8125rem;
  padding: .375rem .5rem; border: 0; border-radius: var(--r-sm);
  background: none; color: var(--ink); cursor: pointer;
  white-space: normal; overflow-wrap: anywhere;
}
.filter-option:hover { background: var(--sunken); }
.filter-option.is-on { background: var(--pine-wash); color: var(--pine-deep); font-weight: 600; }
.filter-option.is-on::after { content: " ✓"; }

.filter-chips {
  display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
  margin-bottom: .75rem; font-size: .8125rem;
}
.filter-chip {
  font: inherit; padding: .1875rem .5rem; cursor: pointer;
  border: 1px solid #cfdfd9; border-radius: 999px;
  background: var(--pine-wash); color: var(--pine-deep);
}
.filter-chip:hover { background: #dfeae6; }
.filter-count { color: var(--ink-faint); }
.filter-clear {
  font: inherit; background: none; border: 0; padding: 0; cursor: pointer;
  color: var(--ink-soft); text-decoration: underline;
}
.filter-clear:hover { color: var(--ink); }

/* Valor bruto alternável entre real e dólar */
.currency-swap {
  font: inherit; font-family: var(--serif); color: var(--ink);
  background: none; border: 0; padding: 0; cursor: pointer;
  border-bottom: 1px dashed var(--rule-strong);
}
.currency-swap:hover { border-bottom-color: var(--ink-soft); }

/* Barra de ferramentas acima da tabela de ativos */
.table-tools {
  display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;
  margin-bottom: .75rem;
}
.table-tools .filter-chips { margin-bottom: 0; }


/* A coluna do papel não pode empurrar a tabela sozinha: o subtítulo quebra
   linha em vez de esticar tudo. */
#positions-table > tbody > tr:not(.entries-row) > td:first-child { max-width: 17rem; }
#positions-table > tbody > tr > td:first-child .sub { white-space: normal; }

/* Onze colunas em tela de notebook: com o respiro padrão a tabela transborda
   por poucos pixels e passa a rolar por nada. Abaixo de ~100rem ela se aperta
   um pouco; sobrando espaço, volta ao respiro normal. */
@media (min-width: 52rem) and (max-width: 100rem) {
  /* Só as colunas seguintes se apertam. Mexer no padding da primeira apagaria
     a indentação, porque este seletor tem ID e vence o dela. */
  #positions-table th,
  #positions-table td + td { padding-left: .5rem; padding-right: .5rem; }
  #positions-table > tbody > tr:not(.entries-row) > td:first-child {
    padding-right: .5rem; max-width: 15rem;
  }
  #positions-table thead th[data-filter] { padding-right: 1.625rem; }
}

/* Valor e botão lado a lado na calculadora */
.calc-row {
  display: flex; align-items: flex-end; gap: .75rem; flex-wrap: wrap;
}
.calc-row .field { flex: 1 1 14rem; margin: 0; }
.calc-row .btn { flex: none; }
.calc-error {
  margin-top: .625rem; padding: .5rem .75rem;
  background: #fdf3f1; border: 1px solid #e6c4bd; border-radius: var(--r-sm);
}

/* Linha que já é a compra: sem seta, mas alinhada com quem tem. */
.leaf-name {
  display: inline-flex; flex-direction: column; gap: .125rem;
  padding-left: 1.1875rem;
}
.group-body .position-row td:first-child .leaf-name { margin-left: 1.25rem; }
.group-body[data-level="1"] .position-row td:first-child .leaf-name { margin-left: 2.5rem; }
.group-body .position-row td:first-child .leaf-name,
.group-body[data-level="1"] .position-row td:first-child .leaf-name {
  position: relative;
}
.group-body .position-row td:first-child .leaf-name::before,
.group-body[data-level="1"] .position-row td:first-child .leaf-name::before {
  content: ""; position: absolute; left: -.75rem; top: -.5rem; bottom: -.5rem;
  border-left: 1px solid var(--rule);
}
@media (max-width: 52rem) {
  .group-body .position-row td:first-child .leaf-name,
  .group-body[data-level="1"] .position-row td:first-child .leaf-name {
    margin-left: 0; padding-left: 0;
  }
  .group-body .position-row td:first-child .leaf-name::before { display: none; }
}

/* ------------------------------------------------ ações destrutivas */
.danger-zone { display: grid; gap: 1px; background: var(--rule); border-radius: var(--r-sm); overflow: hidden; }
.danger-zone form { background: var(--raised); }
.danger-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1.5rem; padding: 1rem 1.125rem; flex-wrap: wrap;
}
.danger-row .help { margin: .25rem 0 0; max-width: 42rem; }
.btn-danger {
  border-color: #d9b3ac; color: var(--down); background: #fdf6f4; flex: none;
}
.btn-danger:hover:not([disabled]) { background: #f8e7e2; border-color: #c99387; }
.btn-danger[disabled] { opacity: .5; cursor: not-allowed; }

/* Taxa acordada, sob o preço unitário do Tesouro */
.rate-hint { color: var(--pine-deep); font-weight: 600; }
.rate-hint.is-pending { color: var(--ink-faint); font-weight: 400; }

/* Papel recém-cadastrado: some sozinho, sem pedir clique. */
.position-row.is-new td { background: var(--pine-wash); }
@media (prefers-reduced-motion: no-preference) {
  .position-row.is-new td { animation: chegou 2.4s ease-out forwards; }
  @keyframes chegou {
    0%, 55% { background: var(--pine-wash); }
    100% { background: transparent; }
  }
}


/* ------------------------------------------- ações de cada compra */
/* A célula precisa criar contexto de empilhamento enquanto o menu está
   aberto: sem isso, a linha do papel seguinte — que vem depois no documento —
   pinta por cima do painel e rouba os cliques. */
.entry-cell { width: 2.25rem; position: relative; }
.entry-actions { position: relative; }
.entry-actions .menu[open] { position: relative; z-index: 60; }
.entry-actions .menu-panel { z-index: 60; }

/* Menu dentro da própria linha do papel, quando ela já é a compra. */
.entry-actions.is-inline {
  display: inline-block; vertical-align: middle; margin-left: .375rem;
}
.entry-actions.is-inline > summary { width: 1.375rem; height: 1.375rem; }
.entry-actions.is-inline .pencil { width: .8125rem; height: .8125rem; }


/* A coluna do papel gruda ao rolar e carrega um z-index próprio: sem levantá-la
   enquanto o menu está aberto, o painel fica preso sob as linhas seguintes. */
#positions-table > tbody > tr > td:first-child:has(details[open]) { z-index: 60; }
.entry-actions .menu > summary {
  display: grid; place-items: center; width: 1.75rem; height: 1.75rem;
  border-radius: var(--r-sm); cursor: pointer; list-style: none;
  color: var(--ink-faint);
}
.entry-actions .menu > summary::-webkit-details-marker { display: none; }
.entry-actions .menu > summary:hover { background: var(--sunken); color: var(--ink); }
.entry-actions .menu[open] > summary { background: var(--sunken); color: var(--ink); }
.entry-actions .pencil { width: .875rem; height: .875rem; }
/* O painel sai do fluxo da tabela.
   `.table-wrap` tem `overflow-x: auto` para rolar na horizontal, e isso faz o
   navegador cortar também na vertical — o menu abria e ficava decepado na
   borda de baixo. Posição fixa escapa desse corte; as coordenadas vêm do
   JavaScript, que mede o botão na hora de abrir. */
.entry-actions .menu-panel {
  position: fixed; left: auto; right: auto; top: auto;
  min-width: 15rem;
  /* Sem recorte aqui: são três itens, nunca fica alto, e `overflow` cortaria
     o submenu que sai pela lateral — o navegador nem entrega o clique nele. */
  overflow: visible;
}

/* Escolha da data do resgate, dentro do menu. */
.menu-form { padding: .375rem .6875rem .5rem; }
.menu-form label {
  display: block; font-family: var(--sans); font-size: .75rem;
  font-weight: 400; color: var(--ink-soft); margin-bottom: .1875rem;
}
.menu-form input[type="date"] {
  width: 100%; font-family: var(--sans); font-size: .8125rem;
  padding: .3125rem .375rem; margin-bottom: .375rem;
  border: 1px solid var(--rule-strong); border-radius: var(--r-sm);
  background: var(--raised); color: var(--ink);
}
.menu-form button { padding-left: 0; padding-right: 0; }
.entry-actions .menu-panel form { margin: 0; }
.entry-actions .menu-panel button,
.entry-actions .menu-panel a {
  display: block; width: 100%; text-align: left;
  /* Tipografia própria: embutido no título, o menu herdaria a serifa em
     negrito do nome do papel. */
  font-family: var(--sans); font-size: .875rem; font-weight: 400;
  line-height: 1.4; letter-spacing: 0;
  padding: .5rem .6875rem; border: 0; border-radius: var(--r-sm);
  background: none; color: var(--ink); cursor: pointer; text-decoration: none;
}
.entry-actions .menu-panel button:hover,
.entry-actions .menu-panel a:hover { background: var(--sunken); }
.entry-actions .menu-panel .is-danger { color: var(--down); }
.entry-actions .menu-panel .is-danger:hover { background: #fdf3f1; }

/* ------------------------------------------------- saldo disponível */
.cash-menu { display: inline-block; vertical-align: middle; margin-left: .3125rem; }
.cash-menu > summary {
  display: grid; place-items: center; width: 1.375rem; height: 1.375rem;
  border-radius: var(--r-sm); cursor: pointer; list-style: none;
  color: var(--ink-faint);
}
.cash-menu > summary::-webkit-details-marker { display: none; }
.cash-menu > summary:hover, .cash-menu[open] > summary {
  background: var(--sunken); color: var(--ink);
}
.cash-menu .coins { width: .9375rem; height: .9375rem; }
.cash-menu .menu-panel { left: 0; right: auto; min-width: 10rem; top: calc(100% + .25rem); }
.cash-menu .menu-panel a {
  font-family: var(--sans); font-size: .875rem; font-weight: 400;
}

.pill-resgate { border-color: #b7cfc5; color: var(--pine-deep); }
.pill-saque { border-color: #d9b3ac; color: var(--down); }
.pill-aplicacao { border-color: var(--rule-strong); color: var(--ink-soft); }

/* ------------------------------------------------ formulário em coluna
   Um campo abaixo do outro. Preencher de cima para baixo é uma linha reta;
   em duas colunas o olho tem de decidir a cada passo para onde ir, e o campo
   que aparece ou some conforme o tipo faz os vizinhos pularem de lugar. */
.form-stacked { max-width: 34rem; }
.form-stacked .grid { grid-template-columns: 1fr; gap: 1.125rem; }
/* Blocos que aparecem e somem conforme o tipo: sem respiro entre eles, a caixa
   de seleção fica colada no texto de ajuda do campo anterior. */
.form-stacked .grid + .grid { margin-top: 1.125rem; }
.form-stacked .check { margin-top: .125rem; }
.form-stacked .field,
.form-stacked .field .help,
.form-stacked .field .error { max-width: 30rem; }
.form-stacked .field input[type="text"],
.form-stacked .field input[type="number"],
.form-stacked .field input[type="date"],
.form-stacked .field select,
.form-stacked .field textarea { max-width: 30rem; }

.shell-full { width: 100%; max-width: 100%; padding-inline: 1.5rem; }

/* Bruto de um título do Tesouro: leva ao extrato de resgate. */
.gross-link {
  color: inherit; text-decoration: none;
  border-bottom: 1px dashed var(--rule-strong);
}
.gross-link:hover { color: var(--pine-deep); border-bottom-color: var(--pine-deep); }

/* ------------------------------------------ extrato do Tesouro Direto */
.td-extrato { font-size: .75rem; table-layout: auto; }
.td-extrato th, .td-extrato td { padding-left: .5rem; padding-right: .5rem; }
.td-extrato .td-faixa th {
  background: var(--sunken); text-align: center; font-weight: 600;
  letter-spacing: .04em; text-transform: uppercase; font-size: .6875rem;
}
.td-extrato thead th { vertical-align: bottom; line-height: 1.25; }
.td-extrato thead th .sub { display: block; font-weight: 400; }
.td-extrato tbody td { padding-top: .875rem; padding-bottom: .875rem; }

.formulas { display: grid; gap: .875rem; margin: 0; }
.formulas dt {
  font-size: .8125rem; color: var(--ink-soft); text-transform: uppercase;
  letter-spacing: .04em;
}
.formulas dd { margin: .1875rem 0 0; font-variant-numeric: tabular-nums; }
.formulas dd .sub { display: block; margin-top: .1875rem; }

/* ------------------------------------------------ consolidado mensal */
.monthly { font-size: .8125rem; }
.monthly th[scope="row"] {
  text-align: left; white-space: nowrap; font-weight: 500;
  color: var(--ink-soft); position: sticky; left: 0; background: var(--raised);
  z-index: 2; padding-right: 1rem;
}
.monthly thead th { white-space: nowrap; }
.monthly thead th:first-child {
  position: sticky; left: 0; background: var(--raised); z-index: 3;
}
.monthly thead th .sub { display: block; font-weight: 400; }
.monthly .is-partial { color: var(--ink-faint); }
.monthly td { font-variant-numeric: tabular-nums; white-space: nowrap; }

.filters-inline { display: flex; align-items: flex-end; gap: .75rem; margin-bottom: 1rem; }
.filters-inline .field { margin: 0; }

.chart-legend {
  display: flex; align-items: center; gap: .375rem; flex-wrap: wrap;
  font-size: .8125rem; color: var(--ink-soft); margin: .5rem 0 0;
}
.chart-legend .key-dot { margin-left: .75rem; }
.chart-legend .key-dot:first-child { margin-left: 0; }
.key-gross { background: var(--pine-deep); }
.key-invested { background: #9aa0a6; }

/* Incremento diário. A cor diz a modalidade e a posição em relação à linha do
   zero diz se rendeu ou perdeu — dois encodings que não se atrapalham porque
   respondem a perguntas diferentes.

   O vermelho de perda ficou de fora da dupla: ele significa prejuízo em toda a
   aplicação, e uma faixa de renda variável subindo naquele vermelho brigaria
   com o que a posição está dizendo. O par escolhido separa bem — ΔE 16 em
   daltonismo, 21 em visão normal —, e os dois já vivem na paleta das roscas. */
.key-rf { background: var(--pine); }
.key-rv { background: #7a4fa3; }
/* A terceira faixa, só para quem tem papel lá fora. O âmbar foi escolhido por
   eliminação: ele é a única região de cor que fica longe das duas primeiras e
   longe do vermelho de prejuízo ao mesmo tempo — ΔE 21 do vermelho, e no trio
   ele nunca é o par mais apertado (o mais apertado continua sendo verde contra
   violeta, que já era). */
.key-cx { background: #c08a1e; }
.legenda-lado { color: var(--ink-faint); font-size: .8125rem; }
/* A frase ficou com sete valores e quebra em duas linhas em tela cheia. O que
   não pode quebrar é um valor pelo meio: "R$" no fim de uma linha e "-395,61"
   no começo da outra se lê como dois números. */
.incremento-resumo {
  margin-top: .5rem; font-size: .875rem; color: var(--ink-soft);
}
.incremento-resumo .num { white-space: nowrap; }
.incremento-resumo .linha { display: block; }
.incremento-resumo .linha + .linha { margin-top: .125rem; }
/* Azul para o que subiu, vermelho para o que caiu — aqui, e só aqui, porque
   é a frase que fala em "no azul" e "no vermelho". No resto da aplicação alta
   é verde, e `.up` continua verde em toda parte. */
.incremento-resumo .sinal-up { color: var(--blue); }
.incremento-resumo .sinal-down { color: var(--down); }

/* ------------------------------- escala de desvio na árvore de metas
   Verde onde o dinheiro deve ir, vermelho onde não deve, mais forte quanto
   maior a distância do alvo. A cor é de fundo e fica fraca de propósito: ela
   ordena o olhar, não substitui o número ao lado. */
.target-row.tint-buy-1 > td { background: rgba(30, 75, 68, .045); }
.target-row.tint-buy-2 > td { background: rgba(30, 75, 68, .095); }
.target-row.tint-buy-3 > td { background: rgba(30, 75, 68, .155); }
.target-row.tint-buy-4 > td { background: rgba(30, 75, 68, .225); }
.target-row.tint-buy-5 > td { background: rgba(30, 75, 68, .305); }

.target-row.tint-avoid-1 > td { background: rgba(163, 53, 40, .045); }
.target-row.tint-avoid-2 > td { background: rgba(163, 53, 40, .095); }
.target-row.tint-avoid-3 > td { background: rgba(163, 53, 40, .155); }
.target-row.tint-avoid-4 > td { background: rgba(163, 53, 40, .225); }
.target-row.tint-avoid-5 > td { background: rgba(163, 53, 40, .305); }

/* O número do desvio acompanha a linha: verde onde comprar, vermelho onde não. */
.target-row[class*="tint-buy"] .drift-cell { color: var(--pine-deep); }
.target-row[class*="tint-avoid"] .drift-cell { color: var(--down); }
.drift-cell .sub { color: inherit; opacity: .75; }

/* O campo de peso precisa continuar legível sobre o fundo tingido. */
.target-row[class*="tint-"] input { background: var(--raised); }

/* Folha da árvore de metas: reserva o espaço da seta que ela não tem. */
.disclosure-gap { display: inline-block; width: 1.125rem; flex: 0 0 auto; }

/* -------------------------------------------- barra de salvar que acompanha
   Gruda no fim da janela enquanto o formulário está à vista e volta ao fluxo
   quando ele acaba. Sem isso, ajustar o primeiro peso de uma árvore longa
   obrigaria a rolar tudo de volta para salvar. */
.save-bar {
  position: sticky; bottom: 0; z-index: 30;
  display: flex; align-items: center; justify-content: flex-end; gap: 1rem;
  flex-wrap: wrap;
  margin-top: 1.25rem; padding: .875rem 1.125rem;
  background: var(--raised);
  border: 1px solid var(--rule); border-radius: var(--r-md);
  box-shadow: 0 -8px 20px -16px rgba(20, 24, 28, .5);
}
.save-bar .faint { margin-right: auto; }

@media (max-width: 40rem) {
  .save-bar { padding: .75rem .875rem; }
  .save-bar .btn { width: 100%; }
}

/* ---------------------------------------- seta e aviso na árvore de metas */
/* A seta precisava girar: sem isso, aberto e fechado tinham o mesmo desenho. */
.target-row .disclosure[aria-expanded="true"] .chevron { transform: rotate(45deg); }

/* Quantos filhos ficaram escondidos. Um pai com um filho à mostra e outro
   oculto parece completo; este é o único sinal de que há mais lá dentro. */
.branch-more {
  display: inline-block; margin-left: .5rem; padding: .0625rem .375rem;
  cursor: pointer;
  font-family: var(--sans); font-size: .6875rem; font-weight: 500;
  line-height: 1.5; letter-spacing: .01em; white-space: nowrap;
  color: var(--ink-soft); background: var(--sunken);
  border: 1px solid var(--rule); border-radius: 999px;
}
.target-row .disclosure:hover + .branch-more,
.branch-more:hover { color: var(--ink); border-color: var(--rule-strong); background: var(--raised); }
.branch-more:focus-visible { outline: 2px solid var(--pine-deep); outline-offset: 1px; }

/* Sinal de série furada, ao lado do líquido do papel. */
.data-gap {
  margin-left: .25rem; font-size: .8125rem; line-height: 1;
  color: var(--down); cursor: help;
}
.data-gap:focus-visible { outline: 2px solid var(--down); outline-offset: 2px; }

/* ------------------------------- pai aberto cede a vez aos filhos
   Enquanto o grupo está aberto, os totais dele saem da frente: os números que
   interessam passam a ser os das linhas de dentro, e dois conjuntos de valores
   na mesma coluna disputam a leitura. Fechando, os totais voltam.

   `visibility` em vez de `display`: o espaço continua reservado, e as colunas
   não mudam de largura a cada clique. */
.group-row:has(.group-toggle[aria-expanded="true"]) > td.numeric {
  visibility: hidden;
}

/* ------------------------------------- extrato do Tesouro, cores da fonte
   A tabela imita o extrato oficial: faixa magenta com o vencimento, faixa
   azul-marinho separando "dados do investimento" de "situação para resgate".
   Quem compara as duas telas lado a lado não deve precisar procurar onde uma
   coluna virou a outra. */
.td-extrato .td-vencimento th {
  background: #c4005c; color: #fff;
  font-size: .8125rem; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; text-align: center;
  padding: .75rem .5rem; border: 0;
}
.td-extrato .td-faixa th {
  background: #1f2a5e; color: #fff;
  font-size: .75rem; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; text-align: center;
  padding: .625rem .5rem; border: 0;
}
.td-extrato .td-faixa th + th { border-left: 2px solid #fff; }
.td-extrato thead tr:last-child th {
  font-size: .6875rem; font-weight: 600; letter-spacing: .02em;
  text-transform: uppercase; color: var(--ink-soft);
  vertical-align: bottom; border-bottom: 1px solid var(--rule-strong);
  /* Cabeçalho quebra em duas linhas em vez de esticar a coluna: com treze
     colunas, cada rótulo longo empurra a tabela para fora da tela e obriga a
     rolar para ver o líquido, que é o número que se procura. */
  /* Estreito de propósito: cada palavra numa linha. Com quinze colunas, o que
     custa caro é a largura, e altura de cabeçalho é espaço que a tabela paga
     uma vez só.

     A medida acompanha a palavra mais longa do cabeçalho ("RENTABILIDADE"):
     apertar mais que isso não estreita a coluna, apenas corta o texto. */
  white-space: normal; max-width: 6.75rem; overflow-wrap: break-word;
}
.td-extrato thead tr:last-child th .sub {
  display: block; font-weight: 400; text-transform: none; letter-spacing: 0;
}
.td-extrato tbody td { border-bottom: 1px solid var(--rule); }

/* Cores do gráfico do Tesouro: ciano no preço real, marinho no teórico. */
.key-real { background: #17b5c4; }
.key-teorico { background: #2b3a8c; }
.td-grafico { margin-bottom: 1.25rem; }
.td-grafico h3 { margin-bottom: .25rem; }

/* Versão do pacote, discreta no rodapé: serve para conferir qual build está
   no ar sem abrir o servidor. */
.footer-version { font-variant-numeric: tabular-nums; opacity: .65; }

/* Saldo incluindo o que ainda espera preço: discreto, logo abaixo do total. */
.balance-awaiting {
  margin-top: .125rem; font-size: .8125rem; color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

/* Papel comprado depois do último fechamento: espera preço, não perdeu dado. */
.awaiting-price {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1rem; height: 1rem; margin-left: .25rem;
  font-size: .625rem; font-weight: 700; line-height: 1;
  color: var(--ink-soft); background: var(--sunken);
  border: 1px solid var(--rule-strong); border-radius: 50%; cursor: help;
}
.awaiting-price:focus-visible { outline: 2px solid var(--pine-deep); outline-offset: 1px; }

/* Levar e trazer a carteira: mesmas linhas da zona de risco, sem a moldura de
   perigo — exportar e importar não destroem nada. */
.wallet-io { margin-top: 1rem; }
.wallet-io .danger-row { border-color: var(--rule); }
.wallet-io .danger-row + .danger-row { margin-top: .75rem; }

/* Quanto do saldo ainda espera preço: o número em destaque, o resto explica. */
.awaiting-amount { font-weight: 600; text-decoration: underline; }

/* ------------------------------------------- submenu do resgate e overlay */
.submenu { position: relative; }
/* Especificidade suficiente para vencer `.entry-actions .menu-panel button`,
   que declara `display: block`. Sem isso o `justify-content` fica escrito e sem
   efeito nenhum — a regra aparece no estilo computado e a seta continua colada
   no texto. */
.entry-actions .menu-panel .submenu-trigger {
  display: flex; align-items: center; justify-content: space-between; gap: .5rem;
  width: 100%;
}
/* Um caractere, não dois cantos de borda girados.
   A construção com `border-top` + `border-right` e `rotate(45deg)` vira um
   traço vertical em fontes e tamanhos que não colaboram — lia-se "Resgatar |",
   que não diz nada sobre haver mais coisa à direita. */
.submenu-arrow {
  flex: 0 0 auto; opacity: .55;
  font-size: 1rem; line-height: 1;
}
.submenu-arrow::before { content: "›"; }
.submenu-panel {
  /* Posição de tela, como o painel que o contém: assim nenhum recorte de
     ancestral o esconde, venha da tabela ou do próprio menu. As coordenadas
     são medidas na abertura. */
  display: none; position: fixed; left: auto; top: auto;
  min-width: 8rem; padding: .375rem;
  background: var(--raised); border: 1px solid var(--rule);
  border-radius: var(--r-md); box-shadow: 0 12px 28px -18px rgba(20, 24, 28, .45);
  z-index: 1;
}
.submenu.is-open .submenu-panel { display: block; }
.submenu.is-open > .submenu-trigger { background: var(--sunken); color: var(--ink); }
/* O lado para onde ele abre é decidido na hora, pelo espaço que sobra. */

.redeem-dialog {
  width: min(26rem, calc(100vw - 2rem)); padding: 1.25rem;
  border: 1px solid var(--rule); border-radius: var(--r-md);
  background: var(--raised); color: var(--ink);
}
.redeem-dialog::backdrop { background: rgba(20, 24, 28, .45); }
.redeem-dialog h2 { margin: 0 0 .25rem; font-size: 1.0625rem; }
.redeem-dialog > form > .help { margin: 0 0 1rem; }
.redeem-dialog .field { margin-bottom: .875rem; }
.redeem-dialog input[readonly] { background: var(--sunken); color: var(--ink-soft); }
.redeem-dialog .form-actions {
  display: flex; justify-content: flex-end; gap: .5rem; margin-top: 1.25rem;
}

/* A janela de confirmação, no lugar do diálogo do navegador.

   O texto dela é a pergunta inteira, não um rótulo: fica no tamanho do corpo
   e na cor da tinta normal, e não no cinza de legenda que o `.help` usa nos
   formulários — quem precisa ler antes de apagar algo não deve ler em cinza
   claro. Os botões herdam o `.form-actions` acima; o alvo mínimo de toque é
   declarado aqui porque esta é a janela que mais aparece no celular. */
.confirma-dialog [data-confirma-texto] {
  margin: 0; color: var(--ink); font-size: .9375rem; line-height: 1.5;
}
.confirma-dialog .form-actions button { min-height: 2.75rem; padding-inline: 1rem; }
/* O botão que confirma fica vermelho quando o que vem depois dele destrói
   algo, e verde quando a janela só está dando um recado. A cor é a mesma do
   prejuízo na tabela — é a cor que este aplicativo usa para "isto tira". */
.confirma-dialog .form-actions .is-danger {
  background: var(--down); border-color: var(--down); color: #fff;
}
.confirma-dialog .form-actions .is-danger:hover { background: #8c2d22; border-color: #8c2d22; }
@media (max-width: 30rem) {
  /* No celular os dois botões ocupam a largura e empilham, com o cancelar
     embaixo — onde o polegar descansa — e o destrutivo em cima, longe dele.
     Lado a lado, num alvo de 44px, o dedo que mira cancelar acerta confirmar. */
  .confirma-dialog .form-actions { flex-direction: column-reverse; }
  .confirma-dialog .form-actions button { width: 100%; }
}

/* Líquido ao pé do saldo: menor, para não disputar com o número grande. */
.balance-net {
  margin-top: .1875rem; font-size: .8125rem; color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}
.hint-mark {
  display: inline-flex; align-items: center; justify-content: center;
  width: .9375rem; height: .9375rem; margin-left: .25rem; padding: 0;
  font: 600 .625rem/1 var(--sans); color: var(--ink-soft);
  background: var(--sunken); border: 1px solid var(--rule-strong);
  border-radius: 50%; cursor: help; vertical-align: text-top;
}
.hint-mark:focus-visible { outline: 2px solid var(--pine-deep); outline-offset: 1px; }

/* Bruto em negrito: é o número que se procura primeiro ao correr a coluna,
   antes de descontar o imposto. Vale para a linha do papel, para o subtotal do
   grupo e para o botão que troca de moeda. */
#positions-table td[data-label="Bruto"],
#positions-table td[data-label="Bruto"] .currency-swap { font-weight: 600; }

/* Aviso de datas que não batem: mesmo formato da interrogação, cor de alerta,
   porque aqui não é curiosidade — é ressalva sobre o número ao lado. */
.hint-warn {
  color: var(--down); border-color: var(--down); background: transparent;
}

/* O alternador da composição é um botão, mas não deve parecer um: o que se vê
   é o número, e o cursor avisa que dá para clicar. */
.alloc-unit {
  background: none; border: 0; padding: 0; margin: 0;
  font: inherit; color: inherit; cursor: pointer;
  border-bottom: 1px dashed #c3cfca;
}
.alloc-unit:hover { border-bottom-color: var(--pine-deep, #1e4b44); }

/* Legenda em linha do gráfico da meta: três chaves de cor e três nomes. */
.chart-legend-inline {
  display: flex; flex-wrap: wrap; gap: 1rem; align-items: center;
  margin-top: .75rem; font-size: .8125rem; color: var(--ink-soft);
}
.chart-legend-inline .chave {
  display: inline-block; width: .65rem; height: .65rem; border-radius: 2px;
  margin-right: .375rem;
}
.chart-legend-inline .chave-total { background: #1e4b44; }
.chart-legend-inline .chave-aportado { background: #b8901f; }
.chart-legend-inline .chave-meta { background: #a33528; }
.chart-legend-inline .chave-meta-real { background: #7a4fa3; }
.meta-patrimonio + .meta-patrimonio { margin-top: 1.25rem; }
.meta-editar { margin-top: 1rem; }
.meta-editar summary { cursor: pointer; color: var(--pine-deep); font-size: .9375rem; }
.meta-apagar { margin-top: .75rem; }

/* Balão da dica, para quem não tem mouse.

   Posição absoluta na página, não no elemento: o ícone costuma morar dentro de
   um contêiner que recorta o que passa da borda, e o balão sairia decepado. */
.dica-balao {
  position: absolute; z-index: 60; max-width: min(19rem, calc(100vw - 2rem));
  padding: .5rem .625rem;
  font: 400 .8125rem/1.4 var(--sans); color: var(--ink);
  background: var(--raised, #fff); border: 1px solid var(--rule, #e2e8e5);
  border-radius: var(--r-md, 10px);
  box-shadow: 0 8px 24px rgba(20, 40, 35, .16);
}

/* Onde não há mouse, o ícone precisa parecer tocável e caber uma ponta de dedo.
   "cursor: help" não diz nada a quem usa o dedo, e quinze pixels de alvo fazem
   errar o toque. */
@media (hover: none) {
  .hint-mark {
    width: 1.375rem; height: 1.375rem; font-size: .75rem;
    cursor: pointer;
  }
}

/* Fundo das linhas na tabela de maiores variações.

   Tom bem lavado: a cor separa os dois grupos de relance, sem competir com os
   números — e os valores continuam legíveis por cima dela, inclusive no modo
   privado, onde o que se vê é a sombra do texto. */
.variacoes .linha-alta > td { background: #eef6f0; }
.variacoes .linha-baixa > td { background: #fbeff0; }

/* A cor é um reforço, não o único sinal: quem não distingue verde de vermelho
   continua lendo o sinal do número e a seta da variação. */
.variacoes .linha-alta > td:first-child { box-shadow: inset 3px 0 0 #2f7a52; }
.variacoes .linha-baixa > td:first-child { box-shadow: inset 3px 0 0 #a33528; }

/* As ações de cada conta ficam lado a lado, e a de apagar não compete em
   destaque com a de entrar. Quebram de linha porque são quatro e uma delas é
   um formulário com campo: numa tela estreita, em linha única, o campo
   espremeria até não caber um número de dois dígitos. */
.person-acoes { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; }
.person .who span + span { display: block; }

/* O campo de projeção de uma conta. Ao contrário da barra das configurações,
   aqui tudo é dito: rótulo, valor em vigor e o sinal de percentual. Lá quem vê
   é quem escondeu; aqui alguém decide pela carteira de outra pessoa. */
.projecao-conta { display: flex; align-items: center; gap: .375rem; }
.projecao-conta label { font-size: .8125rem; color: var(--ink-soft); }
/* Uma lista de dez paradas, sem botão ao lado: escolher já é a decisão. A
   largura é fixa para que as linhas não se desalinhem entre "10%" e "100%". */
.projecao-conta select {
  font: inherit; font-size: .9375rem; width: 5.25rem;
  padding: .375rem .5rem; border: 1px solid var(--rule-strong);
  border-radius: var(--r-md); background: var(--raised); color: var(--ink);
  cursor: pointer;
}


/* O selo ocupa a linha inteira embaixo das ações: é uma frase, e espremê-la
   entre os botões a deixaria em duas palavras por linha. */
.escala-selo {
  flex-basis: 100%; margin: .5rem 0 0; font-size: .8125rem;
  color: var(--ink-soft);
}

/* A busca cresce e os botões ficam do tamanho do texto: um campo de busca do
   tamanho do rótulo não recebe um e-mail inteiro. O teto existe porque um
   campo de busca de mil pixels numa tela larga não fica melhor, fica só
   grande. */
.filtro-usuarios { margin-bottom: 1.25rem; }
.filters .cresce { flex: 1 1 16rem; max-width: 28rem; }
.filters input[type="search"] {
  font: inherit; font-size: .9375rem; width: 100%; padding: .5rem .625rem;
  border: 1px solid var(--rule-strong); border-radius: var(--r-md);
  background: var(--raised); color: var(--ink);
}

/* ============================================================ LOGS DE ACESSO */
/* Um grupo por e-mail, fechado. O cabeçalho é a linha que se lê; as outras só
   existem depois do clique. */
/* `th` centraliza por padrão, e o selo ao lado do e-mail tem largura diferente
   em cada linha — centralizados, os três e-mails começavam em três colunas
   diferentes e a lista parecia torta. */
.logs-acesso .log-cabeca > th { font-weight: 500; text-align: left; }
.log-abre {
  display: inline-flex; align-items: baseline; gap: .5rem;
  font: inherit; color: inherit; background: none; border: 0; padding: 0;
  cursor: pointer; text-align: left;
}
.log-abre:hover .log-quem { text-decoration: underline; }
.log-abre:focus-visible { outline: 2px solid var(--pine); outline-offset: 3px; }
/* A seta gira em vez de trocar de caractere: trocar mudaria a largura e o
   e-mail dançaria meio pixel a cada clique. */
.log-seta {
  display: inline-block; transition: transform .15s ease;
  color: var(--ink-faint);
}
.log-abre[aria-expanded="true"] .log-seta { transform: rotate(90deg); }
.log-selo {
  margin-left: .5rem; font-size: .75rem; color: var(--ink-faint);
  border: 1px solid var(--rule); border-radius: 999px; padding: .0625rem .5rem;
  white-space: nowrap;
}
.log-resumo { font-size: .8125rem; color: var(--ink-soft); }
/* A linha de detalhe recua para se ler como filha do e-mail acima dela. */
.log-linha > td:first-child { padding-left: 1.75rem; }
.log-falha { color: var(--down); }
.log-corte td { font-size: .8125rem; font-style: italic; }
/* Um fio entre grupos, não entre linhas: a tabela vira uma lista de pessoas. */
.logs-acesso tbody + tbody { border-top: 1px solid var(--rule); }

/* Paginação: o texto no meio, as setas nas pontas. O botão morto continua
   ocupando o lugar para a linha não dançar entre uma página e outra. */
.paginacao {
  display: flex; align-items: center; justify-content: center;
  gap: .75rem; margin-top: 1.5rem; flex-wrap: wrap;
}
.paginacao-conta { font-size: .875rem; color: var(--ink-soft); }
.paginacao [aria-disabled="true"] { opacity: .45; cursor: default; }

/* Campo de percentual da calculadora: estreito, alinhado à direita como o
   número que ele é. */
.pct-input {
  width: 6.5rem; text-align: right; padding: .375rem .5rem;
  font-variant-numeric: tabular-nums;
}
.calc-papeis tfoot .soma-passou { color: var(--down); font-weight: 600; }
.calc-papeis tfoot th { font-weight: 400; color: var(--ink-soft); }

/* Boas-vindas: o overlay que abre na primeira visita.

   A animação é curta e sobe de baixo — o suficiente para a tela não trocar de
   assunto num piscar, sem virar espera. Quem pediu menos movimento no sistema
   recebe a abertura sem animação nenhuma. */
.welcome {
  border: 0; padding: 0; background: transparent;
  max-width: min(34rem, calc(100vw - 2rem));
}
.welcome::backdrop { background: rgba(14, 30, 26, .55); }

.welcome-card {
  background: var(--raised, #fff); border-radius: var(--r-lg, 14px);
  padding: 1.75rem; box-shadow: 0 18px 48px rgba(14, 30, 26, .28);
}

.welcome[open] { animation: welcome-entra .26s ease-out; }
.welcome[open]::backdrop { animation: welcome-fundo .26s ease-out; }

@keyframes welcome-entra {
  from { opacity: 0; transform: translateY(14px) scale(.985); }
  to { opacity: 1; transform: none; }
}
@keyframes welcome-fundo { from { opacity: 0; } to { opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
  .welcome[open], .welcome[open]::backdrop { animation: none; }
}

.welcome-head h2 { margin: 0 0 .5rem; }
.welcome-head p { margin: 0 0 .75rem; color: var(--ink-soft); font-size: .9375rem; }
.welcome-pergunta { color: var(--ink) !important; font-weight: 500; }

.perfis { display: flex; flex-direction: column; gap: .625rem; margin: 1rem 0; }

/* A linha inteira é clicável, não só a bolinha: o alvo de um rádio sozinho é
   pequeno demais para o dedo, e aqui a escolha é a única coisa que se faz. */
.perfil {
  display: flex; gap: .75rem; align-items: flex-start; cursor: pointer;
  padding: .75rem .875rem; border: 1px solid var(--rule, #e2e8e5);
  border-radius: var(--r-md, 10px);
}
.perfil:hover { background: var(--pine-wash, #eef4f1); }
.perfil:has(input:checked) {
  border-color: var(--pine, #2f7a52);
  box-shadow: inset 0 0 0 1px var(--pine, #2f7a52);
}
.perfil input { margin-top: .2rem; }
.perfil-corpo { display: flex; flex-direction: column; gap: .2rem; }
.perfil-nome { font-weight: 600; }
.perfil-diz { font-size: .8125rem; color: var(--ink-soft); line-height: 1.45; }

.welcome-exemplo { margin-top: 1rem; }
.welcome-acoes { margin-top: 1.25rem; }
.welcome-rodape { margin-top: .75rem; }

/* Categorias do aporte: um bloco de rascunho, não um cadastro. */
.categorias { margin: 1.25rem 0; }
.nova-categoria {
  display: flex; gap: .75rem; align-items: flex-end; flex-wrap: wrap;
}
.nova-categoria .field { margin: 0; }
.nova-categoria input { width: 13rem; }
.nova-categoria [data-nova-categoria-peso] { width: 6rem; text-align: right; }

.lista-categorias {
  display: flex; flex-wrap: wrap; gap: .5rem;
  list-style: none; margin: .75rem 0 0; padding: 0;
}
.categoria {
  display: inline-flex; align-items: center; gap: .5rem;
  padding: .3125rem .5rem .3125rem .625rem;
  background: var(--pine-wash, #eef4f1); border-radius: 999px;
  font-size: .875rem;
}
.categoria-nome { font-weight: 600; }
.categoria-peso { color: var(--ink-soft); }
.calc-papeis select { max-width: 12rem; }

/* A árvore da calculadora: grupo, e os papéis dele recuados abaixo. */
.calc-arvore .no-grupo > td { background: var(--pine-wash, #eef4f1); }
.calc-arvore .no-grupo.sem-grupo > td { background: none; }
.grupo-nome { font-weight: 600; }
.calc-arvore .no-papel.dentro .celula-papel { padding-left: 2rem; }

/* A pegada: o alvo precisa caber um dedo, e o cursor precisa dizer que arrasta. */
.pegar {
  background: none; border: 0; cursor: grab; color: var(--ink-soft);
  font-size: 1rem; line-height: 1; padding: .25rem .375rem; margin-right: .25rem;
}
.pegar:hover { color: var(--ink); }
.calc-arvore tr.na-mao > td { background: #fff7e6; }
.calc-arvore tr.na-mao .pegar { cursor: grabbing; }
.celula-papel, .celula-grupo { display: flex; flex-direction: column; }
.celula-papel { position: relative; }

/* Cenários salvos da calculadora. */
.cenarios { display: flex; gap: 2rem; flex-wrap: wrap; margin-bottom: 1rem; }
.linha-cenario { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; }
.linha-cenario select, .linha-cenario input { min-width: 12rem; }
.form-oculto { display: contents; }

/* Telas muito estreitas — aparelhos pequenos, ou texto aumentado por quem
   precisa dele. O cabeçalho continua numa linha só: é o que faz a marca
   parecer o item de menu que ela é, em vez do título da página.

   O corpo da marca já vem da conta do bloco acima; aqui só se apertam os
   espaços, que são de largura fixa e por isso pesam mais quanto menor a tela. */
@media (max-width: 22rem) {
  .masthead-inner { gap: .5rem; }
  .masthead-actions { gap: .375rem; }
  .masthead .wordmark { gap: .375rem; }
}

/* A seta cola no campo de data: ela é parte do mesmo controle, não uma ação
   solta ao lado do Aplicar. */
.linha-data { display: inline-flex; align-items: center; gap: .375rem; }
.seta-mes {
  padding: .375rem .5rem; line-height: 1; font-size: 1rem;
  text-decoration: none;
}

/* Legenda dobrada: seis itens, o resto atrás do botão.

   Nenhuma fatia sai do desenho — o que se dobra é a lista, para que cartões
   com três e com quinze linhas não deixem a página irregular. */
.legend-extra { display: none; }
.legenda-aberta .legend-extra { display: grid; }

.legend-mais {
  justify-self: start; margin-top: .25rem; padding: .25rem 0;
  background: none; border: 0; cursor: pointer;
  font: inherit; font-size: .8125rem; color: var(--pine, #2f7a52);
  text-decoration: underline; text-underline-offset: 2px;
}
.legend-mais:hover { color: var(--ink); }

/* Papel a papel: a rosca ocupa a esquerda e as legendas se espalham em duas
   colunas à direita. É o gráfico com mais itens, e em coluna única a lista
   ficava muito mais alta que o desenho ao lado. */
.chart-ativo .chart-body { align-items: flex-start; gap: 2rem; }
.chart-ativo .chart-body svg { flex: 0 0 auto; }
.chart-ativo .legend { flex: 1 1 22rem; min-width: 18rem; }
@media (min-width: 60rem) {
  /* Duas colunas **desde o início**, não só depois de expandir.

     A dobra ficava condicionada à classe de aberto — que vive no corpo do
     gráfico, e não no cartão, porque é o corpo que o script conhece. Com doze
     legendas por padrão isso deixava de servir: medida a 1440px, a lista de
     doze em coluna única ficava com 476px ao lado de uma rosca de 300, e o
     percentual ia parar a meio cartão de distância do nome que descreve. Em
     duas colunas as seis linhas acompanham a altura da rosca.

     De quebra, abrir a lista deixa de trocar o formato dela: só acrescenta
     linhas, em vez de reembaralhar tudo de uma coluna para duas. */
  .chart-ativo .legend {
    grid-template-columns: 1fr 1fr; column-gap: 1.75rem;
    align-content: start;
  }
  .chart-ativo .legend-mais { grid-column: 1 / -1; }
}

/* ------------------------------------------------------- tela de convites
   O código é o conteúdo da tela: ele existe para ser lido em voz alta e
   copiado à mão, então sai em fonte de largura fixa e espaçado — é a diferença
   entre ditar "B, 3, J" e ditar "bêjota". */
.linha-form { display: grid; gap: .75rem; max-width: 28rem; }
.cota { margin: 1rem 0 .5rem; color: var(--ink-soft); font-size: .9375rem; }
.vazio { color: var(--ink-faint); }
td.codigo {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  letter-spacing: .08em; font-size: .9375rem;
}
td.acoes { text-align: right; white-space: nowrap; }
.selo {
  display: inline-block; padding: .125rem .5rem; border-radius: 999px;
  font-size: .8125rem; border: 1px solid currentColor;
}
.selo-pendente { color: var(--amber); }
.selo-aceito { color: var(--up); }
.selo-expirado { color: var(--ink-faint); }

/* ------------------------------------------- ajuste de crédito no extrato
   O "ajustado" e o botão de desfazer andam juntos, na mesma linha do valor.
   O ícone é discreto de propósito: desfazer é raro, e um botão com peso de
   ação principal ao lado de cada linha ajustada pediria para ser clicado. */
.ajuste-linha {
  display: flex; align-items: center; justify-content: flex-end; gap: .25rem;
}
.ajuste { cursor: help; border-bottom: 1px dotted currentColor; }
.desfaz-ajuste { display: inline-flex; }
.icone-undo {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.375rem; height: 1.375rem; padding: 0;
  vertical-align: middle;
  border: 1px solid var(--rule); border-radius: 999px;
  background: var(--raised); color: var(--ink-soft); cursor: pointer;
}
.icone-undo svg { width: .875rem; height: .875rem; }
.icone-undo:hover { color: var(--ink); border-color: var(--rule-strong); }

/* A escolha de criptografar, no cadastro.

   Caixa e rótulo na mesma linha, e o aviso embaixo em corpo menor: ele é a
   parte que ninguém lê se estiver do tamanho do resto, e a parte que importa
   se a pessoa um dia esquecer a senha. */
.campo-cripto { display: grid; gap: .5rem; }
.campo-cripto .linha-caixa {
  display: flex; align-items: flex-start; gap: .5rem;
}
.campo-cripto .linha-caixa input { margin-top: .2rem; flex: none; }
.campo-cripto .linha-caixa label { margin: 0; font-weight: 400; }
.aviso-cripto {
  margin: 0; font-size: .8125rem; line-height: 1.45; color: var(--ink-faint);
  border-left: 2px solid var(--rule); padding-left: .75rem;
}
/* Na lista de usuários, no lugar do botão de personificar. */
/* "dados cifrados" vive na linha de atributos da conta, junto de
   "administrador" e "inativa". O pontilhado e o cursor dizem que há um texto
   por trás; sem eles o aviso parece só mais uma palavra da frase. */
.cifrada { cursor: help; border-bottom: 1px dotted currentColor; }
/* `display: inline` dito de novo porque a regra das linhas da conta faz
   **todo** span de dentro de `.who` virar bloco — e o selo mora dentro de um
   deles. Sem isto ele descia para uma linha só dele, e a conta cifrada ficava
   vinte pixels mais alta que as outras: os mesmos botões, a linha diferente. */
.person .who span.cifrada { display: inline; }

/* ------------------------------------------- o menu de acesso de uma conta */
/* Toda linha mostra os mesmos botões; o que muda é quais aceitam o clique.
   O botão recusado precisa **parecer** recusado e ainda assim receber o
   ponteiro — é por isso que a marca é `aria-disabled` e não `disabled`, e é
   por isso que a aparência tem de ser escrita aqui: o navegador não apaga
   sozinho o que ele não considera desabilitado. */
.btn[aria-disabled="true"],
.menu-panel button[aria-disabled="true"] {
  opacity: .45;
  /* `not-allowed` no botão inteiro, e não `help`: a pergunta aqui é "posso
     clicar?", e a resposta é não. O texto do porquê vem no título. */
  cursor: not-allowed;
}
.btn[aria-disabled="true"]:hover { background: var(--raised); color: var(--ink); }
.menu-panel button[aria-disabled="true"]:hover { background: none; }

.conta-acoes > summary {
  /* `summary` nasce `display: list-item`; sem isto o `.btn` não consegue
     centralizar o conteúdo e o botão fica com a altura das outras ações mas
     com o texto encostado no topo. */
  display: inline-flex;
}
.conta-acoes[open] > summary { background: var(--sunken); }
/* Aberto, o painel precisa passar por cima das linhas seguintes — que vêm
   depois no documento e, sem isto, ganham a disputa por serem posteriores. */
.conta-acoes[open] { z-index: 40; }
/* O painel pende da borda **direita** do botão, que é o lado por onde ele
   corre menos risco de sair da tela: as ações ficam à direita da linha, nas
   duas larguras. Alinhado à esquerda do botão ele crescia para fora — a 420px
   passava 56 pixels da janela e a página ganhava rolagem horizontal, que esta
   folha não permite em tela nenhuma. */
/* Posição de tela, medida na abertura pelo script — a mesma solução dos menus
   da tabela, e pelo mesmo motivo: a linha quebra conforme a largura e o botão
   pode acabar perto de qualquer borda. Ancorado por CSS, o painel saía da tela
   a 420px, começando em x=-87. */
.conta-acoes .menu-panel {
  position: fixed; left: auto; right: auto; top: auto;
  min-width: 13rem; max-width: calc(100vw - 2rem); z-index: 60;
}
.conta-acoes[open] .menu-panel { z-index: 60; }
/* O traço que separa o que se desfaz do que não se desfaz. Sem ele, "Apagar
   conta" fica a um pixel de "Zerar 2º fator" e o dedo que errasse por pouco
   acertaria o irreversível. */
.menu-risco {
  border: 0; border-top: 1px solid var(--rule); margin: .25rem .375rem;
}
.conta-acoes .menu-panel .is-danger { color: var(--down); }
.conta-acoes .menu-panel .is-danger:hover { background: #fdf3f1; }
.menu-seta {
  flex: 0 0 auto; opacity: .55; font-size: .6875rem; line-height: 1;
}
.menu-seta::before { content: "▾"; }

/* O diálogo da senha é mais estreito que o do resgate: são dois campos e uma
   frase, e a largura cheia faria o olho percorrer linha vazia até o campo. */
/* ------------------------------------------------------------- segurança */
/* Uma linha por decisão: o que ela é à esquerda, o estado em que está à
   direita. O rótulo e a legenda ficam na mesma coluna para o olho descer uma
   lista, e não varrer um parágrafo por item. */
.seguranca-linha {
  display: flex; align-items: flex-start; gap: 1rem; flex-wrap: wrap;
  padding: .875rem 0; border-top: 1px solid var(--rule);
}
.seguranca-linha:first-of-type { border-top: 0; padding-top: .25rem; }
.seguranca-texto { display: grid; gap: .125rem; }
.seguranca-texto strong { font-weight: 500; }
.seguranca-linha > .check { flex: 0 0 auto; min-width: 13rem; }
/* A legenda ocupa o espaço que sobra e empurra o botão para a direita; numa
   tela estreita ela quebra para a linha de baixo em vez de espremer a caixa. */
.seguranca-estado { flex: 1 1 18rem; margin: .1875rem 0 0; }
.seguranca-linha > .btn { margin-left: auto; }
/* Desabilitada, a caixa e o rótulo apagam juntos: só a caixa cinza, com o
   rótulo preto ao lado, parece um defeito de desenho e não uma recusa. */
.seguranca-linha .check input:disabled + label { opacity: .5; }

.seguranca-dialogo { width: min(26rem, calc(100vw - 2rem)); }
.seguranca-dialogo h2 { margin: 0 0 .75rem; }
.seguranca-dialogo .aviso-cripto { margin-top: .75rem; }

.senha-dialogo { width: min(24rem, calc(100vw - 2rem)); }
.senha-dialogo .field .help { display: block; margin-top: .25rem; }

/* O QR do segundo fator.

   A cor vem daqui e não do atributo do SVG: a regra vence o `stroke=` que o
   gerador escreve, e assim o código acompanha o tema claro e o escuro. O
   atributo fica como reserva para o caso de a folha não carregar — um QR
   invisível seria pior que um QR fora do tema. */
.qr { width: 11.5rem; height: 11.5rem; display: block; }
.qr-traco { stroke: currentColor; }
.otp-caixa {
  display: grid; gap: 1rem; justify-items: center;
  grid-template-columns: auto minmax(0, 1fr); align-items: start;
}
.otp-caixa > .qr-moldura {
  background: #fff; padding: .5rem; border-radius: var(--r-sm);
  border: 1px solid var(--rule); color: #000;
}
.otp-segredo {
  font-family: var(--mono); font-size: .9375rem;
  letter-spacing: .08em; word-break: break-all; user-select: all;
  background: var(--raised); border: 1px solid var(--rule);
  border-radius: var(--r-sm); padding: .5rem .625rem; display: block;
}
@media (max-width: 34rem) { .otp-caixa { grid-template-columns: minmax(0, 1fr); } }

/* Com o QR e o segredo se revezando, só um ocupa a caixa de cada vez — e aí
   uma coluna só, centrada, em vez das duas que existiam para mostrá-los lado
   a lado. */
.otp-caixa { grid-template-columns: minmax(0, 1fr); justify-items: center; }
.otp-caixa > [data-segredo] { max-width: 24rem; }

/* Um botão que se lê como um link: ele mora no meio de uma frase do passo a
   passo, e um botão com moldura ali partiria a frase em duas. */
.link-inline {
  font: inherit; color: var(--pine); background: none; border: 0; padding: 0;
  text-decoration: underline; cursor: pointer;
}
.link-inline:hover { color: var(--pine-deep); }

/* Os links das lojas: ícone próprio e o nome da loja em texto. Os logotipos
   são marcas e não são desenhados aqui. */
.lojas { display: inline-flex; gap: .375rem; flex-wrap: wrap; margin-left: .25rem; }
.loja-icone { width: .875rem; height: .875rem; flex: 0 0 auto; }
