Mudanças entre as edições de "Widget:Conquistas"
Ir para navegação
Ir para pesquisar
m |
m |
||
| (6 revisões intermediárias pelo mesmo usuário não estão sendo mostradas) | |||
| Linha 13: | Linha 13: | ||
Sem ele, os rewards aparecem como wikitext cru e sem tooltip. | Sem ele, os rewards aparecem como wikitext cru e sem tooltip. | ||
--> | --> | ||
<div class="gla-conquistas-root"> | <!-- | ||
Atributos no root: | |||
data-hidden-style controla o MARCADOR visual das conquistas hidden=true. | |||
Valores aceitos: "badge" | "stripes" | "ribbon" | "stamp" | "subtle". | |||
Default escolhido: "ribbon" (fita diagonal cinza "SECRETA" no canto). | |||
data-reveal-mode controla a CENSURA do conteúdo das hidden=true. O | |||
conteúdo continua no HTML — só fica visualmente coberto até o jogador | |||
clicar pra revelar (anti-spoiler). Valores aceitos: | |||
"none" — sem censura | |||
"blur" — título e descrição borrados (default) | |||
"redacted" — tarjas escuras estilo doc classificado | |||
"placeholder" — texto substituído por "???" | |||
"veil" — card inteiro coberto por overlay com CTA "clique" | |||
Pra trocar qualquer um, edita o atributo abaixo. | |||
--> | |||
<div class="gla-conquistas-root" data-hidden-style="ribbon" data-reveal-mode="blur"> | |||
<div class="gla-conquistas-headerbox"> | <div class="gla-conquistas-headerbox"> | ||
<div class="gla-conquistas-header"> | <div class="gla-conquistas-header"> | ||
| Linha 20: | Linha 38: | ||
</div> | </div> | ||
<div class="gla-conquistas-tabs"> | <div class="gla-conquistas-toolbar"> | ||
<div class="gla-conquistas-tabs-scroll"> | |||
<div class="gla-conquistas-tabs"> | |||
<span class="gla-conquistas-tab is-active" data-tab="geral">Geral</span> | |||
<span class="gla-conquistas-tab" data-tab="personagens">Personagens</span> | |||
<span class="gla-conquistas-tab" data-tab="missao">Missão</span> | |||
<span class="gla-conquistas-tab" data-tab="bau">Baú</span> | |||
<span class="gla-conquistas-tab" data-tab="navegacao">Navegação</span> | |||
<span class="gla-conquistas-tab" data-tab="pvp">PvP</span> | |||
<span class="gla-conquistas-tab" data-tab="pve">PvE</span> | |||
<span class="gla-conquistas-tab" data-tab="coliseu">Coliseu</span> | |||
<span class="gla-conquistas-tab" data-tab="poneglyph">Poneglyph</span> | |||
<span class="gla-conquistas-tab" data-tab="indicacao">Indicação</span> | |||
<span class="gla-conquistas-tab" data-tab="celular">Celular</span> | |||
<span class="gla-conquistas-tab" data-tab="bossrush">Boss Rush</span> | |||
</div> | |||
</div> | |||
<div class="gla-conquistas-controls"> | |||
<input type="text" class="gla-conquistas-search" placeholder="Buscar conquista..."> | |||
<div class="gla-conquistas-filters" id="gla-filter-default" style="display:none"> | |||
<span class="gla-conquistas-filter is-active" data-filter="all">Todas</span> | |||
<span class="gla-conquistas-filter" data-filter="normal">Normal</span> | |||
<span class="gla-conquistas-filter" data-filter="hidden">Secreta</span> | |||
</div> | |||
<div class="gla-conquistas-filters" id="gla-filter-coliseu" style="display:none"> | |||
<span class="gla-conquistas-filter is-active" data-filter="all">Todas</span> | |||
<span class="gla-conquistas-filter" data-filter="onemany">One Man Army</span> | |||
<span class="gla-conquistas-filter" data-filter="corrida">Corrida Colosseum</span> | |||
</div> | |||
</div> | </div> | ||
</div> | </div> | ||
| Linha 99: | Linha 121: | ||
<style> | <style> | ||
/* Fonte para labels pequenos em maiúsculas — sem isso o navegador usa | |||
a sans-serif do skin, que fica fininha demais a 11px com tracking. */ | |||
@import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@600;700&display=swap'); | |||
/* ─── Variáveis ──────────────────────────────────────────────────────── */ | |||
/* Tema branco fixo. Azul fica reservado para detalhes (tab/filtro ativo, | |||
foco da busca, label da recompensa, chevron, hover). Sem dark mode | |||
automático — o widget deve manter o mesmo visual independente do skin. */ | |||
.gla-conquistas-root { | |||
color-scheme: light; | |||
/* Texto */ | |||
--gla-ink: #0f172a; | |||
/* slate-900 — título e texto principal */ | |||
--gla-ink-2: #475569; | |||
/* slate-600 — texto secundário */ | |||
--gla-dim: #94a3b8; | |||
/* slate-400 — placeholder */ | |||
--gla-dim-2: #cbd5e1; | |||
/* slate-300 — bordas sutis */ | |||
/* Superfícies (todas claras) */ | |||
--gla-paper: #ffffff; | |||
--gla-paper-2: #f8fafc; | |||
/* slate-50 — hover sutil */ | |||
--gla-paper-3: #f1f5f9; | |||
/* slate-100 — chip recompensa */ | |||
--gla-rule: #e2e8f0; | |||
/* slate-200 — bordas/divisores */ | |||
/* Accent azul (só pra detalhes) */ | |||
--gla-accent: #2563eb; | |||
/* blue-600 */ | |||
--gla-accent-soft: #60a5fa; | |||
/* blue-400 */ | |||
--gla-accent-bg: #eff6ff; | |||
/* blue-50 — focus ring */ | |||
/* Sombra discreta */ | |||
--gla-shadow: 0 1px 2px rgba(15, 23, 42, 0.04), | |||
0 1px 3px rgba(15, 23, 42, 0.06); | |||
} | |||
/* Força tema claro mesmo se o skin/OS estiver em dark — o widget tem | |||
identidade visual própria e não deve trocar de cor com o ambiente. */ | |||
.gla-conquistas-root, | |||
.gla-conquistas-root * { | |||
color-scheme: light; | |||
} | |||
/* ─── Layout principal ───────────────────────────────────────────────── */ | |||
.gla-conquistas-root { | |||
color: var(--gla-ink); | |||
} | |||
.gla-conquistas-headerbox { | .gla-conquistas-headerbox { | ||
margin: 0 0 | margin: 0 0 16px; | ||
padding: | padding: 0; | ||
background: transparent; | |||
border: none; | |||
} | |||
.gla-conquistas-header { | |||
display: none; | |||
} | } | ||
.gla-conquistas- | /* ─── Toolbar (tabs + busca) ─────────────────────────────────────────── */ | ||
/* Sem chrome próprio — só agrupa tabs e controles. */ | |||
.gla-conquistas-toolbar { | |||
display: block; | |||
width: 100%; | |||
background: transparent; | |||
border: none; | |||
border-radius: 0; | |||
box-shadow: none; | |||
padding: 0; | |||
} | } | ||
.gla-conquistas- | /* ─── Wrapper das abas ───────────────────────────────────────────────── */ | ||
/* Sem scroll horizontal. As abas usam flex-wrap pra quebrar linha | |||
naturalmente em telas estreitas. */ | |||
.gla-conquistas-tabs-scroll { | |||
position: relative; | |||
overflow: visible; | |||
padding: 0; | |||
background: transparent; | |||
border: none; | |||
border-radius: 0; | |||
} | } | ||
| Linha 124: | Linha 215: | ||
flex-wrap: wrap; | flex-wrap: wrap; | ||
gap: 6px; | gap: 6px; | ||
padding: 0; | |||
width: 100%; | |||
min-width: 0; | |||
box-sizing: border-box; | |||
margin: 0 0 12px; | |||
} | } | ||
/* ─── Tab pill / botão ───────────────────────────────────────────────── */ | |||
/* Botões redondos clean: branco com borda cinza, hover sutil, | |||
ativo em azul sólido. Sem fichário, sem stripe. */ | |||
.gla-conquistas-tab { | .gla-conquistas-tab { | ||
flex: 0 0 auto; | |||
text-align: center; | |||
white-space: nowrap; | |||
border: 1px solid | font-size: 13px; | ||
background: | font-weight: 600; | ||
padding: 7px 14px; | |||
border: 1px solid var(--gla-rule); | |||
border-radius: 999px; | |||
background: var(--gla-paper); | |||
color: var(--gla-ink-2); | |||
cursor: pointer; | cursor: pointer; | ||
box-sizing: border-box; | |||
user-select: none; | |||
transition: background 0.15s, color 0.15s, border-color 0.15s, box-shadow 0.15s; | |||
transition: | |||
} | } | ||
.gla-conquistas-tab:hover { | .gla-conquistas-tab:hover { | ||
background: | background: var(--gla-paper-2); | ||
color: var(--gla-ink); | |||
color: | border-color: var(--gla-dim-2); | ||
} | } | ||
.gla-conquistas-tab.is-active { | .gla-conquistas-tab.is-active { | ||
background: | background: var(--gla-accent); | ||
color: #ffffff; | |||
border-color: var(--gla-accent); | |||
box-shadow: 0 1px 2px rgba(37, 99, 235, 0.25); | |||
} | |||
.gla-conquistas-tab.is-active:hover { | |||
background: var(--gla-accent); | |||
color: #ffffff; | |||
border-color: var(--gla-accent); | |||
} | |||
/* ─── Controles (busca + filtros) ────────────────────────────────────── */ | |||
.gla-conquistas-controls { | |||
display: flex; | |||
align-items: center; | |||
gap: 10px; | |||
flex-wrap: wrap; | |||
width: 100%; | |||
box-sizing: border-box; | |||
background: transparent; | |||
border: none; | |||
padding: 0; | |||
margin: 0; | |||
} | |||
/* Cresce no espaço livre até max-width; os filtros ficam encostados à | |||
direita dela em vez de no fim da linha. */ | |||
.gla-conquistas-search { | |||
flex: 1 1 auto; | |||
min-width: 160px; | |||
max-width: 360px; | |||
padding: 8px 16px; | |||
border: 1px solid var(--gla-rule); | |||
border-radius: 999px; | |||
font-size: 13px; | |||
background: var(--gla-paper); | |||
color: var(--gla-ink); | |||
outline: none; | |||
font-family: inherit; | |||
transition: box-shadow 0.15s, border-color 0.15s; | |||
} | |||
.gla-conquistas-search::placeholder { | |||
color: var(--gla-dim); | |||
} | |||
.gla-conquistas-search:focus { | |||
box-shadow: 0 0 0 3px var(--gla-accent-bg); | |||
border-color: var(--gla-accent); | |||
} | |||
/* ─── Filtros ────────────────────────────────────────────────────────── */ | |||
/* Encostados na search via gap natural do .gla-conquistas-controls. */ | |||
.gla-conquistas-filters { | |||
display: flex; | |||
gap: 6px; | |||
flex-wrap: wrap; | |||
} | |||
.gla-conquistas-filter { | |||
padding: 6px 14px; | |||
border: 1px solid var(--gla-rule); | |||
border-radius: 999px; | |||
background: var(--gla-paper); | |||
font-size: 12px; | |||
font-weight: 600; | |||
color: var(--gla-ink-2); | |||
cursor: pointer; | |||
transition: background 0.15s, color 0.15s, border-color 0.15s; | |||
} | |||
.gla-conquistas-filter:hover { | |||
background: var(--gla-paper-2); | |||
color: var(--gla-ink); | |||
border-color: var(--gla-dim-2); | |||
} | |||
.gla-conquistas-filter.is-active { | |||
background: var(--gla-accent); | |||
color: #ffffff; | color: #ffffff; | ||
border-color: | border-color: var(--gla-accent); | ||
} | } | ||
/* | /* ─── Painéis ────────────────────────────────────────────────────────── */ | ||
.gla-conquistas-panel { | .gla-conquistas-panel { | ||
margin: | margin: 14px 0 0; | ||
display: none; | display: none; | ||
} | } | ||
| Linha 163: | Linha 343: | ||
} | } | ||
.gla-conquistas-source { | .gla-conquistas-source { | ||
display: none; | display: none; | ||
} | } | ||
.gla-list { | .gla-list { | ||
display: flex; | display: flex; | ||
| Linha 176: | Linha 353: | ||
} | } | ||
/* | /* ─── Card ───────────────────────────────────────────────────────────── */ | ||
/* Branco com borda cinza. Hover marca borda azul (detalhe). */ | |||
.gla-item { | .gla-item { | ||
display: flex; | display: flex; | ||
flex-direction: column; | flex-direction: column; | ||
background: var(--gla-paper); | |||
border: 1px solid var(--gla-rule); | |||
border-radius: 12px; | border-radius: 12px; | ||
border: | box-shadow: var(--gla-shadow); | ||
transition: border-color 0.15s, box-shadow 0.15s; | |||
} | |||
.gla-item.has-spoiler:hover { | |||
border-color: var(--gla-accent-soft); | |||
box-shadow: 0 2px 8px -2px rgba(37, 99, 235, 0.18); | |||
} | } | ||
| Linha 188: | Linha 373: | ||
display: flex; | display: flex; | ||
align-items: center; | align-items: center; | ||
gap: 16px; | gap: 16px; | ||
padding: | padding: 14px 18px; | ||
min-height: | min-height: 76px; | ||
position: relative; | |||
} | |||
/* Abinha do spoiler vive sobreposta ao bottom da linha de conteúdo, | |||
sem adicionar padding-bottom — assim cards com ou sem spoiler | |||
têm exatamente a mesma altura. */ | |||
.gla-item-left { | |||
display: flex; | |||
align-items: center; | |||
gap: 14px; | |||
flex: 1; | |||
min-width: 0; | |||
} | } | ||
/* | .gla-item-icon { | ||
flex: 0 0 auto; | |||
display: flex; | |||
align-items: center; | |||
justify-content: center; | |||
} | |||
/* Ícone respeita o tamanho do arquivo na wiki (recomendado: 52×52). | |||
Sem dimensões fixas. */ | |||
.gla-item-icon img { | |||
object-fit: contain; | |||
border: none !important; | |||
padding: 0 !important; | |||
background: none !important; | |||
box-shadow: none !important; | |||
display: block; | |||
} | |||
/* Título preto (sem azul). Azul fica só nos detalhes. */ | |||
.gla-item-title { | |||
font-size: 15px; | |||
font-weight: 700; | |||
color: var(--gla-ink); | |||
line-height: 1.25; | |||
} | |||
.gla-conquistas-root .gla-item-title { | |||
color: var(--gla-ink); | |||
} | |||
.gla-item-desc { | |||
font-size: 13px; | |||
color: var(--gla-ink-2); | |||
margin-top: 2px; | |||
line-height: 1.4; | |||
} | |||
/* ─── Recompensa ─────────────────────────────────────────────────────── */ | |||
/* Bloco externo: NÃO tem chrome próprio — só agrupa o label (acima) | |||
e o chip de itens (.reward-wrapper). Label fora da box pra não ser | |||
comprimido quando o chip encolhe com poucos itens. */ | |||
.gla-item-reward { | |||
flex-shrink: 0; | |||
display: flex; | |||
flex-direction: column; | |||
align-items: center; | |||
gap: 6px; | |||
background: transparent; | |||
border: none; | |||
padding: 0; | |||
align-self: center; | |||
margin-top: -4px; | |||
position: relative; | |||
/* ancora pro popover "+M" */ | |||
} | |||
.gla-item-reward-label { | |||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif; | |||
font-size: 11px; | |||
font-weight: 700; | |||
letter-spacing: 0.16em; | |||
text-transform: uppercase; | |||
color: var(--gla-accent); | |||
white-space: nowrap; | |||
} | |||
/* Chip de itens — agora é o .reward-wrapper (emitido pelo Lua/Widget:Item). | |||
Encolhe com a quantidade (min-width pra 1 item, max-width pra caber | |||
5 + chip "+M" sem wrap). */ | |||
.gla-item-reward .reward-wrapper { | |||
display: block; | |||
background: var(--gla-paper-3); | |||
border: 1px solid var(--gla-rule); | |||
border-radius: 10px; | |||
padding: 7px 12px 9px; | |||
min-width: 72px; | |||
/* 285 = espaço pra 4 ícones (4×48 + 3×4) + chip "+M" (48) + gaps + padding. */ | |||
max-width: 285px; | |||
width: fit-content; | |||
box-sizing: border-box; | |||
} | |||
/* ─── Botão spoiler (abinha no bottom-center) ────────────────────────── */ | |||
/* Posicionado absolutamente no bottom-center do .gla-item-main. | |||
Pequeno e horizontalmente centralizado — fica no "corredor" central | |||
livre entre o título/desc à esquerda e a recompensa à direita, | |||
sem aumentar a altura do card. */ | |||
.gla-item-spoiler-toggle { | |||
position: absolute; | |||
/* main padding-left (18) + icon (52) + gap (14) = 84 → alinhado com o começo do título. | |||
A versão anterior usava left:50% (centrado), mas o chip da recompensa | |||
encavalava em telas mais apertadas. Ancorar à esquerda elimina a colisão. */ | |||
left: 84px; | |||
bottom: 6px; | |||
display: inline-flex; | |||
align-items: center; | |||
gap: 6px; | |||
margin: 0; | |||
border: 1px solid var(--gla-rule); | |||
background: var(--gla-paper); | |||
border-radius: 999px; | |||
padding: 2px 12px 3px; | |||
font: inherit; | |||
color: var(--gla-ink-2); | |||
cursor: pointer; | |||
z-index: 1; | |||
transition: background 0.15s, border-color 0.15s, color 0.15s; | |||
} | |||
.gla-item-spoiler-toggle:hover { | |||
background: var(--gla-accent-bg); | |||
border-color: var(--gla-accent-soft); | |||
color: var(--gla-accent); | |||
} | |||
.gla-item-spoiler-toggle:hover .gla-item-chevron { | |||
color: var(--gla-accent); | |||
} | |||
.gla-item-spoiler-text { | |||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif; | |||
font-size: 11px; | |||
font-weight: 700; | |||
letter-spacing: 0.1em; | |||
text-transform: uppercase; | |||
} | |||
/* ─── Chevron (desenhado via border-corner) ─────────────────────────── */ | |||
/* O caractere `›` que o Lua emite não é centralizado dentro do seu | |||
glifo — girar como texto fica torto. Em vez disso esconde o texto | |||
(font-size 0) e desenha o chevron via pseudo-elemento com | |||
border-right + border-top a 45°. Esse shape é perfeitamente simé- | |||
trico, então rotacionar o span pai em volta do centro funciona. */ | |||
.gla-item-chevron { | |||
position: relative; | |||
display: inline-block; | |||
width: 12px; | |||
height: 12px; | |||
font-size: 0; | |||
line-height: 0; | |||
color: var(--gla-accent); | |||
flex-shrink: 0; | |||
transform-origin: 50% 50%; | |||
/* Curva elástica leve — chega no destino com um micro-overshoot | |||
em vez de parar seco no 90°. */ | |||
transition: transform 0.42s cubic-bezier(0.34, 1.56, 0.64, 1), | |||
color 0.15s ease; | |||
user-select: none; | |||
} | |||
.gla-item-chevron::before { | |||
content: ""; | |||
position: absolute; | |||
top: 50%; | |||
left: 50%; | |||
width: 6px; | |||
height: 6px; | |||
border-top: 2px solid currentColor; | |||
border-right: 2px solid currentColor; | |||
transform: translate(-65%, -50%) rotate(45deg); | |||
} | |||
.gla-item.has-spoiler.is-open .gla-item-chevron { | |||
transform: rotate(90deg); | |||
} | |||
/* ─── Spoiler aberto ─────────────────────────────────────────────────── */ | |||
.gla-item-spoiler { | .gla-item-spoiler { | ||
display: none; | display: none; | ||
border-top: 1px solid | border-top: 1px solid var(--gla-rule); | ||
padding: 14px | background: var(--gla-paper-2); | ||
gap: | padding: 14px 18px; | ||
gap: 18px; | |||
flex-direction: row; | flex-direction: row; | ||
align-items: flex-start; | align-items: flex-start; | ||
border-radius: 0 0 12px 12px; | |||
} | } | ||
.gla-item.is-open .gla-item-spoiler { | .gla-item.is-open .gla-item-spoiler { | ||
display: flex; | display: flex; | ||
animation: gla-spoiler-in 0.35s cubic-bezier(0.22, 1, 0.36, 1); | |||
} | } | ||
@keyframes gla-spoiler-in { | |||
from { | |||
opacity: 0; | |||
transform: translateY(-6px); | |||
} | |||
to { | |||
opacity: 1; | |||
transform: translateY(0); | |||
} | |||
} | } | ||
.gla-item-spoiler-info { | .gla-item-spoiler-info { | ||
flex: 1; | flex: 1; | ||
font-size: | font-size: 14px; | ||
color: | color: var(--gla-ink-2); | ||
line-height: 1. | line-height: 1.55; | ||
min-width: 0; | min-width: 0; | ||
} | |||
.gla-item-spoiler-info a { | |||
color: var(--gla-accent); | |||
} | } | ||
.gla-item-spoiler-media { | .gla-item-spoiler-media { | ||
flex | flex: 0 0 360px; | ||
max-width: | max-width: 480px; | ||
} | } | ||
.gla-item-spoiler-media img, | .gla-item-spoiler-media img, | ||
.gla-item-spoiler-media video { | .gla-item-spoiler-media video { | ||
width: 100%; | |||
height: auto; | |||
border-radius: 8px; | border-radius: 8px; | ||
border: | border: 1px solid var(--gla-rule) !important; | ||
display: block; | |||
} | |||
/* ─── Card "secreta no jogo" ──────────────────────────────────────────── | |||
O estado "oculta" não esconde nada — só marca visualmente que ESSA | |||
conquista aparece como ??? no jogo. O marcador precisa ser legível | |||
pra que o jogador pareando game ↔ wiki entenda de imediato "ah, | |||
por isso que essa não aparece pra mim no client". | |||
Cinco variantes selecionáveis via data-hidden-style no root: | |||
- badge : pill "Oculta no jogo" inline ao lado do título | |||
- stripes : padrão diagonal sutil + tag flutuante no topo | |||
- ribbon : fita diagonal cinza "SECRETA" no canto top-left ← default | |||
- stamp : carimbo translúcido "OCULTA" sobreposto à direita | |||
- subtle : só italic + cinza (controle: o que existia antes) | |||
Acento dos marcadores: slate (cinza neutro). Mantém o tema | |||
branco+azul "limpo" — o cinza só sinaliza estado "secreta" sem | |||
competir com o azul institucional. */ | |||
.gla-conquistas-root { | |||
--gla-secret: #475569; | |||
/* slate-600 — ink/fill escuro */ | |||
--gla-secret-bg: #f1f5f9; | |||
/* slate-100 — fill claro */ | |||
--gla-secret-line: #cbd5e1; | |||
/* slate-300 — borda */ | |||
--gla-secret-soft: #f8fafc; | |||
/* slate-50 — bg do card */ | |||
} | |||
/* Baseline: card oculto recebe leve tint slate quase imperceptível. | |||
Não diminui contraste do conteúdo (título preto, desc slate-600 | |||
normal); só serve de "tinta de fundo" pra o card parecer um pouco | |||
diferente mesmo antes do marcador específico da variante. */ | |||
.gla-item.is-hidden, | |||
.gla-item[data-hidden="true"] { | |||
background: var(--gla-secret-soft); | |||
border-color: var(--gla-secret-line); | |||
position: relative; | |||
} | |||
.gla-item.is-hidden:hover, | |||
.gla-item[data-hidden="true"]:hover { | |||
border-color: var(--gla-secret); | |||
box-shadow: 0 2px 8px -2px rgba(71, 85, 105, 0.18); | |||
} | } | ||
.gla-item.is-hidden .gla-item-reward .reward-wrapper, | |||
.gla-item- | .gla-item[data-hidden="true"] .gla-item-reward .reward-wrapper { | ||
background: #ffffff; | |||
color: | border-color: var(--gla-secret-line); | ||
} | } | ||
.gla-item.is-hidden .gla-item- | .gla-item.is-hidden .gla-item-reward-label, | ||
.gla-item[data-hidden="true"] .gla-item- | .gla-item[data-hidden="true"] .gla-item-reward-label { | ||
color: | color: var(--gla-secret); | ||
} | } | ||
.gla-item. | /* ─── Reveal modes ────────────────────────────────────────────────────── | ||
Independente do marcador (badge/ribbon/etc), o conteúdo do card | |||
pode vir "censurado" e ser revelado ao clique — útil pra quem | |||
entra na wiki querendo evitar spoiler. Click em qualquer parte do | |||
card (menos chip de recompensa, links, botão de spoiler) adiciona | |||
.is-revealed via JS. | |||
"none" — sem censura | |||
"blur" — título+desc borrados (default) | |||
"redacted" — tarjas slate (estilo doc classificado) | |||
"placeholder" — texto vira "???" | |||
"veil" — overlay total com CTA "clique para revelar" | |||
O marcador (badge/ribbon/etc) continua visível em blur/redacted/ | |||
placeholder — o jogador SABE que é secreta, só não vê o conteúdo. | |||
No veil até o marcador é coberto. */ | |||
.gla-conquistas-root[data-reveal-mode="blur"] .gla-item[data-hidden="true"]:not(.is-revealed), | |||
.gla-conquistas-root[data-reveal-mode="redacted"] .gla-item[data-hidden="true"]:not(.is-revealed), | |||
.gla-conquistas-root[data-reveal-mode="placeholder"] .gla-item[data-hidden="true"]:not(.is-revealed), | |||
.gla-conquistas-root[data-reveal-mode="veil"] .gla-item[data-hidden="true"]:not(.is-revealed) { | |||
cursor: pointer; | cursor: pointer; | ||
} | } | ||
.gla-item. | .gla-item[data-hidden="true"] .gla-item-main, | ||
.gla-item[data-hidden="true"] .gla-item-title, | |||
.gla-item[data-hidden="true"] .gla-item-desc { | |||
transition: filter 0.25s ease, background-color 0.25s ease, color 0.25s ease; | |||
} | } | ||
/* | /* — BLUR | ||
.gla-conquistas- | Aplicado no .gla-item-main (pai que envolve icon + title + desc + | ||
reward + spoiler-toggle) — borra TUDO de uma vez. Antes só borrava | |||
título e descrição, mas o ícone da conquista também entregava a | |||
secreta. O ribbon "SECRETA" tá no ::before do .gla-item (fora do | |||
main), então continua nítido. */ | |||
.gla-conquistas-root[data-reveal-mode="blur"] .gla-item[data-hidden="true"]:not(.is-revealed) .gla-item-main { | |||
filter: blur(5px); | |||
user-select: none; | |||
} | } | ||
.gla-conquistas- | /* — REDACTED (tarjas estilo doc classificado) */ | ||
.gla-conquistas-root[data-reveal-mode="redacted"] .gla-item[data-hidden="true"]:not(.is-revealed) .gla-item-title, | |||
.gla-conquistas-root[data-reveal-mode="redacted"] .gla-item[data-hidden="true"]:not(.is-revealed) .gla-item-desc { | |||
background: #334155; | |||
color: transparent; | |||
border-radius: | border-radius: 3px; | ||
user-select: none; | |||
width: max-content; | |||
max-width: 100%; | |||
} | } | ||
.gla-conquistas- | .gla-conquistas-root[data-reveal-mode="redacted"] .gla-item[data-hidden="true"]:not(.is-revealed) .gla-item-title::after { | ||
display: none; | |||
} | } | ||
.gla-conquistas- | /* — PLACEHOLDER ("???") */ | ||
.gla-conquistas-root[data-reveal-mode="placeholder"] .gla-item[data-hidden="true"]:not(.is-revealed) .gla-item-title { | |||
color: transparent; | |||
font-size: 0 !important; | |||
line-height: 1.25; | |||
position: relative; | |||
} | } | ||
.gla-conquistas- | .gla-conquistas-root[data-reveal-mode="placeholder"] .gla-item[data-hidden="true"]:not(.is-revealed) .gla-item-title::before { | ||
content: "???"; | |||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif; | |||
font-size: 18px; | |||
font-weight: 700; | |||
letter-spacing: 0.2em; | |||
color: var(--gla-dim); | |||
font- | |||
color: | |||
} | } | ||
.gla-conquistas- | .gla-conquistas-root[data-reveal-mode="placeholder"] .gla-item[data-hidden="true"]:not(.is-revealed) .gla-item-title::after { | ||
display: none; | |||
} | } | ||
.gla-conquistas- | .gla-conquistas-root[data-reveal-mode="placeholder"] .gla-item[data-hidden="true"]:not(.is-revealed) .gla-item-desc { | ||
color: transparent; | |||
font-size: 0 !important; | |||
line-height: 1.4; | |||
position: relative; | |||
} | } | ||
.gla-conquistas-root[data-reveal-mode="placeholder"] .gla-item[data-hidden="true"]:not(.is-revealed) .gla-item-desc::before { | |||
.gla- | content: "??? ??? ??? ???"; | ||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif; | |||
font-size: 13px; | |||
letter-spacing: 0.15em; | |||
color: var(--gla-dim); | |||
} | } | ||
.gla- | /* — VEIL (overlay total cobrindo o card) */ | ||
.gla-conquistas-root[data-reveal-mode="veil"] .gla-item[data-hidden="true"]:not(.is-revealed) { | |||
overflow: hidden; | |||
} | } | ||
.gla- | .gla-conquistas-root[data-reveal-mode="veil"] .gla-item[data-hidden="true"]:not(.is-revealed)::after { | ||
content: ""; | |||
position: absolute; | |||
inset: 0; | |||
background: rgba(248, 250, 252, 0.92); | |||
backdrop-filter: blur(4px); | |||
-webkit-backdrop-filter: blur(4px); | |||
z-index: 4; | |||
pointer-events: none; | |||
transition: opacity 0.25s ease; | |||
} | } | ||
.gla-conquistas-root[data-reveal-mode="veil"] .gla-item[data-hidden="true"]:not(.is-revealed) .gla-item-main::before { | |||
content: "Conquista secreta — clique para revelar"; | |||
position: absolute; | |||
inset: 0; | |||
display: flex; | display: flex; | ||
align-items: center; | align-items: center; | ||
justify-content: center; | |||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif; | |||
font-size: 12px; | |||
font-weight: 700; | |||
letter-spacing: 0.14em; | |||
text-transform: uppercase; | |||
color: var(--gla-secret); | |||
z-index: 5; | |||
padding-left: 36px; | |||
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23475569' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><rect width='18' height='11' x='3' y='11' rx='2' ry='2'/><path d='M7 11V7a5 5 0 0 1 10 0v4'/></svg>"); | |||
background-repeat: no-repeat; | |||
background-position: calc(50% - 105px) 50%; | |||
background-size: 16px 16px; | |||
pointer-events: none; | |||
} | |||
/* Quando revelado: fade-in suave do conteúdo */ | |||
.gla-item[data-hidden="true"].is-revealed .gla-item-title, | |||
.gla-item[data-hidden="true"].is-revealed .gla-item-desc { | |||
animation: gla-reveal 0.4s ease; | |||
} | |||
@keyframes gla-reveal { | |||
from { | |||
opacity: 0; | |||
} | |||
to { | |||
opacity: 1; | |||
} | |||
} | |||
/* ─── Variante A — BADGE (default fallback) ─────────────────────────── */ | |||
/* Pill cinza inline ao lado do título com ícone eye-off. Direto e | |||
legível, não rouba real estate do card. */ | |||
.gla-conquistas-root[data-hidden-style="badge"] .gla-item[data-hidden="true"] .gla-item-left>div:not(.gla-item-icon) { | |||
flex: 1; | flex: 1; | ||
min-width: 0; | min-width: 0; | ||
} | } | ||
.gla-conquistas-root[data-hidden-style="badge"] .gla-item[data-hidden="true"] .gla-item-title { | |||
display: flex; | |||
.gla-item- | align-items: center; | ||
flex-wrap: wrap; | |||
gap: 4px 8px; | |||
border: none | } | ||
background: | .gla-conquistas-root[data-hidden-style="badge"] .gla-item[data-hidden="true"] .gla-item-title::after { | ||
content: "Oculta no jogo"; | |||
display: inline-flex; | |||
align-items: center; | |||
padding: 2px 9px 2px 22px; | |||
background: var(--gla-secret-bg); | |||
color: var(--gla-secret); | |||
border: 1px solid var(--gla-secret-line); | |||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif; | |||
font-size: 10px; | |||
font-weight: 700; | |||
letter-spacing: 0.08em; | |||
text-transform: uppercase; | |||
line-height: 1; | |||
border-radius: 999px; | |||
white-space: nowrap; | |||
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23475569' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><path d='M9.88 9.88a3 3 0 1 0 4.24 4.24'/><path d='M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68'/><path d='M6.61 6.61A13.526 13.526 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61'/><line x1='2' x2='22' y1='2' y2='22'/></svg>"); | |||
background-repeat: no-repeat; | |||
background-position: 6px 50%; | |||
background-size: 12px 12px; | |||
background-color: var(--gla-secret-bg); | |||
} | |||
/* ─── Variante B — STRIPES ─────────────────────────────────────────── */ | |||
.gla-conquistas-root[data-hidden-style="stripes"] .gla-item[data-hidden="true"] { | |||
background-image: | |||
repeating-linear-gradient(-45deg, | |||
transparent 0 14px, | |||
rgba(71, 85, 105, 0.06) 14px 16px); | |||
background-color: var(--gla-secret-soft); | |||
} | |||
.gla-conquistas-root[data-hidden-style="stripes"] .gla-item[data-hidden="true"] .gla-item-main::before { | |||
content: "Oculta no jogo"; | |||
position: absolute; | |||
top: -1px; | |||
left: 18px; | |||
transform: translateY(-50%); | |||
background: var(--gla-secret); | |||
color: #fff; | |||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif; | |||
font-size: 10px; | |||
font-weight: 700; | |||
letter-spacing: 0.12em; | |||
text-transform: uppercase; | |||
line-height: 1; | |||
padding: 4px 10px 5px 24px; | |||
border-radius: 999px; | |||
white-space: nowrap; | |||
z-index: 2; | |||
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><path d='M9.88 9.88a3 3 0 1 0 4.24 4.24'/><path d='M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68'/><path d='M6.61 6.61A13.526 13.526 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61'/><line x1='2' x2='22' y1='2' y2='22'/></svg>"); | |||
background-repeat: no-repeat; | |||
background-position: 7px 50%; | |||
background-size: 12px 12px; | |||
} | |||
.gla-conquistas-root[data-hidden-style="stripes"] .gla-item[data-hidden="true"] .gla-item-main { | |||
padding-top: 20px; | |||
} | } | ||
/* | /* ─── Variante C — RIBBON (default) ─────────────────────────────────── */ | ||
/* Fita diagonal cinza "SECRETA" no canto top-left. */ | |||
.gla- | .gla-conquistas-root[data-hidden-style="ribbon"] .gla-item[data-hidden="true"] { | ||
overflow: hidden; | |||
} | } | ||
.gla-conquistas-root[data-hidden-style="ribbon"] .gla-item[data-hidden="true"]::before { | |||
content: "SECRETA"; | |||
position: absolute; | |||
top: 14px; | |||
left: -38px; | |||
width: 140px; | |||
transform: rotate(-45deg); | |||
background: var(--gla-secret); | |||
color: #fff; | |||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif; | |||
font-size: 10px; | |||
font-weight: 700; | font-weight: 700; | ||
letter-spacing: 0.18em; | |||
text-align: center; | |||
line-height: 1; | |||
padding: 4px 0 5px; | |||
box-shadow: 0 1px 2px rgba(71, 85, 105, 0.25); | |||
z-index: 2; | |||
pointer-events: none; | |||
} | } | ||
.gla-item- | .gla-conquistas-root[data-hidden-style="ribbon"] .gla-item[data-hidden="true"] .gla-item-main { | ||
padding-left: 38px; | |||
} | } | ||
@media (max-width: 720px) { | |||
.gla-conquistas-root[data-hidden-style="ribbon"] .gla-item[data-hidden="true"] .gla-item-main { | |||
padding-left: 38px; | |||
} | |||
} | } | ||
.gla-item- | /* ─── Variante D — STAMP ─────────────────────────────────────────────── */ | ||
font-size: | .gla-conquistas-root[data-hidden-style="stamp"] .gla-item[data-hidden="true"]::before { | ||
content: "OCULTA"; | |||
position: absolute; | |||
top: 50%; | |||
right: 240px; | |||
transform: translateY(-50%) rotate(-12deg); | |||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif; | |||
font-size: 28px; | |||
font-weight: 700; | font-weight: 700; | ||
letter-spacing: . | letter-spacing: 0.25em; | ||
color: var(--gla-secret); | |||
opacity: 0.18; | |||
border: 3px solid var(--gla-secret); | |||
border-radius: 6px; | |||
padding: 4px 12px; | |||
pointer-events: none; | |||
white-space: nowrap; | white-space: nowrap; | ||
z-index: 1; | |||
} | |||
color: | |||
@media (max-width: 720px) { | |||
.gla-conquistas-root[data-hidden-style="stamp"] .gla-item[data-hidden="true"]::before { | |||
top: 14px; | |||
right: 14px; | |||
transform: rotate(-12deg); | |||
font-size: 22px; | |||
} | |||
} | |||
/* ─── Variante E — SUBTLE ────────────────────────────────────────────── */ | |||
.gla-conquistas-root[data-hidden-style="subtle"] .gla-item[data-hidden="true"] { | |||
background: var(--gla-paper-2); | |||
border-color: var(--gla-dim-2); | |||
} | |||
.gla-conquistas-root[data-hidden-style="subtle"] .gla-item[data-hidden="true"] .gla-item-title { | |||
color: var(--gla-ink-2); | |||
font-style: italic; | |||
} | |||
.gla-conquistas-root[data-hidden-style="subtle"] .gla-item[data-hidden="true"] .gla-item-desc { | |||
color: var(--gla-dim); | |||
} | |||
.gla-conquistas-root[data-hidden-style="subtle"] .gla-item[data-hidden="true"] .gla-item-reward .reward-wrapper { | |||
background: var(--gla-paper-3); | |||
border-color: var(--gla-dim-2); | |||
} | |||
.gla-conquistas-root[data-hidden-style="subtle"] .gla-item[data-hidden="true"] .gla-item-reward-label { | |||
color: var(--gla-dim); | |||
} | |||
.gla-conquistas-root[data-hidden-style="subtle"] .gla-item[data-hidden="true"]:hover { | |||
border-color: var(--gla-dim); | |||
box-shadow: var(--gla-shadow); | |||
} | } | ||
.gla-item | .gla-conquistas-root[data-hidden-style="subtle"] .gla-item[data-hidden="true"] .gla-item-title::after, | ||
.gla- | .gla-conquistas-root[data-hidden-style="subtle"] .gla-item[data-hidden="true"]::before { | ||
content: none; | |||
} | } | ||
.gla-item-reward . | /* ─── Reward items (Widget:Item) ─────────────────────────────────────── */ | ||
.gla-item-reward .item-wrapper-special { | |||
filter: none !important; | |||
} | } | ||
.gla-item-reward .reward-items { | .gla-item-reward .reward-items { | ||
display: flex !important; | display: flex !important; | ||
/* nowrap = trava a altura. O JS abaixo move itens excedentes pra | |||
dentro do chip "+M" depois do 5º. */ | |||
flex-wrap: nowrap !important; | flex-wrap: nowrap !important; | ||
justify-content: center; | justify-content: center; | ||
gap: 4px; | gap: 4px; | ||
width: 100%; | width: 100%; | ||
} | |||
/* ─── Chip "+M" (overflow) ─────────────────────────────────────────── */ | |||
/* Mesmo tamanho/forma do .item-wrapper pra alinhar visualmente com os | |||
ícones, mas com texto "+N" no centro. Click abre o popover com os | |||
itens escondidos. */ | |||
.gla-item-reward .reward-more-chip { | |||
display: inline-flex; | |||
align-items: center; | |||
justify-content: center; | |||
width: 48px; | |||
height: 48px; | |||
padding: 0; | |||
border: 1px solid var(--gla-rule); | |||
border-radius: 8px; | |||
background: var(--gla-paper); | |||
color: var(--gla-accent); | |||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif; | |||
font-size: 18px; | |||
font-weight: 700; | |||
line-height: 1; | |||
letter-spacing: -0.02em; | |||
cursor: pointer; | |||
flex-shrink: 0; | |||
transition: background 0.15s, border-color 0.15s, color 0.15s; | |||
} | |||
.gla-item-reward .reward-more-chip:hover, | |||
.gla-item-reward .reward-more-chip[aria-expanded="true"] { | |||
background: var(--gla-accent-bg); | |||
border-color: var(--gla-accent-soft); | |||
} | |||
/* Popover ancorado no chip — drop-down dos itens escondidos. */ | |||
.gla-item-reward .reward-overflow-popover { | |||
position: absolute; | |||
top: calc(100% + 6px); | |||
right: 0; | |||
display: flex; | |||
flex-wrap: wrap; | |||
justify-content: flex-end; | |||
gap: 4px; | |||
padding: 8px; | |||
background: var(--gla-paper); | |||
border: 1px solid var(--gla-rule); | |||
border-radius: 10px; | |||
box-shadow: 0 6px 18px -4px rgba(15, 23, 42, 0.15), | |||
0 2px 6px -2px rgba(15, 23, 42, 0.08); | |||
z-index: 10; | |||
max-width: 268px; | |||
animation: gla-popover-in 0.18s ease; | |||
} | |||
.gla-item-reward .reward-overflow-popover[hidden] { | |||
display: none; | |||
} | |||
@keyframes gla-popover-in { | |||
from { | |||
opacity: 0; | |||
transform: translateY(-4px); | |||
} | |||
to { | |||
opacity: 1; | |||
transform: translateY(0); | |||
} | |||
} | |||
/* ─── Responsivo ─────────────────────────────────────────────────────── */ | |||
@media (max-width: 720px) { | |||
.gla-conquistas-tab { | |||
font-size: 12px; | |||
padding: 6px 11px; | |||
} | |||
.gla-item-main { | |||
flex-wrap: wrap; | |||
padding: 12px 14px; | |||
} | |||
.gla-item-left { | |||
padding-right: 0; | |||
flex: 1 1 100%; | |||
} | |||
.gla-item-reward { | |||
flex: 1 1 100%; | |||
flex-direction: row; | |||
justify-content: flex-start; | |||
max-width: none; | |||
margin-top: 0; | |||
align-self: stretch; | |||
} | |||
/* No mobile o stack vertical empurra o "bottom" do .gla-item-main | |||
pra cima da recompensa — o spoiler absoluto colidiria com o chip. | |||
Saindo do absoluto e deixando ele fluir como 3º item do flex-wrap. */ | |||
.gla-item-spoiler-toggle { | |||
position: static; | |||
transform: none; | |||
align-self: flex-start; | |||
margin: 4px 0 0; | |||
padding: 2px 11px 3px; | |||
} | |||
.gla-item-spoiler { | |||
flex-direction: column; | |||
} | |||
.gla-item-spoiler-media { | |||
flex: 1 1 100%; | |||
max-width: 100%; | |||
} | |||
} | } | ||
</style> | </style> | ||
| Linha 463: | Linha 1 166: | ||
var filterColiseu = root.querySelector("#gla-filter-coliseu"); | var filterColiseu = root.querySelector("#gla-filter-coliseu"); | ||
var searchInput = root.querySelector(".gla-conquistas-search"); | var searchInput = root.querySelector(".gla-conquistas-search"); | ||
function countHiddenInTab(tabName) { | |||
var panel = root.querySelector('.gla-conquistas-panel[data-tab-content="' + tabName + '"]'); | |||
if (!panel) return 0; | |||
var n = 0; | |||
panel.querySelectorAll(".gla-item").forEach(function (card) { | |||
if (card.getAttribute("data-hidden") === "true") n++; | |||
}); | |||
return n; | |||
} | |||
// Mostra a barra de filtros só quando faz sentido: na aba Coliseu mostra | |||
// o subset (One Man Army / Corrida). Nas outras, só mostra o filtro | |||
// normal/hidden se a aba tiver pelo menos uma conquista oculta — | |||
// se não tiver, esconde pra não poluir. | |||
function syncFilterBarForTab(tabName) { | |||
var hiddenCount = countHiddenInTab(tabName); | |||
if (filterColiseu) { | |||
filterColiseu.style.display = tabName === "coliseu" ? "" : "none"; | |||
} | |||
if (filterDefault) { | |||
if (tabName === "coliseu") { | |||
filterDefault.style.display = "none"; | |||
} else { | |||
filterDefault.style.display = hiddenCount > 0 ? "" : "none"; | |||
} | |||
} | |||
if (tabName !== "coliseu" && hiddenCount === 0) { | |||
if (currentFilter === "hidden" || currentFilter === "normal") { | |||
currentFilter = "all"; | |||
} | |||
if (filterDefault) { | |||
filterDefault.querySelectorAll(".gla-conquistas-filter").forEach(function (p) { | |||
p.classList.toggle("is-active", p.getAttribute("data-filter") === "all"); | |||
}); | |||
} | |||
} | |||
} | |||
function applyVisibility() { | function applyVisibility() { | ||
| Linha 512: | Linha 1 255: | ||
}); | }); | ||
// Spoiler — abre/fecha | // Spoiler — abre/fecha só no botão "Spoiler" | ||
root.addEventListener("click", function (e) { | root.addEventListener("click", function (e) { | ||
var | var toggle = e.target.closest(".gla-item-spoiler-toggle"); | ||
if (!toggle) return; | |||
if (e.target.closest(".item-wrapper")) return; | |||
var card = toggle.closest(".gla-item.has-spoiler"); | |||
if (!card) return; | if (!card) return; | ||
e.preventDefault(); | |||
var isOpen = card.classList.contains("is-open"); | var isOpen = card.classList.contains("is-open"); | ||
root.querySelectorAll(".gla-item.is-open").forEach(function (c) { | root.querySelectorAll(".gla-item.is-open").forEach(function (c) { | ||
c.classList.remove("is-open"); | c.classList.remove("is-open"); | ||
}); | }); | ||
if (!isOpen) card.classList.add("is-open"); | root.querySelectorAll(".gla-item-spoiler-toggle").forEach(function (btn) { | ||
btn.setAttribute("aria-expanded", "false"); | |||
}); | |||
if (!isOpen) { | |||
card.classList.add("is-open"); | |||
toggle.setAttribute("aria-expanded", "true"); | |||
} | |||
}); | |||
// ─── Reveal + persistência ──────────────────────────────────────── | |||
// Click no card hidden remove a censura (anti-spoiler) e o estado | |||
// é salvo no localStorage. Próxima visita à página, conquistas que | |||
// o jogador já revelou voltam reveladas — não precisa clicar de novo. | |||
// | |||
// Chave: "glaConquistasRevealed" → JSON com array de data-id. | |||
// Robusto a localStorage indisponível (modo privado, cookies | |||
// bloqueados) — só falha silenciosamente. | |||
var REVEAL_STORAGE_KEY = "glaConquistasRevealed"; | |||
function loadRevealed() { | |||
try { | |||
var raw = window.localStorage.getItem(REVEAL_STORAGE_KEY); | |||
if (!raw) return {}; | |||
var arr = JSON.parse(raw); | |||
if (!Array.isArray(arr)) return {}; | |||
var set = {}; | |||
for (var i = 0; i < arr.length; i++) { | |||
if (arr[i] != null) set[String(arr[i])] = true; | |||
} | |||
return set; | |||
} catch (e) { | |||
return {}; | |||
} | |||
} | |||
function saveRevealed(set) { | |||
try { | |||
var arr = Object.keys(set); | |||
window.localStorage.setItem(REVEAL_STORAGE_KEY, JSON.stringify(arr)); | |||
} catch (e) { /* localStorage indisponível — ok */ } | |||
} | |||
var revealedSet = loadRevealed(); | |||
// Re-aplica .is-revealed nos cards que já tavam revelados em | |||
// sessões anteriores. Roda agora (depois do JS já ter movido os | |||
// cards do source pros painéis). | |||
root.querySelectorAll('.gla-item[data-hidden="true"][data-id]').forEach(function (card) { | |||
if (revealedSet[card.getAttribute("data-id")]) { | |||
card.classList.add("is-revealed"); | |||
} | |||
}); | |||
// Click — revela e persiste. Só ativa se data-reveal-mode no root | |||
// estiver definido como blur/redacted/placeholder/veil. Ignora | |||
// clicks em interativos dentro do card (botão de spoiler, ícones | |||
// de reward com tooltip, links na descrição, chip "+N" de overflow). | |||
root.addEventListener("click", function (e) { | |||
var mode = root.getAttribute("data-reveal-mode") || "none"; | |||
if (mode === "none") return; | |||
var card = e.target.closest('.gla-item[data-hidden="true"]'); | |||
if (!card) return; | |||
if (card.classList.contains("is-revealed")) return; | |||
if (e.target.closest(".gla-item-spoiler-toggle, .item-wrapper, a, .reward-more-chip, .reward-overflow-popover")) return; | |||
card.classList.add("is-revealed"); | |||
var id = card.getAttribute("data-id"); | |||
if (id) { | |||
revealedSet[id] = true; | |||
saveRevealed(revealedSet); | |||
} | |||
}); | }); | ||
| Linha 528: | Linha 1 344: | ||
currentTab = nome; | currentTab = nome; | ||
currentFilter = "all"; | currentFilter = "all"; | ||
tabs.forEach(function (t) { t.classList.remove("is-active"); }); | tabs.forEach(function (t) { t.classList.remove("is-active"); }); | ||
| Linha 545: | Linha 1 352: | ||
if (tab) tab.classList.add("is-active"); | if (tab) tab.classList.add("is-active"); | ||
if (panel) panel.classList.add("is-active"); | if (panel) panel.classList.add("is-active"); | ||
syncFilterBarForTab(nome); | |||
root.querySelectorAll(".gla-conquistas-filter").forEach(function (p) { | |||
if (p.offsetParent !== null && p.style.display !== "none") { | |||
p.classList.toggle("is-active", p.getAttribute("data-filter") === "all"); | |||
} | |||
}); | |||
applyVisibility(); | applyVisibility(); | ||
| Linha 557: | Linha 1 372: | ||
abrirAba("geral"); | abrirAba("geral"); | ||
}); | }); | ||
</script> | |||
<!-- ─── Overflow das recompensas: "+M" chip + popover ───────────────────── | |||
Para cada .reward-items com mais de MAX itens, esconde do (MAX+1)º em | |||
diante, joga os escondidos num popover, e planta um chip "+M" no fim | |||
da linha. Clique no chip abre o popover ancorado abaixo do chip. | |||
Click fora fecha. Esc fecha. | |||
É responsabilidade do widget — o Lua não precisa mudar, já que | |||
.reward-items vem do Widget:Item igual à Predefinição:Reward. | |||
─────────────────────────────────────────────────────────────────────── --> | |||
<script> | |||
(function () { | |||
var MAX_VISIBLE = 4; | |||
function processOne(reward) { | |||
if (reward.dataset.glaOverflow === "done") return; | |||
var line = reward.querySelector(".reward-items"); | |||
if (!line) return; | |||
var items = []; | |||
for (var i = 0; i < line.children.length; i++) { | |||
var c = line.children[i]; | |||
if (c.classList && c.classList.contains("item-wrapper")) items.push(c); | |||
} | |||
if (items.length <= MAX_VISIBLE) { | |||
reward.dataset.glaOverflow = "done"; | |||
return; | |||
} | |||
var hidden = items.slice(MAX_VISIBLE); | |||
var popover = document.createElement("div"); | |||
popover.className = "reward-overflow-popover"; | |||
popover.hidden = true; | |||
hidden.forEach(function (el) { popover.appendChild(el); }); | |||
var chip = document.createElement("button"); | |||
chip.type = "button"; | |||
chip.className = "reward-more-chip"; | |||
chip.setAttribute("aria-expanded", "false"); | |||
chip.setAttribute("aria-label", "Ver mais " + hidden.length + " recompensa(s)"); | |||
chip.textContent = "+" + hidden.length; | |||
line.appendChild(chip); | |||
reward.appendChild(popover); | |||
chip.addEventListener("click", function (e) { | |||
e.stopPropagation(); | |||
var open = chip.getAttribute("aria-expanded") === "true"; | |||
closeAll(); | |||
if (!open) { | |||
popover.hidden = false; | |||
chip.setAttribute("aria-expanded", "true"); | |||
} | |||
}); | |||
reward.dataset.glaOverflow = "done"; | |||
} | |||
function closeAll() { | |||
document.querySelectorAll(".reward-overflow-popover").forEach(function (p) { | |||
p.hidden = true; | |||
}); | |||
document.querySelectorAll(".reward-more-chip").forEach(function (c) { | |||
c.setAttribute("aria-expanded", "false"); | |||
}); | |||
} | |||
function processAll() { | |||
document.querySelectorAll(".gla-item-reward").forEach(processOne); | |||
} | |||
if (document.readyState === "loading") { | |||
document.addEventListener("DOMContentLoaded", processAll); | |||
} else { | |||
processAll(); | |||
} | |||
document.addEventListener("click", function (e) { | |||
if (e.target.closest(".reward-overflow-popover, .reward-more-chip")) return; | |||
closeAll(); | |||
}); | |||
document.addEventListener("keydown", function (e) { | |||
if (e.key === "Escape") closeAll(); | |||
}); | |||
})(); | |||
</script> | </script> | ||
</includeonly> | </includeonly> | ||