personal website
1import type { RefObject } from "react"
2import { CurrentlyPlaying, LastPlayed, type AtProtoStyles } from "atproto-ui"
3import { personalInfo, currentRole, skills } from "../../data/portfolio"
4
5interface HeaderProps {
6 sectionRef: (el: HTMLElement | null) => void
7 onGuestbookClick?: () => void
8}
9
10export function Header({ sectionRef, onGuestbookClick }: HeaderProps) {
11 const scrollToWork = () => {
12 document.getElementById('work')?.scrollIntoView({ behavior: 'smooth' })
13 }
14
15 return (
16 <header id="intro" ref={sectionRef} className="min-h-screen flex items-center opacity-0 relative">
17 {/* Background Image - Full Width */}
18 <div
19 className="absolute top-0 bottom-0 left-1/2 right-1/2 -ml-[50vw] -mr-[50vw] w-screen z-0"
20 style={{
21 backgroundImage: 'url(https://cdn.donmai.us/original/31/2f/__kazusa_blue_archive_drawn_by_astelia__312fc11a21c5d4ce06dc3aa8bfbb7221.jpg)',
22 backgroundSize: 'cover',
23 backgroundPosition: 'center',
24 backgroundRepeat: 'no-repeat',
25 }}
26 >
27 {/* Overlay for better text readability */}
28 <div className="absolute inset-0 bg-background/70"></div>
29 </div>
30
31 <div className="grid lg:grid-cols-5 gap-12 sm:gap-16 w-full relative z-10 items-center">
32 <div className="lg:col-span-3 space-y-6 sm:space-y-8">
33 <div className="space-y-3 sm:space-y-2">
34 <div className="text-sm text-gray-300 font-mono tracking-wider">PORTFOLIO / 2025</div>
35 <h1 className="text-md sm:text-md lg:text-4xl font-light tracking-tight text-cyan-400">
36 {personalInfo.name.first}
37 <br />
38 <span className=" text-gray-400">{personalInfo.name.last}</span>
39 </h1>
40 </div>
41
42 <div className="space-y-6 max-w-md ">
43 <p className="text-lg sm:text-xl text-stone-200 leading-relaxed">
44 {personalInfo.description.map((part, i) => {
45 if (part.url) {
46 return (
47 <a
48 key={i}
49 href={part.url}
50 target="_blank"
51 rel="noopener noreferrer"
52 className="text-cyan-400/70 hover:text-cyan-300 font-medium transition-colors duration-300 underline decoration-cyan-400/30 hover:decoration-cyan-300/50"
53 >
54 {part.text}
55 </a>
56 )
57 }
58
59 if (part.bold) {
60 return (
61 <span key={i} className="text-white font-medium">
62 {part.text}
63 </span>
64 )
65 }
66
67 return part.text
68 })}
69 </p>
70
71
72 <div className="space-y-4">
73 <div className="flex items-center gap-2 text-sm text-gray-300">
74 <div className="w-2 h-2 bg-green-500 rounded-full animate-pulse"></div>
75 {personalInfo.availability.status}
76 </div>
77 <div className="flex items-center gap-4">
78 <a
79 href={`mailto:${personalInfo.contact.email}`}
80 className="glass glass-hover px-6 py-3 rounded-lg transition-all duration-300 inline-flex items-center justify-center gap-2 text-sm text-gray-300 hover:text-white flex-1"
81 >
82 <svg
83 className="w-4 h-4"
84 fill="none"
85 stroke="currentColor"
86 viewBox="0 0 24 24"
87 strokeWidth={2}
88 >
89 <path
90 strokeLinecap="round"
91 strokeLinejoin="round"
92 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"
93 />
94 </svg>
95 Email me
96 </a>
97 <a
98 href="https://nekomimi.leaflet.pub"
99 target="_blank"
100 rel="noopener noreferrer"
101 className="glass glass-hover px-6 py-3 rounded-lg transition-all duration-300 inline-flex items-center justify-center gap-2 text-sm text-gray-300 hover:text-white flex-1"
102 >
103 <svg
104 className="w-4 h-4"
105 fill="none"
106 stroke="currentColor"
107 viewBox="0 0 24 24"
108 strokeWidth={2}
109 >
110 <path
111 strokeLinecap="round"
112 strokeLinejoin="round"
113 d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"
114 />
115 </svg>
116 Read my blog
117 </a>
118 </div>
119 <button
120 onClick={onGuestbookClick}
121 className="glass glass-hover w-full px-6 py-3 rounded-lg transition-all duration-300 inline-flex items-center justify-center gap-2 text-sm text-gray-300 hover:text-white"
122 >
123 <svg
124 className="w-4 h-4"
125 fill="none"
126 stroke="currentColor"
127 viewBox="0 0 24 24"
128 strokeWidth={2}
129 >
130 <path
131 strokeLinecap="round"
132 strokeLinejoin="round"
133 d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z"
134 />
135 </svg>
136 Sign my guestbook
137 </button>
138 </div>
139 </div>
140 </div>
141
142 <div className="hidden lg:flex lg:col-span-2 flex-col justify-end space-y-6 sm:space-y-8 mt-8 lg:mt-0">
143 <div className="space-y-4">
144 <p className="text-sm text-gray-300 font-mono">IM LISTENING TO:</p>
145 <div className="glass rounded-2xl" style={{
146 '--atproto-color-bg': 'transparent',
147 '--atproto-color-border': 'transparent',
148 '--atproto-color-bg-elevated': 'rgba(255, 255, 255, 0.20)',
149 '--atproto-color-text': 'white',
150 '--atproto-color-text-secondary': 'rgba(255, 255, 255, 0.80)',
151 } as AtProtoStyles }>
152 <CurrentlyPlaying did="nekomimi.pet"/>
153 </div>
154 </div>
155 </div>
156 </div>
157
158 {/* Image Source Link */}
159 <a
160 href="https://danbooru.donmai.us/posts/9959832"
161 target="_blank"
162 rel="noopener noreferrer"
163 className="absolute bottom-8 right-8 glass glass-hover p-2 rounded-lg transition-all duration-300 z-20 text-xs dark:text-gray-400 text-gray-600 hover:dark:text-gray-200 hover:text-gray-800"
164 aria-label="View image source"
165 >
166 <svg
167 className="w-4 h-4 inline-block mr-1"
168 fill="none"
169 stroke="currentColor"
170 viewBox="0 0 24 24"
171 strokeWidth={2}
172 >
173 <path
174 strokeLinecap="round"
175 strokeLinejoin="round"
176 d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"
177 />
178 </svg>
179 Source
180 </a>
181
182 {/* Scroll Down Arrow */}
183 <button
184 onClick={scrollToWork}
185 className="absolute bottom-8 left-1/2 -translate-x-1/2 glass glass-hover p-3 rounded-full animate-bounce-slow transition-all duration-300 z-20"
186 aria-label="Scroll to work section"
187 >
188 <svg
189 className="w-5 h-5 text-gray-300"
190 fill="none"
191 stroke="currentColor"
192 viewBox="0 0 24 24"
193 strokeWidth={2}
194 >
195 <path
196 strokeLinecap="round"
197 strokeLinejoin="round"
198 d="M19 14l-7 7m0 0l-7-7m7 7V3"
199 />
200 </svg>
201 </button>
202 </header>
203 )
204}