:root {
    /* =================================================================
       PALETA OFICIAL NEXUS — transcrita do brand_manifest.json do pacote
       da marca, nao escolhida aqui.

       Declarada com os nomes do pacote para que qualquer cor nova do
       produto SAIA daqui, em vez de alguem amostrar um pixel da logo ou
       aproximar a olho. As cores semanticas (sucesso, perigo, aviso) NAO
       pertencem a marca e seguem intocadas: sao sinal, nao identidade.
       ================================================================= */
    --nexus-midnight-blue: #0B1F3B;
    --nexus-royal-blue:    #2563B8;
    --nexus-icy-blue:      #3FB0D6;
    --nexus-graphite:      #0F172A;
    --nexus-silver:        #E5E7EB;

    --gps-color-primary: var(--nexus-midnight-blue);
    --gps-color-primary-light: var(--nexus-royal-blue);
    --gps-color-accent: var(--nexus-icy-blue);
    --gps-color-bg: #F4F6F8;
    --gps-color-surface: #FFFFFF;
    --gps-color-text: #1B2733;
    --gps-color-text-muted: #5B6B7A;
    --gps-color-border: #E1E6EA;
    --gps-color-success: #2E7D4F;
    --gps-color-danger: #B3261E;
    --gps-color-warning: #C77700;

    --gps-space-1: 4px;
    --gps-space-2: 8px;
    --gps-space-3: 16px;
    --gps-space-4: 24px;
    --gps-space-5: 32px;

    --gps-radius: 8px;
    --gps-font: "Segoe UI", system-ui, -apple-system, sans-serif;

    /* =================================================================
       REGRA GLOBAL DE LAYOUT (Sprint 1 - correcao sistemica)

       A causa da inconsistencia visual entre as telas nao era cada
       pagina: era a ausencia de uma medida comum. `.gps-input` tinha
       `margin-top` embutido e fonte 1rem, `.gps-btn` tinha fonte .95rem
       e outro padding — nenhum dos dois com ALTURA definida. Numa barra
       de filtros os dois nunca se alinhavam, e cada tela corrigia por
       conta propria.

       Daqui em diante ha UMA altura de controle, UM ritmo vertical e UM
       recuo de pagina. Corrigir aqui corrige as cinco telas de uma vez.
       ================================================================= */
    --ge-page-padding: 24px;      /* recuo horizontal do conteudo       */
    --ge-section-gap: 16px;       /* respiro entre blocos da pagina     */
    --ge-card-padding: 16px;      /* interior de card e painel          */
    --ge-control-height: 38px;    /* input, select e botao: a MESMA     */
    --ge-control-padding-x: 12px;
    --ge-cell-padding-y: 10px;    /* altura de celula de tabela         */
    --ge-cell-padding-x: 16px;
    --ge-label-gap: 6px;          /* rotulo -> campo                    */
    --ge-form-row-gap: 16px;      /* entre campos de formulario         */
    --ge-font-control: .9rem;
    --ge-font-label: .78rem;
}

* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: var(--gps-font);
    background: var(--gps-color-bg);
    color: var(--gps-color-text);
}

/* ---- Login ---- */
.gps-login-shell {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    background: linear-gradient(135deg, var(--gps-color-primary) 0%, var(--gps-color-primary-light) 100%);
}
.gps-login-card {
    background: var(--gps-color-surface);
    border-radius: var(--gps-radius);
    padding: var(--gps-space-5);
    width: 360px;
    box-shadow: 0 12px 32px rgba(0,0,0,.25);
}
.gps-login-card h1 { font-size: 1.4rem; margin: var(--gps-space-3) 0; }
.gps-login-logo { max-width: 180px; display: block; margin: 0 auto; }
.gps-login-card label { display: block; margin-top: var(--gps-space-3); font-weight: 600; font-size: .9rem; }
/* Phase 2B — textos de apoio da tela de ativacao. */
.gps-login-intro { margin: 0 0 var(--gps-space-3); color: var(--gps-color-text); font-size: .95rem; }
.gps-login-hint { margin: var(--gps-space-3) 0 0; color: var(--gps-color-text-muted); font-size: .82rem; line-height: 1.4; }

/* Campo e botao compartilham altura, fonte e raio. `margin-top` saiu de
   proposito: espacamento e responsabilidade do CONTAINER (GeField,
   GeFormField), nunca do controle — embutido nele, ele reaparecia em
   todo lugar onde o campo fosse usado sem rotulo. */
.gps-input {
    width: 100%;
    height: var(--ge-control-height);
    padding: 0 var(--ge-control-padding-x);
    border: 1px solid var(--gps-color-border);
    border-radius: var(--gps-radius);
    font-family: var(--gps-font);
    font-size: var(--ge-font-control);
    color: var(--gps-color-text);
    background: var(--gps-color-surface);
    transition: border-color .15s ease, box-shadow .15s ease;
}
.gps-input:hover { border-color: #C9D2D9; }
.gps-input:focus {
    outline: none;
    border-color: var(--gps-color-primary-light);
    box-shadow: 0 0 0 3px rgba(37, 99, 184, .16);
}
.gps-input[aria-invalid="true"] { border-color: var(--gps-color-danger); }
.gps-input:disabled { background: var(--gps-color-bg); color: var(--gps-color-text-muted); cursor: not-allowed; }

/* Area de texto e a unica excecao de altura — ela cresce por natureza. */
textarea.gps-input { height: auto; min-height: 72px; padding: 8px var(--ge-control-padding-x); line-height: 1.45; resize: vertical; }
select.gps-input { cursor: pointer; }

/* ---- Buttons ---- */
.gps-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: var(--ge-control-height);
    padding: 0 var(--gps-space-3);
    border-radius: var(--gps-radius);
    border: 1px solid transparent;
    font-family: var(--gps-font);
    font-weight: 600;
    font-size: var(--ge-font-control);
    line-height: 1;
    white-space: nowrap;
    cursor: pointer;
    text-decoration: none;
    transition: background-color .15s ease, border-color .15s ease;
}
.gps-btn:disabled { opacity: .6; cursor: not-allowed; }
.gps-btn:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(37, 99, 184, .3); }
/* Botao de linha de tabela: mesma familia, densidade menor — a alturaade
   controle cheia empurraria a linha e quebraria o ritmo da grade. */
.gps-btn-row { height: 30px; padding: 0 10px; font-size: .82rem; }
.gps-btn-primary { background: var(--gps-color-primary); color: #fff; }
.gps-btn-primary:hover { background: var(--gps-color-primary-light); }
.gps-btn-ghost { background: transparent; color: var(--gps-color-primary); border-color: var(--gps-color-border); }
.gps-btn-ghost:hover { background: var(--gps-color-bg); border-color: #C9D2D9; }
.gps-btn-danger { background: var(--gps-color-danger); color: #fff; }
.gps-btn-block { width: 100%; margin-top: var(--gps-space-4); }

/* ---- Shell ---- */
.gps-shell { display: flex; min-height: 100vh; }

/* =====================================================================
   `min-width: 0` — a linha que impede a PÁGINA de rolar na horizontal.

   MEDIDO, não suposto. Com o padrão `min-width: auto`, um item flex se
   recusa a encolher abaixo da largura mínima do próprio conteúdo. Numa
   viewport de 1425px, com o panorama de 15 colunas dentro:

     documento ........ 2185px  (760px de estouro da página)
     .gps-shell-main .. 1925px  (mais largo que a viewport)
     .ge-table-wrap ... visível 1860 = conteúdo 1860
     rolagem interna .. 0px

   Ou seja: a coluna principal crescia até caber a tabela inteira, a
   janela passava a rolar, e o `overflow-x: auto` do contorno da tabela
   NUNCA entrava em ação — porque o contorno nunca chegou a ser menor
   que o conteúdo. A página rolava e a tabela não, que é o inverso
   exato da intenção.

   Com `min-width: 0` a coluna encolhe até a viewport, o contorno fica
   menor que a tabela, e a rolagem acontece DENTRO do quadro. Rolar um
   quadro é incômodo; rolar a página inteira desalinha o shell e faz a
   barra lateral sair de vista.
   ===================================================================== */
.gps-shell-main {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

/* Pelo mesmo motivo, um nível abaixo: card, seção ou aba com conteúdo
   largo dentro de um container flex em coluna. */
.gps-shell-content > *,
.gps-card { min-width: 0; }
/* Um unico recuo horizontal governa TODA a pagina. Cabecalho, filtros,
   indicadores, tabelas e cards herdam dele — por isso ficam alinhados na
   mesma margem sem nenhum ajuste por tela. */
.gps-shell-content {
    padding: var(--ge-page-padding);
    display: flex;
    flex-direction: column;
    gap: var(--ge-section-gap);
}
/* O ritmo vertical vem do `gap` do container, nao de margens que cada
   bloco declara por conta propria e que se somam de formas diferentes
   dependendo da ordem em que aparecem. */
.gps-shell-content > * { margin-top: 0; margin-bottom: 0; }

.gps-sidebar {
    width: 260px;
    background: var(--gps-color-primary);
    color: #fff;
    flex-shrink: 0;
    padding: var(--gps-space-3) 0;
}
.gps-sidebar-brand {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: var(--gps-space-1) var(--gps-space-3) var(--gps-space-3);
    font-weight: 700;
    border-bottom: 1px solid rgba(255,255,255,.15);
}
.gps-sidebar-menu { list-style: none; margin: 0; padding: var(--gps-space-2) var(--gps-space-2); }
.gps-sidebar-menu li a {
    display: block;
    position: relative;
    padding: 9px var(--gps-space-3);
    border-radius: 6px;
    color: rgba(255,255,255,.82);
    text-decoration: none;
    font-size: .9rem;
    line-height: 1.3;
    transition: background-color .12s ease, color .12s ease;
}
.gps-sidebar-menu li a:hover { background: rgba(255,255,255,.08); color: #fff; }
.gps-sidebar-menu li a:focus-visible {
    outline: none;
    box-shadow: 0 0 0 2px rgba(255,255,255,.55);
}
/* Estado ativo: o item corrente precisa ser legivel de relance, sem
   virar um bloco saturado. Fundo sutil + marca de acento na borda
   esquerda + peso tipografico. A classe `active` e posta pelo NavLink
   do proprio framework a partir da URL — nao ha estado duplicado. */
.gps-sidebar-menu li a.active {
    background: rgba(255,255,255,.14);
    color: #fff;
    font-weight: 600;
}
.gps-sidebar-menu li a.active::before {
    content: "";
    position: absolute;
    left: 0; top: 7px; bottom: 7px;
    width: 3px;
    border-radius: 0 3px 3px 0;
    background: var(--gps-color-accent);
}
.gps-sidebar-divider { border-top: 1px solid rgba(255,255,255,.15); margin: var(--gps-space-2) var(--gps-space-2); }

.gps-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    background: var(--gps-color-surface);
    border-bottom: 1px solid var(--gps-color-border);
    padding: var(--gps-space-3) var(--gps-space-4);
}
.gps-header-competence { color: var(--gps-color-text-muted); text-transform: capitalize; }
.gps-header-user { display: flex; align-items: center; gap: var(--gps-space-3); }
.gps-header-user-info { text-align: right; }
.gps-header-user-name { display: block; font-weight: 600; }
.gps-header-user-role { display: block; font-size: .8rem; color: var(--gps-color-text-muted); }

/* ---- Page header ---- */
.gps-page-header { margin: 0; }
.gps-page-header h1 {
    margin: 0; font-size: 1.5rem; line-height: 1.2;
    letter-spacing: -.01em; color: var(--gps-color-primary);
}
.gps-page-subtitle { color: var(--gps-color-text-muted); margin: 4px 0 0; font-size: .9rem; }

/* =====================================================================
   TIPOGRAFIA — texto para pessoa vai em sentence case.

   "LINHAS NA COMPETENCIA" nao e enfase, e ruido: caixa alta elimina as
   ascendentes e descendentes que o olho usa para reconhecer a palavra,
   e obriga a ler letra a letra. O sistema nao aplica text-transform em
   NENHUM texto humano — rotulo, cabecalho de tabela, KPI, titulo de
   secao ou status. Hierarquia vem de peso, tamanho e cor.

   Siglas (PEC, CR, OR, RE, SRA, FCST, MC, EBITDA), placas e codigos
   continuam maiusculos porque SAO maiusculos — vem assim do dado, nao
   de uma regra de estilo. Ver GeText.Sentence para a apresentacao de
   valores persistidos em caixa alta.
   ===================================================================== */

/* ---- Cards ---- */
.gps-cards-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: var(--gps-space-3); }
.gps-card { background: var(--gps-color-surface); border: 1px solid var(--gps-color-border); border-radius: var(--gps-radius); padding: var(--ge-card-padding); }
.gps-card-title {
    margin: 0; font-size: .95rem; font-weight: 650;
    letter-spacing: -.01em; color: var(--gps-color-text);
}
/* Cabecalho da secao: titulo e subtitulo a esquerda, acoes a direita, na
   mesma linha de base. A margem que antes vivia no titulo saiu dele e
   virou responsabilidade do cabecalho — titulo com margem propria
   desalinhava do botao ao lado. */
.gps-card-head {
    display: flex; align-items: flex-start; gap: var(--gps-space-3);
    margin-bottom: var(--gps-space-3);
}
.gps-card-subtitle {
    margin: 4px 0 0; font-size: .8rem; color: var(--gps-color-text-muted);
    line-height: 1.4;
}
.gps-card-actions { margin-left: auto; display: flex; gap: var(--gps-space-2); flex: 0 0 auto; }
.gps-card-body { display: flex; flex-direction: column; gap: var(--ge-section-gap); }

/* ---- Lista de metadados (rotulo em cima, valor embaixo) ----
   Usada onde a tela DESCREVE algo em vez de listar: identidade da
   instalacao, cabecalho de um lote, ficha de um registro. Grade para
   que nao vire uma coluna de vinte linhas em tela larga. */
.ge-defs {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: var(--ge-form-row-gap); margin: 0;
}
.ge-defs > div { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ge-defs dt {
    font-size: var(--ge-font-label); color: var(--gps-color-text-muted);
    letter-spacing: normal;
}
.ge-defs dd { margin: 0; font-size: .88rem; overflow-wrap: anywhere; }
/* Identificador tecnico (GUID, hash): monoespacado porque e feito para
   ser CONFERIDO caractere a caractere, nao lido. */
.ge-mono { font-family: ui-monospace, SFMono-Regular, Consolas, monospace; font-size: .8rem; }
/* Card com tabela dentro: a tabela ja tem o proprio contorno, entao o
   card cede o recuo horizontal para nao criar moldura dupla. */
.gps-card > .ge-table-wrap { margin: 0 calc(var(--ge-card-padding) * -1) calc(var(--ge-card-padding) * -1); border: 0; border-radius: 0 0 var(--gps-radius) var(--gps-radius); }

/* ---- Badges ---- */
.gps-badge { display: inline-block; padding: 2px 10px; border-radius: 12px; font-size: .78rem; font-weight: 600; background: var(--gps-color-border); color: var(--gps-color-text); }
.gps-badge-success { background: #E4F3E9; color: var(--gps-color-success); }
.gps-badge-danger { background: #FBE7E5; color: var(--gps-color-danger); }
.gps-badge-muted { background: #EDEFF1; color: var(--gps-color-text-muted); }
/* Atencao: nivel intermediario entre neutro e critico. Sem ele, um
   achado de auditoria "ALTO" precisaria ser pintado de vermelho e
   perderia a distincao para o realmente CRITICO. */
.gps-badge-warning { background: #FDF2E2; color: #8A5200; }

/* ---- Table ---- */
.gps-table { width: 100%; border-collapse: collapse; background: var(--gps-color-surface); border-radius: var(--gps-radius); overflow: hidden; }
.gps-table th, .gps-table td { text-align: left; padding: var(--gps-space-2) var(--gps-space-3); border-bottom: 1px solid var(--gps-color-border); }
.gps-table th { background: var(--gps-color-bg); font-size: .82rem; font-weight: 650; color: var(--gps-color-text-muted); }

/* ---- States ---- */
.gps-empty-state, .gps-empty-state-inline { text-align: center; color: var(--gps-color-text-muted); padding: var(--gps-space-5); }
.gps-loading-state { display: flex; align-items: center; gap: var(--gps-space-2); padding: var(--gps-space-4); color: var(--gps-color-text-muted); }
.gps-spinner { width: 18px; height: 18px; border: 3px solid var(--gps-color-border); border-top-color: var(--gps-color-primary); border-radius: 50%; animation: gps-spin 0.8s linear infinite; }
@keyframes gps-spin { to { transform: rotate(360deg); } }

.gps-alert { padding: var(--gps-space-3); border-radius: var(--gps-radius); margin-bottom: var(--gps-space-3); }
.gps-alert-error { background: #FBE7E5; color: var(--gps-color-danger); }
/* Aviso: a tela precisa dizer "isto nao esta disponivel" sem gritar
   erro. Sem este tom, uma limitacao conhecida era pintada de falha. */
.gps-alert-warning { background: #FDF2E2; color: #8A5200; }
/* Phase 2B — estados da ativacao de conta. Mesma linguagem visual
   do alerta de erro ja existente, so mudando a familia de cor. */
.gps-alert-success { background: #E6F4EA; color: var(--gps-color-success); }

/* ---- Formulario administrativo (Phase 2B) ---- */
.gps-form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: var(--gps-space-3); margin-bottom: var(--gps-space-4); }
.gps-form-field label { display: block; margin-bottom: var(--gps-space-1); font-size: .84rem; font-weight: 600; }
.gps-field-hint { margin: var(--gps-space-1) 0 0; font-size: .78rem; color: var(--gps-color-text-muted); }
.gps-alert-success { background: #E6F4EA; color: var(--gps-color-success); }

/* ---- Identidade NEXUS (marca e autoria) ---- */
/* GEOMETRIA DA MARCA — medida, nao arbitrada.

   O lockup NEXUS e 3:1 no arquivo (2172x724 no master; 256x85, 384x128
   e 512x171 nos derivados) e o simbolo e 1:1. Toda caixa que recebe o
   lockup declara altura = largura / 3, e nenhuma delas usa
   `object-fit`.

   Isso e correcao de CAUSA, nao troca de estilo. A marca anterior era
   um quadrado de 1254x1254 com o desenho ocupando apenas 43,6% da
   altura; a tela usava `object-fit: cover` numa caixa em faixa para
   esconder o vao vazio. O arquivo novo nao tem vao — recorta-lo
   cortaria marca.

   ALTURA `auto`, e nao um numero: os derivados do pacote nao sao
   exatamente 3,000 (medido: 256x85 = 3,012; 384x128 = 3,000;
   512x171 = 2,994). Fixar as duas dimensoes faria o navegador esticar
   a marca em ate 0,4% — imperceptivel, mas ainda assim distorcao, e
   ela mudaria conforme o derivado que o srcset escolhesse. Com a
   altura livre, a proporcao do ARQUIVO manda, sempre. O comentario
   `3:1` ao lado de cada largura registra a altura resultante. */

/* Marca textual reduzida — fallback de ultimo recurso, usado apenas se
   nenhum asset oficial estiver publicado. Nunca substitui a logo. */
.ge-mark {
    display: inline-flex; align-items: center; justify-content: center;
    width: 30px; height: 30px; flex: 0 0 auto;
    border-radius: 7px;
    background: rgba(255,255,255,.14);
    color: #fff; font-weight: 700; font-size: .82rem; letter-spacing: .04em;
}
/* Barra lateral: LOCKUP CLARO, ocupando a largura util da coluna.

   A marca anterior entrava aqui como um quadrado de 38px com fundo
   branco opaco, e por isso precisava de uma placa branca arredondada
   por CSS para nao virar um bloco sobre o azul. Depois vinha o nome do
   produto repetido em texto ao lado, porque a 38px o wordmark do asset
   era ilegivel.

   Os assets NEXUS dispensam as duas coisas. Medido: alfa real (0..255)
   com o desenho ocupando 97% do canvas, e luminancia media 213 na
   versao clara — legivel direto sobre o azul, sem suporte. E a 188px o
   lockup mostra "NEXUS" e "GESTAO EXECUTIVA" legiveis, entao o texto ao
   lado vira repeticao e sai.

   260px de barra - 24px de recuo de cada lado = 212px uteis; 188px
   deixa o respiro que o pacote da marca exige em volta do logo. */
.ge-sidebar-logo {
    width: 188px; height: auto;   /* 3:1 -> ~63px */
    display: block; flex: 0 0 auto;
}

/* ---------------------------------------------------------------------
   MARCA DA BARRA LATERAL — simbolo colorido + wordmark em tipografia.

   Ver a nota em Sidebar.razor para a medicao que levou a isto. Em
   resumo: nenhum lockup do pacote tem, ao mesmo tempo, cor e wordmark
   legivel sobre o midnight. O simbolo tem as duas coisas.

   O simbolo e 1:1 e servido como veio. O nome e TEXTO — nao e uma logo
   redesenhada, e por isso pode usar a tipografia do sistema sem violar
   regra de marca nenhuma.
   --------------------------------------------------------------------- */
.ge-sidebar-symbol {
    width: 40px;
    height: 40px;
    display: block;
    flex: 0 0 auto;
}

.ge-sidebar-wordmark {
    display: flex;
    flex-direction: column;
    line-height: 1.1;
    min-width: 0;
}

.ge-sidebar-mark {
    font-size: 1.125rem;
    font-weight: 700;
    /* O respiro entre letras e o que aproxima o texto do desenho do
       wordmark oficial, sem imita-lo. */
    letter-spacing: .14em;
    color: #fff;
}

.ge-sidebar-name {
    font-size: .625rem;
    font-weight: 600;
    letter-spacing: .12em;
    text-transform: uppercase;
    /* Descricao, nao marca: pesa menos que NEXUS por desenho. */
    color: rgba(255, 255, 255, .62);
}
/* Telas publicas: LOCKUP ESCURO sobre o card branco.

   O asset tem alfa real e e nativamente 3:1, entao a caixa e 3:1 e nada
   e recortado. O `object-fit: cover` que existia aqui era remendo para
   a marca quadrada anterior; saiu junto com a causa. */
.ge-auth-logo {
    width: 210px; height: auto;   /* 3:1 -> ~70px */
    display: block; margin: 0 auto;
}
.ge-sidebar-name { font-weight: 600; font-size: 1rem; letter-spacing: -.01em; line-height: 1.2; }
/* A tipografia da marca nas telas publicas vive em auth.css, junto do
   restante do auth shell — um lugar so para hierarquia e espacamento. */

/* ---- Area institucional: Configuracoes > Sobre o Sistema ----
   Unico lugar do sistema onde a autoria aparece. O rodape do shell
   autenticado fica limpo, sem assinatura e sem texto de autoria. */
.ge-about { margin-bottom: var(--gps-space-4); }
.ge-about-heading {
    margin: 0 0 var(--gps-space-3);
    font-size: .78rem; font-weight: 650;
    text-transform: uppercase; letter-spacing: .09em;
    color: var(--gps-color-text-muted);
}
.ge-about-card {
    max-width: 600px;
    padding: var(--gps-space-5) var(--gps-space-5) var(--gps-space-4);
    background: var(--gps-color-surface);
    border: 1px solid var(--gps-color-border);
    border-radius: 14px;
    box-shadow:
        0 1px 2px rgba(11, 31, 59, .05),
        0 8px 24px rgba(11, 31, 59, .05);
    text-align: center;
}
/* Area institucional: mesma variante das telas publicas, e maior —
   aqui a logo E a identificacao do produto. O nome NAO e repetido em
   texto abaixo dela: o proprio lockup ja traz "GESTAO EXECUTIVA". */
.ge-about-logo {
    width: 240px; height: auto;   /* 3:1 -> ~80px */
    display: block; margin: 0 auto var(--gps-space-2);
}
.ge-about-version {
    margin: 0;
    font-size: .82rem; letter-spacing: .02em;
    color: var(--gps-color-text-muted);
}
.ge-about-description {
    margin: var(--gps-space-3) auto 0;
    max-width: 46ch;
    font-size: .95rem; line-height: 1.6;
    color: var(--gps-color-text);
    text-wrap: balance;
}

/* ---- Atribuicao de autoria ----
   Legenda oficial + assinatura manuscrita. Sem nome por extenso: a
   assinatura ja carrega a identidade do criador. Detalhe de autoria,
   jamais elemento dominante da pagina. */
.ge-attribution {
    margin-top: var(--gps-space-4);
    padding-top: var(--gps-space-4);
    border-top: 1px solid var(--gps-color-border);
}
/* Legenda em caixa normal — e uma linha institucional, nao um rotulo
   de formulario. */
.ge-attribution-label {
    display: block;
    font-size: .82rem; font-weight: 600;
    letter-spacing: .01em;
    color: var(--gps-color-text-muted);
}
/* Altura fixa + width auto preserva a PROPORCAO original do asset;
   nenhum filtro, nenhum fundo — a transparencia do PNG e usada como e. */
.ge-attribution-mark {
    display: block; margin: var(--gps-space-2) auto 0;
    height: 72px; width: auto; max-width: 100%;
}

/* Nota de desenvolvimento: existe para quem esta construindo o modulo,
   nao para quem usa o sistema. Presenca reduzida ao minimo e, em
   Production, nem chega a ser renderizada (ver Configuracoes.razor). */
.ge-about-note {
    max-width: 600px;
    margin-top: var(--gps-space-3);
    font-size: .78rem; line-height: 1.5;
    color: var(--gps-color-text-muted);
    opacity: .75;
}

@media (max-width: 620px) {
    .ge-about-card { padding: var(--gps-space-4) var(--gps-space-3); }
    .ge-about-logo { width: 190px; height: auto; }   /* 3:1 -> ~63px */
    .ge-about-description { max-width: none; font-size: .9rem; }
    .ge-attribution-mark { height: 60px; }
}

/* =====================================================================
   VOCABULARIO DE DADOS (Sprint 1)

   Um unico conjunto para os onze modulos. Existe para que cada tela nao
   invente sua propria tabela, sua propria barra de filtro e seu proprio
   espacamento — foi assim que a versao Desktop acumulou 12.400 linhas
   de XAML com meia duzia de dialetos visuais.
   ===================================================================== */

/* ---- Barra de filtros ---- */
.ge-filter-bar {
    display: flex; flex-wrap: wrap; align-items: flex-end;
    gap: var(--gps-space-3);
    padding: var(--ge-card-padding);
    background: var(--gps-color-surface);
    border: 1px solid var(--gps-color-border);
    border-radius: var(--gps-radius);
}
.ge-filter-actions { margin-left: auto; display: flex; gap: var(--gps-space-2); align-items: center; }

.ge-field { display: flex; flex-direction: column; gap: var(--ge-label-gap); min-width: 160px; }
.ge-field.is-grow { flex: 1 1 220px; }
.ge-field > label {
    font-size: var(--ge-font-label); font-weight: 600;
    color: var(--gps-color-text-muted);
    line-height: 1;
}
.ge-competence { display: flex; gap: var(--gps-space-2); }
.ge-competence select:first-child { width: 92px; flex: 0 0 auto; }
.ge-competence select:last-child { flex: 1 1 auto; min-width: 128px; }

/* ---- Busca ---- */
.ge-search { position: relative; display: flex; align-items: center; }
.ge-search svg {
    position: absolute; left: 10px; width: 15px; height: 15px;
    color: var(--gps-color-text-muted); pointer-events: none;
}
.ge-search input { padding-left: 32px; }

/* ---- Tabela ----
   `overflow-x: auto` no contorno: tabela financeira e larga por
   natureza, e a pagina nunca deve rolar horizontalmente por causa
   dela. */
.ge-table-wrap {
    background: var(--gps-color-surface);
    border: 1px solid var(--gps-color-border);
    border-radius: var(--gps-radius);
    overflow-x: auto;
}
.ge-table { width: 100%; border-collapse: collapse; font-size: .875rem; }
.ge-table thead th {
    position: sticky; top: 0; z-index: 1;
    padding: var(--ge-cell-padding-y) var(--ge-cell-padding-x);
    text-align: left; white-space: nowrap;
    font-size: .78rem; font-weight: 650;
    color: var(--gps-color-text-muted);
    background: var(--gps-color-bg);
    border-bottom: 1px solid var(--gps-color-border);
}
.ge-table tbody td {
    padding: var(--ge-cell-padding-y) var(--ge-cell-padding-x);
    border-bottom: 1px solid var(--gps-color-border);
    vertical-align: top;
    color: var(--gps-color-text);
    /* UMA regua vertical. Sem esta linha a celula herda `normal`, que
       depende da fonte que o navegador conseguiu resolver — e conviviam
       tres ritmos na MESMA linha: td em `normal` (20,3px medidos),
       td.ge-wrap em 1.35 e .ge-note em 1.4.

       TROCA CONSCIENTE: medido isoladamente, isto deixa a linha de
       Recorrentes 6%% mais alta (127px -> 134,8px). Paga-se altura por
       determinismo: o ritmo da grade deixa de depender de qual fonte
       carregou. */
    line-height: 1.45;
}
.ge-table.is-dense tbody td { padding: 6px var(--ge-cell-padding-x); }
.ge-table td.ge-actions .gps-btn + .gps-btn { margin-left: 6px; }
.ge-table tbody tr:last-child td { border-bottom: 0; }
.ge-table tbody tr:hover td { background: #FAFCFD; }
.ge-table tfoot td {
    padding: var(--ge-cell-padding-y) var(--ge-cell-padding-x);
    font-weight: 650;
    border-top: 1px solid var(--gps-color-border);
    background: var(--gps-color-bg);
}
/* =====================================================================
   CONTRATO DE ALINHAMENTO POR COLUNA.

   Cabecalho e celula da MESMA coluna recebem o mesmo alinhamento, a
   partir de uma unica classe emitida por GeDataTable a partir da
   declaracao de colunas. A pagina nao anota mais alinhamento em <th> ou
   <td>: nao ha o que discordar.

   A especificidade e deliberadamente alta (.ge-table.ge-aN-x thead th)
   porque a regra base .ge-table thead th ja vale 0-1-2 — foi
   exatamente isso que fez todo <th class="ge-num"> continuar a
   esquerda enquanto a celula ia para a direita.

   Geradas ate 16 colunas. Tabela maior que isso nao esta grande, esta
   pedindo outra forma de apresentacao.
   ===================================================================== */
.ge-table.ge-a1-num thead th:nth-child(1),
.ge-table.ge-a1-num tbody td:nth-child(1),
.ge-table.ge-a1-num tfoot td:nth-child(1) {
    text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; min-width: 112px;
}
.ge-table.ge-a1-center thead th:nth-child(1),
.ge-table.ge-a1-center tbody td:nth-child(1),
.ge-table.ge-a1-center tfoot td:nth-child(1) { text-align: center; }
.ge-table.ge-a1-act thead th:nth-child(1),
.ge-table.ge-a1-act tbody td:nth-child(1),
.ge-table.ge-a1-act tfoot td:nth-child(1) {
    text-align: right; white-space: nowrap; width: 1%; min-width: 0;
}
.ge-table.ge-a2-num thead th:nth-child(2),
.ge-table.ge-a2-num tbody td:nth-child(2),
.ge-table.ge-a2-num tfoot td:nth-child(2) {
    text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; min-width: 112px;
}
.ge-table.ge-a2-center thead th:nth-child(2),
.ge-table.ge-a2-center tbody td:nth-child(2),
.ge-table.ge-a2-center tfoot td:nth-child(2) { text-align: center; }
.ge-table.ge-a2-act thead th:nth-child(2),
.ge-table.ge-a2-act tbody td:nth-child(2),
.ge-table.ge-a2-act tfoot td:nth-child(2) {
    text-align: right; white-space: nowrap; width: 1%; min-width: 0;
}
.ge-table.ge-a3-num thead th:nth-child(3),
.ge-table.ge-a3-num tbody td:nth-child(3),
.ge-table.ge-a3-num tfoot td:nth-child(3) {
    text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; min-width: 112px;
}
.ge-table.ge-a3-center thead th:nth-child(3),
.ge-table.ge-a3-center tbody td:nth-child(3),
.ge-table.ge-a3-center tfoot td:nth-child(3) { text-align: center; }
.ge-table.ge-a3-act thead th:nth-child(3),
.ge-table.ge-a3-act tbody td:nth-child(3),
.ge-table.ge-a3-act tfoot td:nth-child(3) {
    text-align: right; white-space: nowrap; width: 1%; min-width: 0;
}
.ge-table.ge-a4-num thead th:nth-child(4),
.ge-table.ge-a4-num tbody td:nth-child(4),
.ge-table.ge-a4-num tfoot td:nth-child(4) {
    text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; min-width: 112px;
}
.ge-table.ge-a4-center thead th:nth-child(4),
.ge-table.ge-a4-center tbody td:nth-child(4),
.ge-table.ge-a4-center tfoot td:nth-child(4) { text-align: center; }
.ge-table.ge-a4-act thead th:nth-child(4),
.ge-table.ge-a4-act tbody td:nth-child(4),
.ge-table.ge-a4-act tfoot td:nth-child(4) {
    text-align: right; white-space: nowrap; width: 1%; min-width: 0;
}
.ge-table.ge-a5-num thead th:nth-child(5),
.ge-table.ge-a5-num tbody td:nth-child(5),
.ge-table.ge-a5-num tfoot td:nth-child(5) {
    text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; min-width: 112px;
}
.ge-table.ge-a5-center thead th:nth-child(5),
.ge-table.ge-a5-center tbody td:nth-child(5),
.ge-table.ge-a5-center tfoot td:nth-child(5) { text-align: center; }
.ge-table.ge-a5-act thead th:nth-child(5),
.ge-table.ge-a5-act tbody td:nth-child(5),
.ge-table.ge-a5-act tfoot td:nth-child(5) {
    text-align: right; white-space: nowrap; width: 1%; min-width: 0;
}
.ge-table.ge-a6-num thead th:nth-child(6),
.ge-table.ge-a6-num tbody td:nth-child(6),
.ge-table.ge-a6-num tfoot td:nth-child(6) {
    text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; min-width: 112px;
}
.ge-table.ge-a6-center thead th:nth-child(6),
.ge-table.ge-a6-center tbody td:nth-child(6),
.ge-table.ge-a6-center tfoot td:nth-child(6) { text-align: center; }
.ge-table.ge-a6-act thead th:nth-child(6),
.ge-table.ge-a6-act tbody td:nth-child(6),
.ge-table.ge-a6-act tfoot td:nth-child(6) {
    text-align: right; white-space: nowrap; width: 1%; min-width: 0;
}
.ge-table.ge-a7-num thead th:nth-child(7),
.ge-table.ge-a7-num tbody td:nth-child(7),
.ge-table.ge-a7-num tfoot td:nth-child(7) {
    text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; min-width: 112px;
}
.ge-table.ge-a7-center thead th:nth-child(7),
.ge-table.ge-a7-center tbody td:nth-child(7),
.ge-table.ge-a7-center tfoot td:nth-child(7) { text-align: center; }
.ge-table.ge-a7-act thead th:nth-child(7),
.ge-table.ge-a7-act tbody td:nth-child(7),
.ge-table.ge-a7-act tfoot td:nth-child(7) {
    text-align: right; white-space: nowrap; width: 1%; min-width: 0;
}
.ge-table.ge-a8-num thead th:nth-child(8),
.ge-table.ge-a8-num tbody td:nth-child(8),
.ge-table.ge-a8-num tfoot td:nth-child(8) {
    text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; min-width: 112px;
}
.ge-table.ge-a8-center thead th:nth-child(8),
.ge-table.ge-a8-center tbody td:nth-child(8),
.ge-table.ge-a8-center tfoot td:nth-child(8) { text-align: center; }
.ge-table.ge-a8-act thead th:nth-child(8),
.ge-table.ge-a8-act tbody td:nth-child(8),
.ge-table.ge-a8-act tfoot td:nth-child(8) {
    text-align: right; white-space: nowrap; width: 1%; min-width: 0;
}
.ge-table.ge-a9-num thead th:nth-child(9),
.ge-table.ge-a9-num tbody td:nth-child(9),
.ge-table.ge-a9-num tfoot td:nth-child(9) {
    text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; min-width: 112px;
}
.ge-table.ge-a9-center thead th:nth-child(9),
.ge-table.ge-a9-center tbody td:nth-child(9),
.ge-table.ge-a9-center tfoot td:nth-child(9) { text-align: center; }
.ge-table.ge-a9-act thead th:nth-child(9),
.ge-table.ge-a9-act tbody td:nth-child(9),
.ge-table.ge-a9-act tfoot td:nth-child(9) {
    text-align: right; white-space: nowrap; width: 1%; min-width: 0;
}
.ge-table.ge-a10-num thead th:nth-child(10),
.ge-table.ge-a10-num tbody td:nth-child(10),
.ge-table.ge-a10-num tfoot td:nth-child(10) {
    text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; min-width: 112px;
}
.ge-table.ge-a10-center thead th:nth-child(10),
.ge-table.ge-a10-center tbody td:nth-child(10),
.ge-table.ge-a10-center tfoot td:nth-child(10) { text-align: center; }
.ge-table.ge-a10-act thead th:nth-child(10),
.ge-table.ge-a10-act tbody td:nth-child(10),
.ge-table.ge-a10-act tfoot td:nth-child(10) {
    text-align: right; white-space: nowrap; width: 1%; min-width: 0;
}
.ge-table.ge-a11-num thead th:nth-child(11),
.ge-table.ge-a11-num tbody td:nth-child(11),
.ge-table.ge-a11-num tfoot td:nth-child(11) {
    text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; min-width: 112px;
}
.ge-table.ge-a11-center thead th:nth-child(11),
.ge-table.ge-a11-center tbody td:nth-child(11),
.ge-table.ge-a11-center tfoot td:nth-child(11) { text-align: center; }
.ge-table.ge-a11-act thead th:nth-child(11),
.ge-table.ge-a11-act tbody td:nth-child(11),
.ge-table.ge-a11-act tfoot td:nth-child(11) {
    text-align: right; white-space: nowrap; width: 1%; min-width: 0;
}
.ge-table.ge-a12-num thead th:nth-child(12),
.ge-table.ge-a12-num tbody td:nth-child(12),
.ge-table.ge-a12-num tfoot td:nth-child(12) {
    text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; min-width: 112px;
}
.ge-table.ge-a12-center thead th:nth-child(12),
.ge-table.ge-a12-center tbody td:nth-child(12),
.ge-table.ge-a12-center tfoot td:nth-child(12) { text-align: center; }
.ge-table.ge-a12-act thead th:nth-child(12),
.ge-table.ge-a12-act tbody td:nth-child(12),
.ge-table.ge-a12-act tfoot td:nth-child(12) {
    text-align: right; white-space: nowrap; width: 1%; min-width: 0;
}
.ge-table.ge-a13-num thead th:nth-child(13),
.ge-table.ge-a13-num tbody td:nth-child(13),
.ge-table.ge-a13-num tfoot td:nth-child(13) {
    text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; min-width: 112px;
}
.ge-table.ge-a13-center thead th:nth-child(13),
.ge-table.ge-a13-center tbody td:nth-child(13),
.ge-table.ge-a13-center tfoot td:nth-child(13) { text-align: center; }
.ge-table.ge-a13-act thead th:nth-child(13),
.ge-table.ge-a13-act tbody td:nth-child(13),
.ge-table.ge-a13-act tfoot td:nth-child(13) {
    text-align: right; white-space: nowrap; width: 1%; min-width: 0;
}
.ge-table.ge-a14-num thead th:nth-child(14),
.ge-table.ge-a14-num tbody td:nth-child(14),
.ge-table.ge-a14-num tfoot td:nth-child(14) {
    text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; min-width: 112px;
}
.ge-table.ge-a14-center thead th:nth-child(14),
.ge-table.ge-a14-center tbody td:nth-child(14),
.ge-table.ge-a14-center tfoot td:nth-child(14) { text-align: center; }
.ge-table.ge-a14-act thead th:nth-child(14),
.ge-table.ge-a14-act tbody td:nth-child(14),
.ge-table.ge-a14-act tfoot td:nth-child(14) {
    text-align: right; white-space: nowrap; width: 1%; min-width: 0;
}
.ge-table.ge-a15-num thead th:nth-child(15),
.ge-table.ge-a15-num tbody td:nth-child(15),
.ge-table.ge-a15-num tfoot td:nth-child(15) {
    text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; min-width: 112px;
}
.ge-table.ge-a15-center thead th:nth-child(15),
.ge-table.ge-a15-center tbody td:nth-child(15),
.ge-table.ge-a15-center tfoot td:nth-child(15) { text-align: center; }
.ge-table.ge-a15-act thead th:nth-child(15),
.ge-table.ge-a15-act tbody td:nth-child(15),
.ge-table.ge-a15-act tfoot td:nth-child(15) {
    text-align: right; white-space: nowrap; width: 1%; min-width: 0;
}
.ge-table.ge-a16-num thead th:nth-child(16),
.ge-table.ge-a16-num tbody td:nth-child(16),
.ge-table.ge-a16-num tfoot td:nth-child(16) {
    text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; min-width: 112px;
}
.ge-table.ge-a16-center thead th:nth-child(16),
.ge-table.ge-a16-center tbody td:nth-child(16),
.ge-table.ge-a16-center tfoot td:nth-child(16) { text-align: center; }
.ge-table.ge-a16-act thead th:nth-child(16),
.ge-table.ge-a16-act tbody td:nth-child(16),
.ge-table.ge-a16-act tfoot td:nth-child(16) {
    text-align: right; white-space: nowrap; width: 1%; min-width: 0;
}

/* Alinhamento numerico avulso — para numero FORA de coluna declarada
   (rodape composto, celula que mistura). Dentro de tabela, quem manda e
   o contrato de coluna acima. */
.ge-num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; min-width: 112px; }
.ge-nowrap { white-space: nowrap; }
.ge-muted { color: var(--gps-color-text-muted); }
/* Anotacao secundaria dentro de uma celula ou bloco: o dado principal
   fica em corpo normal e o complemento recua um grau. Estava repetida
   inline em dez lugares — dez oportunidades de divergir. */
/* ---- Lista curta de cartao (agenda do dia, proximos compromissos) ----
   Nao e tabela: sao poucos itens de leitura rapida, e uma <table> ali
   traria cabecalho, alinhamento por coluna e contagem que nao servem a
   nada. */
.ge-list { list-style: none; margin: 0; padding: 0; }
.ge-list li {
    padding: var(--gps-space-2) 0;
    border-bottom: 1px solid var(--gps-color-border);
    font-size: var(--ge-font-control); line-height: 1.45;
}
.ge-list li:last-child { border-bottom: 0; }
.ge-list li .ge-strong { margin-right: 8px; }

/* ---- Encerramento de contrato ---- */
/* Acao destrutiva vive separada do resto do cartao, com respiro e uma
   linha acima: ela nao pode parecer mais um botao da fileira. */
.ge-closeout {
    margin-top: var(--gps-space-4);
    padding-top: var(--gps-space-3);
    border-top: 1px solid var(--gps-color-border);
    display: flex; align-items: center; gap: var(--gps-space-3);
    flex-wrap: wrap;
}

/* ---- Eventos gerenciais (extraordinarios) ---- */
/* Caixa de marcacao com rotulo ao lado. Existe aqui, e nao na pagina,
   porque tres telas ja precisam da mesma forma. */
.ge-check {
    display: inline-flex; align-items: center; gap: 8px;
    margin: var(--gps-space-2) 0;
    font-size: var(--ge-font-control);
    cursor: pointer;
}
.ge-check input { width: 16px; height: 16px; margin: 0; cursor: pointer; }
/* Registro cancelado: continua visivel — apagar destruiria a
   rastreabilidade de uma decisao que aconteceu — mas recua para o
   segundo plano. */
.ge-table tbody tr.is-muted td { opacity: .55; }

/* ---- Resumo gerencial da competencia (o "+" do panorama) ---- */
/* Botao de expandir/recolher. Quadrado e pequeno porque ele vive na
   primeira coluna de uma tabela densa: um botao de altura de controle
   cheia empurraria a linha e quebraria o ritmo da grade. */
.ge-btn-toggle {
    width: 26px; height: 26px; padding: 0;
    font-size: 1rem; line-height: 1; font-weight: 700;
}
/* A linha de detalhe atravessa todas as colunas e recua o conteudo, para
   que o resumo se leia como filho da competencia e nao como outra
   tabela solta. */
.ge-table tbody tr.ge-row-detail > td { background: #FAFBFC; padding: 0; }
.ge-month-summary { padding: var(--gps-space-3) var(--gps-space-4); }
.ge-month-summary .ge-table-wrap { max-width: 900px; }
.ge-month-summary-actions { margin-top: var(--gps-space-2); }
/* Secao (ROL, RESULTADO DOS CONTRATOS, INDIRETO, EBITDA): sao os totais
   que estruturam a leitura do resultado. */
.ge-table tbody tr.is-section td { font-weight: 650; background: #F4F6F8; }
/* Categorias do indireto: recuadas, porque sao a composicao da linha
   INDIRETO logo acima — nao itens de mesmo nivel. */
.ge-table tbody tr.is-indirect td:first-child { padding-left: var(--gps-space-5); }

.ge-note { font-size: .78rem; color: var(--gps-color-text-muted); line-height: 1.4; }
.ge-note.is-inline { margin-left: 6px; }
/* Trava por compra comprometida no Forecast. Nao e alerta de erro — o
   comprometido e fato, e a linha esta correta. E informacao de piso, por
   isso usa o texto normal e nao a cor de perigo; o que muda e o peso,
   para o gerente achar a explicacao sem procurar. */
.ge-lock-purchase { display: block; color: var(--gps-color-text); font-weight: 600; }
.ge-lock-variance { display: block; margin-top: 2px; color: var(--gps-color-warning); }
.ge-strong { font-weight: 650; }
/* Valor negativo em coluna financeira. Cor, e nao so o sinal: numa
   tabela densa o menos some, e um desvio negativo lido como positivo e
   pior do que nao mostrar o desvio. */
.ge-negative { color: var(--gps-color-danger); }
.ge-table tbody tr.is-attention td { background: #FFFBF2; }
/* A competencia que a tela esta mostrando, dentro da evolucao anual.
   Nao e alerta: e orientacao — "voce esta aqui". */
.ge-table tbody tr.is-current td { background: #F0F5FA; font-weight: 600; }
.ge-table tbody tr.is-critical td { background: #FDF3F2; }
.ge-table-count {
    margin: 0; padding: 8px var(--ge-cell-padding-x);
    font-size: .78rem; color: var(--gps-color-text-muted);
    border-top: 1px solid var(--gps-color-border);
}

/* ---- Indicadores ---- */
.ge-kpi-row {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: var(--gps-space-3);
}
.ge-kpi {
    display: flex; flex-direction: column; gap: 2px;
    padding: var(--ge-card-padding);
    background: var(--gps-color-surface);
    border: 1px solid var(--gps-color-border);
    border-left: 3px solid var(--gps-color-primary-light);
    border-radius: var(--gps-radius);
}
.ge-kpi-label {
    font-size: .78rem; font-weight: 600;
    color: var(--gps-color-text-muted);
}
.ge-kpi-value { font-size: 1.28rem; line-height: 1.2; letter-spacing: -.01em; font-variant-numeric: tabular-nums; }
.ge-kpi-hint { font-size: .76rem; color: var(--gps-color-text-muted); }
.ge-kpi-positive { border-left-color: var(--gps-color-success); }
.ge-kpi-negative { border-left-color: var(--gps-color-danger); }
.ge-kpi-warning  { border-left-color: var(--gps-color-warning); }

/* ---- Lista de avisos/alertas dentro de um card ---- */
.ge-alert-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--gps-space-2); }
.ge-alert-list li {
    display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--gps-space-2);
    padding-bottom: var(--gps-space-2);
    border-bottom: 1px solid var(--gps-color-border);
    font-size: .875rem;
}
.ge-alert-list li:last-child { border-bottom: 0; padding-bottom: 0; }

/* =====================================================================
   MODAL DE FORMULARIO

   Defeito corrigido: a largura anterior comprimia o formulario numa
   coluna estreita e, com muitos campos, o rodape saia da viewport — os
   botoes Salvar/Cancelar ficavam inalcancaveis.

   Estrutura obrigatoria: CABECALHO FIXO, CORPO ROLAVEL, RODAPE FIXO. A
   rolagem acontece dentro do corpo, entao as acoes estao sempre
   visiveis, independente do tamanho do formulario ou da tela.
   ===================================================================== */
/* =====================================================================
   TAMANHOS OFICIAIS DE DIALOGO — Small / Medium / Large / Full.

   Quatro tamanhos nomeados, escolhidos pelo FLUXO, nunca por pixel solto
   na pagina. A margem de seguranca (48px) e a mesma nos quatro: um
   dialogo nunca encosta na borda da janela.
   ===================================================================== */
:root {
    --ge-modal-small:  540px;
    --ge-modal-medium: 780px;
    --ge-modal-large:  1080px;
    --ge-modal-margin: 48px;
}
.ge-modal {
    /* Sem tamanho aqui: a variante e obrigatoria e GeModal sempre emite
       uma. Base sem largura impede que "esqueci a variante" produza um
       dialogo silenciosamente errado — ele fica visivelmente sem forma. */
    max-height: calc(100vh - 64px);
    display: flex;
    flex-direction: column;
    padding: 0;
    overflow: hidden;
}
.ge-modal.is-small  { width: min(var(--ge-modal-small),  calc(100vw - var(--ge-modal-margin))); }
.ge-modal.is-medium { width: min(var(--ge-modal-medium), calc(100vw - var(--ge-modal-margin))); }
.ge-modal.is-large  { width: min(var(--ge-modal-large),  calc(100vw - var(--ge-modal-margin))); }
.ge-modal.is-full   { width: calc(100vw - var(--ge-modal-margin)); height: calc(100vh - 64px); }
.ge-modal-header {
    flex: 0 0 auto;
    padding: var(--gps-space-3) var(--gps-space-4);
    border-bottom: 1px solid var(--gps-color-border);
}
.ge-modal-header h2 {
    margin: 0; font-size: 1.05rem; font-weight: 650; color: var(--gps-color-text);
}
.ge-modal-body { flex: 1 1 auto; overflow-y: auto; padding: var(--gps-space-4); }
.ge-modal-footer {
    flex: 0 0 auto;
    display: flex; justify-content: flex-end; gap: var(--gps-space-2);
    padding: var(--gps-space-3) var(--gps-space-4);
    border-top: 1px solid var(--gps-color-border);
    background: var(--gps-color-bg);
}


@media (max-width: 640px) {
    /* Em tela pequena o dialogo ocupa a tela: caixa flutuante estreita
       seria pior que a pagina inteira. */
    .ge-modal, .ge-modal.is-small, .ge-modal.is-medium,
    .ge-modal.is-large, .ge-modal.is-full {
        width: 100vw; max-height: 100vh; height: 100vh; border-radius: 0;
    }
}

/* =====================================================================
   FORMULARIO — uma so gramatica: rotulo SEMPRE acima do campo, mesma
   distancia entre rotulo e campo, mesma distancia entre linhas, e erro
   imediatamente abaixo do campo que o gerou.
   ===================================================================== */
.ge-form-section + .ge-form-section { margin-top: var(--gps-space-4); }
.ge-form-section-title {
    margin: 0 0 var(--gps-space-3);
    font-size: .85rem; font-weight: 650;
    color: var(--gps-color-text);
    padding-bottom: 6px;
    border-bottom: 1px solid var(--gps-color-border);
}
/* Duas colunas em tela larga; uma quando nao couber. Formulario longo em
   coluna unica vira uma fita vertical interminavel. */
.ge-form-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: var(--ge-form-row-gap);
}
.ge-form-grid.is-single { grid-template-columns: 1fr; }
.ge-form-field { display: flex; flex-direction: column; gap: var(--ge-label-gap); min-width: 0; }
.ge-form-field.is-full { grid-column: 1 / -1; }
.ge-form-field > label {
    font-size: var(--ge-font-label); font-weight: 650;
    color: var(--gps-color-text-muted); line-height: 1;
}
.ge-form-hint { margin: 0; font-size: .76rem; color: var(--gps-color-text-muted); line-height: 1.4; }
.ge-form-error {
    display: flex; align-items: flex-start; gap: 5px;
    margin: 0; font-size: .78rem; line-height: 1.4;
    color: var(--gps-color-danger);
}

/* ---- Responsividade da barra de filtros ---- */

@media (max-width: 900px) {
    .ge-filter-bar { flex-direction: column; align-items: stretch; }
    .ge-filter-actions { margin-left: 0; }
}

/* ---- Modal ---- */
.gps-modal-overlay { position: fixed; inset: 0; background: rgba(0,0,0,.4); display: flex; align-items: center; justify-content: center; z-index: 1000; }
/* SUPERFICIE APENAS — nunca tamanho.
   Causa raiz medida no DOM: esta regra definia width:360px e padding, e
   vinha DEPOIS de .ge-modal no arquivo. Mesma especificidade (0-1-0),
   entao a ordem de origem decidia: todo GeModal computava 360px/24px.
   So .ge-modal.is-wide escapava, por ter 0-2-0 — exatamente o unico
   dialogo que aparecia correto na evidencia visual.
   Tamanho agora vem SEMPRE das variantes oficiais abaixo. */
.gps-modal { background: var(--gps-color-surface); border-radius: var(--gps-radius); }
.gps-modal-actions { display: flex; justify-content: flex-end; gap: var(--gps-space-2); margin-top: var(--gps-space-4); }

/* ---- Responsividade (mandate item 52) ---- */
@media (max-width: 900px) {
    .gps-shell { flex-direction: column; }
    .gps-sidebar { width: 100%; }
    .gps-sidebar-menu { display: flex; flex-wrap: wrap; }
    .gps-sidebar-menu li a { padding: var(--gps-space-2); }
}

/* =====================================================================
   MÓDULO GERENTE DE CONTRATO — seção acrescentada ao FIM do arquivo.

   Uma regra só, e ela existe por necessidade concreta: o sistema tinha
   aviso de erro, de atenção e de sucesso, mas nenhum aviso NEUTRO. O
   Centro de Alertas precisa dizer de onde vem o dado e até que
   competência ele existe — uma informação que não é erro nem sucesso.
   Sem um tom neutro, essa linha teria de emprestar a cor de um dos
   outros e passaria a parecer um problema ou uma confirmação.
   ===================================================================== */
.gps-alert-info { background: #EDF1F5; color: var(--gps-color-text-muted); }

/* =====================================================================
   EXPERIENCIA EXECUTIVA (Diretor Executivo) — secao ADITIVA.

   Nenhuma regra acima foi alterada: tudo aqui e prefixado `ge-exec-` e
   so se aplica dentro do shell executivo. O motivo de existir uma
   gramatica propria e de produto, nao de estilo: com TRES destinos, a
   barra lateral de 260px do shell gerencial seria um corredor vazio
   ocupando um quinto da largura onde deveria estar o resultado.

   As medidas continuam vindo dos tokens globais (--ge-page-padding,
   --ge-section-gap, --gps-space-*): o shell executivo e outra forma, nao
   outro sistema. Uma pagina executiva tambem nao declara medida propria.
   ===================================================================== */
.ge-exec-shell { display: flex; flex-direction: column; min-height: 100vh; }

.ge-exec-topbar {
    display: flex;
    align-items: center;
    gap: var(--gps-space-4);
    flex-wrap: wrap;
    background: var(--gps-color-primary);
    color: #fff;
    padding: var(--gps-space-2) var(--ge-page-padding);
}
.ge-exec-brand { display: flex; align-items: center; gap: var(--gps-space-2); }
/* Barra superior executiva: SIMBOLO isolado, 1:1.

   A altura util aqui e 30px. Um lockup 3:1 nessa altura teria 90px de
   largura e deixaria a linha "GESTAO EXECUTIVA" com ~4px — ilegivel.
   Regra da marca: em espaco reduzido usa-se o simbolo, nunca o lockup
   espremido. O nome do produto vem ao lado, em texto.

   Sem placa branca: o simbolo tem alfa real, e o brilho metalico o
   sustenta sobre o azul. */
.ge-exec-logo {
    height: 30px; width: 30px;    /* 1:1 */
    display: block; flex: 0 0 auto;
}
.ge-exec-name { font-weight: 700; letter-spacing: -.01em; }
.ge-exec-tagline {
    font-size: .78rem; color: rgba(255,255,255,.72);
    padding-left: var(--gps-space-2);
    border-left: 1px solid rgba(255,255,255,.25);
}

.ge-exec-nav { display: flex; gap: var(--gps-space-1); flex: 1; flex-wrap: wrap; }
.ge-exec-nav-item {
    display: inline-block;
    padding: 8px var(--gps-space-3);
    border-radius: 6px;
    color: rgba(255,255,255,.82);
    text-decoration: none;
    font-size: .92rem;
    line-height: 1.3;
    transition: background-color .12s ease, color .12s ease;
}
.ge-exec-nav-item:hover { background: rgba(255,255,255,.08); color: #fff; }
.ge-exec-nav-item:focus-visible { outline: none; box-shadow: 0 0 0 2px rgba(255,255,255,.55); }
/* Estado ativo com sublinhado de acento: numa barra horizontal, so o
   fundo mais claro nao sobrevive ao contraste da propria barra. */
.ge-exec-nav-item.active {
    background: rgba(255,255,255,.14);
    color: #fff;
    font-weight: 600;
    box-shadow: inset 0 -3px 0 0 var(--gps-color-accent);
}

.ge-exec-identity { display: flex; align-items: center; gap: var(--gps-space-2); }
.ge-exec-user { text-align: right; line-height: 1.2; }
.ge-exec-user-name { display: block; font-weight: 600; font-size: .9rem; }
.ge-exec-user-role { display: block; font-size: .76rem; color: rgba(255,255,255,.72); }
.ge-exec-identity .gps-btn {
    background: transparent;
    color: rgba(255,255,255,.9);
    border: 1px solid rgba(255,255,255,.3);
    text-decoration: none;
    display: inline-flex; align-items: center;
}
.ge-exec-identity .gps-btn:hover { background: rgba(255,255,255,.12); color: #fff; }

.ge-exec-content {
    flex: 1;
    padding: var(--ge-page-padding);
    display: flex;
    flex-direction: column;
    gap: var(--ge-section-gap);
}
/* Mesmo motivo do shell gerencial: o ritmo vertical vem do `gap` do
   container, nao de margens que cada bloco declara por conta propria. */
.ge-exec-content > * { margin-top: 0; margin-bottom: 0; }

/* Declaracao de indisponibilidade. Precisa parecer INFORMACAO, nao
   erro: o dado nao esta faltando por defeito, ele nao existe no modelo —
   e um bloco vermelho faria o leitor procurar um problema inexistente. */
.ge-exec-unavailable {
    border: 1px dashed var(--gps-color-border);
    border-radius: var(--gps-radius);
    padding: var(--ge-card-padding);
    color: var(--gps-color-text-muted);
    font-size: .875rem;
    background: var(--gps-color-surface);
}
.ge-exec-unavailable strong { color: var(--gps-color-text); display: block; margin-bottom: 4px; }

/* Nota de leitura ao pe de uma secao: de onde veio o numero e o que ele
   nao inclui. Em tela executiva isso e parte do dado, nao rodape. */
.ge-exec-note { font-size: .8rem; color: var(--gps-color-text-muted); margin: 0; }

@media (max-width: 900px) {
    .ge-exec-topbar { align-items: stretch; gap: var(--gps-space-2); }
    .ge-exec-nav { order: 3; width: 100%; }
    .ge-exec-identity { margin-left: auto; }
}

/* =====================================================================
   PERFIL DO USUÁRIO — avatar, bloco da barra lateral e tela.

   O avatar é um círculo de tamanho FIXO com `flex-shrink: 0`: num item
   flexível, o nome longo espremeria a foto até ela virar uma elipse, e
   o defeito só apareceria para quem tem nome comprido.

   As iniciais e a foto ocupam exatamente a mesma caixa, então a barra
   não muda de altura quando alguém envia ou remove a própria foto.
   ===================================================================== */
.ge-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    overflow: hidden;
    background: rgba(255, 255, 255, .14);
    border: 1px solid rgba(255, 255, 255, .22);
}
.ge-avatar.is-lg { width: 96px; height: 96px; }

.ge-avatar-img {
    width: 100%;
    height: 100%;
    /* `cover` aqui NÃO é remendo de proporção como era na marca: o
       recorte é a intenção — foto de perfil é enquadrada em círculo, e
       `contain` deixaria barras dentro do círculo. */
    object-fit: cover;
    display: block;
}

.ge-avatar-initials {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    font-weight: 600;
    font-size: .8125rem;
    letter-spacing: .02em;
    color: #fff;
}
.ge-avatar.is-lg .ge-avatar-initials { font-size: 1.75rem; }

/* Na tela de perfil o avatar fica sobre fundo claro. */
.ge-profile .ge-avatar {
    background: var(--gps-color-primary);
    border-color: rgba(0, 0, 0, .12);
}

.ge-sidebar-profile {
    display: flex;
    align-items: center;
    gap: var(--gps-space-2);
    margin-top: var(--gps-space-3);
    padding: var(--gps-space-3) var(--gps-space-3);
    border-top: 1px solid rgba(255, 255, 255, .12);
    text-decoration: none;
    color: #fff;
}
.ge-sidebar-profile:hover { background: rgba(255, 255, 255, .07); }

.ge-sidebar-profile-text {
    /* `min-width: 0` é o que permite o truncamento funcionar dentro de
       um flex item — sem ele o texto força a largura e empurra a barra. */
    min-width: 0;
    display: flex;
    flex-direction: column;
    line-height: 1.25;
}
.ge-sidebar-profile-name,
.ge-sidebar-profile-role {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.ge-sidebar-profile-name { font-size: .8125rem; font-weight: 600; }
.ge-sidebar-profile-role { font-size: .75rem; opacity: .72; }

/* A barra é uma coluna; o perfil desce para o rodapé dela. */
.gps-sidebar { display: flex; flex-direction: column; }
.gps-sidebar-menu { flex: 1 1 auto; }

.ge-profile {
    display: flex;
    align-items: flex-start;
    gap: var(--gps-space-4);
    flex-wrap: wrap;
}
.ge-profile-fields {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: var(--gps-space-3);
    margin: 0;
    flex: 1 1 320px;
}
.ge-profile-fields dt {
    font-size: .75rem;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--gps-color-text-muted, #64748b);
}
.ge-profile-fields dd { margin: 2px 0 0; font-size: .9375rem; }

/* =====================================================================
   TABELAS — LARGURA MÍNIMA E QUEBRA CONTROLADA

   O DEFEITO MEDIDO. `width: 100%` numa tabela de 15 colunas faz o
   navegador espremer o que pode espremer: as colunas de TEXTO. O
   resultado é a coluna "Alerta" com uma palavra por linha e a coluna
   "Achado" virando texto vertical — enquanto as colunas numéricas, que
   têm `white-space: nowrap`, ficam intactas. O texto paga a conta
   sozinho.

   A CORREÇÃO é dar piso às colunas. Com piso, a soma das larguras
   mínimas passa da largura disponível, e aí o `overflow-x: auto` do
   contorno entra em ação — que é o comportamento certo: a tabela rola
   dentro do próprio quadro, e a PÁGINA não rola.

   Rolar um quadro é incômodo; ler texto vertical é impossível.
   ===================================================================== */

/* Piso por TIPO de conteúdo. Os números vêm dos conteúdos reais:
   "R$ 1.234.567,89" não cabe abaixo de 108px na fonte da tabela, e um
   rótulo de contrato ("334371 · CONDOMÍNIO …") fica ilegível abaixo de
   140px. */
.ge-table thead th,
.ge-table tbody td { min-width: 96px; }

/* A primeira coluna costuma ser a identificacao (contrato, conta, mes) e
   e a que mais sofre com o esmagamento. Piso maior — MAS so quando ela e
   de texto: quando a primeira coluna e o "+" do panorama ou uma marca
   curta, 140px seria uma faixa vazia atravessando a tabela inteira. */
/* O `:not()` de cada classe de prosa nao e enfeite: sem ele esta regra
   VENCE por especificidade (0,4,2 contra 0,2,2) e a classe anotada na
   celula e ignorada em silencio — o autor da tela escreve `ge-wrap`, o
   navegador desconsidera, e nao ha erro em lugar nenhum.

   Medido reescrevendo o seletor no CSSOM sobre o CSS real:

     primeira coluna com class="ge-wrap"    140px  ->  240px
     primeira coluna sem classe de prosa    140px  ->  140px

   O piso posicional e um PALPITE sobre o que a primeira coluna contem;
   a classe e uma AFIRMACAO de quem escreveu a tela. Afirmacao vence. */
.ge-table:not(.ge-a1-center):not(.ge-a1-act) thead th:first-child:not(.ge-wrap):not(.ge-clamp):not(.ge-wrap-wide),
.ge-table:not(.ge-a1-center):not(.ge-a1-act) tbody td:first-child:not(.ge-wrap):not(.ge-clamp):not(.ge-wrap-wide) {
    min-width: 140px;
}

/* Coluna de alternancia (o "+"): exatamente o botao. */
.ge-table.ge-a1-center thead th:nth-child(1),
.ge-table.ge-a1-center tbody td:nth-child(1) { min-width: 48px; width: 1%; }

/* Numérica: piso maior e SEM quebra — um valor monetário partido em
   duas linhas deixa de ser comparável na vertical, que é a única razão
   de alinhá-lo à direita. */
/* O alinhamento e aplicado por classe NA TABELA (ge-aN-num), nao por
   classe na celula: as regras posicionais acima ja levam o piso junto.
   Estas aqui cobrem as celulas que declaram a classe diretamente. */
.ge-table td.ge-num,
.ge-table th.ge-num { min-width: 112px; white-space: nowrap; }

/* Ações: o que a coluna precisa e nada além. `width: 1%` com `nowrap`
   faz a tabela dar a ela exatamente a largura dos botões, devolvendo o
   resto ao texto. */
.ge-table td.ge-actions,
.ge-table th.ge-actions {
    width: 1%;
    white-space: nowrap;
    vertical-align: top;
}

/* Marca curta (situação, severidade): não precisa de piso de texto. */
.ge-table td.ge-center,
.ge-table th.ge-center { min-width: 88px; }

/* `ge-nowrap` continua significando "não quebre", mas agora sem
   espremer o vizinho. */
.ge-table td.ge-nowrap { white-space: nowrap; min-width: 0; }

/* ---------------------------------------------------------------------
   COLUNA DE TEXTO LONGO — a mensagem do alerta, o achado da compra, o
   problema do plano.

   Ela QUEBRA (é prosa, não valor) mas com piso generoso, e limita a
   três linhas: uma célula de oito linhas empurra a linha inteira para
   baixo e desalinha a tabela toda. O texto completo fica no `title`,
   que o navegador mostra ao passar o mouse — cortar sem dar acesso ao
   resto seria esconder informação.
   --------------------------------------------------------------------- */
.ge-table td.ge-wrap {
    min-width: 240px;
    white-space: normal;
    overflow-wrap: anywhere;
    line-height: 1.35;
}

/* MEDIDO num navegador, celula de tabela com seis linhas de texto:

     com ge-clamp    display flow-root   visivel  70px   conteudo 221px  CORTOU
     sem ge-clamp    display table-cell  visivel 220px   conteudo 220px  nao

   O `display: -webkit-box` NAO sobrevive num <td>: ele blockifica para
   `flow-root`. Mesmo assim o corte acontece — o navegador aplica o
   line-clamp na caixa blockificada junto com o `overflow: hidden`.

   As quatro propriedades abaixo funcionam como CONJUNTO. Remover
   qualquer uma delas devolve a celula de 220px, que e o que desalinha a
   tabela inteira. */
.ge-table td.ge-clamp {
    min-width: 240px;
    white-space: normal;
    overflow-wrap: anywhere;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Coluna de texto longo COM folga — o "Achado" da auditoria de compras,
   que traz tipo, resumo e referência no mesmo lugar. */
/* `overflow-wrap` aqui pelo mesmo motivo das outras duas classes de
   prosa: um codigo de produto sem espaco
   (OLEO-LUBRIF-SAE-15W40-BALDE-20L) nao tem onde quebrar e passa a
   ditar a largura minima da coluna inteira. Era a unica das tres que
   nao declarava. */
.ge-table td.ge-wrap-wide,
.ge-table th.ge-wrap-wide {
    min-width: 320px;
    white-space: normal;
    overflow-wrap: anywhere;
    line-height: 1.35;
}

/* ---------------------------------------------------------------------
   ROLAGEM INTERNA — o contorno já tem `overflow-x: auto`. Falta dizer ao
   leitor que há mais à direita: sem pista, a coluna cortada parece
   ausente em vez de fora de vista.
   --------------------------------------------------------------------- */
.ge-table-wrap { scrollbar-gutter: stable; }

@media (max-width: 1280px) {
    /* Em tela estreita a rolagem interna é a regra, não a exceção. */
    .ge-table-wrap { overflow-x: auto; }
}

/* ---------------------------------------------------------------------
   MODAL COM TABELA LONGA — título e cabeçalho fixos.

   Rolando cem registros, o leitor perde as duas âncoras ao mesmo tempo:
   QUAL item está analisando e O QUE cada coluna significa. As duas
   ficam presas; só o corpo rola.
   --------------------------------------------------------------------- */
.ge-modal-body .ge-table-wrap {
    max-height: min(60vh, 520px);
    overflow-y: auto;
}
.ge-modal-body .ge-table thead th {
    position: sticky;
    top: 0;
    z-index: 2;
    /* Fundo OPACO: com fundo transparente as linhas passariam por baixo
       do cabeçalho e ele ficaria ilegível durante a rolagem. */
    background: var(--gps-color-bg);
}

/* ---------------------------------------------------------------------
   CABEÇALHO DA COMPETÊNCIA EXPANDIDA — o resumo e a ação que o audita.
   --------------------------------------------------------------------- */
.ge-month-summary-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--gps-space-3);
    flex-wrap: wrap;
    margin-bottom: var(--gps-space-2);
}

/* =====================================================================
   ABAS DO WORKSPACE — navegação entre vistas do MESMO objeto.

   Não são um menu: o contrato continua o mesmo, muda o que se olha
   nele. Por isso ficam dentro do card do contrato e não no topo da
   página, onde competiriam com a navegação do sistema.

   A aba ativa é marcada por uma barra inferior, não por caixa
   preenchida: o preenchimento pesaria mais que o título do contrato
   logo acima, invertendo a hierarquia.
   ===================================================================== */
.ge-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 2px;
    border-bottom: 1px solid var(--gps-color-border);
    margin-bottom: var(--gps-space-3);
}

.ge-tab {
    appearance: none;
    background: transparent;
    border: 0;
    border-bottom: 2px solid transparent;
    padding: var(--gps-space-2) var(--gps-space-3);
    font: inherit;
    font-size: .875rem;
    font-weight: 550;
    color: var(--gps-color-text-muted);
    cursor: pointer;
    /* O deslocamento de 1px cobre a borda do contêiner, para a barra da
       aba ativa não ficar flutuando acima dela. */
    margin-bottom: -1px;
}
.ge-tab:hover { color: var(--gps-color-text); }

.ge-tab.is-active {
    color: var(--gps-color-primary);
    border-bottom-color: var(--gps-color-primary);
}

.ge-tab:focus-visible {
    outline: 2px solid var(--gps-color-primary);
    outline-offset: -2px;
}

/* =====================================================================
   GRAFICO — a decisao de tamanho e do sistema visual, nao do SVG.

   O panorama desenha EBITDA FCST x RE por competencia num SVG inline. O
   elemento ja carregava `class="ge-chart"`, mas a regra nao existia:
   sem ela, `preserveAspectRatio="meet"` com altura travada deixava o
   desenho centralizado com folga num container mais largo que o viewBox,
   em vez de crescer.
   ===================================================================== */
.ge-chart {
    display: block;
    width: 100%;
    max-width: 720px;
    height: auto;
}

