Skip to content

Commit 1a5622a

Browse files
feat: add CTAs to landing page (#678)
1 parent 409842e commit 1a5622a

File tree

4 files changed

+188
-181
lines changed

4 files changed

+188
-181
lines changed

app/components/CallToAction.vue

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<script setup lang="ts">
2+
const socialLinks = {
3+
github: 'https://repo.npmx.dev',
4+
discord: 'https://chat.npmx.dev',
5+
bluesky: 'https://social.npmx.dev',
6+
}
7+
</script>
8+
9+
<template>
10+
<div>
11+
<h2 class="text-lg text-fg-subtle uppercase tracking-wider mb-6">
12+
{{ $t('about.get_involved.title') }}
13+
</h2>
14+
15+
<div class="grid gap-4 sm:grid-cols-3">
16+
<a
17+
:href="socialLinks.github"
18+
target="_blank"
19+
rel="noopener noreferrer"
20+
class="group flex flex-col gap-3 p-4 rounded-lg bg-bg-subtle hover:bg-bg-elevated border border-border hover:border-border-hover transition-all duration-200"
21+
>
22+
<div class="flex gap-2">
23+
<span class="i-carbon:logo-github shrink-0 mt-1 w-5 h-5 text-fg" aria-hidden="true" />
24+
<span class="font-medium text-fg">
25+
{{ $t('about.get_involved.contribute.title') }}
26+
</span>
27+
</div>
28+
<p class="text-sm text-fg-muted leading-relaxed">
29+
{{ $t('about.get_involved.contribute.description') }}
30+
</p>
31+
<span
32+
class="text-sm text-fg-muted group-hover:text-fg inline-flex items-center gap-1 mt-auto"
33+
>
34+
{{ $t('about.get_involved.contribute.cta') }}
35+
<span class="i-carbon:arrow-right rtl-flip w-3 h-3" aria-hidden="true" />
36+
</span>
37+
</a>
38+
39+
<a
40+
:href="socialLinks.discord"
41+
target="_blank"
42+
rel="noopener noreferrer"
43+
class="group flex flex-col gap-3 p-4 rounded-lg bg-bg-subtle hover:bg-bg-elevated border border-border hover:border-border-hover transition-all duration-200"
44+
>
45+
<div class="flex gap-2">
46+
<span class="i-carbon:chat shrink-0 mt-1 w-5 h-5 text-fg" aria-hidden="true" />
47+
<span class="font-medium text-fg">
48+
{{ $t('about.get_involved.community.title') }}
49+
</span>
50+
</div>
51+
<p class="text-sm text-fg-muted leading-relaxed">
52+
{{ $t('about.get_involved.community.description') }}
53+
</p>
54+
<span
55+
class="text-sm text-fg-muted group-hover:text-fg inline-flex items-center gap-1 mt-auto"
56+
>
57+
{{ $t('about.get_involved.community.cta') }}
58+
<span class="i-carbon:arrow-right rtl-flip w-3 h-3" aria-hidden="true" />
59+
</span>
60+
</a>
61+
62+
<a
63+
:href="socialLinks.bluesky"
64+
target="_blank"
65+
rel="noopener noreferrer"
66+
class="group flex flex-col gap-3 p-4 rounded-lg bg-bg-subtle hover:bg-bg-elevated border border-border hover:border-border-hover transition-all duration-200"
67+
>
68+
<div class="flex gap-2">
69+
<span class="i-simple-icons:bluesky shrink-0 mt-1 w-5 h-5 text-fg" aria-hidden="true" />
70+
<span class="font-medium text-fg">
71+
{{ $t('about.get_involved.follow.title') }}
72+
</span>
73+
</div>
74+
<p class="text-sm text-fg-muted leading-relaxed">
75+
{{ $t('about.get_involved.follow.description') }}
76+
</p>
77+
<span
78+
class="text-sm text-fg-muted group-hover:text-fg inline-flex items-center gap-1 mt-auto"
79+
>
80+
{{ $t('about.get_involved.follow.cta') }}
81+
<span class="i-carbon:arrow-right rtl-flip w-3 h-3" aria-hidden="true" />
82+
</span>
83+
</a>
84+
</div>
85+
</div>
86+
</template>

app/pages/about.vue

Lines changed: 1 addition & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,6 @@ const pmLinks = {
2727
vlt: 'https://www.vlt.sh/',
2828
}
2929
30-
const socialLinks = {
31-
github: 'https://repo.npmx.dev',
32-
discord: 'https://chat.npmx.dev',
33-
bluesky: 'https://social.npmx.dev',
34-
}
35-
3630
const { data: contributors, status: contributorsStatus } = useFetch<GitHubContributor[]>(
3731
'/api/contributors',
3832
{
@@ -210,90 +204,7 @@ const { data: contributors, status: contributorsStatus } = useFetch<GitHubContri
210204
</div>
211205
</div>
212206

213-
<!-- Get Involved CTAs -->
214-
<div>
215-
<h2 class="text-lg text-fg-subtle uppercase tracking-wider mb-6">
216-
{{ $t('about.get_involved.title') }}
217-
</h2>
218-
219-
<div class="grid gap-4 sm:grid-cols-3">
220-
<!-- Contribute CTA -->
221-
<a
222-
:href="socialLinks.github"
223-
target="_blank"
224-
rel="noopener noreferrer"
225-
class="group flex flex-col gap-3 p-4 rounded-lg bg-bg-subtle hover:bg-bg-elevated border border-border hover:border-border-hover transition-all duration-200"
226-
>
227-
<div class="flex gap-2">
228-
<span
229-
class="i-carbon:logo-github shrink-0 mt-1 w-5 h-5 text-fg"
230-
aria-hidden="true"
231-
/>
232-
<span class="font-medium text-fg">{{
233-
$t('about.get_involved.contribute.title')
234-
}}</span>
235-
</div>
236-
<p class="text-sm text-fg-muted leading-relaxed">
237-
{{ $t('about.get_involved.contribute.description') }}
238-
</p>
239-
<span
240-
class="text-sm text-fg-muted group-hover:text-fg inline-flex items-center gap-1 mt-auto"
241-
>
242-
{{ $t('about.get_involved.contribute.cta') }}
243-
<span class="i-carbon:arrow-right rtl-flip w-3 h-3" aria-hidden="true" />
244-
</span>
245-
</a>
246-
247-
<!-- Community CTA -->
248-
<a
249-
:href="socialLinks.discord"
250-
target="_blank"
251-
rel="noopener noreferrer"
252-
class="group flex flex-col gap-3 p-4 rounded-lg bg-bg-subtle hover:bg-bg-elevated border border-border hover:border-border-hover transition-all duration-200"
253-
>
254-
<div class="flex gap-2">
255-
<span class="i-carbon:chat shrink-0 mt-1 w-5 h-5 text-fg" aria-hidden="true" />
256-
<span class="font-medium text-fg">{{
257-
$t('about.get_involved.community.title')
258-
}}</span>
259-
</div>
260-
<p class="text-sm text-fg-muted leading-relaxed">
261-
{{ $t('about.get_involved.community.description') }}
262-
</p>
263-
<span
264-
class="text-sm text-fg-muted group-hover:text-fg inline-flex items-center gap-1 mt-auto"
265-
>
266-
{{ $t('about.get_involved.community.cta') }}
267-
<span class="i-carbon:arrow-right rtl-flip w-3 h-3" aria-hidden="true" />
268-
</span>
269-
</a>
270-
271-
<!-- Follow CTA -->
272-
<a
273-
:href="socialLinks.bluesky"
274-
target="_blank"
275-
rel="noopener noreferrer"
276-
class="group flex flex-col gap-3 p-4 rounded-lg bg-bg-subtle hover:bg-bg-elevated border border-border hover:border-border-hover transition-all duration-200"
277-
>
278-
<div class="flex gap-2">
279-
<span
280-
class="i-simple-icons:bluesky shrink-0 mt-1 w-5 h-5 text-fg"
281-
aria-hidden="true"
282-
/>
283-
<span class="font-medium text-fg">{{ $t('about.get_involved.follow.title') }}</span>
284-
</div>
285-
<p class="text-sm text-fg-muted leading-relaxed">
286-
{{ $t('about.get_involved.follow.description') }}
287-
</p>
288-
<span
289-
class="text-sm text-fg-muted group-hover:text-fg inline-flex items-center gap-1 mt-auto"
290-
>
291-
{{ $t('about.get_involved.follow.cta') }}
292-
<span class="i-carbon:arrow-right rtl-flip w-3 h-3" aria-hidden="true" />
293-
</span>
294-
</a>
295-
</div>
296-
</div>
207+
<CallToAction />
297208
</section>
298209

299210
<footer class="mt-16 pt-8 border-t border-border">

app/pages/index.vue

Lines changed: 92 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -34,106 +34,107 @@ defineOgImageComponent('Default', {
3434
</script>
3535

3636
<template>
37-
<main class="container min-h-screen flex flex-col">
38-
<!-- Hero section with vertical centering -->
39-
<header class="flex-1 flex flex-col items-center justify-center text-center py-20">
40-
<!-- Animated title -->
41-
<h1
42-
dir="ltr"
43-
class="flex items-center justify-center gap-2 header-logo font-mono text-5xl sm:text-7xl md:text-8xl font-medium tracking-tight mb-4 motion-safe:animate-fade-in motion-safe:animate-fill-both"
44-
>
45-
<img
46-
aria-hidden="true"
47-
:alt="$t('alt_logo')"
48-
src="/logo.svg"
49-
width="48"
50-
height="48"
51-
class="w-12 h-12 sm:w-20 sm:h-20 md:w-24 md:h-24 rounded-2xl sm:rounded-3xl"
52-
/>
53-
<span class="pb-4">npmx</span>
54-
</h1>
37+
<main>
38+
<section class="container min-h-screen flex flex-col">
39+
<header class="flex-1 flex flex-col items-center justify-center text-center py-20">
40+
<h1
41+
dir="ltr"
42+
class="flex items-center justify-center gap-2 header-logo font-mono text-5xl sm:text-7xl md:text-8xl font-medium tracking-tight mb-4 motion-safe:animate-fade-in motion-safe:animate-fill-both"
43+
>
44+
<img
45+
aria-hidden="true"
46+
:alt="$t('alt_logo')"
47+
src="/logo.svg"
48+
width="48"
49+
height="48"
50+
class="w-12 h-12 sm:w-20 sm:h-20 md:w-24 md:h-24 rounded-2xl sm:rounded-3xl"
51+
/>
52+
<span class="pb-4">npmx</span>
53+
</h1>
5554

56-
<p
57-
class="text-fg-muted text-lg sm:text-xl max-w-md mb-12 motion-safe:animate-slide-up motion-safe:animate-fill-both"
58-
style="animation-delay: 0.1s"
59-
>
60-
{{ $t('tagline') }}
61-
</p>
55+
<p
56+
class="text-fg-muted text-lg sm:text-xl max-w-md mb-12 motion-safe:animate-slide-up motion-safe:animate-fill-both"
57+
style="animation-delay: 0.1s"
58+
>
59+
{{ $t('tagline') }}
60+
</p>
6261

63-
<!-- Search form with micro-interactions -->
64-
<search
65-
class="w-full max-w-xl motion-safe:animate-slide-up motion-safe:animate-fill-both"
66-
style="animation-delay: 0.2s"
67-
>
68-
<form method="GET" action="/search" class="relative" @submit.prevent.trim="search">
69-
<label for="home-search" class="sr-only">
70-
{{ $t('search.label') }}
71-
</label>
62+
<search
63+
class="w-full max-w-xl motion-safe:animate-slide-up motion-safe:animate-fill-both"
64+
style="animation-delay: 0.2s"
65+
>
66+
<form method="GET" action="/search" class="relative" @submit.prevent.trim="search">
67+
<label for="home-search" class="sr-only">
68+
{{ $t('search.label') }}
69+
</label>
7270

73-
<!-- Search input with glow effect on focus -->
74-
<div class="relative group" :class="{ 'is-focused': isSearchFocused }">
75-
<!-- Subtle glow effect -->
76-
<div
77-
class="absolute -inset-px rounded-lg bg-gradient-to-r from-fg/0 via-fg/5 to-fg/0 opacity-0 transition-opacity duration-500 blur-sm group-[.is-focused]:opacity-100"
78-
/>
71+
<div class="relative group" :class="{ 'is-focused': isSearchFocused }">
72+
<div
73+
class="absolute -inset-px rounded-lg bg-gradient-to-r from-fg/0 via-fg/5 to-fg/0 opacity-0 transition-opacity duration-500 blur-sm group-[.is-focused]:opacity-100"
74+
/>
7975

80-
<div class="search-box relative flex items-center">
81-
<span
82-
class="absolute inset-is-4 text-fg-subtle font-mono text-sm pointer-events-none transition-colors duration-200 group-focus-within:text-accent z-1"
83-
>
84-
/
85-
</span>
76+
<div class="search-box relative flex items-center">
77+
<span
78+
class="absolute inset-is-4 text-fg-subtle font-mono text-sm pointer-events-none transition-colors duration-200 group-focus-within:text-accent z-1"
79+
>
80+
/
81+
</span>
8682

87-
<input
88-
id="home-search"
89-
ref="searchInputRef"
90-
v-model="searchQuery"
91-
type="search"
92-
name="q"
93-
autofocus
94-
:placeholder="$t('search.placeholder')"
95-
v-bind="noCorrect"
96-
class="w-full bg-bg-subtle border border-border rounded-lg ps-8 pe-24 py-4 font-mono text-base text-fg placeholder:text-fg-subtle transition-border-color duration-300 focus:border-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/50"
97-
@input="handleInput"
98-
/>
83+
<input
84+
id="home-search"
85+
ref="searchInputRef"
86+
v-model="searchQuery"
87+
type="search"
88+
name="q"
89+
autofocus
90+
:placeholder="$t('search.placeholder')"
91+
v-bind="noCorrect"
92+
class="w-full bg-bg-subtle border border-border rounded-lg ps-8 pe-24 py-4 font-mono text-base text-fg placeholder:text-fg-subtle transition-border-color duration-300 focus:border-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/50"
93+
@input="handleInput"
94+
/>
9995

100-
<button
101-
type="submit"
102-
class="absolute inset-ie-2 px-4 py-2 font-mono text-sm text-bg bg-fg rounded-md transition-[background-color,transform] duration-200 hover:bg-fg/90 active:scale-95 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fg/50"
103-
>
104-
{{ $t('search.button') }}
105-
</button>
96+
<button
97+
type="submit"
98+
class="absolute inset-ie-2 px-4 py-2 font-mono text-sm text-bg bg-fg rounded-md transition-[background-color,transform] duration-200 hover:bg-fg/90 active:scale-95 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fg/50"
99+
>
100+
{{ $t('search.button') }}
101+
</button>
102+
</div>
106103
</div>
107-
</div>
108-
</form>
109-
</search>
104+
</form>
105+
</search>
110106

111-
<!-- Build info badge -->
112-
<BuildEnvironment class="mt-4" />
113-
</header>
107+
<BuildEnvironment class="mt-4" />
108+
</header>
114109

115-
<!-- Popular packages -->
116-
<nav
117-
:aria-label="$t('nav.popular_packages')"
118-
class="pt-4 pb-36 sm:pb-40 text-center motion-safe:animate-fade-in motion-safe:animate-fill-both"
119-
style="animation-delay: 0.3s"
120-
>
121-
<ul class="flex flex-wrap items-center justify-center gap-x-6 gap-y-3 list-none m-0 p-0">
122-
<li
123-
v-for="pkg in ['nuxt', 'vue', 'react', 'svelte', 'vite', 'next', 'astro', 'typescript']"
124-
:key="pkg"
125-
>
126-
<NuxtLink
127-
:to="{ name: 'package', params: { package: [pkg] } }"
128-
class="link-subtle font-mono text-sm inline-flex items-center gap-2 group"
110+
<nav
111+
:aria-label="$t('nav.popular_packages')"
112+
class="pt-4 pb-36 sm:pb-40 text-center motion-safe:animate-fade-in motion-safe:animate-fill-both"
113+
style="animation-delay: 0.3s"
114+
>
115+
<ul class="flex flex-wrap items-center justify-center gap-x-6 gap-y-3 list-none m-0 p-0">
116+
<li
117+
v-for="pkg in ['nuxt', 'vue', 'react', 'svelte', 'vite', 'next', 'astro', 'typescript']"
118+
:key="pkg"
129119
>
130-
<span
131-
class="w-1 h-1 rounded-full bg-accent group-hover:bg-fg transition-colors duration-200"
132-
/>
133-
{{ pkg }}
134-
</NuxtLink>
135-
</li>
136-
</ul>
137-
</nav>
120+
<NuxtLink
121+
:to="{ name: 'package', params: { package: [pkg] } }"
122+
class="link-subtle font-mono text-sm inline-flex items-center gap-2 group"
123+
>
124+
<span
125+
class="w-1 h-1 rounded-full bg-accent group-hover:bg-fg transition-colors duration-200"
126+
/>
127+
{{ pkg }}
128+
</NuxtLink>
129+
</li>
130+
</ul>
131+
</nav>
132+
</section>
133+
134+
<section class="border-t border-border py-24 bg-bg-subtle/10">
135+
<div class="container max-w-3xl mx-auto">
136+
<CallToAction />
137+
</div>
138+
</section>
138139
</main>
139140
</template>

0 commit comments

Comments
 (0)