404lab 2.0.1 → 2.0.2
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/cli/core/templates.js +1 -0
- package/package.json +3 -3
- package/templates/AmongUs.tsx +213 -119
- package/templates/BlueGlitch.tsx +190 -100
- package/templates/GeeksforGeeks.tsx +125 -37
- package/templates/Google.tsx +97 -29
- package/templates/MacOs.tsx +116 -212
- package/templates/ModernPage.tsx +73 -11
- package/templates/Particles.tsx +173 -67
- package/templates/Poet.tsx +139 -54
- package/templates/RetroTv.tsx +182 -130
- package/templates/SimplePage.tsx +60 -16
- package/templates/Snow.tsx +113 -179
- package/templates/StoneAge.tsx +91 -23
- package/templates/StrangerThings.tsx +79 -193
- package/templates/Terminal404.tsx +124 -242
- package/templates/Vercel.tsx +127 -0
package/cli/core/templates.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "404lab",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "A CLI tool for generating beautiful custom 404 pages in Next.js projects",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"preferGlobal": true,
|
|
@@ -20,13 +20,13 @@
|
|
|
20
20
|
"generator",
|
|
21
21
|
"templates"
|
|
22
22
|
],
|
|
23
|
-
"author": "
|
|
23
|
+
"author": "Shreeteja Mutukundu <smutukundu2206@gmail.com>",
|
|
24
24
|
"license": "MIT",
|
|
25
25
|
"engines": {
|
|
26
26
|
"node": ">=16.0.0"
|
|
27
27
|
},
|
|
28
28
|
"repository": {
|
|
29
29
|
"type": "git",
|
|
30
|
-
"url": "https://github.com/
|
|
30
|
+
"url": "https://github.com/shreeteja172/404lab.git"
|
|
31
31
|
}
|
|
32
32
|
}
|
package/templates/AmongUs.tsx
CHANGED
|
@@ -1,152 +1,246 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { useEffect, useRef } from "react";
|
|
3
|
+
import { useEffect, useRef, useState } from "react";
|
|
4
4
|
import Image from "next/image";
|
|
5
5
|
import Link from "next/link";
|
|
6
|
+
import { motion } from "framer-motion";
|
|
7
|
+
import { cn } from "@/components/ui/cn";
|
|
6
8
|
|
|
7
|
-
const AmongUs = () => {
|
|
9
|
+
const AmongUs = ({ className }: { className?: string }) => {
|
|
8
10
|
const containerRef = useRef<HTMLDivElement | null>(null);
|
|
11
|
+
const [stars, setStars] = useState<{ id: number; x: number; y: number; size: number; speed: number; opacity: number }[]>([]);
|
|
9
12
|
|
|
10
13
|
useEffect(() => {
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
"star pointer-events-none absolute w-[2px] h-[2px] bg-white animate-starTwinkle";
|
|
22
|
-
star.style.top = `${top}px`;
|
|
23
|
-
star.style.right = `${right}px`;
|
|
24
|
-
|
|
25
|
-
container.appendChild(star);
|
|
26
|
-
|
|
27
|
-
const runStar = setInterval(() => {
|
|
28
|
-
if (right >= width) {
|
|
29
|
-
star.remove();
|
|
30
|
-
clearInterval(runStar);
|
|
31
|
-
}
|
|
32
|
-
right += 3;
|
|
33
|
-
star.style.right = `${right}px`;
|
|
34
|
-
}, 10);
|
|
35
|
-
};
|
|
14
|
+
const initialStars = Array.from({ length: 100 }).map((_, i) => ({
|
|
15
|
+
id: i,
|
|
16
|
+
x: Math.random() * 100,
|
|
17
|
+
y: Math.random() * 100,
|
|
18
|
+
size: Math.random() * 2 + 0.5,
|
|
19
|
+
speed: Math.random() * 1.5 + 0.5,
|
|
20
|
+
opacity: Math.random() * 0.7 + 0.3,
|
|
21
|
+
}));
|
|
22
|
+
setStars(initialStars);
|
|
23
|
+
}, []);
|
|
36
24
|
|
|
37
|
-
|
|
25
|
+
const typewriterVariants = {
|
|
26
|
+
hidden: { opacity: 0 },
|
|
27
|
+
visible: {
|
|
28
|
+
opacity: 1,
|
|
29
|
+
transition: {
|
|
30
|
+
staggerChildren: 0.08,
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
};
|
|
38
34
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
35
|
+
const letterVariants = {
|
|
36
|
+
hidden: { opacity: 0, y: 5 },
|
|
37
|
+
visible: { opacity: 1, y: 0 },
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const text = "There is 1 Impostor among us";
|
|
44
41
|
|
|
45
42
|
return (
|
|
46
43
|
<div
|
|
47
44
|
ref={containerRef}
|
|
48
|
-
className=
|
|
45
|
+
className={cn(
|
|
46
|
+
"relative flex h-screen w-full flex-col items-center justify-center overflow-hidden bg-[#000000] text-white",
|
|
47
|
+
className
|
|
48
|
+
)}
|
|
49
49
|
>
|
|
50
|
-
<div className="absolute top-[8%] text-center">
|
|
51
|
-
<p className="text-red-400 tracking-[0.3em] text-sm">
|
|
52
|
-
THERE IS 1 IMPOSTOR AMONG US
|
|
53
|
-
</p>
|
|
54
|
-
<h1 className="text-7xl font-extrabold mt-2">404</h1>
|
|
55
|
-
<p className="mt-2 opacity-80">This page was ejected into space.</p>
|
|
56
|
-
|
|
57
|
-
<Link
|
|
58
|
-
href="/"
|
|
59
|
-
className="inline-block mt-6 rounded-md bg-red-500 px-5 py-2 text-sm font-semibold hover:opacity-90 transition"
|
|
60
|
-
>
|
|
61
|
-
Return to Ship
|
|
62
|
-
</Link>
|
|
63
|
-
</div>
|
|
64
|
-
|
|
65
|
-
<Image
|
|
66
|
-
src="https://cdn.iconscout.com/icon/free/png-256/free-red-among-us-icon-svg-download-png-2691060.png"
|
|
67
|
-
alt="Impostor"
|
|
68
|
-
width={120}
|
|
69
|
-
height={120}
|
|
70
|
-
unoptimized
|
|
71
|
-
className="absolute top-[55%] w-24 h-auto animate-astronautFly"
|
|
72
|
-
/>
|
|
73
|
-
|
|
74
|
-
<Image
|
|
75
|
-
src="https://cdn.iconscout.com/icon/free/png-256/free-blue-among-us-icon-svg-download-png-2691064.png"
|
|
76
|
-
alt="Crewmate"
|
|
77
|
-
width={120}
|
|
78
|
-
height={120}
|
|
79
|
-
unoptimized
|
|
80
|
-
className="absolute bottom-[10%] left-[15%] w-24 h-auto animate-floatCrew"
|
|
81
|
-
/>
|
|
82
|
-
|
|
83
50
|
<style jsx global>{`
|
|
84
|
-
@
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
25% {
|
|
89
|
-
top: 52%;
|
|
90
|
-
transform: rotate(10deg);
|
|
91
|
-
}
|
|
92
|
-
50% {
|
|
93
|
-
top: 58%;
|
|
94
|
-
transform: rotate(20deg);
|
|
95
|
-
}
|
|
96
|
-
75% {
|
|
97
|
-
top: 62%;
|
|
98
|
-
transform: rotate(10deg);
|
|
99
|
-
}
|
|
100
|
-
100% {
|
|
101
|
-
left: 110%;
|
|
102
|
-
transform: rotate(20deg);
|
|
103
|
-
}
|
|
51
|
+
@import url('https://fonts.googleapis.com/css2?family=VT323&display=swap');
|
|
52
|
+
|
|
53
|
+
.among-us-font {
|
|
54
|
+
font-family: 'VT323', monospace;
|
|
104
55
|
}
|
|
105
56
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
50% {
|
|
111
|
-
transform: translateY(-12px);
|
|
112
|
-
}
|
|
113
|
-
100% {
|
|
114
|
-
transform: translateY(0px);
|
|
115
|
-
}
|
|
57
|
+
.star-field {
|
|
58
|
+
position: absolute;
|
|
59
|
+
inset: 0;
|
|
60
|
+
pointer-events: none;
|
|
116
61
|
}
|
|
117
62
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
25% {
|
|
123
|
-
background: rgba(255, 255, 255, 0.8);
|
|
124
|
-
}
|
|
125
|
-
50% {
|
|
126
|
-
background: rgba(255, 255, 255, 1);
|
|
127
|
-
}
|
|
128
|
-
75% {
|
|
129
|
-
background: rgba(255, 255, 255, 0.8);
|
|
130
|
-
}
|
|
131
|
-
100% {
|
|
132
|
-
background: rgba(255, 255, 255, 0.4);
|
|
133
|
-
}
|
|
63
|
+
.star {
|
|
64
|
+
position: absolute;
|
|
65
|
+
background: white;
|
|
66
|
+
border-radius: 50%;
|
|
134
67
|
}
|
|
135
68
|
|
|
136
|
-
.
|
|
137
|
-
|
|
69
|
+
.crt-overlay::before {
|
|
70
|
+
content: " ";
|
|
71
|
+
display: block;
|
|
72
|
+
position: absolute;
|
|
73
|
+
top: 0;
|
|
74
|
+
left: 0;
|
|
75
|
+
bottom: 0;
|
|
76
|
+
right: 0;
|
|
77
|
+
background: linear-gradient(rgba(18, 16, 16, 0) 50%, rgba(0, 0, 0, 0.25) 50%), linear-gradient(90deg, rgba(255, 0, 0, 0.06), rgba(0, 255, 0, 0.02), rgba(0, 0, 255, 0.06));
|
|
78
|
+
z-index: 30;
|
|
79
|
+
background-size: 100% 3px, 3px 100%;
|
|
80
|
+
pointer-events: none;
|
|
138
81
|
}
|
|
139
82
|
|
|
140
|
-
.
|
|
141
|
-
|
|
83
|
+
.crt-scanline {
|
|
84
|
+
width: 100%;
|
|
85
|
+
height: 100px;
|
|
86
|
+
z-index: 31;
|
|
87
|
+
background: linear-gradient(0deg, rgba(0, 0, 0, 0) 0%, rgba(255, 255, 255, 0.05) 10%, rgba(0, 0, 0, 0.1) 100%);
|
|
88
|
+
opacity: 0.1;
|
|
89
|
+
position: absolute;
|
|
90
|
+
bottom: 100%;
|
|
91
|
+
animation: scanline 8s linear infinite;
|
|
142
92
|
}
|
|
143
93
|
|
|
144
|
-
|
|
145
|
-
|
|
94
|
+
@keyframes scanline {
|
|
95
|
+
0% { bottom: 100%; }
|
|
96
|
+
100% { bottom: -100px; }
|
|
146
97
|
}
|
|
147
98
|
`}</style>
|
|
99
|
+
|
|
100
|
+
<div className="star-field">
|
|
101
|
+
{stars.map((star) => (
|
|
102
|
+
<motion.div
|
|
103
|
+
key={star.id}
|
|
104
|
+
className="star"
|
|
105
|
+
style={{
|
|
106
|
+
width: star.size,
|
|
107
|
+
height: star.size,
|
|
108
|
+
top: `${star.y}%`,
|
|
109
|
+
left: `${star.x}%`,
|
|
110
|
+
opacity: star.opacity,
|
|
111
|
+
boxShadow: `0 0 ${star.size * 2}px rgba(255, 255, 255, 0.5)`,
|
|
112
|
+
}}
|
|
113
|
+
animate={{
|
|
114
|
+
left: ["100%", "-10%"],
|
|
115
|
+
}}
|
|
116
|
+
transition={{
|
|
117
|
+
duration: 25 / star.speed,
|
|
118
|
+
repeat: Infinity,
|
|
119
|
+
ease: "linear",
|
|
120
|
+
delay: Math.random() * -25,
|
|
121
|
+
}}
|
|
122
|
+
/>
|
|
123
|
+
))}
|
|
124
|
+
</div>
|
|
125
|
+
|
|
126
|
+
<div className="z-10 flex flex-col items-center text-center px-4 among-us-font select-none">
|
|
127
|
+
<motion.h1
|
|
128
|
+
className="text-8xl md:text-[12rem] font-bold tracking-[0.1em] text-white mb-4 leading-none"
|
|
129
|
+
initial={{ opacity: 0, scale: 0.9 }}
|
|
130
|
+
animate={{ opacity: 1, scale: 1 }}
|
|
131
|
+
transition={{ duration: 1.5, ease: "easeOut" }}
|
|
132
|
+
>
|
|
133
|
+
404
|
|
134
|
+
</motion.h1>
|
|
135
|
+
|
|
136
|
+
<motion.div
|
|
137
|
+
className="mb-8 h-12"
|
|
138
|
+
variants={typewriterVariants}
|
|
139
|
+
initial="hidden"
|
|
140
|
+
animate="visible"
|
|
141
|
+
>
|
|
142
|
+
<h2 className="text-2xl md:text-5xl text-red-500 uppercase font-black tracking-[0.2em]">
|
|
143
|
+
{text.split("").map((char, index) => (
|
|
144
|
+
<motion.span key={index} variants={letterVariants}>
|
|
145
|
+
{char}
|
|
146
|
+
</motion.span>
|
|
147
|
+
))}
|
|
148
|
+
</h2>
|
|
149
|
+
</motion.div>
|
|
150
|
+
|
|
151
|
+
<motion.div
|
|
152
|
+
className="space-y-6"
|
|
153
|
+
initial={{ opacity: 0 }}
|
|
154
|
+
animate={{ opacity: 1 }}
|
|
155
|
+
transition={{ delay: 3.5, duration: 1.2 }}
|
|
156
|
+
>
|
|
157
|
+
<p className="text-xl md:text-4xl text-gray-400 max-w-2xl mx-auto tracking-wide leading-relaxed">
|
|
158
|
+
This page was ejected into space.
|
|
159
|
+
</p>
|
|
160
|
+
|
|
161
|
+
<motion.p
|
|
162
|
+
className="text-lg md:text-3xl text-white tracking-widest"
|
|
163
|
+
initial={{ opacity: 0, y: 20 }}
|
|
164
|
+
animate={{ opacity: 1, y: 0 }}
|
|
165
|
+
transition={{ delay: 5, duration: 1 }}
|
|
166
|
+
>
|
|
167
|
+
<span className="text-red-600 font-bold px-2">404-Page</span> was not An Impostor.
|
|
168
|
+
</motion.p>
|
|
169
|
+
|
|
170
|
+
<motion.div
|
|
171
|
+
className="pt-12"
|
|
172
|
+
initial={{ opacity: 0 }}
|
|
173
|
+
animate={{ opacity: 1 }}
|
|
174
|
+
transition={{ delay: 6.5, duration: 1 }}
|
|
175
|
+
>
|
|
176
|
+
<Link
|
|
177
|
+
href="/"
|
|
178
|
+
className="group relative inline-flex items-center justify-center px-12 py-4 font-bold text-white transition-all duration-300 bg-transparent border-2 border-white/30 hover:border-white hover:bg-white hover:text-black rounded-sm uppercase tracking-[0.3em] text-xl"
|
|
179
|
+
>
|
|
180
|
+
Return to Ship
|
|
181
|
+
</Link>
|
|
182
|
+
</motion.div>
|
|
183
|
+
</motion.div>
|
|
184
|
+
</div>
|
|
185
|
+
|
|
186
|
+
<div className="absolute inset-0 pointer-events-none overflow-hidden">
|
|
187
|
+
<motion.div
|
|
188
|
+
className="absolute w-32 md:w-56 h-auto"
|
|
189
|
+
initial={{ left: "-25%", top: "40%", rotate: 0 }}
|
|
190
|
+
animate={{
|
|
191
|
+
left: "125%",
|
|
192
|
+
top: ["40%", "45%", "35%", "40%"],
|
|
193
|
+
rotate: 360
|
|
194
|
+
}}
|
|
195
|
+
transition={{
|
|
196
|
+
duration: 20,
|
|
197
|
+
repeat: Infinity,
|
|
198
|
+
ease: "linear"
|
|
199
|
+
}}
|
|
200
|
+
>
|
|
201
|
+
<Image
|
|
202
|
+
src="https://cdn.iconscout.com/icon/free/png-256/free-red-among-us-icon-svg-download-png-2691060.png"
|
|
203
|
+
alt="Ejected Red"
|
|
204
|
+
width={250}
|
|
205
|
+
height={250}
|
|
206
|
+
unoptimized
|
|
207
|
+
className="drop-shadow-[0_0_20px_rgba(255,0,0,0.5)]"
|
|
208
|
+
/>
|
|
209
|
+
</motion.div>
|
|
210
|
+
|
|
211
|
+
<motion.div
|
|
212
|
+
className="absolute w-24 md:w-40 h-auto"
|
|
213
|
+
initial={{ left: "-25%", top: "70%", rotate: 0 }}
|
|
214
|
+
animate={{
|
|
215
|
+
left: "125%",
|
|
216
|
+
top: ["70%", "55%", "65%", "70%"],
|
|
217
|
+
rotate: -360
|
|
218
|
+
}}
|
|
219
|
+
transition={{
|
|
220
|
+
duration: 28,
|
|
221
|
+
repeat: Infinity,
|
|
222
|
+
ease: "linear",
|
|
223
|
+
delay: 12
|
|
224
|
+
}}
|
|
225
|
+
>
|
|
226
|
+
<Image
|
|
227
|
+
src="https://cdn.iconscout.com/icon/free/png-256/free-blue-among-us-icon-svg-download-png-2691064.png"
|
|
228
|
+
alt="Ejected Blue"
|
|
229
|
+
width={200}
|
|
230
|
+
height={200}
|
|
231
|
+
unoptimized
|
|
232
|
+
className="drop-shadow-[0_0_20px_rgba(0,0,255,0.5)] opacity-60"
|
|
233
|
+
/>
|
|
234
|
+
</motion.div>
|
|
235
|
+
</div>
|
|
236
|
+
|
|
237
|
+
<div className="crt-overlay pointer-events-none absolute inset-0 z-40"></div>
|
|
238
|
+
<div className="crt-scanline z-50"></div>
|
|
239
|
+
<div className="absolute inset-0 pointer-events-none bg-[radial-gradient(circle_at_center,_transparent_0%,_rgba(0,0,0,0.7)_100%)] z-20"></div>
|
|
148
240
|
</div>
|
|
149
241
|
);
|
|
150
242
|
};
|
|
151
243
|
|
|
152
244
|
export default AmongUs;
|
|
245
|
+
|
|
246
|
+
|