@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.
@@ -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(5,6,10,.14), rgba(5,6,10,.92)), url("${String(coverUrl.value).replace(/"/g, '\\"')}")` }
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) kit.value = ssrKitData.value;
64
- else error.value = true;
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-sections">
125
- <header class="mk-header">
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
- <div class="mk-hid">
130
- <h1>{{ streamer.name }}</h1>
131
- <p v-if="streamer.custom_headline" class="mk-headline">{{ streamer.custom_headline }}</p>
132
- <div class="mk-badges">
133
- <span v-if="streamer.platform" class="mk-badge plat">{{ streamer.platform }}</span>
134
- <span v-if="streamer.tier && streamer.tier !== 'free'" class="mk-badge tier">{{ String(streamer.tier).toUpperCase() }}</span>
135
- <span v-if="streamer.slug" class="mk-badge loc">@{{ streamer.slug }}</span>
136
- </div>
137
- <p v-if="streamer.bio" class="mk-bio">{{ streamer.bio }}</p>
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
- </header>
145
-
146
- <!-- Personal link hub: replaces a separate link-in-bio service. -->
147
- <nav class="mk-link-hub no-print" data-sec="links" :aria-label="$t('kit.media.quick_links')">
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
- <!-- Mundo Gamer creator store -->
185
- <section v-if="creatorStore" id="store" class="kit-block kit-card mk-store-block" data-sec="store">
186
- <MgMediaKitStore :store="creatorStore" :contact-email="streamer.contact_email" @click="track('click')" />
187
- </section>
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
- <!-- Creator-selected portfolio and brand imagery -->
190
- <section v-if="portfolioImages.length || brandLogos.length" class="kit-block" data-sec="portfolio">
191
- <h2>{{ $t('kit.media.portfolio') }}</h2>
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
- <div v-if="brandLogos.length" class="mk-brand-logos">
198
- <img v-for="logo in brandLogos" :key="logo" :src="logo" :alt="$t('kit.media.partner_brand')" />
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
- <!-- TV streaming metrics -->
203
- <section v-if="stats" class="kit-block" data-sec="metrics">
204
- <h2>{{ $t('kit.media.key_metrics') }}</h2>
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
- <!-- Audience demographics -->
219
- <section v-if="demographics" class="kit-block" data-sec="audience">
220
- <h2>{{ $t('kit.media.audience') }}</h2>
221
- <div class="mk-cols2">
222
- <div v-if="demographics.age_ranges?.length" class="kit-card mk-pad">
223
- <h3>{{ $t('kit.media.age') }}</h3>
224
- <div v-for="a in demographics.age_ranges" :key="a.label" class="mk-bar">
225
- <div class="top"><span>{{ a.label }}</span><b>{{ a.percent }}%</b></div>
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
- </div>
229
- <div v-if="demographics.gender" class="kit-card mk-pad">
230
- <h3>{{ $t('kit.media.gender_regions') }}</h3>
231
- <div class="mk-gender">
232
- <div v-for="(v, k) in demographics.gender" :key="k" class="g">
233
- <div class="pct">{{ v }}%</div>
234
- <div class="lb">{{ k }}</div>
235
- </div>
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
- <div v-if="demographics.top_countries?.length" class="mk-countries">
238
- <div v-for="c in demographics.top_countries" :key="c.code" class="mk-bar">
239
- <div class="top"><span>{{ c.label }}</span><b>{{ c.percent }}%</b></div>
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
- </div>
244
- </div>
245
- </section>
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
- <!-- Content styles / niches -->
248
- <section v-if="styles.length" class="kit-block" data-sec="styles">
249
- <h2>{{ $t('kit.media.styles') }}</h2>
250
- <div class="mk-tags">
251
- <span v-for="(s, i) in styles" :key="i" class="mk-tag" :class="{ on: i < 4 }">{{ s }}</span>
252
- </div>
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
- <!-- Top games (TV streamers) -->
256
- <section v-if="topGames.length" class="kit-block" data-sec="games">
257
- <h2>{{ $t('kit.media.top_games') }}</h2>
258
- <div class="mk-games">
259
- <div v-for="g in topGames" :key="g.game" class="mk-game">
260
- <span class="nm">{{ g.game }}</span>
261
- <span class="st">
262
- <span>{{ g.hours }}h</span>
263
- <span>{{ g.avg_viewers }} {{ $t('kit.media.avg_short') }}</span>
264
- </span>
265
- </div>
266
- </div>
267
- </section>
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
- <!-- Rate cards & bundles (premium) -->
270
- <section v-if="rateCards.length || bundles.length" class="kit-block" data-sec="rates">
271
- <h2>{{ $t('kit.media.rates') }}</h2>
272
- <div v-if="rateCards.length" class="mk-rates">
273
- <div v-for="(r, i) in rateCards" :key="i" class="mk-rate">
274
- <div class="fmt">{{ r.content_format || r.ad_channel }}</div>
275
- <div class="lb">{{ r.label }}</div>
276
- <div class="price">{{ r.currency }} {{ r.price_min }}<span v-if="r.price_max">–{{ r.price_max }}</span></div>
277
- <div v-if="r.delivery_time_days" class="dl">{{ $t('kit.media.delivery', { d: r.delivery_time_days }) }}</div>
278
- </div>
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
- <div v-if="bundles.length" class="mk-bundles">
281
- <div v-for="(b, i) in bundles" :key="i" class="mk-bundle">
282
- <span v-if="b.discount_percent" class="off">-{{ b.discount_percent }}%</span>
283
- <div class="bn">{{ b.name }}</div>
284
- <div v-if="b.description" class="bd">{{ b.description }}</div>
285
- <ul v-if="b.rate_cards?.length" class="bundle-items">
286
- <li v-for="(it, j) in b.rate_cards" :key="j"><b>{{ it.quantity || 1 }}×</b> {{ it.label }}</li>
287
- </ul>
288
- <div class="bp">{{ b.currency }} {{ b.bundle_price }} <s v-if="b.original_price">{{ b.original_price }}</s></div>
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
- <!-- Partner brands -->
294
- <section v-if="brands.length" class="kit-block" data-sec="brands">
295
- <h2>{{ $t('kit.media.brands') }}</h2>
296
- <div class="mk-brands">
297
- <div v-for="(b, i) in brands" :key="i" class="mk-brand">{{ b.name || b }}</div>
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
- </section>
531
+ </main>
532
+ </div>
300
533
 
301
- <!-- Weekly schedule -->
302
- <section v-if="schedule.length" class="kit-block" data-sec="schedule">
303
- <h2>{{ $t('kit.media.schedule') }}</h2>
304
- <div class="mk-schedule">
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.media.generated') }} <strong>Mundo Gamer</strong> · {{ kit.generated_at?.slice(0, 10) }}
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: 1100px;
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: 280px;
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
- &::after {
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
- /* Header */
369
- .mk-header {
370
- margin: -82px auto 0;
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
- align-items: center;
376
- max-width: 760px;
377
- text-align: center;
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: 156px;
381
- height: 156px;
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 20px 52px rgba(0, 0, 0, .42);
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-hid {
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
- h1 {
396
- font-family: 'Rajdhani', sans-serif;
397
- font-size: clamp(36px, 7vw, 54px);
398
- line-height: 1.05;
399
- margin: 0;
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: 1.5px;
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
- .mk-actions {
646
+
647
+ .mk-internal-bar {
437
648
  display: flex;
438
- justify-content: center;
439
- flex-wrap: wrap;
440
- gap: 10px;
441
- padding-top: 18px;
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
- /* Link-in-bio hub */
445
- .mk-link-hub {
446
- display: grid;
447
- grid-template-columns: 1fr 1fr;
448
- gap: 10px;
449
- width: min(100%, 720px);
450
- margin: 30px auto 2px;
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: 16px;
457
- min-height: 54px;
458
- padding: 0 18px;
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: 14px;
463
- font-weight: 700;
679
+ font-size: 13px;
680
+ font-weight: 600;
464
681
  text-decoration: none;
465
- transition: transform .16s ease, border-color .16s ease, background .16s ease;
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
- &--primary {
476
- grid-column: 1 / -1;
477
- background: var(--kit-accent);
478
- border-color: var(--kit-accent);
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
- b { color: var(--kit-accent-ink); }
482
- &:hover { background: var(--kit-accent); filter: brightness(1.06); }
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
- &--social { min-height: 46px; color: var(--kit-muted); }
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
- /* Sections */
517
- .kit-block {
518
- margin-top: 44px;
519
-
520
- > h2 {
521
- font-size: 13px;
522
- letter-spacing: 3px;
523
- text-transform: uppercase;
524
- color: var(--kit-muted);
525
- font-weight: 700;
526
- margin-bottom: 16px;
527
- display: flex;
528
- align-items: center;
529
- gap: 12px;
530
-
531
- &::after {
532
- content: "";
533
- flex: 1;
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
- a { display: block; overflow: hidden; aspect-ratio: 4 / 3; border: 1px solid var(--kit-line); background: var(--kit-surface); }
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
- .mk-brand-logos {
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
- justify-content: center;
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
- img { width: 112px; height: 54px; object-fit: contain; filter: grayscale(1); opacity: .8; }
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
- /* Metrics grid */
569
- .mk-metrics {
570
- display: grid;
571
- grid-template-columns: repeat(4, 1fr);
572
- gap: 12px;
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
- .mk-metric {
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: 20px 16px;
578
- text-align: center;
579
- position: relative;
580
- overflow: hidden;
581
-
582
- &::before {
583
- content: "";
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
- .val {
592
- font-family: 'Rajdhani', sans-serif;
593
- font-weight: 700;
594
- font-size: 30px;
595
- line-height: 1;
596
- &.accent { color: var(--kit-accent); }
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
- display: grid;
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
- text-align: center;
655
- background: var(--kit-surface-2);
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
- &.on {
689
- border-color: var(--kit-accent);
690
- color: var(--kit-accent);
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
- align-items: center;
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
- /* Schedule */
797
- .mk-schedule {
798
- display: grid;
799
- grid-template-columns: repeat(7, 1fr);
800
- gap: 8px;
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-day {
803
- background: var(--kit-surface);
804
- border: 1px solid var(--kit-line);
805
- padding: 12px 8px;
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
- /* Socials */
817
- .mk-socials {
818
- display: flex;
819
- flex-wrap: wrap;
820
- gap: 10px;
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-soc {
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
- &:hover { border-color: var(--kit-accent); color: var(--kit-accent); }
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
- /* Reach / platform breakdown */
839
- .mk-total-reach {
840
- font-family: 'Rajdhani', sans-serif;
841
- font-weight: 700;
842
- font-size: 28px;
843
- color: var(--kit-accent);
844
- margin: -8px 0 16px;
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
- &:hover { border-color: var(--kit-accent); }
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: 48px;
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
- /* Template ordering (layout emphasis) */
893
- .mk-sections { display: flex; flex-direction: column; }
894
- .mk-sections > .mk-header { order: 0; }
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, .mk-rates, .mk-bundles { grid-template-columns: 1fr; }
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: 230px; }
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) ───