404lab 2.0.2 → 2.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli/core/templates.js +5 -3
- package/package.json +1 -1
- package/templates/AmongUs.tsx +92 -109
- package/templates/BlueGlitch.tsx +34 -32
- package/templates/BugGame.tsx +479 -0
- package/templates/GeeksforGeeks.tsx +38 -44
- package/templates/Google.tsx +51 -37
- package/templates/MacOs.tsx +82 -68
- package/templates/ModernPage.tsx +45 -24
- package/templates/Particles.tsx +35 -18
- package/templates/Poet.tsx +99 -71
- package/templates/RetroTv.tsx +22 -18
- package/templates/SimplePage.tsx +32 -17
- package/templates/Snow.tsx +54 -21
- package/templates/StoneAge.tsx +75 -33
- package/templates/StrangerThings.tsx +11 -10
- package/templates/{Terminal404.tsx → Terminal.tsx} +20 -10
- package/templates/Vercel.tsx +78 -32
- package/templates/Void.tsx +345 -0
package/templates/Google.tsx
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { motion } from "framer-motion";
|
|
4
3
|
import Link from "next/link";
|
|
5
4
|
import { cn } from "@/components/ui/cn";
|
|
6
5
|
import Image from "next/image";
|
|
@@ -14,76 +13,91 @@ const Google = ({ className }: { className?: string }) => {
|
|
|
14
13
|
className
|
|
15
14
|
)}
|
|
16
15
|
>
|
|
17
|
-
<div className="absolute top-10 left-10 md:left-20">
|
|
16
|
+
<div className="absolute top-6 sm:top-10 left-6 sm:left-10 md:left-20">
|
|
18
17
|
<Image
|
|
19
18
|
src="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_92x30dp.png"
|
|
20
19
|
alt="Google"
|
|
21
20
|
width={92}
|
|
22
21
|
height={30}
|
|
23
|
-
className="opacity-80"
|
|
22
|
+
className="opacity-80 scale-90 sm:scale-100"
|
|
24
23
|
/>
|
|
25
24
|
</div>
|
|
26
25
|
|
|
26
|
+
<style jsx global>{`
|
|
27
|
+
@keyframes fadeInSlide {
|
|
28
|
+
from { opacity: 0; transform: translateX(-30px); }
|
|
29
|
+
to { opacity: 1; transform: translateX(0); }
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@keyframes floatRotate {
|
|
33
|
+
0% { transform: translateY(0) rotate(0deg); }
|
|
34
|
+
25% { transform: translateY(-15px) rotate(-2deg); }
|
|
35
|
+
50% { transform: translateY(0) rotate(0deg); }
|
|
36
|
+
75% { transform: translateY(-15px) rotate(2deg); }
|
|
37
|
+
100% { transform: translateY(0) rotate(0deg); }
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@keyframes popIn {
|
|
41
|
+
from { opacity: 0; transform: scale(0.8) rotate(10deg); }
|
|
42
|
+
to { opacity: 1; transform: scale(1) rotate(0deg); }
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.animate-fade-in {
|
|
46
|
+
animation: fadeInSlide 0.8s ease-out forwards;
|
|
47
|
+
opacity: 0;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.animate-pop-in {
|
|
51
|
+
animation: popIn 1s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards;
|
|
52
|
+
opacity: 0;
|
|
53
|
+
animation-delay: 200ms;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.animate-float {
|
|
57
|
+
animation: floatRotate 6s ease-in-out infinite;
|
|
58
|
+
}
|
|
59
|
+
`}</style>
|
|
27
60
|
<div className="w-full max-w-5xl px-8 flex flex-col md:flex-row items-center justify-between gap-16 text-center md:text-left z-10">
|
|
28
|
-
<
|
|
29
|
-
|
|
30
|
-
animate={{ opacity: 1, x: 0 }}
|
|
31
|
-
transition={{ duration: 0.8, ease: "easeOut" }}
|
|
32
|
-
className="max-w-md"
|
|
61
|
+
<div
|
|
62
|
+
className="max-w-md animate-fade-in px-4"
|
|
33
63
|
>
|
|
34
|
-
<h1 className="text-2xl md:text-3xl font-medium text-[#3c4043] mb-4">
|
|
35
|
-
<span className="font-bold text-4xl block mb-2">404.</span>
|
|
64
|
+
<h1 className="text-xl sm:text-2xl md:text-3xl font-medium text-[#3c4043] mb-4">
|
|
65
|
+
<span className="font-bold text-3xl sm:text-4xl block mb-2">404.</span>
|
|
36
66
|
That's an error.
|
|
37
67
|
</h1>
|
|
38
|
-
<p className="text-[#70757a] text-lg leading-relaxed mb-10">
|
|
68
|
+
<p className="text-[#70757a] text-base sm:text-lg leading-relaxed mb-8 sm:mb-10">
|
|
39
69
|
The requested URL was not found on this server.{" "}
|
|
40
70
|
<span className="text-[#3c4043] font-medium italic">That's all we know.</span>
|
|
41
71
|
</p>
|
|
42
72
|
|
|
43
|
-
<div className="flex flex-col sm:flex-row gap-4 justify-center md:justify-start">
|
|
73
|
+
<div className="flex flex-col sm:flex-row gap-3 sm:gap-4 justify-center md:justify-start">
|
|
44
74
|
<Link
|
|
45
75
|
href="/"
|
|
46
|
-
className="px-8 py-3 bg-[#1a73e8] text-white font-medium rounded-md hover:bg-[#185abc] hover:shadow-md transition-all active:scale-95"
|
|
76
|
+
className="px-8 py-3 bg-[#1a73e8] text-white font-medium rounded-md hover:bg-[#185abc] hover:shadow-md transition-all active:scale-95 text-center"
|
|
47
77
|
>
|
|
48
78
|
Back to Safety
|
|
49
79
|
</Link>
|
|
50
|
-
<button className="px-8 py-3 text-[#1a73e8] font-medium rounded-md hover:bg-[#f1f3f4] transition-all">
|
|
80
|
+
<button className="px-8 py-3 text-[#1a73e8] font-medium rounded-md hover:bg-[#f1f3f4] transition-all text-center">
|
|
51
81
|
Try a search
|
|
52
82
|
</button>
|
|
53
83
|
</div>
|
|
54
|
-
</
|
|
84
|
+
</div>
|
|
55
85
|
|
|
56
|
-
<
|
|
57
|
-
|
|
58
|
-
animate={{ opacity: 1, scale: 1, rotate: 0 }}
|
|
59
|
-
transition={{
|
|
60
|
-
duration: 1,
|
|
61
|
-
type: "spring",
|
|
62
|
-
stiffness: 100,
|
|
63
|
-
delay: 0.2
|
|
64
|
-
}}
|
|
65
|
-
className="relative group"
|
|
86
|
+
<div
|
|
87
|
+
className="relative group animate-pop-in"
|
|
66
88
|
>
|
|
67
|
-
<
|
|
68
|
-
animate
|
|
69
|
-
y: [0, -15, 0],
|
|
70
|
-
rotate: [0, -2, 2, 0]
|
|
71
|
-
}}
|
|
72
|
-
transition={{
|
|
73
|
-
duration: 6,
|
|
74
|
-
repeat: Infinity,
|
|
75
|
-
ease: "easeInOut"
|
|
76
|
-
}}
|
|
89
|
+
<div
|
|
90
|
+
className="animate-float"
|
|
77
91
|
>
|
|
78
92
|
<img
|
|
79
93
|
src="https://www.google.com/images/errors/robot.png"
|
|
80
94
|
alt="Broken robot"
|
|
81
95
|
className="w-[280px] md:w-[350px] h-auto drop-shadow-[0_20px_40px_rgba(0,0,0,0.1)] group-hover:drop-shadow-[0_30px_60px_rgba(0,0,0,0.15)] transition-all"
|
|
82
96
|
/>
|
|
83
|
-
</
|
|
97
|
+
</div>
|
|
84
98
|
|
|
85
99
|
<div className="absolute -z-10 bottom-4 left-1/2 -translate-x-1/2 w-32 h-6 bg-black opacity-[0.05] rounded-full blur-xl scale-x-150 animate-pulse" />
|
|
86
|
-
</
|
|
100
|
+
</div>
|
|
87
101
|
</div>
|
|
88
102
|
|
|
89
103
|
<div className="absolute -bottom-24 -left-24 w-64 h-64 bg-[#4285F4] opacity-[0.03] rounded-full blur-3xl animate-pulse" />
|
package/templates/MacOs.tsx
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
import { useEffect, useRef, useState, KeyboardEvent } from "react";
|
|
4
4
|
import { useRouter } from "next/navigation";
|
|
5
|
-
import { motion, AnimatePresence } from "framer-motion";
|
|
6
5
|
import { cn } from "@/components/ui/cn";
|
|
7
6
|
|
|
8
7
|
type OutputLine = {
|
|
@@ -30,8 +29,11 @@ const MacOs = ({ className }: { className?: string }) => {
|
|
|
30
29
|
}, []);
|
|
31
30
|
|
|
32
31
|
useEffect(() => {
|
|
33
|
-
if (bootDone && inputRef.current
|
|
34
|
-
|
|
32
|
+
if (bootDone && inputRef.current) {
|
|
33
|
+
const isIframe = typeof window !== 'undefined' && window.self !== window.top;
|
|
34
|
+
if (!isIframe) {
|
|
35
|
+
inputRef.current.focus({ preventScroll: true });
|
|
36
|
+
}
|
|
35
37
|
}
|
|
36
38
|
}, [bootDone]);
|
|
37
39
|
|
|
@@ -72,80 +74,73 @@ const MacOs = ({ className }: { className?: string }) => {
|
|
|
72
74
|
<div className="absolute bottom-[-10%] left-[-10%] w-[500px] h-[500px] bg-blue-600/10 rounded-full blur-[120px]" />
|
|
73
75
|
</div>
|
|
74
76
|
|
|
75
|
-
<
|
|
76
|
-
|
|
77
|
-
animate={{ opacity: 1, y: 0, scale: 1 }}
|
|
78
|
-
transition={{ duration: 0.8, ease: [0.16, 1, 0.3, 1] }}
|
|
79
|
-
className="w-full max-w-4xl mx-4 z-10"
|
|
77
|
+
<div
|
|
78
|
+
className="w-full max-w-4xl mx-auto px-4 z-10 animate-fade-in-scale"
|
|
80
79
|
>
|
|
81
80
|
<div className="rounded-xl overflow-hidden shadow-[0_30px_100px_rgba(0,0,0,0.6)] border border-white/10 backdrop-blur-3xl bg-[#1c1c1e]/80">
|
|
82
|
-
<div className="flex items-center justify-between px-4 py-3 bg-white/5 border-b border-white/5">
|
|
83
|
-
<div className="flex items-center gap-2">
|
|
84
|
-
<div className="w-3.5 h-3.5 rounded-full bg-[#ff5f57] shadow-inner" />
|
|
85
|
-
<div className="w-3.5 h-3.5 rounded-full bg-[#febc2e] shadow-inner" />
|
|
86
|
-
<div className="w-3.5 h-3.5 rounded-full bg-[#28c840] shadow-inner" />
|
|
81
|
+
<div className="flex items-center justify-between px-4 py-2 sm:py-3 bg-white/5 border-b border-white/5">
|
|
82
|
+
<div className="flex items-center gap-1.5 sm:gap-2">
|
|
83
|
+
<div className="w-2.5 h-2.5 sm:w-3.5 sm:h-3.5 rounded-full bg-[#ff5f57] shadow-inner" />
|
|
84
|
+
<div className="w-2.5 h-2.5 sm:w-3.5 sm:h-3.5 rounded-full bg-[#febc2e] shadow-inner" />
|
|
85
|
+
<div className="w-2.5 h-2.5 sm:w-3.5 sm:h-3.5 rounded-full bg-[#28c840] shadow-inner" />
|
|
87
86
|
</div>
|
|
88
|
-
<div className="text-[13px] text-white/40 font-medium tracking-wide">
|
|
87
|
+
<div className="text-[11px] sm:text-[13px] text-white/40 font-medium tracking-wide truncate px-2">
|
|
89
88
|
guest — zsh — 80×24
|
|
90
89
|
</div>
|
|
91
|
-
<div className="w-12" />
|
|
90
|
+
<div className="w-8 sm:w-12" />
|
|
92
91
|
</div>
|
|
93
92
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
</motion.div>
|
|
127
|
-
))}
|
|
128
|
-
</AnimatePresence>
|
|
129
|
-
|
|
130
|
-
{bootDone && (
|
|
131
|
-
<div className="flex items-center gap-2 mt-1">
|
|
132
|
-
<span className="text-[#32d74b] font-bold">➜</span>
|
|
133
|
-
<span className="text-[#64d2ff] font-bold">~</span>
|
|
134
|
-
<input
|
|
135
|
-
ref={inputRef}
|
|
136
|
-
value={input}
|
|
137
|
-
onChange={(e) => setInput(e.target.value)}
|
|
138
|
-
onKeyDown={(e) => e.key === "Enter" && runCommand(input)}
|
|
139
|
-
className="bg-transparent border-none outline-none flex-1 text-white caret-[#32d74b]"
|
|
140
|
-
spellCheck={false}
|
|
141
|
-
/>
|
|
93
|
+
<div
|
|
94
|
+
ref={terminalRef}
|
|
95
|
+
onClick={() => inputRef.current?.focus()}
|
|
96
|
+
className="p-4 sm:p-6 h-[400px] sm:h-[500px] overflow-y-auto custom-scrollbar text-[12px] sm:text-[14px] leading-relaxed selection:bg-blue-500/30"
|
|
97
|
+
>
|
|
98
|
+
<div>
|
|
99
|
+
{output.map((line, i) => (
|
|
100
|
+
<div
|
|
101
|
+
key={i}
|
|
102
|
+
className="mb-1 animate-fade-in-left"
|
|
103
|
+
>
|
|
104
|
+
{line.type === "command" && (
|
|
105
|
+
<div className="flex items-center gap-2">
|
|
106
|
+
<span className="text-[#32d74b] font-bold">➜</span>
|
|
107
|
+
<span className="text-[#64d2ff] font-bold">~</span>
|
|
108
|
+
<span className="text-white break-all">{line.text}</span>
|
|
109
|
+
</div>
|
|
110
|
+
)}
|
|
111
|
+
{line.type === "output" && (
|
|
112
|
+
<div className="text-white/80 pl-5 sm:pl-6 break-words">{line.text}</div>
|
|
113
|
+
)}
|
|
114
|
+
{line.type === "system" && (
|
|
115
|
+
<div className="text-white/40 italic break-words">{line.text}</div>
|
|
116
|
+
)}
|
|
117
|
+
{line.type === "error" && (
|
|
118
|
+
<div className="text-[#ff453a] pl-5 sm:pl-6 font-medium break-words">{line.text}</div>
|
|
119
|
+
)}
|
|
120
|
+
{line.type === "warning" && (
|
|
121
|
+
<div className="text-[#febc2e] pl-5 sm:pl-6 break-words">{line.text}</div>
|
|
122
|
+
)}
|
|
123
|
+
</div>
|
|
124
|
+
))}
|
|
142
125
|
</div>
|
|
143
|
-
)}
|
|
144
|
-
</div>
|
|
145
|
-
</div>
|
|
146
|
-
|
|
147
|
-
</motion.div>
|
|
148
126
|
|
|
127
|
+
{bootDone && (
|
|
128
|
+
<div className="flex items-center gap-2 mt-1">
|
|
129
|
+
<span className="text-[#32d74b] font-bold">➜</span>
|
|
130
|
+
<span className="text-[#64d2ff] font-bold">~</span>
|
|
131
|
+
<input
|
|
132
|
+
ref={inputRef}
|
|
133
|
+
value={input}
|
|
134
|
+
onChange={(e) => setInput(e.target.value)}
|
|
135
|
+
onKeyDown={(e) => e.key === "Enter" && runCommand(input)}
|
|
136
|
+
className="bg-transparent border-none outline-none flex-1 text-white caret-[#32d74b] min-w-0"
|
|
137
|
+
spellCheck={false}
|
|
138
|
+
/>
|
|
139
|
+
</div>
|
|
140
|
+
)}
|
|
141
|
+
</div>
|
|
142
|
+
</div>
|
|
143
|
+
</div>
|
|
149
144
|
<style jsx>{`
|
|
150
145
|
.custom-scrollbar::-webkit-scrollbar {
|
|
151
146
|
width: 8px;
|
|
@@ -160,6 +155,25 @@ const MacOs = ({ className }: { className?: string }) => {
|
|
|
160
155
|
.custom-scrollbar::-webkit-scrollbar-thumb:hover {
|
|
161
156
|
background: rgba(255, 255, 255, 0.2);
|
|
162
157
|
}
|
|
158
|
+
|
|
159
|
+
@keyframes fadeInScale {
|
|
160
|
+
from { opacity: 0; transform: translateY(40px) scale(0.95); }
|
|
161
|
+
to { opacity: 1; transform: translateY(0) scale(1); }
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
@keyframes fadeInLeft {
|
|
165
|
+
from { opacity: 0; transform: translateX(-5px); }
|
|
166
|
+
to { opacity: 1; transform: translateX(0); }
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.animate-fade-in-scale {
|
|
170
|
+
animation: fadeInScale 0.8s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
|
171
|
+
opacity: 0;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.animate-fade-in-left {
|
|
175
|
+
animation: fadeInLeft 0.2s ease-out forwards;
|
|
176
|
+
}
|
|
163
177
|
`}</style>
|
|
164
178
|
</main>
|
|
165
179
|
);
|
package/templates/ModernPage.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
|
|
4
4
|
import Link from "next/link";
|
|
5
5
|
import { cn } from "@/components/ui/cn";
|
|
6
6
|
|
|
@@ -18,36 +18,57 @@ const ModernPage = ({ className }: { className?: string }) => {
|
|
|
18
18
|
<div className="absolute bottom-[-10%] right-[-10%] w-[40%] h-[40%] bg-blue-900/20 blur-[120px] rounded-full animate-pulse [animation-delay:2s]" />
|
|
19
19
|
</div>
|
|
20
20
|
|
|
21
|
-
<
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
<style jsx global>{`
|
|
22
|
+
@keyframes fadeSlideUp {
|
|
23
|
+
from { opacity: 0; transform: translateY(20px); }
|
|
24
|
+
to { opacity: 1; transform: translateY(0); }
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
@keyframes scaleIn {
|
|
28
|
+
from { opacity: 0; transform: scale(0.9); }
|
|
29
|
+
to { opacity: 1; transform: scale(1); }
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.animate-fade-slide-up {
|
|
33
|
+
animation: fadeSlideUp 0.8s ease-out forwards;
|
|
34
|
+
opacity: 0;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.animate-scale-in {
|
|
38
|
+
animation: scaleIn 0.5s ease-out forwards;
|
|
39
|
+
opacity: 0;
|
|
40
|
+
animation-delay: 200ms;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.animate-fade-slide-up-delayed {
|
|
44
|
+
animation: fadeSlideUp 0.8s ease-out forwards;
|
|
45
|
+
opacity: 0;
|
|
46
|
+
animation-delay: 400ms;
|
|
47
|
+
}
|
|
48
|
+
`}</style>
|
|
49
|
+
|
|
50
|
+
<div
|
|
51
|
+
className="relative z-10 w-full max-w-2xl animate-fade-slide-up"
|
|
26
52
|
>
|
|
27
|
-
<div className="bg-white/[0.03] backdrop-blur-xl border border-white/10 rounded-[2.5rem] p-12 md:p-20 text-center shadow-2xl overflow-hidden group">
|
|
53
|
+
<div className="bg-white/[0.03] backdrop-blur-xl border border-white/10 rounded-[1.5rem] sm:rounded-[2.5rem] p-8 sm:p-12 md:p-20 text-center shadow-2xl overflow-hidden group">
|
|
28
54
|
<div className="absolute inset-0 bg-gradient-to-br from-white/[0.05] to-transparent pointer-events-none" />
|
|
29
55
|
|
|
30
|
-
<
|
|
31
|
-
|
|
32
|
-
animate={{ scale: 1, opacity: 1 }}
|
|
33
|
-
transition={{ delay: 0.2, duration: 0.5 }}
|
|
34
|
-
className="relative inline-block mb-8"
|
|
56
|
+
<div
|
|
57
|
+
className="relative inline-block mb-6 sm:mb-8 animate-scale-in"
|
|
35
58
|
>
|
|
36
|
-
<h1 className="text-[
|
|
59
|
+
<h1 className="text-[6rem] sm:text-[10rem] md:text-[12rem] font-black leading-none tracking-tighter bg-gradient-to-b from-white to-white/20 bg-clip-text text-transparent select-none">
|
|
37
60
|
404
|
|
38
61
|
</h1>
|
|
39
62
|
<div className="absolute -inset-4 bg-white/5 blur-3xl rounded-full z-[-1] group-hover:bg-white/10 transition-colors" />
|
|
40
|
-
</
|
|
63
|
+
</div>
|
|
41
64
|
|
|
42
|
-
<
|
|
43
|
-
|
|
44
|
-
animate={{ opacity: 1, y: 0 }}
|
|
45
|
-
transition={{ delay: 0.4 }}
|
|
65
|
+
<div
|
|
66
|
+
className="animate-fade-slide-up-delayed"
|
|
46
67
|
>
|
|
47
|
-
<h2 className="text-2xl md:text-3xl font-bold text-white mb-4 tracking-tight">
|
|
68
|
+
<h2 className="text-xl sm:text-2xl md:text-3xl font-bold text-white mb-3 sm:mb-4 tracking-tight">
|
|
48
69
|
Lost in the Digital Ether.
|
|
49
70
|
</h2>
|
|
50
|
-
<p className="text-gray-400 text-lg mb-12 max-w-md mx-auto leading-relaxed">
|
|
71
|
+
<p className="text-gray-400 text-base sm:text-lg mb-8 sm:mb-12 max-w-md mx-auto leading-relaxed">
|
|
51
72
|
The page you are seeking has drifted beyond our reach.
|
|
52
73
|
Let's navigate you back to solid ground.
|
|
53
74
|
</p>
|
|
@@ -55,15 +76,15 @@ const ModernPage = ({ className }: { className?: string }) => {
|
|
|
55
76
|
<div className="flex flex-col sm:flex-row gap-4 justify-center items-center">
|
|
56
77
|
<Link
|
|
57
78
|
href="/"
|
|
58
|
-
className="w-full sm:w-auto px-10 py-4 bg-white text-black font-bold rounded-2xl hover:bg-gray-200 transition-all transform hover:-translate-y-1 active:scale-95 shadow-xl shadow-white/5"
|
|
79
|
+
className="w-full sm:w-auto px-8 sm:px-10 py-3.5 sm:py-4 bg-white text-black font-bold rounded-xl sm:rounded-2xl hover:bg-gray-200 transition-all transform hover:-translate-y-1 active:scale-95 shadow-xl shadow-white/5"
|
|
59
80
|
>
|
|
60
81
|
Go Home
|
|
61
82
|
</Link>
|
|
62
|
-
<button className="w-full sm:w-auto px-10 py-4 border border-white/10 text-white font-bold rounded-2xl hover:bg-white/5 transition-all active:scale-95">
|
|
83
|
+
<button className="w-full sm:w-auto px-8 sm:px-10 py-3.5 sm:py-4 border border-white/10 text-white font-bold rounded-xl sm:rounded-2xl hover:bg-white/5 transition-all active:scale-95">
|
|
63
84
|
Take a Tour
|
|
64
85
|
</button>
|
|
65
86
|
</div>
|
|
66
|
-
</
|
|
87
|
+
</div>
|
|
67
88
|
</div>
|
|
68
89
|
|
|
69
90
|
<div className="mt-12 flex justify-center gap-8 text-[10px] text-white/20 font-bold uppercase tracking-[0.3em]">
|
|
@@ -73,7 +94,7 @@ const ModernPage = ({ className }: { className?: string }) => {
|
|
|
73
94
|
<span>•</span>
|
|
74
95
|
<span>Stable Connection</span>
|
|
75
96
|
</div>
|
|
76
|
-
</
|
|
97
|
+
</div>
|
|
77
98
|
</div>
|
|
78
99
|
);
|
|
79
100
|
};
|
package/templates/Particles.tsx
CHANGED
|
@@ -5,7 +5,6 @@ import Particles, { initParticlesEngine } from "@tsparticles/react";
|
|
|
5
5
|
import { loadSlim } from "@tsparticles/slim";
|
|
6
6
|
import { type Container, type ISourceOptions } from "@tsparticles/engine";
|
|
7
7
|
import { cn } from "@/components/ui/cn";
|
|
8
|
-
import { motion } from "framer-motion";
|
|
9
8
|
import Link from "next/link";
|
|
10
9
|
|
|
11
10
|
const Custom404Clean = ({
|
|
@@ -148,28 +147,46 @@ const Custom404Clean = ({
|
|
|
148
147
|
/>
|
|
149
148
|
)}
|
|
150
149
|
|
|
151
|
-
<
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
150
|
+
<style jsx global>{`
|
|
151
|
+
@keyframes fadeInScale {
|
|
152
|
+
from { opacity: 0; transform: scale(0.9); }
|
|
153
|
+
to { opacity: 1; transform: scale(1); }
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
@keyframes slideUpFade {
|
|
157
|
+
from { opacity: 0; transform: translateY(20px); }
|
|
158
|
+
to { opacity: 1; transform: translateY(0); }
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.animate-fade-in-scale {
|
|
162
|
+
animation: fadeInScale 1s ease-out forwards;
|
|
163
|
+
opacity: 0;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.animate-slide-up-fade {
|
|
167
|
+
animation: slideUpFade 0.8s ease-out forwards;
|
|
168
|
+
opacity: 0;
|
|
169
|
+
animation-delay: 500ms;
|
|
170
|
+
}
|
|
171
|
+
`}</style>
|
|
172
|
+
|
|
173
|
+
<div
|
|
174
|
+
className="relative z-10 text-center px-6 animate-fade-in-scale"
|
|
156
175
|
>
|
|
157
|
-
<div className="relative inline-block mb-12">
|
|
158
|
-
<h1 className="text-[
|
|
176
|
+
<div className="relative inline-block mb-8 sm:mb-12">
|
|
177
|
+
<h1 className="text-[8rem] sm:text-[12rem] md:text-[18rem] font-black tracking-tighter leading-none text-transparent bg-clip-text bg-gradient-to-b from-[#ffd700] to-transparent opacity-80">
|
|
159
178
|
404
|
|
160
179
|
</h1>
|
|
161
|
-
<div className="absolute -inset-8 bg-[#ffd700]/10 blur-[100px] rounded-full z-[-1]" />
|
|
180
|
+
<div className="absolute -inset-4 sm:-inset-8 bg-[#ffd700]/10 blur-[60px] sm:blur-[100px] rounded-full z-[-1]" />
|
|
162
181
|
</div>
|
|
163
182
|
|
|
164
|
-
<
|
|
165
|
-
|
|
166
|
-
animate={{ opacity: 1, y: 0 }}
|
|
167
|
-
transition={{ delay: 0.5 }}
|
|
183
|
+
<div
|
|
184
|
+
className="animate-slide-up-fade"
|
|
168
185
|
>
|
|
169
|
-
<h2 className="text-
|
|
186
|
+
<h2 className="text-xl sm:text-3xl md:text-4xl font-bold mb-4 sm:mb-6 tracking-tight text-white/90">
|
|
170
187
|
Lost in the Golden Void
|
|
171
188
|
</h2>
|
|
172
|
-
<p className="text-white/40 text-lg mb-12 max-w-lg mx-auto leading-relaxed">
|
|
189
|
+
<p className="text-white/40 text-base sm:text-lg mb-8 sm:mb-12 max-w-xs sm:max-w-lg mx-auto leading-relaxed">
|
|
173
190
|
The coordinates you provided lead to a region of space that remains uncharted.
|
|
174
191
|
</p>
|
|
175
192
|
|
|
@@ -181,10 +198,10 @@ const Custom404Clean = ({
|
|
|
181
198
|
Return to Base
|
|
182
199
|
</Link>
|
|
183
200
|
</div>
|
|
184
|
-
</
|
|
185
|
-
</
|
|
201
|
+
</div>
|
|
202
|
+
</div>
|
|
186
203
|
|
|
187
|
-
<div className="absolute bottom-10 left-10 text-[10px] text-white/20 font-bold uppercase tracking-widest vertical-text">
|
|
204
|
+
<div className="absolute bottom-6 sm:bottom-10 left-6 sm:left-10 text-[8px] sm:text-[10px] text-white/20 font-bold uppercase tracking-widest vertical-text hidden xs:block">
|
|
188
205
|
Stellar Navigation System // Active
|
|
189
206
|
</div>
|
|
190
207
|
</div>
|