/* ===========================================================================
   TOKENS — cópia literal da normativa emcash (tema dark), com os quatro
   níveis que só a página "Identidade" lista (DDR-062/063/001/007). Nada aqui
   é inventado. O laranja de link de arquivo vem do geko (05/09/2026): o
   laranja de ação #FF8836 ficava claro demais em link de documento.
   =========================================================================== */
:root{
  --bg:#0B0B10; --panel:#15151C; --panel-2:#1D1D26; --bg-subtle:#191921;
  --border:#26262F; --border-strong:#33333F;
  --text:#FAFAFC; --text-primary:#E6E6EC; --text-dim:#B0AFBB; --text-tertiary:#8B8A96;
  --brand-orange:#FF6A00; --text-brand:#FF8836; --text-brand-arquivo:#FF6A00;
  --border-focus:#FF8836; --teal-ui:#4FB1BA;
  --ok:#3FBF78; --ok-bg:#0F2018; --ok-border:#1F5638;
  --bad:#E63950; --bad-fg:#F5556F; --bad-bg:#25121A; --bad-border:#6B1E2E;
  --warn:#E5A020; --warn-fg:#F0B341; --warn-bg:#241A08; --warn-border:#6B4A0F;
  --pending:#918F9E;
  /* escala única: 8pt (DDR-015) e raio 0/4/8/12/16/9999 (DDR-016) */
  --gap:16px; --pad:16px; --sec-gap:32px;
  --r-xs:4px; --r-md:8px; --r-lg:12px; --r-xl:16px; --r-pill:9999px;
  /* Divergência CONSCIENTE contra DDR-068 (Identidade visual emcash, Notion):
     a norma fixa #231F20 (contraste medido 5,68:1) e branco mede so' 2,87:1,
     abaixo do minimo de 3:1 para texto grande -- decisao do Guilherme,
     14/09/2026, ciente da perda de contraste. Ver docs/projeto.md. */
  --text-on-brand:#FFFFFF;
  /* Divergência CONSCIENTE (R14, docs/projeto.md) contra `bg.brand` da
     Identidade Visual emcash (Notion), que fixa #FF6A00 igual no light e no
     dark -- sem tom mais escuro ja ratificado pra' preenchimento de botao.
     So' pro FUNDO SOLIDO de botao/chip ativo (nunca pra' grafico/kpi/acento,
     que continuam em --brand-orange = token oficial, ver dataviz.categorical.1
     na normativa). Decisao do Guilherme, 14/09/2026, depois de eu apontar
     que era divergencia -- contraste com --text-on-brand (branco) SOBE de
     2,87:1 pra' 3,46:1 (passa o minimo de 3:1 de texto grande; ainda abaixo
     de 4,5:1 de texto normal). */
  --brand-orange-botao:#E85F00;
  --sombra-cartao:0 8px 24px rgba(0,0,0,.45);
  --sombra-gaveta:8px 0 24px rgba(0,0,0,.5);
  --scrim:rgba(0,0,0,.6);    /* fundo da gaveta */
  --ease:cubic-bezier(.4,0,.2,1);
  --fonte-titulo:"Manrope",-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  --fonte-texto:"Public Sans",-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
}
*{box-sizing:border-box}
/* `html` tambem escuro -- sem isso, o fundo branco padrao do navegador
   aparece por baixo em qualquer instante em que o `body` fica transparente
   (ex.: o fade de entrada, `body.entrando` mais abaixo) ou antes do CSS
   carregar. Tema escuro unico (R12) nao deveria deixar passar branco em
   NENHUM instante. */
html{background:var(--bg)}
body{margin:0;background:var(--bg);color:var(--text-primary);
     font-family:var(--fonte-texto);line-height:1.5;font-size:14px}
h1,h2,h3,.num{font-family:var(--fonte-titulo)}
.num{font-variant-numeric:tabular-nums}

/* Feedback de APERTAR botão -- zero `:active` no sistema inteiro ate' hoje
   (achado do Guilherme, 14/09/2026, acabamento geral). Um so' encolhimento
   sutil, reaproveitado por toda familia de botao (nunca cor nova, nunca
   sombra) -- o toque de "fundo do dedo/mouse" que falta pro clique parecer
   FISICO. Cada classe ja tem seu proprio `transition` (a maioria com
   `all`), entao o retorno ja anima sozinho; onde faltava (`.destino`,
   so' background/color) foi somado `transform`. */
.btn-modo:active,.btn-principal:active,.btn-csv:active,.fchip:active,
.produto:active,.destino:active,.avatar:active,.acoes button:active{
  transform:scale(.96)}

/* Barra de rolagem PADRÃO do View -- cinza, fina, sem seta. Guilherme,
   13/09/2026: "sem ser esse default feio" (primeira versão era laranja da
   marca; ele preferiu cinza depois de ver -- mesmo desenho, só a cor). O
   MESMO CSS (não uma cópia) é injetado dentro do dashboard embutido -- ver
   `iframeDashboard.js::cssBarraDeRolagem` -- para as duas nunca divergirem
   visualmente. */
::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:var(--text-tertiary);border-radius:999px;
  border:2px solid transparent;background-clip:padding-box}
::-webkit-scrollbar-thumb:hover{background:var(--text-dim);background-clip:padding-box}
*{scrollbar-color:var(--text-tertiary) transparent;scrollbar-width:thin}

/* ---------- topbar ---------- */
.top{position:sticky;top:0;z-index:10;display:flex;align-items:center;gap:var(--gap);
     background:var(--panel);border-bottom:1px solid var(--border);padding:14px 24px}
.logo{height:26px;width:auto;display:block;flex-shrink:0}
/* Logo do topo = icone da carteira emcash + "View" ao lado, mesmo padrao do
   logo do Geko (icone recortado do vetor oficial + nome do produto), pedido
   do Guilherme em 14/09/2026: trocar o wordmark completo "emcash" por isso. */
.logo-marca{display:flex;align-items:center;gap:8px;flex-shrink:0}
.logo-icone{height:24px;width:auto;display:block}
.logo-texto{font-family:var(--fonte-titulo);font-size:18px;font-weight:700;
     letter-spacing:-.02em;color:var(--text-brand)}
.divisor{width:1px;height:24px;background:var(--border-strong)}
.top h1{font-size:18px;font-weight:700;margin:0;color:var(--text)}
.top .sub{font-size:12.5px;color:var(--text-tertiary)}
.cresce{flex:1}
/* Área de ação do dashboard embutido -- Baixar/Modo foco (13/09/2026). Um
   quadro proprio (fundo + borda) em vez de dois botoes soltos: o pedido era
   "mostrar de uma forma melhor, sendo ali a área de ação" -- o quadro é o
   que deixa isso ÓBVIO à primeira vista, não só a posição central. Os
   botões perdem a própria borda aqui dentro (o quadro já é a borda; duas
   juntas pareceriam um erro de estilo) e ganham um traço vertical entre
   eles, para continuar dando pra separar as duas ações sem duas caixas. */
.area-acao{display:flex;align-items:stretch;background:var(--panel-2);
      border:1px solid var(--border-strong);border-radius:var(--r-pill);
      padding:3px;gap:3px;flex-shrink:0}
.area-acao .btn-modo{border:none;padding:5px 14px;border-radius:var(--r-md)}
.area-acao .btn-modo:hover{background:var(--panel)}
.area-acao .btn-modo.ligado{background:var(--panel);color:var(--text)}
.area-acao .btn-modo + .btn-modo{margin-left:2px}
.area-acao .btn-modo + .btn-modo::before{content:"";display:inline-block;
      width:1px;height:14px;background:var(--border-strong);
      margin:0 10px -3px -12px;vertical-align:middle}
.selo{display:inline-flex;align-items:center;gap:7px;border:1px solid var(--border);
      background:var(--panel-2);border-radius:var(--r-pill);padding:5px 12px;
      font-size:12px;color:var(--text-dim);cursor:help}
.selo .ponto{width:7px;height:7px;border-radius:var(--r-pill);background:var(--ok)}
.btn-modo{border:1px solid var(--border-strong);background:transparent;color:var(--text-dim);
      border-radius:var(--r-pill);padding:6px 14px;font-size:12.5px;font-weight:600;
      cursor:pointer;font-family:var(--fonte-texto);transition:all .2s var(--ease)}
.btn-modo:hover{border-color:var(--border-focus);color:var(--text)}
.avatar{width:30px;height:30px;border-radius:var(--r-pill);background:var(--panel-2);
      border:1px solid var(--border-strong);display:grid;place-items:center;
      font-size:12px;font-weight:600;color:var(--text-dim);cursor:pointer;
      font-family:var(--fonte-texto);transition:all .2s var(--ease);flex-shrink:0}
.avatar:hover{border-color:var(--border-focus);color:var(--text)}
.avatar:focus-visible{outline:2px solid var(--border-focus);outline-offset:2px}

/* ---------- casca: trilho + painel + conteúdo ---------- */
.casca{display:grid;grid-template-columns:64px 280px 1fr;min-height:calc(100vh - 57px)}
/* Coluna que some tem de sumir do GRID tambem.
   O painel lateral so existe no Repositorio; nas outras areas ele vai com
   [hidden]. Filho oculto sai do fluxo do grid, e sem estas regras o <main>
   escorregava para a coluna de 280px enquanto a coluna 1fr ficava vazia --
   medido em 11/09/2026: main com 280px numa janela de 1440. A tabela de 6
   colunas do funil cabia em 216px, que e como um painel util vira ilegivel
   sem ninguem mexer no painel. */
.casca:has(> .painel[hidden]){grid-template-columns:64px 1fr}
/* Sem trilho nem painel (a tela de admin, mas TAMBEM a de login -- as duas
   escondem os dois), a `min-height` de tela cheia deixa de fazer sentido
   pro ADMIN -- ela existe pra' barra lateral encostar no rodape' da janela;
   sem barra nenhuma, ela so' cria espaco vazio que o `stretch`/`normal`
   padrao do grid distribui de um jeito que empurra conteudo curto pro meio
   da tela. Duas tentativas anteriores (so' `align-items:start`) nao
   resolveram -- o Guilherme confirmou ao vivo, 14/09/2026. Tirar a
   `min-height` no lugar de tentar realinhar dentro dela elimina a causa em
   vez de compensar o efeito.
   `body:not(.deslogado)` -- SEM isso, esta regra (mais especifica que
   `body.deslogado .casca`, que so' tem UMA classe a mais) tambem zerava a
   altura da tela de LOGIN, que depende dela pra centralizar o cartao na
   janela (`place-items:center`) -- sem altura nenhuma pra centralizar
   dentro, o cartao caia pro topo, com um vazio enorme embaixo. Achado do
   Guilherme ao vivo, 14/09/2026 ("centraliza na tela o card do login"). */
body:not(.deslogado) .casca:has(> .trilho[hidden]):has(> .painel[hidden]){
  grid-template-columns:1fr;min-height:0}

/* TRILHO de destinos — padrão do geko (acabamento v7). Só aparece quando o
   cliente tem mais de um módulo; com um módulo só, ele some. */
.trilho{border-right:1px solid var(--border);background:var(--panel);
        display:flex;flex-direction:column;align-items:center;gap:6px;padding:14px 0}
.destino{width:44px;height:44px;border-radius:var(--r-md);display:grid;place-items:center;
        color:var(--text-tertiary);cursor:pointer;position:relative;
        transition:background .2s var(--ease),color .2s var(--ease),transform .1s var(--ease)}
.destino:hover{background:var(--panel-2);color:var(--text-dim)}
.destino.ativo{background:var(--panel-2);color:var(--text)}
/* filete da aba ativa — um dos TRÊS lugares onde o laranja da marca aparece */
.destino.ativo::before{content:"";position:absolute;left:-14px;top:9px;bottom:9px;
        width:3px;border-radius:var(--r-pill);background:var(--brand-orange)}
.destino svg{width:20px;height:20px}
.destino .nome{position:absolute;left:52px;white-space:nowrap;background:var(--panel-2);
        border:1px solid var(--border-strong);border-radius:var(--r-xs);padding:4px 9px;
        font-size:12px;opacity:0;pointer-events:none;transition:opacity .15s var(--ease);z-index:20}
.destino:hover .nome{opacity:1}

/* PAINEL — a árvore do destino ativo. 280px: com 240 o nome truncava em subpasta. */
.painel{border-right:1px solid var(--border);background:var(--panel);padding:18px 12px;overflow:auto}
.painel .rotulo{font-size:11px;text-transform:uppercase;letter-spacing:.03em;
        color:var(--text-tertiary);padding:0 8px;margin:0 0 10px;font-weight:600}
.arvore{list-style:none;margin:0;padding:0;font-size:13.5px}
.arvore li{margin:1px 0}
.no{display:flex;align-items:center;gap:8px;padding:7px 8px;border-radius:var(--r-xs);
        color:var(--text-dim);cursor:pointer;transition:background .15s var(--ease)}
.no:hover{background:var(--panel-2);color:var(--text-primary)}
.no.ativo{background:var(--panel-2);color:var(--text);font-weight:600}
.no svg{width:15px;height:15px;flex:0 0 15px;color:var(--text-tertiary)}
.no.ativo svg{color:var(--teal-ui)}
.sub{margin-left:18px;padding-left:10px;border-left:1px solid var(--border)}
.conta{margin-left:auto;font-size:11.5px;color:var(--text-tertiary)}

/* ---------- conteúdo ---------- */
/* `margin:auto` faltava -- nao aparecia em nenhuma tela ate' a tela de admin
   (11/09/2026), primeira a esconder trilho E painel ao mesmo tempo num
   desktop largo: o <main> passa a ocupar a faixa (1fr) inteira da .casca, e
   sem centralizar propria ele grudava na borda esquerda dessa faixa inteira,
   sobrando vazio so' do lado direito -- achado pelo Guilherme testando.
   `width:100%` -- SEM ela, `margin:auto` nos dois lados desliga o
   `stretch` padrao de item de grid (regra do CSS Box Alignment: margem
   auto no eixo consome o espaco livre ANTES do stretch, entao o item usa
   `fit-content` em vez de esticar) -- o <main> encolhia pro tamanho do
   PROPRIO CONTEUDO em vez de esticar ate' 1180px, e so' DEPOIS centralizava
   essa caixa pequena. Invisivel em tela com muito conteudo (o
   `fit-content` ja' passava de 1180px de qualquer jeito), mas em
   Investimento (poucos KPIs) a grade `auto-fit` da' com um container bem
   mais estreito do que devia e colapsa pra' 1 coluna -- "parece mobile"
   numa janela larga. Mesma familia do bug do iframe de 300px (comentario
   abaixo, `.tela-cheia`) -- ali' ja' tinha sido corrigido com
   `width:100%;min-width:0`, so' nunca replicado aqui na regra BASE.
   Achado do Guilherme ao vivo, 14/09/2026 ("as abas continuam
   centralizando os dados como mobile"). */
main{padding:28px 32px 80px;max-width:1180px;width:100%;margin:0 auto}
/* Dashboard embutido (HTML de verdade, 13/09/2026) -- o teto de 1180px do
   <main> e' bom para tabela/texto, mas sobra tela vazia dos dois lados
   numa janela larga com um dashboard inteiro (grade de KPIs, gráficos)
   dentro. `.tela-cheia` e' aplicada ao proprio <main> (nao dá para o FILHO
   escapar do teto do PAI só com margem negativa -- o pai tem largura
   própria, centralizada ou não) -- usa a largura real da tela da pessoa,
   sem depender de um valor fixo em px. Guilherme, 13/09/2026. */
/* ACHADO ao vivo (Guilherme, 14/09/2026, via DevTools): o <iframe> do
   dashboard media 300x4834 -- 300px e' o padrao do NAVEGADOR pra iframe sem
   largura definida, nao algo escolhido. Culpado: <main> e' item de grid
   (`.casca`) com `justify-self:stretch` (padrao), mas isso so alinha a
   CAIXA -- nao da a ela uma largura DEFINIDA o bastante pro filho substituido
   (`<iframe>`, `<img>`) resolver `width:100%` contra ela. Mesma familia do
   bug classico "filho de flex/grid nao redimensiona" -- a correcao e' o
   mesmo remedio padrao: largura explicita + min-width:0 no PAI. */
main.tela-cheia{max-width:none;width:100%;min-width:0;padding-left:16px;padding-right:16px}
.dashboard-embutido-iframe{display:block;width:100%;border:none;
  transition:height .2s var(--ease)}
section{margin-bottom:var(--sec-gap)}
h2{font-size:24px;font-weight:700;color:var(--text);margin:0 0 4px;
   padding-bottom:10px;border-bottom:1px solid var(--border)}

/* RECENTES — a raiz do Arquivos (renomeado de "Repositório", 14/09/2026):
   janela de 30 dias, agrupada por pasta. Ate' o mesmo dia havia um DESTAQUE
   separado (so' o arquivo mais recente do workspace) como raiz -- o
   Guilherme achou redundante ao vivo com Recentes bem ali do lado e pediu
   pra' juntar num so'. É a resposta sem navegação: o topo da tela de
   recepção, e é o que serve quem só quer o arquivo do mês e ir embora. */
.recentes{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:var(--gap)}
.cartao{background:var(--panel);border:1px solid var(--border);border-radius:var(--r-lg);
        padding:var(--pad);position:relative;overflow:hidden;
        transition:transform .2s var(--ease),box-shadow .2s var(--ease),border-color .2s var(--ease)}
.cartao::before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--brand-orange)}
.cartao:hover{transform:translateY(-3px);box-shadow:var(--sombra-cartao);border-color:var(--border-strong)}
.cartao .quando{font-size:14px;font-weight:600;color:var(--text-tertiary);margin-bottom:8px}
.cartao a.arquivo{display:block;font-size:15px;font-weight:600;color:var(--text-brand-arquivo);
        text-decoration:none;line-height:1.35;margin-bottom:10px;word-break:break-word}
.cartao a.arquivo:hover{text-decoration:underline}
.cartao a.arquivo:focus-visible{outline:2px solid var(--border-focus);outline-offset:3px;border-radius:var(--r-xs)}
.cartao .meta{font-size:12px;color:var(--text-tertiary);font-variant-numeric:tabular-nums}

/* TABELA de arquivos da pasta aberta */
.tabela-wrap{overflow-x:auto;border:1px solid var(--border);border-radius:var(--r-lg)}
table{width:100%;border-collapse:collapse;background:var(--panel);font-size:13.5px}
/* `table-layout:fixed` -- sem isso, uma tabela com so' o cabecalho (nenhuma
   linha de dado, ex.: filtro "Suspenso" vazio) encolhe pro tamanho do texto
   mais curto do cabecalho: `width:100%` sozinho nao basta em
   `table-layout:auto`, que calcula a proporcao das colunas pelo CONTEUDO
   das linhas -- sem linha, nao ha pelo que calcular, e o resultado e' a
   largura minima. Achado pelo Guilherme ao vivo, 14/09/2026. */
table.tabela-fixa{table-layout:fixed}
/* `table-layout:fixed` sem largura nenhuma declarada divide as colunas em
   partes IGUAIS (Status ficaria do mesmo tamanho que Nome) -- as proporcoes
   abaixo repetem o que o layout automatico jah produzia com dado real.
   Ações ficava com 12% (~134px numa tabela de ~1116px): estreito demais pros
   3 botões (Editar/Suspender/Remover, ~250px de conteudo real) -- um <td> nao
   encolhe filho de flex abaixo do min-content, entao o texto deles se
   sobrepunha em vez de quebrar. Achado pelo Guilherme ao vivo, 14/09/2026;
   redistribuido tirando de Nome e Áreas (que sobravam largura).
   Segunda rodada (mesmo dia): Nome com nomes de teste longos ("ZZ Teste B
   (ficticia) -- espelha a Afya...") ainda quebrava linha com folga sobrando
   nas laterais -- Workspace e Status usam vocabulario curto e fixo (slug,
   "Ativo"/"Suspenso"), entao emprestam mais espaco pro Nome. */
.tabela-fixa th:nth-child(1){width:10%}
.tabela-fixa th:nth-child(2){width:40%}
.tabela-fixa th:nth-child(3){width:18%}
.tabela-fixa th:nth-child(4){width:8%}
.tabela-fixa th:nth-child(5){width:24%}
th{font-size:11px;text-transform:uppercase;letter-spacing:.03em;color:var(--text-dim);
   background:var(--panel-2);text-align:left;padding:0 14px;height:34px;vertical-align:bottom;
   padding-bottom:9px;font-weight:600;white-space:nowrap}
td{padding:12px 14px;border-top:1px solid var(--border);color:var(--text-primary)}
tr:nth-child(even) td{background:var(--bg-subtle)}
tbody tr:hover td{background:var(--panel-2)}
/* "Ver workspace" (EAP 6): linha inteira clicavel em vez de botao "Ver" por
   linha -- pedido do Guilherme, 14/09/2026. Suspenso nunca e' clicavel: nao
   ha' o que ver (mesmo estado que o proprio cliente enxerga). */
tr.linha-clicavel{cursor:pointer}
tr.linha-clicavel:focus-visible{outline:2px solid var(--border-focus);outline-offset:-2px}
tr.linha-suspensa td{color:var(--text-tertiary)}
td.num,th.num{text-align:right;font-variant-numeric:tabular-nums}
/* Competência e Atualizado são RÓTULOS de data, não grandezas: alinhados ao
   centro, porque encostados à direita ao lado de um nome longo pareciam
   desalinhados (Guilherme, 10/09/2026). Tamanho segue à direita -- ele é
   grandeza e a normativa manda comparar magnitude à direita --, mas perde
   peso: cinza terciário e um corpo menor, porque ninguém escolhe um arquivo
   pelo tamanho dele. */
td.centro,th.centro{text-align:center;font-variant-numeric:tabular-nums}
td.tamanho,th.tamanho{text-align:right;font-variant-numeric:tabular-nums;
   color:var(--text-tertiary);font-size:12.5px}
td a{color:var(--text-brand-arquivo);text-decoration:none;font-weight:600}
td a:hover{text-decoration:underline}
td a:focus-visible{outline:2px solid var(--border-focus);outline-offset:2px;border-radius:var(--r-xs)}
.ausente{color:var(--text-tertiary)}

/* NOTA — bloco ausente declara o motivo. "não medimos" ≠ "não tem". */
.nota{background:var(--panel-2);border:1px solid var(--border);border-left:4px solid var(--warn);
      border-radius:var(--r-md);padding:14px var(--pad);font-size:12.5px;color:var(--text-dim)}
.nota b{color:var(--text)}

.vazio{background:var(--panel);border:1px dashed var(--border-strong);border-radius:var(--r-lg);
      padding:40px 24px;text-align:center;color:var(--text-tertiary);font-size:13.5px}

/* Esqueleto de carregamento "Respiração" -- decidido com o Guilherme em
   14/09/2026 (opções exploradas: Sweep de acento x Respiração; Respiração
   venceu, sem laranja nenhum). Substitui o "Carregando..." genérico
   (reaproveitava .vazio) por um esqueleto com a FORMA do conteúdo que está
   prestes a chegar -- pulso suave, escalonado por linha (uníssono lê como
   robótico). app.js::esqueletoLinhas() e admin.js (cópia local, o módulo
   já não importa de app.js) montam as linhas com essas classes. */
.esq-grupo{border:1px solid var(--border);border-radius:var(--r-md);overflow:hidden}
.esq-linha{display:flex;align-items:center;gap:14px;padding:12px 14px;
      border-top:1px solid var(--border)}
.esq-linha:first-child{border-top:0}
.esq-bloco{background:var(--panel-2);border-radius:var(--r-xs);height:14px;flex:1}
.esq-icone{width:20px;height:20px;border-radius:var(--r-xs);background:var(--panel-2);
      flex-shrink:0}
.esq-linha,.esq-linha *{animation:respirar 1.7s var(--ease) infinite}
.esq-linha:nth-child(1){animation-delay:0s}
.esq-linha:nth-child(2){animation-delay:.12s}
.esq-linha:nth-child(3){animation-delay:.24s}
.esq-linha:nth-child(4){animation-delay:.36s}
.esq-linha:nth-child(n+5){animation-delay:.48s}
@keyframes respirar{0%,100%{opacity:.45}50%{opacity:1}}

/* Troca do esqueleto pra' tela real, uma vez so' (ver `entrarSuave` em
   app.js) -- `header.top` fica vazio ate' o primeiro render() de verdade
   (nada em index.html) e surgia tudo de uma vez junto com a troca de
   conteudo, sem transicao nenhuma. Fade curto no `body` inteiro (cobre
   header+casca de uma vez, sem duplicar a mesma regra em cada tela). Achado
   do Guilherme, 14/09/2026 ("o botao novo fica aparecendo"). */
body.entrando{animation:entrarSuave .35s var(--ease)}
@keyframes entrarSuave{from{opacity:0}to{opacity:1}}

/* Trocar de área (Home/Investimento/Operações/Arquivos, `irPara()` em
   app.js) também trocava o conteúdo de `<main>` sem transição nenhuma --
   mesmo achado do fade de login acima, reaproveitando o mesmo keyframe.
   NÃO mora em `render()` (roda a cada tecla/clique de filtro) nem em
   `.tela-cheia`/`.tela-entrando` juntos por acaso -- as duas classes
   convivem sem conflito (uma cuida de largura, a outra so' anima entrada). */
main.tela-entrando{animation:entrarSuave .25s var(--ease)}

/* Filtro Todos/Ativo/Suspenso da tela de Administração -- achado pelo
   Guilherme, 14/09/2026: sem regra nenhuma aqui, o rótulo "Status" ficava
   colado no botão "Novo workspace" acima e os chips encostavam na tabela
   (ou no vazio) logo abaixo, sem respiro nenhum. */
.filtro-status{display:flex;align-items:center;gap:10px;margin:0 0 var(--gap)}
.filtro-status .rotulo-filtro{font-size:12px;font-weight:600;color:var(--text-dim);
      flex-shrink:0}

/* Estado vazio DENTRO da tabela filtrada (ex.: filtro "Suspenso" sem nenhum
   suspenso) -- revisado 14/09/2026: a v1 desta regra trocava a TABELA
   INTEIRA por uma caixa diferente (sem cabeçalho, mais estreita) -- o
   Guilherme reprovou ("deixa a tabela completa com a mensagem, sem
   redimensionar"). Agora é uma linha só, dentro do MESMO <table>, com
   `colspan` na largura das colunas -- cabeçalho nunca some, tabela nunca
   muda de forma entre filtros. */
.celula-vazia{text-align:center;color:var(--text-tertiary);font-size:13.5px;padding:48px 24px}

/* Contrato clicável (drill-down de Operações) e o painel de detalhe que abre
   abaixo da tabela -- não embutido na linha, para não empurrar as linhas
   vizinhas quando abre. */
.link-contrato{background:none;border:none;padding:0;font:inherit;color:var(--text-brand);
  cursor:pointer;text-decoration:underline;text-underline-offset:2px}
.link-contrato[aria-expanded="true"]{font-weight:700}
.detalhe-contrato{background:var(--panel);border:1px solid var(--border-strong);
  border-left:3px solid var(--brand-orange);border-radius:var(--r-lg);
  padding:18px 20px;margin-top:16px}
.detalhe-contrato-corpo h3{margin:0 0 6px;font-size:15px;font-weight:700;color:var(--text)}
.detalhe-contrato-corpo h4{margin:16px 0 8px;font-size:12px;font-weight:700;
  text-transform:uppercase;letter-spacing:.03em;color:var(--text-tertiary)}

@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}

/* ===========================================================================
   HOME DO WORKSPACE — só existe para quem tem mais de um módulo.
   Não é um saguão: cada cartão já RESPONDE alguma coisa, na mesma doutrina
   do "Hoje" do geko (resposta sem navegação).
   =========================================================================== */
.modulos{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:var(--gap)}
/* Numeros do cartao de modulo. Tabular para os digitos nao dancarem entre
   cartoes (DDR: `.num` ja faz isso no resto do sistema). */
.modulo-numeros{display:flex;gap:28px;flex-wrap:wrap;margin-top:18px;
  padding-top:16px;border-top:1px solid var(--border)}
.modulo-num .valor{font-family:var(--fonte-titulo);font-size:24px;font-weight:700;
  color:var(--text);font-variant-numeric:tabular-nums;line-height:1.2}
.modulo-num .valor.negativo{color:var(--bad-fg)}
.modulo-num .rotulo{font-size:11.5px;color:var(--text-tertiary);margin-top:2px}
.nota-cartao{margin:18px 0 0;padding-top:16px;border-top:1px solid var(--border);
  font-size:12.5px;color:var(--text-tertiary)}
/* Ocultos vao para uma secao PROPRIA, abaixo dos disponiveis. */
.sec-retirados{margin-top:18px}
.sec-retirados h3,.sec-retirados h4{font-size:12px;text-transform:uppercase;
  letter-spacing:.03em;color:var(--text-tertiary);margin:0 0 8px;font-weight:600}

/* Grupos de pasta. Espacamento CURTO de proposito: a tela mostra a pasta e
   todas as descendentes, entao margem generosa entre secoes viraria rolagem
   sem conteudo. */
.grupo-pasta + .grupo-pasta{margin-top:20px}
.pasta-titulo{display:flex;align-items:center;gap:8px;margin:0 0 10px;
  font-size:12.5px;text-transform:uppercase;letter-spacing:.04em;
  color:var(--text-tertiary);cursor:pointer;user-select:none;font-weight:600}
.pasta-titulo:hover{color:var(--text-brand)}
.pasta-titulo:focus-visible{outline:2px solid var(--border-focus);outline-offset:2px}
.pasta-titulo .seta{font-size:10px;width:10px}
.pasta-titulo .conta-pasta{margin-left:auto;font-variant-numeric:tabular-nums;
  color:var(--text-tertiary);font-weight:400}
.pasta-titulo.recolhida{color:var(--text-tertiary);opacity:.75}
.modulo{background:var(--panel);border:1px solid var(--border);border-radius:var(--r-lg);
        padding:20px;display:flex;flex-direction:column;gap:14px;text-decoration:none;
        transition:transform .2s var(--ease),box-shadow .2s var(--ease),border-color .2s var(--ease)}
.modulo:hover{transform:translateY(-3px);box-shadow:var(--sombra-cartao);border-color:var(--border-strong)}
.modulo .cabeca{display:flex;align-items:center;gap:11px}
.modulo .icone{width:38px;height:38px;border-radius:var(--r-md);background:var(--panel-2);
        display:grid;place-items:center;color:var(--teal-ui);flex:0 0 38px}
.modulo .icone svg{width:19px;height:19px}
.modulo h3{margin:0;font-size:17px;font-weight:700;color:var(--text)}
.modulo .resposta{border-top:1px solid var(--border);padding-top:13px;display:flex;
        flex-direction:column;gap:9px}
.modulo .linha{display:flex;align-items:baseline;gap:9px;font-size:13px}
.modulo .linha .rot{color:var(--text-tertiary);min-width:74px}
.modulo .linha .val{color:var(--text-primary);font-weight:600;font-variant-numeric:tabular-nums}
.modulo .linha a{color:var(--text-brand-arquivo);text-decoration:none;font-weight:600;
        overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.modulo .linha a:hover{text-decoration:underline}

/* ===========================================================================
   PAINEL DE INVESTIMENTO
   =========================================================================== */
/* Abas — o filete laranja da aba ativa é o 2º dos três lugares do laranja. */
.abas{display:flex;gap:2px;border-bottom:1px solid var(--border);margin-bottom:26px;
      overflow-x:auto;scrollbar-width:none}
.abas button{background:none;border:none;border-bottom:2px solid transparent;color:var(--text-tertiary);
      font-family:var(--fonte-texto);font-size:13.5px;font-weight:600;padding:11px 16px;
      cursor:pointer;white-space:nowrap;transition:color .2s var(--ease)}
.abas button:hover{color:var(--text-dim)}
.abas button[aria-selected="true"]{color:var(--text);border-bottom-color:var(--brand-orange)}

/* KPI — DDR-019. Valor em TINTA NEUTRA, nunca laranja. Rótulo em sentence
   case, 14px/600. Semântica na barra de acento de 3px. Altura mínima 96px. */
.kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(212px,1fr));gap:var(--gap);margin-bottom:26px}
.kpi{background:var(--panel);border:1px solid var(--border);border-radius:var(--r-lg);
     padding:var(--pad) var(--pad) var(--pad) 19px;position:relative;overflow:hidden;min-height:96px;
     display:flex;flex-direction:column;justify-content:center}
.kpi::before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--pending)}
.kpi.tom-marca::before{background:var(--brand-orange)}
.kpi.tom-ok::before{background:var(--ok)}
.kpi.tom-alerta::before{background:var(--warn)}
.kpi .rotulo-kpi{font-size:14px;font-weight:600;color:var(--text-tertiary);margin-bottom:6px}
.kpi .valor{font-family:var(--fonte-titulo);font-size:28px;font-weight:700;color:var(--text);
     line-height:1.1;font-variant-numeric:tabular-nums}
.kpi .apoio{font-size:12px;color:var(--text-tertiary);margin-top:5px;font-variant-numeric:tabular-nums}

.grade2{display:grid;grid-template-columns:1fr 1fr;gap:var(--gap)}
.grade3{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--gap)}
.bloco{background:var(--panel);border:1px solid var(--border);border-radius:var(--r-lg);padding:20px}
.bloco h3{margin:0 0 3px;font-size:15px;font-weight:700;color:var(--text)}

/* Formulário de workspace -- tela PRÓPRIA (nunca empilhada sobre a lista,
   decisão de 14/09/2026 depois do Guilherme apontar rolagem/repetição), na
   largura inteira do <main> (mesma 1180px de qualquer outra tela) em 3
   colunas -- cabe sem rolar. Substitui o card estreito e centralizado da
   primeira versão do adendo de UX (DESIGN.md, decisão C1, revista no mesmo
   dia). */
.form-admin{background:var(--panel);
  border:1px solid var(--border);border-radius:var(--r-lg);padding:28px}
.form-admin h2{margin:0 0 22px;font-size:16px;font-weight:700;color:var(--text)}
.form-admin .campo{margin-bottom:18px}
.form-admin .campo.largo{grid-column:1 / -1}
/* Rótulo com legenda contextual (decisão D1): o rótulo já se explica; o
   marcador de obrigatório só aparece quando a condição vale; a legenda é no
   máximo uma linha -- nunca o parágrafo de `.nota` que existia antes. */
.form-admin .rotulo-campo{display:flex;align-items:center;gap:8px;font-size:12px;
  font-weight:600;color:var(--text-dim);margin-bottom:7px}
.form-admin .obrigatorio-contextual{font-size:10.5px;color:var(--warn-fg);font-weight:600}
.form-admin .legenda-campo{font-size:11.5px;color:var(--text-tertiary);margin-top:6px}
.form-admin input.campo-input{width:100%;box-sizing:border-box;padding:10px 12px;
  border:1px solid var(--border-strong);border-radius:var(--r-xs);background:var(--panel-2);
  color:var(--text);font:inherit}
.form-admin input.campo-input:focus{outline:2px solid var(--border-focus);outline-offset:1px}
.form-admin input.campo-input[disabled]{opacity:.55}

/* Barras horizontais — CSS puro, sem biblioteca. Substituem gráfico de barra. */
.hbars{display:flex;flex-direction:column;gap:11px}
.hbar{display:grid;grid-template-columns:96px 1fr 86px;align-items:center;gap:11px;font-size:13px}
.hbar .rot{color:var(--text-dim);text-align:right}
.hbar .trilha{background:var(--panel-2);height:22px;border-radius:5px;overflow:hidden}
.hbar .preenche{height:100%;background:var(--brand-orange);min-width:3px;border-radius:5px}
.hbar .val{text-align:right;color:var(--text-primary);font-weight:600;font-variant-numeric:tabular-nums}

/* Cross-filter (Fase 3b): a linha vira <button>, entao reseta o cromo nativo
   antes de estilizar -- ".hbar" acima ja garante o grid de 3 colunas. */
button.hbar{border:none;background:none;padding:4px 6px;margin:0 -6px;width:calc(100% + 12px);
  font:inherit;color:inherit;cursor:pointer;border-radius:var(--r-xs);
  transition:background .15s var(--ease)}
button.hbar:hover{background:var(--panel-2)}
button.hbar:focus-visible{outline:2px solid var(--border-focus);outline-offset:2px}
button.hbar.ativo{background:var(--panel-2)}
button.hbar.ativo .rot{color:var(--text);font-weight:700}

/* Barras duplas — leads (fundo) e convertidos (destaque) na MESMA trilha,
   sobrepostas, não empilhadas. Paridade com o HTML da Afya, 12/09/2026. */
.trilha-dupla{position:relative}
.trilha-dupla .preenche{position:absolute;top:0;left:0}
.trilha-dupla .preenche-fundo{background:var(--brand-orange);opacity:.45}
.trilha-dupla .preenche-destaque{background:var(--teal-ui)}

/* Donut — <circle> com stroke-dasharray, sem <path> de arco. */
.donut-wrap{display:flex;align-items:center;gap:22px;flex-wrap:wrap}
.donut{width:120px;height:120px;flex-shrink:0}
.donut-trilha{stroke:var(--panel-2)}
.donut-fatia{stroke:var(--text-tertiary);transition:stroke-dasharray .2s var(--ease),opacity .15s var(--ease)}
.donut-fatia.tom-marca{stroke:var(--brand-orange)}
.donut-fatia.tom-ok{stroke:var(--ok)}
.donut-fatia.tom-alerta{stroke:var(--warn)}
/* Cross-filter (Fase 3b): fatia clicavel apaga as outras quando uma esta ativa
   -- mesmo destaque que a legenda ganha logo abaixo. */
.donut-fatia.clicavel{cursor:pointer}
.donut-wrap:has(.donut-fatia.ativo) .donut-fatia.clicavel:not(.ativo){opacity:.35}
.donut-fatia.clicavel:focus-visible{outline:2px solid var(--border-focus);outline-offset:2px}
.legenda-donut{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:8px;font-size:13px}
.item-donut{display:flex;align-items:center;gap:8px}
.item-donut .marca{width:11px;height:11px;border-radius:3px;background:var(--text-tertiary);flex-shrink:0}
.item-donut .marca.tom-marca{background:var(--brand-orange)}
.item-donut .marca.tom-ok{background:var(--ok)}
.item-donut .marca.tom-alerta{background:var(--warn)}
.item-donut .rot{color:var(--text-dim);flex:1}
.item-donut b{color:var(--text-primary);font-variant-numeric:tabular-nums}
/* Cross-filter (Fase 3b): a legenda tambem clica, igual a fatia dela. */
.item-donut[role="button"]{cursor:pointer;border-radius:var(--r-xs);padding:2px 4px;margin:0 -4px;
  transition:background .15s var(--ease)}
.item-donut[role="button"]:hover{background:var(--panel-2)}
.item-donut[role="button"]:focus-visible{outline:2px solid var(--border-focus);outline-offset:2px}
.item-donut.ativo .rot{color:var(--text);font-weight:700}

/* Série temporal — SVG inline escrito à mão. Nenhum import. */
.serie{width:100%;height:auto;display:block}
.serie .grade{stroke:var(--border);stroke-width:1}
.serie .eixo{fill:var(--text-tertiary);font-size:10px;font-family:var(--fonte-texto)}
.serie .linha1{fill:none;stroke:var(--brand-orange);stroke-width:2;stroke-linejoin:round;stroke-linecap:round}
.serie .linha2{fill:none;stroke:var(--teal-ui);stroke-width:2;stroke-linejoin:round;stroke-linecap:round}
.serie .ponto1{fill:var(--brand-orange)}
.serie .ponto2{fill:var(--teal-ui)}
.legenda-serie{display:flex;gap:18px;margin-top:14px;font-size:12.5px;color:var(--text-dim)}
.legenda-serie span{display:inline-flex;align-items:center;gap:7px}
.legenda-serie i{width:11px;height:11px;border-radius:3px;display:inline-block}

/* TENDENCIA em barras verticais, com drill mes->dia -- Fase 3d, 12/09/2026. */
.tendencia{width:100%;height:auto;display:block}
.tendencia .grade{stroke:var(--border);stroke-width:1}
.tendencia .eixo{fill:var(--text-tertiary);font-size:10px;font-family:var(--fonte-texto)}
.barra-tendencia{fill:var(--brand-orange);opacity:.75;transition:opacity .15s var(--ease)}
.barra-tendencia.clicavel{cursor:pointer}
.barra-tendencia.clicavel:hover{opacity:1}
.barra-tendencia.clicavel:focus-visible{outline:2px solid var(--border-focus);outline-offset:2px}
.barra-tendencia.ativa{opacity:1}
.btn-voltar-drill{background:none;border:none;color:var(--text-brand);font-size:12.5px;
  font-weight:600;cursor:pointer;padding:0;margin:0 0 3px 14px}
.btn-voltar-drill:hover{text-decoration:underline}

.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
         clip:rect(0,0,0,0);white-space:nowrap;border:0}


/* ===========================================================================
   MODO EDITOR — a mesma tela, com um gesto explícito de troca de modo.
   Sinalização em ÂMBAR, nunca no laranja da marca: o laranja tem três lugares
   reservados (acento do KPI, filete da aba ativa, série 1) e estado de modo
   não é um deles. Âmbar já é a família semântica de "atenção" nos tokens.
   =========================================================================== */
body.editor .top{border-bottom-color:var(--warn-border)}
.faixa-modo{display:none;align-items:center;gap:10px;background:var(--warn-bg);
      border-bottom:1px solid var(--warn-border);color:var(--warn-fg);
      padding:9px 24px;font-size:12.5px;font-weight:600;position:sticky;top:57px;z-index:9}
body.editor .faixa-modo{display:flex}
.faixa-modo svg{width:15px;height:15px;flex:0 0 15px}
.faixa-modo .leve{font-weight:400;color:var(--text-dim)}
.btn-modo.ligado{border-color:var(--warn-border);background:var(--warn-bg);color:var(--warn-fg)}

/* Itens que só existem em modo editor */
.so-editor{display:none}
body.editor .so-editor{display:revert}
body.editor tr.so-editor{display:table-row}
body.editor .no.so-editor{display:flex}

/* Item oculto do cliente: aparece em contexto, marcado, e some ao sair do modo */
tr.oculto td{color:var(--text-tertiary)}
tr.oculto td a{color:var(--text-tertiary);text-decoration:line-through}
.tag{display:inline-flex;align-items:center;gap:5px;border-radius:var(--r-pill);
      padding:2px 9px;font-size:11px;font-weight:600;border:1px solid;white-space:nowrap}
.tag.oculta{background:var(--warn-bg);color:var(--warn-fg);border-color:var(--warn-border)}
.tag.nova{background:var(--ok-bg);color:var(--ok);border-color:var(--ok-border)}

/* Ações de linha — só em modo editor, alvo mínimo 32px */
/* `flex-wrap:wrap` -- rede de seguranca contra o MESMO bug da largura da
   coluna (comentario acima, `.tabela-fixa`): um <td> de largura fixa nao
   encolhe filho de flex abaixo do min-content, entao sem quebra de linha o
   conteudo simplesmente sobrepoe em vez de estourar pra baixo. */
.acoes{display:flex;gap:6px;justify-content:flex-end;flex-wrap:wrap}
.acoes button{background:transparent;border:1px solid var(--border-strong);color:var(--text-dim);
      border-radius:var(--r-xs);min-width:32px;height:32px;padding:0 10px;font-size:12px;
      font-weight:600;cursor:pointer;font-family:var(--fonte-texto);
      transition:all .15s var(--ease)}
.acoes button:hover{border-color:var(--border-focus);color:var(--text)}
.acoes button:focus-visible{outline:2px solid var(--border-focus);outline-offset:2px}
.acoes button.perigo:hover{border-color:var(--bad);color:var(--bad-fg)}
@media (hover:none){ .acoes button{min-width:44px;height:44px} }
/* Suspender/Reativar/Remover NAO recarregam a tela inteira (era o esqueleto
   "Respiração" de 4 linhas piscando por cima da tabela toda pra' uma unica
   troca de status) -- so' esta linha entra em espera: botoes desabilitados,
   selo "Atualizando…" do lado, mesma respiração do esqueleto (reaproveita a
   animação, nunca um spinner novo). Pedido do Guilherme, 14/09/2026. */
.acoes button:disabled{opacity:.5;cursor:default}
.acoes .acoes-status{font-size:12px;color:var(--text-tertiary);animation:respirar 1.7s var(--ease) infinite}

/* ===========================================================================
   SITUAÇÃO DO ITEM — semáforo (Guilherme, 10/09/2026).
   Nunca só a cor: ponto + palavra. Cor sozinha não é informação para quem não
   distingue verde de vermelho, e é a falha de acessibilidade mais comum em
   tabela de status.
   =========================================================================== */
.sit{display:inline-flex;align-items:center;gap:7px;font-size:12.5px;font-weight:600;white-space:nowrap}
.sit i{width:8px;height:8px;border-radius:var(--r-pill);flex:0 0 8px}
.sit.exibido{color:var(--ok)}            .sit.exibido i{background:var(--ok)}
.sit.retirado{color:var(--bad-fg)}       .sit.retirado i{background:var(--bad-fg)}
.sit.travado{color:var(--warn-fg)}       .sit.travado i{background:var(--warn-fg)}
.sit.encerrado{color:var(--text-dim)}    .sit.encerrado i{background:var(--pending)}
.sit .porque{font-weight:400;color:var(--text-tertiary)}
/* "Finalizado" ganhou estado proprio em vez de virar verde: contrato pago ate
   o fim nao e bom nem ruim, e' contrato que acabou. Pinta-lo como "Em dia" o
   confundiria com o vivo e adimplente -- e foi ele desaparecendo da tela que
   causou a divergencia "41 vs 40" no painel da Afya. */

/* Renomear é uma caneta ao lado do nome, não um botão na coluna de ações:
   a ação pertence ao nome, e ali ela não compete com Replicar e Retirar. */
.caneta{background:none;border:none;padding:2px;margin-left:6px;cursor:pointer;
   color:var(--text-tertiary);opacity:0;transition:opacity .15s var(--ease),color .15s var(--ease);
   vertical-align:middle;line-height:0}
tr:hover .caneta,.caneta:focus-visible{opacity:1}
.caneta:hover{color:var(--text-brand)}
.caneta svg{width:14px;height:14px}
@media (hover:none){ .caneta{opacity:1;padding:11px} }

/* Resumo da pasta + gatilho de replicação, no topo da tela. */
.resumo{display:flex;align-items:center;gap:18px;flex-wrap:wrap;background:var(--panel);
   border:1px solid var(--border);border-radius:var(--r-lg);padding:14px 18px;margin-bottom:22px}
.resumo .item{display:flex;align-items:baseline;gap:7px;font-size:13px}
.resumo .item .n{font-family:var(--fonte-titulo);font-size:17px;font-weight:700;
   color:var(--text);font-variant-numeric:tabular-nums}
.resumo .item .r{color:var(--text-tertiary)}
.resumo .fim{margin-left:auto;display:flex;align-items:center;gap:9px}
.btn-gatilho{border:1px solid var(--border-strong);background:var(--panel-2);color:var(--text);
   border-radius:var(--r-md);padding:9px 16px;font-size:13px;font-weight:600;cursor:pointer;
   font-family:var(--fonte-texto);transition:all .15s var(--ease)}
.btn-gatilho:hover{border-color:var(--border-focus)}
.btn-gatilho:focus-visible{outline:2px solid var(--border-focus);outline-offset:2px}
.btn-mais{background:none;border:none;color:var(--text-brand);font-size:12.5px;font-weight:600;
   cursor:pointer;font-family:var(--fonte-texto);padding:4px}
details.destinos{margin:-12px 0 22px}
details.destinos summary{list-style:none;cursor:pointer}
details.destinos summary::-webkit-details-marker{display:none}

/* Valor financeiro negativo. A normativa reserva --bad-fg para isso no dark,
   e ele passa o piso de 4,5:1; --bad (#E63950) é cor de MARCA e reprovaria
   como texto pequeno. */
.kpi .valor.negativo{color:var(--bad-fg)}

/* ===========================================================================
   SEM ROLAGEM LATERAL (Guilherme, 10/09/2026).
   A tabela do modo editor estourava a largura por dois motivos: o texto do
   motivo dentro da coluna Situação, e três botões de texto na coluna de ações.
   Correção: o motivo sai da célula (vai para o título e para o menu da linha)
   e as ações viram UM botão de menu de 32px.
   =========================================================================== */
.sit .porque{display:none}
.menu-linha{background:transparent;border:1px solid transparent;color:var(--text-tertiary);
   border-radius:var(--r-xs);width:32px;height:32px;cursor:pointer;line-height:0;
   transition:all .15s var(--ease)}
tr:hover .menu-linha{border-color:var(--border-strong);color:var(--text-dim)}
.menu-linha:hover{border-color:var(--border-focus)!important;color:var(--text)!important}
.menu-linha:focus-visible{outline:2px solid var(--border-focus);outline-offset:2px}
.menu-linha svg{width:16px;height:16px}
.col-menu{width:48px;text-align:right}
@media (hover:none){ .menu-linha{width:44px;height:44px;border-color:var(--border-strong)} }

/* Linha de ação da pasta: discreta, encostada à direita, sem números grandes. */
.acao-pasta{display:flex;align-items:center;justify-content:flex-end;gap:12px;margin-bottom:14px}

/* ===========================================================================
   RESPONSIVO — três larguras (Guilherme, 10/09/2026).
   A versão anterior escondia trilho e painel abaixo de 900px, o que tirava a
   navegação inteira: no tablet a pessoa via a pasta aberta e não tinha como
   trocar de pasta. Corrigido.

   > 1000px  desktop   trilho + painel + conteúdo
   ≤ 1000px  tablet    painel vira GAVETA com backdrop (regra da normativa),
                       trilho continua — ele custa 64px
   ≤ 700px   celular   trilho desce para barra inferior, gaveta ocupa a tela,
                       tabela perde as colunas que o nome do arquivo já diz
   =========================================================================== */
.abre-painel{display:none;width:38px;height:38px;border-radius:var(--r-md);
   border:1px solid var(--border-strong);background:transparent;color:var(--text-dim);
   cursor:pointer;place-items:center;padding:0}
.abre-painel svg{width:18px;height:18px}
.fundo-gaveta{display:none;position:fixed;inset:0;background:var(--scrim);z-index:28}
body.gaveta-aberta .fundo-gaveta{display:block}

@media (max-width:1000px){
  .abre-painel{display:grid}
  .casca{grid-template-columns:64px 1fr}
  /* Aqui o painel e gaveta sobreposta, entao ele nunca ocupa coluna. */
  .casca:has(> .painel[hidden]){grid-template-columns:64px 1fr}
  .casca:has(> .trilho[hidden]){grid-template-columns:1fr}
  .painel{position:fixed;top:57px;left:64px;bottom:0;width:280px;z-index:30;
     transform:translateX(-115%);transition:transform .25s var(--ease);
     box-shadow:var(--sombra-gaveta)}
  body.gaveta-aberta .painel{transform:none}
  main{padding:22px 20px 70px}
  .grade2{grid-template-columns:1fr}
  .grade3{grid-template-columns:1fr}
  .kpis{grid-template-columns:1fr 1fr}
  .top h1{font-size:16px}
}

@media (max-width:700px){
  /* As duas variantes :has() (linhas 96-97) tem mais especificidade que
     ".casca" sozinho e ficam ativas em QUALQUER largura -- sem repeti-las
     aqui elas vencem esta regra e prendem o grid em "64px 1fr", ou pior:
     como o trilho vira position:fixed abaixo, ele sai do auto-placement do
     grid e o <main> (proximo item) cai na coluna de 64px sozinho -- achado
     testando responsividade, 14/09/2026 (main media 64px de largura em
     qualquer tela <=700px, virando "Z Z T e s t e A" uma palavra por linha). */
  .casca,.casca:has(> .painel[hidden]),
  /* Sem trilho nem painel (admin; mesma ressalva do login, ver a regra
   irmã fora do media query) a `min-height` de tela cheia deixa de fazer
   sentido -- ela existe pra' barra lateral encostar no rodape' da janela;
   sem barra nenhuma, ela so' cria espaco vazio que o `stretch`/`normal`
   padrao do grid distribui de um jeito que empurra conteudo curto pro meio
   da tela. Duas tentativas anteriores (so' `align-items:start`) nao
   resolveram -- o Guilherme confirmou ao vivo, 14/09/2026. Tirar a
   `min-height` no lugar de tentar realinhar dentro dela elimina a causa em
   vez de compensar o efeito. `body:not(.deslogado)` pelo mesmo motivo da
   regra irmã: sem isso, o login tambem perdia a centralizacao vertical
   aqui dentro do media query. */
body:not(.deslogado) .casca:has(> .trilho[hidden]):has(> .painel[hidden]){
    grid-template-columns:1fr;min-height:0}
  /* Trilho vira barra inferior: no celular o polegar alcança a base, não a lateral. */
  .trilho{position:fixed;left:0;right:0;bottom:0;top:auto;flex-direction:row;
     justify-content:space-around;gap:0;padding:6px 4px;border-right:none;
     border-top:1px solid var(--border);z-index:26}
  .destino{width:auto;flex:1;height:48px;border-radius:var(--r-md)}
  .destino.ativo::before{left:50%;right:auto;top:2px;bottom:auto;width:20px;height:3px;
     transform:translateX(-50%)}
  .destino .nome{position:static;opacity:1;background:none;border:none;padding:0;
     font-size:10px;display:none}
  .painel{left:0;width:min(300px,86vw);top:53px}
  main{padding:18px 16px 96px}
  .top{padding:10px 14px;gap:10px}
  .top h1{font-size:15px}
  .top .sub,.selo{display:none}          /* o selo migra para dentro do conteúdo */
  .faixa-modo{top:53px;padding:8px 14px;font-size:12px}
  .kpis{grid-template-columns:1fr}
  .recentes,.modulos{grid-template-columns:1fr}
  h2{font-size:20px}
  /* Competência e Tamanho saem: o nome do arquivo já carrega a competência
     (extrato_..._2026-08.xlsx) e o tamanho já era a informação de menor peso.
     Arquivo, situação e data de atualização permanecem — é o que decide o
     download. */
  th.centro:first-of-type,td.centro:first-of-type,
  th.tamanho,td.tamanho{display:none}
  table{font-size:13px}
  td,th{padding-left:10px;padding-right:10px}
  .acao-pasta{justify-content:stretch}
  .acao-pasta .btn-gatilho{flex:1}
}

/* ---------- menu de ações da linha e diálogo de confirmação ---------- */
.menu-flutuante{position:absolute;z-index:60;min-width:200px;background:var(--panel-2);
  border:1px solid var(--border-strong);border-radius:var(--r-md);
  box-shadow:var(--sombra-cartao);padding:6px;display:flex;flex-direction:column}
.item-menu{border:0;background:transparent;color:var(--text-primary);text-align:left;
  padding:9px 12px;border-radius:var(--r-xs);font-size:13px;cursor:pointer;
  font-family:var(--fonte-texto)}
.item-menu:hover{background:var(--bg-subtle)}
.item-menu.perigo{color:var(--bad-fg)}
.item-menu.perigo:hover{background:var(--bad-bg)}

.dialogo-fundo{position:fixed;inset:0;z-index:70;background:var(--scrim);
  display:grid;place-items:center;padding:20px}
.dialogo{background:var(--panel);border:1px solid var(--border-strong);
  border-radius:var(--r-lg);box-shadow:var(--sombra-cartao);padding:24px;
  width:min(460px,100%)}
.dialogo h3{font-size:17px;margin:0 0 6px;color:var(--text)}
.dialogo .arquivo-alvo{font-family:var(--fonte-titulo);font-size:13.5px;
  color:var(--text-brand-arquivo);margin:0 0 14px;word-break:break-all}
.campo-confirma{width:100%;margin-top:12px;padding:10px 12px;font-size:13px;
  background:var(--bg);color:var(--text);border:1px solid var(--border-strong);
  border-radius:var(--r-xs);font-family:var(--fonte-texto)}
.campo-confirma:focus{outline:2px solid var(--border-focus);outline-offset:1px}
.dialogo-acoes{display:flex;gap:10px;justify-content:flex-end;margin-top:20px}
.btn-principal{border:0;background:var(--brand-orange-botao);color:var(--text-on-brand);
  border-radius:var(--r-pill);padding:8px 18px;font-size:13px;font-weight:600;
  cursor:pointer;font-family:var(--fonte-texto);transition:transform .1s var(--ease)}
/* Texto sobre o vermelho de perigo usa o token de texto claro, nao um branco
   literal: a guarda de cores do projeto reprova cor fora do bloco de tokens, e
   ela esta certa -- foi assim que quatro cores soltas foram pegas em 10/09. */
.btn-principal.perigo{background:var(--bad);color:var(--text)}
/* Desabilitado tem de PARECER desabilitado: confirmação irreversível cujo botão
   parece clicável convida ao clique reflexo. */
.btn-principal[disabled]{opacity:.4;cursor:not-allowed}

/* Aviso de ação irreversível. Curto de propósito: texto longo em diálogo
   treina a pessoa a fechar sem ler, e aí o aviso que importa passa batido.
   `margin-bottom` -- faltava, e na tela de admin (onde o aviso vem ANTES do
   filtro Todos/Ativo/Suspenso, não depois de um botão com seu próprio
   espaço) o aviso colava direto no filtro, sem respiro nenhum. Achado do
   Guilherme, 14/09/2026. */
.aviso-curto{margin:14px 0 var(--gap);padding:10px 12px;border-radius:var(--r-xs);
  background:var(--bad-bg);border:1px solid var(--bad-border);
  color:var(--bad-fg);font-size:12.5px}

/* Recentes agrupados por pasta. */
.grupo-recente + .grupo-recente{margin-top:var(--sec-gap)}
.titulo-pasta{font-size:12px;text-transform:uppercase;letter-spacing:.04em;
  color:var(--text-tertiary);margin:0 0 10px;cursor:pointer;display:inline-block}
.titulo-pasta:hover{color:var(--text-brand)}
.titulo-pasta:focus-visible{outline:2px solid var(--border-focus);outline-offset:2px}

/* ---------- barra de produto (área Operações) ---------- */
.barra-produto{display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  margin-bottom:18px;padding-bottom:16px;border-bottom:1px solid var(--border)}
.rotulo-produto{font-size:11px;text-transform:uppercase;letter-spacing:.05em;
  color:var(--text-tertiary);font-weight:600}
.produto-unico{font-family:var(--fonte-titulo);font-size:18px;font-weight:700;
  color:var(--text)}
.produtos{display:flex;gap:8px;flex-wrap:wrap}
.produto{border:1px solid var(--border-strong);background:transparent;
  color:var(--text-dim);border-radius:var(--r-pill);padding:7px 16px;
  font-size:13px;font-weight:600;cursor:pointer;font-family:var(--fonte-texto);
  transition:all .2s var(--ease)}
.produto:hover{border-color:var(--border-focus);color:var(--text)}
.produto.ativo{background:var(--brand-orange-botao);border-color:var(--brand-orange-botao);
  color:var(--text-on-brand)}

/* FILTROS da sidebar de Operações -- Fase 3a, 12/09/2026. Chip reusa o
   desenho de `.produto` (mesma pergunta visual: "isto está escolhido?"),
   só que menor, porque aqui cabem vários grupos na coluna de 280px. */
.fgrupo{margin:0 0 16px}
.flabel{font-size:10.5px;text-transform:uppercase;letter-spacing:.05em;
  color:var(--text-tertiary);font-weight:600;margin:0 0 7px;padding:0 2px}
.fchips{display:flex;gap:6px;flex-wrap:wrap}
.fchip{border:1px solid var(--border-strong);background:transparent;
  color:var(--text-dim);border-radius:var(--r-pill);padding:4px 11px;
  font-size:12px;font-weight:600;cursor:pointer;font-family:var(--fonte-texto);
  transition:all .2s var(--ease)}
.fchip:hover{border-color:var(--border-focus);color:var(--text)}
.fchip.ativo{background:var(--brand-orange-botao);border-color:var(--brand-orange-botao);
  color:var(--text-on-brand)}
.flimpar{display:block;width:100%;text-align:left;background:none;border:none;
  color:var(--text-brand);font-size:12px;font-weight:600;cursor:pointer;
  padding:0 2px;margin:0 0 16px}
.flimpar:hover{text-decoration:underline}

/* BUSCA + EXPORTAR CSV da tabela -- Fase 3c, 12/09/2026. */
.busca-tabela{display:flex;gap:10px;align-items:center;margin:0 0 12px;flex-wrap:wrap}
.busca-tabela input[type="search"]{flex:1;min-width:200px;padding:8px 12px;font-size:13px;
  background:var(--bg);color:var(--text);border:1px solid var(--border-strong);
  border-radius:var(--r-xs);font-family:var(--fonte-texto)}
.busca-tabela input[type="search"]:focus{outline:2px solid var(--border-focus);outline-offset:1px}
.btn-csv{flex:none;border:1px solid var(--border-strong);background:transparent;
  color:var(--text-dim);border-radius:var(--r-xs);padding:8px 14px;font-size:13px;
  font-weight:600;cursor:pointer;font-family:var(--fonte-texto);
  transition:all .2s var(--ease)}
.btn-csv:hover{border-color:var(--border-focus);color:var(--text)}

/* ---------- tela de entrada (antes do login) ---------- */
body.deslogado .casca{grid-template-columns:1fr;place-items:center}
/* .entrada e' so' o empilhamento vertical (cartao + rodape), centralizado
   pelo grid acima. .cartao-entrada carrega a moldura de verdade -- volta
   a ter borda/fundo/sombra como a versao anterior tinha (pedido do
   Guilherme, 14/09/2026: "eu deixaria o card em borda no centro como
   tinha antes"), com a colagem por dentro. */
.entrada{display:flex;flex-direction:column;align-items:center;
  padding:24px;max-width:480px;margin:0 auto}
/* Cartao maior -- ocupa mais espaco da tela (pedido do Guilherme,
   14/09/2026), nao fica so' uma caixinha pequena no meio do vazio. */
.cartao-entrada{display:flex;flex-direction:column;align-items:center;gap:12px;
  text-align:center;background:var(--panel);border:1px solid var(--border);
  border-radius:var(--r-lg);box-shadow:var(--sombra-cartao);
  padding:64px 56px 52px;width:100%}
/* Mais respiro entre a colagem e o botao -- estava colado demais (pedido
   do Guilherme). */
.cartao-entrada .btn-principal{margin-top:36px;padding:14px 40px;font-size:15px}
/* EXCECAO ACEITA (Guilherme, 14/09/2026, avisado do numero antes de
   confirmar): texto branco sobre --brand-orange mede ~2,9:1 -- abaixo do
   piso de 3:1 (texto grande) e 4,5:1 (normal) que o resto do sistema
   segue (--text-on-brand existe por isso, DDR-068). So' o botao Entrar
   da entrada; o --text-on-brand continua valendo em todo o resto do app. */
.cartao-entrada .btn-principal{color:var(--text)}
.logo.grande{height:56px;width:auto}
/* Rodape de copyright fixo na base da TELA, independente do cartao estar
   centralizado -- pedido do Guilherme, 14/09/2026 ("na parte inferior da
   tela"). position:fixed tira do fluxo, entao nao empurra o cartao. */
.rodape-entrada{position:fixed;left:0;right:0;bottom:28px;text-align:center;
  font-size:11.5px;letter-spacing:.04em;color:var(--text-tertiary);margin:0}

/* Colagem de etiquetas -- a sigla do produto (V/I/E/W), decidida com o
   Guilherme em 14/09/2026 depois de 3 rodadas de exploração (DESIGN.md,
   componente "Cartão de entrada"). Cada letra mora no próprio "adesivo",
   levemente girado e sobreposto ao vizinho -- como colado à mão, mas
   composto, não jogado. "I" e "W" carregam a barra de acento de 3px em
   --brand-orange na base -- MESMO desenho do KPI/Cartão de recente, então
   isto está dentro da regra DADO/TINTA, não é exceção. O significado da
   sigla (Visão Interativa da Emcash via Workspaces, docs/projeto.md) NUNCA
   aparece escrito na tela -- só no `title` nativo (hover) e no `.sr-only`
   abaixo, pedido explícito do Guilherme ("não gostei de mostrar escrito"). */
/* Mais espaco entre a logo e a colagem -- estava colado demais (pedido
   do Guilherme, 14/09/2026). Etiquetas maiores tambem, acompanhando o
   cartao maior. */
.colagem{display:flex;align-items:center;justify-content:center;flex-wrap:wrap;
  max-width:340px;margin:28px 0 8px;cursor:default}
.etiqueta{width:68px;height:68px;border-radius:var(--r-lg);display:flex;
  align-items:center;justify-content:center;font-family:var(--fonte-titulo);
  font-weight:800;font-size:32px;box-shadow:var(--sombra-cartao);flex-shrink:0;
  background:var(--panel-2);color:var(--text);position:relative;overflow:hidden}
.etiqueta.acento::after{content:"";position:absolute;left:0;right:0;bottom:0;
  height:3px;background:var(--brand-orange)}
.etiqueta.v{transform:rotate(-3deg) translateY(2px);margin-right:-8px;z-index:4}
.etiqueta.i{transform:rotate(2deg) translateY(-4px);margin-right:-8px;z-index:3}
.etiqueta.e{transform:rotate(-2deg) translateY(-3px);margin-right:-8px;z-index:2}
.etiqueta.w{transform:rotate(3deg) translateY(3px);z-index:1}

.nome-workspace{font-family:var(--fonte-titulo);font-size:17px;font-weight:700;
  color:var(--text-primary);margin:4px 0 0}

/* Suspensa NUNCA usa o vermelho de erro (--bad-fg): é um estado normal,
   decidido por alguém, não uma falha. Mesmo cinza neutro que o KPI usa
   antes de ganhar classificação semântica. */
.aviso-curto.neutro{background:var(--panel-2);border-color:var(--border);
  color:var(--text-dim)}

/* ---------- envio ao cliente ---------- */
.destinos{list-style:none;margin:14px 0 0;padding:0;display:flex;
  flex-direction:column;gap:8px}
.destinos li{display:flex;gap:12px;align-items:baseline;padding:10px 12px;
  background:var(--bg-subtle);border:1px solid var(--border);
  border-radius:var(--r-xs)}
.destinos .canal{font-size:11px;text-transform:uppercase;letter-spacing:.04em;
  color:var(--text-tertiary);font-weight:600;min-width:78px}
.destinos .endereco{font-size:13px;color:var(--text-primary);word-break:break-all}
.sec-envios{margin-top:var(--sec-gap)}
.sec-envios h3{font-size:12px;text-transform:uppercase;letter-spacing:.03em;
  color:var(--text-tertiary);margin:0 0 8px;font-weight:600}

/* ---------- ações de pasta e fila da rotina ---------- */
.menu-pasta{margin-left:auto;border:0;background:transparent;color:var(--text-tertiary);
  cursor:pointer;font-size:15px;line-height:1;padding:0 2px;border-radius:var(--r-xs)}
.menu-pasta:hover{color:var(--text-brand)}
.no:hover .menu-pasta{color:var(--text-dim)}
.sec-pendencias{margin-top:var(--sec-gap)}
.sec-pendencias h3{font-size:12px;text-transform:uppercase;letter-spacing:.03em;
  color:var(--text-tertiary);margin:0 0 8px;font-weight:600}
.pendencias{list-style:none;margin:0;padding:0;display:flex;
  flex-direction:column;gap:6px}
.pendencias li{display:flex;gap:12px;align-items:center;padding:9px 12px;
  background:var(--bg-subtle);border:1px solid var(--border);
  border-radius:var(--r-xs);font-size:13px;color:var(--text-primary)}
.pendencias .desfazer{margin-left:auto;border:0;background:transparent;
  color:var(--text-tertiary);cursor:pointer;font-size:12px;
  font-family:var(--fonte-texto);text-decoration:underline}
.pendencias .desfazer:hover{color:var(--text-brand)}

/* ---------- barra de réplicas (topo do Repositório) ---------- */
.barra-replicas{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  margin-bottom:18px;padding-bottom:16px;border-bottom:1px solid var(--border)}
.replica{display:inline-flex;align-items:center;gap:10px;cursor:pointer;
  border:1px solid var(--border-strong);background:var(--panel-2);
  border-radius:var(--r-pill);padding:7px 14px;font-family:var(--fonte-texto);
  font-size:12.5px;color:var(--text-primary);transition:all .2s var(--ease)}
.replica:hover{border-color:var(--border-focus)}
.replica.aberta{border-color:var(--brand-orange)}
.replica .canal{font-size:11px;text-transform:uppercase;letter-spacing:.04em;
  color:var(--text-tertiary);font-weight:600}
.replica .endereco{color:var(--text-dim);max-width:26ch;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.replica .seta{font-size:10px;color:var(--text-tertiary)}
.historico-replica{flex-basis:100%;margin-top:4px}
.replica.desligada{opacity:.62;border-style:dashed}
.marca-ligado{font-size:11px;color:var(--ok);font-weight:600}
.marca-ligado.herdado{color:var(--text-tertiary);font-weight:400;font-style:italic}
.marca-desligado{font-size:11px;color:var(--text-tertiary)}
/* Pedido na fila: a barra ja mostra o efeito, mas o efeito ainda nao existe.
   Tracejado porque e' a mesma gramatica do resto da tela para "pedido, nao
   aplicado" -- nao e' um estado novo, e' o mesmo em outro lugar. */
.marca-ligado.na-fila,.marca-desligado.na-fila{
  color:var(--warn-fg);font-weight:600;font-style:normal;
  border-bottom:1px dashed var(--warn-border)}
.painel-replica{flex-basis:100%;margin-top:4px;padding:14px;
  background:var(--bg-subtle);border:1px solid var(--border);
  border-radius:var(--r-md)}
.acoes-replica{display:flex;gap:10px;align-items:center;flex-wrap:wrap;
  margin-bottom:12px}
.acoes-replica .nota{margin:0}
.btn-modo.perigo{color:var(--bad-fg);border-color:var(--bad-border)}
.btn-modo.perigo:hover{border-color:var(--bad);background:var(--bad-bg)}
.add-destino{border:1px dashed var(--border-strong);background:transparent;
  color:var(--text-tertiary);border-radius:var(--r-pill);padding:7px 14px;
  font-size:12.5px;cursor:pointer;font-family:var(--fonte-texto)}
.add-destino:hover{border-color:var(--brand-orange);color:var(--text-brand)}
