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,89 +1,195 @@
1
1
  "use client";
2
2
 
3
- import { useEffect } from "react";
4
- import { tsParticles } from "tsparticles-engine";
5
- import { loadPolygonPath } from "tsparticles-path-polygon";
3
+ import { useEffect, useState } from "react";
4
+ import Particles, { initParticlesEngine } from "@tsparticles/react";
5
+ import { loadSlim } from "@tsparticles/slim";
6
+ import { type Container, type ISourceOptions } from "@tsparticles/engine";
7
+ import { cn } from "@/components/ui/cn";
8
+ import { motion } from "framer-motion";
9
+ import Link from "next/link";
10
+
11
+ const Custom404Clean = ({
12
+ fullScreen = true,
13
+ className,
14
+ }: {
15
+ fullScreen?: boolean;
16
+ className?: string;
17
+ }) => {
18
+ const [init, setInit] = useState(false);
6
19
 
7
- const Custom404Clean = () => {
8
20
  useEffect(() => {
9
- const init = async () => {
10
- await loadPolygonPath(tsParticles);
21
+ initParticlesEngine(async (engine) => {
22
+ await loadSlim(engine);
23
+ }).then(() => {
24
+ setInit(true);
25
+ });
26
+ }, []);
11
27
 
12
- await tsParticles.load("tsparticles", {
13
- background: {
14
- color: "#000",
28
+ const particlesLoaded = async (container?: Container): Promise<void> => {
29
+ // console.log(container);
30
+ };
31
+
32
+ const options: ISourceOptions = {
33
+ background: {
34
+ color: "#050505",
35
+ },
36
+ fullScreen: {
37
+ enable: fullScreen,
38
+ zIndex: 0,
39
+ },
40
+ fpsLimit: 120,
41
+ particles: {
42
+ number: {
43
+ value: 80,
44
+ density: {
45
+ enable: true,
46
+ width: 800,
47
+ height: 800,
15
48
  },
16
- fullScreen: {
49
+ },
50
+ color: {
51
+ value: "#ffd700",
52
+ },
53
+ shape: {
54
+ type: "circle",
55
+ },
56
+ opacity: {
57
+ value: {
58
+ min: 0.1,
59
+ max: 0.5,
60
+ },
61
+ animation: {
17
62
  enable: true,
18
- zIndex: -1,
63
+ speed: 1,
64
+ sync: false,
19
65
  },
20
- particles: {
21
- color: {
22
- value: "#ffd966",
23
- },
24
- number: {
25
- value: 0,
26
- },
27
- size: {
28
- value: 2,
29
- },
30
- opacity: {
31
- value: 1,
32
- },
33
- shape: {
34
- type: "circle",
35
- },
36
- move: {
37
- enable: true,
38
- speed: 6,
39
- path: {
40
- enable: true,
41
- generator: "polygonPathGenerator",
42
- options: {
43
- sides: 6,
44
- turnSteps: 30,
45
- angle: 30,
46
- },
47
- },
48
- trail: {
49
- enable: true,
50
- length: 20,
51
- fillColor: "#000",
52
- },
53
- },
66
+ },
67
+ size: {
68
+ value: {
69
+ min: 0.1,
70
+ max: 3,
54
71
  },
55
- emitters: {
56
- rate: {
57
- quantity: 1,
58
- delay: 0.25,
72
+ animation: {
73
+ enable: true,
74
+ speed: 2,
75
+ sync: false,
76
+ },
77
+ },
78
+ links: {
79
+ enable: true,
80
+ distance: 150,
81
+ color: "#ffd700",
82
+ opacity: 0.2,
83
+ width: 1,
84
+ },
85
+ move: {
86
+ enable: true,
87
+ speed: 1,
88
+ direction: "none",
89
+ random: false,
90
+ straight: false,
91
+ outModes: {
92
+ default: "out",
93
+ },
94
+ attract: {
95
+ enable: true,
96
+ rotate: {
97
+ x: 600,
98
+ y: 1200,
59
99
  },
60
- position: {
61
- x: 50,
62
- y: 50,
100
+ },
101
+ },
102
+ },
103
+ interactivity: {
104
+ detectsOn: "canvas",
105
+ events: {
106
+ onHover: {
107
+ enable: true,
108
+ mode: "grab",
109
+ },
110
+ onClick: {
111
+ enable: true,
112
+ mode: "push",
113
+ },
114
+ resize: {
115
+ enable: true,
116
+ delay: 0.5,
117
+ },
118
+ },
119
+ modes: {
120
+ grab: {
121
+ distance: 140,
122
+ links: {
123
+ opacity: 0.5,
63
124
  },
64
125
  },
65
- });
66
- };
67
-
68
- init();
69
- }, []);
126
+ push: {
127
+ quantity: 4,
128
+ },
129
+ },
130
+ },
131
+ detectRetina: true,
132
+ };
70
133
 
71
134
  return (
72
- <div className="relative flex h-screen w-screen items-center justify-center bg-black text-white font-mono">
73
- <div id="tsparticles" />
135
+ <div
136
+ className={cn(
137
+ "relative flex items-center justify-center bg-black text-white overflow-hidden select-none",
138
+ fullScreen ? "h-screen w-full" : "h-full w-full",
139
+ className
140
+ )}
141
+ >
142
+ {init && (
143
+ <Particles
144
+ id="tsparticles"
145
+ particlesLoaded={particlesLoaded}
146
+ options={options}
147
+ className="absolute inset-0 z-0"
148
+ />
149
+ )}
74
150
 
75
- <div
76
- data-content="404"
77
- className="text-[25vw] relative animate-glitch
78
- before:content-[attr(data-content)] before:absolute before:left-0
79
- before:animate-glitchTop before:[clip-path:polygon(0_0,100%_0,100%_33%,0_33%)]
80
- after:content-[attr(data-content)] after:absolute after:left-0
81
- after:animate-glitchBottom after:[clip-path:polygon(0_67%,100%_67%,100%_100%,0_100%)]"
151
+ <motion.div
152
+ initial={{ opacity: 0, scale: 0.9 }}
153
+ animate={{ opacity: 1, scale: 1 }}
154
+ transition={{ duration: 1, ease: "easeOut" }}
155
+ className="relative z-10 text-center px-6"
82
156
  >
83
- 404
157
+ <div className="relative inline-block mb-12">
158
+ <h1 className="text-[12rem] sm:text-[18rem] font-black tracking-tighter leading-none text-transparent bg-clip-text bg-gradient-to-b from-[#ffd700] to-transparent opacity-80">
159
+ 404
160
+ </h1>
161
+ <div className="absolute -inset-8 bg-[#ffd700]/10 blur-[100px] rounded-full z-[-1]" />
162
+ </div>
163
+
164
+ <motion.div
165
+ initial={{ opacity: 0, y: 20 }}
166
+ animate={{ opacity: 1, y: 0 }}
167
+ transition={{ delay: 0.5 }}
168
+ >
169
+ <h2 className="text-2xl sm:text-4xl font-bold mb-6 tracking-tight text-white/90">
170
+ Lost in the Golden Void
171
+ </h2>
172
+ <p className="text-white/40 text-lg mb-12 max-w-lg mx-auto leading-relaxed">
173
+ The coordinates you provided lead to a region of space that remains uncharted.
174
+ </p>
175
+
176
+ <div className="flex flex-col sm:flex-row gap-6 justify-center">
177
+ <Link
178
+ href="/"
179
+ className="px-10 py-4 bg-[#ffd700] text-black font-bold rounded-full hover:bg-[#ffed4a] transition-all transform hover:-translate-y-1 active:scale-95 shadow-xl shadow-[#ffd700]/20"
180
+ >
181
+ Return to Base
182
+ </Link>
183
+ </div>
184
+ </motion.div>
185
+ </motion.div>
186
+
187
+ <div className="absolute bottom-10 left-10 text-[10px] text-white/20 font-bold uppercase tracking-widest vertical-text">
188
+ Stellar Navigation System // Active
84
189
  </div>
85
190
  </div>
86
191
  );
87
192
  };
88
193
 
89
194
  export default Custom404Clean;
195
+
@@ -1,71 +1,156 @@
1
1
  "use client";
2
2
 
3
+ import { motion } from "framer-motion";
3
4
  import Link from "next/link";
4
- import Image from "next/image";
5
+ import { cn } from "@/components/ui/cn";
6
+
7
+ const Poet = ({ className }: { className?: string }) => {
8
+ const containerVariants = {
9
+ hidden: { opacity: 0 },
10
+ visible: {
11
+ opacity: 1,
12
+ transition: { staggerChildren: 0.15, delayChildren: 0.5 }
13
+ }
14
+ };
15
+
16
+ const lineVariants = {
17
+ hidden: { opacity: 0, x: -10 },
18
+ visible: { opacity: 1, x: 0, transition: { duration: 0.8 } }
19
+ };
5
20
 
6
- const Poet = () => {
7
21
  return (
8
- <main className="min-h-screen bg-[#777] flex items-center justify-center p-4">
9
- <div className="max-w-5xl w-full border-2 border-black bg-black text-white">
10
- <div className="bg-[#d0d0d0] text-black px-4 py-3 border-b-2 border-black font-mono">
11
- <div className="text-xl font-bold">
12
- 404 &raquo; Document Not Found
13
- </div>
14
- <div className="text-sm mt-1">
15
- The requested document{" "}
16
- <span className="font-semibold">&quot;/missing.pdf&quot;</span> does
17
- not exist.
18
- </div>
19
- <div className="mt-2 text-sm">
20
- <Link href="/" className="underline font-semibold">
21
- GO Back
22
- </Link>{" "}
23
- - or -{" "}
24
- <Link href="/" className="underline font-semibold">
25
- GO Home
26
- </Link>
27
- </div>
28
- </div>
22
+ <div
23
+ className={cn(
24
+ "min-h-screen bg-[#1a1a1a] flex items-center justify-center p-6 relative overflow-hidden font-serif",
25
+ className
26
+ )}
27
+ >
28
+ <style jsx global>{`
29
+ @import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,700;0,900;1,400&display=swap');
30
+
31
+ .gothic-font {
32
+ font-family: 'Playfair Display', serif;
33
+ }
34
+
35
+ .parchment {
36
+ background-color: #f4ecd8;
37
+ background-image: url("https://www.transparenttextures.com/patterns/natural-paper.png");
38
+ box-shadow:
39
+ inset 0 0 100px rgba(0,0,0,0.1),
40
+ 0 20px 50px rgba(0,0,0,0.5);
41
+ position: relative;
42
+ }
29
43
 
30
- <div className="flex flex-col md:flex-row">
31
- <div className="flex-1 p-6 font-serif leading-snug text-lg">
32
- <p>Once upon a midnight dreary,</p>
33
- <p>While I web surfed, weak and weary,</p>
34
- <p>For pages long forgotten yore.</p>
35
- <p>When I clicked my fav&apos;rite href,</p>
36
- <p>Suddenly there came a warning,</p>
37
- <p>and my heart was filled with mourning,</p>
44
+ .parchment::after {
45
+ content: '';
46
+ position: absolute;
47
+ inset: 0;
48
+ background: radial-gradient(circle at center, transparent 30%, rgba(0,0,0,0.05) 100%);
49
+ pointer-events: none;
50
+ }
51
+ `}</style>
38
52
 
39
- <p className="mt-4 text-2xl">
40
- Mourning for my dear{" "}
41
- <span className="italic">&quot;/missing.pdf&quot;</span>,
42
- </p>
53
+ <motion.div
54
+ initial={{ x: "-120%", y: "20%", rotate: -10, opacity: 0 }}
55
+ animate={{
56
+ x: "120%",
57
+ y: "80%",
58
+ opacity: [0, 0.1, 0.1, 0]
59
+ }}
60
+ transition={{
61
+ duration: 15,
62
+ repeat: Infinity,
63
+ ease: "linear",
64
+ delay: 2
65
+ }}
66
+ className="absolute z-0 pointer-events-none scale-[2]"
67
+ >
68
+ <svg width="200" height="100" viewBox="0 0 200 100" fill="currentColor" className="text-black">
69
+ <path d="M100 50 C120 40 150 20 180 20 C160 40 140 50 100 50 C60 50 40 40 20 20 C50 20 80 40 100 50 Z" />
70
+ <path d="M100 50 C110 55 120 65 100 80 C80 65 90 55 100 50 Z" />
71
+ </svg>
72
+ </motion.div>
43
73
 
44
- <p className="mt-4">&quot;Tis not possible!&quot; I muttered,</p>
74
+ <motion.div
75
+ initial={{ opacity: 0, y: 20 }}
76
+ animate={{ opacity: 1, y: 0 }}
77
+ className="parchment w-full max-w-4xl min-h-[70vh] rounded-sm p-8 md:p-16 flex flex-col md:flex-row gap-12 border border-[#d4c5a1] relative z-10"
78
+ >
79
+ <div className="flex-1 gothic-font">
80
+ <motion.div
81
+ variants={containerVariants}
82
+ initial="hidden"
83
+ animate="visible"
84
+ className="text-[#2c241a] space-y-2 md:space-y-3"
85
+ >
86
+ <motion.p variants={lineVariants} className="text-sm md:text-base opacity-60 mb-8 tracking-widest uppercase">
87
+ // Archive: /missing.pdf
88
+ </motion.p>
45
89
 
46
- <p className="text-3xl mt-2">
90
+ <motion.p variants={lineVariants}>Once upon a midnight dreary,</motion.p>
91
+ <motion.p variants={lineVariants}>While I web surfed, weak and weary,</motion.p>
92
+ <motion.p variants={lineVariants}>For pages long forgotten yore.</motion.p>
93
+ <motion.p variants={lineVariants}>When I clicked my fav&apos;rite href,</motion.p>
94
+ <motion.p variants={lineVariants}>Suddenly there came a warning,</motion.p>
95
+ <motion.p variants={lineVariants}>and my heart was filled with mourning,</motion.p>
96
+
97
+ <motion.p variants={lineVariants} className="pt-4 text-xl md:text-2xl italic font-medium">
98
+ Mourning for my dear &quot;/missing.pdf&quot;,
99
+ </motion.p>
100
+
101
+ <motion.p variants={lineVariants} className="pt-4">&quot;Tis not possible!&quot; I muttered,</motion.p>
102
+
103
+ <motion.p variants={lineVariants} className="text-2xl md:text-3xl font-bold leading-tight">
47
104
  &quot;Give thine pages, I implore!&quot;
48
- </p>
105
+ </motion.p>
49
106
 
50
- <p className="text-4xl mt-6">
51
- Quoth the server, <span className="font-bold">404</span>.
52
- </p>
53
- </div>
107
+ <motion.div variants={lineVariants} className="pt-12">
108
+ <span className="text-5xl md:text-7xl font-black text-[#8b0000] drop-shadow-sm">404</span>
109
+ <p className="text-lg md:text-xl font-bold mt-2 opacity-80 uppercase tracking-tighter">
110
+ Quoth the server, &quot;Nevermore.&quot;
111
+ </p>
112
+ </motion.div>
113
+ </motion.div>
54
114
 
55
- <div className="w-full md:w-[320px] bg-black flex items-center justify-center p-4">
56
- <Image
57
- src="/raven.png"
58
- alt="Raven"
59
- width={320}
60
- height={420}
61
- className="max-h-105 object-contain opacity-90"
62
- priority
63
- />
64
- </div>
115
+ <motion.div
116
+ initial={{ opacity: 0 }}
117
+ animate={{ opacity: 1 }}
118
+ transition={{ delay: 3 }}
119
+ className="mt-12 flex gap-6"
120
+ >
121
+ <Link
122
+ href="/"
123
+ className="px-6 py-2 border-b-2 border-[#8b0000] text-[#8b0000] font-bold hover:bg-[#8b0000]/5 transition-all active:scale-95"
124
+ >
125
+ Back to Light
126
+ </Link>
127
+ <button className="px-6 py-2 text-[#2c241a]/60 font-bold hover:text-[#2c241a] transition-all">
128
+ Mourn Again
129
+ </button>
130
+ </motion.div>
65
131
  </div>
66
- </div>
67
- </main>
132
+
133
+ <div className="w-full md:w-1/3 flex flex-col items-center justify-center grayscale opacity-80 contrast-125">
134
+ <motion.div
135
+ animate={{
136
+ y: [0, -10, 0],
137
+ rotate: [0, 2, 0]
138
+ }}
139
+ transition={{ duration: 5, repeat: Infinity, ease: "easeInOut" }}
140
+ className="relative"
141
+ >
142
+ <svg width="200" height="280" viewBox="0 0 200 280" className="text-[#2c241a]">
143
+ <path fill="currentColor" d="M100 20 C120 20 160 40 160 100 C160 160 120 200 100 220 C80 200 40 160 40 100 C40 40 80 20 100 20 Z" opacity="0.1" />
144
+ <path fill="currentColor" d="M100 40 C110 40 130 50 130 80 C130 110 110 140 100 150 C90 140 70 110 70 80 C70 50 90 40 100 40 Z" />
145
+ <path stroke="currentColor" strokeWidth="2" d="M100 150 L100 240 M80 220 L120 220" />
146
+ <circle cx="100" cy="80" r="40" fill="none" stroke="currentColor" strokeWidth="1" opacity="0.2" />
147
+ </svg>
148
+ </motion.div>
149
+ </div>
150
+ </motion.div>
151
+ </div>
68
152
  );
69
153
  };
70
154
 
71
155
  export default Poet;
156
+