/* Tema escuro fixo: a tela vive numa TV de parede, sem alternância de tema.
   Cores de status vêm da paleta validada (good/warning/serious/critical).

   O navegador da TV (Chrome 79 do webOS) ignora `gap` dentro de flexbox — só
   passou a valer no Chrome 84. Nos contêineres flex o espaçamento é feito com
   margem (`> * + *`), que vale em qualquer navegador; nos de grid o `gap` fica,
   porque ali já funciona desde muito antes. */
:root {
  color-scheme: dark;
  --page:        #0d0d0d;
  --surface:     #1a1a19;
  --surface-2:   #212120;
  --ink:         #ffffff;
  --ink-2:       #c3c2b7;
  --muted:       #898781;
  --line:        #2c2c2a;
  --border:      rgba(255, 255, 255, 0.10);

  --good:        #0ca30c;
  --warning:     #fab219;
  --serious:     #ec835a;
  --critical:    #d03b3b;
  --accent:      #3987e5;

  /* Faixa de 2,4 GHz x 5 GHz, em dois verdes. O par foi validado contra a
     superfície escura (#1a1a19): fica dentro da banda de luminosidade do tema
     escuro, passa do piso de croma, tem contraste ≥ 3:1 com o fundo e separação
     ΔE 18,3 na visão normal / 17,8 em deuteranopia — bem acima do piso de 15/8.

     São verdes de matiz esmeralda (h≈161–170), afastados do verde de status
     (--good, h≈145): assim a barra de bandas não é confundida com a de
     qualidade do sinal, que fica no painel ao lado e ali verde quer dizer
     "bom". Na barra de bandas a cor é só identidade, não julgamento.

     O tom claro vai no 5 GHz de propósito — é a faixa que se quer ver crescer. */
  --banda-24:    #007452;
  --banda-5:     #00b16e;
  /* 6 GHz não existe nos rádios destes hotéis (U7LR, U6 LR, U6+); o segmento só
     entra na barra se a controladora passar a reportá-lo. */
  --banda-6:     #5fd6a4;

  --gap: clamp(12px, 1.2vw, 22px);
  --radius: 14px;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  background: var(--page);
  color: var(--ink);
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  overflow: hidden;
}

body {
  display: flex;
  flex-direction: column;
}

/* ---------- barra de progresso da rotação ---------- */
.rotate-bar {
  height: 4px;
  background: var(--line);
  flex: none;
}
.rotate-bar span {
  display: block;
  height: 100%;
  width: 0;
  background: var(--accent);
}
body.paused .rotate-bar span { background: var(--muted); }

/* ---------- topo ---------- */
.topbar {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: clamp(10px, 1vw, 18px) clamp(16px, 2vw, 34px);
  border-bottom: 1px solid var(--border);
  background: var(--surface);
}
.topbar > * + * { margin-left: var(--gap); }

.brand {
  display: flex;
  align-items: center;
  min-width: 0;
}
.brand > * + * { margin-left: 14px; }

/* Altura fixa e largura livre: aceita logo quadrado ou faixa horizontal
   sem distorcer nem empurrar o título para fora da barra. */
.logo {
  height: clamp(28px, 3vw, 46px);
  width: auto;
  max-width: 220px;
  object-fit: contain;
  flex: none;
}

.brand-text { min-width: 0; }

.brand h1 {
  margin: 0;
  font-size: clamp(17px, 1.5vw, 26px);
  font-weight: 600;
  letter-spacing: -0.01em;
}

.sources {
  display: flex;
  margin-top: 6px;
  font-size: clamp(11px, 0.75vw, 13px);
  color: var(--muted);
}
.sources > * + * { margin-left: 14px; }
/* o rótulo do .src é nó de texto, não elemento: a margem vai na bolinha */
.sources .src { display: flex; align-items: center; }
.sources .src .dot { margin-right: 6px; }
.sources .dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--muted); flex: none;
}
.sources .dot.ok  { background: var(--good); }
.sources .dot.err { background: var(--critical); }

.tabs { display: flex; }
.tabs > * + * { margin-left: 8px; }
.tab {
  padding: 8px 18px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: transparent;
  color: var(--ink-2);
  font: inherit;
  font-size: clamp(12px, 0.9vw, 15px);
  cursor: pointer;
  white-space: nowrap;
}
.tab.active {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--page);
  font-weight: 600;
}

.clockbox { display: flex; align-items: center; }
.clockbox > * + * { margin-left: 14px; }
.clock {
  font-size: clamp(22px, 2.2vw, 40px);
  font-weight: 600;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.date { font-size: clamp(11px, 0.75vw, 13px); color: var(--muted); margin-top: 4px; }
.pause {
  width: 38px; height: 38px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--ink-2);
  cursor: pointer;
  font-size: 12px;
  flex: none;
}
body.paused .pause { color: var(--warning); border-color: var(--warning); }

/* ---------- telas ---------- */
main {
  flex: 1;
  min-height: 0;
  padding: var(--gap) clamp(16px, 2vw, 34px);
}
.screen {
  display: none;
  height: 100%;
  flex-direction: column;
}
.screen.active { display: flex; }
.screen > * + * { margin-top: var(--gap); }

/* ---------- KPIs ---------- */
.kpis {
  flex: none;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--gap);
}
.kpi {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: clamp(12px, 1.1vw, 22px) clamp(14px, 1.3vw, 26px);
  display: flex;
  flex-direction: column;
}
.kpi > * + * { margin-top: 2px; }
.kpi-label {
  font-size: clamp(11px, 0.85vw, 15px);
  color: var(--ink-2);
  font-weight: 500;
}
.kpi-value {
  font-size: clamp(34px, 4.2vw, 78px);
  font-weight: 600;
  line-height: 1.05;
  color: var(--critical);          /* padrão: contadores de problema */
  font-variant-numeric: tabular-nums;
}
.kpi-value.good    { color: var(--good); }
.kpi-value.neutral { color: var(--ink); }
.kpi-value.warn    { color: var(--warning); }
.kpi-value.accent  { color: var(--accent); }
.kpi-value.zero    { color: var(--muted); }
.kpi-foot {
  font-size: clamp(10px, 0.72vw, 13px);
  color: var(--muted);
}

/* ---------- painéis ---------- */
/* Coluna da esquerda das telas de site: três painéis empilhados que dividem a
   altura por igual. Grid e não flex justamente pelo `gap`. */
/* Telas de site: faixa dos três painéis em cima, tabela de rádios embaixo.
   Empilhados numa coluna lateral, cada painel ficava com a largura ~3x a
   altura — achatado. Lado a lado, ocupando um terço da largura cada e mais da
   metade da altura útil, a proporção cai para perto de 3:2. Quadrado de
   verdade exigiria estreitar a faixa e deixar tarja preta dos dois lados, o
   que numa TV é desperdício de tela.

   A faixa leva um pouco mais de altura que a tabela: os painéis é que são
   lidos de longe, e a tabela já traz os rádios fora do ar nas primeiras
   linhas. */
.site-corpo {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-rows: 1.3fr 1fr;
  gap: var(--gap);
}
.trio {
  min-height: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--gap);
}
/* Coluna de painéis da tela de rede (um por site). */
.lado {
  min-height: 0;
  display: grid;
  grid-auto-rows: 1fr;
  gap: var(--gap);
}
.panel {
  min-height: 0;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.panel-head {
  flex: none;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  padding: clamp(9px, 0.8vw, 16px) clamp(14px, 1.3vw, 26px);
  border-bottom: 1px solid var(--border);
}
.panel-head h2 {
  margin: 0;
  font-size: clamp(12px, 0.95vw, 17px);
  font-weight: 600;
  white-space: nowrap;
}
.hint {
  font-size: clamp(10px, 0.72vw, 13px);
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-left: 10px;
}

.panel-corpo {
  flex: 1;
  min-height: 0;
  padding: clamp(10px, 0.95vw, 18px) clamp(14px, 1.3vw, 26px);
  display: flex;
  flex-direction: column;
  /* space-evenly em vez de center: quando sobra altura o conteúdo se espalha e
     preenche o painel; quando falta, o aperto é distribuído em vez de cortar as
     duas pontas de uma vez, como o center fazia. */
  justify-content: space-evenly;
  overflow: hidden;
}
.panel-corpo > * + * { margin-top: clamp(6px, 0.7vw, 13px); }

.table-wrap { flex: 1; min-height: 0; overflow: auto; }

/* ---------- barra empilhada (bandas e faixas de sinal) ---------- */
.stack {
  flex: none;
  display: flex;
  height: clamp(18px, 1.9vw, 32px);
  border-radius: 6px;
  overflow: hidden;
  background: var(--line);
}
.stack span {
  display: block;
  height: 100%;
  transition: width .6s ease;
}
/* Fresta de 2px na cor do painel entre segmentos vizinhos: separa as faixas sem
   depender só da diferença de cor — o que importa agora que 2,4 e 5 GHz são dois
   verdes. Como o box-sizing é border-box, a borda cai dentro da largura e a soma
   dos segmentos continua fechando 100%. */
.stack span + span { border-left: 2px solid var(--surface); }

/* Cores das faixas, sem o .stack na frente de propósito: as mesmas classes
   pintam o segmento da barra e a bolinha da legenda. Ficam em classe, e não em
   style inline, porque a CSP da dashboard é style-src 'self' — atributo style
   vindo de innerHTML é descartado pelo navegador. */
.seg-24  { background: var(--banda-24); }
.seg-5   { background: var(--banda-5); }
.seg-6   { background: var(--banda-6); }
/* Qualidade do sinal, do melhor ao pior. Os nomes acompanham as classes para
   que o CSS e a legenda digam a mesma coisa. */
.seg-excelente { background: var(--good); }
.seg-otimo     { background: #6fbf3f; }
.seg-bom       { background: var(--warning); }
.seg-ruim      { background: var(--critical); }

/* Legenda em grid de duas colunas: rótulo com a cor à esquerda, valor à direita.
   Cada faixa aparece com número, nunca só com cor. */
.stack-leg {
  flex: none;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(5px, 0.5vw, 9px) clamp(10px, 1vw, 18px);
  font-size: clamp(12px, 0.92vw, 17px);
}
.stack-leg .item {
  display: flex;
  align-items: center;
  min-width: 0;
}
.stack-leg .item > * + * { margin-left: 7px; }
.stack-leg .cor {
  width: 10px; height: 10px;
  border-radius: 3px;
  flex: none;
}
.stack-leg .rot {
  color: var(--ink-2);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Intervalo de dBm ao lado do nome: recuado em cor e tamanho, para o nome da
   faixa continuar sendo o que se lê primeiro. */
.stack-leg .rot i {
  font-style: normal;
  color: var(--muted);
  font-size: 0.86em;
}
.stack-leg .val {
  color: var(--ink);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  margin-left: auto;
  padding-left: 8px;
}

/* ---------- gráfico de barras (clientes por faixa) ----------
   Três colunas: rótulo, trilho da barra e quantidade. Como é uma grade, os
   rótulos alinham entre si e os números também, sem depender do comprimento de
   cada barra. `gap` aqui é legítimo — o contêiner é grid, não flex. */
.barras {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  column-gap: clamp(10px, 1vw, 20px);
  row-gap: clamp(12px, 1.6vw, 26px);
}
.b-rot {
  color: var(--ink-2);
  font-size: clamp(12px, 0.95vw, 18px);
  white-space: nowrap;
}
.b-trilho {
  height: clamp(18px, 1.9vw, 32px);
  background: var(--line);
  border-radius: 6px;
  overflow: hidden;
}
/* A cor vem da classe seg-* — a mesma família usada no resto da tela. */
.b-fill {
  display: block;
  height: 100%;
  border-radius: 6px;
  transition: width .6s ease;
}
.b-val {
  color: var(--ink);
  font-weight: 700;
  font-size: clamp(17px, 1.5vw, 30px);
  font-variant-numeric: tabular-nums;
  text-align: right;
  min-width: 1.6em;      /* 9 e 52 param na mesma coluna */
}

/* ---------- métrica com barra (ocupação do canal, densidade) ---------- */
.metric { flex: none; }
.metric-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 5px;
}
.metric-label {
  font-size: clamp(12px, 0.92vw, 17px);
  color: var(--ink-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.metric-val {
  font-size: clamp(16px, 1.35vw, 26px);
  font-weight: 700;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  margin-left: 10px;
  white-space: nowrap;
}
.metric-val.good { color: var(--good); }
.metric-val.warn { color: var(--warning); }
.metric-val.down { color: var(--critical); }
.bar {
  height: clamp(8px, 0.7vw, 14px);
  border-radius: 999px;
  background: var(--line);
  overflow: hidden;
}
.bar span {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--good);
  transition: width .6s ease, background .6s ease;
}
.bar span.warn { background: var(--warning); }
.bar span.down { background: var(--critical); }

/* Par rótulo/valor sem barra, para números que não são percentuais. */
.dupla {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  font-size: clamp(12px, 0.92vw, 17px);
  color: var(--muted);
}
.dupla b {
  color: var(--ink);
  font-weight: 700;
  font-size: clamp(15px, 1.25vw, 24px);
  font-variant-numeric: tabular-nums;
  margin-left: 10px;
}

/* ---------- tabelas ---------- */
/* Larguras das colunas. Ficam aqui, e não em <col style="…">, porque a CSP da
   dashboard é style-src 'self': atributo style inline é descartado pelo
   navegador e a tabela cairia em colunas de largura igual. */
.t-radios col:nth-child(1) { width: 40%; }   /* rádio    */
.t-radios col:nth-child(2) { width: 20%; }   /* modelo   */
.t-radios col:nth-child(3) { width: 23%; }   /* situação */
.t-radios col:nth-child(4) { width: 17%; }   /* clientes */

/* No log, as três primeiras colunas têm conteúdo de tamanho conhecido (hora,
   nome do site, tipo do evento) e só precisam do que couber. Todo o resto vai
   para a mensagem, que é a única com texto corrido — antes ela cortava no meio
   de "…canal saturado, 82% de ocup…", justo onde está a informação. */
.t-log col:nth-child(1) { width: 9%; }       /* quando */
.t-log col:nth-child(2) { width: 14%; }      /* site   */
.t-log col:nth-child(3) { width: 11%; }      /* tipo   */
.t-log col:nth-child(4) { width: 66%; }      /* evento */

/* Linhas mais juntas que nas tabelas de rádio: aqui o valor está em ver muitos
   eventos de uma vez, e cada linha é uma frase curta, não um dado a comparar. */
.t-log thead th { padding-top: 7px; padding-bottom: 7px; }
.t-log tbody td {
  padding-top: clamp(3px, 0.32vw, 7px);
  padding-bottom: clamp(3px, 0.32vw, 7px);
  padding-left: clamp(10px, 0.85vw, 17px);
  padding-right: clamp(10px, 0.85vw, 17px);
}
.t-log thead th {
  padding-left: clamp(10px, 0.85vw, 17px);
  padding-right: clamp(10px, 0.85vw, 17px);
}

/* table-layout fixed + colgroup: garante que nome longo vire reticências
   em vez de estourar a largura — ninguém rola a tela de uma TV. */
table {
  width: 100%;
  table-layout: fixed;
  border-collapse: collapse;
  font-size: clamp(11px, 0.92vw, 17px);
}
thead th {
  position: sticky;
  top: 0;
  background: var(--surface-2);
  color: var(--muted);
  font-weight: 500;
  font-size: clamp(10px, 0.72vw, 13px);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  text-align: left;
  padding: 9px clamp(12px, 1.1vw, 22px);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
tbody td {
  padding: clamp(6px, 0.6vw, 12px) clamp(12px, 1.1vw, 22px);
  border-bottom: 1px solid var(--line);
  color: var(--ink-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
tbody td.name { color: var(--ink); font-weight: 500; }
th.num, tbody td.num { font-variant-numeric: tabular-nums; text-align: right; }
tbody tr:last-child td { border-bottom: none; }
tbody tr.alert td { background: rgba(208, 59, 59, 0.09); }
tbody tr.warn td  { background: rgba(250, 178, 25, 0.07); }

/* pílula de status: cor + rótulo, nunca cor sozinha */
.pill {
  display: inline-flex;
  align-items: center;
  font-weight: 600;
  color: var(--ink);
  font-size: 0.92em;
}
.pill::before {
  content: "";
  width: 9px; height: 9px;
  border-radius: 50%;
  background: var(--muted);
  margin-right: 7px;
  flex: none;
}
.pill.ok::before       { background: var(--good); }
.pill.down::before     { background: var(--critical); }
.pill.warn::before     { background: var(--warning); }
.pill.serious::before  { background: var(--serious); }
.pill.unknown::before  { background: var(--muted); }
.pill.down { color: var(--critical); }

/* ---------- tela de rede ---------- */
/* O log leva bem mais largura que a coluna de densidade: ele tem a mensagem
   por extenso, e a densidade é só barra e número, que cabem apertados. */
.rede-corpo {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: 1fr 1.85fr;
  gap: var(--gap);
}

/* horário do evento, em coluna estreita e alinhado por dígito */
td.quando { font-variant-numeric: tabular-nums; color: var(--muted); }
/* etiqueta de severidade do log */
.sev {
  display: inline-flex;
  align-items: center;
  font-weight: 600;
  font-size: 0.88em;
  white-space: nowrap;
}
.sev::before {
  content: "";
  width: 8px; height: 8px;
  border-radius: 50%;
  margin-right: 6px;
  flex: none;
  background: var(--muted);
}
.sev.critico::before { background: var(--critical); }
.sev.alerta::before  { background: var(--warning); }
.sev.ok::before      { background: var(--good); }
.sev.info::before    { background: var(--accent); }
.sev.critico { color: var(--critical); }
.sev.alerta  { color: var(--warning); }

.erro {
  flex: none;
  padding: clamp(10px, 1vw, 18px) clamp(14px, 1.3vw, 26px);
  border: 1px solid rgba(208, 59, 59, 0.4);
  border-radius: var(--radius);
  background: rgba(208, 59, 59, 0.09);
  color: #f07777;
  font-size: clamp(12px, 0.95vw, 16px);
}
.erro[hidden] { display: none; }

.empty {
  padding: clamp(20px, 3vw, 48px);
  text-align: center;
  color: var(--muted);
  font-size: clamp(13px, 1vw, 17px);
}
.empty.err { color: var(--serious); }

/* ---------- responsivo ---------- */
@media (max-width: 1100px) {
  .kpis { grid-template-columns: repeat(2, 1fr); }
  .rede-corpo { grid-template-columns: 1fr; }
  .lado { grid-auto-rows: auto; }
  /* sem largura para três painéis lado a lado, eles voltam a empilhar e a tela
     passa a rolar — melhor que espremer as legendas até não dizerem nada */
  .trio { grid-template-columns: 1fr; }
  .site-corpo { grid-template-rows: none; grid-auto-rows: minmax(min-content, auto); }
  .topbar { flex-wrap: wrap; }
  .stack-leg { grid-template-columns: 1fr; }
}
