/* ═══════════════════════════════════════════════════════════════════════
   MENU PRINCIPAL — a primeira tela remodelada do NOVO BOSS APP
   ═══════════════════════════════════════════════════════════════════════
   REGRA DESTA TELA (Boss, 14/09/2026): TUDO CABE NUMA TELA SÓ.
   Nada de rolar pra achar botão. MEDIDO num iPhone 14 (390x844), que é o
   celular mais comum de hoje:

       topo (LOGAR · logo · 4 redondos)            94
       BOSS EM LIVE (só quando tem live)           28
       busca                                       36
       5 atalhos (2 linhas de texto)               65
       os 7 cartões, com os respiros              413
       barra de abas                               58
       respiros do resto                           60
       ────────────────────────────────────────────────
                                                  754  de 844

   Num celular curto de verdade (375x667, o iPhone 8) a tela rola uns 80 px.
   Isso é de nascença, não é regressão: medido na versão de 14/09 dava 740
   de 667. Se um dia for pra caber lá também, o corte tem que sair de
   altura de peça, não de largura.

   SEGUNDA REGRA, QUE CUSTOU DUAS ENTREGAS REPROVADAS (15/09):

   a) BOTÃO LADO A LADO TEM O MESMO TAMANHO. Não é parecido, é o mesmo
      número. Garantido por três coisas juntas, e tirar uma quebra tudo:
        1. o `ferramentas/arte.py` entrega o grupo na mesma proporção
        2. `min-width: 0` nos cartões, pras duas colunas do grid serem iguais
        3. `align-items: stretch`, pra texto que cresceu não desigualar a fileira

   b) A CAIXA DO CARTÃO É A PROPORÇÃO DA ARTE, SEMPRE. Nada de
      `min-height: fit-content` nem `overflow: visible` em cartão com arte.
      Quando a caixa sai da proporção, o navegador estica a imagem, e o
      canto redondo DESENHADO NA ARTE vira um oval achatado: é isso que o
      Boss vê como "cortado e não arredondado". Bastou um SVG escondido com
      `height: auto` pra acontecer. Se um texto não couber na caixa, quem
      diminui é a FONTE, nunca a caixa.

   E, antes de empacotar, roda o `ferramentas/conferir-menu.js` em 320, 360,
   375, 390, 412 e 430. Ele mede tudo isso, inclusive o quanto cada caixa
   está fora da proporção da arte, e devolve aprovado sim ou não.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── A TELA ─────────────────────────────────────────────────────────────
   `align-self: stretch` NAO E ENFEITE, e o que faz o menu usar a tela toda.

   O `body` do app antigo e `display:flex; flex-direction:column;
   align-items:center`, pra centralizar as telas dele. Item de flex assim
   nasce com a largura do CONTEUDO, nao do pai. Ou seja: a largura do menu
   estava sendo decidida pela maior palavra de dentro dele, e nao pelo
   celular. Num Pixel de 412 o menu ficava com 331 e sobravam 81 px de
   fundo vazio dos dois lados, sem ninguem perceber.

   Ficou escondido ate 15/09 porque, por acaso, o conteudo pedia quase a
   largura da tela. Quando eu coloquei `min-width: 0` nos cartoes (pra
   igualar as duas colunas), o conteudo passou a pedir menos e o menu
   encolheu junto. */
body.menu-novo-aberto #app-novo { align-self: stretch; width: 100%; }

#menu {
  position: relative; z-index: var(--z-conteudo);
  width: 100%; max-width: 520px; margin: 0 auto;
  padding: 0 12px calc(var(--barra-total) + 10px);
  font-family: var(--fonte-texto);
  box-sizing: border-box;
}
@media (min-width: 760px) { #menu { max-width: 820px; } }

/* Zera o visual padrão de <button> dentro do menu. Usa :where() de
   propósito: ele não soma especificidade, então qualquer regra de
   componente aqui embaixo ganha sem precisar de !important.
   (Sem isto a barra de abas sai BRANCA: botão sem background declarado
   usa o cinza do sistema, e foi exatamente o que aconteceu.) */
:where(#menu, #menu-barra, #mn-mais) :where(button) {
  background: none; border: 0; padding: 0; margin: 0;
  font: inherit; color: inherit; text-align: inherit;
  -webkit-tap-highlight-color: transparent;
  cursor: pointer;
}

/* ── TOPO ───────────────────────────────────────────────────────────────
   Três colunas: o LOGAR à esquerda, a logo CENTRADA por cima, e os quatro
   redondos à direita. A logo é absoluta de propósito: assim ela fica no
   meio da tela de verdade, sem depender do tamanho do que está do lado.

   A data de atualização NÃO mora mais aqui: ela foi pra tela de
   carregamento, que é onde a pessoa realmente para pra ler. */
.mn-topo {
  position: relative;
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 8px; min-height: 92px;
  padding-top: calc(env(safe-area-inset-top, 0px) + 10px);
}
.mn-topo-esq { display: flex; flex-direction: column; align-items: flex-start; gap: 5px; }

/* O LOGAR ocupa o lugar onde estava o ATT, e maior que ele era. A data de
   atualizacao saiu daqui: ela agora mora na tela de carregamento. */
.mn-logar {
  display: inline-flex; align-items: center; gap: 7px;
  /* Escuro e quase opaco, igual aos redondos. Translúcido ele sumia em
     cima da faixa BOSS FC dourada do wallpaper, que é justo onde ele cai. */
  background: rgba(1,14,4,0.8);
  backdrop-filter: blur(6px);
  border: 1px solid rgba(0,200,75,0.55);
  border-radius: var(--canto-redondo);
  padding: 7px 13px;
  font-family: var(--fonte-rotulo); font-weight: 700;
  font-size: 0.76rem; letter-spacing: 0.1em;
  color: var(--boss-verde);
  white-space: nowrap;
  box-shadow: var(--brilho-verde);
}
.mn-logar svg { width: 14px; height: 14px; }

/* Quatro redondos, todos do mesmo tamanho: recado · ajuda · sino · config.
   Pedido do Boss: os dois novos tem que ser iguais aos que ja existiam.

   Em 2x2, e nao em fila. Em fila os quatro ocupam 164px de largura e
   ENGOLEM a logo centrada num celular de 375. Em duas linhas ocupam 82 e
   sobra espaco pra logo respirar no meio. */
.mn-acoes {
  display: grid; grid-template-columns: repeat(2, 38px);
  gap: 6px; flex: 0 0 auto; padding-top: 2px;
}
.mn-redondo {
  position: relative;
  width: 38px; height: 38px; border-radius: 50%;
  display: grid; place-items: center;
  background: rgba(1,14,4,0.72);
  border: 1px solid var(--borda);
  color: var(--texto-forte);
  backdrop-filter: blur(6px);
  box-shadow: var(--brilho-verde);
  transition: border-color .15s, transform .12s, box-shadow .15s;
}
.mn-redondo:active { transform: scale(0.94); }
.mn-redondo svg { width: 18px; height: 18px; }

/* ── BOSS EM LIVE, abaixo da logo ───────────────────────────────────────
   A primeira versao tinha halo vermelho piscando no botao inteiro. Ficou
   com "cara de IA" (palavras do Boss) e era isso mesmo: neon pulsando e o
   jeito mais generico possivel de dizer "ao vivo".

   Refeito com a linguagem de transmissao de verdade: pilula escura e
   chapada, um ponto vermelho SOLIDO que pisca (so o ponto, nao a caixa),
   a palavra AO VIVO em vermelho e o nome em branco. Nada brilha.

   O `position: static` nao e enfeite: o botao vem do app antigo e traz o
   posicionamento dele junto, e era isso que fazia ele montar em cima da
   busca. */
/* O `margin-bottom` nao e capricho: sem ele o pe do LIVE e o topo da busca
   caem no mesmo pixel (os dois em 124) e parece que um esta em cima do
   outro. Encostado e sobreposto sao a mesma coisa pra quem olha.

   Os 16 px de respiro entre o LIVE e a busca ficaram divididos em 8 aqui e
   8 no `margin-top` da busca (15/09). O motivo: fora do horario o LIVE some,
   e o pe do sino e da engrenagem caia no MESMO pixel do topo da busca (94 e
   94 em 375). Os 8 da busca valem nos dois casos; a soma com o LIVE nao
   mudou. */
.mn-live { display: flex; justify-content: center; margin-top: 4px; margin-bottom: 8px; }
.mn-live:empty { display: none; }
/* Fora do horario da live o botao continua NO DOM (o legado so poe
   `display:none` nele), e a vaga ficaria com 20 px de respiro vazio. Quem
   liga esta classe e um observador no `menu.js`, olhando o `style` do botao. */
.mn-live.sem-live { display: none; }

.mn-live .acv-btn {
  position: static !important;
  /* SEM !important no display, e isso nao e detalhe. O `setupLiveButton()`
     do legado escreve `style.display = 'none'` no botao fora do horario, a
     cada minuto. Inline perde pra `!important`: com ele aqui, o BOSS EM LIVE
     ficou PRESO na tela depois das 23:59 (o Boss pegou em 15/09, 00:45).
     Sem `!important`, o inline `none` do legado ganha, e dentro do horario
     (inline vazio) o `inline-flex` daqui vale. */
  display: inline-flex; align-items: center; gap: 8px;
  background: rgba(8,4,5,0.82) !important;
  border: 1px solid rgba(255,71,87,0.42) !important;
  border-radius: 7px !important;
  padding: 6px 12px !important;
  margin: 0 !important;
  box-shadow: none !important;
  font-family: var(--fonte-rotulo) !important; font-weight: 600 !important;
  font-size: 0.72rem !important; letter-spacing: 0.1em !important;
  color: var(--texto-forte) !important;
  text-transform: uppercase;
  backdrop-filter: blur(6px);
}
/* o icone de ondas que vinha do app antigo sai: quem diz "ao vivo" e o ponto */
.mn-live .acv-btn svg { display: none !important; }

.mn-live .acv-btn::before {
  content: ''; flex: 0 0 auto;
  width: 7px; height: 7px; border-radius: 50%;
  background: #ff3b4e;
  animation: mn-ponto-vivo 1.6s ease-in-out infinite;
}
.mn-live .acv-btn::after {
  content: 'AO VIVO';
  font-size: 0.62rem; letter-spacing: 0.14em; font-weight: 700;
  color: #ff6b78;
  padding-left: 8px; margin-left: 2px;
  border-left: 1px solid rgba(255,71,87,0.28);
}
@keyframes mn-ponto-vivo {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.25; }
}
@media (prefers-reduced-motion: reduce) {
  .mn-live .acv-btn::before { animation: none; }
}

.mn-ponto {
  position: absolute; top: 5px; right: 6px;
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--boss-ouro); border: 2px solid #010a02;
}

/* ── LOGO ───────────────────────────────────────────────────────────────  */
.mn-marca {
  position: absolute; left: 50%; top: calc(env(safe-area-inset-top, 0px) + 4px);
  transform: translateX(-50%);
  text-align: center; pointer-events: none;
}
.mn-logo { width: 68px; height: 68px; object-fit: contain; display: block; }
.mn-logo-falta {
  width: 68px; height: 68px;
  display: grid; place-items: center;
  border: 2px dashed var(--borda); border-radius: 50%;
  font-family: var(--fonte-titulo); font-weight: 800;
  font-size: 1.05rem; line-height: 1; color: var(--boss-ouro);
  letter-spacing: 0.04em;
}

/* ── BUSCA ──────────────────────────────────────────────────────────────  */
.mn-busca {
  /* Mais estreita que a fileira de botoes, de proposito: ela e o campo de
     entrada, nao um botao. Ocupando a largura toda ela competia com os
     cartoes em vez de abrir a tela. */
  display: flex; align-items: center; gap: 9px;
  /* 8 em cima: e o respiro pros quatro redondos quando nao tem LIVE (ver .mn-live) */
  width: calc(100% - 28px); margin: var(--e2) auto 0;
  background: rgba(1,14,4,0.78);
  border: 1px solid var(--borda);
  border-radius: var(--canto-redondo);
  padding: 0 13px; height: 36px;
  backdrop-filter: blur(6px);
  box-shadow: var(--brilho-verde);
  transition: border-color .15s, box-shadow .15s;
}
/* Âncora do painel de sugestão (ver a seção dele lá embaixo).

   O `z-index` fica AQUI, e não só no painel, por uma armadilha que custou
   um teste: `backdrop-filter` cria uma camada de empilhamento própria. Ou
   seja, o painel podia ter z-index 5000 que ele continuaria preso DENTRO
   da caixa da busca, e a caixa é desenhada antes dos atalhos e dos cartões
   (ordem do HTML). Resultado: a lista de sugestão nascia ATRÁS dos botões.
   Levantando a caixa inteira, o painel sobe junto. */
.mn-busca { position: relative; z-index: 50; }
.mn-busca:focus-within {
  border-color: var(--boss-verde);
  box-shadow: 0 0 0 3px rgba(0,200,75,0.14);
}
.mn-busca svg { width: 15px; height: 15px; color: var(--texto-fraco); flex: 0 0 auto; }
.mn-busca input {
  flex: 1; min-width: 0;
  background: none; border: 0; outline: none;
  font-family: var(--fonte-texto); font-size: 0.78rem; color: var(--texto-forte);
}
.mn-busca input::placeholder {
  color: var(--texto-fraco);
  font-family: var(--fonte-rotulo); letter-spacing: 0.03em;
}

/* ── OS 5 ATALHOS EM LINHA ──────────────────────────────────────────────  */
.mn-atalhos {
  display: grid; grid-template-columns: repeat(5, 1fr);
  gap: 7px; margin-top: 14px;
}
.mn-atalho {
  position: relative;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 4px; padding: 9px 1px;
  background: rgba(1,14,4,0.66);
  border: 1px solid var(--borda);
  border-radius: 10px;
  color: var(--texto);
  box-shadow: var(--brilho-verde);
  overflow: hidden;
  transition: border-color .15s, transform .12s, box-shadow .15s;
}
.mn-atalho:active { transform: scale(0.95); }
.mn-atalho svg { width: 20px; height: 20px; color: var(--texto-forte); }
.mn-atalho b {
  font-family: var(--fonte-rotulo); font-weight: 500;
  font-size: 0.58rem; color: var(--texto);
  text-align: center; line-height: 1.12; letter-spacing: 0.01em;
}
.mn-atalho[data-cor="verde"] svg { color: var(--boss-verde); }
.mn-atalho[data-cor="ouro"]  svg { color: var(--boss-ouro); }

/* ── O ATALHO COM ARTE ──────────────────────────────────────────────────
   Mesma regra dos sete cartões, e por um motivo: a arte que o Boss mandou
   em 15/09 (uma folha com as cinco pecas, cortada pelo
   `ferramentas/cortar_atalhos.py`) JA E O BOTAO INTEIRO: moldura, fundo e o
   nome escrito dentro. Entao, com arte, o app nao desenha NADA em volta
   (sem borda, sem fundo, sem halo) e nao escreve o nome por cima, senao
   vira texto dobrado. O `<b>` fica no DOM so pro leitor de tela, invisivel.

   A caixa e a proporcao da arte (o JS escreve o aspect-ratio, quadrado), e
   NADA de `min-height: fit-content`: e a mesma armadilha dos cartoes, a
   caixa nunca muda por causa do conteudo.

   O `background-origin: border-box` faz a arte passar por baixo da borda
   transparente de 1 px, senao sobra um anel de 1 px em volta e a peca
   parece menor que a caixa. O raio de 14% vem do canto desenhado nas
   pecas, medido pelo `cortar_atalhos.py` (67 a 73 px em 480, ou 14% a 15%):
   um pouco MENOR que o da arte de proposito, pra o recorte nunca comer a
   moldura dela. Em porcentagem, e nao em px, porque o botao e quadrado e
   cresce com a tela: 14% acompanha. */
.mn-atalho.com-arte {
  background-image: var(--arte);
  background-size: 100% 100%;
  background-repeat: no-repeat;
  background-origin: border-box;
  background-color: transparent;
  border-color: transparent;
  box-shadow: none;
  border-radius: 14%;
  padding: 0;
}
.mn-atalho.com-arte svg { display: none; }
/* O nome ja esta escrito na arte. Aqui ele some da tela mas continua no
   DOM, pra o botao seguir tendo nome pro leitor de tela. */
.mn-atalho.com-arte b {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
  padding: 0; background: none;
}

/* ── OS 7 BOTOES COM ARTE ───────────────────────────────────────────────
   Cada um recebe a arte dele em --arte. Enquanto a arte não existe, o
   cartão mostra o ícone desbotado no fundo e já fica apresentável. */
.mn-cartoes {
  display: grid; grid-template-columns: 1fr 1fr;
  /* `stretch`, e nao `start` (mudou em 15/09).
     Com `start` cada cartao ficava com a altura da PROPRIA caixa, e era o
     certo enquanto cada arte tinha uma proporcao diferente. Agora o
     ferramentas/arte.py entrega o grupo inteiro na mesma proporcao, entao
     `stretch` nao deforma nada no caso normal: ele so entra em acao quando
     o TEXTO de um cartao nao cabe (o titulo "MERCADO FRAG" quebra em duas
     linhas abaixo de 344) e iguala o vizinho em vez de deixar um mais alto
     que o outro, que foi o que o Boss viu. */
  align-items: stretch;
  gap: 11px; margin-top: 16px;
}
.mn-cartao {
  /* A PROPORCAO DO BOTAO E A MESMA DA ARTE. Isso nao e detalhe: as artes
     vem com a moldura desenhada dentro delas. Com `cover` e altura fixa, o
     navegador CORTA as beiradas da imagem pra preencher, e a moldura da
     arte nunca coincide com a borda do botao. Dava a impressao de dois
     contornos de tamanhos diferentes, um dentro do outro.

     A proporcao vem da tabela FORMATOS do ferramentas/arte.py, que por sua
     vez veio da medida do DESENHO das artes. Assim a arte ocupa o botao
     exatamente, sem sobra e sem corte, em qualquer largura de tela. */
  position: relative; overflow: hidden;
  aspect-ratio: 640 / 443;
  /* `min-width: 0` E O QUE MANTEM AS DUAS COLUNAS IGUAIS.
     Item de grid nasce com `min-width: auto`, ou seja, ele se recusa a
     ficar menor que a maior palavra que tem dentro. A palavra "MERCADO"
     empurrava a coluna da esquerda pra 145 px num celular de 320, e a
     direita ficava com 140. Como a grade e uma so pros sete cartoes, TODA
     a coluna da esquerda ficava 5 px mais larga (e, pela proporcao, 4 px
     mais alta) que a da direita. Era o "tamanho bagunçado" que o Boss viu,
     e nao dava pra achar olhando so pras alturas. */
  min-width: 0;
  padding: 11px;
  display: flex; flex-direction: column; justify-content: flex-end;
  border: 1px solid var(--borda);
  border-radius: 14px;
  box-shadow: var(--brilho-forte);
  background-color: #04140a;
  background-image: var(--arte, none);
  /* 100% e nao 108%: o zoom extra existia pra empurrar resto de beirada
     escura pra fora, mas o ferramentas/arte.py passou a entregar a arte ja
     limpa. Mantendo 108% a gente so comia 4% do assunto de cada lado, e era
     isso que cortava o topo das cartas, do escudo e do trofeu. */
  background-size: 100% 100%; background-position: center;
  text-align: left;
  transition: transform .14s, border-color .15s;
}
.mn-cartao:active { transform: scale(0.98); }
.mn-cartao.largo { grid-column: 1 / -1; }

/* O VEU, DEPOIS DA RECLAMACAO DO BOSS (14/09)
   Ele existe pro texto branco ler por cima de qualquer arte. So que estava
   em 0,88 no pe do cartao, e as artes JA vem com o pe escuro (foi o que eu
   pedi pra ele na hora de gerar: "canto de baixo vazio e escuro"). Os dois
   somados viravam uma faixa preta no pe, que de longe le como borda.

   Agora ele comeca so a 34% da altura e vai escurecendo. Como o
   `ferramentas/arte.py` passou a CORTAR o vazio do pe da arte, embaixo do
   degrade tem desenho de verdade, e nao um retangulo preto. Degrade em
   cima de imagem le como composicao; degrade em cima de vazio le como
   borda, que foi o que o Boss viu. */
.mn-cartao::before {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(
    180deg, transparent 0%, transparent 34%,
    rgba(0,0,0,0.30) 62%, rgba(0,0,0,0.72) 88%, rgba(0,0,0,0.80) 100%);
}
/* o ícone de fundo, que some sozinho quando a arte chega */
.mn-cartao-icone {
  position: absolute; right: -10px; top: -8px;
  width: 64px; height: 64px; opacity: 0.12;
  color: var(--cor, var(--boss-verde));
  pointer-events: none;
}
/* a classe entra pelo JS so depois da imagem carregar de verdade */
.mn-cartao.com-arte .mn-cartao-icone { display: none; }

/* A BORDA, DEPOIS DE TRES RODADAS (14/09)
   Primeira tentativa: deixar a moldura da propria arte ser a borda. Deu
   errado, porque a IA desenha a moldura com uma VINHETA ESCURA por dentro,
   e na tela isso virava uma sobra escura em volta do botao.

   Agora o `ferramentas/arte.py` recorta pra dentro da moldura: a arte chega
   aqui so com a cena, sem moldura e sem vinheta. Entao a borda do app volta
   a ser a unica, e e a MESMA nos sete botoes, com arte ou sem. */
/* Fundo transparente, e com !important de proposito: as regras `.vip` e
   `.baixo` pintam um fundo proprio e tem a MESMA especificidade desta. As
   artes da AREA VIP e do TOP 10 tem area transparente de verdade (20% e 5%),
   e qualquer cor ali atras vira um quadrado escuro por tras do desenho. */
.mn-cartao.com-arte { background-color: transparent !important; }

/* SEM CONTORNO VERDE nos quatro de cima (pedido do Boss, 14/09).
   Com a arte preenchendo o botao inteiro, a borda virava um risco verde por
   cima da imagem em vez de dar acabamento. Fica so o halo de fora, que e
   sombra e nao encosta na arte.
   A AREA VIP e os dois baixos mantem a borda: a VIP porque a borda dourada
   e a marca dela, e os baixos porque sao o rodape da tela e a borda separa
   um do outro. */
/* Nenhum cartao com arte poe borda por cima dela. A arte JA traz a moldura
   desenhada: somar a borda do app dava dois contornos.
   O `.vip` e o `.baixo` aparecem na lista porque as regras deles pintam
   borda propria e tem a MESMA especificidade desta. */
/* Cartao COM ARTE: o app nao desenha NADA em volta dela.
   Sem borda, sem fundo, sem halo, e com o canto quase reto.
   (EXCECAO, 15/09: a AREA VIP e os dois baixos ganham a borda do app,
   logo abaixo. O motivo esta la.)

   O halo verde saiu junto e o motivo e o mesmo da faixa preta: ele
   clareava a volta do botao, e o canto arredondado da arte (que e
   transparente) deixava o fundo escuro da pagina aparecer ali. O contraste
   entre os dois desenhava um contorno escuro que nao existe em lugar
   nenhum do CSS. Sem halo, a volta e o canto ficam da mesma cor.

   O raio cai de 14 pra 6 porque o canto arredondado ja vem desenhado na
   arte: um raio maior que o dela recortava por fora do desenho. */
.mn-cartao.com-arte,
.mn-cartao.com-arte.vip,
.mn-cartao.com-arte.baixo {
  border-color: transparent;
  box-shadow: none;
  /* 8 px, e nao zero. Zero foi a versao de 14/09, apostando tudo no canto
     que vem desenhado na arte. A aposta e boa mas nao tem rede: se uma arte
     chegar de canto reto, ou se a caixa sair da proporcao da arte por
     qualquer motivo, o botao aparece quadrado e o Boss ve na hora.

     8 px nao e chute. Medi o canto desenhado nas sete artes: de 27 a 37 px
     no arquivo, ou seja 4,1% a 5,3% da largura (o `ferramentas/arte.py`
     mede isso de novo quando muda uma arte). Num cartao de 188 px isso da
     7,7 a 8,5 px na tela. Recortando em 8 px, a diferenca pro desenho e
     menor que um pixel: ninguem ve, e o canto passa a ser garantido pelo
     app em vez de confiado a imagem. */
  border-radius: 8px;
}

/* A BORDA DOS TRES LARGOS E DESENHADA PELO APP (15/09, terceira rodada)
   O Boss pediu AREA VIP, MERCADO FRAG e TOP 10 "arredondados, com a borda
   visivel, igual COMPARAR e NOTICIAS". Nos quatro de cima a moldura da
   propria arte faz esse papel. Nos tres largos ela nao da conta, e o
   motivo e medida, nao gosto:

     - a arte larga e reduzida MAIS que a quadrada (1807 px de origem
       cabendo em 170 na tela, contra 1379): a moldura desenhada chega
       com 0,5 px de espessura e metade do brilho, e some no celular
     - o canto desenhado nela e MENOR que os 8 px do recorte (4,7 px no
       MERCADO FRAG), entao o recorte come a linha justamente nos cantos,
       e o botao parece quadrado e sem borda

   Entao nestes tres a borda e do app: 1 px na cor da moldura da arte
   (medida na propria imagem, nao escolhida no olho) e no mesmo raio de
   8 px do recorte. `background-origin: border-box` faz a arte passar por
   BAIXO da borda, pra linha do app cair exatamente em cima da linha da
   arte, e nao do lado dela: duas linhas lado a lado era o "contorno
   dobrado" que ja reprovou uma vez.

   Os quatro de cima ficam como estao: o Boss aprovou, e neles a moldura
   da arte ja chega com 0,9 px e o canto bate com o recorte. */
.mn-cartao.com-arte.vip   { --moldura: #fffb84; }
.mn-cartao.com-arte.baixo { --moldura: #2cde8d; }
.mn-cartao.com-arte.vip,
.mn-cartao.com-arte.baixo {
  border-color: var(--moldura);
  background-origin: border-box;
}

/* Os textos do cartão são <span> dentro de um flex. Sem display:block eles
   ficam um do lado do outro, e o rótulo, o título e a descrição viram uma
   frase só. Foi exatamente o que aconteceu no VIP e nos cartões baixos. */
/* O :not() aqui não é frescura. A versão sem ele (`.mn-cartao > *`) tinha a
   MESMA especificidade da regra do ícone e vinha depois, então ganhava e
   trocava o `position: absolute` do ícone por `relative`. Resultado: o ícone
   saía do canto, virava um bloco de 64px dentro da coluna e empurrava TODO
   cartão de 95 pra 166 de altura. A tela inteira estourava por causa disso. */
.mn-cartao > :not(.mn-cartao-icone):not(.mn-selo):not(.seta) { position: relative; }
.mn-cartao .rotulo, .mn-cartao .titulo, .mn-cartao .desc { display: block; }
.mn-cartao .rotulo {
  font-family: var(--fonte-rotulo); font-weight: 600;
  font-size: 0.56rem; letter-spacing: 0.16em;
  color: var(--cor, var(--boss-verde));
  text-transform: uppercase; margin-bottom: 2px;
}
.mn-cartao .titulo {
  font-family: var(--fonte-titulo); font-weight: 800;
  font-size: 1.32rem; line-height: 0.95;
  /* Titulo em OURO, descricao em BRANCO (pedido do Boss, 14/09). O <em>
     dentro do titulo e a excecao invertida: na ULTIMAS NOTICIAS e na AREA
     VIP so a segunda palavra e que e dourada, e a primeira fica branca. */
  color: var(--boss-ouro); text-transform: uppercase;
  text-shadow: 0 2px 10px rgba(0,0,0,0.8);
}
.mn-cartao .titulo em { font-style: normal; color: var(--texto-forte); }
.mn-cartao .desc {
  margin-top: 3px; padding-right: 30px;
  font-size: 0.74rem; line-height: 1.26; color: var(--texto-forte);
  /* uma linha so em todos os botoes, sem excecao */
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  /* Com o veu mais leve, a descricao passa a cair em cima da arte de
     verdade. A sombra garante a leitura no caso ruim (o dourado claro do
     BOSS TACA) sem precisar escurecer o cartao inteiro de novo. */
  text-shadow: 0 1px 3px rgba(0,0,0,0.95), 0 0 10px rgba(0,0,0,0.7);
}
.mn-cartao .seta {
  position: absolute; right: 9px; bottom: 9px;
  width: 24px; height: 24px; border-radius: 50%;
  display: grid; place-items: center;
  border: 1px solid rgba(160,255,200,0.45);
  box-shadow: inset 0 1px 0 rgba(180,255,215,0.28), 0 0 10px rgba(0,200,75,0.14);
  background: rgba(0,0,0,0.35); color: #fff;
}
.mn-cartao .seta svg { width: 11px; height: 11px; }
/* O SELO "NOVO". A vaga dele nasce escondida em TODOS os sete cartões e
   quem acende é o `js/nucleo/novidades.js`, olhando o que mudou de verdade
   na última publicação. Dura 24 horas e apaga sozinho (regra do Boss,
   15/09). Nos cinco atalhos ele não existe, também por regra dele.

   `position: absolute` importa: é o que garante que acender o selo NÃO
   incha a caixa do cartão. Caixa inchada sai da proporção da arte, e aí a
   arte estica e o canto redondo vira oval - o defeito de 15/09. */
.mn-selo {
  position: absolute; top: 0; right: 0; z-index: 2;
  background: var(--boss-vermelho); color: #fff;
  font-family: var(--fonte-rotulo); font-weight: 700;
  font-size: 0.55rem; letter-spacing: 0.1em;
  padding: 3px 9px; border-radius: 0 14px 0 10px;
}
/* Explícito, e não confiando no padrão do navegador: o CSS do app antigo
   mexe em `display` de span em várias regras, e basta uma pegar aqui pro
   selo aparecer aceso o tempo todo. */
.mn-selo[hidden] { display: none !important; }
/* Nos dois cartões baixos o canto de cima é mais fechado (raio 8 contra
   14), então a barriga do selo acompanha, senão sobra um bico branco. */
.mn-cartao.baixo .mn-selo { padding: 2px 8px; border-radius: 0 8px 0 9px; font-size: 0.5rem; }
/* Na ÁREA VIP o selo é dourado, e não vermelho: ela é a peça dourada da
   tela e o vermelho ali briga com a moldura em vez de chamar atenção. */
.mn-cartao.vip .mn-selo {
  background: var(--boss-ouro); color: #1a1205;
  padding: 2px 9px; border-radius: 0 10px 0 9px; font-size: 0.5rem;
}

/* ── O CARTAO DA AREA VIP, que e dourado ────────────────────────────────  */
.mn-cartao.vip {
  /* Maior que os cartoes baixos de proposito: e a porta paga, e a peca
     mais importante da tela. Estava do mesmo tamanho dos outros e sumia. */
  /* mesma regra: a proporcao do formato que o arte.py gera pra ela */
  /* A CAIXA E EXATAMENTE A PROPORCAO DA ARTE, E PONTO FINAL.
     Aqui ja teve `min-height: fit-content` + `overflow: visible`, pra o
     cartao crescer em vez de cortar o texto. Parecia esperto e era uma
     bomba: no dia em que o conteudo passou do tamanho da caixa (bastou um
     SVG escondido com altura automatica), o cartao inchou, a arte foi
     esticada dentro de uma proporcao que nao e a dela, e o canto redondo
     desenhado na arte virou um oval achatado.

     A regra agora e a inversa, e e mais simples de manter: a caixa NUNCA
     muda, e quem tem que caber dentro dela e o conteudo. Se um texto nao
     couber, o `ferramentas/conferir-menu.js` reprova antes de empacotar e
     quem diminui e a fonte, nunca a caixa. */
  aspect-ratio: 1400 / 304;
  /* UM POUCO MENOR (pedido do Boss, 15/09, terceira rodada). A caixa
     continua sendo a proporcao da arte (regra b la em cima), entao "menor"
     so pode ser MAIS ESTREITA: a altura vem junto. 90% da largura da
     fileira, centrada. Em 375 vai de 351x76 pra 316x68. Nao e 95% porque
     9 px de recuo de cada lado parece desalinhamento, e nao decisao. */
  width: 90%; justify-self: center;
  padding: 8px 12px 8px 10px;
  flex-direction: row; align-items: center; gap: 13px;
  border-color: rgba(232,183,58,0.5);
  box-shadow: var(--brilho-ouro);
  background-color: #14100a;
}
.mn-cartao.vip::before {
  background: linear-gradient(90deg, rgba(232,183,58,0.14) 0%, rgba(0,0,0,0.5) 70%);
}
/* Sem arte (o fallback): a coroa cheia entra no fluxo, do lado do texto. */
.mn-vip-coroa { width: 38px; height: 38px; color: var(--boss-ouro); fill: currentColor; flex: 0 0 auto; }
/* A COROA DA ÁREA VIP, terceira versão (15/09, quarta rodada).
   A arte tem uma coroa desenhada, em CONTORNO, na faixa de 7,9% a 18,6%
   da largura. No navegador ela aparece; no celular do Boss ela não lê como
   coroa, e ele pediu a coroa de volta duas vezes ("sumida" e "faltou a
   coroa"). Então o app desenha a coroa CHEIA em cima da coroa da arte, no
   mesmo lugar e no mesmo tamanho, medidos na imagem: caixa x 110..258,
   y 80..220 de 1400x304, cor mediana #fad23f. O desenho é o contorno da
   própria coroa da arte (as 3 pontas, os 2 vales e a base), então cai
   exatamente por cima. Como o cartão tem SEMPRE a proporção da arte, a
   porcentagem acerta o lugar em qualquer largura de tela.

   Absoluta, e não no fluxo, por causa da armadilha de 15/09: um SVG no
   fluxo com altura automática inflou o cartão e esticou a arte. Absoluto
   não tem altura pra dar errado: a caixa do cartão nem sabe que ele existe.
   O `padding-left: 20%` continua reservando o espaço, pra o texto não subir
   em cima dela.

   ⚠️ Se a arte da VIP for trocada e a coroa mudar de lugar, estes quatro
   números mudam junto (medir na area-vip.webp nova). */
.mn-cartao.vip.com-arte .mn-vip-coroa {
  display: block; position: absolute;
  left: 7.86%; top: 26.3%; width: 10.57%; height: 46.05%;
  color: #fad23f; fill: currentColor;
  filter: drop-shadow(0 0 3px rgba(250,210,63,0.55));
  pointer-events: none;
}
.mn-cartao.vip.com-arte { padding-left: 20%; }
.mn-vip-texto { flex: 1; min-width: 0; }
.mn-cartao.vip .titulo { font-size: 1.3rem; }
.mn-cartao.vip .desc { margin-top: 2px; padding: 0; font-size: 0.72rem; line-height: 1.2; color: var(--texto-forte); }
.mn-vip-acessar {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; gap: 5px;
  background: linear-gradient(180deg, #f3cf63, #c9922a);
  box-shadow: inset 0 1px 0 rgba(255,245,205,0.6), 0 3px 14px rgba(232,183,58,0.3);
  color: #1a1204; border-radius: 7px;
  padding: 8px 12px;
  font-family: var(--fonte-rotulo); font-weight: 700;
  font-size: 0.72rem; letter-spacing: 0.08em; white-space: nowrap;
}
.mn-vip-acessar svg { width: 12px; height: 12px; }

/* ── OS DOIS CARTOES BAIXOS ─────────────────────────────────────────────  */
.mn-cartao.baixo {
  /* mesma regra do VIP: a caixa e a proporcao da arte e nao se mexe.
     O titulo "MERCADO FRAG" cabe numa linha com 20 px de folga em 390 e 9
     em 360, e e o `conferir-menu.js` que garante isso a cada entrega. */
  aspect-ratio: 700 / 248;
  padding: 5px 7px;
  flex-direction: row; align-items: center; gap: 6px;
  background-color: rgba(3,18,8,0.8);
}
.mn-cartao.baixo::before { background: none; }
/* Com arte, o texto passa a ficar em cima da imagem e precisa de veu, senao
   depende da sorte de a arte ser escura naquele pedaco. Da esquerda pra
   direita, porque e a esquerda que tem texto. */
.mn-cartao.baixo.com-arte::before {
  background: linear-gradient(90deg,
    rgba(0,0,0,0.78) 0%, rgba(0,0,0,0.62) 46%, rgba(0,0,0,0.18) 78%, transparent 100%);
}
/* OS TAMANHOS AQUI SAO CONTADOS, NAO ESCOLHIDOS NO OLHO.
   "MERCADO FRAG" e o titulo mais longo do menu e ele mora no cartao mais
   estreito. Em 15/09 ele estava passando na LINHA: 84 px de texto dentro de
   84 px de espaco. Com essa folga de zero, qualquer meio pixel a menos
   jogava "FRAG" pra segunda linha, o cartao crescia e ficava mais alto que
   o TOP 10 do lado. Foi assim que o "tamanho bagunçado" apareceu.

   Icone, seta, respiro e fonte foram apertados o suficiente pra sobrar 20
   px de folga em 390 e 9 px em 360. Mexeu em algum destes numeros? Meca o
   titulo de novo, nao confie no olho. */
.mn-cartao.baixo .mn-cartao-icone {
  position: static; width: 18px; height: 18px;
  opacity: 0.85; flex: 0 0 auto; display: block;
}
.mn-cartao.baixo .mn-cartao-corpo { flex: 1; min-width: 0; }
.mn-cartao.baixo .titulo { font-size: 0.86rem; line-height: 1.05; letter-spacing: 0.01em; }
.mn-cartao.baixo .desc { margin-top: 1px; padding: 0; font-size: 0.64rem; line-height: 1.15; color: var(--texto-forte); }
.mn-cartao.baixo .seta { position: static; width: 18px; height: 18px; }

/* ── A TELA DE EM BREVE ─────────────────────────────────────────────────
   O recado do LOGAR mora AQUI DENTRO, não solto no menu (pedido do Boss). */
#mn-breve {
  position: fixed; inset: 0; z-index: var(--z-modal);
  display: none; align-items: center; justify-content: center;
  padding: 22px;
  background: rgba(1,8,3,0.9);
  backdrop-filter: blur(10px);
}
#mn-breve.aberto { display: flex; }
.mn-breve-caixa {
  width: 100%; max-width: 340px;
  background: linear-gradient(165deg, #06180c, #020a04);
  border: 1px solid var(--borda);
  border-radius: 18px;
  padding: 26px 22px 20px;
  text-align: center;
}
.mn-breve-caixa .icone { width: 44px; height: 44px; color: var(--boss-verde); margin-bottom: 12px; }
.mn-breve-caixa h2 {
  font-family: var(--fonte-titulo); font-weight: 800;
  font-size: 1.9rem; letter-spacing: 0.06em; line-height: 1;
  color: var(--boss-ouro); text-transform: uppercase; margin-bottom: 12px;
}
.mn-breve-caixa p {
  font-family: var(--fonte-rotulo); font-weight: 500;
  font-size: 0.86rem; line-height: 1.45; letter-spacing: 0.04em;
  color: var(--texto-forte); text-transform: uppercase; margin-bottom: 20px;
}
.mn-breve-caixa button {
  width: 100%;
  background: rgba(0,200,75,0.12);
  border: 1px solid var(--borda); border-radius: 10px;
  padding: 11px;
  font-family: var(--fonte-rotulo); font-weight: 700;
  font-size: 0.8rem; letter-spacing: 0.1em; color: var(--boss-verde);
  cursor: pointer;
}

/* ── O SININHO DENTRO DA FOLHA DE EM BREVE ──────────────────────────────
   Nasceu em 22/09. O EM BREVE deixou de ser só recado: este botão é o que
   a pessoa pode FAZER a respeito, e por isso ele é DOURADO e o ENTENDI
   embaixo continua verde. Dourado é a cor do "isto aqui é o principal" no
   app inteiro, e a hierarquia tem que ficar clara sem ler.

   É o único botão da caixa com duas linhas de texto, então ele NÃO herda o
   `text-align: center` da caixa: título e explicação alinham à esquerda, do
   lado do desenho do sino, senão a segunda linha centrada vira poema.

   ⚠️ `text-transform: none` na explicação. A caixa põe TUDO em maiúscula
   (o `p` ali de cima), e uma frase de duas linhas toda em caixa alta no
   celular é o que o Boss chama de bloco: não se lê, se olha.             */
.mn-breve-sino {
  width: 100%;
  display: flex; align-items: center; gap: 11px;
  text-align: left;
  margin-bottom: 10px;
  padding: 11px 13px;
  background: linear-gradient(135deg, rgba(232,183,58,0.16), rgba(232,183,58,0.05));
  border: 1px solid rgba(232,183,58,0.45);
  border-radius: 12px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .12s, border-color .15s, background .15s;
}
.mn-breve-sino:active { transform: scale(0.97); }
.mn-breve-sino > span { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.mn-breve-sino b {
  font-family: var(--fonte-rotulo); font-weight: 800;
  font-size: 0.76rem; letter-spacing: 0.08em; line-height: 1.1;
  color: var(--boss-ouro); text-transform: uppercase;
}
.mn-breve-sino small {
  font-family: var(--fonte-texto); font-weight: 400;
  font-size: 0.68rem; line-height: 1.32; letter-spacing: 0;
  color: var(--texto); text-transform: none;
}
.mn-breve-sino-i {
  flex: 0 0 auto; width: 26px; height: 26px;
  color: var(--boss-ouro);
}
/* JÁ LIGADO: vira verde e para de chamar. Ele continua na tela porque a
   resposta "pode deixar, eu te aviso" é a informação que a pessoa veio
   buscar - sumir com o botão devolveria a dúvida. */
.mn-breve-sino.ligado {
  background: rgba(0,200,75,0.10);
  border-color: var(--borda);
  cursor: default;
}
.mn-breve-sino.ligado b { color: var(--boss-verde); }
.mn-breve-sino.ligado .mn-breve-sino-i { color: var(--boss-verde); }

/* ── A BARRA DE ABAS ────────────────────────────────────────────────────
   MODELO: a foto que o Boss mandou em 15/09. Barra CHAPADA, as cinco abas
   do mesmo tamanho, canto de cima arredondado, um fio verde correndo a
   largura toda e o brilho forte só em cima da aba aberta.

   O que saiu daqui: o círculo dourado levantado em FERRAMENTAS. Quem
   destaca agora é a aba ABERTA, e não uma aba fixa. */
#menu-barra {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-barra);
  display: grid; grid-template-columns: repeat(5, 1fr);
  height: var(--barra-total);
  padding-bottom: env(safe-area-inset-bottom, 0px);
  background: linear-gradient(180deg, rgba(4,26,11,0.97), rgba(1,11,4,0.98));
  border-top: 1px solid rgba(0,200,75,0.45);
  border-radius: 16px 16px 0 0;
  box-shadow: inset 0 1px 0 rgba(120,255,175,0.22), 0 -10px 34px rgba(0,0,0,0.75);
  backdrop-filter: blur(16px);
}
.mn-aba {
  position: relative;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 3px; color: #93a89b;
  transition: color .15s;
}
.mn-aba svg { width: 22px; height: 22px; stroke-width: 1.7; }
.mn-aba b {
  font-family: var(--fonte-rotulo); font-weight: 600;
  font-size: 0.64rem; letter-spacing: 0.01em;
}

/* A aba aberta nao muda so de cor: ela ganha um risco de luz em cima e um
   halo por tras do icone. Sem isso, num celular no sol, "verde" e "cinza"
   viram a mesma coisa e a pessoa nao sabe onde esta. */
.mn-aba.ativa { color: var(--boss-verde); }
.mn-aba.ativa::before {
  content: ''; position: absolute; top: 0; left: 16%; right: 16%;
  height: 2px; border-radius: 0 0 3px 3px;
  background: var(--boss-verde);
  box-shadow: 0 0 14px 1px var(--boss-verde);
}
.mn-aba.ativa svg { filter: drop-shadow(0 0 9px rgba(0,200,75,0.55)); }

/* Enquanto a tela estiver escondida, nada dela aparece nem ocupa espaço. */
#app-novo[hidden], #menu-barra[hidden] { display: none !important; }

/* ── O QUE DO APP ANTIGO SOME ENQUANTO O MENU NOVO ESTA NA FRENTE ───────
   Escondido por CSS, nunca removido: o código antigo lê esses elementos
   (o _activate faz btn.classList.toggle no #btn-config-main) e quebra se
   eles sumirem do DOM. Quando o usuário entra numa tela do legado, a
   classe sai do body e tudo volta ao normal. */
body.menu-novo-aberto #btn-config-main,
body.menu-novo-aberto #btn-circle-fs,
body.menu-novo-aberto #viewer-tour-convite,
body.menu-novo-aberto #breadcrumb-bar,
body.menu-novo-aberto #scroll-top-btn,
body.menu-novo-aberto #pwa-install-btn { display: none !important; }

/* O fundo de partículas do app antigo fica atrás do nosso wallpaper. */
body.menu-novo-aberto #particles-bg { opacity: 0; }

/* O CÍRCULO DOURADO DE FERRAMENTAS FOI EMBORA em 15/09, e fica o registro
   pra não voltar sozinho: o Boss pediu a aba em destaque, eu levantei ela
   num círculo de ouro (o padrão de app com ação central), e depois ele
   mandou a foto do modelo que ele quer. Nesse modelo a barra é chapada e o
   destaque é da aba ABERTA. Se um dia voltar, volta pelo `git show`. */

/* ═══════════════════════════════════════════════════════════════════════
   O QUE ENTROU EM 15/09, DEPOIS DO MENU APROVADO
   ═══════════════════════════════════════════════════════════════════════
   Cinco peças novas, e nenhuma delas encosta no que o Boss já aprovou:
   os sete cartões, os cinco atalhos, a busca e o topo continuam com os
   mesmos números. As duas que entram DENTRO da tela (os recursos e o
   ticker) foram medidas antes: ver o comentário de cada uma.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── OS RECURSOS DA CONTA, EMBAIXO DO LOGAR ─────────────────────────────
   BOSS POINTS e BOSS COINS. Hoje é sempre zero (a gamificação vai junto
   com o login), e o Boss quis assim: é o spoiler.

   CUSTO DE ALTURA: ZERO. E isso não é sorte, é o lugar escolhido. A coluna
   da esquerda do topo tinha 31 px ocupados (o LOGAR) dentro de uma faixa
   de 92 px de altura mínima, ou seja, 51 px vazios desde que a data de
   atualização mudou de casa pra tela de carregamento. As duas pilhas têm
   27 px e entram nesse vão. O menu continua com a mesma altura de antes.

   LARGURA, que é o que aperta: a logo é centrada e absoluta, então a
   coluna da esquerda vai até onde a logo começa. Num celular de 320 (o
   pior caso) isso dá 114 px. As duas pilhas somam 97. Cabe, e é por isso
   que o nome da moeda não está escrito ao lado: com "POINTS" e "COINS"
   escritos, elas passariam de 145 e entrariam por baixo da logo. */
.mn-recursos { display: flex; gap: 5px; }
.mn-recurso {
  display: inline-flex; align-items: center; gap: 5px;
  background: rgba(1,14,4,0.8);
  backdrop-filter: blur(6px);
  border: 1px solid var(--borda);
  border-radius: var(--canto-redondo);
  /* mais apertado do lado da moeda que do lado do número: a moeda é
     redonda e já traz o próprio respiro desenhado */
  padding: 3px 9px 3px 4px;
  box-shadow: var(--brilho-verde);
  line-height: 1;
  transition: transform .12s, border-color .15s;
}
.mn-recurso:active { transform: scale(0.94); }
.mn-recurso img { width: 19px; height: 19px; display: block; }
.mn-recurso b {
  font-family: var(--fonte-titulo); font-weight: 700;
  font-size: 0.88rem; letter-spacing: 0.02em;
  /* O número nasce na cor da própria moeda. É o que faz a pilha ser lida
     como UM recurso, e não como uma bolinha com um número ao lado. */
  color: var(--texto-forte);
  /* Espaço reservado pra dois dígitos. Sem isso, o dia em que alguém
     tiver 10 pontos a pilha da esquerda cresce e desalinha as duas. */
  min-width: 8px; text-align: right;
}
.mn-recurso[data-r="points"] b { color: #7de89f; }
.mn-recurso[data-r="coins"]  b { color: var(--boss-ouro); }
.mn-recurso[data-r="coins"]      { border-color: rgba(232,183,58,0.38); }

/* ── A ETIQUETA DE "EM BREVE" NA ABA ────────────────────────────────────
   Pedido do Boss pra aba FERRAMENTAS (15/09).

   É TEXTO PELADO, sem cápsula, sem fundo e sem borda. A primeira versão
   era uma pílula dourada bonitinha, e a régua reprovou ela: a aba tem 57
   px e o conteúdo dela (ícone 22 + respiro 3 + nome 12 = 37) fica centrado,
   sobrando 10 px em cima e 10 embaixo. A pílula tinha 12,7 px e entrava 5
   px POR CIMA da palavra "Ferramentas".

   As duas saídas erradas eram empurrar o conteúdo da aba pra cima (aí esta
   aba fica desalinhada das outras quatro, que é o defeito que o Boss pega
   de longe) e encolher a letra até ninguém ler. A saída certa foi tirar a
   cápsula: sem fundo, sem borda e sem respiro interno, a etiqueta tem 6,4
   px de altura e sobra folga nos dois lados. Continua legível porque é
   dourada em cima de barra escura, que é o maior contraste que o app tem. */
.mn-aba-selo {
  position: absolute; bottom: 3px; left: 50%; transform: translateX(-50%);
  font-style: normal;
  font-family: var(--fonte-rotulo); font-weight: 700;
  font-size: 0.4rem; letter-spacing: 0.14em; line-height: 1;
  color: var(--boss-ouro);
  white-space: nowrap; pointer-events: none;
}

/* ── O TICKER DOS APOIADORES FOI DESCONTINUADO (Boss, 15/09) ────────────
   Ele chegou a voltar nesta mesma noite e o Boss cortou na hora:
   "o ticker foi descontinuado, ele fica em apoiadores, o ranking apenas".

   Fica o registro pra nunca mais nascer de novo: os apoiadores aparecem em
   UM lugar só, o RANKING DE APOIADORES, que é o primeiro item da folha do
   MAIS. Nada de nome rolando no menu.

   O `#menu` voltou a ser bloco comum junto com ele: a coluna flex com
   `min-height: 100dvh` existia só pra empurrar o ticker até o pé da tela.
   O que ficou está no `git show` do commit que tirou. */

/* ── A SUGESTÃO DA BUSCA ────────────────────────────────────────────────
   As 5 cartas que aparecem embaixo do campo enquanto a pessoa digita.

   `position: absolute` NÃO é enfeite: é o que faz a lista não empurrar
   nada. Se ela ocupasse altura de verdade, os 5 atalhos e os 7 cartões
   desceriam a cada letra digitada, e o menu que cabe numa tela deixaria
   de caber. Ela flutua por cima, e o resto do menu fica exatamente onde
   estava.

   z-index alto o suficiente pra passar por cima dos cartões (que ficam no
   --z-conteudo) e baixo o suficiente pra ficar embaixo da barra de abas. */
.bs-painel {
  position: absolute; top: calc(100% + 6px); left: 0; right: 0; z-index: 50;
  padding: 6px;
  background: linear-gradient(180deg, rgba(3,18,8,0.98), rgba(1,10,4,0.99));
  border: 1px solid var(--borda);
  border-radius: var(--canto-m);
  box-shadow: var(--brilho-verde), 0 18px 40px rgba(0,0,0,0.6);
  backdrop-filter: blur(14px);
  overflow: hidden;
}
.bs-painel[hidden] { display: none !important; }

.bs-linha {
  display: flex; align-items: center; gap: 10px;
  width: 100%; padding: 6px;
  border-radius: 10px;
  transition: background .12s;
  cursor: pointer;
}
.bs-linha:active { background: rgba(0,200,75,0.12); }

/* A foto da carta é QUADRADA (256x256 é o que o ADM publica), então a
   moldura também é. Esticar num retângulo cortaria a cabeça do jogador. */
.bs-foto {
  flex: 0 0 auto;
  width: 40px; height: 40px; border-radius: 9px;
  overflow: hidden;
  background: rgba(255,255,255,0.05);
  /* a cor da AVALIAÇÃO DO BOSS naquela carta, que vem do ADM. É a mesma
     cor que ela tem na ficha e na tier list: quem já conhece o app lê a
     nota antes de ler o nome. */
  border: 1px solid var(--cat, var(--borda-fraca));
  box-shadow: 0 0 10px -2px var(--cat, transparent);
}
.bs-foto img { width: 100%; height: 100%; object-fit: cover; display: block; }

.bs-corpo { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.bs-nome {
  font-family: var(--fonte-titulo); font-weight: 700;
  font-size: 0.95rem; letter-spacing: 0.02em; line-height: 1.1;
  color: var(--texto-forte);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.bs-meta {
  font-family: var(--fonte-rotulo); font-weight: 600;
  font-size: 0.6rem; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--texto-fraco);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.bs-seta { flex: 0 0 auto; width: 15px; height: 15px; color: var(--texto-fraco); }

/* A última linha, quando tem mais do que os 5 que cabem. Ela leva pra
   grade do VER, que é o mesmo lugar onde o ENTER sempre levou. */
.bs-todas {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  width: 100%; margin-top: 2px; padding: 9px;
  border-top: 1px solid var(--borda-fraca);
  font-family: var(--fonte-rotulo); font-weight: 700;
  font-size: 0.64rem; letter-spacing: 0.12em;
  color: var(--boss-verde);
  cursor: pointer;
}
.bs-todas svg { width: 13px; height: 13px; }

.bs-vazio {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  padding: 16px 10px;
  font-family: var(--fonte-rotulo); font-weight: 600;
  font-size: 0.7rem; letter-spacing: 0.06em;
  color: var(--texto-fraco);
}
.bs-vazio svg { width: 14px; height: 14px; }

/* ── A FOLHA DO MAIS: TUDO QUE EXISTE NO APP, EM LISTA ──────────────────
   O `z-index` é 880 de propósito: acima do conteúdo do menu e ABAIXO da
   barra de abas (900). O MAIS é uma ABA, não um modal - a barra continua
   visível por cima dele e a pessoa sai tocando INÍCIO, igual em qualquer
   app. Se ele cobrisse a barra, o único jeito de sair seria achar o X. */
#mn-mais {
  position: fixed; inset: 0; z-index: 880;
  display: flex; flex-direction: column;
  background: linear-gradient(180deg, rgba(2,14,6,0.97), rgba(1,8,3,0.99));
  backdrop-filter: blur(14px);
  opacity: 0; transform: translateY(16px); pointer-events: none;
  transition: opacity .18s ease, transform .18s ease;
}
#mn-mais.aberto { opacity: 1; transform: none; pointer-events: auto; }
#mn-mais[hidden] { display: none !important; }
@media (prefers-reduced-motion: reduce) { #mn-mais { transition: none; } }

.ms-topo {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: calc(env(safe-area-inset-top, 0px) + 14px) 16px 10px;
  border-bottom: 1px solid var(--borda-fraca);
}
.ms-topo h2 {
  margin: 0;
  font-family: var(--fonte-titulo); font-weight: 800;
  font-size: 1.5rem; letter-spacing: 0.06em; line-height: 1;
  color: var(--boss-ouro);
}
.ms-fechar {
  width: 34px; height: 34px; border-radius: 50%;
  display: grid; place-items: center;
  background: rgba(1,14,4,0.72);
  border: 1px solid var(--borda);
  color: var(--texto-forte);
  transition: transform .12s;
  cursor: pointer;
}
.ms-fechar:active { transform: scale(0.94); }
.ms-fechar svg { width: 16px; height: 16px; }

/* O respiro de baixo é a barra inteira mais uma folga: sem ele a última
   linha da lista nasce ATRÁS da barra de abas e ninguém consegue tocar. */
.ms-rolo {
  flex: 1; overflow-y: auto; -webkit-overflow-scrolling: touch;
  padding: 12px 12px calc(var(--barra-total) + 18px);
}
.ms-grupo { margin-bottom: 14px; }
.ms-grupo h3 {
  margin: 0 0 6px 6px;
  font-family: var(--fonte-rotulo); font-weight: 700;
  font-size: 0.6rem; letter-spacing: 0.16em;
  color: var(--texto-fraco); text-transform: uppercase;
}
.ms-linha {
  display: flex; align-items: center; gap: 11px;
  width: 100%; margin-bottom: 6px;
  padding: 9px 10px;
  background: rgba(1,14,4,0.6);
  border: 1px solid var(--borda-fraca);
  border-radius: var(--canto-m);
  transition: border-color .15s, transform .12s;
  cursor: pointer;
}
.ms-linha:active { transform: scale(0.985); border-color: var(--borda); }
.ms-ico {
  flex: 0 0 auto;
  width: 30px; height: 30px; border-radius: 9px;
  display: grid; place-items: center;
  background: rgba(0,200,75,0.10);
  border: 1px solid var(--borda);
  color: var(--boss-verde);
}
.ms-ico svg { width: 17px; height: 17px; }
.ms-corpo { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.ms-nome {
  display: flex; align-items: center; gap: 6px;
  font-family: var(--fonte-titulo); font-weight: 700;
  font-size: 0.98rem; letter-spacing: 0.02em; line-height: 1.1;
  color: var(--texto-forte);
}
.ms-selo {
  font-style: normal;
  font-family: var(--fonte-rotulo); font-weight: 700;
  font-size: 0.48rem; letter-spacing: 0.1em; line-height: 1;
  color: var(--boss-ouro);
  background: rgba(232,183,58,0.14);
  border: 1px solid rgba(232,183,58,0.35);
  border-radius: 999px; padding: 2px 5px;
}
/* Uma linha só, com reticências: a descrição é dica, não é texto pra ler.
   Duas linhas fariam as 24 linhas da lista terem alturas diferentes.
   `display: block` não é enfeite: em `span` (que nasce inline) o
   `text-overflow: ellipsis` simplesmente não vale, e o texto sai cortado
   no seco em vez de terminar em reticências. */
.ms-desc {
  display: block;
  font-family: var(--fonte-texto); font-size: 0.68rem; line-height: 1.2;
  color: var(--texto-fraco); text-align: left;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ms-seta { flex: 0 0 auto; width: 16px; height: 16px; color: var(--texto-fraco); }
.ms-pe {
  padding: 8px 0 4px; text-align: center;
  font-family: var(--fonte-rotulo); font-size: 0.6rem; letter-spacing: 0.1em;
  color: var(--texto-fraco); text-transform: uppercase;
}

/* ── AS DUAS MOEDAS GRANDES, DENTRO DA FOLHA DE AVISO ───────────────────
   É o único lugar do app onde dá pra LER "BOSS POINTS" e "BOSS COINS", e
   por isso ele existe: lá em cima no menu elas têm 19 px e o nome escrito
   na arte não lê. Quem abre a LOJA ou toca numa das pilhas cai aqui. */
.mn-breve-moedas { display: flex; justify-content: center; gap: 24px; margin-bottom: 14px; }
.mn-breve-moeda { display: flex; flex-direction: column; align-items: center; gap: 7px; }
.mn-breve-moeda img { width: 66px; height: 66px; display: block; }
.mn-breve-moeda b {
  font-family: var(--fonte-rotulo); font-weight: 700;
  font-size: 0.58rem; letter-spacing: 0.1em;
  color: var(--texto-fraco);
}

/* ── QUANDO A BARRA DE BAIXO ESTÁ DESLIGADA ─────────────────────────────
   Pedido do Boss (15/09): poder ocultar a barra de abas pela configuração.
   Quem liga e desliga é o `js/nucleo/barra.js`, que põe esta classe no
   `body`.

   SÃO DUAS COISAS, e a segunda é a que passa despercebido: além de a barra
   sumir, o RESPIRO que o menu reservava pra ela tem que sumir junto. O
   `#menu` guarda `--barra-total` embaixo (58 px mais a área de gesto do
   celular) pra última fileira de botão não nascer atrás da barra; sem
   barra, esse respiro vira um buraco de 68 px no pé da tela.

   A folha do MAIS tem o mesmo respiro pelo mesmo motivo, e entra junto. */
body.sem-barra #menu-barra { display: none !important; }
body.sem-barra #menu { padding-bottom: calc(env(safe-area-inset-bottom, 0px) + 10px); }
body.sem-barra .ms-rolo { padding-bottom: calc(env(safe-area-inset-bottom, 0px) + 18px); }

/* ── O CONTROLE DO SOM, DENTRO DA CONFIGURAÇÃO DO APP DE HOJE ───────────
   A seção é injetada no modal do legado pelo `js/nucleo/som.js`. O ON/OFF
   usa o `.vcfg-toggle` que já existe lá (pra ficar igual ao MODO LEVE);
   só a linha do volume é nova, e mora aqui porque este arquivo entra
   DEPOIS na cascata e não precisa brigar com o CSS antigo. */
#som-cfg .som-cfg-vol {
  display: flex; align-items: center; gap: 10px; margin-top: 12px;
  transition: opacity .15s;
}
#som-cfg .som-cfg-vol.mudo { opacity: 0.35; }
#som-cfg .som-cfg-vol-rot {
  font-family: var(--fonte-rotulo); font-weight: 700;
  font-size: 0.62rem; letter-spacing: 0.1em; color: var(--texto-fraco);
}
#som-cfg input[type="range"] {
  flex: 1; min-width: 0; height: 22px;
  accent-color: var(--boss-verde);
}
#som-cfg .som-cfg-vol-num {
  min-width: 40px; text-align: right;
  font-family: var(--fonte-titulo); font-weight: 700;
  font-size: 0.95rem; color: var(--boss-verde);
}

/* ── CELULAR ESTREITO (ate 360) ─────────────────────────────────────────
   A descricao e de uma linha so, com reticencias. Isso e certo, mas num
   celular de 320 quase toda frase batia no limite e virava "Por evento e
   pos...". Uma fonte um pouco menor nessa faixa resolve sem mexer no
   texto nem quebrar a regra da linha unica. */
@media (max-width: 360px) {
  .mn-cartao .desc { font-size: 0.66rem; }
  .mn-cartao.baixo .desc { font-size: 0.6rem; }
  .mn-cartao.baixo .titulo { font-size: 0.78rem; }
  /* A VIP ficou 10% mais estreita em 15/09 e em 320 a descricao passou a
     cortar com reticencias. A regra generica logo acima nao pega nela:
     `.mn-cartao.vip .desc` tem especificidade maior. Entao a linha dela e
     explicita, e o ACESSAR cede 2 px de padding. */
  .mn-cartao.vip .desc { font-size: 0.62rem; }
  .mn-vip-acessar { padding: 7px 10px; }
  .mn-cartao .titulo { font-size: 1.18rem; }
  .mn-cartao .seta { width: 21px; height: 21px; right: 7px; bottom: 7px; }
  /* 1/5 da tela em 320 dá 54 px de largura: "BUILDER" e "SEU TIME" batem
     na parede com a fonte cheia. */
  .mn-atalho { padding: 7px 0; gap: 3px; }
  .mn-atalho svg { width: 18px; height: 18px; }
  .mn-atalho b { font-size: 0.52rem; }

  /* As duas pilhas de recurso somam 97 px em 320, contra 114 disponíveis
     antes da logo. Cabe, mas com 17 px de folga só - e é ela que segura o
     dia em que o número virar dois dígitos. Aqui elas cedem 6 px cada uma
     pra folga virar 29. */
  .mn-recurso { padding: 3px 7px 3px 3px; gap: 4px; }
  .mn-recurso img { width: 17px; height: 17px; }
  .mn-recurso b { font-size: 0.8rem; }

  /* 1/5 de 320 dá 64 px de aba: "EM BREVE" com o espacejamento cheio
     encostaria nas bordas. */
  .mn-aba-selo { letter-spacing: 0.08em; }

  .bs-foto { width: 36px; height: 36px; }
  .bs-nome { font-size: 0.88rem; }
  .bs-meta { font-size: 0.56rem; }

  .ms-desc { font-size: 0.64rem; }
  .ms-nome { font-size: 0.92rem; }
  .ms-linha { gap: 9px; padding: 8px 9px; }
}


/* ── O BAIXAR ATT PISCA QUANDO TEM VERSAO NOVA ────────────────────────
   Ligado pelo `js/nucleo/atualizacao.js`.

   O QUE MUDOU EM 22/09, e por que
   ═══════════════════════════════
   O Boss: *"o botao BAIXAR ATT deve piscar sempre que houver uma
   atualizacao ou identificar que a versao do cara nao e a mais recente"*.

   Antes o aviso era UM ANEL DOURADO FINO a `inset: 2px`, pulsando so a
   opacidade entre 0,35 e 1. Num atalho de 68 px, com arte por baixo, isso
   passa despercebido: tecnicamente aceso, na pratica invisivel.

   Agora quem pisca e O BOTAO INTEIRO: o halo dourado respira em volta, a
   arte clareia junto e a pilula NOVA pisca meio ciclo atrasada, pra o olho
   pegar o movimento mesmo sem estar olhando pra la.

   NAO e pisca-pisca de alarme: e a mesma luz de borda que o app inteiro
   usa, indo e voltando em 2 s. E ele para SOZINHO quando a atualizacao
   entra (quem apaga a classe e o `acender(false)`).

   Quem tem "reduzir movimento" ligado ve tudo aceso e parado.             */
.mn-atalho.mn-atalho-nova-att {
  position: relative;
  border-color: var(--boss-ouro, #e8b73a);
  animation: mnAttPisca 2s ease-in-out infinite;
}
/* ⚠️ TUDO DENTRO DA CAIXA: o atalho tem canto recortado por `clip-path`,
   e o que sai da caixa e cortado calado (a primeira versao punha o anel a
   -3px e a pilula a -7px, e a medida dizia "visivel" com nada na tela). */
.mn-atalho.mn-atalho-nova-att::after {
  content: ''; position: absolute; inset: 2px; border-radius: inherit;
  border: 2px solid var(--boss-ouro, #e8b73a); pointer-events: none;
  animation: mnNovaAtt 2s ease-in-out infinite;
}
/* O halo e o `box-shadow`, e nao um segundo elemento, justamente porque o
   `clip-path` do atalho cortaria qualquer filho que saisse da caixa. */
@keyframes mnAttPisca {
  0%, 100% { box-shadow: 0 0 0 0 rgba(232,183,58,0);    filter: none; }
  50%      { box-shadow: 0 0 16px 2px rgba(232,183,58,.55); filter: brightness(1.25); }
}
@keyframes mnNovaAtt {
  0%, 100% { opacity: .28; transform: scale(1); }
  50%      { opacity: 1;   transform: scale(1.05); }
}
.mn-nova-att {
  position: absolute; top: 5px; right: 5px; z-index: 3;
  padding: 3px 7px; border-radius: 999px;
  background: var(--boss-ouro, #e8b73a); color: #0a0f0c;
  font-family: var(--fonte-rotulo, inherit); font-weight: 800;
  font-size: 0.58rem; letter-spacing: 0.1em; line-height: 1;
  box-shadow: 0 2px 10px rgba(232,183,58,0.5);
  /* meio ciclo atrasada em relacao ao botao: enquanto um apaga, o outro
     acende, e sempre tem alguma coisa se movendo ali */
  animation: mnPilulaPisca 2s ease-in-out infinite;
  animation-delay: 1s;
}
@keyframes mnPilulaPisca {
  0%, 100% { opacity: 1;  transform: scale(1); }
  50%      { opacity: .4; transform: scale(0.92); }
}
@media (prefers-reduced-motion: reduce) {
  .mn-atalho.mn-atalho-nova-att,
  .mn-atalho.mn-atalho-nova-att::after,
  .mn-nova-att { animation: none; opacity: 1; }
  .mn-atalho.mn-atalho-nova-att { box-shadow: 0 0 16px 2px rgba(232,183,58,.55); }
}
