@mundogamernetwork/shared-ui 1.1.49 → 1.1.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/kit/kit-base.css +123 -0
- package/package.json +1 -1
- package/pages/presskit/game/[slug].vue +90 -25
- package/stores/auth.ts +6 -1
package/assets/kit/kit-base.css
CHANGED
|
@@ -642,6 +642,129 @@ body:has(.kit-press) {
|
|
|
642
642
|
border-color: var(--kit-accent, #FDB215);
|
|
643
643
|
}
|
|
644
644
|
|
|
645
|
+
/* ── Anchor nav bar ─────────────────────────────────────────────────*/
|
|
646
|
+
.kit-anchornav {
|
|
647
|
+
background: var(--kit-surface, #14171d);
|
|
648
|
+
border-bottom: 1px solid var(--kit-line, #252a34);
|
|
649
|
+
position: sticky;
|
|
650
|
+
top: 0;
|
|
651
|
+
z-index: 90;
|
|
652
|
+
}
|
|
653
|
+
.kit-anchornav-inner {
|
|
654
|
+
max-width: var(--kit-maxw, 1180px);
|
|
655
|
+
margin: 0 auto;
|
|
656
|
+
padding: 0 24px;
|
|
657
|
+
display: flex;
|
|
658
|
+
gap: 0;
|
|
659
|
+
overflow-x: auto;
|
|
660
|
+
scrollbar-width: none;
|
|
661
|
+
}
|
|
662
|
+
.kit-anchornav-inner::-webkit-scrollbar { display: none; }
|
|
663
|
+
.kit-anchornav-item {
|
|
664
|
+
display: inline-block;
|
|
665
|
+
padding: 14px 16px;
|
|
666
|
+
font-size: 0.78rem;
|
|
667
|
+
font-weight: 600;
|
|
668
|
+
letter-spacing: 0.8px;
|
|
669
|
+
text-transform: uppercase;
|
|
670
|
+
color: var(--kit-muted, #8b92a0);
|
|
671
|
+
text-decoration: none;
|
|
672
|
+
white-space: nowrap;
|
|
673
|
+
border-bottom: 2px solid transparent;
|
|
674
|
+
transition: color 0.15s, border-color 0.15s;
|
|
675
|
+
}
|
|
676
|
+
.kit-anchornav-item:hover {
|
|
677
|
+
color: var(--kit-text, #f4f6fa);
|
|
678
|
+
border-bottom-color: var(--kit-accent, #FDB215);
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
/* ── Sticky CTA bar ──────────────────────────────────────────────────*/
|
|
682
|
+
.kit-stickybar {
|
|
683
|
+
position: fixed;
|
|
684
|
+
bottom: 0;
|
|
685
|
+
left: 0;
|
|
686
|
+
right: 0;
|
|
687
|
+
z-index: 100;
|
|
688
|
+
background: var(--kit-surface, #14171d);
|
|
689
|
+
border-top: 1px solid var(--kit-line, #252a34);
|
|
690
|
+
padding: 12px 24px;
|
|
691
|
+
display: flex;
|
|
692
|
+
align-items: center;
|
|
693
|
+
justify-content: space-between;
|
|
694
|
+
gap: 16px;
|
|
695
|
+
opacity: 0;
|
|
696
|
+
transform: translateY(100%);
|
|
697
|
+
transition: opacity 0.25s, transform 0.25s;
|
|
698
|
+
pointer-events: none;
|
|
699
|
+
}
|
|
700
|
+
.kit-stickybar.visible {
|
|
701
|
+
opacity: 1;
|
|
702
|
+
transform: translateY(0);
|
|
703
|
+
pointer-events: auto;
|
|
704
|
+
}
|
|
705
|
+
.kit-stickybar-name {
|
|
706
|
+
font-size: 0.9rem;
|
|
707
|
+
font-weight: 700;
|
|
708
|
+
color: var(--kit-text, #f4f6fa);
|
|
709
|
+
white-space: nowrap;
|
|
710
|
+
overflow: hidden;
|
|
711
|
+
text-overflow: ellipsis;
|
|
712
|
+
min-width: 0;
|
|
713
|
+
flex: 1;
|
|
714
|
+
}
|
|
715
|
+
.kit-stickybar-actions {
|
|
716
|
+
display: flex;
|
|
717
|
+
gap: 8px;
|
|
718
|
+
flex-shrink: 0;
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
/* ── Small button variant ────────────────────────────────────────────*/
|
|
722
|
+
.kit-btn-sm {
|
|
723
|
+
padding: 7px 14px;
|
|
724
|
+
font-size: 0.78rem;
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
/* ── Back to top button ──────────────────────────────────────────────*/
|
|
728
|
+
.kit-backtop {
|
|
729
|
+
position: fixed;
|
|
730
|
+
bottom: 72px;
|
|
731
|
+
right: 24px;
|
|
732
|
+
z-index: 101;
|
|
733
|
+
width: 40px;
|
|
734
|
+
height: 40px;
|
|
735
|
+
background: var(--kit-accent, #FDB215);
|
|
736
|
+
color: var(--kit-accent-ink, #13161C);
|
|
737
|
+
border: none;
|
|
738
|
+
font-size: 1.1rem;
|
|
739
|
+
font-weight: 800;
|
|
740
|
+
cursor: pointer;
|
|
741
|
+
display: flex;
|
|
742
|
+
align-items: center;
|
|
743
|
+
justify-content: center;
|
|
744
|
+
box-shadow: 0 4px 16px rgba(0,0,0,0.4);
|
|
745
|
+
transition: opacity 0.15s;
|
|
746
|
+
}
|
|
747
|
+
.kit-backtop:hover { opacity: 0.85; }
|
|
748
|
+
|
|
749
|
+
/* ── Cover title — always visible ───────────────────────────────────*/
|
|
750
|
+
.kit-cover-title {
|
|
751
|
+
font-size: 2.6rem;
|
|
752
|
+
font-weight: 800;
|
|
753
|
+
margin: 0 0 8px;
|
|
754
|
+
line-height: 1.1;
|
|
755
|
+
color: var(--kit-text, #f4f6fa);
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
/* ── Poster slightly larger ─────────────────────────────────────────*/
|
|
759
|
+
.kit-cover-poster {
|
|
760
|
+
width: 160px;
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
/* ── Inner block spacing (screenshots + logos together) ─────────────*/
|
|
764
|
+
.kit-block-inner {
|
|
765
|
+
margin-top: 32px;
|
|
766
|
+
}
|
|
767
|
+
|
|
645
768
|
/* ── Responsive ─────────────────────────────────────────────────────*/
|
|
646
769
|
@media (max-width: 900px) {
|
|
647
770
|
.kit-layout {
|
package/package.json
CHANGED
|
@@ -73,6 +73,46 @@ function onPoolsReady(count: number) {
|
|
|
73
73
|
keyPoolsVisible.value = count > 0;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
// Scroll state for sticky CTA + back-to-top
|
|
77
|
+
const scrolled = ref(false);
|
|
78
|
+
let heroHeight = 0;
|
|
79
|
+
|
|
80
|
+
function onScroll() {
|
|
81
|
+
scrolled.value = window.scrollY > heroHeight;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function scrollToTop() {
|
|
85
|
+
window.scrollTo({ top: 0, behavior: 'smooth' });
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
onMounted(() => {
|
|
89
|
+
const hero = document.querySelector('.kit-cover') as HTMLElement | null;
|
|
90
|
+
heroHeight = hero ? hero.offsetHeight : 300;
|
|
91
|
+
window.addEventListener('scroll', onScroll, { passive: true });
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
onUnmounted(() => {
|
|
95
|
+
window.removeEventListener('scroll', onScroll);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// Dynamic anchor nav — only sections that have content
|
|
99
|
+
const navSections = computed(() => {
|
|
100
|
+
const k = kit.value;
|
|
101
|
+
if (!k) return [];
|
|
102
|
+
const s: { id: string; label: string }[] = [];
|
|
103
|
+
s.push({ id: 'overview', label: 'kit.press.about' });
|
|
104
|
+
s.push({ id: 'factsheet', label: 'kit.press.fact_sheet' });
|
|
105
|
+
if (screenshots.value.length || brandAssets.value.length) s.push({ id: 'media', label: 'kit.press.screenshots' });
|
|
106
|
+
if (videos.value.length) s.push({ id: 'trailers', label: 'kit.press.videos' });
|
|
107
|
+
if (articles.value.length) s.push({ id: 'articles', label: 'kit.press.articles' });
|
|
108
|
+
if (coverage.value.length) s.push({ id: 'creators', label: 'kit.press.coverage' });
|
|
109
|
+
if (awards.value.length) s.push({ id: 'awards', label: 'kit.press.awards' });
|
|
110
|
+
if (team.value.length) s.push({ id: 'team', label: 'kit.press.team' });
|
|
111
|
+
if (showcases.value.length) s.push({ id: 'events', label: 'kit.press.showcases' });
|
|
112
|
+
if (k.press_contact_email) s.push({ id: 'contact', label: 'kit.press.contact' });
|
|
113
|
+
return s;
|
|
114
|
+
});
|
|
115
|
+
|
|
76
116
|
const socials = computed(() => {
|
|
77
117
|
const s = kit.value?.social_links || {};
|
|
78
118
|
return Object.entries(s).filter(([, v]) => v).map(([k, v]) => ({ platform: k, url: v as string }));
|
|
@@ -138,7 +178,7 @@ useSeoMeta({
|
|
|
138
178
|
<div class="kit-cover-text">
|
|
139
179
|
<span v-if="kit.release_status" class="kit-eyebrow">{{ String(kit.release_status).replace(/_/g, ' ') }}</span>
|
|
140
180
|
<img v-if="kit.logo_url" class="kit-cover-logo-img" :src="kit.logo_url" :alt="kit.name" />
|
|
141
|
-
<h1
|
|
181
|
+
<h1 class="kit-cover-title">{{ kit.name }}</h1>
|
|
142
182
|
<p v-if="kit.tagline" class="kit-tagline">{{ kit.tagline }}</p>
|
|
143
183
|
<p v-if="kit.developer" class="kit-kicker">{{ kit.developer }}</p>
|
|
144
184
|
<div class="kit-actions">
|
|
@@ -149,10 +189,31 @@ useSeoMeta({
|
|
|
149
189
|
</div>
|
|
150
190
|
</header>
|
|
151
191
|
|
|
192
|
+
<!-- ANCHOR NAV -->
|
|
193
|
+
<nav v-if="navSections.length" class="kit-anchornav">
|
|
194
|
+
<div class="kit-anchornav-inner">
|
|
195
|
+
<a
|
|
196
|
+
v-for="s in navSections"
|
|
197
|
+
:key="s.id"
|
|
198
|
+
:href="`#${s.id}`"
|
|
199
|
+
class="kit-anchornav-item"
|
|
200
|
+
>{{ $te(s.label) ? $t(s.label) : s.label }}</a>
|
|
201
|
+
</div>
|
|
202
|
+
</nav>
|
|
203
|
+
|
|
204
|
+
<!-- STICKY CTA BAR (appears after scrolling past hero) -->
|
|
205
|
+
<div class="kit-stickybar" :class="{ visible: scrolled }">
|
|
206
|
+
<span class="kit-stickybar-name">{{ kit.name }}</span>
|
|
207
|
+
<div class="kit-stickybar-actions">
|
|
208
|
+
<a v-if="allowDownload" class="kit-btn kit-btn-primary kit-btn-sm" @click="track('download')">{{ $t('kit.press.download_assets') }}</a>
|
|
209
|
+
<a v-if="kit.press_contact_email" class="kit-btn kit-btn-ghost kit-btn-sm" :href="`mailto:${kit.press_contact_email}`" @click="track('contact')">{{ $t('kit.press.request_key') }}</a>
|
|
210
|
+
</div>
|
|
211
|
+
</div>
|
|
212
|
+
|
|
152
213
|
<div class="kit-wrap">
|
|
153
214
|
<div class="kit-layout">
|
|
154
215
|
<aside class="kit-sidebar">
|
|
155
|
-
<div class="kit-card kit-factsheet">
|
|
216
|
+
<div id="factsheet" class="kit-card kit-factsheet">
|
|
156
217
|
<h3 class="kit-fact-title">{{ $t('kit.press.fact_sheet') }}</h3>
|
|
157
218
|
<div v-for="f in facts" :key="f.label" class="kit-fact">
|
|
158
219
|
<span class="k">{{ $te(f.label) ? $t(f.label) : f.label }}</span>
|
|
@@ -168,7 +229,7 @@ useSeoMeta({
|
|
|
168
229
|
</div>
|
|
169
230
|
</aside>
|
|
170
231
|
|
|
171
|
-
<main class="kit-main">
|
|
232
|
+
<main id="overview" class="kit-main">
|
|
172
233
|
<section v-if="kit.description" class="kit-block">
|
|
173
234
|
<h2>{{ $t('kit.press.about') }}</h2>
|
|
174
235
|
<div class="kit-lead" v-html="kit.description" />
|
|
@@ -181,29 +242,30 @@ useSeoMeta({
|
|
|
181
242
|
</div>
|
|
182
243
|
</section>
|
|
183
244
|
|
|
184
|
-
<section v-if="videos.length" class="kit-block">
|
|
245
|
+
<section v-if="videos.length" id="trailers" class="kit-block">
|
|
185
246
|
<h2>{{ $t('kit.press.videos') }}</h2>
|
|
186
247
|
<PressKitVideoPlayer :videos="videos" />
|
|
187
248
|
</section>
|
|
188
249
|
|
|
189
|
-
<section v-if="screenshots.length" class="kit-block">
|
|
190
|
-
<div
|
|
191
|
-
|
|
192
|
-
<
|
|
250
|
+
<section v-if="screenshots.length || brandAssets.length" id="media" class="kit-block">
|
|
251
|
+
<div v-if="screenshots.length">
|
|
252
|
+
<div class="kit-shead"><h2>{{ $t('kit.press.screenshots') }}</h2><a v-if="allowDownload" class="kit-dl" @click="track('download')">{{ $t('kit.press.download_all') }}</a></div>
|
|
253
|
+
<div class="kit-gallery">
|
|
254
|
+
<a v-for="(s, i) in screenshots" :key="i" class="kit-shot" :href="s.url" target="_blank" rel="noopener"><img :src="s.thumbnail_url || s.url" :alt="s.title || ''" /></a>
|
|
255
|
+
</div>
|
|
193
256
|
</div>
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
</a>
|
|
257
|
+
<div v-if="brandAssets.length" :class="{ 'kit-block-inner': screenshots.length }">
|
|
258
|
+
<div class="kit-shead"><h2>{{ $t('kit.press.logo_icons') }}</h2></div>
|
|
259
|
+
<div class="kit-logos">
|
|
260
|
+
<a v-for="(b, i) in brandAssets" :key="i" class="kit-logo-tile" :href="b.url" target="_blank" rel="noopener" @click="track('download')">
|
|
261
|
+
<span class="ic">◆</span>{{ b.title || b.type }}
|
|
262
|
+
</a>
|
|
263
|
+
</div>
|
|
202
264
|
</div>
|
|
203
265
|
</section>
|
|
204
266
|
|
|
205
|
-
<!--
|
|
206
|
-
<section v-if="articles.length" class="kit-block">
|
|
267
|
+
<!-- Conteúdos & Artigos -->
|
|
268
|
+
<section v-if="articles.length" id="articles" class="kit-block">
|
|
207
269
|
<div class="kit-shead"><h2>{{ $t('kit.press.articles') }}</h2></div>
|
|
208
270
|
<div class="kit-articles">
|
|
209
271
|
<a v-for="(a, i) in articles" :key="i" class="kit-article" :href="a.url" target="_blank" rel="noopener" @click="track('click')">
|
|
@@ -213,8 +275,8 @@ useSeoMeta({
|
|
|
213
275
|
</div>
|
|
214
276
|
</section>
|
|
215
277
|
|
|
216
|
-
<!--
|
|
217
|
-
<section v-if="coverage.length" class="kit-block">
|
|
278
|
+
<!-- Cobertura de Criadores -->
|
|
279
|
+
<section v-if="coverage.length" id="creators" class="kit-block">
|
|
218
280
|
<h2>{{ $t('kit.press.coverage') }}</h2>
|
|
219
281
|
<div class="kit-creators">
|
|
220
282
|
<a v-for="(c, i) in coverage" :key="i" class="kit-creator" :href="c.url || undefined" target="_blank" rel="noopener">
|
|
@@ -226,7 +288,7 @@ useSeoMeta({
|
|
|
226
288
|
</div>
|
|
227
289
|
</section>
|
|
228
290
|
|
|
229
|
-
<section v-if="awards.length" class="kit-block">
|
|
291
|
+
<section v-if="awards.length" id="awards" class="kit-block">
|
|
230
292
|
<h2>{{ $t('kit.press.awards') }}</h2>
|
|
231
293
|
<PressKitAwards :awards="awards" />
|
|
232
294
|
</section>
|
|
@@ -237,15 +299,15 @@ useSeoMeta({
|
|
|
237
299
|
</section>
|
|
238
300
|
|
|
239
301
|
<!-- Créditos -> Equipe -->
|
|
240
|
-
<section v-if="team.length" class="kit-block">
|
|
302
|
+
<section v-if="team.length" id="team" class="kit-block">
|
|
241
303
|
<h2>{{ $t('kit.press.team') }}</h2>
|
|
242
304
|
<div class="kit-team">
|
|
243
305
|
<div v-for="(m, i) in team" :key="i" class="kit-member"><span>{{ m.name }}</span><span class="role">{{ m.role }}</span></div>
|
|
244
306
|
</div>
|
|
245
307
|
</section>
|
|
246
308
|
|
|
247
|
-
<!--
|
|
248
|
-
<section v-if="hasEcosystem" class="kit-block">
|
|
309
|
+
<!-- Ecossistema Mundo Gamer -->
|
|
310
|
+
<section v-if="hasEcosystem" id="events" class="kit-block">
|
|
249
311
|
<h2>{{ $t('kit.press.ecosystem') }}</h2>
|
|
250
312
|
<div class="kit-eco">
|
|
251
313
|
<div v-if="showcases.length" class="kit-eco-card full">
|
|
@@ -282,7 +344,7 @@ useSeoMeta({
|
|
|
282
344
|
/>
|
|
283
345
|
</section>
|
|
284
346
|
|
|
285
|
-
<section v-if="kit.press_contact_email" class="kit-block">
|
|
347
|
+
<section v-if="kit.press_contact_email" id="contact" class="kit-block">
|
|
286
348
|
<div class="kit-cta">
|
|
287
349
|
<h2>{{ $t('kit.press.covering', { name: kit.name }) }}</h2>
|
|
288
350
|
<p>{{ $t('kit.press.cta_text') }}</p>
|
|
@@ -299,4 +361,7 @@ useSeoMeta({
|
|
|
299
361
|
</div>
|
|
300
362
|
</template>
|
|
301
363
|
</div>
|
|
364
|
+
|
|
365
|
+
<!-- Back to top -->
|
|
366
|
+
<button v-if="scrolled" class="kit-backtop" aria-label="Back to top" @click="scrollToTop">↑</button>
|
|
302
367
|
</template>
|
package/stores/auth.ts
CHANGED
|
@@ -71,8 +71,13 @@ export const useAuthStore = defineStore({
|
|
|
71
71
|
userId: (state) => (state.user ? state.user.id : null),
|
|
72
72
|
isSignedIn: (state) => state.signedIn,
|
|
73
73
|
},
|
|
74
|
+
// Persisted via pinia-plugin-persistedstate when the consuming app registers
|
|
75
|
+
// the module; storage is left as the plugin default (localStorage, SSR-safe)
|
|
76
|
+
// so this store does NOT reference the `persistedState` global. Referencing it
|
|
77
|
+
// threw "persistedState is not defined" during SSR on fronts that consume this
|
|
78
|
+
// layer without the module (the base, network-site, never had it). Fronts with
|
|
79
|
+
// the module still persist; fronts without it simply skip persistence, no crash.
|
|
74
80
|
persist: {
|
|
75
|
-
storage: persistedState.localStorage,
|
|
76
81
|
pick: ["user", "signedIn"],
|
|
77
82
|
afterHydrate: ({ store }) => {
|
|
78
83
|
store.initialized = false;
|