/* =============================================================================
   MGS-MOTOR  ·  o motor gráfico da casa
   -----------------------------------------------------------------------------
   Uma fonte para TODA peça que sai daqui: Ramura, MGS, Campo (Cláudia),
   proposta de cliente, artefato, PDF.

   POR QUE ELE EXISTE — medido em 30/08/2026, não suposto:
     234 arquivos .html com bloco :root · 43 paletas distintas · zero arquivo
     de estilo compartilhado.
     A mesma marinha da Ramura aparecia como #0a1e38 (117 arquivos),
     #0e2748 (106), #12294f (106) e #1d3a63 (106). Quatro valores, uma cor.

   E A DERIVA EM ESTADO PURO, que fechou o caso:
     na Ramura, --ciano, --ouro, --ouro-escuro e --verde eram TODOS #00FFA8.
     Quatro nomes para uma cor — e "--ouro" apontando para um verde. Alguém
     trocou o valor e deixou os nomes. No Campo, --laranja e --rosa eram o
     mesmo #FFAE6B. Nome que mente é pior que cor errada: ele sobrevive à
     correção.

   O QUE ELE NÃO É:
     um framework escrito do zero. É uma CAMADA FINA — tokens e um punhado de
     componentes — por cima de bibliotecas que já existem e são livres
     (ECharts, Jspreadsheet CE, Tabulator). Motor que tenta ser framework
     come meses e nunca fica pronto.

   AS TRÊS MARCAS NÃO SE MISTURAM — medido, e com zero sobreposição:
     Ramura ... marinha  ... 124 arquivos ... data-marca="ramura"
     MGS ...... teal     ....41 arquivos ... data-marca="mgs"
     Campo .... verde/laranja 61 arquivos ... data-marca="campo"
     A casa nunca teve 43 desenhos: teve 3 marcas escritas 43 vezes.

   COMO USAR:
     <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/mgs-motor@X.Y.Z/mgs.css">
     <body data-marca="ramura">

     🔴 SEMPRE COM VERSÃO CRAVADA (@1.2.3), NUNCA @latest.
        Peça entregue ao cliente não pode mudar de aparência sozinha quando eu
        corrijo o motor. Ver [[artefato-publico-congela-na-versao]].

   ⚠️ UM CSS DE TERCEIRO ENTRA JUNTO: `vendor/tabulator.min.css` (MIT, Oli
      Folkerd). Ele é ESTRUTURAL — posiciona linha e célula. Tentei viver sem
      ele em 30/08/2026 e a tabela empilhou as colunas uma embaixo da outra.
      Entra ANTES deste arquivo, para a cascata da casa vencer a aparência dele.
      O Jspreadsheet NÃO precisa do dele: usa <table> de verdade.

   A ESTRUTURA dos nomes saiu da paleta da MGS, que era a mais madura das três
   (tinha painel/linha/fraco/médio e o "sobre-X" de contraste). As outras duas
   foram mapeadas nela.
   ============================================================================= */

/* AS FONTES.
   ⚠️ `@import` tem de ser a PRIMEIRA coisa do arquivo: regra antes dele faz o
      navegador DESCARTAR o import inteiro, em silêncio, e a página cai na fonte
      de sistema sem avisar ninguém. É a falha calada mais comum de CSS.
   💡 Mais rápido ainda é pôr o <link> no topo da página; o import fica aqui
      para o motor funcionar sozinho, sem depender de quem o usa lembrar.
   🔴 E TODA família declarada abaixo tem pilha de reserva DE VERDADE: no
      curral da Cláudia não há sinal, e fonte que não baixa tem de cair em algo
      escolhido, não no que sobrar. */
@import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap');

/* -----------------------------------------------------------------------------
   1. O NÚCLEO — o esqueleto que toda marca preenche.
   Os valores aqui são o modo CLARO neutro: uma peça sem data-marca ainda
   nasce legível, em vez de nascer transparente.
   -------------------------------------------------------------------------- */
:root {
  /* superfícies, do fundo para a frente */
  --mgs-fundo:        #f2f4f7;
  --mgs-painel:       #ffffff;
  --mgs-painel-2:     #f7f9fb;
  --mgs-linha:        #dde3ea;
  --mgs-linha-suave:  rgba(16, 20, 24, .10);

  /* texto, do mais forte ao mais apagado */
  --mgs-texto:        #101418;
  --mgs-texto-2:      #5b6675;
  --mgs-tenue:        #8b95a3;

  /* a marca — o único bloco que cada casa troca */
  --mgs-marca:        #0a1e38;
  --mgs-marca-forte:  #12294f;
  --mgs-marca-fraca:  rgba(10, 30, 56, .08);
  --mgs-marca-media:  rgba(10, 30, 56, .16);
  --mgs-sobre-marca:  #ffffff;   /* texto POR CIMA da cor da marca */

  /* os três estados, e só três: eles carregam significado, não decoração */
  --mgs-ok:           #1f9d6b;
  --mgs-ok-bg:        #e6f6ee;
  --mgs-alerta:       #e08a1e;
  --mgs-alerta-bg:    #fdf2e0;
  --mgs-erro:         #c0392b;
  --mgs-erro-bg:      #fdecea;

  /* A VARIAÇÃO DO KPI — a seta e a palavra dizem a direção; a cor só reforça.
     No núcleo eles valem o ok e o erro de sempre; cada marca pode dar os seus
     (o Grupo K dá, e usa o amarelo da própria marca no que pede atenção).
     ⚠️ Nascem AQUI porque token que só existe dentro de uma marca é órfão: o
     componente que o usa quebra em toda marca que não o declarou — e foi esta
     prova que cobrou, em 06/09/2026, quando o leitor dela finalmente passou a
     enxergar o bloco do Grupo K. */
  --mgs-delta-bom:    #1f9d6b;
  --mgs-delta-ruim:   #c0392b;

  /* TIPOGRAFIA — três papéis, e a troca de qualquer um é UMA LINHA.
     Medido em 30/08/2026 nos 234 arquivos da casa: JetBrains Mono em 44,
     Space Grotesk em 38, e mais sete famílias soltas. Não tínhamos tipografia:
     tínhamos nove decisões independentes.

     ⏳ A DE TEXTO ESTÁ EM TESTE. O Marcelo mandou seguir com o que a casa já
        usa e escolher o modelo depois — por isso ela é um token, e trocar é
        mexer numa linha e rodar a prova. Ver `tipografia.html`.
        A ressalva que fica registrada: Space Grotesk virou uma das faces que
        hoje denunciam página gerada por IA, de tão usada. Não é defeito
        técnico; é quilometragem. */
  --mgs-fonte-titulo: 'Space Grotesk', ui-sans-serif, system-ui, "Segoe UI", Arial, sans-serif;
  --mgs-fonte: 'Space Grotesk', ui-sans-serif, system-ui, -apple-system, "Segoe UI",
               Roboto, "Helvetica Neue", Arial, sans-serif;
  --mgs-fonte-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, "SF Mono", Menlo,
               Consolas, "Liberation Mono", monospace;

  /* o título pede menos espaço entre letras que o texto; o número pede largura
     fixa. Isto é tipografia, não gosto: coluna de número que dança não se
     compara de relance, que é a única coisa que ela serve para fazer. */
  /* ⚠️ 600, e não 650. O `@import` traz os pesos 400, 500, 600 e 700 — medido
     na folha que ele mesmo aponta. Pedir 650 numa face não-variável faz o
     navegador escolher o vizinho em silêncio, e o título sai com um peso que
     ninguém decidiu. Se um dia a face for variável, o @import precisa pedir a
     FAIXA (`wght@400..700`) antes de este número voltar a ser livre. */
  --mgs-titulo-peso: 600;
  --mgs-titulo-aperto: -.02em;
  --mgs-t-xs:   .75rem;
  --mgs-t-sm:   .875rem;
  --mgs-t-base: 1rem;
  --mgs-t-lg:   1.125rem;
  --mgs-t-xl:   1.375rem;
  --mgs-t-2xl:  1.75rem;
  --mgs-t-3xl:  2.25rem;

  /* espaço — múltiplos de 4, para parar de inventar 13px e 27px */
  --mgs-e-1: 4px;  --mgs-e-2: 8px;  --mgs-e-3: 12px; --mgs-e-4: 16px;
  --mgs-e-5: 24px; --mgs-e-6: 32px; --mgs-e-7: 48px; --mgs-e-8: 64px;

  /* apoio: a quarta cor, que só algumas peças usam (no Campo é o azul do
     exame). Mora no núcleo com valor neutro porque componente que usa token
     de UMA marca só nasce quebrado nas outras — e quebra calado: var() sem
     valor não dá erro, dá vazio. */
  --mgs-apoio:      #3C8FB5;
  --mgs-apoio-bg:   #EDF8FD;


  /* AS SÉRIES — a paleta categórica dos gráficos.
     ⚠️ A ORDEM É O MECANISMO DE SEGURANCA, não é gosto: ela foi escolhida
     para que cores VIZINHAS continuem distintas para quem enxerga cor de outro
     jeito. Trocar a ordem quebra isso em silêncio. Atribuir sempre na ordem, e
     NUNCA reciclar: a 9ª série vira "Outros", nunca uma cor inventada.
     Medido em 30/08/2026 com o validador da casa, contra ESTA superfície:
       banda de luminosidade . piso de croma . separação para daltonismo
       (pior vizinho ΔE 9,1) . piso de visão normal (19,6) . contraste
     🟡 Três destas ficam abaixo de 3:1 no branco (#1baf7a, #eda100, #e87ba4):
        no claro, gráfico SEMPRE com rótulo visível ou tabela ao lado. */
  --mgs-serie-1: #2a78d6;   --mgs-serie-2: #eb6834;
  --mgs-serie-3: #1baf7a;   --mgs-serie-4: #eda100;
  --mgs-serie-5: #e87ba4;   --mgs-serie-6: #008300;
  --mgs-serie-7: #4a3aa7;   --mgs-serie-8: #e34948;

  /* a superfície do gráfico e a grade, que têm de ser DISCRETAS:
     a grade é referência, não desenho. */
  --mgs-viz-fundo:  var(--mgs-painel);
  --mgs-viz-grade:  var(--mgs-linha-suave);
  --mgs-viz-eixo:   var(--mgs-tenue);

  /* o halo. \u26a0\ufe0f `none` \u00e9 o neutro certo: pe\u00e7a sem neon N\u00c3O ganha brilho
     acidental, e as duas marcas escuras acendem o seu por cima. */
  --mgs-brilho:     none;

  --mgs-raio:       10px;
  --mgs-raio-sm:    6px;
  --mgs-sombra:     0 1px 2px rgba(16,20,24,.06), 0 4px 12px rgba(16,20,24,.06);
  --mgs-sombra-sm:  0 1px 2px rgba(16,20,24,.08);
  --mgs-largura-leitura: 72ch;   /* linha longa demais ninguém lê */
}

/* -----------------------------------------------------------------------------
   2. AS MARCAS
   Cada bloco só redefine o que MUDA. Nenhuma marca redefine espaçamento ou
   escala tipográfica — se uma precisasse, o núcleo é que estaria errado.
   -------------------------------------------------------------------------- */

/* RAMURA — marinha sobre escuro. Origem: Ramura-Sistema-v1-nuvem.html.
   🔴 A correção: --ciano/--ouro/--ouro-escuro/--verde eram os quatro #00FFA8.
      Aqui existe UM verde de marca. O nome "ouro" morreu: mentia. */
[data-marca="ramura"] {
  --mgs-fundo:       #0A1E38;
  --mgs-painel:      #12294F;
  --mgs-painel-2:    #0e2748;
  --mgs-linha:       #1d3a63;
  --mgs-linha-suave: rgba(157, 179, 208, .20);

  --mgs-texto:       #EAF2FF;
  --mgs-texto-2:     #9DB3D0;
  --mgs-tenue:       #6f86a6;

  --mgs-marca:       #00FFA8;
  --mgs-marca-forte: #29E0F5;
  --mgs-marca-fraca: rgba(0, 255, 168, .10);
  --mgs-marca-media: rgba(0, 255, 168, .20);
  --mgs-sobre-marca: #0A1E38;

  --mgs-alerta:      #FFB020;
  --mgs-alerta-bg:   rgba(255, 176, 32, .14);
  --mgs-erro:        #FF7B7B;
  --mgs-erro-bg:     rgba(255, 123, 123, .14);
  --mgs-ok:          #00FFA8;
  --mgs-ok-bg:       rgba(0, 255, 168, .12);

  /* \U0001f534 O HALO. Ele era usado em 4 regras e declarado em NENHUMA marca — a
     camada de neon inteira ficava inerte, e a minha própria prova abençoava o
     buraco (ela testava `var(--mgs-brilho, none)` e passava justamente porque
     o token não existia). Achado pela auditoria de 30/08/2026.
     ⚠️ Só nas duas marcas ESCURAS: em superfície clara o halo suja em vez de
        acender. O Campo não declara, e `.mgs-neon` lá cai para `none`. */
  --mgs-brilho:      0 0 24px rgba(0, 255, 168, .28);

  /* as séries, degrau ESCURO — GERADAS E MEDIDAS por `gera-serie-escura.js`
     em 04/09/2026, com piso APCA **Lc 45** (o piso de ELEMENTO gráfico; o de
     texto, 60, vale para o rótulo ao lado, que usa --mgs-texto).

     🔴 O QUE ESTAVA AQUI ANTES, e por que saiu. O bloco anterior dizia
     "mesmas oito cores, outro degrau" e "passa inteira (tudo >= 3:1)" — e
     eram, hexadecimal por hexadecimal, AS MESMAS do degrau claro. Medidas
     contra este painel (#12294F): **Lc 24 a 41**, e a série 6 em **2,92:1**,
     abaixo do 3:1 que o próprio comentário prometia. Promessa escrita em
     comentário não é medição.

     Três exigências ao mesmo tempo, e por isso o gerador BUSCA em vez de
     calcular: (1) Lc >= 45 contra os quatro fundos das duas marcas escuras;
     (2) a MAIOR saturação que ainda cumpre (1) — clarear em HSL até bater o
     piso devolve pastel, que é a mesma queixa por outro caminho; (3) matizes
     separados por construção e fora de ±22° do verde-menta da marca, para
     nenhuma série ser lida como "a cor da Ramura". */
  --mgs-serie-1: #4a9eff;   --mgs-serie-2: #ab8aff;
  --mgs-serie-3: #ff45f9;   --mgs-serie-4: #ff6989;
  --mgs-serie-5: #ed7e00;   --mgs-serie-6: #92cc00;
  --mgs-serie-7: #00cc07;   --mgs-serie-8: #00bbcc;
}

/* MGS — teal sobre carbono. Origem: Grupo-K-fluxo-locacao-*.html, a paleta
   mais madura das três e o esqueleto de nomes deste arquivo. */
[data-marca="mgs"] {
  --mgs-fundo:       #08090A;
  --mgs-painel:      #12171B;
  --mgs-painel-2:    #1B2228;
  --mgs-linha:       #2C353C;
  --mgs-linha-suave: rgba(154, 161, 164, .22);

  --mgs-texto:       #EDEFF0;
  --mgs-texto-2:     #C8CCCE;
  --mgs-tenue:       #82898C;

  --mgs-marca:       #03F5D3;
  --mgs-marca-forte: #00A79E;
  --mgs-marca-fraca: rgba(3, 245, 211, .09);
  --mgs-marca-media: rgba(3, 245, 211, .17);
  --mgs-sobre-marca: #08090A;

  --mgs-alerta:      #D8A146;
  --mgs-alerta-bg:   rgba(216, 161, 70, .11);
  --mgs-erro:        #e2705f;
  --mgs-erro-bg:     rgba(226, 112, 95, .12);
  --mgs-ok:          #03F5D3;
  --mgs-ok-bg:       rgba(3, 245, 211, .10);
  --mgs-brilho:      0 0 24px rgba(3, 245, 211, .26);

  /* as séries, degrau ESCURO — GERADAS E MEDIDAS por `gera-serie-escura.js`
     em 04/09/2026, com piso APCA **Lc 45** (o piso de ELEMENTO gráfico; o de
     texto, 60, vale para o rótulo ao lado, que usa --mgs-texto).

     🔴 O QUE ESTAVA AQUI ANTES, e por que saiu. O bloco anterior dizia
     "mesmas oito cores, outro degrau" e "passa inteira (tudo >= 3:1)" — e
     eram, hexadecimal por hexadecimal, AS MESMAS do degrau claro. Medidas
     contra este painel (#12294F): **Lc 24 a 41**, e a série 6 em **2,92:1**,
     abaixo do 3:1 que o próprio comentário prometia. Promessa escrita em
     comentário não é medição.

     Três exigências ao mesmo tempo, e por isso o gerador BUSCA em vez de
     calcular: (1) Lc >= 45 contra os quatro fundos das duas marcas escuras;
     (2) a MAIOR saturação que ainda cumpre (1) — clarear em HSL até bater o
     piso devolve pastel, que é a mesma queixa por outro caminho; (3) matizes
     separados por construção e fora de ±22° do verde-menta da marca, para
     nenhuma série ser lida como "a cor da Ramura". */
  --mgs-serie-1: #4a9eff;   --mgs-serie-2: #ab8aff;
  --mgs-serie-3: #ff45f9;   --mgs-serie-4: #ff6989;
  --mgs-serie-5: #ed7e00;   --mgs-serie-6: #92cc00;
  --mgs-serie-7: #00cc07;   --mgs-serie-8: #00bbcc;
}

/* ════════════════════════════════════════════════════════════════════
   GRUPO K — amarelo-limão sobre chumbo. A identidade REAL deles, medida.
   ---------------------------------------------------------------------------
   Ordem do Marcelo, 05/09/2026:

     *"Busca no site do Grupo K quais são as cores que eles usam, porque eles
      usam um amarelo diferente, acho que é preto e amarelo. Tenta olhar dentro
      da nossa paleta qual a combinação de cor com essas cores base, e vê se o
      motor aprova o layout com essas cores do Grupo K."*

   🔎 DE ONDE VIERAM. Abri `grupok.ind.br` e contei as cores computadas de
   todos os elementos da página. As três dominantes:

       #3a3939  chumbo   788 ocorrências   ← o "preto" deles, e não é preto
       #000000  preto    304
       #f2f527  amarelo   95               ← a marca, e bate com o logo (medi o PNG)

   ⚖️ E O MOTOR APROVOU A BASE DELES, medida antes de virar CSS:

       preto sobre amarelo ....... APCA Lc 95  · WCAG 17,9:1   ← o par do logo
       amarelo sobre preto ....... APCA Lc 96  · WCAG 17,9:1
       amarelo sobre chumbo ...... APCA Lc 88  · WCAG  9,8:1
       branco sobre chumbo ....... APCA Lc 100 · WCAG 11,5:1

   Todos muito acima do piso da casa (Lc 60 para texto). É uma identidade que já
   nasce legível — o que faz sentido: amarelo de segurança sobre máquina escura
   é o par que a indústria usa há um século, e por este motivo.

   🔑 O QUE MUDA E O QUE NÃO MUDA COM A MARCA
   Mudam fundo, painel, linha, texto e a cor de REALCE. **NÃO mudam as oito
   séries categóricas** — rodei o `gera-serie-escura.js` contra este fundo e ele
   devolveu as mesmas oito. É de propósito: a identidade de uma série é o MATIZ,
   e elas estão espalhadas para se distinguirem inclusive por quem enxerga cor
   de outro jeito. Tingir as oito de amarelo deixaria bonito e ilegível.
   O que dá identidade ao painel é o outro eixo: DESTACAR, uma cor só, e essa
   cor é a da marca. Ver `mgs-painel.js`.
   ════════════════════════════════════════════════════════════════════ */
[data-marca="grupo-k"] {
  --mgs-fundo:       #121212;
  --mgs-painel:      #1c1c1b;
  --mgs-painel-2:    #262625;
  --mgs-linha:       #373735;
  --mgs-linha-suave: rgba(242, 245, 39, .14);

  --mgs-texto:       #f2f2ef;
  --mgs-texto-2:     #c2c2bc;
  --mgs-tenue:       #8a8a84;

  --mgs-marca:       #f2f527;
  /* ⚠️ `marca-forte` é para texto SOBRE fundo escuro; o amarelo puro já passa,
     então ela existe só para hierarquia (hover, estado ativo). */
  --mgs-marca-forte: #d4d61f;
  --mgs-marca-fraca: rgba(242, 245, 39, .09);
  --mgs-marca-media: rgba(242, 245, 39, .18);

  /* A variacao dos KPIs, na FAMILIA da marca: o matiz do amarelo girado de
     40 em 40 graus (mgs.familiaDaMarca). O ambar subiu de luminosidade ate
     bater o piso de TEXTO (Lc 60) -- o primeiro candidato dava Lc 56, e um
     numero de KPI e texto, nao elemento grafico. */
  /* 🔁 SEGUNDA VOLTA, 06/09: *"os numeros percentuais embaixo eu quero
     tambem nas mesmas cores do grafico 2"*. O grafico 2 e marca + cinza,
     e a leitura semantica cai certa: o AMARELO marca o que precisa de
     atencao (a variacao ruim) e o cinza o que nao precisa. E a mesma regra
     que ele deu para os botoes -- o amarelo ressalta o que importa --
     aplicada ao numero. Quem diz a direcao continua sendo a seta. */
  /* 🔴 TERCEIRA VOLTA, 06/09 — e esta foi MEDIDA, não discutida.
     *"o 0,8% acima esta sem formatacao"*. Estava mesmo: `--mgs-delta-bom` era
     `#c2c2bc`, EXATAMENTE o valor de `--mgs-texto-2`. A variacao boa saia
     pintada com a cor do texto ao redor — informacao zero, e com cara de CSS
     que nao pegou. Medido no navegador: a cor do delta e a da nota ao lado, as
     duas em rgb(194,194,188).

     🔑 O cinza FRIO resolve sem sair da paleta: luminosidade parecida, matiz
     oposto ao cinza quente do texto — entao le como decisao, e nao como falta.
     E continua discreto de proposito: quem grita e o amarelo, que marca o que
     precisa de atencao. A `prova-mgs` passou a REPROVAR delta-bom igual ao
     texto, para isto nao voltar em silencio. */
  /* 🔁 QUARTA VOLTA, 06/09 — e ele inverteu a leitura:
     *"inverte as cores, deixa o amarelo para quando for positivo, e o negativo
      usa um vermelho neon"*.

     🔑 A regra muda de "amarelo marca o que precisa de atenção" para "a cor da
     MARCA celebra o que foi bem, e o que foi mal grita em vermelho". É mais
     direto de ler num painel que o diretor olha de passagem — e o amarelo
     deixa de ser a cor do problema, que era o incômodo.

     ⚠️ O vermelho é MEDIDO, não escolhido de olho: #ff3860 dá 4,86:1 sobre o
     painel e 5,34:1 sobre o fundo, os dois acima do piso de 4,5 da WCAG AA.
     O #ff0033, mais "neon", dava 4,30 e reprovaria. */
  --mgs-delta-bom:  #f2f527;
  --mgs-delta-ruim: #ff3860;
  /* 🔑 PRETO sobre o amarelo, e não branco: APCA Lc 95 contra Lc -14.
     É o par do próprio logo deles, e o único que se lê. */
  --mgs-sobre-marca: #000000;

  /* 🔴 O VERDE ESTAVA COLADO NO AMARELO — achado do Marcelo em 05/09:
     *"amarelo com verde com vermelho, acho que tem que ser amarelo e um outro
     tom ali; mas vê o que o motor fala para a gente."*

     O motor falou, e ele estava certo. Medi a separação de matiz entre os
     quatro tons desta marca:

         amarelo × verde-limão (#7ecc00) ..... 22°   ✗ abaixo do piso de 25°
         amarelo × âmbar (#ffb340) ........... 25°   no limite
         amarelo × vermelho ................. 52°   ✓
         verde × vermelho ................... 74°   ✓

     Na tela isso aparecia na barra de etapas: três traços verde-limão seguidos
     de um amarelo, e não dá para dizer onde um acaba. O piso de 25° é o mesmo
     que o `gera-serie-escura.js` usa para as oito séries, e vale aqui pelo mesmo
     motivo: cor que não separa não informa.

     🔑 Os substitutos foram MEDIDOS, não escolhidos: verde-água a 106° do
     amarelo (APCA 61) e rosa-vermelho a 74° (APCA 60). O âmbar do alerta sobe
     para 29° usando o mesmo laranja da série 5, que já passou pelo gerador. */
  /* 🚦 OS TRÊS ESTADOS — discretos, para o amarelo ser o único que salta.
     `node gera-estados.js --marca #f2f527 --painel #1c1c1b --fundo #121212`

     🔴 A QUINTA EXIGÊNCIA nasceu de uma queixa do Marcelo em 06/09:
     *"o amarelo já é forte e carrega a identidade do grupo; o verde está
     competindo com ela. Nos gráficos tem um tom de cinza que compete menos."*

     Medido com `mgs.croma`, ele tinha razão com número:
         marca amarelo ... 0,81
         verde anterior .. 0,90   ← gritava MAIS que a marca
         alerta anterior . 0,90   ← idem

     Agora há teto de saliência (72% do croma da marca) e o vencedor é o mais
     DISCRETO que cumpre o piso de contraste — e não o mais vivo nem o mais
     contrastante. As duas primeiras tentativas erraram pelo mesmo motivo:
     maximizar uma grandeza que já tinha piso.

         ok     #7ec1ce  matiz 190°  APCA 62/63  croma 0,31  · 129° da marca
         erro   #dfaaaf  matiz 354°  APCA 62/63  croma 0,21  ·  67° da marca
         alerta #d6b194  matiz  26°  APCA 62/63  croma 0,26  ·  35° da marca

     Todos acima do piso de leitura (60) e todos bem abaixo da marca em
     saliência. É o "se tudo salta, nada salta" do `mgs-forma`, aplicado à paleta
     de estados em vez de às séries de gráfico. */
  --mgs-alerta:      #d6b194;
  --mgs-alerta-bg:   rgba(214, 177, 148, .12);
  --mgs-erro:        #dfaaaf;
  --mgs-erro-bg:     rgba(223, 170, 175, .12);
  --mgs-ok:          #7ec1ce;
  --mgs-ok-bg:       rgba(126, 193, 206, .12);
  --mgs-brilho:      0 0 24px rgba(242, 245, 39, .22);

  /* as oito séries, GERADAS E MEDIDAS por `gera-serie-escura.js` contra o painel
     #1c1c1b e o fundo #121212, evitando ±22° do matiz da marca (61°, o amarelo).
     Piso APCA Lc 60 — o de TEXTO, mais duro que o de elemento gráfico.
     Medidas: Lc 60 a 64 contra os dois fundos, e nenhum par a menos de 25°. */
  --mgs-serie-1: #7ab8ff;   --mgs-serie-2: #bfa6ff;
  --mgs-serie-3: #ff85fb;   --mgs-serie-4: #ff94ab;
  --mgs-serie-5: #ff9c2b;   --mgs-serie-6: #7ecc00;
  --mgs-serie-7: #00cf07;   --mgs-serie-8: #00cca0;
}

/* CAMPO (Cláudia) — claro, papel de fazenda. Origem: Campo-v54.
   🔴 A correção: --laranja e --rosa eram o mesmo #FFAE6B, e --laranja-esc e
      --rosa-esc idem. Um par só sobreviveu. */
[data-marca="campo"] {
  --mgs-fundo:       #f2f4f7;
  --mgs-painel:      #ffffff;
  --mgs-painel-2:    #FFF4EA;
  --mgs-linha:       #dde3ea;
  --mgs-linha-suave: rgba(16, 20, 24, .10);

  --mgs-texto:       #101418;
  --mgs-texto-2:     #5b6675;
  --mgs-tenue:       #8b95a3;

  --mgs-marca:       #D4813E;
  --mgs-marca-forte: #FF8000;
  --mgs-marca-fraca: rgba(212, 129, 62, .10);
  --mgs-marca-media: rgba(212, 129, 62, .20);
  /* 🔴 ERA #ffffff, e a própria prova reprovou: branco sobre este laranja
     dá 3,00:1, abaixo do piso de leitura (4,5:1). Escuro dá 6,17:1. E este é o
     único dos três desenhos que alguém lê NO SOL, de pé ao lado do tronco. */
  --mgs-sobre-marca: #101418;

  --mgs-ok:          #1f9d6b;
  --mgs-ok-bg:       #e6f6ee;
  --mgs-alerta:      #e08a1e;
  --mgs-alerta-bg:   #fdf2e0;
  --mgs-erro:        #c0392b;
  --mgs-erro-bg:     #fdecea;

  /* o azul do exame, que só o Campo tem */
  --mgs-apoio:       #3C8FB5;
  --mgs-apoio-bg:    #EDF8FD;
}

/* -----------------------------------------------------------------------------
   3. O ALICERCE
   -------------------------------------------------------------------------- */
.mgs, .mgs * { box-sizing: border-box; }

/* 🔴 30/08/2026 — QUIRKS MODE. Numa página servida SEM `<!doctype html>` o
   navegador entra em modo de compatibilidade, e nele a `<table>` NÃO HERDA a
   cor do que está em volta: ela volta para preto. Aconteceu com a lei da
   escolha — o texto ficou preto sobre carbono, invisível, e nenhum seletor
   meu casava com a célula: era herança que não aconteceu.
   No artefato publicado o invólucro põe o doctype e o problema não existe. Mas
   o motor tem de aguentar os DOIS mundos: quem serve o arquivo cru também usa. */
.mgs table { color: inherit; font-family: inherit; }

/* ═══════════════════════════════════════════════════════════════════════════
   🔴 O ALIAS QUE RESOLVIA NO TEMA ERRADO — achado do Marcelo em 06/09/2026:
   *"o gráfico um está com as bordas marcadas, e as bordas mesmo estão em
    branco"*.

   Ele estava certo, e a causa é sutil. Lá em cima, no `:root`, existe:

       --mgs-viz-fundo: var(--mgs-painel);

   Parece que acompanha a marca, e NÃO acompanha. Uma custom property que
   referencia outra é resolvida NO ESCOPO ONDE FOI DECLARADA — e no `:root` o
   `--mgs-painel` ainda é o do tema CLARO, branco. As marcas escuras redefinem
   `--mgs-painel` no `<body>`, tarde demais: o `--mgs-viz-fundo` já tinha virado
   `#ffffff` e é esse valor, já resolvido, que o body herda.

   🔑 Na tela isso vira a borda de 2px que separa as fatias de uma barra
   empilhada: ela deveria ser da cor do painel (um respiro invisível) e saía
   BRANCA sobre chumbo — um risco em volta de cada fatia. O `mgs-viz` estava
   certo pedindo `viz-fundo`; o token é que mentia.

   ⚖️ O conserto é redeclarar no MESMO elemento que carrega a marca. `.mgs` é a
   classe do `<body>`, onde o `data-marca` vive, então aqui o `var()` enxerga o
   painel certo. Vale para as três de uma vez, e para toda marca futura — sem
   precisar lembrar de repetir dentro de cada bloco de marca.
   ═══════════════════════════════════════════════════════════════════════════ */
.mgs {
  --mgs-viz-fundo:  var(--mgs-painel);
  --mgs-viz-grade:  var(--mgs-linha-suave);
  --mgs-viz-eixo:   var(--mgs-tenue);
}

.mgs {
  margin: 0;
  background: var(--mgs-fundo);
  color: var(--mgs-texto);
  font-family: var(--mgs-fonte);
  font-size: var(--mgs-t-base);
  line-height: 1.55;
  -webkit-text-size-adjust: 100%;
}

:where(.mgs) h1, .mgs h2, .mgs h3, .mgs h4 {
  font-family: var(--mgs-fonte-titulo);
  font-weight: var(--mgs-titulo-peso);
  line-height: 1.2;
  margin: 0 0 var(--mgs-e-3);
  text-wrap: balance;          /* título não deixa uma palavra sozinha na 2ª linha */
}
:where(.mgs) h1 { font-size: var(--mgs-t-3xl); letter-spacing: var(--mgs-titulo-aperto); }
:where(.mgs) h2 { font-size: var(--mgs-t-2xl); letter-spacing: var(--mgs-titulo-aperto); }
:where(.mgs) h3 { font-size: var(--mgs-t-xl); letter-spacing: 0; }
:where(.mgs) h4 { font-size: var(--mgs-t-lg); letter-spacing: 0; }

/* número com largura fixa em TODO lugar onde ele se compara em coluna */
.mgs-kpi-valor, .mgs-tabela td, .mgs-num, .mgs-delta,
.mgs-planilha .jss_worksheet > tbody > tr > td { font-variant-numeric: tabular-nums; }
:where(.mgs) p  { margin: 0 0 var(--mgs-e-4); max-width: var(--mgs-largura-leitura); }
.mgs a  { color: var(--mgs-marca-forte); text-underline-offset: 2px; }
.mgs code, .mgs kbd { font-family: var(--mgs-fonte-mono); font-size: .92em; }
.mgs img { max-width: 100%; height: auto; }

/* -----------------------------------------------------------------------------
   4. COMPONENTES — só os que esta casa REPETE. Cada um entrou por já existir
   escrito à mão em três lugares, não por parecer útil.
   -------------------------------------------------------------------------- */

/* cartão */
.mgs-cartao {
  background: var(--mgs-painel);
  border: 1px solid var(--mgs-linha);
  border-radius: var(--mgs-raio);
  padding: var(--mgs-e-4);
  box-shadow: var(--mgs-sombra-sm);
}
.mgs-cartao--marca { border-left: 3px solid var(--mgs-marca); }
.mgs-cartao--alerta{ border-left: 3px solid var(--mgs-alerta); }
.mgs-cartao--erro  { border-left: 3px solid var(--mgs-erro); }

/* selo */
.mgs-selo {
  display: inline-flex; align-items: center; gap: var(--mgs-e-1);
  padding: 2px var(--mgs-e-2);
  border-radius: 999px;
  font-size: var(--mgs-t-xs); font-weight: 600;
  background: var(--mgs-marca-fraca); color: var(--mgs-marca);
  white-space: nowrap;
}
.mgs-selo--ok    { background: var(--mgs-ok-bg);    color: var(--mgs-ok); }
.mgs-selo--alerta{ background: var(--mgs-alerta-bg);color: var(--mgs-alerta); }
.mgs-selo--erro  { background: var(--mgs-erro-bg);  color: var(--mgs-erro); }

/* tabela — a que mais se reescreveu à mão nesta casa.
   Vem com o que sempre faltava: cabeçalho que fica, primeira coluna que fica,
   e rolagem lateral PRÓPRIA (a página nunca rola de lado). */
.mgs-tabela-caixa { overflow: auto; -webkit-overflow-scrolling: touch; }
.mgs-tabela { border-collapse: separate; border-spacing: 0; width: 100%; font-size: var(--mgs-t-sm); }
.mgs-tabela th, .mgs-tabela td {
  padding: var(--mgs-e-2) var(--mgs-e-3);
  border-bottom: 1px solid var(--mgs-linha);
  text-align: left; vertical-align: top;
}
.mgs-tabela thead th {
  position: sticky; top: 0; z-index: 20;
  background: var(--mgs-painel); color: var(--mgs-texto-2);
  font-weight: 600; font-size: var(--mgs-t-xs);
  text-transform: uppercase; letter-spacing: .04em;
}
/* a coluna-âncora: th no tbody, para a data/nome não fugir ao rolar de lado */
.mgs-tabela tbody th, .mgs-tabela thead th:first-child {
  position: sticky; left: 0; z-index: 10;
  background: var(--mgs-painel); font-weight: 500;
}
.mgs-tabela thead th:first-child { z-index: 25; }
.mgs-tabela tbody tr:hover td { background: var(--mgs-marca-fraca); }
.mgs-tabela .mgs-num { text-align: right; font-variant-numeric: tabular-nums; }

/* aviso */
.mgs-aviso {
  border-radius: var(--mgs-raio-sm);
  padding: var(--mgs-e-3) var(--mgs-e-4);
  background: var(--mgs-alerta-bg);
  border-left: 3px solid var(--mgs-alerta);
  font-size: var(--mgs-t-sm);
}
.mgs-aviso--erro { background: var(--mgs-erro-bg); border-left-color: var(--mgs-erro); }
.mgs-aviso--ok   { background: var(--mgs-ok-bg);   border-left-color: var(--mgs-ok); }

/* cabeçalho e rodapé de peça */
.mgs-cabecalho {
  display: flex; align-items: baseline; gap: var(--mgs-e-3);
  padding: var(--mgs-e-4) 0; border-bottom: 1px solid var(--mgs-linha);
  margin-bottom: var(--mgs-e-5);
}
.mgs-cabecalho .mgs-marca-nome { font-weight: 700; letter-spacing: -.01em; }
.mgs-rodape-fonte {
  margin-top: var(--mgs-e-6); padding-top: var(--mgs-e-3);
  border-top: 1px solid var(--mgs-linha);
  color: var(--mgs-tenue); font-size: var(--mgs-t-xs);
}

/* botão *//* \U0001f534 O PISO DE 44px VALE AQUI TAMBEM. A lei estava escrita para o campo e a
   celula, e o botao ficou de fora com ~39,7px (8+8 de padding + 14px x 1,55 de
   linha + 2 de borda). O unico lugar onde ele alcancava 44 era dentro de
   `.mgs-acoes` abaixo de 480px -- ou seja, num tablet de 481px ao lado do
   tronco a lei nao valia. Irmao da celula de 33px, achado pelo auditor de
   consertos em 30/08/2026. */

.mgs-botao {
  min-height: 44px;
  display: inline-flex; align-items: center; gap: var(--mgs-e-2);
  padding: var(--mgs-e-2) var(--mgs-e-4);
  border-radius: var(--mgs-raio-sm); border: 1px solid var(--mgs-marca);
  background: var(--mgs-marca); color: var(--mgs-sobre-marca);
  font: inherit; font-size: var(--mgs-t-sm); font-weight: 600;
  cursor: pointer;
}
.mgs-botao--vazio { background: transparent; color: var(--mgs-marca); }
.mgs-botao:disabled { opacity: .5; cursor: not-allowed; }

/* ---------------------------------------------------------------------------
   AS FAMÍLIAS DE BOTÃO — 9º módulo (mgs-composicao.js), 04/09/2026
   Pedido do Marcelo: «quais são as tendências hoje para criar esses botões —
   se é um botão 3D, se é só o título, se tem um demarcado de onde está o
   botão». Quem ESCOLHE é `mgs.sugereBotao()`; aqui está só o desenho.
   Cada família carrega o custo dela escrito: uma peça pode usar todas, mas
   nenhuma é gratuita.
   --------------------------------------------------------------------------- */

/* TAMANHO. Três degraus, e o menor JÁ é o piso de toque (44 px, Apple HIG e
   WCAG 2.5.5). Os sistemas de produto mais usados param em 40 px de altura
   "média" — abaixo do piso, e por isso essa medida não existe aqui. */
.mgs-botao--compacto { min-height: 44px; padding-inline: var(--mgs-e-4); }
.mgs-botao--grande {
  min-height: 56px; padding-inline: var(--mgs-e-6);
  font-size: var(--mgs-t-base);
}

/* TONAL — fundo fraco da marca. O meio-termo do Material 3: pesa mais que o
   contorno e menos que o sólido, e é o par natural de um sólido na mesma tela. */
.mgs-botao--tonal {
  background: var(--mgs-marca-fraca);
  color: var(--mgs-marca);
  border-color: transparent;
}

/* FANTASMA — só o texto. A área de toque continua inteira: o que some é a
   moldura, não o alvo. Terceiro nível de ação, nunca destrutiva. */
.mgs-botao--fantasma {
  background: transparent; border-color: transparent;
  color: var(--mgs-texto);
}
.mgs-botao--fantasma:hover { background: var(--mgs-marca-fraca); }

/* ELEVADO — o botão se separa do que passa por baixo. Sombra CURTA: sombra
   longa em botão vira brinquedo, e some na impressão. */
.mgs-botao--elevado {
  background: var(--mgs-painel);
  color: var(--mgs-texto);
  border-color: var(--mgs-linha);
  box-shadow: var(--mgs-sombra);
}
.mgs-botao--elevado:active { box-shadow: var(--mgs-sombra-sm); transform: translateY(1px); }

/* VIDRO — o glassmorphism de 2026. ⚠️ Só vale POR CIMA de imagem ou gradiente:
   sobre cor sólida não há o que desfocar e ele vira um cinza sujo. E o
   contraste do texto muda com o que passa atrás — medir na peça, não aqui. */
.mgs-botao--vidro {
  background: color-mix(in srgb, var(--mgs-painel) 55%, transparent);
  -webkit-backdrop-filter: blur(14px) saturate(1.4);
  backdrop-filter: blur(14px) saturate(1.4);
  border-color: color-mix(in srgb, var(--mgs-texto) 22%, transparent);
  color: var(--mgs-texto);
}
@supports not (backdrop-filter: blur(1px)) {
  /* sem desfoque, vidro é só um retângulo translúcido ilegível: cai para
     o painel sólido em vez de fingir que funcionou */
  .mgs-botao--vidro { background: var(--mgs-painel); }
}

/* BRUTO — neobrutalismo: borda grossa e sombra DURA, sem desfoque. Peça que
   quer ser lembrada. Em tela de operação cansa, e por isso o motor recusa. */
.mgs-botao--bruto {
  background: var(--mgs-marca);
  color: var(--mgs-sobre-marca);
  border: 2px solid var(--mgs-texto);
  border-radius: var(--mgs-raio-sm);
  box-shadow: 4px 4px 0 0 var(--mgs-texto);
}
.mgs-botao--bruto:active { box-shadow: 1px 1px 0 0 var(--mgs-texto); transform: translate(3px, 3px); }

/* RELEVO — neumorfismo. ⚠️ NUNCA para ação primária, e o motor não sugere:
   ele vive de sombra sobre fundo igual, o que derruba o contraste da borda.
   Fica para controle de ajuste em peça calma, e só em superfície clara. */
.mgs-botao--relevo {
  background: var(--mgs-painel);
  color: var(--mgs-texto);
  border-color: transparent;
  box-shadow: 6px 6px 12px color-mix(in srgb, var(--mgs-texto) 12%, transparent),
             -6px -6px 12px color-mix(in srgb, var(--mgs-painel) 92%, white);
}
.mgs-botao--relevo:active {
  box-shadow: inset 4px 4px 8px color-mix(in srgb, var(--mgs-texto) 14%, transparent),
              inset -4px -4px 8px color-mix(in srgb, var(--mgs-painel) 92%, white);
}

/* PERIGO — modificador de PAPEL, não de família: qualquer família pode ser a
   ação destrutiva, e o que muda é a cor. */
.mgs-botao--perigo {
  background: var(--mgs-erro); border-color: var(--mgs-erro);
  color: var(--mgs-sobre-marca);
}
.mgs-botao--perigo.mgs-botao--vazio,
.mgs-botao--perigo.mgs-botao--fantasma {
  background: transparent; color: var(--mgs-erro);
}

/* ---------------------------------------------------------------------------
   OS IRMÃOS DA FILEIRA
   «dois verdes com 2 linhas e um laranja com 3 — dava para alocar melhor para
   que ambos tivessem o mesmo tamanho» (Marcelo, 04/09/2026)
   --------------------------------------------------------------------------- */

/* .mgs-fileira — todos esticam até a altura do maior. Resolve o caso simples:
   os três quadradinhos passam a ter a mesma altura. */
.mgs-fileira {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: var(--mgs-e-3);
  align-items: stretch;
}
.mgs-fileira > * { display: flex; flex-direction: column; justify-content: flex-start; }

/* .mgs-fileira--trilhos — quando o alinhamento tem de valer DENTRO de cada
   bloco: título com título, corpo com corpo, rodapé com rodapé, ainda que um
   texto tenha três linhas e o vizinho tenha uma. É o subgrid, que virou
   disponível em todos os navegadores em 2026 — antes disso só dava com
   JavaScript medindo altura, ou com altura fixa (que corta o texto).
   Cada filho declara quantas faixas ocupa. */
.mgs-fileira--trilhos { grid-auto-flow: column; grid-template-rows: auto 1fr auto; }
.mgs-fileira--trilhos > * {
  display: grid;
  grid-row: span 3;
  grid-template-rows: subgrid;
  gap: 0;
}
@supports not (grid-template-rows: subgrid) {
  /* sem subgrid, o alinhamento interno não existe -- mas a altura igual sim.
     Degradar dizendo o que se perdeu é melhor que fingir que funcionou. */
  .mgs-fileira--trilhos > * { display: flex; flex-direction: column; }
}

/* ---------------------------------------------------------------------------
   O BENTO — a distribuição dos elementos na tela
   «se eu não tenho nada que está dimensionando isso, vai acontecer o que
   aconteceu com o app da Cláudia: a folha ocupando metade da tela e a outra
   metade vazia» (Marcelo, 04/09/2026)
   Blocos de tamanhos DIFERENTES de propósito: quando todos têm o mesmo peso,
   nenhum tem. A âncora ocupa ~2x a área do segundo maior.
   --------------------------------------------------------------------------- */
.mgs-bento {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--mgs-e-4);
  max-width: 1600px;
  margin-inline: auto;
}
.mgs-bento > * { min-width: 0; }            /* sem isso, um bloco largo estoura a grade */
.mgs-bento--ancora { grid-column: span 6; grid-row: span 2; }
.mgs-bento--meio   { grid-column: span 4; }
.mgs-bento--terco  { grid-column: span 3; }
.mgs-bento--cheio  { grid-column: 1 / -1; }
.mgs-bento--formulario { grid-template-columns: repeat(6, minmax(0, 1fr)); max-width: 720px; }
.mgs-bento--leitura    { grid-template-columns: 1fr; max-width: 680px; }
.mgs-bento--lista      { gap: var(--mgs-e-3); max-width: 1440px; }
@media (max-width: 1100px) {
  .mgs-bento { grid-template-columns: repeat(8, minmax(0, 1fr)); }
  .mgs-bento--ancora { grid-column: span 8; }
}
@media (max-width: 720px) {
  .mgs-bento { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .mgs-bento > * { grid-column: 1 / -1; }
  .mgs-fileira { grid-auto-flow: row; }
}

/* grade */
.mgs-grade { display: grid; gap: var(--mgs-e-4); }
@media (min-width: 700px)  { .mgs-grade--2 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .mgs-grade--3 { grid-template-columns: repeat(3, 1fr); } }

/* o que é MEDIDO e o que é ESTIMADO — a lei da casa vira estilo, para
   ninguém precisar lembrar de marcar à mão */
.mgs-estimado { border-bottom: 1px dashed var(--mgs-alerta); cursor: help; }
.mgs-medido::after { content: " ✓"; color: var(--mgs-ok); font-size: .85em; }


/* ÍCONE. Herda a cor e o tamanho do texto ao lado — ícone com vida própria vira
   uma segunda voz na frase. O alinhamento é pelo eixo do texto, não pela caixa. */
.mgs-icone-caixa { display: inline-flex; align-items: center; vertical-align: -.16em; }
.mgs-icone { display: block; }
/* \U0001f534 O buraco VISÍVEL. Antes, ícone com nome errado virava uma caixa 0×0 e
   o único aviso era um `console.error` — inútil num celular no pasto. */
.mgs-icone-faltando {
  width: 1.1em; height: 1.1em;
  border: 1px dashed var(--mgs-erro);
  border-radius: 3px;
  background: var(--mgs-erro-bg);
}
/* ícone dentro de botão ou selo ganha o respiro do texto vizinho */
.mgs-botao .mgs-icone-caixa, .mgs-selo .mgs-icone-caixa { margin-right: var(--mgs-e-2); }

/* -----------------------------------------------------------------------------
   4b. PAINEL — as peças de dashboard.
   Entraram porque esta casa já as escrevia à mão em toda proposta: a fileira de
   números no topo, o cartão de gráfico e a grade que segura os dois.
   -------------------------------------------------------------------------- */

/* a grade do painel: 12 colunas no monitor, 1 no celular, sem media query à mão */
.mgs-painel {
  display: grid;
  /* 200px e não 260: com 260 a fileira de quatro números quebrava 3 + 1, e o
     quarto sozinho embaixo vira uma segunda leitura. Quatro KPI são UMA linha. */
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--mgs-e-4);
  align-items: start;
}
.mgs-painel > .larga  { grid-column: span 2; }
.mgs-painel > .inteira{ grid-column: 1 / -1; }
@media (max-width: 640px) {
  .mgs-painel > .larga, .mgs-painel > .inteira { grid-column: auto; }
}

/* O NÚMERO. ⚠️ Nem todo dado quer virar gráfico: um número só se lê melhor
   grande do que desenhado. Quando há UM valor, esta é a forma certa. */
.mgs-kpi {
  background: var(--mgs-painel);
  border: 1px solid var(--mgs-linha);
  border-radius: var(--mgs-raio);
  padding: var(--mgs-e-4) var(--mgs-e-5);
  box-shadow: var(--mgs-sombra-sm);
}
.mgs-kpi-rotulo {
  font-size: var(--mgs-t-xs); color: var(--mgs-texto-2);
  text-transform: uppercase; letter-spacing: .06em; margin: 0 0 var(--mgs-e-2);
}
.mgs-kpi-valor {
  font-size: var(--mgs-t-3xl); font-weight: 650; line-height: 1;
  color: var(--mgs-texto); font-variant-numeric: tabular-nums;
}
.mgs-kpi-unidade { font-size: var(--mgs-t-lg); color: var(--mgs-texto-2); font-weight: 500; }
.mgs-kpi-nota { margin: var(--mgs-e-2) 0 0; font-size: var(--mgs-t-sm); color: var(--mgs-texto-2); }

/* a variação. 🔴 A SETA NUNCA VAI SOZINHA: verde e vermelho já significam
   estado nesta casa, então a direção vem no símbolo E na palavra. */
.mgs-delta { display: inline-flex; align-items: center; gap: var(--mgs-e-1);
  font-size: var(--mgs-t-sm); font-weight: 600; font-variant-numeric: tabular-nums; }
/* 🔴 A VARIACAO DO KPI SAIA DA IDENTIDADE -- achado do Marcelo em 06/09/2026:
   *"os big numbers la em cima estao com o vermelho mostrando que o resultado
    esta pior... DEDUZI que e pior. E ele sai da identidade. Tem outras cores
    que dao para usar ali que remetem mais o amarelo."*

   Duas coisas na mesma frase, e as duas certas: a cor nao comunicava (ele
   DEDUZIU pelo texto, nao pela cor) e ainda destoava do resto da tela.

   🔑 Quem comunica direcao aqui e a SETA e a PALAVRA -- "acima", "abaixo",
   com o triangulo antes. A cor so reforca, e reforco nao precisa gritar nem
   vir de outra familia. Por isso ela passa por tokens PROPRIOS do delta: cada
   marca pode dar os seus, e quem nao der continua no ok/erro de sempre. */
.mgs-delta.subiu  { color: var(--mgs-delta-bom, var(--mgs-ok)); }
.mgs-delta.caiu   { color: var(--mgs-delta-ruim, var(--mgs-erro)); }
.mgs-delta.parado { color: var(--mgs-texto-2); }
.mgs-delta.subiu::before  { content: "\2191"; }
.mgs-delta.caiu::before   { content: "\2193"; }
.mgs-delta.parado::before { content: "\2192"; }

/* o cartão de gráfico: título, a tela, e a linha de fonte embaixo */
.mgs-viz {
  background: var(--mgs-painel);
  border: 1px solid var(--mgs-linha);
  border-radius: var(--mgs-raio);
  padding: var(--mgs-e-4) var(--mgs-e-5) var(--mgs-e-3);
  box-shadow: var(--mgs-sombra-sm);
}
.mgs-viz-cabeca { display: flex; justify-content: space-between; align-items: baseline;
  gap: var(--mgs-e-3); margin-bottom: var(--mgs-e-3); flex-wrap: wrap; }
.mgs-viz-titulo { font-size: var(--mgs-t-lg); font-weight: 600; margin: 0; }
.mgs-viz-sub    { font-size: var(--mgs-t-sm); color: var(--mgs-texto-2); margin: 0; }
.mgs-viz-tela   { width: 100%; min-height: 240px; }
.mgs-viz-fonte  { margin: var(--mgs-e-3) 0 0; font-size: var(--mgs-t-xs); color: var(--mgs-tenue); }

/* a legenda — identidade NUNCA é só a cor: vem sempre com o nome ao lado */
.mgs-legenda { display: flex; flex-wrap: wrap; gap: var(--mgs-e-2) var(--mgs-e-4);
  margin: 0 0 var(--mgs-e-3); padding: 0; list-style: none;
  font-size: var(--mgs-t-sm); color: var(--mgs-texto-2); }
.mgs-legenda li { display: inline-flex; align-items: center; gap: var(--mgs-e-2); }
.mgs-legenda i { width: 10px; height: 10px; border-radius: 3px; background: currentColor; flex: none; }

/* a tabela por trás do gráfico. 🔑 NÃO É ENFEITE: é o que sustenta a regra de
   alívio quando a cor sozinha não alcança o contraste, e é o que se copia. */
.mgs-viz-dados { margin-top: var(--mgs-e-3); }
.mgs-viz-dados summary { cursor: pointer; font-size: var(--mgs-t-sm); color: var(--mgs-texto-2); }
.mgs-viz-dados[open] summary { margin-bottom: var(--mgs-e-2); }

/* rolagem só dentro da peça larga — a página nunca rola de lado */
.mgs-rola-x { overflow-x: auto; }


/* -----------------------------------------------------------------------------
   4c. A GRADE — a pele do Tabulator e do Jspreadsheet.
   ⚠️ CORREÇÃO DE 30/08/2026 — a frase que estava aqui era FALSA, e a
      auditoria a pegou contradizendo o cabeçalho deste mesmo arquivo.
      O que continua verdade: o CSS deles não vem por CDN. É por isso que
      existe o `vendor/tabulator.min.css` dentro do pacote.
      O que era falso: ele É CARREGADO. O montador o injeta ANTES deste
      arquivo, porque a folha deles é ESTRUTURAL — posiciona linha e célula,
      e sem ela a tabela empilha as colunas uma embaixo da outra (medido).
      O que sai dos nossos tokens é a APARÊNCIA, escrita abaixo, que vence
      na cascata por vir depois.
   -------------------------------------------------------------------------- */

/* --- para LER: Tabulator ---------------------------------------------------- */
.tabulator {
  background: var(--mgs-painel);
  border: 1px solid var(--mgs-linha);
  border-radius: var(--mgs-raio);
  font-family: var(--mgs-fonte);
  font-size: var(--mgs-t-sm);
  color: var(--mgs-texto);
  overflow: hidden;
}
.tabulator .tabulator-header {
  background: var(--mgs-painel-2);
  border-bottom: 1px solid var(--mgs-linha);
  color: var(--mgs-texto-2);
  font-weight: 600;
}
.tabulator .tabulator-header .tabulator-col {
  background: transparent;
  border-right: 1px solid var(--mgs-linha-suave);
}
.tabulator .tabulator-header .tabulator-col-content { padding: var(--mgs-e-3) var(--mgs-e-3); }
.tabulator .tabulator-header .tabulator-col-title {
  font-size: var(--mgs-t-xs); text-transform: uppercase; letter-spacing: .05em;
}
/* a seta de ordenação herda a cor do texto, nunca a da marca: ela é controle,
   não identidade */
.tabulator .tabulator-col-sorter .tabulator-arrow { border-bottom-color: var(--mgs-tenue); }
.tabulator .tabulator-col[aria-sort="ascending"] .tabulator-arrow,
.tabulator .tabulator-col[aria-sort="descending"] .tabulator-arrow { border-bottom-color: var(--mgs-marca); }

.tabulator .tabulator-row { background: var(--mgs-painel); border-bottom: 1px solid var(--mgs-linha-suave); }
.tabulator .tabulator-row.tabulator-row-even { background: var(--mgs-painel-2); }
.tabulator .tabulator-row:hover { background: var(--mgs-marca-fraca); }
.tabulator .tabulator-row .tabulator-cell {
  padding: var(--mgs-e-3);
  border-right: 1px solid var(--mgs-linha-suave);
  color: var(--mgs-texto);
}
/* número alinhado à direita e com dígito de largura fixa — coluna de número que
   dança não se compara de relance, que é a única coisa que ela serve para fazer */
.tabulator .tabulator-cell.mgs-num { font-variant-numeric: tabular-nums; }
/* a celula RICA: a que a peca montou com mais de uma linha dentro. Sem estas
   duas regras o Tabulator a mantem numa linha so e corta o fim da frase --
   e o `variableHeight` da coluna nunca chega a valer. */
.tabulator .tabulator-cell.mgs-celula-rica {
  white-space: normal;
  overflow-wrap: anywhere;
  line-height: 1.3;
}
.tabulator .tabulator-placeholder { color: var(--mgs-tenue); font-size: var(--mgs-t-sm); }
.tabulator .tabulator-footer { background: var(--mgs-painel-2); border-top: 1px solid var(--mgs-linha); color: var(--mgs-texto-2); }

.mgs-busca {
  font: inherit; font-size: var(--mgs-t-sm);
  /* 🔴 A LEI DOS 44px NAO ALCANCAVA A CAIXA DE BUSCA. Terceira vez que o
     mesmo piso e escrito num lugar e esquecido em outro: primeiro a celula da
     planilha (33px), depois o botao (39,7px), agora a busca (40px). Medida
     na tela pela `prova-do-olho.js`, que existe justamente porque a prova
     por regex so via os tres lugares onde a regra ESTAVA escrita. */
  min-height: 44px;
  padding: var(--mgs-e-2) var(--mgs-e-3);
  margin-bottom: var(--mgs-e-3);
  width: 100%; max-width: 320px;
  border: 1px solid var(--mgs-linha); border-radius: var(--mgs-raio-sm);
  background: var(--mgs-painel-2); color: var(--mgs-texto);
}
.mgs-busca::placeholder { color: var(--mgs-tenue); }
.mgs-busca:focus-visible { outline: 2px solid var(--mgs-marca); outline-offset: 1px; }
/* A busca QUE VIVE NO TITULO -- pedido do Marcelo, 06/09/2026: *"quando clicar
   no titulo pode digitar o que quer buscar ali e ja aparece"*.
   Ela herda a caixa do titulo para o gesto nao mover a tela: mesma altura,
   mesma letra, sem moldura -- so o sublinhado da marca diz que agora e campo. */
/* A LUPA ao lado do titulo -- pedido do Marcelo, 06/09/2026: *"so coloca uma
   lupinha ai do lado para a pessoa saber que se clicar da para procurar"*.
   Ela e a unica coisa na tela que diz que o titulo e clicavel: o cursor de
   texto so aparece depois de o mouse chegar, e no celular nunca aparece. */
/* ═══════════════════════════════════════════════════════════════════════════
   A CAIXA DO FILTRO DE COLUNA — fina, e não uma segunda linha de células.

   🔴 Ela nasceu com o estilo padrão do Tabulator: borda de 2px, canto de 8px e
   altura de célula. O Marcelo viu na hora: *"os campos de filtro, pode deixar
   eles mais finos... ficaram grosseiros"*.

   🔑 O motivo é hierárquico, não de gosto. O cabeçalho de uma tabela é
   REFERÊNCIA — ele diz o que cada coluna é. Uma caixa com a mesma presença de
   uma célula acrescenta uma segunda linha de conteúdo ali, e o olho passa a ler
   duas coisas onde deveria ler um rótulo. O filtro tem de estar disponível sem
   disputar: linha de 1px, canto curto, fundo um degrau abaixo do cabeçalho.

   ⚠️ Discreto NÃO é apagado: o texto digitado usa a cor de texto cheia e o
   placeholder o tênue, que já passou pelo piso de contraste. Filtro que não se
   lê depois de preenchido esconde por que a lista está curta.
   ═══════════════════════════════════════════════════════════════════════════ */
.tabulator .tabulator-header-filter input {
  width: 100%;
  min-height: 28px;
  padding: 3px 8px;
  background: var(--mgs-fundo);
  border: 1px solid var(--mgs-linha);
  border-radius: 5px;
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 400;
  color: var(--mgs-texto);
}
.tabulator .tabulator-header-filter input::placeholder {
  color: var(--mgs-tenue);
  font-size: 12px;
}
.tabulator .tabulator-header-filter input:focus {
  outline: none;
  border-color: var(--mgs-marca);
}
/* o filtro não empurra o cabeçalho: ele mora colado embaixo do rótulo */
.tabulator .tabulator-header-filter { padding-top: 2px; }

.mgs-lupa {
  display: inline-flex; vertical-align: -1px;
  width: 15px; height: 15px; margin-left: 7px;
  opacity: .55; color: var(--mgs-marca);
}
.mgs-lupa svg { width: 100%; height: 100%; }
.mgs-viz-titulo[role="button"]:hover .mgs-lupa { opacity: 1; }

.mgs-busca--titulo {
  width: 100%; margin: 0;
  background: transparent;
  /* 1px, e nao 2: *"o sublinhado quando clicamos na lupa ficou grosseiro"*.
     A linha aqui so precisa dizer "isto virou campo" -- ela nao compete com
     o texto do titulo, que ja e o elemento forte. */
  border: 0; border-bottom: 1px solid var(--mgs-marca);
  border-radius: 0; padding: 0 0 2px;
  font: inherit;
  font-size: var(--mgs-t-3, 1.05rem);
  font-weight: 640;
  color: var(--mgs-texto);
}
/* O titulo clicavel: o cursor avisa que ali se digita, antes do clique. */
.mgs-viz-titulo[role="button"] { cursor: text; }
.mgs-viz-titulo[role="button"]:hover { color: var(--mgs-marca); }

/* --- para ESCREVER: Jspreadsheet -------------------------------------------- */
/* a v4 usa .jexcel e a v5 usa .jss_worksheet. As duas ficam aqui: trocar de
   versão não pode apagar a aparência sem ninguém ver. */
.mgs-planilha .jexcel, .mgs-planilha .jss_worksheet {
  font-family: var(--mgs-fonte);
  font-size: var(--mgs-t-sm);
  color: var(--mgs-texto);
  border-collapse: collapse;
}
.mgs-planilha .jexcel > thead > tr > td,
.mgs-planilha .jss_worksheet > thead > tr > td {
  background: var(--mgs-painel-2);
  color: var(--mgs-texto-2);
  border: 1px solid var(--mgs-linha);
  font-size: var(--mgs-t-xs); text-transform: uppercase; letter-spacing: .05em;
  font-weight: 600; padding: var(--mgs-e-2) var(--mgs-e-3);
}
.mgs-planilha .jexcel > tbody > tr > td,
.mgs-planilha .jss_worksheet > tbody > tr > td {
  background: var(--mgs-painel);
  border: 1px solid var(--mgs-linha-suave);
  color: var(--mgs-texto);
  padding: var(--mgs-e-2) var(--mgs-e-3);
  /* \U0001f534 A LEI DOS 44px NÃO ALCANÇAVA A PEÇA EM QUE ELA DIGITA. A lei estava
     escrita para `.mgs-campo` — e o `mgs-grade.js` diz, no próprio arquivo, que
     a peça dela NÃO é o formulário, é a planilha. Medido no Chromium a 390×844:
     as células tinham de 33px a 71px. 33 contra os 44 da lei.
     Consequência: erro de toque com a mão suja — e o dado entra na linha da
     égua ERRADA, sem nada acusar. Achado pela auditoria de 30/08/2026. */
  height: 44px;
  min-height: 44px;
}
/* a coluna do canto (o número da linha) é referência, não dado */
.mgs-planilha .jexcel > tbody > tr > td:first-child,
.mgs-planilha .jss_worksheet > tbody > tr > td:first-child {
  background: var(--mgs-painel-2); color: var(--mgs-tenue);
  font-size: var(--mgs-t-xs); text-align: center;
}
/* 🔑 A CÉLULA ATIVA TEM DE GRITAR. Quem digita entre uma égua saindo e a
   próxima entrando não pode perder um segundo procurando onde está o cursor. */
.mgs-planilha .jexcel > tbody > tr > td.highlight,
.mgs-planilha .jss_worksheet > tbody > tr > td.highlight {
  background: var(--mgs-marca-fraca) !important;
}
.mgs-planilha .jexcel_container .jexcel_corner,
.mgs-planilha .jss_worksheet .jss_corner { background: var(--mgs-marca); border-color: var(--mgs-marca); }
.mgs-planilha td.jexcel_cursor, .mgs-planilha td.jss_cursor,
.mgs-planilha .jexcel > tbody > tr > td.selected,
.mgs-planilha .jss_worksheet > tbody > tr > td.selected {
  outline: 2px solid var(--mgs-marca); outline-offset: -2px;
}
.mgs-planilha input, .mgs-planilha textarea {
  font: inherit; color: var(--mgs-texto); background: var(--mgs-painel);
}
/* 🔴 A caixa de colar. Ela é um textarea invisível que o Jspreadsheet usa para
   copiar e colar, e o CSS DELES que a tira da tela — que nós não carregamos.
   Sem esta regra ela aparece como um quadrado solto embaixo da folha. */
.mgs-planilha .jss_textarea, .mgs-planilha .jexcel_textarea {
  position: absolute; left: -9999px; top: -9999px;
  width: 1px; height: 1px; opacity: 0; border: 0; padding: 0;
}

/* o rodapé "jspreadsheet" e a barra de fórmula que não usamos */
.mgs-planilha .jexcel_about, .mgs-planilha .jss_about,
.mgs-planilha .jexcel_toolbar { display: none; }


/* -----------------------------------------------------------------------------
   4d. ENTRADA — as peças de RECEBER.
   O motor sabia exibir e não sabia receber. Entraram por causa da tela da
   Cláudia, e o que manda aqui é uma frase dela:

     "enquanto uma égua tá saindo a outra já tá entrando, por isso que eu vou
      abreviando."

   🔴 DUAS LEIS QUE SAEM DISSO, e valem para toda peça de entrada da casa:
      1. ALVO DE 44px. Ela digita no celular, de pé, ao lado do tronco, e erra o
         toque se o campo tiver a altura de um botão de formulário de site.
      2. O FOCO TEM DE GRITAR. Quem tem segundos não pode gastar um procurando
         onde está o cursor.
   -------------------------------------------------------------------------- */

.mgs-campo-grupo { display: flex; flex-direction: column; gap: var(--mgs-e-2);
  margin-bottom: var(--mgs-e-4); }

.mgs-rotulo {
  font-size: var(--mgs-t-sm); font-weight: 600; color: var(--mgs-texto);
  display: flex; align-items: center; gap: var(--mgs-e-2);
}
/* obrigatório se diz por escrito, nunca só por um asterisco vermelho: cor
   sozinha não carrega significado — a mesma lei da série e do ícone */
.mgs-rotulo .obrigatorio { font-weight: 400; font-size: var(--mgs-t-xs);
  color: var(--mgs-texto-2); }

.mgs-campo, .mgs-selecao, .mgs-area {
  font: inherit;
  font-size: var(--mgs-t-base);      /* 16px: abaixo disso o iPhone dá zoom ao focar */
  font-family: var(--mgs-fonte);
  color: var(--mgs-texto);
  background: var(--mgs-painel);
  border: 1px solid var(--mgs-linha);
  border-radius: var(--mgs-raio-sm);
  padding: var(--mgs-e-3);
  min-height: 44px;                  /* a lei 1 */
  width: 100%;
}
.mgs-area { min-height: 92px; resize: vertical; }
.mgs-campo::placeholder, .mgs-area::placeholder { color: var(--mgs-tenue); }

/* 🔑 o campo de NÚMERO herda a fonte de dígito, e alinha à direita: número que
   dança não se confere de relance */
.mgs-campo[type="number"], .mgs-campo.mgs-num {
  font-family: var(--mgs-fonte-mono); font-variant-numeric: tabular-nums;
  text-align: right;
}
/* e a célula que ela preenche é TEXTO por padrão, de propósito: a folha dela
   mistura número, sigla e símbolo na mesma linha ("OE: 3,5 +ed") */

.mgs-campo:focus-visible, .mgs-selecao:focus-visible, .mgs-area:focus-visible {
  outline: 2px solid var(--mgs-marca);   /* a lei 2 */
  outline-offset: 1px;
  border-color: var(--mgs-marca);
}
.mgs-campo:disabled, .mgs-selecao:disabled, .mgs-area:disabled {
  background: var(--mgs-painel-2); color: var(--mgs-tenue); cursor: not-allowed;
}

/* a seta do <select> desenhada com o token, para não depender do tema do sistema */
.mgs-selecao {
  appearance: none;
  padding-right: var(--mgs-e-6);
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 18px) calc(50% + 2px), calc(100% - 13px) calc(50% + 2px);
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}

/* a dica embaixo do campo, e o erro. ⚠️ O ERRO DIZ O QUE FAZER, nunca só que
   está errado — "inválido" não ensina ninguém a consertar. */
.mgs-dica  { font-size: var(--mgs-t-xs); color: var(--mgs-texto-2); margin: 0; }
.mgs-erro-campo { font-size: var(--mgs-t-xs); color: var(--mgs-erro); margin: 0;
  display: flex; align-items: flex-start; gap: var(--mgs-e-2); }
.mgs-campo-grupo.tem-erro .mgs-campo,
.mgs-campo-grupo.tem-erro .mgs-selecao { border-color: var(--mgs-erro); }

/* a linha de botões do rodapé de um formulário */
.mgs-acoes { display: flex; gap: var(--mgs-e-3); flex-wrap: wrap;
  margin-top: var(--mgs-e-5); }
@media (max-width: 480px) {
  /* no celular o botão ocupa a linha: alvo grande vale mais que economia de espaço */
  .mgs-acoes { flex-direction: column; }
  .mgs-acoes .mgs-botao { width: 100%; min-height: 48px; }
}

/* 🔴 O ESTADO DA CÉLULA — e este é o componente que a tela dela mais usa.
   Enquanto ela digita, a barra embaixo mostra O QUE O MOTOR ENTENDEU daquela
   célula. Três estados, e o terceiro é o que importa: "não entendi" tem de
   aparecer, senão o motor engole a célula em silêncio. */
.mgs-eco {
  display: flex; align-items: center; gap: var(--mgs-e-2);
  font-size: var(--mgs-t-sm); padding: var(--mgs-e-2) var(--mgs-e-3);
  border-radius: var(--mgs-raio-sm); border: 1px solid transparent;
  min-height: 36px;
}
.mgs-eco--entendi   { background: var(--mgs-ok-bg);     color: var(--mgs-ok);
                      border-color: var(--mgs-ok); }
.mgs-eco--duvida    { background: var(--mgs-alerta-bg); color: var(--mgs-alerta);
                      border-color: var(--mgs-alerta); }
.mgs-eco--nao-entendi { background: var(--mgs-erro-bg); color: var(--mgs-erro);
                      border-color: var(--mgs-erro); }
.mgs-eco b { font-family: var(--mgs-fonte-mono); font-weight: 500; }


/* -----------------------------------------------------------------------------
   4e. NEON — a camada de brilho.
   Pedida pelo Marcelo em 30/08/2026: "acho que são cores que podem chamar a
   atenção pela beleza — mas deixa no repertório para não precisarmos lembrar
   depois."

   🔴 AS TRÊS LEIS, e sem elas o neon só estraga a peça:
      1. SÓ EM SUPERFÍCIE ESCURA. Em fundo claro ele some ou vibra — por isso o
         `--mgs-brilho` só existe nas paletas escuras, e o motor não o inventa.
      2. NEON É REALCE, NÃO TEXTO. Ele pinta a marca, o número do KPI e a borda
         em foco. Nunca o parágrafo: cor viva passa no contraste e ainda VIBRA
         em corpo de 14px. O motor mede o croma do texto e barra quem tenta.
      3. UM SOZINHO. Dois neons na mesma peça e nenhum chama atenção. Os
         estados continuam sendo verde/âmbar/vermelho de sempre.

   ⚠️ É O ÚNICO EFEITO DO MOTOR INTEIRO, e está aqui de propósito: sombra
      pesada, canto muito arredondado e degradê em botão são a linguagem de 2014
      e datam a peça. O halo do neon não é decoração: é o que faz a cor parecer
      emitir luz em vez de ser pintada.
   -------------------------------------------------------------------------- */

/* sem paleta neon, o token não existe e o brilho vira nada — nunca um halo
   cinza acidental */
.mgs-brilho { box-shadow: var(--mgs-brilho, none); }

/* o número que emite luz: o KPI de uma peça de impacto */
.mgs-neon {
  color: var(--mgs-marca);
  text-shadow: var(--mgs-brilho, none);
}

/* a borda que acende. Em peça sem neon ela continua sendo só uma borda. */
.mgs-cartao--neon {
  border-color: var(--mgs-marca);
  box-shadow: var(--mgs-brilho, var(--mgs-sombra-sm));
}

/* o botão de impacto — UM por tela, e ele é a ação principal */
.mgs-botao--neon {
  background: var(--mgs-marca);
  color: var(--mgs-sobre-marca);
  border-color: var(--mgs-marca);
  box-shadow: var(--mgs-brilho, none);
}

/* quem pediu menos movimento também recebe menos brilho: halo forte cansa, e
   em tela pequena ao sol ele só atrapalha */
@media (prefers-reduced-motion: reduce) {
  .mgs-brilho, .mgs-neon, .mgs-cartao--neon, .mgs-botao--neon {
    box-shadow: none; text-shadow: none;
  }
}

/* -----------------------------------------------------------------------------
   5. IMPRESSÃO — toda peça desta casa vira PDF em algum momento.
   O 72% de aproveitamento de página se ganha ou se perde aqui.
   -------------------------------------------------------------------------- */
@media print {
  /* ⚠️ As duas únicas cores literais permitidas no motor inteiro, e a prova
     conhece a exceção: no papel a marca SAI. Fundo escuro da Ramura ou da MGS
     em PDF queima tinta e não se lê. Qualquer outro hex aqui reprova. */
  .mgs { background: #fff; color: #000; }
  .mgs-cartao, .mgs-aviso, .mgs-tabela tbody tr { break-inside: avoid; }
  .mgs-tabela thead { display: table-header-group; }
  .mgs-nao-imprime { display: none !important; }
}

/* quem pediu menos movimento, recebe menos movimento */
@media (prefers-reduced-motion: reduce) {
  .mgs *, .mgs *::before, .mgs *::after {
    animation-duration: .01ms !important; transition-duration: .01ms !important;
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   O PAINEL MONTADO  ·  as peças do `mgs-painel.js`  ·  05/09/2026
   ---------------------------------------------------------------------------
   Pedido do Marcelo com oito referências: *"bem distribuído, cores impactantes
   de acordo com a paleta que ele sugeriu"*.

   🔑 NENHUMA COR LITERAL AQUI. Tudo sai de token, então o mesmo painel muda de
   cara inteiro quando `mgs.aplica()` decide outra paleta — que é exatamente o
   "muda de acordo com o dado do cliente" que ele pediu. Cor escrita à mão nesta
   folha seria a peça deixando de obedecer ao motor.
   ═══════════════════════════════════════════════════════════════════════════ */

.mgs-painel-raiz { display: grid; gap: var(--mgs-e-5); }

.mgs-painel-cabeca {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: var(--mgs-e-4); flex-wrap: wrap;
}
.mgs-painel-titulo {
  margin: 0; font-family: var(--mgs-fonte-titulo, var(--mgs-fonte));
  font-size: var(--mgs-t-2xl); font-weight: 680; letter-spacing: -.01em;
}
.mgs-painel-pergunta {
  margin: var(--mgs-e-1) 0 0; font-size: var(--mgs-t-sm); color: var(--mgs-texto-2);
}
/* ⚠️ O CARIMBO. As oito referências trazem "data as of..." — painel sem ele
   pode estar mostrando ontem, e ninguém descobre olhando. */
.mgs-painel-carimbo {
  margin: 0; font-size: var(--mgs-t-xs); color: var(--mgs-tenue);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}

/* A FAIXA DE KPIs — a primeira dobra de todas as referências.
   `auto-fit` com piso de 190px: em telefone vira uma coluna sem media query, e
   nenhum cartão fica menor que o número que ele carrega. */
.mgs-painel-kpis {
  display: grid; gap: var(--mgs-e-4);
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
}

/* ═════ ⬛ O BLOCO SEM DADO ═════
   Ele OCUPA o lugar e explica. É o defeito de todo modelo pronto: bloco sem
   dado que some faz quem olha achar que viu o painel inteiro.

   🔑 Tracejado e sem preenchimento de propósito — ele tem de se ler como
   "espaço reservado", nunca como um cartão que por acaso está vazio. */
.mgs-lacuna {
  display: grid; gap: var(--mgs-e-2); align-content: center;
  min-height: 160px; padding: var(--mgs-e-4) var(--mgs-e-5);
  border: 1px dashed var(--mgs-linha); border-radius: var(--mgs-raio);
  background: transparent;
}
.mgs-lacuna-titulo { margin: 0; font-size: var(--mgs-t-sm); font-weight: 600; color: var(--mgs-texto-2); }
.mgs-lacuna-diz { margin: 0; font-size: var(--mgs-t-lg); font-weight: 600; color: var(--mgs-tenue); }
.mgs-lacuna-porque { margin: 0; font-size: var(--mgs-t-sm); color: var(--mgs-texto-2); line-height: 1.45; }
.mgs-lacuna-falta {
  margin: 0; font-size: var(--mgs-t-xs); color: var(--mgs-tenue);
  font-family: var(--mgs-fonte-mono, monospace);
}

/* O rodapé que conta as lacunas — na MESMA tela dos números bonitos. */
.mgs-painel-lacunas {
  padding: var(--mgs-e-4) var(--mgs-e-5); border-radius: var(--mgs-raio);
  border: 1px solid var(--mgs-linha); background: var(--mgs-painel-2, var(--mgs-painel));
  font-size: var(--mgs-t-sm); color: var(--mgs-texto-2);
}
.mgs-painel-lacunas b { color: var(--mgs-texto); }
.mgs-painel-lacunas ul { margin: var(--mgs-e-2) 0 0; padding-left: var(--mgs-e-5); display: grid; gap: var(--mgs-e-1); }
.mgs-painel-lacunas em { font-style: normal; color: var(--mgs-tenue); }

/* A âncora é mais alta que os outros: é ela que responde a primeira pergunta.
   Sem altura própria, o gráfico da âncora fica do tamanho de um terço e a
   hierarquia que o `sugereLayout` decidiu não aparece na tela. */
.mgs-bento--ancora .mgs-viz-tela { min-height: 320px; }
.mgs-bento--terco .mgs-viz-tela,
.mgs-bento--meio .mgs-viz-tela { min-height: 220px; }

/* ══════════════════════════════════════════════════════════════════════
   🔴 DOIS DEFEITOS DO MOTOR, medidos na tela do Pátio em 05/09/2026
   ══════════════════════════════════════════════════════════════════════

   1 · A TIPOGRAFIA DO TEMA ATROPELAVA AS CLASSES DE COMPONENTE

   `.mgs h2` tem especificidade (0,1,1) e `.mgs-viz-titulo` tem (0,1,0). Numa
   página com `<body class="mgs">` — que é como o motor manda usar — o título de
   um cartão de gráfico saía com `--mgs-t-2xl` (28px), tamanho de título de
   página, dentro de um cartão de 220px de altura.

   ⚠️ Nada acusava: CSS que perde uma disputa não dá erro, só fica feio. As
   cinco réguas de composição passaram limpas — elas medem vazio, ritmo, irmãos
   e rótulos, não hierarquia de tamanho. Quem pegou foi o olho.

   🔑 A cura é `:where()`: ele zera a especificidade do que está dentro, então
   `:where(.mgs) h2` vale (0,0,1) — uma regra de elemento, que QUALQUER classe
   vence. É assim que uma base de tipografia deve ser escrita: ela dá o ponto de
   partida e sai da frente de quem tem nome.

   2 · `margin-inline: auto` DESLIGA O STRETCH DO GRID

   `.mgs-bento` tem `margin-inline: auto` para centralizar quando a página é
   mais larga que 1600px. Mas dentro de um container `display:grid`, um item com
   margem `auto` **deixa de esticar** e encolhe para o tamanho do conteúdo: a
   grade do painel ficou com 1158px enquanto a faixa de KPIs, irmã dela, tinha
   1232px. Foi a régua `mgs.medeRitmo` do próprio motor que acusou o
   desalinhamento — ela existe exatamente para isso.
   ══════════════════════════════════════════════════════════════════════ */
.mgs-painel-raiz > * { width: 100%; margin-inline: 0; }

/* ⚠️ O CARTÃO DE GRÁFICO ESTICA A TELA DE DESENHO ATÉ O FIM.
   Medido em 05/09: a âncora ocupa duas linhas da grade (`grid-row: span 2`),
   mas a tela do gráfico tinha `min-height` e parava ali — sobrava um terço do
   cartão em branco embaixo do desenho, e o `mgs.medeOcupacao` não pega isso
   (ele mede a PÁGINA, não o miolo de um bloco). Cartão que cresce sem o desenho
   crescer junto é vazio com moldura. */
.mgs-viz { display: flex; flex-direction: column; }
.mgs-viz-tela { flex: 1 1 auto; }

/* ═════ OS PESOS DO PAINEL — divisores de 12, e nada atravessa linha ═════
   🔴 Achado do Marcelo em 05/09: *"a primeira coluna tem três gráficos, e pra
   baixo vai ficando desalinhada com a do meio com dois, depois com dois menores
   ainda."* A âncora antiga ocupava 6 colunas E DUAS LINHAS, e as linhas
   seguintes começavam cada uma num lugar. Estas classes não têm `grid-row`:
   cada linha fecha 12 e a próxima começa alinhada. */
.mgs-p12 { grid-column: 1 / -1; }
.mgs-p8  { grid-column: span 8; }
.mgs-p6  { grid-column: span 6; }
.mgs-p4  { grid-column: span 4; }
.mgs-p3  { grid-column: span 3; }

/* ⚠️ Em tela média a grade do motor vira 8 colunas, e em telefone, 4. Os pesos
   colapsam junto — senão um `span 8` numa grade de 4 estoura para fora. */
@media (max-width: 1100px) {
  .mgs-p8 { grid-column: 1 / -1; }
  .mgs-p6, .mgs-p4, .mgs-p3 { grid-column: span 4; }
}
@media (max-width: 720px) {
  .mgs-p8, .mgs-p6, .mgs-p4, .mgs-p3 { grid-column: 1 / -1; }
}

/* A âncora é mais alta: ela responde a primeira pergunta. */
.mgs-p8 .mgs-viz-tela  { min-height: 300px; }
.mgs-p12 .mgs-viz-tela { min-height: 260px; }

/* ═════ O "R$" QUE FICAVA SOZINHO NUMA LINHA ═════
   🔴 *"O real está separado de um número, aí está parecendo que o quadrado tem
   o dobro do tamanho."* Medido: "R$ 132.130" a 36px em 184px de largura dava
   72px de altura — duas linhas, com o "R$" sozinho na primeira. O cartão
   dobrava de altura e a faixa de KPIs perdia o alinhamento.

   🔑 Duas travas juntas, porque uma só não resolve: `nowrap` impede a quebra,
   e o tamanho fluido impede que o número vaze do cartão quando ele é grande.
   Só `nowrap` empurraria "R$ 5.621.917" para fora da borda. */
.mgs-kpi-valor {
  white-space: nowrap;
  font-size: clamp(22px, 2.6vw, var(--mgs-t-3xl));
}
.mgs-kpi-nota { text-wrap: pretty; }

/* 🔴 CÉLULA QUE CORTA O TEXTO — achado pela `prova-do-olho.js` em 05/09:
   *"o texto é 252px numa caixa de 219px e a caixa corta — rótulo pela metade
   parece dado, e não é."*

   O Tabulator corta por padrão (`text-overflow: ellipsis` sem as reticências em
   alguns temas). Numa tabela de pátio isso vira "Compressor de ar Kaeser
   Airtower 3" — e quem lê acha que o modelo termina ali.

   🔑 Quebrar linha é melhor que cortar: a linha fica mais alta e o dado fica
   inteiro. Tabela de operação não é planilha de imprimir; ela é para ler. */
.tabulator .tabulator-cell {
  white-space: normal;
  overflow-wrap: anywhere;
  height: auto !important;
}
.tabulator .tabulator-row { height: auto !important; }

/* 🔴 O DETAILS DE UM CARTÃO ESTICAVA OS VIZINHOS — medido em 05/09/2026:
   *"quando eu fecho os números, ele dobra o tamanho do gráfico. Todos estão
   fazendo a mesma coisa, ele vai esticando a caixa do gráfico."*

   Medi: abrir o "ver os números" do primeiro cartão levava ele de 443 para 716px
   — e o cartão AO LADO ia junto, de 443 para 716, com 273px de vazio embaixo do
   desenho. A causa é o padrão do CSS Grid: `align-items: stretch` faz todos os
   itens de uma linha terem a altura do mais alto.

   🔑 `align-items: start` no painel: cada cartão tem a própria altura, e abrir
   a tabela de um não mexe em ninguém. É o comportamento que se espera de um
   painel — e o `stretch` só parecia certo enquanto nada crescia. */
.mgs-painel-raiz .mgs-bento { align-items: start; }

/* ⚠️ E a tela do gráfico deixa de ser elástica. Com `flex: 1 1 auto` ela
   acompanhava a altura do cartão, então qualquer coisa que crescesse embaixo
   deformava o desenho. Altura vem do peso do bloco, e nada mais a muda. */
.mgs-painel-raiz .mgs-viz-tela { flex: 0 0 auto; }
