File manager - Edit - /home/webapp69.cm.in.th/u69319090005/Portfolio/index.html
Back
<!DOCTYPE html> <html lang="th" class="scroll-smooth"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>พอร์ตโฟลิโอส่วนตัว | จีรพัฒน์ สายทอง - Full-Stack Developer & UI/UX Designer</title> <!-- SEO Meta Tags --> <meta name="description" content="พอร์ตโฟลิโอส่วนตัวของ จีรพัฒน์ สายทอง นักพัฒนาฟูลสแต็กระดับมืออาชีพ และนักออกแบบอินเตอร์เฟส (UI/UX) ที่มุ่งมั่นสร้างสรรค์เว็บแอปพลิเคชันที่ทันสมัยและมีประสิทธิภาพสูง"> <meta name="keywords" content="จีรพัฒน์ สายทอง, พอร์ตโฟลิโอ, Full-Stack Developer, UI/UX Designer, React, Node.js, Tailwind CSS, พอร์ตโฟลิโอภาษาไทย, BabyMonster Theme"> <meta name="author" content="จีรพัฒน์ สายทอง"> <!-- CSS Stylesheet --> <link rel="stylesheet" href="style.css"> <!-- Tailwind CSS CDN --> <script src="https://cdn.tailwindcss.com"></script> <!-- Tailwind Configuration --> <script> tailwind.config = { darkMode: 'class', theme: { extend: { fontFamily: { sans: ['Inter', 'sans-serif'], display: ['Outfit', 'sans-serif'], }, colors: { brand: { 50: '#faf5ff', 100: '#f3e8ff', 500: '#a855f7', /* KWANGYA Neon Purple */ 600: '#9333ea', 700: '#7e22ce', 900: '#581c87', }, cyber: { black: '#030303', blue: '#00d2ff', /* Electric Blue */ silver: '#e2e8f0', /* Silver */ } }, boxShadow: { 'glass-light': '0 8px 32px 0 rgba(168, 85, 247, 0.04)', 'glass-dark': '0 8px 32px 0 rgba(0, 0, 0, 0.5)', } } } } </script> <!-- Lucide Icons CDN --> <script src="https://unpkg.com/lucide@latest"></script> </head> <body class="intro-active bg-slate-50 text-slate-800 dark:bg-[#030303] dark:text-slate-100 min-h-screen relative overflow-x-hidden selection:bg-brand-500/30 selection:text-brand-600"> <!-- Full Screen Intro Overlay --> <div id="intro-overlay" class="intro-overlay"> <!-- Ambient glowing light --> <div id="intro-glow" class="intro-ambient-glow"></div> <!-- Canvas for Digital Particles / Cyber Animation --> <canvas id="intro-canvas" class="absolute inset-0 w-full h-full pointer-events-none z-[2]"></canvas> <!-- MP4 Video Player Element --> <div id="intro-video-container" class="intro-video-container"> <video id="intro-video-element" muted playsinline> <!-- Mobile Video (New MP4 for screens <= 767px) --> <source src="ssstik.io_@jenyyifer_1783065556094.mp4" media="(max-width: 767px)" type="video/mp4"> <!-- Desktop Video (Latest MP4 for screens >= 768px) --> <source src="ssstik.io_@_yunnabi__1783067177044.mp4" media="(min-width: 768px)" type="video/mp4"> <!-- Fallback online loop video in case local mp4 is missing --> <source src="https://assets.mixkit.co/videos/preview/mixkit-futuristic-subway-station-with-neon-lights-4413-large.mp4" type="video/mp4"> </video> </div> <!-- Centered Stage Content --> <div class="relative z-10 text-center flex flex-col items-center justify-center"> <!-- Stage 1: Big Logo J Glitch --> <h1 id="intro-logo-j" class="intro-logo-j" data-text="J">J</h1> <!-- Stage 2: JEERAPAT.S Full Logo --> <h1 id="intro-logo-full" class="glitch-logo" data-text="JEERAPAT.S">JEERAPAT.S</h1> <!-- Stage 4: WELCOME TO MY PORTFOLIO --> <div id="intro-welcome-container" class="intro-welcome-container"> <h2 id="intro-welcome-text" class="intro-welcome-title"></h2> </div> </div> <!-- Skip button --> <button id="intro-skip" class="intro-skip-btn">Skip Intro</button> </div> <!-- Dynamic Image Background for Dark Mode --> <div id="dynamic-bg-container" class="fixed top-0 left-0 w-full h-full pointer-events-none z-[-2] overflow-hidden opacity-0 dark:opacity-100 transition-opacity duration-1000 ease-in-out"> <!-- Gradient Overlay for readability --> <div class="absolute inset-0 bg-gradient-to-b from-[#030303]/90 via-[#030303]/70 to-[#030303]/95 z-10"></div> <img src="bg-dark.jpg" onerror="this.src='https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?q=80&w=2564&auto=format&fit=crop'" alt="Dynamic Background" class="absolute inset-0 w-full h-full object-cover scale-105 opacity-50 mix-blend-screen transition-transform duration-[3000ms] ease-out origin-center" id="dynamic-bg-img"> </div> <!-- Dynamic Image Background for Light Mode --> <div id="dynamic-bg-container-light" class="fixed top-0 left-0 w-full h-full pointer-events-none z-[-2] overflow-hidden opacity-100 dark:opacity-0 transition-opacity duration-1000 ease-in-out"> <!-- Gradient Overlay for readability --> <div class="absolute inset-0 bg-gradient-to-b from-slate-50/95 via-slate-50/80 to-slate-50/95 z-10"></div> <img src="bg-.jpg" onerror="this.src='https://images.unsplash.com/photo-1557683316-973673baf926?q=80&w=2564&auto=format&fit=crop'" alt="Dynamic Light Background" class="absolute inset-0 w-full h-full object-cover scale-100 opacity-40 transition-transform duration-[3000ms] ease-out origin-center" id="dynamic-bg-img-light"> </div> <!-- Cyber Grid Background Overlay --> <div class="fixed top-0 left-0 w-full h-full pointer-events-none z-[-1.5] cyber-grid"></div> <!-- Cyber Particles Canvas --> <canvas id="cyber-particles" class="fixed top-0 left-0 w-full h-full pointer-events-none z-[-1.2]"></canvas> <!-- KWANGYA Glowing Neon Radial Backgrounds with Slow Floating Animations --> <div class="fixed top-0 left-0 w-full h-full pointer-events-none z-[-1] overflow-hidden transition-opacity duration-700 dark:opacity-60"> <div class="absolute top-[-10%] left-[-10%] w-[50vw] h-[50vw] rounded-full bg-brand-500/10 dark:bg-brand-500/10 blur-[120px] animate-slow-glow-1"></div> <div class="absolute bottom-[-10%] right-[-10%] w-[60vw] h-[60vw] rounded-full bg-blue-500/10 dark:bg-blue-950/10 blur-[150px] animate-slow-glow-2"></div> </div> <!-- ==================== NAVIGATION BAR ==================== --> <header id="navbar" class="fixed top-0 left-0 w-full z-50 transition-all duration-300 border-b border-transparent bg-transparent"> <div class="max-w-7xl mx-auto px-6 h-20 flex items-center justify-between"> <!-- Brand Logo / Monogram --> <a href="#hero" class="flex items-center space-x-3 group" aria-label="หน้าแรก"> <div class="w-10 h-10 rounded-xl bg-gradient-to-tr from-brand-600 to-blue-500 flex items-center justify-center text-white font-bold text-lg shadow-md group-hover:scale-105 transition-transform duration-300"> J </div> <span class="font-display font-bold text-xl tracking-tight text-slate-900 dark:text-white transition-colors duration-300"> JEERAPAT<span class="text-brand-500">.S</span> </span> </a> <!-- Desktop Navigation Links (>= 1024px) --> <nav class="hidden lg:flex items-center space-x-8"> <a href="#hero" class="nav-link font-medium text-slate-600 hover:text-brand-500 dark:text-slate-300 dark:hover:text-brand-500 text-sm transition-colors duration-300 relative py-1 px-1" id="nav-hero">หน้าแรก</a> <a href="#about" class="nav-link font-medium text-slate-600 hover:text-brand-500 dark:text-slate-300 dark:hover:text-brand-500 text-sm transition-colors duration-300 relative py-1 px-1" id="nav-about">เกี่ยวกับฉัน</a> <a href="#projects" class="nav-link font-medium text-slate-600 hover:text-brand-500 dark:text-slate-300 dark:hover:text-brand-500 text-sm transition-colors duration-300 relative py-1 px-1" id="nav-projects">ผลงานเด่น</a> <a href="#contact" class="nav-link font-medium text-slate-600 hover:text-brand-500 dark:text-slate-300 dark:hover:text-brand-500 text-sm transition-colors duration-300 relative py-1 px-1" id="nav-contact">ติดต่อฉัน</a> </nav> <!-- Action Area: Theme Toggle, Language & Hamburger --> <div class="flex items-center space-x-3 sm:space-x-4"> <!-- Language Switcher (Desktop/Tablet) --> <div class="hidden sm:flex items-center bg-white/40 dark:bg-zinc-900/40 border border-slate-200/60 dark:border-zinc-800/60 rounded-xl p-1 shadow-sm"> <button id="btn-lang-th" onclick="setLanguage('th')" class="px-2.5 py-1.5 rounded-lg text-xs font-bold bg-brand-50 text-brand-600 dark:bg-brand-500/20 dark:text-brand-500 transition-all duration-300 min-w-[36px]" aria-label="ภาษาไทย">TH</button> <button id="btn-lang-en" onclick="setLanguage('en')" class="px-2.5 py-1.5 rounded-lg text-xs font-bold text-slate-500 hover:text-brand-600 dark:text-slate-400 dark:hover:text-brand-500 hover:bg-slate-100 dark:hover:bg-zinc-800 transition-all duration-300 min-w-[36px]" aria-label="English">EN</button> <button id="btn-lang-ko" onclick="setLanguage('ko')" class="px-2.5 py-1.5 rounded-lg text-xs font-bold text-slate-500 hover:text-brand-600 dark:text-slate-400 dark:hover:text-brand-500 hover:bg-slate-100 dark:hover:bg-zinc-800 transition-all duration-300 min-w-[36px]" aria-label="한국어">KR</button> </div> <!-- Dark Mode Toggle Button --> <button id="theme-toggle" class="p-3 rounded-xl border border-slate-200/60 bg-white/40 dark:bg-zinc-900/40 dark:border-zinc-800/60 text-slate-700 dark:text-slate-300 hover:text-brand-500 dark:hover:text-brand-500 hover:shadow-sm focus:outline-none transition-all duration-300 cursor-pointer min-h-[44px] min-w-[44px]" aria-label="สลับธีม"> <i data-lucide="moon" class="w-[18px] h-[18px] transition-transform duration-500 block dark:hidden"></i> <i data-lucide="sun" class="w-[18px] h-[18px] transition-transform duration-500 hidden dark:block"></i> </button> <!-- Mobile/Tablet Hamburger Trigger (< 1024px) --> <button id="mobile-menu-trigger" class="lg:hidden p-3 rounded-xl border border-slate-200/60 bg-white/40 dark:bg-zinc-900/40 dark:border-zinc-800/60 text-slate-700 dark:text-slate-300 hover:text-brand-500 dark:hover:text-brand-500 focus:outline-none transition-all duration-300 cursor-pointer min-h-[44px] min-w-[44px]" aria-label="เปิดเมนูนำทาง"> <i data-lucide="menu" id="hamburger-icon" class="w-5 h-5"></i> </button> </div> </div> </header> <!-- Mobile Drawer Menu Overlay --> <div id="mobile-menu-drawer" class="fixed inset-0 z-50 pointer-events-none transition-all duration-300" role="dialog" aria-modal="true"> <!-- Backdrop Blur overlay --> <div id="mobile-menu-backdrop" class="absolute inset-0 bg-slate-900/20 dark:bg-black/60 backdrop-blur-sm opacity-0 transition-opacity duration-300 pointer-events-none"></div> <!-- Drawer Container --> <div id="mobile-menu-content" class="absolute right-0 top-0 h-full w-[280px] max-w-full bg-white dark:bg-[#09090b] border-l border-slate-200/60 dark:border-zinc-850 shadow-2xl p-6 flex flex-col justify-between transform translate-x-full transition-transform duration-300 pointer-events-auto"> <div> <div class="flex items-center justify-between pb-6 border-b border-slate-100 dark:border-zinc-800"> <span class="font-display font-bold text-lg text-slate-900 dark:text-white">เมนูนำทาง</span> <button id="mobile-menu-close" class="p-2 rounded-lg text-slate-500 hover:text-brand-500 dark:text-slate-400 dark:hover:text-brand-500 focus:outline-none cursor-pointer min-h-[40px] min-w-[40px]" aria-label="ปิดเมนูนำทาง"> <i data-lucide="x" class="w-5 h-5"></i> </button> </div> <nav class="flex flex-col space-y-4 mt-8"> <a href="#hero" class="mobile-nav-link text-base font-semibold text-slate-600 dark:text-slate-300 hover:text-brand-500 dark:hover:text-brand-500 py-3 px-4 rounded-xl hover:bg-slate-50 dark:hover:bg-zinc-850 transition-all duration-300" id="m-nav-hero">หน้าแรก</a> <a href="#about" class="mobile-nav-link text-base font-semibold text-slate-600 dark:text-slate-300 hover:text-brand-500 dark:hover:text-brand-500 py-3 px-4 rounded-xl hover:bg-slate-50 dark:hover:bg-zinc-850 transition-all duration-300" id="m-nav-about">เกี่ยวกับฉัน</a> <a href="#projects" class="mobile-nav-link text-base font-semibold text-slate-600 dark:text-slate-300 hover:text-brand-500 dark:hover:text-brand-500 py-3 px-4 rounded-xl hover:bg-slate-50 dark:hover:bg-zinc-850 transition-all duration-300" id="m-nav-projects">ผลงานเด่น</a> <a href="#contact" class="mobile-nav-link text-base font-semibold text-slate-600 dark:text-slate-300 hover:text-brand-500 dark:hover:text-brand-500 py-3 px-4 rounded-xl hover:bg-slate-50 dark:hover:bg-zinc-850 transition-all duration-300" id="m-nav-contact">ติดต่อฉัน</a> </nav> </div> <div class="pt-6 border-t border-slate-100 dark:border-zinc-800"> <!-- Language Switcher (Mobile) --> <div class="flex sm:hidden items-center justify-center space-x-1 bg-slate-100 dark:bg-zinc-900/60 rounded-xl p-1.5 mb-6"> <button id="m-btn-lang-th" onclick="setLanguage('th')" class="flex-1 py-2 rounded-lg text-xs font-bold bg-white dark:bg-zinc-800 text-brand-600 dark:text-brand-500 shadow-sm transition-all duration-300" aria-label="ภาษาไทย">TH</button> <button id="m-btn-lang-en" onclick="setLanguage('en')" class="flex-1 py-2 rounded-lg text-xs font-bold text-slate-500 hover:text-brand-600 dark:text-slate-400 dark:hover:text-brand-500 hover:bg-white dark:hover:bg-zinc-800 transition-all duration-300" aria-label="English">EN</button> <button id="m-btn-lang-ko" onclick="setLanguage('ko')" class="flex-1 py-2 rounded-lg text-xs font-bold text-slate-500 hover:text-brand-600 dark:text-slate-400 dark:hover:text-brand-500 hover:bg-white dark:hover:bg-zinc-800 transition-all duration-300" aria-label="한국어">KR</button> </div> <p class="text-xs text-slate-400 dark:text-slate-500 text-center">© 2026 จีรพัฒน์ สายทอง.<br>สงวนลิขสิทธิ์ทั้งหมด.</p> </div> </div> </div> <!-- ==================== HERO SECTION ==================== --> <section id="hero" class="min-h-screen flex items-center justify-center pt-24 pb-16 px-6 relative"> <div class="max-w-7xl mx-auto w-full grid grid-cols-1 lg:grid-cols-2 gap-12 lg:gap-8 items-center"> <!-- Left Column: Copywriting --> <div class="flex flex-col space-y-6 text-center lg:text-left"> <!-- Quick Badge --> <div class="inline-flex items-center self-center lg:self-start space-x-2 bg-brand-50/80 dark:bg-brand-500/10 border border-brand-500/20 text-brand-600 dark:text-brand-500 py-1.5 px-3 rounded-full text-xs font-semibold tracking-wide animate-pulse"> <span class="w-1.5 h-1.5 rounded-full bg-brand-500"></span> <span>พร้อมรับงานพัฒนาและร่วมงานอิสระ</span> </div> <!-- Main Title Area --> <div class="space-y-3"> <span class="text-slate-500 dark:text-slate-400 font-display font-medium text-lg md:text-xl block tracking-wide">ยินดีต้อนรับสู่พอร์ตโฟลิโอของฉัน</span> <h1 class="text-4xl sm:text-5xl md:text-6xl lg:text-7xl font-display font-extrabold tracking-tight leading-none text-slate-900 dark:text-white"> จีรพัฒน์ <span class="text-transparent bg-clip-text bg-gradient-to-r from-brand-500 to-blue-500">สายทอง</span> </h1> <!-- Dynamic Text Rotator (Roles) --> <div class="text-xl md:text-2xl lg:text-3xl font-display font-semibold text-slate-600 dark:text-slate-300 h-10 flex items-center justify-center lg:justify-start"> <span class="mr-2">ตำแหน่ง:</span> <span id="role-text" class="text-brand-600 dark:text-brand-500 border-r-2 border-brand-500 pr-1 animate-pulse font-bold">Full-Stack Developer</span> </div> </div> <!-- Slogan & Subtext --> <p class="text-base sm:text-lg text-slate-600 dark:text-slate-455 max-w-lg mx-auto lg:mx-0 leading-relaxed font-light"> สร้างสรรค์เว็บแอปพลิเคชันและอินเตอร์เฟสยุคใหม่ที่เต็มเปี่ยมไปด้วยเอกลักษณ์ สวยงามสไตล์ Minimalist สะอาดตา และมีประสิทธิภาพสูง รองรับระบบ Responsive สมบูรณ์แบบบนทุกหน้าจอ </p> <!-- Touch Targets Buttons (CTA) --> <div class="flex flex-col sm:flex-row items-center justify-center lg:justify-start gap-4 pt-4"> <a href="#projects" class="w-full sm:w-auto px-8 py-3.5 rounded-xl bg-brand-600 text-white hover:bg-brand-700 dark:bg-brand-500 dark:text-black dark:hover:bg-brand-600 font-bold shadow-lg shadow-brand-500/10 hover:shadow-brand-500/20 hover:-translate-y-0.5 transition-all duration-300 text-center min-h-[48px] flex items-center justify-center"> ดูผลงานของฉัน </a> <a href="#contact" class="w-full sm:w-auto px-8 py-3.5 rounded-xl border border-slate-300/80 bg-white/50 hover:bg-slate-100 dark:border-zinc-800 dark:bg-zinc-900/50 dark:hover:bg-zinc-800/80 text-slate-700 dark:text-slate-300 font-semibold hover:-translate-y-0.5 transition-all duration-300 text-center min-h-[48px] flex items-center justify-center"> ติดต่อฉัน </a> </div> <!-- Social Icons Row in Hero --> <div class="flex items-center justify-center lg:justify-start space-x-5 pt-6 text-slate-400 dark:text-slate-500"> <a href="https://github.com" target="_blank" rel="noopener noreferrer" class="hover:text-brand-500 dark:hover:text-brand-500 hover:scale-110 transition-all duration-300 p-2" aria-label="GitHub"> <i data-lucide="github" class="w-5 h-5"></i> </a> <a href="https://linkedin.com" target="_blank" rel="noopener noreferrer" class="hover:text-brand-500 dark:hover:text-brand-500 hover:scale-110 transition-all duration-300 p-2" aria-label="LinkedIn"> <i data-lucide="linkedin" class="w-5 h-5"></i> </a> <a href="mailto:cirphathnsaythxng44@gmail.com" class="hover:text-brand-500 dark:hover:text-brand-500 hover:scale-110 transition-all duration-300 p-2" aria-label="อีเมล"> <i data-lucide="mail" class="w-5 h-5"></i> </a> </div> </div> <!-- Right Column: Premium Framed Profile Picture Card in KWANGYA Aesthetic --> <div class="flex justify-center items-center relative lg:pl-8"> <!-- Glowing Purple/Blue Radial Backplate --> <div class="absolute w-[320px] h-[320px] rounded-full bg-gradient-to-tr from-brand-500/20 to-blue-600/10 dark:from-brand-500/15 dark:to-zinc-950/20 blur-[80px] animate-float-slow"></div> <!-- Glassmorphic Styled Framed Card holding Jeerapat's photo --> <div class="relative w-full max-w-[340px] sm:max-w-[370px] aspect-[3/4] rounded-[28px] p-3 bg-white/50 dark:bg-zinc-900/50 border border-slate-200/50 dark:border-zinc-800/50 glass-card shadow-glass-light dark:shadow-glass-dark hover:scale-[1.03] hover:border-brand-500/40 transition-all duration-500 animate-float"> <!-- Inner image block with interactive shadow overlay --> <div class="w-full h-full rounded-[20px] overflow-hidden relative group"> <img src="profile.jpg" alt="จีรพัฒน์ สายทอง" class="w-full h-full object-cover transition-transform duration-700 group-hover:scale-105"> <!-- Dark Gradient Vignette for K-pop feel --> <div class="absolute inset-0 bg-gradient-to-t from-zinc-950/80 via-zinc-950/20 to-transparent opacity-85"></div> <!-- Sleek overlay badge holding core brand identifier --> <div class="absolute bottom-5 left-5 right-5 p-4 rounded-xl bg-black/60 backdrop-blur-md border border-white/10 text-left"> <span class="text-[10px] font-bold text-brand-500 uppercase tracking-widest block mb-1">PROFESSIONAL DEV</span> <h3 class="font-display font-extrabold text-base sm:text-lg text-white">จีรพัฒน์ สายทอง</h3> </div> </div> <!-- Decorative floating emblems (atoms, brackets) representing development --> <div class="absolute -top-4 -right-4 w-12 h-12 rounded-2xl bg-zinc-950/90 border border-brand-500 text-brand-500 flex items-center justify-center shadow-lg animate-float-slow"> <i data-lucide="atom" class="w-6 h-6"></i> </div> <div class="absolute -bottom-3 -left-3 w-10 h-10 rounded-xl bg-white dark:bg-zinc-900 border border-slate-200 dark:border-zinc-800 text-brand-500 flex items-center justify-center shadow-md animate-float" style="animation-delay: 2.2s"> <i data-lucide="braces" class="w-5 h-5"></i> </div> </div> </div> </div> </section> <!-- ==================== ABOUT ME SECTION ==================== --> <section id="about" class="py-24 px-6 relative bg-white/30 dark:bg-zinc-900/30 border-y border-slate-200/30 dark:border-zinc-800/30"> <div class="max-w-7xl mx-auto"> <!-- Section Header --> <div class="text-center space-y-4 mb-16"> <h2 class="text-3xl md:text-4xl font-display font-extrabold tracking-tight text-slate-900 dark:text-white"> เกี่ยวกับ <span class="text-brand-500">ฉัน</span> </h2> <div class="w-12 h-1 bg-brand-500 mx-auto rounded-full"></div> <p class="text-slate-500 dark:text-slate-400 max-w-xl mx-auto text-sm md:text-base font-light leading-relaxed"> เรื่องราวความเป็นมา ประวัติการทำงาน การศึกษา และเทคโนโลยีคอมพิวเตอร์ที่ผมเลือกสรรมาใช้งานในการสรรสร้างผลงานในแต่ละวัน </p> </div> <!-- About Main Grid Layout: Bio & Timeline --> <div class="grid grid-cols-1 lg:grid-cols-12 gap-12 items-start mb-20"> <!-- Story Bio (Left Columns) --> <div class="lg:col-span-5 space-y-6"> <div class="p-8 rounded-3xl bg-white/60 dark:bg-zinc-900/60 border border-slate-200/60 dark:border-zinc-800/60 glass-card shadow-glass-light dark:shadow-glass-dark"> <h3 class="font-display font-bold text-2xl text-slate-900 dark:text-white mb-4">เรื่องราวของผม</h3> <p class="text-slate-600 dark:text-slate-350 leading-relaxed text-sm sm:text-base font-light space-y-4"> ผมชื่อ <strong>จีรพัฒน์ สายทอง</strong> เป็น <strong>นักพัฒนา Full-Stack Developer</strong> ที่มุ่งเน้นการสร้างสรรค์หน้าเว็บสไตล์โมเดิร์นคลีน ทันสมัย เรียบร้อย และรองรับอนิเมชั่นระดับพรีเมียม <br><br> ปรัชญาหลักในการพัฒนาโปรเจกต์ของผมยึดหลัก <strong>"ความเรียบง่ายแต่เปี่ยมด้วยคุณภาพ" (Elegant Minimalism)</strong> คัดกรององค์ประกอบที่ไม่จำเป็นออกเพื่อให้สิ่งสำคัญแสดงผลอย่างเต็มพิกัด คุมธีมสีเข้มสไตล์หรูหรา และจัดวางระบบตอบสนองอย่างรวดเร็ว (Fully Responsive) เพื่ออำนวยความสะดวกให้ผู้ใช้อย่างสูงสุด </p> <!-- Direct Profile Details Badge --> <div class="grid grid-cols-2 gap-4 mt-8 pt-6 border-t border-slate-100 dark:border-zinc-800 text-sm"> <div> <span class="text-slate-400 dark:text-slate-500 block text-xs">ที่ตั้งสำนักงาน</span> <span class="font-semibold text-slate-700 dark:text-slate-300">23 หมู่ 3 ต.หัวทุ่ง อ.ลอง จ.แพร่ ประเทศไทย</span> </div> <div> <span class="text-slate-400 dark:text-slate-500 block text-xs">อีเมลหลัก</span> <span class="font-semibold text-slate-700 dark:text-slate-300">cirphathnsaythxng44@gmail.com</span> </div> <div> <span class="text-slate-400 dark:text-slate-500 block text-xs">สถานะงาน</span> <span class="font-semibold text-brand-600 dark:text-brand-500">กำลังหางาน</span> </div> <div> <span class="text-slate-400 dark:text-slate-500 block text-xs">ภาษา</span> <span class="font-semibold text-slate-700 dark:text-slate-300">ไทย, อังกฤษ</span> </div> </div> </div> </div> <!-- Experience/Education Timeline (Right Columns) --> <div class="lg:col-span-7 space-y-6"> <h3 class="font-display font-bold text-2xl text-slate-900 dark:text-white pl-4">ประสบการณ์และการศึกษา</h3> <div class="relative border-l-2 border-slate-200/80 dark:border-zinc-850 ml-4 space-y-8 py-2"> <!-- Timeline Item 1 --> <div class="relative pl-8 group"> <!-- Bullet Dot --> <div class="absolute -left-[9px] top-1.5 w-4 h-4 rounded-full bg-brand-500 border-4 border-white dark:border-[#030303] group-hover:scale-125 transition-transform duration-300"></div> <!-- Timeline Card --> <div class="p-6 rounded-2xl bg-white/50 dark:bg-zinc-900/50 border border-slate-200/50 dark:border-zinc-800/50 shadow-sm hover:shadow-md transition-all duration-300"> <span class="inline-block text-xs font-semibold text-brand-600 dark:text-brand-500 bg-brand-50/80 dark:bg-brand-500/10 py-1 px-2.5 rounded-full mb-3">2023 - 2025</span> <h4 class="font-display font-bold text-lg text-slate-900 dark:text-white">ประกาศนียบัตรวิชาชีพ (ปวช.) สาขาวิชาเทคโนโลยีคอมพิวเตอร์</h4> <p class="text-slate-500 dark:text-slate-400 text-sm font-medium mb-2">วิทยาลัยเทคนิคแพร่</p> <p class="text-slate-600 dark:text-slate-400 text-xs sm:text-sm font-light leading-relaxed"> ศึกษาและฝึกปฏิบัติงานด้านคอมพิวเตอร์ ทั้งการประกอบ ซ่อมบำรุง และแก้ไขปัญหาคอมพิวเตอร์ ฮาร์ดแวร์ ซอฟต์แวร์ ระบบเครือข่าย รวมถึงการติดตั้งระบบปฏิบัติการและโปรแกรมต่าง ๆ มีประสบการณ์ฝึกปฏิบัติการตรวจเช็ก ซ่อมบำรุง และแก้ไขปัญหาเครื่องพิมพ์เบื้องต้น พร้อมพัฒนาทักษะการวิเคราะห์ปัญหาและการบริการผู้ใช้งาน </p> </div> </div> <!-- Timeline Item 2 --> <div class="relative pl-8 group"> <!-- Bullet Dot --> <div class="absolute -left-[9px] top-1.5 w-4 h-4 rounded-full bg-brand-500 border-4 border-white dark:border-[#030303] group-hover:scale-125 transition-transform duration-300"></div> <!-- Timeline Card --> <div class="p-6 rounded-2xl bg-white/50 dark:bg-zinc-900/50 border border-slate-200/50 dark:border-zinc-800/50 shadow-sm hover:shadow-md transition-all duration-300"> <span class="inline-block text-xs font-semibold text-rose-600 dark:text-rose-455 bg-rose-50/80 dark:bg-brand-500/10 py-1 px-2.5 rounded-full mb-3">2019 - 2022</span> <h4 class="font-display font-bold text-lg text-slate-900 dark:text-white">จบการศึกษาระดับมัธยมศึกษาตอนต้น</h4> <p class="text-slate-500 dark:text-slate-400 text-sm font-medium mb-2">โรงเรียนบ้านไผ่ล้อม</p> <p class="text-slate-600 dark:text-slate-400 text-xs sm:text-sm font-light leading-relaxed"> สำเร็จการศึกษาระดับมัธยมศึกษาตอนต้น พร้อมพัฒนาทักษะด้านเทคโนโลยีสารสนเทศ การใช้งานคอมพิวเตอร์เบื้องต้น และการทำงานร่วมกับผู้อื่น ซึ่งเป็นพื้นฐานสำคัญในการศึกษาต่อสายอาชีพด้านเทคโนโลยี </p> </div> </div> </div> </div> </div> <!-- ==================== TECH STACK & SKILLS GRID ==================== --> <div class="mt-20 pt-16 border-t border-slate-200/60 dark:border-zinc-800/60"> <!-- Tab controls to select skill category dynamically --> <div class="flex flex-col sm:flex-row items-center justify-between gap-6 mb-10"> <h3 class="font-display font-bold text-2xl text-slate-900 dark:text-white">เทคโนโลยีที่เชี่ยวชาญ</h3> <!-- Category Selectors with touch-padding --> <div class="flex flex-wrap items-center bg-slate-100/80 dark:bg-zinc-900/80 border border-slate-200/30 dark:border-zinc-850 p-1.5 rounded-2xl gap-1"> <button onclick="filterSkills('all')" id="tab-all" class="skill-tab-active px-4 py-2 rounded-xl text-xs sm:text-sm font-semibold text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white cursor-pointer min-h-[40px] transition-all duration-300"> ทั้งหมด </button> <button onclick="filterSkills('frontend')" id="tab-frontend" class="px-4 py-2 rounded-xl text-xs sm:text-sm font-semibold text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white cursor-pointer min-h-[40px] transition-all duration-300"> ฟรอนต์เอนด์ (Frontend) </button> <button onclick="filterSkills('backend')" id="tab-backend" class="px-4 py-2 rounded-xl text-xs sm:text-sm font-semibold text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white cursor-pointer min-h-[40px] transition-all duration-300"> แบ็กเอนด์ (Backend) </button> <button onclick="filterSkills('tools')" id="tab-tools" class="px-4 py-2 rounded-xl text-xs sm:text-sm font-semibold text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white cursor-pointer min-h-[40px] transition-all duration-300"> เครื่องมือ (Tools) </button> </div> </div> <!-- Skills Badges Grid with Responsive Breakpoints --> <!-- Responsive layout: Mobile 2 columns, Tablet 3 columns, Desktop 5 columns --> <div id="skills-grid" class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 gap-4"> <!-- Skill Card React (Frontend) --> <div class="skill-card p-4 rounded-2xl bg-white/40 dark:bg-zinc-900/40 border border-slate-200/60 dark:border-zinc-800/60 flex items-center space-x-3 hover:scale-105 hover:bg-white dark:hover:bg-zinc-900 hover:border-brand-500/40 hover:shadow-sm cursor-default transition-all duration-300" data-category="frontend"> <div class="w-10 h-10 rounded-xl bg-cyan-500/10 text-cyan-550 flex items-center justify-center"> <i data-lucide="atom" class="w-5 h-5"></i> </div> <div> <h4 class="font-semibold text-slate-800 dark:text-slate-200 text-sm">React.js</h4> <span class="text-slate-400 dark:text-slate-500 text-[10px] uppercase font-bold tracking-wider">Frontend</span> </div> </div> <!-- Skill Card HTML5 (Frontend) --> <div class="skill-card p-4 rounded-2xl bg-white/40 dark:bg-zinc-900/40 border border-slate-200/60 dark:border-zinc-800/60 flex items-center space-x-3 hover:scale-105 hover:bg-white dark:hover:bg-zinc-900 hover:border-brand-500/40 hover:shadow-sm cursor-default transition-all duration-300" data-category="frontend"> <div class="w-10 h-10 rounded-xl bg-orange-500/10 text-orange-500 flex items-center justify-center"> <i data-lucide="code-2" class="w-5 h-5"></i> </div> <div> <h4 class="font-semibold text-slate-800 dark:text-slate-200 text-sm">HTML5 / CSS3</h4> <span class="text-slate-400 dark:text-slate-500 text-[10px] uppercase font-bold tracking-wider">Frontend</span> </div> </div> <!-- Skill Card Tailwind CSS (Frontend) --> <div class="skill-card p-4 rounded-2xl bg-white/40 dark:bg-zinc-900/40 border border-slate-200/60 dark:border-zinc-800/60 flex items-center space-x-3 hover:scale-105 hover:bg-white dark:hover:bg-zinc-900 hover:border-brand-500/40 hover:shadow-sm cursor-default transition-all duration-300" data-category="frontend"> <div class="w-10 h-10 rounded-xl bg-rose-500/10 text-rose-500 flex items-center justify-center"> <i data-lucide="palette" class="w-5 h-5"></i> </div> <div> <h4 class="font-semibold text-slate-800 dark:text-slate-200 text-sm">Tailwind CSS</h4> <span class="text-slate-400 dark:text-slate-500 text-[10px] uppercase font-bold tracking-wider">Frontend</span> </div> </div> <!-- Skill Card TypeScript (Frontend) --> <div class="skill-card p-4 rounded-2xl bg-white/40 dark:bg-zinc-900/40 border border-slate-200/60 dark:border-zinc-800/60 flex items-center space-x-3 hover:scale-105 hover:bg-white dark:hover:bg-zinc-900 hover:border-brand-500/40 hover:shadow-sm cursor-default transition-all duration-300" data-category="frontend"> <div class="w-10 h-10 rounded-xl bg-blue-500/10 text-blue-500 flex items-center justify-center"> <i data-lucide="braces" class="w-5 h-5"></i> </div> <div> <h4 class="font-semibold text-slate-800 dark:text-slate-200 text-sm">TypeScript</h4> <span class="text-slate-400 dark:text-slate-500 text-[10px] uppercase font-bold tracking-wider">Frontend</span> </div> </div> <!-- Skill Card Node.js (Backend) --> <div class="skill-card p-4 rounded-2xl bg-white/40 dark:bg-zinc-900/40 border border-slate-200/60 dark:border-zinc-800/60 flex items-center space-x-3 hover:scale-105 hover:bg-white dark:hover:bg-zinc-900 hover:border-brand-500/40 hover:shadow-sm cursor-default transition-all duration-300" data-category="backend"> <div class="w-10 h-10 rounded-xl bg-emerald-500/10 text-emerald-500 flex items-center justify-center"> <i data-lucide="server" class="w-5 h-5"></i> </div> <div> <h4 class="font-semibold text-slate-800 dark:text-slate-200 text-sm">Node.js</h4> <span class="text-slate-400 dark:text-slate-500 text-[10px] uppercase font-bold tracking-wider">Backend</span> </div> </div> <!-- Skill Card PostgreSQL (Backend) --> <div class="skill-card p-4 rounded-2xl bg-white/40 dark:bg-zinc-900/40 border border-slate-200/60 dark:border-zinc-800/60 flex items-center space-x-3 hover:scale-105 hover:bg-white dark:hover:bg-zinc-900 hover:border-brand-500/40 hover:shadow-sm cursor-default transition-all duration-300" data-category="backend"> <div class="w-10 h-10 rounded-xl bg-blue-600/10 text-blue-600 flex items-center justify-center"> <i data-lucide="database" class="w-5 h-5"></i> </div> <div> <h4 class="font-semibold text-slate-800 dark:text-slate-200 text-sm">PostgreSQL</h4> <span class="text-slate-400 dark:text-slate-500 text-[10px] uppercase font-bold tracking-wider">Backend</span> </div> </div> <!-- Skill Card MongoDB (Backend) --> <div class="skill-card p-4 rounded-2xl bg-white/40 dark:bg-zinc-900/40 border border-slate-200/60 dark:border-zinc-800/60 flex items-center space-x-3 hover:scale-105 hover:bg-white dark:hover:bg-zinc-900 hover:border-brand-500/40 hover:shadow-sm cursor-default transition-all duration-300" data-category="backend"> <div class="w-10 h-10 rounded-xl bg-green-500/10 text-green-500 flex items-center justify-center"> <i data-lucide="layers" class="w-5 h-5"></i> </div> <div> <h4 class="font-semibold text-slate-800 dark:text-slate-200 text-sm">MongoDB</h4> <span class="text-slate-400 dark:text-slate-500 text-[10px] uppercase font-bold tracking-wider">Backend</span> </div> </div> <!-- Skill Card Express.js (Backend) --> <div class="skill-card p-4 rounded-2xl bg-white/40 dark:bg-zinc-900/40 border border-slate-200/60 dark:border-zinc-800/60 flex items-center space-x-3 hover:scale-105 hover:bg-white dark:hover:bg-zinc-900 hover:border-brand-500/40 hover:shadow-sm cursor-default transition-all duration-300" data-category="backend"> <div class="w-10 h-10 rounded-xl bg-zinc-500/10 text-zinc-500 dark:text-zinc-450 flex items-center justify-center"> <i data-lucide="cpu" class="w-5 h-5"></i> </div> <div> <h4 class="font-semibold text-slate-800 dark:text-slate-200 text-sm">Express.js</h4> <span class="text-slate-400 dark:text-slate-500 text-[10px] uppercase font-bold tracking-wider">Backend</span> </div> </div> <!-- Skill Card Git & GitHub (Tools) --> <div class="skill-card p-4 rounded-2xl bg-white/40 dark:bg-zinc-900/40 border border-slate-200/60 dark:border-zinc-800/60 flex items-center space-x-3 hover:scale-105 hover:bg-white dark:hover:bg-zinc-900 hover:border-brand-500/40 hover:shadow-sm cursor-default transition-all duration-300" data-category="tools"> <div class="w-10 h-10 rounded-xl bg-amber-500/10 text-amber-500 flex items-center justify-center"> <i data-lucide="git-branch" class="w-5 h-5"></i> </div> <div> <h4 class="font-semibold text-slate-800 dark:text-slate-200 text-sm">Git & GitHub</h4> <span class="text-slate-400 dark:text-slate-500 text-[10px] uppercase font-bold tracking-wider">Tools</span> </div> </div> <!-- Skill Card Docker (Tools) --> <div class="skill-card p-4 rounded-2xl bg-white/40 dark:bg-zinc-900/40 border border-slate-200/60 dark:border-zinc-800/60 flex items-center space-x-3 hover:scale-105 hover:bg-white dark:hover:bg-zinc-900 hover:border-brand-500/40 hover:shadow-sm cursor-default transition-all duration-300" data-category="tools"> <div class="w-10 h-10 rounded-xl bg-sky-500/10 text-sky-500 flex items-center justify-center"> <i data-lucide="container" class="w-5 h-5"></i> </div> <div> <h4 class="font-semibold text-slate-800 dark:text-slate-200 text-sm">Docker</h4> <span class="text-slate-400 dark:text-slate-500 text-[10px] uppercase font-bold tracking-wider">Tools</span> </div> </div> <!-- Skill Card Figma (Tools) --> <div class="skill-card p-4 rounded-2xl bg-white/40 dark:bg-zinc-900/40 border border-slate-200/60 dark:border-zinc-800/60 flex items-center space-x-3 hover:scale-105 hover:bg-white dark:hover:bg-zinc-900 hover:border-brand-500/40 hover:shadow-sm cursor-default transition-all duration-300" data-category="tools"> <div class="w-10 h-10 rounded-xl bg-purple-500/10 text-purple-500 flex items-center justify-center"> <i data-lucide="figma" class="w-5 h-5"></i> </div> <div> <h4 class="font-semibold text-slate-800 dark:text-slate-200 text-sm">Figma</h4> <span class="text-slate-400 dark:text-slate-500 text-[10px] uppercase font-bold tracking-wider">Tools</span> </div> </div> <!-- Skill Card Webpack/Vite (Tools) --> <div class="skill-card p-4 rounded-2xl bg-white/40 dark:bg-zinc-900/40 border border-slate-200/60 dark:border-zinc-800/60 flex items-center space-x-3 hover:scale-105 hover:bg-white dark:hover:bg-zinc-900 hover:border-brand-500/40 hover:shadow-sm cursor-default transition-all duration-300" data-category="tools"> <div class="w-10 h-10 rounded-xl bg-yellow-500/10 text-yellow-500 flex items-center justify-center"> <i data-lucide="zap" class="w-5 h-5"></i> </div> <div> <h4 class="font-semibold text-slate-800 dark:text-slate-200 text-sm">Vite / NPM</h4> <span class="text-slate-400 dark:text-slate-500 text-[10px] uppercase font-bold tracking-wider">Tools</span> </div> </div> </div> </div> </div> </section> <!-- ==================== PROJECTS SECTION ==================== --> <section id="projects" class="py-24 px-6 relative"> <div class="max-w-7xl mx-auto"> <!-- Section Header --> <div class="text-center space-y-4 mb-16"> <h2 class="text-3xl md:text-4xl font-display font-extrabold tracking-tight text-slate-900 dark:text-white"> ผลงาน <span class="text-brand-500">เด่น</span> </h2> <div class="w-12 h-1 bg-brand-500 mx-auto rounded-full"></div> <p class="text-slate-500 dark:text-slate-400 max-w-xl mx-auto text-sm md:text-base font-light leading-relaxed"> "ซ่อมคอม ซ่อมปริ้นเตอร์ จบทุกปัญหา งานไว มั่นใจในคุณภาพ" </p> </div> <!-- Responsive Project Grid Layout --> <!-- Responsive Grid: 1 column on Mobile, 2 on Tablet, 3 on Desktop --> <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8"> <!-- Project Card 1 --> <article class="group cyber-glow-card rounded-2xl bg-white/50 dark:bg-zinc-900/50 border border-slate-200/60 dark:border-zinc-800/60 overflow-hidden hover:shadow-xl hover:-translate-y-1 transition-all duration-300 flex flex-col justify-between h-full"> <div> <!-- Abstract Cyber Glow Card Banner --> <div class="relative h-48 bg-gradient-to-tr from-[#2e0854] via-[#581c87] to-[#00d2ff] overflow-hidden flex items-center justify-center p-6"> <div class="absolute inset-0 bg-[radial-gradient(#ffffff_1px,transparent_1px)] [background-size:16px_16px] opacity-25"></div> <div class="text-white text-center"> <i data-lucide="monitor" class="w-16 h-16 mx-auto mb-2 opacity-85 group-hover:scale-110 transition-transform duration-300"></i> <p class="text-sm font-semibold tracking-wide">Computer Repair</p> </div> </div> <!-- Card Body Content --> <div class="p-6 space-y-4"> <div class="flex items-center justify-between"> <h3 class="font-display font-bold text-xl text-slate-900 dark:text-white group-hover:text-brand-500 transition-colors duration-300"> ซ่อมคอมพิวเตอร์ </h3> </div> <p class="text-slate-600 dark:text-slate-400 text-xs sm:text-sm font-light leading-relaxed font-semibold italic"> "ซ่อมไว ใส่ใจทุกปัญหา คืนชีวิตใหม่ให้คอมพิวเตอร์" </p> <ul class="text-slate-600 dark:text-slate-400 text-xs sm:text-sm font-light leading-relaxed list-disc pl-4 space-y-1"> <li>ตรวจเช็กและวิเคราะห์ปัญหาคอมพิวเตอร์ทั้งฮาร์ดแวร์และซอฟต์แวร์</li> <li>ติดตั้งและอัปเกรดระบบปฏิบัติการ โปรแกรม และอุปกรณ์เสริม</li> <li>แก้ไขปัญหาไวรัส ระบบช้า และการเชื่อมต่อเครือข่าย</li> <li>ดูแลบำรุงรักษาคอมพิวเตอร์เพื่อเพิ่มประสิทธิภาพการใช้งาน</li> </ul> </div> </div> </article> <!-- Project Card 2 --> <article class="group cyber-glow-card rounded-2xl bg-white/50 dark:bg-zinc-900/50 border border-slate-200/60 dark:border-zinc-800/60 overflow-hidden hover:shadow-xl hover:-translate-y-1 transition-all duration-300 flex flex-col justify-between h-full"> <div> <!-- Abstract Cyber Glow Card Banner --> <div class="relative h-48 bg-gradient-to-tr from-[#030303] via-[#1a0b2e] to-[#a855f7] overflow-hidden flex items-center justify-center p-6"> <div class="absolute inset-0 bg-[radial-gradient(#ffffff_1px,transparent_1px)] [background-size:16px_16px] opacity-25"></div> <div class="text-white text-center"> <i data-lucide="printer" class="w-16 h-16 mx-auto mb-2 opacity-85 group-hover:scale-110 transition-transform duration-300"></i> <p class="text-sm font-semibold tracking-wide">Printer Repair</p> </div> </div> <!-- Card Body Content --> <div class="p-6 space-y-4"> <h3 class="font-display font-bold text-xl text-slate-900 dark:text-white group-hover:text-brand-500 transition-colors duration-300"> ซ่อมเครื่องพิมพ์ (Printer) </h3> <p class="text-slate-600 dark:text-slate-400 text-xs sm:text-sm font-light leading-relaxed font-semibold italic"> "พิมพ์ชัดทุกงาน ซ่อมทุกอาการ บริการด้วยความเชี่ยวชาญ" </p> <ul class="text-slate-600 dark:text-slate-400 text-xs sm:text-sm font-light leading-relaxed list-disc pl-4 space-y-1"> <li>ซ่อมและบำรุงรักษาเครื่องพิมพ์ Inkjet, Laser และ Multifunction</li> <li>แก้ไขปัญหากระดาษติด พิมพ์ไม่ออก สีเพี้ยน และระบบจ่ายหมึก</li> <li>เปลี่ยนอะไหล่และทำความสะอาดเครื่องพิมพ์ตามมาตรฐาน</li> <li>ให้คำแนะนำการใช้งานและการดูแลรักษาเพื่อลดปัญหาในอนาคต</li> </ul> </div> </div> </article> <!-- Project Card 3 --> <article class="group cyber-glow-card rounded-2xl bg-white/50 dark:bg-zinc-900/50 border border-slate-200/60 dark:border-zinc-800/60 overflow-hidden hover:shadow-xl hover:-translate-y-1 transition-all duration-300 flex flex-col justify-between h-full"> <div> <!-- Abstract Cyber Glow Card Banner --> <div class="relative h-48 bg-gradient-to-tr from-[#0c0f24] via-[#151a4a] to-[#00d2ff] overflow-hidden flex items-center justify-center p-6"> <div class="absolute inset-0 bg-[radial-gradient(#ffffff_1px,transparent_1px)] [background-size:16px_16px] opacity-25"></div> <div class="text-white text-center"> <i data-lucide="wrench" class="w-16 h-16 mx-auto mb-2 opacity-85 group-hover:scale-110 transition-transform duration-300"></i> <p class="text-sm font-semibold tracking-wide">IT Internship</p> </div> </div> <!-- Card Body Content --> <div class="p-6 space-y-4"> <h3 class="font-display font-bold text-xl text-slate-900 dark:text-white group-hover:text-brand-500 transition-colors duration-300"> ฝึกงานด้านช่างคอมพิวเตอร์และเทคโนโลยีสารสนเทศ </h3> <div class="space-y-3"> <div> <p class="text-slate-800 dark:text-slate-200 text-sm font-semibold mb-1"> ผลงานเด่น </p> <ul class="text-slate-600 dark:text-slate-400 text-xs sm:text-sm font-light leading-relaxed list-disc pl-4 space-y-1"> <li>ตรวจเช็ก ซ่อมบำรุง และแก้ไขปัญหาคอมพิวเตอร์เบื้องต้น</li> <li>ติดตั้งระบบปฏิบัติการ Windows และโปรแกรมพื้นฐานสำหรับผู้ใช้งาน</li> <li>ดูแลอุปกรณ์คอมพิวเตอร์ อุปกรณ์ต่อพ่วง และระบบเครือข่ายภายในหน่วยงาน</li> <li>ช่วยแก้ไขปัญหาเครื่องพิมพ์ เช่น กระดาษติด พิมพ์ไม่ออก และการเชื่อมต่อเครื่องพิมพ์</li> <li>ให้คำแนะนำผู้ใช้งานเกี่ยวกับการดูแลรักษาอุปกรณ์คอมพิวเตอร์และเครื่องพิมพ์</li> </ul> </div> <div> <p class="text-slate-800 dark:text-slate-200 text-sm font-semibold mb-1"> ทักษะที่ได้รับจากการฝึกงาน </p> <ul class="text-slate-600 dark:text-slate-400 text-xs sm:text-sm font-light leading-relaxed list-disc pl-4 space-y-1"> <li>การวิเคราะห์และแก้ไขปัญหาทางด้านคอมพิวเตอร์</li> <li>การซ่อมบำรุงคอมพิวเตอร์และเครื่องพิมพ์เบื้องต้น</li> <li>การติดตั้งและดูแลระบบซอฟต์แวร์</li> <li>การทำงานเป็นทีมและการให้บริการผู้ใช้งาน</li> </ul> </div> </div> </div> </div> </article> </div> </div> </section> <!-- ==================== CONTACT SECTION ==================== --> <section id="contact" class="py-24 px-6 relative bg-white/30 dark:bg-zinc-900/30 border-t border-slate-200/30 dark:border-zinc-800/30"> <div class="max-w-7xl mx-auto"> <!-- Section Header --> <div class="text-center space-y-4 mb-16"> <h2 class="text-3xl md:text-4xl font-display font-extrabold tracking-tight text-slate-900 dark:text-white"> ติดต่อ <span class="text-brand-500">ฉัน</span> </h2> <div class="w-12 h-1 bg-brand-500 mx-auto rounded-full"></div> <p class="text-slate-500 dark:text-slate-400 max-w-xl mx-auto text-sm md:text-base font-light leading-relaxed"> หากมีข้อสงสัยเกี่ยวกับงานพัฒนาซอฟต์แวร์ ข้อเสนอโปรเจกต์ใหม่ ๆ หรือต้องการสนทนาแลกเปลี่ยนข้อมูล สามารถกรอกฟอร์มส่งข้อความมาหาผมได้ทันที! </p> </div> <!-- Main Layout: Contact form and contact coordinates --> <div class="grid grid-cols-1 lg:grid-cols-12 gap-12 items-start"> <!-- Left Side: Coordinates & Social Grid (5 columns) --> <div class="lg:col-span-5 space-y-6"> <div class="p-8 rounded-3xl bg-white/60 dark:bg-zinc-900/60 border border-slate-200/60 dark:border-zinc-800/60 glass-card shadow-glass-light dark:shadow-glass-dark"> <h3 class="font-display font-bold text-2xl text-slate-900 dark:text-white mb-6">ช่องทางการติดต่อ</h3> <div class="space-y-6"> <!-- Email Channel --> <div class="flex items-start space-x-4"> <div class="w-12 h-12 rounded-xl bg-brand-500/10 text-brand-500 flex items-center justify-center shrink-0"> <i data-lucide="mail" class="w-5 h-5"></i> </div> <div> <span class="text-slate-400 dark:text-slate-500 text-xs block font-semibold uppercase tracking-wider">ส่งอีเมลหาฉัน</span> <a href="mailto:cirphathnsaythxng44@gmail.com" class="font-semibold text-slate-700 dark:text-slate-350 hover:text-brand-500 transition-colors duration-300 text-sm sm:text-base"> cirphathnsaythxng44@gmail.com </a> </div> </div> <!-- Location Channel --> <div class="flex items-start space-x-4"> <div class="w-12 h-12 rounded-xl bg-rose-500/10 text-brand-500 flex items-center justify-center shrink-0"> <i data-lucide="map-pin" class="w-5 h-5"></i> </div> <div> <span class="text-slate-400 dark:text-slate-500 text-xs block font-semibold uppercase tracking-wider">ที่อยู่ปัจจุบัน</span> <span class="font-semibold text-slate-700 dark:text-slate-350 text-sm sm:text-base"> 23 หมู่ 3 ต.หัวทุ่ง อ.ลอง จ.แพร่ ประเทศไทย </span> </div> </div> <!-- Phone Channel --> <div class="flex items-start space-x-4"> <div class="w-12 h-12 rounded-xl bg-cyan-500/10 text-cyan-500 flex items-center justify-center shrink-0"> <i data-lucide="phone" class="w-5 h-5"></i> </div> <div> <span class="text-slate-400 dark:text-slate-500 text-xs block font-semibold uppercase tracking-wider">เบอร์โทรศัพท์</span> <a href="tel:0930235214" class="font-semibold text-slate-700 dark:text-slate-350 hover:text-brand-500 transition-colors duration-300 text-sm sm:text-base"> 0930235214 </a> </div> </div> </div> <!-- Glowing Social circles --> <div class="pt-8 mt-8 border-t border-slate-100 dark:border-zinc-800"> <span class="text-slate-400 dark:text-slate-500 text-xs block font-bold uppercase tracking-wider mb-4">ช่องทางการติดตาม</span> <div class="flex items-center space-x-4"> <a href="https://github.com" target="_blank" rel="noopener noreferrer" class="w-12 h-12 rounded-full border border-slate-200 dark:border-zinc-800 bg-white/40 dark:bg-zinc-900/40 text-slate-400 hover:text-brand-500 dark:hover:text-brand-500 flex items-center justify-center hover:scale-110 hover:shadow-md transition-all duration-300 min-h-[44px] min-w-[44px]" aria-label="Github Profile"> <i data-lucide="github" class="w-5 h-5"></i> </a> <a href="https://linkedin.com" target="_blank" rel="noopener noreferrer" class="w-12 h-12 rounded-full border border-slate-200 dark:border-zinc-800 bg-white/40 dark:bg-zinc-900/40 text-slate-400 hover:text-rose-500 dark:hover:text-rose-500 flex items-center justify-center hover:scale-110 hover:shadow-md transition-all duration-300 min-h-[44px] min-w-[44px]" aria-label="LinkedIn Profile"> <i data-lucide="linkedin" class="w-5 h-5"></i> </a> <a href="https://twitter.com" target="_blank" rel="noopener noreferrer" class="w-12 h-12 rounded-full border border-slate-200 dark:border-zinc-800 bg-white/40 dark:bg-zinc-900/40 text-slate-400 hover:text-brand-500 dark:hover:text-brand-500 flex items-center justify-center hover:scale-110 hover:shadow-md transition-all duration-300 min-h-[44px] min-w-[44px]" aria-label="Twitter Profile"> <i data-lucide="twitter" class="w-5 h-5"></i> </a> </div> </div> </div> </div> <!-- Right Side: Contact Form (7 columns) --> <div class="lg:col-span-7"> <form id="portfolio-contact-form" class="p-8 rounded-3xl bg-white/60 dark:bg-zinc-900/60 border border-slate-200/60 dark:border-zinc-800/60 glass-card shadow-glass-light dark:shadow-glass-dark space-y-6" novalidate> <h3 class="font-display font-bold text-2xl text-slate-900 dark:text-white mb-2">ส่งข้อความหาผม</h3> <div class="grid grid-cols-1 sm:grid-cols-2 gap-6"> <!-- Name Input --> <div class="space-y-2"> <label for="contact-name" class="block text-xs font-semibold text-slate-500 dark:text-slate-400 uppercase tracking-wider">ชื่อของคุณ</label> <input type="text" id="contact-name" name="name" placeholder="คุณสมพงษ์ ยินดี" class="custom-input w-full p-4 rounded-xl border border-slate-250 dark:border-zinc-800 dark:text-white text-sm outline-none transition-all duration-300 min-h-[48px]" required> <span class="text-xs text-red-500 hidden" id="err-name">กรุณากรอกชื่อของคุณ</span> </div> <!-- Email Input --> <div class="space-y-2"> <label for="contact-email" class="block text-xs font-semibold text-slate-500 dark:text-slate-400 uppercase tracking-wider">ที่อยู่อีเมลของคุณ</label> <input type="email" id="contact-email" name="email" placeholder="example@domain.com" class="custom-input w-full p-4 rounded-xl border border-slate-250 dark:border-zinc-800 dark:text-white text-sm outline-none transition-all duration-300 min-h-[48px]" required> <span class="text-xs text-red-500 hidden" id="err-email">กรุณากรอกที่อยู่อีเมลที่ถูกต้อง</span> </div> </div> <!-- Message Input --> <div class="space-y-2"> <label for="contact-message" class="block text-xs font-semibold text-slate-500 dark:text-slate-400 uppercase tracking-wider">ข้อความของคุณ</label> <textarea id="contact-message" name="message" rows="5" placeholder="พิมพ์ข้อความของคุณที่นี่..." class="custom-input w-full p-4 rounded-xl border border-slate-250 dark:border-zinc-800 dark:text-white text-sm outline-none resize-none transition-all duration-300 min-h-[120px]" required></textarea> <span class="text-xs text-red-500 hidden" id="err-message">กรุณากรอกข้อความของคุณ</span> </div> <!-- Submit Button (Large touch-friendly with min padding) --> <button type="submit" class="w-full py-4 px-6 rounded-xl bg-brand-600 hover:bg-brand-700 text-white dark:bg-brand-500 dark:hover:bg-brand-600 dark:text-black font-bold shadow-md shadow-brand-500/15 hover:shadow-lg transition-all duration-300 flex items-center justify-center space-x-2 cursor-pointer min-h-[52px]"> <span>ส่งข้อความ</span> <i data-lucide="send" class="w-4 h-4"></i> </button> </form> </div> </div> </div> </section> <!-- ==================== FOOTER ==================== --> <footer class="py-12 px-6 bg-slate-900/5 dark:bg-black/40 border-t border-brand-500/20 dark:border-brand-500/30 relative shadow-[0_-8px_30px_rgba(168,85,247,0.06)] dark:shadow-[0_-10px_40px_rgba(168,85,247,0.12)]"> <!-- Top glowing laser line decorative bar --> <div class="absolute top-0 left-0 w-full h-[2px] bg-gradient-to-r from-transparent via-brand-500 to-transparent shadow-[0_0_12px_rgba(168,85,247,0.8)]"></div> <div class="max-w-4xl mx-auto text-center space-y-6"> <!-- Divider --> <div class="text-slate-300 dark:text-zinc-850 tracking-widest text-lg font-light select-none"> ━━━━━━━━━━━━━━━━━━ </div> <!-- Brand Title --> <h3 class="font-display font-extrabold text-2xl tracking-wider text-slate-800 dark:text-white"> JEERAPAT<span class="text-brand-500">.S</span> </h3> <!-- Tags / Subtitles --> <div class="flex flex-wrap justify-center items-center gap-x-4 gap-y-2 text-sm text-slate-500 dark:text-slate-400 font-medium tracking-wide"> <span>Computer Repair</span> <span class="text-brand-500/60">•</span> <span>Printer Repair</span> <span class="text-brand-500/60">•</span> <span>Web Development</span> </div> <!-- Copyright --> <p class="text-xs text-slate-400 dark:text-slate-500 tracking-wider"> © 2026 All Rights Reserved </p> </div> </footer> <!-- ==================== STICKY BOTTOM NAVIGATION ==================== --> <div id="bottom-nav" class="fixed bottom-6 left-1/2 -translate-x-1/2 z-40 w-[92%] max-w-md bg-white/85 dark:bg-[#09090b]/85 border border-slate-200/50 dark:border-zinc-800/50 rounded-2xl shadow-lg shadow-slate-900/5 dark:shadow-black/40 backdrop-blur-lg px-4 py-2 transition-all duration-300 transform"> <nav class="flex items-center justify-around"> <a href="#hero" class="bottom-nav-link flex flex-col items-center justify-center py-1 px-3 rounded-xl text-slate-500 dark:text-slate-400 hover:text-brand-500 dark:hover:text-brand-500 transition-all duration-300 group relative" id="b-nav-hero"> <i data-lucide="home" class="w-5 h-5 mb-0.5 transition-transform duration-300 group-hover:-translate-y-0.5"></i> <span class="text-[10px] font-semibold tracking-wider transition-colors duration-300">หน้าแรก</span> <span class="absolute bottom-0 w-1.5 h-1.5 bg-brand-500 rounded-full scale-0 transition-transform duration-300 indicator"></span> </a> <a href="#about" class="bottom-nav-link flex flex-col items-center justify-center py-1 px-3 rounded-xl text-slate-500 dark:text-slate-400 hover:text-brand-500 dark:hover:text-brand-500 transition-all duration-300 group relative" id="b-nav-about"> <i data-lucide="user" class="w-5 h-5 mb-0.5 transition-transform duration-300 group-hover:-translate-y-0.5"></i> <span class="text-[10px] font-semibold tracking-wider transition-colors duration-300">เกี่ยวกับฉัน</span> <span class="absolute bottom-0 w-1.5 h-1.5 bg-brand-500 rounded-full scale-0 transition-transform duration-300 indicator"></span> </a> <a href="#projects" class="bottom-nav-link flex flex-col items-center justify-center py-1 px-3 rounded-xl text-slate-500 dark:text-slate-400 hover:text-brand-500 dark:hover:text-brand-500 transition-all duration-300 group relative" id="b-nav-projects"> <i data-lucide="briefcase" class="w-5 h-5 mb-0.5 transition-transform duration-300 group-hover:-translate-y-0.5"></i> <span class="text-[10px] font-semibold tracking-wider transition-colors duration-300">ผลงานเด่น</span> <span class="absolute bottom-0 w-1.5 h-1.5 bg-brand-500 rounded-full scale-0 transition-transform duration-300 indicator"></span> </a> <a href="#contact" class="bottom-nav-link flex flex-col items-center justify-center py-1 px-3 rounded-xl text-slate-500 dark:text-slate-400 hover:text-brand-500 dark:hover:text-brand-500 transition-all duration-300 group relative" id="b-nav-contact"> <i data-lucide="mail" class="w-5 h-5 mb-0.5 transition-transform duration-300 group-hover:-translate-y-0.5"></i> <span class="text-[10px] font-semibold tracking-wider transition-colors duration-300">ติดต่อฉัน</span> <span class="absolute bottom-0 w-1.5 h-1.5 bg-brand-500 rounded-full scale-0 transition-transform duration-300 indicator"></span> </a> </nav> </div> <!-- ==================== FLOATING BACK TO TOP BUTTON ==================== --> <button id="back-to-top" class="fixed bottom-24 lg:bottom-6 right-6 p-3.5 rounded-full bg-white dark:bg-zinc-900 border border-slate-200/80 dark:border-zinc-800 text-slate-500 dark:text-slate-400 hover:text-brand-500 hover:border-brand-500/50 hover:shadow-lg shadow-md cursor-pointer pointer-events-none opacity-0 translate-y-4 transition-all duration-300 z-40 min-h-[46px] min-w-[46px]" aria-label="กลับสู่ด้านบน"> <i data-lucide="arrow-up" class="w-5 h-5"></i> </button> <!-- ==================== SUCCESS TOAST ALERT ==================== --> <div id="success-toast" class="fixed bottom-24 lg:bottom-6 left-6 z-50 p-4 bg-white/90 dark:bg-zinc-900/90 border border-emerald-500/30 rounded-2xl shadow-xl flex items-center space-x-3 pointer-events-none opacity-0 translate-y-4 transition-all duration-300 glass-card"> <div class="w-8 h-8 rounded-lg bg-emerald-500/10 text-emerald-500 flex items-center justify-center shrink-0"> <i data-lucide="check-circle" class="w-4 h-4"></i> </div> <div> <h5 class="text-sm font-bold text-slate-900 dark:text-white">ส่งข้อความเรียบร้อยแล้ว!</h5> <p class="text-xs text-slate-500 dark:text-slate-400">ผมจะรีบติดต่อกลับหาคุณโดยเร็วที่สุดครับ 🚀</p> </div> </div> <!-- ==================== CORE INTERACTIVE LOGIC ==================== --> <script> // Initialize Lucide Icons lucide.createIcons(); /* --- Theme Toggle & Dark Mode Controller --- */ const themeToggleBtn = document.getElementById('theme-toggle'); const dynamicImg = document.getElementById('dynamic-bg-img'); const dynamicImgLight = document.getElementById('dynamic-bg-img-light'); // Check initial state if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) { document.documentElement.classList.add('dark'); if (dynamicImg) { dynamicImg.classList.remove('scale-105'); dynamicImg.classList.add('scale-100'); } if (dynamicImgLight) { dynamicImgLight.classList.remove('scale-100'); dynamicImgLight.classList.add('scale-105'); } } else { document.documentElement.classList.remove('dark'); if (dynamicImg) { dynamicImg.classList.remove('scale-100'); dynamicImg.classList.add('scale-105'); } if (dynamicImgLight) { dynamicImgLight.classList.remove('scale-105'); dynamicImgLight.classList.add('scale-100'); } } themeToggleBtn.addEventListener('click', () => { if (document.documentElement.classList.contains('dark')) { document.documentElement.classList.remove('dark'); localStorage.theme = 'light'; if (dynamicImg) { dynamicImg.classList.remove('scale-100'); dynamicImg.classList.add('scale-105'); } if (dynamicImgLight) { dynamicImgLight.classList.remove('scale-105'); dynamicImgLight.classList.add('scale-100'); } } else { document.documentElement.classList.add('dark'); localStorage.theme = 'dark'; if (dynamicImg) { dynamicImg.classList.remove('scale-105'); dynamicImg.classList.add('scale-100'); } if (dynamicImgLight) { dynamicImgLight.classList.remove('scale-100'); dynamicImgLight.classList.add('scale-105'); } } }); /* --- Mobile Menu Drawer Controller --- */ const mobileMenuTrigger = document.getElementById('mobile-menu-trigger'); const mobileMenuDrawer = document.getElementById('mobile-menu-drawer'); const mobileMenuBackdrop = document.getElementById('mobile-menu-backdrop'); const mobileMenuContent = document.getElementById('mobile-menu-content'); const mobileMenuCloseBtn = document.getElementById('mobile-menu-close'); const mobileNavLinks = document.querySelectorAll('.mobile-nav-link'); function openMobileMenu() { mobileMenuDrawer.classList.remove('pointer-events-none'); mobileMenuBackdrop.classList.add('opacity-100'); mobileMenuBackdrop.classList.remove('pointer-events-none'); mobileMenuContent.classList.remove('translate-x-full'); } function closeMobileMenu() { mobileMenuContent.classList.add('translate-x-full'); mobileMenuBackdrop.classList.remove('opacity-100'); mobileMenuBackdrop.classList.add('pointer-events-none'); setTimeout(() => { mobileMenuDrawer.classList.add('pointer-events-none'); }, 300); } mobileMenuTrigger.addEventListener('click', openMobileMenu); mobileMenuCloseBtn.addEventListener('click', closeMobileMenu); mobileMenuBackdrop.addEventListener('click', closeMobileMenu); mobileNavLinks.forEach(link => { link.addEventListener('click', closeMobileMenu); }); /* --- Floating Header on Scroll --- */ const navbar = document.getElementById('navbar'); window.addEventListener('scroll', () => { if (window.scrollY > 50) { navbar.classList.add('bg-white/75', 'dark:bg-zinc-950/75', 'backdrop-blur-md', 'shadow-sm', 'border-slate-200/50', 'dark:border-zinc-900/50', 'h-16'); navbar.classList.remove('bg-transparent', 'border-transparent', 'h-20'); } else { navbar.classList.add('bg-transparent', 'border-transparent', 'h-20'); navbar.classList.remove('bg-white/75', 'dark:bg-zinc-950/75', 'backdrop-blur-md', 'shadow-sm', 'border-slate-200/50', 'dark:border-zinc-900/50', 'h-16'); } }); /* --- Role Text Rotator in Hero --- */ const roles = ['Full-Stack Developer', 'UI/UX Designer', 'Software Engineer']; let currentRoleIndex = 0; const roleTextContainer = document.getElementById('role-text'); function rotateRoleText() { roleTextContainer.style.opacity = 0; setTimeout(() => { currentRoleIndex = (currentRoleIndex + 1) % roles.length; roleTextContainer.textContent = roles[currentRoleIndex]; roleTextContainer.style.opacity = 1; }, 300); } setInterval(rotateRoleText, 3500); /* --- Scroll Spy & Active Nav Link Highlight --- */ const sections = document.querySelectorAll('section'); const navLinks = document.querySelectorAll('.nav-link'); const mNavLinks = document.querySelectorAll('.mobile-nav-link'); const bNavLinks = document.querySelectorAll('.bottom-nav-link'); window.addEventListener('scroll', () => { let currentSectionId = ''; sections.forEach(section => { const sectionTop = section.offsetTop; const sectionHeight = section.offsetHeight; // Check if section is currently active in the viewport middle if (window.scrollY >= (sectionTop - 120)) { currentSectionId = section.getAttribute('id'); } }); // Update Desktop Nav Links navLinks.forEach(link => { link.classList.remove('active-nav-link'); if (link.getAttribute('href') === `#${currentSectionId}`) { link.classList.add('active-nav-link'); } }); // Update Mobile Nav Links mNavLinks.forEach(link => { link.classList.remove('text-brand-500', 'bg-slate-50', 'dark:bg-zinc-850'); if (link.getAttribute('href') === `#${currentSectionId}`) { link.classList.add('text-brand-500', 'bg-slate-50', 'dark:bg-zinc-850'); } }); // Update Bottom Nav Links bNavLinks.forEach(link => { const indicator = link.querySelector('.indicator'); if (link.getAttribute('href') === `#${currentSectionId}`) { link.classList.remove('text-slate-500', 'dark:text-slate-400'); link.classList.add('text-brand-500', 'dark:text-brand-500'); if (indicator) { indicator.classList.remove('scale-0'); indicator.classList.add('scale-100'); } } else { link.classList.remove('text-brand-500', 'dark:text-brand-500'); link.classList.add('text-slate-500', 'dark:text-slate-400'); if (indicator) { indicator.classList.remove('scale-100'); indicator.classList.add('scale-0'); } } }); }); /* --- Back To Top Arrow Controller --- */ const backToTopBtn = document.getElementById('back-to-top'); window.addEventListener('scroll', () => { if (window.scrollY > 600) { backToTopBtn.classList.remove('pointer-events-none', 'opacity-0', 'translate-y-4'); backToTopBtn.classList.add('opacity-100', 'translate-y-0'); } else { backToTopBtn.classList.add('pointer-events-none', 'opacity-0', 'translate-y-4'); backToTopBtn.classList.remove('opacity-100', 'translate-y-0'); } }); backToTopBtn.addEventListener('click', () => { window.scrollTo({ top: 0, behavior: 'smooth' }); }); /* --- Skill Badges Filtering Logic --- */ function filterSkills(category) { const skills = document.querySelectorAll('.skill-card'); const tabs = ['all', 'frontend', 'backend', 'tools']; // Update Tab Styles tabs.forEach(tabName => { const tabBtn = document.getElementById(`tab-${tabName}`); tabBtn.classList.remove('skill-tab-active'); if (tabName === category) { tabBtn.classList.add('skill-tab-active'); } }); // Filter skill items with standard fade transitions skills.forEach(skill => { const skillCategory = skill.getAttribute('data-category'); if (category === 'all' || skillCategory === category) { skill.style.display = 'flex'; setTimeout(() => { skill.style.opacity = '1'; skill.style.transform = 'scale(1)'; }, 50); } else { skill.style.opacity = '0'; skill.style.transform = 'scale(0.95)'; setTimeout(() => { skill.style.display = 'none'; }, 300); } }); } /* --- Interactive Contact Form with Verification --- */ const contactForm = document.getElementById('portfolio-contact-form'); const successToast = document.getElementById('success-toast'); // Verification elements const inpName = document.getElementById('contact-name'); const inpEmail = document.getElementById('contact-email'); const inpMessage = document.getElementById('contact-message'); const errName = document.getElementById('err-name'); const errEmail = document.getElementById('err-email'); const errMessage = document.getElementById('err-message'); // Verification helpers function validateEmail(email) { const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return re.test(String(email).toLowerCase()); } contactForm.addEventListener('submit', (e) => { e.preventDefault(); let hasError = false; // Validate name if (!inpName.value.trim()) { errName.classList.remove('hidden'); inpName.classList.add('border-brand-500', 'focus:ring-brand-500/10'); hasError = true; } else { errName.classList.add('hidden'); inpName.classList.remove('border-brand-500', 'focus:ring-brand-500/10'); } // Validate email if (!inpEmail.value.trim() || !validateEmail(inpEmail.value.trim())) { errEmail.classList.remove('hidden'); inpEmail.classList.add('border-brand-500', 'focus:ring-brand-500/10'); hasError = true; } else { errEmail.classList.add('hidden'); inpEmail.classList.remove('border-brand-500', 'focus:ring-brand-500/10'); } // Validate message if (!inpMessage.value.trim()) { errMessage.classList.remove('hidden'); inpMessage.classList.add('border-brand-500', 'focus:ring-brand-500/10'); hasError = true; } else { errMessage.classList.add('hidden'); inpMessage.classList.remove('border-brand-500', 'focus:ring-brand-500/10'); } // Trigger Submission simulation if inputs are valid if (!hasError) { // Mock Success Feedback successToast.classList.remove('opacity-0', 'translate-y-4'); successToast.classList.add('opacity-100', 'translate-y-0'); // Reset Inputs contactForm.reset(); // Dismiss Toast after 3.5 seconds setTimeout(() => { successToast.classList.remove('opacity-100', 'translate-y-0'); successToast.classList.add('opacity-0', 'translate-y-4'); }, 3500); } }); // Remove error borders in real time when typing inpName.addEventListener('input', () => { if (inpName.value.trim()) { errName.classList.add('hidden'); inpName.classList.remove('border-brand-500'); } }); inpEmail.addEventListener('input', () => { if (inpEmail.value.trim() && validateEmail(inpEmail.value.trim())) { errEmail.classList.add('hidden'); inpEmail.classList.remove('border-brand-500'); } }); inpMessage.addEventListener('input', () => { if (inpMessage.value.trim()) { errMessage.classList.add('hidden'); inpMessage.classList.remove('border-brand-500'); } }); /* --- Cyber Particles Canvas Effect --- */ const canvas = document.getElementById('cyber-particles'); if (canvas) { const ctx = canvas.getContext('2d'); let particles = []; const particleCount = 40; function resizeCanvas() { canvas.width = window.innerWidth; canvas.height = window.innerHeight; } window.addEventListener('resize', resizeCanvas); resizeCanvas(); class Particle { constructor() { this.reset(); } reset() { this.x = Math.random() * canvas.width; this.y = Math.random() * canvas.height; this.size = Math.random() * 2 + 0.8; this.speedX = Math.random() * 0.3 - 0.15; this.speedY = Math.random() * 0.3 - 0.15; this.alpha = Math.random() * 0.45 + 0.1; } update() { this.x += this.speedX; this.y += this.speedY; if (this.x < 0 || this.x > canvas.width || this.y < 0 || this.y > canvas.height) { this.reset(); } } draw() { ctx.save(); const isDark = document.documentElement.classList.contains('dark'); ctx.fillStyle = isDark ? `rgba(168, 85, 247, ${this.alpha})` : `rgba(168, 85, 247, ${this.alpha * 0.4})`; ctx.beginPath(); ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2); ctx.fill(); ctx.restore(); } } for (let i = 0; i < particleCount; i++) { particles.push(new Particle()); } function animate() { ctx.clearRect(0, 0, canvas.width, canvas.height); particles.forEach(p => { p.update(); p.draw(); }); requestAnimationFrame(animate); } animate(); } /* --- Full Screen Intro Controller --- */ (function() { const introOverlay = document.getElementById('intro-overlay'); const introGlow = document.getElementById('intro-glow'); const introLogoJ = document.getElementById('intro-logo-j'); const introLogoFull = document.getElementById('intro-logo-full'); const introVideoContainer = document.getElementById('intro-video-container'); const videoElement = document.getElementById('intro-video-element'); const introWelcomeContainer = document.getElementById('intro-welcome-container'); const introWelcomeText = document.getElementById('intro-welcome-text'); const introSkip = document.getElementById('intro-skip'); const introCanvas = document.getElementById('intro-canvas'); const body = document.body; if (!introOverlay) return; let ctx = null; let particles = []; let animationFrameId = null; let active = true; let particleSpeedMultiplier = 1.0; // Particle system for Intro if (introCanvas) { ctx = introCanvas.getContext('2d'); function resizeIntroCanvas() { introCanvas.width = window.innerWidth; introCanvas.height = window.innerHeight; } window.addEventListener('resize', resizeIntroCanvas); resizeIntroCanvas(); class DigitalParticle { constructor() { this.reset(); } reset() { this.x = Math.random() * introCanvas.width; this.y = Math.random() * introCanvas.height; this.size = Math.random() * 2 + 0.8; this.speedY = -(Math.random() * 1.2 + 0.4); // move up slowly this.speedX = (Math.random() * 0.4 - 0.2); this.alpha = Math.random() * 0.6 + 0.2; this.char = Math.random() > 0.5 ? '0' : '1'; } update() { this.y += this.speedY * particleSpeedMultiplier; this.x += this.speedX * particleSpeedMultiplier; if (this.y < 0 || this.x < 0 || this.x > introCanvas.width) { this.reset(); this.y = introCanvas.height; } } draw() { ctx.fillStyle = `rgba(168, 85, 247, ${this.alpha})`; ctx.font = `${this.size * 6}px monospace`; ctx.fillText(this.char, this.x, this.y); } } for (let i = 0; i < 45; i++) { particles.push(new DigitalParticle()); } function animateIntro() { if (!active) return; ctx.clearRect(0, 0, introCanvas.width, introCanvas.height); particles.forEach(p => { p.update(); p.draw(); }); animationFrameId = requestAnimationFrame(animateIntro); } animateIntro(); } // Helper function for typing effect function typeText(element, text, speed, callback) { let index = 0; element.textContent = ''; element.classList.add('intro-welcome-cursor'); function type() { if (!active) return; if (index < text.length) { element.textContent += text.charAt(index); index++; setTimeout(type, speed); } else { element.classList.remove('intro-welcome-cursor'); if (callback) callback(); } } type(); } let timeouts = []; // 1.5s: Reveal Skip Button so the user has immediate exit control timeouts.push(setTimeout(() => { if (!active) return; introSkip.classList.add('visible'); }, 1500)); // TIMELINE SEQUENCE: // Stage 0: 0:00 - Black Screen. (No actions, elements hidden). // Stage 1: 0.8s - Logo J Glitch appears timeouts.push(setTimeout(() => { if (!active) return; introLogoJ.classList.add('visible', 'glitching'); introGlow.classList.add('active'); }, 800)); // Stage 2: 2.2s - Transition to JEERAPAT.S timeouts.push(setTimeout(() => { if (!active) return; introLogoJ.classList.remove('visible', 'glitching'); introLogoFull.classList.add('visible'); // Cyber animation: speed up particles during full logo reveal particleSpeedMultiplier = 3.0; }, 2200)); // Stage 3: 3.8s - Play MP4 Clip timeouts.push(setTimeout(() => { if (!active) return; // Fade out logo and slowdown particles introLogoFull.style.opacity = '0'; introLogoFull.style.transform = 'scale(0.95)'; introLogoFull.style.transition = 'opacity 0.5s ease, transform 0.5s ease'; particleSpeedMultiplier = 0.5; // Fade in video container introVideoContainer.classList.add('active'); let videoProceeded = false; function playEndedOrTimeout() { if (videoProceeded) return; videoProceeded = true; proceedToWelcome(); } // Absolute fallback: if video is missing, loading slowly, or blocked, proceed after 5 seconds timeouts.push(setTimeout(playEndedOrTimeout, 5000)); // Play Video if (videoElement) { videoElement.addEventListener('ended', playEndedOrTimeout); videoElement.addEventListener('error', playEndedOrTimeout); videoElement.play().then(() => { // Video started playing successfully }).catch(err => { console.log("Autoplay blocked or video error: ", err); playEndedOrTimeout(); }); } else { playEndedOrTimeout(); } }, 3800)); let welcomeStarted = false; function proceedToWelcome() { if (welcomeStarted || !active) return; welcomeStarted = true; // Fade out video introVideoContainer.classList.remove('active'); // Show welcome container introWelcomeContainer.classList.add('visible'); // Type: WELCOME TO MY PORTFOLIO timeouts.push(setTimeout(() => { if (!active) return; typeText(introWelcomeText, "WELCOME TO MY PORTFOLIO", 65, () => { // Once typing finishes, wait 1.5 seconds then fade out intro overlay timeouts.push(setTimeout(endIntro, 1500)); }); }, 300)); } // End Intro cleanly and show Home page function endIntro() { if (!active) return; active = false; if (animationFrameId) { cancelAnimationFrame(animationFrameId); } // Fade out the whole intro overlay introOverlay.style.opacity = '0'; introOverlay.style.visibility = 'hidden'; timeouts.forEach(clearTimeout); body.classList.remove('intro-active'); // Remove overlay from DOM to free resources setTimeout(() => { if (videoElement) { videoElement.pause(); videoElement.src = ""; videoElement.load(); } introOverlay.remove(); }, 1000); } // Skip event introSkip.addEventListener('click', endIntro); })(); </script> <!-- Language Logic --> <script src="i18n.js"></script> </body> </html>
| ver. 1.4 |
Github
|
.
| PHP 7.4.33 | Generation time: 0.24 |
proxy
|
phpinfo
|
Settings