/* Portfolio Components — Phan Phuoc Thinh */ /* ─── Doodle SVG Decorations ─── */ function DoodleBrackets({ style, color = 'currentColor' }) { return ( ); } function DoodleArrow({ style, color = 'currentColor' }) { return ( ); } function DoodleCircle({ style, color = 'currentColor', size = 40 }) { return ( ); } function DoodleCode({ style, color = 'currentColor' }) { return ( ); } function DoodleChart({ style, color = 'currentColor' }) { return ( ); } function DoodleStar({ style, color = 'currentColor', size = 24 }) { return ( ); } /* ─── Navigation ─── */ function Nav({ activeSection, onNavigate, tweaks }) { const navItems = [ { id: 'home', label: 'Home', icon: 'M3 12l9-9 9 9M5 10v10a1 1 0 001 1h3a1 1 0 001-1v-4h4v4a1 1 0 001 1h3a1 1 0 001-1V10' }, { id: 'about', label: 'About', icon: 'M12 11a4 4 0 100-8 4 4 0 000 8zM4 21v-1a6 6 0 0112 0v1M16 21v-1a6 6 0 016 0v1' }, { id: 'experience', label: 'Experience', icon: 'M20 7H4a2 2 0 00-2 2v10a2 2 0 002 2h16a2 2 0 002-2V9a2 2 0 00-2-2zM16 7V5a2 2 0 00-2-2h-4a2 2 0 00-2 2v2' }, { id: 'projects', label: 'Projects', icon: 'M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z' }, { id: 'contact', label: 'Contact', icon: 'M3 5h18a2 2 0 012 2v10a2 2 0 01-2 2H3a2 2 0 01-2-2V7a2 2 0 012-2zm0 0l9 6 9-6' }]; const primary = tweaks.primaryColor; return ( ); } /* ─── Project Card ─── */ function ProjectCard({ project, index, onClick, tweaks }) { const [hovered, setHovered] = React.useState(false); const primary = tweaks.primaryColor; return (
onClick(project)} onMouseEnter={() => setHovered(true)} onMouseLeave={() => setHovered(false)} style={{ position: 'relative', width: '100%', aspectRatio: '368/280', borderRadius: 16, overflow: 'hidden', cursor: 'pointer', background: 'rgba(57,62,70,0.5)', backdropFilter: 'blur(4px)', transform: hovered ? 'translateY(-8px) scale(1.02)' : 'translateY(0)', boxShadow: hovered ? `0 20px 40px rgba(0,0,0,0.4), 0 0 0 1px ${primary}33` : '0 4px 20px rgba(0,0,0,0.2)', transition: 'all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94)' }}>
{project.title}
{project.category}
{project.title}
); } /* ─── Skill Badge ─── */ function SkillBadge({ label, tweaks }) { const [hovered, setHovered] = React.useState(false); return ( setHovered(true)} onMouseLeave={() => setHovered(false)} style={{ display: 'inline-block', padding: '8px 20px', borderRadius: 24, background: hovered ? tweaks.primaryColor : 'rgba(57,62,70,0.6)', color: hovered ? '#0D1B2A' : '#EEE', fontFamily: 'Poppins, sans-serif', fontWeight: 600, fontSize: 14, transition: 'all 0.3s ease', cursor: 'default', border: `1px solid ${hovered ? tweaks.primaryColor : 'rgba(238,238,238,0.15)'}` }}> {label}); } /* ─── Footer ─── */ function Footer({ onNavigate, tweaks }) { const primary = tweaks.primaryColor; const links = [ { id: 'home', label: 'Home' }, { id: 'about', label: 'About' }, { id: 'experience', label: 'Experience' }, { id: 'projects', label: 'Projects' }, { id: 'contact', label: 'Contact' }]; const socials = [ { label: 'GitHub', icon: 'M12 2C6.477 2 2 6.477 2 12c0 4.42 2.865 8.166 6.839 9.489.5.092.682-.217.682-.482 0-.237-.009-.866-.013-1.7-2.782.604-3.369-1.34-3.369-1.34-.454-1.156-1.11-1.463-1.11-1.463-.908-.62.069-.608.069-.608 1.003.07 1.531 1.03 1.531 1.03.892 1.529 2.341 1.087 2.91.831.092-.646.35-1.086.636-1.336-2.22-.253-4.555-1.11-4.555-4.943 0-1.091.39-1.984 1.029-2.683-.103-.253-.446-1.27.098-2.647 0 0 .84-.268 2.75 1.026A9.578 9.578 0 0112 6.836a9.59 9.59 0 012.504.337c1.909-1.294 2.747-1.026 2.747-1.026.546 1.377.203 2.394.1 2.647.64.699 1.028 1.592 1.028 2.683 0 3.842-2.339 4.687-4.566 4.935.359.309.678.919.678 1.852 0 1.336-.012 2.415-.012 2.743 0 .267.18.579.688.481C19.137 20.164 22 16.418 22 12c0-5.523-4.477-10-10-10z' }, { label: 'LinkedIn', icon: 'M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.064 2.064 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z' }, { label: 'Email', icon: 'M3 5h18a2 2 0 012 2v10a2 2 0 01-2 2H3a2 2 0 01-2-2V7a2 2 0 012-2zm0 0l9 6 9-6' }]; return ( ); } /* ─── Scroll Reveal ─── */ function Reveal({ children, delay = 0 }) { const ref = React.useRef(null); const [visible, setVisible] = React.useState(false); React.useEffect(() => { const el = ref.current; if (!el) return; const obs = new IntersectionObserver(([e]) => { if (e.isIntersecting) {setVisible(true);obs.disconnect();} }, { threshold: 0.15 }); obs.observe(el); return () => obs.disconnect(); }, []); return (
{children}
); } Object.assign(window, { DoodleBrackets, DoodleArrow, DoodleCircle, DoodleCode, DoodleChart, DoodleStar, Nav, ProjectCard, SkillBadge, Footer, Reveal });