abhishek-portfolio-template 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.
Files changed (101) hide show
  1. package/README.md +59 -0
  2. package/bin/cli.js +54 -0
  3. package/package.json +27 -0
  4. package/template/components.json +22 -0
  5. package/template/next.config.ts +79 -0
  6. package/template/package.json +43 -0
  7. package/template/postcss.config.js +6 -0
  8. package/template/public/BoliviaSignature-ZpWnz.ttf +0 -0
  9. package/template/public/Gemini_Generated_Image_xc97toxc97toxc97.png +0 -0
  10. package/template/public/Hendrigo.otf +0 -0
  11. package/template/public/audiomass-output.mp3 +0 -0
  12. package/template/public/file.svg +1 -0
  13. package/template/public/globe.svg +1 -0
  14. package/template/public/googlec77e59474f5a09cb.html +1 -0
  15. package/template/public/icon-192x192.png +0 -0
  16. package/template/public/icon-512x512.png +0 -0
  17. package/template/public/next.svg +1 -0
  18. package/template/public/paper sound .mpeg +0 -0
  19. package/template/public/removebg.png +0 -0
  20. package/template/public/resume.pdf +0 -0
  21. package/template/public/sw.js +1 -0
  22. package/template/public/swe-worker-5c72df51bb1f6ee0.js +1 -0
  23. package/template/public/vercel.svg +1 -0
  24. package/template/public/window.svg +1 -0
  25. package/template/public/workbox-f1770938.js +1 -0
  26. package/template/src/app/about/page.tsx +91 -0
  27. package/template/src/app/actions/optimize-text.ts +54 -0
  28. package/template/src/app/gaming/page.tsx +308 -0
  29. package/template/src/app/github/[username]/page.tsx +97 -0
  30. package/template/src/app/globals.css +321 -0
  31. package/template/src/app/layout.tsx +39 -0
  32. package/template/src/app/manifest.ts +25 -0
  33. package/template/src/app/not-found.tsx +16 -0
  34. package/template/src/app/page.tsx +28 -0
  35. package/template/src/app/robots.ts +12 -0
  36. package/template/src/app/sitemap.ts +38 -0
  37. package/template/src/app/template.tsx +5 -0
  38. package/template/src/app/works/[slug]/page.tsx +50 -0
  39. package/template/src/app/works/client.tsx +44 -0
  40. package/template/src/app/works/page.tsx +24 -0
  41. package/template/src/components/about/about-client.tsx +259 -0
  42. package/template/src/components/home/bento-gallery.tsx +52 -0
  43. package/template/src/components/home/contact-section.tsx +34 -0
  44. package/template/src/components/home/craft-card.tsx +18 -0
  45. package/template/src/components/home/featured-projects.tsx +186 -0
  46. package/template/src/components/home/focus-card.tsx +171 -0
  47. package/template/src/components/home/identity-card.tsx +45 -0
  48. package/template/src/components/home/philosophy-card.tsx +104 -0
  49. package/template/src/components/home/skills-in-motion.tsx +109 -0
  50. package/template/src/components/home/tech-stack-marquee.tsx +56 -0
  51. package/template/src/components/ui/3d-folder.tsx +569 -0
  52. package/template/src/components/ui/avatar.tsx +50 -0
  53. package/template/src/components/ui/badge.tsx +36 -0
  54. package/template/src/components/ui/basic-avatar.tsx +12 -0
  55. package/template/src/components/ui/button.tsx +117 -0
  56. package/template/src/components/ui/clipboard-secret.tsx +39 -0
  57. package/template/src/components/ui/command-menu.tsx +519 -0
  58. package/template/src/components/ui/command-palette.tsx +152 -0
  59. package/template/src/components/ui/consciousness-mode.tsx +200 -0
  60. package/template/src/components/ui/copy-code-button.tsx +135 -0
  61. package/template/src/components/ui/display-cards.tsx +70 -0
  62. package/template/src/components/ui/dotted-map.tsx +128 -0
  63. package/template/src/components/ui/dropdown-menu.tsx +200 -0
  64. package/template/src/components/ui/emoji-rating.tsx +123 -0
  65. package/template/src/components/ui/exit-message.tsx +50 -0
  66. package/template/src/components/ui/image-zoom-overlay.tsx +178 -0
  67. package/template/src/components/ui/input-otp.tsx +71 -0
  68. package/template/src/components/ui/kbd.tsx +87 -0
  69. package/template/src/components/ui/location-tag.tsx +232 -0
  70. package/template/src/components/ui/minimal-testimonial.tsx +97 -0
  71. package/template/src/components/ui/mobile-menu.tsx +191 -0
  72. package/template/src/components/ui/navbar.tsx +148 -0
  73. package/template/src/components/ui/page-transition.tsx +24 -0
  74. package/template/src/components/ui/pixeleted-404-not-found.tsx +110 -0
  75. package/template/src/components/ui/preloader-wrapper.tsx +102 -0
  76. package/template/src/components/ui/preloader.tsx +104 -0
  77. package/template/src/components/ui/project-contributors.tsx +57 -0
  78. package/template/src/components/ui/scroll-area.tsx +117 -0
  79. package/template/src/components/ui/signature.tsx +173 -0
  80. package/template/src/components/ui/smooth-scroll.tsx +31 -0
  81. package/template/src/components/ui/social-icons.tsx +103 -0
  82. package/template/src/components/ui/social-stories.tsx +394 -0
  83. package/template/src/components/ui/sound-constants.ts +1 -0
  84. package/template/src/components/ui/text-explode.tsx +188 -0
  85. package/template/src/components/ui/toast.tsx +80 -0
  86. package/template/src/components/ui/tooltip.tsx +30 -0
  87. package/template/src/components/ui/user-location.tsx +151 -0
  88. package/template/src/components/ui/vertical-image-stack.tsx +345 -0
  89. package/template/src/components/works/changelog-overlay.tsx +212 -0
  90. package/template/src/components/works/currently-working-card.tsx +130 -0
  91. package/template/src/components/works/project-details-view.tsx +464 -0
  92. package/template/src/components/works/project-grid.tsx +81 -0
  93. package/template/src/fonts/BoliviaSignature-ZpWnz.ttf +0 -0
  94. package/template/src/fonts/Hendrigo.otf +0 -0
  95. package/template/src/lib/data.ts +61 -0
  96. package/template/src/lib/fonts.ts +14 -0
  97. package/template/src/lib/github.ts +15 -0
  98. package/template/src/lib/supabase.ts +11 -0
  99. package/template/src/lib/utils.ts +6 -0
  100. package/template/tailwind.config.ts +31 -0
  101. package/template/tsconfig.json +34 -0
@@ -0,0 +1,308 @@
1
+ "use client";
2
+
3
+ import { motion, AnimatePresence, useMotionValue, useSpring, useTransform } from "framer-motion";
4
+ import { useRouter } from "next/navigation";
5
+ import { ArrowLeft, Smartphone, Crosshair, X, Zap, Cpu, Shield, Activity, Trophy, Binary, Wifi, Terminal } from "lucide-react";
6
+ import { useState, useRef, MouseEvent, useEffect } from "react";
7
+
8
+ // --- CYBER-SPEC DATA --- //
9
+ const GAMES = [
10
+ {
11
+ id: "bgmi",
12
+ name: "BGMI",
13
+ fullname: "BATTLEGROUNDS MOBILE INDIA",
14
+ ign: "AbhiOp",
15
+ kd: "5.2",
16
+ rank: "Conqueror Grade",
17
+ icon: Smartphone,
18
+ accent: "#10b981", // Emerald
19
+ unit: "01"
20
+ },
21
+ {
22
+ id: "codm",
23
+ name: "CODM",
24
+ fullname: "Call of Duty: Mobile",
25
+ ign: "Ghost_04",
26
+ kd: "3.8",
27
+ rank: "Legendary Series",
28
+ icon: Crosshair,
29
+ accent: "#f59e0b", // Amber
30
+ unit: "02"
31
+ }
32
+ ];
33
+
34
+ // --- 3D TILT POD COMPONENT --- //
35
+ function CombatPod({ children, onClick, accent }: any) {
36
+ const x = useMotionValue(0);
37
+ const y = useMotionValue(0);
38
+ const mouseX = useSpring(x, { stiffness: 400, damping: 60 });
39
+ const mouseY = useSpring(y, { stiffness: 400, damping: 60 });
40
+
41
+ function onMouseMove({ currentTarget, clientX, clientY }: MouseEvent) {
42
+ const { left, top, width, height } = currentTarget.getBoundingClientRect();
43
+ x.set(clientX - left - width / 2);
44
+ y.set(clientY - top - height / 2);
45
+ }
46
+ const rotateX = useTransform(mouseY, [-150, 150], [8, -8]);
47
+ const rotateY = useTransform(mouseX, [-150, 150], [-8, 8]);
48
+
49
+ return (
50
+ <motion.div
51
+ style={{ perspective: 1000 }}
52
+ className="group relative cursor-pointer w-full max-w-[300px] sm:max-w-sm"
53
+ onClick={onClick}
54
+ onMouseMove={onMouseMove}
55
+ onMouseLeave={() => { x.set(0); y.set(0); }}
56
+ >
57
+ <motion.div
58
+ style={{ rotateX, rotateY }}
59
+ className="aspect-[4/5] md:aspect-square relative preserve-3d transition-all duration-500 rounded-[32px] overflow-hidden bg-[#0a0a0a] border border-white/5 flex flex-col"
60
+ >
61
+ {/* Visual Layers */}
62
+ <div className="absolute inset-0 bg-gradient-to-t from-black via-transparent to-transparent opacity-80" />
63
+
64
+ {/* Floating Glow */}
65
+ <motion.div
66
+ className="absolute -inset-[100px] opacity-0 group-hover:opacity-20 transition-opacity duration-700 pointer-events-none"
67
+ style={{ background: `radial-gradient(circle at center, ${accent}88 0%, transparent 70%)` }}
68
+ />
69
+
70
+ {children}
71
+
72
+ {/* Neon Corner Accents */}
73
+ <div className="absolute top-0 right-0 p-4">
74
+ <div className="w-1.5 h-1.5 rounded-full animate-pulse shadow-[0_0_10px_currentColor]" style={{ backgroundColor: accent, color: accent }} />
75
+ </div>
76
+ </motion.div>
77
+ </motion.div>
78
+ );
79
+ }
80
+
81
+ export default function GamingPage() {
82
+ const [selectedGame, setSelectedGame] = useState<any>(null);
83
+ const router = useRouter();
84
+ const [currentTime, setCurrentTime] = useState("");
85
+
86
+ useEffect(() => {
87
+ const update = () => {
88
+ const now = new Date();
89
+ setCurrentTime(now.toLocaleTimeString('en-US', { hour12: false, hour: '2-digit', minute: '2-digit', second: '2-digit' }));
90
+ };
91
+ update();
92
+ const interval = setInterval(update, 1000);
93
+ return () => clearInterval(interval);
94
+ }, []);
95
+
96
+ return (
97
+ <div className="min-h-screen bg-[#050505] text-white selection:bg-white/20 font-mono flex flex-col items-center relative overflow-x-hidden max-w-full">
98
+
99
+ {/* --- CYBER BACKGROUND SYSTEM (STRICT BOUNDARIES) --- */}
100
+ <div className="fixed inset-0 pointer-events-none z-0 overflow-hidden">
101
+ {/* Tech Grid */}
102
+ <div className="absolute inset-0 opacity-[0.06]"
103
+ style={{
104
+ backgroundImage: "linear-gradient(#444 1px, transparent 1px), linear-gradient(90deg, #444 1px, transparent 1px)",
105
+ backgroundSize: "64px 64px"
106
+ }}
107
+ />
108
+
109
+ {/* Center Vignette */}
110
+ <div className="absolute inset-0"
111
+ style={{ background: "radial-gradient(circle at center, transparent 0%, #050505 90%)" }}
112
+ />
113
+
114
+ {/* Wandering Pulse (Clamped to prevent overflow) */}
115
+ <motion.div
116
+ animate={{
117
+ left: ["-5%", "70%", "-5%"],
118
+ top: ["10%", "60%", "10%"]
119
+ }}
120
+ transition={{ duration: 25, repeat: Infinity, ease: "linear" }}
121
+ className="absolute w-[500px] h-[500px] blur-[150px] opacity-[0.04] bg-emerald-500 rounded-full"
122
+ />
123
+ </div>
124
+
125
+ {/* --- NAVIGATION HUD --- */}
126
+ <header className="fixed top-0 inset-x-0 p-4 sm:p-6 lg:p-8 z-50 flex justify-between items-start pointer-events-none">
127
+ <div className="flex flex-col gap-3 pointer-events-auto">
128
+ <button
129
+ onClick={() => router.back()}
130
+ className="flex items-center gap-2.5 px-4 py-2 rounded-xl bg-white/5 backdrop-blur-2xl border border-white/10 text-white/50 hover:text-white hover:bg-white/10 transition-all group shadow-xl"
131
+ >
132
+ <ArrowLeft size={16} className="group-hover:-translate-x-1 transition-transform" />
133
+ <span className="uppercase tracking-[0.2em] text-[9px] font-black">Archive_Exit</span>
134
+ </button>
135
+
136
+ <div className="hidden md:flex items-center gap-3 text-[7px] uppercase font-black tracking-widest text-white/10 ml-1">
137
+ <div className="flex items-center gap-1.5"><Wifi size={9} /> LINK_UP</div>
138
+ <div className="flex items-center gap-1.5"><Terminal size={9} /> NODE_04</div>
139
+ </div>
140
+ </div>
141
+
142
+ <div className="flex flex-col items-end text-right pointer-events-auto">
143
+ <div className="flex items-center gap-2.5 text-white/70 font-black tabular-nums">
144
+ <span className="text-base sm:text-2xl tracking-tighter">{currentTime}</span>
145
+ <div className="w-[1px] h-4 sm:h-6 bg-white/10" />
146
+ <span className="text-[9px] uppercase tracking-[0.2em] text-emerald-500/50 font-bold hidden xs:inline">Feed_On</span>
147
+ </div>
148
+ <p className="text-[7px] uppercase tracking-widest text-white/10 font-black mt-1">SYS_REL_2.6</p>
149
+ </div>
150
+ </header>
151
+
152
+ {/* --- MAIN INTERFACE (SAFE ZONES) --- */}
153
+ <main className="relative z-10 w-full max-w-5xl flex flex-col items-center pt-28 sm:pt-40 pb-20 px-4 overflow-x-hidden">
154
+
155
+ {/* Tech Title */}
156
+ <motion.div
157
+ initial={{ opacity: 0, scale: 0.98 }}
158
+ animate={{ opacity: 1, scale: 1 }}
159
+ className="mb-14 sm:mb-24 text-center space-y-4"
160
+ >
161
+ <div className="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-emerald-500/5 border border-emerald-500/10 text-[8px] uppercase font-black text-emerald-500/60 tracking-[0.3em]">
162
+ <Binary size={10} className="animate-pulse" />
163
+ Accessing Identity_Grid
164
+ </div>
165
+ <h1 className="text-[42px] sm:text-6xl md:text-8xl font-black uppercase italic tracking-tighter leading-tight opacity-95">
166
+ Gaming <br className="sm:hidden" /> Profile
167
+ </h1>
168
+ </motion.div>
169
+
170
+ {/* Grid of Pods */}
171
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-8 md:gap-14 w-full place-items-center">
172
+ {GAMES.map((game, i) => (
173
+ <motion.div
174
+ key={game.id}
175
+ initial={{ opacity: 0, y: 20 }}
176
+ animate={{ opacity: 1, y: 0 }}
177
+ transition={{ delay: i * 0.1 }}
178
+ className="w-full flex justify-center"
179
+ >
180
+ <CombatPod onClick={() => setSelectedGame(game)} accent={game.accent}>
181
+ <div className="absolute inset-0 p-8 md:p-10 flex flex-col justify-between z-10">
182
+ <div className="flex justify-between items-start">
183
+ <div className="text-5xl font-black opacity-[0.03] text-white italic select-none">{game.unit}</div>
184
+ <div className="p-3.5 rounded-2xl bg-white/10 border border-white/5 group-hover:bg-white/20 transition-all">
185
+ <game.icon size={28} className="text-white/40 group-hover:text-white transition-all transform group-hover:scale-110" />
186
+ </div>
187
+ </div>
188
+
189
+ <div className="space-y-6">
190
+ <div className="space-y-1">
191
+ <div className="flex items-center gap-2">
192
+ <div className="w-4 h-[1px] bg-emerald-500/30" />
193
+ <span className="text-[9px] uppercase font-black text-white/30 tracking-[0.2em]">{game.fullname}</span>
194
+ </div>
195
+ <h2 className="text-5xl font-black uppercase italic tracking-tighter group-hover:translate-x-1 transition-transform">
196
+ {game.name}
197
+ </h2>
198
+ </div>
199
+
200
+ <div className="flex items-center justify-between pt-6 border-t border-white/5 group-hover:border-white/10 transition-colors">
201
+ <div className="flex flex-col">
202
+ <span className="text-[7px] uppercase font-black text-white/20 tracking-widest mb-0.5">Rec_Status</span>
203
+ <span className="text-[11px] font-black uppercase text-emerald-500/80 group-hover:text-emerald-400">Expand identity &rarr;</span>
204
+ </div>
205
+ <Cpu size={16} className="text-white/10" />
206
+ </div>
207
+ </div>
208
+ </div>
209
+ </CombatPod>
210
+ </motion.div>
211
+ ))}
212
+ </div>
213
+ </main>
214
+
215
+ {/* --- IDENTITY SHEET (MODAL) --- */}
216
+ <AnimatePresence>
217
+ {selectedGame && (
218
+ <motion.div
219
+ initial={{ opacity: 0 }}
220
+ animate={{ opacity: 1 }}
221
+ exit={{ opacity: 0 }}
222
+ onClick={() => setSelectedGame(null)}
223
+ className="fixed inset-0 z-[100] flex items-center justify-center bg-black/95 backdrop-blur-3xl p-4 sm:p-10"
224
+ >
225
+ <motion.div
226
+ initial={{ scale: 0.97, opacity: 0 }}
227
+ animate={{ scale: 1, opacity: 1 }}
228
+ exit={{ scale: 0.97, opacity: 0 }}
229
+ onClick={(e) => e.stopPropagation()}
230
+ className="w-full max-w-xl bg-[#0c0c0c] border border-white/10 rounded-[42px] sm:rounded-[64px] overflow-hidden flex flex-col relative p-10 sm:p-16 shadow-[0_0_150px_-30px_rgba(255,255,255,0.08)] max-h-[95vh] overflow-y-auto [&::-webkit-scrollbar]:hidden [scrollbar-width:none] [-ms-overflow-style:none]"
231
+ >
232
+ {/* HUD Corners */}
233
+ <div className="absolute top-8 left-8 w-5 h-5 border-t border-l border-white/10" />
234
+ <div className="absolute bottom-8 right-8 w-5 h-5 border-b border-r border-white/10" />
235
+ <Shield size={160} className="absolute -bottom-14 -right-14 text-white/[0.01] pointer-events-none" />
236
+
237
+ <div className="flex justify-between items-start mb-14">
238
+ <div className="space-y-2">
239
+ <div className="flex items-center gap-2.5 text-emerald-500 font-black text-[10px] tracking-[0.4em] uppercase">
240
+ <div className="w-2 h-2 rounded-full bg-emerald-500/20 flex items-center justify-center">
241
+ <div className="w-1 h-1 rounded-full bg-emerald-500 animate-pulse" />
242
+ </div>
243
+ Verified_Node_Access
244
+ </div>
245
+ <h3 className="text-5xl sm:text-7xl font-black uppercase italic tracking-tighter leading-none">{selectedGame.name}</h3>
246
+ </div>
247
+ <button
248
+ onClick={() => setSelectedGame(null)}
249
+ className="w-12 h-12 rounded-full bg-white/5 border border-white/10 flex items-center justify-center hover:bg-white/10 transition-all group shrink-0"
250
+ >
251
+ <X size={20} className="group-hover:rotate-90 transition-transform text-white/40 group-hover:text-white" />
252
+ </button>
253
+ </div>
254
+
255
+ <div className="space-y-12">
256
+ {/* Operative ID Section */}
257
+ <div className="space-y-3">
258
+ <p className="text-[10px] uppercase font-black text-white/20 tracking-[0.5em]">Identity_ID</p>
259
+ <div className="flex items-center gap-6">
260
+ <p className="text-5xl sm:text-7xl font-black tracking-tighter text-white/90">{selectedGame.ign}</p>
261
+ <div className="h-[1px] flex-1 bg-gradient-to-r from-emerald-500/40 to-transparent" />
262
+ </div>
263
+ </div>
264
+
265
+ {/* Combat Grid */}
266
+ <div className="grid grid-cols-2 gap-10 sm:gap-14 pt-12 border-t border-white/5">
267
+ <div className="space-y-3">
268
+ <p className="text-[10px] uppercase font-black text-white/20 tracking-[0.3em] flex items-center gap-2">
269
+ <Zap size={14} className="text-emerald-500/50" /> Performance
270
+ </p>
271
+ <div className="flex items-baseline gap-2">
272
+ <span className="text-5xl sm:text-6xl font-black tabular-nums">{selectedGame.kd}</span>
273
+ <span className="text-[10px] font-black text-white/30 uppercase tracking-[0.2em]">K/D</span>
274
+ </div>
275
+ </div>
276
+ <div className="space-y-3">
277
+ <p className="text-[10px] uppercase font-black text-white/20 tracking-[0.3em] flex items-center gap-2">
278
+ <Trophy size={14} className="text-emerald-500/50" /> Rank_Class
279
+ </p>
280
+ <p className="text-2xl sm:text-3xl font-black text-white/80 uppercase italic tracking-tight">{selectedGame.rank}</p>
281
+ </div>
282
+ </div>
283
+ </div>
284
+
285
+ {/* Footer HUD info */}
286
+ <div className="mt-16 pt-10 border-t border-white/5 flex justify-between items-center text-[10px] uppercase font-black tracking-[0.3em] text-white/5 select-none">
287
+ <span>SYSTEM_ID: 0x84_GAMING</span>
288
+ <span className="text-emerald-500/20">Archive.04</span>
289
+ </div>
290
+ </motion.div>
291
+ </motion.div>
292
+ )}
293
+ </AnimatePresence>
294
+
295
+ {/* --- BOTTOM HUD TICKER (DESKTOP) --- */}
296
+ <footer className="fixed bottom-0 inset-x-0 p-8 z-40 hidden lg:flex justify-between items-center pointer-events-none opacity-20">
297
+ <div className="text-[9px] uppercase font-black tracking-[0.6em] text-white/30">
298
+ SVR_G_PROTOCOL_V6
299
+ </div>
300
+ <div className="flex gap-10 text-[8px] uppercase font-black tracking-[0.3em] text-white/20">
301
+ <span className="flex items-center gap-2"><Cpu size={10} /> UNIT_SYNC_DONE</span>
302
+ <span className="flex items-center gap-2"><Binary size={10} /> DECRYPT_PASSED</span>
303
+ </div>
304
+ </footer>
305
+
306
+ </div>
307
+ );
308
+ }
@@ -0,0 +1,97 @@
1
+ import { getGitHubProfile, getGitHubReadme, getGitHubAchievements } from "@/lib/github";
2
+ import { GitHubProfileHeader } from "@/components/github/profile-header";
3
+ import { RepoCard } from "@/components/github/repo-card";
4
+ import { ReadmeViewer } from "@/components/github/readme-viewer";
5
+ import { ContributionGraph } from "@/components/github/contribution-graph";
6
+ import Link from "next/link";
7
+ import { ArrowLeft } from "lucide-react";
8
+ import { Metadata } from "next";
9
+
10
+ export async function generateMetadata({ params }: { params: Promise<{ username: string }> }): Promise<Metadata> {
11
+ const { username } = await params;
12
+ return {
13
+ title: `${username} - GitHub Profile`,
14
+ description: `View ${username}'s open source contributions and projects.`,
15
+ };
16
+ }
17
+
18
+ export default async function GitHubPage({ params }: { params: Promise<{ username: string }> }) {
19
+ const { username } = await params;
20
+
21
+ // Parallel Fetching for Speed
22
+ const [profile, readme, achievements] = await Promise.all([
23
+ getGitHubProfile(username),
24
+ getGitHubReadme(username),
25
+ getGitHubAchievements(username)
26
+ ]);
27
+
28
+ if (!profile) {
29
+ return (
30
+ <div className="min-h-screen bg-[#050805] text-white flex flex-col items-center justify-center p-4">
31
+ <h1 className="text-4xl font-bold mb-4">User Not Found</h1>
32
+ <p className="text-white/50 mb-8 max-w-md text-center">
33
+ Could not fetch data for "{username}". This might happen if the GitHub API Token is missing or the user does not exist.
34
+ </p>
35
+ <Link href="/" className="px-6 py-3 bg-white text-black rounded-full font-medium hover:scale-105 transition-transform">
36
+ Go Home
37
+ </Link>
38
+ </div>
39
+ );
40
+ }
41
+
42
+ return (
43
+ <main className="min-h-screen bg-[#050805] text-white selection:bg-blue-500/30">
44
+
45
+ {/* Navbar Placeholder / Back Button */}
46
+ <nav className="fixed top-0 left-0 right-0 z-50 p-6 flex justify-between items-center bg-gradient-to-b from-[#050805] to-transparent pointer-events-none">
47
+ <Link href="/" className="pointer-events-auto flex items-center gap-2 text-white/60 hover:text-white transition-colors bg-black/20 backdrop-blur-md px-4 py-2 rounded-full border border-white/5">
48
+ <ArrowLeft className="w-4 h-4" />
49
+ <span className="text-sm font-medium">Back to Portfolio</span>
50
+ </Link>
51
+ </nav>
52
+
53
+ <div className="max-w-[1400px] mx-auto px-6 py-20">
54
+ <div className="grid grid-cols-1 lg:grid-cols-12 gap-12">
55
+
56
+ {/* Sidebar (Left Column) */}
57
+ <aside className="lg:col-span-3 lg:static top-24 h-fit">
58
+ <GitHubProfileHeader profile={profile} achievements={achievements} />
59
+ </aside>
60
+
61
+ {/* Main Content (Right Column) */}
62
+ <div className="lg:col-span-9 flex flex-col gap-8">
63
+
64
+ {/* 1. README */}
65
+ {readme && (
66
+ <section className="w-full">
67
+ <ReadmeViewer content={readme} />
68
+ </section>
69
+ )}
70
+
71
+ {/* 2. Pinned Repos */}
72
+ <section>
73
+ <h2 className="text-base font-semibold text-white mb-4">Pinned</h2>
74
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
75
+ {profile.pinnedItems.nodes.length > 0 ? (
76
+ profile.pinnedItems.nodes.map((repo, idx) => (
77
+ <RepoCard key={repo.name} repo={repo} index={idx} />
78
+ ))
79
+ ) : (
80
+ <p className="text-white/40 col-span-full text-sm">No pinned repositories found.</p>
81
+ )}
82
+ </div>
83
+ </section>
84
+
85
+ {/* 3. Contribution Graph */}
86
+ <section>
87
+ <h2 className="text-base font-semibold text-white mb-4">Contributions</h2>
88
+ <div className="w-full overflow-hidden">
89
+ <ContributionGraph profile={profile} />
90
+ </div>
91
+ </section>
92
+ </div>
93
+ </div>
94
+ </div>
95
+ </main>
96
+ );
97
+ }