diff --git a/apps/blade/public/profile.jpg b/apps/blade/public/profile.jpg new file mode 100644 index 00000000..3226f652 Binary files /dev/null and b/apps/blade/public/profile.jpg differ diff --git a/apps/blade/public/resume.pdf b/apps/blade/public/resume.pdf new file mode 100644 index 00000000..a1d5cac4 Binary files /dev/null and b/apps/blade/public/resume.pdf differ diff --git a/apps/blade/src/app/ericgeorge/page.tsx b/apps/blade/src/app/ericgeorge/page.tsx new file mode 100644 index 00000000..24ba3d5a --- /dev/null +++ b/apps/blade/src/app/ericgeorge/page.tsx @@ -0,0 +1,388 @@ +"use client"; + +import React, { useState, useEffect } from "react"; +import { GeistMono } from "geist/font/mono"; +import { cn } from "@forge/ui"; +import { FaLinkedin } from "react-icons/fa"; +import Link from "next/link"; + +const PIPBOY_GREEN = "#1aff80"; + +const Page = () => { + const [activeTab, setActiveTab] = useState("INTRO"); + const [time, setTime] = useState(new Date()); + + useEffect(() => { + const timer = setInterval(() => setTime(new Date()), 1000); + return () => clearInterval(timer); + }, []); + + const tabs = ["INTRO", "PROJECTS", "CONTACT"]; + + return ( +
+ {/* + + */} +
+ + {/* DRASTIC SCANLINES: Higher contrast and larger size for that low-res feel */} +
+ + {/* CHROMATIC ABERRATION: Subtle RGB bleed at the edges */} +
+ + +
+ +
+ + +
+ + +
+ +
+
+ + +
+ +
+ + {/* Header */} +
+
+ + +
+ + + + + + + + + + + + + + {time.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit' })} +
+
+
+ + {/* Main Content Sections */} +
+
+ {activeTab === "INTRO" && } + {activeTab === "PROJECTS" && } + {activeTab === "CONTACT" && } + +
+
+ + {/* Footer Dashboard */} +
+
+
+
+ STATUS: NGMI +
+
+
+
+
+ HP 320/320 + 99% hahacoolnumber +
+
+ +
+ +
+ +
+
LVL 21
+
+
+
+
+
+
+ +
+
+ +
+ ); +}; + +const TypewriterText = ({ text, delay = 50, startDelay = 0 }: { text: string; delay?: number; startDelay?: number }) => { + const [displayText, setDisplayText] = useState(""); + const [isComplete, setIsComplete] = useState(false); + + useEffect(() => { + let timeout: NodeJS.Timeout; + let currentText = ""; + let index = 0; + + const type = () => { + if (index < text.length) { + currentText += text[index]; + setDisplayText(currentText); + index++; + timeout = setTimeout(type, delay); + } else { + setIsComplete(true); + } + }; + + const startTimeout = setTimeout(type, startDelay); + return () => { + clearTimeout(startTimeout); + clearTimeout(timeout); + }; + }, [text, delay, startDelay]); + + return ( + + {displayText} + {!isComplete && ( + + )} + + ); +}; + +const IntroContent = () => ( +
+ {/* Profile Image with CRT Filter - need to tone this down a little */} +
+
+ {/* Decorative Frame */} +
+
+ +
+ Eric George + {/* Image Scanline Overlay */} +
+ {/* Vignette on image */} +
+
+ + +
+
+ + {/* Intro Text */} +
+
+

+ +

+
+

+ +

+

+ +

+

+ +

+
+

+ +

+
+
+
+); + +const ProjectsContent = () => ( +
+ + + {/* Project Details */} +
+
+

+ +

+
+

+ A really fun game that we designed at Swamphacks to help people learn ASL. It was basically a combo of Guitar Hero and DDR but with ASL. My favorite part about this project was that it ended up being a pretty solid game at the end of it. We had tons of people swarm our table to try it out! +

+
+
+

AWARDS

+

2nd Place @ Swamphacks

+

Best Game Design @ Swamphacks

+
+
+

TECH STACK

+

MobileNetV2 • MediaPipe • Real-time AI

+
+
+

+ +

+ + View Project on Devpost + +
+
+
+

+ +

+
+

+ Emergent was a cool project that me and my friends built at Knighthacks. Its essentially a crisis-management simulation software that aims to streamline and improve the way that organizations simulate disasters. It was a really engaging problem to delve into and also very fun to build. +

+
+
+

AWARDS

+

1st Place @ Knighthacks

+

2nd Place in Google ADK Challenge @ Knighthacks

+
+
+

TECH STACK

+

Google ADK • NextJS • ElevenLabs

+
+
+

+ +

+ + View Project on Devpost + +
+
+
+
+); + +const ContactContent = () => ( +
+

+ +

+ +
+ {[ + { label: "LINKEDIN", value: "eric-george-90a26a278", href: "https://www.linkedin.com/in/eric-george-90a26a278/" }, + { label: "GITHUB", value: "myr124", href: "https://github.com/myr124" }, + { label: "EMAIL", value: "ericgeo324@gmail.com", href: "mailto:ericgeo324@gmail.com" }, + { label: "LOCATION", value: "ORLANDO, FL", href: "#" }, + ].map((contact, i) => ( +
+ {contact.label} + + + +
+ ))} +
+ +
+); + + + +export default Page; diff --git a/apps/blade/src/app/globals.css b/apps/blade/src/app/globals.css index feda8638..f2630758 100644 --- a/apps/blade/src/app/globals.css +++ b/apps/blade/src/app/globals.css @@ -3,102 +3,313 @@ @tailwind utilities; @layer base { - :root { - --background: 0 0% 100%; - --foreground: 224 71.4% 4.1%; - --card: 0 0% 100%; - --card-foreground: 224 71.4% 4.1%; - --popover: 0 0% 100%; - --popover-foreground: 224 71.4% 4.1%; - --primary: 262.1 83.3% 57.8%; - --primary-lighter: 262.1 83.3% 55%; - --primary-foreground: 210 20% 98%; - --secondary: 220 14.3% 95.9%; - --secondary-foreground: 220.9 39.3% 11%; - --muted: 220 14.3% 95.9%; - --muted-foreground: 220 8.9% 46.1%; - --accent: 220 14.3% 95.9%; - --accent-foreground: 220.9 39.3% 11%; - --destructive: 0 84.2% 60.2%; - --destructive-foreground: 210 20% 98%; - --border: 220 13% 91%; - --input: 220 13% 91%; - --ring: 262.1 83.3% 57.8%; - --radius: 0.5rem; - --chart-1: 12 76% 61%; - --chart-2: 173 58% 39%; - --chart-3: 197 37% 24%; - --chart-4: 43 74% 66%; - --chart-5: 27 87% 67%; - } - - .dark { - --background: 224 71.4% 4.1%; - --foreground: 210 20% 98%; - --card: 224 71.4% 4.1%; - --card-foreground: 210 20% 98%; - --popover: 224 71.4% 4.1%; - --popover-foreground: 210 20% 98%; - --primary: 263.4 70% 50.4%; - --primary-lighter: 262.1 83.3% 60%; - --primary-foreground: 210 20% 98%; - --secondary: 215 27.9% 16.9%; - --secondary-foreground: 210 20% 98%; - --muted: 215 27.9% 16.9%; - --muted-foreground: 217.9 10.6% 64.9%; - --accent: 215 27.9% 16.9%; - --accent-foreground: 210 20% 98%; - --destructive: 0 62.8% 30.6%; - --destructive-foreground: 210 20% 98%; - --border: 215 27.9% 16.9%; - --input: 215 27.9% 16.9%; - --ring: 263.4 70% 50.4%; - --chart-1: 220 70% 50%; - --chart-2: 160 60% 45%; - --chart-3: 30 80% 55%; - --chart-4: 280 65% 60%; - --chart-5: 340 75% 55%; - } + :root { + --background: 0 0% 100%; + --foreground: 224 71.4% 4.1%; + --card: 0 0% 100%; + --card-foreground: 224 71.4% 4.1%; + --popover: 0 0% 100%; + --popover-foreground: 224 71.4% 4.1%; + --primary: 262.1 83.3% 57.8%; + --primary-lighter: 262.1 83.3% 55%; + --primary-foreground: 210 20% 98%; + --secondary: 220 14.3% 95.9%; + --secondary-foreground: 220.9 39.3% 11%; + --muted: 220 14.3% 95.9%; + --muted-foreground: 220 8.9% 46.1%; + --accent: 220 14.3% 95.9%; + --accent-foreground: 220.9 39.3% 11%; + --destructive: 0 84.2% 60.2%; + --destructive-foreground: 210 20% 98%; + --border: 220 13% 91%; + --input: 220 13% 91%; + --ring: 262.1 83.3% 57.8%; + --radius: 0.5rem; + --chart-1: 12 76% 61%; + --chart-2: 173 58% 39%; + --chart-3: 197 37% 24%; + --chart-4: 43 74% 66%; + --chart-5: 27 87% 67%; + } + + .dark { + --background: 224 71.4% 4.1%; + --foreground: 210 20% 98%; + --card: 224 71.4% 4.1%; + --card-foreground: 210 20% 98%; + --popover: 224 71.4% 4.1%; + --popover-foreground: 210 20% 98%; + --primary: 263.4 70% 50.4%; + --primary-lighter: 262.1 83.3% 60%; + --primary-foreground: 210 20% 98%; + --secondary: 215 27.9% 16.9%; + --secondary-foreground: 210 20% 98%; + --muted: 215 27.9% 16.9%; + --muted-foreground: 217.9 10.6% 64.9%; + --accent: 215 27.9% 16.9%; + --accent-foreground: 210 20% 98%; + --destructive: 0 62.8% 30.6%; + --destructive-foreground: 210 20% 98%; + --border: 215 27.9% 16.9%; + --input: 215 27.9% 16.9%; + --ring: 263.4 70% 50.4%; + --chart-1: 220 70% 50%; + --chart-2: 160 60% 45%; + --chart-3: 30 80% 55%; + --chart-4: 280 65% 60%; + --chart-5: 340 75% 55%; + } } .moving-border { - animation: moving-border 10s linear infinite; + animation: moving-border 10s linear infinite; } @keyframes moving-border { - 0% { - transform: rotate(0deg) scale(10); - } - 100% { - transform: rotate(-360deg) scale(10); - } + 0% { + transform: rotate(0deg) scale(10); + } + + 100% { + transform: rotate(-360deg) scale(10); + } } .animate-mobile-initial-expand { - animation: initialMobileExpand 0.5s ease-out forwards; + animation: initialMobileExpand 0.5s ease-out forwards; } @keyframes initialMobileExpand { - 0% { - height: 0px; - } - 100% { - height: 26rem; - } + 0% { + height: 0px; + } + + 100% { + height: 26rem; + } } .animate-fade-in { - animation: fadeIn 0.5s ease-in forwards; + animation: fadeIn 0.5s ease-in forwards; } @keyframes fadeIn { - 0% { - opacity: 0; - } - 70% { - opacity: 0; - } - 100% { - opacity: 1; - } + 0% { + opacity: 0; + } + + 70% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} + +/* Pip-Boy CRT Effects */ +@keyframes flicker { + 0% { + opacity: 0.27861; + } + + 5% { + opacity: 0.34769; + } + + 10% { + opacity: 0.23604; + } + + 15% { + opacity: 0.90626; + } + + 20% { + opacity: 0.18128; + } + + 25% { + opacity: 0.83891; + } + + 30% { + opacity: 0.65583; + } + + 35% { + opacity: 0.67807; + } + + 40% { + opacity: 0.26559; + } + + 45% { + opacity: 0.84693; + } + + 50% { + opacity: 0.96019; + } + + 55% { + opacity: 0.08594; + } + + 60% { + opacity: 0.20313; + } + + 65% { + opacity: 0.71988; + } + + 70% { + opacity: 0.53455; + } + + 75% { + opacity: 0.37288; + } + + 80% { + opacity: 0.71428; + } + + 85% { + opacity: 0.70419; + } + + 90% { + opacity: 0.7003; + } + + 95% { + opacity: 0.36108; + } + + 100% { + opacity: 0.24387; + } +} + +@keyframes grain { + + 0%, + 100% { + transform: translate(0, 0); + } + + 10% { + transform: translate(-2%, -8%); + } + + 30% { + transform: translate(-12%, 4%); + } + + 50% { + transform: translate(3%, -18%); + } + + 70% { + transform: translate(-8%, 18%); + } + + 90% { + transform: translate(12%, 0%); + } } + +@keyframes scan-bar { + 0% { + top: -25vh; + opacity: 0; + } + + 20% { + opacity: 0.15; + } + + 80% { + opacity: 0.15; + } + + 100% { + top: 125vh; + opacity: 0; + } +} + +@keyframes startup { + 0% { + opacity: 0; + filter: blur(20px) brightness(4) scale(1.1); + } + + 30% { + opacity: 0.8; + filter: blur(10px) brightness(2) scale(1.05); + } + + 50% { + opacity: 0.3; + filter: blur(5px) brightness(1.5) scale(1.02); + } + + 100% { + opacity: 1; + filter: blur(0) brightness(1) scale(1); + } +} + +@keyframes cursor-blink { + + 0%, + 100% { + opacity: 1; + } + + 50% { + opacity: 0; + } +} + +.animate-flicker { + animation: flicker 0.12s infinite; +} + +.animate-grain { + animation: grain 0.5s steps(3) infinite; +} + +.animate-scan-bar { + animation: scan-bar 12s linear infinite; +} + +.animate-startup { + animation: startup 1.8s cubic-bezier(0.19, 1, 0.22, 1); +} + +.animate-cursor { + animation: cursor-blink 0.8s step-end infinite; +} + +.text-glow { + text-shadow: 0 0 15px rgba(26, 255, 128, 0.8); +} + +.custom-scrollbar::-webkit-scrollbar { + width: 8px; +} + +.custom-scrollbar::-webkit-scrollbar-track { + background: rgba(26, 255, 128, 0.05); + border-left: 1px solid rgba(26, 255, 128, 0.1); +} + +.custom-scrollbar::-webkit-scrollbar-thumb { + background: rgba(26, 255, 128, 0.4); + border: 2px solid #020502; +} \ No newline at end of file diff --git a/apps/blade/src/app/layout.tsx b/apps/blade/src/app/layout.tsx index 8e2118d8..acd01d10 100644 --- a/apps/blade/src/app/layout.tsx +++ b/apps/blade/src/app/layout.tsx @@ -13,47 +13,47 @@ import "./globals.css"; import { env } from "~/env"; export const metadata: Metadata = { - metadataBase: new URL( - env.NODE_ENV === "production" - ? "https://blade.knighthacks.org" - : "http://localhost:3000", - ), - title: "Blade", - description: "The centralized platform for all things Knight Hacks", - openGraph: { + metadataBase: new URL( + env.NODE_ENV === "production" + ? "https://blade.knighthacks.org" + : "http://localhost:3000", + ), title: "Blade", description: "The centralized platform for all things Knight Hacks", - url: "https://blade.knighthacks.org", - siteName: "Blade", - images: [{ url: "https://blade.knighthacks.org/banner.png" }], - }, + openGraph: { + title: "Blade", + description: "The centralized platform for all things Knight Hacks", + url: "https://blade.knighthacks.org", + siteName: "Blade", + images: [{ url: "https://blade.knighthacks.org/banner.png" }], + }, }; export const viewport: Viewport = { - themeColor: [ - { media: "(prefers-color-scheme: light)", color: "white" }, - { media: "(prefers-color-scheme: dark)", color: "black" }, - ], + themeColor: [ + { media: "(prefers-color-scheme: light)", color: "white" }, + { media: "(prefers-color-scheme: dark)", color: "black" }, + ], }; export default function RootLayout(props: { children: React.ReactNode }) { - return ( - - - - {props.children} -
- -
- -
- - - ); + return ( + + + + {props.children} +
+ +
+ +
+ + + ); }