:root {
  --bg: #0f1115;
  --panel: #171a21;
  --panel-alt: #1e2129;
  --border: #2a2e38;
  --text: #e6e8ec;
  --text-dim: #9aa1ac;
  --text-faint: #6b7280;
  --accent: #4f8cff;
  --accent-dim: #2b3a5c;
  --danger: #ff6b6b;
  --warn: #f2b04a;
  --ok: #3ddc84;
  --hot: #ff8a3d;
  --radius: 10px;
}

* { box-sizing: border-box; }

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

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

.hidden { display: none !important; }

/* --- 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, 196px);
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 14px 10px;
  background: var(--panel);
  border-right: 1px solid var(--border);
  z-index: 20;
}

.sidebar .brand {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 8px 14px;
}
.brand-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px; height: 28px;
  border-radius: 8px;
  background: var(--accent);
  color: #fff;
  font-size: 0.78rem;
  font-weight: 700;
}

.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, 12px 10px 3px);
  font-size: 0.64rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.side-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: var(--rail-item-pad, 9px 10px);
  background: transparent;
  border: none;
  border-radius: 9px;
  color: var(--text-dim);
  font-size: 0.9rem;
  text-align: left;
  cursor: pointer;
}
.side-item:hover { background: var(--panel-alt); color: var(--text); }
.side-item.active { background: var(--accent-dim); color: #fff; }
.side-icon { width: 20px; text-align: center; flex: 0 0 auto; }
.side-label {
  display: var(--rail-label, block);
  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; }

.live-dot {
  display: inline-block;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--text-faint);
  vertical-align: middle;
}

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}
.side-item.live-on { color: var(--text); }
.side-item.live-on .live-dot { background: var(--ok); animation: pulse 2s infinite; }

/* Desligado é um ESTADO, não a ausência de um. Vermelho e com outro texto,
   porque um item apagado no meio de outros apagados não avisa nada. */
.side-item.live-off { color: var(--danger); }
.side-item.live-off .live-dot { background: var(--danger); }
.side-item.live-off:hover { background: rgba(255, 107, 107, 0.1); color: var(--danger); }

/* 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;
  --rail-item-pad: 10px 4px;
  --rail-brand-just: center;
  --rail-brand-pad: 4px 0 12px;
  --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, 4px 8px 14px);
}
/* 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.64rem);
  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: 10px 4px;
    --rail-brand-just: center;
    --rail-brand-pad: 4px 0 12px;
    --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 -------------------------------------------------------------- */

.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(--panel);
  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; }

.field { display: flex; flex-direction: column; gap: 5px; }
.field.grow { flex: 1; min-width: 260px; }
.field label { font-size: 0.74rem; color: var(--text-dim); text-transform: none; }
.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: 8px 10px;
  border-radius: 8px;
  font-size: 0.88rem;
  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: 4px; }
.chip {
  background: var(--panel-alt);
  border: 1px solid var(--border);
  color: var(--text-dim);
  border-radius: 7px;
  padding: 7px 10px;
  font-size: 0.8rem;
  cursor: pointer;
}
.chip:hover { color: var(--text); }
.chip.on { background: var(--accent-dim); color: #fff; border-color: var(--accent); }

.btn {
  background: var(--panel-alt);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 8px 16px;
  border-radius: 8px;
  cursor: pointer;
  font-size: 0.88rem;
}
.btn:hover { border-color: var(--accent); }
.btn-primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn-primary:hover { filter: brightness(1.1); }
.btn-ghost { background: transparent; color: var(--text-dim); }

/* --- 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(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px;
}
.article.hot { border-color: rgba(255, 138, 61, 0.4); }

/* 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; }

.article-body { flex: 1; min-width: 0; }

.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 0 5px; font-size: 1rem; line-height: 1.35; font-weight: 600; overflow-wrap: anywhere; }
.article-title a { color: var(--text); }
.article-title a:hover { color: var(--accent); }

.article-summary {
  margin: 0 0 7px;
  color: var(--text-dim);
  font-size: 0.86rem;
  line-height: 1.45;
  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.78rem;
  color: var(--text-dim);
}
.article-meta .publisher { color: var(--text); }
.article-meta .sep { color: var(--text-faint); }
.article-meta .spacer { flex: 1; }

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

.badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 20px;
  border: 1px solid var(--border);
  font-size: 0.72rem;
  color: var(--text-dim);
  background: transparent;
  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); }
.badge.cat { color: var(--warn); border-color: rgba(242, 176, 74, 0.3); }
/* 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;
  overflow-y: auto;
  position: relative;
}

.drawer-close {
  position: absolute;
  top: 14px; right: 14px;
  background: var(--panel-alt);
  border: 1px solid var(--border);
  color: var(--text-dim);
  width: 30px; height: 30px;
  border-radius: 8px;
  cursor: pointer;
}

.drawer-title { margin: 0 0 4px; font-size: 1.25rem; }
.drawer-sub { margin: 0 0 16px; color: var(--text-dim); font-size: 0.84rem; line-height: 1.5; }
.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(--panel);
  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%; }
}

/* --- 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(--panel);
  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; }

@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(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
.post.hot { border-color: rgba(255, 138, 61, 0.45); }

/* 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: 4 / 5;
  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 10px 10px; display: flex; flex-direction: column; gap: 4px; }

/* 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: 8px;
  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-top,
.col-body.dens-lista .post-head,
.col-body.dens-lista .article-top { 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.82rem;
  line-height: 1.35;
}

/* 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.72rem;
  line-height: 1.3;
  color: var(--text-dim);
  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-handle { font-size: 0.82rem; font-weight: 600; }

.post-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.76rem;
  color: var(--text-faint);
  margin-top: auto;
  padding-top: 4px;
}
.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(--panel);
  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); }

.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) ---------------------------------- */

.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: 12px;
  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);
  border-radius: var(--radius);
  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: 8px;
  padding: 10px 12px 4px;
}
.col-kind { font-size: 0.95rem; }
.col-title {
  margin: 0;
  font-size: 0.92rem;
  font-weight: 600;
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.col-count { color: var(--text-faint); font-size: 0.72rem; }
.col-sub {
  margin: 0;
  padding: 0 12px 8px;
  color: var(--text-faint);
  font-size: 0.7rem;
  overflow: hidden;
  text-overflow: ellipsis;
  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;
}
.col-chips { display: flex; align-items: center; gap: 3px; }
.col-chip-grow { flex: 1; }
.col-chip-sep { width: 1px; height: 12px; background: var(--border); margin: 0 2px; }

.col-chip {
  background: transparent;
  border: 1px solid transparent;
  border-radius: 6px;
  color: var(--text-faint);
  font-size: 0.66rem;
  font-family: inherit;
  line-height: 1;
  padding: 4px 5px;
  cursor: pointer;
  white-space: nowrap;
}
.col-chip:hover { color: var(--text); background: var(--panel-alt); }
.col-chip.on { background: var(--accent-dim); border-color: var(--accent); color: #fff; }

.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 {
  background: transparent;
  border: none;
  color: var(--text-faint);
  cursor: pointer;
  font-size: 0.72rem;
  padding: 2px 4px;
  border-radius: 5px;
}
.col-btn:hover { color: var(--text); background: var(--panel-alt); }

.col-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 10px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.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: uma foto por linha, quadrada. Era uma faixa de 190px de altura — mais
   perto de uma miniatura do que da foto — e num feed em que a imagem É a
   notícia isso obrigava a abrir o post para decidir qualquer coisa. O quadrado
   quase dobra a foto e ainda deixa dois cards na tela. */
.col-body.dens-media .post-media { height: auto; min-height: 0; aspect-ratio: 1 / 1; }

/* Grande: DUAS fotos por linha, em 4:5, com a legenda embaixo — a grade do
   Instagram, que é onde este material nasceu. Duas de 4:5 mostram mais foto por
   rolagem do que uma larga sozinha, e comparar dois posts lado a lado é o que
   se faz nesta densidade: escolher qual vira post.

   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% - 4px); 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: 4 / 5; }
.col-body.dens-grande .thumb-wrap { height: auto; min-height: 0; aspect-ratio: 4 / 5; }
/* 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. */
.col-body.dens-grande .post-head { gap: 5px; }
.col-body.dens-grande .post-stars { font-size: 0.62rem; }
.col-body.dens-grande .post-handle { font-size: 0.78rem; }
.col-body.dens-grande .lang-chip { padding: 1px 4px; font-size: 0.62rem; }
/* 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; }
.col-body.dens-grande .article { padding: 8px; }

/* 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; }
.col-body.dens-lista .article { flex-direction: row; gap: 9px; padding: 8px; }
.col-body.dens-lista .thumb-wrap { width: 62px; height: 46px; flex: 0 0 62px; }
.col-body.dens-lista .article-summary,
.col-body.dens-lista .cluster-line { display: none; }
.col-body.dens-lista .article-title { font-size: 0.86rem; }

.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); }

@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; }

/* --- 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; }

/* 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;
  background: var(--accent-dim);
  color: var(--text);
  border-radius: 10px;
  padding: 1px 7px;
  font-size: 0.68rem;
  font-weight: 600;
}

.dates-nav { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 14px; }
.dates-nav .chip { padding: 3px 8px; font-size: 0.72rem; }

.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. */
.dates-sep {
  display: block;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-faint);
  border-bottom: 1px solid var(--border);
  padding-bottom: 4px;
  margin-bottom: 8px;
}

/* O que já passou fica esmaecido — está ali para lembrar, não para pautar. */
.dates-past { opacity: 0.6; }
.dates-today .dates-sep { color: var(--accent); border-color: var(--accent-dim); }

.dates-day {
  display: grid;
  grid-template-columns: 68px 1fr;
  gap: 8px;
  padding: 5px 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-faint); font-size: 0.76rem; padding-top: 2px; }

.dates-items { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.dates-item { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.dates-title { font-size: 0.86rem; }
.dates-off { opacity: 0.45; }

/* A idade, à direita do título. Discreta: é complemento, não a informação. */
.dates-age { color: var(--text-faint); font-size: 0.72rem; }

.badge.cat-clube { color: var(--ok); border-color: rgba(61, 220, 132, 0.35); }
.badge.cat-titulo { color: var(--hot); border-color: rgba(255, 138, 61, 0.35); }
.badge.cat-comp { color: var(--warn); border-color: rgba(242, 176, 74, 0.35); }

.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(--panel);
  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: 8px; flex-wrap: wrap; align-items: center; }
.dates-export-box {
  margin: 10px 0 4px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 8px 12px;
}
.dates-export-box > summary { cursor: pointer; font-size: 0.82rem; color: var(--text-dim); }
.dates-export-box[open] > summary { margin-bottom: 8px; color: var(--text); }

/* --- 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: 6px;
  right: 6px;
  z-index: 3;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: rgba(12, 16, 22, 0.72);
  color: var(--text-faint, #5c6478);
  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: #1f7a4d;
  border-color: #2ba05f;
  color: #eafff2;
}

/* 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(--panel);
  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;
}
