:root {
    --ink: #182338;
    --ink-2: #33415c;
    --muted: #69758a;
    --line: #dce2ea;
    --line-strong: #c7d0dc;
    --paper: #f3f6fa;
    --white: #ffffff;
    --blue: #315efb;
    --blue-dark: #2445bc;
    --cyan: #19a7a0;
    --amber: #d68a16;
    --red: #c6404c;
    --nav: #00203f;
    --radius: 10px;

    /* As cores da marca, medidas no arquivo da logo e nao estimadas a olho.
       A palavra "Fsys" e #003064; a bandeira, #F3000B e #FFA003.

       --nav era #101a2d, um azul quase preto que nao vinha de lugar nenhum. E
       o fundo da barra lateral e do painel do login, justamente onde a marca
       aparece — e logo sobre cor que nao e da marca parece colada por cima.
       Agora e o proprio #003064 escurecido, da mesma familia. */
    --marca-azul: #003064;
    --marca-vermelho: #f3000b;
    --marca-ambar: #ffa003;

    /* A largura da pagina e o respiro entre blocos moram AQUI, e nao em cada
       componente. Antes `max-width: 1440px; margin: 0 auto` estava repetido em
       nove classes, e quem esquecia de repetir ganhava um bloco desalinhado —
       ou pior: dentro de uma grade, a margem automatica cancelava o
       esticamento e o cartao encolhia ate a largura do proprio texto. */
    --largura: 1440px;
    --gap-secao: 22px;
    --shadow: 0 12px 36px rgba(24, 35, 56, .07);
    --display: "Arial Narrow", "Aptos Narrow", "Roboto Condensed", sans-serif;
    --body: "Segoe UI Variable", "Aptos", "Segoe UI", sans-serif;
    --mono: "Cascadia Code", "SFMono-Regular", Consolas, monospace;
}

* { box-sizing: border-box; }
html { color-scheme: light; }
body { margin: 0; color: var(--ink); background: var(--paper); font-family: var(--body); font-size: 14px; line-height: 1.5; }
button, input, select, textarea { font: inherit; }
a { color: inherit; }
button, a { -webkit-tap-highlight-color: transparent; }
:focus-visible { outline: 3px solid rgba(49, 94, 251, .28); outline-offset: 2px; }
h1, h2, h3, p { margin-top: 0; }
h1, h2 { font-family: var(--display); letter-spacing: -.025em; }
/* O titulo nasceu do tamanho de uma pagina de apresentacao da API — 3rem numa
   tela cujo assunto e uma tabela de 1.240 linhas empurra o dado para baixo da
   dobra. Login e instalacao, que continuam sendo paginas de apresentacao,
   mantem o titulo grande com regra propria. */
h1 { font-size: clamp(1.55rem, 2.4vw, 2rem); line-height: 1.1; margin-bottom: 6px; }
h2 { font-size: 1.1rem; margin-bottom: 6px; }
code, pre, .version-tag { font-family: var(--mono); }
.eyebrow { margin-bottom: 8px; color: var(--blue); font-family: var(--mono); font-size: 11px; font-weight: 700; letter-spacing: .13em; }
.app-shell { display: grid; grid-template-columns: 248px minmax(0, 1fr); min-height: 100vh; }
.sidebar { position: sticky; top: 0; height: 100vh; display: flex; flex-direction: column; padding: 26px 18px 18px; color: #dce5f5; background: var(--nav); z-index: 20; }
/* A marca.

   Eram tres barrinhas azuis e cianas montadas em CSS (`.brand-mark`) com o nome
   ao lado em texto — um desenho inventado, de quando o projeto era so uma API.
   Agora e a logo de verdade: a bandeira e a palavra "Fsys" ja vem na imagem, e
   por isso nao ha mais `strong` com o nome ao lado. Repetir o nome em texto
   embaixo de uma logo que ja o escreve e ruido.

   Sao dois arquivos, e os dois precisam existir: sobre fundo claro vai
   `fsys.png`, com a palavra no azul da marca; sobre a barra lateral e o painel
   do login, que sao escuros, vai `fsys-claro.png`, com a palavra em branco. O
   mesmo arquivo nos dois lugares deixaria a palavra ilegivel num deles. */
.brand { display: flex; flex-direction: column; align-items: flex-start; gap: 7px; text-decoration: none; }
.brand img { display: block; width: 116px; height: auto; }
.brand small { color: #8fa3c2; font-family: var(--mono); font-size: 9px; letter-spacing: .15em; text-transform: uppercase; }
/* `flex: 0 1 auto` com `min-height: 0` e o que deixa esta lista ENCOLHER e
   rolar por dentro quando nao cabe. Sem isso o conteudo vazava da barra, que
   tem altura fixa de 100vh, e abaixo dela aparecia uma faixa branca — o fundo
   azul acabava onde a tela acabava. Aparecia ao expandir um modulo de muitas
   telas, que e justamente o caso novo. Relatado pelo usuario em 07/10/2026.

   `min-height: 0` nao e supersticao: um item de flex nao encolhe abaixo do
   proprio conteudo sem ele, e `overflow` sozinho nao resolveria. */
.nav { display: grid; gap: 5px; margin-top: 34px; flex: 0 1 auto; min-height: 0; overflow-y: auto; }
.nav a { display: flex; align-items: center; gap: 12px; padding: 10px 12px; color: #aeb9cc; border-radius: 7px; text-decoration: none; font-weight: 600; }
.nav a:hover { color: white; background: rgba(255,255,255,.07); }
.nav a span { width: 22px; color: #6f85aa; font-family: var(--mono); font-size: 18px; text-align: center; }

/* O modulo aberto. O layout marcava `class="ativo"` neste link desde que o menu
   existe, e a folha nunca teve a regra: o destaque era calculado e descartado.
   Achado em 06/10/2026, ao dar dois niveis ao menu. */
.nav a.ativo { color: white; background: rgba(109,139,255,.18); }
.nav a.ativo span { color: #8ba3ff; }

/* As telas do modulo aberto. A linha a esquerda e o que diz que elas pertencem
   ao item de cima — sem ela, com o menu rolado, a sublista parece outro modulo. */
.nav-telas { display: grid; gap: 1px; margin: 2px 0 6px 23px; padding-left: 11px; border-left: 1px solid rgba(255,255,255,.12); }
.nav-telas a { padding: 7px 10px; font-size: 12.5px; font-weight: 600; }
.nav-telas a.ativo { color: white; background: var(--blue); }
.sidebar-foot { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 10px; margin-top: auto; padding: 15px 4px 0; border-top: 1px solid rgba(255,255,255,.1); }
.sidebar-foot > div { display: flex; min-width: 0; flex-direction: column; }
.sidebar-foot strong { overflow: hidden; font-size: 13px; text-overflow: ellipsis; white-space: nowrap; }
.sidebar-foot small { color: #76859d; font-size: 10px; }
.user-dot { width: 9px; height: 9px; background: #3fd2a5; border-radius: 50%; box-shadow: 0 0 0 4px rgba(63,210,165,.12); }
.sidebar .icon-button { color: #8f9db3; }
.main { min-width: 0; padding: 42px clamp(24px, 4vw, 64px) 64px; }
.mobile-head { display: none; }
/* Todo bloco de primeiro nivel da pagina se alinha pelo mesmo eixo, e o
   respiro entre eles e um so. Componentes nao carregam mais largura propria:
   um painel dentro de uma grade ocupa a coluna inteira, como deve. */
.main > * { max-width: var(--largura); margin-right: auto; margin-left: auto; }
.main > * + * { margin-top: var(--gap-secao); }

.page-header { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; }
.page-header p:last-child { margin: 0; max-width: 70ch; color: var(--muted); font-size: 13px; }
.page-header.compact { align-items: center; }
.back-link { display: inline-block; margin-bottom: 16px; color: var(--muted); font-size: 13px; text-decoration: none; }
.header-actions { display: flex; align-items: center; gap: 12px; }
.button { display: inline-flex; align-items: center; justify-content: center; gap: 10px; min-height: 42px; padding: 9px 16px; border: 1px solid transparent; border-radius: 7px; cursor: pointer; font-weight: 700; text-decoration: none; transition: transform .15s ease, background .15s ease, border .15s ease; }
.button:hover { transform: translateY(-1px); }
.button.primary { color: white; background: var(--blue); box-shadow: 0 6px 16px rgba(49,94,251,.18); }
.button.primary:hover { background: var(--blue-dark); }
.button.secondary { color: var(--ink); background: white; border-color: var(--line-strong); }
.button.quiet { color: var(--blue); background: transparent; border-color: var(--line); }
.button.danger { color: var(--red); background: #fff6f7; border-color: #f1c9ce; }
.button.small { min-height: 34px; padding: 6px 11px; font-size: 12px; }
.button.wide { width: 100%; }
.icon-button { display: inline-grid; width: 34px; height: 34px; place-items: center; padding: 0; color: var(--ink); background: transparent; border: 0; border-radius: 6px; cursor: pointer; }
.icon-button:hover { background: rgba(49,94,251,.08); }
.panel { padding: 20px 22px; background: var(--white); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); }
.panel-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.panel-head h2 { margin: 0; }
.signal-strip { display: grid; grid-template-columns: repeat(4, 1fr); overflow: hidden; background: white; border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); }
.signal-strip > div { display: flex; align-items: center; justify-content: space-between; min-height: 92px; padding: 20px 24px; border-right: 1px solid var(--line); }
.signal-strip > div:last-child { border: 0; }
.signal-strip span { color: var(--muted); font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; }
.signal-strip strong { font-family: var(--display); font-size: 32px; }
.dashboard-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: var(--gap-secao); }
.request-flow, .quick-start { padding: 26px; }
.status-dot { display: inline-flex; align-items: center; gap: 7px; color: var(--muted); font-family: var(--mono); font-size: 10px; }
.status-dot::before { width: 7px; height: 7px; background: var(--muted); border-radius: 50%; content: ""; }
.status-dot.ok::before { background: #24b77d; box-shadow: 0 0 0 4px #e2f6ee; }.status-dot.bad::before { background: var(--red); box-shadow: 0 0 0 4px #fbe7e9; }
.flow-track { display: grid; grid-template-columns: 1fr 46px 1fr 46px 1fr; align-items: center; margin-top: 38px; }
.flow-step { min-height: 160px; padding: 20px; background: #f8faff; border: 1px solid #dfe6f3; border-radius: 8px; }
.flow-step p { margin: 8px 0 0; color: var(--muted); font-size: 13px; }
.flow-code { display: block; margin-bottom: 24px; color: var(--blue); font-family: var(--mono); font-size: 11px; }
.flow-line { height: 1px; background: var(--line-strong); position: relative; }.flow-line i { position: absolute; right: 0; top: -3px; width: 7px; height: 7px; border-top: 1px solid var(--line-strong); border-right: 1px solid var(--line-strong); transform: rotate(45deg); }
.quick-start pre, .test-output { overflow: auto; padding: 18px; color: #c9daf8; background: #152139; border-radius: 7px; font-size: 12px; line-height: 1.8; }
.quick-start > p:not(.eyebrow) { color: var(--muted); font-size: 13px; }.quick-start > a { color: var(--blue); font-weight: 700; text-decoration: none; }
.flash, .error-summary { padding: 13px 17px; border-radius: 8px; }
.flash-success { color: #116449; background: #e7f8f1; border: 1px solid #b7e8d6; }.flash-error, .error-summary { color: #8d2934; background: #fff3f4; border: 1px solid #f0c5ca; }
/* O aviso do cálculo de metas não é erro nem sucesso: é uma divergência que
   alguém precisa ver e decidir. Sem esta regra ele saía sem cor nenhuma, e um
   recado importante ficava com a aparência de rodapé. */
.flash-warning { color: #8c651c; background: #fff8e8; border: 1px solid #f0dcae; }
/* E `info` e o recado que nao e nenhum dos tres: "nenhum parametro mudou". Ele
   existia e saia sem cor — o mesmo defeito que o aviso acima ja tinha. */
.flash-info { color: #2d4b7c; background: #eef4fd; border: 1px solid #c6d9f3; }

/* Os degraus da politica comercial, na tela e na ficha do CRM. Subir e ganhar
   desconto, descer e perder: as duas cores sao as do sucesso e do erro, porque
   e assim que o cliente sente a mudanca. */
.degrau { display: inline-block; min-width: 20px; padding: 1px 7px; border-radius: 10px; font-size: 12px; font-weight: 700; text-align: center; }
.degrau-subiu { color: #116449; background: #e7f8f1; }
.degrau-desceu { color: #8d2934; background: #fff3f4; }
.degrau-igual { color: var(--muted); background: var(--paper); }
.degrau-entrou { color: #116449; background: #e7f8f1; }
.degrau-saiu { color: #8d2934; background: #fff3f4; }
.degrau-fora { color: var(--muted); background: transparent; }
.error-summary strong { display: block; margin-bottom: 5px; }.error-summary p { margin: 3px 0; font-size: 13px; }
.table-panel { padding: 0; overflow: hidden; }
.table-tools { display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 12px 16px; color: var(--muted); border-bottom: 1px solid var(--line); font-size: 12px; }
/* A faixa de acao do lote, embaixo da tabela: a borda fica em cima, ao contrario
   de .table-tools, porque ela fecha a tabela em vez de abri-la. */
.table-lote { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; padding: 12px 16px; color: var(--muted); border-top: 1px solid var(--line); font-size: 12px; }
.table-lote > span:first-child { font-weight: 600; color: var(--ink-2); }
.table-lote small { color: var(--muted); }
/* Os dois botoes de uma linha de divergencia, lado a lado e sem quebrar. */
.acoes-linha { display: flex; gap: 6px; white-space: nowrap; }
/* Um produto da conferencia de aderencia, com todas as tabelas dele. */
.bloco-produto { border-top: 1px solid var(--line); }
.bloco-produto > header { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 10px 22px; padding: 12px 16px 8px; }
.bloco-produto > header strong { display: block; font-size: 14px; }
.bloco-produto > header small { color: var(--muted); font-size: 11px; }
.bloco-produto .numeros { display: flex; flex-wrap: wrap; gap: 22px; }
.bloco-produto .numeros span { display: block; font-family: var(--mono); font-size: 13px; text-align: right; }
.bloco-produto .numeros small { display: block; color: var(--muted); font-family: inherit; font-size: 10px; letter-spacing: .04em; text-transform: uppercase; }
.bloco-produto table { font-size: 12px; }
.bloco-produto td small { display: block; color: var(--muted); font-size: 10px; }
/* A linha que nao exige decisao fica presente e discreta: ela esta ali para
   mostrar o que QUEBRA se o preco do ERP for trazido para ca. */
.bloco-produto tr.quieta td { color: var(--muted); }
.bloco-produto tr.decidir td { background: rgba(255, 160, 3, .07); }
.search-field { display: flex; align-items: center; gap: 8px; width: min(360px, 60%); padding: 0 11px; background: var(--paper); border: 1px solid var(--line); border-radius: 7px; }
.search-field input { width: 100%; padding: 8px 0; background: transparent; border: 0; outline: 0; }
/* ------------------------------------------------------ a tabela que estoura

   A tabela mais larga que a tela rolava de lado por uma barra no FIM dela —
   que, numa tabela de trezentas linhas, fica no fim da pagina. Quem estivesse
   na linha 150 tinha de descer ate o fim, rolar de lado e voltar. Relatado pelo
   usuario em 23/10/2026.

   A correcao e dar ao involucro uma ALTURA MAXIMA. Com ela, a barra horizontal
   deixa de ser o fim da TABELA e passa a ser o fim da CAIXA: ela fica a vista
   o tempo todo enquanto se percorre a tabela.

   De quebra resolve a outra metade do mesmo problema, que o relato mostrava sem
   nomear: no meio de uma tabela larga, sem o cabecalho a vista, nao da para
   saber de que coluna e cada numero.

   Tabela curta nao muda em nada: `max-height` so corta o que passa dela, e sem
   corte nao ha barra nenhuma.

   `--altura-da-tabela` existe para a tela que precise de outro teto. Mudar o
   valor aqui muda todas de uma vez, que e a intencao. */
.table-wrap {
    overflow: auto;
    max-height: var(--altura-da-tabela, 72vh);
}

/* O cabecalho grudado no topo da caixa.
   A sombra faz o papel da borda: com `border-collapse: collapse` o navegador
   nao pinta a borda de um elemento grudado, e sem ela o cabecalho flutua sobre
   as linhas sem nada que o separe. */
.table-wrap thead th {
    position: sticky;
    top: 0;
    z-index: 2;
    box-shadow: inset 0 -1px 0 var(--line);
}

/* Cabecalho de DUAS linhas (a conferencia da grade, as faixas, o reajuste): a
   segunda linha grudaria no mesmo topo e cobriria a primeira. Enquanto nao
   houver motivo para acertar cada altura a mao, ela nao gruda — a rolagem
   lateral, que e o que foi pedido, continua valendo. */
.table-wrap thead:has(tr + tr) th { position: static; box-shadow: none; }

/* Na impressao nao existe rolagem: a altura maxima cortaria a tabela na
   primeira folha e o resto nao sairia. O cabecalho repetido por folha e o
   `display: table-header-group` que o navegador ja da ao `thead`. */
@media print {
    .table-wrap { overflow: visible; max-height: none; }
    .table-wrap thead th { position: static; box-shadow: none; }
}
table { width: 100%; border-collapse: collapse; }
/* 16px por celula era o espacamento de uma lista de meia duzia de endpoints.
   Nas telas de hoje — produtos, execucoes, comissoes — cada linha a mais e uma
   rolagem a mais, e a leitura horizontal piora, nao melhora. */
th, td { padding: 9px 16px; border-bottom: 1px solid var(--line); text-align: left; vertical-align: middle; }
th { color: var(--muted); background: #fbfcfe; font-family: var(--mono); font-size: 10px; letter-spacing: .06em; text-transform: uppercase; }
td { font-size: 13px; }td strong, td small { display: block; }td small { max-width: 380px; margin-top: 3px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }td code { color: var(--blue-dark); }
tr:last-child td { border-bottom: 0; }
.status-pill { display: inline-flex; align-items: center; padding: 4px 8px; border-radius: 20px; font-size: 10px; font-weight: 700; white-space: nowrap; }
.status-pill.published { color: #116449; background: #e4f7ef; }.status-pill.draft { color: #8c651c; background: #fff5dd; }.status-pill.off { color: var(--muted); background: #edf0f4; }
.version-tag { color: var(--ink-2); font-size: 12px; }
.empty-state { padding: 80px 30px; text-align: center; }.empty-state p { color: var(--muted); }.empty-glyph { display: grid; width: 54px; height: 54px; margin: 0 auto 18px; color: var(--blue); background: #edf1ff; border-radius: 50%; place-items: center; font-size: 24px; }
.editor-grid { display: grid; grid-template-columns: minmax(0, 1fr) 370px; gap: var(--gap-secao); align-items: start; }
.editor-main, .editor-side { display: grid; gap: 18px; min-width: 0; }
.editor-side { position: sticky; top: 24px; }
.form-panel { padding: 24px; }
.section-heading { display: flex; align-items: flex-start; gap: 14px; margin-bottom: 22px; }
.section-heading > span { display: grid; flex: 0 0 auto; width: 30px; height: 30px; color: var(--blue); background: #edf1ff; border-radius: 6px; place-items: center; font-family: var(--mono); font-size: 10px; font-weight: 700; }
.section-heading > div { flex: 1; }.section-heading h2, .section-heading p { margin: 0; }.section-heading p { color: var(--muted); font-size: 13px; }
label { display: grid; gap: 7px; margin-bottom: 16px; color: var(--ink-2); font-size: 12px; font-weight: 700; }
label small { color: var(--muted); font-weight: 400; }
input, select, textarea { width: 100%; padding: 10px 11px; color: var(--ink); background: white; border: 1px solid var(--line-strong); border-radius: 6px; outline: 0; transition: border .15s, box-shadow .15s; }
input:focus, select:focus, textarea:focus { border-color: var(--blue); box-shadow: 0 0 0 3px rgba(49,94,251,.1); }
textarea { resize: vertical; }
.grid-2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
.grid-3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
.input-prefix { display: flex; align-items: stretch; }.input-prefix span { display: flex; align-items: center; padding: 0 10px; color: var(--muted); background: var(--paper); border: 1px solid var(--line-strong); border-right: 0; border-radius: 6px 0 0 6px; font-family: var(--mono); font-size: 11px; }.input-prefix input { border-radius: 0 6px 6px 0; }
.filter-list { display: grid; gap: 10px; }
.filter-row { display: grid; grid-template-columns: 24px 1fr 1fr 130px 130px 100px 32px; align-items: end; gap: 9px; padding: 12px; background: #f8faff; border: 1px solid #e2e7f0; border-radius: 8px; }
.filter-row label { margin: 0; }.drag-handle { align-self: center; color: #9ba7b8; }.required-check { display: flex; align-items: center; gap: 7px; min-height: 42px; }.required-check input { width: auto; }.filter-row .remove { margin-bottom: 4px; color: var(--red); }
.sql-editor { position: relative; }.sql-editor > span { position: absolute; right: 12px; top: 11px; z-index: 2; color: #7f91ae; font-family: var(--mono); font-size: 10px; }.sql-editor textarea, [data-test-parameters] { color: #d7e3f8; background: #142039; border-color: #263654; border-radius: 8px; font-family: var(--mono); font-size: 13px; line-height: 1.7; tab-size: 2; }
.save-bar { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 8px 0 24px; }.save-bar p { margin: 0; color: var(--muted); font-size: 12px; }
.tester, .history { padding: 22px; }.tester > p { color: var(--muted); font-size: 13px; }.tester textarea { margin: 8px 0 12px; }.test-output { min-height: 180px; max-height: 420px; margin: 14px 0 0; white-space: pre-wrap; word-break: break-word; }
.side-empty { padding: 34px 18px; color: var(--muted); text-align: center; }.side-empty > span { display: block; margin-bottom: 10px; color: var(--blue); font-size: 28px; }.side-empty p { margin: 0; }
.version-list { display: grid; margin-top: 16px; }.version-item { position: relative; padding: 15px 0 15px 22px; border-left: 1px solid var(--line); }.version-item::before { position: absolute; left: -4px; top: 21px; width: 7px; height: 7px; background: white; border: 2px solid var(--blue); border-radius: 50%; content: ""; }.version-item > div { display: flex; align-items: center; justify-content: space-between; }.version-item > div span { padding: 2px 6px; color: #8c651c; background: #fff5dd; border-radius: 10px; font-size: 9px; }.version-item > div span.live { color: #116449; background: #e4f7ef; }.version-item p { margin: 5px 0 2px; font-size: 12px; }.version-item small { color: var(--muted); font-size: 10px; }.text-button { margin-top: 6px; padding: 0; color: var(--blue); background: none; border: 0; cursor: pointer; font-size: 11px; font-weight: 700; }
.split-grid { display: grid; grid-template-columns: minmax(280px, .65fr) minmax(0, 1.5fr); gap: var(--gap-secao); align-items: start; }.split-grid .table-panel { padding: 24px; }
.token-reveal { display: grid; grid-template-columns: 1fr 1.4fr; gap: 28px; padding: 22px 26px; color: white; background: var(--blue); border-radius: var(--radius); }.token-reveal h2 { margin-bottom: 4px; }.token-reveal p { margin: 0; color: #dce4ff; }.token-reveal .eyebrow { color: #aebfff; }.copy-field { display: flex; align-items: center; gap: 10px; min-width: 0; }.copy-field code { flex: 1; overflow: auto; padding: 12px; color: #dce4ff; background: rgba(9,25,79,.38); border-radius: 6px; white-space: nowrap; }
.token-list, .user-list { display: grid; margin: 16px -24px -24px; }.token-item, .user-item { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 14px; padding: 16px 24px; border-top: 1px solid var(--line); }.token-icon, .avatar { display: grid; width: 38px; height: 38px; color: var(--blue); background: #edf1ff; border-radius: 8px; place-items: center; font-weight: 800; }.token-item > div:nth-child(2), .user-item > div:nth-child(2) { display: grid; }.token-item code { margin: 2px 0; color: var(--muted); font-size: 11px; }.token-item small, .user-item small { color: var(--muted); font-size: 10px; }.user-item strong span { margin-left: 5px; color: var(--blue); font-size: 9px; text-transform: uppercase; }.avatar { color: white; background: var(--ink-2); border-radius: 50%; }
.status-switch { min-width: 64px; padding: 5px 9px; color: var(--muted); background: #edf0f4; border: 0; border-radius: 20px; cursor: pointer; font-size: 10px; font-weight: 700; }.status-switch.on { color: #116449; background: #e4f7ef; }.status-switch:disabled { cursor: not-allowed; opacity: .65; }
.swagger-panel { padding: 12px; }.swagger-panel .swagger-ui .topbar { display: none; }.swagger-loading { display: grid; min-height: 300px; place-items: center; align-content: center; color: var(--muted); }.swagger-loading span { width: 26px; height: 26px; border: 2px solid var(--line); border-top-color: var(--blue); border-radius: 50%; animation: spin .8s linear infinite; }
.error-page { max-width: 620px; margin: 10vh auto; padding: 40px; text-align: center; background: white; border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); }.error-page > span { display: grid; width: 52px; height: 52px; margin: 0 auto 20px; color: var(--red); background: #fff0f2; border-radius: 50%; place-items: center; font-size: 24px; }.error-page details { margin: 20px 0; text-align: left; }.error-page pre { overflow: auto; padding: 12px; background: var(--paper); }
.auth-body { min-height: 100vh; background: white; }.auth-panel { display: grid; grid-template-columns: 1.05fr .95fr; min-height: 100vh; }.auth-story { position: relative; display: flex; flex-direction: column; justify-content: space-between; overflow: hidden; padding: clamp(32px, 6vw, 80px); color: white; background: var(--nav); }.auth-story::after { position: absolute; right: -120px; bottom: -200px; width: 500px; height: 500px; border: 1px solid rgba(120,149,209,.15); border-radius: 50%; box-shadow: 0 0 0 80px rgba(70,99,160,.05), 0 0 0 160px rgba(70,99,160,.035); content: ""; }.auth-story h1 { max-width: 600px; font-size: clamp(3rem, 6vw, 5.6rem); line-height: .93; }.auth-story .eyebrow { color: #6f91ff; }.brand.light { color: white; }.auth-story .brand img { width: 158px; }
/* Os modulos do sistema, no painel do login. No lugar de `.pipeline-art`, que
   desenhava GET /produtos -> :fabricante -> { JSON }: a promessa certa de
   quando o projeto era uma API, e enganosa depois que ele virou o sistema de
   gestao da operacao comercial. */
.modulos-art { position: relative; z-index: 1; display: flex; flex-wrap: wrap; gap: 7px; max-width: 520px; color: #b9c7dc; font-size: 11.5px; }
.modulos-art span { padding: 7px 12px; border: 1px solid #27486e; border-radius: 999px; background: rgba(255,255,255,.03); }
.auth-form-wrap { display: grid; padding: 32px; place-items: center; }.auth-form { display: grid; width: min(400px, 100%); gap: 6px; }.auth-form h2 { font-size: 2rem; }.auth-form > div:first-child > p:last-child { color: var(--muted); }.field-error { margin-bottom: 12px; padding: 10px 12px; color: #8d2934; background: #fff3f4; border-radius: 6px; font-size: 12px; }
.install-body { background: #eef2f7; }.install-shell { max-width: 1120px; min-height: 100vh; margin: 0 auto; background: white; box-shadow: 0 0 80px rgba(24,35,56,.08); }.install-head { display: flex; align-items: center; justify-content: space-between; padding: 24px 42px; border-bottom: 1px solid var(--line); }.install-head .brand { color: var(--ink); }.install-step { color: var(--muted); font-size: 11px; }.install-step span { margin-left: 12px; color: var(--blue); font-family: var(--mono); }.install-form { padding: 46px clamp(24px, 6vw, 72px) 60px; }.page-intro { max-width: 650px; margin-bottom: 42px; }.page-intro h1 { font-size: clamp(2.6rem, 6vw, 4.5rem); }.page-intro > p:last-child { color: var(--muted); }.setup-section { display: grid; grid-template-columns: 42px 230px minmax(0,1fr); gap: 22px; padding: 30px 0; border-top: 1px solid var(--line); }.setup-number { display: grid; width: 36px; height: 36px; color: white; background: var(--blue); border-radius: 7px; place-items: center; font-family: var(--mono); font-weight: 700; }.setup-number.mysql { background: var(--amber); }.setup-number.sqlserver { background: var(--cyan); }.setup-number.admin { background: var(--ink-2); }.setup-copy p { color: var(--muted); font-size: 12px; }.setup-fields label { margin-bottom: 4px; }.check-stack { padding-top: 20px; }.check { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }.check input { width: auto; }.install-action { display: flex; align-items: center; justify-content: space-between; gap: 20px; padding-top: 26px; border-top: 1px solid var(--line); }.install-action p { margin: 0; color: var(--muted); font-size: 12px; }
@keyframes spin { to { transform: rotate(360deg); } }
@media (max-width: 1120px) { .editor-grid { grid-template-columns: 1fr; }.editor-side { position: static; grid-template-columns: 1fr 1fr; }.filter-row { grid-template-columns: 20px repeat(2,1fr) 100px; }.filter-row .required-check, .filter-row .remove { align-self: center; }.setup-section { grid-template-columns: 40px 1fr; }.setup-fields { grid-column: 2; }.dashboard-grid { grid-template-columns: 1fr; } }
@media (max-width: 820px) { .app-shell { grid-template-columns: 1fr; }.sidebar { position: fixed; left: -270px; width: 248px; transition: left .2s ease; box-shadow: 20px 0 40px rgba(0,0,0,.2); }.sidebar.open { left: 0; }.main { padding: 20px 18px 48px; }.mobile-head { display: flex; align-items: center; gap: 12px; margin: -4px 0 28px; }.page-header { align-items: flex-start; flex-direction: column; }.signal-strip { grid-template-columns: repeat(2,1fr); }.signal-strip > div:nth-child(2) { border-right: 0; }.signal-strip > div:nth-child(-n+2) { border-bottom: 1px solid var(--line); }.flow-track { grid-template-columns: 1fr; }.flow-line { width: 1px; height: 32px; margin-left: 26px; }.flow-line i { right: -3px; top: auto; bottom: 0; transform: rotate(135deg); }.split-grid, .token-reveal, .editor-side { grid-template-columns: 1fr; }.auth-panel { grid-template-columns: 1fr; }.auth-story { min-height: 42vh; }.auth-story h1 { font-size: 3.2rem; }.modulos-art { display: none; }.setup-section { grid-template-columns: 36px 1fr; }.grid-3 { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .grid-2, .grid-3 { grid-template-columns: 1fr; }.filter-row { grid-template-columns: 20px 1fr 32px; }.filter-row label { grid-column: 2; }.filter-row .remove { grid-column: 3; grid-row: 1; }.required-check { grid-column: 2 !important; }.header-actions, .save-bar, .install-action { align-items: stretch; flex-direction: column; }.signal-strip > div { min-height: 72px; padding: 15px; }.signal-strip strong { font-size: 25px; }.setup-fields { grid-column: 1 / -1; }.setup-copy p { display: none; }.install-head { padding: 20px; }.token-item { grid-template-columns: auto 1fr; }.token-item form, .token-item > .status-pill { grid-column: 2; justify-self: start; }.copy-field { align-items: stretch; flex-direction: column; } }
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { scroll-behavior: auto !important; transition: none !important; animation-duration: .001ms !important; } }


/* Indicador de ambiente na barra lateral.
   Em produção fica discreto; em desenvolvimento chama atenção de propósito,
   para que as duas instalações nunca sejam confundidas. */
.env-badge {
    margin: 0 1rem 0.75rem;
    padding: 0.55rem 0.75rem;
    border-radius: 0.6rem;
    border: 1px solid transparent;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    line-height: 1.25;
}

.env-badge strong {
    font-size: 0.72rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.env-badge small {
    font-size: 0.7rem;
    opacity: 0.75;
    overflow-wrap: anywhere;
}

.env-badge.env-dev {
    background: rgba(240, 173, 12, 0.14);
    border-color: rgba(240, 173, 12, 0.45);
    color: #f0ad0c;
}

.env-badge.env-prod {
    background: rgba(120, 140, 170, 0.12);
    border-color: rgba(120, 140, 170, 0.28);
}

/* Destaque de estado num painel. Usados nas telas de Precificacao e no
   editor de endpoints; sem estes, a caixa de erro ficava igual a de
   sucesso, e a secao de SQL nao se separava do resto do formulario. */
.panel-erro { border-color: rgba(198, 64, 76, .45); background: #fdf3f4; }
.panel-erro h2, .panel-erro h3 { color: var(--red); }
.panel-ok { border-color: rgba(25, 167, 160, .45); background: #f0faf9; }
.panel-ok h2, .panel-ok h3 { color: var(--cyan); }
/* E o terceiro caso: a pendencia que nao e erro do sistema e precisa de alguem.
   A reativacao pendente da politica comercial e isso — o cliente voltou a
   comprar e o cadastro ficou para tras. Em vermelho pareceria falha; sem cor,
   passaria batido no meio da tela. */
.panel-aviso { border-color: rgba(224, 169, 42, .5); background: #fffaf0; }
.panel-aviso h2, .panel-aviso h3 { color: #8c651c; }
.sql-section { margin-top: 18px; }
.sql-section > h2 { display: flex; align-items: center; justify-content: space-between; gap: 12px; }

/* Cartao que e um link inteiro — os modulos da tela inicial.
   Sem isto, tudo dentro do cartao (titulo, descricao, numeros e rotulos)
   saia sublinhado: a folha zera o sublinhado em .brand, .nav a, .button e
   .back-link, mas nao havia regra para um painel que tambem e link. */
a.panel { display: block; color: inherit; text-decoration: none; transition: border-color .15s ease, transform .15s ease; }
a.panel:hover { border-color: var(--blue); transform: translateY(-2px); }

/* Numeros de resumo dentro de um cartao. Antes a tela inicial reaproveitava
   .filter-row, que e uma grade de sete colunas fixas do editor de endpoints:
   os numeros caiam nas colunas erradas e os rotulos grudavam uns nos outros.

   Grade, e nao linha flexivel: com flex + wrap, quatro numeros num cartao
   estreito quebravam 3 + 1, e o cartao ao lado, com dois numeros, alinhava a
   base em outra altura. Colunas de largura igual deixam todos os cartoes com o
   mesmo rodape. */
.painel-numeros { display: grid; grid-template-columns: repeat(auto-fit, minmax(68px, 1fr)); gap: 10px 16px; margin-top: auto; padding-top: 4px; }
.painel-numeros > span { display: block; min-width: 0; }
.painel-numeros strong { display: block; font-family: var(--display); font-size: 1.6rem; line-height: 1.1; }
.painel-numeros small { display: block; margin-top: 2px; color: var(--muted); font-size: 11px; line-height: 1.25; }

/* Os cartoes da tela inicial tem alturas diferentes conforme o resumo.
   Esticar todos e o que alinha a base de cada coluna.

   O `margin: auto` e o `max-width` vem de .panel, que foi feito para um painel
   solto no meio da pagina. Dentro da grade eles cancelam o esticamento: o
   cartao passa a ter a largura do proprio conteudo e fica centralizado na
   coluna. Era por isso que a segunda fila — cartoes com menos texto — saia mais
   estreita e recuada que a primeira, com as bordas sem alinhar com nada. */
.dashboard-grid > .panel { display: flex; flex-direction: column; min-height: 176px; }
.cartao-descricao { margin: .35rem 0 .9rem; color: var(--ink-2); }
.cartao-abrir { margin-top: auto; color: var(--blue); font-weight: 700; }

/* O cartao de modulo tem duas partes: o topo, que e um link para a primeira
   tela que o perfil abre, e a lista de telas. Era um <a> embrulhando tudo, e os
   links das telas cairiam dentro dele — <a> dentro de <a> e invalido. */
.cartao-modulo { gap: 0; }
.cartao-topo { display: flex; flex: 1; flex-direction: column; color: inherit; text-decoration: none; }
.cartao-telas { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line); }
.cartao-telas a { padding: 4px 9px; color: var(--ink-2); background: var(--paper); border-radius: 6px; font-size: 12px; font-weight: 600; text-decoration: none; }
.cartao-telas a:hover { color: var(--white); background: var(--blue); }

/* ===========================================================================
   Componentes que faltavam
   ===========================================================================

   Três coisas vinham sendo improvisadas com `.filter-row`, que é a grade de
   sete colunas FIXAS do editor de endpoints. Ela não foi feita para mais nada,
   e o resultado aparecia na tela: na Precificação os quatro links do cabeçalho
   caíam em colunas separadas com os ícones quebrando para baixo; no cadastro de
   usuários o campo Nome ficava do tamanho de uma coluna de 24px e o botão
   Gravar montava em cima do campo Senha.

   O problema não era a folha: era não existir o componente certo. Abaixo estão
   os três que faltavam.
   =========================================================================== */

/* --- navegação do módulo ---------------------------------------------------
   A barra lateral leva ao MÓDULO; daí para dentro, cada módulo tem as suas
   telas. Precificação tem quatro (produtos, triagem, fabricantes, comissões),
   Relatórios tem seis, Usuários tem duas.

   Até agora cada um resolvia isso do seu jeito — Precificação com links soltos
   no cabeçalho, Relatórios com abas próprias na folha do módulo, Usuários com
   um link no canto. Três aparências para a mesma ideia, e nenhuma delas
   dizendo onde a pessoa está.

   É o componente que mais importa para o sistema crescer: módulo novo ganha a
   sua navegação sem inventar outra. */
.subnav {
    display: flex;
    flex-wrap: wrap;
    gap: 2px;
    padding: 4px;
    background: var(--white);
    border: 1px solid var(--line);
    border-radius: var(--radius);
}

.subnav a {
    padding: 7px 14px;
    color: var(--ink-2);
    border-radius: 7px;
    font-size: 13px;
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
    transition: background .15s ease, color .15s ease;
}

.subnav a:hover { color: var(--ink); background: var(--paper); }
.subnav a.ativo { color: var(--white); background: var(--blue); }

/* O que fica à direita — uma ação, não uma tela. */
.subnav .fim { margin-left: auto; display: flex; gap: 2px; align-items: center; }

/* --- linha de campos -------------------------------------------------------
   Campos lado a lado que sabem quebrar. Cada campo tem uma largura mínima e
   cresce até caber; quem não couber desce inteiro, com o rótulo junto — que era
   justamente o que a grade fixa não fazia. */
.linha-campos {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    align-items: start;
    gap: 14px;
}

.linha-campos > label { margin-bottom: 0; }

/* Campo que precisa de mais espaço que os outros (um e-mail, uma descrição). */
.linha-campos > .largo { grid-column: span 2; }

/* A ação fica no fim da linha, alinhada pela base dos campos — e não colada no
   campo anterior nem montada em cima dele. */
/* A acao acompanha a BASE dos campos, e nao o topo: e onde a mao vai depois de
   preencher o ultimo. */
.linha-campos > .acoes { display: flex; align-items: center; gap: 10px; align-self: end; padding-bottom: 1px; }

/* --- linha de ações ---------------------------------------------------------
   Botões, links ou marcadores em sequência. É o uso mais comum de todos, e era
   o que mais aparecia disfarçado de `.filter-row`: um formulário de uma linha
   com um campo e um botão, um grupo de filtros rápidos, um par Incluir/Excluir
   dentro de uma célula de tabela. */
.linha-acoes { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.linha-acoes > label { margin-bottom: 0; }
.linha-acoes input:not([type=checkbox]):not([type=radio]), .linha-acoes select { width: auto; min-width: 140px; }

/* --- barra de filtro -------------------------------------------------------
   Os selects de uma listagem. Mesma ideia da linha de campos, com o botão
   sempre ao lado e nunca para fora do painel — o "Limpar" da Precificação
   estava escapando da borda do cartão. */
.barra-filtro {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    padding: 12px 16px;
    border-bottom: 1px solid var(--line);
}

.barra-filtro > * { margin-bottom: 0; }
.barra-filtro select,
.barra-filtro input[type="text"],
.barra-filtro input[type="search"] { min-width: 170px; width: auto; }
.barra-filtro .cresce { flex: 1 1 200px; min-width: 0; }
.barra-filtro .marcador { display: inline-flex; align-items: center; gap: 7px; color: var(--ink-2); font-size: 12px; font-weight: 600; white-space: nowrap; }
.barra-filtro .marcador input { width: auto; }
/* Selecao de varios: altura fixa para a barra de filtro nao crescer com o
   cadastro, e rolagem propria quando ha mais fabricantes do que cabem. */
.barra-filtro select.multi { min-width: 190px; max-width: 260px; height: auto; padding: 4px; overflow-y: auto; }
.barra-filtro .fim { margin-left: auto; display: flex; align-items: center; gap: 8px; }

/* --- números de resumo -----------------------------------------------------
   Cinco cartões de 180px de altura para mostrar cinco números ocupavam uma tela
   inteira antes da tabela que eles resumem. Aqui os mesmos números cabem numa
   faixa, e continuam legíveis: o número grande, o rótulo pequeno, a explicação
   em uma linha.

   Cada item pode ser um link — na Precificação eles filtram a lista. */
.faixa-numeros {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(168px, 1fr));
    overflow: hidden;
    background: var(--white);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
}

.faixa-numeros > * {
    padding: 14px 18px;
    color: inherit;
    border-left: 1px solid var(--line);
    text-decoration: none;
}

.faixa-numeros > *:first-child { border-left: 0; }
.faixa-numeros a:hover { background: #f7f9ff; }
.faixa-numeros a.ativo { box-shadow: inset 0 -3px 0 var(--blue); }
.faixa-numeros .rotulo { display: block; color: var(--muted); font-family: var(--mono); font-size: 10px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; }
.faixa-numeros .valor { display: block; margin: 4px 0 2px; font-family: var(--display); font-size: 1.75rem; line-height: 1; }
.faixa-numeros .nota { display: block; color: var(--muted); font-size: 11px; line-height: 1.35; }
.faixa-numeros .valor.alerta { color: var(--amber); }
.faixa-numeros .valor.ruim { color: var(--red); }
.faixa-numeros .valor.bom { color: var(--cyan); }

/* --- caixa de aviso dentro da página ---------------------------------------
   Os dois blocos da Precificação (custo para a margem, publicar no MOINHO) eram
   painéis brancos iguais aos demais, e por isso se liam como conteúdo, não como
   aviso. Aqui a faixa colorida da esquerda diz o que é sem roubar a atenção. */
.aviso {
    padding: 14px 18px;
    background: var(--white);
    border: 1px solid var(--line);
    border-left: 3px solid var(--line-strong);
    border-radius: var(--radius);
}

.aviso p { margin: 0 0 6px; font-size: 13px; }
.aviso p:last-child { margin-bottom: 0; }
.aviso .acoes { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 12px; }
.aviso.atencao { border-left-color: var(--amber); }
.aviso.grave { border-left-color: var(--red); }
.aviso.ok { border-left-color: var(--cyan); }

@media (max-width: 820px) {
    .linha-campos > .largo { grid-column: auto; }
    .barra-filtro .fim { margin-left: 0; width: 100%; }
}

/* Bloqueios em planilha (/admin/metas/territorios/planilha).
   Duas colunas para os dois formatos de arquivo, a lista de avisos da prévia e o
   detalhe que guarda as linhas uma a uma — fechado por padrão, porque a conta por
   marca é o que se lê primeiro e a lista pode ter centenas de linhas. */
.grade-arquivos { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: var(--gap-secao); }
.grade-arquivos h3 { margin: 0 0 6px; font-size: 14px; }
.grade-arquivos p { margin: 0 0 10px; color: var(--muted); font-size: 13px; }
.grade-arquivos .button { margin-right: 6px; }

.lista-avisos { margin: 0; padding-left: 20px; color: var(--muted); font-size: 13px; }
.lista-avisos li { margin-bottom: 4px; }

.previa-linhas { margin-top: 14px; }
.previa-linhas summary { color: var(--blue); cursor: pointer; font-size: 13px; }
.previa-linhas .table-wrap { margin-top: 10px; border: 1px solid var(--line); border-radius: var(--radius); }

/* A saída da replicação disparada pela tela: é o mesmo texto que sai na linha de
   comando, e vale mostrar como está — quem opera já conhece esse relatório. */
.saida-rodada { max-height: 320px; overflow: auto; margin: 10px 0 0; padding: 12px; background: var(--paper); border-radius: 6px; font-size: 12px; line-height: 1.5; white-space: pre-wrap; }

/* A meta digitada na propria linha da tabela (/admin/metas/ciclo).
   Alinhado a direita porque numero se compara pela coluna da unidade, e estreito
   para nao empurrar as colunas de diagnostico fora da tela. A regra global
   `input, select, textarea { width: 100% }` da linha 143 espalharia o campo pela
   celula inteira; a classe sozinha ja vence em especificidade. */
.meta-na-linha { width: 110px; padding: 5px 8px; border: 1px solid var(--line-strong); border-radius: 6px; text-align: right; font-family: var(--mono); font-size: 13px; }
.meta-na-linha:focus { border-color: var(--blue); outline: 0; }
.meta-na-linha:disabled { color: var(--muted); background: var(--paper); }

.barra-metas { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; padding: 14px 16px; border-top: 1px solid var(--line); }
.barra-metas small { color: var(--muted); font-size: 12px; }

/* A conferencia do ajuste manual da meta (/admin/metas/ciclo com um fabricante
   filtrado). A cor diz em qual dos tres casos a soma esta, e e a mesma leitura
   que o servidor faz: fecha, difere dentro do limite, ou passa dele. */
.soma-ajuste { font-family: var(--mono); font-size: 12px; }
.soma-ajuste.fecha { color: var(--cyan); }
.soma-ajuste.tolerada { color: var(--amber); }
.soma-ajuste.acima { color: var(--red); font-weight: 700; }

/* O campo do ajuste manual herda a aparencia de `.meta-na-linha`; a classe propria
   existe para o JS achar os campos sem depender da aparencia, e marca a linha
   quando o valor sai do que o calculo produziu. */
.ajuste-meta:focus { border-color: var(--amber); }

/* A grade de precificacao.

   Uma linha por produto, celula editavel ao lado de celula calculada. O campo e
   discreto de proposito: numa tabela de vinte colunas, vinte caixas com borda
   grossa viram ruido e escondem justamente o que mudou. A marca de alterado e
   posta pelo JS (fundo ambar), e a classe existe para ele achar os campos sem
   depender da aparencia. */
.grade-campo { padding: 3px 5px; color: inherit; background: transparent; border: 1px solid transparent; border-radius: 5px; font: inherit; }
.grade-campo:hover { border-color: var(--line); }
.grade-campo:focus { background: #fff; border-color: var(--blue); outline: none; }

/* O botao do CUE, na coluna de custo da grade.
   Discreto de proposito: ele aparece em centenas de linhas, e um botao cheio
   em cada uma transformaria a tabela numa parede de botoes. Fica com cara de
   link ate o ponteiro chegar perto. */
.grade-cue { padding: 2px 6px; font: inherit; font-size: .8rem; color: var(--blue); background: transparent; border: 1px dashed var(--line); border-radius: 5px; cursor: pointer; white-space: nowrap; }
.grade-cue:hover { color: #fff; background: var(--blue); border-style: solid; border-color: var(--blue); }
.grade-cue:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; }
