@mundogamernetwork/shared-ui 1.1.36 → 1.1.38

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.
@@ -0,0 +1,920 @@
1
+ <script setup lang="ts">
2
+ import { useRoute, useRouter } from "vue-router";
3
+ import type { PageData } from "@mundogamernetwork/mgn-flipbook";
4
+ import type { MagazinePage } from "../../../types/magazine";
5
+ import { getMagazinePageHotspots } from "../../../utils/magazineHotspots";
6
+
7
+ useSeoMeta({
8
+ title: "MGN Magazine",
9
+ description:
10
+ "Discover, be inspired and connect in the magazine that breathes digital gaming. Welcome to your new source of gamer passion!",
11
+ ogTitle: "MGN Magazine",
12
+ ogDescription:
13
+ "Discover, be inspired and connect in the magazine that breathes digital gaming. Welcome to your new source of gamer passion!",
14
+ ogImage: "/imgs/seo-magazine-image.jpg",
15
+ ogUrl: "/magazine",
16
+ twitterTitle: "MGN Magazine",
17
+ twitterDescription:
18
+ "Discover, be inspired and connect in the magazine that breathes digital gaming. Welcome to your new source of gamer passion!",
19
+ twitterImage: "/imgs/seo-magazine-image.jpg",
20
+ twitterCard: "summary",
21
+ });
22
+
23
+ interface MagazineItem {
24
+ id: string;
25
+ edition_number: number;
26
+ language: {
27
+ id: string;
28
+ };
29
+ }
30
+
31
+ interface LanguageItem {
32
+ id: string;
33
+ localized_name: string;
34
+ magazine_slug: string;
35
+ }
36
+
37
+ interface ReadingProgress {
38
+ lastPage: number;
39
+ maxPageReached: number;
40
+ updatedAt: string;
41
+ }
42
+
43
+ const route = useRoute();
44
+ const router = useRouter();
45
+ const locale = useNuxtApp().$i18n.locale;
46
+ const slug = computed(() => route.params.slug as string);
47
+
48
+ const magazineStore = useMagazineStore();
49
+ const { magazine, magazines, magazinePages } = magazineStore;
50
+ const institutionalStore = useInstitutionalStore();
51
+ const { language } = institutionalStore;
52
+
53
+ const languages: Ref<LanguageItem[]> = ref([]);
54
+ const languageId = ref("");
55
+ const authStore = useAuthStore();
56
+ const { user, signedIn } = storeToRefs(authStore);
57
+
58
+ const {
59
+ public: { apiBaseURL },
60
+ } = useRuntimeConfig();
61
+
62
+ const status = ref("init");
63
+ const startPage = ref(0);
64
+
65
+ const readingProgressStorageKey = computed(
66
+ () => `mgn-magazine-progress:${slug.value}`,
67
+ );
68
+
69
+ function getStoredReadingProgress(): ReadingProgress | null {
70
+ if (typeof window === "undefined") return null;
71
+
72
+ try {
73
+ const raw = window.localStorage.getItem(readingProgressStorageKey.value);
74
+ if (!raw) return null;
75
+ const parsed = JSON.parse(raw) as Partial<ReadingProgress>;
76
+ if (
77
+ typeof parsed.lastPage !== "number" ||
78
+ typeof parsed.maxPageReached !== "number"
79
+ ) {
80
+ return null;
81
+ }
82
+
83
+ return {
84
+ lastPage: parsed.lastPage,
85
+ maxPageReached: parsed.maxPageReached,
86
+ updatedAt:
87
+ typeof parsed.updatedAt === "string"
88
+ ? parsed.updatedAt
89
+ : new Date().toISOString(),
90
+ };
91
+ } catch (error) {
92
+ console.error("Error restoring reading progress:", error);
93
+ return null;
94
+ }
95
+ }
96
+
97
+ function saveReadingProgress(page: number) {
98
+ if (typeof window === "undefined") return;
99
+ if (!Number.isFinite(page) || page < 0) return;
100
+
101
+ const current = getStoredReadingProgress();
102
+ const nextProgress: ReadingProgress = {
103
+ lastPage: page,
104
+ maxPageReached: Math.max(current?.maxPageReached ?? 0, page),
105
+ updatedAt: new Date().toISOString(),
106
+ };
107
+
108
+ window.localStorage.setItem(
109
+ readingProgressStorageKey.value,
110
+ JSON.stringify(nextProgress),
111
+ );
112
+ }
113
+
114
+ function restoreReadingProgress() {
115
+ const progress = getStoredReadingProgress();
116
+ if (!progress) {
117
+ startPage.value = 0;
118
+ return;
119
+ }
120
+
121
+ const totalPages = magazinePages.data?.length ?? 0;
122
+ if (!totalPages) {
123
+ startPage.value = 0;
124
+ return;
125
+ }
126
+
127
+ startPage.value = Math.min(
128
+ Math.max(progress.lastPage, 0),
129
+ Math.max(totalPages - 1, 0),
130
+ );
131
+ }
132
+
133
+ // Lead capture modal
134
+ const showLeadModal = ref(false);
135
+ const leadForm = reactive({ name: "", email: "" });
136
+ const leadSubmitting = ref(false);
137
+ const leadCaptured = ref(false);
138
+
139
+ // Download gating
140
+ const downloadPending = ref(false);
141
+ const showDownloadGateMessage = ref("");
142
+
143
+ // Flipbook pages mapped for MgnFlipbook
144
+ const flipbookPages = computed<PageData[]>(() => {
145
+ if (!magazinePages.data || magazinePages.data.length === 0) return [];
146
+ return magazinePages.data.map((page: MagazinePage) => ({
147
+ index: page.page_number - 1,
148
+ thumbnailUrl: page.thumbnail_url,
149
+ imageUrl: page.image_url,
150
+ hiresUrl: page.hires_url,
151
+ hotspots: getMagazinePageHotspots({
152
+ page,
153
+ flipbookCode: magazine.data?.flipbook_code,
154
+ }),
155
+ }));
156
+ });
157
+
158
+ // Determine if lead capture modal should show
159
+ const requiresLeadCapture = computed(() => {
160
+ if (leadCaptured.value) return false;
161
+ if (!magazinePages.meta) return false;
162
+ return magazinePages.meta.requires_lead || magazinePages.meta.capture_leads;
163
+ });
164
+
165
+ async function getMagazineData() {
166
+ try {
167
+ await magazineStore.getMagazine(slug.value);
168
+ status.value = magazine.status;
169
+ } catch (error) {
170
+ console.error("Error fetching magazine:", error);
171
+ }
172
+ }
173
+
174
+ async function loadFlipbookPages() {
175
+ try {
176
+ await magazineStore.fetchMagazinePages(slug.value);
177
+ restoreReadingProgress();
178
+
179
+ // Track view analytic
180
+ magazineStore.trackAnalytic(slug.value, "view");
181
+
182
+ // Show lead capture if needed
183
+ if (requiresLeadCapture.value) {
184
+ showLeadModal.value = true;
185
+ }
186
+ } catch (error) {
187
+ console.error("Error fetching magazine pages:", error);
188
+ }
189
+ }
190
+
191
+ function downloadPdf() {
192
+ if (magazine.data.pdf_url_src) {
193
+ window.open(magazine.data.pdf_url_src, "_blank");
194
+ magazineStore.trackAnalytic(slug.value, "download");
195
+ }
196
+ }
197
+
198
+ /**
199
+ * Download gating logic:
200
+ * 1. Premium magazine → must be subscriber
201
+ * 2. Non-public magazine → must be logged in (user_id)
202
+ * 3. Public magazine → unlock with name + email (lead capture / newsletter)
203
+ * 4. Logged in user → download directly (no lead capture needed)
204
+ */
205
+ function handleFlipbookDownload() {
206
+ // Gate 1: Premium magazine - need active subscription
207
+ if (magazine.data.premium === true) {
208
+ showDownloadGateMessage.value = "premium";
209
+ return;
210
+ }
211
+
212
+ // Gate 2: Non-public magazine - must be registered/signed in
213
+ if (magazine.data.public === false && signedIn.value === false) {
214
+ showDownloadGateMessage.value = "signin";
215
+ return;
216
+ }
217
+
218
+ // Gate 3: Signed-in users can always download (no lead capture needed)
219
+ if (signedIn.value === true) {
220
+ downloadPdf();
221
+ return;
222
+ }
223
+
224
+ // Gate 4: Public magazine + not signed in → need lead capture (name + email)
225
+ if (!leadCaptured.value) {
226
+ downloadPending.value = true;
227
+ showLeadModal.value = true;
228
+ return;
229
+ }
230
+
231
+ // All gates passed - download
232
+ downloadPdf();
233
+ }
234
+
235
+ async function submitLead() {
236
+ if (!leadForm.name || !leadForm.email) return;
237
+ leadSubmitting.value = true;
238
+ const success = await magazineStore.captureLead(
239
+ slug.value,
240
+ leadForm.name,
241
+ leadForm.email,
242
+ );
243
+ leadSubmitting.value = false;
244
+ if (success) {
245
+ leadCaptured.value = true;
246
+ showLeadModal.value = false;
247
+
248
+ // Auto-trigger download if lead was captured for download purpose
249
+ if (downloadPending.value) {
250
+ downloadPending.value = false;
251
+ downloadPdf();
252
+ }
253
+ }
254
+ }
255
+
256
+ function closeLeadModal() {
257
+ showLeadModal.value = false;
258
+ downloadPending.value = false;
259
+ }
260
+
261
+ function onPageChange(page: number) {
262
+ saveReadingProgress(page);
263
+ }
264
+
265
+ function onHotspotClick(
266
+ hotspotId: string,
267
+ page: number,
268
+ data?: unknown,
269
+ ) {
270
+ saveReadingProgress(page);
271
+ const analyticsEvent =
272
+ typeof data === "object" &&
273
+ data !== null &&
274
+ "analyticsEvent" in data &&
275
+ typeof data.analyticsEvent === "string"
276
+ ? data.analyticsEvent
277
+ : "ad_click";
278
+
279
+ magazineStore.trackAnalytic(slug.value, analyticsEvent);
280
+
281
+ if (typeof window === "undefined") return;
282
+
283
+ try {
284
+ window.dispatchEvent(
285
+ new CustomEvent("mgn-magazine-hotspot-click", {
286
+ detail: {
287
+ slug,
288
+ hotspotId,
289
+ page,
290
+ data,
291
+ },
292
+ }),
293
+ );
294
+ } catch (error) {
295
+ console.error("Error dispatching hotspot click event:", error);
296
+ }
297
+ }
298
+
299
+ async function fetchMagazine() {
300
+ try {
301
+ await magazineStore.fetchMagazine({
302
+ filter: {
303
+ status: 1,
304
+ edition_number: magazine.data.edition_number,
305
+ platform_id: import.meta.env.VITE_SYSTEM_ID,
306
+ },
307
+ sort: "id",
308
+ order: "desc",
309
+ per_page: "all",
310
+ page: 1,
311
+ });
312
+
313
+ filterLanguages();
314
+ } catch (error) {
315
+ console.error("Error fetching magazine:", error);
316
+ }
317
+ }
318
+
319
+ async function fetchLanguage() {
320
+ try {
321
+ await institutionalStore.fetchLanguage({});
322
+ } catch (error) {
323
+ console.error("Error fetching languages:", error);
324
+ }
325
+ }
326
+
327
+ function filterLanguages() {
328
+ if (magazine.data && magazines.data && magazines.data.length > 0) {
329
+ languageId.value = magazine.data.language.id;
330
+ const languageIds = magazines.data.map(
331
+ (item: MagazineItem) => item.language.id,
332
+ );
333
+ languages.value = language.data.filter((language: LanguageItem) =>
334
+ languageIds.includes(language.id),
335
+ );
336
+ languages.value.forEach((language: LanguageItem) => {
337
+ const magazineItem = magazines.data.find(
338
+ (item: MagazineItem) => item.language.id === language.id,
339
+ );
340
+ if (magazineItem) {
341
+ language.magazine_slug = magazineItem.slug;
342
+ }
343
+ });
344
+ }
345
+ }
346
+
347
+ const handleChangeLanguage = () => {
348
+ const selectedLanguage = languages.value.find(
349
+ (lang: LanguageItem) => lang.id === languageId.value,
350
+ );
351
+
352
+ if (selectedLanguage) {
353
+ const magazineSlug = selectedLanguage.magazine_slug;
354
+ router.push(`/${locale.value}/magazine/${magazineSlug}/preview`);
355
+ }
356
+ };
357
+
358
+ async function loadPreviewData() {
359
+ status.value = "init";
360
+ await fetchLanguage();
361
+ await getMagazineData();
362
+ await fetchMagazine();
363
+ await loadFlipbookPages();
364
+ if (import.meta.client) {
365
+ nextTick(() => {
366
+ const element = document.getElementById("header");
367
+ element?.scrollIntoView();
368
+ });
369
+ }
370
+ }
371
+
372
+ watch(slug, () => {
373
+ loadPreviewData();
374
+ }, { immediate: true });
375
+
376
+ const runtimeConfig = useRuntimeConfig();
377
+
378
+ const accountsRegisterUrl = computed(() => {
379
+ const base_url = runtimeConfig.public.accountsBaseUrl;
380
+ if (typeof window !== 'undefined') {
381
+ const current = window.location.href;
382
+ return `${base_url}/register?redirect_to=${encodeURIComponent(current)}&system_id=${runtimeConfig.public.platformId}`;
383
+ }
384
+ return `${base_url}/register?system_id=${runtimeConfig.public.platformId}`;
385
+ });
386
+ </script>
387
+
388
+ <template>
389
+ <div class="container magazine-inside">
390
+ <section v-if="!magazine.data || status !== 'success'">
391
+ <MagazinePreviewSkelectonLoading />
392
+ </section>
393
+ <section v-else>
394
+ <ClientOnly>
395
+ <MgnFlipbook
396
+ v-if="flipbookPages.length > 0 || magazine.data.pdf_url_src"
397
+ :pages="flipbookPages.length > 0 ? flipbookPages : undefined"
398
+ :pdf-url="magazine.data.pdf_url_src"
399
+ :start-page="startPage"
400
+ :enable-sound="true"
401
+ :enable-zoom="true"
402
+ :enable-fullscreen="true"
403
+ :enable-keyboard="true"
404
+ :enable-download="true"
405
+ theme="mgn"
406
+ @page-change="onPageChange"
407
+ @download="handleFlipbookDownload"
408
+ @hotspot-click="onHotspotClick"
409
+ />
410
+ <template #fallback>
411
+ <MagazineFlipBookSkelectonLoading />
412
+ </template>
413
+ </ClientOnly>
414
+ <div
415
+ v-if="!flipbookPages.length && !magazine.data.pdf_url_src && (magazinePages.status === 'pending' || magazinePages.status === 'init')"
416
+ >
417
+ <MagazineFlipBookSkelectonLoading />
418
+ </div>
419
+ <div class="actions">
420
+ <select
421
+ v-model="languageId"
422
+ class="select"
423
+ @change="handleChangeLanguage"
424
+ >
425
+ <option :key="'none'" :value="'none'">
426
+ {{ $t("more.magazine.text_3") }}
427
+ </option>
428
+ <option v-for="lang in languages" :key="lang.id" :value="lang.id">
429
+ {{ lang.localized_name }}
430
+ </option>
431
+ </select>
432
+ </div>
433
+ <div class="description">
434
+ {{ magazine.data.short_description }}
435
+ </div>
436
+ <br />
437
+ <div class="description" v-html="magazine.data.description"></div>
438
+ <div class="condition">
439
+ <div
440
+ v-if="magazine.data.public === false && signedIn === false"
441
+ class="signin"
442
+ >
443
+ {{ $t("more.magazine.text_2") }}
444
+ <a class="btn primary" :href="accountsRegisterUrl">{{
445
+ $t("more.magazine.btn_4")
446
+ }}</a>
447
+ </div>
448
+ <div v-else-if="magazine.data.premium === true" class="signin">
449
+ {{ $t("more.magazine.text_4") }}
450
+ <button class="btn primary">
451
+ {{ $t("more.magazine.btn_5") }}
452
+ </button>
453
+ </div>
454
+ <div v-else class="download">
455
+ <button
456
+ class="btn primary"
457
+ :disabled="!magazine.data.pdf_url"
458
+ @click="downloadPdf"
459
+ >
460
+ {{ $t("more.magazine.btn_2") }}
461
+ </button>
462
+ </div>
463
+ </div>
464
+
465
+ <!-- Lead Capture Modal (for viewing or download) -->
466
+ <Teleport to="body">
467
+ <div v-if="showLeadModal" class="lead-modal-overlay" @click.self="closeLeadModal">
468
+ <div class="lead-modal">
469
+ <h3>{{
470
+ downloadPending
471
+ ? $t("more.magazine.download_lead_title", "Download this magazine")
472
+ : $t("more.magazine.lead_title", "Access this magazine")
473
+ }}</h3>
474
+ <p>{{
475
+ downloadPending
476
+ ? $t("more.magazine.download_lead_desc", "Enter your name and email to download.")
477
+ : $t("more.magazine.lead_desc", "Enter your details to continue reading.")
478
+ }}</p>
479
+ <form @submit.prevent="submitLead">
480
+ <input
481
+ v-model="leadForm.name"
482
+ type="text"
483
+ :placeholder="$t('name', 'Name')"
484
+ required
485
+ class="lead-input"
486
+ />
487
+ <input
488
+ v-model="leadForm.email"
489
+ type="email"
490
+ :placeholder="$t('email', 'Email')"
491
+ required
492
+ class="lead-input"
493
+ />
494
+ <button
495
+ type="submit"
496
+ class="btn primary lead-btn"
497
+ :disabled="leadSubmitting"
498
+ >
499
+ {{
500
+ leadSubmitting
501
+ ? "..."
502
+ : downloadPending
503
+ ? $t("more.magazine.download_lead_submit", "Download")
504
+ : $t("more.magazine.lead_submit", "Continue")
505
+ }}
506
+ </button>
507
+ </form>
508
+ <button class="lead-close" @click="closeLeadModal">&times;</button>
509
+ </div>
510
+ </div>
511
+ </Teleport>
512
+
513
+ <!-- Download Gate Messages -->
514
+ <Teleport to="body">
515
+ <div v-if="showDownloadGateMessage" class="lead-modal-overlay" @click.self="showDownloadGateMessage = ''">
516
+ <div class="lead-modal">
517
+ <!-- Premium gate -->
518
+ <template v-if="showDownloadGateMessage === 'premium'">
519
+ <h3>{{ $t("more.magazine.premium_download_title", "Premium Content") }}</h3>
520
+ <p>{{ $t("more.magazine.premium_download_desc", "Upgrade to premium to download this magazine.") }}</p>
521
+ <button class="btn primary lead-btn" @click="showDownloadGateMessage = ''">
522
+ {{ $t("more.magazine.btn_5", "Upgrade") }}
523
+ </button>
524
+ </template>
525
+
526
+ <!-- Signin gate -->
527
+ <template v-else-if="showDownloadGateMessage === 'signin'">
528
+ <h3>{{ $t("more.magazine.signin_download_title", "Sign in to download") }}</h3>
529
+ <p>{{ $t("more.magazine.signin_download_desc", "Create an account or sign in to download this magazine.") }}</p>
530
+ <a class="btn primary lead-btn" :href="accountsRegisterUrl" style="text-decoration: none; text-align: center;">
531
+ {{ $t("more.magazine.btn_4", "Sign up") }}
532
+ </a>
533
+ </template>
534
+
535
+ <button class="lead-close" @click="showDownloadGateMessage = ''">&times;</button>
536
+ </div>
537
+ </div>
538
+ </Teleport>
539
+
540
+ <NewsletterFullWidthComponent />
541
+ <MagazinesList />
542
+ </section>
543
+ <DiscordEmbedComponent class="mt-5" />
544
+ </div>
545
+ </template>
546
+
547
+ <style lang="scss" scoped>
548
+ .magazine-inside {
549
+ h1 {
550
+ font-family: Roboto;
551
+ font-size: 32px;
552
+ font-style: normal;
553
+ font-weight: 900;
554
+ line-height: 40px;
555
+ color: var(--text-magazine);
556
+ }
557
+
558
+ .sub-infos {
559
+ display: flex;
560
+ align-items: center;
561
+ gap: 24px;
562
+ align-self: stretch;
563
+ margin-top: 24px;
564
+
565
+ .edition {
566
+ color: var(--text-magazine);
567
+ font-family: Roboto;
568
+ font-size: 14px;
569
+ font-style: normal;
570
+ font-weight: 400;
571
+ line-height: 20px;
572
+ }
573
+
574
+ .data {
575
+ font-family: Roboto;
576
+ font-size: 14px;
577
+ font-style: normal;
578
+ font-weight: 400;
579
+ line-height: 20px;
580
+ color: var(--text-magazine);
581
+ text-transform: uppercase;
582
+ }
583
+ }
584
+
585
+ .image-content {
586
+ margin-top: 40px;
587
+ margin-bottom: 40px;
588
+ display: flex;
589
+ padding: 16px 0px;
590
+ flex-direction: column;
591
+ justify-content: center;
592
+ align-items: center;
593
+ gap: 24px;
594
+ align-self: stretch;
595
+
596
+ .premium-card {
597
+ position: relative;
598
+
599
+ .premium {
600
+ display: flex;
601
+ width: 534px;
602
+ height: 692.757px;
603
+ padding: 16px;
604
+ flex-direction: column;
605
+ justify-content: center;
606
+ align-items: center;
607
+ flex-shrink: 0;
608
+ background: rgba(19, 22, 28, 0.5);
609
+ backdrop-filter: blur(2px);
610
+ position: absolute;
611
+ color: var(--text-magazine);
612
+ text-align: center;
613
+ font-family: Roboto;
614
+ font-size: 18px;
615
+ font-style: normal;
616
+ font-weight: 600;
617
+ line-height: 26px;
618
+
619
+ img {
620
+ width: 100%;
621
+ height: auto;
622
+ position: relative;
623
+ }
624
+ }
625
+ }
626
+
627
+ img {
628
+ width: 534px;
629
+ height: 695px;
630
+ flex-shrink: 0;
631
+ box-shadow: -7px 1px 12.8px 0px rgba(0, 0, 0, 0.15);
632
+ }
633
+ }
634
+
635
+ .description {
636
+ font-family: Roboto;
637
+ font-size: 16px;
638
+ font-style: normal;
639
+ font-weight: 400;
640
+ color: var(--text-magazine);
641
+ line-height: 24px;
642
+ word-break: break-all;
643
+ }
644
+
645
+ .condition {
646
+ width: 100%;
647
+ text-align: -webkit-center;
648
+
649
+ .signin {
650
+ display: flex;
651
+ padding: 8px 16px;
652
+ flex-direction: column;
653
+ align-items: center;
654
+ gap: 16px;
655
+ align-self: stretch;
656
+ max-width: 618px;
657
+ width: 100%;
658
+ margin-top: 24px;
659
+ background-color: var(--news-card-bg);
660
+ color: var(--text-magazine);
661
+ font-family: Roboto;
662
+ font-size: 14px;
663
+ font-style: normal;
664
+ font-weight: 400;
665
+ line-height: 20px;
666
+
667
+ .btn {
668
+ display: flex;
669
+ width: 220px;
670
+ height: 44px;
671
+ padding: 0px 12px;
672
+ justify-content: center;
673
+ font-family: Roboto;
674
+ font-size: 16px;
675
+ font-style: normal;
676
+ font-weight: 400;
677
+ line-height: 24px;
678
+ align-items: center;
679
+ }
680
+ }
681
+
682
+ .download {
683
+ margin-top: 24px;
684
+ width: 100%;
685
+ display: flex;
686
+ gap: 24px;
687
+ justify-content: flex-end;
688
+
689
+ .select {
690
+ border-style: solid;
691
+ background: transparent;
692
+ border-width: 0px 0px 1px 0px;
693
+ padding: 12px 12px;
694
+ display: flex;
695
+ max-width: 224px;
696
+ flex-direction: row;
697
+ align-items: center;
698
+ justify-content: flex-start;
699
+ align-self: stretch;
700
+ flex-shrink: 0;
701
+ margin-right: 16px;
702
+ color: var(--darkcommunity-content-text-inactive, #aaaaaa);
703
+ text-align: left;
704
+ font: var(--body-1, 400 16px/24px "Roboto", sans-serif);
705
+ position: relative;
706
+ flex: 1;
707
+ transition: 0.15s ease-in-out;
708
+
709
+ &:last-child {
710
+ margin-right: 0px;
711
+ }
712
+
713
+ &:focus,
714
+ &:focus-visible,
715
+ &:active {
716
+ transition: 0.15s ease-in-out;
717
+ border: 2px solid var(--search-bar-active-border-color);
718
+ }
719
+
720
+ option {
721
+ background: var(--search-bar-bg);
722
+ padding: 0px 16px;
723
+ gap: 16px;
724
+ align-items: center;
725
+ justify-content: flex-start;
726
+ height: 48px !important;
727
+ position: relative;
728
+ color: var(--active) !important;
729
+ text-align: left;
730
+ font: var(--body-1, 400 16px/24px "Roboto", sans-serif) !important;
731
+ }
732
+ }
733
+
734
+ .btn {
735
+ display: flex;
736
+ width: 220px;
737
+ height: 44px;
738
+ padding: 0px 12px;
739
+ justify-content: center;
740
+ font-family: Roboto;
741
+ font-size: 16px;
742
+ font-style: normal;
743
+ font-weight: 400;
744
+ line-height: 24px;
745
+ align-items: center;
746
+ }
747
+ }
748
+ }
749
+ }
750
+
751
+ .actions {
752
+ display: flex;
753
+ justify-content: center;
754
+ align-items: center;
755
+ margin: 20px auto;
756
+ .select {
757
+ border-style: solid;
758
+ background: transparent;
759
+ border-width: 0px 0px 1px 0px;
760
+ padding: 5px 12px;
761
+ display: flex;
762
+ flex-direction: row;
763
+ max-width: 224px;
764
+ align-items: center;
765
+ justify-content: flex-start;
766
+ align-self: stretch;
767
+ flex-shrink: 0;
768
+ margin-right: 16px;
769
+ color: var(--darkcommunity-content-text-inactive, #aaaaaa);
770
+ text-align: left;
771
+ font: var(--body-1, 400 16px/24px "Roboto", sans-serif);
772
+ position: relative;
773
+ flex: 1;
774
+ transition: 0.15s ease-in-out;
775
+
776
+ &:last-child {
777
+ margin-right: 0px;
778
+ }
779
+
780
+ &:focus,
781
+ &:focus-visible,
782
+ &:active {
783
+ transition: 0.15s ease-in-out;
784
+ border: 2px solid var(--search-bar-active-border-color);
785
+ }
786
+
787
+ option {
788
+ background: var(--search-bar-bg);
789
+ padding: 0px 16px;
790
+ gap: 16px;
791
+ align-items: center;
792
+ justify-content: flex-start;
793
+ height: 48px !important;
794
+ position: relative;
795
+ color: var(--active) !important;
796
+ text-align: left;
797
+ font: var(--body-1, 400 16px/24px "Roboto", sans-serif) !important;
798
+ }
799
+ }
800
+ }
801
+
802
+ @media screen and (max-width: 768px) {
803
+ .magazine-inside {
804
+ .image-content {
805
+ margin-bottom: 300px;
806
+
807
+ img {
808
+ width: 300px;
809
+ height: 400px;
810
+ flex-shrink: 0;
811
+ box-shadow: -7px 1px 12.8px 0px rgba(0, 0, 0, 0.15);
812
+ }
813
+
814
+ .premium-card {
815
+ .premium {
816
+ width: 300px;
817
+ height: 400px;
818
+ }
819
+ }
820
+ }
821
+ }
822
+ .actions {
823
+ flex-direction: row;
824
+ gap: 1rem;
825
+ }
826
+ }
827
+
828
+ @media screen and (min-width: 0px) and (max-width: 460px) {
829
+ .actions {
830
+ flex-direction: column !important;
831
+ gap: 1rem;
832
+ }
833
+ }
834
+
835
+ .lead-modal-overlay {
836
+ position: fixed;
837
+ top: 0;
838
+ left: 0;
839
+ width: 100%;
840
+ height: 100%;
841
+ background: rgba(0, 0, 0, 0.7);
842
+ display: flex;
843
+ align-items: center;
844
+ justify-content: center;
845
+ z-index: 9999;
846
+ }
847
+
848
+ .lead-modal {
849
+ background: var(--news-card-bg, #1a1a2e);
850
+ border-radius: 12px;
851
+ padding: 32px;
852
+ max-width: 420px;
853
+ width: 90%;
854
+ position: relative;
855
+ color: var(--text-magazine, #fff);
856
+
857
+ h3 {
858
+ font-family: Roboto;
859
+ font-size: 20px;
860
+ font-weight: 700;
861
+ margin-bottom: 8px;
862
+ }
863
+
864
+ p {
865
+ font-family: Roboto;
866
+ font-size: 14px;
867
+ margin-bottom: 24px;
868
+ opacity: 0.8;
869
+ }
870
+
871
+ form {
872
+ display: flex;
873
+ flex-direction: column;
874
+ gap: 12px;
875
+ }
876
+
877
+ .lead-input {
878
+ width: 100%;
879
+ padding: 12px 16px;
880
+ border-radius: 8px;
881
+ border: 1px solid rgba(255, 255, 255, 0.2);
882
+ background: rgba(255, 255, 255, 0.05);
883
+ color: var(--text-magazine, #fff);
884
+ font-family: Roboto;
885
+ font-size: 14px;
886
+ outline: none;
887
+ box-sizing: border-box;
888
+
889
+ &:focus {
890
+ border-color: var(--primary, #ee3831);
891
+ }
892
+
893
+ &::placeholder {
894
+ color: rgba(255, 255, 255, 0.4);
895
+ }
896
+ }
897
+
898
+ .lead-btn {
899
+ width: 100%;
900
+ height: 44px;
901
+ margin-top: 8px;
902
+ }
903
+
904
+ .lead-close {
905
+ position: absolute;
906
+ top: 12px;
907
+ right: 16px;
908
+ background: none;
909
+ border: none;
910
+ color: var(--text-magazine, #fff);
911
+ font-size: 24px;
912
+ cursor: pointer;
913
+ opacity: 0.6;
914
+
915
+ &:hover {
916
+ opacity: 1;
917
+ }
918
+ }
919
+ }
920
+ </style>