404lab 1.0.0

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.
@@ -0,0 +1,268 @@
1
+ "use client";
2
+
3
+ import { useEffect, useState } from "react";
4
+ import Link from "next/link";
5
+
6
+ const Terminal404 = () => {
7
+ const [text, setText] = useState("");
8
+ const [commandVisible, setCommandVisible] = useState(false);
9
+ const [cursorBlink, setCursorBlink] = useState(true);
10
+
11
+ useEffect(() => {
12
+ const message = "$ ERROR 404 | Page not found in the digital void";
13
+ let i = 0;
14
+
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-linear-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
+ }
150
+
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
+ }
161
+
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
+ }
173
+
174
+ .cursor.hidden {
175
+ opacity: 0;
176
+ }
177
+
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
+ }
184
+
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
+ }
211
+
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);
219
+ }
220
+
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>
235
+
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>
242
+
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>
247
+
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>
252
+
253
+ <div className="mb-4 text-sm opacity-80">
254
+ Type &apos;help&apos; for available commands...
255
+ </div>
256
+ </>
257
+ )}
258
+ </div>
259
+
260
+ <Link href="/" className="link-button">
261
+ → Return to homepage
262
+ </Link>
263
+ </div>
264
+ </main>
265
+ );
266
+ };
267
+
268
+ export default Terminal404;