at main 8.2 kB view raw
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}