/* ==========================================================================
   WisdomAdvisor — design system mínimo + app shell
   --------------------------------------------------------------------------
   Fase de UX (§13.1 do PLANO-WISDOM-ADVISOR-AI.md). Organizado em camadas:
     1. Tokens          — cores da marca, espaçamento, tipografia
     2. Base            — reset e elementos nativos
     3. App shell       — sidebar + topbar + área de conteúdo
     4. Componentes     — card, botão, campo, tabela, pill, badge
     5. Estados         — carregando, vazio, erro, indisponível
     6. Telas           — login e Análise de Empresa
     7. Responsivo      — sidebar off-canvas no mobile
   Sem framework e sem build: é CSS puro servido estático pela Lambda.
   ========================================================================== */

/* ── 1. Tokens ─────────────────────────────────────────────────────────── */
/*
   Tema navy escuro (padrão CredBusiness). A troca de tema acontece AQUI e em
   mais lugar nenhum: todo componente abaixo lê var(--*), então quem quiser
   voltar ao claro reescreve este bloco e nada mais.

   Por que escuro: número colorido precisa saltar do fundo. Sobre branco, o
   verde de +2,3% e o vermelho de -2,3% têm contraste parecido e a tabela vira
   uma massa cinza; sobre navy os dois saltam. É a razão pela qual terminal
   financeiro é escuro, e não preferência estética.

   Regra de contraste: --ink sobre --bg dá 14:1, --muted sobre --surface dá
   4,8:1 (AA para texto normal). Nenhum par abaixo de 4,5:1 carrega informação.
*/
:root {
  /* Marca — o aqua sobrevive como acento, mas clareado, porque o tom original
     (#1bbdd4) sobre navy fica abaixo do mínimo de contraste para texto. */
  --aqua: #22d3ee;
  --teal-d: #67e8f9;
  --green: #4ade80;
  --amber: #fbbf24;
  --err: #f87171;

  /* Apelidos semânticos. As telas escrevem var(--ok)/var(--warn)/var(--danger)
     para colorir número por leitura (rentabilidade positiva, volatilidade
     extrema, drawdown). Mantidos como apelido, nunca como cor solta: quem muda
     o significado muda aqui, e a tela inteira acompanha. */
  --ok: #4ade80;
  --warn: #fbbf24;
  --info: #22d3ee;
  --danger: #f87171;

  /* Superfícies e texto */
  --bg: #0a0c10;
  --surface: #18181b;
  --surface-2: #232327;
  --surface-3: #2e2e33;
  --ink: #f4f4f5;
  --muted: #a1a1aa;
  --border: #2e2e33;

  /* Navegação — no tema escuro a sidebar é mais escura que a área de trabalho,
     invertendo a relação anterior: a área de conteúdo é que ganha destaque. */
  --nav-bg-top: #09090b;
  --nav-bg-bottom: #101013;
  --nav-ink: #a1a1aa;
  --nav-ink-strong: #ffffff;

  /* Métrica */
  --radius: 10px;
  --radius-sm: 7px;
  /* Estreitado de 236 para 208: os 28px foram para a tabela de bolsas, que
     tem onze colunas de numero e e o bloco mais apertado do produto.

     A CONTA, MEDIDA e nao estimada (estimar ja errou uma vez: dava 732px e a
     barra apareceu assim mesmo). Em janela de 1817px, com o menu a 212:
       area util .................. 1.605px
       tabela de bolsas precisa ...   795px
       tabela de referencias ......   744px
       soma + intervalo ........... 1.555px  → sobram 50px
     Cabe. O erro anterior foi dividir a area meio a meio entre duas tabelas de
     tamanhos diferentes: a de bolsas tem tres colunas a mais. A divisao agora e
     proporcional a necessidade de cada uma (ver .desk-grid--mercado). */
  --sidebar-w: 212px;
  --topbar-h: 58px;
  --shadow-card: 0 8px 24px -16px rgba(0, 0, 0, 0.8);

  /* Densidade de terminal: linha de tabela baixa, para caber mais número por
     dobra. Gestor lê a coluna em diagonal — espaço em branco atrapalha. */
  --row-h: 34px;
}

/* ── 2. Base ───────────────────────────────────────────────────────────── */
* { box-sizing: border-box; margin: 0; padding: 0; }

[hidden] { display: none !important; }

/* color-scheme: dark faz o navegador escurecer o que ele mesmo desenha e a
   folha de estilo não alcança — barra de rolagem, calendário do input[type=
   date], seta do select, autofill. Sem isto sobram retângulos brancos no meio
   da tela escura, que é o detalhe que denuncia tema escuro mal feito. */
:root { color-scheme: dark; }

body {
  font-family: 'Segoe UI', system-ui, -apple-system, Roboto, sans-serif;
  background: var(--bg);
  color: var(--ink);
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--aqua); }

/* Todo número da aplicação é tabular: a coluna de dinheiro tem que alinhar na
   vírgula, senão não se lê em diagonal. Vale para tabela, tile e KPI de uma
   vez só, em vez de cada tela lembrar de pedir. */
.table, .tile, .kpi, .mult__value, .num { font-variant-numeric: tabular-nums; }

/* ── 3. App shell ──────────────────────────────────────────────────────── */
.app-shell {
  display: grid;
  grid-template-columns: var(--sidebar-w) 1fr;
  min-height: 100vh;

  /* O FUNDO DA BARRA LATERAL É PINTADO AQUI, na coluna, e não no elemento.
     A `.sidebar` é `position: sticky` com `height: 100vh` — ela acompanha a
     rolagem, mas o fundo dela mede uma tela. Numa página alta (Mercado tem
     2.200px), abaixo da primeira dobra aparecia o fundo da PÁGINA no lugar do
     menu: um corte horizontal no meio da lateral, como se o menu acabasse ali.
     Pintando a faixa na grade, a coluna inteira fica com a cor certa por
     quanto a página for. */
  background: linear-gradient(
    to right,
    var(--nav-bg-bottom) 0,
    var(--nav-bg-bottom) var(--sidebar-w),
    transparent var(--sidebar-w)
  );
}

@media (max-width: 900px) {
  /* No mobile a barra é off-canvas: a faixa pintada apareceria como uma tarja
     à esquerda do conteúdo. */
  .app-shell { background: none; }
}

/* Sidebar -------------------------------------------------------------- */
.sidebar {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
  background: linear-gradient(180deg, var(--nav-bg-top), var(--nav-bg-bottom));
  color: var(--nav-ink);
  padding: 18px 0 14px;
}

.sidebar__brand {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 0 18px 20px;
  color: var(--nav-ink-strong);
  font-size: 1.05rem;
  font-weight: 800;
  letter-spacing: -0.3px;
}

.sidebar__nav { flex: 1; overflow-y: auto; }

/* Rótulo de agrupamento ("Configurações") */
.sidebar__group {
  padding: 18px 18px 6px;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: rgba(169, 198, 210, 0.6);
}

/* Fonte e respiro ajustados para "Clientes e carteiras" e "Analise de
   empresa" caberem numa linha: quebrados em duas, os itens ficavam com 60px de
   altura e o menu ganhava um ritmo irregular. */
.nav-item {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 10px 15px;
  border-left: 3px solid transparent;
  color: var(--nav-ink);
  font-size: 0.86rem;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}
.nav-item:hover { background: rgba(255, 255, 255, 0.06); color: var(--nav-ink-strong); }
.nav-item.is-active {
  background: rgba(34, 211, 238, 0.13);
  border-left-color: var(--aqua);
  color: var(--nav-ink-strong);
}
.nav-item__icon { width: 18px; text-align: center; font-size: 0.95rem; }

.sidebar__foot {
  padding: 14px 18px 0;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  font-size: 0.78rem;
}
.sidebar__foot a { color: var(--nav-ink); text-decoration: none; }
.sidebar__foot a:hover { color: var(--nav-ink-strong); }

/* Coluna principal ------------------------------------------------------ */
.main { display: flex; flex-direction: column; min-width: 0; }

.topbar {
  height: var(--topbar-h);
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 0 24px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}
/* min-width:0 + ellipsis: sem isso o título de rota longo empurra a topbar
   além da largura da tela e a página inteira ganha rolagem horizontal. */
.topbar__left { display: flex; align-items: center; gap: 12px; min-width: 0; }
.topbar__title {
  font-size: 1rem; font-weight: 700;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ── Seletor de empresa (só o dono da plataforma vê) ──────────────────────
   Fica ANTES do bloco de identidade e com aparência de controle, não de
   rótulo: é um comando que muda o que a tela inteira mostra.

   O estado "fora" existe porque operar na empresa errada é o erro caro deste
   recurso. Quando o dono está navegando em outro cliente, o seletor ganha
   borda âmbar — a mesma cor que o produto usa para "atenção" em todo lugar. */
.topbar__firma {
  display: flex; align-items: center; gap: 7px;
  margin-left: auto; margin-right: 12px;
  padding: 5px 9px;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--muted);
}
/* O `background: transparent` que estava aqui deixava a LISTA ABERTA do select
   com o fundo branco do sistema — texto claro sobre branco, ilegível. O
   dropdown nativo não herda o fundo do pai: ele precisa da cor no próprio
   `select` e, no Chrome, também em cada `option`. */
.topbar__firma select {
  border: 0;
  background: var(--surface);
  color: var(--ink);
  font: inherit; font-size: 0.82rem; max-width: 220px;
}
/* Vale para TODO select do produto, não só o da topbar: o defeito é do
   dropdown nativo em tema escuro e apareceu no seletor de empresa por acaso —
   os filtros de carteira, período e moeda têm exatamente o mesmo. Corrigir só
   onde foi visto deixaria os outros esperando alguém reclamar. */
select option {
  background: var(--surface-2);
  color: var(--ink);
}
.topbar__firma select:focus-visible { outline: 2px solid var(--aqua); outline-offset: 2px; }
.topbar__firma--fora {
  border-color: var(--warn);
  background: color-mix(in srgb, var(--warn) 12%, var(--surface));
}
.topbar__firma--fora select { color: var(--warn); font-weight: 600; }

/* ── Trocar e criar modelo de alocação ────────────────────────────────────
   Painel que abre DENTRO do cartão do modelo, ao lado da lista: o gestor está
   conversando com o cliente quando decide isso, e mandá-lo para outra tela
   quebraria a conversa. */
.modelo-painel {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 16px; margin: 12px 0 4px; padding: 12px;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface);
}
.modelo-lista { display: flex; flex-direction: column; gap: 4px; }
.modelo-grupo + .modelo-grupo { margin-top: 10px; }
.modelo-item {
  display: flex; flex-direction: column; gap: 2px; width: 100%;
  padding: 8px 10px; text-align: left;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: transparent; color: var(--ink); font: inherit; cursor: pointer;
}
.modelo-item:hover { border-color: var(--aqua); background: var(--surface-2); }
/* O modelo EM USO fica marcado: sem isso o gestor não sabe qual está valendo
   e troca para o mesmo achando que mudou algo. */
.modelo-item.is-on { border-color: var(--aqua); background: color-mix(in srgb, var(--aqua) 14%, var(--surface)); }
.modelo-item .criteria-sig { font-size: 0.74rem; }

.mo-bloco {
  display: grid; grid-template-columns: 1fr 72px 150px auto;
  gap: 6px; align-items: start; margin-bottom: 6px;
}
.mo-bloco input, .mo-bloco select {
  padding: 5px 8px; font: inherit; font-size: 0.8rem;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface-2); color: var(--ink);
}
.modelo-soma { margin-top: 8px; font-size: 0.8rem; }

@media (max-width: 620px) {
  /* Quatro colunas em 390px viram quatro campos ilegíveis. */
  .mo-bloco { grid-template-columns: 1fr; }
}

.topbar__user { display: flex; align-items: center; gap: 10px; flex: none; }
.avatar {
  width: 34px; height: 34px;
  display: grid; place-items: center;
  border-radius: 50%;
  /* Iniciais em tinta escura sobre aqua: no tema escuro o aqua clareou para
     alcançar contraste como texto, e branco sobre ele cai para 3:1. */
  background: var(--aqua);
  color: #052f3a;
  font-size: 0.8rem;
  font-weight: 700;
}
.topbar__id { line-height: 1.2; text-align: right; }
.topbar__name { font-size: 0.85rem; font-weight: 600; }
.topbar__role { font-size: 0.72rem; color: var(--muted); }

/* Botão hamburguer — só aparece no mobile (ver §7) */
.nav-toggle {
  display: none;
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--ink);
  border-radius: var(--radius-sm);
  padding: 6px 9px;
  cursor: pointer;
}

/* A área de trabalho ocupava no máximo 1180px e ficava colada à esquerda: num
   monitor de 1900px sobravam ~470px de fundo vazio à direita, e a tela inteira
   lia como um formulário perdido numa página em branco. Terminal financeiro
   preenche o monitor — o gestor comprou a tela larga para caber mais número.
   O teto alto continua existindo porque numa ultrawide de 3440px a tabela
   esticaria a ponto de o olho perder a linha entre uma coluna e outra. */
.view {
  padding: 20px 26px 48px;
  width: 100%;
  max-width: 1760px;
  margin-inline: auto;
}
/* Cabeçalho da tela: só a linha de contexto. O título da rota é o <h1> da
   topbar, para não repetir o mesmo texto duas vezes na mesma dobra. */
.view__head { margin-bottom: 16px; }
.view__head p { color: var(--muted); font-size: 0.87rem; }

/* ── 4. Componentes ────────────────────────────────────────────────────── */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 18px;
  box-shadow: var(--shadow-card);
}
.card + .card { margin-top: 16px; }
.card__head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-bottom: 14px; flex-wrap: wrap;
}
/* Todo título de seção é flex porque agora carrega um ícone SVG à esquerda —
   sem isto o <svg> assenta na linha de base do texto e fica alto demais. */
.card h2, .card__head h2 {
  display: flex; align-items: center; gap: 8px;
  font-size: 0.98rem; font-weight: 700; color: var(--ink);
}
.card h2 .ico, .card__head h2 .ico { color: var(--aqua); }
.card h3 { font-size: 0.88rem; font-weight: 700; }

/* Bloco de dado interno (usado nos cards da Análise de Empresa) */
.tile {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 14px;
}
.tile h3 {
  font-size: 0.72rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--muted); margin-bottom: 10px;
}
/* `align-items: start` é o que impede o tile curto de esticar até a altura do
   mais alto. Sem isso, um bloco de 4 linhas ao lado de um de 19 virava um
   retângulo vazio de 600px — foi o que aconteceu na tela de Mercado, onde o
   Tesouro Selic tem 4 títulos e o IPCA+ tem 19. */
.tile-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 14px;
  align-items: start;
}

/* `min-width: 0` é o que permite o tile ENCOLHER. Sem isto, o conteúdo dele
   (uma tabela, por exemplo) impõe a própria largura mínima, a faixa da grade
   cresce além do container e a PÁGINA inteira passa a rolar na horizontal —
   com o cartão da direita cortado pela borda da janela. */
.tile { min-width: 0; }

/* ── Filtro de período da tela de Mercado ──────────────────────────────── */
/*
   Trocar de janela não vai ao servidor: as dez variações já vêm no payload e a
   série semanal de dez anos cobre o período livre. Por isso os chips podem ser
   muitos sem custo — o que pesaria seria uma chamada por clique.
*/
.filtros {
  display: flex; flex-direction: column; gap: 10px;
  padding-bottom: 12px; margin-bottom: 4px;
  border-bottom: 1px solid var(--border);
}
.filtros__chips { display: flex; flex-wrap: wrap; gap: 6px; }

.chip-periodo {
  padding: 5px 11px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--muted);
  font: 600 0.77rem inherit;
  cursor: pointer;
  white-space: nowrap;
}
.chip-periodo:hover { color: var(--ink); border-color: var(--aqua); }
.chip-periodo.is-on {
  background: color-mix(in srgb, var(--aqua) 20%, var(--surface));
  border-color: var(--aqua);
  color: var(--aqua);
}

.filtros__datas { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; font-size: 0.8rem; color: var(--muted); }
.filtros__datas input {
  margin-left: 6px;
  padding: 5px 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink);
  font: inherit; font-size: 0.8rem;
}

/* Procedência, no rodapé da tela de Mercado.
   Era um card na coluna lateral e virou faixa: o conteúdo é curto e de
   consulta, não pede a altura de um painel. Em tela estreita as partes
   quebram e empilham sozinhas. */
/* GRID, não flex. Com `flex-wrap` as três fontes quebravam em pontos
   diferentes conforme o comprimento do texto de cada uma, e o carimbo de hora
   (que era empurrado por `margin-left:auto`) ia parar no meio da segunda
   linha — o bloco parecia desalinhado mesmo estando "certo". Aqui as fontes
   ocupam colunas de largura igual, uma embaixo da outra quando não cabem, e o
   carimbo tem linha própria separada por um filete. */
.fontes {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: start;
  column-gap: 10px; row-gap: 8px;
  margin-top: 14px; padding: 11px 14px;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface);
  font-size: 0.76rem; color: var(--muted); line-height: 1.5;
}
.fontes b { color: var(--ink); font-weight: 600; }
.fontes__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 4px 18px;
}
.fontes__quando {
  grid-column: 2;
  padding-top: 7px;
  border-top: 1px solid var(--border);
}

/* Seletor de carteira do gráfico de evolução (Mercado). Mesma barra de
   filtros dos chips de janela, uma linha abaixo: o gráfico tem dois recortes
   — período e carteira — e eles pertencem ao mesmo controle. */
.filtros__carteira { display: flex; align-items: center; gap: 9px; font-size: 0.8rem; }
.filtros__carteira select {
  flex: 1; min-width: 0;
  padding: 5px 9px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink);
  font: inherit; font-size: 0.8rem;
}

/* A coluna da janela escolhida é a que o usuário está olhando: ganha peso
   para não se perder entre as fixas. */
.table td.periodo { font-weight: 700; line-height: 1.2; }

/* Equivalente ao ano, embaixo do acumulado. Menor e apagado: o acumulado e a
   resposta pedida, o ao ano e a referencia que evita a leitura errada de
   "+408%" como se fosse por ano. */
.periodo__aa {
  font-size: 0.66rem;
  font-weight: 600;
  opacity: 0.72;
  margin-top: 1px;
}

/* Bandeira de país na tabela de bolsas. Tamanho fixo e borda de 1px: sem a
   borda, bandeira com campo branco (Japão, Suíça) some no fundo escuro. */
.flag {
  width: 20px; height: 15px; flex: none;
  border-radius: 2px;
  box-shadow: 0 0 0 1px var(--border);
}

/* Posição mundial da bolsa. Tipografia menor e apagada: ordena a leitura sem
   competir com o nome do índice. */
.table .rank {
  color: var(--muted);
  font-size: 0.76rem;
  font-variant-numeric: tabular-nums;
  text-align: right;
  padding-right: 12px;
}

/* A linha do Brasil ganha marca à esquerda. O ponto da tabela é justamente
   onde a B3 cai no mundo — e sem destaque ela se perde entre as outras. */
.table tr.is-brasil td:first-child { box-shadow: inset 3px 0 0 var(--aqua); }
.table tr.is-brasil .rank { color: var(--aqua); font-weight: 700; }

/* Linha de agrupamento dentro da tabela. Substitui o recurso de quebrar a
   tabela em vários blocos lado a lado, que era o que estourava a largura.
   No Tesouro ela também é o botão de abrir e fechar o grupo. */
.table .row-group td {
  background: var(--surface-2);
  height: 32px;
  cursor: pointer;
  user-select: none;
}
.table tbody tr.row-group:hover td { background: var(--surface-3); }
/* Sinal e nome na mesma linha: no celular a coluna encolhia e o "+" ficava
   sozinho em cima do nome. */
.table .row-group td:first-child { white-space: nowrap; }

.row-group__sinal {
  display: inline-block;
  width: 16px; height: 16px;
  margin-right: 8px;
  border: 1px solid var(--border);
  border-radius: 3px;
  background: var(--surface);
  color: var(--aqua);
  font-size: 0.8rem;
  font-weight: 700;
  line-height: 14px;
  text-align: center;
  vertical-align: middle;
}
.row-group.is-aberto .row-group__sinal { background: var(--aqua); color: #052f3a; border-color: var(--aqua); }

.row-group__nome {
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--aqua);
  white-space: nowrap;
}

/* O resumo é o que faz o grupo recolhido continuar informando: quantos
   títulos, a faixa de taxa e a de vencimento. Sem ele, recolher só esconderia
   a informação e obrigaria a abrir tudo de novo. */
.row-group__resumo {
  font-size: 0.74rem;
  font-weight: 400;
  color: var(--muted);
  text-transform: none;
  letter-spacing: 0;
}
/* Só o span ao lado do nome ganha recuo e quebra de linha: o resto do resumo
   são CÉLULAS da tabela, e `display:block` numa td desmonta as colunas. */
span.row-group__resumo { margin-left: 10px; }

@media (max-width: 620px) {
  span.row-group__resumo { display: block; margin: 2px 0 0 24px; }
}

/* Texto secundário. As telas escrevem class="muted" em 28 lugares — legenda de
   gráfico, unidade, data de referência, nota de rodapé — e a classe NUNCA foi
   declarada: o texto saía na cor cheia e nada era secundário de fato. Mesmo
   padrão dos tokens --ok/--warn que faltavam antes; auditado com um diff entre
   as classes usadas nas telas e as declaradas aqui. */
.muted { color: var(--muted); }

/* Chip de seleção da consulta livre. O layout vem inline da própria tela; o
   que falta aqui é só o estado, que inline não alcança. */
.chip:hover { background: var(--surface-2); }
.chip:has(input:checked) { background: color-mix(in srgb, var(--aqua) 18%, var(--surface)); border-color: var(--aqua); }

/* Linha chave/valor.
   Era flex com `space-between`: com rótulo longo de um lado e texto longo do
   outro, os dois cresciam até se encostarem e a leitura virava uma coisa só.
   Grid de duas colunas resolve — o rótulo tem largura própria e o valor quebra
   dentro da dele. Abaixo de 520px vira uma coluna, porque duas não cabem. */
.kv {
  display: grid;
  grid-template-columns: minmax(90px, 34%) 1fr;
  gap: 6px 12px;
  padding: 7px 0;
  font-size: 0.88rem;
  align-items: start;
}
.kv + .kv { border-top: 1px solid var(--border); }
.kv > b { color: var(--muted); font-weight: 600; }
.kv > span { font-variant-numeric: tabular-nums; text-align: right; overflow-wrap: anywhere; }

@media (max-width: 520px) {
  .kv { grid-template-columns: 1fr; gap: 2px; }
  .kv > span { text-align: left; }
}

/* Botões ---------------------------------------------------------------- */
/* Botão primário sólido, não degradê: sobre fundo escuro o degradê aqua vira
   um borrão e o rótulo perde contraste na ponta clara. Texto escuro sobre
   aqua cheio dá 8,9:1, contra 3,1:1 do branco sobre o mesmo aqua. */
.btn {
  display: inline-flex; align-items: center; gap: 7px;
  border: 0;
  border-radius: var(--radius-sm);
  padding: 9px 15px;
  font: 700 0.86rem inherit;
  color: #052f3a;
  background: var(--aqua);
  cursor: pointer;
  white-space: nowrap;
}
.btn:hover:not(:disabled) { background: #4de2f7; }
.btn:disabled { opacity: 0.45; cursor: default; }
.btn--ghost { background: var(--surface-2); color: var(--ink); border: 1px solid var(--border); }
.btn--ghost:hover:not(:disabled) { background: var(--surface-3); }
.btn--amber { background: var(--amber); color: #2a1800; }
.btn--amber:hover:not(:disabled) { background: #ffc76e; }
.btn--sm { padding: 6px 11px; font-size: 0.78rem; border-radius: 7px; }
.btn--block { width: 100%; }

/* Campos ---------------------------------------------------------------- */
.field { display: block; }
.field > label {
  display: block; font-size: 0.78rem; font-weight: 600;
  color: var(--muted); margin: 0 0 5px;
}
.field input, .field select {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: 0.92rem;
  background: var(--surface);
  color: var(--ink);
  outline: none;
}
.field input:focus, .field select:focus { border-color: var(--aqua); box-shadow: 0 0 0 3px rgba(27, 189, 212, 0.15); }
.field + .field { margin-top: 12px; }
.field-row { display: flex; gap: 12px; flex-wrap: wrap; }
.field-row > .field { flex: 1 1 180px; margin-top: 0; }

/* Eco do valor interpretado. Aparece embaixo do campo quando o que foi
   digitado tem ponto ou vírgula — o momento em que "139.400" pode virar
   139,40 sem ninguém ver. Ocupa altura fixa para o formulário não pular
   enquanto se digita. */
.field-echo {
  min-height: 1.05em;
  margin-top: 4px;
  font-size: 0.76rem;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.field-echo--err { color: var(--danger); }

/* Tabela ---------------------------------------------------------------- */
.table-wrap { overflow-x: auto; }

/* Comparação no celular: quatro colunas de ativo não cabem em 390px, e ao
   rolar para o lado o NOME do indicador saía da tela — a pessoa ficava vendo
   números sem saber de quê. A primeira coluna gruda na esquerda.

   Só abaixo de 900px: no desktop a tabela cabe inteira e a sombra do sticky
   seria enfeite. */
@media (max-width: 900px) {
  .table--comparacao th:first-child,
  .table--comparacao td:first-child {
    position: sticky;
    left: 0;
    z-index: 1;
    background: var(--surface);
    /* A borda separa o rótulo fixo dos números que passam por baixo. Sem ela
       o texto encosta no número e os dois viram uma coisa só. */
    box-shadow: 1px 0 0 var(--border);
  }
  /* A faixa de seção atravessa a tabela inteira: se ela também grudasse,
     ficaria uma tarja solta por cima das colunas ao rolar. */
  .table--comparacao td[colspan] { position: static; box-shadow: none; }
}
.table { width: 100%; border-collapse: collapse; font-size: 0.86rem; }

/* Tabela de mercado: a mais apertada do produto. Sao onze colunas em metade
   da tela, e cada pixel economizado aqui e o que evita a barra horizontal —
   que foi exatamente o defeito reportado. Fonte menor, respiro minimo e
   larguras fixas nas colunas de numero. */
.table--mercado { font-size: 0.76rem; }
.table--mercado td, .table--mercado th { padding-left: 5px; padding-right: 5px; }
.table--mercado .ident__nome { font-size: 0.79rem; }
.table--mercado .ident__sub { font-size: 0.68rem; }
.table--mercado .flag { width: 17px; height: 13px; }
.table--mercado td.cap::before { font-size: 0.65rem; }
.table--mercado .rank { font-size: 0.7rem; padding-right: 6px; }
.table th {
  text-align: left; padding: 7px 10px;
  font-size: 0.68rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.05em; color: var(--muted);
  background: var(--surface-2);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
  position: sticky; top: 0; z-index: 1;
}
.table td {
  height: var(--row-h);
  padding: 5px 10px;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}
.table tbody tr:hover td { background: var(--surface-2); }
.table tr:last-child td { border-bottom: 0; }
/* ── Coluna de ações ──────────────────────────────────────────────────────
   NÃO usar `display:flex` no <td>: a célula deixa de ser table-cell, sai do
   fluxo da tabela e a linha PARA DE CRESCER com o conteúdo. Com cinco botões
   (abrir, editar, PIN, restringir, remover) eles quebravam para fora da
   própria linha e se encavalavam com a linha de baixo — e, como
   `.table-wrap` tem `overflow-x:auto`, o eixo vertical vira `auto` junto e a
   tabela ainda ganhava uma barra de rolagem própria. Foi o defeito que o
   Arnaldo mandou em print na tela de Clientes.

   A célula continua sendo célula; quem flui são os botões, como inline-flex
   com margem. Quebra de linha natural, altura da linha acompanha. */
.table td.actions { white-space: normal; }
/* O rótulo do botão nunca quebra dentro dele: "Trocar / PIN" em duas linhas
   engorda a linha inteira da tabela. Quem quebra é a lista de botões. */
.table td.actions > .btn { white-space: nowrap; }

/* Botão só de ícone: quadrado, sem o padding lateral de um botão com texto.
   É o que permite cinco ações caberem numa linha de tabela. O significado
   fica no `title` e no `aria-label` — nunca só na forma do desenho. */
.btn--ico { padding: 5px 7px; }
.btn--ico .ico { margin: 0; }

/* Ação sem volta ganha a cor de atenção na borda, não no fundo: fundo
   vermelho num botão de tabela puxa o olho para o que menos deve ser
   clicado. */
.btn--perigo { border-color: color-mix(in srgb, var(--danger) 45%, var(--border)); }
.btn--perigo:hover { border-color: var(--danger); color: var(--danger); }
.table td.actions > .btn,
.table td.actions > span,
.table td.actions > form {
  display: inline-flex;
  align-items: center;
  vertical-align: middle;
  margin: 3px 6px 3px 0;
}

/* Coluna de valor: à direita e tabular. Dinheiro alinhado à esquerda obriga o
   olho a reencontrar a vírgula em cada linha. */
.table .num, .table th.num { text-align: right; font-variant-numeric: tabular-nums; }
/* Sinal do resultado. A cor é o dado — não repetir o sinal em palavra. */
.num--up { color: var(--ok); }
.num--down { color: var(--danger); }

/* Pills e badges -------------------------------------------------------- */
.pill {
  display: inline-block; padding: 2px 10px; border-radius: 999px;
  font-size: 0.72rem; font-weight: 700;
}
/* No tema escuro a pill é a cor semântica DILUÍDA NO FUNDO, nunca no branco.
   O `color-mix(..., #fff)` anterior clareava o chip até virar um retângulo
   pastel claro no meio de uma tela navy — chamava mais atenção que o número
   que ele qualificava. Aqui o fundo é 18% da cor sobre --surface e o texto é a
   cor cheia, que é o padrão que mantém o contraste em AA nos cinco níveis. */
.pill--ok { background: color-mix(in srgb, var(--ok) 18%, var(--surface)); color: var(--ok); }
.pill--off { background: var(--surface-3); color: var(--muted); }
.pill--info { background: color-mix(in srgb, var(--info) 18%, var(--surface)); color: var(--info); }
/* Situação irregular da companhia na CVM (recuperação judicial, suspensão). */
.pill--warn {
  background: color-mix(in srgb, var(--warn) 18%, var(--surface));
  color: var(--warn);
  border: 1px solid color-mix(in srgb, var(--warn) 38%, var(--surface));
}
/* O bloco de risco emite pill--danger para "volatilidade muito alta" — é o
   caso que mais precisa saltar aos olhos, então é o único que ganha borda
   cheia além do fundo. */
.pill--danger {
  background: color-mix(in srgb, var(--danger) 18%, var(--surface));
  color: var(--danger);
  border: 1px solid color-mix(in srgb, var(--danger) 42%, var(--surface));
}

/* Níveis da régua de mercado (backend/marketRules.js). Os nomes são os
   mesmos que o backend devolve em `level`, de propósito: a tela não traduz
   nível em cor por conta própria — quem define a faixa é a régua. */
.pill--bom { background: color-mix(in srgb, var(--ok) 18%, var(--surface)); color: var(--ok); }
.pill--atencao { background: color-mix(in srgb, var(--warn) 18%, var(--surface)); color: var(--warn); }
.pill--ruim { background: color-mix(in srgb, var(--danger) 18%, var(--surface)); color: var(--danger); }
.pill--neutro { background: var(--surface-3); color: var(--muted); }

/* Múltiplos: o número grande e, logo abaixo, a régua que diz o que ele
   significa. Sem a régua o gestor precisa saber de cor a convenção de cada
   indicador — que era exatamente a lacuna. */
.mult__value { font-size: 1.5rem; font-weight: 700; line-height: 1.1; color: var(--ink); }
.mult__head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.mult__range { font-size: 0.8rem; color: var(--muted); margin-top: 6px; line-height: 1.45; }

/* Diálogo modal (<dialog> nativo — sem biblioteca) ---------------------- */
/* O <dialog> nativo vem com fundo branco do agente de usuário — sem declarar
   background aqui o modal abria como um retângulo branco sobre a tela escura. */
.modal {
  border: 1px solid var(--border);
  padding: 0;
  border-radius: var(--radius);
  width: calc(100% - 32px);
  max-width: 380px;
  background: var(--surface);
  color: var(--ink);
  box-shadow: 0 24px 60px -20px rgba(0, 0, 0, 0.85);
}
.modal::backdrop { background: rgba(9, 9, 11, 0.72); }
.modal__head {
  padding: 16px 18px;
  border-bottom: 1px solid var(--border);
  font-size: 0.98rem;
  font-weight: 700;
}
.modal__body { padding: 18px; }
.modal__foot {
  display: flex; justify-content: flex-end; gap: 8px;
  padding: 14px 18px;
  background: var(--surface-2);
  border-top: 1px solid var(--border);
}

/* Mensagem inline (sucesso/erro) ---------------------------------------- */
.msg { margin-top: 12px; font-size: 0.85rem; min-height: 1.1em; }
.msg--err { color: var(--err); }
.msg--ok { color: var(--green); }

/* ── 5. Estados ────────────────────────────────────────────────────────── */
/* Um único componente cobre carregando / vazio / erro / indisponível —
   assim nenhuma tela inventa o seu próprio jeito de comunicar o mesmo. */
.state {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  padding: 30px 18px; text-align: center; color: var(--muted); font-size: 0.88rem;
}
.state__icon { color: var(--muted); display: flex; }
.state__title { font-weight: 700; color: var(--ink); font-size: 0.95rem; }
.state--error .state__icon, .state--error .state__title { color: var(--danger); }

/* Spinner do estado "carregando" */
.spinner {
  width: 22px; height: 22px; border-radius: 50%;
  border: 3px solid var(--border); border-top-color: var(--aqua);
  animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ── 6. Telas ──────────────────────────────────────────────────────────── */
/* Login / criação de escritório ----------------------------------------- */
.auth-screen { min-height: 100vh; display: flex; flex-direction: column; background: var(--bg); }
/* Sem faixa de degradê colorido: a marca aparece pelo logo e pela tipografia.
   O degradê aqua era a coisa mais chamativa da primeira tela do produto e não
   dizia nada sobre ele. */
.auth-hero {
  text-align: center;
  padding: 56px 20px 28px;
}
.auth-hero .brand { justify-content: center; }
.auth-hero h1 { font-size: 1.75rem; font-weight: 800; letter-spacing: -0.5px; color: var(--ink); }
.auth-hero p { color: var(--muted); margin-top: 8px; font-size: 0.93rem; }
.auth-body { flex: 1; display: flex; justify-content: center; padding: 20px 18px 40px; }
.auth-card { width: 100%; max-width: 400px; align-self: flex-start; }

.tabs { display: flex; gap: 4px; background: var(--bg); border: 1px solid var(--border); border-radius: 9px; padding: 4px; margin-bottom: 18px; }
.tabs button {
  flex: 1; border: 0; background: transparent; padding: 9px; border-radius: 6px;
  font: 600 0.86rem inherit; color: var(--muted); cursor: pointer;
}
.tabs button.is-active { background: var(--surface-3); color: var(--ink); }

.auth-foot { text-align: center; color: var(--muted); font-size: 0.76rem; padding: 14px; }

/* Análise de Empresa ---------------------------------------------------- */
.search-bar { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; }
.search-bar .field { flex: 1 1 220px; }
#ticker-input { text-transform: uppercase; letter-spacing: 0.04em; font-weight: 600; }
/* O uppercase vale para o que o usuário digita, não para a dica: sem isto o
   placeholder vira "EX.: PETR4", que parece erro de digitação. */
#ticker-input::placeholder { text-transform: none; letter-spacing: normal; font-weight: 400; }

/* Comparação de ativos --------------------------------------------------
   O campo desta tela recebe de dois a quatro códigos de cinco letras: cabe em
   420px. Com o `flex: 1 1 220px` da barra ele crescia sem teto e, num monitor
   largo, o botão "Comparar" terminava a meia tela do que se acabou de digitar.
   O teto vale só aqui — na Análise de Empresa a barra ocupa a linha inteira de
   propósito. */
.search-bar--compact .field { flex: 0 1 420px; }

/* <select> que vive solto numa linha de texto, fora de um `.field`. Sem isto
   o navegador desenha o controle nativo — claro, no tema escuro — e ele fica
   sendo o único elemento fora do tema na tela. */
.select-inline {
  padding: 7px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: 0.82rem;
  background: var(--surface-2);
  color: var(--ink);
  outline: none;
  max-width: 260px;
}
.select-inline:focus { border-color: var(--aqua); box-shadow: 0 0 0 3px rgba(27, 189, 212, 0.15); }

/* Busca numa linha só (11/09/2026): campo, botão e atalho do cliente. Os três
   controles com a MESMA altura — o botão era 8px mais baixo que o campo e
   ficava desalinhado da caixa de texto ao lado. */
.compare-busca #compare-input,
.compare-busca .btn,
.compare-busca .select-inline { height: 42px; }
.compare-busca .btn { padding-block: 0; }
.compare-busca .select-inline { font-size: 0.88rem; min-width: 200px; }

/* O atalho do cliente é outra forma de preencher o mesmo campo: fica na
   linha, separado por um fio, e só quebra para baixo em tela estreita. */
.compare-cliente { margin-left: 14px; padding-left: 24px; border-left: 1px solid var(--border); }
.compare-cliente:empty { display: none; }
.compare-cliente__linha {
  display: flex; gap: 10px; align-items: center; flex-wrap: wrap; font-size: 0.78rem;
}
/* Recado vazio fora do fluxo: com `flex-wrap`, o span sem texto caía numa
   segunda linha invisível e empurrava o seletor 10px acima do campo ao lado. */
.compare-cliente__linha > span:empty { display: none; }
/* Mensagem de validação vazia não ocupa altura: eram 27px sobrando no cartão. */
.compare-busca + .msg:empty { display: none; }
@media (max-width: 760px) {
  .compare-cliente { flex-basis: 100%; margin-left: 0; padding-left: 0; border-left: 0; }
}

/* Tela vazia: o estado e os atalhos no MESMO cartão. Soltos na página, o ícone
   ficava centralizado num vazio da altura da tela e os pares liam como rodapé
   de outra coisa. Estado mais baixo, para os pares subirem. */
.compare-vazio { margin-top: 16px; text-align: center; }
.compare-vazio .state { padding: 18px 18px 8px; gap: 4px; }
.compare-pares__dica { color: var(--muted); font-size: 0.78rem; margin-bottom: 12px; }

/* Pares prontos em CARDS: os dois tickers em destaque e o setor embaixo. */
.compare-pares__lista {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  gap: 10px; max-width: 1120px; margin: 0 auto;
}
.compare-par {
  display: flex; flex-direction: column; align-items: flex-start; gap: 3px;
  padding: 12px 14px;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface-2); color: var(--ink);
  font: inherit; text-align: left; cursor: pointer;
  transition: border-color .15s, background .15s;
}
.compare-par:hover { border-color: var(--aqua); background: var(--surface-3); }
.compare-par:focus-visible { outline: 2px solid var(--aqua); outline-offset: 2px; }
.compare-par__tickers { font-weight: 700; font-size: 0.95rem; letter-spacing: 0.02em; }
.compare-par__x { color: var(--muted); font-weight: 400; margin: 0 6px; }
.compare-par__setor { color: var(--muted); font-size: 0.75rem; }

.ai-card { margin-top: 16px; }
.ai-block + .ai-block { margin-top: 12px; }
.ai-block h4 { font-size: 0.8rem; font-weight: 700; color: var(--teal-d); margin-bottom: 5px; }
.ai-block p { font-size: 0.89rem; line-height: 1.55; }
.ai-block ul { margin-left: 18px; font-size: 0.89rem; line-height: 1.55; }
.ai-block ul li + li { margin-top: 3px; }
.ai-disclaimer {
  margin-top: 14px; padding-top: 10px; border-top: 1px solid var(--border);
  color: var(--muted); font-size: 0.74rem; font-style: italic;
}
.source-note { margin-top: 12px; font-size: 0.75rem; color: var(--muted); }

/* ── 8. Ícones ─────────────────────────────────────────────────────────── */
/*
   Os ícones eram emoji (💹 na marca, 📊 💼 ⚖️ 🔎 🔔 no menu, 🧾 📈 🧭 nos
   títulos de seção). Emoji tem três defeitos num produto financeiro: o desenho
   muda por sistema operacional, a cor é fixa e não acompanha o tema, e o
   registro visual é informal — nenhum concorrente do segmento usa.

   A troca é por um sprite SVG único, declarado inline no fim do index.html e
   referenciado por <svg class="ico"><use href="#ico-nome"></use></svg>.
   Inline, e não em arquivo à parte, porque nesta stack cada estático é uma
   invocação de Lambda (ver comentário em backend/app.js) — o sprite pega
   carona no HTML que já vai de qualquer jeito.
   `currentColor` no traço faz o ícone herdar a cor do texto ao redor, então
   ele acompanha estado (ativo, silenciado, perigo) de graça.
*/
.ico {
  width: 18px; height: 18px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.ico--sm { width: 15px; height: 15px; }
.ico--lg { width: 26px; height: 26px; stroke-width: 1.4; }

/* Marca — símbolo + palavra, no lugar do emoji 💹 */
.brand { display: flex; align-items: center; gap: 9px; }
.brand__mark { width: 26px; height: 26px; flex: none; }
.brand__text { font-weight: 800; letter-spacing: -0.3px; }
.brand__text em { font-style: normal; color: var(--aqua); }

/* ── 9. KPIs ───────────────────────────────────────────────────────────── */
/* Faixa de indicadores no topo da tela (padrão CredBusiness). O número é o
   protagonista: rótulo pequeno em cima, valor grande, variação embaixo. */
.kpi-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 12px;
  margin-bottom: 16px;
}
.kpi {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px 16px;
}
.kpi__label {
  font-size: 0.68rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.07em; color: var(--muted);
}
.kpi__value {
  font-size: 1.55rem; font-weight: 700; line-height: 1.15; margin-top: 7px;
  letter-spacing: -0.5px;
}
.kpi__delta { font-size: 0.8rem; font-weight: 600; margin-top: 5px; color: var(--muted); }
/* Segunda linha do KPI, para quando o numero principal precisa dizer contra o
   que ele se compara (spot de mercado x PTAX oficial do dolar). Menor e mais
   apagada que o delta de proposito: e nota de rodape, nao um segundo numero. */
.kpi__nota {
  margin-top: 7px;
  padding-top: 6px;
  border-top: 1px solid var(--border);
  font-size: 0.72rem;
  font-weight: 500;
  line-height: 1.4;
  color: var(--muted);
}
.kpi__delta .num--up { color: var(--ok); }
.kpi__delta .num--down { color: var(--danger); }
/* Destaque do KPI principal da tela (AUM, patrimônio) — barra de acento à
   esquerda em vez de fundo colorido, que competiria com os números. */
.kpi--lead { border-left: 3px solid var(--aqua); }

/* ── 9.1 Mesa ──────────────────────────────────────────────────────────── */
/*
   Duas colunas: à esquerda o que se lê (clientes, o que mexeu), à direita o
   que se age (fila de atenção, alocação, concentração). A coluna da direita é
   fixa em 380px porque o conteúdo dela é lista curta — deixá-la elástica faria
   a tabela de clientes encolher em tela média, que é o oposto do que se quer.

   Abaixo de 1100px vira coluna única, com a fila de atenção ainda no topo do
   bloco lateral: se só couber uma coisa na dobra, que seja o que pede ação.
*/
.desk-grid { display: grid; grid-template-columns: minmax(0, 1fr) 380px; gap: 16px; align-items: start; }

/* Mercado: os dois lados carregam a MESMA tabela de períodos, então a divisão
   é proporcional e não fixa. A esquerda cede largura porque tem rolagem própria
   e quinze linhas; a direita precisa de espaço porque tem as mesmas colunas em
   três linhas e não pode ficar espremida a ponto de rolar sempre.
   Abaixo de 1400px vira uma coluna — duas tabelas de nove colunas lado a lado
   nesse espaço não se leem. */
/* Mercado: bolsas a esquerda, referencias + regua + procedencia a direita.
   Divisao praticamente igual — as duas tabelas tem as mesmas colunas de
   periodo e precisam do mesmo espaco.
   Abaixo de 1500px nao cabem lado a lado: vira uma coluna, e ai cada tabela
   usa a largura inteira em vez de rolar de lado. */
/* 1,08 contra 1: a proporcao entre 795px (bolsas, onze colunas) e 744px
   (referencias, oito). Meio a meio deixava a de bolsas 51px curta — era a
   barra horizontal reportada. */
.desk-grid--mercado {
  grid-template-columns: minmax(0, 1.06fr) minmax(0, 1fr);
  /* Intervalo menor entre os paineis e respiro menor DENTRO dos cartoes:
     sao 28px devolvidos as tabelas. MEDIDO: as duas juntas precisavam de
     1.472px e a area dava 1.461 — faltavam 11px no TOTAL, nao na proporcao.
     Apertar a divisao so trocaria qual das duas ficava com a barra. */
  gap: 12px;
}

.desk-grid--mercado > div > .card { padding: 13px; }
/* As duas colunas terminam na MESMA linha: o último card de cada uma estica
   até a base da outra. Sem isso sobrava um retângulo preto embaixo da coluna
   mais curta — e a diferença muda com o gráfico, os grupos do Tesouro abertos
   e a largura da janela, então não há arranjo fixo de cards que a zere. */
.desk-grid--mercado { align-items: stretch; }
.desk-grid--mercado > div > .card:last-child { flex: 1 0 auto; }

@media (max-width: 1500px) {
  .desk-grid--mercado { grid-template-columns: 1fr; }
}

/* Total do mundo em trilhões: é referência consolidada, não cotação — cor
   diferente para não ser lida como preço ao vivo ao lado dos outros. */
.cap-total { color: var(--teal-d); font-weight: 700; white-space: nowrap; }

/* ── Célula de identificação do ativo ──────────────────────────────────── */
/*
   A célula quebrava em três e quatro linhas e a tabela virava uma pilha de
   blocos altos. O nome agora não quebra: se não couber, corta com reticências
   e o título completo fica no `title` do <td>.

   Uma linha de tabela alta não é só feio — ela reduz quantas bolsas cabem na
   dobra, que é justamente o que esta tela existe para mostrar de uma vez.

   O `display:flex` ficava no próprio <td> e tirava a célula do algoritmo de
   tabela: ela deixava de ser table-cell, ignorava a largura da coluna e
   desenhava a borda inferior só na largura do conteúdo — daí os traços soltos
   sob a coluna Índice, o desalinhamento com o cabeçalho e a impressão de linha
   quebrada. O flex agora vive num wrapper DENTRO da célula, que é o único
   lugar onde ele não conflita com o layout de tabela.
*/
.table td.ident { vertical-align: middle; }
.ident__row { display: flex; align-items: center; gap: 8px; min-width: 0; }
.ident__txt { min-width: 0; }
.ident__nome {
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: 1.25;
}
.ident__nome .pill { margin-left: 5px; vertical-align: middle; }
.ident__sub {
  color: var(--muted);
  font-size: 0.72rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: 1.25;
}

/* Valor de mercado da bolsa em trilhões. Fonte um pouco menor e apagada: é
   contexto de tamanho, não a cotação — não pode competir com os percentuais. */
.table td.cap { color: var(--teal-d); font-weight: 600; }
.table td.cap::before { content: 'US$ '; color: var(--muted); font-weight: 400; font-size: 0.72rem; }
.desk-grid__main, .desk-grid__side { display: flex; flex-direction: column; gap: 16px; min-width: 0; }

/* A faixa de largura total (`.desk-grid__faixa`, `grid-column: 1 / -1`) foi
   removida em 01/09/2026 junto com o ultimo cartao que a usava. Ela existia
   para o que nao coubesse em meia tela, e no fim so servia de estacionamento:
   o cartao ia para o rodape e a coluna mais curta ficava com um retangulo
   preto do tamanho da diferenca. Hoje cada cartao da Mesa mora numa das duas
   colunas, escolhidas para as alturas se aproximarem. */

/* A regra global `.card + .card` empilha margem entre cartões; dentro da Mesa
   quem separa é o `gap` do flex, senão o espaço sai dobrado. */
.desk-grid .card + .card { margin-top: 0; }

/* O radar mora na coluna da direita da Mesa, e o involucro dele nasce no HTML
   ANTES de saber se existe radar (a IA pode estar desligada na conta, ou a
   chamada pode falhar — nos dois casos o JS esvazia o div).
   Div vazio nao ocupa altura, mas continua sendo item do flex e leva o `gap`
   junto: sem esta regra a coluna ganhava 16px de sobra no rodape sempre que
   nao havia radar. */
#radar-root:empty { display: none; }

/* O radar nasceu como cartao de largura total logo abaixo dos KPIs e carrega
   dai a margem de baixo. Dentro da coluna quem separa e o `gap` do flex. */
.desk-grid .radar-card { margin-bottom: 0; }

@media (max-width: 1100px) {
  .desk-grid { grid-template-columns: 1fr; }
}

/* Radar de IA — ocupa a largura toda logo abaixo dos KPIs. Acento à esquerda
   em vez de fundo colorido: é o único bloco da tela escrito por um modelo, e
   isso precisa ser visível sem que ele grite mais alto que os números. */
.radar-card { border-left: 3px solid var(--aqua); margin-bottom: 16px; }
.radar-list { display: flex; flex-direction: column; }
.radar-item { display: flex; gap: 9px; align-items: flex-start; padding: 9px 0; }
.radar-item + .radar-item { border-top: 1px solid var(--border); }
.radar-item .sev-dot { margin-top: 6px; }

/* Carta do cliente — o único bloco do produto que é PROSA, e por isso o único
   que abandona a densidade de terminal: linha mais alta e medida de leitura
   limitada a ~72 caracteres. Texto corrido na largura do cartão seria ilegível
   e não pareceria o que é: um documento para o cliente final. */
.letter { max-width: 72ch; }
.letter__title { font-size: 1.02rem; font-weight: 700; margin-bottom: 12px; }
.letter p { font-size: 0.91rem; line-height: 1.65; margin-bottom: 11px; }
.letter__notes { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border); }
.letter__notes h4 {
  font-size: 0.7rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.07em; color: var(--muted); margin-bottom: 7px;
}
.letter__notes ul { margin-left: 18px; font-size: 0.87rem; line-height: 1.55; }
.letter__notes li + li { margin-top: 4px; }

/* ── Topo da Mesa: carteira e janela ───────────────────────────────────── */
.mesa-topo {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}
.mesa-topo__carteira { display: flex; align-items: center; gap: 9px; font-size: 0.82rem; }
.mesa-topo__carteira select {
  padding: 7px 11px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-size: 0.85rem;
  font-weight: 600;
  min-width: 240px;
}
.mesa-topo__unico { font-size: 0.92rem; font-weight: 700; }
.mesa-topo__janela { display: flex; gap: 6px; flex-wrap: wrap; }

/* A Mesa divide a primeira linha entre o ARCA (esquerda) e o comparativo
   (direita, com a alocação embaixo). A esquerda leva um pouco mais porque
   carrega a tabela de blocos, que tem seis colunas; a direita precisa de
   ~700px para o gráfico não virar um risco achatado. Numa área útil de
   1.660px isso dá ~900px e ~730px. */
.desk-grid--mesa { grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); }

@media (max-width: 1200px) {
  .desk-grid--mesa { grid-template-columns: 1fr; }
}

/* ── Rosca de alocação ─────────────────────────────────────────────────── */
.rosca-bloco { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.rosca { width: 132px; height: 132px; flex: none; }
.rosca__rotulo { fill: var(--muted); font-size: 6px; letter-spacing: 0.08em; font-weight: 700; }
.rosca__valor { fill: var(--ink); font-size: 8px; font-weight: 700; letter-spacing: -0.2px; }

.rosca-legenda { flex: 1; min-width: 190px; display: flex; flex-direction: column; gap: 5px; }
.rosca-legenda__item {
  display: grid;
  grid-template-columns: 10px 1fr auto auto;
  gap: 8px;
  align-items: center;
  font-size: 0.79rem;
  font-variant-numeric: tabular-nums;
}
.rosca-legenda__cor { width: 9px; height: 9px; border-radius: 2px; }
.rosca-legenda__nome { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rosca-legenda__pct { font-weight: 700; }
.rosca-legenda__valor { font-size: 0.72rem; }

/* Linha da fila de atenção */
.attn { display: flex; gap: 9px; align-items: flex-start; padding: 9px 0; }
.attn + .attn { border-top: 1px solid var(--border); }
.attn .sev-dot { margin-top: 6px; }

/* Par de blocos lado a lado (maiores ganhos / maiores perdas) */
.grid-2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 14px; }
/* Duas colunas desiguais: a da esquerda leva uma série temporal (precisa de
   largura para as barras respirarem) e a da direita uma rosca, que é quadrada.
   Em telas estreitas volta a empilhar. */
@media (min-width: 1100px) {
  .grid-2--largo { grid-template-columns: minmax(0, 1.9fr) minmax(0, 1fr); }
}

/* ── 10. Gráficos ──────────────────────────────────────────────────────── */
/*
   SVG desenhado no próprio cliente (assets/chart.js). Sem biblioteca: a stack
   é serverless sem build, e um CDN seria bloqueado pelo CSP do portal. O que
   o produto precisa cabe em quatro formas — linha, área, barra e waterfall.
*/
.chart { width: 100%; display: block; overflow: visible; }
.chart__grid { stroke: var(--border); stroke-width: 1; }
.chart__axis { fill: var(--muted); font-size: 10px; font-variant-numeric: tabular-nums; }

/* Marcacao de virada de ano. Tracejada e apagada: e regua, nao dado — se
   competisse com as curvas, o olho pararia nela em vez de na inclinacao. */
.chart__ano { stroke: var(--surface-3); stroke-width: 1; stroke-dasharray: 4 4; }
.chart__ano-rotulo {
  fill: var(--ink);
  font-size: 11px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.chart__line { fill: none; stroke: var(--aqua); stroke-width: 2; stroke-linejoin: round; }
/* Série de comparação (CDI, IBOV): tracejada e apagada, para nunca disputar
   leitura com a carteira do cliente. */
.chart__line--ref { stroke: var(--muted); stroke-width: 1.5; stroke-dasharray: 4 3; }
.chart__area { fill: var(--aqua); opacity: 0.12; }
.chart__bar { fill: var(--aqua); }
.chart__bar--up { fill: var(--ok); }
.chart__bar--down { fill: var(--danger); }
/* Barras da série de renda (chart.barras). O histórico fica apagado e os 12
   meses da janela corrente ficam cheios: é a janela que sustenta os KPIs do
   painel, e ela precisa se distinguir sem virar uma segunda cor no gráfico. */
.chart__bar { fill: color-mix(in srgb, var(--aqua) 45%, transparent); }
.chart__bar.is-recent { fill: var(--aqua); }
.chart__bar.is-down { fill: var(--danger); }

/* Gráfico de RESULTADO (aba Vendas): aqui a barra positiva é lucro, e lucro
   no mercado é verde — o aqua do gráfico de renda não carrega esse sentido.
   Escopado no container para não repintar os demais gráficos do produto.

   A cor NUNCA é a única leitura: as barras nascem da linha do zero, então
   lucro e prejuízo se distinguem pela posição. É exigência medida, não
   preferência — o verde e o vermelho deste tema ficam a ΔE 7,9 em
   deuteranopia, abaixo do mínimo de 8 para separação só por cor.

   A opacidade subiu de 55% para 78% (e de 70% para 88% no prejuízo) quando a
   altura das barras passou a ser a do valor puro, sem piso: a barra do ano
   pequeno tem poucos pixels de altura, e translúcida ela se dissolvia no fundo
   do painel. Aumentar o contraste devolve visibilidade sem tocar no tamanho —
   que é o que carrega o número. */
.chart--resultado .chart__bar { fill: color-mix(in srgb, var(--ok) 78%, transparent); }
.chart--resultado .chart__bar.is-down { fill: color-mix(in srgb, var(--danger) 88%, transparent); }

/* Contorno de meio pixel na mesma cor: numa barra de 1–2px o preenchimento
   sozinho fica na fronteira do anti-aliasing e some conforme o zoom. O traço
   não engorda a leitura (é a mesma cor, meio pixel de cada lado). */
.chart--resultado .chart__bar { stroke: var(--ok); stroke-width: 0.5; }
.chart--resultado .chart__bar.is-down { stroke: var(--danger); }

/* Linha do zero: mais forte que a grade, porque é a base de leitura da barra. */
.chart__axis-line { stroke: var(--border); stroke-width: 1.5; }

/* Rotulo de dados sobre a barra. Mais forte que o eixo (e dado, nao regua) e
   com tabular-nums para os valores alinharem entre as colunas. So aparece em
   serie curta — quem chama passa `rotuloValor`. */
.chart__value {
  fill: var(--ink);
  font-size: 10px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.chart__value.is-down { fill: var(--err); }
/* Dentro da barra o texto fica sobre o verde/vermelho cheio: precisa do
   contraste invertido, senao some. */
.chart__value.is-inside { fill: var(--bg); }

/* Barras empilhadas: dividendo e JCP. Duas cores só, e a segunda é o âmbar do
   tema — não uma cor nova. JCP tem 15% de IR retido, então distingui-lo do
   dividendo não é enfeite: é a diferença entre o bruto e o que cai na conta. */
.chart__stack--0 { fill: var(--aqua); }
.chart__stack--1 { fill: var(--amber); }
.chart__line--acum { stroke: var(--ok); stroke-width: 2; fill: none; stroke-dasharray: 5 3; }
.chart__axis--acum { fill: var(--ok); opacity: 0.8; }
.chart-legend i.chart-swatch--0 { background: var(--aqua); }
.chart-legend i.chart-swatch--1 { background: var(--amber); }
.chart-legend i.chart-swatch--acum { background: var(--ok); }

/* Legenda da rosca. Grade de quatro colunas para nome, valor e percentual
   ficarem alinhados entre as linhas — em flex simples cada linha alinha por
   conta própria e a coluna de números vira escada. */
.rosca-legenda { display: flex; flex-direction: column; gap: 6px; margin-top: 12px; }
.rosca-legenda__item {
  display: grid;
  grid-template-columns: 12px 1fr auto auto;
  align-items: center;
  gap: 8px;
  font-size: 0.83rem;
}
.rosca-legenda__item i { width: 12px; height: 12px; border-radius: 3px; flex: none; }
.rosca-legenda__nome { color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rosca-legenda__item b { font-variant-numeric: tabular-nums; }
.rosca-legenda__pct { color: var(--muted); font-variant-numeric: tabular-nums; min-width: 46px; text-align: right; }

/* Ranking em barras horizontais (chart.ranking). Grade de três colunas para os
   valores ficarem alinhados à direita entre si — número desalinhado obriga o
   leitor a comparar contando dígitos. */
.rank-bars { display: flex; flex-direction: column; gap: 7px; margin-top: 10px; }
.rank-bars__row {
  display: grid;
  grid-template-columns: 88px 1fr auto;
  align-items: center;
  gap: 10px;
}
.rank-bars__label {
  font-size: 0.82rem; font-weight: 700; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
}
.rank-bars__track { background: var(--surface-3); border-radius: 4px; height: 16px; overflow: hidden; }
.rank-bars__bar { height: 100%; background: var(--aqua); border-radius: 4px; }
.rank-bars__row--baixo .rank-bars__bar { background: var(--muted); }
.rank-bars__value {
  font-size: 0.82rem; font-variant-numeric: tabular-nums; text-align: right;
  min-width: 92px;
}
@media (max-width: 520px) {
  .rank-bars__row { grid-template-columns: 66px 1fr auto; gap: 7px; }
  .rank-bars__value { min-width: 78px; font-size: 0.76rem; }
}
.chart__dot { fill: var(--aqua); }

/* Barras divergentes (contribuição para o resultado) */
/* Janela rolavel do grafico divergente. Lista longa (todos os papeis no lucro)
   rola por dentro em vez de empurrar a tabela abaixo para fora da tela.
   `overscroll-behavior` impede que o fim da lista continue rolando a pagina. */
.diverge-scroll {
  overflow-y: auto;
  overscroll-behavior: contain;
  padding-right: 6px;
}
.diverge-scroll::-webkit-scrollbar { width: 8px; }
.diverge-scroll::-webkit-scrollbar-track { background: transparent; }
.diverge-scroll::-webkit-scrollbar-thumb {
  background: var(--surface-3);
  border-radius: 4px;
}
.diverge-scroll::-webkit-scrollbar-thumb:hover { background: var(--border); }
/* Firefox nao tem os pseudo-elementos acima. */
.diverge-scroll { scrollbar-width: thin; scrollbar-color: var(--surface-3) transparent; }

.diverge { display: flex; flex-direction: column; gap: 7px; }
.diverge__row { display: grid; grid-template-columns: 150px minmax(0, 1fr) 86px; gap: 12px; align-items: center; font-size: 0.84rem; }
.diverge__label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.diverge__track { position: relative; height: 16px; background: var(--surface-2); border-radius: 3px; }
/* A linha do zero fica no meio e é a referência de leitura: sem ela, barra
   para a esquerda e para a direita viram duas listas independentes. */
.diverge__zero { position: absolute; left: 50%; top: -1px; bottom: -1px; width: 1px; background: var(--border); }
.diverge__bar { position: absolute; top: 3px; bottom: 3px; border-radius: 2px; }
.diverge__bar.is-up { background: var(--ok); }
.diverge__bar.is-down { background: var(--danger); }
.diverge__value { text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; }

@media (max-width: 640px) {
  .diverge__row { grid-template-columns: 110px minmax(0, 1fr) 74px; gap: 8px; font-size: 0.78rem; }
}

/* Legenda */
/* Legenda: era pequena e apagada demais para identificar a curva. Fica maior,
   com a cor em bloco e o retorno em destaque — e num painel proprio, separado
   do grafico por uma linha, para virar quadro de leitura em vez de rodape. */
.chart-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 18px;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
  font-size: 0.86rem;
  color: var(--ink);
}
.chart-legend span { display: inline-flex; align-items: center; gap: 8px; font-weight: 600; }
.chart-legend b { font-variant-numeric: tabular-nums; font-size: 0.92rem; }
/* Bloco de cor, nao tracinho: 2px de altura sumiam no fundo escuro. */
.chart-legend i { width: 14px; height: 14px; border-radius: 3px; background: var(--aqua); flex: none; }
.chart-legend i.is-ref { background: var(--muted); }

/* Bolinha de severidade do alerta. Era 🔴/🟡/⚪, que além de emoji trazia um
   problema de acessibilidade: o círculo branco some no fundo escuro. Aqui a
   cor vem dos tokens semânticos e o texto ao lado carrega o significado. */
.sev-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; flex: none; }
.sev-dot--alta { background: var(--danger); }
.sev-dot--media { background: var(--warn); }
.sev-dot--baixa { background: var(--muted); }

/* ── 6.1 Índice de seções ──────────────────────────────────────────────── */
/*
   A carteira de um cliente tem oito blocos empilhados. No desktop dava para
   rolar; no celular virava rolagem sem fim, sem saber o que vinha depois nem
   como voltar ao resumo.

   Rola na horizontal em vez de quebrar linha: duas ou três linhas de chips
   comeriam a dobra inteira justamente na tela onde ela é mais escassa.
*/
/* ── Abas da carteira ───────────────────────────────────────────────────── */
/*
   Substituem o índice que rolava até a seção. A carteira tem nove blocos, e
   empilhados numa página só viravam rolagem sem fim — clicar num chip e
   continuar rolando não é a mesma coisa que trocar de tela.

   Sublinhado na aba ativa, e não pílula preenchida: a barra fica logo abaixo
   do cabeçalho do cliente, e um bloco de cor cheia ali disputaria atenção com
   os KPIs, que são o que a tela existe para mostrar.
*/
.tabs {
  display: flex;
  gap: 2px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
  margin: 2px 0 16px;
  padding-bottom: 1px;
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: var(--topbar-h);
  z-index: 5;
  background: var(--bg);
  scrollbar-width: none;
}
.tabs::-webkit-scrollbar { display: none; }

.tabs__btn {
  flex: none;
  padding: 9px 15px;
  border: 0;
  border-bottom: 2px solid transparent;
  background: transparent;
  color: var(--muted);
  font-size: 0.83rem;
  font-weight: 600;
  font-family: inherit;
  white-space: nowrap;
  cursor: pointer;
  /* -2px cobre a borda do container: sem isso, a linha da aba ativa fica um
     pixel acima da linha da barra e parece desalinhada. */
  margin-bottom: -1px;
}
.tabs__btn:hover { color: var(--ink); }
.tabs__btn.is-active { color: var(--aqua); border-bottom-color: var(--aqua); }

/* Alvo de toque de 38px no celular, mesma regra dos demais controles. */
@media (hover: none) and (pointer: coarse) {
  .tabs__btn { padding: 11px 16px; min-height: 38px; }
}

.tabpanel[hidden] { display: none; }

.section-nav {
  display: flex;
  gap: 7px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
  padding: 4px 0 10px;
  margin-bottom: 4px;
  position: sticky;
  top: var(--topbar-h);
  z-index: 5;
  background: var(--bg);
  /* Sem barra de rolagem visível: ela some no desktop e atrapalha no toque. */
  scrollbar-width: none;
}
.section-nav::-webkit-scrollbar { display: none; }

.section-nav a {
  flex: none;
  padding: 6px 12px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--muted);
  font-size: 0.78rem;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}
.section-nav a:hover { color: var(--ink); border-color: var(--aqua); }

/* Âncora não pode parar embaixo da topbar fixa: sem isto, clicar em
   "Movimentação" levava o título para trás do cabeçalho. */
[id^="sec-"], #policy-root, #performance-root, #attribution-root, #letter-root {
  scroll-margin-top: calc(var(--topbar-h) + 56px);
}

/* ── 7. Acessibilidade e toque ─────────────────────────────────────────── */

/* Foco visível. Faltava por completo: quem navega por teclado percorria a tela
   inteira sem saber onde estava, e num produto que abre carteira de terceiros
   isso é grave. `:focus-visible` só aparece na navegação por teclado, então o
   clique de mouse continua limpo. */
.btn:focus-visible,
.nav-item:focus-visible,
.tabs button:focus-visible,
.field input:focus-visible,
.field select:focus-visible,
a:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--aqua);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Quem pediu menos movimento não recebe transição nenhuma. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
  .spinner { animation: spin 1.6s linear infinite !important; }
}

/* ── 8. Responsivo ─────────────────────────────────────────────────────── */
/*
   O produto nasceu de desktop e no celular ele era usável, não bom: tabela de
   sete colunas rolando às cegas, botão pequeno demais para o polegar e o menu
   ocupando a tela inteira.

   A regra que orienta este bloco: no celular o gestor não opera, ele CONSULTA
   — está no carro, na sala do cliente, entre reuniões. Então o que precisa
   sobreviver é o número, e o que pode encolher é o cromo em volta.
*/

/* Altura mínima de alvo de toque. 38px é o menor tamanho que ainda se acerta
   com o polegar em movimento; abaixo disso o usuário erra e culpa o app. */
@media (hover: none) and (pointer: coarse) {
  .btn { min-height: 38px; }
  .btn--sm { min-height: 34px; padding: 8px 12px; }
  .nav-item { padding: 12px 18px; }
  .table td { height: 40px; }
  /* Hover não existe em toque: manter o realce faria a última linha tocada
     ficar acesa para sempre. */
  .table tbody tr:hover td { background: transparent; }
}

@media (max-width: 900px) {
  .app-shell { grid-template-columns: 1fr; }
  .nav-toggle { display: block; }
  .sidebar {
    position: fixed; z-index: 30; top: 0; left: 0;
    width: min(var(--sidebar-w), 82vw);
    transform: translateX(-100%);
    transition: transform 0.2s ease;
  }
  .sidebar.is-open { transform: translateX(0); box-shadow: 0 0 40px rgba(0, 0, 0, 0.55); }
  /* Fundo escurecido para fechar o menu tocando fora dele */
  .nav-backdrop { position: fixed; inset: 0; z-index: 20; background: rgba(9, 9, 11, 0.66); }

  .view { padding: 16px 14px 56px; }
  .topbar { padding: 0 12px; gap: 8px; position: sticky; top: 0; z-index: 10; }
  /* No celular sobra pouca largura: fica o avatar (identidade) e o Sair.
     Nome e papel saem — o usuário já sabe quem é (§13.1). */
  .topbar__id { display: none; }

  .card { padding: 14px; border-radius: 9px; }
  .card + .card { margin-top: 12px; }
  .tile { padding: 12px; }
  .kpi { padding: 12px 14px; }
  .kpi__value { font-size: 1.35rem; }
  .kpi-row { grid-template-columns: repeat(auto-fit, minmax(148px, 1fr)); gap: 10px; }

  /* Cabeçalho de cartão vira duas linhas em vez de espremer título e botão. */
  .card__head { align-items: flex-start; gap: 8px; }
  .card__head h2 { font-size: 0.94rem; }
}

/* ── Telefone ──────────────────────────────────────────────────────────── */
@media (max-width: 620px) {
  /* Rolagem horizontal com inércia e sem barra ocupando altura. A PRIMEIRA
     COLUNA FICA FIXA: numa tabela de sete colunas, rolar para ver o resultado
     fazia perder de vista de qual ativo era a linha — que é o único jeito de
     ler errado um número certo. */
  .table-wrap {
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
  }
  .table th:first-child,
  .table td:first-child {
    position: sticky; left: 0; z-index: 2;
    background: var(--surface);
    /* Sombra só do lado direito, para marcar que há conteúdo rolando por baixo. */
    box-shadow: 6px 0 8px -6px rgba(0, 0, 0, 0.6);
  }
  .table th:first-child { z-index: 3; background: var(--surface-2); }
  .table tbody tr:hover td:first-child { background: var(--surface); }
  .table { font-size: 0.82rem; }
  .table td, .table th { padding-left: 8px; padding-right: 8px; }

  /* O tile dentro de card no celular vira largura cheia. */
  .tile-grid, .grid-2 { grid-template-columns: 1fr; }

  /* Ações empilham em vez de vazar da célula. Um botão por linha, largura
     cheia — cinco botões lado a lado em 390px não cabem de jeito nenhum. */
  .table td.actions > .btn {
    display: flex;
    width: 100%;
    justify-content: center;
    margin: 0 0 6px 0;
  }
  .table td.actions > .btn:last-child { margin-bottom: 0; }

  /* Formulário: um campo por linha. Dois campos lado a lado em 360px viram
     dois campos ilegíveis. */
  .field-row { flex-direction: column; gap: 10px; }
  .field-row > .field { flex: 1 1 auto; }

  /* Modal colado no rodapé é mais fácil de alcançar com o polegar. */
  .modal {
    max-width: none;
    width: 100%;
    margin: auto auto 0;
    border-radius: var(--radius) var(--radius) 0 0;
    /* Respeita a faixa do gesto de voltar no iPhone. */
    padding-bottom: env(safe-area-inset-bottom, 0);
  }
  .modal__foot { flex-wrap: wrap; }
  .modal__foot .btn { flex: 1 1 auto; justify-content: center; }

  /* Gráfico mais baixo: 240px de altura em tela de 640px come metade da dobra. */
  .chart { height: 190px !important; }

  .view__head p { font-size: 0.84rem; }
  .kpi__value { font-size: 1.25rem; }

  /* A carta é leitura corrida; no telefone ela ganha a largura toda. */
  .letter { max-width: none; }
  .letter p { font-size: 0.95rem; line-height: 1.7; }

  /* Coluna de rótulo das barras divergentes encolhe mais no telefone. */
  .diverge__row { grid-template-columns: 92px minmax(0, 1fr) 68px; }

  /* O sticky da primeira coluna conflita com o sticky do cabeçalho quando a
     tabela está dentro de um wrapper baixo; desligar o do cabeçalho no
     telefone evita o cabeçalho flutuar por cima da própria tabela. */
  .table th { position: static; }
}

/* Telas muito estreitas (360px e abaixo): o menu lateral ocupa quase tudo e a
   faixa de KPI vira uma coluna só, porque dois KPIs de 140px não cabem. */
@media (max-width: 380px) {
  .kpi-row { grid-template-columns: 1fr; }
  .brand__text { font-size: 0.98rem; }
}

/* ── Modelo ARCA ─────────────────────────────────────────────────────────
   Duas roscas lado a lado, alvo e realidade. Elas ficam GRANDES e do MESMO
   tamanho de propósito: a leitura é comparar fatia com fatia entre os dois
   círculos, e tamanhos diferentes fariam a mesma fatia parecer maior num
   deles. Em tela estreita empilham, e aí a comparação passa a ser vertical. */
/* Duas roscas e a recomendacao NA MESMA LINHA.

   A recomendacao leva mais largura que uma rosca porque cada ordem e uma
   frase inteira, do tipo "reduzir R$ 75.697,11 em Ativos internacionais". 
   Frase quebrada em tres linhas deixa de ser ordem e vira paragrafo. */
/* Duas faixas, nao tres colunas soltas: o PAR DE ROSCAS de um lado e a coluna
   da recomendacao do outro.
   Por que: a coluna da direita cresce depois que a leitura da IA chega (ela e
   assincrona). Enquanto as tres colunas eram irmas no mesmo grid com `stretch`,
   as roscas herdavam a altura da coluna da IA — a tela abria ajustada e, quando
   o texto da IA chegava, os dois paineis das roscas esticavam e deixavam um
   vazio embaixo do desenho. Agrupando as roscas, a altura delas deixa de
   depender do que a IA escreveu. */
.arca-topo {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 1.25fr);
  gap: 12px;
  margin: 4px 0 14px;
  align-items: start;
}
/* Coluna da esquerda: roscas EM CIMA, tabela EMBAIXO — as duas dentro da mesma
   celula do grid. A tabela ficava fora do grid, em largura total, e a altura do
   cartao era "a maior coluna do topo MAIS a tabela"; como a leitura da IA e bem
   mais alta que as roscas, sobrava um vazio grande sob os desenhos e a tabela so
   comecava depois dele. Empilhada aqui, ela preenche exatamente esse vazio. */
.arca-modelo {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
/* Dentro da coluna a tabela e a continuacao das roscas: separacao em cima, nada
   embaixo (a nota de fonte vem depois do grid e traz o proprio espaco). */
.arca-modelo .arca-tabela { margin: 12px 0 0; }

/* As duas roscas continuam com a MESMA altura entre si (`stretch`), que e o que
   mantem as legendas alinhadas na base — o que elas nao seguem mais e a IA. */
.arca-roscas {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 12px;
  align-items: stretch;
}
.arca-rosca {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 12px 8px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 10px;
}
.arca-rosca__titulo {
  margin: 0;
  font-size: 0.76rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}
/* Sem rotulo a rosca e um quadrado de 150px. COM rotulo ela e mais larga que
   alta (a viewBox abre 42 unidades de cada lado para o texto caber), entao a
   altura passa a ser derivada da largura — travar as duas achatava o desenho. */
.arca-rosca .rosca { width: 150px; height: 150px; }
.arca-rosca .rosca--rotulada { width: 100%; max-width: none; height: auto; }

/* A letra da sigla no lugar do quadradinho de cor: ela é a legenda E a cor,
   numa coluna só. Tinta escura porque todas as quatro cores são claras. */
.arca-letra {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  margin-right: 7px;
  border-radius: 5px;
  color: #0a0c10;
  font-size: 0.72rem;
  font-weight: 800;
  vertical-align: middle;
}

/* A tabela ocupa a largura toda e as colunas tem largura DECLARADA. Sem isso o
   navegador dimensiona pelo conteudo, os seis campos se aglomeram a esquerda e
   sobra metade do cartao vazia a direita — que foi como esta tabela nasceu. */
.arca-tabela { width: 100%; table-layout: fixed; margin-bottom: 12px; }
.arca-tabela th:nth-child(1), .arca-tabela td:nth-child(1) { width: 29%; }
.arca-tabela th:nth-child(2), .arca-tabela td:nth-child(2) { width: 11%; }
.arca-tabela th:nth-child(3), .arca-tabela td:nth-child(3) { width: 18%; }
.arca-tabela th:nth-child(4), .arca-tabela td:nth-child(4) { width: 14%; }
.arca-tabela th:nth-child(5), .arca-tabela td:nth-child(5) { width: 16%; }
.arca-tabela th:nth-child(6), .arca-tabela td:nth-child(6) { width: 12%; }
.arca-tabela td { vertical-align: middle; }

/* Legenda sob cada rosca. A rosca sozinha nao diz qual fatia e qual, e ler
   angulo a olho nao distingue 22% de 28% — que e justamente a diferenca entre
   dentro e fora da banda. */
/* A legenda desce para o RODAPE do painel (margin-top:auto num flex column).
   O espaco entre o grafico e ela e do grafico, nao um vao: com a coluna da
   direita crescendo por causa da leitura de IA, as duas roscas ficavam com um
   buraco embaixo enquanto o desenho continuava pequeno. */
.arca-legenda {
  width: 100%;
  margin: auto 0 0;
  padding-top: 10px;
  border-top: 1px solid var(--border);
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.arca-legenda li {
  display: grid;
  grid-template-columns: 10px 1fr auto;
  align-items: center;
  gap: 8px;
  font-size: 0.79rem;
}
.arca-legenda__cor { width: 10px; height: 10px; border-radius: 3px; flex: none; }
.arca-legenda__nome { color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.arca-legenda__pct { font-variant-numeric: tabular-nums; }

.arca-ordens {
  padding: 11px 13px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-left: 3px solid var(--aqua);
  border-radius: 8px;
  font-size: 0.86rem;
  line-height: 1.6;
}
.arca-ordem { margin-top: 5px; }
.arca-ordem__acao {
  display: inline-block;
  min-width: 62px;
  margin-right: 6px;
  padding: 1px 7px;
  border-radius: 4px;
  font-size: 0.74rem;
  font-weight: 700;
  text-align: center;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.arca-ordem__acao--comprar { background: rgba(34, 211, 238, 0.16); color: var(--aqua); }
.arca-ordem__acao--reduzir { background: rgba(251, 191, 36, 0.16); color: var(--warn); }

/* Numa coluna so nao existe vazio para a tabela preencher, e a ordem que
   importa volta a ser a da leitura: rosca (o que e), recomendacao (o que
   fazer) e so entao a tabela (o detalhe). `display: contents` dissolve o
   involucro da coluna para que os tres virem itens do mesmo grid e possam
   ser reordenados.

   Vale em dois casos: tela estreita (abaixo de 1240px) e o ARCA da Mesa, que
   divide a linha com o comparativo e por isso NUNCA tem largura para roscas,
   tabela e recomendacao lado a lado — ali o empilhamento e a forma normal,
   nao a degradacao. */
.arca-empilhado .arca-topo { grid-template-columns: 1fr; }
.arca-empilhado .arca-modelo { display: contents; }
.arca-empilhado .arca-roscas { order: 1; }
.arca-empilhado .arca-acoes { order: 2; }
.arca-empilhado .arca-modelo .arca-tabela { order: 3; margin: 0; }

@media (max-width: 1240px) {
  .arca-topo { grid-template-columns: 1fr; }
  .arca-modelo { display: contents; }
  .arca-roscas { order: 1; }
  .arca-acoes { order: 2; }
  .arca-modelo .arca-tabela { order: 3; margin: 0; }
}
@media (max-width: 720px) {
  .arca-roscas { grid-template-columns: 1fr; }
}

/* Desvio fora da banda. Âmbar, não vermelho/verde: no ARCA o erro é a
   DISTÂNCIA do alvo, e distância não tem sinal bom. */
.arca-fora { color: var(--warn); font-weight: 700; }

/* Bloco da recomendacao, terceira coluna do topo do ARCA. */
.arca-acoes {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px 13px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-left: 3px solid var(--aqua);
  border-radius: 10px;
}
.arca-acoes__rodape {
  margin-top: auto;
  padding-top: 8px;
  border-top: 1px solid var(--border);
  font-size: 0.76rem;
  color: var(--muted);
}

/* Dentro da coluna o bloco de ordens perde a moldura propria: ele JA esta
   dentro de um painel com moldura, e caixa dentro de caixa vira ruido. */
.arca-acoes .arca-ordens {
  padding: 0;
  background: none;
  border: 0;
  border-radius: 0;
}
.arca-ordens--ok { color: var(--ok); display: flex; gap: 7px; align-items: flex-start; }

/* Cada ordem e uma linha de duas colunas: o verbo, sempre na mesma largura,
   e a frase. Verbo alinhado deixa as tres ordens legiveis de relance. */
.arca-ordem { display: grid; grid-template-columns: 70px minmax(0, 1fr); gap: 8px; align-items: baseline; }
.arca-ordem__texto { line-height: 1.45; }

/* Rotulo na propria fatia da rosca, com linha-guia ate o anel. */
.rosca--rotulada { width: 100%; height: auto; max-width: 320px; }
.rosca__guia { stroke-width: 0.7; opacity: 0.55; }
.rosca__fatia { fill: var(--muted); font-size: 6.4px; }
.rosca__fatia-pct { font-weight: 700; }

/* Leitura de IA dentro do painel de reenquadramento. Separada por uma linha e
   com fundo próprio: o gestor precisa distinguir, sem esforço, o que é conta
   exata (as ordens acima) do que é julgamento de modelo. */
.arca-ia {
  margin-top: 10px;
  padding: 10px 11px;
  background: var(--surface-3);
  border-radius: 8px;
  font-size: 0.82rem;
  line-height: 1.5;
}
.arca-ia__topo {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 6px;
  font-size: 0.76rem;
  color: var(--aqua);
}
.arca-ia__topo .muted { margin-left: auto; font-size: 0.72rem; }
.arca-ia__leitura { margin: 0 0 7px; }
.arca-ia__ponto { margin-top: 5px; }
.arca-ia--espera { color: var(--muted); display: flex; gap: 7px; align-items: flex-start; }

/* Selo do bloco na leitura de IA. A cor sai da aritmética (dentro/fora da
   banda), nunca do texto do modelo — a tabela e o selo têm de contar a mesma
   história. */
.arca-ia__selo {
  display: inline-block;
  margin-right: 6px;
  padding: 1px 7px;
  border-radius: 4px;
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  vertical-align: baseline;
}
.arca-ia__selo--ok { background: rgba(74, 222, 128, 0.15); color: var(--ok); }
.arca-ia__selo--fora { background: rgba(251, 191, 36, 0.15); color: var(--warn); }
.arca-ia__ponto { margin-top: 9px; }

/* ── Porta de entrada da Mesa ────────────────────────────────────────────
   A escolha da carteira vem ANTES dos números, então ela é a tela inteira e
   não um seletor discreto no topo: é uma decisão de a quem os dados vão ser
   mostrados, não um filtro. */
.mesa-porta {
  max-width: 560px;
  margin: 40px auto;
  padding: 24px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
}
.mesa-porta h2 {
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 0 0 8px;
  font-size: 1.05rem;
}
.mesa-porta p { margin: 0 0 18px; font-size: 0.87rem; line-height: 1.5; }
.mesa-porta__lista { display: flex; flex-direction: column; gap: 8px; }
.mesa-porta__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  padding: 13px 15px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 9px;
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
}
.mesa-porta__item:hover { background: var(--surface-3); border-color: var(--aqua); }
.mesa-porta__nome { font-weight: 600; }

/* Valor em cima da barra (chart.empilhadasComLinha). Peso 700 e tamanho menor
   que o KPI: ele informa sem competir com os cartões do topo, que são o
   primeiro nível de leitura da tela. */
.chart__valor-barra {
  fill: var(--ink);
  font-size: 11px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* ── Paleta de séries dos gráficos ──────────────────────────────────────── */
/*
   POR QUE UMA PALETA PRÓPRIA: a rosca usava --aqua, --amber, --ok e --info
   nesta ordem, e --info é EXATAMENTE #22d3ee, o mesmo valor de --aqua (assim
   como --ok repete --green). Com quatro classes de ativo, a quarta fatia saía
   com a cor idêntica à primeira — duas partes indistinguíveis num gráfico que
   existe para distinguir partes.

   As seis cores abaixo são conferidas entre si: nenhuma repete outra, e todas
   têm contraste suficiente sobre o fundo navy.
*/
:root {
  --chart-1: #22d3ee;  /* ciano  */
  --chart-2: #fbbf24;  /* âmbar  */
  --chart-3: #4ade80;  /* verde  */
  --chart-4: #a78bfa;  /* roxo   */
  --chart-5: #f472b6;  /* rosa   */
  --chart-6: #60a5fa;  /* azul   */
}

/* ─── Indicadores de compra ──────────────────────────────────────────────
   Classes próprias da tela de triagem. Declaradas aqui e não improvisadas no
   HTML porque este projeto já teve `.muted` usada em 28 lugares sem nunca ter
   sido declarada — o estilo some e ninguém percebe até alguém olhar a tela.  */

/* Lista dos onze critérios, no painel que fica sempre visível. Duas colunas em
   tela larga: onze itens em coluna única empurram o ranking para fora da
   primeira dobra, que é justamente o que o gestor abriu a tela para ver. */
.criteria-list {
  list-style: none;
  margin: 10px 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 6px 18px;
}
.criteria-list li { font-size: 0.9rem; }
.criteria-list .muted { font-size: 0.8rem; display: block; }

/* Motivos da leitura de IA. */
.reason-list { margin: 8px 0 0; padding-left: 18px; }
.reason-list li { margin-bottom: 7px; line-height: 1.45; }
.reason-list .pill { margin-right: 6px; }

/* Linha clicável do ranking. `cursor` e o realce no hover são o que sinaliza
   que a linha abre a empresa — sem eles a tabela parece estática. O hover é
   desligado no toque: no celular a última linha tocada ficaria acesa para
   sempre (mesma correção já aplicada às outras tabelas do produto). */
.row-click { cursor: pointer; }
@media (hover: hover) {
  .row-click:hover td { background: var(--surface-3); }
}

/* Nome da empresa e texto de comparação: colunas de texto corrido dentro de
   tabelas numéricas. Sem o teto de largura, uma frase de comparação longa
   estica a tabela e empurra a página inteira para fora da janela. */
.col-name {
  max-width: 340px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Aviso de leitura vencida ou desatualizada. */
.msg--warn {
  background: color-mix(in srgb, var(--warn) 14%, var(--surface));
  color: var(--warn);
  border-radius: 8px;
  padding: 8px 11px;
  margin: 0 0 10px;
}

/* O "ver todas" recolhido. */
details > summary { cursor: pointer; font-weight: 600; }
details[open] > summary { margin-bottom: 10px; }

/* A nota do painel de critérios encostava na última linha da grade — a lista
   é `display:grid` e o parágrafo seguinte não herda margem dela. */
.criteria-note { margin-top: 14px; }

/* Explicação do critério, entre parênteses ao lado do nome. Fica em uma linha
   própria em tela estreita: colada ao nome, ela quebraria no meio da frase. */
.criteria-sig { color: var(--muted); font-weight: 400; font-size: 0.82rem; }

/* ── Ressalvas da apuração de imposto ──────────────────────────────────── */
/*
   DISCRETO de propósito. A primeira versão usava `msg--warn`, e o bloco de
   avisos ficava mais chamativo que o próprio valor apurado — num mês isento,
   um retângulo de alerta com quatro linhas ao lado de "R$ 0,00". Aviso que
   grita sempre vira paisagem, e aí o gestor para de ler também o que importa.

   Aqui é texto de rodapé que se abre ao clique. Quando algo realmente muda o
   número (classe sem regra, day trade suspeito), a view manda `open` e o
   conteúdo já aparece — sem precisar de cor de alerta para isso.
*/
.tax-avisos {
  margin-top: 14px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
  font-size: 0.82rem;
  color: var(--muted);
}
.tax-avisos > summary { font-weight: 600; color: var(--muted); }
.tax-avisos ul { margin: 0; padding-left: 1.1rem; }
.tax-avisos li { margin-bottom: 4px; }
