Skip to content

Commit 450ac3d

Browse files
committed
light switch and redesign/new picture
1 parent d8cef1a commit 450ac3d

4 files changed

Lines changed: 122 additions & 69 deletions

File tree

package-lock.json

Lines changed: 42 additions & 42 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

public/images/profile.jpg

2.04 MB
Loading

public/images/profile2.jpg

12.9 KB
Loading

src/pages/index.jsx

Lines changed: 80 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Github, Linkedin, Mail, Download, ExternalLink } from 'lucide-react';
33

44
export default function Portfolio() {
55
const [theme, setTheme] = useState('light');
6+
const [copied, setCopied] = useState(false);
67

78
const bg = theme === 'light' ? 'bg-white' : 'bg-neutral-900';
89
const text = theme === 'light' ? 'text-neutral-900' : 'text-neutral-100';
@@ -61,40 +62,92 @@ export default function Portfolio() {
6162

6263
return (
6364
<div className={`min-h-screen ${bg} ${text} transition-colors duration-300`}>
64-
<button
65-
onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}
66-
className={`fixed bottom-6 left-6 z-50 w-12 h-12 rounded-full ${accent} ${accentText} flex items-center justify-center text-xs font-mono hover:scale-110 transition-transform shadow-lg`}
67-
aria-label="Toggle theme"
68-
>
69-
{theme === 'light' ? '●' : '○'}
70-
</button>
7165

72-
{/* Header */}
73-
<header className={`border-b ${border} py-8 px-6`}>
74-
<div className="max-w-5xl mx-auto">
75-
<div className="flex items-start justify-between">
76-
<div>
77-
<h1 className="text-4xl font-mono font-bold mb-2">Emmet Hoversten</h1>
78-
<p className={`${textMuted} font-mono text-sm`}>AI Engineer / Software Developer</p>
79-
</div>
80-
<div className="flex gap-3">
81-
<a href="https://github.com/ejhover" target="_blank" rel="noopener noreferrer"
82-
className={`${textMuted} hover:${text} transition-colors`}>
83-
<Github size={20} />
84-
</a>
85-
<a href="https://www.linkedin.com/in/emmet-hoversten-59929a173/" target="_blank" rel="noopener noreferrer"
86-
className={`${textMuted} hover:${text} transition-colors`}>
87-
<Linkedin size={20} />
88-
</a>
89-
<a href="mailto:emmethoversten@gmail.com"
90-
className={`${textMuted} hover:${text} transition-colors`}>
66+
{/* navbar/header */}
67+
<header className={`border-b ${border} py-8 px-6 relative`}>
68+
<div className="max-w-5xl mx-auto flex items-center justify-between relative">
69+
70+
{/* name/title */}
71+
<div className="flex flex-col">
72+
<h1 className="text-4xl font-mono font-bold mb-2">Emmet Hoversten</h1>
73+
<p className={`${textMuted} font-mono text-sm`}>AI Engineer / Software Developer</p>
74+
</div>
75+
76+
{/* lightswitch */}
77+
<div className="absolute left-1/2 top-1/2 transform -translate-x-1/2 -translate-y-1/2">
78+
<button
79+
onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}
80+
className="w-10 h-16 bg-neutral-100 rounded-md shadow-lg border border-neutral-300 flex items-center justify-center active:scale-95 transition-transform"
81+
aria-label="Toggle theme"
82+
>
83+
{/* screws */}
84+
<div className="absolute top-3 w-1 h-1 bg-neutral-400 rounded-full shadow-inner" />
85+
<div className="absolute bottom-3 w-1 h-1 bg-neutral-400 rounded-full shadow-inner" />
86+
87+
{/* slot background */}
88+
<div className="relative w-3 h-10 bg-neutral-300 rounded-sm flex items-center justify-center shadow-inner">
89+
{/* lever */}
90+
<div
91+
className={`
92+
absolute w-3 h-5 bg-white rounded-sm shadow-md
93+
transition-all duration-300 ease-in-out
94+
origin-center
95+
${theme === 'light' ? '-translate-y-4' : 'translate-y-4'}
96+
`}
97+
/>
98+
</div>
99+
</button>
100+
</div>
101+
102+
{/* contact icons */}
103+
<div className="flex items-center gap-4">
104+
<div className="group relative flex items-center px-2 py-2">
105+
{/* email animation */}
106+
<div className="overflow-hidden flex justify-end max-w-0 group-hover:max-w-xs transition-all duration-500 ease-out">
107+
<button
108+
onClick={() => {
109+
navigator.clipboard.writeText("emmethoversten@gmail.com");
110+
setCopied(true);
111+
setTimeout(() => setCopied(false), 1500);
112+
}}
113+
className={`mr-3 text-sm font-mono ${text} whitespace-nowrap overflow-hidden border-r-2 border-current opacity-0 group-hover:opacity-100 transition-opacity duration-200 delay-200 group-hover:animate-typing`}
114+
>
115+
emmethoversten [at] gmail [dot] com
116+
</button>
117+
</div>
118+
119+
{/* mail icon */}
120+
<button
121+
onClick={() => {
122+
navigator.clipboard.writeText("emmethoversten@gmail.com");
123+
setCopied(true);
124+
setTimeout(() => setCopied(false), 1500);
125+
}}
126+
className={`${textMuted} hover:${text} transition-all duration-300`}
127+
>
91128
<Mail size={20} />
92-
</a>
129+
</button>
130+
131+
{/* copy to clipboard animation */}
132+
<div className={`absolute mt-10 text-xs font-mono opacity-0 group-hover:opacity-100 transition-opacity duration-200 ${textMuted}`}>
133+
{copied ? "Copied!" : "Click to copy"}
134+
</div>
93135
</div>
136+
137+
{/* github */}
138+
<a href="https://github.com/ejhover" target="_blank" rel="noopener noreferrer" className={`${textMuted} hover:${text} transition-all duration-300 px-2`}>
139+
<Github size={20} />
140+
</a>
141+
142+
{/* linkedin */}
143+
<a href="https://www.linkedin.com/in/emmet-hoversten-59929a173/" target="_blank" rel="noopener noreferrer" className={`${textMuted} hover:${text} transition-all duration-300 px-2`}>
144+
<Linkedin size={20} />
145+
</a>
94146
</div>
95147
</div>
96148
</header>
97149

150+
98151
<main className="max-w-5xl mx-auto px-6 py-16">
99152
{/* profile */}
100153
<section className="mb-20">

0 commit comments

Comments
 (0)