@mundogamernetwork/shared-ui 1.1.50 → 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.
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mundogamernetwork/shared-ui",
3
- "version": "1.1.50",
3
+ "version": "1.1.51",
4
4
  "description": "Mundo Gamer Network - Shared UI Layer (Nuxt 3)",
5
5
  "type": "module",
6
6
  "main": "./nuxt.config.ts",
@@ -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 v-else>{{ kit.name }}</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 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>
191
- <div class="kit-gallery">
192
- <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>
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
- </section>
195
-
196
- <section v-if="brandAssets.length" class="kit-block">
197
- <div class="kit-shead"><h2>{{ $t('kit.press.logo_icons') }}</h2></div>
198
- <div class="kit-logos">
199
- <a v-for="(b, i) in brandAssets" :key="i" class="kit-logo-tile" :href="b.url" target="_blank" rel="noopener" @click="track('download')">
200
- <span class="ic">◆</span>{{ b.title || b.type }}
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
- <!-- NEW: Conteúdos & Artigos (community + external) -->
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
- <!-- NEW: Cobertura de Criadores -->
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
- <!-- NEW: Ecossistema Mundo Gamer -->
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>