/* =====================================================================
   PADRÃO VISUAL PCNET · CAMADA 2 — COMPONENTES

   Implementação de referência. Consome só --pk-* (pcnet-tokens.css) e não
   escreve nenhuma cor, raio ou duração à mão.

   ---------------------------------------------------------------------
   O TOKEN É O CONTRATO; A CLASSE É CONVENIÊNCIA.
   Um plugin legado que já tem .dc-card / .fp-card / .fw-card NÃO precisa
   renomear nada — precisa fazer aquelas classes consumirem --pk-* e bater
   com a receita daqui. Renomear classe é churn sem ganho visual; trocar o
   valor por token é o ganho inteiro. Código NOVO usa .pk-*.
   ---------------------------------------------------------------------

   Ordem: base → superfície → botão → formulário → status → navegação →
   feedback → responsivo. Cada bloco é independente: dá para apagar o que
   o projeto não usa.
   ===================================================================== */

/* =====================================================================
   BASE
   ===================================================================== */
.pk-app,
.pk-app *,
.pk-app *::before,
.pk-app *::after { box-sizing: border-box; }

.pk-app {
  font-family: var(--pk-font);
  font-size: var(--pk-text-md);
  line-height: var(--pk-leading);
  background: var(--pk-bg);
  color: var(--pk-ink);
  -webkit-font-smoothing: antialiased;
  -webkit-text-size-adjust: 100%;   /* iOS não reescala fonte ao girar o aparelho */
}

/* 🔴 TELA STANDALONE: a caixa é filha direta do <body>, e o <body> sem estilo
   traz a margem de 8px do navegador (2026-09-23). Era uma moldura BRANCA em
   volta de toda tela que emite o próprio <!DOCTYPE> — relatórios e métricas do
   dashboardpcnet, dashboard do firewall, visão geral e insights do wazuh —, que
   no escuro vira listra clara nas bordas e no rodapé, e deixava o cabeçalho
   fixo (que começa em x=0) "vazando" 8px à esquerda da caixa. O painel de TV
   escapava só porque tem `<body style="margin: 0">`.
   `:has(> .pk-app)` só casa com a standalone: dentro do layout do GLPI a caixa
   mora na .page-body, nunca como filha do <body>. O fundo acompanha o tema
   para a área abaixo de uma caixa mais curta que a janela. */
body:has(> .pk-app) {
  margin: 0;
  background: var(--pk-bg);
}

.pk-app h1, .pk-app h2, .pk-app h3, .pk-app h4 {
  font-family: var(--pk-font);
  font-weight: 700;
  letter-spacing: -.01em;
  line-height: var(--pk-leading-tight);
  color: var(--pk-ink);
}

.pk-app code, .pk-app kbd, .pk-mono { font-family: var(--pk-font-mono); }

/* Ícones de traço (Lucide, Tabler) escalam com o font-size do pai. O traço
   fino é parte da identidade: 1.75 no corpo, 1.6 quando o ícone é grande. */
.pk-app svg.lucide,
.pk-app svg.pk-icon {
  width: 1em; height: 1em;
  vertical-align: -.125em;
  stroke-width: 1.75;
  flex: none;
}

/* =====================================================================
   SUPERFÍCIES — painel e card
   A diferença entre os dois é intenção, não aparência: painel CONTÉM,
   card é CLICÁVEL. Card sem destino é painel.
   ===================================================================== */
/* VIDRO E FLUTUAÇÃO — o que o portal faz, e o padrão publicava sem usar.
   Até 2026-08-31 esta peça vinha `--pk-surface` opaca com `--pk-shadow-sm`
   (0 1px 3px, cinza), enquanto o `.fw-panel` do portal — a MESMA peça, é dele
   que esta veio — usa vidro a 72% e `0 16px 34px rgba(16,38,6,.42)`. Os dois
   valores já estavam nos tokens do host (`--pk-glass`, `--pk-shadow-rest`,
   inclusive redefinidos para o tema escuro); ninguém os tinha ligado à peça.
   É o que fazia o card do portal flutuar e o do plugin ficar colado. */
/* 🎨 `--pk-card-tom` (2026-09-24): o vidro aceita cor, como o botão aceita
   `--pk-btn-bg`. O plugin põe `--pk-card-tom: var(--pk-info)` na peça (ou num
   modificador dela) e o fundo e o fio saem tingidos; sem ele o `var()` cai no
   próprio vidro e a peça fica neutra, idêntica à de antes. A força do tom é
   `--pk-card-tom-forca` (8% no claro, 12% no escuro — medidos para a Tinta
   Fraca continuar ≥ 4,5:1 sobre as cores cheias da casa; ver o bloco CARD de
   pcnetui-forma.css). Pedido do dono: "cards de dashboard coloridos, com
   efeito de vidro". */
.pk-panel {
  background: color-mix(in srgb, var(--pk-card-tom, var(--pk-glass)) var(--pk-card-tom-forca, 8%), var(--pk-glass));
  -webkit-backdrop-filter: blur(16px) saturate(1.3);
          backdrop-filter: blur(16px) saturate(1.3);
  border: 1px solid color-mix(in srgb, var(--pk-card-tom, var(--pk-hairline)) 35%, var(--pk-hairline));
  border-radius: var(--pk-radius);
  box-shadow: var(--pk-shadow-rest);
  padding: var(--pk-space-in);
}
.pk-panel + .pk-panel { margin-top: 20px; }

.pk-panel__head  { margin-bottom: var(--pk-sp-4); }
.pk-panel__title {
  font-size: var(--pk-text-2xl);
  font-weight: 700;
  color: var(--pk-ink);
  display: flex; align-items: center; gap: var(--pk-sp-2);
}
.pk-panel__sub {
  color: var(--pk-ink-2);
  font-size: var(--pk-text-base);
  margin-top: 4px;
}

.pk-card {
  background: color-mix(in srgb, var(--pk-card-tom, var(--pk-glass)) var(--pk-card-tom-forca, 8%), var(--pk-glass));
  -webkit-backdrop-filter: blur(16px) saturate(1.3);
          backdrop-filter: blur(16px) saturate(1.3);
  border: 1px solid color-mix(in srgb, var(--pk-card-tom, var(--pk-hairline)) 35%, var(--pk-hairline));
  border-radius: var(--pk-radius);
  box-shadow: var(--pk-shadow-rest);
  padding: 22px;
  text-decoration: none;
  color: inherit;
  cursor: pointer;
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-areas: "icon title" "icon desc";
  align-items: center;
  column-gap: var(--pk-sp-4);
  row-gap: var(--pk-sp-1);
  /* Lista explícita, nunca `transition: all`: o `all` anima também largura e
     posição quando o layout reflui, e o card "escorrega" ao redimensionar. */
  transition: border-color var(--pk-ease), box-shadow var(--pk-ease),
              background-color var(--pk-ease);
}
.pk-card:hover {
  background: color-mix(in srgb, var(--pk-card-tom, var(--pk-glass-2)) var(--pk-card-tom-forca, 8%), var(--pk-glass-2));
  border-color: color-mix(in srgb, var(--pk-card-tom, var(--pk-hairline-hover)) 45%, var(--pk-hairline-hover));
  box-shadow: var(--pk-shadow-float);
}
.pk-card:focus-visible { outline: 3px solid var(--pk-green); outline-offset: 2px; }

.pk-card__icon {
  grid-area: icon;
  width: 54px; height: 54px;
  border-radius: var(--pk-radius-sm);
  display: grid; place-items: center;
  background: var(--pk-green-soft);
  color: var(--pk-green-dark);
  font-size: 27.5px;
}
.pk-card__title { grid-area: title; align-self: end;   font-size: var(--pk-text-xl); font-weight: 700; }
.pk-card__desc  { grid-area: desc;  align-self: start; font-size: var(--pk-text-md); color: var(--pk-ink-2); }

/* Card em destaque: gradiente branco→verde suave. UM por tela — dois destaques
   são zero destaques. */
.pk-card--primary {
  background: linear-gradient(135deg, var(--pk-surface) 0%, var(--pk-green-soft) 100%);
  border-color: var(--pk-green-line);
}
.pk-card--primary .pk-card__icon  { background: var(--pk-green); color: var(--pk-on-green); }
.pk-card--primary .pk-card__title { color: var(--pk-green-ink); }

/* Card SEM ícone: a coluna do ícone some (é `auto`, zero de largura), mas o
   `column-gap` de 21px ficava, e o título começava 39px da borda em vez de
   18 — medido no espécime "Equipamentos" do Blueprint (2026-09-23). Sem ícone
   a grade tem uma coluna só. */
.pk-card:not(:has(> .pk-card__icon)) {
  grid-template-columns: 1fr;
  grid-template-areas: "title" "desc";
}

.pk-card--compact { padding: 18px; }
.pk-card--compact .pk-card__icon  { width: 42px; height: 42px; font-size: 20.5px; }
.pk-card--compact .pk-card__title { font-size: var(--pk-text-md); }

.pk-grid       { display: grid; gap: var(--pk-space); }
.pk-grid--2    { grid-template-columns: repeat(2, 1fr); }
.pk-grid--auto { grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); }

/* =====================================================================
   BOTÕES
   ===================================================================== */

/* Os quatro parâmetros de cor do botão, com o valor da casa por omissão.
   🔴 Declarados AQUI e não como fallback inline (`var(--x, --pk-green)`), e a
   diferença foi medida em 2026-08-26: o indexador de alias do Blueprint casa
   `--x: var(--pk-y)` por regex (inc/alcance.class.php:170) e resolve a cadeia
   antes de comparar duas regras. Com o fallback inline ele não enxergava a
   indireção, o `.pk-btn` passou a declarar um `background` que nenhum outro
   botão verde do parque declarava, e — como `background` é uma das três
   propriedades com VETO na similaridade (inc/variante.class.php:774) — a peça
   oficial deixou de agrupar com os botões que ela deveria representar: de 6
   plugins para 1. A trava de calibração pegou na hora.

   Também não ficam em pcnetui-forma.css: aquela camada é opt-in, e um
   consumidor que não a pedisse ficaria com botão SEM FUNDO. Ficam ao lado da
   peça que os consome. */
:root {
  --pk-btn-bg:       var(--pk-green);         /* @param */
  --pk-btn-fg:       var(--pk-on-green);      /* @param */
  --pk-btn-bg-hover: var(--pk-green-hover);   /* @param */
  --pk-btn-fg-hover: var(--pk-on-green);      /* @param */
}

.pk-btn {
  font-family: var(--pk-font);
  font-size: var(--pk-text-md);
  font-weight: 700;
  letter-spacing: .3px;
  padding: 12px 24px;
  border: none;
  border-radius: var(--pk-radius-sm);
  cursor: pointer;
  /* 🔴 A COR É PARÂMETRO, A FORMA NÃO — mudado em 2026-08-26, e é a razão de
     o parque nunca ter adotado esta peça. Enquanto o verde estava cimentado
     aqui, quem tinha um botão vermelho não conseguia usar `.pk-btn` sem
     sobrescrever — e sobrescrever é exatamente como se cria retalho. Medido:
     9 usos desta classe fora deste plugin, em 1 plugin só, contra 16 nomes
     próprios de botão no parque.

     Com o par --pk-btn-bg/--pk-btn-fg, migrar vira SUBTRAÇÃO: apaga-se o que
     é forma da regra local e deixa-se o background/color, que era legítimo.

     ⚠️ Os dois andam JUNTOS de propósito, e não há derivação automática do
     texto a partir do fundo. Tentar adivinhar erra: uma tinta calculada para
     cair bem sobre fundo claro fica ilegível sobre um vermelho escuro, e não
     existe função CSS com suporte para escolher entre claro e escuro. Quem
     troca o fundo declara a tinta; quem trocar só um dos dois é apontado pela
     aba Decidir, que mede o contraste dos dois temas. */
  background: var(--pk-btn-bg);
  color:      var(--pk-btn-fg);
  box-shadow: var(--pk-shadow-green);
  display: inline-flex; align-items: center; gap: var(--pk-sp-2);
  min-height: 44px;   /* alvo de toque da diretriz da Apple — vale em qualquer tela */
  /* 🔴 `all`, e não a lista. A lista que estava aqui cobria `background`,
     `box-shadow` e `transform` — e o modificador --ghost, 25 linhas abaixo,
     muda `color` E `border-color` no hover: nenhuma das duas animava. A borda
     do ghost saltava de cor enquanto a do .pk-iconbtn deslizava, no mesmo
     arquivo, e nenhum print mostra isso. Trocar `all` por lista é otimização
     real quando há risco de animar layout; aqui não há, e o custo dela é
     transformar uma regra uniforme por construção em uma que depende de
     alguém lembrar de cada propriedade que uma variante futura vá mexer. */
  transition: all var(--pk-ease);
}
/* O hover escurece UM degrau, não até --pk-green-dark: aquele fundo dá 3.75:1
   com branco e 3.42:1 com --pk-on-green — o botão ficaria ilegível justamente
   enquanto está sob o cursor. --pk-green-hover mantém 5.37:1 com o mesmo texto. */
/* O hover lê o parâmetro pelo mesmo motivo que o repouso. Sem isto, uma
   variante que trocasse só `--pk-btn-bg` voltaria ao VERDE ao passar o mouse:
   esta regra é (0,2,0), igual à do modificador, e vence ou perde por ordem —
   detalhe que só aparece com o cursor em cima, nunca num print. */
.pk-btn:hover  { background: var(--pk-btn-bg-hover);
                 color: var(--pk-btn-fg-hover);
                 transform: translateY(-2px); box-shadow: var(--pk-shadow-green-hover); }
.pk-btn:active { transform: translateY(0); }
/* Um anel, não dois. Até 2026-08-26 esta linha desenhava `box-shadow:
   var(--pk-focus)` — verde a 25% de alfa, ~1,2:1 contra o card — enquanto
   `pcnetui-forma.css` desenhava por cima um `outline` de 3px em
   --pk-green-dark (3,75:1). Duas marcas de foco, de cores diferentes, no
   mesmo botão. Fica o outline, que é o que passa na medição e o que não é
   cortado por `overflow: hidden`. O fallback repete o valor porque a camada
   `forma` é opt-in: sem ela, o botão continuaria sem anel nenhum. */
.pk-btn:focus-visible {
  outline: var(--pk-ring, 3px solid var(--pk-green-dark));
  outline-offset: var(--pk-ring-offset, 2px);
}
.pk-btn[disabled] { opacity: .6; cursor: not-allowed; transform: none; }

/* As variantes são só COR — a forma inteira vem do .pk-btn acima. É o modelo
   que um plugin deve copiar ao migrar: declare o par, não redeclare a peça. */
.pk-btn--danger {
  --pk-btn-bg: var(--pk-danger);
  --pk-btn-fg: var(--pk-on-dark);
  box-shadow: none;
}
.pk-btn--danger:hover { --pk-btn-bg-hover: var(--pk-danger-ink);
                        --pk-btn-fg-hover: var(--pk-on-dark);
                        box-shadow: none; }

/* =====================================================================
   O GHOST E O BOTÃO DE ÍCONE SÃO A MESMA PEÇA, EM DUAS FORMAS

   Medido em 2026-08-26: os dois declaravam, separadamente, o mesmo
   `--pk-surface`, a mesma `1px solid --pk-border` e a mesma `--pk-ink-2` —
   e discordavam em três detalhes que ninguém decidiu, porque discordar era
   possível. Declarar o comum UMA vez torna a deriva impossível daqui em
   diante; o que os distingue fica logo abaixo, explícito.

   ⚠️ As três discordâncias continuam com os valores de hoje, DE PROPÓSITO:
   mudá-las altera produção e é decisão do dono, não efeito colateral de uma
   refatoração. São o primeiro item que a aba Decidir aponta:
     1. sombra em repouso ...... ghost `none`      × ícone `--pk-shadow-sm`
     2. gesto no hover ......... ghost não levanta × ícone levanta 1px
     3. borda no hover ......... ghost `--pk-green` × ícone `--pk-border-hover`
   ===================================================================== */
.pk-btn--ghost,
.pk-iconbtn {
  --pk-btn-bg: var(--pk-surface);
  --pk-btn-fg: var(--pk-ink-2);
  --pk-btn-bg-hover: var(--pk-surface);
  --pk-btn-fg-hover: var(--pk-green-ink);
  background: var(--pk-btn-bg);
  color: var(--pk-btn-fg);
  border: 1px solid var(--pk-border);
}
.pk-btn--ghost:hover,
.pk-iconbtn:hover {
  --pk-btn-fg: var(--pk-green-ink);
  color: var(--pk-btn-fg);
}

/* O que distingue o ghost: ele vive no fluxo do formulário, chapado. */
.pk-btn--ghost        { box-shadow: none; }
.pk-btn--ghost:hover  { --pk-btn-bg-hover: var(--pk-surface);
                        --pk-btn-fg-hover: var(--pk-green-ink);
                        background: var(--pk-surface); border-color: var(--pk-green);
                        transform: none; box-shadow: none; }

/* O que distingue o botão de ícone: é quadrado, sem rótulo, e vive na barra. */
.pk-iconbtn {
  width: 40px; height: 40px;
  border-radius: var(--pk-radius-sm);
  display: grid; place-items: center;
  cursor: pointer;
  box-shadow: var(--pk-shadow-sm);
  transition: all var(--pk-ease);
}
.pk-iconbtn:hover  { border-color: var(--pk-border-hover);
                     box-shadow: var(--pk-shadow-md); transform: translateY(-1px); }
.pk-iconbtn svg    { color: var(--pk-green-dark); }

/* O botão de ícone precisa do MESMO anel do .pk-btn — não tinha nenhum, nem
   aqui nem no portal, e é o alvo mais difícil de achar sem rótulo. */
.pk-iconbtn:focus-visible {
  outline: var(--pk-ring, 3px solid var(--pk-green-dark));
  outline-offset: var(--pk-ring-offset, 2px);
}

/* =====================================================================
   FORMULÁRIO
   ===================================================================== */
.pk-field { display: flex; flex-direction: column; gap: var(--pk-sp-2); margin-bottom: var(--pk-sp-4); }

.pk-label {
  font-size: var(--pk-text-base);
  font-weight: 600;
  color: var(--pk-ink);
  display: flex; align-items: center; gap: var(--pk-sp-1);
}
/* O asterisco e a mensagem de erro são TEXTO, e texto sai do -ink
   (Ink-Not-Fill Rule). Com a cor cheia davam 3,35:1 no escuro (.pk-req do
   lansentinelbackups) e 4,27 / 3,68:1 (.pk-field-error no Blueprint). O -ink
   muda por tema: 5,81:1 sobre o fundo claro, 6,45:1 sobre o card escuro. */
.pk-req  { color: var(--pk-danger-ink); font-weight: 700; }
.pk-opt  { color: var(--pk-ink-3); font-weight: 400; font-size: var(--pk-text-sm); }
.pk-hint { font-size: var(--pk-text-sm); color: var(--pk-ink-3); margin-top: -2px; }

.pk-input,
.pk-textarea,
.pk-select {
  width: 100%;
  font-family: var(--pk-font);
  font-size: var(--pk-text-md);
  color: var(--pk-ink);
  background: var(--pk-surface);
  border: 1px solid var(--pk-border);
  border-radius: var(--pk-radius-sm);
  padding: 12px 15px;
  outline: none;
  transition: border-color var(--pk-ease), box-shadow var(--pk-ease);
}
.pk-textarea { min-height: 300px; resize: vertical; line-height: var(--pk-leading-loose); }
.pk-input::placeholder, .pk-textarea::placeholder { color: var(--pk-ink-3); }

.pk-input:focus, .pk-textarea:focus, .pk-select:focus {
  border-color: var(--pk-green);
  box-shadow: var(--pk-focus);
}

.pk-field.has-error .pk-input,
.pk-field.has-error .pk-textarea,
.pk-field.has-error .pk-select {
  border-color: var(--pk-danger);
  box-shadow: var(--pk-focus-danger);
}
/* O erro vive DENTRO do campo, junto do rótulo — não num resumo lá em cima.
   Resumo no topo obriga a pessoa a memorizar o que corrigir e rolar de volta. */
.pk-field-error {
  font-size: var(--pk-text-base);
  color: var(--pk-danger-ink);
  display: none; align-items: center; gap: var(--pk-sp-1);
}
.pk-field.has-error .pk-field-error { display: flex; }

/* Radio/checkbox como cartão selecionável: alvo grande e estado óbvio. */
.pk-radios { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: var(--pk-sp-2); }
.pk-radio  { position: relative; }
.pk-radio input { position: absolute; opacity: 0; }
.pk-radio label {
  display: flex; align-items: center; justify-content: center; gap: var(--pk-sp-2);
  padding: 12px;
  border: 1px solid var(--pk-border);
  border-radius: var(--pk-radius-sm);
  cursor: pointer;
  font-size: var(--pk-text-base); font-weight: 500;
  color: var(--pk-ink-2);
  background: var(--pk-surface);
  min-height: 44px;
  transition: border-color var(--pk-ease), color var(--pk-ease), background-color var(--pk-ease);
}
.pk-radio label:hover { border-color: var(--pk-border-hover); color: var(--pk-ink); }
.pk-radio input:checked + label {
  border-color: var(--pk-green);
  color: var(--pk-green-ink);
  background: var(--pk-green-soft);
  font-weight: 600;
}
.pk-radio input:focus-visible + label { outline: 3px solid var(--pk-green); outline-offset: 2px; }

/* Zona de upload — caixa tracejada. O widget cru do navegador destoa a ponto
   de o usuário achar que a tela está quebrada. */
.pk-dropzone {
  border: 1px dashed var(--pk-border-hover);
  border-radius: var(--pk-radius-sm);
  background: var(--pk-surface-2);
  padding: 18px;
  text-align: center;
  color: var(--pk-ink-2);
}
.pk-file {
  display: flex; align-items: center; gap: var(--pk-sp-2);
  padding: 10px 12px;
  background: var(--pk-surface-2);
  border: 1px solid var(--pk-border);
  border-radius: var(--pk-radius-sm);
  font-size: var(--pk-text-base);
}
.pk-file__name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pk-file__size { color: var(--pk-ink-3); font-size: var(--pk-text-sm); }

/* =====================================================================
   STATUS E BADGE
   Pílula: fundo suave + texto escuro da mesma família. Ver a regra em
   pcnet-tokens.css seção 10 — cor sozinha nunca comunica estado.
   ===================================================================== */
.pk-status {
  font-family: var(--pk-font);
  font-size: var(--pk-text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .4px;
  padding: 4px 10px;
  border-radius: var(--pk-radius-pill);
  white-space: nowrap;
  display: inline-flex; align-items: center; gap: var(--pk-sp-1);   /* o gap é do ÍCONE obrigatório */
}
.pk-status--novo        { background: var(--pk-st-novo-bg);        color: var(--pk-st-novo-ink); }
.pk-status--andamento   { background: var(--pk-st-andamento-bg);   color: var(--pk-st-andamento-ink); }
.pk-status--pendente    { background: var(--pk-st-pendente-bg);    color: var(--pk-st-pendente-ink); }
.pk-status--solucionado { background: var(--pk-st-solucionado-bg); color: var(--pk-st-solucionado-ink); }
.pk-status--fechado     { background: var(--pk-st-fechado-bg);     color: var(--pk-st-fechado-ink); }

.pk-badge {
  border-radius: var(--pk-radius-pill);
  font-family: var(--pk-font);
  font-weight: 700;
  letter-spacing: .3px;
  padding: .35em .8em;
  background: var(--pk-green-soft);
  color: var(--pk-green-ink);
}

.pk-chip {
  display: inline-flex; align-items: center; gap: var(--pk-sp-2);
  background: var(--pk-green-soft);
  border: 1px solid var(--pk-green-line);
  color: var(--pk-green-ink);
  border-radius: var(--pk-radius-pill);
  padding: 6px 14px;
  font-size: var(--pk-text-base); font-weight: 600;
}

/* Linha de item (chamado, registro): moldura verde inteira e nada de tabela.
   Até 2026-08-20 a linha levava `border-left: 4px solid var(--pk-green)` como
   acento lateral. Saiu por decisão do dono do produto: a tarja de um lado só
   "dá cara de IA" — é o enfeite que todo gerador de tela repete, e não comunica
   nada (a mesma cor aparecia em toda linha, fosse qual fosse o estado).
   No lugar entra a borda dos cards do menu do dashboardpcnet, que já é o
   tratamento aprovado da casa: moldura de 2px no perímetro INTEIRO, raio de
   card e elevação — o contorno delimita a linha em vez de decorar uma aresta,
   e o verde só acende de verdade sob o cursor. */
.pk-row {
  border: 2px solid var(--pk-green-line);
  border-radius: var(--pk-radius);
  background: var(--pk-surface);
  box-shadow: var(--pk-shadow-sm);
  padding: 16px 20px;
  display: flex; align-items: flex-start; gap: var(--pk-sp-3);
  text-decoration: none; color: inherit; cursor: pointer;
  transition: border-color var(--pk-ease), box-shadow var(--pk-ease);
}
/* O repouso já é verde, então o hover não pode ser --pk-hairline-hover (oliva a
   24%): ficaria mais APAGADO que o estado normal. Acende para o verde cheio,
   como o card do menu do dashboardpcnet faz. */
.pk-row:hover  { border-color: var(--pk-green); box-shadow: var(--pk-shadow-md); }
.pk-row__id    { font-family: var(--pk-font-mono); font-size: var(--pk-text-base);
                 font-weight: 700; color: var(--pk-green-ink); }
.pk-row__title { font-size: var(--pk-text-md); font-weight: 600; }
.pk-row__meta  { font-size: var(--pk-text-sm); color: var(--pk-ink-3); }

/* =====================================================================
   NAVEGAÇÃO
   ===================================================================== */
.pk-nav      { display: flex; align-items: center; gap: var(--pk-sp-1); }
.pk-nav__item {
  font-family: var(--pk-font);
  font-size: var(--pk-text-base); font-weight: 600;
  color: var(--pk-ink-2);
  background: none; border: none; cursor: pointer;
  padding: 8px 14px;
  border-radius: var(--pk-radius-xs);
  display: inline-flex; align-items: center; gap: var(--pk-sp-2);
  transition: background-color var(--pk-ease), color var(--pk-ease);
}
.pk-nav__item:hover      { background: var(--pk-surface-2); color: var(--pk-ink); }
.pk-nav__item.is-active  { background: var(--pk-green-soft); color: var(--pk-green-ink); }

/* Toggle segmentado — a alternativa honesta a duas abas quando são só dois modos. */
.pk-toggle {
  display: inline-flex;
  background: var(--pk-surface-2);
  border: 1px solid var(--pk-border);
  border-radius: var(--pk-radius-sm);
  padding: 4px; gap: var(--pk-sp-1);
}
.pk-toggle button {
  font-family: var(--pk-font);
  font-size: var(--pk-text-base); font-weight: 600;
  color: var(--pk-ink-2);
  background: none; border: none; cursor: pointer;
  padding: 8px 16px;
  border-radius: var(--pk-radius-xs);
  display: inline-flex; align-items: center; gap: var(--pk-sp-2);
  /* `box-shadow` estava fora desta lista e `.is-active` logo abaixo o muda: a
     pastilha ativa ganhava a sombra num salto enquanto a cor deslizava. Mesma
     origem do defeito do --ghost. */
  transition: all var(--pk-ease);
}
.pk-toggle button.is-active {
  background: var(--pk-surface);
  color: var(--pk-green-ink);
  box-shadow: var(--pk-shadow-sm);
}

/* Stepper de wizard. O rótulo some em ≤600px; o ponto fica. */
.pk-stepper   { display: flex; align-items: center; margin-bottom: var(--pk-sp-4); }
.pk-step      { display: flex; align-items: center; gap: var(--pk-sp-2); flex: 1; }
.pk-step__dot {
  width: 30px; height: 30px;
  border-radius: 50%;
  display: grid; place-items: center;
  background: var(--pk-surface-2);
  border: 2px solid var(--pk-border);
  color: var(--pk-ink-3);
  font-weight: 700; font-size: var(--pk-text-base);
  flex-shrink: 0;
  transition: background-color var(--pk-ease), border-color var(--pk-ease), color var(--pk-ease);
}
.pk-step__label { font-size: var(--pk-text-base); font-weight: 600; color: var(--pk-ink-3); white-space: nowrap; }
.pk-step__line  { flex: 1; height: 2px; background: var(--pk-border); margin: 0 12px; border-radius: 2px; }
.pk-step.is-active .pk-step__dot   { background: var(--pk-green); border-color: var(--pk-green); color: var(--pk-on-green); }
.pk-step.is-active .pk-step__label { color: var(--pk-ink); }
.pk-step.is-done .pk-step__dot     { background: var(--pk-green-soft); border-color: var(--pk-green); color: var(--pk-green-ink); }
.pk-step.is-done .pk-step__label   { color: var(--pk-green-ink); }

/* Painel suspenso: menu de usuário, launcher, combobox. Nasce invisível e
   sem eventos — `display:none` não é animável, `opacity + pointer-events` é. */
.pk-pop {
  position: absolute; top: calc(100% + 10px); right: 0;
  width: 280px; max-width: 92vw;
  background: var(--pk-surface);
  border: 1px solid var(--pk-border);
  border-radius: var(--pk-radius);
  box-shadow: var(--pk-shadow-lg);
  padding: 10px;
  opacity: 0; transform: translateY(-8px) scale(.98); pointer-events: none;
  transition: opacity var(--pk-ease-fast), transform var(--pk-ease);
  z-index: 300;
}
.is-open > .pk-pop { opacity: 1; transform: none; pointer-events: auto; }
.pk-pop__item {
  display: flex; align-items: center; gap: var(--pk-sp-2);
  padding: 10px;
  border-radius: var(--pk-radius-xs);
  text-decoration: none;
  color: var(--pk-ink);
  font-size: var(--pk-text-base); font-weight: 500;
  transition: background-color var(--pk-ease);
}
.pk-pop__item:hover { background: var(--pk-green-soft); }
.pk-pop__item svg   { width: 18px; height: 18px; color: var(--pk-green-dark); }
.pk-pop__item--danger        { color: var(--pk-danger-ink); }
.pk-pop__item--danger svg    { color: var(--pk-danger-ink); }
.pk-pop__item--danger:hover  { background: var(--pk-danger-soft); }
.pk-pop__sep { height: 1px; background: var(--pk-border); margin: 8px 4px; }

/* =====================================================================
   TABELA
   Quando a lista PRECISA ser tabela (muitas colunas comparáveis), tira-se o
   ar de back-office: cabeçalho sem peso, linha com respiro, hover verde.
   Para menos de 5 campos por item, prefira .pk-row.
   ===================================================================== */
.pk-table { width: 100%; border-collapse: collapse; font-family: var(--pk-font); }
.pk-table thead th {
  font-weight: 700;
  font-size: .82rem;
  letter-spacing: .5px;
  text-transform: uppercase;
  color: var(--pk-ink-3);
  background: transparent;
  border-bottom: 1px solid var(--pk-hairline);
  padding: 10px 12px;
  text-align: left;
}
.pk-table tbody td { padding: 12px; border-bottom: 1px solid var(--pk-border); }
.pk-table tbody tr:hover > * { background: var(--pk-green-soft); }

/* =====================================================================
   FEEDBACK — alerta, nota e toast
   ===================================================================== */
.pk-alert {
  border-radius: var(--pk-radius);
  border: 1px solid;
  padding: 14px 18px;
  display: flex; gap: var(--pk-sp-2); align-items: flex-start;
  font-size: var(--pk-text-sm);
  line-height: var(--pk-leading);
}
.pk-alert--info    { background: var(--pk-info-soft);    border-color: var(--pk-info-line);    color: var(--pk-info-ink); }
.pk-alert--warning { background: var(--pk-warning-soft); border-color: var(--pk-warning-line); color: var(--pk-warning-ink); }
.pk-alert--danger  { background: var(--pk-danger-soft);  border-color: var(--pk-danger-line);  color: var(--pk-danger-ink); }
.pk-alert--success { background: var(--pk-green-soft);   border-color: var(--pk-green-line);   color: var(--pk-green-ink); }

/* Link dentro de alerta herda a cor do alerta, nunca o verde global: verde
   sobre fundo vermelho-claro é ilegível, e é acessibilidade, não estética. */
.pk-alert a { color: inherit; text-decoration: underline; font-weight: 700; }

.pk-toast-wrap {
  position: fixed; top: 78px; right: 24px;
  z-index: 10005;
  display: flex; flex-direction: column; gap: var(--pk-sp-2);
}
/* Mesma troca da .pk-row: o acento de 4px à esquerda (verde no toast comum,
   vermelho no de erro) saiu por rejeição do dono do produto. A intensidade não
   diminuiu, só mudou de lugar — o verde cheio que ocupava uma aresta agora
   contorna o toast inteiro, que é o que faz um aviso passageiro ser notado. */
.pk-toast {
  background: var(--pk-surface);
  border: 2px solid var(--pk-green);
  border-radius: var(--pk-radius-sm);
  padding: 14px 18px;
  box-shadow: var(--pk-shadow-lg);
  display: flex; align-items: center; gap: var(--pk-sp-3);
  min-width: 280px; max-width: 380px;
  font-size: var(--pk-text-base);
  animation: pk-toast-in .3s ease;
}
/* Tem de ser border-COLOR, não border-left-color: sem o acento lateral, pintar
   só a aresta esquerda deixaria a regra órfã e o toast de erro sem sinal. */
.pk-toast--error   { border-color: var(--pk-danger); }
.pk-toast--error   svg { color: var(--pk-danger); }
.pk-toast--success svg { color: var(--pk-green-dark); }
.pk-toast strong { display: block; color: var(--pk-ink); }
.pk-toast span   { color: var(--pk-ink-2); font-size: var(--pk-text-base); }
@keyframes pk-toast-in { from { opacity: 0; transform: translateX(40px); } to { opacity: 1; transform: none; } }

.pk-spin { animation: pk-spin 1s linear infinite; }
@keyframes pk-spin { to { transform: rotate(360deg); } }

/* =====================================================================
   RESPONSIVO
   ===================================================================== */
@media (max-width: 600px) {
  .pk-panel        { padding: 18px; }
  .pk-grid--2      { grid-template-columns: 1fr; }
  .pk-step__label  { display: none; }
  .pk-toast-wrap   { top: 66px; left: 14px; right: 14px; }
  .pk-toast        { min-width: 0; max-width: none; }
}

/* Ponteiro grosso (dedo): alvo mínimo de 44px. Não é enfeite — abaixo disso
   o toque erra e o usuário conclui que o botão não funciona. */
@media (pointer: coarse) {
  .pk-nav__item,
  .pk-pop__item,
  .pk-toggle button   { min-height: 44px; }
  .pk-iconbtn         { width: 44px; height: 44px; }
}

/* Sem hover real (iOS): o Safari GRUDA o :hover até você tocar em outro lugar,
   e o card fica preso no estado ativo. Reverte-se ao repouso e troca-se o
   retorno visual por :active, que responde ao toque em ~100ms. */
@media (hover: none) {
  .pk-card:hover, .pk-row:hover {
    border-color: var(--pk-hairline);
    box-shadow: var(--pk-shadow-sm);
  }
  .pk-btn:hover, .pk-iconbtn:hover { transform: none; }
  .pk-card:active, .pk-row:active  { transform: scale(.985); }
  .pk-btn:active                   { transform: scale(.97); }
}

/* =====================================================================
   COMBOBOX — campo de busca com lista filtrável
   Existe porque um <select> nativo com 200 categorias é inoperável: não
   filtra, não mostra descrição, e no celular vira uma roleta gigante.
   O JS é do projeto; o CSS abaixo é o contrato de classes que ele dirige
   (`.is-open` no contêiner, `.is-active` na opção sob o teclado).
   ===================================================================== */
.pk-combo { position: relative; }

.pk-combo__input {
  width: 100%;
  font-family: var(--pk-font);
  font-size: var(--pk-text-md);
  color: var(--pk-ink);
  background: var(--pk-surface);
  border: 1px solid var(--pk-border);
  border-radius: var(--pk-radius-sm);
  padding: 12px 42px 12px 15px;   /* 42 à direita: espaço da seta */
  outline: none; cursor: pointer;
  transition: border-color var(--pk-ease), box-shadow var(--pk-ease);
}
.pk-combo__input:focus { border-color: var(--pk-green); box-shadow: var(--pk-focus); }

/* pointer-events:none para o clique atravessar a seta e chegar ao input —
   sem isso, clicar exatamente na seta não abre a lista. */
.pk-combo__caret {
  position: absolute; right: 15px; top: 50%; transform: translateY(-50%);
  color: var(--pk-ink-3); pointer-events: none;
}

.pk-combo__list {
  position: absolute; top: calc(100% + 6px); left: 0; right: 0;
  max-height: 300px; overflow-y: auto;
  background: var(--pk-surface);
  border: 1px solid var(--pk-border);
  border-radius: var(--pk-radius-sm);
  box-shadow: var(--pk-shadow-lg);
  padding: 6px; z-index: 50;
  display: none;
}
.pk-combo.is-open .pk-combo__list { display: block; }

.pk-combo__opt {
  display: flex; flex-direction: column; gap: var(--pk-sp-1);
  padding: 10px 12px;
  border-radius: var(--pk-radius-xs);
  cursor: pointer;
  font-size: var(--pk-text-base); color: var(--pk-ink);
}
/* .is-active é a navegação por TECLADO e tem de ser visualmente igual ao
   hover — quem usa setas precisa ver onde está. */
.pk-combo__opt:hover, .pk-combo__opt.is-active { background: var(--pk-green-soft); }
.pk-combo__opt small { color: var(--pk-ink-3); font-size: var(--pk-text-sm); }
.pk-combo__opt mark  { background: var(--pk-green-line); color: var(--pk-green-ink);
                       border-radius: 3px; padding: 0 1px; }
.pk-combo__empty { padding: 16px 12px; text-align: center; color: var(--pk-ink-3); font-size: var(--pk-text-base); }
.pk-combo__list::-webkit-scrollbar { width: 8px; }
.pk-combo__list::-webkit-scrollbar-thumb { background: var(--pk-border-hover); border-radius: 4px; }

/* =====================================================================
   POPOVER DE AJUDA — o "i" ao lado do rótulo
   Para explicar um conceito do domínio (o que é "urgência alta") sem gastar
   uma linha de dica permanente em todo formulário. Abre no hover E no clique:
   o hover não existe no toque, e só clique obriga o mouse a mirar.
   ===================================================================== */
.pk-info { position: relative; display: inline-flex; }
.pk-info__btn {
  background: none; border: none; padding: 0; cursor: pointer;
  line-height: 1; display: inline-flex;
  color: var(--pk-green-dark); font-size: var(--pk-text-md);
}
.pk-info__btn:hover, .pk-info__btn:focus-visible { color: var(--pk-green-ink); }

.pk-info__pop {
  position: absolute; left: 0; top: calc(100% + 8px); z-index: 40;
  width: 340px; max-width: 78vw;
  background: var(--pk-surface);
  border: 1px solid var(--pk-border);
  border-radius: var(--pk-radius-sm);
  box-shadow: var(--pk-shadow-md);
  padding: 14px 16px;
  display: none; flex-direction: column; gap: var(--pk-sp-2);
  font-weight: 400;
}
.pk-info:hover .pk-info__pop, .pk-info.is-open .pk-info__pop { display: flex; }
.pk-info__pop strong { font-size: var(--pk-text-base); color: var(--pk-ink); }
.pk-info__pop p      { font-size: var(--pk-text-sm); color: var(--pk-ink-2); margin: 0; }
.pk-info__lvl {
  display: flex; gap: var(--pk-sp-2); align-items: flex-start; line-height: 1.4;
  font-size: var(--pk-text-sm); color: var(--pk-ink-2);
}
.pk-info__lvl svg { color: var(--pk-green-dark); margin-top: 2px; width: 14px; height: 14px; flex: none; }
.pk-info__lvl b   { color: var(--pk-ink); }

/* Área de toque do "i": o ícone tem 18px e o alvo precisa de 44. O padding
   cresce a área e a margem negativa devolve o espaço, sem mexer no layout. */
@media (pointer: coarse) {
  .pk-info__btn { padding: 14px; margin: -14px; }
}

/* =====================================================================
   CARD DE ESCOLHA — vertical, ícone em cima
   Diferente do .pk-card (horizontal): serve a uma GRADE de opções
   equivalentes, onde o olho varre em Z e o ícone é o que distingue.
   Use para escolher categoria, tipo, destino. Para um destino único e
   importante, .pk-card.
   ===================================================================== */
.pk-pick {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--pk-sp-3); padding: 22px 16px; min-height: 120px;
  background: var(--pk-surface);
  border: 1px solid var(--pk-border);
  border-radius: var(--pk-radius);
  cursor: pointer; text-align: center; text-decoration: none;
  /* Lista explícita e easing suave. Com `transition: all` + a curva de
     overshoot, o hover ganha um "pulinho" que lê como falha de render. */
  transition: transform var(--pk-ease), box-shadow var(--pk-ease),
              border-color var(--pk-ease), background-color var(--pk-ease);
}
.pk-pick:hover {
  border-color: var(--pk-green);
  background: var(--pk-green-soft);
  transform: translateY(-2px);
  box-shadow: var(--pk-shadow-md);
}
.pk-pick:focus-visible { outline: 3px solid var(--pk-green); outline-offset: 2px; }
.pk-pick__icon {
  width: 50px; height: 50px;
  border-radius: var(--pk-radius-sm);
  display: grid; place-items: center;
  background: var(--pk-green-soft); color: var(--pk-green-dark);
  font-size: 25.5px;
  transition: background-color var(--pk-ease), color var(--pk-ease);
}
.pk-pick:hover .pk-pick__icon { background: var(--pk-green); color: var(--pk-on-green); }
.pk-pick__name { font-size: var(--pk-text-base); font-weight: 600; color: var(--pk-ink); line-height: 1.25; }
.pk-pick__hint { font-size: var(--pk-text-xs); color: var(--pk-ink-3); }

.pk-pick-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--pk-sp-3); }
@media (max-width: 600px) { .pk-pick-grid { grid-template-columns: repeat(2, 1fr); } }

/* =====================================================================
   CARD LATERAL E NOTÍCIA
   ===================================================================== */
.pk-side-card {
  background: var(--pk-surface);
  border: 1px solid var(--pk-hairline);
  border-radius: var(--pk-radius);
  box-shadow: var(--pk-shadow-sm);
  overflow: hidden;   /* o raio recorta a primeira e a última linha da lista */
}
.pk-side-card__head {
  display: flex; align-items: center; gap: var(--pk-sp-2);
  padding: 16px 18px;
  border-bottom: 1px solid var(--pk-border);
  font-size: var(--pk-text-base); font-weight: 700; color: var(--pk-ink);
}
.pk-side-card__head svg { color: var(--pk-green-dark); }
.pk-side-card__foot { padding: 12px 18px; text-align: center; }
.pk-side-card__foot a { font-size: var(--pk-text-base); font-weight: 600;
                        color: var(--pk-green-ink); text-decoration: none; }

.pk-news { display: flex; flex-direction: column; }
.pk-news-card {
  position: relative;
  display: grid; grid-template-columns: 1fr auto; align-items: center; gap: var(--pk-sp-2);
  padding: 13px 18px;
  border-bottom: 1px solid var(--pk-border);
  text-decoration: none; color: inherit;
  transition: background-color var(--pk-ease);
}
.pk-news-card:last-child { border-bottom: none; }
.pk-news-card:hover { background: var(--pk-surface-2); }
/* Acento verde que APARECE no hover, em vez de deslocar a linha: o
   ::before já ocupa o lugar, só a opacidade muda — sem reflow. */
.pk-news-card::before {
  content: ''; position: absolute; left: 0; top: 10px; bottom: 10px;
  width: 3px; border-radius: 3px; background: var(--pk-green);
  opacity: 0; transition: opacity var(--pk-ease);
}
.pk-news-card:hover::before { opacity: 1; }
/* min-width:0 é obrigatório: item de grid tem min-width:auto por padrão, e sem
   isto o título longo estica a coluna em vez de truncar — o -webkit-line-clamp
   abaixo nunca chega a valer. */
.pk-news-card__body { min-width: 0; display: flex; flex-direction: column; gap: var(--pk-sp-1); }
.pk-news-card__title {
  font-size: var(--pk-text-base); font-weight: 600; color: var(--pk-ink); line-height: 1.35;
  overflow: hidden; text-overflow: ellipsis;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.pk-news-card__meta { display: flex; align-items: center; gap: var(--pk-sp-1);
                      font-size: var(--pk-text-xs); color: var(--pk-ink-3); }
.pk-news-card__tag  { font-weight: 600; color: var(--pk-green-ink); }
.pk-news-card__go   { color: var(--pk-ink-3); }
.pk-news-card:hover .pk-news-card__go { color: var(--pk-green-ink); }

/* =====================================================================
   SEÇÃO COLAPSÁVEL E GRADE DE APLICATIVOS
   ===================================================================== */
.pk-collapse__head {
  width: 100%; display: flex; align-items: center; justify-content: space-between; gap: var(--pk-sp-3);
  background: none; border: none; padding: 0 0 14px; cursor: pointer; color: inherit;
}
.pk-collapse__caret { color: var(--pk-ink-3); transition: transform var(--pk-ease); }
.pk-collapse.is-collapsed .pk-collapse__caret { transform: rotate(-90deg); }
.pk-collapse.is-collapsed .pk-collapse__body  { display: none; }

/* 🔴 A REGRA GENÉRICA DE TÍTULO ATROPELAVA A PEÇA. Logo abaixo, neste mesmo
   arquivo, `.pk-app h1, .pk-app h2, .pk-app h3, .pk-app h4` aperta o
   `letter-spacing` para -.01em — e vale (0,1,1), contra os (0,1,0) de
   `.pk-section-title` (pcnet-shell.css:119). Resultado medido no navegador
   (CSS.getMatchedStylesForNode): o título de seção saía com -0.175px onde o
   padrão manda +0.8px, ou seja com o tracking INVERTIDO em relação ao portal,
   que é justamente o que faz esse título ser reconhecível. Peso e caixa alta
   aplicavam; só o espaçamento perdia — o tipo de defeito que nenhum print
   denuncia. A peça recupera a especificidade aqui.
   É a mesma armadilha já registrada no CLAUDE.md: impor por `.pk-app .classe`
   atropela quem declara menos. */
.pk-app .pk-section-title { letter-spacing: .8px; }

/* O título de seção do portal (`pcnet-shell.css`) pinta de verde o ícone
   quando ele é `<svg>` — que é o que o portal usa. O parque usa Font Awesome,
   e um `<i>` ficava com a cor do texto. Mesma regra, o outro elemento. */
.pk-section-title i { color: var(--pk-green-dark); }

/* O LADRILHO — a peça do launcher do portal (`.fw-app-tile`).
   🔴 Ela existia só em `pcnet-efeitos.css`, uma camada OPT-IN que nenhum dos
   quinze consumidores pede — enquanto a grade dela (`.pk-tile-grid`, logo
   abaixo) morava aqui, em `componentes`, que todos pedem. Peça numa camada e
   grade em outra: o resultado é que o ladrilho tinha ZERO uso no parque, e os
   menus de plugin desenharam cada um o seu cartão.
   Fica aqui ao lado da grade. `efeitos` segue intacta (o md5 dela é contrato
   com a skill) e as duas regras são idênticas, então pedir a camada não cria
   conflito. */
.pk-tile {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--pk-sp-2); padding: 14px 8px; min-height: 84px;
  /* ⚠️ NÃO volte a pôr `aspect-ratio` aqui, e o motivo foi MEDIDO em 2026-09-01.
     Uma tentativa de "fixar a proporção áurea" pôs `aspect-ratio: 1.618` nesta
     peça, e altura imposta + filho encolhível = TEXTO CORTADO: o
     `dashboardpcnet` perdia o nome dos três ladrilhos em 5 de 8 larguras
     (inclusive 1366, a mais comum) e o `agendapcnet` perdia "Minha
     Localização" em 4 de 8. A justificativa daquela mudança ("cada irmão
     ficava com uma altura") era FALSA: a grade é `display: grid`, e em grid os
     itens da mesma linha já esticam para a altura da linha por padrão
     (`align-items: stretch`). A proporção nunca precisou ser imposta — ela sai
     sozinha do conteúdo, e é o conteúdo que manda na altura. */
  border: 1px solid transparent;
  border-radius: var(--pk-radius-sm);
  text-decoration: none; color: var(--pk-ink); cursor: pointer;
  transition: border-color var(--pk-ease), box-shadow var(--pk-ease);
}
/* Hover do portal: nada de preenchimento — o vidro vem da sombra INTERNA na
   diagonal (brilho em cima à esquerda, sombra embaixo à direita). */
.pk-tile:hover {
  background: transparent;
  border-color: var(--pk-hairline-hover);
  box-shadow: var(--pk-glass-inset);
}
.pk-tile:focus-visible { outline: 3px solid var(--pk-green); outline-offset: 2px; }
.pk-tile__icon { color: var(--pk-green-dark); line-height: 0; position: relative; }
.pk-tile__icon svg { width: 27px; height: 27px; stroke-width: 1.6; display: block; }
/* 27px e não 25: o portal desenha o ícone com SVG do Lucide a 27×27
   (`portal.css:315`) e os plugins usam glifo do Font Awesome. Medido lado a
   lado, 25px deixava o glifo 2px menor que o do portal na mesma peça. */
.pk-tile__icon i   { font-size: 27px; line-height: 1; }
.pk-tile__name {
  /* 15px é a medida do portal (`portal.css:330`), cravada lá e sem token
     equivalente aqui — `--pk-text-md` é 17.5px e `--pk-text-sm`, 14.5. Fica o
     valor do portal: esta peça É a dele, e casar o nome é o que faz as duas
     lerem como a mesma coisa. */
  font-size: 15px; font-weight: 500; text-align: center;
  line-height: 1.25; color: var(--pk-ink-2);
  /* Sem `line-clamp` e sem `overflow: hidden`: o nome do item de menu é a
     única informação da peça, e cortá-lo com reticências para preservar uma
     proporção troca o que a tela PRECISA dizer pelo que ela parece. Nome longo
     ocupa duas linhas e a caixa cresce — em grid, as irmãs crescem junto. */
  overflow-wrap: anywhere;
}
/* A DESCRIÇÃO — o launcher do portal não tem, e não precisa: lá são nove ícones
   num painel suspenso, e o nome do módulo basta. Numa TELA de menu de plugin a
   descrição é informação que a tela mostrava, e mandá-la para o `title` foi a
   perda que custou uma rodada inteira em 2026-09-01. A peça é a mesma; o que
   muda é que aqui ela tem uma linha a mais. */
.pk-tile__desc {
  font-size: var(--pk-text-sm); font-weight: 400; text-align: center;
  line-height: 1.4; color: var(--pk-ink-3); overflow-wrap: anywhere;
}

/* GRADE LARGA — a mesma peça, na escala de uma tela em vez da de um painel
   suspenso. `--pk-tile-col` é o único parâmetro: 132px é a medida do launcher
   (nove lado a lado), 240px é a de um menu de plugin com três itens e
   descrição. Nada mais muda — nem a peça, nem o hover, nem o ícone. */
.pk-tile-grid--larga { --pk-tile-col: 240px; }

/* Sem permissão: visível, cinza e não clicável. Esconder ensina que o recurso
   não existe; mostrar com cadeado ensina que existe e a quem pedir. */
.pk-tile--locked { cursor: not-allowed; opacity: .5; filter: grayscale(1); }
.pk-tile--locked:hover { background: transparent; border-color: transparent; box-shadow: none; }

.pk-tile-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--pk-tile-col, 132px), 1fr));
  /* 21px (--pk-sp-4) e não 12: o vão de 12 vem do launcher do portal, onde há
     NOVE ícones lado a lado e o aperto é o desenho. Num menu de plugin, com
     três itens, 12px sobre 134 de largura (9%) lê como colado — foi a primeira
     coisa que o dono apontou depois da migração. */
  gap: var(--pk-sp-4);
  background: var(--pk-surface);
  border: 1px solid var(--pk-hairline);
  border-radius: var(--pk-radius);
  /* O painel do launcher no portal (`portal.css:275`) é superfície opaca COM
     sombra (`--shadow-lg`). Aqui a sombra faltava, e uma caixa sem elevação ao
     lado de um cabeçalho com elevação lê como duas caixas de produtos
     diferentes — foi o que o dono apontou em 2026-09-01. */
  box-shadow: var(--pk-shadow-lg);
  /* O padding é o da peça de origem (16px). Desta grade, só o VÃO mudou — que
     foi a queixa. Tamanho não estava em questão e não se mexe no que não foi
     pedido. */
  padding: 16px;
}

/* =====================================================================
   ESTADOS DE TELA INTEIRA — sucesso e acesso negado
   ===================================================================== */
.pk-success { text-align: center; padding: 36px 24px; }
.pk-success__icon { font-size: 73.5px; color: var(--pk-green-dark); margin-bottom: var(--pk-sp-3); }
.pk-success h2    { font-size: var(--pk-text-2xl); margin-bottom: var(--pk-sp-2); }
.pk-success p     { color: var(--pk-ink-2); margin-bottom: var(--pk-sp-1); }
/* O identificador em monoespaçada e grande: é o único dado que a pessoa
   precisa copiar ou ditar ao telefone. */
.pk-success__id   { font-family: var(--pk-font-mono); font-size: var(--pk-text-2xl);
                    font-weight: 700; color: var(--pk-green-ink); }

/* Gate de acesso: cobre a tela com o próprio fundo da página a 96%, e não
   com um véu preto. Véu escuro comunica "modal, feche e continue"; aqui a
   mensagem é "esta tela não é para você", e o fundo claro diz isso melhor. */
.pk-gate {
  position: fixed; inset: 0; z-index: 11000;
  display: none; align-items: center; justify-content: center;
  /* 🔴 `color-mix` e não o literal `rgba(238,241,246,.96)`. O valor era o de
     `--pk-bg` a 96% — correto no claro e CRAVADO: `--pk-bg` muda por tema
     (#eef1f6 / #111a13) e a folha escura não tem regra nenhuma para esta peça,
     então o véu de tela cheia saía quase BRANCO com o tema escuro ligado.
     Apontado pela sessão que audita o monitorpcnet em 2026-09-01; era a única
     superfície de tela cheia do padrão que não acompanhava o tema.
     `color-mix` segue os dois sem `!important` e sem duplicar a regra lá. */
  background: color-mix(in srgb, var(--pk-bg) 96%, transparent);
  padding: 24px;
}
.pk-gate.is-on { display: flex; }
.pk-gate__card {
  background: var(--pk-surface);
  border: 1px solid var(--pk-border);
  border-radius: var(--pk-radius);
  box-shadow: var(--pk-shadow-lg);
  padding: 40px; max-width: 420px; text-align: center;
}
.pk-gate__card svg { font-size: 64.5px; color: var(--pk-ink-3); margin-bottom: var(--pk-sp-4); }
.pk-gate__card h2  { font-size: var(--pk-text-2xl); margin-bottom: var(--pk-sp-2); }
.pk-gate__card p   { color: var(--pk-ink-2); font-size: var(--pk-text-base); line-height: 1.5; }

/* =====================================================================
   RESUMO DE ERROS
   COMPLEMENTA o erro no campo (.pk-field-error), nunca o substitui: o
   resumo diz QUANTOS e leva até lá; o erro no campo diz O QUÊ. Só vale a
   pena em formulário longo, onde o primeiro campo inválido pode estar
   fora da tela.
   ===================================================================== */
.pk-error-summary {
  background: var(--pk-danger-soft);
  border: 1px solid var(--pk-danger-line);
  border-radius: var(--pk-radius-sm);
  padding: 14px 18px; margin-bottom: var(--pk-sp-4);
}
.pk-error-summary h3 {
  display: flex; align-items: center; gap: var(--pk-sp-2);
  font-size: var(--pk-text-md); color: var(--pk-danger-ink); margin-bottom: var(--pk-sp-2);
}
.pk-error-summary ul { list-style: none; margin: 0; padding: 0; }
.pk-error-summary li { margin: 4px 0; }
.pk-error-summary a  { color: var(--pk-danger-ink); font-size: var(--pk-text-base);
                       text-decoration: underline; cursor: pointer; }
@media (pointer: coarse) {
  .pk-error-summary a { min-height: 44px; display: inline-flex; align-items: center; }
}

/* Notícias em GRADE — a variante de home, onde cada notícia é um card
   autônomo em vez de uma linha dentro do card lateral. Mesmo componente,
   duas densidades: a lista serve a uma coluna estreita, a grade a uma
   largura cheia onde 3 linhas empilhadas pareceriam sobra de espaço. */
.pk-news--grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: var(--pk-space);
  background: none; border: none; padding: 0;
}
.pk-news--grid .pk-news-card {
  border: 1px solid var(--pk-hairline);
  border-radius: var(--pk-radius);
  padding: 16px 18px;
  background: var(--pk-surface);
  box-shadow: var(--pk-shadow-sm);
}
.pk-news--grid .pk-news-card:hover { border-color: var(--pk-hairline-hover); box-shadow: var(--pk-shadow-md); }
/* o acento vertical não cabe num card com borda própria: vira sublinhado do título */
.pk-news--grid .pk-news-card::before { display: none; }

/* =====================================================================
   TEXTO DE GRÁFICO — segue o tema, como todo o resto.

   O Highcharts carimba a cor de CADA texto que desenha (eixo, legenda,
   título, rótulo de valor) diretamente no <text>/<tspan>, a partir de um
   objeto JS. Cor escrita em JS não acompanha o alternador de tema: o
   alternador só troca um atributo no <html>, e o gráfico já foi desenhado.

   O parque tinha três desses valores cravados — #9ca3af, #6a9a6a e
   #e8f5e8 — todos escolhidos quando estes painéis eram SÓ escuros. No
   tema claro davam 2.44:1, 3.26:1 e 1.13:1; o último é texto quase branco
   sobre card branco, ou seja, invisível.

   Não existe cor única que sirva nos dois temas: contraste alto sobre
   quase-branco pede luminância baixa, e sobre quase-preto pede luminância
   alta. Ou a cor segue o tema, ou um dos dois fica ilegível.

   Em SVG quem pinta é o `fill`, não o `color`; os dois estão aqui porque
   o Highcharts escreve os dois. O !important é necessário: estilo inline
   vence CSS sem ele.

   ⚠️ Só TEXTO. As cores de série (barra, linha, fatia) ficam intactas —
   elas codificam o dado, e como elemento gráfico o mínimo é 3.0, que elas
   cumprem nos dois temas.                                                */
.pk-app .highcharts-axis-labels text,
.pk-app .highcharts-axis-labels tspan,
.pk-app .highcharts-legend-item text,
.pk-app .highcharts-legend-item tspan,
.pk-app .highcharts-axis-title,
.pk-app .highcharts-axis-title tspan {
  fill:  var(--pk-ink-2) !important;
  color: var(--pk-ink-2) !important;
}

.pk-app .highcharts-title,
.pk-app .highcharts-title tspan,
.pk-app .highcharts-subtitle,
.pk-app .highcharts-subtitle tspan,
.pk-app .highcharts-data-label text,
.pk-app .highcharts-data-label tspan,
.pk-app .highcharts-data-labels text,
.pk-app .highcharts-data-labels tspan,
/* stackLabels é um grupo à parte no Highcharts e não cai em data-label:
   é o total escrito no topo da barra empilhada. No Wazuh eram 10 números
   em #e8f5e8 — 1.13:1 sobre o card branco, ou seja, invisíveis. */
.pk-app .highcharts-stack-labels text,
.pk-app .highcharts-stack-labels tspan {
  fill:  var(--pk-ink) !important;
  color: var(--pk-ink) !important;
}


/* =====================================================================
   COR DE LINK DENTRO DA CAIXA DO PLUGIN.

   O `a` genérico é pintado pelo Tabler, que resolve
   `color-mix(..., var(--tblr-link-color))`. Neste servidor esse token vale
   rgb(69,148,54) — o verde do tema do PRÓPRIO GLPI, que não muda com o nosso
   alternador. Medido: 3,79:1 sobre o card branco e 4,10:1 sobre o card escuro,
   os dois abaixo do mínimo de 4,5. Eram 172 links em krimbo/commits,
   flowpcnet/postagens e flowpcnet/checklistitem.

   A correção NÃO é `.pk-app a { color: ... }`: isso teria especificidade (0,1,1)
   e passaria por cima de toda cor de link que os plugins definem de propósito.
   O que se faz é redefinir o TOKEN dentro da caixa — a regra do Tabler continua
   sendo a mesma, só resolve para um valor que segue o tema, e qualquer regra de
   plugin continua vencendo normalmente.                                       */
.pk-app,
[data-pcnet-escopo] {
  --tblr-link-color:       var(--pk-green-ink);
  /* 🔴 O HOVER ESCREVIA COM O VERDE DE PREENCHIMENTO (2026-09-23). Era
     `var(--pk-green)`, o #8CC63F — e o `a:hover` do Tabler (0,1,1) vence a cor
     de quase todo link-botão de plugin (0,1,0): sob o cursor o texto caía para
     2,01:1 ("Monitoramento" no menu do Firewall) e 1,85:1 ("Limpar busca" e
     "Voltar ao dashboard" no Dashboard Cliente). Three Greens Rule: o verde
     cheio preenche, quem escreve é o -ink.
     O hover continua visível: 30% da Tinta sobre o -ink ESCURECE o verde no
     claro (8,51:1 no branco) e o CLAREIA no escuro (10,57:1 no card), porque a
     Tinta troca de lado junto com o tema. Nunca abaixo do repouso. */
  --tblr-link-hover-color: color-mix(in srgb, var(--pk-green-ink) 70%, var(--pk-ink));

  /* Mesma ideia para o cinza do Tabler. Várias telas do parque embutem markup
     NATIVO do GLPI dentro da caixa do plugin — a busca do checklist, o botão
     secundário dos relatórios. Ali o texto usa --tblr-secondary, que neste
     servidor vale #768363 (verde-acinzentado do tema do próprio GLPI) e dá
     3,84:1 sobre o card escuro e 3,94:1 como texto do botão.

     ⚠️ Isto NÃO é repintar o chrome do GLPI: o seletor só alcança o que está
     DENTRO da caixa do plugin. O menu, a barra lateral e o cabeçalho do GLPI
     continuam intocados, que é a fronteira acordada. */
  --tblr-body-color: var(--pk-ink);
}

/* ⚠️ --tblr-secondary NÃO entra na lista acima, e a tentativa de incluí-lo foi
   revertida no mesmo dia: no Tabler ele serve de TEXTO (.text-muted) e de
   FUNDO (.btn-secondary). Apontá-lo para um token de texto deixou o botão
   "Gerar PDF" com fundo #aec3ae e tinta quase branca — 1,82:1, pior do que
   estava. É a mesma armadilha de sempre: um token, dois trabalhos.
   O certo é alcançar só as classes de TEXTO. */
.pk-app .text-muted,
.pk-app .text-secondary,
[data-pcnet-escopo] .text-muted,
[data-pcnet-escopo] .text-secondary { color: var(--pk-ink-2) !important; }

/* 🔴 O BOTÃO SECUNDÁRIO DO TABLER dentro da caixa vira o BOTÃO FANTASMA da casa
   (2026-09-23). "Gerar PDF" nos seletores de relatório do dashboardpcnet saía
   #fcfcfc sobre o cinza-oliva do tema do GLPI (#768363): 3,94:1 nos dois
   temas, ao lado do "Visualizar" verde da casa. O token --tblr-secondary não
   pode ser remapeado (ver acima); o que se remapeia são as variáveis DO BOTÃO,
   que o Tabler declara em `.btn-secondary` (0,1,0) — daí (0,2,0) aqui, sem
   `!important`. Papel, borda e Tinta Média; hover em Verde Tinta, como o
   `.pk-btn--ghost`. O mesmo para o `.btn-outline-secondary` ("Ações" da busca
   nativa, o botão "i" dos dropdowns do core): tinta #768363 a 3,57:1 no claro. */
.pk-app .btn-secondary,
.pk-app .btn-outline-secondary,
[data-pcnet-escopo] .btn-secondary,
[data-pcnet-escopo] .btn-outline-secondary {
  --tblr-btn-color:               var(--pk-ink-2);
  --tblr-btn-bg:                  var(--pk-surface);
  --tblr-btn-border-color:        var(--pk-border);
  --tblr-btn-hover-color:         var(--pk-green-ink);
  --tblr-btn-hover-bg:            var(--pk-surface);
  --tblr-btn-hover-border-color:  var(--pk-border-hover);
  --tblr-btn-active-color:        var(--pk-green-ink);
  --tblr-btn-active-bg:           var(--pk-surface-2);
  --tblr-btn-active-border-color: var(--pk-border-hover);
  --tblr-btn-disabled-color:      var(--pk-ink-3);
  --tblr-btn-disabled-bg:         var(--pk-surface-2);
  --tblr-btn-disabled-border-color: var(--pk-border);
}

/* O título de formulário nativo (`.navigationheader .status`, "Etapa do funil -
   Visita Agendada - ID 2") escreve com --tblr-status-color = --tblr-secondary:
   3,22:1 no claro, 3,93:1 no escuro. Remapeia-se a VARIÁVEL da peça e não só
   a cor: o GLPI tira dela também o fundo lavado (a 10%), e assim tinta e
   lavado saem do mesmo tom. É o TÍTULO do formulário, então a Tinta, não a
   Tinta Média: com --pk-ink-2 o texto ficava em 4,51–4,62:1 sobre o próprio
   lavado, no fio do mínimo (medido na prévia de 2026-09-24). */
.pk-app .navigationheader .status,
[data-pcnet-escopo] .navigationheader .status { --tblr-status-color: var(--pk-ink); }

/* =====================================================================
   O CAMPO E A TABELA DO TABLER SEGUEM O TEMA DENTRO DA CAIXA (2026-09-23)

   🔴 O par estava trocado PELA METADE. A regra acima remapeia a TINTA do
   Tabler (--tblr-body-color → --pk-ink, que no escuro vira #eaf2e8) e deixava
   o FUNDO do campo (--tblr-bg-forms) no branco do tema do GLPI: no escuro, todo
   .form-control/.form-select de plugin saía com tinta clara sobre fundo branco
   — 1,14:1, medido no levaetrazpcnet, onde o dono viu "fica tudo apagado".

   E não só .form-control: a regra do core que pinta campo SEM essa classe
   (css/legacy/includes/_inputs.scss:34, dez :not() encadeados) e o select sem
   .form-select (:52) usam as MESMAS variáveis — var(--tblr-body-color),
   var(--tblr-bg-forms), var(--tblr-border-color). Completar o par aqui corrige
   os ~66 campos do parque sem .form-control sem um !important sequer.

   A receita foi provada no levaetrazpcnet em 2026-09-14 (contorno local, com
   a medição nos dois temas) e sobe para cá para valer em toda caixa. Todos os
   valores são tokens que mudam por tema: no claro resolvem para o que o parque
   já via (#fff, #e3e8ef, #f6f8fb); só o escuro muda. */
.pk-app,
[data-pcnet-escopo] {
  --tblr-bg-forms:     var(--pk-surface);
  --tblr-border-color: var(--pk-border);
  /* o botão desmarcado do btn-group da busca nativa (tabela/mapa) pinta
     --tblr-bg-surface (#fff, fora do tema) com o ícone na tinta clara */
  --tblr-bg-surface:   var(--pk-surface);
  /* 🔴 E o campo DESABILITADO, que ficou de fora da primeira leva (2026-09-23):
     `.form-control:disabled` pinta --tblr-bg-surface-secondary (#fafbfc no tema
     do GLPI), e no escuro os três campos de segredo do krimbo/config viravam
     faixas brancas com a tinta clara (1,1:1) e o placeholder a 2,68:1. É o
     "Papel Rebaixado" que o DESIGN.md manda para campo desabilitado. O mesmo
     token pinta o `.badge` sem cor do Tabler — que no escuro tinha o mesmo
     defeito, fundo quase branco sob --tblr-body-color já remapeada. */
  --tblr-bg-surface-secondary: var(--pk-surface-2);

  /* AS ABAS E O FORMULÁRIO NATIVOS DO GLPI dentro da caixa (crm etapa.form):
     --glpi-tabs-* são calculados no :root a partir de --tblr-bg-surface e
     --tblr-muted e HERDADOS JÁ RESOLVIDOS — o remapeamento de --tblr-bg-surface
     acima não chega neles. Medido: coluna de abas #fbfbfb com tinta #768363
     (3,91:1) nos dois temas, e o painel das abas continuava claro no escuro.
     Redeclarados aqui, com os tokens da casa, eles passam a seguir o tema. */
  --glpi-tabs-bg:                  var(--pk-surface-2);
  --glpi-tabs-fg:                  var(--pk-ink-2);
  --glpi-tabs-border-color:        var(--pk-border);
  --glpi-tabs-active-bg:           var(--pk-surface);
  --glpi-tabs-active-fg:           var(--pk-ink);
  --glpi-tabs-active-border-color: var(--pk-border);
}

.pk-app .form-control::placeholder,
.pk-app input::placeholder,
.pk-app textarea::placeholder,
[data-pcnet-escopo] .form-control::placeholder {
  color: var(--pk-ink-3);
  opacity: 1;   /* o Firefox aplica opacidade extra ao placeholder por padrão */
}

/* A LISTA do <select> é desenhada pelo sistema operacional, e no Chrome do
   Windows ela usa o fundo e a cor de cada <option>: sem isto a lista abria
   branca com a tinta clara herdada — invisível no escuro. */
.pk-app select option,
.pk-app select optgroup,
[data-pcnet-escopo] select option,
[data-pcnet-escopo] select optgroup {
  background-color: var(--pk-surface);
  color: var(--pk-ink);
}

/* 🔴 CHECKBOX DESMARCADO. Com o fundo do campo virando a superfície, a caixa
   e a borda (--tblr-border-color-translucent, azul a 10%) ficam da cor do card:
   1,01:1 no escuro, medido. O que identifica um checkbox desmarcado é SÓ o
   contorno, e a WCAG 1.4.11 pede 3:1 para ele. 75% de --pk-ink-3 sobre a
   superfície é o menor degrau que passa nos dois temas (3,79 escuro / 3,17
   claro). :not(:focus) deixa o foco com o anel do core. */
.pk-app .form-check-input:not(:checked):not(:indeterminate):not(:focus),
[data-pcnet-escopo] .form-check-input:not(:checked):not(:indeterminate):not(:focus) {
  border-color: color-mix(in srgb, var(--pk-ink-3) 75%, var(--pk-surface));
}

/* 🔴 A ZEBRA do Search::show saía BRANCA no escuro em toda linha par. O Tabler
   não pinta a célula com background-color: pinta com
   box-shadow: inset 0 0 0 9999px var(--tblr-table-bg-state, …), e
   .table-striped põe em --tblr-table-striped-bg um quase-branco (#f9fafb) que
   não segue o tema. O seletor tem de alcançar a .table: é nela que o Tabler
   declara a variável. */
.pk-app .table,
[data-pcnet-escopo] .table {
  --tblr-table-striped-bg: var(--pk-surface-2);
}

/* A busca nativa embutida na caixa: rodapé "Exibindo 1 a N" com fundo quase
   branco (1,81:1 no escuro) e a etiqueta de entidade com a tinta do tema do
   GLPI (3,31:1 nos dois). A etiqueta vai pelo TOKEN, porque o core declara
   .glpi-badge { color: var(--glpi-badge-fg) !important }. */
.pk-app .search-footer,
[data-pcnet-escopo] .search-footer {
  background-color: var(--pk-surface-2);
}
.pk-app .glpi-badge,
[data-pcnet-escopo] .glpi-badge {
  --glpi-badge-fg: var(--pk-green-ink);
  --glpi-badge-bg: color-mix(in srgb, var(--pk-green) 14%, var(--pk-surface));
  background-color: var(--glpi-badge-bg);
}

/* O cabeçalho de coluna da busca nativa usa o cinza do tema do GLPI
   (--tblr-secondary, #768363) como TINTA: 3,87:1 no claro. O token não pode ser
   remapeado (no Tabler ele também é FUNDO do .btn-secondary), então a correção
   vai na classe de texto. */
.pk-app .table thead th,
[data-pcnet-escopo] .table thead th {
  color: var(--pk-ink-2);
}

/* 🔴 O BOTÃO FANTASMA da busca nativa ("Pesquisar", "Ordenação", "Exportar",
   o favorito e o recarregar) vai pelas VARIÁVEIS DO BOTÃO, e não por `color`.
   Até 2026-09-28 esta regra dava `color: var(--pk-ink-2)` direto no elemento: o
   repouso ficava certo, mas a cor cravada vencia também o estado ABERTO
   (`.btn.show`, o dropdown de filtros) e o hover, cujo FUNDO continuava o do
   Tabler — --tblr-secondary, o #768363 do tema do GLPI. Medido na varredura
   final: "Pesquisar" e "Ordenação" a 1,44:1 no claro (#5b6678 sobre #768363) e
   2,16:1 no escuro (crm-empresas, crm-etapas, mpc-historico). O Tabler declara
   as variáveis em `.btn-ghost-secondary` (0,1,0); aqui (0,2,0), sem
   `!important`, como o `.btn-secondary` acima. Aberto = o chip verde da casa
   (Verde Tinta sobre o verde rebaixado: 5,76:1 no claro, 9,14:1 no escuro);
   hover = Papel Rebaixado com a Verde Tinta. O `.btn-active-search` do core
   (filtro ativo) continua com a cor dele: o seletor do core é mais forte. */
.pk-app .btn-ghost-secondary,
[data-pcnet-escopo] .btn-ghost-secondary {
  --tblr-btn-color:               var(--pk-ink-2);
  --tblr-btn-hover-color:         var(--pk-green-ink);
  --tblr-btn-hover-bg:            var(--pk-surface-2);
  --tblr-btn-hover-border-color:  transparent;
  --tblr-btn-active-color:        var(--pk-green-ink);
  --tblr-btn-active-bg:           var(--pk-green-soft);
  --tblr-btn-active-border-color: transparent;
  --tblr-btn-disabled-color:      var(--pk-ink-3);
}

/* O TÍTULO DE SEÇÃO DE DROPDOWN do Tabler (`h6.dropdown-header`: "Página
   atual" e "Todas as páginas" no Exportar da busca nativa) escreve com
   --tblr-secondary: 4,04:1 sobre o menu branco e 3,84:1 sobre o menu escuro
   (mpc-historico). Tinta Média nos dois temas (5,81:1 / 8,30:1). O corpo vai
   para a Legenda: o Tabler o crava em .75rem (12px), abaixo do piso de texto
   funcional do DESIGN.md. */
.pk-app .dropdown-header,
[data-pcnet-escopo] .dropdown-header {
  color: var(--pk-ink-2);
  font-size: var(--pk-text-xs);
}

/* OS SELOS DO CABEÇALHO DO FORMULÁRIO NATIVO (`templates/components/form/
   header_content.html.twig`): a entidade e o "Entidades filhas". O core os
   pinta com fundo lavado FIXO, que não segue o tema (claro também no escuro),
   corpo de 10px (.625rem, mixin tabler-badge-fix) e, quando a conta não pode
   mudar a recursividade, o rótulo em verde do tema do GLPI a 70% de opacidade:
   2,23:1 nos dois temas (crm-etapa-form, flowpcnet checklistitem). Chip da
   casa: fundo -soft, tinta -ink, opacidade cheia — marcado ou não, e travado
   ou não, quem diz é a caixinha, não o apagado do texto. Corpo na Legenda.
   Era contorno local no flowpcnet (flowpcnet.css, "SUBTRAIR quando o host
   cobrir"): agora o host cobre. `:not(.asset-deleted)` deixa o vermelho do
   item na lixeira com o core. */
.pk-app .navigationheader .card-header .badge,
[data-pcnet-escopo] .navigationheader .card-header .badge {
  font-size: var(--pk-text-xs);
}
.pk-app .navigationheader:not(.asset-deleted) .card-header .badge.entity-name,
[data-pcnet-escopo] .navigationheader:not(.asset-deleted) .card-header .badge.entity-name {
  background-color: var(--pk-info-soft);
  color: var(--pk-info-ink);
}
.pk-app .navigationheader .card-header .is_recursive-toggle,
[data-pcnet-escopo] .navigationheader .card-header .is_recursive-toggle {
  background-color: var(--pk-green-soft);
  color: var(--pk-green-ink);
}
.pk-app .navigationheader .card-header .is_recursive-toggle .form-check-label,
[data-pcnet-escopo] .navigationheader .card-header .is_recursive-toggle .form-check-label {
  color: var(--pk-green-ink);
  opacity: 1;
}

/* O CORPO do cabeçalho de coluna: o GLPI crava `table.table thead th
   { font-size: .625rem }` — 10px — em css/includes/_base.scss:347 (0,1,3), e ele
   vence o 12px que o frotapcnet declara em `.fp-table thead th` (0,1,2). O
   DESIGN.md põe o piso de texto funcional na Legenda, 12,5px. Aqui (0,2,2). Só
   o corpo; densidade da célula e peso seguem com quem desenhou a tabela. */
.pk-app .table thead th,
[data-pcnet-escopo] .table thead th {
  font-size: var(--pk-text-xs);
  /* Tinta Fraca, a mesma da `.pk-table` e do skin do portal: o cabeçalho de
     coluna tem UMA tinta no parque (g6-familia-04; a camada forma a estende aos
     nomes de tabela dos plugins). Sobrescreve o --pk-ink-2 da regra acima só
     no th: 5,27:1 no branco, 5,60:1 no card escuro. */
  color: var(--pk-ink-3);
}

/* A PAGINAÇÃO da busca nativa (`templates/components/pager.html.twig`): a
   página ativa saía #fff sobre --tblr-primary (o verde-broto do tema do GLPI)
   — 2,05:1 nos dois temas — e as outras com a tinta do corpo sobre o fundo do
   Tabler. As variáveis são do componente (`.pagination`, 0,1,0); remapeá-las
   na caixa (0,2,0) faz a peça seguir a casa: Verde Broto com Verde Raiz por
   cima (6,27:1), números em Tinta Média, hover e foco no Papel Rebaixado. */
.pk-app .pagination,
[data-pcnet-escopo] .pagination {
  --tblr-pagination-color:               var(--pk-ink-2);
  --tblr-pagination-hover-color:         var(--pk-green-ink);
  --tblr-pagination-hover-bg:            var(--pk-surface-2);
  --tblr-pagination-focus-color:         var(--pk-green-ink);
  --tblr-pagination-focus-bg:            var(--pk-surface-2);
  --tblr-pagination-active-color:        var(--pk-on-green);
  --tblr-pagination-active-bg:           var(--pk-green);
  --tblr-pagination-active-border-color: var(--pk-green);
  --tblr-pagination-disabled-color:      var(--pk-ink-3);
}

/* A SETA DO <select> SEM .form-select. O core (css/legacy/includes/
   _inputs.scss:52, `select:not(.form-select)`) põe `appearance: none` e desenha
   a seta num SVG em data-URI com `stroke='var(--tblr-gray-800)'` — e var() não
   resolve dentro de uma imagem: o traço vira `none` e o select perde a seta.
   "Todos os hunters" e "Todos os clientes" liam como campo de texto
   (crm-dashboard, mpc-painel), nos dois temas.
   A cor vai LITERAL no SVG, por tema, num token (--pk-seta-select, definido
   logo abaixo para o claro e em pcnetui-tema-escuro.css para o escuro).
   `:where()` de propósito: (0,1,1), o MESMO peso da regra do core, e esta folha
   carrega depois — vence o core e PERDE para qualquer seta que o plugin desenhe
   (o agendapcnet e o lansentineldevices têm as suas, em verde, e ficam). O
   `[multiple]`/`[size]` continua sem seta: o core os zera com (0,2,1).

   🔴 A SETA LADRILHAVA EM TELA STANDALONE (2026-09-28). Esta regra só punha a
   IMAGEM e contava com o core para o resto (repeat, posição, tamanho,
   appearance). Em tela com DOCTYPE próprio o core não vem, e o atalho
   `background: var(--pk-surface)` do `.pk-select` repõe `repeat`: a fileira de
   setas corria por baixo do texto (dashboardpcnet sla_detail — 2,67:1 no claro,
   1,64:1 no escuro — remendado lá com três linhas locais). Agora a regra traz
   repeat, posição e tamanho do core, com os MESMOS valores: onde o core existe
   nada muda (mesmo peso, mesmo valor); onde não existe, a seta é uma só. O
   `.pk-app .pk-select` (pcnetui-forma, 0,2,0) continua pondo a posição dele.

   ⚠️ SEM `appearance` aqui, de propósito. Onde o core vem, ele já põe o `none`
   (mesmo peso); em tela standalone, o `appearance: none` do host apagava a seta
   NATIVA do select cujo plugin zera a imagem com o atalho `background` em peso
   maior — os quatro filtros do wazuh-insights (`.wd-app .ins-select`, 0,2,0)
   ficaram sem seta nenhuma, nos dois temas (revisão de 2026-09-28). Quem quer a
   seta da casa em tela standalone declara o próprio `appearance: none` (o
   `.filter-select` do dashboardpcnet declara). */
:root {
  --pk-seta-select: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%235b6678' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3E%3C/svg%3E");
}
:where(.pk-app, [data-pcnet-escopo]) select:not(.form-select) {
  background-image: var(--pk-seta-select);
  background-repeat: no-repeat;
  background-position: right .75rem center;
  background-size: 16px 12px;
}
/* A lista aberta ([multiple], [size] > 1) não tem seta — o core a zera com
   (0,2,1); em tela standalone é esta regra que zera. */
:where(.pk-app, [data-pcnet-escopo]) select:not(.form-select):where([multiple], [size]:not([size="1"])) {
  background-image: none;
}

/* O CHECKBOX E O RÁDIO NATIVOS (sem .form-check-input, que o Tabler desenha)
   marcavam no AZUL do navegador — mpc-config. `accent-color` é a propriedade
   feita para isso; o Verde Traço e não o Broto porque a caixa marcada é um
   alvo gráfico e precisa de 3:1 contra o papel (o Broto dá 2,05:1; o Traço,
   3,75:1 no claro e 8,87:1 no escuro). O navegador escolhe sozinho a cor do
   visto por contraste. */
.pk-app input[type="checkbox"],
.pk-app input[type="radio"],
[data-pcnet-escopo] input[type="checkbox"],
[data-pcnet-escopo] input[type="radio"] {
  accent-color: var(--pk-green-dark);
}

/* A seta do select da casa (ver acima) precisa de espaço à direita para o texto
   não correr por baixo dela. O !important é porque css/legacy/includes/_inputs.scss:52
   (select:not(.form-select)) impõe o padding do Tabler. Só o lado direito: a ALTURA
   do campo não muda nesta leva — devolver à peça .pk-input os 12px 15px que ela
   declara (o core rouba e a deixa com 35px) muda o tamanho de campos em várias
   telas e ficou para decisão do dono (2026-09-24). */
.pk-app .pk-select {
  padding-right: 40px !important;
  background-position: right 15px center;
}


/* =====================================================================
   ABA E MODAL — as duas peças que o padrão prometia e não tinha

   Escritas em 2026-08-26. Até então `--pk-radius` dizia no comentário "card,
   painel, MODAL, dropdown" e o modal nunca existiu; aba só existia no skin do
   `portalpcnet`, repintando a nativa do GLPI, e portanto só alcançava telas
   nativas — nunca uma tela de plugin.

   A consequência era concreta: a aba Decidir não tinha o que cobrar dessas duas
   famílias, e cada plugin que precisou de uma inventou a sua. Um padrão que
   promete e não entrega empurra a divergência para quem precisa da peça hoje.

   Nenhuma das duas é invenção: a aba segue o que o skin do portal já aplicava
   (skin/helpdesk.css:372) e o modal deriva de `.pk-gate` e `.pk-pop`, que já
   concordam entre si. O que muda é passarem a existir em `.pk-*`, alcançáveis
   por qualquer tela do parque.
   ===================================================================== */

/* --- ABA ------------------------------------------------------------
   O canto arredondado só em cima: uma aba é uma pasta, e a borda de baixo é a
   linha da qual a ativa se destaca. `border-bottom` de 2px transparente no
   repouso — e não `border: none` — para a ativa não empurrar o texto 2px ao
   ganhar a linha verde. É o defeito clássico de aba, e ele só aparece
   clicando. */
.pk-tabs {
  display: flex; gap: var(--pk-sp-1);
  border-bottom: 1px solid var(--pk-hairline);
  overflow-x: auto;
}
.pk-tab {
  font-family: var(--pk-font);
  font-size: var(--pk-text-base);
  font-weight: 600;
  color: var(--pk-ink-2);
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  border-radius: var(--pk-radius-sm) var(--pk-radius-sm) 0 0;
  padding: 10px 16px;
  cursor: pointer;
  white-space: nowrap;
  display: inline-flex; align-items: center; gap: var(--pk-sp-2);
  transition: all var(--pk-ease);
}
.pk-tab:hover        { color: var(--pk-green-ink); background: var(--pk-green-soft); }
.pk-tab.is-active    { color: var(--pk-green-ink); border-bottom-color: var(--pk-green); }
/* A aba INATIVA não esmaece por opacidade: `opacity: .6` levava a Tinta Média
   a 2,40:1 sobre o fundo da página ("Faturamento" no catálogo do Blueprint) —
   opacidade apaga o texto junto com o estado. Tinta Fraca, peso 500 (as outras
   são 600) e o hover neutro dizem "não clica"; a leitura fica em 4,66:1 no
   claro (sobre --pk-bg, o pior caso) e 6,4:1 no escuro. O `.pk-app` repetido é
   porque a camada forma crava o 600 da aba em (0,2,0). */
.pk-tab[disabled],
.pk-tab[disabled]:hover,
.pk-app .pk-tab[disabled] { color: var(--pk-ink-3); background: none; font-weight: 500; cursor: not-allowed; }
.pk-tab:focus-visible {
  outline: var(--pk-ring, 3px solid var(--pk-green-dark));
  outline-offset: var(--pk-ring-offset, 2px);
}

/* --- MODAL ----------------------------------------------------------
   Mesmo véu do `.pk-gate` (que já é o valor de --pk-bg a 96%) e mesmo raio do
   card. `max-height` com rolagem interna porque conteúdo de modal cresce sem
   avisar, e sem isto o botão de confirmar sai da tela em telas baixas — que é
   o mesmo defeito da coluna de ação que a tabela do dedo-duro teve. */
.pk-modal {
  position: fixed; inset: 0; z-index: 11000;
  /* a fonte da casa: o modal é pendurado no <body>, fora da .pk-app, e herdava
     o Inter do Tabler (o CRM migrou o confirm para cá em 2026-09-28 e o título
     saiu em Inter — a revisão da Onda B mediu) */
  font-family: var(--pk-font);
  display: none; align-items: center; justify-content: center;
  /* 🔴 `color-mix` e não o literal `rgba(238,241,246,.96)`. O valor era o de
     `--pk-bg` a 96% — correto no claro e CRAVADO: `--pk-bg` muda por tema
     (#eef1f6 / #111a13) e a folha escura não tem regra nenhuma para esta peça,
     então o véu de tela cheia saía quase BRANCO com o tema escuro ligado.
     Apontado pela sessão que audita o monitorpcnet em 2026-09-01; era a única
     superfície de tela cheia do padrão que não acompanhava o tema.
     `color-mix` segue os dois sem `!important` e sem duplicar a regra lá. */
  background: color-mix(in srgb, var(--pk-bg) 96%, transparent);
  padding: 24px;
}
.pk-modal.is-on { display: flex; }
.pk-modal__caixa {
  background: var(--pk-surface);
  border: 1px solid var(--pk-hairline);
  border-radius: var(--pk-radius);
  box-shadow: var(--pk-shadow-lg);
  padding: 28px;
  width: 100%; max-width: 520px;
  max-height: calc(100vh - 48px);
  overflow-y: auto;
}
.pk-modal__head {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--pk-sp-3); margin-bottom: var(--pk-sp-3);
}
.pk-modal__title { font-size: var(--pk-text-xl); font-weight: 700; color: var(--pk-ink); }
.pk-modal__body  { font-size: var(--pk-text-base); color: var(--pk-ink-2); line-height: var(--pk-leading); }
/* Ações à direita, e com espaço entre si: é a última coisa que a pessoa lê. */
.pk-modal__foot  { display: flex; gap: var(--pk-sp-2); justify-content: flex-end; margin-top: 22px; flex-wrap: wrap; }

@media (max-width: 600px) {
  .pk-modal { padding: 12px; align-items: flex-end; }
  .pk-modal__caixa { padding: 20px; max-height: calc(100vh - 24px); }
  /* No celular o polegar alcança a base: as ações ocupam a largura toda e
     ficam em ordem inversa, com a principal por último e mais perto. */
  .pk-modal__foot { flex-direction: column-reverse; }
  .pk-modal__foot > * { width: 100%; justify-content: center; }
}

/* =====================================================================
   SELECT2 — o campo de seleção do GLPI, dentro da caixa do plugin.

   Ele aparece em TODO formulário do parque e desenha o próprio widget com
   fundo branco fixo. No tema escuro sobrava texto claro sobre branco: medido
   1,14:1 no campo de fabricante do estoque do Flow — o valor era invisível.

   ⚠️ O dropdown do Select2 é anexado ao <body>, FORA da caixa do plugin, e por
   isso precisa da segunda regra sem escopo. Ela é limitada às classes do
   próprio Select2, então não alcança o chrome do GLPI.                       */
.pk-app .select2-container--default .select2-selection,
[data-pcnet-escopo] .select2-container--default .select2-selection {
  background: var(--pk-surface);
  border-color: var(--pk-border);
  color: var(--pk-ink);
}
.pk-app .select2-container--default .select2-selection__rendered,
.pk-app .select2-container--default .select2-selection__placeholder,
[data-pcnet-escopo] .select2-container--default .select2-selection__rendered {
  color: var(--pk-ink);
}
.pk-app .select2-container--default .select2-selection__arrow b,
[data-pcnet-escopo] .select2-container--default .select2-selection__arrow b {
  border-top-color: var(--pk-ink-2);
}

html[data-pcnet-tema="escuro"] .select2-dropdown {
  background: var(--pk-surface);
  border-color: var(--pk-border);
  color: var(--pk-ink);
}
html[data-pcnet-tema="escuro"] .select2-container--default .select2-results__option {
  color: var(--pk-ink);
}
html[data-pcnet-tema="escuro"] .select2-container--default .select2-results__option--highlighted[aria-selected] {
  background: var(--pk-green);
  color: var(--pk-on-green);
}
html[data-pcnet-tema="escuro"] .select2-search__field {
  background: var(--pk-surface-2);
  color: var(--pk-ink);
  border-color: var(--pk-border);
}
