/* ==========================================================================
   BigGoTV — folha de estilo ÚNICA dos três painéis.

     br-sv01.biggotv.com   index.html         master
     revenda.biggotv.com   revenda.html       revenda
     login.biggotv.com     gerenciador.html   aparelho

   ─────────────────────────────────────────────────────────────────────────
   POR QUE ELA EXISTE (08/08/2026)

   Antes: o master carregava 407 KB de Tailwind e usava um vermelho que NÃO é
   o da marca (#dc2626); a revenda e o gerenciador tinham cada um o seu CSS
   embutido, copiado de um para o outro. Três telas do mesmo produto com três
   aparências e um vermelho errado no meio.

   Agora: um arquivo. Mudou a cor aqui, mudou nos três. O Tailwind saiu
   inteiro — 407 KB viraram ~14 KB.

   ⚠️ AS CLASSES DE UTILIDADE ABAIXO TÊM NOMES DO TAILWIND DE PROPÓSITO.
   O HTML do master usa cerca de 60 delas. Reescrever aquele HTML seria muito
   mais arriscado do que reproduzir as poucas classes que ele realmente usa —
   então elas existem aqui, com as cores certas. Ao acrescentar tela nova,
   prefira os componentes (.card, .bt, .tabela) às utilidades.
   ========================================================================== */

/* --------------------------------------------------------------- tokens */
:root {
  /* Vermelhos — os MESMOS do aplicativo (ui/theme/Color.kt) e do site. */
  --vermelho: #FF1717;
  --vermelho-forte: #FF0000;
  --vermelho-escuro: #7A0000;
  --vermelho-hover: #FF3A3A;

  /* Fundos e superfícies */
  --fundo: #050505;
  --fundo-2: #090909;
  --superficie: #161616;
  --superficie-2: #1c1c1c;
  --painel: #0C0C0C;

  /* Bordas */
  --borda: rgba(255, 23, 23, .55);
  --borda-forte: rgba(255, 23, 23, .95);
  --divisoria: rgba(255, 255, 255, .08);

  /* Textos */
  --texto: #FFFFFF;
  --texto-2: #C8C8C8;
  --texto-3: #777777;

  /* Sinais — os únicos lugares onde outra cor entra, e sempre por SIGNIFICADO */
  --ok: #3FB950;
  --alerta: #D29922;
  --erro: #FF1717;

  --raio: 14px;
  --raio-p: 10px;
  --sombra: 0 18px 44px rgba(0, 0, 0, .5);
}

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--fundo);
  color: var(--texto);
  line-height: 1.55;
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  font-size: 15px;
  /* 🐛 O FUNDO NÃO ERA O MESMO DO SITE — achado em 10/08/2026 comparando as duas folhas regra
   * a regra, depois de o dono dizer três vezes que continuava desalinhado e eu insistir que
   * estava idêntico.
   *
   * Eu tinha conferido a POSIÇÃO (logo, fio, container) e dado por encerrado. O que faltava
   * era o fundo, e a diferença era dupla:
   *
   *                          site                     painel (antes)
   *   brilho de cima         60rem × 30rem, 0,14      58rem × 26rem, 0,11   ← menor e apagado
   *   brilho de baixo/dir.   40rem × 24rem, 0,18      NÃO EXISTIA
   *
   * Um brilho a menos e o outro mais fraco: o painel ficava chapado embaixo enquanto o site
   * tinha o vermelho subindo do canto. É o tipo de diferença que a vista percebe e a régua de
   * posição não pega — eu estava medindo a coisa certa no lugar errado.
   *
   * Copiado LITERALMENTE do estilo.css do site. Se um mudar, mude o outro. */
  background-image:
    radial-gradient(60rem 30rem at 50% -12rem, rgba(255, 23, 23, 0.14), transparent 70%),
    radial-gradient(40rem 24rem at 100% 100%, rgba(122, 0, 0, 0.18), transparent 70%);
  background-attachment: fixed;
  min-height: 100vh;
}

a { color: var(--vermelho); text-decoration: none; }
a:hover { color: var(--vermelho-hover); }
img { max-width: 100%; height: auto; }
figure { margin: 0; }

h1 { font-size: 1.3rem; margin: 0; font-weight: 800; letter-spacing: -.01em; }
h2 { font-size: 1.05rem; margin: 0 0 12px; font-weight: 700; }
h3 { font-size: .98rem; margin: 0 0 6px; font-weight: 700; }

/* --------------------------------------------------------------- estrutura */
/* ═══════════════════════════════════════════════════════════════════════════════════════════
 * A MESMA RÉGUA DO SITE — X, Y e tamanho. Pedido do dono em 10/08/2026: "termine de alinhar
 * fundo e logotipo em X e Y e tamanho dos painéis com os do site".
 *
 * Estavam TRÊS medidas diferentes para a mesma coisa:
 *
 *                          site          revenda/gerenciador   master
 *   largura útil           1080px        1080px                1120px  (max-w-6xl = 72rem)
 *   recuo lateral          20px          20px                  16px    (p-4)
 *   logo começa em Y       44px          —                     46px
 *
 * No site: `.faixa` dá 20px de lado, `.centro` limita a 1080, a barra tem 30px de margem (a
 * altura do fio chanfrado) e o menu 14px de recuo — o logotipo nasce em 44.
 *
 * Aqui o recuo de cima sai do container e passa para a faixa, para a conta ser a MESMA: 30 de
 * margem + 14 de recuo = 44. O `#app` do master é forçado junto, porque ele usa classes de
 * utilidade (`max-w-6xl`, `p-4`) que davam outros números.
 * ═══════════════════════════════════════════════════════════════════════════════════════════ */
.env,
#app {
  max-width: 1120px;      /* 1080 úteis + os 20px de cada lado, como o site */
  margin: 0 auto;
  padding: 0 20px 20px;   /* o recuo DE CIMA é da faixa, não do container */
}

.topo {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; flex-wrap: wrap; margin-bottom: 18px;
}
/* 🔴 O LOGOTIPO ENTROU NO TOPO DOS PAINÉIS — 10/08/2026, reclamação do dono: "os painéis não
 * estão com o topo no padrão das outras, não tem o logotipo".
 *
 * Ele estava certo e a falha era minha: eu levei as CORES e a CHAPA do aplicativo para cá,
 * mas deixei o topo escrito "BigGoTV" em texto, enquanto o site e o app mostram a marca
 * desenhada. Padrão pela metade é o que faz duas telas do mesmo produto parecerem de empresas
 * diferentes — foi exatamente o que aconteceu antes com o site verde e o app vermelho.
 *
 * O arquivo é o MESMO do site (public/img/logo.png, 800×320, gerado do original de 3125px).
 * 34px de altura acompanha a proporção que o app usa na faixa dele. */
.marca { display: flex; align-items: center; gap: 12px; }
.marca img { width: 132px; height: auto; display: block; }   /* mesma largura do site */
.marca .nome { font-size: 1.3rem; font-weight: 800; }
.marca .nome b { color: var(--vermelho); }
.papel { color: var(--texto-3); font-size: .8rem; }

/* 🐛 `:not(.bgg-canto)` — E ISTO FOI UM ERRO MEU QUE O DONO VIU NA TELA.
 *
 * `.topo` é o nome de DUAS coisas neste arquivo: o cabeçalho do painel e o fio chanfrado do
 * fundo (`.bgg-canto.topo`). Ao dar `margin-top: 30px` para "o cabeçalho", a regra pegou
 * TAMBÉM o fio e o empurrou 30px para baixo — então ele descia até debaixo do logotipo.
 *
 * Medido, na mesma janela de 1920:
 *
 *              site          painel (com o defeito)
 *   fio        0 → 30px      30 → 60px      ← empurrado
 *   folga      +14px         −13px          ← logotipo POR CIMA do fio
 *
 * Era exatamente a diferença que ele descrevia: "as páginas estão alinhadas e os painéis
 * não". Nome de classe repetido para coisas diferentes é armadilha — a regra atinge as duas
 * e só uma aparece no teste.
 *
 * A altura do logotipo virou 132px de largura, a mesma do site, para os dois terminarem no
 * mesmo tamanho de marca. */
/* 30 de margem (a altura do fio chanfrado) + 14 de recuo = logotipo em Y=44, o mesmo do site.
   No site isso é `.barra-topo { margin-top: 30px }` + `.menu { padding: 14px 0 }`. */
.topo:not(.bgg-canto) { margin-top: 30px; padding-top: 14px; }
@media (max-width: 560px) { .topo:not(.bgg-canto) { margin-top: 12px; padding-top: 10px; } }

/* --------------------------------------------------------------- abas */
.abas { display: flex; gap: 8px; margin-bottom: 20px; flex-wrap: wrap; }
.tab, .aba {
  padding: 8px 16px; border-radius: 999px; cursor: pointer; font-size: .88rem;
  border: 1px solid var(--divisoria); color: var(--texto-2);
  background: transparent; font-family: inherit; transition: .15s;
  user-select: none;
}
.tab:hover, .aba:hover { border-color: var(--borda); color: var(--texto); }
.tab.on, .aba.on {
  border-color: var(--borda); background: rgba(255, 23, 23, .12);
  color: #fff; font-weight: 600;
}

/* --------------------------------------------------------------- cartões */
/* O cartão é a CHAPA do aplicativo (`bggPanel`): fundo em degradê, fio vermelho de um pixel e
 * brilho ao passar o mouse — o mesmo que lá acontece ao receber o foco do controle. Era cinza
 * chapado com borda branca translúcida, o desenho padrão de qualquer painel. Mesma regra no
 * estilo.css do site. */
.card, .cartao {
  background: linear-gradient(180deg, rgba(22, 22, 22, .96), rgba(9, 9, 9, .96));
  border: 1px solid rgba(255, 23, 23, .28);
  border-radius: var(--raio);
  margin-bottom: 16px;
  transition: border-color .2s ease, box-shadow .2s ease;
}
.card { padding: 0; }          /* o master usa .card junto de .p-3/.p-4/.p-6 */
.cartao { padding: 18px; }
.card:hover, .cartao:hover {
  border-color: var(--borda);
  box-shadow: 0 0 0 1px rgba(255, 23, 23, .16), 0 8px 26px rgba(255, 23, 23, .09);
}

/* Números do topo: o que importa é o MAIOR elemento da tela. */
.numeros { display: grid; gap: 12px; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); margin-bottom: 16px; }
/* Mesma chapa dos cartões — os números do topo são o maior elemento da tela e ficariam
   destoando se continuassem cinza chapado. */
.numero {
  background: linear-gradient(180deg, rgba(22, 22, 22, .96), rgba(9, 9, 9, .96));
  border: 1px solid rgba(255, 23, 23, .28);
  border-radius: var(--raio); padding: 15px 16px;
}
.numero b { display: block; font-size: 1.85rem; line-height: 1.05; font-variant-numeric: tabular-nums; }
.numero span { color: var(--texto-3); font-size: .78rem; }
.numero.destaque { border-color: var(--borda); background: linear-gradient(180deg, rgba(255,23,23,.08), var(--superficie) 75%); }
.numero.destaque b { color: var(--vermelho); }

/* --------------------------------------------------------------- listas */
.item, .linha-lista {
  display: flex; gap: 10px; align-items: center; flex-wrap: wrap;
  padding: 12px 0; border-bottom: 1px solid var(--divisoria);
}
.item:last-child, .linha-lista:last-child { border-bottom: none; }
.mac { font-family: ui-monospace, Consolas, monospace; font-size: .93rem; min-width: 150px; }
.crescer { flex: 1; min-width: 130px; }

/* --------------------------------------------------------------- selos */
.selo {
  font-size: .72rem; padding: 2px 10px; border-radius: 999px;
  border: 1px solid var(--divisoria); color: var(--texto-2);
  white-space: nowrap;
}
.s-ativo { color: var(--ok); border-color: rgba(63, 185, 80, .4); }
.s-trial, .s-alerta { color: var(--alerta); border-color: rgba(210, 153, 34, .4); }
.s-bloq, .s-erro { color: var(--vermelho); border-color: var(--borda); }

/* --------------------------------------------------------------- formulários */
.inp, input[type=text], input[type=password], input[type=number], select, textarea {
  width: 100%; background: #0b0b0b; border: 1px solid var(--divisoria);
  color: var(--texto); padding: 11px 13px; border-radius: var(--raio-p);
  font-size: .95rem; font-family: inherit;
}
.inp:focus, input:focus, select:focus, textarea:focus { outline: none; border-color: var(--borda); }
.inp::placeholder, input::placeholder, textarea::placeholder { color: #5a5a5a; }
/* A caixa de texto do "Falar com o suporte": alta o bastante para caber um parágrafo, e só
   redimensionável na vertical — arrastar para o lado estoura o modal. */
.area-msg { min-height: 110px; resize: vertical; font: inherit; }
input[type=checkbox] { width: auto; accent-color: var(--vermelho); }

/* Campo de data+hora (o vencimento do link temporário). O calendário é o do próprio navegador —
   nada de biblioteca de fora, que é a regra deste projeto desde o Leaflet do `unpkg.com`.
   ⚠️ `color-scheme: dark` NÃO é enfeite: sem ele o navegador desenha o calendário e o ícone do
   relógio no tema claro, e o ícone fica preto sobre fundo preto — invisível. */
input[type=datetime-local] {
  width: 100%; background: #0b0b0b; border: 1px solid var(--divisoria);
  color: var(--texto); padding: 11px 13px; border-radius: var(--raio-p);
  font-size: .95rem; font-family: inherit;
  color-scheme: dark;
}
label { font-size: .88rem; color: var(--texto-2); }

/* --------------------------------------------------------------- botões */
.btn, .bt {
  background: linear-gradient(180deg, var(--vermelho), var(--vermelho-escuro) 190%);
  color: #fff; border: 1px solid var(--borda-forte);
  padding: 11px 20px; border-radius: 999px; font-weight: 700;
  cursor: pointer; font-size: .92rem; font-family: inherit;
  transition: .15s; white-space: nowrap;
}
.btn:hover, .bt:hover { background: var(--vermelho-hover); transform: translateY(-1px); }
.btn2, .bt2 {
  background: rgba(255, 255, 255, .04); color: var(--texto);
  border: 1px solid var(--divisoria); padding: 8px 15px; border-radius: 999px;
  cursor: pointer; font-size: .85rem; font-family: inherit; transition: .15s;
  white-space: nowrap;
}
.btn2:hover, .bt2:hover { border-color: var(--borda); background: rgba(255, 23, 23, .09); color: #fff; }
.btn:disabled, .bt:disabled, .btn2:disabled, .bt2:disabled { opacity: .42; cursor: not-allowed; transform: none; }
.bt-perigo { border-color: var(--borda); color: var(--vermelho); }
.bt-perigo:hover { background: rgba(255, 23, 23, .14); }

/* --------------------------------------------------------------- avisos */
.aviso {
  padding: 11px 14px; border-radius: var(--raio-p); margin: 12px 0;
  font-size: .9rem; border: 1px solid var(--divisoria); color: var(--texto-2);
}
.aviso.erro { border-color: var(--borda); background: rgba(255, 23, 23, .08); color: var(--texto); }
.aviso.bom { border-color: rgba(63, 185, 80, .4); background: rgba(63, 185, 80, .08); }
.aviso.atencao { border-color: rgba(210, 153, 34, .4); background: rgba(210, 153, 34, .08); }

/* --------------------------------------------------------------- janelas */
.fundo-modal, #modal.aberto {
  position: fixed; inset: 0; background: rgba(0, 0, 0, .78);
  display: flex; align-items: center; justify-content: center;
  padding: 18px; z-index: 50;
}
.modal {
  background: var(--painel); border: 1px solid var(--borda);
  border-radius: 16px; padding: 22px; width: 100%; max-width: 560px;
  max-height: 88vh; overflow: auto; box-shadow: var(--sombra);
}

/* --------------------------------------------------------------- diversos */
.fraco { color: var(--texto-3); font-size: .82rem; }
.linha { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.grade { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.rolagem { overflow-x: auto; }

/* ==========================================================================
   UTILIDADES com nomes do Tailwind — só as que o HTML do master usa.
   Ver o aviso no topo do arquivo antes de acrescentar.
   ========================================================================== */
.flex { display: flex; } .grid { display: grid; } .hidden { display: none; }
.relative { position: relative; } .absolute { position: absolute; } .fixed { position: fixed; }
.inset-0 { inset: 0; } .top-3 { top: .75rem; } .right-4 { right: 1rem; } .z-50 { z-index: 50; }
.flex-1 { flex: 1 1 0%; } .flex-wrap { flex-wrap: wrap; }
.items-center { align-items: center; } .items-start { align-items: flex-start; }
.justify-between { justify-content: space-between; } .justify-center { justify-content: center; }
.mx-auto { margin-left: auto; margin-right: auto; }
.gap-2 { gap: .5rem; } .gap-3 { gap: .75rem; }
.grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.space-y-1 > * + * { margin-top: .25rem; } .space-y-0\.5 > * + * { margin-top: .125rem; }
.divide-y > * + * { border-top: 1px solid var(--divisoria); }
.divide-neutral-800 > * + * { border-color: var(--divisoria); }

.p-3 { padding: .75rem; } .p-4 { padding: 1rem; } .p-6 { padding: 1.5rem; } .p-8 { padding: 2rem; }
.px-2 { padding-left: .5rem; padding-right: .5rem; }
.py-0\.5 { padding-top: .125rem; padding-bottom: .125rem; } .py-2 { padding-top: .5rem; padding-bottom: .5rem; }
.mb-1 { margin-bottom: .25rem; } .mb-2 { margin-bottom: .5rem; } .mb-3 { margin-bottom: .75rem; }
.mb-4 { margin-bottom: 1rem; } .mb-6 { margin-bottom: 1.5rem; }
.mt-0\.5 { margin-top: .125rem; } .mt-1 { margin-top: .25rem; } .mt-2 { margin-top: .5rem; }
.mt-3 { margin-top: .75rem; } .mt-24 { margin-top: 6rem; } .ml-2 { margin-left: .5rem; }

.w-full { width: 100%; } .w-24 { width: 6rem; } .w-28 { width: 7rem; }
.w-40 { width: 10rem; } .w-56 { width: 14rem; }
.min-w-\[160px\] { min-width: 160px; } .min-w-\[180px\] { min-width: 180px; }
.min-w-\[200px\] { min-width: 200px; } .min-w-\[220px\] { min-width: 220px; } .min-w-\[260px\] { min-width: 260px; }
.max-w-sm { max-width: 24rem; } .max-w-lg { max-width: 32rem; } .max-w-xl { max-width: 36rem; }
.max-w-2xl { max-width: 42rem; } .max-w-6xl { max-width: 72rem; }
.max-h-72 { max-height: 18rem; } .min-h-screen { min-height: 100vh; }
.overflow-auto { overflow: auto; } .truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.break-all { word-break: break-all; }
.rounded { border-radius: var(--raio-p); } .rounded-xl { border-radius: var(--raio); }

.text-xs { font-size: .75rem; } .text-sm { font-size: .875rem; } .text-lg { font-size: 1.06rem; }
.text-xl { font-size: 1.2rem; } .text-2xl { font-size: 1.45rem; } .text-3xl { font-size: 1.85rem; line-height: 1.1; }
.font-bold { font-weight: 700; } .font-mono { font-family: ui-monospace, Consolas, monospace; }

/* Cinzas: mapeados para os tokens, não para a escala do Tailwind. */
.text-neutral-200 { color: #e6e6e6; } .text-neutral-300 { color: var(--texto-2); }
.text-neutral-400 { color: var(--texto-2); } .text-neutral-500 { color: var(--texto-3); }
.text-neutral-600 { color: #5f5f5f; } .text-neutral-700 { color: #4a4a4a; }
.bg-black\/70 { background: rgba(0, 0, 0, .78); }
.bg-neutral-800 { background: rgba(255, 255, 255, .06); }

/* Sinais: o vermelho é o DA MARCA, não o #dc2626 que o Tailwind trazia. */
.text-red-300, .text-red-400, .text-red-500 { color: var(--vermelho); }
.text-green-300 { color: var(--ok); } .text-yellow-300, .text-yellow-400 { color: var(--alerta); }
.bg-green-900 { background: rgba(63, 185, 80, .16); }
.bg-red-900 { background: rgba(255, 23, 23, .16); }
.bg-yellow-900 { background: rgba(210, 153, 34, .16); }

/*
 * 🔴 CLASSE QUE NÃO EXISTE AQUI NÃO DÁ ERRO — ELA SÓ NÃO FAZ NADA.
 *
 * Esta folha é escrita à mão desde que o Tailwind de CDN saiu (09/08/2026), então ela tem apenas
 * as classes que alguém precisou até hoje. Escrever `md:grid-cols-2` numa tela sem que ela exista
 * aqui deixa a grade com UMA coluna, sem aviso nenhum — foi exatamente o que aconteceu com a aba
 * Aplicativos em 12/08/2026: eu pus Android e Windows lado a lado, e o dono viu os dois empilhados.
 *
 * Duas coisas nasceram desse erro:
 *   · as classes que faltavam entraram (a de 2 e a de 4 colunas, mais o espaçamento abaixo);
 *   · `scripts/conferir-classes.mjs` passou a reprovar classe usada sem regra, no `npm run check`.
 */
@media (min-width: 768px) {
  .md\:grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .md\:grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  /* Já era usada na aba Dispositivos e também não existia — outro silêncio antigo. */
  .md\:grid-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  /* A de 5 entrou em 15/08: a dashboard passou a separar "Android baixado" de "PC baixado",
     e o cartão a mais não cabia em 4. O fiscal pegou antes de ir para a tela. */
  .md\:grid-cols-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
  .md\:grid-cols-6 { grid-template-columns: repeat(6, minmax(0, 1fr)); }
}

/* Espaçamento que faltava na escala. Mesmos passos de 0,25rem do resto da folha. */
.gap-4 { gap: 1rem; }
.p-5 { padding: 1.25rem; }
.mt-5 { margin-top: 1.25rem; } .mt-6 { margin-top: 1.5rem; }
.ml-6 { margin-left: 1.5rem; }
.w-32 { width: 8rem; }
.w-44 { width: 11rem; }
.space-y-2 > * + * { margin-top: .5rem; }
/* O corpo já usa esta pilha de fontes; a classe existia no HTML e não na folha. */
.font-sans { font-family: "Segoe UI", Roboto, system-ui, -apple-system, sans-serif; }

/* ==========================================================================
   CELULAR — os painéis são usados no telefone com frequência (a revenda
   ativando cliente na rua, o master conferindo algo rápido).
   ========================================================================== */
@media (max-width: 640px) {
  body { font-size: 14.5px; }
  .env { padding: 14px; }
  .topo { gap: 10px; }
  .abas { gap: 6px; margin-bottom: 14px; }
  .tab, .aba { padding: 7px 13px; font-size: .82rem; }
  .btn, .bt, .btn2, .bt2 { width: 100%; text-align: center; }
  .linha { flex-direction: column; align-items: stretch; }
  .item { padding: 11px 0; }
  .mac { min-width: 0; width: 100%; }
  .numeros { grid-template-columns: repeat(2, 1fr); gap: 10px; }
  .numero { padding: 12px; } .numero b { font-size: 1.5rem; }
  .modal { padding: 18px; max-height: 92vh; }
  .p-6, .p-8 { padding: 1rem; }
  .mt-24 { margin-top: 2rem; }
}

/* ==========================================================================
   Componentes específicos das telas de revenda e do gerenciador.
   Vieram dos <style> embutidos que cada uma tinha; agora vivem aqui, junto
   com o resto, para o visual dos três painéis mudar de um lugar só.
   ========================================================================== */

/* Tela de entrar (revenda e gerenciador) */
.entrar { max-width: 400px; margin: 8vh auto; }
.entrar .cartao { padding: 22px; }

/* Ficha do aparelho, no topo direito do gerenciador */
.ficha { text-align: right; font-size: .85rem; color: var(--texto-2); }
.ficha b { color: var(--texto); font-family: ui-monospace, Consolas, monospace; }
.ficha > div + div { margin-top: 2px; }

/* Declaração de responsabilidade — o texto que separa reprodutor de distribuidor */
.declaracao {
  border: 1px solid var(--borda); border-radius: var(--raio);
  background: rgba(255, 23, 23, .05); padding: 18px;
  font-size: .88rem; color: var(--texto-2); margin-bottom: 16px;
}
.declaracao b { color: #fff; }
label.decl, label.dec {
  display: flex; gap: 9px; align-items: flex-start;
  font-size: .82rem; color: var(--texto-2); margin: 12px 0;
  cursor: pointer;
}
label.decl input, label.dec input { margin-top: 3px; flex: none; }
/* A mesma caixinha, mas para uma opção de UMA linha (o "Host fixo") em vez do parágrafo da
   declaração de responsabilidade: alinha no meio, e não pelo topo. */
label.decl-linha { align-items: center; }
label.decl-linha input { margin-top: 0; }

@media (max-width: 640px) {
  .entrar { margin: 4vh auto; }
  .ficha { text-align: left; }
  .topo { flex-direction: column; align-items: stretch; }
}

/* ==========================================================================
   O FUNDO DO APLICATIVO, TRAZIDO PARA OS TRÊS PAINÉIS — 08/08/2026

   Mesma receita de `ui/theme/BggStyle.kt` no app e de `estilo.css` no site:
   quatro luzes de DUAS TEMPERATURAS (quente em cima, carmim embaixo), vinheta,
   grão anti-faixa e os chanfros dos cantos com o fio vermelho na quina.

   ⚠️ Se um dos três mudar, mudam os três. É o mesmo produto — o revendedor
   abre o painel e o cliente abre o app, e os dois precisam parecer a mesma
   casa.

   Tudo `fixed` e `pointer-events: none`: é cenário, nunca intercepta clique.
   ========================================================================== */
body::before {
  content: ""; position: fixed; inset: 0; z-index: -2; pointer-events: none;
  background:
    radial-gradient(120% 120% at 50% 48%, transparent 0%, transparent 36%, rgba(0,0,0,.66) 100%),
    radial-gradient(60% 55% at 50% 106%, rgba(122,0,24,.42), transparent 70%),
    radial-gradient(42% 40% at 98% 5%, rgba(255,59,59,.15), transparent 70%),
    radial-gradient(30% 28% at 10% 2%, rgba(255,23,23,.28), transparent 70%),
    radial-gradient(52% 48% at 4% -2%, rgba(224,42,10,.42), transparent 70%),
    #060303;
}

/* Grão: quebra as faixas de cor do degradê escuro em tela de 8 bits. */
body::after {
  content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none; opacity: .026;
  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='r'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23r)'/%3E%3C/svg%3E");
}

/* Chanfros: chapa vermelha embaixo, escura por cima; a sobra é o fio.
   x em porcentagem, degrau em pixel — é o que mantém o corte a 45° em
   qualquer largura de janela. */
.bgg-canto { position: fixed; left: 0; right: 0; z-index: -1; pointer-events: none; }
.bgg-canto span { position: absolute; inset: 0; display: block; }
/* 🔴 AS FRAÇÕES SÃO AS DO APLICATIVO, e agora batem em app, site e painéis (10/08/2026).
 *
 * Aqui estavam 62% e 26% em cima e 38%/74% embaixo, com degrau de 13px. No app são
 * PASSO_CIMA_1 = 0,24 · PASSO_CIMA_2 = 0,60 · PASSO_BAIXO_1 = 0,36 · PASSO_BAIXO_2 = 0,72
 * (ui/common/BggGrade.kt), e o site já usava esses. Dois pontos percentuais de diferença
 * ninguém mede a olho, mas é exatamente assim que três "quase iguais" viram três desenhos
 * diferentes com o tempo — foi o que aconteceu com o logo dentro do próprio app.
 *
 * Se a régua do app mudar, mude aqui e no estilo.css do site. São os três lugares. */
.bgg-canto.topo { top: 0; height: 30px; }
.bgg-canto.topo span:first-child {
  background: linear-gradient(90deg, rgba(255,23,23,.55), #FFD9D9 55%, rgba(255,23,23,.15));
  clip-path: polygon(0 0, 60% 0, calc(60% - 15px) 15px, 24% 15px, calc(24% - 15px) 30px, 0 30px);
}
.bgg-canto.topo span:last-child {
  background: linear-gradient(180deg, rgba(26,5,5,.94), rgba(11,3,3,.55));
  clip-path: polygon(0 0, calc(60% - 3px) 0, calc(60% - 18px) 12px, calc(24% - 3px) 12px,
                     calc(24% - 18px) 27px, 0 27px);
}
.bgg-canto.rodape { bottom: 0; height: 60px; }
.bgg-canto.rodape span:first-child {
  background: linear-gradient(270deg, rgba(255,23,23,.55), #FFD9D9 55%, rgba(255,23,23,.15));
  clip-path: polygon(100% 100%, 36% 100%, calc(36% + 30px) 70%, 72% 70%, calc(72% + 30px) 40%, 100% 40%);
}
.bgg-canto.rodape span:last-child {
  background: linear-gradient(0deg, rgba(26,5,5,.94), rgba(11,3,3,.55));
  clip-path: polygon(100% 100%, calc(36% + 3px) 100%, calc(36% + 33px) 75%, calc(72% + 3px) 75%,
                     calc(72% + 33px) 45%, 100% 45%);
}
@media (max-width: 560px) { .bgg-canto { display: none; } }

/* ─────────────────────────────────────────────────────────────────────────────────────────
 * Três classes que nasceram para tirar `style="..."` de dentro do HTML dos painéis.
 *
 * Enquanto existir UM atributo `style` inline, a política de segurança precisa permitir
 * `'unsafe-inline'` em `style-src` — e essa permissão vale para a página inteira, não só para
 * aquele atributo. Trocar seis atributos por três classes é o que fecha a porta.
 * ───────────────────────────────────────────────────────────────────────────────────────── */
.marca-topo { margin-bottom: 18px; }
.mapa-radar { height: 440px; background: #0c0c0c; }
.btn-perigo { border-color: #7f1d1d; color: #fca5a5; }

/* ═══════════════════════════════════════════════════════════════════════════════════════════
   PAINEL DA REVENDA — as classes que substituíram estilo embutido, em 11/08/2026.

   Motivo: com `style="..."` dentro do HTML, a política de segurança é obrigada a permitir
   estilo embutido — e permitir embutido é permitir também o que um atacante injetar. Mesma
   reforma que o painel master passou no mesmo dia.

   ⚠️ Cada valor foi copiado 1:1 do que estava embutido, DE PROPÓSITO. Existem quatro espaços
   diferentes acima de linha de botão (10, 12, 14 e 16px) e dois tamanhos de subtítulo. Unificar
   pareceria mais limpo, mas mudaria o visual — e reforma de segurança que muda o desenho não dá
   para conferir olhando: qualquer diferença na tela passa a ter duas explicações possíveis.
   Consolidar é decisão de desenho, para outro dia.
   ═══════════════════════════════════════════════════════════════════════════════════════════ */
.rotulo-campo { margin-bottom: 4px; }
.campos       { display: grid; gap: 10px; }
.prazos       { display: grid; gap: 8px; }
.prazos-massa { display: grid; gap: 9px; margin: 14px 0; }
.dica         { margin: 0 0 10px; }
.dica-larga   { margin: 0 0 12px; }
.dica-fim     { margin: 10px 0 0; }
.nota-final   { margin: 16px 0 0; }
.cab-ficha    { margin: 0 0 14px; }
.sub          { margin: 18px 0 8px; font-size: 1rem; }
.sub-topo     { margin: 0 0 8px; font-size: 1rem; }
.acoes        { margin-top: 14px; }
.acoes-larga  { margin-top: 16px; }
.acoes-curta  { margin-top: 12px; }
.bt-espaco    { margin-top: 10px; }
.vermelho     { color: var(--vermelho); }
.dir          { text-align: right; }
.esq          { text-align: left; }
.centro       { text-align: center; }

/* ─── Gerenciador do aparelho (login.biggotv.com), reformado em 11/08/2026 ───────────────────
   Mesma regra da revenda: valores copiados 1:1 do que estava embutido. */
.campo-empilhado { margin-bottom: 10px; }
.campo-pin       { margin: 12px 0; }
.dica-curta      { margin: 8px 0 0; }
.dados-lista     { display: grid; gap: 8px; font-size: .9rem; }
.lista-ajuda     { display: grid; gap: 6px; font-size: .92rem; }
.branco          { color: #fff; }
.bt-link         { display: inline-block; text-decoration: none; }
/* O bloco de host/usuário/senha nasce escondido. Quem mostra é `modoAdd()`, pela classe —
   e NÃO por `style.display`, porque o estado do formulário deixou de ser lido do DOM. */
.campo-xc          { display: none; gap: 10px; grid-template-columns: 1fr; }
.campo-xc.mostrar  { display: grid; }
.campo-m3u.esconder { display: none; }

/* Caixa de destaque dentro de um card — usada no resumo da aba Aplicativos (12/08/2026).
   Nasceu como style="background:#111" embutido, e o conferidor de botões reprovou na hora:
   estilo embutido obriga a política de segurança a permitir estilo embutido. */
.caixa-interna { background: #111; }

/* Caixa da versão que está AGUARDANDO publicação (aba Aplicativos).
   Vermelha e destacada de propósito: é uma pendência, não um estado normal — e é a única coisa
   naquela tela que exige uma decisão do dono. Fica aqui, e não em `style=`, porque a política de
   segurança do painel proíbe estilo embutido (ver item 8c do CLAUDE.md). */
.caixa-pendente{
  border:1px solid rgba(229,9,20,.7);
  background:rgba(229,9,20,.10);
}

/* ─── Gerenciador de downloads: zona de arrastar e barra de progresso (15/08/2026) ─────────
   Tudo aqui, e não em `style=`: a política de segurança dos painéis proíbe estilo embutido
   (item 8c do CLAUDE.md), e a classe `.sobre` é ligada e desligada pelo JavaScript. */
.zona-solta{
  border: 2px dashed var(--borda);
  border-radius: var(--raio);
  background: var(--fundo-2);
  padding: 30px 18px;
  text-align: center;
  cursor: pointer;
  display: block;
  transition: border-color .15s, background .15s;
}
.zona-solta:hover{ border-color: var(--borda-forte); }
/* Enquanto o arquivo está pairando sobre a área. Sem este retorno, quem arrasta não sabe se
   soltar ali vai valer — e solta fora, o que faz o navegador ABRIR o arquivo e sair da página,
   perdendo a tela do painel. */
.zona-solta.sobre{
  border-color: var(--borda-forte);
  background: rgba(255, 23, 23, .08);
}
.zona-solta input{ display: none; }
.zona-titulo{ font-weight: 700; margin-bottom: 4px; }

/* Barra de progresso do envio. Necessária porque 120 MB levam minutos: sem ela a tela parece
   travada e o dono recarrega a página no meio do envio — o mesmo defeito do item 8d. */
.barra{
  height: 8px;
  border-radius: 99px;
  background: var(--superficie-2);
  overflow: hidden;
  margin-top: 8px;
}
.barra > i{
  display: block;
  height: 100%;
  background: var(--vermelho);
  transition: width .2s;
}

/* A caixa do link TEMPORÁRIO, recuada dentro da linha do arquivo. Precisa se distinguir do
   link permanente à primeira vista: são dois endereços do mesmo arquivo, e confundir um com o
   outro faz o dono divulgar o que vence. */
.caixa-temp{
  background: var(--fundo-2);
  border: 1px solid var(--divisoria);
  border-radius: var(--raio-p);
}

/* ═══════════════════════════════════════════════════════════════════════════════════════════════
   ESTATÍSTICAS — 17/08/2026, para a aba nova do painel master (public/painel-stats.js).

   ⚠️ `rolagem-tabela` já existia no site, e NÃO estava aqui: a tabela dos servidores usaria a
   classe e ela não faria nada. Tabela mais larga que a tela empurra a PÁGINA para os lados em vez
   de rolar dentro da própria caixa — foi medido em 375px no site.
   ═══════════════════════════════════════════════════════════════════════════════════════════════ */
.graf { width: 100%; height: auto; display: block; }

/* A barra é feita de trilha + fita. A largura da fita entra por CSSOM (ver `pintarBarras`),
   porque atributo `style=` no HTML é proibido pela política de segurança do painel. */
.barra-rot    { flex: 0 0 34%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.barra-trilha { flex: 1 1 auto; height: 10px; border-radius: 999px;
                background: rgba(255, 255, 255, .07); overflow: hidden; display: block; }
.barra-fita   { display: block; height: 100%; border-radius: 999px; min-width: 2px; }
.barra-num    { flex: 0 0 3.5rem; text-align: right; }

.rolagem-tabela { overflow-x: auto; }
.rolagem-tabela .tabela { width: 100%; border-collapse: collapse; }
.rolagem-tabela .tabela th,
.rolagem-tabela .tabela td { padding: 6px 10px; text-align: left; font-size: 12px;
                             border-bottom: 1px solid var(--divisoria); }
.rolagem-tabela .tabela th { color: var(--texto-3); font-weight: 600; }

/* ═══════════════════════════════════════════════════════════════════════════════════════════════
   O SELO DE ONLINE E O PONTO DAS FAIXAS DO RADAR — 17/08/2026.

   🔴 "online" aqui quer dizer: ABRIU o aplicativo nos últimos 5 minutos. O aparelho avisa o painel
   ao abrir, não de minuto em minuto — quem está assistindo há três horas aparece como "visto há
   3 h", e isso está certo. O `title` do selo diz isso na tela, para o número não ser lido como
   "quantas TVs estão ligadas".
   ═══════════════════════════════════════════════════════════════════════════════════════════════ */
.selo-online {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 2px 9px; border-radius: 999px; font-size: 11px; font-weight: 600;
  color: #7ee08a; background: rgba(63, 185, 80, .14); border: 1px solid rgba(63, 185, 80, .45);
  cursor: help;
}
/* O pontinho antes do texto: é o SEGUNDO sinal, além da cor de fundo — cor sozinha nunca é a
   única informação. */
.selo-online::before {
  content: ''; width: 7px; height: 7px; border-radius: 50%; background: var(--ok);
}

/* Estatísticas: o botão do período escolhido, e as setas de variação.
   ⚠️ A seta (▲ ▼) é o segundo sinal além da cor — quem não distingue verde de vermelho lê a seta,
   e a porcentagem vem escrita do lado de qualquer jeito. */
.periodo-on { border-color: var(--vermelho); color: #fff; background: rgba(255, 23, 23, .12); }
.var-sobe  { color: #3fb950; }
.var-desce { color: #e0575c; }
.var-igual { color: var(--texto-3); }

/* Radar: o pontinho da faixa, na legenda e na lista. A cor entra por CSSOM (data-cor), porque
   atributo `style=` no HTML é proibido pela política de segurança do painel. */
.ponto-faixa {
  display: inline-block; width: 9px; height: 9px; border-radius: 50%;
  flex: 0 0 9px; background: var(--texto-3);
}

/* ═══════════════════════════════════════════════════════════════════════════════════════════════
   CONTADOR DE LISTAS — as duas cores, pedido do dono em 17/08/2026:
   "com listas quero que mostre com cor também igual 0 listas, porém outra cor".

   O ciano é o mesmo #0099ba já validado para os gráficos da aba Estatísticas — contra a superfície
   escura, com separação conferida em três tipos de daltonismo. Reaproveitar em vez de inventar um
   tom novo mantém o painel falando uma língua só.

   ⚠️ CONTRASTE CALCULADO, não escolhido a olho: o texto #5fd0e6 sobre o fundo composto (#122b30,
   que é o ciano a 16% sobre #161616) dá 8,24:1 — o mínimo do WCAG para texto pequeno é 4,5, e o
   selo de "online" que já existia dá 8,95.

   🔴 E o ciano é DE PROPÓSITO mais calmo que o amarelo. Aparelho sem lista nenhuma é a causa mais
   comum de "não abre nada", e é o que precisa puxar o olho; se as duas cores gritassem igual, o
   aviso deixaria de ser aviso. Mesma pílula, mesmo peso de fonte — quem separa é a temperatura.
   ═══════════════════════════════════════════════════════════════════════════════════════════════ */
.selo-listas,
.selo-sem-lista {
  display: inline-block; padding: 2px 9px; border-radius: 999px;
  font-size: 11px; font-weight: 600; cursor: help; white-space: nowrap;
}
.selo-listas {
  color: #5fd0e6; background: rgba(0, 153, 186, .16); border: 1px solid rgba(0, 153, 186, .45);
}
.selo-sem-lista {
  color: #f0c674; background: rgba(210, 153, 34, .16); border: 1px solid rgba(210, 153, 34, .5);
}
/*
 * 🔔 VERSÃO ANTIGA — item 462. Mesma temperatura do "sem lista": é aviso, não erro.
 * O aparelho funciona; ele só não tem as correções mais novas. Vermelho aqui competiria
 * com "bloqueado" e "vencida", que são as duas coisas que tiram o cliente do ar.
 */
.selo-versao-velha {
  display: inline-block; padding: 2px 9px; border-radius: 999px;
  font-size: 11px; font-weight: 600; cursor: help; white-space: nowrap;
  color: #f0c674; background: rgba(210, 153, 34, .16); border: 1px solid rgba(210, 153, 34, .5);
}

/* ═══════════════════════════════════════════════════════════════════════════════════════════════
   ETIQUETA DE PLATAFORMA — "PC" ou "Android", pedido do dono em 17/08/2026.

   🔴 O PRIMEIRO SINAL É A PALAVRA, não a cor: o selo diz "PC" ou "Android" por escrito. A cor
   existe para dar para CORRER O OLHO por 26 linhas sem ler cada uma.

   ⚠️ AS CORES FORAM MEDIDAS, não escolhidas de olho. Distância em OKLab (×100), incluindo as três
   simulações de daltonismo (deuteranopia, protanopia, tritanopia), sempre no PIOR caso:

     PC (#d3a5f5) vs Android (#3fb950)    27,4   ← é a distinção que o dono pediu
     Android vs o verde claro de "online" 13,4
     Android vs o ciano de listas         15,7
     PC vs o ciano de listas               9,4   ← o par mais parecido de toda a fileira
     contraste sobre o cartão           8,5:1 (PC) e 6,1:1 (Android)

   🐛 E o violeta É CLARO de propósito. Testei quatro tons: quanto mais escuro e saturado, mais
   perto do ciano ele chega para quem tem deuteranopia — #c07df0 cai para 3,1 e #b96ff0 para 1,1,
   ou seja, indistinguível do selo do lado. O tom claro é o único que se separa dos dois ao mesmo
   tempo.

   🔴 E O VERDE DO ANDROID É ESCURO PELO MESMO MOTIVO, ao contrário. O verde do robô da Google
   (#3DDC84) parecia a escolha óbvia e é a PIOR de todas: fica a 1,7 do cinza neutro e a 4,8 do
   verde de "online" — ou seja, some no meio da própria fileira. Quem salva não é o tom, é a
   LUMINOSIDADE: ela é o único eixo que sobrevive às três simulações de daltonismo, e é por isso
   que um verde médio-escuro se separa de um verde claro que um verde vivo não se separaria.

   ⚠️ Sim, "Android" e "online" são os dois verdes da mesma fileira, e isso foi pesado. O que
   desfaz a confusão não é a cor: é a POSIÇÃO. O selo de plataforma fica sempre logo depois do MAC,
   na mesma coluna em toda linha, e o de online fica na ponta direita. Quem corre o olho por uma
   coluna nunca está olhando a outra. (E o selo de online tem o pontinho, que o de plataforma não
   tem — ver o comentário dele acima.)
   ═══════════════════════════════════════════════════════════════════════════════════════════════ */
/* A forma, e o tom NEUTRO — que é o que sobra para um sistema que eu não reconheço. Ele fica
   cinza de propósito: pintar de verde um "Tizen 7.0" seria dizer Android sem ter conferido. */
.selo-so {
  display: inline-block; padding: 2px 9px; border-radius: 999px;
  font-size: 11px; font-weight: 600; cursor: help; white-space: nowrap;
  color: #a3a3a3; background: rgba(115, 115, 115, .14); border: 1px solid rgba(115, 115, 115, .45);
}
.selo-so-pc {
  color: #d3a5f5; background: rgba(176, 76, 224, .16); border-color: rgba(176, 76, 224, .5);
}
.selo-so-android {
  color: #3fb950; background: rgba(63, 185, 80, .13); border-color: rgba(63, 185, 80, .42);
}

/* ═══════════════════════════════════════════════════════════════════════════════════════════════
   DE QUEM É A LISTA, E SE ELA ESTÁ TRANCADA — selos coloridos, pedido do dono em 17/08/2026:
   *"mostrar a tag 'de outra revenda' ou 'de master' ou 'sem revenda', e tag protegida, tags sempre
   com cores"*.

   Eram todas cinza, e cinza igual em três informações diferentes é o mesmo que não ter selo: para
   saber de quem era a lista, a revenda tinha de LER cada linha.

   🔴 A cor aqui diz uma coisa por vez, e a escala não é decorativa — é quanto cuidado a linha pede:

     de master     violeta   tem dono, e o dono é o suporte: fale com ele antes de mexer
     outra revenda âmbar     tem dono, e não é você
     sem revenda   cinza     ninguém reivindica (lista do cliente, ou antiga demais para saber)
     sua           ciano     é sua

   ⚠️ E "protegida" é VERDE enquanto "sem PIN" é VERMELHO, e não o contrário. O vermelho está no
   estado que pede ação: lista sem PIN pode ser editada e apagada por qualquer revenda que abra
   aquele MAC — é a consequência que o dono aceitou junto com a regra de 16/08.

   🐛 E O VERMELHO É ESCURO POR MEDIÇÃO, não por gosto. O primeiro que escrevi aqui foi um rosa
   claro (#ff8f8f) e ele ficava a **0,8** do âmbar de "outra revenda" para quem tem deuteranopia —
   ou seja, a MESMA cor. E os dois aparecem lado a lado o tempo todo: lista de outra revenda que
   não tem PIN é exatamente a linha que a revenda mais precisa distinguir. Escurecido, o par vai a
   11,1. De novo a luminosidade sendo o único eixo que sobrevive ao daltonismo.

   Medido: o par mais parecido de todos os seis selos fica em 11,0, e o contraste mais baixo é
   4,6:1. As cores conversam com as dos selos de plataforma (bloco acima), e estas telas não
   mostram os dois conjuntos ao mesmo tempo.
   ═══════════════════════════════════════════════════════════════════════════════════════════════ */
.selo-de-master   { color: #d3a5f5; background: rgba(176, 76, 224, .16); border-color: rgba(176, 76, 224, .5); }
.selo-de-revenda  { color: #f0c674; background: rgba(210, 153, 34, .16); border-color: rgba(210, 153, 34, .5); }
.selo-sem-revenda { color: #a3a3a3; background: rgba(115, 115, 115, .14); border-color: rgba(115, 115, 115, .45); }
.selo-minha       { color: #5fd0e6; background: rgba(0, 153, 186, .16); border-color: rgba(0, 153, 186, .45); }
.selo-protegida   { color: #3fb950; background: rgba(63, 185, 80, .13); border-color: rgba(63, 185, 80, .42); }
.selo-aberta      { color: #e0575c; background: rgba(224, 87, 92, .14); border-color: rgba(224, 87, 92, .5); }

/* ═══════════════════════════════════════════════════════════════════════════════════════════════
   A CELA DA ETIQUETA DE ORIGEM na aba Contas — 19/08/2026.

   🐛 NASCEU DE UM CORTE QUE O DONO VIU NA TELA: a barriga de baixo da pílula aparecia ceifada.

   A causa: `.selo` é um elemento INLINE, e padding e borda de inline NÃO esticam a linha. A cela
   tinha `truncate`, que traz `overflow: hidden` — e existe por um bom motivo, impedir que nome
   comprido de revenda dobre a altura da linha (medido: 47 px viravam 90 px). Só que o que sobrava
   da pílula para fora da linha era cortado. Medido: 0,31 px abaixo da borda da cela — e o primeiro
   a desaparecer é a LINHA DA BORDA, que é justamente o que dá a forma de pílula. Por isso 0,31 px
   se vê de longe: não some um pedaço do fundo, some o contorno.

   O conserto é a cela virar FLEX. Aí a pílula é item de flex, tem caixa própria com altura
   própria, e para de depender da linha de texto do pai.

   ⚠️ E o truncar MUDA DE LUGAR: sai da cela e entra na PRÓPRIA pílula, senão o nome comprido de
   revenda volta a dobrar a altura da linha. Lá dentro o corte é de propósito, com reticências, e
   o nome inteiro continua no `title`.

   🔴 Escrito como `.cela-selo > .selo`, e NÃO em `.selo` direto: aquele selo é o mesmo do painel
   da revenda, e mexer nele daqui mudaria uma tela que não está em questão.
   ═══════════════════════════════════════════════════════════════════════════════════════════════ */
/* O endereço da lista em uso, mostrado como TEXTO e não como campo — ver o comentário em
   formularioDeEdicao(). Monoespaçado porque é credencial: caractere trocado tem de saltar aos
   olhos. Quebra em qualquer ponto porque URL de provedor não tem espaço e estouraria a caixa. */
/* Monoespaçado curto, para valor que se lê caractere a caractere — chave, código, MAC no meio de
   uma frase. Diferente de `.mac`, que tem largura mínima porque vive em coluna de tabela. */
.mono { font-family: ui-monospace, Consolas, monospace; letter-spacing: .02em; }

.lista-em-uso {
  font-family: ui-monospace, Consolas, monospace;
  font-size: .8rem; line-height: 1.5;
  word-break: break-all; user-select: all;
}

.cela-selo { display: flex; align-items: center; min-width: 0; }
.cela-selo > .selo { display: inline-block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
/* O MAC cadastrado à mão que nunca abriu o aplicativo. A borda TRACEJADA é o segundo sinal: "falta
   dado" tem cara de coisa incompleta, e não de mais uma plataforma. */
.selo-so-indefinido {
  color: #8a8a8a; background: none; border-style: dashed;
}

/* O texto do relato preserva as quebras de linha que o cliente escreveu — reflow apagaria a
   separacao entre "o que acontece" e "quando acontece", que e como as pessoas escrevem. */
.relato-texto { white-space: pre-wrap; }

/* Vencido: vermelho-alaranjado, DIFERENTE do bloqueado — as duas situacoes pedem acoes opostas
   (um precisa renovar, o outro foi desligado de proposito). */
.selo-vencido { color: #f0a06a; background: rgba(224, 122, 60, .16); border: 1px solid rgba(224, 122, 60, .5); }


/* ═══════════════════════════════════════════════════════════════
   A GRADE DA LISTA DE APARELHOS — pedido do dono em 03/09/2026:
   "queria que as coisas ficassem mais alinhadas, tem coisas que não tem coluna".

   O que havia era `flex` com `flex-wrap`: cada linha se arrumava sozinha, então um
   aparelho sem "app antigo", ou com "2 listas" em vez de "1 lista", empurrava tudo o
   que vinha depois. Nada casava com a linha de cima.

   🔴 AS LARGURAS SÃO FIXAS, E ISSO NÃO É PREGUIÇA. Cada aparelho é um <div> próprio,
   ou seja, uma grade própria. Coluna medida pelo conteúdo (`max-content`, `auto`) só
   alinha DENTRO da mesma grade — entre linhas independentes, continuaria dançando.
   Largura fixa é o que faz duas grades separadas caírem no mesmo lugar.

   ⚠️ E TODA CÉLULA OPCIONAL PRECISA EXISTIR VAZIA. Se "app antigo" não emitir nada
   quando o aparelho está em dia, a grade não pula a coluna: ela puxa a próxima para
   o lugar dela, e a linha inteira sai torta. Ver painel-master.js.

   ⚠️ Abaixo de 1120px a grade não cabe e vira o flex de antes, de propósito: alinhar
   é bom, cortar informação não é.
   ═══════════════════════════════════════════════════════════════ */
.grade-aparelho {
  display: grid;
  grid-template-columns:
    9.5rem            /* MAC — 17 caracteres monoespaçados */
    4.5rem            /* Android / PC */
    minmax(7rem, 1fr) /* modelo · sistema — o único que estica */
    5.5rem            /* situação */
    5rem              /* listas */
    3.5rem            /* versão */
    5.5rem            /* app antigo */
    7.5rem            /* licença */
    8.5rem            /* quem ativou */
    5.5rem;           /* visto há */
  align-items: center;
  justify-items: start;
  gap: .5rem;
}
/* Sem isto, uma célula com texto longo estoura a coluna em vez de cortar. */
.grade-aparelho > * { min-width: 0; max-width: 100%; }
.cel-corta { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
@media (max-width: 1120px) {
  .grade-aparelho { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
}

/* Uma linha da lista de itens da demonstracao (aba Aplicativos). Mesma ideia da
   .grade-aparelho: larguras fixas, porque cada linha e uma grade propria. */
.grade-item-demo {
  display: grid;
  grid-template-columns: 4.2rem 5rem minmax(8rem, 1fr) 5.5rem 5.5rem max-content max-content;
  align-items: center;
  justify-items: start;
  gap: .5rem;
  padding: .4rem 0;
  border-top: 1px solid var(--borda);
}
.grade-item-demo > * { min-width: 0; max-width: 100%; }
@media (max-width: 760px) {
  .grade-item-demo { display: flex; flex-wrap: wrap; }
}

/* Previa da capa no formulario de item da demonstracao (aba Aplicativos).
   Teto de altura para a janela nao crescer com pôster grande. */
.previa-capa { max-height: 150px; border-radius: 6px; }

/* ═══════════════════════════════════════════════════════════════
   JANELA COM MUITO CAMPO — o botão Salvar precisa continuar alcançável.

   O teto fica na JANELA e a rolagem no CORPO, não o contrário: o "×" de fechar é
   `absolute` na janela, e se a janela inteira rolasse ele sairia de vista junto com o
   conteúdo. Mesma lição da Regra 2 do aplicativo.
   ═══════════════════════════════════════════════════════════════ */
.janela-alta { max-height: 88vh; display: flex; flex-direction: column; }
/* `min-height: 0` não é enfeite: sem ele um filho de flex não encolhe abaixo do
   conteúdo, e a rolagem simplesmente não acontece. */
.janela-corpo { overflow-y: auto; min-height: 0; }

/* ═══════════════════════════════════════════════════════════════
   MINIATURA DA CAPA — ela espelha o que o APARELHO faz, e por isso muda com o tipo.

   Pôster de filme/série: o app usa ContentScale.Crop, então aqui é `cover` numa caixa 2:3.
   Logotipo de canal:     o app usa ContentScale.Fit sobre fundo branco, então aqui é
                          `contain`, com o mesmo fundo.

   🔴 Logotipo cortado não se reconhece. Com uma caixa única 2:3, um logotipo 5:4 perdia as
   laterais — o painel mostrava um enquadramento que o aparelho nunca faria.

   A caixa tem largura fixa (cabe o mais largo dos dois) e altura menor que a linha, para a
   miniatura não engordar a lista.
   ═══════════════════════════════════════════════════════════════ */
.mini-caixa {
  width: 4.2rem; height: 3.2rem;
  display: flex; align-items: center; justify-content: center;
}
.mini-poster {
  height: 100%; aspect-ratio: 2 / 3; object-fit: cover;
  border-radius: 4px; display: block;
}
.mini-logo {
  max-width: 100%; max-height: 100%; object-fit: contain;
  background: #fff; border-radius: 4px; padding: 2px; display: block;
}
.mini-vazia {
  height: 100%; aspect-ratio: 2 / 3; border-radius: 4px;
  background: rgba(255, 255, 255, .06); border: 1px dashed var(--borda);
}

/* 🌍 Seletor de língua (13/09/2026): UM menu suspenso <details class="idioma"> com bandeira — o mesmo
 * desenho do site. No gerenciador fica na linha do topo (abre para baixo); na revenda é fixo no canto
 * de baixo (.linguas-fixas, abre para CIMA). Bandeira = SVG em /img (emoji de bandeira não existe no
 * Windows). Pedido do dono: menu suspenso com bandeira, no lugar de um botão por língua. */
details.idioma { position: relative; display: inline-block; }
details.idioma summary {
  list-style: none; cursor: pointer; user-select: none;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 12px 6px 10px; border: 1px solid var(--divisoria, rgba(255,255,255,.1)); border-radius: 999px;
  background: rgba(255, 255, 255, .03); color: var(--texto-2, #c8c8c8); font-size: .86rem; line-height: 1.2; white-space: nowrap;
}
details.idioma summary::-webkit-details-marker { display: none; }
details.idioma summary::after { content: ""; width: 0; height: 0; margin-left: 2px; border-left: 4px solid transparent; border-right: 4px solid transparent; border-top: 5px solid currentColor; opacity: .7; }
details.idioma summary:hover, details.idioma[open] summary { color: #fff; border-color: var(--borda, rgba(255,23,23,.55)); }
details.idioma ul {
  list-style: none; margin: 0; padding: 6px;
  position: absolute; right: 0; top: calc(100% + 6px); min-width: 176px; z-index: 60;
  background: #161616; border: 1px solid var(--borda, rgba(255,23,23,.55)); border-radius: 12px;
  box-shadow: 0 12px 34px rgba(0, 0, 0, .6);
}
details.idioma li .op-lingua, details.idioma li .atual {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  padding: 8px 10px; border: 0; border-radius: 8px; background: none; color: #fff; font: inherit; font-size: .92rem; white-space: nowrap; cursor: pointer;
}
details.idioma li .op-lingua:hover { background: rgba(255, 23, 23, .12); }
details.idioma li .atual { color: #777; cursor: default; }
details.idioma li .atual::after { content: "\2713"; margin-left: auto; color: var(--vermelho, #FF1717); }   /* ✓ */
.bandeira { width: 20px; height: 14px; border-radius: 2px; flex: none; box-shadow: 0 0 0 1px rgba(255, 255, 255, .14); }
details.idioma .atual .bandeira { opacity: .7; }
/* revenda: fixo no canto, abre para cima */
.linguas-fixas { position: fixed; right: 14px; bottom: 14px; z-index: 50; }
.linguas-fixas details.idioma ul { top: auto; bottom: calc(100% + 6px); }
