/* =====================================================================
   OLT Observer — base e componentes
   Depende de tokens.css. Mobile-first: o estado sem media query e o do
   celular; breakpoints ampliam. Tecnico em campo abre isso no telefone.
   ===================================================================== */

/* ---------- fontes das marcas ---------- */
@font-face {
  font-family: "Rubik";
  src: url("/estatico/fontes/Rubik-VariableFont_wght.ttf") format("truetype-variations");
  font-weight: 300 900;
  font-display: swap;
}
@font-face {
  font-family: "WIXX Display";
  src: url("/estatico/fontes/WIXX-Display.ttf") format("truetype");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "WIXX Text";
  src: url("/estatico/fontes/WIXX-Text.ttf") format("truetype");
  font-weight: 400;
  font-display: swap;
}

/* ---------- reset enxuto ---------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html { -webkit-text-size-adjust: 100%; }

body {
  min-height: 100dvh;              /* dvh: barra do navegador movel nao corta */
  background: var(--sup-base);
  color: var(--tinta);
  font-family: var(--fonte-corpo);
  font-size: var(--t-md);
  line-height: var(--linha-normal);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
  font-family: var(--fonte-titulo);
  font-weight: var(--peso-medio);
  line-height: var(--linha-apertada);
  text-wrap: balance;              /* evita orfa de uma palavra no titulo */
}
h1 { font-size: var(--t-2xl); }
h2 { font-size: var(--t-xl); }
h3 { font-size: var(--t-lg); }

p { max-width: var(--medida); }

a { color: var(--marca-primaria); text-decoration-thickness: 1px; text-underline-offset: 2px; }

/* Sublinhado e para link DENTRO DE TEXTO CORRIDO, onde ele e a unica
   pista de que aquela palavra e clicavel. Fora dali ele so suja: um
   BOTAO ja parece clicavel pela caixa (e sublinhado dentro de botao e
   estilo de link vazando pra onde nao devia), e um TITULO de secao ja
   e obviamente o alvo — sublinhar um nome de OLT inteiro cria uma
   regua azul atravessando a linha. Nos dois casos o sublinhado volta
   no hover, que e quando a pergunta "isto clica?" e feita de verdade. */
.btn, .nav a, .gaveta__titulo a, .frota__olt a, .volta a { text-decoration: none; }
.gaveta__titulo a:hover, .frota__olt a:hover, .volta a:hover { text-decoration: underline; }

img, svg { display: block; max-width: 100%; }

/* Numero optico, ID de ONU, potencia: fonte tabular. Sem isso as
   colunas "dancam" a cada atualizacao e a leitura em varredura falha. */
.mono, td.num, .dbm {
  font-family: var(--fonte-mono);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}

/* ---------- foco visivel: requisito WCAG 2.4.7, nunca remover ---------- */
:focus-visible {
  outline: 2px solid var(--marca-primaria);
  outline-offset: 2px;
  border-radius: var(--raio-sm);
}
:focus:not(:focus-visible) { outline: none; }

/* No tema claro --marca-primaria (azul claro Telgo, taupe Wixx) fica abaixo
   de 3:1 sobre os fundos claros (WCAG 2.4.11) — mesmo a variante -forte nao
   resolve para o azul da Telgo. --marca-tinta e uma cor oficial da marca
   (nao generica) que cravou >10:1 nos dois brands sem mudar nada no escuro,
   onde --marca-primaria ja passa com folga. */
[data-theme="light"] :focus-visible { outline-color: var(--marca-tinta); }

/* Pular para o conteudo — primeiro tab da pagina, para quem usa teclado */
.pular {
  position: absolute; left: -9999px;
  background: var(--sup-1); color: var(--tinta);
  padding: var(--e-3) var(--e-4); border-radius: var(--raio-md);
  z-index: var(--z-aviso);
}
.pular:focus { left: var(--e-4); top: var(--e-4); }

.so-leitor-de-tela {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* =====================================================================
   ESTRUTURA — cabecalho + navegacao
   Mobile: barra inferior (alcance do polegar).
   Desktop: barra lateral (mais itens visiveis, sem esconder conteudo).
   ===================================================================== */
.app {
  display: grid;
  grid-template-areas: "cabecalho" "conteudo";
  grid-template-rows: auto 1fr;
  min-height: 100dvh;
}

.cabecalho {
  grid-area: cabecalho;
  position: sticky; top: 0; z-index: var(--z-cabecalho);
  display: flex; align-items: center; gap: var(--e-4);
  padding: var(--e-3) var(--e-4);
  background: var(--sup-1);
  border-bottom: var(--borda) solid var(--linha);
}
.cabecalho .marca-logo { height: 28px; width: auto; }

/* Escuro e o padrao, entao a NEGATIVA e a que aparece por omissao; a
   positiva so entra quando o tema claro e escolhido explicitamente.
   Duas <img> em vez de trocar o src por JS: a marca certa ja chega
   pintada no primeiro quadro, sem piscar a versao errada.

   Isto vale para entrar.html/convite.html, que ainda tem fundo CLARO
   nas duas telas — so o .cabecalho do app fica escuro nas duas agora
   (ver abaixo), entao ele precisa da negativa sempre, nas duas telas,
   por fora desta troca geral por tema. */
.marca-logo--positivo { display: none; }
[data-theme="light"] .marca-logo--negativo { display: none; }
[data-theme="light"] .marca-logo--positivo { display: inline-block; }
header.cabecalho .marca-logo--negativo { display: inline-block; }
header.cabecalho .marca-logo--positivo { display: none; }
.cabecalho .empresa {
  font-family: var(--fonte-titulo);
  font-size: var(--t-md);
  color: var(--tinta-2);
}

/* Cabecalho ganha o mesmo azul escuro institucional da nav no tema
   claro (pedido do Jaime, 2026-08-06: "o topo... o azul mais solido,
   como no menu lateral"), com uma faixa amarela no lugar do fio cinza
   — o mesmo detalhe que ja marca "onde voce esta" no item ativo do
   menu, so que como assinatura do topo. So no claro: o escuro ja usa
   --sup-1 (quase preto) e nao foi objeto da reclamacao original. */
[data-theme="light"] .cabecalho {
  background: var(--marca-tinta);
  border-bottom: 3px solid var(--marca-acento);
}
[data-theme="light"] .cabecalho .empresa,
[data-theme="light"] .cabecalho .quem__nome {
  color: var(--marca-tinta-texto-fraco);
}
/* Os botoes do cabecalho perdem a CAIXA. Sair e alternar tema sao
   acoes de canto — usadas raramente, e nunca a razao de alguem abrir a
   tela. Com borda em volta cada um virava um retangulo desenhado
   competindo com o conteudo, e eram dois lado a lado. Viram acao
   fantasma: so o rotulo, e a caixa aparece no hover, quando a pessoa
   ja demonstrou intencao. Vale nos DOIS temas — a caixa incomodava
   igual no escuro. */
.cabecalho .btn--contorno {
  border-color: transparent;
  background: transparent;
  padding: 0 var(--e-3);
}
.cabecalho .btn--contorno:hover { background: var(--sup-3); }
[data-theme="light"] .cabecalho .btn--contorno { color: var(--marca-tinta-texto); }
[data-theme="light"] .cabecalho .btn--contorno:hover { background: rgb(255 255 255 / 0.12); }

.conteudo {
  grid-area: conteudo;
  /* Item de grid nasce com `min-width: auto` e por isso pode ESTOURAR a
     propria trilha: um <select> com o nome de uma OLT longa levava a
     coluna a 500px num celular de 375, e a pagina inteira rolava de
     lado. Aqui e o ponto unico que protege todas as telas — cada uma
     tem seu jeito de ter conteudo largo, e nenhuma deveria precisar
     lembrar disto. Medido em /clientes, 21/09/2026. */
  min-width: 0;
  padding: var(--e-4);
  /* Espaco da barra inferior. Soma o safe-area do iPhone: a barra
     cresce esse tanto (padding dela, abaixo), e sem somar aqui o fim
     de toda tabela ficava escondido atras dela no celular — achado do
     Jaime, 11/09/2026 ("a barra esta em cima da pagina"). */
  padding-bottom: calc(var(--alvo-toque) + var(--e-6) + env(safe-area-inset-bottom));
}

/* Navegacao mobile: barra inferior fixa */
.nav {
  position: fixed; bottom: 0; left: 0; right: 0;
  z-index: var(--z-menu);
  display: flex;
  background: var(--sup-1);
  border-top: var(--borda) solid var(--linha);
  padding-bottom: env(safe-area-inset-bottom);   /* notch / barra do iPhone */
  /* A barra rola de lado. Achado do Jaime, 11/09/2026, no celular: com
     11 itens (Administrador) so os 6 primeiros cabiam e o resto
     simplesmente nao existia — sem rolagem, sem sinal de que havia
     mais. O `min-width` abaixo e calibrado pra que o ultimo item
     visivel fique CORTADO na borda: e o proprio convite pra arrastar,
     sem precisar de seta nem gradiente. `base.html` centraliza o item
     ativo ao carregar, pra quem esta em Configuracoes nao abrir a tela
     com a barra parada no Dashboard. */
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.nav::-webkit-scrollbar { display: none; }
.nav a {
  flex: 1 0 auto;
  min-width: 72px;
  min-height: var(--alvo-toque);
  display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 2px;
  padding: var(--e-2);
  color: var(--tinta-2);
  font-size: var(--t-xs);
  text-decoration: none;
}
.nav a[aria-current="page"] { color: var(--marca-primaria); }
.nav a[aria-current="page"] .ic { color: var(--marca-primaria); }
/* So aparece no trilho do desktop (ver abaixo) — na barra do mobile o
   item de grupo fica solto, sem rotulo de secao nenhum. */
.nav__grupo-rotulo { display: none; }

@media (min-width: 60rem) {   /* 960px — breakpoint por conteudo: cabe a lateral + tabela densa */
  .app {
    grid-template-areas: "cabecalho cabecalho" "nav conteudo";
    grid-template-columns: 232px 1fr;
    grid-template-rows: auto 1fr;
  }
  .nav {
    grid-area: nav;
    position: sticky; top: 57px; align-self: start;
    height: calc(100dvh - 57px);
    flex-direction: column;
    border-top: 0; border-right: var(--borda) solid var(--linha);
    padding: var(--e-3);
    gap: var(--e-1);
    overflow: hidden auto;   /* no trilho, rola pra baixo, nunca de lado */
  }
  .nav a {
    flex: 0 0 auto;
    min-width: 0;
    flex-direction: row; justify-content: flex-start; gap: var(--e-3);
    min-height: var(--alvo-min);
    padding: var(--e-2) var(--e-3);
    border-radius: var(--raio-md);
    font-size: var(--t-md);
  }
  .nav a:hover { background: var(--sup-3); color: var(--tinta); }
  .nav a[aria-current="page"] { background: var(--marca-primaria-fraca); color: var(--marca-primaria-forte); }
  .conteudo { padding: var(--e-5); padding-bottom: var(--e-6); }

  /* Agrupamento e SO uma nicidade do trilho largo — rotulo de secao
     acima dos filhos, que ficam levemente indentados pra mostrar que
     pertencem ali. Nao muda nenhum outro comportamento do link. */
  .nav__grupo-rotulo {
    display: block;
    margin-top: var(--e-2);
    padding: var(--e-2) var(--e-3) 0;
    font-size: var(--t-xs); font-weight: var(--peso-forte);
    text-transform: uppercase; letter-spacing: .06em;
    color: var(--tinta-3);
  }
  .nav__filho { padding-left: calc(var(--e-3) + var(--e-4)); }
}
[data-theme="light"] .nav__grupo-rotulo { color: var(--marca-tinta-texto-fraco); }

[data-theme="dark"] .nav a[aria-current="page"] {
  background: var(--sup-3);
  color: var(--marca-primaria);
}

/* A nav carrega o azul escuro institucional no tema claro — antes disso
   --marca-tinta so aparecia no anel de foco, a marca ficava quase
   ausente do dia a dia claro (pedido do Jaime, 2026-08-06: "usar mais a
   cor escura da identidade"). Vira uma ilha escura dentro do claro, e
   por isso reusa o MESMO tratamento que a nav ja tem no tema escuro
   (pilula sutil translucida no ativo, nao o azul palido que so faz
   sentido sobre fundo claro). */
[data-theme="light"] .nav {
  background: var(--marca-tinta);
  border-color: var(--marca-tinta);
}
[data-theme="light"] .nav a,
[data-theme="light"] .nav a .ic {
  color: var(--marca-tinta-texto-fraco);
}
[data-theme="light"] .nav a[aria-current="page"] {
  color: var(--marca-tinta-texto);
  background: rgb(255 255 255 / 0.08);
}
[data-theme="light"] .nav a[aria-current="page"] .ic { color: var(--marca-primaria); }
[data-theme="light"] .nav a:hover { background: rgb(255 255 255 / 0.06); color: var(--marca-tinta-texto); }

/* =====================================================================
   CARTAO e KPI
   ===================================================================== */
.cartao {
  background: var(--sup-1);
  border: var(--borda) solid var(--linha);
  border-radius: var(--raio-lg);
  padding: var(--e-4);
}
.cartao > h2, .cartao > h3 { margin-bottom: var(--e-3); }

.kpis {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--e-3);
}
.kpi { display: flex; flex-direction: column; gap: var(--e-1); }
.kpi .valor {
  font-family: var(--fonte-titulo);
  font-size: var(--t-3xl);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.kpi .rotulo {
  font-size: var(--t-xs);
  color: var(--tinta-2);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* =====================================================================
   ETIQUETA DE ESTADO — cor + icone + texto, os tres sempre juntos
   Cor sozinha nunca comunica: daltonismo, monitor ruim, sala clara.
   ===================================================================== */
.estado {
  display: inline-flex; align-items: center; gap: var(--e-2);
  padding: 2px var(--e-2);
  border-radius: var(--raio-cheio);
  font-size: var(--t-xs);
  font-weight: var(--peso-medio);
  white-space: nowrap;
  border: var(--borda) solid transparent;
}
.estado::before {
  content: "";
  width: 8px; height: 8px;
  border-radius: var(--raio-cheio);
  background: currentColor;
  flex: none;
}
.estado--critico  { color: var(--estado-critico-forte);  background: var(--estado-critico-fraco); }
.estado--alerta   { color: var(--estado-alerta-forte);   background: var(--estado-alerta-fraco); }
.estado--ok       { color: var(--estado-ok-forte);       background: var(--estado-ok-fraco); }
.estado--energia  { color: var(--estado-energia-forte);  background: var(--estado-energia-fraco); }
.estado--massa    { color: var(--estado-massa-forte);    background: var(--estado-massa-fraco); }
.estado--neutro   { color: var(--tinta-2);               background: var(--estado-neutro-fraco); }

[data-theme="dark"] .estado--critico { color: var(--estado-critico); }
[data-theme="dark"] .estado--alerta  { color: var(--estado-alerta); }
[data-theme="dark"] .estado--ok      { color: var(--estado-ok); }
[data-theme="dark"] .estado--energia { color: var(--estado-energia); }
[data-theme="dark"] .estado--massa   { color: var(--estado-massa); }

/* Forma do ponto muda junto com a cor: redundancia para daltonicos */
.estado--critico::before { border-radius: 2px; }                    /* quadrado */
.estado--alerta::before  { border-radius: 2px; transform: rotate(45deg); }  /* losango */
.estado--ok::before      { border-radius: var(--raio-cheio); }      /* circulo */

/* =====================================================================
   SEMAFORO DE SINAL OPTICO
   ===================================================================== */
.sinal { display: inline-flex; align-items: baseline; gap: var(--e-2); }
.sinal .dbm { font-size: var(--t-sm); font-weight: var(--peso-medio); }
/* Token de TEXTO, nao de preenchimento -- e aqui a especificidade e
   0,2,0, entao estas tres venceriam a correcao feita em
   `componentes.css` para qualquer `.dbm` dentro de um sinal. Ver o
   bloco de `.sinal--*` em componentes.css para os numeros medidos. */
.sinal--bom .dbm      { color: var(--estado-ok-texto); }
.sinal--atencao .dbm  { color: var(--estado-alerta-texto); }
.sinal--ruim .dbm     { color: var(--estado-critico-texto); }
.sinal--sem-dado .dbm { color: var(--tinta-3); }
.sinal .barra {
  width: 48px; height: 4px; border-radius: var(--raio-cheio);
  background: var(--estado-neutro-fraco); overflow: hidden;
}
.sinal .barra > i { display: block; height: 100%; border-radius: inherit; }
.sinal--bom .barra > i     { background: var(--estado-ok); }
.sinal--atencao .barra > i { background: var(--estado-alerta); }
.sinal--ruim .barra > i    { background: var(--estado-critico); }

/* =====================================================================
   TABELA OPERACIONAL — densa, varrivel, com cabecalho fixo
   ===================================================================== */
.tabela-rolagem { overflow-x: auto; }        /* nunca rolar a pagina toda no eixo X */
table.dados {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--t-sm);
}
table.dados th {
  position: sticky; top: 0; z-index: 1;
  background: var(--sup-2);
  text-align: left;
  font-weight: var(--peso-forte);
  font-size: var(--t-xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--tinta-2);
  padding: var(--e-2) var(--e-3);
  border-bottom: var(--borda) solid var(--linha);
  white-space: nowrap;
}
table.dados td {
  padding: var(--e-2) var(--e-3);
  height: var(--altura-linha-tabela);
  border-bottom: var(--borda) solid var(--sup-2);
  vertical-align: middle;
}
/* Ultima linha nao carrega borda propria — quem fecha e a borda do
   cartao que envolve a tabela, uma linha a mais seria redundante. */
table.dados tbody tr:last-child td { border-bottom: none; }
table.dados tbody tr:hover { background: var(--sup-2); }
/* CENTRALIZADO, cabecalho E dado (Jaime, 07/10/2026, olhando a tabela
   de sinal de uma porta de 40 ONUs).

   Era `th` a esquerda e `td` a direita. Numa coluna larga — e a de
   sinal fica larga, porque o cabecalho "VARIACAO" e maior que "-0,1" —
   isso joga o numero para um canto e o rotulo para o outro: a dupla
   deixa de ler como uma coluna so.

   `tabular-nums` CONTINUA, e nao e detalhe: ele e que mantem todo
   digito com a mesma largura, entao numeros de mesmo formato (que e o
   caso de dBm e de contagem aqui) continuam alinhando a virgula mesmo
   centralizados. Sem ele a coluna dancaria a cada atualizacao.

   Vale para as 19 telas que usam `.num` — alinhamento de numero e
   convencao do produto inteiro, e uma tabela centralizada no meio de
   dezoito a direita seria pior que qualquer das duas escolhas. */
table.dados td.num,
table.dados th.num { text-align: center; font-variant-numeric: tabular-nums; }
table.dados td:first-child { font-weight: 500; }

/* =====================================================================
   BOTOES
   ===================================================================== */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--e-2);
  min-height: var(--alvo-min);
  padding: 0 var(--e-4);
  border: var(--borda) solid transparent;
  border-radius: var(--raio-md);
  background: var(--sup-2);
  color: var(--tinta);
  font: inherit;
  font-weight: var(--peso-medio);
  cursor: pointer;
  transition: background var(--transicao), border-color var(--transicao);
}
.btn:hover { background: var(--sup-3); }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }

/* --marca-tinta, nao --tinta-invertida: --tinta-invertida troca com o
   TEMA (viraria quase-preto sobre azul claro no escuro, quase-branco no
   claro) — o fundo aqui e sempre --marca-primaria, que nao muda de tema,
   entao o texto tambem nao pode. Auditoria de marca 2026-08-06: antes
   disto, Telgo usava #16181D (preto inventado, nao o #333D47 do manual)
   e a Wixx usava branco sobre o proprio cinza — 2.92:1, reprovando WCAG
   AA (4.5:1). --marca-tinta ja e a cor certa por marca: 5.65:1 na Telgo,
   7.20:1 na Wixx. */
.btn--primario {
  background: var(--marca-primaria);
  color: var(--marca-tinta);
}
.btn--primario:hover { background: var(--marca-primaria-forte); }

.btn--contorno { background: transparent; border-color: var(--linha-forte); }
.btn--contorno:hover { background: var(--sup-2); }

/* Acao destrutiva (desprovisionar, remover): sempre distinta, nunca
   primaria, e nunca ao lado da acao segura sem separacao visual. */
.btn--perigo { background: var(--estado-critico); color: #fff; }
.btn--perigo:hover { background: var(--estado-critico-forte); }

@media (max-width: 40rem) { .btn { min-height: var(--alvo-toque); width: 100%; } }

/* =====================================================================
   FORMULARIO
   ===================================================================== */
/* `min-width: 0` nao e detalhe: um item flex nasce com `min-width:
   auto`, que o proíbe de encolher abaixo do conteudo. Com um <select>
   de OLT dentro ("ANS - Rack Vila Formosa - Datacom DM4615 - OLT", 46
   caracteres), o campo travava em 419px e empurrava a PAGINA para
   501px de rolagem lateral num celular de 375 — medido em /clientes,
   21/09/2026. O `max-width: 100%` do controle sozinho nao resolve:
   100% de um pai que nao encolheu continua sendo 419. */
.campo { display: flex; flex-direction: column; gap: var(--e-1); margin-bottom: var(--e-4);
  min-width: 0; }
.campo label { font-size: var(--t-sm); font-weight: var(--peso-medio); color: var(--tinta-2); }
/* O `.forma-encerrar` JUNTO, e nao so `.campo`.
   ACHADO NO RENDER, 06/10/2026: o formulario de encerrar desvio (que
   subiu hoje de manha) e o de classificar incidente nao usam `.campo`
   — sao linhas de acao, nao campos rotulados —, e sem esta linha os
   `input`/`select` deles caiam no padrao do navegador: CAIXA BRANCA
   sobre o tema escuro. Nao e so feio; e o unico retangulo branco da
   tela, entao o olho vai nele antes de ir no que importa.
   O estilo de campo e do CONTROLE, nao do involucro que por acaso
   esta em volta — por isso a correcao e aqui, e nao uma copia da
   regra dentro de cada formulario novo. */
.campo input, .campo select, .campo textarea,
.forma-encerrar input, .forma-encerrar select {
  min-height: var(--alvo-min);
  /* Um <select> se estica para caber a MAIOR opcao, e nome de OLT e
     longo: "ANS - Rack Vila Formosa - Datacom DM4615 - OLT" tem 46
     caracteres e levava o campo a 419px. Num celular de 375 isso
     empurra a PAGINA INTEIRA para 501px de rolagem lateral — medido em
     /clientes, 21/09/2026. `min-width: 0` e o par obrigatorio: sem ele
     o item flex/grid ignora o max-width e usa o tamanho do conteudo. */
  max-width: 100%;
  min-width: 0;
  padding: var(--e-2) var(--e-3);
  background: var(--sup-base);
  color: var(--tinta);
  border: var(--borda) solid var(--linha-forte);
  border-radius: var(--raio-md);
  font: inherit;
  /* 14px no desktop: a ferramenta e densa e o campo nao e o conteudo.
     No celular sobe para 16px — abaixo disso o iOS DA ZOOM ao focar, e
     a tela salta. A regra do iOS vale onde ha iOS, nao em todo lugar. */
  font-size: var(--t-md);
}
.campo .dica { font-size: var(--t-xs); color: var(--tinta-3); }
.campo .erro { font-size: var(--t-xs); color: var(--estado-critico); }
.campo input[aria-invalid="true"] { border-color: var(--estado-critico); }

/* =====================================================================
   ESTADOS DE PAGINA — vazio, carregando, erro.
   Nao sao detalhe: numa ferramenta operacional, "nada aqui" e uma
   resposta legitima e precisa ser tao clara quanto o dado.
   ===================================================================== */
/* .vazio mora em componentes.css — uma definicao so. */

.esqueleto {
  background: linear-gradient(90deg, var(--sup-2) 25%, var(--sup-3) 50%, var(--sup-2) 75%);
  background-size: 200% 100%;
  animation: brilho 1.4s infinite;
  border-radius: var(--raio-sm);
  height: 1em;
}
@keyframes brilho { to { background-position: -200% 0; } }
@media (prefers-reduced-motion: reduce) { .esqueleto { animation: none; } }

/* HTMX: indicador de carregamento sem piscar a tela inteira */
.htmx-indicator { opacity: 0; transition: opacity var(--transicao); }
.htmx-request .htmx-indicator { opacity: 1; }

/* ---------------------------------------------- painel operacional */
.numeros { display: flex; gap: var(--e-6); flex-wrap: wrap; margin-bottom: var(--e-3); }
.numeros .numero { font-size: 2.2rem; font-weight: 600; line-height: 1.1; }
.numeros .rotulo { font-size: var(--t-xs); letter-spacing: .08em;
  text-transform: uppercase; color: var(--tinta-2); }

.cartao.destaque { border-left: 3px solid var(--estado-critico); }

.aviso-topo { border-left: 3px solid var(--estado-alerta);
  background: var(--estado-alerta-fraco); padding: var(--e-3);
  border-radius: 0 var(--raio-md) var(--raio-md) 0; margin-bottom: var(--e-4);
  font-size: var(--t-sm); }

/* A cor carrega a decisao: quem le a tela de longe ja separa o que
   custa caminhao do que nao custa. */
.acao-despachar { color: var(--estado-critico); }
.acao-poupar    { color: var(--estado-ok); }

/* SEGUNDA declaracao de `.sinal--*` neste mesmo arquivo (a primeira
   esta no semaforo, ~200 linhas acima). Hoje quem vence e a de
   `componentes.css`, carregado depois -- mas duas definicoes da mesma
   classe sao uma armadilha esperando a ordem dos arquivos mudar, e esta
   sessao ja perdeu tempo tres vezes com seletor de uma classe so
   sobrescrevendo a cor do sinal. Entao as duas usam o token de TEXTO, e
   qualquer que vença diz a mesma coisa. */
.sinal { font-variant-numeric: tabular-nums; font-weight: 600; }
.sinal--bom     { color: var(--estado-ok-texto); }
.sinal--atencao { color: var(--estado-alerta-texto); }
.sinal--ruim    { color: var(--estado-critico-texto); }
.sinal--sem_dado{ color: var(--tinta-2); }
/* Cor sozinha nunca comunica (daltonismo) — o numero em si ja e dado
   real, mas a leitura "isto e grave" nao pode depender so da cor dele.
   Mesma forma do .pino/.estado: bom fica circulo, atencao losango,
   ruim quadrado. */
.sinal--bom::before, .sinal--atencao::before, .sinal--ruim::before {
  content: ""; display: inline-block; width: 7px; height: 7px;
  margin-right: var(--e-1); background: currentColor; border-radius: 50%;
  vertical-align: middle;
}
.sinal--atencao::before { border-radius: 2px; transform: rotate(45deg); }
.sinal--ruim::before    { border-radius: 2px; }
.alerta { color: var(--estado-alerta); font-size: var(--t-xs); }

/* ------------------------------------------------------- visao de rede */
.bolinha { display: inline-block; width: 9px; height: 9px; border-radius: 50%; }
.bolinha--bom         { background: var(--estado-ok); }
.bolinha--atencao     { background: var(--estado-alerta); }
.bolinha--ruim        { background: var(--estado-critico); }
.bolinha--vazia       { background: var(--tinta-3, var(--tinta-2)); }
/* Sem contato NAO usa o cinza de "vazia": e um estado de alarme, nao de
   ausencia. Confundir os dois faz o painel parecer calmo quando nao esta. */
.bolinha--sem_contato { background: var(--estado-critico); outline: 2px solid var(--estado-critico-fraco); }
.tabela-rede td { vertical-align: top; }

/* --------------------------------------------------- provisionamento */
.linha-form { display: flex; gap: var(--e-2); align-items: center; flex-wrap: wrap; }
.linha-form input[type=text] { min-width: 260px; }
/* `.campo` carrega margin-bottom pensado pra formulario EMPILHADO (um
   campo embaixo do outro) — aqui, ao lado de um <button> irmao sem essa
   margem, ela desalinhava a caixa de texto pra cima do botao dentro do
   align-items:center (a margem conta na caixa do item, so no botao
   nao). Zerada so aqui: o gap de `.linha-form` ja cobre o espacamento,
   inclusive quando embrulha em telas estreitas. Achado em 01/09/2026,
   vale pras tres telas que usam `.linha-form` (incidentes, provisionar,
   usuarios) de uma vez so. */
.linha-form .campo { margin-bottom: 0; }
.roteiro { background: var(--sup-1); border: 1px solid var(--linha);
  border-radius: var(--raio-md); padding: var(--e-3); overflow-x: auto;
  font-family: var(--fonte-mono); font-size: var(--t-sm); line-height: 1.5;
  white-space: pre; }
.aviso { border-left: 3px solid var(--estado-critico);
  background: var(--estado-critico-fraco); padding: var(--e-3) var(--e-4);
  border-radius: 0 var(--raio-md) var(--raio-md) 0; margin-bottom: var(--e-4);
  font-size: var(--t-sm); }
/* O botao que escreve na rede nao pode parecer com o que so navega. */
.perigo { background: var(--estado-critico); color: #fff; border: none; font-weight: 600; }
.perigo:hover { filter: brightness(1.1); }
