/* Plano de design (tratamento Operacional)
   Conceito: quadro de plantão com três filas que rolam sozinhas sob um cabeçalho fixo;
   cada condomínio é uma ficha plana e cada ocorrência uma linha da ficha, marcada à
   esquerda pela faixa reta da cor do evento. A cor fica só na faixa; o resto é neutro.
   Cor (neutros puxados para o azul-ardósia do destaque; claro p/ mesa, escuro p/ TV):
     --fundo #e9edf2 / #0e141b     --superficie #fbfcfe / #18212b
     --superficie-2 #eff2f6 / #212c38   --borda #d3dae3 / #2e3c4b
     --texto #1a2430 / #e6edf5     --texto-2 #566476 / #97a6b7
     --destaque #2c5a8a / #84b3e1  --perigo #b42318 / #f28b82 (semântica, fora do destaque)
     Semânticas da coluna VPN (estado, não destaque): --ok #1d6b45 / #74cf9c,
       --atencao #7a5200 / #f0c36a, --critico = --perigo. Usadas como texto e, misturadas
       10–16% à superfície, como fundo da ficha. Níveis da queda: instável (superfície-2, texto
       secundário), vermelho (tinta 10%), vivo (--critico sólido com --sobre-critico #fff / #0e141b:
       no escuro o crítico é claro, então o texto é escuro para manter >= 4.5:1).
     --barra-mistura: a cor do evento é misturada 20–25% com o texto do tema para manter
       a faixa >= 3:1 contra a superfície nos dois temas (cores.js fica intocado).
   Tipo: IBM Plex Sans (texto, 400/500/600); IBM Plex Sans Condensed (nome do condomínio,
     economiza largura nas colunas); números com tabular-nums na família do texto.
     Escala 12 / 14 / 16 / 20 px.
   Forma: um raio de 5 px para fichas e diálogos, borda de 1 px, sem sombra; pílulas
     de contagem totalmente arredondadas. */
:root {
  --fundo: #e9edf2;
  --superficie: #fbfcfe;
  --superficie-2: #eff2f6;
  --borda: #d3dae3;
  --texto: #1a2430;
  --texto-2: #566476;
  --destaque: #2c5a8a;
  --perigo: #b42318;
  --ok: #1d6b45;
  --atencao: #7a5200;
  --critico: var(--perigo);
  --sobre-critico: #ffffff;
  --vivo: rgba(255, 0, 0, 0.9);
  --sobre-vivo: #ffffff;
  --aviso-fundo: #fbe7bf;
  --aviso-texto: #5e4300;
  --veu: rgb(14 20 27 / 0.5);
  --sombra-menu: rgb(14 20 27 / 0.14);
  --barra-mistura: var(--texto);
  --barra-peso: 80%;

  --fonte-texto: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  --fonte-nome: "IBM Plex Sans Condensed", "IBM Plex Sans", "Arial Narrow", system-ui, sans-serif;
  --t-0: 0.75rem;
  --t-1: 0.875rem;
  --t-2: 1rem;
  --t-3: 1.25rem;

  --raio: 5px;
  --gap: 12px;
  --faixa: 3px;
  color-scheme: light;
}

/* Tema escuro: TV sempre; operador quando o sistema pede. Desenhado à parte, não invertido:
   superfícies sobem em luminância por camada e o texto secundário fica mais frio. */
body.tv {
  --fundo: #0e141b;
  --superficie: #18212b;
  --superficie-2: #212c38;
  --borda: #2e3c4b;
  --texto: #e6edf5;
  --texto-2: #97a6b7;
  --destaque: #84b3e1;
  --perigo: #f28b82;
  --ok: #74cf9c;
  --atencao: #f0c36a;
  --critico: var(--perigo); /* redeclarada: var() resolve onde é declarada */
  --sobre-critico: #0e141b;
  --aviso-fundo: #4a3a10;
  --aviso-texto: #fbe7b0;
  --veu: rgb(5 8 12 / 0.65);
  --sombra-menu: rgb(5 8 12 / 0.5);
  --barra-peso: 75%;
  color-scheme: dark;
}
@media (prefers-color-scheme: dark) {
  body {
    --fundo: #0e141b;
    --superficie: #18212b;
    --superficie-2: #212c38;
    --borda: #2e3c4b;
    --texto: #e6edf5;
    --texto-2: #97a6b7;
    --destaque: #84b3e1;
    --perigo: #f28b82;
    --ok: #74cf9c;
    --atencao: #f0c36a;
    --critico: var(--perigo); /* redeclarada: var() resolve onde é declarada */
    --sobre-critico: #0e141b;
    --aviso-fundo: #4a3a10;
    --aviso-texto: #fbe7b0;
    --veu: rgb(5 8 12 / 0.65);
    --sombra-menu: rgb(5 8 12 / 0.5);
    --barra-peso: 75%;
    color-scheme: dark;
  }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--fundo);
  color: var(--texto);
  font-family: var(--fonte-texto);
  font-size: var(--t-1);
  line-height: 1.4;
}
body.tv { font-size: var(--t-2); }

button { font: inherit; color: inherit; }
:focus-visible { outline: 2px solid var(--destaque); outline-offset: 2px; }

/* Cabeçalho */
.topo {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--gap);
  padding: 10px 16px;
  background: var(--superficie);
  border-bottom: 1px solid var(--borda);
}
.topo h1 {
  margin: 0;
  font-size: var(--t-2);
  font-weight: 600;
}
body.tv .topo h1 { font-size: var(--t-3); }
.operador { display: flex; align-items: center; gap: 8px; min-width: 0; }
.operador[hidden] { display: none; }
.operador .nome { color: var(--texto-2); overflow-wrap: anywhere; }
.discreto {
  background: none;
  border: 1px solid transparent;
  border-radius: var(--raio);
  padding: 2px 8px;
  color: var(--texto-2);
  cursor: pointer;
}
.discreto:hover { border-color: var(--borda); color: var(--texto); }
body.tv .operador { display: none; }
.topo-acoes { display: flex; align-items: center; gap: 8px; min-width: 0; }
#tela-cheia[hidden] { display: none; }

/* Tela cheia (TV): sem cabeçalho e com margens mínimas; o painel ocupa a tela inteira. */
body.tela-cheia .topo { display: none; }
body.tela-cheia .colunas { padding: 8px 8px 0; gap: 8px; }

/* Faixa offline */
.offline {
  padding: 6px 16px;
  background: var(--aviso-fundo);
  color: var(--aviso-texto);
  font-size: var(--t-0);
  font-weight: 500;
}
.offline[hidden] { display: none; }

/* Faixa de acesso negado: mesmo formato da offline, no tom de atenção (perigo tingido),
   para não ser confundida com uma queda de conexão. */
.aviso-acesso {
  padding: 6px 16px;
  background: color-mix(in srgb, var(--perigo) 14%, var(--superficie));
  color: var(--perigo);
  font-size: var(--t-0);
  font-weight: 600;
}
.aviso-acesso[hidden] { display: none; }

/* Falha de ação: aviso curto no rodapé, não bloqueia cliques no painel. */
.aviso-acao {
  position: fixed;
  left: 50%;
  bottom: 16px;
  transform: translateX(-50%);
  max-width: calc(100vw - 32px);
  padding: 8px 14px;
  background: var(--superficie);
  color: var(--texto);
  border: 1px solid var(--perigo);
  border-left-width: 4px;
  border-radius: var(--raio);
  font-size: var(--t-1);
  pointer-events: none;
  z-index: 20;
}
.aviso-acao[hidden] { display: none; }

/* Colunas */
.colunas {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--gap);
  padding: var(--gap) 16px;
  align-items: start;
}
.coluna { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.coluna h2 {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  padding: 2px 2px 4px;
  font-size: var(--t-0);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--texto-2);
}
body.tv .coluna h2 { font-size: var(--t-1); }
.contador,
.total,
.timer {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  border-radius: 999px;
  background: var(--superficie-2);
  color: var(--texto);
  white-space: nowrap;
}
.contador { padding: 0 7px; letter-spacing: 0; background: var(--superficie); border: 1px solid var(--borda); }
.cartoes { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.vazio { margin: 0; padding: 4px 2px; color: var(--texto-2); }

/* Duas colunas ou mais: cada fila rola dentro da altura da tela, cabeçalho parado. */
@media (min-width: 900px) {
  body {
    height: 100vh;
    height: 100dvh;
    display: grid;
    grid-template-rows: auto auto minmax(0, 1fr);
    overflow: hidden;
  }
  .colunas {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    align-items: stretch;
    min-height: 0;
    padding-bottom: 0;
  }
  /* Painel com a coluna VPN à esquerda: mais estreita, só um resumo por VPN caída. */
  .colunas.com-vpn { grid-template-columns: minmax(12rem, 0.6fr) repeat(3, minmax(0, 1fr)); }
  .coluna { min-height: 0; }
  body.tela-cheia { grid-template-rows: auto minmax(0, 1fr); }
  .cartoes {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding-bottom: var(--gap);
    scrollbar-width: thin;
    scrollbar-color: var(--borda) transparent;
  }
}

/* Cartão: ficha plana, borda de 1 px, sem sombra. */
.cartao {
  position: relative;
  flex: none;
  display: flex;
  background: var(--superficie);
  border: 1px solid var(--borda);
  border-radius: var(--raio);
}
.cartao .corpo { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.cartao header {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: 10px;
  row-gap: 2px;
  padding: 8px 10px 7px;
}
.cartao h3 {
  flex: 1 1 12rem;
  min-width: 0;
  margin: 0;
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 2px 8px;
  font-weight: 400;
  line-height: 1.25;
}
/* O código identifica o condomínio na central: maior e na cor principal; o nome acompanha, menor. */
.cartao .codigo {
  font-size: var(--t-3);
  font-weight: 400;
  font-variant-numeric: tabular-nums;
  color: var(--texto);
}
body.tv .cartao .codigo { font-size: 1.5rem; }
.cartao .nome {
  min-width: 0;
  font-family: var(--fonte-nome);
  font-size: var(--t-1);
  color: var(--texto-2);
  overflow-wrap: anywhere;
  text-wrap: balance;
}
body.tv .cartao .nome { font-size: var(--t-2); }
.cartao .info {
  margin-left: auto;
  color: var(--texto-2);
  font-size: var(--t-0);
  font-variant-numeric: tabular-nums;
  text-align: right;
}
body.tv .cartao .info { font-size: var(--t-1); }
.timer {
  margin-left: auto;
  padding: 1px 8px;
  font-size: var(--t-0);
}
body.tv .timer { font-size: var(--t-1); }

/* Linha de ocorrência: linha plana da ficha, faixa reta de severidade à esquerda. */
.linha {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 10px 6px calc(10px + var(--faixa));
  border-top: 1px solid var(--borda);
  box-shadow: inset var(--faixa) 0 0 color-mix(in srgb, var(--cor) var(--barra-peso), var(--barra-mistura));
}
.cartao .corpo > .linha:last-child { border-bottom-left-radius: calc(var(--raio) - 1px); }
.linha .texto { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.linha b { font-weight: 500; overflow-wrap: anywhere; }
.linha small { color: var(--texto-2); font-size: var(--t-0); overflow-wrap: anywhere; }
body.tv .linha small { font-size: var(--t-1); }
.total {
  flex: none;
  min-width: 2.25em;
  padding: 1px 8px;
  text-align: center;
}

/* Trilho de ações: botões fantasma; só Fechar leva cor (perigo). */
.acoes {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 4px;
  border-left: 1px solid var(--borda);
}
.acao {
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  border: 1px solid transparent;
  border-radius: var(--raio);
  background: none;
  cursor: pointer;
  color: var(--texto-2);
  font-size: var(--t-2);
  line-height: 1;
}
.acao:hover { background: var(--superficie-2); color: var(--texto); }
.acao.perigo { color: var(--perigo); }
.acao.perigo:hover { background: color-mix(in srgb, var(--perigo) 12%, var(--superficie)); color: var(--perigo); }
.pausas {
  display: none;
  position: absolute;
  right: 44px;
  top: 4px;
  z-index: 2;
  margin: 0;
  padding: 4px;
  list-style: none;
  flex-direction: column;
  gap: 2px;
  background: var(--superficie);
  border: 1px solid var(--borda);
  border-radius: var(--raio);
  box-shadow: 0 4px 12px var(--sombra-menu);
}
.cartao.menu-aberto .pausas { display: flex; }
.pausas button {
  padding: 4px 12px;
  border: none;
  border-radius: var(--raio);
  background: none;
  font-variant-numeric: tabular-nums;
  text-align: left;
  white-space: nowrap;
  cursor: pointer;
}
.pausas button:hover { background: var(--superficie-2); }
body.tv .acoes { display: none; }

/* Novo alerta em cartão já assumido: contorno que acende e apaga, 4 x 1,25 s = 5 s.
   Só opacity anima; o contorno é um pseudo-elemento. */
.cartao::after {
  content: "";
  position: absolute;
  inset: -1px;
  border: 2px solid var(--destaque);
  border-radius: var(--raio);
  opacity: 0;
  pointer-events: none;
}
.cartao.destaque::after { animation: pulso 1.25s ease-in-out 4; }
@keyframes pulso {
  0%, 100% { opacity: 0; }
  50% { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .cartao.destaque::after { animation: none; opacity: 1; }
}

/* Diálogos */
dialog {
  border: 1px solid var(--borda);
  border-radius: var(--raio);
  background: var(--superficie);
  color: var(--texto);
  padding: 0;
  max-width: min(420px, calc(100vw - 32px));
}
dialog::backdrop { background: var(--veu); }
.dialogo { display: flex; flex-direction: column; gap: 10px; padding: 20px; }
.dialogo h2 { margin: 0; font-size: var(--t-3); text-wrap: balance; }
.dialogo p { margin: 0; color: var(--texto-2); max-width: 65ch; }
.dialogo label { font-size: var(--t-0); font-weight: 500; color: var(--texto-2); text-transform: uppercase; letter-spacing: 0.02em; }
.dialogo input,
.entrar input {
  font: inherit;
  padding: 6px 8px;
  border: 1px solid var(--borda);
  border-radius: var(--raio);
  background: var(--superficie-2);
  color: var(--texto);
}
.botoes { display: flex; justify-content: flex-end; gap: 8px; }
.primario,
.botao-primario {
  padding: 6px 14px;
  border: 1px solid var(--destaque);
  border-radius: var(--raio);
  background: var(--destaque);
  color: var(--superficie);
  font-weight: 600;
  cursor: pointer;
}

.erro { margin: 0; color: var(--perigo); font-size: var(--t-1); }
.erro[hidden] { display: none; }

/* Tela de login do operador (e-mail e senha da conta Shomer TI) */
.entrar {
  grid-column: 1 / -1;
  justify-self: start;
  align-self: start;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
  max-width: 28rem;
  margin-top: 10vh;
  padding: 20px;
  border: 1px solid var(--borda);
  border-radius: var(--raio);
  background: var(--superficie);
}
.entrar h2 { margin: 0; font-size: var(--t-3); }
.entrar p { margin: 0; color: var(--texto-2); max-width: 65ch; }
.entrar .erro { color: var(--perigo); }
.entrar label { margin-bottom: -6px; font-size: var(--t-0); font-weight: 500; color: var(--texto-2); text-transform: uppercase; letter-spacing: 0.02em; }
.entrar input { align-self: stretch; }
.botao-primario:disabled { opacity: 0.6; cursor: progress; }

/* Links do cabeçalho entre painel e estatísticas: mesmo peso dos botões discretos. */
a.discreto { text-decoration: none; }
a.discreto[hidden] { display: none; }
/* Na TV o link existe, mas não compete com o painel: menor e apagado. */
body.tv #link-estatisticas { font-size: var(--t-0); opacity: 0.6; }

/* Estatísticas (/estatisticas): tabela densa sob uma barra de filtros; rola só a tabela.
   Mesmos tokens do painel; a faixa do evento repete a da linha do cartão. */
body.estatisticas .colunas { display: block; }
.estatisticas-tela { display: flex; flex-direction: column; gap: 10px; min-height: 0; height: 100%; }
.estatisticas-barra {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 16px;
}
.estatisticas-barra .desde {
  margin: 0;
  color: var(--texto-2);
  font-size: var(--t-0);
  font-variant-numeric: tabular-nums;
}
.filtros { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; }
.filtros label {
  font-size: var(--t-0);
  font-weight: 500;
  color: var(--texto-2);
  text-transform: uppercase;
  letter-spacing: 0.02em;
}
.filtros select,
.filtros input {
  font: inherit;
  max-width: 100%;
  padding: 4px 8px;
  border: 1px solid var(--borda);
  border-radius: var(--raio);
  background: var(--superficie);
  color: var(--texto);
}
.filtros input { width: 16rem; }
.zerar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-left: auto; }
.zerar[hidden] { display: none; }
.zerar .pergunta { font-weight: 600; color: var(--perigo); }
.botao-perigo {
  padding: 4px 12px;
  border: 1px solid var(--perigo);
  border-radius: var(--raio);
  background: none;
  color: var(--perigo);
  font-weight: 600;
  cursor: pointer;
}
.botao-perigo:hover { background: color-mix(in srgb, var(--perigo) 12%, var(--superficie)); }
.botao-perigo:disabled { opacity: 0.6; cursor: progress; }

.estatisticas-tabela {
  min-height: 0;
  overflow: auto;
  border: 1px solid var(--borda);
  border-radius: var(--raio);
  background: var(--superficie);
}
.estatisticas-tabela > .vazio { padding: 10px; }
.tabela-estatisticas { width: 100%; border-collapse: collapse; }
.tabela-estatisticas th {
  position: sticky;
  top: 0;
  z-index: 1;
  padding: 6px 10px;
  background: var(--superficie-2);
  border-bottom: 1px solid var(--borda);
  font-size: var(--t-0);
  font-weight: 600;
  text-align: left;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--texto-2);
  white-space: nowrap;
}
.tabela-estatisticas td {
  padding: 5px 10px;
  border-top: 1px solid var(--borda);
  vertical-align: baseline;
}
.tabela-estatisticas tbody tr:first-child td { border-top: none; }
.tabela-estatisticas tbody tr:hover td { background: var(--superficie-2); }
.tabela-estatisticas .codigo {
  font-size: var(--t-2);
  font-variant-numeric: tabular-nums;
  color: var(--texto);
  white-space: nowrap;
}
.tabela-estatisticas .nome { font-family: var(--fonte-nome); color: var(--texto-2); overflow-wrap: anywhere; }
.tabela-estatisticas .evento {
  padding-left: calc(10px + var(--faixa) + 6px);
  box-shadow: inset var(--faixa) 0 0 color-mix(in srgb, var(--cor) var(--barra-peso), var(--barra-mistura));
}
.tabela-estatisticas .total-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  white-space: nowrap;
}
.tabela-estatisticas .ultima { font-variant-numeric: tabular-nums; color: var(--texto-2); white-space: nowrap; }

/* Estatísticas: VPN acima da tabela de eventos; em tela larga, ao lado (coluna estreita). */
.estatisticas-corpo { display: grid; gap: var(--gap); min-height: 0; flex: 1; grid-template-rows: auto minmax(0, 1fr); }
.estatisticas-vpn {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
  min-height: 0;
  overflow: auto;
}
.estatisticas-vpn h2,
.vpn-ranking h3 {
  margin: 0;
  font-size: var(--t-0);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--texto-2);
}
.vpn-rankings { display: grid; grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); gap: var(--gap); }
.vpn-ranking {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
  overflow-x: auto;
}
.vpn-ranking .tabela-estatisticas {
  border: 1px solid var(--borda);
  border-radius: var(--raio);
  background: var(--superficie);
  border-collapse: separate;
  border-spacing: 0;
}
.vpn-ranking .tabela-estatisticas th:first-child { border-top-left-radius: var(--raio); }
.vpn-ranking .tabela-estatisticas th:last-child { border-top-right-radius: var(--raio); }
.vpn-ranking .tabela-estatisticas .codigo { font-size: var(--t-1); font-weight: 600; }
@media (min-width: 1200px) {
  .estatisticas-corpo { grid-template-columns: minmax(0, 1fr) minmax(20rem, 26rem); grid-template-rows: minmax(0, 1fr); }
  .estatisticas-vpn { order: 2; }
  .vpn-rankings { grid-template-columns: 1fr; }
}

@media (min-width: 900px) {
  body.estatisticas .colunas { padding-bottom: var(--gap); }
}
@media (max-width: 640px) {
  .filtros input { width: 100%; }
  .zerar { margin-left: 0; }
}

/* Coluna VPN: estado das VPNs dos condomínios (painelVpn). Fichas planas como as do quadro;
   a cor semântica vai no fundo tingido e no texto de estado, nunca numa faixa lateral.
   O quadro some do fluxo (display: contents) para as três colunas serem itens do mesmo grid. */
.quadro { display: contents; }
.vpn {
  flex: none;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  padding: 8px 10px;
  background: var(--superficie);
  border: 1px solid var(--borda);
  border-radius: var(--raio);
}
.vpn-neutra { color: var(--texto-2); }
.vpn-neutra b { font-weight: 500; }
.vpn-ok {
  background: color-mix(in srgb, var(--ok) 10%, var(--superficie));
  border-color: color-mix(in srgb, var(--ok) 40%, var(--borda));
}
.vpn-titulo {
  font-size: var(--t-0);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--ok);
}
.vpn-numero {
  font-size: 2rem;
  font-weight: 500;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
  color: var(--texto);
}
.vpn-atualizado { font-size: var(--t-0); color: var(--texto-2); font-variant-numeric: tabular-nums; }
.vpn-resumo {
  margin: 0;
  padding: 0 2px 2px;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 2px 8px;
  font-size: var(--t-0);
  font-variant-numeric: tabular-nums;
}
.vpn-resumo b { font-weight: 600; color: var(--texto); }
.vpn-caida {
  background: color-mix(in srgb, var(--critico) 10%, var(--superficie));
  border-color: color-mix(in srgb, var(--critico) 45%, var(--borda));
}
.vpn-caida h3 {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px 8px;
  font-weight: 400;
  line-height: 1.25;
}
/* Mesmo tratamento do código no cartão de alerta: maior, na cor do texto; o nome acompanha. */
.vpn .codigo {
  min-width: 0;
  font-size: var(--t-3);
  font-variant-numeric: tabular-nums;
  color: var(--texto);
  overflow-wrap: anywhere;
}
.vpn .nome {
  min-width: 0;
  font-family: var(--fonte-nome);
  font-size: var(--t-1);
  color: var(--texto-2);
  overflow-wrap: anywhere;
}
.vpn-tempo { font-size: var(--t-0); font-weight: 600; color: var(--critico); font-variant-numeric: tabular-nums; }
.vpn-atraso {
  background: color-mix(in srgb, var(--atencao) 16%, var(--superficie));
  border-color: color-mix(in srgb, var(--atencao) 50%, var(--borda));
  color: var(--atencao);
}
.vpn-atraso b { font-weight: 600; text-wrap: balance; }
.vpn-atraso-tempo { font-variant-numeric: tabular-nums; }

/* Níveis da queda: a maioria dura segundos, então a ficha começa discreta e ganha força. */
.vpn-instavel {
  padding: 5px 10px;
  background: var(--superficie-2);
  border-color: var(--borda);
}
.vpn-instavel .codigo { font-size: var(--t-2); }
.vpn-instavel .nome { font-size: var(--t-0); }
.vpn-instavel .vpn-tempo { font-weight: 500; color: var(--texto-2); }
/* Vermelho vivo pedido pelo Huandel (rgba(255, 0, 0, 0.9)), igual nos dois temas, texto branco. */
.vpn-vivo {
  background: var(--vivo);
  border-color: var(--vivo);
  color: var(--sobre-vivo);
  animation: vpn-vivo 2s ease-in-out infinite;
}
.vpn-vivo .codigo,
.vpn-vivo .nome,
.vpn-vivo .vpn-tempo,
.vpn-vivo .vpn-selo { color: inherit; }
.vpn-vivo .codigo { font-weight: 600; }
@keyframes vpn-vivo {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--vivo) 55%, transparent); }
  50% { box-shadow: 0 0 0 5px color-mix(in srgb, var(--vivo) 0%, transparent); }
}
@media (prefers-reduced-motion: reduce) {
  .vpn-vivo { animation: none; outline: 2px solid var(--vivo); outline-offset: 2px; }
}

/* Selo de instabilidade (>= 3 quedas em 15 min): na ficha caída e nas linhas das online. */
.vpn-selo { font-size: var(--t-0); font-weight: 600; color: var(--atencao); font-variant-numeric: tabular-nums; }
.vpn-instaveis {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.vpn-instaveis li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 8px;
  min-width: 0;
  padding: 4px 10px;
  background: color-mix(in srgb, var(--atencao) 10%, var(--superficie));
  border: 1px solid color-mix(in srgb, var(--atencao) 40%, var(--borda));
  border-radius: var(--raio);
}
.vpn-instaveis .codigo { font-size: var(--t-1); font-weight: 600; font-variant-numeric: tabular-nums; color: var(--texto); }
.vpn-instaveis .nome { min-width: 0; font-family: var(--fonte-nome); font-size: var(--t-0); color: var(--texto-2); overflow-wrap: anywhere; }
.vpn-instaveis .vpn-selo { flex-basis: 100%; }

body.tv .vpn .codigo { font-size: 1.5rem; }
body.tv .vpn-instavel .codigo { font-size: var(--t-3); }
body.tv .vpn-instaveis .codigo { font-size: var(--t-2); }
body.tv .vpn-instaveis .nome,
body.tv .vpn-selo { font-size: var(--t-1); }
body.tv .vpn .nome { font-size: var(--t-2); }
body.tv .vpn-numero { font-size: 2.75rem; }
body.tv .vpn-titulo,
body.tv .vpn-atualizado,
body.tv .vpn-resumo,
body.tv .vpn-tempo { font-size: var(--t-1); }
body.tv .vpn-atraso { font-size: var(--t-2); }
