"use client"; import { useRef, useState } from "react"; import SafeImage from "./SafeImage"; interface Task { name: string; description: string; status: string; technologies: string[]; } interface ProjectLink { name: string; url: string; } interface Project { name: string; description: string; logo?: string; links?: ProjectLink[]; tasks: Task[]; } interface Experience { company: string; position: string; startDate: string; endDate: string; logo?: string; } interface Education { degree: string; school: string; startDate: string; endDate: string; } interface HeroProps { name: string; lastName: string; title: string; description: string; skills: string[]; projects: Project[]; experiences: Experience[]; education: Education[]; languages: { name: string; level: string }[]; interests: string[]; location: string; } // ─── BentoCard ─────────────────────────────────────────────────────────────── function BentoCard({ num, label, href, children, accent = false, delay = 0, className = "", style = {}, onClick, }: { num: string; label: string; href: string; children: React.ReactNode; accent?: boolean; delay?: number; className?: string; style?: React.CSSProperties; onClick?: (e: React.MouseEvent) => void; }) { const cardRef = useRef(null); const [mousePosition, setMousePosition] = useState({ x: -1000, y: -1000 }); const [isHovered, setIsHovered] = useState(false); const handleMouseMove = (e: React.MouseEvent) => { if (cardRef.current) { const rect = cardRef.current.getBoundingClientRect(); setMousePosition({ x: e.clientX - rect.left, y: e.clientY - rect.top, }); } }; return ( setIsHovered(true)} onMouseLeave={() => setIsHovered(false)} style={{ animationName: "fadeUp", animationDuration: "0.7s", animationTimingFunction: "ease", animationFillMode: "both", animationDelay: `${delay}ms`, display: "flex", flexDirection: "column", padding: "1.75rem", border: "1px solid rgba(255,255,255,0.05)", background: accent ? "rgba(200,169,110,0.03)" : "rgba(14,16,20,0.4)", backdropFilter: "blur(12px)", textDecoration: "none", color: "inherit", position: "relative", overflow: "hidden", cursor: "pointer", transition: "border-color 0.4s ease, transform 0.4s ease, background 0.4s ease, box-shadow 0.4s ease", borderRadius: "16px", minHeight: "220px", boxShadow: isHovered ? "0 8px 32px rgba(0,0,0,0.4)" : "0 4px 16px rgba(0,0,0,0.2)", transform: isHovered ? "translateY(-4px) scale(1.01)" : "translateY(0) scale(1)", borderColor: isHovered ? "rgba(200,169,110,0.3)" : "rgba(255,255,255,0.05)", ...style, }} > {/* Spotlight Effect */}
{num} · {label}
{children}
); } // ─── Hero ───────────────────────────────────────────────────────────────────── export default function Hero({ name, lastName, title, description, skills, projects, experiences, education, languages, interests, location, }: HeroProps) { const feat1 = projects.find(p => p.name === "FOON") || projects[0]; const feat2 = projects.find(p => p.name === "Gazelle") || projects[1]; const topSkills = skills.slice(0, 10); const handleFeatureClick = (projectName: string) => { const idx = projects.findIndex((p) => p.name === projectName); if (idx !== -1) { window.dispatchEvent(new CustomEvent("openProject", { detail: { index: idx } })); } }; const levelColor = (level: string) => { if (level === "Native") return "#c8a96e"; if (level === "C2") return "#3a7a5a"; return "#4a6050"; }; return (
{/* ── Headline ─────────────────────────────────────────────────── */}

Let's bend
spacetime

{/* ── Name + description strip ──────────────────────────────── */}
{title}
{name}{" "} {lastName}

{description}

Based in {location}
{/* ── Divider ───────────────────────────────────────────────── */}
{/* ── Creative Bento grid ──────────────────────────────────────── */}
{/* 01 — FOON (Span 2x2: Large Feature) */} handleFeatureClick(feat1.name)} >
{feat1.logo && (
)}

{feat1.name}

Featured Project

{feat1.description}

{feat1.tasks.slice(0, 2).map((task) => (
{task.name} {task.status}
{task.description.length > 80 ? task.description.slice(0, 80) + "..." : task.description}
))}
{feat1.tasks.flatMap((t) => t.technologies).filter((v, i, a) => a.indexOf(v) === i).slice(0, 6).map((tech) => ( {tech} ))}
{feat1.links && (
{feat1.links.map((l) => ( ↗ {l.name} ))}
)}
{/* 02 — Gazelle (Span 2x1) */} handleFeatureClick(feat2.name)} >
{feat2.logo && ( )}

{feat2.name}

{feat2.description}

{feat2.tasks.slice(0, 4).map((task) => (
{task.name}
))}
{/* 03 — Experience (Span 1x1) */}

Experience

{experiences.slice(0, 2).map((exp, i) => (
{exp.position}
{exp.company}
))}
{/* 04 — Education (Span 1x1) */}

Education

{education.slice(0, 2).map((edu, i) => (
{edu.degree}
{edu.school.split(" ").slice(-2).join(" ")}
))}
{/* 05 — Skills (Span 2x1) */}

Arsenal

{skills.length} TECHNOLOGIES
{topSkills.map((skill, i) => ( {skill} ))} {skills.length > 10 && ( +{skills.length - 10} more )}
{/* 06 — About (Span 2x1) */}

Beyond Code

Languages
{languages.map((lang) => ( {lang.name} {lang.level} ))}
Interests
{interests.map((interest) => ( {interest} ))}
{/* ── Scroll hint ───────────────────────────────────────────── */}
Scroll to explore
); }