/* As cores do painel, num lugar só.
   
   O nome de cada uma diz o PAPEL, não o tom: `--card` continua sendo o fundo do
   card depois de trocarmos o cinza por um azulado, e as mil linhas que a
   consomem não precisaram ser revisitadas. Trocar de tema é reescrever este
   bloco, e só ele.

   Não há tema claro, e isso é uma decisão, não uma pendência: o painel é lido o
   dia inteiro ao lado de uma transmissão, e o fundo escuro é o que não compete
   com ela. */
:root {
  /* As três profundidades do fundo. A régua é a distância do olho: `--bg` é o
     chão, `--panel` é a moldura (barra lateral, gavetas), `--card` é o que se
     lê. Um card precisa se destacar do chão SEM virar uma caixa branca. */
  --bg: #0d1117;
  --panel: #171a21;
  --card: #1e2129;
  --card-hover: #1b212b;
  /* O antigo nome de `--card`. Mantido porque metade do arquivo o usa, e
     renomear mil ocorrências para ganhar um sinônimo não paga o risco. */
  --panel-alt: #1e2129;
  --border: #2a2e38;
  /* A borda de quem está em foco ou selecionado. Separada de `--border` porque
     as duas mudam por motivos diferentes. */
  --border-strong: #2f3846;

  /* Três níveis de texto, e nenhum a mais. `--text` é o que se lê, `--text-dim`
     é o que acompanha (autor, horário, contagem), `--text-faint` é o que só
     precisa estar lá (rótulo de seção, placeholder). Um quarto nível vira
     decisão sem critério. */
  --text: #e6e8ec;
  --text-dim: #9aa1ac;
  --text-faint: #6b7280;
  /* Variante mais clara do faint, só pra texto muito pequeno (rótulo "ADMIN"
     na sidebar, status "2ºT · 38'" do card de partida) — contraste mínimo
     ainda legível nesse tamanho. Não confundir com `--text-faint`. */
  --text-faint-aa: #888888;

  /* O azul é o único acento de ação: chip ligado, botão primário, item de
     navegação aberto. Usá-lo em mais coisas o faz parar de significar algo. */
  --accent: #4f8cff;
  --accent-strong: #5f9bff;
  /* O azul TRANSLÚCIDO, para preencher sem virar botão: o item aberto da barra
     lateral e o card em destaque. Sendo `rgba`, ele funciona sobre qualquer um
     dos três fundos sem precisar de uma variante por profundidade. */
  --accent-soft: rgba(79, 140, 255, 0.16);
  --accent-dim: #2b3a5c;
  /* Texto sobre fundo cheio de `--accent` (botão primário, pílula ativa,
     marca do logo) — quase preto, não branco: mantém contraste alto sem
     estourar o brilho ao lado do resto da tela escura. */
  --accent-on: #0e0e0e;

  /* O botão secundário é CLARO sobre fundo escuro, e a inversão é de propósito:
     ele e o primário ficam empilhados e do mesmo tamanho nos modais, então a cor
     é a única coisa que os diferencia. Dois tons de azul ali seriam dois botões
     iguais. */
  --btn-alt-bg: #edeef1;
  --btn-alt-bg-hover: #ffffff;
  --btn-alt-text: #14171c;

  --danger: #ff6b6b;
  --warn: #f2b04a;
  --ok: #3ddc84;
  --hot: #ff8a3d;

  /* Três raios. `--radius` é o padrão (card, campo, botão), `--radius-sm` é o
     que é pequeno demais para o padrão não parecer inchado (chip, badge), e
     `--radius-pill` é a cápsula. */
  --radius-sm: 6px;
  --radius: 8px;
  --radius-lg: 14px;
  --radius-pill: 999px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  background: var(--bg);
  color: var(--text);
}

/* Barra de rolagem discreta, em toda a ferramenta — a nativa do Windows entra
   larga e clara demais e briga com o painel escuro (o mesmo tratamento usado no
   Tempo Real). O polegar é `--border`, com respiro de 2px feito por uma borda
   transparente recortada, e clareia no hover para dizer que é arrastável. */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--border);
  border-radius: var(--radius-pill);
  border: 2px solid transparent;
  background-clip: content-box;
  transition: background-color 0.15s ease;
}
::-webkit-scrollbar-thumb:hover {
  background: var(--text-faint);
  background-clip: content-box;
}
::-webkit-scrollbar-corner { background: transparent; }

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

.hidden { display: none !important; }

/* --- Ícones ----------------------------------------------------------------
   Todo SVG do painel nasce com 16px e `currentColor`. O tamanho vem daqui e não
   do atributo `width` do SVG porque o mesmo ícone é desenhado em quatro lugares
   com três tamanhos — mudar por CSS é mudar onde a decisão é tomada.

   `flex: 0 0 auto` porque quase todos vivem dentro de um flex ao lado de um
   texto que pode ser longo: sem isto o ícone é o primeiro a ser espremido, e um
   ícone de 11px de largura por 16 de altura é um borrão. */
.ico {
  width: 16px;
  height: 16px;
  flex: 0 0 auto;
  display: block;
}

/* Um ícone dentro de uma frase é `inline-block` e sobe 2px: `display: block`
   quebraria a linha, e sem o deslocamento ele senta na base do texto em vez de
   no meio dele — o coração das curtidas ficava um degrau abaixo do número. */
.post-likes .ico, .btn .ico, .peek-line .ico, .dim > .ico {
  display: inline-block;
  vertical-align: -3px;
  width: 14px;
  height: 14px;
}
.btn .ico { vertical-align: -3px; margin-right: 2px; }
.posted-check .ico { width: 13px; height: 13px; }
/* Os dois botões de fechar (gaveta e prévia) centram o X por flex — eles eram
   um caractere de texto, e um SVG dentro de uma caixa dimensionada para uma
   letra fica encostado no canto de cima. */
.drawer-close, .peek-close { display: flex; align-items: center; justify-content: center; }
.ms-caret .ico { width: 14px; height: 14px; }

/* --- Barra lateral -------------------------------------------------------- */
/*
   A navegação saiu do topo e foi para a lateral porque a tela principal virou um
   deck: numa fileira horizontal de abas, cada pixel gasto é uma coluna que não
   cabe. Na vertical sobra espaço, e a largura inteira fica para o conteúdo.
*/

.shell { display: flex; min-height: 100vh; }

/* A largura e a visibilidade dos rótulos saem de VARIÁVEIS, e as regras que as
   consomem são escritas uma vez só. Há dois gatilhos para o modo recolhido — a
   tela estreita e o botão — e sem as variáveis cada um precisaria repetir o
   mesmo bloco de declarações. Duas cópias do mesmo visual divergem: a correção
   feita numa não chega à outra, e o defeito só aparece num dos dois caminhos. */
.sidebar {
  position: sticky;
  top: 0;
  height: 100vh;
  flex: 0 0 var(--rail-w, 208px);
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 14px 10px;
  background: var(--panel);
  border-right: 1px solid var(--border);
  z-index: 20;
}

.sidebar .brand {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 0 0 10px 6px;
}
.brand-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px; height: 26px;
  border-radius: 8px;
  background: var(--accent);
  color: var(--accent-on);
  font-size: 0.6875rem;
  font-weight: 700;
  line-height: 14px;
  letter-spacing: 0.1px;
}
.brand-name {
  font-size: 0.875rem;
  font-weight: 600;
  line-height: 19px;
  letter-spacing: -0.1px;
}

.side-nav { display: flex; flex-direction: column; gap: 2px; }
.side-foot { margin-top: auto; display: flex; flex-direction: column; gap: 2px; }

/* Rótulo de seção: nomeia o grupo e não vai a lugar nenhum. Discreto de
   propósito — ele organiza a leitura, não compete com os itens. */
.side-section {
  padding: var(--rail-section-pad, 14px 0 4px 10px);
  font-size: 0.5625rem;
  font-weight: 600;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: var(--text-faint-aa);
}

.side-item {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  height: var(--rail-item-h, 32px);
  padding: var(--rail-item-pad, 0 10px);
  background: transparent;
  border: none;
  border-radius: var(--radius);
  color: var(--text-dim);
  font-size: 0.8125rem;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
}
.side-item:hover { background: var(--card-hover); color: var(--text); }

/* O item aberto é a cápsula `--accent-dim`, sólida — o Figma usa esse tom
   sólido pra dizer "onde a pessoa está", reservando o azul cheio do botão
   primário pra "faça isto". O ícone acompanha o texto (ambos `--text`) em vez
   de ficar azul: só o fundo precisa dizer que está aberto. */
.side-item.active { background: var(--accent-dim); color: var(--text); font-weight: 500; }

.side-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  flex: 0 0 auto;
}
.side-label {
  display: var(--rail-label, block);
  line-height: 18px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.brand-name { display: var(--rail-label, inline); }

.health-pill {
  font-size: 0.72rem;
  padding: 4px 10px;
  border-radius: 20px;
  border: 1px solid var(--border);
  color: var(--text-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.health-pill.ok { color: var(--ok); border-color: rgba(61, 220, 132, 0.35); }
.health-pill.warn { color: var(--warn); border-color: rgba(242, 176, 74, 0.35); }
.health-pill.bad { color: var(--danger); border-color: rgba(255, 107, 107, 0.4); }
.side-foot .health-pill { margin: 6px 4px; text-align: center; }

/* O modo recolhido: só os ícones. Ele NÃO vira menu escondido de propósito —
   trocar de tela é a ação mais frequente do painel, e um menu que precisa ser
   aberto antes cobra um clique por troca.

   Dois gatilhos, um visual. Telas estreitas recolhem sozinhas (sem depender de
   JS); no desktop quem decide é o botão, e a escolha fica no navegador. */
.rail-vars,
.shell.rail {
  --rail-w: 58px;
  --rail-label: none;
  --rail-pad: 12px 6px;
  --rail-item-just: center;
  /* 0 vertical: a altura de 32px do `.side-item` mais `align-items: center`
     já centralizam o ícone sozinhos — padding vertical aqui só sobraria o
     conteúdo pra fora da caixa (o arquivo usa `box-sizing: border-box`). */
  --rail-item-pad: 0 4px;
  --rail-brand-just: flex-start;
  --rail-brand-pad: 0 0 10px 6px;
  --rail-section-size: 0;
  --rail-section-pad: 8px 6px 2px;
  --rail-section-border: 1px solid var(--border);
}

.sidebar { padding: var(--rail-pad, 14px 10px); }
.side-item { justify-content: var(--rail-item-just, flex-start); }
/* Um `.rail-vars` solto não existe no HTML: ele está no seletor acima só para o
   bloco de variáveis ter um nome próprio e o `.shell.rail` não parecer o único
   dono delas. */
.sidebar .brand {
  justify-content: var(--rail-brand-just, flex-start);
  padding: var(--rail-brand-pad, 0 0 10px 6px);
}
/* Sem espaço para o nome da seção, ela vira o que sempre foi por baixo: uma
   separação. */
.side-section {
  font-size: var(--rail-section-size, 0.5625rem);
  border-top: var(--rail-section-border, none);
}

@media (max-width: 900px) {
  .shell {
    --rail-w: 58px;
    --rail-label: none;
    --rail-pad: 12px 6px;
    --rail-item-just: center;
    --rail-item-pad: 0 4px;
    --rail-brand-just: flex-start;
    --rail-brand-pad: 0 0 10px 6px;
    --rail-section-size: 0;
    --rail-section-pad: 8px 6px 2px;
    --rail-section-border: 1px solid var(--border);
  }
  /* O botão some: nesta largura a barra já está recolhida e não há para onde
     expandir. Um botão que não muda nada é pior que botão nenhum. */
  #side-rail { display: none; }
}

/* O botão de recolher. No rodapé, junto de Sair: ele é ajuste da moldura, não
   navegação, e no topo competiria com o item mais clicado da tela. */
#side-rail { opacity: 0.65; }
#side-rail:hover { opacity: 1; }

/* --- Layout -------------------------------------------------------------- */

/* A coluna de conteúdo: a barra do Admin em cima, a tela embaixo. `min-width: 0`
   porque o deck rola na horizontal — sem ele, a largura do conteúdo empurra a
   coluna e a barra lateral é espremida para fora da tela. */
.content { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.app { flex: 1; min-width: 0; padding: 16px; }
/* As telas de operação continuam sendo leitura corrida, e texto largo demais é
   ruim de ler: elas mantêm a coluna centrada. O deck é a exceção, e ocupa tudo. */
.app > .panel, .app > .article-list, .app > .list-header, .app > section:not(.deck),
.app > details { max-width: 1180px; margin-left: auto; margin-right: auto; }

.panel {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 16px;
  margin-bottom: 14px;
}

.panel-title { margin: 0 0 4px; font-size: 1rem; }
.panel-note { margin: 0 0 10px; color: var(--text-dim); font-size: 0.82rem; line-height: 1.5; }
.panel-note.foot { margin: 12px 0 0; color: var(--text-faint); }

.state-msg { color: var(--text-dim); padding: 20px; text-align: center; }
.state-msg.error { color: var(--danger); }
.dim { color: var(--text-dim); }

/* --- Filtros ------------------------------------------------------------- */

.filters-panel { padding: 14px 16px; }

.filters-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: flex-end;
}
.filters-row + .filters-row { margin-top: 12px; }
/* Título e chips na mesma linha (o ranking de horas faz isso): sem zerar a
   margem do título, o `align-items: flex-end` da fileira deixa os chips 4px
   abaixo dele, e a linha inteira parece desalinhada por acidente. */
.filters-row .panel-title { margin-bottom: 0; }

.field { display: flex; flex-direction: column; gap: 5px; }
.field.grow { flex: 1; min-width: 260px; }
.field label { font-size: 0.75rem; line-height: 15px; color: var(--text-dim); text-transform: none; letter-spacing: 0.1px; }
.hint-inline { color: var(--text-faint); font-size: 0.68rem; }

.field.checkbox { flex-direction: row; align-items: center; gap: 7px; }
.field.checkbox label { font-size: 0.82rem; color: var(--text); }

/* `email` e `password` entraram junto com a tela de login. Sem eles, os campos
   herdavam o input branco do navegador — legível, mas gritando num painel
   escuro, e denunciando que aquela tela não era parte do produto. */
input[type="text"], input[type="search"], input[type="number"],
input[type="email"], input[type="password"], input[type="date"],
select, textarea {
  background: var(--panel-alt);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 10px 13px;
  border-radius: var(--radius);
  font-size: 0.8125rem;
  line-height: 17px;
  min-width: 150px;
  font-family: inherit;
}
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--accent); }
textarea { width: 100%; resize: vertical; line-height: 1.5; }
/* O seletor nativo de data vem com o ícone preto do navegador, invisível
   sobre o painel escuro — o campo parecia não ter calendário nenhum. */
input[type="date"]::-webkit-calendar-picker-indicator { filter: invert(0.7); cursor: pointer; }
select[multiple] { min-height: 38px; max-height: 38px; overflow-y: auto; }
select[multiple]:focus { max-height: 160px; }

.chips { display: flex; gap: 6px; }
.chip {
  background: var(--panel-alt);
  border: 1px solid var(--border);
  color: var(--text-dim);
  border-radius: var(--radius);
  padding: 8px 13px;
  font-size: 0.8125rem;
  line-height: 17px;
  cursor: pointer;
}
.chip:hover { color: var(--text); }
/* Pílula "Toggle / seleção" do Figma, ativa: azul cheio (não o `--accent-dim`
   escuro) com texto quase-preto — o mesmo par que o botão primário usa. */
.chip.on { background: var(--accent); color: var(--accent-on); border-color: var(--accent); font-weight: 500; }

/* "Botão / ação" do Figma: 14px semibold, canto 8, respiro 13/18 — e texto
   quase-preto nos cheios, o mesmo par do chip ativo. */
.btn {
  background: var(--panel-alt);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 13px 18px;
  border-radius: var(--radius);
  cursor: pointer;
  font-size: 0.875rem;
  line-height: 18px;
}
.btn:hover { border-color: var(--accent); }
.btn-primary { background: var(--accent); border-color: var(--accent); color: var(--accent-on); }
.btn-primary:hover { filter: brightness(1.1); }
.btn-ghost { background: transparent; color: var(--text-dim); }

/* O secundário é CLARO sobre fundo escuro, e a inversão é deliberada.

   Ele e o primário aparecem empilhados e do mesmo tamanho nos modais de prévia
   ("Ver o post" em cima de "Vou postar"), então a COR é a única coisa que
   distingue os dois. Um cinza-escuro ao lado de um azul-escuro são dois botões
   de peso parecido, e quem só passa os olhos clica no de cima. */
.btn-alt {
  background: var(--text);
  border-color: var(--text);
  color: var(--accent-on);
  font-weight: 600;
}
.btn-alt:hover { background: var(--btn-alt-bg-hover); border-color: var(--btn-alt-bg-hover); }
.btn-primary { font-weight: 600; }

/* --- Cabeçalho da lista -------------------------------------------------- */

.list-header {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 0 4px 10px;
  flex-wrap: wrap;
}
.list-title { font-weight: 600; font-size: 0.95rem; }
.list-note { color: var(--text-faint); font-size: 0.78rem; flex: 1; }
.list-refresh { color: var(--text-faint); font-size: 0.74rem; }

/* --- Cards de notícia ---------------------------------------------------- */

.article-list { display: flex; flex-direction: column; gap: 10px; }

.article {
  display: flex;
  gap: 14px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px;
  overflow: hidden;
}

/* Caixa de proporção fixa: a imagem pode falhar, o card não muda de tamanho. */
.thumb-wrap {
  flex: 0 0 160px;
  width: 160px;
  height: 100px;
  border-radius: 8px;
  overflow: hidden;
  background: var(--panel-alt);
}
.article img.thumb { width: 100%; height: 100%; object-fit: cover; display: block; }

/* `gap` e não margem nos filhos: o Figma espaça o corpo do card com um gap
   único de 5px, e margens por elemento davam 5px aqui, 7px ali. */
.article-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 5px; }

.article-top {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 5px;
}

.stars { letter-spacing: 1px; font-size: 0.85rem; color: var(--text-faint); }
.stars.s3 { color: var(--warn); }
.stars.s4, .stars.s5 { color: var(--hot); }

.heat-reason { color: var(--text-dim); font-size: 0.76rem; }

.article-title { margin: 0; font-size: 0.875rem; line-height: 19px; font-weight: 600; overflow-wrap: anywhere; }
.article-title a { color: var(--text); }
.article-title a:hover { color: var(--accent); }

.article-summary {
  margin: 0;
  color: var(--text-dim);
  font-size: 0.6875rem;
  line-height: 15px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  overflow-wrap: anywhere;
}

.cluster-line {
  background: none;
  border: none;
  padding: 0 0 6px;
  color: var(--accent);
  font-size: 0.78rem;
  cursor: pointer;
  font-family: inherit;
}
.cluster-line:hover { text-decoration: underline; }

.article-meta {
  display: flex;
  align-items: center;
  gap: 7px;
  flex-wrap: wrap;
  font-size: 0.625rem;
  color: var(--text-faint);
}
.article-meta .publisher { color: var(--text); }
.article-meta .sep { color: var(--text-faint); }
.article-meta .spacer { flex: 1; }

/* Nasce escondida: só o card compacto (densidade lista) mostra esta linha. */
.article-clube { display: none; align-items: center; gap: 4px; }
.article-clube-nome { font-size: 0.625rem; color: var(--text-dim); }
.article-lang {
  background: var(--border);
  border-radius: 4px;
  padding: 1px 4px;
  font-size: 0.5rem;
  font-weight: 500;
  color: var(--text-dim);
}

.date-unknown { color: var(--warn); }
.date-unknown em { font-style: normal; opacity: 0.8; font-size: 0.72rem; }

/* "Chip / etiqueta" do Figma — a etiqueta canônica do sistema: cápsula de
   canto 6px sobre `--panel-alt`, não a pílula redonda transparente de antes. */
.badge {
  display: inline-block;
  padding: 2px 7px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  font-size: 0.625rem;
  line-height: 14px;
  letter-spacing: 0.15px;
  color: var(--text-dim);
  background: var(--panel-alt);
  font-family: inherit;
}
button.badge { cursor: pointer; }
button.badge:hover { border-color: var(--accent); color: var(--text); }

/* O clube que é o assunto se destaca; o citado fica discreto. Substituiu a
   fileira de porcentagens, que dava a todos os clubes o mesmo peso visual. */
.badge.team.primary { color: var(--accent); border-color: var(--accent-dim); font-weight: 600; }
.badge.team.mention { color: var(--text-faint); border-color: var(--border); }
.badge.more { color: var(--text-faint); border-style: dashed; }
.badge.dup { color: var(--danger); border-color: rgba(255, 107, 107, 0.4); }
/* A etiqueta de categoria é NEUTRA: no Figma toda "Chip / etiqueta" usa o
   mesmo par (`--panel-alt` + `--text-dim`), sem cor por tipo. */
/* Collab: nota discreta, não alerta — o post é legítimo do perfil, só foi
   publicado pela outra conta. Some no modo compacto junto com a categoria. */
.badge.collab { color: var(--text-faint); border-style: dashed; max-width: 14ch;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.badge.first { color: var(--ok); border-color: rgba(61, 220, 132, 0.4); margin-right: 6px; }

/* Tradução automática: informação, não alerta. O card em português é o estado
   normal do painel — o selo existe para quem precisa saber que aquele texto
   passou por um modelo antes de citá-lo, e para dizer de qual idioma veio. */
.badge.traduzido {
  color: var(--accent);
  border-color: var(--accent-dim);
  border-style: dashed;
}

/* "ver original": discreto de propósito. Ele é um gesto de conferência, feito
   por quem já leu a tradução e quer checar a manchete — não uma escolha que se
   apresenta antes da leitura. Fica abaixo do texto, no fluxo, e não flutuando
   sobre o card, para não competir com o link da notícia. */
.ver-original {
  margin-top: 6px;
  font-size: 0.72rem;
  color: var(--text-faint);
  text-decoration: none;
  border-bottom: 1px dotted var(--border);
}
.ver-original:hover { color: var(--accent); border-bottom-color: var(--accent-dim); }
/* Aberto, ele deixa de ser um convite e passa a ser um estado — e o card está
   mostrando texto que NÃO é o que o resto do painel mostra. Precisa saltar. */
.ver-original.on { color: var(--accent); border-bottom-style: solid; }

/* No modo compacto o card já corta a legenda; um selo e um botão a mais não
   caberiam sem empurrar o texto para fora. O texto continua traduzido — só os
   controles somem, como já acontece com a categoria e o collab. */
/* Segundo bloco dentro da aba Sistema: a tradução tem modelo próprio, e sem um
   título ela pareceria continuação da lista da classificação. */
.settings-subtitle {
  margin: 22px 0 6px;
  font-size: 0.85rem;
  color: var(--text-dim);
  font-weight: 600;
}

.load-more { display: flex; justify-content: center; padding: 16px 0; }

/* --- Times --------------------------------------------------------------- */

.team-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 10px;
}

.team-card {
  text-align: left;
  background: var(--panel-alt);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px;
  cursor: pointer;
  color: var(--text);
  font-family: inherit;
}
.team-card:hover { border-color: var(--accent); }

.team-card-head { display: flex; justify-content: space-between; align-items: baseline; }
.team-uf { color: var(--text-faint); font-size: 0.72rem; }
.team-numbers { display: flex; align-items: baseline; gap: 6px; margin: 8px 0 6px; }
.team-numbers .big { font-size: 1.6rem; font-weight: 700; line-height: 1; }
.team-unit { color: var(--text-dim); font-size: 0.72rem; }
.team-bar { height: 4px; background: var(--border); border-radius: 3px; overflow: hidden; }
.team-bar i { display: block; height: 100%; background: var(--accent); }
.team-foot { color: var(--text-faint); font-size: 0.72rem; margin-top: 7px; }

/* --- Gaveta lateral ------------------------------------------------------ */

.drawer {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  z-index: 40;
  display: flex;
  justify-content: flex-end;
}

.drawer-panel {
  width: min(520px, 100%);
  background: var(--panel);
  border-left: 1px solid var(--border);
  padding: 20px 24px;
  box-shadow: -10px 0 34px rgba(0, 0, 0, 0.45);
  overflow-y: auto;
  position: relative;
}

/* Só o ícone, sem moldura de botão — é como o Figma desenha "fechar" na
   gaveta (um "x" solto na linha do título, não uma caixa no canto). */
.drawer-close {
  position: absolute;
  top: 20px; right: 24px;
  background: transparent;
  border: none;
  color: var(--text-dim);
  width: 21px; height: 21px;
  padding: 0;
  cursor: pointer;
}
.drawer-close:hover { color: var(--text); }

.drawer-title { margin: 0 0 4px; padding-right: 28px; font-size: 1.375rem; font-weight: 600; line-height: 28px; letter-spacing: -0.4px; }
.drawer-sub { margin: 0 0 16px; color: var(--text-dim); font-size: 0.8125rem; line-height: 18px; }
.drawer-h3 { margin: 20px 0 8px; font-size: 0.86rem; color: var(--text-dim); font-weight: 600; }
.drawer-cta { margin-top: 22px; width: 100%; }

.stat-row { display: flex; gap: 8px; flex-wrap: wrap; }
.mini-stat {
  flex: 1;
  min-width: 90px;
  background: var(--panel-alt);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px;
  text-align: center;
}
.mini-stat b { display: block; font-size: 1.3rem; }
.mini-stat span { color: var(--text-dim); font-size: 0.7rem; }

.drawer-list { list-style: none; margin: 0; padding: 0; }
.drawer-list li {
  padding: 8px 0;
  border-bottom: 1px solid var(--border);
  font-size: 0.86rem;
  line-height: 1.45;
}
.drawer-list li:last-child { border-bottom: none; }
.drawer-list li .dim { display: block; font-size: 0.74rem; margin-top: 2px; }
.drawer-list.compact li { display: flex; justify-content: space-between; padding: 6px 0; }

/* --- Sparkline ----------------------------------------------------------- */

.spark {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 60px;
  background: var(--panel-alt);
  border-radius: 8px;
  padding: 6px;
}
.spark.tall { height: 110px; }
.spark i { flex: 1; background: var(--accent-dim); border-radius: 2px 2px 0 0; min-height: 3px; }
.spark i.has-hot { background: var(--hot); }
.spark i:hover { background: var(--accent); }

/* --- Saúde --------------------------------------------------------------- */

.health-panel.ok { border-color: rgba(61, 220, 132, 0.28); }
.health-panel.warn { border-color: rgba(242, 176, 74, 0.32); }
.health-panel.bad { border-color: rgba(255, 107, 107, 0.4); }

.health-head { display: flex; gap: 12px; align-items: flex-start; }
.health-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: 8px;
  margin-top: 12px;
}
.health-grid div {
  background: var(--panel-alt);
  border-radius: 8px;
  padding: 10px;
  text-align: center;
}
.health-grid b { display: block; font-size: 1.25rem; }
.health-grid span { color: var(--text-dim); font-size: 0.72rem; }

/* --- Tabelas ------------------------------------------------------------- */

table.data { width: 100%; border-collapse: collapse; font-size: 0.84rem; }
table.data th {
  text-align: left;
  color: var(--text-dim);
  font-weight: 500;
  padding: 8px 10px;
  border-bottom: 1px solid var(--border);
  font-size: 0.76rem;
}
table.data td { padding: 9px 10px; border-bottom: 1px solid var(--border); vertical-align: top; }
table.data tr:last-child td { border-bottom: none; }
table.data tr.covered { opacity: 0.62; }

.slug { color: var(--text-faint); font-size: 0.74rem; }
.err-detail { color: var(--danger); font-size: 0.72rem; }

/* Nota informativa numa linha de execução: cinza, nunca vermelho. Contas de fora
   (patrocinador, liga, conta-irmã do clube, que chegam por coautoria) não pedem
   ação nenhuma — pintá-las como erro fez a primeira rodada real parecer um
   incidente com 84 handles em vermelho, sendo que 77 eram rotina. */
.run-note { color: var(--text-faint); font-size: 0.72rem; }
.covered-tag { color: var(--text-faint); font-size: 0.72rem; }

/* Fonte desligada à mão. Mesmo esmaecido de `covered` — as duas dizem "nada a
   fazer aqui" —, mas sem a tarja de "coberta por outra fonte", que seria uma
   afirmação falsa: ninguém está cobrindo o buraco de uma fonte que alguém
   desligou de propósito. */
table.data tr.source-off { opacity: 0.62; }

/* A fileira de botões da coluna Ações não pode quebrar linha: com "Desligar" e
   "Editar" empilhados, cada linha da tabela ganha altura dupla e a lista de
   duzentas fontes deixa de caber na tela. */
.source-actions { white-space: nowrap; }
.source-actions .btn { margin-right: 4px; }

/* A linha de edição ocupa a largura inteira da tabela, então ela não herda o
   alinhamento das células — o fundo levemente destacado é o que mostra a qual
   linha ela pertence. */
.source-edit-row > td { background: var(--panel-alt); }

/* Lista de feeds que a sondagem descobriu, ou amostra do que entraria. Fonte
   monoespaçada nas URLs porque elas são para COPIAR, e um caractere trocado
   numa URL de feed é meia hora de diagnóstico. */
.probe-found {
  margin: 6px 0 0;
  padding-left: 18px;
  color: var(--text-dim);
  font-size: 0.78rem;
}
.probe-found code { font-size: 0.76rem; word-break: break-all; }

/* Empurra o botão de gerência para a direita da fileira de filtros. */
.filters-row .spacer { flex: 1; }

.dot {
  display: inline-block;
  width: 9px; height: 9px;
  border-radius: 50%;
  background: var(--text-faint);
}
.dot.big { width: 13px; height: 13px; margin-top: 5px; flex: 0 0 auto; }
.dot.ok { background: var(--ok); }
.dot.warn { background: var(--warn); }
.dot.bad { background: var(--danger); }
/* Cinza, e não amarelo: fonte sem feed dedicado é estado permanente e correto.
   Amarelo pede atenção, e atenção gasta em algo que não tem conserto é atenção
   que falta quando um feed de verdade quebrar. */
.dot.muted { background: var(--text-faint); }

/* --- Modal --------------------------------------------------------------- */

.modal {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.6);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 50;
  padding: 16px;
}

.modal-box {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 22px;
  width: min(480px, 100%);
}
.modal-box h2 { margin: 0 0 8px; font-size: 1.1rem; }
.modal-box label { display: block; margin-bottom: 14px; font-size: 0.82rem; color: var(--text-dim); }
.modal-box input { width: 100%; margin-top: 5px; }
.modal-actions { display: flex; gap: 8px; justify-content: flex-end; }

.hint { color: var(--text-dim); font-size: 0.8rem; line-height: 1.5; margin: 0 0 16px; }
.error { color: var(--danger); font-size: 0.82rem; margin: 12px 0 0; }
code {
  background: var(--panel-alt);
  padding: 1px 5px;
  border-radius: 4px;
  font-size: 0.85em;
}

/* --- Responsivo ---------------------------------------------------------- */

@media (max-width: 760px) {
  .topbar-inner { flex-wrap: wrap; }
  .tabs { order: 3; width: 100%; overflow-x: auto; }
  .article { flex-direction: column; }
  .thumb-wrap { flex: none; width: 100%; height: 160px; }
  .field.grow { min-width: 100%; }
  .drawer-panel { width: 100%; }
}

/* --- O formulário da coluna, dentro da gaveta ------------------------------
   Onze campos empilhados num painel de 520px. O que os separa não é enfeite: o
   rótulo de um campo e a dica do campo anterior ficavam a 5px um do outro, e a
   leitura de cima para baixo virava um bloco só de texto cinza onde não se
   enxergava onde um campo terminava e o outro começava.

   As larguras vão a 100% pelo mesmo motivo do desenho: um `<select>` de 165px
   ao lado de um campo de texto que ocupa a gaveta inteira parece um controle
   desabilitado, não um controle estreito. */
#drawer-body .field { margin-bottom: 15px; }
#drawer-body .field .hint-inline { margin-top: 1px; }
#drawer-body .multiselect,
#drawer-body .ms-toggle,
#drawer-body select,
#drawer-body input[type="text"],
#drawer-body input[type="search"] { width: 100%; }

/* O botão fica numa linha só dele, da largura da gaveta. "Remover" e a
   confirmação continuam na linha de cima — a ação destrutiva e a principal não
   podem ficar do mesmo tamanho lado a lado. */
#drawer-body .imp-form-actions { flex-wrap: wrap; margin-top: 20px; }
#drawer-body #col-save { flex: 1 1 100%; }

/* --- Multi-seleção com checkboxes ---------------------------------------- */
/* Substitui o `<select multiple>` nativo, que exige ctrl/cmd para somar itens
   e zera a seleção inteira num clique desatento. */

.multiselect { position: relative; }

.ms-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-width: 165px;
  background: var(--panel-alt);
  border: 1px solid var(--border);
  color: var(--text-dim);
  padding: 8px 10px;
  border-radius: 8px;
  font-size: 0.88rem;
  font-family: inherit;
  cursor: pointer;
}
.ms-toggle:hover { border-color: var(--accent); }
.ms-toggle.on { color: var(--text); border-color: var(--accent-dim); background: rgba(79, 140, 255, 0.08); }
.ms-summary { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ms-caret { color: var(--text-faint); font-size: 0.7rem; }

.ms-panel {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  z-index: 30;
  width: 250px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.5);
  overflow: hidden;
}

.ms-tools { display: flex; gap: 6px; padding: 8px; border-bottom: 1px solid var(--border); }
.ms-search { flex: 1; min-width: 0; padding: 6px 8px; font-size: 0.82rem; }
.ms-clear {
  background: none;
  border: none;
  color: var(--text-faint);
  font-size: 0.76rem;
  cursor: pointer;
  padding: 0 4px;
  font-family: inherit;
}
.ms-clear:hover { color: var(--danger); }

.ms-options { max-height: 260px; overflow-y: auto; padding: 4px; }

.ms-option {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 0.85rem;
}
.ms-option:hover { background: var(--panel-alt); }
.ms-option input { margin: 0; cursor: pointer; accent-color: var(--accent); }
.ms-label { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ms-empty { color: var(--text-faint); font-size: 0.8rem; padding: 10px; margin: 0; }

/* --- Aviso de versão ----------------------------------------------------- */

.warn-box {
  border-color: rgba(242, 176, 74, 0.4);
  text-align: left;
  color: var(--text);
}
.warn-box strong { color: var(--warn); display: block; margin-bottom: 8px; }
.warn-box p { margin: 0 0 8px; font-size: 0.86rem; line-height: 1.55; color: var(--text-dim); }

/* --- Login ---------------------------------------------------------------- */

/* `position: fixed` cobrindo tudo, e não um modal: enquanto não há sessão, o
   conteúdo atrás não deve nem ser alcançável por tabulação ou rolagem. */
.login-screen {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg, #0f1115);
  padding: 24px;
}

body.locked { overflow: hidden; }

.login-box {
  width: 100%;
  max-width: 380px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 32px;
  border: 1px solid var(--border, #262b36);
  border-radius: 12px;
  background: var(--panel, #161a22);
}

.login-box h1 { margin: 0; font-size: 24px; }
.login-box .hint { margin: 0 0 4px; }
.login-box label { display: flex; flex-direction: column; gap: 6px; font-size: 13px; }

.btn-block { width: 100%; }

.link-btn {
  background: none;
  border: 0;
  padding: 0;
  color: var(--muted, #8b93a7);
  font-size: 12px;
  text-decoration: underline;
  cursor: pointer;
}
.link-btn:hover { color: var(--text, #e6e9ef); }

/* --- Configurações: abas -------------------------------------------------- */

/* `width`, e não `max-width`: o .modal-box já fixa `width: min(480px, 100%)`, e
   um max-width maior nunca venceria uma largura já declarada — o painel de
   usuários ficava espremido em 480px com a grade colapsada numa coluna só.
   O `max-height` + rolagem existe porque a lista cresce com o time: sem ele o
   formulário some para fora da tela assim que houver alguns usuários. */
.modal-box-wide {
  width: min(760px, 100%);
  max-height: 88vh;
  overflow-y: auto;
}

.settings-tabs {
  display: flex;
  gap: 4px;
  margin-bottom: 18px;
  border-bottom: 1px solid var(--border, #262b36);
}

.settings-tab {
  background: none;
  border: 0;
  border-bottom: 2px solid transparent;
  padding: 8px 14px;
  color: var(--muted, #8b93a7);
  font-size: 14px;
  cursor: pointer;
}
.settings-tab.active {
  color: var(--text, #e6e9ef);
  border-bottom-color: var(--accent, #4f8cff);
}

.settings-pane { display: flex; flex-direction: column; gap: 12px; }
.settings-pane > .user-form label { margin-bottom: 0; }

/* --- Usuários ------------------------------------------------------------- */

.user-form {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 16px;
  border: 1px solid var(--border, #262b36);
  border-radius: 8px;
}

.user-form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px;
}
.user-form-grid label { display: flex; flex-direction: column; gap: 6px; font-size: 13px; }

.checkbox-label {
  flex-direction: row !important;
  align-items: center;
  gap: 8px !important;
  align-self: center;
}
/* O .modal-box força `width: 100%` em todo input; num checkbox isso vira uma
   caixa esticada com o rótulo fugindo para o lado. */
.checkbox-label input[type="checkbox"] {
  width: auto;
  margin: 0;
  flex: 0 0 auto;
}

.users-list { display: flex; flex-direction: column; gap: 8px; max-height: 320px; overflow-y: auto; }

.user-row {
  display: grid;
  /* `minmax(0, 1fr)` e não `1fr`: em grid, `1fr` é `minmax(auto, 1fr)`, e o
     mínimo `auto` se recusa a encolher abaixo do conteúdo. Um e-mail longo
     empurrava a coluna e passava por cima dos botões. */
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border: 1px solid var(--border, #262b36);
  border-radius: 8px;
}
.user-row strong,
.user-mail {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Conta desativada continua legível — apenas recuada. Escondê-la faria o admin
   recriar um acesso que já existe e esbarrar num 409 sem entender. */
.user-inactive { opacity: 0.55; }

.user-id { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.user-mail { font-size: 12px; color: var(--muted, #8b93a7); }
.user-tags { display: flex; gap: 6px; margin-top: 2px; }
.user-meta { font-size: 12px; color: var(--muted, #8b93a7); white-space: nowrap; }
.user-actions { display: flex; gap: 6px; }

.btn-sm { padding: 4px 10px; font-size: 12px; }
.btn-danger:hover { border-color: #b4444f; color: #ff8b96; }

.tag {
  font-size: 11px;
  padding: 1px 7px;
  border-radius: 999px;
  border: 1px solid var(--border, #262b36);
}
.tag-admin { border-color: #3c5a99; color: #8fb2ff; }
.tag-off { border-color: #6b4a1f; color: #e0a760; }
/* Os universos A MAIS de um perfil. Discreta de propósito: ela explica por que
   o mesmo @ aparece em dois blocos da grade, e não é o assunto da linha. */
.tag-universe { border-color: #33415c; color: #93a4c8; }

@media (max-width: 620px) {
  .user-row { grid-template-columns: 1fr; }
  .user-actions { justify-content: flex-start; }
}

/* --- Instagram: posts ---------------------------------------------------- */

.post-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
  gap: 12px;
}

.post {
  display: flex;
  flex-direction: column;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}

/* Proporção fixa: a imagem do CDN expira com frequência, e sem a caixa
   reservada o card encolheria ao trocar pelo placeholder — a grade inteira
   pularia embaixo de quem está lendo.

   4:5 e não 16:9: quem publica no Instagram e no X publica em retrato, e a
   caixa larga cortava a foto em cima e embaixo — o card ficava com MENOS foto
   do que antes, que era o oposto do que se queria. 4:5 é o formato em que o
   material chega. */
.post-media {
  position: relative;
  display: block;
  aspect-ratio: 313 / 150;
  background: var(--panel-alt);
  /* Sem isto a proporção não vale nada. O card é um flex column, e o mínimo
     automático de um item flex é o tamanho do CONTEÚDO — uma foto em retrato
     empurrava a caixa para a altura intrínseca dela e o card crescia, foto a
     foto, com uma altura diferente cada. Era por aqui que a grade pulava. */
  min-height: 0;
}
.post-media img { width: 100%; height: 100%; object-fit: cover; display: block; }

.post-play {
  position: absolute;
  right: 8px;
  bottom: 8px;
  background: rgba(0, 0, 0, 0.6);
  color: #fff;
  border-radius: 50%;
  width: 26px;
  height: 26px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.7rem;
}

.post-body { padding: 8px 9px 9px; display: flex; flex-direction: column; gap: 3px; }

/* O cabeçalho numa linha: @perfil, estrelas, idioma. Antes eram DUAS linhas
   (perfil numa, estrelas e motivo noutra) e elas comiam a altura que agora é da
   foto. `nowrap` porque quebrar essa linha desfaria a economia inteira. */
.post-head {
  display: flex;
  align-items: center;
  gap: 5px;
  flex-wrap: nowrap;
  overflow: hidden;
}
.post-head .post-profile { flex: 0 1 auto; min-width: 0; padding: 0; }
.post-head .post-handle { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.post-stars { flex: 0 0 auto; font-size: 0.72rem; letter-spacing: -0.5px; }
.post-head .lang-chip { flex: 0 0 auto; margin-left: auto; }

/* A faixa do ✓. O botão é absoluto no canto superior direito do CARD, e onde a
   foto fica ao LADO do texto — a lista principal e a densidade "lista" do deck
   — esse canto pertence à primeira linha do corpo: o chip de idioma, que é
   empurrado para a direita, ia parar embaixo do botão.

   Reserva-se a faixa em vez de mover o ✓: ele tem que cair no mesmo ponto nos
   três layouts, senão quem varre o feed marcando posts precisa procurar o botão
   a cada card. */
.article-list .article > .article-body > .article-meta,
.col-body.dens-lista .post-head { padding-right: 28px; }

/* Uma linha, e o resto no `title`. A legenda de um post é quase sempre longa
   demais para caber e curta demais para valer três linhas de card — quem quer
   ler abre o post, que é o que o card inteiro convida a fazer. */
.post-caption {
  margin: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 0.6875rem;
  color: var(--text-dim);
}

/* Por que este post está aqui — "4,8× o normal do perfil para 15 min".

   Fica ABAIXO da legenda e não no cabeçalho: a legenda é do perfil, isto é
   nosso, e misturar as duas coisas na mesma linha faria o número parecer parte
   do que a conta escreveu. Cabe uma linha, com o texto inteiro no `title`
   quando não couber — ele já vem cortado em três partes por `postReason`.

   Discreto, e no mesmo tom do `.heat-reason` do card de notícia: os dois dizem
   a mesma coisa ("por que este item está em alta") e ler um deve ensinar a ler
   o outro. Sem destaque de cor porque o valor varia — pintar 4,8× e 0,3× do
   mesmo jeito seria ênfase falsa em metade dos cards. */
.post-reason {
  margin: 0;
  font-size: 0.625rem;
  line-height: 1.3;
  color: var(--text-faint);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.post-profile {
  display: flex;
  align-items: center;
  gap: 6px;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  color: var(--text);
  font-family: inherit;
  text-align: left;
}
.post-profile:hover .post-handle { color: var(--accent); }
.post-avatar { width: 18px; height: 18px; border-radius: 50%; flex: none; display: block; }
.post-handle { font-size: 0.6875rem; font-weight: 500; }

.post-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.625rem;
  color: var(--text-faint);
  margin-top: auto;
}
.post-likes { color: var(--text-dim); font-weight: 600; }
.post-open { color: var(--text-faint); }
.post-open:hover { color: var(--accent); }

/* --- Instagram: perfis --------------------------------------------------- */

.panel-count {
  font-size: 0.75rem;
  color: var(--text-faint);
  font-weight: 400;
  margin-left: 6px;
}

.profile-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(215px, 1fr));
  gap: 8px;
}

.profile-card {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-areas:
    "avatar id"
    "avatar numbers"
    "foot foot";
  align-items: center;
  gap: 2px 10px;
  text-align: left;
  background: var(--panel-alt);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 10px;
  cursor: pointer;
  color: var(--text);
  font-family: inherit;
}
.profile-card:hover { border-color: var(--accent); }

.profile-avatar {
  grid-area: avatar;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.8rem;
  font-weight: 700;
}

.profile-id { grid-area: id; display: flex; flex-direction: column; min-width: 0; }
.profile-id strong {
  font-size: 0.85rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.profile-handle { color: var(--text-faint); font-size: 0.72rem; }

.profile-numbers { grid-area: numbers; display: flex; align-items: baseline; gap: 5px; }
.profile-numbers b { font-size: 0.95rem; }
.profile-numbers span { color: var(--text-faint); font-size: 0.7rem; }

.profile-foot {
  grid-area: foot;
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 8px;
  padding-top: 7px;
  border-top: 1px solid var(--border);
  font-size: 0.72rem;
}

/* --- Instagram: coleta --------------------------------------------------- */

.collect-actions { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0 4px; }
.collect-actions button:disabled { opacity: 0.45; cursor: not-allowed; }

.collect-msg {
  margin: 10px 0 0;
  font-size: 0.84rem;
  padding: 8px 11px;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  color: var(--text-dim);
}
.collect-msg.ok { color: var(--ok); border-color: rgba(61, 220, 132, 0.35); }
.collect-msg.error { color: var(--danger); border-color: rgba(255, 107, 107, 0.4); }

@media (max-width: 760px) {
  .post-grid { grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); }
}

/* --- Instagram: densidade de exibição ------------------------------------ */
/*
   Três formas de olhar a mesma lista, porque são três tarefas diferentes:
   julgar uma imagem (grande), varrer o dia (compacto) e caçar um post
   específico (lista). Um card de 290px é ótimo para a primeira e péssimo para
   as outras duas.
*/

.post-grid.density-compacto {
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 8px;
}
.post-grid.density-compacto .post-caption { font-size: 0.76rem; }
.post-grid.density-compacto .post-body { padding: 6px 8px 8px; gap: 3px; }
/* Na densidade compacta a legenda some inteira: o card já é pequeno demais para
   uma linha de texto disputar espaço com a foto, e o `title` continua lá. */
.post-grid.density-compacto .badge.collab { display: none; }

.post-grid.density-lista { display: block; }

.post-row {
  display: grid;
  grid-template-columns: 44px 130px auto 74px minmax(120px, 1fr) 2fr 76px;
  align-items: center;
  gap: 10px;
  padding: 6px 10px;
  border-bottom: 1px solid var(--border);
  font-size: 0.82rem;
}
.post-row:hover { background: var(--panel-alt); }
.post-row.hot { box-shadow: inset 3px 0 0 var(--hot); }

.row-thumb {
  position: relative;
  display: block;
  width: 44px;
  height: 44px;
  border-radius: 6px;
  overflow: hidden;
  background: var(--panel-alt);
}
.row-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.row-play {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.35);
  color: #fff;
  font-size: 0.65rem;
}

.row-profile {
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  color: var(--text);
  font-family: inherit;
  font-size: 0.82rem;
  font-weight: 600;
  text-align: left;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.row-profile:hover { color: var(--accent); }

.row-likes { color: var(--text-dim); font-weight: 600; white-space: nowrap; }
.row-reason { color: var(--text-faint); font-size: 0.74rem; overflow: hidden;
              text-overflow: ellipsis; white-space: nowrap; }
.row-caption { color: var(--text-dim); overflow: hidden; text-overflow: ellipsis;
               white-space: nowrap; }
.row-date { color: var(--text-faint); font-size: 0.74rem; text-align: right;
            white-space: nowrap; }

/* Abaixo disto a linha não cabe: legenda e motivo saem, e o essencial fica. */
@media (max-width: 980px) {
  .post-row { grid-template-columns: 44px 1fr auto 74px 76px; }
  .row-reason, .row-caption { display: none; }
}

/* --- Contador de posts no cabeçalho -------------------------------------- */

.post-count {
  color: var(--text);
  font-size: 0.8rem;
  font-weight: 600;
  white-space: nowrap;
}

.list-header .btn-sm { margin-left: 8px; }

/* Seletor de modelo da classificação (⚙ Configurações → Sistema, só admin). */
.model-box {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.model-option {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  cursor: pointer;
}

.model-option.on {
  border-color: var(--accent);
  background: rgba(79, 140, 255, 0.08);
}

/* `.modal-box input` força `width: 100%`, e num radio isso estica a bolinha
   para a largura do card — ela aparece centralizada no topo, longe do texto que
   ela seleciona. Mesmo tropeço que `.checkbox-label` já documenta acima; a
   regra genérica foi escrita para campos de texto e não vale para controles. */
.model-option input[type="radio"] {
  width: auto;
  flex: 0 0 auto;
  margin: 3px 0 0;
}

.model-option > span {
  flex: 1;
  min-width: 0;
}

.model-option strong {
  display: inline-block;
  margin-right: 8px;
}

.model-option code {
  font-size: 12px;
  color: var(--text-dim);
}

.model-option em {
  display: block;
  margin-top: 3px;
  font-style: normal;
  font-size: 13px;
  color: var(--text-dim);
}

/* --- Quadro de melhorias (admin) ----------------------------------------- */

.imp-head-top { display: flex; gap: 12px; align-items: flex-start; justify-content: space-between; }
.imp-head-top .panel-note { max-width: 62ch; }

/* A barra é o único número que se lê de longe: quanto do que foi pedido já
   saiu. Fica no topo por isso. */
.imp-progress {
  height: 6px;
  background: var(--panel-alt);
  border: 1px solid var(--border);
  border-radius: 4px;
  overflow: hidden;
  margin: 4px 0 8px;
}
.imp-progress i { display: block; height: 100%; background: var(--ok); transition: width 0.3s; }

.imp-score { margin: 0 0 12px; font-size: 0.84rem; color: var(--text-dim); }
.imp-score b { color: var(--text); }

.imp-filters { flex-wrap: wrap; }

.imp-area { margin-bottom: 18px; }
.imp-area-title {
  margin: 0 0 8px;
  padding: 0 4px;
  font-size: 0.9rem;
  font-weight: 600;
  display: flex;
  gap: 8px;
  align-items: baseline;
}
.imp-area-title .dim { font-size: 0.78rem; font-weight: 400; }

.imp-list { display: flex; flex-direction: column; gap: 10px; }

.imp-card {
  background: var(--card);
  border: 1px solid var(--border);
  border-left: 3px solid var(--border);
  border-radius: var(--radius);
  padding: 12px 14px;
}
/* A borda da esquerda repete o estado em cor, para varrer a lista sem ler
   pílula por pílula. */
.imp-card.imp-concluida { border-left-color: var(--ok); }
.imp-card.imp-em_andamento { border-left-color: var(--warn); }
.imp-card.imp-descartada { opacity: 0.6; }

.imp-card-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.imp-key {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.7rem;
  color: var(--text-faint);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 2px 6px;
}
.imp-title { margin: 0; font-size: 0.95rem; font-weight: 600; flex: 1; min-width: 200px; }

.imp-kind { text-transform: lowercase; }
.imp-kind-correcao { color: var(--danger); border-color: rgba(255, 107, 107, 0.35); }
.imp-kind-melhoria { color: var(--accent); border-color: var(--accent-dim); }
.imp-kind-entrega { color: var(--warn); border-color: rgba(242, 176, 74, 0.35); }

.imp-status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 0.76rem;
  color: var(--text-dim);
  white-space: nowrap;
}
.imp-status.ok { color: var(--ok); }
.imp-status.warn { color: var(--warn); }

/* O texto do cliente, do jeito que ele escreveu. */
.imp-detail {
  margin: 8px 0 0;
  color: var(--text-dim);
  font-size: 0.84rem;
  line-height: 1.55;
}

.imp-done {
  margin-top: 10px;
  padding: 8px 10px;
  background: var(--panel-alt);
  border-radius: 8px;
  /* Cinza por padrão, verde só quando o item está de fato concluído: num item
     em andamento a mesma caixa é uma ANOTAÇÃO de andamento, e pintá-la de
     verde faria a lista parecer mais pronta do que está. */
  border-left: 2px solid var(--border);
  font-size: 0.84rem;
  line-height: 1.55;
  display: flex;
  gap: 8px;
}
.imp-done b { white-space: nowrap; color: var(--text-dim); }
.imp-concluida .imp-done { border-left-color: var(--ok); }
.imp-concluida .imp-done b { color: var(--ok); }

.imp-card-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-top: 10px;
  font-size: 0.74rem;
}

.imp-form { display: flex; flex-direction: column; gap: 10px; margin-top: 10px; }
.imp-form label { display: flex; flex-direction: column; gap: 5px; font-size: 0.74rem; color: var(--text-dim); }
.imp-form-grid { display: flex; gap: 12px; flex-wrap: wrap; }
.imp-form-grid label { flex: 1; min-width: 180px; }
.imp-form-actions { display: flex; align-items: center; gap: 10px; }
/* A mensagem empurra os botões para as pontas: salvar à direita, apagar à
   esquerda, e a confirmação no meio onde o olho já está. */
.imp-msg { flex: 1; font-size: 0.78rem; }
.imp-msg.error { color: var(--danger); }
/* O atalho que vem junto de uma recusa — hoje o "Incluir @cristiano em
   Portugal" do cadastro repetido. Ele mora DENTRO da mensagem, e não ao lado do
   botão de salvar, porque é a mensagem que explica por que ele existe. */
.imp-msg .btn { margin-left: 10px; vertical-align: middle; white-space: nowrap; }

.imp-new summary { cursor: pointer; font-size: 0.9rem; font-weight: 600; }
.imp-new[open] summary { margin-bottom: 10px; }

@media (max-width: 640px) {
  .imp-head-top { flex-direction: column; }
  .imp-form-grid { flex-direction: column; }
}

/* --- Perfis: a cara de gerência (admin) ---------------------------------- */

/* As caixas de "também aparece em". Fora da grade de campos (`imp-form-grid`)
   porque elas são uma lista que cresce com o número de universos — dentro da
   grade, a coluna delas espremeria os outros quatro campos a cada universo
   novo. */
.prof-universes {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 12px;
}
.prof-universes-label { font-size: 0.78rem; color: var(--text-dim); }
.prof-universes-label .hint-inline { display: block; margin-top: 2px; }

.universe-checks { display: flex; flex-wrap: wrap; gap: 6px; }

.universe-check {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px;
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 0.78rem;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
}
.universe-check:hover { background: var(--panel-alt); }
.universe-check input { accent-color: var(--accent); cursor: pointer; }
/* O principal fica marcado e travado: ele vem do `<select>` ao lado, e uma
   caixa que desmarca o universo principal prometeria um estado que o servidor
   recusa — perfil sem universo nenhum. */
.universe-check.principal {
  border-color: var(--accent);
  color: var(--text);
  cursor: default;
}
.universe-check.principal input { cursor: default; }

.prof-rows { display: flex; flex-direction: column; gap: 2px; }

.prof-row {
  display: grid;
  grid-template-columns: 12px minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 10px;
  padding: 8px 6px;
  border-radius: 8px;
  border-bottom: 1px solid var(--border);
}
.prof-row:hover { background: var(--panel-alt); }
.prof-row:last-child { border-bottom: none; }

/* Pausado continua legível: some da coleta, não da tela — é preciso enxergá-lo
   para poder religá-lo. */
.prof-off { opacity: 0.62; }

.prof-id { min-width: 0; }
.prof-id strong { display: block; font-size: 0.9rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.prof-handle { display: flex; align-items: center; gap: 6px; font-size: 0.76rem; color: var(--text-faint); }
.prof-handle a { color: var(--text-faint); }
.prof-handle a:hover { color: var(--accent); }

.prof-numbers { display: flex; flex-direction: column; align-items: flex-end; font-size: 0.74rem; color: var(--text-dim); white-space: nowrap; }
.prof-numbers b { color: var(--text); font-size: 0.82rem; }

.prof-actions { display: flex; gap: 6px; }

/* O formulário e o erro ocupam a linha inteira, embaixo das quatro colunas. */
.prof-form, .prof-error { grid-column: 1 / -1; }
.prof-error { margin: 0; }

@media (max-width: 640px) {
  .prof-row { grid-template-columns: 12px minmax(0, 1fr); }
  .prof-numbers, .prof-actions { grid-column: 2; align-items: flex-start; }
  .prof-numbers { flex-direction: row; gap: 8px; }
}

/* --- Entrar com o Google -------------------------------------------------- */

.btn-google { display: flex; align-items: center; justify-content: center; gap: 10px; font-weight: 600; }
.btn-google .g-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px; height: 20px;
  border-radius: 50%;
  background: #fff;
  color: #4285f4;
  font-weight: 700;
  font-size: 13px;
  line-height: 1;
}

/* Separador com o texto no meio da linha. */
.login-sep {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 2px 0;
  color: var(--text-faint);
  font-size: 12px;
}
.login-sep::before, .login-sep::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--border);
}

.tag-google { border-color: #3c5a99; color: #9ab4e8; }

/* --- Deck ---------------------------------------------------------------- */
/*
   Colunas lado a lado, cada uma rolando por conta própria. A rolagem VERTICAL
   fica dentro da coluna, e não na página: é isso que permite ler uma coluna sem
   mexer nas outras — a diferença entre um deck e uma página com três listas
   empilhadas.
*/

.deck {
  display: flex;
  gap: 16px;
  align-items: stretch;
  overflow-x: auto;
  /* Menos o cabeçalho e a folga da área: a coluna termina onde a janela termina,
     e é a barra interna dela que rola. */
  height: calc(100vh - 32px);
  padding-bottom: 4px;
  scroll-snap-type: x proximity;
}

.col {
  /* 340px é o MESMO número do `COL_MIN_WIDTH` do app.js, e a igualdade é a
     decisão: a largura de partida é o menor tamanho que o arrasto permite, para
     caber o máximo de colunas na tela. Quem quiser mais largura arrasta a borda;
     ninguém precisa arrastar para estreitar.

     Não desce mais do que isso porque abaixo de ~305px a primeira fileira de
     chips (Agora/Em alta/1h…/tudo) deixa de caber e vaza para fora da coluna —
     medido contra este CSS. A segunda fileira aguenta menos largura, porque o
     `.col-chip-grow` absorve a sobra.

     `test_columns.py` trava os dois números juntos: se um mudar sozinho, ou a
     coluna nasce mais larga do que precisa, ou nasce quebrada. */
  flex: 0 0 340px;
  /* Sem isto, uma legenda com uma palavra longa e sem espaço (uma torcida
     gritando "VAAAAMOS, FLAMENGOOOOO...") vira o conteúdo mínimo da coluna, e o
     flexbox alarga a coluna para caber a palavra inteira mesmo com
     flex-grow: 0 — a largura fixa deixa de valer. `min-width: 0` tira o
     conteúdo da conta: a coluna fica nos 372px e é a palavra que estoura,
     não a coluna. */
  min-width: 0;
  display: flex;
  flex-direction: column;
  min-height: 0;
  position: relative;
  background: var(--panel);
  border: 1px solid var(--border);
  /* 10px, e não `--radius` (8px): a coluna é a moldura de tudo e no Figma tem
     o canto mais aberto que os cards que ela guarda. */
  border-radius: 10px;
  padding: 10px;
  gap: 7px;
  scroll-snap-align: start;
}

/* Um pisca discreto quando entra coisa nova, no lugar da antiga pílula de
   "1 notícia nova": diz que chegou sem exigir um clique para ver. */
.col-fresh { border-color: var(--accent); transition: border-color 0.4s; }

.col-head {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 0;
}
.col-kind { display: flex; align-items: center; gap: 4px; color: var(--text-dim); flex: 0 0 auto; }
.col-kind .ico { width: 15px; height: 15px; }
.col-title {
  margin: 0;
  font-size: 0.9375rem;
  line-height: 20px;
  letter-spacing: -0.15px;
  font-weight: 600;
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* A contagem é o que NÃO encolhe nesta linha: ela é curta e fixa ("142 posts"),
   e o recorte ao lado é que pode ser longo. Deixar os dois encolherem juntos
   produzia "14… · Cruzeiro, Fla…", em que nenhum dos dois se lê. */
.col-count { color: var(--text-dim); flex: 0 0 auto; }
.col-cut { overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.col-cut::before { content: "· "; color: var(--text-faint); }
.col-sub {
  margin: 0;
  padding: 0 12px 8px;
  color: var(--text-faint);
  font-size: 0.7rem;
  display: flex;
  align-items: baseline;
  gap: 8px;
  overflow: hidden;
  white-space: nowrap;
  border-bottom: 1px solid var(--border);
}

/* --- Controles dentro da coluna ------------------------------------------ */
/*
   Ordem, período, temperatura e tamanho ficam à mão, no cabeçalho. São os
   controles que mudam durante a leitura ("e na última hora?"), ao contrário dos
   do ⚙, que se ajustam uma vez. Em 372px isso só cabe com chip miúdo — e cabe.
*/

.col-ctrl {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 2px 8px 7px;
}
/* `gap: 2px` e não 3: os oito chips (Agora · Em alta · 1h · 6h · 12h · 24h ·
   48h · tudo) mais o separador cabem em 340px por poucos pixels, e cada unidade
   de folga aqui é multiplicada por nove. Com 3px, "tudo" era cortado ao meio. */
.col-chips { display: flex; align-items: center; gap: 2px; }
.col-chip-grow { flex: 1; }
/* O Figma põe os chips de recorte numa fileira contínua, sem divisória. */
.col-chip-sep { display: none; }

/* "Chip / filtro": o mesmo componente dos meses em Datas importantes. */
.col-chip {
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  color: var(--text-dim);
  font-size: 0.6875rem;
  font-family: inherit;
  line-height: 14px;
  letter-spacing: 0.1px;
  padding: 3px 7px;
  cursor: pointer;
  white-space: nowrap;
}
.col-chip:hover { color: var(--text); background: var(--card-hover); }
/* Ligado é AZUL CHEIO com texto branco. A versão anterior era um contorno azul
   com fundo quase invisível, e num monitor de brilho baixo — que é como estes
   painéis vivem, ao lado de uma transmissão — "24h ligado" e "24h desligado"
   eram o mesmo chip. */
.col-chip.on {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-on);
  font-weight: 500;
}

/* Os três botões de densidade, no cabeçalho e SEMPRE visíveis — ao contrário
   das ações, que só aparecem no hover. A régua está no `columnHtml`: densidade
   se mexe durante a leitura, mover e remover não. */
.col-dens { display: flex; gap: 1px; flex: 0 0 auto; }
.col-dens-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  border-radius: var(--radius-sm);
  color: var(--text-dim);
  cursor: pointer;
  padding: 4px;
}
.col-dens-btn .ico { width: 14px; height: 14px; }
.col-dens-btn:hover { color: var(--text); background: var(--card-hover); }
/* Aceso é só o ícone acendendo, sem cápsula: no Figma os três convivem na
   mesma linha do título e uma cápsula azul ali competiria com o recorte. */
.col-dens-btn.on { color: var(--text); background: transparent; }

.col-actions { display: flex; gap: 2px; opacity: 0; transition: opacity 0.15s; }
/* Os controles só aparecem no hover: seis botões por coluna, sempre visíveis,
   competiriam com o conteúdo — que é o que se veio ler. */
.col:hover .col-actions, .col:focus-within .col-actions { opacity: 1; }
.col-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  color: var(--text-faint);
  cursor: pointer;
  padding: 4px;
  border-radius: var(--radius-sm);
}
.col-btn .ico { width: 14px; height: 14px; }
.col-btn:hover { color: var(--text); background: var(--card-hover); }

.col-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  /* O respiro é do `.col` agora (padding 10px), como no Figma — aqui ele
     duplicaria a margem entre a borda da coluna e o primeiro card. */
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 9px;
}
.col-more { display: flex; justify-content: center; padding: 4px 0 10px; }

/* Os cards vieram de uma lista larga; na coluna a foto vai para cima. */
/* Os cards NÃO encolhem.
   A coluna é um contêiner flex vertical, e o padrão do flex é espremer os filhos
   para caber — num card de post, que é quase só imagem, isso transformava cada
   post numa tira de trinta pixels. O `flex: none` devolve a altura natural a
   cada card e deixa a rolagem fazer o trabalho dela. */
.col-body > * { flex: none; }

.col-body .article { flex-direction: column; gap: 8px; padding: 10px; }
.col-body .thumb-wrap { flex: 0 0 auto; width: 100%; height: 120px; }
.col-body .article-summary { -webkit-line-clamp: 2; }
.col-body .post { margin: 0; }

/* --- Densidade ------------------------------------------------------------
   Três tamanhos porque são três tarefas: julgar uma imagem, varrer o dia e
   caçar um item específico. A do meio é o padrão. */

/* Média e grande: foto no topo, largura cheia — Card / Notícia foto do
   Figma. O padding sai do `.article` (a foto fica rente à borda, cortada
   pelo `overflow: hidden` do card) e entra no `.article-body`. */
.col-body.dens-media .article,
.col-body.dens-grande .article {
  flex-direction: column;
  gap: 0;
  padding: 0;
}
.col-body.dens-media .thumb-wrap,
.col-body.dens-grande .thumb-wrap {
  width: 100%;
  height: 135px;
  flex: none;
  border-radius: 0;
}
.col-body.dens-media .article-body,
.col-body.dens-grande .article-body {
  padding: 9px 11px 11px;
}
.col-body.dens-media .article-meta,
.col-body.dens-grande .article-meta {
  padding-right: 28px;
}

/* Média: uma foto por linha, na proporção do `Card / Foto`/`Card / Notícia
   foto` do Figma (313×150 ≈ 2,09:1). Era quadrada antes disso ser medido no
   Figma — ver git blame se o histórico do quadrado importar. */
.col-body.dens-media .post-media { height: auto; min-height: 0; aspect-ratio: 313 / 150; }

/* Grande: DUAS fotos por linha — a grade do Instagram, que é onde este
   material nasceu. Mesma proporção do Figma que a média (o componente é o
   mesmo nas duas densidades, só muda quantas cabem por linha).

   Duas por linha com `flex-wrap`, e não com `grid`: numa grade de linhas
   automáticas o navegador precisa medir a altura do card ANTES de saber a
   largura da coluna, e uma foto cuja altura vem da proporção não tem o que
   informar nessa hora — as fotos colapsavam para uma tira de 17px. O flex
   resolve a largura primeiro, que é justamente o que a proporção precisa. */
.col-body.dens-grande {
  flex-direction: row;
  flex-wrap: wrap;
  align-content: flex-start;
}
.col-body.dens-grande > * { flex: 0 0 calc(50% - 4.5px); min-width: 0; }
/* O que não é card ocupa a linha inteira: "carregar mais" e os avisos de estado
   não são um item da grade. */
.col-body.dens-grande > .col-more,
.col-body.dens-grande > .state-msg { flex-basis: 100%; }
.col-body.dens-grande .post-media { height: auto; min-height: 0; aspect-ratio: 313 / 150; }
.col-body.dens-grande .thumb-wrap { height: auto; min-height: 0; aspect-ratio: 313 / 135; }
/* Meia coluna é pouca largura para @perfil + estrelas + idioma numa linha só:
   tudo encolhe um pouco para que sobre nome de perfil legível — é por ele que
   se reconhece a conta antes de ler qualquer outra coisa. */
/* Na grade o card tem tipografia PRÓPRIA, um degrau acima da densidade média
   — medido nas instâncias do Figma dentro da coluna, não no componente solto. */
.col-body.dens-grande .post-handle { font-size: 0.75rem; line-height: 16px; }
.col-body.dens-grande .post-caption { font-size: 0.75rem; line-height: 17px; }
.col-body.dens-grande .post-reason,
.col-body.dens-grande .post-meta { font-size: 0.6875rem; line-height: 15px; letter-spacing: 0.1px; }
.col-body.dens-grande .post-meta { color: var(--text-faint-aa); }
/* O motivo do score cobrava duas linhas de um card que tem meia coluna; ele
   continua no `title` das estrelas, para quem perguntar. */
.col-body.dens-grande .heat-reason { display: none; }
.col-body.dens-grande .post-body { padding: 7px 8px 9px; }

/* Lista: a miniatura vira selo ao lado do texto, e cabe três vezes mais item na
   mesma altura de tela. */
.col-body.dens-lista { gap: 4px; }
/* `Card / Notícia compacta` do Figma: SEM foto. A miniatura-selo que existia
   aqui era de antes do componente ser desenhado. */
.col-body.dens-lista .article { flex-direction: row; gap: 9px; padding: 9px; }
.col-body.dens-lista .thumb-wrap,
.col-body.dens-lista .article-summary,
.col-body.dens-lista .cluster-line { display: none; }
.col-body.dens-lista .article-body { gap: 4px; }
.col-body.dens-lista .article-title { font-size: 0.8125rem; font-weight: 500; line-height: 17px; }
.col-body.dens-lista .article-meta { padding-right: 28px; column-gap: 6px; }
.col-body.dens-lista .article-clube { display: flex; }
.col-body.dens-lista .posted-check { width: 14px; height: 14px; }

.col-body.dens-lista .post { flex-direction: row; align-items: stretch; }
.col-body.dens-lista .post-media { width: 62px; height: auto; min-height: 62px; flex: 0 0 62px; }
.col-body.dens-lista .post-body { padding: 7px 9px; gap: 3px; min-width: 0; }
.col-body.dens-lista .post-caption { -webkit-line-clamp: 1; }
.col-body.dens-lista .post-play { transform: scale(0.7); }

/* --- Redimensionar a coluna ------------------------------------------------
   A alça fica na borda direita, meio dentro do `gap` do deck e meio dentro da
   coluna, para não roubar espaço de clique do conteúdo. Só o traço central
   pinta ao passar o mouse ou arrastar — do contrário seis colunas em fila
   ganhariam seis tracinhos acesos o tempo todo, disputando atenção com o que
   se veio ler. */
.col-resize {
  position: absolute;
  top: 0;
  right: -6px;
  width: 12px;
  height: 100%;
  cursor: col-resize;
  touch-action: none;
  z-index: 2;
}
.col-resize::after {
  content: "";
  position: absolute;
  top: 0;
  left: 5px;
  width: 2px;
  height: 100%;
  border-radius: 1px;
  background: transparent;
}
.col-resize:hover::after { background: var(--border); }
.col-resizing .col-resize::after { background: var(--accent); }

/* Enquanto arrasta, nada de selecionar texto da página por baixo do mouse. */
.col-resizing, .col-resizing * { user-select: none; }

.col-add {
  flex: 0 0 200px;
  border-style: dashed;
  background: transparent;
  align-items: stretch;
}
.col-add-btn {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  background: transparent;
  border: none;
  color: var(--text-dim);
  cursor: pointer;
  font-size: 0.86rem;
  border-radius: var(--radius);
}
.col-add-btn:hover { background: var(--panel-alt); color: var(--text); }
.col-add-plus { font-size: 1.6rem; line-height: 1; }

/* Restaurar o padrão apaga o deck inteiro, então ele fica discreto e no rodapé
   da coluna — perto o suficiente para ser encontrado, longe o suficiente do
   "+ Adicionar coluna" para não ser clicado no lugar dele. */
.deck-reset {
  flex: 0 0 auto;
  padding: 10px 8px;
  font-size: 0.74rem;
  color: var(--text-dim);
  text-align: center;
}
.deck-reset:hover { color: var(--danger); }

/* ---------- Partidas (Tempo Real) — seção fixa do deck, ver o comentário no
   template de paintDeck em app.js. `Card / Partida larga`, Figma 776:3494
   (estados 776:3457 ao vivo / 774:3456 encerrado) — MESMO componente que o
   Tempo Real (labmode-tempo-real) já implementa com fidelidade verificada;
   CSS portado de lá (public/index.html daquele repo), não redesenhado. Os
   tokens de cor já são os mesmos dos dois lados desde o Fase 1 do redesign
   (--panel-alt/--border/--text/--text-dim/--text-faint-aa/--accent/--ok
   têm o mesmo nome E o mesmo valor nos dois CSS) — só as durações de
   transição (--rapido/--normal/--curva de lá) foram trocadas pelos valores
   equivalentes já hardcoded aqui, porque este arquivo não usa variável de
   tempo/curva nenhuma. ---------- */
.col-matches .col-body { gap: 11px; }

.match-card {
  background: var(--panel-alt); border: 1px solid var(--border); border-radius: 8px;
  padding: 11px 13px; display: flex; flex-direction: column; gap: 11px;
  transition: border-color 0.18s ease;
}
.match-card:hover { border-color: var(--text-faint); }

.match-topo { display: flex; align-items: center; gap: 8px; }
.match-meta {
  flex: 1 0 0; min-width: 0; font-size: 0.6875rem; font-weight: 400; line-height: 15px;
  color: var(--text-faint-aa); letter-spacing: .1px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.match-live { display: flex; align-items: center; gap: 5px; flex: none; }
.match-live .match-pulse {
  width: 6px; height: 6px; border-radius: 50%; background: var(--ok); flex: none;
  animation: match-pulso 1.6s ease-in-out infinite;
}
.match-live span:last-child { font-size: 0.6875rem; font-weight: 600; line-height: 15px; color: var(--ok); letter-spacing: .1px; white-space: nowrap; }
@keyframes match-pulso { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }
.match-status {
  flex: none; background: var(--panel-alt); border: 1px solid var(--border); border-radius: 6px;
  padding: 1px 6px; font-size: 0.625rem; font-weight: 400; line-height: 14px;
  color: var(--text-dim); letter-spacing: .15px; white-space: nowrap;
}

.match-confronto { display: flex; align-items: center; gap: 14px; width: 100%; }
.match-confronto .match-lado { flex: 1 0 0; min-width: 0; display: flex; align-items: center; gap: 7px; }
.match-confronto .match-lado.mandante { justify-content: flex-end; }
.match-nome {
  font-size: 0.9375rem; font-weight: 600; line-height: 20px; letter-spacing: -.15px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--text);
}
.match-lado.mandante .match-nome { text-align: right; }
.match-posicao {
  flex: none; background: var(--border); border-radius: 4px; padding: 1px 5px;
  font-size: 0.625rem; font-weight: 400; line-height: 14px; color: var(--text-dim); letter-spacing: .1px;
}
.match-perdedor { color: var(--text-dim); }
.match-placar { flex: none; width: 82px; display: flex; align-items: center; gap: 9px; }
.match-gol { width: 26px; font-size: 1.25rem; font-weight: 600; line-height: 24px; letter-spacing: -.4px; color: var(--text); text-align: center; }
.match-gol.casa { text-align: right; }
.match-x { flex: none; width: 12px; text-align: center; font-size: 0.8125rem; line-height: 24px; color: var(--text-faint-aa); }

.match-acoes { border-top: 1px solid var(--border); padding-top: 10px; display: flex; gap: 8px; }
.match-acao {
  flex: 1 0 0; min-width: 0; display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  background: var(--panel); border: 1px solid var(--border); border-radius: 8px;
  padding: 5px 11px; font-family: inherit; font-size: 0.75rem; font-weight: 600; line-height: 16px;
  cursor: pointer; white-space: nowrap; color: var(--accent);
  transition: background-color 0.12s ease, border-color 0.12s ease, transform 0.12s cubic-bezier(.2, .7, .3, 1);
}
.match-acao .ico { width: 12px; height: 12px; transition: transform 0.18s cubic-bezier(.2, .7, .3, 1); }
.match-acao:hover { background: var(--panel-alt); border-color: var(--accent); }
.match-acao:hover .ico { transform: scale(1.15) rotate(-8deg); }
.match-acao:active { transform: scale(.98); }

@media (max-width: 640px) {
  /* No celular, uma coluna por vez, ocupando a tela — arrastar de lado troca de
     coluna, que é o gesto que já se espera de um deck. */
  .col { flex-basis: calc(100vw - 90px); }
  .deck { scroll-snap-type: x mandatory; }
  /* A alça de redimensionar é coisa de tela grande e de mouse: no celular a
     coluna já ocupa a tela inteira, e a mesma borda é o gesto de trocar de
     coluna — uma alça ali só atrapalharia o arrastar de lado. */
  .col-resize { display: none; }
}

/* --- Bancada de portais (superadmin) --------------------------------------
 *
 * Uma tela de formulário e tabela, montada com o que já existe (`.panel`,
 * `.data`, `.btn`, `.collect-actions`). O que precisou de estilo próprio é o
 * que ela tem de específico: linhas de formulário que se quebram sozinhas, a
 * tabela de sondagem onde o item BARRADO precisa parecer barrado sem sumir, e
 * o campo de colar elenco.
 */

.portal-form {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: flex-end;
  margin-bottom: 10px;
}
.portal-form .field { min-width: 190px; }
.portal-form .field.grow { flex: 1; min-width: 280px; }
.portal-form .field.checkbox { padding-bottom: 8px; }
.portal-form input, .portal-form select { width: 100%; }

.portal-table td { vertical-align: middle; }
.portal-actions { white-space: nowrap; text-align: right; }
.portal-actions .btn { margin-left: 4px; }

/* O item que NÃO passaria fica apagado, não escondido. Esconder deixaria a
 * tabela com a aparência de um feed perfeito e tiraria da tela exatamente a
 * informação que se foi buscar: quanto o filtro está descartando, e por quê. */
.probe-table tr.probe-out { opacity: 0.66; }
.probe-table tr.probe-out:hover { opacity: 1; }
.probe-table td:last-child { font-size: 0.78rem; max-width: 280px; }

/* `<details>` com cara de painel: a caixa de cadastro e a de elencos são as
 * duas coisas que não se usa toda hora, e abertas o tempo todo empurrariam a
 * lista de portais — que é o que se olha — para fora da tela. */
details.panel > summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  gap: 6px;
}
details.panel > summary::-webkit-details-marker { display: none; }
details.panel > summary::before {
  content: "▸";
  color: var(--text-faint);
  font-size: 0.8rem;
}
details.panel[open] > summary::before { content: "▾"; }
details.panel > summary:hover { color: var(--accent); }

.squad-list { display: flex; flex-direction: column; gap: 6px; }
.squad-item {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 7px 10px;
  background: var(--panel-alt);
  border-radius: 6px;
  font-size: 0.84rem;
}
.squad-item .slug { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.squad-yaml {
  width: 100%;
  min-height: 220px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.78rem;
  line-height: 1.5;
  resize: vertical;
  white-space: pre;
}

/* --- Árvore de temas do filtro -------------------------------------------
 *
 * O recorte de uma fonte deixou de ser uma escolha entre opções e passou a ser
 * um conjunto — futebol internacional E tênis ao mesmo tempo —, e um `<select>`
 * não sabe dizer isso. Caixas de seleção, com as de país aninhadas sob a do
 * tema-pai.
 */

.scope-label {
  display: block;
  font-size: 0.74rem;
  color: var(--text-dim);
  margin: 4px 0 6px;
}

.scope-tree {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 12px;
}

.scope-theme {
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
}

.scope-check {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  padding: 10px 12px;
  cursor: pointer;
  transition: background 0.12s;
}
.scope-check:hover { background: var(--panel-alt); }
.scope-check.on { background: rgba(79, 140, 255, 0.08); }
.scope-check input { margin-top: 2px; accent-color: var(--accent); cursor: pointer; }
.scope-check span { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; min-width: 0; }
.scope-check strong { font-size: 0.88rem; }
.scope-check em {
  font-style: normal;
  font-size: 0.72rem;
  color: var(--text-faint);
  white-space: nowrap;
}
.scope-check small {
  flex-basis: 100%;
  font-size: 0.74rem;
  color: var(--text-dim);
  line-height: 1.45;
}

/* Zero clubes num filtro é o defeito silencioso: ele barra 100% dos itens e o
 * sintoma acusa o feed, que está certo. Pintado, ele se anuncia antes. */
.scope-empty { color: var(--warn) !important; }

.scope-countries {
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
  padding: 6px 12px 10px 34px;
  border-top: 1px solid var(--border);
  background: rgba(0, 0, 0, 0.12);
}
/* Desabilitado, e não escondido: sumir esconderia que o sub-filtro existe de
 * quem ainda não marcou o tema — que é exatamente quem precisa saber. */
.scope-countries.off { opacity: 0.4; }
.scope-countries.off .scope-check { cursor: not-allowed; }
.scope-countries .hint-inline { flex-basis: 100%; margin: 4px 0 0; }

.scope-check.small { padding: 5px 9px; border-radius: 6px; }
.scope-check.small span { gap: 5px; }

/* --- Feeds descobertos ---------------------------------------------------
 *
 * Aparecem quando o endereço sondado não era um feed — o caso mais comum ao
 * cadastrar veículo estrangeiro, porque a URL de RSS não é adivinhável. Cada
 * linha é clicável e vira a próxima sondagem.
 */

.discovered {
  margin-top: 14px;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--panel-alt);
}
.discovered > strong { display: block; font-size: 0.86rem; margin-bottom: 2px; }
.discovered .panel-note { margin-bottom: 8px; }

.discovered-item {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  width: 100%;
  padding: 7px 9px;
  margin-bottom: 4px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 6px;
  color: var(--text);
  text-align: left;
  cursor: pointer;
  font: inherit;
}
.discovered-item:hover { border-color: var(--accent); background: rgba(79, 140, 255, 0.08); }
.discovered-item .dot { margin-top: 6px; flex: 0 0 auto; }
.discovered-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.discovered-body b { font-size: 0.84rem; font-weight: 600; }
.discovered-body .slug { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

#admin-body { max-width: 1180px; margin-inline: auto; }

/* --- A barra do Admin ------------------------------------------------------
   Duas fileiras: os cinco grupos em cima, as telas do grupo aberto embaixo.

   Onze abas numa fileira só era o problema que tirou a navegação do topo da
   tela no dia do deck — ou quebra em duas linhas, ou espreme cada nome até ele
   não ser mais lido. Em dois níveis, são cinco em cima e no máximo cinco
   embaixo, e cada fileira tem um trabalho só: a de cima diz o assunto, a de
   baixo diz a tela.

   Ela vive FORA do `#app` (ver index.html), então não pode herdar o padding da
   área de conteúdo — ele é repetido aqui. */
/* `.admin-nav`, e não `.admin-bar`: esse nome já era da BARRINHA de gráfico das
   tabelas do Admin, oito pixels de altura com fundo azul (mais abaixo neste
   arquivo). Sendo a dela declarada depois, era ela que vencia — e a navegação
   inteira herdava `height: 8px`, com as duas fileiras transbordando por cima do
   conteúdo. Um nome repetido em CSS não dá erro: dá o layout do outro. */
.admin-nav {
  padding: 14px 16px 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
  /* Nunca encolhe. Ela é irmã do `#app` num flex de coluna, e o `#app` de uma
     tela longa empurra o total para além da altura da janela — sem isto, o
     flexbox espremia a navegação até sobrar só o padding. */
  flex: 0 0 auto;
}

.admin-groups { display: flex; gap: 4px; flex-wrap: wrap; }
.admin-group {
  background: transparent;
  border: none;
  border-radius: var(--radius-pill);
  color: var(--text-dim);
  font-family: inherit;
  font-size: 0.86rem;
  font-weight: 500;
  padding: 7px 14px;
  cursor: pointer;
}
.admin-group:hover { color: var(--text); background: var(--card-hover); }
.admin-group.on { background: var(--accent); color: #fff; }

/* A segunda fileira é mais leve que a primeira de propósito: as duas são
   navegação, e duas cápsulas azuis empilhadas fariam a pessoa procurar qual das
   duas responde pelo que está na tela. Aqui a marca é um sublinhado. */
.admin-items {
  display: flex;
  gap: 2px;
  flex-wrap: wrap;
  border-bottom: 1px solid var(--border);
}
.admin-item {
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  color: var(--text-dim);
  font-family: inherit;
  font-size: 0.84rem;
  padding: 8px 12px;
  cursor: pointer;
}
.admin-item:hover { color: var(--text); }
.admin-item.on { color: var(--accent); border-bottom-color: var(--accent); }

/* Com a barra na tela, o conteúdo abaixo não precisa do respiro de cima: os
   dois juntos abriam um vão do tamanho de uma linha entre a aba e o que ela
   abriu. */
.admin-nav:not(.hidden) + .app { padding-top: 12px; }

/* --- Tela Admin ----------------------------------------------------------- */

/* As abas reusam o desenho das de Configurações — são a mesma ideia de
   navegação —, mas aqui elas convivem com o seletor de período na mesma linha,
   então perdem a margem inferior que lá separava a aba do conteúdo. */
.admin-tabs { margin-bottom: 0; border-bottom: none; }

/* O período escolhido à mão. Fileira própria embaixo dos botões, e não no meio
   deles: dois campos de data têm três vezes a largura de um chip, e enfiá-los na
   mesma linha empurraria "90 dias" para a linha de baixo sozinho. */
.admin-dates { align-items: center; gap: 10px; }
.admin-date {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.78rem;
  color: var(--text-dim);
}
.admin-date input {
  padding: 4px 8px;
  font-size: 0.8rem;
  color: var(--text);
  background: var(--panel-alt);
  border: 1px solid var(--border);
  border-radius: 6px;
  /* O ícone do seletor nativo é preto no tema escuro — invisível contra o
     fundo do campo. `invert` é o caminho que não exige reimplementar o
     calendário inteiro. */
  color-scheme: dark;
}
.admin-dates-hint { flex-basis: 100%; font-size: 0.72rem; }

@media (max-width: 620px) {
  .admin-dates { align-items: flex-start; }
}

/* Barra de proporção dentro da célula da tabela. Ela responde "quanto disto,
   comparado com o maior" — a pergunta que o número sozinho não responde sem
   fazer conta de cabeça a cada linha. */
.admin-bar-cell { width: 30%; min-width: 80px; }
.admin-bar {
  display: block;
  height: 8px;
  border-radius: 4px;
  background: var(--accent-dim);
  min-width: 2px;
}

/* O mapa de calor.
   `aspect-ratio: 16/9` e não quadrado: a grade representa uma JANELA DE
   NAVEGADOR, e desenhá-la quadrada distorceria as posições — um clique no canto
   direito apareceria no meio. */
.heatmap {
  display: grid;
  aspect-ratio: 16 / 9;
  width: 100%;
  /* Sem teto, numa tela larga a grade fica com mais de 800px de altura e empurra
     o resto do painel para fora da vista — inclusive o ranking de alvos, que é a
     parte que decide alguma coisa. */
  max-width: 900px;
  gap: 1px;
  background: var(--panel-alt);
  border-radius: 8px;
  overflow: hidden;
}
.heatmap span { background: transparent; }
/* A cor vem do `opacity` inline, calculado em raiz quadrada no JS. Uma célula
   sem clique fica transparente e mostra o fundo — é o que dá à mancha uma
   referência de onde ela está na tela. */
.heatmap span[style] { background: var(--hot); }

/* --- Datas importantes ---------------------------------------------------- */

/* O número ao lado de "Datas" na barra lateral. Empurrado para a direita para
   não disputar espaço com o rótulo quando a barra está estreita. */
.side-count {
  margin-left: auto;
  flex: 0 0 auto;
  background: var(--accent-soft);
  color: var(--accent);
  border-radius: var(--radius-pill);
  padding: 1px 7px;
  font-size: 0.68rem;
  font-weight: 600;
}
/* No modo recolhido o contador some junto com os rótulos. Ele é um número solto
   ao lado de um ícone sem nome — "7" sem "Efemérides" na frente não diz sete do
   quê, e ainda empurrava o ícone para fora do centro do trilho. */
.sidebar .side-count { display: var(--rail-label, block); }

.dates-nav { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 14px; }
/* "Chip / filtro" do Figma: menor que o "Toggle / seleção" e SEM moldura
   quando desligado — só o mês aceso ganha a cápsula azul. */
.dates-nav .chip {
  padding: 3px 7px;
  font-size: 0.6875rem;
  line-height: 14px;
  border-radius: var(--radius-sm);
  letter-spacing: 0.1px;
  background: transparent;
  border-color: transparent;
}
.dates-nav .chip.on { background: var(--accent); border-color: var(--accent); color: var(--accent-on); }

.dates-admin-bar { margin-bottom: 10px; }
.dates-new { margin-bottom: 14px; }

.dates-section { margin-bottom: 18px; }
/* O separador é uma linha de texto e um filete, não um título: ele organiza a
   leitura sem competir com o nome das efemérides, que é o que se vem ler. */
/* Rótulo + filete À DIREITA (não sublinhado): é assim que o Figma separa
   PASSARAM / HOJE / VÊM AÍ. */
.dates-sep {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 0.625rem;
  font-weight: 600;
  line-height: 14px;
  text-transform: uppercase;
  letter-spacing: 0.9px;
  color: var(--text-dim);
  padding-top: 6px;
  margin-bottom: 8px;
}
.dates-sep::after { content: ""; flex: 1; height: 1px; background: var(--border); }

.dates-today .dates-sep { color: var(--ok); }

.dates-day {
  display: grid;
  grid-template-columns: 66px 1fr;
  gap: 10px;
  padding: 4px 0;
}
/* O bloco de hoje não repete a data ao lado — o separador já a diz por extenso. */
.dates-day.big { grid-template-columns: 1fr; }
.dates-when { color: var(--text-dim); font-size: 0.75rem; line-height: 18px; letter-spacing: 0.1px; }

.dates-items { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.dates-item { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; }
.dates-title { font-size: 0.8125rem; line-height: 18px; }
.dates-day.big .dates-title { font-size: 0.875rem; font-weight: 500; line-height: 19px; letter-spacing: -0.1px; }
.dates-off { opacity: 0.45; }

/* A idade, à direita do título. Discreta: é complemento, não a informação. */
.dates-age { color: var(--text-dim); font-size: 0.75rem; line-height: 16px; letter-spacing: 0.1px; }

.dates-actions { display: inline-flex; gap: 8px; margin-left: auto; }
.dates-actions .link-btn { font-size: 0.7rem; color: var(--text-faint); }
.dates-actions .link-btn:hover { color: var(--text); }
/* O formulário ocupa a largura toda da linha, abaixo dela. */
.dates-form { flex-basis: 100%; margin-top: 6px; }

/* A linha de hoje, no topo do deck. Uma linha só, largura inteira, e nada de
   borda pesada: ela precisa ser notada sem roubar a atenção das colunas. */
.deck-today { padding: 0 12px 8px; }
.deck-today-line {
  width: 100%;
  text-align: left;
  background: var(--card);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  color: var(--text);
  padding: 8px 12px;
  font-size: 0.82rem;
  cursor: pointer;
}
.deck-today-line:hover { background: var(--panel-alt); }

/* --- Calibragem da coleta -------------------------------------------------
   Grade de cartões, um por parâmetro. Cartão e não linha de formulário porque
   cada um carrega uma explicação de duas ou três linhas — a explicação é o que
   torna o número ajustável por alguém que não escreveu o coletor, e num
   formulário em linha ela não caberia. */
.tuning-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 14px;
}

.tuning-knob {
  border: 1px solid var(--border, #262b36);
  border-radius: 10px;
  padding: 12px 14px;
  background: var(--panel-alt, #12161e);
}

/* Borda de quem foi mexido e ainda não salvo. É a única pista de que existe
   trabalho pendente numa tela com vinte campos — sem ela, sair sem salvar é
   silencioso. */
.tuning-dirty { border-color: #4f7dd8; }

.tuning-head {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 6px;
}

.tuning-help {
  margin: 0 0 10px;
  color: var(--text-dim, #8a93a6);
  font-size: 0.78rem;
  line-height: 1.5;
}

.tuning-knob input[type="text"] {
  width: 100%;
  box-sizing: border-box;
}

.tuning-foot {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin: 8px 0 0;
  font-size: 0.75rem;
}

/* A barra de salvar acompanha a rolagem: a grade é longa, e um botão só no fim
   obrigaria a rolar de volta depois de mexer no primeiro campo. */
.tuning-bar {
  position: sticky;
  bottom: 12px;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 14px;
}

.tag-warn { border-color: #6b4a1f; color: #e0a760; }

/* --- Chip de idioma -------------------------------------------------------
   Substituiu o par selo + "ver original". A sigla diz tudo o que os dois
   diziam: existir significa "traduzido", o texto é a origem, e o clique abre o
   original. O que era duas linhas do card virou três caracteres na fileira que
   já existia. */
.lang-chip {
  cursor: pointer;
  background: none;
  font-weight: 600;
  letter-spacing: 0.04em;
  border-color: #3c5a99;
  color: #9ab4e8;
  font-size: 10px;
  padding: 1px 6px;
}
.lang-chip:hover { border-color: #5a7fc7; color: #c2d4f5; }

/* Aceso enquanto o original está à vista. Sem esta pista, quem clicou não tem
   como saber que o texto na tela é o do veículo e não a tradução — o card ficaria
   em espanhol sem explicação. */
.lang-chip.on {
  background: #3c5a99;
  color: #eaf1ff;
  border-color: #3c5a99;
}

/* --- Linha de hoje: quantas efemérides couberem --------------------------- */
.deck-today-line {
  display: flex;
  align-items: baseline;
  gap: 8px;
  /* `nowrap` + `hidden` fazem o corte; quem decide QUAIS itens somem é o
     `fitTodayLine`, medindo. Sem o corte no CSS, um item que "quase cabe"
     apareceria pela metade antes de a medição rodar. */
  white-space: nowrap;
  overflow: hidden;
}
.deck-today-label { flex: 0 0 auto; }
.deck-today-items {
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
}
.deck-today-item { flex: 0 0 auto; }
/* Separador entre datas, desenhado pelo CSS: um `·` no HTML sobraria pendurado
   quando o item seguinte fosse escondido. */
.deck-today-item + .deck-today-item::before {
  content: "·";
  margin-right: 8px;
  color: var(--text-faint, #5c6478);
}
.deck-today-more { flex: 0 0 auto; }

/* --- Exportação das datas -------------------------------------------------- */
.dates-admin-bar { display: flex; gap: 20px; flex-wrap: wrap; align-items: center; }
/* Ação de texto, sem moldura de botão — o Figma desenha só ícone + rótulo. */
.dates-admin-bar .btn {
  background: none;
  border: none;
  padding: 0;
  gap: 6px;
  color: var(--text-dim);
  font-size: 0.8125rem;
  line-height: 18px;
}
.dates-admin-bar .btn:hover { color: var(--text); }
.dates-admin-bar .btn .ico { width: 14px; height: 14px; }

.dates-export-box {
  margin: 10px 0 4px;
  background: var(--panel-alt);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 11px 13px;
}
.dates-export-box > summary { cursor: pointer; font-size: 0.8125rem; line-height: 18px; color: var(--text); }
.dates-export-box[open] > summary { margin-bottom: 8px; }

/* --- Postados -------------------------------------------------------------
   O ✓ no canto do card e o verde que ele acende.

   O verde é LEVE de propósito. Ele responde "já usamos?" durante uma varredura
   do feed, e um destaque forte competiria com as estrelas — que respondem outra
   coisa, e são o motivo de a pessoa estar olhando. */
.posted-check {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 3;
  width: 17px;
  height: 17px;
  border-radius: 50%;
  /* O disco e o anel são o ícone do Figma reproduzido em CSS: disco escuro
     translúcido, anel `--text-dim`, "v" em `--text`. Marcado, tudo vira verde
     com o "v" escuro por cima. */
  border: 1px solid var(--text-dim);
  background: rgba(15, 17, 21, 0.55);
  color: var(--text);
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Discreto até ser útil: no meio de uma grade, vinte círculos acesos seriam
     mais ruído que as etiquetas que acabamos de tirar. */
  opacity: 0.45;
  transition: opacity 0.12s ease;
}
.article:hover .posted-check,
.post:hover .posted-check,
.posted-check:focus-visible { opacity: 1; }

.posted-check.on {
  opacity: 1;
  background: var(--ok);
  border-color: var(--ok);
  color: var(--panel);
}

/* O card marcado. `position: relative` é o que ancora o botão — sem ele o ✓
   escaparia para o canto da página. */
.article, .post, .posted-card { position: relative; }

.article.is-posted,
.post.is-posted,
.posted-card.is-posted {
  border-color: rgba(43, 160, 95, 0.5);
  background: linear-gradient(rgba(43, 160, 95, 0.08), rgba(43, 160, 95, 0.08)), var(--panel);
}

/* --- A aba Postados -------------------------------------------------------- */
.posted-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 10px;
}
.posted-search {
  flex: 1 1 220px;
  min-width: 180px;
}

.posted-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 12px;
}

.posted-card {
  display: flex;
  gap: 10px;
  padding: 10px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.posted-thumb {
  flex: 0 0 84px;
  height: 84px;
  border-radius: 8px;
  overflow: hidden;
  background: var(--panel-alt);
}
.posted-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }

.posted-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.posted-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.posted-origin { font-size: 0.76rem; color: var(--text-dim); }
.posted-title { margin: 0; font-size: 0.86rem; line-height: 1.35; }
.posted-title a { color: var(--text); text-decoration: none; }
.posted-title a:hover { color: var(--accent); }
.posted-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  font-size: 0.72rem;
  color: var(--text-faint, #5c6478);
  /* O ✓ ocupa o canto superior direito; sem a folga, "marcado há 2 min" passa
     por baixo dele. */
  padding-right: 26px;
}

/* --- Áreas ---------------------------------------------------------------- */

/* A etiqueta da área, na tabela de usuários. A cor vem inline, do banco: a
   mesma área precisa aparecer da mesma cor aqui, no cartão e na barra. */
.area-badge { max-width: 16ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* "Sem área" é informação, não erro: cinza, e nunca vermelho. Quem ainda não
   foi atribuído não fez nada de errado. */
.area-none { color: var(--text-faint); border-style: dashed; }

.tag-gestor { color: var(--accent); border-color: var(--accent-dim); }

.area-card {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px 14px;
  margin-bottom: 12px;
  background: var(--panel-alt);
}
.area-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.area-head .spacer { flex: 1; }
/* `display:inline-block` porque a mesma bolinha é usada em dois lugares: no
   cabeçalho do cartão, que é flex, e dentro de uma célula da tabela "Uso por
   área", que não é — sem ele a bolinha some na tabela. */
.area-dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex: 0 0 auto;
  vertical-align: middle;
  margin-right: 6px;
}
.area-manager { color: var(--text-dim); font-size: 0.76rem; }
.area-numbers { color: var(--text-dim); font-size: 0.78rem; }
.area-actions { display: inline-flex; gap: 8px; }
.area-actions .link-btn { font-size: 0.7rem; color: var(--text-faint); }
.area-actions .link-btn:hover { color: var(--text); }

/* A barra de comparação entre áreas. Largura proporcional aos eventos, cor da
   própria área — é a legenda e o dado na mesma marca. */
.area-bar {
  height: 6px;
  background: var(--card);
  border-radius: 3px;
  margin: 8px 0;
  overflow: hidden;
}
.area-bar span { display: block; height: 100%; border-radius: 3px; min-width: 2px; }

/* --- O campo "Pessoa": lista e caixa de texto no mesmo lugar -------------- */

.combo { position: relative; display: flex; align-items: center; }
.combo input { width: 100%; padding-right: 28px; }

/* A seta é a única pista visível de que existe uma lista atrás do campo. Fica
   fora da ordem de tabulação (`tabindex="-1"`): quem usa teclado abre a lista
   com a seta para baixo, e um passo extra do Tab só atrapalharia. */
.combo-toggle {
  position: absolute;
  right: 6px;
  background: none;
  border: 0;
  color: var(--text-dim);
  cursor: pointer;
  font-size: 0.8rem;
  line-height: 1;
  padding: 4px;
}
.combo-toggle:hover { color: var(--text); }

.combo-list {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  z-index: 40;
  max-height: 260px;
  overflow-y: auto;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
}

.combo-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 10px;
  cursor: pointer;
  font-size: 0.8rem;
  color: var(--text);
}
.combo-item:hover,
.combo-item.on { background: var(--panel-alt); }
.combo-name { font-weight: 600; }
/* O e-mail cede o espaço primeiro: é o nome e a área que se lê para escolher, e
   o e-mail é o que se confere depois. */
.combo-mail { color: var(--text-dim); font-size: 0.74rem; flex: 1; min-width: 0;
              overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.combo-empty { padding: 10px; color: var(--text-dim); font-size: 0.76rem; line-height: 1.5; }

/* "Sem área" na comparação da Visão geral. Fica pálida de propósito: é o resto,
   não uma equipe, e destacá-la como as outras convidaria a lê-la como se fosse. */
.area-none-row td { color: var(--text-dim); }
.area-none-row strong { font-weight: 500; }

.area-rank-btn { margin-top: 4px; }
.area-rank { margin-top: 8px; }
/* A posição no ranking. Monoespaçada e fixa para os números não dançarem
   entre a primeira e a décima linha. */
.area-rank-pos {
  display: inline-block;
  min-width: 1.6em;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}

.area-members { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.area-member {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 2px 9px;
  font-size: 0.74rem;
  color: var(--text-dim);
}
/* O `×` que tira a pessoa da área. Apagado em repouso e legível no hover do
   chip: ele fica ao lado de dezenas de e-mails, e um botão vermelho repetido
   trinta vezes transformaria a lista da equipe num painel de alarmes. O alvo de
   clique é maior do que o glifo (padding), porque errar este clique não é
   inofensivo. */
.area-member-off {
  background: none;
  border: 0;
  padding: 0 2px;
  margin-right: -3px;
  line-height: 1;
  font-size: 0.95rem;
  color: var(--text-faint);
  opacity: 0;
  cursor: pointer;
}
.area-member:hover .area-member-off,
.area-member-off:focus-visible { opacity: 1; }
.area-member-off:hover { color: var(--danger); }
/* Em tela de toque não existe hover: lá o botão fica sempre visível, senão ele
   simplesmente não existe para quem usa o painel no tablet. */
@media (hover: none) {
  .area-member-off { opacity: 1; }
}

.area-form { margin-top: 10px; }

/* --- Destaque de tendência -------------------------------------------------
   O card diz "3,5× o normal do perfil para 9 min" desde sempre, na linha mais
   apagada dele. Quem varre uma coluna lê a foto e o @perfil; o número só
   aparecia para quem parava. Aqui ele passa a ser lido primeiro.

   Três coisas mudam e NADA MAIS: a borda com o filete, uma tinta no fundo e a
   cor do número e das estrelas. Nenhum selo novo, nenhuma linha nova — a
   informação já estava escrita, o que faltava era hierarquia.

   O laranja de 4★+ saiu junto (ver `renderPostCard`): duas cores de urgência na
   mesma borda não são duas informações, são nenhuma. */

/* **"Já postei" vence o destaque**, e é o `:not()` que diz isso — não uma regra
   depois na folha desfazendo esta. O card em alta pergunta "isto vira post?", e
   num card já marcado essa pergunta foi respondida: ele volta ao verde apagado
   com o ✓ aceso, e as estrelas voltam à cor da própria régua.

   Escrito como exceção no seletor porque desfazer custa mais do que nunca
   fazer: o `.stars` colorido teria que ser devolvido cor a cor (s3, s4, s5), e
   a primeira estrela nova que alguém acrescentasse nasceria verde num card
   postado, sem ninguém perceber. */
/* **O destaque é AZUL, e antes era verde.** A troca não é de gosto: neste
   painel o verde passou a querer dizer uma coisa só — "já virou post" —, e ele
   estava dizendo duas. Um card verde por estar em alta ao lado de um card verde
   por já ter sido usado obrigava a ler o ✓ do canto para saber qual era qual,
   que é exatamente a leitura que o destaque existe para dispensar.

   Azul é o acento de ação do painel, e "isto está subindo, olhe" é um pedido de
   ação. Verde ficou sendo só o estado de quem já respondeu ao pedido. */
.post.trend:not(.is-posted) {
  border-color: var(--accent);
  background: rgba(79, 140, 255, 0.25);
}
/* A linha do motivo inteira acende, num peso só — o Figma não destaca o
   número separado do resto da frase. */
.post.trend:not(.is-posted) .post-reason { color: var(--accent); font-weight: 500; }
.post.trend:not(.is-posted) .post-reason .ratio { color: inherit; font-weight: inherit; }

/* **Um destaque só, e ele é o alerta.** `.post.trend` sai de `emAlta`, a mesma
   função que decide o pop-up: um card azul é, por construção, um post que
   apitaria — não há segunda faixa, nem um "quase lá" pintado mais fraco.

   Havia: um grau a 3× fixo e outro no limiar do perfil, os dois com esta mesma
   regra de CSS. Como pintavam igual, o deck marcava de azul posts muito abaixo
   do que o Admin configurou, e a marca prometia um alerta que nunca vinha. */

/* A legenda vira zona de clique junto com a foto — sem virar link, para não
   prometer uma navegação que ela não faz. */
.post-caption[data-peek] { cursor: pointer; }
.thumb-wrap[data-peek] { cursor: pointer; }

/* --- A prévia do item, e o alerta -------------------------------------------
   A mesma janela para os dois: o alerta é a prévia com uma faixa no topo e
   outro par de botões. Uma decisão só ("isto vira post?") merece uma tela só. */

.peek-veil {
  position: fixed;
  inset: 0;
  background: rgba(9, 11, 15, 0.72);
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}

.peek-card {
  width: min(660px, 100%);
  max-height: calc(100vh - 40px);
  background: var(--panel);
  border: 1px solid var(--border-strong);
  border-radius: 14px;
  overflow: hidden auto;
  box-shadow: 0 18px 48px rgba(0, 0, 0, 0.5);
}
/* A janela do alerta se identifica pela borda, do mesmo verde do card que a
   provocou. */
/* O alerta se identifica pela BORDA de 2px em accent — não por uma faixa de
   texto no topo (o Figma não desenha faixa nenhuma; quem anuncia é o selo
   "Em alta" no cabeçalho). */
.peek-card.is-alerta { border: 2px solid var(--accent); }

.peek-close {
  position: fixed;
  top: 18px;
  right: 20px;
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background: var(--card);
  border: 1px solid var(--border);
  color: var(--text-dim);
  cursor: pointer;
  z-index: 51;
}
.peek-close:hover { color: var(--text); }

.peek-banner {
  margin: 0;
  background: var(--accent);
  color: #fff;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-align: center;
  padding: 6px 10px;
}

.peek-inner { display: grid; grid-template-columns: 320px 1fr; }

/* A NOTÍCIA abre numa coluna só: foto em cima, título e texto embaixo.

   O post do Instagram é um retrato e ocupa bem uma coluna alta ao lado da
   legenda. A foto da notícia é 16:9 — na mesma coluna ela ficava uma faixa fina
   no meio de um vão vazio, e a manchete, que é o que se veio ler, era espremida
   em 56% da largura da janela. */
.peek-card.is-news .peek-inner { grid-template-columns: 1fr; }
/* Caixa de 210px DENTRO da coluna de texto (entre o cabeçalho e o título),
   não uma faixa colada na borda de cima — é onde o Figma a coloca. */
.peek-card.is-news .peek-shot {
  min-height: 0;
  height: 210px;
  border-radius: var(--radius);
  overflow: hidden;
}
.peek-when { margin-left: auto; font-size: 0.75rem; line-height: 16px; letter-spacing: 0.1px; color: var(--text-dim); }
.peek-spacer { height: 1px; }

.peek-shot { position: relative; background: var(--panel-alt); min-height: 220px; }
.peek-shot img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* A foto da notícia é 16:9 e não enche uma coluna alta; recortá-la para caber
   cortaria justamente o rosto de quem a notícia é. */
.peek-card.is-news .peek-shot img { object-fit: contain; }
.peek-shot .post-play {
  position: absolute;
  left: 10px;
  bottom: 10px;
}

.peek-side { padding: 18px 20px; display: grid; gap: 10px; align-content: start; }
.peek-top { display: flex; align-items: center; gap: 6px; }
.peek-handle {
  font: inherit;
  font-size: 1.0625rem;
  font-weight: 600;
  line-height: 22px;
  letter-spacing: -0.2px;
  color: var(--text);
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  text-align: left;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.peek-handle:hover { color: var(--accent); }
.peek-handle.as-text { cursor: default; }
.peek-handle.as-text:hover { color: var(--text); }
.peek-stars { margin-left: auto; flex: 0 0 auto; font-size: 0.82rem; }

/* O selo "Em alta": cápsula azul cheia, no alto e à direita. Cheia aqui, e
   contornada no `ratio-badge` logo abaixo — os dois falam da mesma coisa, e
   dois cheios seguidos viravam um bloco azul só. */
.peek-badge {
  margin-left: auto;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: var(--accent);
  color: var(--panel);
  border-radius: var(--radius);
  padding: 3px 7px;
  font-size: 0.75rem;
  font-weight: 500;
  line-height: 22px;
  letter-spacing: -0.2px;
}
.peek-badge .ico { width: 16px; height: 16px; }
.peek-stars.trend .stars { color: var(--accent); }

/* O multiplicador em selo: na janela ele é a razão de a pessoa estar olhando,
   e não mais uma linha de metadado. */
.ratio-badge {
  justify-self: start;
  background: transparent;
  color: var(--accent);
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  padding: 6px 11px;
  font-size: 0.75rem;
  line-height: 16px;
}
.ratio-badge b { color: var(--accent); font-weight: 700; }
/* O selo do multiplicador em alta: contorno azul e texto azul, não bloco cheio.

   Cheio, ele empatava em peso com o botão primário logo abaixo e a janela
   passava a ter dois azuis sólidos disputando o olho — um que informa e um que
   pede clique. O contorno mantém a cor (que é o que liga o selo ao card de onde
   a pessoa veio) e devolve a ênfase ao botão. */
/* Em alta não muda o selo: o Figma desenha um só — contorno e texto em
   `--accent`, fundo transparente. */
.ratio-badge.trend {
  background: transparent;
  border-color: var(--accent);
  color: var(--accent);
}
.ratio-badge.trend b { color: var(--accent); }

.peek-line { margin: 0; font-size: 0.75rem; color: var(--text-dim); line-height: 17px; }
.peek-cap { margin: 0; font-size: 0.75rem; color: var(--text); line-height: 17px; }
.peek-cap.as-title { font-size: 1.0625rem; font-weight: 600; line-height: 19px; color: var(--text); }

.peek-acts { display: grid; gap: 8px; margin-top: 0; }
.peek-btn {
  font: inherit;
  font-size: 0.875rem;
  font-weight: 600;
  line-height: 18px;
  border-radius: var(--radius);
  padding: 13px 18px;
  border: 1px solid transparent;
  cursor: pointer;
  text-align: center;
  text-decoration: none;
  display: block;
}
.peek-btn:hover { filter: brightness(1.07); text-decoration: none; }

/* O par empilhado, e a cor é a única coisa que separa os dois — eles têm a
   mesma largura, a mesma altura e o mesmo peso de fonte.

   Eram os dois verdes, um claro e um cheio. Verde neste painel já quer dizer
   "já virou post" (a marca ✓ no canto do card, a tela Postados), e um botão
   verde escrito "Ver o post" dizia a mesma cor para uma coisa diferente. O azul
   é o acento de AÇÃO; o verde ficou sendo só o de estado. */
/* Os dois botões da prévia têm texto quase-preto — o mesmo par do chip ativo.
   O claro é `--text` (não o branco puro do `--btn-alt-bg`). */
.peek-btn.ghost { background: var(--text); color: var(--accent-on); }
.peek-btn.ghost:hover { background: var(--btn-alt-bg-hover); }
.peek-btn.solid { background: var(--accent); color: var(--accent-on); }
.peek-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* A etiqueta de mercado e o botão que ela justifica — só na janela do item.
   O deck não ganha nada disto: etiqueta em todo card é ruído, e foi por isso
   que a categoria do LLM saiu de lá. */
.peek-transfer { display: grid; gap: 8px; margin-top: 2px; }
.transfer-chip {
  justify-self: start;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.2px;
  background: #123a24;
  color: #7ee2a8;
  border: 1px solid #1e5a38;
}
/* Renovação é outro negócio, e a cor diz isso sem precisar de legenda: o
   atleta fica, não chega. */
.transfer-chip.renovacao { background: #2a2416; color: #f2c777; border-color: #574524; }
/* Desabilitado de verdade, e com cara de desabilitado: um botão que parece
   clicável e não faz nada é pior que botão nenhum. */
.peek-btn.gerar {
  background: #1b2030;
  color: #8b93a7;
  border: 1px dashed #39415a;
  cursor: not-allowed;
}
.peek-btn.gerar:hover { filter: none; }
.gerar-nota { font-size: 11px; font-weight: 500; opacity: 0.75; margin-left: 6px; }

/* O diagnóstico da camada de transferências. Quatro colunas que viram uma só
   no estreito — a tela de Configurações abre em modal, e o modal encolhe. */
.transfer-diag {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 14px;
  margin: 10px 0;
}
.transfer-diag h5 {
  margin: 0 0 6px;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: var(--muted);
}
.transfer-diag ul { margin: 0; padding-left: 16px; font-size: 13px; line-height: 1.7; }
.transfer-diag code { font-size: 12px; }
/* A rodada que falhou precisa saltar: é ela que explica o resto. */
.transfer-diag .run-failed { color: #ff8a8a; }
.transfer-diag .run-failed em { color: #ffb4b4; font-style: normal; }
.state-msg.warn { color: #f2c777; }

/* Numa coluna estreita a foto vira faixa no topo: espremida ao lado do texto
   ela deixaria de responder o que se veio olhar. */
@media (max-width: 620px) {
  .peek-inner { grid-template-columns: 1fr; }
  .peek-shot { min-height: 0; height: 200px; }
  .peek-close { top: 10px; right: 12px; }
}

/* --- Som do alerta ---------------------------------------------------------
   O sino desligado fica apagado em vez de vermelho: som desligado é preferência
   legítima, e o vermelho do "Ao vivo" desligado existe porque LÁ é um estado
   anormal — o painel parou de receber. Aqui não parou nada. */
.side-item.som-off { color: var(--text-faint); }
.side-item.som-off:hover { color: var(--text-dim); }

.som-lista { list-style: none; margin: 0; padding: 0; }

.som-linha {
  display: flex;
  align-items: center;
  gap: 8px;
  border-bottom: 1px solid var(--border);
}
.som-linha:last-child { border-bottom: none; }

.som-escolha {
  flex: 1;
  display: flex;
  align-items: flex-start;
  gap: 10px;
  min-width: 0;
  padding: 10px 4px;
  background: none;
  border: 0;
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.som-escolha:hover { color: var(--accent); }

/* Largura fixa para as bolinhas ficarem numa coluna só: sem isto o ● e o ○
   medem diferente e o texto de cada linha começa num lugar. */
.som-marca {
  width: 14px;
  flex: none;
  color: var(--text-faint);
  line-height: 1.5;
}
.som-linha.on .som-marca { color: var(--accent); }
.som-linha.on b { color: var(--accent); }

.som-texto { min-width: 0; }
.som-texto b { display: block; font-size: 0.9rem; font-weight: 600; }
.som-texto .dim {
  display: block;
  font-size: 0.76rem;
  color: var(--text-dim);
  margin-top: 2px;
  line-height: 1.4;
}

.som-ouvir { flex: none; padding: 4px 10px; }

.som-nota { margin-top: 18px; margin-bottom: 0; font-size: 0.78rem; }
/* --- Trends (superadmin, em avaliação) ------------------------------------ */
/*
   UMA página, e essa é a restrição que desenha tudo aqui. A tela responde a
   pergunta "o que está em alta agora, em cada universo?" e precisa caber sem
   rolagem infinita — daí a grade de cards compactos em vez de uma lista, e daí
   os cards de universo virem agrupados em vez de misturados.

   O idioma de destaque (3× morno, 5× quente) é o MESMO dos cards do deck, de
   propósito: quem já leu um card em alta lá reconhece o verde aqui sem
   aprender uma segunda convenção.
*/

.trends { padding: 16px; display: flex; flex-direction: column; gap: 16px; }

.trends-head-row {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 16px;
  flex-wrap: wrap;
}
.trends-actions { display: flex; align-items: center; gap: 10px; }
.trends-when { color: var(--text-faint); font-size: 0.78rem; white-space: nowrap; }
.trends-summary {
  margin: 8px 0 0;
  color: var(--text-dim);
  font-size: 0.82rem;
}
.trends-warn {
  margin: 10px 0 0;
  padding: 8px 12px;
  border-left: 3px solid var(--warn);
  background: rgba(242, 176, 74, 0.08);
  color: var(--text-dim);
  font-size: 0.8rem;
  line-height: 1.5;
}
.trends-warn.error { border-left-color: var(--danger); background: rgba(255, 107, 107, 0.08); }
.trends-warn code { color: var(--text); font-size: 0.76rem; }

/* Chips de universo. Mesma forma dos chips de escopo das colunas de notícia —
   a pessoa já sabe que um chip aceso é um recorte aplicado. */
.trend-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.trend-chip {
  background: var(--card);
  border: 1px solid var(--border);
  color: var(--text-dim);
  padding: 6px 12px;
  border-radius: 999px;
  cursor: pointer;
  font-size: 0.8rem;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.trend-chip:hover { border-color: var(--accent); }
.trend-chip.active { background: var(--accent-dim); border-color: var(--accent); color: var(--text); }
.trend-chip-n { color: var(--text-faint); font-size: 0.72rem; }
.trend-chip.active .trend-chip-n { color: var(--text-dim); }

.trend-group { display: flex; flex-direction: column; gap: 10px; }
.trend-group-title {
  margin: 0;
  font-size: 0.82rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-faint);
  display: flex;
  align-items: center;
  gap: 8px;
}
.trend-group-n {
  background: var(--panel-alt);
  border-radius: 999px;
  padding: 1px 8px;
  font-size: 0.72rem;
  letter-spacing: 0;
}

/* `auto-fill` e não `auto-fit`: com poucos tópicos num universo, o `auto-fit`
   estica um card só para a largura inteira da tela, e um card gigante ao lado
   de uma grade de cards pequenos lê como defeito de layout. */
.trend-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
  gap: 12px;
}

.trend-card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px 14px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.trend-card.is-warm { border-color: rgba(61, 220, 132, 0.35); }
.trend-card.is-hot {
  border-color: var(--ok);
  background: linear-gradient(180deg, rgba(61, 220, 132, 0.07), transparent 60%), var(--panel);
}

.trend-card-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10px;
}
.trend-term {
  font-weight: 600;
  font-size: 0.98rem;
  /* Termo longo não pode empurrar o multiplicador para fora do card. */
  overflow-wrap: anywhere;
}
.trend-score {
  color: var(--text-dim);
  font-size: 0.76rem;
  white-space: nowrap;
}
.trend-card.is-hot .trend-score { color: var(--ok); font-weight: 600; }

.trend-meta { margin: 0; color: var(--text-faint); font-size: 0.74rem; }
.trend-context { margin: 0; font-size: 0.82rem; line-height: 1.45; color: var(--text-dim); }
.trend-context.dim { color: var(--text-faint); font-style: italic; }

.trend-ents { display: flex; flex-wrap: wrap; gap: 5px; }
.trend-ent {
  background: var(--panel-alt);
  border-radius: 6px;
  padding: 2px 7px;
  font-size: 0.72rem;
  color: var(--text-dim);
}

.trend-items {
  list-style: none;
  margin: 2px 0 0;
  padding: 8px 0 0;
  border-top: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.trend-item a { display: flex; gap: 6px; align-items: baseline; color: var(--text); }
.trend-item a:hover .trend-item-title { color: var(--accent); }
.trend-item-icon { flex: none; font-size: 0.76rem; }
/* Duas linhas e para. O card é um cartão de leitura rápida, não a matéria. */
.trend-item-title {
  font-size: 0.78rem;
  line-height: 1.35;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.trend-item-src { color: var(--text-faint); font-size: 0.7rem; padding-left: 20px; }

.trend-none { margin: 2px 0 0; color: var(--text-faint); font-size: 0.74rem; font-style: italic; }

/* --- Alertas: os níveis por perfil (superadmin) -----------------------------
 *
 * A tela é uma pilha de painéis, um por nível, e cada um é uma lista de @ com
 * um número grande ao lado do nome. O número é grande de propósito: ele é a
 * decisão — "este nível apita a 20×" — e o resto do painel é a explicação dela.
 */

.alert-tier-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.alert-tier-head .panel-title { display: flex; align-items: baseline; gap: 10px; margin: 0; }
.alert-tier-actions { display: flex; gap: 6px; flex: none; }

/* O multiplicador, ao lado do nome e maior que ele. "Tier 2" não diz nada em
   janeiro sobre o que alguém escolheu em novembro; "Tier 2 · 10×" diz. */
.alert-tier-mult {
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--accent, #6ea8fe);
  font-variant-numeric: tabular-nums;
}

.alert-default-row,
.alert-add-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin: 10px 0 6px;
}

.alert-mult { display: inline-flex; align-items: center; gap: 8px; }
.alert-mult input { width: 90px; text-align: right; font-variant-numeric: tabular-nums; }
.alert-mult span { color: var(--text-dim); font-size: 0.82rem; }

/* --- O seletor de perfis: por universo, com marcação em bloco ---------------
 *
 * Ele é INLINE e não um menu suspenso. Um popover com quatrocentas linhas
 * agrupadas fica preso à altura da janela e rola dentro de uma tela que já
 * rola — duas rolagens aninhadas, e a de fora é a que o dedo pega primeiro.
 * Aberto no lugar, ele empurra o resto da página para baixo, que é o
 * comportamento que a pessoa já entende.
 */

.alert-picker {
  margin: 10px 0 2px;
  border: 1px solid var(--border, #262b36);
  border-radius: 10px;
  background: var(--panel-alt, #12161e);
  overflow: hidden;
}

.alert-pick-tools {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border, #262b36);
}
.alert-pick-search { flex: 1 1 220px; min-width: 0; }
/* O contador empurrado para a direita: ele é o resumo da decisão, e resumo fica
   na ponta da linha, não no meio dela. */
.alert-pick-tools .hint { margin-left: auto; white-space: nowrap; }

/* A altura é limitada e a rolagem é DAQUI: sem isso, um cadastro de
   quatrocentos perfis empurraria os botões de salvar para fora da tela, e a
   pessoa marcaria tudo sem nunca ver o que fazer com a marcação. */
.alert-pick-groups {
  max-height: 460px;
  overflow-y: auto;
  padding: 4px 0;
}

.alert-pick-group { padding: 6px 0; }
.alert-pick-group + .alert-pick-group { border-top: 1px solid var(--border, #262b36); }

/* O cabeçalho do universo gruda no topo ao rolar. Numa lista longa, sem isto a
   pessoa rola até o meio de "Clubes Internacionais" e perde de vista em qual
   universo está marcando. */
.alert-pick-head {
  position: sticky;
  top: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 6px 12px;
  background: var(--panel-alt, #12161e);
}
.alert-pick-all { display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: 0.82rem; }
.alert-pick-count {
  font-size: 0.72rem;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}

/* Duas colunas quando cabe: um universo de quarenta clubes em coluna única são
   quarenta linhas de rolagem para uma informação de três palavras cada. */
.alert-pick-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 2px 10px;
  padding: 0 12px 4px;
}

.alert-pick {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 4px 6px;
  border-radius: 6px;
  font-size: 0.8rem;
  cursor: pointer;
  min-width: 0;
}
.alert-pick:hover { background: var(--panel, #171b24); }
.alert-pick .dim {
  color: var(--text-faint);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.alert-pick.is-off { opacity: 0.6; }

/* "sai de Tier 2" — o aviso de que marcar aqui MOVE o perfil. Âmbar porque não
   é erro nem confirmação: é uma consequência que a pessoa precisa ver antes de
   salvar, não depois. */
.alert-pick-move { border-color: #6b4a1f; color: #e0a760; font-size: 10px; }

.alert-pick-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 10px 12px;
  border-top: 1px solid var(--border, #262b36);
}
.alert-pick-actions .hint { flex: 1 1 260px; }

.alert-profiles {
  list-style: none;
  margin: 8px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  /* A lista rola em vez de esticar o painel: um nível com quarenta perfis
     empurraria os outros níveis para fora da tela, e a comparação entre eles é
     o que faz esta tela ser legível. */
  max-height: 320px;
  overflow-y: auto;
}

.alert-profile {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 10px;
  border: 1px solid var(--border, #262b36);
  border-radius: 8px;
  font-size: 0.82rem;
}
.alert-profile .dim { color: var(--text-faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.alert-profile button { margin-left: auto; flex: none; }
/* Perfil pausado continua na lista, recuado. Tirá-lo daria a impressão de que a
   configuração dele se perdeu — e ele volta quando a coleta voltar. */
.alert-profile.is-off { opacity: 0.6; }

.alert-profile-net {
  flex: none;
  font-size: 0.68rem;
  color: var(--text-faint);
  border: 1px solid var(--border, #262b36);
  border-radius: 999px;
  padding: 1px 7px;
}

.alert-tier-form,
.alert-new-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 10px;
  align-items: end;
  margin: 10px 0;
  padding: 12px;
  border: 1px solid var(--border, #262b36);
  border-radius: 10px;
  background: var(--panel-alt, #12161e);
}
.alert-tier-form label,
.alert-new-row label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 0.76rem;
  color: var(--text-dim);
}
.alert-field-wide { grid-column: 1 / -1; }

@media (max-width: 620px) {
  .alert-tier-head { flex-direction: column; }
  .alert-profile-select { min-width: 0; }
}
