@mundogamernetwork/shared-ui 1.8.2 → 1.8.4
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/components/keys/KeyCampaignDashboardCard.vue +14 -0
- package/components/keys/KeyCampaignsCarousel.vue +13 -95
- package/components/ui/MgHeaderUIUser.vue +1 -1
- package/components/ui/MgWalletPlanBadge.vue +1 -1
- package/package.json +1 -1
- package/pages/key-campaign/[slug].vue +8 -2
- package/pages/key-campaigns/[slug].vue +16 -4
- package/pages/key-campaigns/index.vue +18 -6
- package/pages/media-kit/[slug].vue +643 -610
- package/pages/presskit/game/[slug].vue +8 -2
- package/public/imgs/default-avatar.png +0 -0
- package/services/campaignService.ts +11 -8
- package/services/mediaKitProposalService.ts +35 -0
- package/stores/shortlist.ts +113 -0
|
@@ -1,16 +1,58 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { fetchPublicMediaKit, trackMediaKitEvent } from '../../services/mediaKitService';
|
|
3
|
+
import { sendMediaKitProposal } from '../../services/mediaKitProposalService';
|
|
3
4
|
import MediaKitWallBlock from '../../components/indie-wall/MediaKitWallBlock.vue';
|
|
4
5
|
import MgMediaKitStore from '../../components/MediaKit/MgMediaKitStore.vue';
|
|
5
6
|
|
|
6
7
|
const route = useRoute();
|
|
7
8
|
const slug = computed(() => route.params.slug as string);
|
|
9
|
+
const localePath = useLocalePath();
|
|
10
|
+
const { t } = useI18n();
|
|
11
|
+
|
|
12
|
+
// Same cross-link pattern as shared-ui/pages/presskit/game/[slug].vue — the
|
|
13
|
+
// "made with" footer CTA points here regardless of which service serves this page.
|
|
14
|
+
const runtimeConfig = useRuntimeConfig();
|
|
15
|
+
const cfg = (runtimeConfig.public as any) || {};
|
|
16
|
+
const agencyBase: string = cfg.agencyBaseUrl || '';
|
|
17
|
+
const authStore = useAuthStore();
|
|
18
|
+
const toast = useToast();
|
|
19
|
+
|
|
20
|
+
// ── C2: internal shortlist / Campaign Wizard bar ──
|
|
21
|
+
// Only ever renders on agency-frontend (isAgencyHost) — Campaign Wizard and the
|
|
22
|
+
// shortlist's localStorage only live there; rendering this on tv-frontend/
|
|
23
|
+
// community-frontend would silently lose items on navigation (different origin).
|
|
24
|
+
// `viewer_can_manage_shortlist` is server-computed (brand/agency/studio profile_types,
|
|
25
|
+
// see PublicMediaKitController::viewerCanBypassRateCardGate) — the true security
|
|
26
|
+
// boundary is already there (gated rate cards never leave the API for ineligible
|
|
27
|
+
// viewers); this only controls whether the bar itself renders.
|
|
28
|
+
const shortlist = useShortlistStore();
|
|
8
29
|
|
|
9
30
|
const kit = ref<Record<string, any> | null>(null);
|
|
10
31
|
const loading = ref(true);
|
|
11
32
|
const error = ref(false);
|
|
12
33
|
|
|
13
34
|
const userId = computed(() => kit.value?.user_id);
|
|
35
|
+
const influencerProId = computed<number | null>(() => kit.value?.influencer_professional_info_id ?? null);
|
|
36
|
+
const isOwnKit = computed(() => !!authStore.user?.id && !!userId.value && String(authStore.user.id) === String(userId.value));
|
|
37
|
+
const showShortlistBar = computed(() =>
|
|
38
|
+
!!cfg.isAgencyHost
|
|
39
|
+
&& !!kit.value?.viewer_can_manage_shortlist
|
|
40
|
+
&& !isOwnKit.value
|
|
41
|
+
&& !!influencerProId.value,
|
|
42
|
+
);
|
|
43
|
+
const inShortlist = computed(() => influencerProId.value ? shortlist.has(influencerProId.value) : false);
|
|
44
|
+
const campaignWizardUrl = computed(() => `${agencyBase}/dashboard/campaign-wizard?influencers=${shortlist.ids.join(',')}`);
|
|
45
|
+
|
|
46
|
+
function toggleShortlist() {
|
|
47
|
+
if (!influencerProId.value) return;
|
|
48
|
+
shortlist.toggle({
|
|
49
|
+
id: influencerProId.value,
|
|
50
|
+
name: streamer.value?.name || slug.value,
|
|
51
|
+
slug: streamer.value?.slug || slug.value,
|
|
52
|
+
image: streamer.value?.avatar || null,
|
|
53
|
+
rate_cards: rateCards.value,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
14
56
|
const streamer = computed(() => kit.value?.streamer ?? {});
|
|
15
57
|
const stats = computed(() => kit.value?.stats ?? null);
|
|
16
58
|
const topGames = computed(() => kit.value?.top_games ?? []);
|
|
@@ -32,8 +74,20 @@ const brandLogos = computed(() => kit.value?.brand_logos ?? streamer.value?.bran
|
|
|
32
74
|
const creatorStore = computed(() => kit.value?.creator_store ?? null);
|
|
33
75
|
const customLinks = computed(() => kit.value?.custom_links ?? streamer.value?.custom_links ?? []);
|
|
34
76
|
|
|
77
|
+
// ── D2 ecosystem data ──
|
|
78
|
+
const selectedGames = computed<string[]>(() => kit.value?.selected_games ?? []);
|
|
79
|
+
const audienceGeo = computed<any[]>(() => kit.value?.audience_geo ?? []);
|
|
80
|
+
const platformsPlayed = computed<any[]>(() => kit.value?.platforms_played ?? []);
|
|
81
|
+
const academyMentor = computed(() => kit.value?.academy_mentor ?? null);
|
|
82
|
+
const communityStats = computed(() => kit.value?.community ?? null);
|
|
83
|
+
const tvChannelLogin = computed<string | null>(() => streamer.value?.tv_channel_login ?? null);
|
|
84
|
+
const tvSiteUrl = import.meta.env.VITE_TV_SITE_URL || 'https://mundogamer.tv';
|
|
85
|
+
const tvChannelUrl = computed(() => tvChannelLogin.value
|
|
86
|
+
? `${tvSiteUrl}/${route.params.locale || 'en'}/stream/${tvChannelLogin.value}`
|
|
87
|
+
: null);
|
|
88
|
+
|
|
35
89
|
const coverStyle = computed(() => coverUrl.value
|
|
36
|
-
? { backgroundImage: `linear-gradient(180deg, rgba(
|
|
90
|
+
? { backgroundImage: `linear-gradient(180deg, rgba(10,10,12,.15), rgba(10,10,12,.85)), url("${String(coverUrl.value).replace(/"/g, '\\"')}")` }
|
|
37
91
|
: undefined);
|
|
38
92
|
|
|
39
93
|
const PLATFORM_LABEL: Record<string, string> = {
|
|
@@ -54,20 +108,100 @@ const scheduleByDay = computed(() => {
|
|
|
54
108
|
return [0, 1, 2, 3, 4, 5, 6].map((d) => ({ d, key: DOW[d], slot: map[d] || null }));
|
|
55
109
|
});
|
|
56
110
|
|
|
111
|
+
// ── Tabs: template picks which one opens first, casting-details-style ──
|
|
112
|
+
const TAB_KEYS = ['profile', 'rates', 'performance'] as const;
|
|
113
|
+
const TEMPLATE_DEFAULT_TAB: Record<string, number> = {
|
|
114
|
+
creator: 0, audience: 0, commercial: 1, performance: 2,
|
|
115
|
+
};
|
|
116
|
+
const activeTab = ref(TEMPLATE_DEFAULT_TAB[template.value] ?? 0);
|
|
117
|
+
const hasRatesTab = computed(() => rateCards.value.length > 0 || bundles.value.length > 0);
|
|
118
|
+
const hasPerformanceTab = computed(() => !!stats.value || !!academyMentor.value || !!communityStats.value || schedule.value.length > 0);
|
|
119
|
+
|
|
120
|
+
// ── Rate card / bundle proposal builder ──
|
|
121
|
+
const cartMode = ref<'packages' | 'individual'>(hasRatesTab.value && rateCards.value.length ? 'individual' : 'packages');
|
|
122
|
+
const selectedCardIndexes = ref<Set<number>>(new Set());
|
|
123
|
+
|
|
124
|
+
function toggleCardSelection(i: number) {
|
|
125
|
+
const next = new Set(selectedCardIndexes.value);
|
|
126
|
+
next.has(i) ? next.delete(i) : next.add(i);
|
|
127
|
+
selectedCardIndexes.value = next;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const cartItems = computed(() => rateCards.value.filter((_: any, i: number) => selectedCardIndexes.value.has(i)));
|
|
131
|
+
const cartTotal = computed(() => cartItems.value.reduce((sum: number, c: any) => sum + Number(c.price_min || 0), 0));
|
|
132
|
+
const cartCurrency = computed(() => cartItems.value[0]?.currency || 'BRL');
|
|
133
|
+
|
|
134
|
+
const sendingProposal = ref(false);
|
|
135
|
+
|
|
136
|
+
async function submitBundleProposal(bundle: any) {
|
|
137
|
+
await submitProposal({
|
|
138
|
+
title: `${t('kit.media.rates_bundle_proposal_title')}: ${bundle.name}`,
|
|
139
|
+
amount: Number(bundle.bundle_price || 0),
|
|
140
|
+
currency: bundle.currency || 'BRL',
|
|
141
|
+
deliverables: (bundle.rate_cards || []).map((i: any) => ({ title: i.label, description: `${i.quantity || 1}x` })),
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
async function submitCartProposal() {
|
|
146
|
+
if (!cartItems.value.length) return;
|
|
147
|
+
await submitProposal({
|
|
148
|
+
title: t('kit.media.rates_custom_proposal_title'),
|
|
149
|
+
amount: cartTotal.value,
|
|
150
|
+
currency: cartCurrency.value,
|
|
151
|
+
deliverables: cartItems.value.map((c: any) => ({ title: c.label, description: c.content_format || c.ad_channel })),
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
async function submitProposal(opts: { title: string; amount: number; currency: string; deliverables: { title: string; description?: string }[] }) {
|
|
156
|
+
if (!influencerProId.value) return;
|
|
157
|
+
|
|
158
|
+
if (!authStore.user?.id) {
|
|
159
|
+
const returnTo = useRequestURL().href;
|
|
160
|
+
navigateTo(localePath(`/login?redirect=${encodeURIComponent(returnTo)}`));
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
sendingProposal.value = true;
|
|
165
|
+
try {
|
|
166
|
+
await sendMediaKitProposal({
|
|
167
|
+
receiverInfluencerProId: influencerProId.value,
|
|
168
|
+
senderUserId: authStore.user.id,
|
|
169
|
+
title: opts.title,
|
|
170
|
+
proposedAmount: opts.amount,
|
|
171
|
+
currency: opts.currency,
|
|
172
|
+
deliverables: opts.deliverables,
|
|
173
|
+
});
|
|
174
|
+
toast.success(t('kit.media.proposal_sent'));
|
|
175
|
+
selectedCardIndexes.value = new Set();
|
|
176
|
+
track('contact');
|
|
177
|
+
} catch (err) {
|
|
178
|
+
toast.error(t('kit.media.proposal_error'));
|
|
179
|
+
} finally {
|
|
180
|
+
sendingProposal.value = false;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
57
184
|
// SSR-safe fetch so bots/link-preview scrapers (which don't run JS) get the
|
|
58
185
|
// real creator data for the SEO tags below, instead of the site-wide default.
|
|
59
186
|
const { data: ssrKitData } = await useAsyncData(
|
|
60
187
|
`media-kit-${slug.value}`,
|
|
61
188
|
() => fetchPublicMediaKit(slug.value).then(r => r.data?.data || r.data).catch(() => null),
|
|
62
189
|
);
|
|
63
|
-
if (ssrKitData.value)
|
|
64
|
-
|
|
190
|
+
if (ssrKitData.value) {
|
|
191
|
+
kit.value = ssrKitData.value;
|
|
192
|
+
activeTab.value = TEMPLATE_DEFAULT_TAB[kit.value?.template || 'creator'] ?? 0;
|
|
193
|
+
} else {
|
|
194
|
+
error.value = true;
|
|
195
|
+
}
|
|
65
196
|
loading.value = false;
|
|
66
197
|
|
|
67
198
|
onMounted(() => {
|
|
68
199
|
if (kit.value?.user_id) {
|
|
69
200
|
trackMediaKitEvent(kit.value.user_id, { type: 'view', referrer: document.referrer || undefined }).catch(() => {});
|
|
70
201
|
}
|
|
202
|
+
if (cfg.isAgencyHost) {
|
|
203
|
+
shortlist.hydrate();
|
|
204
|
+
}
|
|
71
205
|
});
|
|
72
206
|
|
|
73
207
|
const requestUrl = useRequestURL();
|
|
@@ -121,202 +255,296 @@ function onDownload() {
|
|
|
121
255
|
<template v-else>
|
|
122
256
|
<div class="mk-cover" :class="{ 'has-image': coverUrl }" :style="coverStyle" />
|
|
123
257
|
|
|
124
|
-
<div class="kit-wrap mk-
|
|
125
|
-
|
|
258
|
+
<div class="kit-wrap mk-layout">
|
|
259
|
+
<!-- ══════════════ SIDEBAR ══════════════ -->
|
|
260
|
+
<aside class="mk-sidebar">
|
|
126
261
|
<img v-if="streamer.avatar" class="mk-avatar" :src="streamer.avatar" :alt="streamer.name" />
|
|
127
262
|
<div v-else class="mk-avatar mk-avatar-ph" />
|
|
128
263
|
|
|
129
|
-
<
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
264
|
+
<h1 class="mk-name">{{ streamer.name }}</h1>
|
|
265
|
+
<p v-if="streamer.custom_headline" class="mk-headline">{{ streamer.custom_headline }}</p>
|
|
266
|
+
<p v-if="streamer.slug" class="mk-handle">@{{ streamer.slug }}</p>
|
|
267
|
+
|
|
268
|
+
<div class="mk-badges">
|
|
269
|
+
<span v-if="streamer.platform" class="mk-badge plat">{{ streamer.platform }}</span>
|
|
270
|
+
<span v-if="streamer.tier && streamer.tier !== 'free'" class="mk-badge tier">{{ String(streamer.tier).toUpperCase() }}</span>
|
|
271
|
+
</div>
|
|
272
|
+
|
|
273
|
+
<div v-if="showShortlistBar" class="mk-internal-bar no-print">
|
|
274
|
+
<button class="kit-btn" :class="inShortlist ? 'kit-btn-primary' : 'kit-btn-ghost'" @click="toggleShortlist">
|
|
275
|
+
{{ inShortlist ? $t('kit.media.shortlist_remove') : $t('kit.media.shortlist_add') }}
|
|
276
|
+
</button>
|
|
277
|
+
<a v-if="shortlist.count" class="kit-btn kit-btn-ghost" :href="campaignWizardUrl" target="_blank" rel="noopener">
|
|
278
|
+
{{ $t('kit.media.go_to_campaign') }} ({{ shortlist.count }})
|
|
279
|
+
</a>
|
|
138
280
|
</div>
|
|
139
281
|
|
|
140
282
|
<div class="mk-actions no-print">
|
|
141
283
|
<a class="kit-btn kit-btn-primary" @click="onDownload">{{ $t('kit.media.download_pdf') }}</a>
|
|
142
284
|
<a v-if="streamer.contact_email" class="kit-btn kit-btn-ghost" :href="`mailto:${streamer.contact_email}`" @click="track('contact')">{{ $t('kit.media.contact') }}</a>
|
|
143
285
|
</div>
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
<a v-for="(link, index) in customLinks" :key="`${link.url}-${index}`" class="mk-link" :class="{ 'mk-link--primary': index === 0 }" :href="link.url" target="_blank" rel="noopener" @click="track('click')">
|
|
149
|
-
<span>{{ link.label }}</span><b>↗</b>
|
|
150
|
-
</a>
|
|
151
|
-
<a v-if="streamer.contact_email" class="mk-link mk-link--primary" :href="`mailto:${streamer.contact_email}`" @click="track('contact')">
|
|
152
|
-
<span>{{ $t('kit.media.work_with_me') }}</span><b>↗</b>
|
|
153
|
-
</a>
|
|
154
|
-
<a v-if="creatorStore" class="mk-link" href="#store" @click="track('click')">
|
|
155
|
-
<span>{{ $t('kit.media.visit_store') }}</span><b>↓</b>
|
|
156
|
-
</a>
|
|
157
|
-
<a v-if="userId" class="mk-link" href="#support" @click="track('click')">
|
|
158
|
-
<span>{{ $t('kit.media.visit_mural') }}</span><b>↓</b>
|
|
159
|
-
</a>
|
|
160
|
-
<a v-for="s in socials" :key="s.platform" class="mk-link mk-link--social" :href="s.url" target="_blank" rel="noopener" @click="track('click')">
|
|
161
|
-
<span>{{ PLATFORM_LABEL[s.platform] || s.platform }}</span><b>↗</b>
|
|
162
|
-
</a>
|
|
163
|
-
</nav>
|
|
164
|
-
|
|
165
|
-
<!-- Reach / multi-platform followers -->
|
|
166
|
-
<section v-if="platforms.length" class="kit-block" data-sec="reach">
|
|
167
|
-
<h2>{{ $t('kit.media.reach') }}</h2>
|
|
168
|
-
<p v-if="totalFollowers" class="mk-total-reach">{{ fmt(totalFollowers) }} <span>{{ $t('kit.media.total_reach') }}</span></p>
|
|
169
|
-
<div class="mk-platforms">
|
|
170
|
-
<a v-for="p in platforms" :key="p.platform" class="mk-platform" :href="p.url || undefined" target="_blank" rel="noopener" @click="track('click')">
|
|
171
|
-
<div class="pl-head">
|
|
172
|
-
<span class="pl-name">{{ PLATFORM_LABEL[p.platform] || p.platform }}</span>
|
|
173
|
-
<span v-if="p.verified" class="pl-verified" :title="$t('kit.media.verified')">✓</span>
|
|
174
|
-
</div>
|
|
175
|
-
<div class="pl-followers">{{ fmt(p.followers) }}</div>
|
|
176
|
-
<div class="pl-meta">
|
|
177
|
-
<span v-if="p.engagement_rate != null">{{ p.engagement_rate }}% {{ $t('kit.media.eng_short') }}</span>
|
|
178
|
-
<span v-if="p.avg_views != null">{{ fmt(p.avg_views) }} {{ $t('kit.media.views_short') }}</span>
|
|
179
|
-
</div>
|
|
180
|
-
</a>
|
|
286
|
+
|
|
287
|
+
<div v-if="totalFollowers" class="mk-sb-stat">
|
|
288
|
+
<span class="n">{{ fmt(totalFollowers) }}</span>
|
|
289
|
+
<span class="l">{{ $t('kit.media.total_reach') }}</span>
|
|
181
290
|
</div>
|
|
182
|
-
</section>
|
|
183
291
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
292
|
+
<!-- Personal link hub: replaces a separate link-in-bio service. -->
|
|
293
|
+
<nav v-if="customLinks.length || tvChannelUrl || creatorStore || userId" class="mk-link-hub no-print" data-sec="links" :aria-label="$t('kit.media.quick_links')">
|
|
294
|
+
<a v-if="tvChannelUrl" class="mk-link mk-link--tv" :href="tvChannelUrl" target="_blank" rel="noopener" @click="track('click')">
|
|
295
|
+
<span>📺 {{ $t('kit.media.tv_channel') }}</span><b>↗</b>
|
|
296
|
+
</a>
|
|
297
|
+
<a v-for="(link, index) in customLinks" :key="`${link.url}-${index}`" class="mk-link" :href="link.url" target="_blank" rel="noopener" @click="track('click')">
|
|
298
|
+
<span>{{ link.label }}</span><b>↗</b>
|
|
299
|
+
</a>
|
|
300
|
+
<a v-if="creatorStore" class="mk-link" href="#store" @click="track('click')">
|
|
301
|
+
<span>{{ $t('kit.media.visit_store') }}</span><b>↓</b>
|
|
302
|
+
</a>
|
|
303
|
+
<a v-if="userId" class="mk-link" href="#support" @click="track('click')">
|
|
304
|
+
<span>{{ $t('kit.media.visit_mural') }}</span><b>↓</b>
|
|
305
|
+
</a>
|
|
306
|
+
</nav>
|
|
188
307
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
<div v-if="portfolioImages.length" class="mk-portfolio">
|
|
193
|
-
<a v-for="(image, index) in portfolioImages" :key="image" :href="image" target="_blank" rel="noopener" @click="track('click')">
|
|
194
|
-
<img :src="image" :alt="`${streamer.name} — ${index + 1}`" />
|
|
308
|
+
<div v-if="socials.length" class="mk-socials no-print">
|
|
309
|
+
<a v-for="s in socials" :key="s.platform" class="mk-soc" :href="s.url" target="_blank" rel="noopener" :title="PLATFORM_LABEL[s.platform] || s.platform" @click="track('click')">
|
|
310
|
+
{{ (PLATFORM_LABEL[s.platform] || s.platform).slice(0, 2).toUpperCase() }}
|
|
195
311
|
</a>
|
|
196
312
|
</div>
|
|
197
|
-
|
|
198
|
-
|
|
313
|
+
</aside>
|
|
314
|
+
|
|
315
|
+
<!-- ══════════════ MAIN: TABS ══════════════ -->
|
|
316
|
+
<main class="mk-main">
|
|
317
|
+
<div class="mk-tabs no-print">
|
|
318
|
+
<button class="mk-tab" :class="{ active: activeTab === 0 }" @click="activeTab = 0">{{ $t('kit.media.tab_profile') }}</button>
|
|
319
|
+
<button v-if="hasRatesTab" class="mk-tab" :class="{ active: activeTab === 1 }" @click="activeTab = 1">{{ $t('kit.media.tab_rates') }}</button>
|
|
320
|
+
<button v-if="hasPerformanceTab" class="mk-tab" :class="{ active: activeTab === 2 }" @click="activeTab = 2">{{ $t('kit.media.tab_performance') }}</button>
|
|
199
321
|
</div>
|
|
200
|
-
</section>
|
|
201
322
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
<p v-if="period" class="mk-period">{{ $t('kit.media.last_days', { days: period.days }) }} · {{ period.start }} — {{ period.end }}</p>
|
|
206
|
-
<div class="mk-metrics">
|
|
207
|
-
<div class="mk-metric"><div class="val accent">{{ fmt(stats.total_followers) }}</div><div class="lab">{{ $t('kit.media.followers') }}</div></div>
|
|
208
|
-
<div class="mk-metric"><div class="val">{{ fmt(stats.avg_viewers) }}</div><div class="lab">{{ $t('kit.media.avg_viewers') }}</div></div>
|
|
209
|
-
<div class="mk-metric"><div class="val">{{ fmt(stats.peak_viewers) }}</div><div class="lab">{{ $t('kit.media.peak_viewers') }}</div></div>
|
|
210
|
-
<div class="mk-metric"><div class="val">{{ stats.streams_per_week }}</div><div class="lab">{{ $t('kit.media.streams_week') }}</div></div>
|
|
211
|
-
<div class="mk-metric"><div class="val">{{ fmt(stats.total_streams_90d) }}</div><div class="lab">{{ $t('kit.media.total_streams') }}</div></div>
|
|
212
|
-
<div class="mk-metric"><div class="val">{{ stats.total_hours_90d }}h</div><div class="lab">{{ $t('kit.media.hours') }}</div></div>
|
|
213
|
-
<div class="mk-metric"><div class="val accent">+{{ fmt(stats.new_followers_90d) }}</div><div class="lab">{{ $t('kit.media.new_followers') }}</div></div>
|
|
214
|
-
<div class="mk-metric"><div class="val">{{ fmt(stats.total_chat_messages) }}</div><div class="lab">{{ $t('kit.media.chat') }}</div></div>
|
|
215
|
-
</div>
|
|
216
|
-
</section>
|
|
323
|
+
<!-- ── TAB: PERFIL ── -->
|
|
324
|
+
<div class="mk-tabpanel" :class="{ active: activeTab === 0 }" data-print-tab="profile">
|
|
325
|
+
<p v-if="streamer.bio" class="mk-bio">{{ streamer.bio }}</p>
|
|
217
326
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
<div class="mk-track"><div class="mk-fill" :style="{ width: a.percent + '%' }" /></div>
|
|
327
|
+
<section v-if="academyMentor" class="kit-block" data-sec="academy">
|
|
328
|
+
<h2>{{ $t('kit.media.academy_mentor_title') }}</h2>
|
|
329
|
+
<div class="mk-mentor-badge">
|
|
330
|
+
🎓 {{ $t('kit.media.academy_mentor_label') }} · <b>{{ academyMentor.creator_title }}</b>
|
|
331
|
+
<span v-if="academyMentor.game">— {{ academyMentor.game }}</span>
|
|
332
|
+
<span class="mk-mentor-stats">
|
|
333
|
+
{{ academyMentor.total_students }} {{ $t('kit.media.academy_students') }} · {{ academyMentor.avg_rating.toFixed(1) }}★
|
|
334
|
+
</span>
|
|
227
335
|
</div>
|
|
228
|
-
</
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
<
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
<div class="
|
|
235
|
-
|
|
336
|
+
</section>
|
|
337
|
+
|
|
338
|
+
<section v-if="platforms.length" class="kit-block" data-sec="reach">
|
|
339
|
+
<h2>{{ $t('kit.media.reach') }}</h2>
|
|
340
|
+
<div class="mk-platforms">
|
|
341
|
+
<a v-for="p in platforms" :key="p.platform" class="mk-platform" :href="p.url || undefined" target="_blank" rel="noopener" @click="track('click')">
|
|
342
|
+
<div class="pl-head">
|
|
343
|
+
<span class="pl-name">{{ PLATFORM_LABEL[p.platform] || p.platform }}</span>
|
|
344
|
+
<span v-if="p.verified" class="pl-verified" :title="$t('kit.media.verified')">✓</span>
|
|
345
|
+
</div>
|
|
346
|
+
<div class="pl-followers">{{ fmt(p.followers) }}</div>
|
|
347
|
+
<div class="pl-meta">
|
|
348
|
+
<span v-if="p.engagement_rate != null">{{ p.engagement_rate }}% {{ $t('kit.media.eng_short') }}</span>
|
|
349
|
+
<span v-if="p.avg_views != null">{{ fmt(p.avg_views) }} {{ $t('kit.media.views_short') }}</span>
|
|
350
|
+
</div>
|
|
351
|
+
</a>
|
|
236
352
|
</div>
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
353
|
+
</section>
|
|
354
|
+
|
|
355
|
+
<section v-if="audienceGeo.length" class="kit-block" data-sec="geo">
|
|
356
|
+
<h2>{{ $t('kit.media.audience_geo') }}</h2>
|
|
357
|
+
<div class="mk-geo">
|
|
358
|
+
<div v-for="c in audienceGeo" :key="c.isocode" class="mk-bar">
|
|
359
|
+
<div class="top">
|
|
360
|
+
<span><img v-if="c.flag_url" :src="c.flag_url" class="mk-flag" :alt="c.name">{{ c.name }}</span>
|
|
361
|
+
<b>{{ c.percent }}%</b>
|
|
362
|
+
</div>
|
|
240
363
|
<div class="mk-track"><div class="mk-fill" :style="{ width: c.percent + '%' }" /></div>
|
|
241
364
|
</div>
|
|
242
365
|
</div>
|
|
243
|
-
</
|
|
244
|
-
|
|
245
|
-
|
|
366
|
+
</section>
|
|
367
|
+
|
|
368
|
+
<section v-if="demographics" class="kit-block" data-sec="audience">
|
|
369
|
+
<h2>{{ $t('kit.media.audience') }}</h2>
|
|
370
|
+
<div class="mk-cols2">
|
|
371
|
+
<div v-if="demographics.age_ranges?.length" class="kit-card mk-pad">
|
|
372
|
+
<h3>{{ $t('kit.media.age') }}</h3>
|
|
373
|
+
<div v-for="a in demographics.age_ranges" :key="a.label" class="mk-bar">
|
|
374
|
+
<div class="top"><span>{{ a.label }}</span><b>{{ a.percent }}%</b></div>
|
|
375
|
+
<div class="mk-track"><div class="mk-fill" :style="{ width: a.percent + '%' }" /></div>
|
|
376
|
+
</div>
|
|
377
|
+
</div>
|
|
378
|
+
<div v-if="demographics.gender" class="kit-card mk-pad">
|
|
379
|
+
<h3>{{ $t('kit.media.gender_regions') }}</h3>
|
|
380
|
+
<div class="mk-gender">
|
|
381
|
+
<div v-for="(v, k) in demographics.gender" :key="k" class="g">
|
|
382
|
+
<div class="pct">{{ v }}%</div>
|
|
383
|
+
<div class="lb">{{ k }}</div>
|
|
384
|
+
</div>
|
|
385
|
+
</div>
|
|
386
|
+
</div>
|
|
387
|
+
</div>
|
|
388
|
+
</section>
|
|
246
389
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
</section>
|
|
390
|
+
<section v-if="styles.length" class="kit-block" data-sec="styles">
|
|
391
|
+
<h2>{{ $t('kit.media.styles') }}</h2>
|
|
392
|
+
<div class="mk-tags">
|
|
393
|
+
<span v-for="(s, i) in styles" :key="i" class="mk-tag" :class="{ on: i < 4 }">{{ s }}</span>
|
|
394
|
+
</div>
|
|
395
|
+
</section>
|
|
254
396
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
397
|
+
<section v-if="selectedGames.length" class="kit-block" data-sec="selected-games">
|
|
398
|
+
<h2>{{ $t('kit.media.selected_games') }}</h2>
|
|
399
|
+
<div class="mk-tags">
|
|
400
|
+
<span v-for="(g, i) in selectedGames" :key="i" class="mk-tag">{{ g }}</span>
|
|
401
|
+
</div>
|
|
402
|
+
</section>
|
|
403
|
+
|
|
404
|
+
<section v-if="platformsPlayed.length" class="kit-block" data-sec="platforms-played">
|
|
405
|
+
<h2>{{ $t('kit.media.platforms_played') }}</h2>
|
|
406
|
+
<div class="mk-platforms-played">
|
|
407
|
+
<div v-for="p in platformsPlayed" :key="p.id" class="mk-plat-box">
|
|
408
|
+
<img v-if="p.icon_url" :src="p.icon_url" :alt="p.name">
|
|
409
|
+
<span class="lb">{{ p.name }}</span>
|
|
410
|
+
</div>
|
|
411
|
+
</div>
|
|
412
|
+
</section>
|
|
413
|
+
|
|
414
|
+
<section v-if="topGames.length" class="kit-block" data-sec="games">
|
|
415
|
+
<h2>{{ $t('kit.media.top_games') }}</h2>
|
|
416
|
+
<div class="mk-games">
|
|
417
|
+
<div v-for="g in topGames" :key="g.game" class="mk-game">
|
|
418
|
+
<span class="nm">{{ g.game }}</span>
|
|
419
|
+
<span class="st">
|
|
420
|
+
<span>{{ g.hours }}h</span>
|
|
421
|
+
<span>{{ g.avg_viewers }} {{ $t('kit.media.avg_short') }}</span>
|
|
422
|
+
</span>
|
|
423
|
+
</div>
|
|
424
|
+
</div>
|
|
425
|
+
</section>
|
|
268
426
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
<
|
|
278
|
-
|
|
427
|
+
<section v-if="brands.length" class="kit-block" data-sec="brands">
|
|
428
|
+
<h2>{{ $t('kit.media.brands') }}</h2>
|
|
429
|
+
<div class="mk-brands">
|
|
430
|
+
<div v-for="(b, i) in brands" :key="i" class="mk-brand">{{ b.name || b }}</div>
|
|
431
|
+
</div>
|
|
432
|
+
</section>
|
|
433
|
+
|
|
434
|
+
<section v-if="portfolioImages.length || brandLogos.length" class="kit-block" data-sec="portfolio">
|
|
435
|
+
<h2>{{ $t('kit.media.portfolio') }}</h2>
|
|
436
|
+
<div v-if="portfolioImages.length" class="mk-portfolio">
|
|
437
|
+
<a v-for="(image, index) in portfolioImages" :key="image" :href="image" target="_blank" rel="noopener" @click="track('click')">
|
|
438
|
+
<img :src="image" :alt="`${streamer.name} — ${index + 1}`" />
|
|
439
|
+
</a>
|
|
440
|
+
</div>
|
|
441
|
+
<div v-if="brandLogos.length" class="mk-brand-logos">
|
|
442
|
+
<img v-for="logo in brandLogos" :key="logo" :src="logo" :alt="$t('kit.media.partner_brand')" />
|
|
443
|
+
</div>
|
|
444
|
+
</section>
|
|
279
445
|
</div>
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
<div
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
446
|
+
|
|
447
|
+
<!-- ── TAB: RATE CARDS ── -->
|
|
448
|
+
<div v-if="hasRatesTab" class="mk-tabpanel" :class="{ active: activeTab === 1 }" data-print-tab="rates">
|
|
449
|
+
<div class="mk-rc-layout">
|
|
450
|
+
<div class="mk-rc-main">
|
|
451
|
+
<div v-if="bundles.length" class="mk-rc-group">
|
|
452
|
+
<h2>{{ $t('kit.media.rates_bundles') }}</h2>
|
|
453
|
+
<div v-for="(b, i) in bundles" :key="i" class="mk-rc-item">
|
|
454
|
+
<div class="mk-rc-info">
|
|
455
|
+
<span v-if="b.discount_percent" class="off">-{{ b.discount_percent }}%</span>
|
|
456
|
+
<div class="mk-rc-title">{{ b.name }}</div>
|
|
457
|
+
<p v-if="b.description" class="mk-rc-desc">{{ b.description }}</p>
|
|
458
|
+
</div>
|
|
459
|
+
<div class="mk-rc-side">
|
|
460
|
+
<div class="mk-rc-price">{{ b.currency }} {{ b.bundle_price }}</div>
|
|
461
|
+
<button class="mk-rc-add" :disabled="sendingProposal" @click="submitBundleProposal(b)">{{ $t('kit.media.rates_send_proposal') }}</button>
|
|
462
|
+
</div>
|
|
463
|
+
</div>
|
|
464
|
+
</div>
|
|
465
|
+
|
|
466
|
+
<div v-if="rateCards.length" class="mk-rc-group">
|
|
467
|
+
<h2>{{ $t('kit.media.rates_individual') }}</h2>
|
|
468
|
+
<div v-for="(r, i) in rateCards" :key="i" class="mk-rc-item">
|
|
469
|
+
<input type="checkbox" class="mk-rc-check" :checked="selectedCardIndexes.has(i)" @change="toggleCardSelection(i)">
|
|
470
|
+
<div class="mk-rc-info">
|
|
471
|
+
<div class="fmt">{{ r.content_format || r.ad_channel }}</div>
|
|
472
|
+
<div class="mk-rc-title">{{ r.label }}</div>
|
|
473
|
+
</div>
|
|
474
|
+
<div class="mk-rc-side">
|
|
475
|
+
<div class="mk-rc-price">{{ r.currency }} {{ r.price_min }}<span v-if="r.price_max">–{{ r.price_max }}</span></div>
|
|
476
|
+
</div>
|
|
477
|
+
</div>
|
|
478
|
+
</div>
|
|
479
|
+
</div>
|
|
480
|
+
|
|
481
|
+
<aside v-if="rateCards.length" class="mk-rc-summary no-print">
|
|
482
|
+
<h3>{{ $t('kit.media.rates_your_package') }}</h3>
|
|
483
|
+
<template v-if="cartItems.length">
|
|
484
|
+
<div v-for="(c, i) in cartItems" :key="i" class="mk-rc-summary-line"><span>{{ c.label }}</span><span>{{ c.currency }} {{ c.price_min }}</span></div>
|
|
485
|
+
<div class="mk-rc-summary-total"><span>{{ $t('common.total') }}</span><span>{{ cartCurrency }} {{ cartTotal }}</span></div>
|
|
486
|
+
<button class="kit-btn kit-btn-primary" style="width:100%;" :disabled="sendingProposal" @click="submitCartProposal">{{ $t('kit.media.rates_send_proposal') }}</button>
|
|
487
|
+
</template>
|
|
488
|
+
<p v-else class="mk-rc-summary-hint">{{ $t('kit.media.rates_pick_hint') }}</p>
|
|
489
|
+
<p class="mk-rc-summary-hint">{{ $t('kit.media.rates_login_hint') }}</p>
|
|
490
|
+
</aside>
|
|
289
491
|
</div>
|
|
290
492
|
</div>
|
|
291
|
-
</section>
|
|
292
493
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
494
|
+
<!-- ── TAB: PERFORMANCE ── -->
|
|
495
|
+
<div v-if="hasPerformanceTab" class="mk-tabpanel" :class="{ active: activeTab === 2 }" data-print-tab="performance">
|
|
496
|
+
<section v-if="stats" class="kit-block" data-sec="metrics">
|
|
497
|
+
<h2>{{ $t('kit.media.key_metrics') }}</h2>
|
|
498
|
+
<p v-if="period" class="mk-period">{{ $t('kit.media.last_days', { days: period.days }) }} · {{ period.start }} — {{ period.end }}</p>
|
|
499
|
+
<div class="mk-metrics">
|
|
500
|
+
<div class="mk-metric"><div class="val accent">{{ fmt(stats.total_followers) }}</div><div class="lab">{{ $t('kit.media.followers') }}</div></div>
|
|
501
|
+
<div class="mk-metric"><div class="val">{{ fmt(stats.avg_viewers) }}</div><div class="lab">{{ $t('kit.media.avg_viewers') }}</div></div>
|
|
502
|
+
<div class="mk-metric"><div class="val">{{ fmt(stats.peak_viewers) }}</div><div class="lab">{{ $t('kit.media.peak_viewers') }}</div></div>
|
|
503
|
+
<div class="mk-metric"><div class="val">{{ stats.streams_per_week }}</div><div class="lab">{{ $t('kit.media.streams_week') }}</div></div>
|
|
504
|
+
<div class="mk-metric"><div class="val">{{ fmt(stats.total_streams_90d) }}</div><div class="lab">{{ $t('kit.media.total_streams') }}</div></div>
|
|
505
|
+
<div class="mk-metric"><div class="val">{{ stats.total_hours_90d }}h</div><div class="lab">{{ $t('kit.media.hours') }}</div></div>
|
|
506
|
+
<div class="mk-metric"><div class="val accent">+{{ fmt(stats.new_followers_90d) }}</div><div class="lab">{{ $t('kit.media.new_followers') }}</div></div>
|
|
507
|
+
<div class="mk-metric"><div class="val">{{ fmt(stats.total_chat_messages) }}</div><div class="lab">{{ $t('kit.media.chat') }}</div></div>
|
|
508
|
+
</div>
|
|
509
|
+
</section>
|
|
510
|
+
|
|
511
|
+
<section v-if="communityStats" class="kit-block" data-sec="community">
|
|
512
|
+
<h2>{{ $t('kit.media.community_title') }}</h2>
|
|
513
|
+
<div class="mk-cross-card">
|
|
514
|
+
<span class="mk-cross-badge">Community</span>
|
|
515
|
+
<div class="mk-cross-row"><span>{{ $t('kit.media.community_memberships') }}</span><b>{{ communityStats.communities }}</b></div>
|
|
516
|
+
<div class="mk-cross-row"><span>{{ $t('kit.media.community_posts_30d') }}</span><b>{{ communityStats.posts_30d }}</b></div>
|
|
517
|
+
</div>
|
|
518
|
+
</section>
|
|
519
|
+
|
|
520
|
+
<section v-if="schedule.length" class="kit-block" data-sec="schedule">
|
|
521
|
+
<h2>{{ $t('kit.media.schedule') }}</h2>
|
|
522
|
+
<div class="mk-schedule">
|
|
523
|
+
<div v-for="d in scheduleByDay" :key="d.d" class="mk-day" :class="{ on: d.slot }">
|
|
524
|
+
<div class="dn">{{ $t(d.key) }}</div>
|
|
525
|
+
<div v-if="d.slot" class="hr">{{ d.slot.start_time }}</div>
|
|
526
|
+
<div v-else class="off">—</div>
|
|
527
|
+
</div>
|
|
528
|
+
</div>
|
|
529
|
+
</section>
|
|
298
530
|
</div>
|
|
299
|
-
</
|
|
531
|
+
</main>
|
|
532
|
+
</div>
|
|
300
533
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
<
|
|
305
|
-
<div v-for="d in scheduleByDay" :key="d.d" class="mk-day" :class="{ on: d.slot }">
|
|
306
|
-
<div class="dn">{{ $t(d.key) }}</div>
|
|
307
|
-
<div v-if="d.slot" class="hr">{{ d.slot.start_time }}</div>
|
|
308
|
-
<div v-else class="off">—</div>
|
|
309
|
-
</div>
|
|
310
|
-
</div>
|
|
534
|
+
<!-- ══════════════ Full-width: Store + Mural (real embedded widgets, not tabbed) ══════════════ -->
|
|
535
|
+
<div class="kit-wrap mk-below-tabs">
|
|
536
|
+
<section v-if="creatorStore" id="store" class="kit-block kit-card mk-store-block" data-sec="store">
|
|
537
|
+
<MgMediaKitStore :store="creatorStore" :contact-email="streamer.contact_email" @click="track('click')" />
|
|
311
538
|
</section>
|
|
312
539
|
|
|
313
|
-
<!-- IndieWall / mural — self-contained widget (own fetch, realtime, stepper) -->
|
|
314
540
|
<section v-if="userId" id="support" class="kit-block" data-sec="support">
|
|
315
541
|
<MediaKitWallBlock :user-id="userId" />
|
|
316
542
|
</section>
|
|
317
543
|
|
|
318
544
|
<footer class="mk-footer">
|
|
319
|
-
{{ $t('kit.
|
|
545
|
+
<p v-if="!isPremium" class="kit-footer__text">{{ $t('kit.press.made_with') }} <strong>Mundo Gamer Agency</strong></p>
|
|
546
|
+
<a v-if="!isPremium" :href="`${agencyBase}/dashboard/media-kit`" target="_blank" rel="noopener" class="kit-footer__cta">{{ $t('kit.media.create_yours') }}</a>
|
|
547
|
+
<p class="mk-footer-meta">{{ $t('kit.media.generated') }} {{ kit.generated_at?.slice(0, 10) }}</p>
|
|
320
548
|
</footer>
|
|
321
549
|
</div>
|
|
322
550
|
</template>
|
|
@@ -339,156 +567,142 @@ function onDownload() {
|
|
|
339
567
|
color: var(--kit-muted);
|
|
340
568
|
}
|
|
341
569
|
.kit-wrap {
|
|
342
|
-
max-width:
|
|
570
|
+
max-width: 1180px;
|
|
343
571
|
margin: 0 auto;
|
|
344
572
|
padding: 0 24px 60px;
|
|
345
573
|
}
|
|
346
574
|
|
|
347
575
|
/* Cover */
|
|
348
576
|
.mk-cover {
|
|
349
|
-
height:
|
|
577
|
+
height: 220px;
|
|
350
578
|
background: linear-gradient(120deg, var(--kit-accent-2, #6b15ac) 0%, #2a0e4e 50%, var(--kit-bg) 100%);
|
|
351
579
|
background-position: center;
|
|
352
580
|
background-size: cover;
|
|
353
581
|
position: relative;
|
|
354
582
|
border-bottom: 1px solid var(--kit-line);
|
|
355
583
|
|
|
356
|
-
|
|
584
|
+
&.has-image::after {
|
|
357
585
|
content: "";
|
|
358
586
|
position: absolute;
|
|
359
587
|
inset: 0;
|
|
360
|
-
background: radial-gradient(circle at 80% 20%, rgba(168, 85, 247, .35), transparent 60%);
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
&.has-image::after {
|
|
364
588
|
background: linear-gradient(180deg, rgba(5, 6, 10, .04), rgba(5, 6, 10, .52));
|
|
365
589
|
}
|
|
366
590
|
}
|
|
367
591
|
|
|
368
|
-
/*
|
|
369
|
-
.mk-
|
|
370
|
-
|
|
592
|
+
/* ── Layout: sidebar + main ── */
|
|
593
|
+
.mk-layout {
|
|
594
|
+
display: grid;
|
|
595
|
+
grid-template-columns: 320px 1fr;
|
|
596
|
+
gap: 32px;
|
|
597
|
+
margin-top: -80px;
|
|
371
598
|
position: relative;
|
|
372
599
|
z-index: 2;
|
|
600
|
+
align-items: start;
|
|
601
|
+
}
|
|
602
|
+
@media (max-width: 900px) {
|
|
603
|
+
.mk-layout { grid-template-columns: 1fr; margin-top: -60px; }
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
/* ── Sidebar ── */
|
|
607
|
+
.mk-sidebar {
|
|
608
|
+
background: var(--kit-surface);
|
|
609
|
+
border: 1px solid var(--kit-line);
|
|
610
|
+
padding: 24px;
|
|
373
611
|
display: flex;
|
|
374
612
|
flex-direction: column;
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
613
|
+
gap: 16px;
|
|
614
|
+
position: sticky;
|
|
615
|
+
top: 24px;
|
|
378
616
|
}
|
|
617
|
+
@media (max-width: 900px) { .mk-sidebar { position: static; } }
|
|
618
|
+
|
|
379
619
|
.mk-avatar {
|
|
380
|
-
width:
|
|
381
|
-
height:
|
|
620
|
+
width: 128px;
|
|
621
|
+
height: 128px;
|
|
622
|
+
border-radius: 100%;
|
|
382
623
|
border: 3px solid var(--kit-accent);
|
|
383
624
|
object-fit: cover;
|
|
384
|
-
flex-shrink: 0;
|
|
385
625
|
background: var(--kit-surface-2);
|
|
386
|
-
box-shadow: 0
|
|
387
|
-
}
|
|
388
|
-
.mk-avatar-ph {
|
|
389
|
-
background: linear-gradient(135deg, var(--kit-accent-2, #6b15ac), var(--kit-accent));
|
|
626
|
+
box-shadow: 0 12px 32px rgba(0, 0, 0, .35);
|
|
390
627
|
}
|
|
391
|
-
.mk-
|
|
392
|
-
width: 100%;
|
|
393
|
-
padding-top: 18px;
|
|
628
|
+
.mk-avatar-ph { background: linear-gradient(135deg, var(--kit-accent-2, #6b15ac), var(--kit-accent)); }
|
|
394
629
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
.mk-headline {
|
|
403
|
-
margin: 8px auto 0;
|
|
404
|
-
max-width: 620px;
|
|
405
|
-
color: var(--kit-accent);
|
|
406
|
-
font-family: 'Rajdhani', sans-serif;
|
|
407
|
-
font-size: 20px;
|
|
408
|
-
font-weight: 600;
|
|
409
|
-
}
|
|
410
|
-
.mk-badges {
|
|
411
|
-
display: flex;
|
|
412
|
-
justify-content: center;
|
|
413
|
-
gap: 8px;
|
|
414
|
-
margin: 12px 0;
|
|
415
|
-
flex-wrap: wrap;
|
|
416
|
-
}
|
|
630
|
+
.mk-name { font-family: 'Rajdhani', sans-serif; font-size: 28px; line-height: 1.1; margin: 4px 0 0; }
|
|
631
|
+
.mk-headline { color: var(--kit-accent); font-family: 'Rajdhani', sans-serif; font-size: 15px; font-weight: 600; margin: 0; }
|
|
632
|
+
.mk-handle { color: var(--kit-muted); font-size: 13px; margin: 0; }
|
|
633
|
+
|
|
634
|
+
.mk-badges { display: flex; flex-wrap: wrap; gap: 6px; }
|
|
417
635
|
.mk-badge {
|
|
418
636
|
font-family: 'Rajdhani', sans-serif;
|
|
419
637
|
font-weight: 700;
|
|
420
638
|
font-size: 11px;
|
|
421
|
-
letter-spacing:
|
|
639
|
+
letter-spacing: 1px;
|
|
422
640
|
text-transform: uppercase;
|
|
423
641
|
padding: 4px 10px;
|
|
424
642
|
|
|
425
643
|
&.plat { background: var(--kit-surface-2); border: 1px solid var(--kit-line); }
|
|
426
644
|
&.tier { background: var(--kit-accent); color: var(--kit-accent-ink); }
|
|
427
|
-
&.loc { color: var(--kit-muted); border: 1px solid var(--kit-line); }
|
|
428
|
-
}
|
|
429
|
-
.mk-bio {
|
|
430
|
-
color: #c4c4d2;
|
|
431
|
-
font-size: 15px;
|
|
432
|
-
line-height: 1.65;
|
|
433
|
-
max-width: 66ch;
|
|
434
|
-
margin: 6px auto 0;
|
|
435
645
|
}
|
|
436
|
-
|
|
646
|
+
|
|
647
|
+
.mk-internal-bar {
|
|
437
648
|
display: flex;
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
padding
|
|
649
|
+
flex-direction: column;
|
|
650
|
+
gap: 8px;
|
|
651
|
+
width: 100%;
|
|
652
|
+
padding: 12px;
|
|
653
|
+
border: 1px dashed var(--kit-accent);
|
|
654
|
+
background: rgba(253, 178, 21, .06);
|
|
442
655
|
}
|
|
656
|
+
.mk-actions { display: flex; flex-direction: column; gap: 8px; width: 100%; }
|
|
443
657
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
658
|
+
.mk-sb-stat {
|
|
659
|
+
display: flex;
|
|
660
|
+
flex-direction: column;
|
|
661
|
+
gap: 2px;
|
|
662
|
+
padding: 10px 0 10px 14px;
|
|
663
|
+
border-left: 4px solid var(--kit-accent);
|
|
664
|
+
|
|
665
|
+
.n { font-family: 'Rajdhani', sans-serif; font-weight: 700; font-size: 24px; color: var(--kit-accent); }
|
|
666
|
+
.l { font-size: 12px; color: var(--kit-muted); text-transform: uppercase; letter-spacing: .5px; }
|
|
451
667
|
}
|
|
668
|
+
|
|
669
|
+
/* Link hub in sidebar */
|
|
670
|
+
.mk-link-hub { display: flex; flex-direction: column; gap: 1px; background: var(--kit-line); border: 1px solid var(--kit-line); width: 100%; }
|
|
452
671
|
.mk-link {
|
|
453
672
|
display: flex;
|
|
454
673
|
align-items: center;
|
|
455
674
|
justify-content: space-between;
|
|
456
|
-
gap:
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
border: 1px solid var(--kit-line);
|
|
460
|
-
background: color-mix(in srgb, var(--kit-surface) 92%, transparent);
|
|
675
|
+
gap: 10px;
|
|
676
|
+
padding: 10px 12px;
|
|
677
|
+
background: var(--kit-surface-2);
|
|
461
678
|
color: var(--kit-text);
|
|
462
|
-
font-size:
|
|
463
|
-
font-weight:
|
|
679
|
+
font-size: 13px;
|
|
680
|
+
font-weight: 600;
|
|
464
681
|
text-decoration: none;
|
|
465
|
-
transition:
|
|
466
|
-
|
|
467
|
-
&:hover {
|
|
468
|
-
transform: translateY(-2px);
|
|
469
|
-
border-color: var(--kit-accent);
|
|
470
|
-
background: var(--kit-surface-2);
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
b { color: var(--kit-accent); font-size: 16px; }
|
|
682
|
+
transition: background .15s;
|
|
474
683
|
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
color: var(--kit-accent-ink);
|
|
684
|
+
&:hover { background: color-mix(in srgb, var(--kit-accent) 8%, var(--kit-surface-2)); }
|
|
685
|
+
b { color: var(--kit-accent); }
|
|
686
|
+
&--tv { background: color-mix(in srgb, var(--kit-accent) 10%, var(--kit-surface-2)); }
|
|
687
|
+
}
|
|
480
688
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
689
|
+
.mk-socials { display: flex; flex-wrap: wrap; gap: 8px; }
|
|
690
|
+
.mk-soc {
|
|
691
|
+
width: 34px; height: 34px;
|
|
692
|
+
display: flex; align-items: center; justify-content: center;
|
|
693
|
+
border: 1px solid var(--kit-line);
|
|
694
|
+
color: var(--kit-muted);
|
|
695
|
+
font-size: 11px; font-weight: 700;
|
|
696
|
+
text-decoration: none;
|
|
484
697
|
|
|
485
|
-
|
|
698
|
+
&:hover { border-color: var(--kit-accent); color: var(--kit-accent); }
|
|
486
699
|
}
|
|
487
700
|
|
|
488
|
-
/* Buttons */
|
|
701
|
+
/* Buttons (shared) */
|
|
489
702
|
.kit-btn {
|
|
490
703
|
display: inline-flex;
|
|
491
704
|
align-items: center;
|
|
705
|
+
justify-content: center;
|
|
492
706
|
gap: 8px;
|
|
493
707
|
font-family: 'Rajdhani', sans-serif;
|
|
494
708
|
font-weight: 700;
|
|
@@ -504,6 +718,7 @@ function onDownload() {
|
|
|
504
718
|
background: var(--kit-accent);
|
|
505
719
|
color: var(--kit-accent-ink);
|
|
506
720
|
&:hover { filter: brightness(1.1); }
|
|
721
|
+
&:disabled { opacity: .5; cursor: not-allowed; }
|
|
507
722
|
}
|
|
508
723
|
&.kit-btn-ghost {
|
|
509
724
|
background: rgba(255, 255, 255, .04);
|
|
@@ -513,442 +728,260 @@ function onDownload() {
|
|
|
513
728
|
}
|
|
514
729
|
}
|
|
515
730
|
|
|
516
|
-
/*
|
|
517
|
-
.
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
height: 1px;
|
|
535
|
-
background: var(--kit-line);
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
|
-
.mk-store-block { padding: 24px; scroll-margin-top: 24px; }
|
|
540
|
-
.mk-portfolio {
|
|
541
|
-
display: grid;
|
|
542
|
-
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
543
|
-
gap: 10px;
|
|
731
|
+
/* ── Main / tabs ── */
|
|
732
|
+
.mk-main { min-width: 0; }
|
|
733
|
+
.mk-tabs { display: flex; border-bottom: 1px solid var(--kit-line); margin-bottom: 24px; }
|
|
734
|
+
.mk-tab {
|
|
735
|
+
font: inherit;
|
|
736
|
+
font-family: 'Rajdhani', sans-serif;
|
|
737
|
+
font-weight: 700;
|
|
738
|
+
font-size: 14px;
|
|
739
|
+
letter-spacing: .5px;
|
|
740
|
+
text-transform: uppercase;
|
|
741
|
+
padding: 12px 4px;
|
|
742
|
+
margin-right: 28px;
|
|
743
|
+
color: var(--kit-muted);
|
|
744
|
+
background: none;
|
|
745
|
+
border: none;
|
|
746
|
+
border-bottom: 2px solid transparent;
|
|
747
|
+
cursor: pointer;
|
|
748
|
+
appearance: none;
|
|
544
749
|
|
|
545
|
-
|
|
546
|
-
img { width: 100%; height: 100%; object-fit: cover; transition: transform .2s ease; }
|
|
547
|
-
a:hover img { transform: scale(1.03); }
|
|
750
|
+
&.active, &:hover { color: var(--kit-text); border-bottom-color: var(--kit-accent); }
|
|
548
751
|
}
|
|
549
|
-
|
|
752
|
+
|
|
753
|
+
.mk-tabpanel { display: none; flex-direction: column; gap: 40px; }
|
|
754
|
+
.mk-tabpanel.active { display: flex; }
|
|
755
|
+
|
|
756
|
+
.mk-bio { font-size: 15px; line-height: 1.65; color: #c4c4d2; max-width: 64ch; margin: 0; }
|
|
757
|
+
|
|
758
|
+
/* Sections */
|
|
759
|
+
.kit-block > h2 {
|
|
760
|
+
font-size: 12px;
|
|
761
|
+
letter-spacing: 2px;
|
|
762
|
+
text-transform: uppercase;
|
|
763
|
+
color: var(--kit-muted);
|
|
764
|
+
font-weight: 700;
|
|
765
|
+
margin-bottom: 16px;
|
|
550
766
|
display: flex;
|
|
551
767
|
align-items: center;
|
|
552
|
-
|
|
553
|
-
flex-wrap: wrap;
|
|
554
|
-
gap: 16px;
|
|
555
|
-
margin-top: 16px;
|
|
556
|
-
padding: 18px;
|
|
557
|
-
border: 1px solid var(--kit-line);
|
|
558
|
-
background: var(--kit-surface);
|
|
768
|
+
gap: 12px;
|
|
559
769
|
|
|
560
|
-
|
|
561
|
-
}
|
|
562
|
-
.mk-period {
|
|
563
|
-
color: var(--kit-muted);
|
|
564
|
-
font-size: 13px;
|
|
565
|
-
margin: -8px 0 16px;
|
|
770
|
+
&::after { content: ""; flex: 1; height: 1px; background: var(--kit-line); }
|
|
566
771
|
}
|
|
772
|
+
.mk-store-block { padding: 24px; scroll-margin-top: 24px; }
|
|
567
773
|
|
|
568
|
-
/*
|
|
569
|
-
.mk-
|
|
570
|
-
display:
|
|
571
|
-
|
|
572
|
-
gap:
|
|
774
|
+
/* Academy mentor badge */
|
|
775
|
+
.mk-mentor-badge {
|
|
776
|
+
display: flex;
|
|
777
|
+
flex-direction: column;
|
|
778
|
+
gap: 4px;
|
|
779
|
+
padding: 12px 14px;
|
|
780
|
+
background: color-mix(in srgb, var(--kit-accent) 10%, transparent);
|
|
781
|
+
border: 1px solid color-mix(in srgb, var(--kit-accent) 35%, transparent);
|
|
782
|
+
font-size: 14px;
|
|
783
|
+
|
|
784
|
+
b { color: var(--kit-accent); }
|
|
785
|
+
.mk-mentor-stats { font-size: 12px; color: var(--kit-muted); }
|
|
573
786
|
}
|
|
574
|
-
|
|
787
|
+
|
|
788
|
+
/* Reach / platforms */
|
|
789
|
+
.mk-platforms { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; }
|
|
790
|
+
.mk-platform {
|
|
575
791
|
background: var(--kit-surface);
|
|
576
792
|
border: 1px solid var(--kit-line);
|
|
577
|
-
padding:
|
|
578
|
-
text-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
position: absolute;
|
|
585
|
-
top: 0; left: 0;
|
|
586
|
-
width: 100%;
|
|
587
|
-
height: 2px;
|
|
588
|
-
background: var(--kit-accent);
|
|
589
|
-
}
|
|
793
|
+
padding: 16px;
|
|
794
|
+
text-decoration: none;
|
|
795
|
+
color: inherit;
|
|
796
|
+
display: flex;
|
|
797
|
+
flex-direction: column;
|
|
798
|
+
gap: 6px;
|
|
799
|
+
transition: border-color .15s;
|
|
590
800
|
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
}
|
|
598
|
-
.lab {
|
|
599
|
-
font-size: 11px;
|
|
600
|
-
text-transform: uppercase;
|
|
601
|
-
letter-spacing: 1px;
|
|
602
|
-
color: var(--kit-muted);
|
|
603
|
-
margin-top: 8px;
|
|
604
|
-
}
|
|
801
|
+
&:hover { border-color: var(--kit-accent); }
|
|
802
|
+
.pl-head { display: flex; align-items: center; justify-content: space-between; }
|
|
803
|
+
.pl-name { font-size: 12px; text-transform: uppercase; letter-spacing: 1px; color: var(--kit-muted); }
|
|
804
|
+
.pl-verified { color: #27ae60; font-weight: 700; }
|
|
805
|
+
.pl-followers { font-family: 'Rajdhani', sans-serif; font-weight: 700; font-size: 24px; }
|
|
806
|
+
.pl-meta { display: flex; gap: 12px; font-size: 12px; color: var(--kit-muted); flex-wrap: wrap; }
|
|
605
807
|
}
|
|
606
808
|
|
|
809
|
+
/* Geo */
|
|
810
|
+
.mk-geo { display: flex; flex-direction: column; gap: 10px; }
|
|
811
|
+
.mk-flag { width: 18px; height: 13px; object-fit: cover; margin-right: 8px; vertical-align: middle; }
|
|
812
|
+
|
|
607
813
|
/* Demographics */
|
|
608
|
-
.mk-cols2 {
|
|
609
|
-
|
|
610
|
-
grid-template-columns: 1fr 1fr;
|
|
611
|
-
gap: 24px;
|
|
612
|
-
}
|
|
613
|
-
.kit-card {
|
|
614
|
-
background: var(--kit-surface);
|
|
615
|
-
border: 1px solid var(--kit-line);
|
|
616
|
-
}
|
|
814
|
+
.mk-cols2 { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
|
|
815
|
+
.kit-card { background: var(--kit-surface); border: 1px solid var(--kit-line); }
|
|
617
816
|
.mk-pad {
|
|
618
817
|
padding: 20px;
|
|
619
|
-
|
|
620
|
-
h3 {
|
|
621
|
-
font-size: 14px;
|
|
622
|
-
font-weight: 700;
|
|
623
|
-
margin-bottom: 14px;
|
|
624
|
-
letter-spacing: .5px;
|
|
625
|
-
}
|
|
818
|
+
h3 { font-size: 14px; font-weight: 700; margin-bottom: 14px; letter-spacing: .5px; }
|
|
626
819
|
}
|
|
627
820
|
.mk-bar {
|
|
628
821
|
margin-bottom: 12px;
|
|
629
|
-
|
|
630
|
-
.top {
|
|
631
|
-
display: flex;
|
|
632
|
-
justify-content: space-between;
|
|
633
|
-
font-size: 13px;
|
|
634
|
-
margin-bottom: 5px;
|
|
635
|
-
|
|
636
|
-
b { color: var(--kit-accent); font-weight: 600; }
|
|
637
|
-
}
|
|
638
|
-
}
|
|
639
|
-
.mk-track {
|
|
640
|
-
height: 8px;
|
|
641
|
-
background: var(--kit-surface-2);
|
|
642
|
-
}
|
|
643
|
-
.mk-fill {
|
|
644
|
-
height: 100%;
|
|
645
|
-
background: linear-gradient(90deg, var(--kit-accent-2, #6b15ac), var(--kit-accent));
|
|
822
|
+
.top { display: flex; justify-content: space-between; align-items: center; font-size: 13px; margin-bottom: 5px; b { color: var(--kit-accent); font-weight: 600; } }
|
|
646
823
|
}
|
|
824
|
+
.mk-track { height: 8px; background: var(--kit-surface-2); }
|
|
825
|
+
.mk-fill { height: 100%; background: linear-gradient(90deg, var(--kit-accent-2, #6b15ac), var(--kit-accent)); }
|
|
647
826
|
.mk-gender {
|
|
648
|
-
display: flex;
|
|
649
|
-
gap: 16px;
|
|
650
|
-
margin-top: 4px;
|
|
651
|
-
|
|
827
|
+
display: flex; gap: 16px; margin-top: 4px;
|
|
652
828
|
.g {
|
|
653
|
-
flex: 1;
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
border: 1px solid var(--kit-line);
|
|
657
|
-
padding: 14px;
|
|
658
|
-
|
|
659
|
-
.pct {
|
|
660
|
-
font-family: 'Rajdhani', sans-serif;
|
|
661
|
-
font-weight: 700;
|
|
662
|
-
font-size: 26px;
|
|
663
|
-
color: var(--kit-accent);
|
|
664
|
-
}
|
|
665
|
-
.lb {
|
|
666
|
-
font-size: 12px;
|
|
667
|
-
color: var(--kit-muted);
|
|
668
|
-
text-transform: uppercase;
|
|
669
|
-
letter-spacing: 1px;
|
|
670
|
-
}
|
|
829
|
+
flex: 1; text-align: center; background: var(--kit-surface-2); border: 1px solid var(--kit-line); padding: 14px;
|
|
830
|
+
.pct { font-family: 'Rajdhani', sans-serif; font-weight: 700; font-size: 26px; color: var(--kit-accent); }
|
|
831
|
+
.lb { font-size: 12px; color: var(--kit-muted); text-transform: uppercase; letter-spacing: 1px; }
|
|
671
832
|
}
|
|
672
833
|
}
|
|
673
|
-
.mk-countries { margin-top: 14px; }
|
|
674
834
|
|
|
675
835
|
/* Tags */
|
|
676
|
-
.mk-tags {
|
|
677
|
-
display: flex;
|
|
678
|
-
flex-wrap: wrap;
|
|
679
|
-
gap: 8px;
|
|
680
|
-
}
|
|
836
|
+
.mk-tags { display: flex; flex-wrap: wrap; gap: 8px; }
|
|
681
837
|
.mk-tag {
|
|
682
838
|
background: var(--kit-surface-2);
|
|
683
839
|
border: 1px solid var(--kit-line);
|
|
684
840
|
padding: 6px 13px;
|
|
685
841
|
font-size: 13px;
|
|
686
842
|
color: #d4d4e0;
|
|
843
|
+
&.on { border-color: var(--kit-accent); color: var(--kit-accent); }
|
|
844
|
+
}
|
|
687
845
|
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
846
|
+
/* Platforms played */
|
|
847
|
+
.mk-platforms-played { display: flex; flex-wrap: wrap; gap: 1px; background: var(--kit-line); }
|
|
848
|
+
.mk-plat-box {
|
|
849
|
+
width: 96px; height: 96px;
|
|
850
|
+
background: var(--kit-surface);
|
|
851
|
+
display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px;
|
|
852
|
+
img { width: 32px; height: 32px; object-fit: contain; }
|
|
853
|
+
.lb { font-size: 10px; color: var(--kit-muted); text-align: center; }
|
|
692
854
|
}
|
|
693
855
|
|
|
694
856
|
/* Top games */
|
|
695
|
-
.mk-games {
|
|
696
|
-
display: flex;
|
|
697
|
-
flex-direction: column;
|
|
698
|
-
gap: 8px;
|
|
699
|
-
}
|
|
857
|
+
.mk-games { display: flex; flex-direction: column; gap: 8px; }
|
|
700
858
|
.mk-game {
|
|
701
|
-
display: flex;
|
|
702
|
-
|
|
703
|
-
justify-content: space-between;
|
|
704
|
-
background: var(--kit-surface);
|
|
705
|
-
border: 1px solid var(--kit-line);
|
|
706
|
-
padding: 12px 16px;
|
|
707
|
-
|
|
859
|
+
display: flex; align-items: center; justify-content: space-between;
|
|
860
|
+
background: var(--kit-surface); border: 1px solid var(--kit-line); padding: 12px 16px;
|
|
708
861
|
.nm { font-weight: 600; }
|
|
709
862
|
.st { display: flex; gap: 18px; color: var(--kit-muted); font-size: 13px; }
|
|
710
863
|
}
|
|
711
864
|
|
|
712
|
-
/* Rate cards */
|
|
713
|
-
.mk-rates {
|
|
714
|
-
display: grid;
|
|
715
|
-
grid-template-columns: repeat(3, 1fr);
|
|
716
|
-
gap: 12px;
|
|
717
|
-
}
|
|
718
|
-
.mk-rate {
|
|
719
|
-
background: var(--kit-surface);
|
|
720
|
-
border: 1px solid var(--kit-line);
|
|
721
|
-
padding: 18px;
|
|
722
|
-
|
|
723
|
-
.fmt { font-size: 11px; text-transform: uppercase; letter-spacing: 1px; color: var(--kit-accent); font-weight: 700; }
|
|
724
|
-
.lb { font-family: 'Rajdhani', sans-serif; font-weight: 600; font-size: 16px; margin: 6px 0 10px; }
|
|
725
|
-
.price{ font-family: 'Rajdhani', sans-serif; font-weight: 700; font-size: 22px; }
|
|
726
|
-
.dl { font-size: 12px; color: var(--kit-muted); margin-top: 6px; }
|
|
727
|
-
}
|
|
728
|
-
|
|
729
|
-
/* Bundles */
|
|
730
|
-
.mk-bundles {
|
|
731
|
-
display: grid;
|
|
732
|
-
grid-template-columns: 1fr 1fr;
|
|
733
|
-
gap: 12px;
|
|
734
|
-
margin-top: 12px;
|
|
735
|
-
}
|
|
736
|
-
.mk-bundle {
|
|
737
|
-
background: linear-gradient(135deg, var(--kit-surface), var(--kit-surface-2));
|
|
738
|
-
border: 1px solid var(--kit-accent);
|
|
739
|
-
padding: 18px;
|
|
740
|
-
position: relative;
|
|
741
|
-
|
|
742
|
-
.off {
|
|
743
|
-
position: absolute;
|
|
744
|
-
top: 14px; right: 14px;
|
|
745
|
-
background: var(--kit-accent);
|
|
746
|
-
color: var(--kit-accent-ink);
|
|
747
|
-
font-size: 11px;
|
|
748
|
-
font-weight: 700;
|
|
749
|
-
padding: 3px 9px;
|
|
750
|
-
font-family: 'Rajdhani', sans-serif;
|
|
751
|
-
letter-spacing: 1px;
|
|
752
|
-
}
|
|
753
|
-
.bn { font-family: 'Rajdhani', sans-serif; font-weight: 700; font-size: 17px; }
|
|
754
|
-
.bd { font-size: 13px; color: var(--kit-muted); margin: 4px 0 10px; }
|
|
755
|
-
.bp {
|
|
756
|
-
font-family: 'Rajdhani', sans-serif;
|
|
757
|
-
font-weight: 700;
|
|
758
|
-
font-size: 24px;
|
|
759
|
-
color: var(--kit-accent);
|
|
760
|
-
|
|
761
|
-
s { color: var(--kit-muted); font-size: 15px; font-weight: 500; margin-left: 8px; }
|
|
762
|
-
}
|
|
763
|
-
.bundle-items {
|
|
764
|
-
list-style: none;
|
|
765
|
-
padding: 0;
|
|
766
|
-
margin: 0 0 12px;
|
|
767
|
-
display: flex;
|
|
768
|
-
flex-direction: column;
|
|
769
|
-
gap: 4px;
|
|
770
|
-
|
|
771
|
-
li { font-size: 13px; color: #c4c4d2; }
|
|
772
|
-
li b { color: var(--kit-accent); font-family: 'Rajdhani', sans-serif; }
|
|
773
|
-
}
|
|
774
|
-
}
|
|
775
|
-
|
|
776
865
|
/* Brands */
|
|
777
|
-
.mk-brands {
|
|
778
|
-
display: grid;
|
|
779
|
-
grid-template-columns: repeat(5, 1fr);
|
|
780
|
-
gap: 10px;
|
|
781
|
-
}
|
|
866
|
+
.mk-brands { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
|
|
782
867
|
.mk-brand {
|
|
783
868
|
aspect-ratio: 5 / 2;
|
|
784
869
|
background: var(--kit-surface-2);
|
|
785
870
|
border: 1px solid var(--kit-line);
|
|
786
|
-
display: flex;
|
|
787
|
-
align-items: center;
|
|
788
|
-
justify-content: center;
|
|
871
|
+
display: flex; align-items: center; justify-content: center;
|
|
789
872
|
color: var(--kit-muted);
|
|
790
|
-
font-family: 'Rajdhani', sans-serif;
|
|
791
|
-
font-weight: 700;
|
|
792
|
-
font-size: 14px;
|
|
793
|
-
letter-spacing: 1px;
|
|
873
|
+
font-family: 'Rajdhani', sans-serif; font-weight: 700; font-size: 13px; letter-spacing: 1px;
|
|
794
874
|
}
|
|
795
875
|
|
|
796
|
-
/*
|
|
797
|
-
.mk-
|
|
798
|
-
display: grid;
|
|
799
|
-
|
|
800
|
-
|
|
876
|
+
/* Portfolio */
|
|
877
|
+
.mk-portfolio {
|
|
878
|
+
display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px;
|
|
879
|
+
a { display: block; overflow: hidden; aspect-ratio: 4 / 3; border: 1px solid var(--kit-line); background: var(--kit-surface); }
|
|
880
|
+
img { width: 100%; height: 100%; object-fit: cover; }
|
|
801
881
|
}
|
|
802
|
-
.mk-
|
|
803
|
-
|
|
804
|
-
border: 1px solid var(--kit-line);
|
|
805
|
-
|
|
806
|
-
text-align: center;
|
|
807
|
-
|
|
808
|
-
&.on { border-color: var(--kit-accent); }
|
|
809
|
-
&.on .dn { color: var(--kit-accent); }
|
|
810
|
-
|
|
811
|
-
.dn { font-size: 11px; text-transform: uppercase; letter-spacing: 1px; color: var(--kit-muted); }
|
|
812
|
-
.hr { font-family: 'Rajdhani', sans-serif; font-weight: 700; margin-top: 6px; font-size: 14px; }
|
|
813
|
-
.off { color: var(--kit-muted); opacity: .4; margin-top: 6px; }
|
|
882
|
+
.mk-brand-logos {
|
|
883
|
+
display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 16px;
|
|
884
|
+
margin-top: 16px; padding: 18px; border: 1px solid var(--kit-line); background: var(--kit-surface);
|
|
885
|
+
img { width: 112px; height: 54px; object-fit: contain; filter: grayscale(1); opacity: .8; }
|
|
814
886
|
}
|
|
815
887
|
|
|
816
|
-
/*
|
|
817
|
-
.mk-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
888
|
+
/* Rate cards / builder */
|
|
889
|
+
.mk-rc-layout { display: grid; grid-template-columns: 1fr 260px; gap: 20px; align-items: start; }
|
|
890
|
+
@media (max-width: 760px) { .mk-rc-layout { grid-template-columns: 1fr; } }
|
|
891
|
+
.mk-rc-group { display: flex; flex-direction: column; gap: 1px; background: var(--kit-line); margin-bottom: 24px; }
|
|
892
|
+
.mk-rc-group > h2 {
|
|
893
|
+
background: var(--kit-bg);
|
|
894
|
+
font-size: 12px; letter-spacing: 2px; text-transform: uppercase; color: var(--kit-muted); font-weight: 700;
|
|
895
|
+
padding: 4px 0 12px;
|
|
896
|
+
}
|
|
897
|
+
.mk-rc-item {
|
|
898
|
+
display: flex; align-items: center; gap: 14px;
|
|
899
|
+
background: var(--kit-surface); padding: 14px 16px;
|
|
900
|
+
border-left: 4px solid var(--kit-muted);
|
|
901
|
+
}
|
|
902
|
+
.mk-rc-check { flex: none; width: 18px; height: 18px; accent-color: var(--kit-accent); }
|
|
903
|
+
.mk-rc-info {
|
|
904
|
+
flex: 1; min-width: 0;
|
|
905
|
+
.fmt { font-size: 11px; text-transform: uppercase; letter-spacing: 1px; color: var(--kit-accent); font-weight: 700; }
|
|
906
|
+
}
|
|
907
|
+
.mk-rc-title { font-weight: 600; font-size: 15px; margin-top: 2px; }
|
|
908
|
+
.mk-rc-desc { font-size: 12.5px; color: var(--kit-muted); margin: 4px 0 0; }
|
|
909
|
+
.mk-rc-side { flex: none; text-align: right; display: flex; flex-direction: column; align-items: flex-end; gap: 8px; }
|
|
910
|
+
.mk-rc-price { font-family: 'Rajdhani', sans-serif; font-weight: 700; font-size: 16px; }
|
|
911
|
+
.mk-rc-add {
|
|
912
|
+
font: inherit; font-size: 11px; font-weight: 700; color: var(--kit-accent);
|
|
913
|
+
border: 1px solid var(--kit-accent); background: none; padding: 5px 10px; cursor: pointer;
|
|
914
|
+
&:hover { background: var(--kit-accent); color: var(--kit-accent-ink); }
|
|
915
|
+
&:disabled { opacity: .5; cursor: not-allowed; }
|
|
916
|
+
}
|
|
917
|
+
.off { background: var(--kit-accent); color: var(--kit-accent-ink); font-size: 10px; font-weight: 800; padding: 2px 6px; display: inline-block; margin-bottom: 6px; }
|
|
918
|
+
|
|
919
|
+
.mk-rc-summary { background: var(--kit-surface); border: 1px solid var(--kit-line); padding: 16px; position: sticky; top: 16px; }
|
|
920
|
+
.mk-rc-summary-line { display: flex; justify-content: space-between; font-size: 13px; color: #c4c4d2; padding: 6px 0; border-bottom: 1px solid var(--kit-line); }
|
|
921
|
+
.mk-rc-summary-total { display: flex; justify-content: space-between; font-weight: 700; font-size: 15px; padding: 10px 0; }
|
|
922
|
+
.mk-rc-summary-hint { font-size: 11.5px; color: var(--kit-muted); margin: 10px 0 0; line-height: 1.5; }
|
|
923
|
+
|
|
924
|
+
/* Performance tab */
|
|
925
|
+
.mk-metrics { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
|
|
926
|
+
.mk-metric {
|
|
927
|
+
background: var(--kit-surface); border: 1px solid var(--kit-line); padding: 20px 16px; text-align: center; position: relative; overflow: hidden;
|
|
928
|
+
&::before { content: ""; position: absolute; top: 0; left: 0; width: 100%; height: 2px; background: var(--kit-accent); }
|
|
929
|
+
.val { font-family: 'Rajdhani', sans-serif; font-weight: 700; font-size: 30px; line-height: 1; &.accent { color: var(--kit-accent); } }
|
|
930
|
+
.lab { font-size: 11px; text-transform: uppercase; letter-spacing: 1px; color: var(--kit-muted); margin-top: 8px; }
|
|
821
931
|
}
|
|
822
|
-
.mk-
|
|
823
|
-
display: flex;
|
|
824
|
-
align-items: center;
|
|
825
|
-
gap: 8px;
|
|
826
|
-
background: var(--kit-surface);
|
|
827
|
-
border: 1px solid var(--kit-line);
|
|
828
|
-
padding: 9px 16px;
|
|
829
|
-
font-size: 14px;
|
|
830
|
-
text-transform: capitalize;
|
|
831
|
-
color: #d4d4e0;
|
|
832
|
-
text-decoration: none;
|
|
833
|
-
transition: border-color .15s, color .15s;
|
|
932
|
+
.mk-period { color: var(--kit-muted); font-size: 13px; margin: -8px 0 16px; }
|
|
834
933
|
|
|
835
|
-
|
|
836
|
-
}
|
|
934
|
+
.mk-cross-card { background: var(--kit-surface); border: 1px solid var(--kit-line); padding: 18px; max-width: 340px; }
|
|
935
|
+
.mk-cross-badge { font-size: 10px; font-weight: 700; letter-spacing: 1px; text-transform: uppercase; padding: 3px 8px; background: var(--kit-surface-2); border: 1px solid var(--kit-line); color: var(--kit-muted); display: inline-block; margin-bottom: 12px; }
|
|
936
|
+
.mk-cross-row { display: flex; justify-content: space-between; padding: 6px 0; border-bottom: 1px solid var(--kit-line); font-size: 13px; &:last-child { border-bottom: none; } b { color: var(--kit-accent); } }
|
|
837
937
|
|
|
838
|
-
|
|
839
|
-
.mk-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
font-size:
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
span {
|
|
847
|
-
font-family: 'Inter', sans-serif;
|
|
848
|
-
font-size: 13px;
|
|
849
|
-
color: var(--kit-muted);
|
|
850
|
-
font-weight: 500;
|
|
851
|
-
text-transform: uppercase;
|
|
852
|
-
letter-spacing: 1px;
|
|
853
|
-
}
|
|
854
|
-
}
|
|
855
|
-
.mk-platforms {
|
|
856
|
-
display: grid;
|
|
857
|
-
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
|
|
858
|
-
gap: 12px;
|
|
938
|
+
.mk-schedule { display: grid; grid-template-columns: repeat(7, 1fr); gap: 8px; }
|
|
939
|
+
.mk-day {
|
|
940
|
+
background: var(--kit-surface); border: 1px solid var(--kit-line); padding: 12px 8px; text-align: center;
|
|
941
|
+
&.on { border-color: var(--kit-accent); .dn { color: var(--kit-accent); } }
|
|
942
|
+
.dn { font-size: 11px; text-transform: uppercase; letter-spacing: 1px; color: var(--kit-muted); }
|
|
943
|
+
.hr { font-family: 'Rajdhani', sans-serif; font-weight: 700; margin-top: 6px; font-size: 14px; }
|
|
944
|
+
.off { color: var(--kit-muted); opacity: .4; margin-top: 6px; }
|
|
859
945
|
}
|
|
860
|
-
.mk-platform {
|
|
861
|
-
background: var(--kit-surface);
|
|
862
|
-
border: 1px solid var(--kit-line);
|
|
863
|
-
padding: 16px;
|
|
864
|
-
text-decoration: none;
|
|
865
|
-
color: inherit;
|
|
866
|
-
display: flex;
|
|
867
|
-
flex-direction: column;
|
|
868
|
-
gap: 6px;
|
|
869
|
-
transition: border-color .15s;
|
|
870
946
|
|
|
871
|
-
|
|
947
|
+
/* Below tabs: store + mural */
|
|
948
|
+
.mk-below-tabs { padding-top: 48px; display: flex; flex-direction: column; gap: 48px; }
|
|
872
949
|
|
|
873
|
-
.pl-head { display: flex; align-items: center; justify-content: space-between; }
|
|
874
|
-
.pl-name { font-size: 12px; text-transform: uppercase; letter-spacing: 1px; color: var(--kit-muted); }
|
|
875
|
-
.pl-verified { color: #27ae60; font-weight: 700; }
|
|
876
|
-
.pl-followers{ font-family: 'Rajdhani', sans-serif; font-weight: 700; font-size: 24px; }
|
|
877
|
-
.pl-meta { display: flex; gap: 12px; font-size: 12px; color: var(--kit-muted); flex-wrap: wrap; }
|
|
878
|
-
}
|
|
879
|
-
|
|
880
|
-
/* Footer */
|
|
881
950
|
.mk-footer {
|
|
951
|
+
display: flex;
|
|
952
|
+
flex-direction: column;
|
|
953
|
+
align-items: center;
|
|
954
|
+
gap: 8px;
|
|
882
955
|
border-top: 1px solid var(--kit-line);
|
|
883
|
-
margin-top:
|
|
956
|
+
margin-top: 24px;
|
|
884
957
|
padding: 24px 0;
|
|
885
958
|
text-align: center;
|
|
886
|
-
color: var(--kit-muted);
|
|
887
|
-
font-size: 13px;
|
|
888
|
-
|
|
889
959
|
strong { color: var(--kit-accent); font-weight: 700; }
|
|
890
960
|
}
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
.mk-sections > .mk-footer { order: 100; }
|
|
896
|
-
.mk-sections > [data-sec="links"] { order: 1; }
|
|
897
|
-
.mk-sections > [data-sec="reach"] { order: 2; }
|
|
898
|
-
.mk-sections > [data-sec="store"] { order: 3; }
|
|
899
|
-
.mk-sections > [data-sec="portfolio"] { order: 4; }
|
|
900
|
-
.mk-sections > [data-sec="metrics"] { order: 5; }
|
|
901
|
-
.mk-sections > [data-sec="audience"] { order: 6; }
|
|
902
|
-
.mk-sections > [data-sec="styles"] { order: 7; }
|
|
903
|
-
.mk-sections > [data-sec="games"] { order: 8; }
|
|
904
|
-
.mk-sections > [data-sec="rates"] { order: 9; }
|
|
905
|
-
.mk-sections > [data-sec="brands"] { order: 10; }
|
|
906
|
-
.mk-sections > [data-sec="schedule"] { order: 11; }
|
|
907
|
-
.mk-sections > [data-sec="connect"] { order: 12; }
|
|
908
|
-
.mk-sections > [data-sec="support"] { order: 13; scroll-margin-top: 24px; }
|
|
909
|
-
|
|
910
|
-
[data-template="performance"] {
|
|
911
|
-
.mk-sections > [data-sec="metrics"] { order: 1; }
|
|
912
|
-
.mk-sections > [data-sec="reach"] { order: 2; }
|
|
913
|
-
.mk-sections > [data-sec="games"] { order: 3; }
|
|
914
|
-
}
|
|
915
|
-
[data-template="commercial"] {
|
|
916
|
-
.mk-sections > [data-sec="reach"] { order: 1; }
|
|
917
|
-
.mk-sections > [data-sec="rates"] { order: 2; }
|
|
918
|
-
.mk-sections > [data-sec="brands"] { order: 3; }
|
|
919
|
-
.mk-sections > [data-sec="metrics"] { order: 4; }
|
|
920
|
-
}
|
|
921
|
-
[data-template="audience"] {
|
|
922
|
-
.mk-sections > [data-sec="reach"] { order: 1; }
|
|
923
|
-
.mk-sections > [data-sec="audience"] { order: 2; }
|
|
924
|
-
.mk-sections > [data-sec="styles"] { order: 3; }
|
|
925
|
-
.mk-sections > [data-sec="metrics"] { order: 4; }
|
|
961
|
+
.mk-footer-meta {
|
|
962
|
+
color: var(--kit-muted);
|
|
963
|
+
font-size: 13px;
|
|
964
|
+
margin: 0;
|
|
926
965
|
}
|
|
927
966
|
|
|
928
967
|
/* Responsive */
|
|
929
968
|
@media (max-width: 840px) {
|
|
930
969
|
.mk-metrics { grid-template-columns: repeat(2, 1fr); }
|
|
931
|
-
.mk-cols2
|
|
970
|
+
.mk-cols2 { grid-template-columns: 1fr; }
|
|
932
971
|
.mk-brands { grid-template-columns: repeat(3, 1fr); }
|
|
933
972
|
.mk-schedule { grid-template-columns: repeat(4, 1fr); }
|
|
934
973
|
.mk-portfolio { grid-template-columns: 1fr 1fr; }
|
|
935
974
|
}
|
|
936
|
-
|
|
937
975
|
@media (max-width: 560px) {
|
|
938
976
|
.kit-wrap { padding-inline: 14px; }
|
|
939
|
-
.mk-cover { height:
|
|
940
|
-
.mk-avatar { width: 132px; height: 132px; }
|
|
941
|
-
.mk-header { margin-top: -68px; }
|
|
942
|
-
.mk-link-hub { grid-template-columns: 1fr; }
|
|
943
|
-
.mk-link--primary { grid-column: auto; }
|
|
944
|
-
.mk-actions { width: 100%; }
|
|
945
|
-
.kit-btn { flex: 1; justify-content: center; }
|
|
946
|
-
.mk-portfolio { grid-template-columns: 1fr; }
|
|
947
|
-
.mk-store-block { padding: 16px; }
|
|
977
|
+
.mk-cover { height: 180px; }
|
|
948
978
|
}
|
|
949
979
|
|
|
950
980
|
@media print {
|
|
951
981
|
.no-print { display: none !important; }
|
|
982
|
+
/* Tabs don't apply to print/PDF export — every panel renders so nothing
|
|
983
|
+
the creator built gets silently dropped from the exported PDF. */
|
|
984
|
+
.mk-tabpanel { display: flex !important; }
|
|
952
985
|
}
|
|
953
986
|
|
|
954
987
|
// ── Scroll unlock (body has overflow-y: hidden globally in some frontends) ───
|