/* Folha do Invista — saiu do <style> do index.html em 24/08/2026.
   Motivo: `style-src 'self'` (sem 'unsafe-inline') recusa o bloco <style>
   INTEIRO, não só o atributo `style=`. Medido: com a diretiva e o CSS ainda
   no HTML, `document.styleSheets` vinha VAZIO e a página perdia todo o
   estilo. É exatamente o mesmo movimento que o JS fez em 17/08 — arquivo
   coberto por 'self' em vez de nonce (o index é estático, não template) ou
   hash (que envelheceria a cada edição).
   Custo declarado: uma requisição a mais, cacheável, e o hash do service
   worker precisa cobrir este arquivo — senão volta o defeito de 23/08, com
   o aparelho servindo folha de semanas atrás. */
  /* FONTES LOCAIS (31/08/2026; Inter + JetBrains Mono desde 05/09/2026 —
     antes Instrument Sans + IBM Plex Mono): sans (interface) + mono
     (números), baixadas no build por fetch_fonts.py — a CSP (`font-src
     'self'`) e a doutrina "exibição serve dado interno" proíbem Google
     Fonts. Os woff2 NÃO entram em ARQUIVOS_SW (não existem no checkout do
     CI, igual chart.umd.min.js): quem invalida o PWA num bump é o `?v=`
     daqui, e este arquivo É hasheado. `font-display:swap` cai na pilha de
     sistema enquanto carrega — e no estágio de teste, que não roda os
     fetchers. */
  @font-face{font-family:"Inter";font-style:normal;font-weight:400;font-display:swap;
    src:url("/static/fonts/inter-400.woff2?v=5.2.5") format("woff2")}
  @font-face{font-family:"Inter";font-style:normal;font-weight:500;font-display:swap;
    src:url("/static/fonts/inter-500.woff2?v=5.2.5") format("woff2")}
  @font-face{font-family:"Inter";font-style:normal;font-weight:600;font-display:swap;
    src:url("/static/fonts/inter-600.woff2?v=5.2.5") format("woff2")}
  @font-face{font-family:"Inter";font-style:normal;font-weight:700;font-display:swap;
    src:url("/static/fonts/inter-700.woff2?v=5.2.5") format("woff2")}
  @font-face{font-family:"JetBrains Mono";font-style:normal;font-weight:400;font-display:swap;
    src:url("/static/fonts/jetbrains-mono-400.woff2?v=5.2.5") format("woff2")}
  @font-face{font-family:"JetBrains Mono";font-style:normal;font-weight:500;font-display:swap;
    src:url("/static/fonts/jetbrains-mono-500.woff2?v=5.2.5") format("woff2")}
  @font-face{font-family:"JetBrains Mono";font-style:normal;font-weight:600;font-display:swap;
    src:url("/static/fonts/jetbrains-mono-600.woff2?v=5.2.5") format("woff2")}
  /* ========================== TOKENS ==========================
     Redesign "Painel" (31/08/2026, handoff design_handoff_invista): a
     escala neutra inteira usa a MESMA matiz 265 (azul-arroxeado frio) em
     oklch — é isso que dá o tom coeso. Os nomes NOVOS do handoff são os
     CANÔNICOS (detêm valor); os antigos (--bg --card --line --tx --mut
     --acc --sup2 --hover --aviso --head --sombra) viram ALIAS e continuam
     valendo — o lerCores() do app.js e as utilitárias u-* leem por eles.
     Apagar um alias exige migrar TODOS os consumidores antes (o teste de
     tokens cobra a definição). As cores de SÉRIE (--s1..--s6) existem
     porque os gráficos são canvas: o JS as lê com getComputedStyle — e o
     lerCores NORMALIZA cada valor via canvas (oklch -> hex), porque dois
     pontos do app.js concatenam alfa em hex. Os blocos de tema redefinem
     SÓ canônicos; os alias moram uma vez aqui.
     Cinco tokens nasceram em 05/09/2026 com a iteração das fichas de
     Mercado: --inset-2 (segundo nível de faixa interna: cabeçalho/rodapé
     de tabela e fundo do segment control), --accent-line (a linha do
     gráfico de preço, que era hex literal no app.js), --pill-active (fundo
     da pílula/segmento selecionado) e --classe-moeda (quadrado de classe
     dos shells novos). Token novo entra nos QUATRO
     blocos e em CANONICOS de tests/test_front_fundacao.py, senão o teste
     dos dois blocos claros idênticos reprova. */
  :root{
    --bg-page:oklch(.17 .012 265);--bg-nav:oklch(.13 .01 265);
    --bg-card:oklch(.22 .016 265);--bg-inset:oklch(.19 .014 265);
    --bg-card-hover:oklch(.25 .018 265);
    --border:oklch(.28 .016 265);--border-strong:oklch(.30 .016 265);
    --divider:oklch(.24 .014 265);
    --text:oklch(.95 .005 265);--text-2:oklch(.82 .008 265);
    --text-3:oklch(.70 .01 265);--text-4:oklch(.64 .01 265);
    --accent:oklch(.58 .17 265);--accent-text:oklch(.78 .12 265);
    --accent-soft:oklch(.62 .17 265);
    --pos:oklch(.80 .15 165);--pos-bg:oklch(.28 .05 165);--pos-solid:oklch(.52 .15 165);
    --neg:oklch(.72 .16 25);--neg-bg:oklch(.22 .03 25);--neg-border:oklch(.36 .08 25);
    --warn:oklch(.80 .14 75);--benchmark:oklch(.72 .01 265);
    --grid:oklch(.70 .01 265/.12);
    --anel-foco:0 0 0 3px oklch(.58 .17 265/.18);
    --s1:oklch(.72 .15 265);--s2:oklch(.80 .15 165);--s3:oklch(.80 .14 75);
    --s4:oklch(.78 .13 330);--s5:oklch(.74 .14 300);--s6:oklch(.78 .13 210);
    --classe-fii:oklch(.80 .15 165);--classe-acao:oklch(.58 .17 265);
    --classe-etf:oklch(.80 .14 75);--classe-bdr:oklch(.78 .13 330);
    --classe-tesouro:oklch(.74 .14 300);
    --classe-moeda:oklch(.78 .13 210);
    --inset-2:oklch(.175 .013 265);--accent-line:oklch(.66 .17 265);
    --pill-active:oklch(.26 .02 265);
    --fonte-sans:"Inter",system-ui,Segoe UI,Roboto,sans-serif;
    --fonte-mono:"JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
    /* ALIAS legados — não apagar sem migrar os consumidores */
    --bg:var(--bg-page);--card:var(--bg-card);--line:var(--border);
    --tx:var(--text);--mut:var(--text-3);--acc:var(--accent);
    --sup2:var(--bg-inset);--hover:var(--bg-card-hover);--aviso:var(--warn);
    --head:var(--bg-nav);--sombra:transparent;
    --esp1:4px;--esp2:8px;--esp3:12px;--esp4:18px;--esp5:26px;
    --r1:8px;--r2:12px;--r3:999px;
  }
  /* Tema CLARO: padrão do sistema quando a conta não escolheu (mesma
     precedência do idioma — conta > navegador > sistema). O atributo
     data-tema no <html> vence a media query, nos dois sentidos. Derivação
     do handoff: L invertido, matizes mantidas (265/165/25/75), chroma um
     pouco menor. */
  @media (prefers-color-scheme: light){
    :root:not([data-tema="escuro"]){
      --bg-page:oklch(.965 .008 265);--bg-nav:oklch(.995 .003 265);
      --bg-card:oklch(.995 .003 265);--bg-inset:oklch(.94 .01 265);
      --bg-card-hover:oklch(.945 .012 265);
      --border:oklch(.87 .015 265);--border-strong:oklch(.83 .018 265);
      --divider:oklch(.91 .012 265);
      --text:oklch(.22 .02 265);--text-2:oklch(.35 .015 265);
      --text-3:oklch(.45 .012 265);--text-4:oklch(.52 .012 265);
      --accent:oklch(.52 .16 265);--accent-text:oklch(.46 .14 265);
      --accent-soft:oklch(.56 .16 265);
      --pos:oklch(.52 .13 165);--pos-bg:oklch(.92 .04 165);--pos-solid:oklch(.50 .13 165);
      --neg:oklch(.55 .15 25);--neg-bg:oklch(.94 .02 25);--neg-border:oklch(.75 .08 25);
      --warn:oklch(.60 .12 75);--benchmark:oklch(.55 .01 265);
      --grid:oklch(.45 .012 265/.16);
      --anel-foco:0 0 0 3px oklch(.52 .16 265/.22);
      --s1:oklch(.55 .15 265);--s2:oklch(.55 .13 165);--s3:oklch(.60 .12 75);
      --s4:oklch(.58 .13 330);--s5:oklch(.55 .14 300);--s6:oklch(.58 .13 210);
      --classe-fii:oklch(.52 .13 165);--classe-acao:oklch(.52 .16 265);
      --classe-etf:oklch(.60 .12 75);--classe-bdr:oklch(.58 .13 330);
      --classe-tesouro:oklch(.55 .14 300);
    --classe-moeda:oklch(.55 .12 210);
    --inset-2:oklch(.925 .01 265);--accent-line:oklch(.52 .16 265);
    --pill-active:oklch(.92 .012 265);
    }
  }
  :root[data-tema="claro"]{
    --bg-page:oklch(.965 .008 265);--bg-nav:oklch(.995 .003 265);
    --bg-card:oklch(.995 .003 265);--bg-inset:oklch(.94 .01 265);
    --bg-card-hover:oklch(.945 .012 265);
    --border:oklch(.87 .015 265);--border-strong:oklch(.83 .018 265);
    --divider:oklch(.91 .012 265);
    --text:oklch(.22 .02 265);--text-2:oklch(.35 .015 265);
    --text-3:oklch(.45 .012 265);--text-4:oklch(.52 .012 265);
    --accent:oklch(.52 .16 265);--accent-text:oklch(.46 .14 265);
    --accent-soft:oklch(.56 .16 265);
    --pos:oklch(.52 .13 165);--pos-bg:oklch(.92 .04 165);--pos-solid:oklch(.50 .13 165);
    --neg:oklch(.55 .15 25);--neg-bg:oklch(.94 .02 25);--neg-border:oklch(.75 .08 25);
    --warn:oklch(.60 .12 75);--benchmark:oklch(.55 .01 265);
    --grid:oklch(.45 .012 265/.16);
    --anel-foco:0 0 0 3px oklch(.52 .16 265/.22);
    --s1:oklch(.55 .15 265);--s2:oklch(.55 .13 165);--s3:oklch(.60 .12 75);
    --s4:oklch(.58 .13 330);--s5:oklch(.55 .14 300);--s6:oklch(.58 .13 210);
    --classe-fii:oklch(.52 .13 165);--classe-acao:oklch(.52 .16 265);
    --classe-etf:oklch(.60 .12 75);--classe-bdr:oklch(.58 .13 330);
    --classe-tesouro:oklch(.55 .14 300);
    --classe-moeda:oklch(.55 .12 210);
    --inset-2:oklch(.925 .01 265);--accent-line:oklch(.52 .16 265);
    --pill-active:oklch(.92 .012 265);
  }
  :root[data-tema="escuro"]{
    --bg-page:oklch(.17 .012 265);--bg-nav:oklch(.13 .01 265);
    --bg-card:oklch(.22 .016 265);--bg-inset:oklch(.19 .014 265);
    --bg-card-hover:oklch(.25 .018 265);
    --border:oklch(.28 .016 265);--border-strong:oklch(.30 .016 265);
    --divider:oklch(.24 .014 265);
    --text:oklch(.95 .005 265);--text-2:oklch(.82 .008 265);
    --text-3:oklch(.70 .01 265);--text-4:oklch(.64 .01 265);
    --accent:oklch(.58 .17 265);--accent-text:oklch(.78 .12 265);
    --accent-soft:oklch(.62 .17 265);
    --pos:oklch(.80 .15 165);--pos-bg:oklch(.28 .05 165);--pos-solid:oklch(.52 .15 165);
    --neg:oklch(.72 .16 25);--neg-bg:oklch(.22 .03 25);--neg-border:oklch(.36 .08 25);
    --warn:oklch(.80 .14 75);--benchmark:oklch(.72 .01 265);
    --grid:oklch(.70 .01 265/.12);
    --anel-foco:0 0 0 3px oklch(.58 .17 265/.18);
    --s1:oklch(.72 .15 265);--s2:oklch(.80 .15 165);--s3:oklch(.80 .14 75);
    --s4:oklch(.78 .13 330);--s5:oklch(.74 .14 300);--s6:oklch(.78 .13 210);
    --classe-fii:oklch(.80 .15 165);--classe-acao:oklch(.58 .17 265);
    --classe-etf:oklch(.80 .14 75);--classe-bdr:oklch(.78 .13 330);
    --classe-tesouro:oklch(.74 .14 300);
    --classe-moeda:oklch(.78 .13 210);
    --inset-2:oklch(.175 .013 265);--accent-line:oklch(.66 .17 265);
    --pill-active:oklch(.26 .02 265);
  }
  /* foco visível: não havia NENHUMA regra :focus no arquivo — navegar por
     Tab era cego, e o outline padrão some no fundo escuro */
  :focus-visible{outline:2px solid transparent;outline-offset:2px;border-radius:4px;box-shadow:var(--anel-foco)}
  *{box-sizing:border-box;margin:0;padding:0}
  body{background:var(--bg);color:var(--tx);font:14px/1.5 var(--fonte-sans)}
  /* SEM `backdrop-filter`, em NENHUMA largura. Ele já custou dois bugs neste
     arquivo, os dois por criar CAMADA DE COMPOSIÇÃO num cabeçalho `sticky`:
     em 14/08 o bloco contenedor engoliu a barra inferior `fixed` no celular
     (consertado só no mobile, e por isso o segundo aconteceu); em 15/08, no
     TABLET em paisagem, o Safari/iPadOS passou a pintar o cabeçalho numa
     altura e a testar o clique em outra — o dono descreveu como "o clique dos
     botões estava mais abaixo do que o texto", e a navegação ficou inviável.
     `var(--card)` é o MESMO tom de `--head` sem os 8% de transparência, que é
     o que o desfoque existia para disfarçar. O efeito perdido é decorativo; o
     que se ganha é o cabeçalho voltar a ser uma camada comum. */
  header{position:sticky;top:0;z-index:50;display:flex;align-items:center;gap:14px;padding:10px 22px;
    background:var(--bg-nav);
    border-bottom:1px solid var(--line);flex-wrap:wrap}
  .brand{display:flex;align-items:center;gap:10px;margin-right:6px}
  .brand .mark{width:24px;height:24px;border-radius:6px;background:var(--accent);
    display:flex;align-items:center;justify-content:center;font-size:13px}
  .brand b{font-size:17px;letter-spacing:.4px}
  .brand .dom{color:var(--mut);font-size:11px;display:block;margin-top:-3px}
  /* A nav QUEBRA em vez de rolar na horizontal. Medido em 15/08: a 900px de
     largura ela precisa de 949px e o "Eventos" ficava CLIPADO — presente no
     DOM, invisível e sem receber clique. Rolagem horizontal de barra de abas
     não tem affordance no toque: quem não sabe que pode arrastar conclui que
     o site perdeu a aba. Quebrar custa uma linha de altura só quando não
     couber, e nunca esconde botão. Acima de ~1100px é inerte (949 cabe). */
  nav{display:flex;gap:3px;flex-wrap:wrap}
  /* Dois níveis (redesign 31/08/2026): a linha de sub-abas ocupa a largura
     toda DENTRO do header (flex-wrap a joga para a fila de baixo); a folha
     "Mais" é um menu ancorado no header sticky (sticky é positioned, então o
     absolute resolve contra ele). No celular ela vira bottom sheet — regra na
     media query. */
  #nav-sub{order:10;width:100%;gap:2px;border-top:1px solid var(--divider);
    padding-top:4px;margin-top:2px}
  #nav-sub button{font-size:13px;padding:5px 10px}
  /* Ancorado sob o BOTÃO "Mais", não no canto direito (01/09/2026, print do
     dono: o menu abria a 1.100px do botão). `--mais-x` é escrito por
     `abrirMais()` a partir do retângulo do botão; sem ela vale a borda
     direita, que é o fallback de antes. */
  #sheet-mais{position:absolute;top:calc(100% + 2px);left:var(--mais-x,auto);
    right:var(--mais-r,14px);z-index:60;
    background:var(--bg-card);border:1px solid var(--line);border-radius:10px;
    padding:6px;flex-direction:column;min-width:170px;gap:2px}
  #sheet-mais button{text-align:left;border-radius:8px;width:100%}
  #sheet-mais button.active{box-shadow:none;background:var(--bg-card-hover)}
  nav button{background:none;border:none;color:var(--mut);font-size:14px;padding:8px 13px;cursor:pointer;
    border-radius:999px;transition:background .15s,color .15s;white-space:nowrap}
  nav button:hover{color:var(--tx);background:var(--hover)}
  nav button.active{color:var(--text);font-weight:600;background:none;box-shadow:inset 0 -2px 0 var(--accent-soft)}
  #userbox{margin-left:auto;color:var(--mut);display:flex;gap:8px;align-items:center}
  /* Menu da CONTA (02/09/2026, fidelidade ao handoff): o cabeçalho é UMA
     fila — o avatar abre perfil, tema, idioma e sair. Tema e idioma são
     filas de opções (.seg) DENTRO do menu; o <select> escondido segue dono
     do valor, ver o comentário no index.html. */
  #conta-btn{padding:2px;border-radius:999px;gap:3px;min-height:32px;transition:box-shadow .15s}
  #conta-btn:hover,#conta-btn:focus-visible{box-shadow:0 0 0 3px oklch(0.58 0.17 265 / 0.25)}
  .conta-menu{min-width:240px;padding:8px}
  .conta-nome{padding:6px 12px 10px;border-bottom:1px solid var(--divider);margin-bottom:4px}
  .conta-nome .nm{color:var(--text);font-size:13px;font-weight:600;overflow:hidden;text-overflow:ellipsis;
    white-space:nowrap;display:block;max-width:260px}
  .conta-menu [role=menuitem]{display:flex;align-items:center;gap:9px;width:100%;text-align:left;
    background:none;border:none;color:var(--mut);font:inherit;font-size:13px;padding:8px 12px;
    border-radius:8px;cursor:pointer;white-space:nowrap;text-decoration:none;min-height:36px}
  .conta-menu [role=menuitem]:hover,.conta-menu [role=menuitem]:focus-visible{color:var(--tx);background:var(--hover)}
  .conta-menu .ic{width:16px;height:16px}
  .conta-sec{display:flex;flex-direction:column;gap:6px;padding:8px 12px}
  .conta-lbl{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--text-4)}
  .conta-sec .seg{width:100%}
  .conta-sec .seg .mseg{flex:1;text-align:center;justify-content:center;display:inline-flex;align-items:center;gap:6px;min-height:30px}
  .conta-sec .seg .mseg[aria-selected="true"]{background:var(--accent);color:#fff}
  .conta-sec .hsel-flag svg{width:16px;height:11px}
  /* Os controles do cabeçalho recebem a MESMA pílula do #user-chip
     (14/08/2026, print do dono): carteira, tema e idioma ficavam soltos sobre o
     fundo — `select` nativo, sem superfície, sem borda, sem raio — enquanto os
     cards logo abaixo têm as três coisas. O botão de busca era o único com
     contêiner, e era isso que fazia a inconsistência saltar em vez de passar.
     Nada de estilo novo: os tokens (`--sup2`, `--line`, o raio) já existiam. */
  /* `min-height` de 32px MORA AQUI, na regra base, e não na do celular: a
     primeira tentativa (15/08) pôs só dentro de `@media(max-width:700px)` e o
     celular em PAISAGEM — que é largo, 844px — ficou de fora, com pílulas de
     20px. É a mesma forma de erro do `backdrop-filter` consertado só no
     mobile, duas vezes no mesmo dia. Mínimo da WCAG 2.2 AA: 24px. */
  #carteira-box{background:var(--sup2);
    border:1px solid var(--line);border-radius:999px;padding:4px 12px;
    min-height:32px;align-items:center;transition:border-color .15s}
  #carteira-box:hover{border-color:var(--acc)}
  /* a seta nativa do <select> some: ela é o que mais destoava do resto da
     interface, e o rótulo ao lado já diz que o campo abre */
  #carteira-box select{appearance:none;-webkit-appearance:none}
  /* Menu de tema/idioma no cabeçalho (01/09/2026): o <select> nativo abria a
     lista do sistema operacional — fundo branco no tema escuro, sem raio,
     sem token nenhum. O menu é o MESMO desenho da folha "Mais": mesma
     superfície, borda, raio e estado ativo. O <select> fica no DOM
     (escondido) como dono do valor — ver o comentário no index.html. */
  .hsel{position:relative}
  .hsel-btn{display:flex;align-items:center;gap:6px;background:none;border:none;
    color:inherit;font:inherit;font-size:12px;cursor:pointer;padding:0;min-height:24px}
  .hsel-arr{color:var(--mut);font-size:10.5px;line-height:1}
  .hsel-menu{display:none;position:absolute;top:calc(100% + 8px);right:0;z-index:60;
    background:var(--bg-card);border:1px solid var(--line);border-radius:10px;
    padding:6px;min-width:160px;flex-direction:column;gap:2px;
    box-shadow:0 8px 24px var(--sombra)}
  .hsel.aberto .hsel-menu{display:flex}
  .hsel-menu button{display:flex;align-items:center;gap:9px;width:100%;text-align:left;
    background:none;border:none;color:var(--mut);font:inherit;font-size:13px;
    padding:8px 12px;border-radius:8px;cursor:pointer;white-space:nowrap}
  .hsel-menu button:hover,.hsel-menu button:focus-visible{color:var(--tx);background:var(--hover)}
  .hsel-menu button[aria-selected="true"]{color:var(--text);font-weight:600;
    background:var(--bg-card-hover)}
  .hsel-flag{display:inline-flex;line-height:0}
  .avatar-circle{width:30px;height:30px;border-radius:50%;object-fit:cover;flex-shrink:0;
    display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:700;color:#fff}
  .conta-menu #btn-logout:hover,.conta-menu #btn-logout:focus-visible{color:var(--neg)}
  /* Sem teto de largura (01/09/2026, pedido do dono): o `max-width:1760px`
     deixava 80px de vazio de cada lado numa tela de 1920 — e as grades já
     são `auto-fit`, então a largura extra vira coluna, não linha comprida. */
  main{margin:22px auto;padding:0 20px}
  @media(min-width:1600px){
    .cart-grid{grid-template-columns:minmax(0,1fr) 380px}
    .tk-grid{grid-template-columns:minmax(0,1fr) 380px}
  }
  /* `min-width:0` aqui pela mesma armadilha do grid explicada abaixo: o card
     costuma ser ITEM de um grid (inclusive de grids com `style` inline, que
     nenhuma classe alcança), e sem isto ele se recusa a encolher e estoura a
     coluna. Foi o que fez /perfil rolar de lado no iPhone SE só no WebKit — o
     Chromium calcula o mínimo de outro jeito e não mostrava. */
  .card{background:var(--card);border:1px solid var(--line);border-radius:12px;padding:18px;margin-bottom:18px;min-width:0}
  .grid{display:grid;gap:14px}
  /* A ARMADILHA DO GRID, curada de uma vez (22/08/2026): item de grid nasce
     com `min-width:auto`, que o PROÍBE de encolher abaixo do próprio conteúdo
     — então ele ESTOURA a coluna em vez de caber, e o documento inteiro passa
     a rolar de lado. Bateu duas vezes no mesmo dia: no card de KPI (patrimônio
     de FII na casa dos bilhões) e no rótulo do Perfil ("Telefone (opcional) —
     contato alternativo…", 366px numa caixa de 312). Aqui a regra vale para
     TODO filho de `.grid`, que é o que impede a terceira vez. */
  .grid>*{min-width:0}
  .kpis{grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}
  /* min-width:0 é o conserto (22/08/2026): item de grid nasce com
     `min-width:auto`, que o PROÍBE de encolher abaixo do próprio conteúdo —
     então um valor longo (patrimônio líquido de FII na casa dos bilhões)
     estoura o card em vez de caber nele. Sem isto o card media 167px com
     211px de conteúdo, vazava, e a ficha do ativo rolava 21px DE LADO no
     celular (medido em 360/390/412/600px). `overflow-wrap` quebra o número
     em vez de cortá-lo: valor cortado seria pior que valor em duas linhas. */
  .kpi{min-width:0;container-type:inline-size}
  .kpi .lbl{color:var(--text-3);font-size:12px;font-weight:600;text-transform:uppercase;letter-spacing:.04em}
  /* fonte por CONTAINER: o valor encolhe antes de quebrar — 28px fixo
     partia o numero no meio ("R$ 64.620,9 / 3") no card estreito */
  .kpi .val{font-size:19px;font-weight:500;font-family:var(--fonte-mono);font-variant-numeric:tabular-nums;letter-spacing:-.03em;margin-top:2px;min-width:0;overflow-wrap:anywhere}
  @container (min-width:190px){.kpi .val{font-size:22px}}
  @container (min-width:240px){.kpi .val{font-size:26px}}
  @container (min-width:300px){.kpi .val{font-size:29px}}
  /* faixa de KPIs da Carteira (02/09/2026, handoff): patrimônio mais largo,
     sublinha de 12px sob cada valor; `.kpis.kpis-faixa` porque a regra
     `.kpis` do celular vem depois no arquivo e venceria a classe simples */
  .kpis.kpis-faixa{grid-template-columns:1.35fr 1fr 1fr 1fr;gap:12px}
  .kpis.kpis-faixa>.hint{grid-column:1/-1}   /* a nota do modo US$ atravessa a faixa, nao ocupa uma coluna */
  .kpi-sub{font-size:12px;line-height:1.4;margin-top:6px;font-variant-numeric:tabular-nums;
    display:flex;flex-wrap:wrap;gap:4px 8px;align-items:center}
  .kpi-sub b{color:var(--text-2);font-weight:600}
  .badge-dia{display:inline-block;padding:1px 7px;border-radius:5px;font-family:var(--fonte-mono);
    font-weight:600;font-size:12px;background:var(--pos-solid);color:#fff}
  .badge-dia.dia-neg{background:var(--neg)}
  @media(max-width:1100px){.kpis.kpis-faixa{grid-template-columns:1fr 1fr}}
  @media(max-width:700px){.kpis.kpis-faixa{grid-template-columns:1fr 1fr;gap:9px}
    .kpis.kpis-faixa .kpi-hero{grid-column:1/-1}}
  table{width:100%;border-collapse:collapse}
  th{color:var(--text-4);text-align:right;font-weight:600;font-size:11.5px;text-transform:uppercase;letter-spacing:.03em;padding:9px 10px;background:var(--bg-inset);border-bottom:1px solid var(--line);cursor:pointer;white-space:nowrap}
  td{padding:11px 10px;text-align:right;border-bottom:1px solid var(--divider);white-space:nowrap;font-family:var(--fonte-mono);font-variant-numeric:tabular-nums;font-size:13px;transition:background .12s}
  th:first-child,td:first-child{text-align:left}
  tr:hover td{background:var(--bg-card-hover)}
  .pos{color:var(--pos)}.warn{color:var(--warn)}.neg{color:var(--neg)}.mut{color:var(--mut)}
  input,select{background:var(--sup2);border:1px solid var(--line);color:var(--tx);padding:9px 12px;border-radius:8px;font-size:14px}
  /* O iOS estiliza input[type=date] por conta própria: CENTRALIZA o valor e
     usa largura/padding nativos, ignorando os do site. No formulário do perfil
     isso deixava a data de nascimento centralizada e mais larga que os campos
     vizinhos, todos alinhados à esquerda. `appearance:none` devolve o controle
     ao nosso CSS; `min-width:0` impede que a largura intrínseca do campo
     estoure a coluna do grid. O seletor de data continua abrindo normalmente. */
  input[type=date]{text-align:left;-webkit-appearance:none;appearance:none;min-width:0}
  button.btn{background:var(--accent);border:1px solid transparent;color:#fff;padding:9px 16px;border-radius:8px;font-size:14px;font-weight:600;cursor:pointer}
  button.btn:disabled{opacity:.5}
  .row{display:flex;gap:10px;flex-wrap:wrap;align-items:center}
  /* ---- LOGIN (handoff de 05/09/2026): duas colunas 1fr|560, painel de
     proposta de valor com card demo, formulario max 416 centrado; <1024 so o
     formulario; celular com campos de 48px. Tudo em tokens do site. */
  #login-view{min-height:100vh;background:var(--bg-page)}
  .login-grid{display:grid;grid-template-columns:1fr 560px;min-height:100vh}
  .login-painel{background:var(--bg-nav);border-right:1px solid var(--border);padding:40px 56px;display:flex;flex-direction:column;gap:20px;min-width:0;
    background-image:radial-gradient(ellipse 60% 50% at 30% 20%,color-mix(in oklab,var(--accent) 14%,transparent),transparent 70%)}
  .login-painel .brand .mark{width:30px;height:30px;border-radius:8px}
  .login-h1{font-size:40px;font-weight:700;letter-spacing:-.025em;line-height:1.1;max-width:520px;margin:14px 0 0}
  .login-sub{font-size:15px;color:var(--text-3);max-width:520px;margin:0;line-height:1.5}
  .login-demo{max-width:600px;margin:6px 0 0}
  .login-demo-kpis{grid-template-columns:repeat(auto-fit,minmax(104px,1fr));gap:8px;margin-bottom:8px}
  .login-demo-kpis .kpi{padding:8px 10px}
  .login-demo-kpis .kpi .val{font-size:16px;white-space:nowrap}
  .login-demo-chart{height:120px}
  .login-rodape{margin:auto 0 0;padding:0;list-style:none;display:flex;gap:22px;flex-wrap:wrap;color:var(--text-3);font-size:13px}
  .login-rodape li::before{content:"";display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--pos);margin-right:8px;vertical-align:middle}
  .login-col{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px 72px;min-width:0}
  .login-form{width:100%;max-width:416px;margin:0;display:flex;flex-direction:column;gap:12px}
  .login-form h2{font-size:26px;margin:0}
  .login-brand-m{display:none;margin:0 0 6px}
  .login-sub2{color:var(--text-3);font-size:14px;margin:-4px 0 4px;line-height:1.45}
  .login-campo{display:flex;flex-direction:column;gap:6px;font-size:12px;font-weight:600;color:var(--text-2);min-width:0}
  .login-campo .rot{display:flex;justify-content:space-between;align-items:baseline;gap:10px}
  .login-campo-senha{display:grid;grid-template-columns:1fr auto;grid-template-areas:"rot esq" "campo campo" "msg msg";align-items:baseline}
  .login-campo-senha .rot{grid-area:rot}.login-campo-senha .login-senha{grid-area:campo}.login-campo-senha .msg{grid-area:msg}
  .login-esqueci{grid-area:esq;font-weight:500;color:var(--accent-text);cursor:pointer;font-size:12px}
  .login-campo input{height:46px;width:100%;box-sizing:border-box;font-size:14px}
  .login-campo input:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px color-mix(in oklab,var(--accent) 18%,transparent)}
  .login-campo.erro input{border-color:var(--neg)}
  .login-campo .msg{font-weight:400;color:var(--neg);font-size:12px}
  .login-campo .msg:empty{display:none}
  .login-senha{position:relative;display:block}
  .login-senha input{padding-right:88px}
  .login-olho{position:absolute;right:6px;top:50%;transform:translateY(-50%);background:none;border:0;color:var(--accent-text);font:inherit;font-size:12px;font-weight:600;cursor:pointer;padding:8px 10px;min-height:32px;border-radius:6px}
  .login-olho:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
  .login-lembrar{display:flex;gap:8px;align-items:center;font-size:13px;color:var(--text-2);cursor:pointer}
  .login-lembrar input{width:16px;height:16px;accent-color:var(--accent);margin:0;flex:none}
  #login-btn{height:46px;margin-top:8px;font-size:15px}
  #login-btn[aria-busy="true"]{opacity:.7;cursor:progress}
  .login-ou{display:flex;align-items:center;gap:12px;color:var(--text-4);font-size:11.5px;margin:2px 0}
  .login-ou::before,.login-ou::after{content:"";flex:1;height:1px;background:var(--border)}
  button.btn.login-passkey{background:var(--bg-inset);border:1px solid var(--border-strong);color:var(--text);height:46px;display:inline-flex;align-items:center;justify-content:center;gap:8px}
  .login-chave{color:var(--warn)}
  .login-nota{font-size:12px;text-align:center;color:var(--text-3);margin:-4px 0 0;line-height:1.45}
  .login-nota a{color:var(--accent-text);cursor:pointer}
  .login-rod{display:flex;justify-content:space-between;gap:12px;flex-wrap:wrap;border-top:1px solid var(--border);padding-top:16px;margin-top:18px;font-size:13px;color:var(--text-3)}
  .login-rod a{color:var(--accent-text);font-weight:600;cursor:pointer}
  .login-banner{border:1px solid var(--neg-border);background:var(--neg-bg);color:var(--neg);border-radius:8px;padding:10px 12px;font-size:13px;line-height:1.45}
  .login-banner a{color:inherit;text-decoration:underline;cursor:pointer}
  .login-banner .mono{font-family:var(--fonte-mono);font-size:12px;display:block;margin-top:4px;opacity:.9}
  .login-banner[data-tipo="aviso"]{border-color:color-mix(in oklab,var(--warn) 45%,transparent);background:color-mix(in oklab,var(--warn) 12%,var(--bg-card));color:var(--warn)}
  .login-banner[data-tipo="neutro"]{border-color:var(--border);background:var(--bg-inset);color:var(--text-2)}
  .login-banner[data-tipo="ok"]{border-color:color-mix(in oklab,var(--pos) 45%,transparent);background:var(--pos-bg);color:var(--pos)}
  .login-aguarde{align-items:center;text-align:center}
  .login-chave-lg{width:72px;height:72px;border-radius:20px;background:var(--bg-inset);border:1px solid var(--border);display:flex;align-items:center;justify-content:center;font-size:32px;box-shadow:0 0 0 10px color-mix(in oklab,var(--accent) 12%,transparent)}
  .login-aguarde h2{font-size:22px}
  .login-aguarde .mono,#login-passkey-email{font-family:var(--fonte-mono)}
  .login-status{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--text-2);margin:0}
  .login-ponto{width:8px;height:8px;border-radius:50%;background:var(--accent);animation:login-pulso 1.2s ease-in-out infinite}
  @keyframes login-pulso{0%,100%{opacity:.35}50%{opacity:1}}
  @media(max-width:1279px){.login-grid{grid-template-columns:1fr 480px}.login-painel{padding:40px}.login-col{padding:40px}.login-h1{font-size:34px}}
  @media(max-width:1023px){.login-grid{grid-template-columns:1fr}.login-painel{display:none}.login-col{padding:32px 16px}.login-brand-m{display:flex}}
  @media(max-width:700px){.login-campo input{height:48px;border-radius:10px;font-size:15px}#login-btn,button.btn.login-passkey{height:48px;border-radius:10px}
    .login-col{padding:20px 16px calc(28px + env(safe-area-inset-bottom,0px))}.login-rod{justify-content:center;text-align:center}}
  @media(max-height:520px){.login-col{padding:12px 16px}.login-form{gap:8px}.login-brand-m{display:none}}
  .err{color:var(--neg);font-size:13px;min-height:18px}
  /* `min-width:0` pela MESMA razão do `.kpi` (22/08/2026): a dica costuma ser
     item de grid — no perfil ela envolve o input dentro de um
     `display:grid` — e item de grid nasce com `min-width:auto`, que o proíbe
     de encolher abaixo do conteúdo. Sem isto, o label "Telefone (opcional) —
     contato alternativo…" media 312px com 366px de conteúdo e a página
     /perfil rolava DE LADO no iPhone SE (360px), achado no WebKit. */
  .hint{color:var(--mut);font-size:12px;min-width:0;overflow-wrap:anywhere}
  /* `label` fecha a mesma armadilha nos formulários: no Perfil os rótulos
     envolvem o próprio input dentro de um grid, e o WebKit (só ele) se
     recusava a encolhê-los — 390px de documento numa tela de 360. */
  label{min-width:0}
  h2{font-size:15px;margin-bottom:12px;color:var(--text);font-weight:600}
  .chartbox{position:relative;height:300px}
  /* Rentabilidade por período: 8 colunas na coluna principal de ~1.000px —
     com o padding padrão a última ("desde o início") ficava CORTADA na
     rolagem interna (auditoria de 02/09/2026). Célula mais justa e o rótulo
     da linha pode quebrar. */
  #perf-table td,#perf-table th{padding:8px 8px;font-size:12.5px}
  #perf-table td:first-child{white-space:normal;min-width:130px;line-height:1.3;text-align:left}
  #perf-table th:first-child{text-align:left}
  /* nota e perfil na MESMA linha da tabela de posições (linha de 44px) */
  .nota-linha{display:inline-flex;gap:5px;align-items:center;justify-content:flex-end;white-space:nowrap}
  /* legenda = chips com o valor do período (handoff "Gráficos") */
  .chip-v{font-family:var(--fonte-mono);font-weight:600}
  .chip-cart{color:var(--text);border-color:var(--accent);background:color-mix(in oklab,var(--accent) 22%,transparent)}
  /* leitura por IA recolhida na lateral: 3-4 mil caracteres numa coluna
     de 340px viravam uma parede; o botão expande */
  .ia-clamp{max-height:300px;overflow:hidden;-webkit-mask-image:linear-gradient(#000 72%,transparent);mask-image:linear-gradient(#000 72%,transparent)}
  .btn-ghost-sm{padding:4px 0;font-size:13px}
  #ov-acoes{justify-content:flex-end}
  /* Cabeçalho da ficha no cartão ESTREITO (04/09/2026, print do dono a
     390px): o bloco preço+ações cai para a linha de baixo com a largura
     toda, e `text-align:right` + `flex-end` deixavam o preço colado à
     direita com um vazio à esquerda e o "Lançar negócio" ÓRFÃO numa
     terceira linha, também à direita — o olho ia esquerda → direita →
     direita. Empilhado, tudo alinha à esquerda e a ação primária ocupa a
     linha inteira. Container query e não media query: a régua é a largura
     do CARTÃO (armadilha nº 9). `:root .u-ta-right.tk-cab-dir` porque o
     utilitário (0,2,0) venceria a classe simples; `#ov-acoes .btn` (1,1,0)
     vence o `button.btn` (0,1,1). Medido em tests/test_front_geometria.py. */
  .tk-cab{container-type:inline-size}
  /* cabeçalho da ficha (handoff das fichas, 05/09/2026): cotação | hairline |
     ações numa linha, à direita; quadrado de classe à esquerda */
  /* margin-left:auto: entre o container de 700px e ~900px (celular em
     PAISAGEM, 844x390) o bloco cai para a segunda linha e o space-between do
     pai o deixava ENCOSTADO A ESQUERDA, com 144px vazios a direita — medido
     pela matriz da ficha em 06/09/2026 (armadilha n 2: largo e BAIXO) */
  .tk-cab-dir{display:flex;align-items:center;justify-content:flex-end;gap:14px;flex-wrap:wrap;text-align:right;margin-left:auto}
  .tk-cab-cot{text-align:right}
  .tk-cab .hairline{align-self:stretch;min-height:44px;border-left:1px solid var(--divider)}
  .classe-quad{width:50px;height:50px;flex:none;border-radius:12px;display:grid;place-items:center;margin-right:14px;
    font:600 12px/1 var(--fonte-mono);letter-spacing:.04em;color:var(--classe-cor,var(--text-3));
    background:color-mix(in oklab,var(--classe-cor,var(--text-3)) 18%,transparent);overflow:hidden}
  .classe-quad img{width:100%;height:100%;object-fit:contain;background:#fff;display:block}
  .classe-quad[data-classe="fii"]{--classe-cor:var(--classe-fii)}
  .classe-quad[data-classe="stock"]{--classe-cor:var(--classe-acao)}
  .classe-quad[data-classe="etf"]{--classe-cor:var(--classe-etf)}
  .classe-quad[data-classe="bdr"]{--classe-cor:var(--classe-bdr)}
  .classe-quad[data-classe="tesouro"]{--classe-cor:var(--classe-tesouro)}
  .classe-quad[data-classe="moeda"],.classe-quad[data-classe="cripto"]{--classe-cor:var(--classe-moeda)}
  @container (max-width:700px){
    .tk-cab-dir{width:100%;flex-direction:column;align-items:stretch;gap:8px;text-align:left}
    .tk-cab-cot{text-align:left}
    .tk-cab .hairline{display:none}
    /* celular (handoff 9m/8m1): Comparar | Lancar negocio lado a lado na
       primeira fila, Excel | PDF na segunda — grade 2x2, ordem por CSS sem
       mover no. Ate 05/09 a primaria ocupava a linha inteira. */
    /* :not(.u-d-none): o id (1,0,0) vencia o utilitario e os quatro botoes
       voltavam no celular nas fichas que os escondem (Tesouro, moedas) */
    #ov-acoes:not(.u-d-none){display:grid;grid-template-columns:1fr 1fr;gap:8px}
    #ov-acoes>*{min-width:0;justify-content:center}
    #ov-acoes [data-act="cmpficha"]{order:1}
    #ov-acoes .btn{order:2}
    #ov-acoes [data-act="dodownload-a222"]{order:3}
    #ov-acoes [data-act="dodownload-9831"]{order:4}
  }
  /* tabela larga (cadeia de opcoes no celular): primeira coluna fixa e o resto
     rola DENTRO do invólucro — nunca a pagina */
  .ind-todos{margin-top:14px;border-top:1px solid var(--border);padding-top:10px}
  .ind-todos summary{cursor:pointer;font-weight:600;font-size:14px;margin-bottom:8px}
  .ind-todos #ind-busca{max-width:220px}
  .ind-todos td.dir-maior{color:var(--pos)}.ind-todos td.dir-menor{color:var(--neg)}
  .tabela-fixa{overflow-x:auto}
  .tabela-fixa th:first-child,.tabela-fixa td:first-child{position:sticky;left:0;background:var(--bg-card);z-index:1}
  /* width:100% (23/08/2026, print do dono): quase todo gráfico tem altura
     própria (hoje a classe `u-h-220` e irmãs, no fim do arquivo; até
     24/08/2026 era `style="height:220px"`), que vence o height:auto daqui —
     e com altura fixa + aspect-ratio o navegador DERIVA a largura da altura
     (220×4/3 ≈ 293px num card de 370): o gráfico encolhia no celular.
     Com width E height especificados o aspect-ratio é ignorado; o 4/3 só
     governa quem não tem altura própria.
     A conversão dos `style=` em classe PRESERVA isso por ordem de origem: os
     utilitários vêm depois desta media query e têm a mesma especificidade,
     então continuam ganhando o height — e o width:100% daqui, que nenhum
     utilitário toca, continua valendo. Medido: 13.006 caixas idênticas. */
  @media(max-width:700px){.chartbox{height:auto;aspect-ratio:4/3;width:100%}}
  a{color:var(--acc);cursor:pointer;text-decoration:none}
  .mselect{position:relative}
  .mselect-btn{background:var(--sup2);border:1px solid var(--line);color:var(--tx);padding:9px 12px;border-radius:8px;
    font-size:14px;cursor:pointer;display:flex;align-items:center;gap:8px;max-width:260px}
  .mselect-btn .lbl{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .mselect-btn .arr{color:var(--mut);font-size:11px}
  .mselect-menu{display:none;position:absolute;top:calc(100% + 4px);left:0;z-index:60;background:var(--sup2);
    border:1px solid var(--line);border-radius:8px;padding:6px;min-width:230px;max-height:280px;overflow-y:auto;
    box-shadow:0 8px 24px var(--sombra)}
  .mselect-menu.open{display:block}
  .mselect-menu label{display:flex;align-items:center;gap:8px;padding:7px 9px;border-radius:6px;cursor:pointer;
    font-size:13px;white-space:nowrap}
  .mselect-menu label:hover{background:var(--bg-card-hover)}
  .mselect-menu input[type=checkbox]{accent-color:var(--acc);width:15px;height:15px;padding:0;margin:0;flex-shrink:0}
  .mselect-menu .clear{display:block;padding:7px 9px;font-size:12px}
  .mselect-search{width:100%;margin-bottom:4px;padding:7px 9px;font-size:13px}
  .score-badge{display:inline-block;min-width:36px;text-align:center;padding:3px 8px;border-radius:8px;font-weight:700;color:#fff;font-size:13px}
  th.sortable{user-select:none}
  th.sortable:hover{color:var(--tx)}
  th .sort-hint{opacity:.35;font-size:10.5px}
  .advf-menu{min-width:min(330px,calc(100vw - 32px));padding:10px}
  .advf-row{display:flex;gap:6px;align-items:center;margin:5px 0}
  .advf-row span{flex:1;font-size:13px;color:var(--mut);white-space:nowrap}
  .advf-row input{width:86px;padding:6px 8px;font-size:13px}
  .advf-rating{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:10px}
  .advf-rating .chip{display:flex;gap:5px;align-items:center;border:1px solid var(--line);
    border-radius:999px;padding:3px 10px;font-size:12px;cursor:pointer}
  .advf-rating .chip input{width:13px;height:13px;padding:0;margin:0;accent-color:var(--acc)}
  #tk-imoveis-table tr.sel td{background:color-mix(in oklab,var(--accent) 14%,transparent)}
  #tk-imoveis-table tr[data-idx]:hover td{background:color-mix(in oklab,var(--accent) 8%,transparent)}
  .pillar-bar{height:8px;border-radius:4px;background:var(--hover);overflow:hidden;flex:1}
  .pillar-bar div{height:100%;border-radius:4px}
  .logo-sm{width:20px;height:20px;border-radius:5px;vertical-align:-4px;margin-right:7px;background:#fff;object-fit:contain}
  .cell-sub{display:block;font-size:11px;color:var(--text-4);font-weight:400;margin-top:2px;line-height:1.3;font-family:var(--fonte-sans)}
  .logo-lg{width:52px;height:52px;border-radius:10px;background:#fff;object-fit:contain;margin-right:14px}
  /* Toast e modal (13/08/2026) — substituem alert()/confirm()/prompt(), que
     bloqueiam a thread, não são traduzíveis pelo dicionário do app, mostram o
     domínio no iOS e (no caso do prompt) são bloqueados por alguns
     navegadores. Nada de biblioteca: são ~25 linhas de CSS. */
  #toasts{position:fixed;right:16px;bottom:16px;z-index:60;display:flex;flex-direction:column;gap:8px;max-width:min(380px,calc(100vw - 32px))}
  .toast{background:var(--card);border:1px solid var(--line);border-left:3px solid var(--acc);
         border-radius:10px;padding:11px 14px;box-shadow:0 8px 24px var(--sombra);
         font-size:13px;color:var(--tx);animation:toast-in .18s ease-out}
  .toast.ok{border-left-color:var(--pos)} .toast.err{border-left-color:var(--neg)}
  @keyframes toast-in{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
  /* Tooltip PRÓPRIO (13/08/2026): os 65 `title=` nativos somem no toque e no
     leitor de tela — e é neles que mora a melhor explicação do produto.
     O texto continua no atributo (o dicionário de idioma percorre `title`);
     aqui ele é só APRESENTADO, com hover, foco e toque. */
  #dica{position:fixed;z-index:80;max-width:min(320px,calc(100vw - 24px));
        background:var(--card);color:var(--tx);border:1px solid var(--line);
        border-radius:8px;padding:8px 11px;font-size:12.5px;line-height:1.45;
        box-shadow:0 8px 24px var(--sombra);pointer-events:none;display:none}
  .skel{background:linear-gradient(90deg,var(--line) 25%,var(--hover) 37%,var(--line) 63%);
        background-size:400% 100%;animation:skel 1.2s ease-in-out infinite;
        border-radius:6px;height:13px;margin:7px 0}
  @keyframes skel{0%{background-position:100% 0}100%{background-position:0 0}}
  .barra{height:6px;border-radius:3px;background:var(--bg-inset);overflow:hidden;margin-top:8px}
  .barra div{height:100%;background:var(--accent-soft);transition:width .25s;width:0}
  #paleta-fundo{position:fixed;inset:0;z-index:65;background:rgba(6,10,18,.5);
                display:flex;align-items:flex-start;justify-content:center;padding:10vh 16px}
  #paleta{background:var(--card);border:1px solid var(--line);border-radius:14px;
          width:min(560px,100%);box-shadow:0 18px 48px var(--sombra);overflow:hidden}
  #paleta input{width:100%;border:none;border-bottom:1px solid var(--line);
                background:transparent;color:var(--tx);font-size:15px;padding:14px 16px}
  #paleta .item{padding:9px 16px;cursor:pointer;display:flex;gap:9px;align-items:center;font-size:13.5px}
  #paleta .item.sel{background:var(--hover)}
  #paleta .tipo{color:var(--mut);font-size:11px;margin-left:auto}
  /* autocompletar de ativos: mesma linguagem visual da paleta, ancorado ao
     input ativo (posição calculada em JS); z-index acima do modal para o
     campo de ticker dentro de modal também sugerir */
  #ac-menu{position:absolute;display:none;z-index:75;background:var(--card);
           border:1px solid var(--line);border-radius:10px;overflow:hidden;
           box-shadow:0 12px 32px var(--sombra);max-height:320px;overflow-y:auto;
           max-width:calc(100vw - 16px)}
  #ac-menu .item{padding:8px 12px;cursor:pointer;display:flex;gap:9px;
                 align-items:center;font-size:13px;white-space:nowrap}
  #ac-menu .item.sel,#ac-menu .item:hover{background:var(--hover)}
  #ac-menu .tipo{color:var(--mut);font-size:11px;margin-left:auto;padding-left:8px}
  #modal-fundo{position:fixed;inset:0;z-index:70;background:rgba(6,10,18,.66);
               display:flex;align-items:center;justify-content:center;padding:16px}
  /* max-height + rolagem (21/08/2026): o seletor de seções do PDF tem 10
     linhas e sem isto o modal estourava a viewport sem barra de rolagem —
     lista cortada nas duas pontas, print do dono */
  #modal-cx{background:var(--card);border:1px solid var(--line);border-radius:14px;
            padding:20px;width:min(420px,100%);box-shadow:0 18px 48px var(--sombra);
            max-height:min(85vh,85%);overflow:auto}
  #modal-cx h3{margin:0 0 6px;font-size:16px}
  #modal-cx .corpo{color:var(--mut);font-size:13px;margin-bottom:12px}
  #modal-cx input{width:100%;margin-bottom:12px}
  /* a regra acima existe para o INPUT DE TEXTO dos modais de campo; num
     CHECKBOX, width:100% vira uma linha inteira própria, desalinhada do
     rótulo (o layout quebrado do "PDF sob medida", 21/08/2026). A exceção
     mora AQUI, na classe, e não em style= de cada checkbox — senão o
     próximo modal com caixas repete o defeito */
  #modal-cx input[type=checkbox]{width:auto;margin:0 8px 0 0;vertical-align:middle}
  #modal-cx .acoes{display:flex;gap:8px;justify-content:flex-end}
  .import-previa{min-width:0;overflow-wrap:anywhere}
  /* ======================== COMPONENTES ========================
     Vocabulário do redesign "Painel" (31/08/2026). Consumidor novo nasce
     falando estes nomes; as utilitárias u-* seguem no FIM do arquivo
     (ordem de origem é a especificidade delas — ver o comentário lá). */
  .inset{background:var(--bg-inset);border-radius:9px;padding:10px 12px}
  .chip{display:inline-flex;align-items:center;gap:5px;border:1px solid var(--line);
    border-radius:6px;padding:2px 8px;font-size:11.5px;font-weight:600;color:var(--text-3);
    background:var(--bg-inset);white-space:nowrap}
  .chip-pos{color:var(--pos);background:var(--pos-bg);border-color:transparent}
  .chip-neg{color:var(--neg);background:var(--neg-bg);border-color:transparent}
  .chip-warn{color:var(--warn);background:color-mix(in oklab,var(--warn) 16%,transparent);border-color:transparent}
  .chip-acc{color:var(--accent-text);background:color-mix(in oklab,var(--accent) 16%,transparent);border-color:transparent}
  .fonte-nota{color:var(--text-4);font-size:11.5px;line-height:1.4;margin-top:10px}
  .btn-sec{background:transparent;border:1px solid var(--border-strong);color:var(--text);
    padding:9px 16px;border-radius:8px;font-size:14px;font-weight:600;cursor:pointer}
  .btn-sec:hover{background:var(--bg-card-hover)}
  .btn-ghost{background:transparent;border:none;color:var(--accent-text);padding:9px 12px;
    border-radius:8px;font-size:14px;cursor:pointer}
  .num{font-family:var(--fonte-mono);font-variant-numeric:tabular-nums}
  .spark{display:inline-block;width:84px;height:22px;line-height:0}
  /* o <svg> é desenhado com width=84 fixo (carregarSparklines) e o vão da
     lateral tem 56px: sem isto ele transborda 28px para fora da célula — foi
     o que fazia o card Acompanhando rolar de lado (medido em 01/09/2026).
     Com viewBox, 100% escala o desenho para o vão que houver. */
  .spark svg{display:block;width:100%;height:100%}
  .at-item{border-left:3px solid var(--warn);background:var(--bg-inset);
    border-radius:0 8px 8px 0;padding:8px 11px;margin:6px 0;font-size:13px;cursor:pointer}
  .at-item:hover{background:var(--bg-card-hover)}
  .at-item .meta{display:block;color:var(--text-4);font-size:11.5px;margin-top:2px}
  .at-neg{border-left-color:var(--neg)}
  .at-acc{border-left-color:var(--accent-soft)}
  /* Carteira: coluna principal + lateral 330px (handoff 1b). `minmax(0,1fr)`
     e `>*{min-width:0}` pela armadilha nº 6 (item de grid não encolhe). */
  .cart-grid{display:grid;grid-template-columns:minmax(0,1fr) 330px;gap:16px;align-items:start}
  .cart-grid>*{min-width:0}
  .cart-lado .card{padding:14px;margin-bottom:16px}
  .cart-lado h2{font-size:14px}
  .cart-lado .chartbox{height:180px}
  /* Card de gráfico que CRESCE com a fila (05/09/2026, pedido do dono: a
     renda recebida no Proventos "usa só o terço de cima"). Medido a 1920:
     a fila do grid `.u-d7` é ditada pelo vizinho (tabela de 12 meses,
     659px) e o chartbox tinha altura FIXA (`u-h-240`) — 354px de faixa
     morta abaixo do canvas. O mesmo desenho do topo do Mercado: card em
     coluna flex, chartbox `flex:1` e o canvas FORA DO FLUXO (senão a
     altura que o Chart.js grava no canvas volta a contar como conteúdo e
     a fila cresce em laço). A régua é `@container` no CARD e não media
     query: a 390px o card tem 370px e nada muda (medido: 240px); a
     1024-1920 tem 485-933px e o gráfico preenche. `--grafico-largo` é o
     que o JS lê para decidir o modo empilhado: UMA régua, na folha, em
     vez de uma constante de largura copiada no script. `:root` (0,3,0)
     porque o utilitário `:root .u-h-240` (0,2,0) vem depois e venceria
     (armadilha nº 9). `align-self` no link "ver dados": em coluna flex o
     item esticaria para a largura toda, e no celular a geometria tem de
     ser a de hoje: o link com a largura do proprio texto. */
  .card-cresce{container-type:inline-size;display:flex;flex-direction:column}
  .card-cresce>a{align-self:flex-start}
  @container (min-width:440px){
    :root .card-cresce .chartbox{flex:1;height:auto;min-height:240px;--grafico-largo:1}
    .card-cresce .chartbox canvas{position:absolute;left:0;top:0}
  }
  .evo-dd-faixa{height:64px;margin-top:2px}
  /* Sliders do screener (handoff 3b): dois <input type=range> sobrepostos;
     so os POLEGARES recebem ponteiro. Eles escrevem nos inputs numericos —
     que continuam a unica fonte do query (scrQuery nao muda). */
  .faixa2{position:relative;height:20px;margin:2px 0 4px}
  .faixa2 input[type=range]{position:absolute;inset:0;width:100%;height:20px;
    margin:0;padding:0;background:none;pointer-events:none;
    -webkit-appearance:none;appearance:none}
  .faixa2 input[type=range]::-webkit-slider-runnable-track{height:3px;
    background:var(--bg-inset);border-radius:2px;border:none}
  .faixa2 input[type=range]::-moz-range-track{height:3px;
    background:var(--bg-inset);border-radius:2px;border:none}
  .faixa2 input[type=range]::-webkit-slider-thumb{pointer-events:auto;
    -webkit-appearance:none;width:14px;height:14px;border-radius:50%;
    background:var(--accent);border:2px solid var(--bg-card);margin-top:-5.5px}
  .faixa2 input[type=range]::-moz-range-thumb{pointer-events:auto;
    width:11px;height:11px;border-radius:50%;background:var(--accent);
    border:2px solid var(--bg-card)}
  .scr-campo{margin:7px 0}
  .scr-campo .scr-cab{display:flex;justify-content:space-between;
    font-size:12px;color:var(--text-3)}
  .scr-campo .scr-nums{display:flex;gap:6px}
  .scr-campo .scr-nums input{width:72px;padding:4px 6px;font-size:12px}
  /* Icones de linha (handoff): sprite inline, stroke=currentColor. No
     DESKTOP a barra principal e so texto (como o prototipo); no celular o
     icone sobe para cima do rotulo na tab bar. */
  .ic{width:18px;height:18px;stroke:currentColor;fill:none;stroke-width:1.7;
    stroke-linecap:round;stroke-linejoin:round;display:none;vertical-align:-4px}
  .ic-on{display:inline-block}
  .ic-s{width:14px;height:14px;vertical-align:-2.5px;margin-right:4px}
  #sheet-mais .ic{display:inline-block;margin-right:8px}
  .cart-lado td{padding:7px 8px;font-size:12.5px}
  .cart-lado .spark{width:56px}
  /* O card LATERAL tem 330-380px — a largura de um celular — e a tabela do
     Acompanhando (4 colunas) media 390px dentro de 300px de card: o wrapper
     `overflow-x:auto` escondia as ações ✎ ✕ sem dizer (armadilha nº 4; print
     do dono, 01/09/2026). A regra é a mesma do celular (`table.cartoes` vira
     cartão por linha), só que decidida pela largura do CONTÊINER e não da
     viewport — é o card que é estreito, não a tela. Container query: a
     mesma tabela no fluxo de uma coluna (< 1280px, card com 900px) segue
     como tabela. Regras espelhadas do bloco `@media(max-width:700px)`. */
  .cart-lado{container-type:inline-size}
  @container (max-width:520px){
    .cart-lado table.cartoes tr:has(th){display:none}
    .cart-lado table.cartoes tr{display:grid;grid-template-columns:1fr;gap:2px 16px;
      border:1px solid var(--line);border-radius:10px;padding:9px 11px;margin-bottom:8px;
      box-sizing:border-box}
    /* piso de 120px (não 148): o card tem 300px úteis e 148×2+16 não cabia,
       então o par nunca acontecia e cotação/sparkline empilhavam em quatro
       filas. A ÚLTIMA célula (ações ✎ ✕) atravessa a largura, como a
       primeira: sozinha em meia coluna ela abria buraco à direita. */
    .cart-lado table.cartoes.pares tr{
      grid-template-columns:repeat(auto-fit,minmax(max(120px,45%),1fr))}
    .cart-lado table.cartoes td{border:none;padding:1px 0;font-size:12.5px;min-width:0}
    .cart-lado table.cartoes td:first-child{font-weight:600;grid-column:1/-1}
    .cart-lado table.cartoes td:last-child{grid-column:1/-1}
    .cart-lado table.cartoes td[data-r]{display:flex;flex-wrap:wrap;white-space:normal;
      justify-content:flex-end;align-items:baseline;gap:2px 8px;text-align:right}
    .cart-lado table.cartoes td[data-r]::before{content:attr(data-r);color:var(--mut);
      font-size:11px;text-align:left;white-space:nowrap;margin-right:auto}
  }
  .u-ovx-auto{scrollbar-width:thin;scrollbar-color:var(--border-strong) transparent}
  .u-ovx-auto::-webkit-scrollbar{height:8px;width:8px}
  .u-ovx-auto::-webkit-scrollbar-thumb{background:var(--border-strong);border-radius:4px}
  .u-ovx-auto::-webkit-scrollbar-track{background:transparent}
  .cart-lado th{padding:6px 8px}
  @media(max-width:1279px){.cart-grid{grid-template-columns:1fr}}
  /* Topo das abas de mercado (01/09/2026, print do dono): três cards iguais
     em três colunas, e o grid ESTICAVA o do índice (gráfico de 170px) e o
     dos destaques (duas filas de chips) até a altura do ranking — 550px de
     card com 300px de vazio dentro. Agora são DUAS colunas: o ranking
     (`.mkt-rank`) ocupa a direita de alto a baixo; índice e destaques
     empilham à esquerda, e o card do índice CRESCE para fechar a altura com
     o gráfico ocupando o que sobra (`flex:1`) — o espaço vira dado, não
     borda. `grid-template-rows:1fr auto`: o item que atravessa as duas
     filas dita a altura e a folga vai toda para a fila do gráfico.
     Abaixo de 1000px volta ao `auto-fit` de uma coluna. */
  /* `:root .u-d7.mkt-topo` (0,3,0): o utilitário `:root .u-d7` (0,2,0) vem
     DEPOIS neste arquivo e, com especificidade igual, vencia — medido: as
     colunas continuavam iguais com a regra "aplicada". */
  @media(min-width:1000px){
    :root .u-d7.mkt-topo{grid-template-columns:minmax(0,1fr) minmax(0,1.25fr);
      grid-template-rows:1fr auto;align-items:start}
    :root .u-d7.mkt-topo.quatro{grid-template-rows:1fr auto auto}
    :root .u-d7.mkt-topo>.card{grid-column:1}
    :root .u-d7.mkt-topo>.mkt-rank{grid-column:2;grid-row:1/-1}
    :root .u-d7.mkt-topo>.card:first-child{display:flex;flex-direction:column;align-self:stretch}
    :root .u-d7.mkt-topo>.card:first-child .chartbox{flex:1;height:auto;min-height:170px}
    /* O canvas sai do FLUXO (03/09/2026, medido ao subir o topo): o Chart.js
       grava no canvas a altura que o chartbox tem, e essa altura voltava a
       contar como conteúdo do card — a fila `1fr` crescia até a altura do
       ranking, o gráfico ia a 630px e os Destaques caíam para BAIXO do
       ranking. Fora do fluxo, o chartbox pede só o min-height e recebe a
       folga da fila; o canvas preenche o que o chartbox tem. */
    :root .u-d7.mkt-topo>.card:first-child .chartbox canvas{position:absolute;left:0;top:0}
  }
  /* Mercado (03/09/2026, decisão do dono): índice, ranking e destaques no
     TOPO e a lista abaixo. O handoff punha os cards abaixo da tabela, mas a
     desenhou com 12 linhas FILTRADAS; o site abre a classe inteira (393
     FIIs, 1.009 BDRs) com 100 linhas antes da sentinela, e os cards ficavam
     a milhares de pixels do topo — informação enterrada que ninguém via. */
  .mkt-topo{margin-bottom:16px}
  /* chips de segmento (handoff 3b): os mais frequentes à mão, o resto no
     menu com busca; selecionado = fundo sólido do acento + ✕ */
  .seg-chips{display:flex;flex-wrap:wrap;gap:6px;margin:-2px 0 10px}
  .seg-chips:empty{display:none}
  .seg-chips .chip{cursor:pointer;font-weight:500;font-size:12px;padding:3px 9px;max-width:100%;color:var(--text-2)}
  .seg-chips .chip>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .seg-chips .chip.on{color:#fff;background:var(--accent);border-color:var(--accent)}
  .scr-n{font-weight:600;margin-left:2px}
  /* Mercado: coluna de filtros persistente de 288px (handoff 3b) + main.
     No celular a coluna vira um card comum no fluxo. */
  .mkt-grid{display:grid;grid-template-columns:288px minmax(0,1fr);gap:16px;align-items:start}
  .mkt-grid>*{min-width:0}
  .mkt-filtros{position:sticky;top:72px;max-height:calc(100vh - 88px);overflow-y:auto}
  .mkt-filtros input[type=search],.mkt-filtros select,.mkt-filtros .mselect,
  .mkt-filtros .mselect-btn{width:100%;max-width:none;margin-bottom:8px}
  .mkt-filtros .scr-panel .scr-row{display:flex;margin:3px 0}
  .mkt-filtros .scr-panel .scr-row span{flex:1}
  @media(max-width:1000px){.mkt-grid{grid-template-columns:1fr}
    .mkt-filtros{position:static;max-height:none}}
  /* Ficha do ativo: lateral de 340px (handoff 3a) */
  .tk-grid{grid-template-columns:minmax(0,1fr) 340px}
  @media(max-width:1279px){.tk-grid{grid-template-columns:1fr}}
  /* grade de indicadores em mosaico: celulas separadas por 1px de --line
     (gap sobre fundo), como o handoff desenha */
  #ov-indicadores{gap:1px;background:var(--line);border:1px solid var(--line);
    border-radius:10px;overflow:hidden}
  #ov-indicadores .kpi{background:var(--bg-card);border:none;border-radius:0;
    margin:0;padding:10px 12px}
  /* sub-abas da ficha: ancoras de rolagem sobre a pilha de cards */
  /* Abas reais da ficha (05/09/2026). Quebram em FILAS em toda largura — barra
     com overflow-x esconde aba sem dizer (armadilha nº 4); no celular cada aba
     ganha alvo de 44px e divide a fila. */
  .abas{display:flex;flex-wrap:wrap;gap:2px;margin:0 0 12px;border-bottom:1px solid var(--divider)}
  .aba{background:none;border:0;border-radius:0;color:var(--text-3);font:500 13.5px/1.2 var(--fonte-sans);
    padding:10px 12px;min-height:36px;cursor:pointer;box-shadow:none}
  .aba:hover{color:var(--text);background:transparent}
  .aba.on{color:var(--text);font-weight:600;box-shadow:inset 0 -2px 0 var(--accent)}
  @media(max-width:700px){.aba{min-height:44px;flex:1 1 auto;text-align:center}}
  .tk-grid.sem-lado{grid-template-columns:minmax(0,1fr)}
  /* legenda em chips sobre o grafico (handoff): clicavel, serie escondida
     fica apagada e riscada — cor nunca sozinha */
  .legenda-chips{display:flex;flex-wrap:wrap;gap:6px;margin:0 0 8px}
  .legenda-chips .chip{cursor:pointer;font-family:var(--fonte-mono);font-size:11.5px}
  .legenda-chips .chip:not(.on){opacity:.45;text-decoration:line-through}
  /* faixa de mercado da ficha (handoff): 6 celulas numa linha no desktop, 3 no
     tablet, 2 colunas no celular. Classe dupla porque a regra `.kpis` do
     celular vem depois no arquivo e venceria a classe simples (mesma razao
     da .kpis.kpis-faixa da Carteira) */
  .kpis.faixa-mercado{grid-template-columns:repeat(6,minmax(0,1fr));gap:12px;margin-bottom:16px}
  @media(max-width:1100px){.kpis.faixa-mercado{grid-template-columns:repeat(3,minmax(0,1fr))}}
  @media(max-width:700px){.kpis.faixa-mercado{grid-template-columns:repeat(2,minmax(0,1fr));gap:9px}}
    box-shadow:inset 0 -2px 0 var(--accent-soft)}
  /* Extratos (handoff 3c): stepper com estado visivel e dropzona */
  .st-bola{display:inline-flex;align-items:center;justify-content:center;
    width:22px;height:22px;border-radius:50%;background:var(--bg-inset);
    border:1px solid var(--border-strong);font-size:12px;font-weight:600;
    margin-right:6px;vertical-align:-4px}
  .st-ok{border-color:var(--pos)}
  .st-ok .st-bola{background:var(--pos-solid);border-color:var(--pos-solid);color:#fff}
  .st-ativo{border-color:var(--accent);box-shadow:var(--anel-foco)}
  .st-ativo .st-bola{background:var(--accent);border-color:var(--accent);color:#fff}
  .dropzona{border:1.5px dashed var(--border-strong);border-radius:9px;
    padding:10px;transition:border-color .12s,background .12s}
  .dropzona.arrastando{border-color:var(--accent);
    background:color-mix(in oklab,var(--accent) 8%,transparent)}
  /* Comparador (handoff 3d): melhor valor da linha em verde e 600 */
  #cmp-table td.cmp-best{color:var(--pos);font-weight:600}
  /* com 2 ativos a tabela cheia jogava os valores para a borda direita da
     tela — ela passa a ter a largura do CONTEUDO, com piso por coluna */
  #cmp-table{width:auto;min-width:420px}
  #cmp-table th:not(:first-child),#cmp-table td:not(:first-child){min-width:170px}
  .cmp-bola{display:inline-block;width:9px;height:9px;border-radius:50%;
    margin-right:5px;vertical-align:0}
  /* Heatmap da rentabilidade mensal (handoff): fundo com opacidade
     proporcional à magnitude (5 degraus por color-mix — segue o tema) e
     barra de 3px comparando o mês com o CDI. Nada acima do piso de 10,5px:
     a célula tem UM número; o resto vai para o title e para o rodapé. */
  #perf-mensal-table td{text-align:center;padding:7px 4px;font-size:11.5px}
  #perf-mensal-table th{text-align:center}
  #perf-mensal-table td:first-child{text-align:left}
  /* O rodapé é texto LIVRE num `td` (nowrap por padrão): na grade larga ele
     cabia nas 14 colunas; na TRANSPOSTA do celular (3 colunas, 03/09/2026)
     ele ditava a largura da tabela inteira e empurrava os anos para fora
     do invólucro rolável — quebra de linha na classe, não por instância. */
  #perf-mensal-table .hm-rod{white-space:normal;text-align:left;line-height:1.5}
  .hm-p1{background:color-mix(in oklab,var(--pos) 10%,var(--bg-card))}
  .hm-p2{background:color-mix(in oklab,var(--pos) 19%,var(--bg-card))}
  .hm-p3{background:color-mix(in oklab,var(--pos) 28%,var(--bg-card))}
  .hm-p4{background:color-mix(in oklab,var(--pos) 38%,var(--bg-card))}
  .hm-p5{background:color-mix(in oklab,var(--pos) 48%,var(--bg-card))}
  .hm-n1{background:color-mix(in oklab,var(--neg) 10%,var(--bg-card))}
  .hm-n2{background:color-mix(in oklab,var(--neg) 19%,var(--bg-card))}
  .hm-n3{background:color-mix(in oklab,var(--neg) 28%,var(--bg-card))}
  .hm-n4{background:color-mix(in oklab,var(--neg) 38%,var(--bg-card))}
  .hm-n5{background:color-mix(in oklab,var(--neg) 48%,var(--bg-card))}
  .hm-vazio{background:var(--bg-inset);color:var(--text-4)}
  .hm-b{display:block;height:3px;border-radius:2px;margin:3px auto 0;width:72%}
  .hm-cdi-acima{background:var(--accent-soft)}
  .hm-cdi-abaixo{background:var(--text-4)}
  .hm-rod{text-align:left;color:var(--text-3);font-size:11.5px}
  .hm-rod .hm-b{display:inline-block;width:14px;vertical-align:middle;margin:0 3px}
  /* chips-toggle da legenda do grafico e seletor de colunas (handoff) */
  .chip.on{color:var(--accent-text);border-color:var(--accent);
    background:color-mix(in oklab,var(--accent) 16%,transparent)}
  button.chip{cursor:pointer}
  #pos-table.hide-score .c-score{display:none}
  #pos-table.hide-quantity .c-quantity{display:none}
  #pos-table.hide-avg_price .c-avg_price{display:none}
  #pos-table.hide-last_close .c-last_close{display:none}
  #pos-table.hide-market_value .c-market_value{display:none}
  #pos-table.hide-proventos .c-proventos{display:none}
  #pos-table.hide-dy .c-dy{display:none}
  #pos-table.hide-ganho .c-ganho{display:none}
  #pos-table.hide-realizado .c-realizado{display:none}
  #pos-table.hide-resultado .c-resultado{display:none}
  #pos-table.hide-spark .c-spark{display:none}
  .seg{display:inline-flex;gap:2px;background:var(--bg-inset);border:1px solid var(--line);
    border-radius:9px;padding:2px}
  .seg .mseg{border:none;background:transparent;border-radius:7px}
  .seg .mseg.on{background:var(--accent);color:#fff}
  /* "…" → menu Personalizado (02/09/2026): abre ancorado à ESQUERDA do
     botão (o segment fica no meio da tela; à direita ele sairia do card
     estreito); as pílulas de dentro voltam a ter borda porque não estão
     numa faixa .seg visualmente */
  .perio-menu{left:0;right:auto;min-width:300px;padding:12px 14px;gap:0}
  .perio-tit{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--text-4);margin-bottom:8px}
  .perio-grade{display:flex;flex-wrap:wrap;gap:6px}
  .perio-grade .mseg{border:1px solid var(--line);background:var(--sup2);border-radius:999px;min-height:30px;
    width:auto;flex:0 0 auto;padding:5px 12px}
  .perio-datas .btn{width:auto}
  .perio-grade .mseg:hover{border-color:var(--acc)}
  .perio-grade .mseg.on{background:var(--accent);border-color:var(--accent);color:#fff}
  .perio-datas{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
  .perio-datas label{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--text-3)}
  .perio-datas input[type=date]{width:auto;padding:5px 8px;font-size:12.5px}
  /* MOBILE (13/08/2026). O arquivo tinha UMA media query em 4.200 linhas —
     o layout não quebrava (graças a flex-wrap e auto-fit), mas era um site
     de desktop reduzido: cabeçalho de 3-4 linhas, filtros em 8 e tabela de
     10 colunas em rolagem horizontal. O público de Kinvo/Real Valor
     acompanha carteira no celular. */
  /* TABLET (15/08/2026). A faixa entre o celular e o desktop largo não tinha
     regra nenhuma: recebia o layout de desktop, e a nav de 949px não cabia.
     Com a quebra da regra base nenhum botão some mais, mas o cabeçalho ia a
     187px numa tela de 601px de altura — 31% do que o dono tem para ver a
     carteira. Compactar a nav a devolve para UMA fila na maioria dos tablets
     em paisagem; onde ainda não couber, a quebra continua valendo e o custo é
     uma fila a mais, nunca um botão escondido. */
  @media(min-width:701px) and (max-width:1100px){
    .brand .dom{display:none}          /* o domínio some; a marca fica */
    nav{gap:2px}
    nav button{font-size:13px;padding:7px 9px}
  }
  /* TELA BAIXA (15/08/2026). Celular em PAISAGEM tem 390px de altura e 844 de
     largura: pela largura ele cai na faixa de tablet, e o cabeçalho de 175px
     comia 45% do que sobra para ver a carteira. As media queries do arquivo
     todas olhavam a LARGURA; aqui o recurso escasso é a ALTURA, e é ela que
     manda. Só encolhe — nenhuma regra de posição, para não colidir com a
     barra inferior nem com o `sticky`. */
  /* Tela BAIXA (celular em paisagem, 844x390). Ela e LARGA — 844px passa do
     breakpoint de 700 —, entao as regras de celular nao a alcancam: e a
     armadilha que o CLAUDE.md documenta e que mordeu de novo em 17/08/2026.
     Medido antes: cabecalho de 109px em 390 de altura (28% da tela) com o
     userbox em QUATRO filas.

     Aqui o recurso escasso e a ALTURA, entao a decisao e a mesma do retrato:
     tema e idioma saem (moram no Perfil) e o userbox nao quebra linha. */
  @media(max-height:500px){
    header{padding:5px 12px;gap:8px}
    .brand .dom{display:none}
    .brand .mark{width:26px;height:26px;font-size:14px}
    .brand b{font-size:15px}
    nav button{font-size:12px;padding:5px 8px}
    #carteira-box{padding:2px 9px}
    /* DUAS faixas em vez de tres: marca e userbox dividem a primeira (96 +
       243 = 339px numa tela de 844), e a nav fica na segunda. Antes eram tres
       empilhadas — marca, nav e userbox — porque a soma passa da largura e o
       `flex-wrap` do header quebrava cada uma para a sua linha. */
    nav{order:3;width:100%}
    #userbox{flex-wrap:nowrap;margin-left:auto}
  }
  @media(max-width:700px){
    /* Matriz mensal TRANSPOSTA (03/09/2026): o dono quer até CINCO anos lado
       a lado — a carteira envelhece e os anos se somam. Em 390px os cinco
       cabiam por um triz com a célula de mesa (7px 4px, 11,5px); em 360px
       não cabiam (332px de conteúdo em 312). Célula mais justa e coluna do
       mês no mínimo. Acima de cinco o invólucro rola — declarado. */
    #perf-mensal-table td,#perf-mensal-table th{padding:6px 2px;font-size:11px}
    /* `:not(.hm-rod)`: o rodapé também é first-child da linha dele, e o
       nowrap da coluna do mês venceria o `white-space:normal` do rodapé
       por especificidade — mediu 624px numa tela de 360 na primeira versão */
    #perf-mensal-table td:first-child:not(.hm-rod),#perf-mensal-table th:first-child{width:1%;white-space:nowrap;padding-right:5px}
    td,th{padding:6px 6px;font-size:12px}
    #toasts{right:8px;left:8px;bottom:8px;max-width:none}
    /* O `backdrop-filter:none` que morava AQUI subiu para a regra base em
       15/08 — consertar só o celular foi o que deixou o tablet quebrado por
       um dia. O histórico fica registrado: `backdrop-filter` cria BLOCO
       CONTENEDOR para descendentes `position:fixed` (mesma regra do
       `transform` e do `filter`), então o `bottom:0` da nav resolvia contra o
       HEADER e não contra a viewport — a barra inferior era desenhada DENTRO
       do cabeçalho, por cima do #userbox, e conta, tema, idioma e "sair"
       ficavam inacessíveis (print do dono em 14/08/2026,
       docs/bugs/mobile-cabecalho-cortado-14-08.png).
       MEDIDO a 390x844: a nav ia para 55–90 com o header em 0–91 (userbox em
       50–82, coberto); sem o blur ela vai para 809–844, que é onde o CSS
       sempre quis pôr. */
    header{padding:8px 12px;gap:8px}
    .brand .dom{display:none}          /* o domínio some; a marca fica */
    .brand b{font-size:15px}
    nav{order:3;width:100%;padding-bottom:2px}
    nav button{font-size:13px;padding:7px 11px}
    /* UMA fila (17/08/2026, print do dono). Media antes: 6 controles em 3
       filas no iPhone SE, com o "sair" sozinho na terceira e o cabecalho em
       129px (19% da tela); em paisagem eram 4 filas e 28% da tela. O
       `flex-wrap:wrap` que existia para nao cortar nada acabava empilhando.

       O que cabe numa fila de 375px sao 4 controles, nao 6 — entao TEMA e
       IDIOMA saem do cabecalho no celular. Nao e perda de funcao: os dois
       ja existem na tela de Perfil (`#pf-tema`/`#pf-lang`), que e onde
       preferencia mora, e o avatar leva ate la num toque. Ficam os que se
       usam o tempo todo: carteira, busca, perfil e sair. */
    #userbox{margin-left:auto;gap:6px;flex-wrap:nowrap;justify-content:flex-end}
    /* o `min-height:32px` vem da regra base — ver o comentário lá */
    #carteira-box{padding:3px 9px}
    #btn-busca{min-height:32px}
    #btn-busca .atalho{display:none}   /* não há Ctrl+K no celular */
    /* Filtros da carteira: eram 8 linhas empilhadas ANTES de qualquer dado.
       Viram uma folha que abre sob demanda, com o resumo do que está ativo. */
    #flt-bar{display:none;flex-direction:column;gap:8px;padding-top:8px}
    #flt-bar.aberto{display:flex}
    /* Este botão NUNCA apareceu até 24/08/2026, e a conversão dos `style=`
       é que expôs: ele nascia com `style="display:none;..."` no markup, e
       inline vence regra de folha — inclusive esta, que existe justamente
       para mostrá-lo no celular. Ou seja, a folha de filtros sob demanda
       estava inalcançável no aparelho para o qual foi feita. Com o
       `display:none` virando classe, o `#id` daqui (1,0,0) passa a ganhar e
       o botão aparece. É a única mudança de comportamento da reforma, e ela
       foi medida: 32 propriedades diferentes em 7.110 elementos × 6
       contextos, todas rastreadas a este botão e ao <span> dentro dele (que
       vira item de flex e por isso é blocado). */
    #flt-toggle{display:inline-flex}
    #flt-bar select,#flt-bar input,#flt-bar .mselect{width:100%}
    /* nav vira barra INFERIOR: no polegar, e sem roubar o topo da tela */
    /* A barra inferior QUEBRA em filas; não rola. Medido em 15/08 nos dois
       motores: as 14 abas precisam de 763px e o celular tem 440 — seis
       (Derivativos, Comparar, Ativo, Importar, Impostos, Eventos) ficavam
       CLIPADAS, presentes no DOM e sem receber toque. `overflow-x:auto` numa
       barra de abas não tem affordance: quem não sabe arrastar conclui que a
       aba sumiu, e foi essa a queixa.
       A altura deixa de ser a constante 64px e passa a ser MEDIDA (`--nav-h`,
       ver `ancorarBarra()`): com quebra, a barra tem 2 filas a 440px e 3 a
       360px, e um número fixo aqui voltaria a cobrir o conteúdo — que é
       exatamente o bug de 14/08 por outro caminho. */
    #nav-principal{position:fixed;bottom:0;left:0;right:0;z-index:45;background:var(--bg-nav);
        border-top:1px solid var(--line);padding:5px 6px 5px;gap:2px;
        flex-wrap:wrap;justify-content:space-around;
        padding-bottom:calc(5px + env(safe-area-inset-bottom,0px))}
    nav button{font-size:11px;padding:6px 9px;flex-direction:column}
    /* barra de 5 destinos: alvo >=44px (handoff) e ativo por COR, nao por
       sublinhado — sublinhado na borda de baixo da tela nao se ve */
    #nav-principal button{min-height:44px;flex:1;display:flex;
        align-items:center;justify-content:center;font-size:10.5px;gap:1px}
    #nav-principal .ic{display:block;width:19px;height:19px;margin:0 auto}
    #nav-principal button.active{box-shadow:none;color:var(--accent-text);font-weight:600}
    #nav-sub{border-top:none;margin-top:0;padding-top:0}
    #nav-sub button{font-size:11.5px;padding:4px 8px}
    /* `width:auto` porque o `nav{width:100%}` desta mesma media query
       alcança a folha (ela é um <nav>) e vencia o par left/right: medido
       a 390px, a folha ia de 10 a 400 — 10px para fora da tela. */
    #sheet-mais{position:fixed;left:10px;right:10px;top:auto;width:auto;
        bottom:calc(var(--nav-h,64px) + 10px)}
    #sheet-mais button{min-height:44px;justify-content:flex-start}
    /* o menu Personalizado do período vira FOLHA inferior como o "Mais":
       ancorado ao "…" ele saía da tela pela direita (02/09/2026) */
    .perio-menu{position:fixed;left:10px;right:10px;top:auto;width:auto;min-width:0;
        bottom:calc(var(--nav-h,64px) + 10px)}
    /* UMA regra só, e a ordem importa: `padding` é ATALHO e zera o
       `padding-bottom` declarado antes dele. Eram duas regras, com o atalho
       na segunda — então o `padding-bottom:64px` escrito em 14/08 para a
       barra não cobrir o conteúdo **nunca valeu**, e o fim da tabela sempre
       ficou embaixo dela. Achado em 15/08 pelo teste de geometria, não pela
       leitura do CSS: as duas linhas parecem certas isoladas. */
    main{margin:14px auto;padding:0 10px calc(var(--nav-h,64px) + 12px)}
    .card{padding:13px;border-radius:10px;margin-bottom:13px}
    .kpis{grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:9px}
    .kpi .val{font-size:20px}
    select,input,button{max-width:100%}
    .mselect-btn{max-width:none;width:100%}
    .mselect-menu{min-width:min(280px,calc(100vw - 28px))}
    /* tabela de posições vira CARTÃO por linha: 10 colunas em 375px é
       rolagem horizontal permanente, que é o pior jeito de ler carteira */
    /* o cabeçalho é injetado como <tr> via innerHTML (tbody implícito) —
       não existe <thead> para esconder; some a LINHA de th, senão ela vira
       a primeira "carta" deformada */
    table.cartoes tr:has(th){display:none}
    /* Cada linha é um par rótulo↔valor ocupando a largura da COLUNA (print
       do dono, 23/08/2026): antes os valores moravam numa coluna à direita e
       a metade esquerda do cartão ficava vazia.

       DUAS COLUNAS desde 24/08/2026 (segundo print do mesmo cartão), mas SÓ
       em `.pares`: com uma coluna só, as 10 linhas viravam um cartão alto com
       um vão enorme entre rótulo e valor em cada fila. O modificador existe
       porque a régua é o CONTEÚDO, não a tabela — par curto (número, data,
       selo) cabe em meia largura; texto livre não. Medido antes de escolher:
       na watchlist, a "Nota pessoal" em meia coluna some pela esquerda, e nas
       filas de coleta a "Observação" é a mensagem de erro inteira. Quem opta
       pelo par declara isso no markup, e tabela nova nasce com uma coluna —
       que é o padrão que nunca quebra. */
    table.cartoes tr{display:grid;grid-template-columns:1fr;gap:2px 16px;
      border:1px solid var(--line);border-radius:10px;padding:9px 11px;margin-bottom:8px;
      box-sizing:border-box}
    /* `max(148px, 45%)` no piso do minmax dispensa breakpoint (armadilha nº 1
       desta seção: consertar numa largura só deixa o defeito de pé nas
       outras) — o piso percentual impede a TERCEIRA coluna perto de 700px e o
       piso em pixels cai para uma coluna abaixo de ~330px, onde duas não
       caberiam. */
    table.cartoes.pares tr{
      grid-template-columns:repeat(auto-fit,minmax(max(148px,45%),1fr))}
    table.cartoes td{border:none;padding:1px 0;font-size:12.5px;min-width:0}
    table.cartoes td:first-child{font-weight:600}
    /* só a identificação do ativo atravessa as duas colunas. Célula LARGA no
       meio da grade foi tentada (nota, valor, resultado) e devolvida: item
       que ocupa a fila inteira empurra o vizinho para a fila seguinte e abre
       BURACO — o "Cotação sozinho com a direita vazia" que é justamente a
       queixa do print. E o buraco muda de lugar conforme o filtro de período
       tira a coluna "Realizado", ou seja, layout que depende de PARIDADE. */
    table.cartoes td:first-child{grid-column:1/-1}
    /* `flex-end` + `margin-right:auto` no rótulo, e NÃO `space-between`: a
       célula composta tem mais de um item de valor (o "12,5% da carteira" ao
       lado do valor de mercado, o selo de perfil ao lado da nota) e o
       space-between espalhava os três pela largura toda — era isso que
       jogava o número para o MEIO da linha. Assim o rótulo encosta à
       esquerda e o valor inteiro fica junto, à direita.
       `flex-wrap` é o que impede o estrago quando o valor não cabe em meia
       largura (medido com -R$ 341,76 (-3,50%) a 390px): sem ele o conteúdo
       TRANSBORDA para fora do cartão à esquerda — o rótulo empurrado pelo
       `auto` não cede — em vez de descer uma linha. */
    table.cartoes td[data-r]{display:flex;flex-wrap:wrap;white-space:normal;
      justify-content:flex-end;align-items:baseline;gap:2px 8px;text-align:right}
    table.cartoes td[data-r]::before{content:attr(data-r);color:var(--mut);
      font-size:11px;text-align:left;white-space:nowrap;margin-right:auto}
  }
  /* item de notícia (23/08/2026, print do dono): no celular a fila de
     meta (data/fonte/código) espremia o texto na metade direita — abaixo
     de 700px o TEXTO quebra para a linha de baixo em largura total */
  .nt-row{display:flex;gap:10px;align-items:flex-start;padding:8px 0;
    border-bottom:1px solid var(--border,#8882)}
  .nt-texto{flex:1;min-width:0}
  /* resumo do feed com TETO de 3 linhas: o texto integral (com o "The post
     ... appeared first" do RSS) empurrava o card para baixo sem dizer mais
     nada — o title segue com o texto inteiro */
  .nt-resumo{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;
    overflow:hidden}
  @media(max-width:700px){
    .nt-row{flex-wrap:wrap;row-gap:3px}
    .nt-texto{flex-basis:100%}
  }
  /* A MESMA quebra no card ESTREITO do desktop (lateral de 330-380px): a
     regra so no viewport <=700 deixou o titulo com um fio de coluna no
     print de 31/08 — e a armadilha do breakpoint por outro caminho: a regua
     e a LARGURA DO CONTEINER, nao a da tela */
  .cart-lado .nt-row{flex-wrap:wrap;row-gap:3px}
  .cart-lado .nt-texto{flex-basis:100%}
  /* estrela da lista de acompanhamento (13/08/2026) */
  .wl-star{cursor:pointer;margin-left:5px;color:var(--mut);text-decoration:none;font-size:14px}
  .wl-star.on{color:var(--warn)}
  .wl-star:hover{color:var(--warn)}
  /* chips dos destaques do dia */
  .dst-chip{display:inline-flex;align-items:center;gap:6px;border:1px solid var(--line);
    border-radius:8px;padding:5px 10px;margin:3px 6px 3px 0;cursor:pointer;font-size:13px}
  .dst-chip:hover{border-color:var(--acc)}
  /* painel do screener (faixas por classe) */
  .scr-panel{border:1px solid var(--line);border-radius:10px;padding:10px 12px;margin:4px 0 10px}
  .scr-panel .scr-row{display:inline-flex;align-items:center;gap:5px;margin:3px 12px 3px 0}
  .scr-panel .scr-row span{font-size:12px;color:var(--mut);min-width:0}
  .scr-panel input[type=number]{width:76px;padding:4px 6px;font-size:12px}
  /* Card "Módulos do sistema" do Admin (13/08/2026, refeito). A primeira
     versão era UMA tabela com a lista de rotas de cada módulo no corpo:
     parede de texto, 18 linhas, e o trabalho que o dono faz de verdade —
     "liberar o módulo X para o fulano" — exigia achar a pessoa em 18
     seletores diferentes, um por linha. Agora a vista padrão é a pergunta
     real ("o que esta conta pode ver?") e as rotas viraram <details>. */
  .mseg{background:var(--sup2);border:1px solid var(--line);color:var(--mut);
        padding:5px 12px;border-radius:999px;font-size:12.5px;cursor:pointer}
  .mseg:hover{border-color:var(--acc);color:var(--tx)}
  .mseg.on{background:var(--acc);border-color:var(--acc);color:#fff}
  .mseg.lig{background:var(--pos);border-color:var(--pos);color:var(--bg-page)}
  .mseg.desl{background:var(--neg);border-color:var(--neg);color:#fff}
  .mod-cols{display:flex;gap:14px;align-items:flex-start}
  .mod-esq{flex:0 0 250px;min-width:0}
  .mod-dir{flex:1;min-width:0}
  .mod-contas{max-height:340px;overflow-y:auto;border:1px solid var(--line);border-radius:10px}
  .mod-conta{padding:7px 10px;border-bottom:1px solid var(--line);cursor:pointer;font-size:13px}
  .mod-conta:last-child{border-bottom:none}
  .mod-conta:hover{background:var(--hover)}
  .mod-conta.sel{background:var(--hover);box-shadow:inset 3px 0 0 var(--acc)}
  .mod-grade{display:grid;grid-template-columns:repeat(auto-fill,minmax(235px,1fr));gap:8px}
  .mod-item{display:flex;gap:9px;align-items:flex-start;border:1px solid var(--line);
            border-radius:10px;padding:9px 11px;cursor:pointer}
  .mod-item:hover{border-color:var(--acc)}
  .mod-item input[type=checkbox]{accent-color:var(--acc);width:16px;height:16px;
            margin:2px 0 0;padding:0;flex-shrink:0}
  .mod-item.off{opacity:.6;cursor:default}
  .mod-item.salvando{opacity:.45}
  .mod-tag{display:inline-block;font-size:10.5px;text-transform:uppercase;letter-spacing:.4px;
           border:1px solid var(--line);border-radius:999px;padding:1px 7px;color:var(--mut);margin-left:6px}
  .mod-tag.geral{color:var(--pos);border-color:var(--pos)}
  .mod-tag.restrito{color:var(--acc);border-color:var(--acc)}
  .mod-tag.desligado{color:var(--neg);border-color:var(--neg)}
  @media(max-width:700px){
    .mod-cols{flex-direction:column}
    .mod-esq{flex:none;width:100%}
    .mod-contas{max-height:210px}
    .mod-grade{grid-template-columns:1fr}
  }

  /* ------------------------------------------------------------------
     UTILITÁRIOS (24/08/2026) — geradas da conversão dos 727 `style=` do
     markup. Existem porque a CSP perdeu `'unsafe-inline'` no `style-src`:
     sem a diretiva o navegador RECUSA atributo `style` vindo do markup,
     inclusive o que o próprio app escreve por innerHTML.

     Ficam NO FIM do arquivo de propósito. Inline vencia toda regra de folha,
     e ORDEM DE ORIGEM é a única forma de reproduzir isso sem `!important` —
     que venceria também as media queries e traria a armadilha nº 5 de volta
     pelo outro lado (o `height` do gráfico precisa continuar ganhando de
     `height:auto`, e o `width:100%` da media query precisa continuar
     valendo).

     `:root` na frente de cada seletor NÃO é enfeite: `style=` vencia toda
     regra de folha, e uma classe sozinha (0,1,0) perde para `button.btn`
     (0,1,1) — medido, o botão do screener voltou de `padding:6px 12px` para
     os `9px 16px` do `.btn` e cresceu 8x6px. Com `:root` a especificidade vai
     a (0,2,0) e a folha volta a ganhar de seletor com elemento. `!important`
     resolveria também, e foi RECUSADO: ele venceria as media queries, e a
     armadilha nº 5 do CSS voltaria pelo outro lado.

     Nome: regra de uma ou duas declarações vira nome falado (`u-mb-8`,
     `u-d-none`); acima disso é a abreviação da primeira propriedade mais um
     número, porque `u-maxw-640-m-60-auto-p-24-bd-1-solid-2a3550` é pior que
     o `style=` que substitui. Quem quer saber o que a classe faz lê aqui.
     ------------------------------------------------------------------ */
  :root .u-maxw{max-width:640px;margin:60px auto;padding:24px;border:1px solid var(--line);border-radius:12px;background:var(--card);color:var(--tx);font:14px/1.5 var(--fonte-sans)}
  :root .u-d-none{display:none}
  :root .u-d{display:none;align-items:center;gap:4px;cursor:pointer}
  :root .u-lh-0{line-height:0}
  :root .u-bg{background:transparent;border:none;color:inherit;font-size:12px;cursor:pointer;padding:0;max-width:130px}
  :root .u-p-5-11-fs-13{padding:5px 11px;font-size:13px}
  :root .u-c-mut-fs-11{color:var(--mut);font-size:11px}
  :root .u-d2{display:flex;align-items:center;gap:4px;cursor:pointer}
  :root .u-bg2{background:transparent;border:none;color:inherit;font-size:12px;cursor:pointer;padding:0}
  :root .u-d-flex-lh-0{display:flex;line-height:0}
  :root .u-d3{display:none;align-items:center;gap:8px;margin:4px 0}
  :root .u-w-auto{width:auto}
  :root .u-bg-line{background:var(--line)}
  :root .u-m-0{margin:0}
  :root .u-d4{display:none;padding:5px 11px;font-size:13px}
  :root .u-p-6-12{padding:6px 12px}
  :root .u-tt-none{text-transform:none}
  :root .u-ovx-auto{overflow-x:auto}
  :root .u-mb-8{margin-bottom:8px}
  :root .u-d5{display:inline-flex;align-items:center;gap:5px;cursor:pointer}
  :root .u-w-190{width:190px}
  :root .u-ml-12{margin-left:12px}
  :root .u-mb-12{margin-bottom:12px}
  :root .u-d-none-mb-12{display:none;margin-bottom:12px}
  :root .u-d6{display:flex;height:26px;border-radius:8px;overflow:hidden}
  :root .u-mt-6{margin-top:6px}
  :root .u-m-0-0-4{margin:0 0 4px}
  :root .u-mb-6{margin-bottom:6px}
  :root .u-h-200{height:200px}
  :root .u-mt-8{margin-top:8px}
  :root .u-w{width:150px;display:block;margin-top:4px}
  :root .u-w2{width:80px;display:block;margin-top:4px}
  :root .u-d-block-mt-4{display:block;margin-top:4px}
  :root .u-mt-10-minh-18{margin-top:10px;min-height:18px}
  :root .u-w-130{width:130px}
  :root .u-h-170{height:170px}
  :root .u-m-0-0-6{margin:0 0 6px}
  :root .u-ai-flex-start{align-items:flex-start}
  :root .u-mb-10{margin-bottom:10px}
  :root .u-m-0-0-8{margin:0 0 8px}
  :root .u-h-150{height:150px}
  :root .u-mt-10{margin-top:10px}
  :root .u-h-260{height:260px}
  :root .u-mt-10-d-none{margin-top:10px;display:none}
  :root .u-g-18-mb-8{gap:18px;margin-bottom:8px}
  :root .u-h-240{height:240px}
  :root .u-ovx-auto-mt-10{overflow-x:auto;margin-top:10px}
  :root .u-m-2-0-12{margin:2px 0 12px}
  :root .u-d7{display:grid;grid-template-columns:repeat(auto-fit,minmax(330px,1fr));gap:14px}
  :root .u-p-6{padding:6px}
  :root .u-cur-pointer{cursor:pointer}
  :root .u-mt-8-minh-16{margin-top:8px;min-height:16px}
  :root .u-d8{display:flex;gap:6px;align-items:center;margin-top:6px;cursor:pointer}
  :root .u-d9{display:flex;gap:6px;align-items:center;margin-top:4px;cursor:pointer}
  :root .u-d-none-bdc-e67e22{display:none;border-color:var(--warn)}
  :root .u-m-0-c-e67e22{margin:0;color:var(--warn)}
  :root .u-m{margin:22px 0 10px;font-size:15px;color:var(--mut);text-transform:uppercase;letter-spacing:.5px}
  :root .u-bdc-5c2b2b{border-color:var(--neg-border)}
  :root .u-c-e74c3c{color:var(--neg)}
  :root .u-w-220{width:220px}
  :root .u-bg-e74c3c{background:var(--neg)}
  :root .u-w-110-tt-uppercase{width:110px;text-transform:uppercase}
  :root .u-w-120{width:120px}
  :root .u-m-4-4-20{margin:4px 4px 20px}
  :root .u-maxw-1200-m-0-auto{max-width:1200px;margin:0 auto}
  :root .u-d10{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(420px,100%),1fr));gap:18px;align-items:start}
  :root .u-mb-0{margin-bottom:0}
  :root .u-mb-14-ai-center{margin-bottom:14px;align-items:center}
  :root .u-w3{width:84px;height:84px;border-radius:50%;object-fit:cover;background:var(--sup2);border:1px solid var(--line)}
  :root .u-p-6-maxw-230{padding:6px;max-width:230px}
  :root .u-mt-4{margin-top:4px}
  :root .u-g-10{gap:10px}
  :root .u-d11{display:block;width:100%;margin-top:4px}
  :root .u-d12{display:flex;align-items:center;gap:8px;margin-top:8px}
  :root .u-mt-2-ai-center{margin-top:2px;align-items:center}
  :root .u-d-none-mt-6{display:none;margin-top:6px}
  :root .u-mt-6-g-6{margin-top:6px;gap:6px}
  :root .u-w-110{width:110px}
  :root .u-bg3{background:#fff;display:inline-block;padding:8px;border-radius:8px}
  :root .u-w-140{width:140px}
  :root .u-d13{display:none;white-space:pre-wrap;background:var(--sup2);padding:8px;border-radius:8px;margin-top:6px}
  :root .u-d-block-mt-14{display:block;margin-top:14px}
  :root .u-g-14-fwrap-wrap{gap:14px;flex-wrap:wrap}
  :root .u-d14{display:flex;align-items:center;gap:6px}
  :root .u-mt{margin-top:8px;gap:6px;flex-wrap:wrap;display:none}
  :root .u-mt2{margin-top:8px;gap:6px;flex-wrap:wrap}
  :root .u-w-150{width:150px}
  :root .u-w-70{width:70px}
  :root .u-w-100{width:100px}
  :root .u-mt-6-d-none{margin-top:6px;display:none}
  :root .u-mb-0-bdc-5a2b2b{margin-bottom:0;border-color:var(--neg-border)}
  :root .u-c-e05d5d{color:var(--neg)}
  :root .u-w-110-d-none{width:110px;display:none}
  :root .u-mb-4{margin-bottom:4px}
  :root .u-p-4-10{padding:4px 10px}
  :root .u-mt3{margin-top:8px;display:flex;gap:6px;flex-wrap:wrap}
  :root .u-mt-14-jc-space-between{margin-top:14px;justify-content:space-between}
  :root .u-g-6{gap:6px}
  :root .u-h-190-mt-6{height:190px;margin-top:6px}
  :root .u-w-230{width:230px}
  :root .u-w-70pc{width:70%}
  :root .u-w-120-tt-uppercase{width:120px;text-transform:uppercase}
  :root .u-w-90{width:90px}
  :root .u-w-280{width:280px}
  :root .u-tt-uppercase{text-transform:uppercase}
  :root .u-d15{display:inline-flex;gap:5px;align-items:center;cursor:pointer}
  :root .u-jc{justify-content:space-between;align-items:flex-start}
  :root .u-ai-center-fwrap-nowrap{align-items:center;flex-wrap:nowrap}
  :root .u-fs-24-fw-700{font-size:24px;font-weight:700}
  :root .u-ta-right{text-align:right}
  :root .u-fs-28-fw-700{font-size:28px;font-weight:700}
  :root .u-fs-15{font-size:15px}
  :root .u-mt-14{margin-top:14px}
  :root .u-d16{display:none;margin-bottom:8px;color:var(--warn)}
  :root .u-h-240-mt-10{height:240px;margin-top:10px}
  :root .u-d17{display:block;margin-top:4px;width:130px}
  :root .u-d18{display:block;margin-top:4px;width:120px}
  :root .u-d19{display:none;height:240px;margin-top:8px}
  :root .u-mt-8-lh-1-5{margin-top:8px;line-height:1.5}
  :root .u-h-220{height:220px}
  :root .u-lh-1-7{line-height:1.7}
  :root .u-lh-1-55{line-height:1.55}
  :root .u-mt4{margin-top:8px;border-top:1px solid var(--border,#8882);padding-top:6px}
  :root .u-h{height:320px;border-radius:8px;display:none;margin-bottom:8px}
  :root .u-m-4-0{margin:4px 0}
  :root .u-mr-10{margin-right:10px}
  :root .u-mt-2{margin-top:2px}
  :root .u-fs-12{font-size:12px}
  :root .u-p-4-8{padding:4px 8px}
  :root .u-fw-600{font-weight:600}
  :root .u-bg-grid{background:var(--grid)}
  :root .u-m-0-0-10{margin:0 0 10px}
  :root .u-minw-74-ws-nowrap{min-width:74px;white-space:nowrap}
  :root .u-tt-none-mt-2{text-transform:none;margin-top:2px}
  :root .u-m-10-0{margin:10px 0}
  :root .u-d20{display:flex;gap:8px;align-items:flex-start;margin:6px 0}
  :root .u-p-3-8-fs-12{padding:3px 8px;font-size:12px}
  :root .u-fl-1{flex:1}
  :root .u-ws{white-space:pre-wrap;margin:0;font-size:12px;background:var(--card,#00000010);border-radius:6px;padding:6px 8px}
  :root .u-ta-left{text-align:left}
  :root .u-mr-6{margin-right:6px}
  :root .u-ta-left-ws-nowrap{text-align:left;white-space:nowrap}
  :root .u-p-4-8-bg-e74c3c{padding:4px 8px;background:var(--neg)}
  :root .u-g-6-m-8-0{gap:6px;margin:8px 0}
  :root .u-w-100pc-mb-8{width:100%;margin-bottom:8px}
  :root .u-p-16-4{padding:16px 4px}
  :root .u-minw-0{min-width:0}
  :root .u-ws-normal{white-space:normal}
  :root .u-maxw2{max-width:360px;overflow:hidden;text-overflow:ellipsis}
  :root .u-mt-3{margin-top:3px}
  :root .u-ws-normal-mt-3{white-space:normal;margin-top:3px}
  :root .u-g{gap:4px;justify-content:flex-end;display:inline-flex}
  :root .u-ta-left-mt-4{text-align:left;margin-top:4px}
  :root .u-ta{text-align:left;max-width:300px;overflow:hidden;text-overflow:ellipsis}
  :root .u-fs-13{font-size:13px}
  :root .u-p-4-8-bg-93a0b8{padding:4px 8px;background:var(--text-3)}
  :root .u-p-4-8-bg-7a1f1f{padding:4px 8px;background:var(--neg-border)}
  :root .u-p-4-10-bg-e74c3c{padding:4px 10px;background:var(--neg)}
  :root .u-p-4-8-bg-2ecc71{padding:4px 8px;background:var(--pos-solid)}
  :root .u-maxw-340{max-width:340px}
  :root .u-p-4-8-bg-7f8c8d{padding:4px 8px;background:var(--text-4)}
  :root .u-p-4-8-bg-27ae60{padding:4px 8px;background:var(--pos-solid)}
  :root .u-p-4-8-bg-c0392b{padding:4px 8px;background:var(--neg)}
  :root .u-p-4-8-bg-95a5a6{padding:4px 8px;background:var(--text-4)}
  :root .u-p-5-12{padding:5px 12px}
  :root .u-p-5-10-bg-e74c3c{padding:5px 10px;background:var(--neg)}
  :root .u-bd{border:1px solid var(--bd);border-radius:8px;padding:10px 12px;margin-bottom:8px}
  :root .u-jc-space-between{justify-content:space-between}
  :root .u-ml-14{margin-left:14px}
  :root .u-ml-14-mt-2{margin-left:14px;margin-top:2px}
  :root .u-ws-nowrap{white-space:nowrap}
  :root .u-maxw3{max-width:180px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  :root .u-bdl-3-solid-acc{border-left:3px solid var(--acc)}
  :root .u-gtc{grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}
  :root .u-bd2{border:1px solid var(--warn);border-radius:8px;padding:8px 12px;color:var(--warn);margin-bottom:8px}
  :root .u-fs-11{font-size:11px}
  :root .u-d21{display:flex;align-items:center;gap:8px;margin:4px 0;font-size:13px;color:var(--tx);cursor:pointer}
  :root .u-bdl-3-solid-e67e22{border-left:3px solid var(--warn)}
  :root .u-bd3{border:1px solid var(--warn);border-radius:8px;padding:8px 12px;color:var(--warn)}
  :root .u-flex-basis-100pc{flex-basis:100%}
  :root .u-c-e67e22{color:var(--warn)}
  :root .u-p-12{padding:12px}
  :root .u-fs-18{font-size:18px}
  :root .u-minw-120{min-width:120px}
  :root .u-fs{font-size:10.5px;text-transform:uppercase;letter-spacing:.4px}
  :root .u-fw-600-mt-2{font-weight:600;margin-top:2px}
  :root .u-minw-150-fw-700{min-width:150px;font-weight:700}
  :root .u-minw-110{min-width:110px}
  :root .u-d22{display:flex;align-items:center;gap:8px;margin-top:3px}
  :root .u-fw-600-fs-13{font-weight:600;font-size:13px}
  :root .u-w4{width:56px;height:5px;border-radius:3px;background:var(--line);overflow:hidden}
  :root .u-d23{display:flex;align-items:center;gap:7px}
  :root .u-mr-0{margin-right:0}
  :root .u-maxw4{max-width:170px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  :root .u-d24{display:flex;align-items:center;gap:10px;margin:4px 0}
  :root .u-w-56{width:56px}
  :root .u-maxw-280{max-width:280px}
  :root .u-m-6-0{margin:6px 0}
  :root .u-mt-6-c-e67e22{margin-top:6px;color:var(--warn)}
  :root .u-ta-center-p-10{text-align:center;padding:10px}
  :root .u-ta2{text-align:left;max-width:240px;overflow:hidden;text-overflow:ellipsis}
  :root .u-c-tx{color:var(--tx)}
  :root .u-maxw5{max-width:160px;overflow:hidden;text-overflow:ellipsis}
  :root .u-ta3{text-align:left;max-width:220px;overflow:hidden;text-overflow:ellipsis}
  :root .u-minw-44-ws-nowrap{min-width:44px;white-space:nowrap}
  :root .u-minw{min-width:66px;white-space:nowrap;cursor:pointer}
  :root .u-fs-17{font-size:17px}
  :root .u-maxw6{max-width:220px;overflow:hidden;text-overflow:ellipsis}
  :root .u-d25{display:flex;align-items:center;gap:10px;margin:5px 0}
  :root .u-w-150-fs-13{width:150px;font-size:13px}
  :root .u-w-110-fs-13{width:110px;font-size:13px}
  :root .u-fs-34-fw-700{font-size:34px;font-weight:700}
  :root .u-w-100pc{width:100%}
  :root .u-grid-column-1-1-mt-6{grid-column:1/-1;margin-top:6px}
  :root .u-d26{display:flex;height:12px;border-radius:999px;overflow:hidden;background:var(--sup2)}
  :root .u-mr-12{margin-right:12px}
  :root .u-maxw7{max-width:190px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  :root .u-maxw8{max-width:260px;overflow:hidden;text-overflow:ellipsis}
  :root .u-fs2{font-size:10.5px;text-transform:uppercase;letter-spacing:.4px;margin-bottom:3px}
  :root .u-p-5-12-bg-line{padding:5px 12px;background:var(--line)}
  /* Escritas à mão (as de cima são geradas): sobraram da conversão dos
     `style=` que tinham parte estática e parte calculada — a estática virou
     esta classe e a cor/ largura foi para `corCls`/`data-larg`. */
  :root .u-p-2-7-br-10{padding:2px 7px;border-radius:10px;font-size:11px;white-space:nowrap}
  :root .u-c-0f1420-fw600{color:var(--bg-page);font-weight:600}
  :root .u-fw600-fs11{font-weight:600;font-size:11px}
  :root .u-h-100pc{height:100%}
  :root .u-d-inline-block-8-8{display:inline-block;width:8px;height:8px;border-radius:2px;margin-right:4px}
  :root .u-cartao-classe{margin:0 0 8px;border-left:3px solid;display:flex;gap:26px;align-items:center;flex-wrap:wrap;padding:12px 16px}
  :root .u-op-65{opacity:.65}
/* Planejamento: a coluna de resultado cresce sem impor largura ao celular. */
.plan-grid { display:grid; grid-template-columns:minmax(280px,360px) minmax(0,1fr); gap:20px; align-items:start; }
.plan-grid>* { min-width:0; }
.plan-form { display:flex; flex-direction:column; gap:16px; }
.plan-form label { display:flex; flex-direction:column; gap:6px; }
.plan-form input:not([type=checkbox]), .plan-form select { width:100%; min-width:0; box-sizing:border-box; }
.plan-fields { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:14px; margin-top:12px; }
.plan-form .plan-check { flex-direction:row; align-items:center; }
.plan-form details { border-top:1px solid var(--line); padding-top:12px; }
.plan-form summary { cursor:pointer; padding:8px 0; }
.plan-chart { height:300px; width:100%; }
.plan-table { max-height:520px; }
.plan-results .kpis { grid-template-columns:repeat(2,minmax(0,1fr)); }
@media(max-width:1000px) { .plan-grid { grid-template-columns:minmax(0,1fr); } }
@media(max-width:400px) { .plan-fields { grid-template-columns:minmax(0,1fr); } }

/* Conferência de IR no campo de visão, inclusive com décadas no histórico. */
.fiscal-dialog{width:min(1100px,calc(100% - 32px));max-height:85vh;padding:20px;background:var(--card);color:var(--tx);border:1px solid var(--line);border-radius:14px;overflow:auto}
.fiscal-dialog::backdrop{background:rgba(0,0,0,.65)}
.fiscal-campos{border:0;padding:0;margin:12px 0;min-width:0}
.fiscal-dialog .row{flex-wrap:wrap}
.fiscal-dialog table{font-size:12px}

/* IR segue os tokens do site e limita a leitura, inclusive no ultrawide. */
.ir-page{max-width:1360px;margin-inline:auto}
.ir-page-heading{padding:8px 2px 22px}
.ir-page-heading h1{font-size:26px;letter-spacing:-.5px;margin:0 0 8px}
.ir-page>.card{padding:24px;margin-bottom:20px}
.ir-page h2{font-size:18px;margin-bottom:10px}
.ir-page h3{font-size:15px;margin:0}
.ir-page .hint{line-height:1.55}
.ir-page>.card>p.hint{max-width:100ch}
.ir-intro{margin-bottom:16px}
.ir-filterbar{display:flex;gap:16px;flex-wrap:wrap;align-items:end;margin:20px 0 12px}
.ir-filterbar label{display:flex;flex-direction:column;gap:6px;min-width:180px}
.ir-filterbar select{min-height:40px}
.ir-darf-footer{display:flex;gap:16px;justify-content:space-between;align-items:center;flex-wrap:wrap;margin:16px 0 10px}
.ir-help{padding:14px 0;border-top:1px solid var(--line);margin-top:14px}
.ir-help summary,.ir-quick-sale summary{cursor:pointer;font-weight:600;line-height:1.5}
.ir-help[open]>p,.ir-help[open]>form{margin-top:12px}
.ir-section-header{margin-bottom:24px;max-width:90ch}
.ir-plan-grid{display:grid;grid-template-columns:minmax(280px,360px) minmax(0,1fr);gap:28px;align-items:start}
.ir-plan-grid>*{min-width:0}
.ir-sale-form{padding:20px;background:var(--bg-inset);border:1px solid var(--line);border-radius:var(--r2)}
.ir-sale-form .plan-fields{margin-top:0;gap:14px}
.ir-sale-form .ir-campo-inteiro{grid-column:1/-1}
.ir-sale-form input{min-height:42px}
.ir-sale-form>button{align-self:flex-start;max-width:100%}
.ir-list-heading{display:flex;justify-content:space-between;gap:12px;align-items:center;margin-bottom:14px}
.ir-empty-plan{display:grid;place-content:center;min-height:240px;text-align:center;padding:24px;border:1px dashed var(--line);border-radius:var(--r2);gap:10px}
.ir-empty-plan .hint{max-width:42ch}
.ir-sale-list table{font-size:12px}
.ir-actions{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-top:18px}
.ir-plan-result:empty{display:none}
.ir-plan-result:not(:empty){border-top:1px solid var(--line);padding-top:24px;margin-top:24px}
.ir-plan-result .kpis{grid-template-columns:repeat(3,minmax(0,1fr));margin:16px 0}
.ir-quick-sale{border-top:1px solid var(--line);margin-top:24px;padding-top:18px}
.ir-quick-sale>p{margin:12px 0}
.ir-quick-fields{display:grid;grid-template-columns:repeat(3,minmax(0,200px)) max-content;gap:12px;align-items:end}
.ir-quick-fields label{display:flex;flex-direction:column;gap:6px}
.ir-quick-fields input{width:100%;min-width:0;min-height:40px;box-sizing:border-box}
.fiscal-dialog{margin:auto;max-height:90vh}
.ir-dialog-heading{justify-content:space-between;padding-bottom:14px;border-bottom:1px solid var(--line);margin-bottom:16px}
.fiscal-dialog .fiscal-campos>details{border:1px solid var(--line);border-radius:var(--r2);padding:14px;margin:12px 0}
.fiscal-dialog summary{cursor:pointer;font-weight:600}
.fiscal-dialog details[open]>form{margin-top:14px}
.fiscal-dialog .plan-form>button{align-self:flex-start}
@media(max-width:900px){
  .ir-plan-grid{grid-template-columns:minmax(0,1fr)}
  .ir-sale-form .plan-fields{grid-template-columns:repeat(2,minmax(0,1fr))}
  .ir-sale-form .ir-campo-inteiro{grid-column:auto}
  .ir-sale-form .ir-campo-inteiro:last-child{grid-column:1/-1}
  .ir-empty-plan{min-height:150px}
  .ir-quick-fields{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media(max-width:600px){
  .ir-page>.card{padding:16px;margin-bottom:16px}
  .ir-page-heading h1{font-size:23px}
  .ir-page h2{font-size:17px}
  .ir-sale-form{padding:14px}
  .ir-sale-form>button{align-self:stretch}
  .ir-plan-result .kpis{grid-template-columns:repeat(2,minmax(0,1fr))}
  .ir-filterbar label{flex:1;min-width:130px}
  .ir-darf-footer{align-items:stretch}
  .ir-darf-footer>button{width:100%}
  .fiscal-dialog{padding:14px;width:calc(100% - 20px)}
}
.ir-section-nav{display:flex;flex-wrap:wrap;gap:8px;margin:0 0 22px}
.ir-page>.card{scroll-margin-top:90px}
.ir-page .btn.secondary{background:var(--bg-inset);color:var(--text-2);border:1px solid var(--line)}
.ir-page .btn.secondary:hover{background:var(--bg-card-hover)}
.ir-section-nav .btn{border-radius:var(--r3)}
