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.
@@ -1,268 +1,150 @@
1
1
  "use client";
2
2
 
3
- import { useEffect, useState } from "react";
3
+ import { useEffect, useRef, useState } from "react";
4
4
  import Link from "next/link";
5
+ import { motion, AnimatePresence } from "framer-motion";
6
+ import { cn } from "@/components/ui/cn";
5
7
 
6
- const Terminal404 = () => {
7
- const [text, setText] = useState("");
8
- const [commandVisible, setCommandVisible] = useState(false);
9
- const [cursorBlink, setCursorBlink] = useState(true);
8
+ const Terminal404 = ({ className }: { className?: string }) => {
9
+ const canvasRef = useRef<HTMLCanvasElement>(null);
10
+ const [displayText, setDisplayText] = useState("");
11
+ const [isDecrypted, setIsDecrypted] = useState(false);
10
12
 
11
13
  useEffect(() => {
12
- const message = "$ ERROR 404 | Page not found in the digital void";
13
- let i = 0;
14
+ const canvas = canvasRef.current;
15
+ if (!canvas) return;
16
+ const ctx = canvas.getContext("2d");
17
+ if (!ctx) return;
14
18
 
15
- const interval = setInterval(() => {
16
- setText(message.slice(0, i));
17
- i++;
18
- if (i > message.length) {
19
- clearInterval(interval);
20
- setTimeout(() => setCommandVisible(true), 500);
21
- }
22
- }, 50);
23
-
24
- return () => clearInterval(interval);
25
- }, []);
26
-
27
- useEffect(() => {
28
- const blink = setInterval(() => {
29
- setCursorBlink((prev) => !prev);
30
- }, 530);
31
- return () => clearInterval(blink);
32
- }, []);
33
-
34
- return (
35
- <main className="min-h-screen w-full bg-black p-8 font-mono overflow-hidden relative">
36
- <div className="absolute inset-0 pointer-events-none">
37
- <div className="absolute inset-0 bg-gradient-to-b from-transparent via-transparent to-black opacity-20"></div>
38
- <div className="absolute inset-0 scanlines"></div>
39
- </div>
40
-
41
- <style jsx>{`
42
- @keyframes glitch {
43
- 0% {
44
- clip-path: inset(40% 0 61% 0);
45
- transform: translate(0);
46
- }
47
- 20% {
48
- clip-path: inset(92% 0 1% 0);
49
- transform: translate(-2px, 2px);
50
- }
51
- 40% {
52
- clip-path: inset(43% 0 1% 0);
53
- transform: translate(-2px, -2px);
54
- }
55
- 60% {
56
- clip-path: inset(25% 0 58% 0);
57
- transform: translate(2px, 2px);
58
- }
59
- 80% {
60
- clip-path: inset(54% 0 7% 0);
61
- transform: translate(2px, -2px);
62
- }
63
- 100% {
64
- clip-path: inset(58% 0 43% 0);
65
- transform: translate(0);
66
- }
67
- }
68
-
69
- @keyframes flicker {
70
- 0%,
71
- 19%,
72
- 21%,
73
- 23%,
74
- 25%,
75
- 54%,
76
- 56%,
77
- 100% {
78
- opacity: 1;
79
- text-shadow:
80
- 0 0 10px rgba(31, 240, 66, 0.8),
81
- 0 0 20px rgba(31, 240, 66, 0.6),
82
- 0 0 30px rgba(31, 240, 66, 0.4);
83
- }
84
- 20%,
85
- 24%,
86
- 55% {
87
- opacity: 0.8;
88
- text-shadow:
89
- 0 0 5px rgba(31, 240, 66, 0.4),
90
- 0 0 10px rgba(31, 240, 66, 0.2);
91
- }
92
- }
93
-
94
- @keyframes fadeInUp {
95
- from {
96
- opacity: 0;
97
- transform: translateY(10px);
98
- }
99
- to {
100
- opacity: 1;
101
- transform: translateY(0);
102
- }
103
- }
104
-
105
- @keyframes pulse-glow {
106
- 0%,
107
- 100% {
108
- text-shadow:
109
- 0 0 10px rgba(31, 240, 66, 0.8),
110
- 0 0 20px rgba(31, 240, 66, 0.5),
111
- 0 0 30px rgba(31, 240, 66, 0.3);
112
- }
113
- 50% {
114
- text-shadow:
115
- 0 0 15px rgba(31, 240, 66, 1),
116
- 0 0 30px rgba(31, 240, 66, 0.7),
117
- 0 0 45px rgba(31, 240, 66, 0.4);
118
- }
119
- }
120
-
121
- @keyframes typewriter {
122
- from {
123
- width: 0;
124
- }
125
- to {
126
- width: 100%;
127
- }
128
- }
129
-
130
- .scanlines {
131
- background: repeating-linear-gradient(
132
- 0deg,
133
- rgba(0, 0, 0, 0.15),
134
- rgba(0, 0, 0, 0.15) 1px,
135
- transparent 1px,
136
- transparent 2px
137
- );
138
- pointer-events: none;
139
- animation: scanlines 8s linear infinite;
140
- }
141
-
142
- @keyframes scanlines {
143
- 0% {
144
- transform: translateY(0);
145
- }
146
- 100% {
147
- transform: translateY(10px);
148
- }
149
- }
19
+ canvas.width = window.innerWidth;
20
+ canvas.height = window.innerHeight;
150
21
 
151
- .terminal-text {
152
- color: #1ff042;
153
- font-size: 1.4rem;
154
- line-height: 1.8;
155
- text-shadow:
156
- 0 0 10px rgba(31, 240, 66, 0.8),
157
- 0 0 20px rgba(31, 240, 66, 0.5),
158
- 0 0 30px rgba(31, 240, 66, 0.3);
159
- animation: flicker 4s infinite;
160
- }
22
+ const characters = "0123456789ABCDEFHIJKLMNOPQRSTUVWXYZ";
23
+ const fontSize = 16;
24
+ const columns = canvas.width / fontSize;
25
+ const drops: number[] = [];
161
26
 
162
- .cursor {
163
- display: inline-block;
164
- width: 1em;
165
- height: 1.4em;
166
- background: #1ff042;
167
- margin-left: 4px;
168
- box-shadow:
169
- 0 0 10px rgba(31, 240, 66, 0.8),
170
- 0 0 20px rgba(31, 240, 66, 0.5);
171
- animation: pulse-glow 1.5s ease-in-out infinite;
172
- }
27
+ for (let i = 0; i < columns; i++) {
28
+ drops[i] = 1;
29
+ }
173
30
 
174
- .cursor.hidden {
175
- opacity: 0;
176
- }
31
+ const draw = () => {
32
+ ctx.fillStyle = "rgba(0, 0, 0, 0.05)";
33
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
177
34
 
178
- .command-line {
179
- font-size: 1.25rem;
180
- line-height: 1.7;
181
- animation: fadeInUp 0.6s ease-out forwards;
182
- opacity: 0;
183
- }
35
+ ctx.fillStyle = "#0F0";
36
+ ctx.font = fontSize + "px monospace";
184
37
 
185
- .command-line:nth-child(1) {
186
- animation-delay: 0s;
187
- }
188
- .command-line:nth-child(2) {
189
- animation-delay: 0.3s;
190
- }
191
- .command-line:nth-child(3) {
192
- animation-delay: 0.6s;
193
- }
194
-
195
- .link-button {
196
- display: inline-block;
197
- margin-top: 2rem;
198
- padding: 1rem 2rem;
199
- border: 2px solid #1ff042;
200
- color: #1ff042;
201
- background: rgba(31, 240, 66, 0.05);
202
- text-decoration: none;
203
- font-size: 1.15rem;
204
- font-weight: 600;
205
- letter-spacing: 0.12em;
206
- transition: all 200ms ease;
207
- animation: fadeInUp 0.6s ease-out 0.9s forwards;
208
- opacity: 0;
209
- cursor: pointer;
210
- }
38
+ for (let i = 0; i < drops.length; i++) {
39
+ const text = characters.charAt(Math.floor(Math.random() * characters.length));
40
+ ctx.fillText(text, i * fontSize, drops[i] * fontSize);
211
41
 
212
- .link-button:hover {
213
- background: rgba(31, 240, 66, 0.15);
214
- box-shadow: 0 0 20px rgba(31, 240, 66, 0.6);
215
- text-shadow:
216
- 0 0 10px rgba(31, 240, 66, 0.8),
217
- 0 0 20px rgba(31, 240, 66, 0.6);
218
- transform: translateY(-2px);
42
+ if (drops[i] * fontSize > canvas.height && Math.random() > 0.975) {
43
+ drops[i] = 0;
219
44
  }
45
+ drops[i]++;
46
+ }
47
+ };
48
+
49
+ const interval = setInterval(draw, 33);
50
+ const handleResize = () => {
51
+ canvas.width = window.innerWidth;
52
+ canvas.height = window.innerHeight;
53
+ };
54
+ window.addEventListener("resize", handleResize);
55
+
56
+ return () => {
57
+ clearInterval(interval);
58
+ window.removeEventListener("resize", handleResize);
59
+ };
60
+ }, []);
220
61
 
221
- .link-button:active {
222
- transform: translateY(0);
223
- }
224
- `}</style>
225
-
226
- <div className="relative z-10 max-w-3xl">
227
- <div className="terminal-text font-bold tracking-wider">
228
- <div className="mb-6">
229
- <span className="inline">{text}</span>
230
- <span
231
- className={`cursor ${cursorBlink ? "" : "hidden"}`}
232
- aria-hidden="true"
233
- />
234
- </div>
62
+ useEffect(() => {
63
+ const target = "404 // ACCESS DENIED";
64
+ let iterations = 0;
65
+
66
+ const interval = setInterval(() => {
67
+ setDisplayText(prev =>
68
+ target.split("").map((char, index) => {
69
+ if (index < iterations) return target[index];
70
+ return "0123456789ABCDEF"[Math.floor(Math.random() * 16)];
71
+ }).join("")
72
+ );
73
+
74
+ if (iterations >= target.length) {
75
+ clearInterval(interval);
76
+ setIsDecrypted(true);
77
+ }
78
+ iterations += 1/3;
79
+ }, 30);
235
80
 
236
- {commandVisible && (
237
- <>
238
- <div className="command-line mb-4 text-xs sm:text-sm">
239
- <span className="text-green-400">$</span> searching through
240
- dimensional rift...
241
- </div>
81
+ return () => clearInterval(interval);
82
+ }, []);
242
83
 
243
- <div className="command-line mb-4 text-xs sm:text-sm">
244
- <span className="text-green-400">$</span> [404_VOID_DETECTED]
245
- attempting recovery protocol
246
- </div>
84
+ return (
85
+ <div
86
+ className={cn(
87
+ "min-h-screen bg-black flex flex-col items-center justify-center p-8 overflow-hidden font-mono relative",
88
+ className
89
+ )}
90
+ >
91
+ <canvas
92
+ ref={canvasRef}
93
+ className="absolute inset-0 z-0 opacity-20 pointer-events-none"
94
+ />
95
+
96
+ <div className="absolute inset-0 z-1 pointer-events-none bg-[radial-gradient(circle_at_center,_transparent_0%,_rgba(0,0,0,0.8)_100%)]" />
97
+
98
+ <motion.div
99
+ initial={{ opacity: 0, scale: 0.9 }}
100
+ animate={{ opacity: 1, scale: 1 }}
101
+ className="z-10 w-full max-w-4xl bg-black/40 backdrop-blur-sm border border-[#0f0]/20 p-8 sm:p-12 rounded-lg shadow-[0_0_50px_rgba(0,255,0,0.1)] relative overflow-hidden group"
102
+ >
103
+ <div className="absolute top-0 left-0 w-full h-1 bg-gradient-to-r from-transparent via-[#0f0]/40 to-transparent" />
104
+
105
+ <div className="flex items-center gap-2 mb-8 text-[#0f0]/60 text-xs sm:text-sm tracking-widest uppercase">
106
+ <div className="w-2 h-2 bg-[#0f0] rounded-full animate-pulse" />
107
+ System Status: Breach Detected
108
+ </div>
247
109
 
248
- <div className="command-line mb-6 text-xs sm:text-sm">
249
- <span className="text-green-400">$</span> [FAILED] page lost in
250
- the digital void
251
- </div>
110
+ <h1 className="text-3xl sm:text-6xl font-bold text-[#0f0] mb-6 tracking-tighter drop-shadow-[0_0_15px_rgba(0,255,0,0.5)] min-h-[1.2em]">
111
+ {displayText}
112
+ </h1>
113
+
114
+ <p className="text-[#0f0]/80 text-lg sm:text-xl md:text-2xl mb-12 max-w-2xl leading-relaxed">
115
+ The node you are attempting to ping is non-responsive.
116
+ The packets have been lost in the digital aether.
117
+ </p>
118
+
119
+ <div className="flex flex-col sm:flex-row gap-6">
120
+ <Link
121
+ href="/"
122
+ className="px-8 py-4 bg-[#0f0] text-black font-black uppercase tracking-tighter hover:bg-[#00cc00] transition-colors flex items-center justify-center gap-2 group/btn active:scale-95"
123
+ >
124
+ Terminal Home
125
+ <span className="group-hover/btn:translate-x-1 transition-transform">_</span>
126
+ </Link>
127
+ <button className="px-8 py-4 border border-[#0f0]/40 text-[#0f0] font-bold uppercase tracking-widest hover:bg-[#0f0]/5 transition-colors">
128
+ Brute Force Recovery
129
+ </button>
130
+ </div>
252
131
 
253
- <div className="mb-4 text-sm opacity-80">
254
- Type &apos;help&apos; for available commands...
255
- </div>
256
- </>
257
- )}
132
+ <div className="mt-12 pt-8 border-t border-[#0f0]/10 grid grid-cols-2 md:grid-cols-4 gap-4 text-[10px] text-[#0f0]/40 font-bold uppercase tracking-wider">
133
+ <div>IP: 127.0.0.1</div>
134
+ <div>Port: 404</div>
135
+ <div>Hash: MD5(VOID)</div>
136
+ <div>Sig: 0xDEADBEEF</div>
258
137
  </div>
259
138
 
260
- <Link href="/" className="link-button">
261
- → Return to homepage
262
- </Link>
139
+ <div className="absolute bottom-0 left-0 w-full h-[1px] bg-gradient-to-r from-transparent via-[#0f0]/20 to-transparent" />
140
+ </motion.div>
141
+
142
+ <div className="absolute bottom-6 right-6 text-[#0f0]/20 text-sm italic pointer-events-none">
143
+ root@void:/# _
263
144
  </div>
264
- </main>
145
+ </div>
265
146
  );
266
147
  };
267
148
 
268
149
  export default Terminal404;
150
+
@@ -0,0 +1,127 @@
1
+ "use client";
2
+
3
+ import { motion } from "framer-motion";
4
+ import Link from "next/link";
5
+ import { cn } from "@/components/ui/cn";
6
+ import { useEffect, useState } from "react";
7
+
8
+ const allLogs = [
9
+ "Compiling page /404...",
10
+ "Analyzing dependencies...",
11
+ "Error: Module not found",
12
+ "Deployment failed [404]"
13
+ ];
14
+
15
+ const Vercel = ({ className }: { className?: string }) => {
16
+ const [logs, setLogs] = useState<{ text: string, time: string }[]>([]);
17
+ const [mounted, setMounted] = useState(false);
18
+
19
+ useEffect(() => {
20
+ setMounted(true);
21
+ let i = 0;
22
+ const interval = setInterval(() => {
23
+ if (i < allLogs.length) {
24
+ const time = new Date().toLocaleTimeString('en-US', { hour12: false, hour: '2-digit', minute: '2-digit', second: '2-digit' });
25
+ setLogs(prev => [...prev, { text: allLogs[i], time }]);
26
+ i++;
27
+ } else {
28
+ clearInterval(interval);
29
+ }
30
+ }, 1000);
31
+ return () => clearInterval(interval);
32
+ }, []);
33
+
34
+ return (
35
+ <div
36
+ className={cn(
37
+ "min-h-screen bg-black text-white flex flex-col items-center justify-center p-8 overflow-hidden font-sans relative",
38
+ className
39
+ )}
40
+ >
41
+ <div className="absolute inset-0 z-0 opacity-20 [background-image:radial-gradient(#333_1px,transparent_1px)] [background-size:40px_40px]" />
42
+
43
+ <div className="relative z-10 w-full max-w-2xl flex flex-col items-center">
44
+ <motion.div
45
+ initial={{ opacity: 0, scale: 0.8 }}
46
+ animate={{ opacity: 1, scale: 1 }}
47
+ transition={{ duration: 0.5 }}
48
+ className="mb-16"
49
+ >
50
+ <svg width="80" height="80" viewBox="0 0 75 65" fill="none">
51
+ <path d="M37.5 0L75 65H0L37.5 0Z" fill="white" />
52
+ </svg>
53
+ </motion.div>
54
+
55
+ <div className="text-center mb-16">
56
+ <motion.h1
57
+ initial={{ opacity: 0, y: 10 }}
58
+ animate={{ opacity: 1, y: 0 }}
59
+ className="text-8xl sm:text-9xl font-bold tracking-tighter mb-4"
60
+ >
61
+ 404
62
+ </motion.h1>
63
+ <motion.p
64
+ initial={{ opacity: 0 }}
65
+ animate={{ opacity: 1 }}
66
+ transition={{ delay: 0.2 }}
67
+ className="text-gray-400 text-lg sm:text-xl font-medium"
68
+ >
69
+ This deployment could not be found.
70
+ </motion.p>
71
+ </div>
72
+
73
+ <div className="w-full bg-[#111] border border-white/10 rounded-lg p-6 font-mono text-sm mb-12 shadow-2xl">
74
+ <div className="flex gap-2 mb-4 border-b border-white/5 pb-4">
75
+ <div className="w-3 h-3 rounded-full bg-red-500" />
76
+ <div className="w-3 h-3 rounded-full bg-[#333]" />
77
+ <div className="w-3 h-3 rounded-full bg-[#333]" />
78
+ </div>
79
+ <div className="space-y-2">
80
+ {logs.map((log, i) => (
81
+ <motion.div
82
+ key={i}
83
+ initial={{ opacity: 0, x: -5 }}
84
+ animate={{ opacity: 1, x: 0 }}
85
+ className={cn(
86
+ "flex gap-4",
87
+ log.text.includes("Error") || log.text.includes("failed") ? "text-red-400" : "text-gray-400"
88
+ )}
89
+ >
90
+ <span className="text-gray-600">[{log.time}]</span>
91
+ <span>{log.text}</span>
92
+ </motion.div>
93
+ ))}
94
+ <motion.span
95
+ animate={{ opacity: [1, 0] }}
96
+ transition={{ repeat: Infinity, duration: 0.8 }}
97
+ className="inline-block w-2 h-4 bg-white/40 ml-1"
98
+ />
99
+ </div>
100
+ </div>
101
+
102
+ <div className="flex flex-col sm:flex-row gap-4 w-full">
103
+ <Link
104
+ href="/"
105
+ className="flex-1 bg-white text-black font-bold py-4 rounded-md text-center hover:bg-gray-200 transition-colors active:scale-95 shadow-lg shadow-white/5"
106
+ >
107
+ View Documentation
108
+ </Link>
109
+ <button className="flex-1 border border-white/10 text-white font-bold py-4 rounded-md hover:bg-white/5 transition-colors active:scale-95">
110
+ Check Status
111
+ </button>
112
+ </div>
113
+
114
+ <div className="mt-20 flex gap-8 text-[10px] text-gray-600 font-bold uppercase tracking-widest">
115
+ <div className="flex items-center gap-2">
116
+ <div className="w-1.5 h-1.5 rounded-full bg-red-500 animate-pulse" />
117
+ Vercel System
118
+ </div>
119
+ <div>Region: SFO1</div>
120
+ <div>ID: 404-VOID</div>
121
+ </div>
122
+ </div>
123
+ </div>
124
+ );
125
+ };
126
+
127
+ export default Vercel;