redesign: Hacker theme for security researcher portfolio

- Complete visual overhaul with cyberpunk/terminal aesthetic
- Dark theme with matrix green (#00ff41), cyan, magenta accents
- Terminal-styled sections with command prompts
- Sharp angular design (removed all rounded corners)
- Added glowing borders, scanline effects, animations
- New SVG favicon with terminal prompt icon
- Added framer-motion page transitions for smooth theme switching
- "Enter my zen world" section for calm pastel pages
- Updated metadata/SEO for security researcher branding
- Social links: GitHub, LinkedIn, X, Email

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
neutrino2211
2026-01-16 19:25:16 +01:00
parent 6835ccf1cc
commit fae5636f6b
8 changed files with 964 additions and 344 deletions

View File

@@ -13,6 +13,7 @@
"@mdx-js/react": "^3.1.1",
"@next/mdx": "^16.1.1",
"@types/mdx": "^2.0.13",
"framer-motion": "^12.26.2",
"gray-matter": "^4.0.3",
"next": "16.1.1",
"react": "19.2.3",

38
pnpm-lock.yaml generated
View File

@@ -20,6 +20,9 @@ importers:
'@types/mdx':
specifier: ^2.0.13
version: 2.0.13
framer-motion:
specifier: ^12.26.2
version: 12.26.2(react-dom@19.1.0(react@19.2.3))(react@19.2.3)
gray-matter:
specifier: ^4.0.3
version: 4.0.3
@@ -1165,6 +1168,20 @@ packages:
resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==}
engines: {node: '>= 0.4'}
framer-motion@12.26.2:
resolution: {integrity: sha512-lflOQEdjquUi9sCg5Y1LrsZDlsjrHw7m0T9Yedvnk7Bnhqfkc89/Uha10J3CFhkL+TCZVCRw9eUGyM/lyYhXQA==}
peerDependencies:
'@emotion/is-prop-valid': '*'
react: ^18.0.0 || ^19.0.0
react-dom: ^18.0.0 || ^19.0.0
peerDependenciesMeta:
'@emotion/is-prop-valid':
optional: true
react:
optional: true
react-dom:
optional: true
function-bind@1.1.2:
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
@@ -1690,6 +1707,12 @@ packages:
minimist@1.2.8:
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
motion-dom@12.26.2:
resolution: {integrity: sha512-KLMT1BroY8oKNeliA3JMNJ+nbCIsTKg6hJpDb4jtRAJ7nCKnnpg/LTq/NGqG90Limitz3kdAnAVXecdFVGlWTw==}
motion-utils@12.24.10:
resolution: {integrity: sha512-x5TFgkCIP4pPsRLpKoI86jv/q8t8FQOiM/0E8QKBzfMozWHfkKap2gA1hOki+B5g3IsBNpxbUnfOum1+dgvYww==}
ms@2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
@@ -3416,6 +3439,15 @@ snapshots:
dependencies:
is-callable: 1.2.7
framer-motion@12.26.2(react-dom@19.1.0(react@19.2.3))(react@19.2.3):
dependencies:
motion-dom: 12.26.2
motion-utils: 12.24.10
tslib: 2.8.1
optionalDependencies:
react: 19.2.3
react-dom: 19.1.0(react@19.2.3)
function-bind@1.1.2: {}
function.prototype.name@1.1.8:
@@ -4151,6 +4183,12 @@ snapshots:
minimist@1.2.8: {}
motion-dom@12.26.2:
dependencies:
motion-utils: 12.24.10
motion-utils@12.24.10: {}
ms@2.1.3: {}
nanoid@3.3.11: {}

4
public/icon.svg Normal file
View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="none">
<rect width="32" height="32" fill="#0a0a0a"/>
<text x="4" y="22" font-family="monospace" font-size="18" font-weight="bold" fill="#00ff41">&gt;_</text>
</svg>

After

Width:  |  Height:  |  Size: 235 B

View File

@@ -1,32 +1,38 @@
@import "tailwindcss";
:root {
/* Neo-brutalist muted color palette */
--background: #FAF8F5;
--foreground: #3D3D3D;
--card-bg: #FEFDFB;
--border-color: #3D3D3D;
/* Hacker/Cyberpunk color palette */
--background: #0a0a0a;
--background-secondary: #111111;
--foreground: #00ff41;
--foreground-dim: #00cc33;
--foreground-muted: #008f11;
/* Muted accent colors */
--sage: #B8C5B3;
--sage-light: #CBD6C8;
--sage-dark: #A8B5A0;
--card-bg: #0d0d0d;
--card-bg-hover: #141414;
--border-color: #00ff41;
--border-dim: #00cc33;
--terracotta: #D4B5A0;
--terracotta-light: #E0C9B8;
--terracotta-dark: #C9A88E;
/* Accent colors */
--cyan: #00d4ff;
--cyan-dim: #00a8cc;
--magenta: #ff00ff;
--magenta-dim: #cc00cc;
--yellow: #ffff00;
--yellow-dim: #cccc00;
--red: #ff3333;
--red-dim: #cc2929;
--orange: #ff6600;
--blue-grey: #A5B4BE;
--blue-grey-light: #B8C5CE;
--blue-grey-dark: #9BAAB5;
/* Terminal colors */
--terminal-green: #00ff41;
--terminal-amber: #ffb000;
--terminal-blue: #0080ff;
--rose: #D4B5B8;
--rose-light: #E0C9CC;
--rose-dark: #C9A8AB;
--sand: #E8DCC8;
--sand-light: #F0E8D8;
--sand-dark: #DDD0BB;
/* Glow effects */
--glow-green: 0 0 10px #00ff41, 0 0 20px #00ff4180, 0 0 30px #00ff4140;
--glow-cyan: 0 0 10px #00d4ff, 0 0 20px #00d4ff80;
--glow-magenta: 0 0 10px #ff00ff, 0 0 20px #ff00ff80;
}
@theme inline {
@@ -36,54 +42,333 @@
--font-mono: var(--font-geist-mono);
}
@media (prefers-color-scheme: dark) {
/* No light mode - always dark for hacker aesthetic */
@media (prefers-color-scheme: light) {
:root {
--background: #1A1A1A;
--foreground: #E8E3D8;
--card-bg: #242424;
--border-color: #4D4D4D;
--sage: #8A9985;
--sage-light: #9BAA96;
--sage-dark: #7A8975;
--terracotta: #A38E7D;
--terracotta-light: #B29E8D;
--terracotta-dark: #937E6D;
--blue-grey: #7D8C95;
--blue-grey-light: #8D9CA5;
--blue-grey-dark: #6D7C85;
--rose: #A38E91;
--rose-light: #B39EA1;
--rose-dark: #937E81;
--sand: #B8AC98;
--sand-light: #C8BCA8;
--sand-dark: #A89C88;
--background: #0a0a0a;
--foreground: #00ff41;
}
}
body {
background: var(--background);
color: var(--foreground);
font-family: Arial, Helvetica, sans-serif;
font-family: 'Courier New', Courier, monospace;
transition: background-color 0.4s ease, color 0.4s ease;
}
/* Neo-brutalist shadow utilities */
.shadow-neo-brutal {
box-shadow: 5px 5px 0px var(--border-color);
/* Scanline effect overlay */
.scanlines::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: repeating-linear-gradient(
0deg,
rgba(0, 0, 0, 0.15),
rgba(0, 0, 0, 0.15) 1px,
transparent 1px,
transparent 2px
);
pointer-events: none;
z-index: 100;
}
.shadow-neo-brutal-hover {
box-shadow: 7px 7px 0px var(--border-color);
/* CRT screen flicker */
@keyframes flicker {
0% { opacity: 0.97; }
5% { opacity: 0.95; }
10% { opacity: 0.97; }
15% { opacity: 0.94; }
20% { opacity: 0.98; }
50% { opacity: 0.96; }
80% { opacity: 0.97; }
90% { opacity: 0.94; }
100% { opacity: 0.98; }
}
.shadow-brutal {
box-shadow: 5px 5px 0px var(--border-color);
.crt-flicker {
animation: flicker 0.15s infinite;
}
.shadow-brutal-hover {
box-shadow: 7px 7px 0px var(--border-color);
/* Typing cursor animation */
@keyframes blink {
0%, 50% { opacity: 1; }
51%, 100% { opacity: 0; }
}
.cursor-blink::after {
content: "_";
animation: blink 1s infinite;
}
/* Glitch effect */
@keyframes glitch {
0% {
transform: translate(0);
}
20% {
transform: translate(-2px, 2px);
}
40% {
transform: translate(-2px, -2px);
}
60% {
transform: translate(2px, 2px);
}
80% {
transform: translate(2px, -2px);
}
100% {
transform: translate(0);
}
}
.glitch:hover {
animation: glitch 0.3s ease-in-out;
}
/* Text glitch effect */
@keyframes textGlitch {
0% {
text-shadow: 2px 0 #ff00ff, -2px 0 #00ffff;
}
25% {
text-shadow: -2px 0 #ff00ff, 2px 0 #00ffff;
}
50% {
text-shadow: 2px 0 #ff00ff, -2px 0 #00ffff;
}
75% {
text-shadow: -2px 0 #ff00ff, 2px 0 #00ffff;
}
100% {
text-shadow: 2px 0 #ff00ff, -2px 0 #00ffff;
}
}
.text-glitch:hover {
animation: textGlitch 0.2s ease-in-out infinite;
}
/* Matrix rain background */
@keyframes matrix-rain {
0% {
background-position: 0% 0%;
}
100% {
background-position: 0% 100%;
}
}
/* Neon glow effects */
.glow-green {
text-shadow: var(--glow-green);
}
.glow-cyan {
text-shadow: var(--glow-cyan);
}
.glow-magenta {
text-shadow: var(--glow-magenta);
}
.box-glow-green {
box-shadow: 0 0 5px #00ff41, 0 0 10px #00ff4180, inset 0 0 5px #00ff4120;
}
.box-glow-cyan {
box-shadow: 0 0 5px #00d4ff, 0 0 10px #00d4ff80, inset 0 0 5px #00d4ff20;
}
.box-glow-magenta {
box-shadow: 0 0 5px #ff00ff, 0 0 10px #ff00ff80, inset 0 0 5px #ff00ff20;
}
/* Terminal window styling */
.terminal-window {
background: linear-gradient(180deg, #1a1a1a 0%, #0d0d0d 100%);
border: 1px solid #00ff41;
box-shadow: 0 0 10px #00ff4140, inset 0 0 50px #00ff4108;
}
.terminal-header {
background: linear-gradient(90deg, #1a1a1a, #0d0d0d);
border-bottom: 1px solid #00ff4180;
}
/* Typing animation */
@keyframes typing {
from { width: 0; }
to { width: 100%; }
}
.typing-effect {
overflow: hidden;
white-space: nowrap;
animation: typing 2s steps(30, end);
}
/* Pulse animation for active elements */
@keyframes pulse-green {
0%, 100% {
box-shadow: 0 0 5px #00ff41;
}
50% {
box-shadow: 0 0 20px #00ff41, 0 0 30px #00ff4180;
}
}
.pulse-glow {
animation: pulse-green 2s ease-in-out infinite;
}
/* Code highlight style */
.code-block {
background: #0d0d0d;
border-left: 3px solid #00ff41;
font-family: 'Courier New', monospace;
}
/* Hacker button style */
.hacker-btn {
background: transparent;
border: 1px solid #00ff41;
color: #00ff41;
position: relative;
overflow: hidden;
transition: all 0.3s ease;
}
.hacker-btn::before {
content: "";
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, #00ff4120, transparent);
transition: left 0.5s ease;
}
.hacker-btn:hover::before {
left: 100%;
}
.hacker-btn:hover {
background: #00ff4115;
box-shadow: 0 0 10px #00ff4180, inset 0 0 10px #00ff4120;
}
/* Zen button - simple transition without hardcoded colors */
.zen-btn {
background: transparent;
transition: all 0.3s ease;
}
/* Link styling */
.hacker-link {
color: #00d4ff;
text-decoration: none;
position: relative;
}
.hacker-link::after {
content: "";
position: absolute;
bottom: -2px;
left: 0;
width: 0;
height: 1px;
background: #00d4ff;
transition: width 0.3s ease;
}
.hacker-link:hover::after {
width: 100%;
}
.hacker-link:hover {
text-shadow: 0 0 10px #00d4ff80;
}
/* Selection styling */
::selection {
background: #00ff41;
color: #0a0a0a;
}
/* Scrollbar styling */
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-track {
background: #0a0a0a;
}
::-webkit-scrollbar-thumb {
background: #00ff4180;
}
::-webkit-scrollbar-thumb:hover {
background: #00ff41;
}
/* Card hover effects */
.hacker-card {
background: #0d0d0d;
border: 1px solid #00ff4140;
transition: all 0.3s ease;
}
.hacker-card:hover {
border-color: #00ff41;
box-shadow: 0 0 20px #00ff4130, inset 0 0 20px #00ff4108;
}
/* Status indicator */
.status-online {
width: 8px;
height: 8px;
background: #00ff41;
box-shadow: 0 0 10px #00ff41;
animation: pulse-green 2s ease-in-out infinite;
}
/* ASCII art styling */
.ascii-art {
font-family: 'Courier New', monospace;
white-space: pre;
line-height: 1.2;
font-size: 10px;
color: #00ff4180;
}
/* Grid overlay effect */
.grid-overlay {
background-image:
linear-gradient(rgba(0, 255, 65, 0.03) 1px, transparent 1px),
linear-gradient(90deg, rgba(0, 255, 65, 0.03) 1px, transparent 1px);
background-size: 20px 20px;
}
/* Fade in animation */
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.fade-in {
animation: fadeIn 0.5s ease-out forwards;
}
.fade-in-delay-1 { animation-delay: 0.1s; opacity: 0; }
.fade-in-delay-2 { animation-delay: 0.2s; opacity: 0; }
.fade-in-delay-3 { animation-delay: 0.3s; opacity: 0; }
.fade-in-delay-4 { animation-delay: 0.4s; opacity: 0; }
.fade-in-delay-5 { animation-delay: 0.5s; opacity: 0; }

View File

@@ -15,29 +15,35 @@ const geistMono = Geist_Mono({
export const metadata: Metadata = {
metadataBase: new URL("https://mainasara.dev"),
title: {
default: "Mainasara Tsowa - Developer & Cybersecurity Expert",
default: "Mainasara Tsowa | Security Researcher & Full-Stack Developer",
template: "%s | Mainasara Tsowa",
},
description:
"Passionate developer and cybersecurity expert building secure, elegant digital solutions. Explore projects, creative writing, and technical insights.",
"Security researcher and full-stack developer specializing in penetration testing, OSINT frameworks, vulnerability research, and building secure applications with Next.js. Open for security consulting and development projects.",
keywords: [
"developer",
"security researcher",
"penetration testing",
"pentest",
"cybersecurity",
"full-stack",
"web development",
"security",
"programming",
"digital art",
"creative writing",
"OSINT",
"vulnerability research",
"Next.js developer",
"full-stack developer",
"security tooling",
"web security",
"application security",
"security consulting",
"React developer",
"TypeScript",
],
authors: [{ name: "Mainasara Tsowa" }],
authors: [{ name: "Mainasara Tsowa", url: "https://mainasara.dev" }],
creator: "Mainasara Tsowa",
publisher: "Mainasara Tsowa",
robots: "index, follow",
openGraph: {
title: "Mainasara Tsowa - Developer & Cybersecurity Expert",
title: "Mainasara Tsowa | Security Researcher & Full-Stack Developer",
description:
"Passionate developer and cybersecurity expert building secure, elegant digital solutions.",
"Security researcher specializing in offensive security, OSINT frameworks, and building secure applications with Next.js.",
url: "https://mainasara.dev",
siteName: "Mainasara Tsowa",
locale: "en_US",
@@ -47,15 +53,15 @@ export const metadata: Metadata = {
url: "/media/me/me.jpeg",
width: 800,
height: 800,
alt: "Mainasara Tsowa",
alt: "Mainasara Tsowa - Security Researcher",
},
],
},
twitter: {
card: "summary_large_image",
title: "Mainasara Tsowa - Developer & Cybersecurity Expert",
title: "Mainasara Tsowa | Security Researcher & Full-Stack Developer",
description:
"Passionate developer and cybersecurity expert building secure, elegant digital solutions.",
"Security researcher specializing in offensive security, OSINT frameworks, and secure application development.",
images: ["/media/me/me.jpeg"],
creator: "@neutrino2211",
},
@@ -63,8 +69,8 @@ export const metadata: Metadata = {
canonical: "https://mainasara.dev",
},
icons: {
icon: [{ url: "/favicon.ico" }, { url: "/icon.png", type: "image/png" }],
apple: [{ url: "/apple-icon.png" }],
icon: [{ url: "/icon.svg", type: "image/svg+xml" }],
apple: [{ url: "/icon.svg" }],
},
manifest: "/manifest.json",
verification: {
@@ -83,9 +89,9 @@ export default function RootLayout({
children: React.ReactNode;
}>) {
return (
<html lang="en" suppressHydrationWarning>
<html lang="en" suppressHydrationWarning className="dark">
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
className={`${geistSans.variable} ${geistMono.variable} antialiased bg-[#0a0a0a]`}
>
{children}
</body>

View File

@@ -6,228 +6,416 @@ import Link from "next/link";
export const metadata: Metadata = {
title: "Home",
description:
"Welcome to my personal portfolio. I'm Mainasara Tsowa, a developer and cybersecurity expert passionate about building secure, elegant digital solutions.",
"Security Researcher & Full-Stack Developer with expertise in penetration testing, security tooling, and building secure applications with Next.js.",
openGraph: {
title: "Home | Mainasara Tsowa",
title: "Mainasara Tsowa | Security Researcher",
description:
"Welcome to my personal portfolio. Developer and cybersecurity expert building secure, elegant digital solutions.",
"Security Researcher & Full-Stack Developer specializing in offensive security, OSINT, and secure application development.",
url: "https://mainasara.dev",
},
twitter: {
title: "Home | Mainasara Tsowa",
title: "Mainasara Tsowa | Security Researcher",
description:
"Welcome to my personal portfolio. Developer and cybersecurity expert building secure, elegant digital solutions.",
"Security Researcher & Full-Stack Developer specializing in offensive security, OSINT, and secure application development.",
},
};
export default function Home() {
return (
<div className="min-h-screen bg-[#FAF8F5] font-mono">
<div className="max-w-4xl mx-auto px-6 py-12">
<header className="text-center mb-16">
<div className="mb-8">
<div className="w-32 h-32 mx-auto bg-[#3D3D3D] rounded-full flex items-center justify-center border-[3px] border-[#B8C5B3]">
<div className="min-h-screen bg-[#0a0a0a] font-mono relative grid-overlay">
{/* Scanline overlay */}
<div className="fixed inset-0 pointer-events-none z-50 opacity-30">
<div className="w-full h-full bg-[repeating-linear-gradient(0deg,transparent,transparent_2px,rgba(0,0,0,0.3)_2px,rgba(0,0,0,0.3)_4px)]" />
</div>
<div className="max-w-5xl mx-auto px-6 py-8 relative z-10">
{/* Header */}
<header className="mb-12">
<div className="flex flex-col md:flex-row items-center gap-8 mb-8">
{/* Profile Image - Clean, no terminal effect */}
<div className="relative">
<div className="w-36 h-36 overflow-hidden border-2 border-[#00ff41] box-glow-green">
<Image
src="/media/me/me.jpeg"
alt="Mainasara Tsowa"
className="rounded-full"
width={128}
height={128}
className="w-full h-full object-cover"
width={144}
height={144}
/>
</div>
<div className="absolute -bottom-2 -right-2 status-online" />
</div>
<h1 className="text-4xl md:text-5xl font-bold text-[#3D3D3D] mb-4 uppercase tracking-wide">
Mainasara Tsowa
{/* Info */}
<div className="text-center md:text-left flex-1">
<div className="text-[#00ff4180] text-sm mb-2">
$ whoami
</div>
<h1 className="text-3xl md:text-4xl font-bold text-[#00ff41] glow-green mb-2 text-glitch">
MAINASARA TSOWA
</h1>
<p className="text-lg text-[#5D5D5D] max-w-2xl mx-auto leading-relaxed font-semibold">
Developer & Cybersecurity Expert working on secure, elegant digital
solutions
<div className="text-[#00d4ff] text-lg mb-4">
<span className="text-[#ff00ff]">&gt;</span> Security Researcher{" "}
<span className="text-[#00ff4160]">|</span> Full-Stack Developer
</div>
<p className="text-[#00ff4180] max-w-lg leading-relaxed text-sm">
<span className="text-[#00d4ff]">/*</span> Building secure systems and breaking insecure ones.
Specialized in offensive security, OSINT frameworks, and Next.js applications.{" "}
<span className="text-[#00d4ff]">*/</span>
</p>
</div>
</div>
{/* Quick Stats */}
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
<div className="hacker-card p-4 text-center">
<div className="text-[#00d4ff] text-2xl font-bold">5+</div>
<div className="text-[#00ff4160] text-xs uppercase">Years Exp</div>
</div>
<div className="hacker-card p-4 text-center">
<div className="text-[#ff00ff] text-2xl font-bold">Next.js</div>
<div className="text-[#00ff4160] text-xs uppercase">Specialist</div>
</div>
<div className="hacker-card p-4 text-center">
<div className="text-[#ffff00] text-2xl font-bold">OSINT</div>
<div className="text-[#00ff4160] text-xs uppercase">Tools</div>
</div>
<div className="hacker-card p-4 text-center">
<div className="text-[#00ff41] text-2xl font-bold">Pentest</div>
<div className="text-[#00ff4160] text-xs uppercase">Security</div>
</div>
</div>
</header>
<nav className="mb-16">
<div className="bg-[#FEFDFB] border-[3px] border-[#3D3D3D] rounded-md p-6 shadow-brutal">
<ul className="flex flex-wrap justify-center gap-4 md:gap-8">
{/*<li>
{/* Social Links Bar */}
<nav className="mb-12 fade-in fade-in-delay-1">
<div className="flex flex-wrap justify-center gap-4">
<a
href="https://blog.mainasara.dev"
className="text-[#3D3D3D] font-bold hover:bg-[#E8DCC8] px-4 py-2 transition-colors border-2 border-[#3D3D3D] hover:border-[#5D5D5D] rounded-sm"
href="https://github.com/neutrino2211"
target="_blank"
rel="noopener noreferrer"
className="hacker-btn px-6 py-3 flex items-center gap-2 text-sm"
>
Blog
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
<path
fillRule="evenodd"
d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z"
clipRule="evenodd"
/>
</svg>
GitHub
</a>
</li>*/}
<a
href="https://www.linkedin.com/in/mainasara-tsowa-17098b214/"
target="_blank"
rel="noopener noreferrer"
className="hacker-btn px-6 py-3 flex items-center gap-2 text-sm"
>
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
<path d="M19 0h-14c-2.761 0-5 2.239-5 5v14c0 2.761 2.239 5 5 5h14c2.762 0 5-2.239 5-5v-14c0-2.761-2.238-5-5-5zm-11 19h-3v-11h3v11zm-1.5-12.268c-.966 0-1.75-.79-1.75-1.764s.784-1.764 1.75-1.764 1.75.79 1.75 1.764-.783 1.764-1.75 1.764zm13.5 12.268h-3v-5.604c0-3.368-4-3.113-4 0v5.604h-3v-11h3v1.765c1.396-2.586 7-2.777 7 2.476v6.759z" />
</svg>
LinkedIn
</a>
<a
href="https://x.com/neutrino2211"
target="_blank"
rel="noopener noreferrer"
className="hacker-btn px-6 py-3 flex items-center gap-2 text-sm"
>
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
<path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" />
</svg>
@neutrino2211
</a>
<a
href="mailto:tsowamainasara@gmail.com"
className="hacker-btn px-6 py-3 flex items-center gap-2 text-sm border-[#00d4ff] text-[#00d4ff] hover:bg-[#00d4ff15]"
>
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
</svg>
Contact
</a>
</div>
</nav>
{/* Navigation - Zen World */}
<nav className="mb-12 fade-in fade-in-delay-2">
<div className="terminal-window p-4">
<div className="text-[#00ff4180] text-xs mb-1">$ cd ~/zen/</div>
<div className="text-[#00ff41cc] text-sm mb-4 text-center">
<span className="text-[#00d4ff]">//</span> Enter my zen world <span className="text-[#00d4ff]">//</span>
</div>
<ul className="flex flex-wrap justify-center gap-3">
<li>
<Link
href="/digital-art"
className="text-[#3D3D3D] font-bold hover:bg-[#E0C9CC] px-4 py-2 transition-colors border-2 border-[#3D3D3D] hover:border-[#5D5D5D] rounded-sm"
className="zen-btn px-4 py-2 text-sm border border-[#ff00ff] text-[#ff00ff] hover:bg-[#ff00ff20] hover:shadow-[0_0_15px_#ff00ff40]"
>
Digital Art
digital-art
</Link>
</li>
<li>
<Link
href="/stories"
className="text-[#3D3D3D] font-bold hover:bg-[#F0E8D8] px-4 py-2 transition-colors border-2 border-[#3D3D3D] hover:border-[#5D5D5D] rounded-sm"
className="zen-btn px-4 py-2 text-sm border border-[#ffff00] text-[#ffff00] hover:bg-[#ffff0020] hover:shadow-[0_0_15px_#ffff0040]"
>
Mini Stories
stories
</Link>
</li>
<li>
<Link
href="/thoughts"
className="text-[#3D3D3D] font-bold hover:bg-[#CBD6C8] px-4 py-2 transition-colors border-2 border-[#3D3D3D] hover:border-[#5D5D5D] rounded-sm"
className="zen-btn px-4 py-2 text-sm border border-[#00d4ff] text-[#00d4ff] hover:bg-[#00d4ff20] hover:shadow-[0_0_15px_#00d4ff40]"
>
Thoughts
thoughts
</Link>
</li>
</ul>
</div>
</nav>
<main className="space-y-16">
<section
id="about"
className="bg-[#FEFDFB] border-[3px] border-[#3D3D3D] rounded-md p-8 shadow-brutal"
>
<h2 className="text-2xl font-bold text-[#3D3D3D] mb-6 text-center uppercase">
About
</h2>
<p className="text-[#5D5D5D] leading-relaxed text-center max-w-3xl mx-auto font-semibold">
I&apos;m a passionate developer and cybersecurity expert who
believes in building beautiful, secure, and purposeful digital
solutions. When I&apos;m not coding or exploring security tooling,
you&apos;ll probably find me trying my hands at some creative
projects.
<main className="space-y-12">
{/* About Section */}
<section className="fade-in fade-in-delay-3">
<div className="terminal-window overflow-hidden">
<div className="terminal-header px-4 py-2 flex items-center gap-2">
<span className="text-[#00ff41] text-sm opacity-60">about.sh</span>
</div>
<div className="p-6">
<div className="text-[#00ff4160] text-sm mb-4">
$ cat /home/mainasara/about.txt
</div>
<div className="space-y-4 text-[#00ff41cc]">
<p className="leading-relaxed">
<span className="text-[#00d4ff]">[*]</span> Security researcher with a passion for
breaking things to understand how they work. I build tools that help security
professionals work more efficiently.
</p>
<p className="leading-relaxed">
<span className="text-[#ff00ff]">[*]</span> Full-stack developer specializing in
Next.js and React ecosystems. I believe secure code is the foundation of
every great application.
</p>
<p className="leading-relaxed">
<span className="text-[#ffff00]">[*]</span> When not hunting vulnerabilities or
writing code, I explore creative outlets through digital art and fiction writing.
</p>
</div>
</div>
</div>
</section>
<section
id="expertise"
className="bg-[#FEFDFB] border-[3px] border-[#3D3D3D] rounded-md p-8 shadow-brutal"
>
<h2 className="text-2xl font-bold text-[#3D3D3D] mb-6 text-center uppercase">
Expertise
</h2>
{/* Skills Section */}
<section className="fade-in fade-in-delay-4">
<div className="terminal-window overflow-hidden">
<div className="terminal-header px-4 py-2 flex items-center gap-2">
<span className="text-[#00ff41] text-sm opacity-60">skills.json</span>
</div>
<div className="p-6">
<div className="text-[#00ff4160] text-sm mb-4">
$ cat /etc/skills.json | jq
</div>
<div className="grid md:grid-cols-2 gap-6">
<div className="bg-[#CBD6C8] border-2 border-[#3D3D3D] rounded-sm p-6">
<h3 className="text-lg font-bold text-[#3D3D3D] mb-3 uppercase">
Development
{/* Security Skills */}
<div className="hacker-card p-5">
<h3 className="text-[#ff3333] font-bold mb-4 flex items-center gap-2">
<span className="text-lg">{"{"}</span>
<span>&quot;security&quot;</span>
<span className="text-lg">:</span>
</h3>
<ul className="space-y-2 text-[#5D5D5D]">
<li className="flex items-center">
<span className="w-3 h-3 bg-[#3D3D3D] rounded-full mr-3"></span>
Full-Stack Applications
<ul className="space-y-2 text-sm ml-4">
<li className="flex items-center gap-2">
<span className="text-[#00d4ff]">&quot;</span>
<span className="text-[#00ff41cc]">Penetration Testing</span>
<span className="text-[#00d4ff]">&quot;</span>
<span className="text-[#00ff4160]">,</span>
</li>
<li className="flex items-center">
<span className="w-3 h-3 bg-[#3D3D3D] rounded-full mr-3"></span>
Clean Architecture
<li className="flex items-center gap-2">
<span className="text-[#00d4ff]">&quot;</span>
<span className="text-[#00ff41cc]">OSINT & Reconnaissance</span>
<span className="text-[#00d4ff]">&quot;</span>
<span className="text-[#00ff4160]">,</span>
</li>
<li className="flex items-center">
<span className="w-3 h-3 bg-[#3D3D3D] rounded-full mr-3"></span>
Performance Optimization
<li className="flex items-center gap-2">
<span className="text-[#00d4ff]">&quot;</span>
<span className="text-[#00ff41cc]">Security Architecture</span>
<span className="text-[#00d4ff]">&quot;</span>
<span className="text-[#00ff4160]">,</span>
</li>
<li className="flex items-center gap-2">
<span className="text-[#00d4ff]">&quot;</span>
<span className="text-[#00ff41cc]">Vulnerability Research</span>
<span className="text-[#00d4ff]">&quot;</span>
<span className="text-[#00ff4160]">,</span>
</li>
<li className="flex items-center gap-2">
<span className="text-[#00d4ff]">&quot;</span>
<span className="text-[#00ff41cc]">Security Tooling</span>
<span className="text-[#00d4ff]">&quot;</span>
</li>
</ul>
<div className="text-[#ff3333] font-bold mt-2">{"}"}</div>
</div>
<div className="bg-[#B8C5CE] border-2 border-[#3D3D3D] rounded-sm p-6">
<h3 className="text-lg font-bold text-[#3D3D3D] mb-3 uppercase">
Cybersecurity
{/* Development Skills */}
<div className="hacker-card p-5">
<h3 className="text-[#00d4ff] font-bold mb-4 flex items-center gap-2">
<span className="text-lg">{"{"}</span>
<span>&quot;development&quot;</span>
<span className="text-lg">:</span>
</h3>
<ul className="space-y-2 text-[#5D5D5D]">
<li className="flex items-center">
<span className="w-3 h-3 bg-[#3D3D3D] rounded-full mr-3"></span>
Security Tooling
<ul className="space-y-2 text-sm ml-4">
<li className="flex items-center gap-2">
<span className="text-[#ff00ff]">&quot;</span>
<span className="text-[#00ff41cc]">Next.js / React</span>
<span className="text-[#ff00ff]">&quot;</span>
<span className="text-[#00ff4160]">,</span>
</li>
<li className="flex items-center">
<span className="w-3 h-3 bg-[#3D3D3D] rounded-full mr-3"></span>
Penetration Testing
<li className="flex items-center gap-2">
<span className="text-[#ff00ff]">&quot;</span>
<span className="text-[#00ff41cc]">TypeScript / Node.js</span>
<span className="text-[#ff00ff]">&quot;</span>
<span className="text-[#00ff4160]">,</span>
</li>
<li className="flex items-center">
<span className="w-3 h-3 bg-[#3D3D3D] rounded-full mr-3"></span>
Security Architecture
<li className="flex items-center gap-2">
<span className="text-[#ff00ff]">&quot;</span>
<span className="text-[#00ff41cc]">Python / Go</span>
<span className="text-[#ff00ff]">&quot;</span>
<span className="text-[#00ff4160]">,</span>
</li>
<li className="flex items-center gap-2">
<span className="text-[#ff00ff]">&quot;</span>
<span className="text-[#00ff41cc]">API Design & Integration</span>
<span className="text-[#ff00ff]">&quot;</span>
<span className="text-[#00ff4160]">,</span>
</li>
<li className="flex items-center gap-2">
<span className="text-[#ff00ff]">&quot;</span>
<span className="text-[#00ff41cc]">Cloud & DevOps</span>
<span className="text-[#ff00ff]">&quot;</span>
</li>
</ul>
<div className="text-[#00d4ff] font-bold mt-2">{"}"}</div>
</div>
</div>
</div>
</div>
</section>
{/* Projects Section */}
<ProjectsSection />
<section
id="writing"
className="bg-[#FEFDFB] border-[3px] border-[#3D3D3D] rounded-md p-8 shadow-brutal"
>
<h2 className="text-2xl font-bold text-[#3D3D3D] mb-6 text-center uppercase">
Creative Corner
</h2>
<div className="grid md:grid-cols-3 gap-6">
{/* Creative Corner */}
<section className="fade-in fade-in-delay-5">
<div className="terminal-window overflow-hidden">
<div className="terminal-header px-4 py-2 flex items-center gap-2">
<span className="text-[#00ff41] text-sm opacity-60">creative.exe</span>
</div>
<div className="p-6">
<div className="text-[#00ff4160] text-sm mb-4">
$ ./creative --list
</div>
<div className="grid md:grid-cols-3 gap-4">
<Link
href="/digital-art"
className="bg-[#F0E8D8] border-2 border-[#3D3D3D] rounded-sm p-6 text-center hover:bg-[#E8DCC8] transition-colors"
className="hacker-card p-6 text-center group"
>
<div className="text-4xl mb-3">🎨</div>
<h3 className="text-lg font-bold text-[#3D3D3D] mb-2 uppercase">
Digital Art
</h3>
<p className="text-[#5D5D5D] text-sm">
Someone messing around with colors and shapes.
<div className="text-4xl mb-3 group-hover:scale-110 transition-transform">
<span className="text-[#ff00ff]">[</span>
<span className="text-[#00ff41]">ART</span>
<span className="text-[#ff00ff]">]</span>
</div>
<h3 className="text-[#ff00ff] font-bold mb-2">Digital Art</h3>
<p className="text-[#00ff4160] text-xs">
Experimental visuals and creative explorations
</p>
</Link>
<Link
href="/stories"
className="bg-[#CBD6C8] border-2 border-[#3D3D3D] rounded-sm p-6 text-center hover:bg-[#B8C5B3] transition-colors"
className="hacker-card p-6 text-center group"
>
<div className="text-4xl mb-3">📝</div>
<h3 className="text-lg font-bold text-[#3D3D3D] mb-2 uppercase">
Mini Stories
</h3>
<p className="text-[#5D5D5D] text-sm">
I like good narratives, so I try to imitate them.
<div className="text-4xl mb-3 group-hover:scale-110 transition-transform">
<span className="text-[#ffff00]">[</span>
<span className="text-[#00ff41]">TXT</span>
<span className="text-[#ffff00]">]</span>
</div>
<h3 className="text-[#ffff00] font-bold mb-2">Mini Stories</h3>
<p className="text-[#00ff4160] text-xs">
Short fiction and narrative experiments
</p>
</Link>
<Link
href="/thoughts"
className="bg-[#B8C5CE] border-2 border-[#3D3D3D] rounded-sm p-6 text-center hover:bg-[#A5B4BE] transition-colors"
className="hacker-card p-6 text-center group"
>
<div className="text-4xl mb-3">🌸</div>
<h3 className="text-lg font-bold text-[#3D3D3D] mb-2 uppercase">
Thoughts
</h3>
<p className="text-[#5D5D5D] text-sm">
Rants on technology, maybe something else.
<div className="text-4xl mb-3 group-hover:scale-110 transition-transform">
<span className="text-[#00d4ff]">[</span>
<span className="text-[#00ff41]">LOG</span>
<span className="text-[#00d4ff]">]</span>
</div>
<h3 className="text-[#00d4ff] font-bold mb-2">Thoughts</h3>
<p className="text-[#00ff4160] text-xs">
Reflections on tech, security, and life
</p>
</Link>
</div>
</div>
</div>
</section>
<section
id="contact"
className="bg-[#FEFDFB] border-[3px] border-[#3D3D3D] rounded-md p-8 shadow-brutal"
>
<h2 className="text-2xl font-bold text-[#3D3D3D] mb-6 text-center uppercase">
Get In Touch
</h2>
<div className="text-center">
<p className="text-[#5D5D5D] mb-6 font-semibold">
Let&apos;s collaborate on something interesting
{/* Contact Section */}
<section>
<div className="terminal-window overflow-hidden">
<div className="terminal-header px-4 py-2 flex items-center gap-2">
<span className="text-[#00ff41] text-sm opacity-60">contact.sh</span>
</div>
<div className="p-6 text-center">
<div className="text-[#00ff4160] text-sm mb-6">
$ echo &quot;Let&apos;s connect&quot;
</div>
<div className="mb-6">
<p className="text-[#00ff41cc] mb-2">
Available for security consulting, development projects, and interesting collaborations.
</p>
<p className="text-[#00ff4160] text-sm">
Response time: &lt; 24h
</p>
</div>
<div className="flex flex-wrap justify-center gap-4">
<a
href="mailto:tsowamainasara@gmail.com"
className="inline-block bg-[#3D3D3D] text-white px-8 py-4 font-bold border-2 border-[#3D3D3D] hover:bg-[#FEFDFB] hover:text-[#3D3D3D] transition-colors rounded-sm"
className="hacker-btn px-8 py-4 font-bold text-lg"
>
SEND EMAIL
<span className="text-[#00ff4160] mr-2">$</span>
SEND_MESSAGE
</a>
<a
href="https://github.com/neutrino2211"
target="_blank"
rel="noopener noreferrer"
className="hacker-btn px-8 py-4 font-bold text-lg border-[#00d4ff] text-[#00d4ff] hover:bg-[#00d4ff15]"
>
<span className="text-[#00d4ff80] mr-2">$</span>
VIEW_CODE
</a>
</div>
</div>
</div>
</section>
</main>
<footer className="mt-20 text-center">
<div className="flex justify-center space-x-6 mb-6">
{/* Footer */}
<footer className="mt-16 text-center">
<div className="terminal-window p-6">
<div className="flex justify-center gap-6 mb-6">
<a
href="https://github.com/neutrino2211/"
className="text-[#3D3D3D] font-bold hover:text-[#B8C5B3] transition-colors"
href="https://github.com/neutrino2211"
target="_blank"
rel="noopener noreferrer"
className="text-[#00ff4180] hover:text-[#00ff41] transition-colors"
>
<span className="sr-only">GitHub</span>
<svg className="w-8 h-8" fill="currentColor" viewBox="0 0 24 24">
<svg className="w-6 h-6" fill="currentColor" viewBox="0 0 24 24">
<path
fillRule="evenodd"
d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z"
@@ -237,27 +425,34 @@ export default function Home() {
</a>
<a
href="https://www.linkedin.com/in/mainasara-tsowa-17098b214/"
className="text-[#3D3D3D] font-bold hover:text-[#A5B4BE] transition-colors"
target="_blank"
rel="noopener noreferrer"
className="text-[#00ff4180] hover:text-[#00d4ff] transition-colors"
>
<span className="sr-only">LinkedIn</span>
<svg className="w-8 h-8" fill="currentColor" viewBox="0 0 24 24">
<svg className="w-6 h-6" fill="currentColor" viewBox="0 0 24 24">
<path d="M19 0h-14c-2.761 0-5 2.239-5 5v14c0 2.761 2.239 5 5 5h14c2.762 0 5-2.239 5-5v-14c0-2.761-2.238-5-5-5zm-11 19h-3v-11h3v11zm-1.5-12.268c-.966 0-1.75-.79-1.75-1.764s.784-1.764 1.75-1.764 1.75.79 1.75 1.764-.783 1.764-1.75 1.764zm13.5 12.268h-3v-5.604c0-3.368-4-3.113-4 0v5.604h-3v-11h3v1.765c1.396-2.586 7-2.777 7 2.476v6.759z" />
</svg>
</a>
<a
href="https://x.com/neutrino2211/"
className="text-[#3D3D3D] font-bold hover:text-[#D4B5A0] transition-colors"
href="https://x.com/neutrino2211"
target="_blank"
rel="noopener noreferrer"
className="text-[#00ff4180] hover:text-[#ff00ff] transition-colors"
>
<span className="sr-only">Twitter</span>
<svg className="w-8 h-8" fill="currentColor" viewBox="0 0 24 24">
<path d="M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z" />
<svg className="w-6 h-6" fill="currentColor" viewBox="0 0 24 24">
<path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" />
</svg>
</a>
</div>
<div className="bg-[#3D3D3D] text-white p-4 font-bold rounded-md">
<p className="text-sm uppercase">
Built with Charm Crush, Z.AI GLM and some muted colors
</p>
<div className="text-[#00ff4140] text-xs">
<span className="text-[#00ff4160]">/*</span> Built with Next.js |{" "}
<span className="text-[#00d4ff80]">mainasara.dev</span> |{" "}
{new Date().getFullYear()}{" "}
<span className="text-[#00ff4160]">*/</span>
</div>
<div className="mt-2 text-[#00ff4130] text-xs font-mono">
root@mainasara:~# <span className="cursor-blink"></span>
</div>
</div>
</footer>
</div>

25
src/app/template.tsx Normal file
View File

@@ -0,0 +1,25 @@
"use client";
import { motion } from "framer-motion";
import { usePathname } from "next/navigation";
export default function Template({ children }: { children: React.ReactNode }) {
const pathname = usePathname();
const isHackerTheme = pathname === "/";
return (
<motion.div
key={pathname}
initial={{ opacity: 0, y: 8 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -8 }}
transition={{
duration: 0.35,
ease: [0.22, 1, 0.36, 1],
}}
className={isHackerTheme ? "bg-[#0a0a0a]" : ""}
>
{children}
</motion.div>
);
}

View File

@@ -4,17 +4,30 @@ import { useState } from "react";
import { projects, Project } from "@/data/projects";
const categoryColors = {
security: "bg-[#E0C9B8] hover:border-[#5D5D5D]",
development: "bg-[#B8C5CE] hover:border-[#5D5D5D]",
art: "bg-[#E0C9CC] hover:border-[#5D5D5D]",
other: "bg-[#E8DCC8] hover:border-[#5D5D5D]",
};
const categoryHoverColors = {
security: "hover:text-[#C9A88E]",
development: "hover:text-[#9BAAB5]",
art: "hover:text-[#C9A8AB]",
other: "hover:text-[#DDD0BB]",
security: {
border: "border-[#ff3333]",
text: "text-[#ff3333]",
glow: "hover:shadow-[0_0_15px_#ff333340]",
tag: "bg-[#ff333320] text-[#ff3333]",
},
development: {
border: "border-[#00d4ff]",
text: "text-[#00d4ff]",
glow: "hover:shadow-[0_0_15px_#00d4ff40]",
tag: "bg-[#00d4ff20] text-[#00d4ff]",
},
art: {
border: "border-[#ff00ff]",
text: "text-[#ff00ff]",
glow: "hover:shadow-[0_0_15px_#ff00ff40]",
tag: "bg-[#ff00ff20] text-[#ff00ff]",
},
other: {
border: "border-[#ffff00]",
text: "text-[#ffff00]",
glow: "hover:shadow-[0_0_15px_#ffff0040]",
tag: "bg-[#ffff0020] text-[#ffff00]",
},
};
export default function ProjectsSection() {
@@ -24,64 +37,117 @@ export default function ProjectsSection() {
const additionalProjects = projects.filter((project) => !project.featured);
return (
<section
id="projects"
className="bg-[#FEFDFB] border-[3px] border-[#3D3D3D] rounded-md p-8 shadow-brutal"
>
<h2 className="text-2xl font-bold text-[#3D3D3D] mb-6 text-center uppercase">
Featured Projects
</h2>
<section id="projects">
<div className="terminal-window rounded-lg overflow-hidden">
<div className="terminal-header px-4 py-2 flex items-center gap-2">
<span className="text-[#00ff41] text-sm opacity-60">projects.sh</span>
</div>
<div className="p-6">
<div className="text-[#00ff4160] text-sm mb-6">
$ ls -la ~/projects/ --featured
</div>
<div className="grid md:grid-cols-2 gap-6 mb-6">
{featuredProjects.map((project) => (
<ProjectCard key={project.id} project={project} />
{featuredProjects.map((project, index) => (
<ProjectCard key={project.id} project={project} index={index} />
))}
</div>
<div
className={`overflow-hidden transition-all duration-500 ease-in-out ${
isExpanded ? "max-h-[1000px] opacity-100" : "max-h-0 opacity-0"
isExpanded ? "max-h-[2000px] opacity-100" : "max-h-0 opacity-0"
}`}
>
{additionalProjects.length > 0 && (
<div className="text-[#00ff4160] text-sm mb-4 mt-4">
$ ls -la ~/projects/ --all
</div>
)}
<div className="grid md:grid-cols-2 gap-6">
{additionalProjects.map((project) => (
<ProjectCard key={project.id} project={project} />
{additionalProjects.map((project, index) => (
<ProjectCard
key={project.id}
project={project}
index={index + featuredProjects.length}
/>
))}
</div>
</div>
{additionalProjects.length > 0 && (
<div className="text-center mt-6">
<div className="text-center mt-8">
<button
onClick={() => setIsExpanded(!isExpanded)}
className="bg-[#3D3D3D] text-white px-6 py-3 font-bold border-2 border-[#3D3D3D] hover:bg-[#FEFDFB] hover:text-[#3D3D3D] transition-colors uppercase rounded-sm"
className="hacker-btn px-8 py-3 font-bold"
>
{isExpanded ? "Show Less" : "Read More"}
<span className="text-[#00ff4160] mr-2">$</span>
{isExpanded ? "COLLAPSE" : "SHOW_ALL"}
</button>
</div>
)}
</div>
</div>
</section>
);
}
function ProjectCard({ project }: { project: Project }) {
const colorClass = categoryColors[project.category];
const hoverColorClass = categoryHoverColors[project.category];
function ProjectCard({ project, index }: { project: Project; index: number }) {
const colors = categoryColors[project.category];
return (
<div
className={`${colorClass} border-2 border-[#3D3D3D] rounded-sm p-6 transition-colors`}
className={`hacker-card p-5 transition-all duration-300 ${colors.border} border ${colors.glow}`}
>
<h3 className="text-lg font-bold text-[#3D3D3D] mb-2 uppercase">
{/* Project header */}
<div className="flex items-start justify-between mb-3">
<div className="flex items-center gap-2">
<span className="text-[#00ff4160] text-xs font-mono">
[{String(index).padStart(2, "0")}]
</span>
<span className={`text-xs px-2 py-0.5 ${colors.tag} font-mono`}>
{project.category}
</span>
</div>
{project.featured && (
<span className="text-[#ffff00] text-xs animate-pulse">*</span>
)}
</div>
{/* Project title */}
<h3 className={`text-lg font-bold mb-2 ${colors.text}`}>
<span className="text-[#00ff4160]">./</span>
{project.title}
</h3>
<p className="text-[#5D5D5D] text-sm mb-3">{project.description}</p>
{/* Description */}
<p className="text-[#00ff41cc] text-sm mb-4 leading-relaxed">
<span className="text-[#00ff4160]"># </span>
{project.description}
</p>
{/* Link */}
{project.link && (
<a
href={project.link}
className={`text-[#3D3D3D] font-bold underline ${hoverColorClass} transition-colors`}
target="_blank"
rel="noopener noreferrer"
className={`inline-flex items-center gap-2 text-sm font-mono ${colors.text} hover:underline group`}
>
View Project
<span className="text-[#00ff4160]">&gt;</span>
<span>VIEW_PROJECT</span>
<svg
className="w-4 h-4 transform group-hover:translate-x-1 transition-transform"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M13 7l5 5m0 0l-5 5m5-5H6"
/>
</svg>
</a>
)}
</div>