/* Painel NOC da ExNet — design system.

   Mesma estrutura do NOC MASTER (barra escura fixa sobre conteúdo claro, para
   a barra ficar igual em todas as telas e o conteúdo ter contraste alto para
   leitura longa), na paleta vermelho/azul-marinho da marca — as duas cores da
   águia da ExNet Fiber.

   ⚠️ Toda chave do menu (nav.py) precisa de regra de cor aqui. Sem `color`
   declarado o navegador aplica a cor de link :visited e o botão muda sozinho
   conforme o operador clica — parece escolha de design e é bug. O
   tests/test_nav.py falha se alguma chave ficar de fora. */

:root {
  /* Navegação (escura) */
  --nav-1:      #0b1220;
  --nav-2:      #070d18;
  --nav-borda:  #1c2b44;
  --nav-texto:  #c6d4e6;

  /* Conteúdo (claro) */
  --fundo:      #ffffff;
  --fundo-alt:  #eef4fa;
  --texto:      #0a1524;
  --texto-2:    #4a5a6e;
  --texto-3:    #7d8fa5;
  --borda:      #dce5f0;

  /* Marca FlyUp */
  --ciano:      #0891b2;
  --ciano-claro:#22d3ee;
  --indigo:     #4f46e5;

  /* Semântica */
  --azul:       #0a6fb0;
  --verde:      #0a8f5f;
  --ambar:      #d98207;
  --vermelho:   #c81e4a;
  --neutro:     #8496ab;

  --raio: 10px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
  color: var(--texto);
  background: var(--fundo);
}

a { color: var(--ciano); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ===================================================== navegação global */

#gnav {
  display: flex; align-items: center; gap: 6px;
  padding: 0 18px; min-height: 52px; flex-wrap: wrap;
  background: linear-gradient(180deg, var(--nav-1), var(--nav-2));
  border-bottom: 1px solid var(--nav-borda);
  position: sticky; top: 0; z-index: 100000;
  /* overflow visível: com overflow-x:auto o submenu absoluto fica cortado.
     O flex-wrap já cobre tela estreita. */
  overflow: visible;
}

#gnav .marca {
  display: inline-flex; align-items: center; gap: 8px;
  color: #fff; font-weight: 800; letter-spacing: .3px;
  font-size: 14px; margin-right: 14px; white-space: nowrap;
}
/* Marca larga e ícone quadrado são coisas diferentes: fixar os dois lados
   esmagaria a asa. */
#gnav .marca img { height: 26px; width: auto; display: block; }

#gnav a, #gnav .gbtn {
  color: var(--nav-texto);
  font-size: 12px; font-weight: 700; letter-spacing: .4px;
  padding: 7px 12px; border-radius: 8px; white-space: nowrap;
  text-decoration: none; border: 1px solid transparent;
}
#gnav a:visited { color: var(--nav-texto); }
#gnav a:hover, #gnav .gbtn:hover {
  background: rgba(255,255,255,.07); color: #fff; text-decoration: none;
}
#gnav a.ativo, #gnav a.ativo:visited,
#gnav .grp.ativo > .gbtn {
  background: var(--ciano); color: #fff; border-color: var(--ciano-claro);
}

/* --- cor por família (uma regra cobre o grupo e todos os filhos) --- */
#gnav .home                                  { color: #e8eef7; background: rgba(255,255,255,.06); }
#gnav .alarmes                               { color: #ff6b7a; background: rgba(200,30,74,.16);  border-color: rgba(200,30,74,.42); }
#gnav .rede, #gnav .equipamentos, #gnav .sla { color: #7fb0f0; background: rgba(127,176,240,.12); border-color: rgba(127,176,240,.32); }

/* --- grupos com submenu --- */
#gnav .grp { position: relative; display: inline-flex; }
#gnav .gbtn { cursor: pointer; user-select: none; display: inline-flex; align-items: center; gap: 5px; }
#gnav .gbtn i { font-style: normal; font-size: 9px; opacity: .75; transition: transform .15s; }
#gnav .grp.aberto .gbtn i { transform: rotate(180deg); }

#gnav .gsub {
  display: none; position: absolute; top: calc(100% + 7px); left: 0;
  min-width: 190px; flex-direction: column; gap: 5px; padding: 7px;
  border-radius: var(--raio);
  background: linear-gradient(180deg, var(--nav-1), var(--nav-2));
  border: 1px solid var(--nav-borda);
  box-shadow: 0 14px 34px rgba(0,0,0,.6);
  z-index: 100001;
}
/* Ponte invisível: sem ela o menu fecha ao atravessar o vão com o mouse. */
#gnav .gsub::before { content: ''; position: absolute; top: -9px; left: 0; right: 0; height: 9px; }
#gnav .gsub a { display: block; width: 100%; text-align: left; }
/* Hover não existe em toque: sem esta consulta o menu não abre no celular. */
@media (hover: hover) { #gnav .grp:hover .gsub { display: flex; } }
#gnav .grp.aberto .gsub { display: flex; }
/* Submenu encostado na borda direita vazaria para fora da tela; o JS mede o
   botão e troca para cá. */
#gnav .gsub.direita { left: auto; right: 0; }

#gnav .espaco { flex: 1; }
#gnav .usuario { color: var(--texto-3); font-size: 11.5px; }
#gnav .usuario b { color: #fff; }

.badge {
  display: inline-block; min-width: 18px; padding: 0 5px; margin-left: 5px;
  background: var(--vermelho); color: #fff;
  border-radius: 9px; font-size: 10.5px; font-weight: 800; text-align: center;
}
.badge.oculto { display: none; }

/* ============================================================= conteúdo */

.conteudo { padding: 20px 26px 40px; max-width: 1500px; margin: 0 auto; }

.hd {
  display: flex; justify-content: space-between; align-items: flex-start;
  border-bottom: 2px solid var(--texto);
  padding-bottom: 10px; margin-bottom: 14px; gap: 16px; flex-wrap: wrap;
}
.hd h1 { font-size: 19px; margin: 0; }
.hd .sub { margin-top: 3px; }

/* Regra global, e não só dentro de .hd: `.sub` é usada como texto auxiliar em
   várias telas (nota de ordenação, "medido por", resumo de bloco). Sem ela,
   fora do cabeçalho esses textos herdavam o tamanho do corpo e apareciam com
   cara de título — o que ficou evidente no celular. */
.sub { color: var(--texto-3); font-size: 11.5px; }

/* ------------------------------------------------------------ KPI cards */

.kpis { display: flex; gap: 10px; flex-wrap: wrap; margin: 14px 0 18px; }
.kpi {
  border: 1px solid var(--borda); border-radius: var(--raio);
  padding: 11px 15px; min-width: 140px; background: #fff; flex: 1 1 140px;
}
.kpi .l {
  font-size: 10px; text-transform: uppercase; letter-spacing: .5px;
  color: var(--texto-3); font-weight: 700;
}
.kpi .v { font-size: 22px; font-weight: 800; margin-top: 3px; line-height: 1.15; }
.kpi .d { font-size: 10.5px; color: var(--texto-2); margin-top: 2px; }
.kpi.big  .v { color: var(--ciano); }
.kpi.ok   .v { color: var(--verde); }
.kpi.over .v { color: var(--vermelho); }
.kpi.warn .v { color: var(--ambar); }
/* Sem medição: travessão em cinza, com o motivo no title. Nunca zero. */
.kpi.sem  .v { color: var(--texto-3); font-weight: 700; }

/* -------------------------------------------------------------- blocos */

.bloco { margin-bottom: 22px; }
.bloco > h2, .bloco-hd h2 {
  font-size: 11px; text-transform: uppercase; letter-spacing: .6px;
  color: var(--texto-2); margin: 0 0 8px; font-weight: 800;
}
.bloco-hd { display: flex; justify-content: space-between; align-items: center; gap: 14px; flex-wrap: wrap; margin-bottom: 8px; }
.bloco-hd h2 { margin: 0; }

.caixa { border: 1px solid var(--borda); border-radius: var(--raio); padding: 12px; background: #fff; }
.grade2 { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
@media (max-width: 900px) { .grade2 { grid-template-columns: 1fr; } }

/* ------------------------------------------------------------- tabelas */

/* Rolagem no contêiner, não no documento. ⚠️ O medidor de estouro da página
   não enxerga rolagem interna — medir as duas coisas ao validar no celular. */
.tab-wrap { overflow-x: auto; }
table.tab { width: 100%; border-collapse: collapse; font-size: 12.5px; }
table.tab th {
  background: var(--texto); color: #fff; text-align: left;
  padding: 8px 10px; font-size: 10.5px;
  text-transform: uppercase; letter-spacing: .4px; font-weight: 700;
  position: sticky; top: 0;
}
table.tab th.num, table.tab td.num { text-align: right; }
table.tab td { padding: 8px 10px; border-bottom: 1px solid var(--borda); }
table.tab tr:hover td { background: #f6fbfd; }
table.tab tr.grp td {
  background: var(--fundo-alt); font-weight: 800; text-transform: uppercase;
  font-size: 10.5px; letter-spacing: .6px; color: #456;
}
table.tab td.b { font-weight: 800; color: var(--ciano); }
td.ok   { color: var(--verde);    font-weight: 700; }
td.over { color: var(--vermelho); font-weight: 800; }
td.sem  { color: var(--texto-3); }

.vazio { text-align: center; color: var(--texto-3); padding: 26px 10px; font-size: 12.5px; }

/* Estado honesto para tela que depende de dado que não veio. */
.aviso {
  border: 1px solid var(--borda); border-left: 3px solid var(--ambar);
  background: #fffbf2; border-radius: 8px;
  padding: 12px 14px; font-size: 12.5px; color: var(--texto-2);
}
.aviso.ruim { border-left-color: var(--vermelho); background: #fdf0f3; }
.aviso b { color: var(--texto); }

/* ------------------------------------------------------------- pílulas */

.pil {
  display: inline-block; padding: 2px 8px; border-radius: 9px;
  font-size: 10px; font-weight: 800; color: #fff;
  text-transform: uppercase; letter-spacing: .3px; white-space: nowrap;
}
.sev-0 { background: var(--neutro); }
.sev-1 { background: #4a90c2; }
.sev-2 { background: var(--ambar); color: #2a1c00; }
.sev-3 { background: #e0700a; }
.sev-4 { background: var(--vermelho); }
.sev-5 { background: #9b1030; }
.pil.bloq { background: var(--ambar); color: #2a1c00; }
.pil.ativo { background: var(--verde); }

/* ------------------------------------------------- faixa de saúde */

.faixa { display: flex; gap: 8px; flex-wrap: wrap; }
.faixa .st {
  display: inline-flex; align-items: center; gap: 7px;
  border: 1px solid var(--borda); border-radius: 999px;
  padding: 6px 13px; background: #fff; font-size: 12px;
}
.faixa .st b { font-weight: 800; }
.faixa .bola { width: 9px; height: 9px; border-radius: 50%; background: var(--verde); }
.faixa .bola.neutra { background: var(--neutro); }
.faixa .bola.ruim   { background: var(--vermelho); }
.faixa .st-s { color: var(--texto-2); font-size: 11px; }
.faixa .st-s.ruim { color: var(--vermelho); font-weight: 700; }

/* -------------------------------------------------- mapa das PONs */

.ponmap { display: flex; flex-wrap: wrap; gap: 12px; }
.ponslot { border: 1px solid var(--borda); border-radius: var(--raio); padding: 10px; background: #fff; }
.ponslot h3 {
  margin: 0 0 8px; font-size: 10px; text-transform: uppercase;
  letter-spacing: .5px; color: var(--texto-2);
  display: flex; align-items: center; gap: 8px;
}
.pongrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(58px, 1fr)); gap: 6px; }
.pon {
  border: 1px solid var(--borda); border-radius: 7px;
  padding: 6px 5px; text-align: center; background: #f7fafd; cursor: default;
}
.pon .n { font-size: 15px; font-weight: 800; line-height: 1.1; }
.pon .s { font-size: 9.5px; color: var(--texto-3); margin-top: 1px; }
/* Verde = tudo no ar. Âmbar só quando a queda é relevante (≥5 ONTs ou ≥30%
   da porta): pintar a cada 1 ONT caída deixou 35 de 40 âmbar no painel antigo
   e o alerta virou paisagem. Cinza = porta sem ONT autorizada. */
.pon.ok      { border-color: rgba(10,143,95,.4);  background: #eefaf5; }
.pon.ok .n   { color: var(--verde); }
.pon.atencao { border-color: rgba(217,130,7,.5);  background: #fff8ec; }
.pon.atencao .n { color: var(--ambar); }
.pon.vazia   { opacity: .55; }
.pon.vazia .n { color: var(--texto-3); }

/* ------------------------------------------------------- barras */

.barra { height: 7px; border-radius: 4px; background: var(--fundo-alt); overflow: hidden; }
.barra > i { display: block; height: 100%; background: var(--ciano); }
.barra.alta > i { background: var(--vermelho); }
.barra.media > i { background: var(--ambar); }

/* ------------------------------------------------------- controles */

.btn {
  font-size: 12px; font-weight: 700; padding: 6px 13px;
  border-radius: 7px; border: 1px solid var(--ciano);
  background: var(--ciano); color: #fff; cursor: pointer;
}
.btn:hover { filter: brightness(1.08); }
.btn.leve { background: #fff; color: var(--ciano); }
.btn.leve:hover { background: #eefafd; }
.btn:disabled { opacity: .5; cursor: default; }

select, input[type=text], input[type=password], input[type=search] {
  font-family: inherit; font-size: 12.5px;
  padding: 6px 10px; border: 1px solid var(--borda);
  border-radius: 7px; background: #fff; color: var(--texto); max-width: 460px;
}
select:focus, input:focus { outline: 2px solid var(--ciano); outline-offset: -1px; }

.controles { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.chip {
  border: 1px solid var(--borda); border-radius: 999px; background: #fff;
  padding: 5px 12px; font-size: 11.5px; font-weight: 700; cursor: pointer;
  color: var(--texto-2);
}
.chip.on { background: var(--ciano); border-color: var(--ciano); color: #fff; }

.pager { display: flex; gap: 5px; align-items: center; margin-top: 10px; flex-wrap: wrap; }
.pager button {
  min-width: 30px; padding: 4px 8px; font-size: 11.5px; font-weight: 700;
  border: 1px solid var(--borda); background: #fff; border-radius: 6px; cursor: pointer;
  color: var(--texto-2);
}
.pager button.on { background: var(--ciano); border-color: var(--ciano); color: #fff; }
.pager .info { color: var(--texto-3); font-size: 11px; margin-left: 6px; }

/* ------------------------------------------------------------- rodapé */

.rodape {
  border-top: 1px solid var(--borda); margin-top: 10px;
  padding: 11px 26px; font-size: 10.5px; color: var(--texto-3); text-align: center;
}

/* ================================================================ login */

.tela-login {
  display: flex; align-items: center; justify-content: center;
  min-height: 100vh; position: relative; overflow: hidden;
  background: linear-gradient(180deg, #0d1b2e, #050a12);
}
#malha { position: absolute; inset: 0; width: 100%; height: 100%; }

.caixa-login {
  position: relative; z-index: 1; width: min(390px, 92vw);
  background: rgba(255,255,255,.97);
  border-radius: 14px; padding: 30px;
  box-shadow: 0 22px 60px rgba(0,0,0,.55);
}
.caixa-login .idr { text-align: center; margin-bottom: 18px; }
.caixa-login .idr img { height: 54px; width: auto; }
.caixa-login h1 { margin: 0; font-size: 18px; letter-spacing: .3px; text-align: center; }
.caixa-login .sub { margin: 4px 0 20px; color: var(--texto-3); font-size: 12px; text-align: center; }
.caixa-login label { display: block; margin-bottom: 13px; }
.caixa-login label > span {
  display: block; margin-bottom: 5px; font-size: 10px;
  text-transform: uppercase; letter-spacing: .5px;
  color: var(--texto-3); font-weight: 700;
}
/* :not([type=checkbox]) é essencial — sem isso a caixa de seleção do "manter
   conectado" também ganha width:100%, vira um item flex de largura total e
   espreme o rótulo em três linhas. */
.caixa-login input:not([type=checkbox]) {
  width: 100%; max-width: none; padding: 10px 12px; font-size: 14px;
}
.caixa-login .check {
  display: flex; align-items: center; gap: 8px;
  font-size: 12px; color: var(--texto-2); margin: 6px 0 2px;
}
.caixa-login .check input { flex: 0 0 auto; width: 15px; height: 15px; margin: 0; }
.caixa-login button {
  width: 100%; margin-top: 14px; padding: 11px;
  font-size: 14px; font-weight: 800; letter-spacing: .5px;
  border-radius: 8px; border: 0; color: #fff; cursor: pointer;
  background: linear-gradient(90deg, var(--ciano), var(--indigo));
}
.caixa-login button:hover { filter: brightness(1.1); }
.erro {
  background: #fdeaef; border: 1px solid var(--vermelho); color: #8d1233;
  padding: 9px 11px; border-radius: 8px; margin-bottom: 14px; font-size: 12.5px;
}

/* ================================================================ mobile */

@media (max-width: 760px) {
  #gnav { padding: 8px 12px; gap: 4px; }
  #gnav .marca { width: 100%; margin: 0 0 4px; }
  #gnav .espaco { display: none; }
  #gnav .usuario { width: 100%; margin-top: 4px; }
  .conteudo { padding: 14px; }
  .kpi { flex: 1 1 132px; min-width: 132px; }
  table.tab { font-size: 11.5px; }
  table.tab th, table.tab td { padding: 6px 7px; }
  .pongrid { grid-template-columns: repeat(auto-fill, minmax(52px, 1fr)); }
  /* Coluna secundária some antes de a que importa ficar cortada. */
  .soXL { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}
