File manager - Edit - /home/webapp69.cm.in.th/u69319090001/69319090001/index.html
Back
<!DOCTYPE html> <html lang="th" class="scroll-smooth dark"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Portfolio | กรกฎ ใจมูล</title> <!-- Tailwind CSS CDN --> <script src="https://cdn.tailwindcss.com"></script> <script> tailwind.config = { darkMode: 'class', theme: { extend: { colors: { brand: { cyan: '#22d3ee', purple: '#a855f7', darkBg: '#020617', cardBg: 'rgba(15, 23, 42, 0.45)' } }, fontFamily: { sans: ['Inter', 'sans-serif'], outfit: ['Outfit', 'sans-serif'] } } } } </script> <!-- Custom styles --> <link rel="stylesheet" href="style.css"> <!-- Lucide Icons CDN --> <script src="https://unpkg.com/lucide@latest"></script> </head> <body class="bg-slate-50 text-slate-900 dark:bg-[#020617] dark:text-slate-100 min-h-screen relative bg-grid-pattern selection:bg-cyan-500/30 selection:text-cyan-200 transition-colors duration-300"> <!-- Glow Background Accents --> <div class="absolute top-[-10%] left-[-10%] w-[50vw] h-[50vw] rounded-full bg-cyan-500/10 blur-[120px] pointer-events-none animate-pulse-slow"> </div> <div class="absolute top-[40%] right-[-10%] w-[45vw] h-[45vw] rounded-full bg-purple-500/10 blur-[120px] pointer-events-none animate-pulse-slow"> </div> <div class="absolute bottom-[-10%] left-[20%] w-[50vw] h-[50vw] rounded-full bg-indigo-500/10 blur-[120px] pointer-events-none animate-pulse-slow"> </div> <!-- Header / Navbar --> <header class="fixed top-0 left-0 w-full z-50 transition-all duration-300" id="main-header"> <nav class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 h-20 flex items-center justify-between"> <!-- Logo --> <a href="#hero" class="flex items-center space-x-2 group"> <div class="w-10 h-10 rounded-xl bg-gradient-to-tr from-cyan-400 to-purple-500 flex items-center justify-center shadow-lg shadow-cyan-500/20 group-hover:scale-105 transition-transform duration-300"> <span class="text-white font-bold text-xl font-outfit">P</span> </div> <span class="font-outfit text-xl font-bold bg-gradient-to-r from-white via-slate-100 to-slate-400 bg-clip-text text-transparent group-hover:to-cyan-400 transition-all duration-300">Portfolio</span> </a> <!-- Desktop Nav Menu --> <div class="hidden md:flex items-center space-x-1 lg:space-x-2"> <a href="#hero" class="nav-link px-4 py-2 text-sm font-medium text-slate-300 hover:text-cyan-400 transition-colors duration-300 relative" data-section="hero">หน้าแรก</a> <a href="#about" class="nav-link px-4 py-2 text-sm font-medium text-slate-300 hover:text-cyan-400 transition-colors duration-300 relative" data-section="about">เกี่ยวกับฉัน</a> <a href="#projects" class="nav-link px-4 py-2 text-sm font-medium text-slate-300 hover:text-cyan-400 transition-colors duration-300 relative" data-section="projects">ผลงาน</a> <a href="#contact" class="nav-link px-4 py-2 text-sm font-medium text-slate-300 hover:text-cyan-400 transition-colors duration-300 relative" data-section="contact">ติดต่อ</a> <!-- Contact CTA Button --> <a href="#contact" class="ml-4 px-5 py-2.5 rounded-xl bg-slate-900/80 border border-slate-700 hover:border-cyan-500/50 hover:bg-slate-800 text-sm font-semibold text-cyan-400 hover:text-cyan-300 transition-all duration-300 flex items-center gap-2 shadow-inner"> <i data-lucide="send" class="w-4 h-4"></i> Let's Talk </a> <!-- Theme Toggle Button (Desktop) --> <button id="theme-toggle" class="ml-2 px-3.5 py-2.5 rounded-xl bg-slate-900/80 border border-slate-700 hover:border-cyan-500/50 hover:bg-slate-800 text-slate-300 hover:text-cyan-400 transition-all duration-300 flex items-center justify-center min-h-[44px]" aria-label="Toggle Theme"> <i data-lucide="sun" id="theme-toggle-icon" class="w-4 h-4"></i> </button> </div> <!-- Mobile Menu Button --> <button id="mobile-menu-btn" class="md:hidden w-12 h-12 flex items-center justify-center rounded-xl bg-slate-900/50 border border-slate-800 hover:border-slate-700 text-slate-300 hover:text-white transition-all focus:outline-none" aria-label="Toggle Menu"> <i data-lucide="menu" id="menu-icon" class="w-6 h-6 transition-transform duration-300"></i> </button> </nav> <!-- Mobile Dropdown Menu --> <div id="mobile-dropdown" class="absolute top-20 left-0 w-full glass-panel border-t border-slate-800/80 hidden flex-col px-4 py-6 space-y-3 shadow-2xl transition-all duration-300 ease-in-out origin-top scale-y-95 opacity-0"> <a href="#hero" class="mobile-nav-link flex items-center space-x-3 px-4 py-3 rounded-xl hover:bg-slate-800/50 text-slate-300 hover:text-cyan-400 transition-all duration-200" data-section="hero"> <i data-lucide="home" class="w-5 h-5"></i> <span class="font-medium">หน้าแรก</span> </a> <a href="#about" class="mobile-nav-link flex items-center space-x-3 px-4 py-3 rounded-xl hover:bg-slate-800/50 text-slate-300 hover:text-cyan-400 transition-all duration-200" data-section="about"> <i data-lucide="user" class="w-5 h-5"></i> <span class="font-medium">เกี่ยวกับฉัน</span> </a> <a href="#projects" class="mobile-nav-link flex items-center space-x-3 px-4 py-3 rounded-xl hover:bg-slate-800/50 text-slate-300 hover:text-cyan-400 transition-all duration-200" data-section="projects"> <i data-lucide="folder-git-2" class="w-5 h-5"></i> <span class="font-medium">ผลงาน</span> </a> <a href="#contact" class="mobile-nav-link flex items-center space-x-3 px-4 py-3 rounded-xl hover:bg-slate-800/50 text-slate-300 hover:text-cyan-400 transition-all duration-200" data-section="contact"> <i data-lucide="mail" class="w-5 h-5"></i> <span class="font-medium">ติดต่อ</span> </a> <hr class="border-slate-800 my-2"> <a href="#contact" class="flex items-center justify-center space-x-2 px-4 py-3.5 rounded-xl bg-gradient-to-r from-cyan-500 to-purple-600 hover:from-cyan-400 hover:to-purple-500 text-white font-semibold text-center transition-all duration-300 shadow-lg shadow-cyan-500/10"> <i data-lucide="send" class="w-5 h-5"></i> <span>ติดต่อฉันตอนนี้</span> </a> </div> </header> <main class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 pt-24 pb-16"> <!-- Hero Section --> <section id="hero" class="min-h-[85vh] flex flex-col md:flex-row items-center justify-between py-12 md:py-20 gap-12 md:gap-8"> <!-- Hero Details --> <div class="flex-1 space-y-6 text-center md:text-left order-2 md:order-1"> <div class="inline-flex items-center space-x-2 px-3.5 py-1.5 rounded-full bg-cyan-500/10 border border-cyan-500/30 text-cyan-400 text-sm font-semibold tracking-wide"> <span class="w-2 h-2 rounded-full bg-cyan-400 animate-ping"></span> <span>พร้อมรับงาน / Available for Hire</span> </div> <h1 class="text-4xl sm:text-5xl lg:text-6xl font-extrabold tracking-tight leading-none"> สวัสดีครับ, ผมคือ <br class="hidden sm:inline"> <span class="bg-gradient-to-r from-cyan-400 via-teal-300 to-purple-500 bg-clip-text text-transparent">กรกฎ ใจมูล</span> </h1> <!-- CTAs --> <div class="flex flex-col sm:flex-row items-center justify-center md:justify-start gap-4 pt-4"> <a href="#projects" class="w-full sm:w-auto px-8 py-4 rounded-xl bg-gradient-to-r from-cyan-500 to-purple-600 hover:from-cyan-400 hover:to-purple-500 text-white font-bold transition-all duration-300 shadow-lg hover:shadow-cyan-500/25 flex items-center justify-center gap-2 hover:-translate-y-0.5"> ดูผลงานของฉัน <i data-lucide="arrow-right" class="w-5 h-5"></i> </a> <a href="#contact" class="w-full sm:w-auto px-8 py-4 rounded-xl bg-slate-900/60 border border-slate-800 hover:border-slate-700 hover:bg-slate-800/80 text-slate-300 font-bold transition-all duration-300 flex items-center justify-center gap-2"> ติดต่อฉัน <i data-lucide="mail" class="w-5 h-5"></i> </a> </div> <!-- Social Badges --> <div class="flex items-center justify-center md:justify-start gap-4 pt-6 text-slate-400"> <a href="https://github.com/thban554" target="_blank" class="hover:text-cyan-400 transition-colors" aria-label="GitHub"> <i data-lucide="github" class="w-6 h-6"></i> </a> <a href="tel:097-056-6414" class="hover:text-cyan-400 transition-colors" aria-label="Phone"> <i data-lucide="phone" class="w-6 h-6"></i> </a> <a href="mailto:thban554@gmail.com" class="hover:text-cyan-400 transition-colors" aria-label="Email"> <i data-lucide="mail" class="w-6 h-6"></i> </a> </div> </div> <!-- Hero Graphic --> <div class="flex-grow flex justify-center order-1 md:order-2"> <div class="relative w-72 h-72 sm:w-80 sm:h-80 lg:w-[350px] lg:h-[350px] animate-float group"> <!-- Aura rings --> <div class="absolute inset-0 rounded-3xl bg-gradient-to-tr from-cyan-500 to-purple-500 opacity-20 blur-xl group-hover:opacity-35 transition-opacity duration-500"> </div> <!-- Outer border ring --> <div class="absolute inset-0 rounded-3xl border border-cyan-500/30 p-2"> <!-- Glass Box Inner Container --> <div class="w-full h-full rounded-2xl glass-panel overflow-hidden relative border-slate-800 bg-slate-900/40 backdrop-blur-md"> <img src="profile.jpg" alt="กรกฎ ใจมูล" class="w-full h-full object-cover rounded-xl group-hover:scale-105 transition-transform duration-500" loading="eager"> <!-- Name overlay badge --> <div class="absolute bottom-4 left-4 right-4 glass-panel px-4 py-3 rounded-xl border-slate-700/50 flex justify-between items-center"> <div> <h3 class="text-sm font-bold text-white font-outfit">กรกฎ ใจมูล</h3> <p class="text-[10px] text-cyan-400">Full-Stack Student / Developer</p> </div> <span class="text-xs bg-cyan-500/20 text-cyan-300 px-2.5 py-1 rounded-md border border-cyan-500/30 font-semibold">ฮาร์ทบิท</span> </div> </div> </div> </div> </div> </section> <!-- About Me Section --> <section id="about" class="py-16 md:py-24 border-t border-slate-900"> <div class="text-center max-w-3xl mx-auto mb-16"> <h2 class="text-3xl sm:text-4xl font-bold mb-4 font-outfit"> เกี่ยวกับฉัน & ทักษะความสามารถ </h2> <div class="h-1.5 w-20 bg-gradient-to-r from-cyan-400 to-purple-500 mx-auto rounded-full"></div> <p class="text-slate-400 mt-6 text-sm sm:text-base"> ประวัติการเรียนรู้ ความเชี่ยวชาญด้านเทคโนโลยีที่คัดสรรมาเพื่อตอบโจทย์งานระบบเว็บยุคใหม่ </p> </div> <!-- Tabbed Profile & Contact Row --> <div class="grid grid-cols-1 lg:grid-cols-12 gap-8 items-stretch mb-12"> <!-- Left Column (Profile Tab Card) --> <div class="lg:col-span-5 flex flex-col"> <!-- Tab Title --> <div class="flex"> <div class="px-6 py-2.5 rounded-t-xl bg-slate-900 border-t border-x border-slate-800 text-slate-200 font-semibold text-sm flex items-center gap-2"> <i data-lucide="user" class="w-4 h-4 text-cyan-400"></i> โปรไฟล์ </div> </div> <!-- Card Body --> <div class="flex-grow glass-panel p-6 rounded-b-2xl rounded-r-2xl border-slate-800/80 flex flex-col items-center justify-center text-center space-y-4"> <div class="relative w-48 h-48 rounded-2xl overflow-hidden border-2 border-cyan-500/20 shadow-lg shadow-cyan-500/5 group"> <img src="profile.jpg" alt="กรกฎ ใจมูล" class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500"> </div> <div> <h3 class="text-2xl font-bold text-slate-100 font-outfit">กรกฎ ใจมูล</h3> <p class="text-sm text-cyan-400 mt-1">Student / Web Developer</p> </div> </div> </div> <!-- Right Column (About Me Tab Card) --> <div class="lg:col-span-7 flex flex-col"> <!-- Tab Title --> <div class="flex"> <div class="px-6 py-2.5 rounded-t-xl bg-gradient-to-r from-cyan-500/20 to-purple-500/20 border-t border-x border-cyan-500/30 text-cyan-300 font-semibold text-sm flex items-center gap-2"> <i data-lucide="info" class="w-4 h-4 text-cyan-400"></i> เกี่ยวกับฉัน </div> </div> <!-- Card Body --> <div class="flex-grow glass-panel p-6 sm:p-8 rounded-b-2xl rounded-l-2xl border-cyan-500/20 space-y-6"> <div class="grid grid-cols-1 md:grid-cols-2 gap-6"> <!-- ข้อมูลส่วนตัว --> <div class="space-y-4"> <h4 class="text-lg font-bold text-slate-100 flex items-center gap-2 pb-2 border-b border-slate-800"> <i data-lucide="user-check" class="w-5 h-5 text-cyan-400"></i> ข้อมูลส่วนตัว </h4> <div class="space-y-3 text-sm"> <div class="flex justify-between border-b border-slate-900 pb-1.5"> <span class="text-slate-500">ชื่อจริง</span> <strong class="text-slate-200">กรกฎ ใจมูล</strong> </div> <div class="flex justify-between border-b border-slate-900 pb-1.5"> <span class="text-slate-500">ชื่อเล่น</span> <strong class="text-slate-200">ฮาร์ทบิท</strong> </div> <div class="flex justify-between border-b border-slate-900 pb-1.5"> <span class="text-slate-500">อายุ</span> <strong class="text-slate-200">18 ปี</strong> </div> </div> </div> <!-- ช่องทางการติดต่อ --> <div class="space-y-4"> <h4 class="text-lg font-bold text-slate-100 flex items-center gap-2 pb-2 border-b border-slate-800"> <i data-lucide="contact" class="w-5 h-5 text-purple-400"></i> ช่องทางการติดต่อ </h4> <div class="space-y-3 text-sm"> <a href="tel:097-056-6414" class="flex justify-between border-b border-slate-900 pb-1.5 hover:text-cyan-400 transition-colors group"> <span class="text-slate-500">โทร</span> <strong class="text-slate-200 group-hover:text-cyan-400">097-056-6414</strong> </a> <div class="flex justify-between border-b border-slate-900 pb-1.5"> <span class="text-slate-500">ที่อยู่</span> <strong class="text-slate-200 text-right">62 ถ.หลังตลาดทิพยเนตร ต.หายยา</strong> </div> <a href="mailto:thban554@gmail.com" class="flex justify-between border-b border-slate-900 pb-1.5 hover:text-cyan-400 transition-colors group"> <span class="text-slate-500">อีเมล</span> <strong class="text-slate-200 group-hover:text-cyan-400 text-xs sm:text-sm">thban554@gmail.com</strong> </a> </div> </div> </div> </div> </div> </div> <!-- Education, Work Experience & Activities Row --> <div class="grid grid-cols-1 lg:grid-cols-12 gap-8 items-stretch mb-12"> <!-- Education & Work Experience Card --> <div class="lg:col-span-6 glass-panel p-6 sm:p-8 rounded-2xl border-slate-800/80 space-y-6"> <!-- ประวัติทางการศึกษา --> <div class="space-y-4"> <h3 class="text-xl font-bold text-slate-100 flex items-center gap-3"> <i data-lucide="graduation-cap" class="w-6 h-6 text-cyan-400"></i> ประวัติทางการศึกษา </h3> <div class="relative pl-6 border-l border-slate-800 space-y-4"> <!-- Item 1 --> <div class="relative"> <div class="absolute -left-[30px] top-1.5 w-3.5 h-3.5 rounded-full bg-cyan-400 border-4 border-slate-950"></div> <h4 class="text-sm font-semibold text-slate-200">ประถมศึกษา</h4> <p class="text-xs text-slate-400 mt-0.5">โรงเรียนพุทธิโศภน</p> </div> <!-- Item 2 --> <div class="relative"> <div class="absolute -left-[30px] top-1.5 w-3.5 h-3.5 rounded-full bg-cyan-400 border-4 border-slate-950"></div> <h4 class="text-sm font-semibold text-slate-200">มัธยมต้น</h4> <p class="text-xs text-slate-400 mt-0.5">โรงเรียนวัฒโนทัยพายัพ</p> </div> <!-- Item 3 --> <div class="relative"> <div class="absolute -left-[30px] top-1.5 w-3.5 h-3.5 rounded-full bg-purple-500 border-4 border-slate-950"></div> <h4 class="text-sm font-semibold text-cyan-300">ปัจจุบัน</h4> <p class="text-xs text-slate-400 mt-0.5">วิทยาลัยเทคนิคเชียงใหม่</p> </div> </div> </div> <!-- ประสบการณ์ทำงาน --> <div class="space-y-4 pt-4 border-t border-slate-800"> <h3 class="text-xl font-bold text-slate-100 flex items-center gap-3"> <i data-lucide="briefcase" class="w-6 h-6 text-purple-400"></i> ประสบการณ์ทำงาน </h3> <div class="relative pl-6 border-l border-slate-800"> <div class="relative"> <div class="absolute -left-[30px] top-1.5 w-3.5 h-3.5 rounded-full bg-purple-500 border-4 border-slate-950"></div> <h4 class="text-sm font-semibold text-slate-200">ฝึกงานร้านซ่อม Macbook</h4> <p class="text-xs text-slate-400 mt-0.5">เคยฝึกงานอยู่ร้านซ่อม macbook เชียงใหม่</p> </div> </div> </div> </div> <!-- Favorite Activities Card --> <div class="lg:col-span-6 glass-panel p-6 sm:p-8 rounded-2xl border-slate-800/80 flex flex-col justify-between space-y-6"> <div class="space-y-4"> <h3 class="text-xl font-bold text-slate-100 flex items-center gap-3"> <i data-lucide="heart" class="w-6 h-6 text-pink-500 animate-pulse"></i> กิจกรรมที่ชอบ </h3> <div class="grid grid-cols-1 sm:grid-cols-2 gap-4 items-center"> <ul class="space-y-3 text-slate-300 text-sm"> <li class="flex items-center gap-2"> <span class="w-1.5 h-1.5 rounded-full bg-cyan-400"></span> เล่น rov, roblox </li> <li class="flex items-center gap-2"> <span class="w-1.5 h-1.5 rounded-full bg-cyan-400"></span> เล่นกับแมว </li> <li class="flex items-center gap-2"> <span class="w-1.5 h-1.5 rounded-full bg-cyan-400"></span> อ่านการ์ตูน </li> </ul> <!-- Cat Picture Container --> <div class="flex justify-center sm:justify-end"> <div class="relative w-36 h-36 rounded-2xl overflow-hidden border border-slate-800 shadow-md group"> <img src="cat.jpg" alt="น้องแมวสุดโปรด" class="w-full h-full object-cover group-hover:scale-110 transition-transform duration-500"> <div class="absolute bottom-2 left-2 right-2 bg-slate-950/70 backdrop-blur-sm px-2 py-0.5 rounded-lg text-center border border-slate-800"> <span class="text-[10px] text-slate-300 font-semibold">เล่นกับแมว 🐱</span> </div> </div> </div> </div> </div> <div class="pt-4 border-t border-slate-800"> <h4 class="text-xs font-bold uppercase text-slate-500 tracking-wider mb-2">ทักษะที่เกี่ยวข้องกับการฝึกงาน</h4> <div class="flex flex-wrap gap-1.5"> <span class="px-2 py-0.5 text-xs rounded bg-slate-900 border border-slate-800 text-slate-300">Mac Diagnostics</span> <span class="px-2 py-0.5 text-xs rounded bg-slate-900 border border-slate-800 text-slate-300">Hardware Assembly</span> <span class="px-2 py-0.5 text-xs rounded bg-slate-900 border border-slate-800 text-slate-300">macOS Troubleshooting</span> </div> </div> </div> </div> <!-- Skills Matrix (Underneath) --> <div class="space-y-6"> <h3 class="text-xl sm:text-2xl font-bold text-slate-100 flex items-center gap-3 px-2"> <i data-lucide="code-2" class="w-6 h-6 text-purple-400"></i> ทักษะการพัฒนา (Skills Matrix) </h3> <div class="grid grid-cols-1 md:grid-cols-3 gap-4"> <!-- Frontend Glass Card --> <div class="glass-panel p-5 rounded-2xl border-slate-800"> <div class="flex items-center space-x-2.5 text-cyan-400 mb-4"> <i data-lucide="layout" class="w-5 h-5"></i> <h4 class="font-bold text-slate-100">Frontend</h4> </div> <div class="flex flex-wrap gap-2"> <span class="px-2.5 py-1 text-xs rounded-lg bg-slate-900 border border-slate-800 text-slate-300">HTML5 / CSS3</span> <span class="px-2.5 py-1 text-xs rounded-lg bg-slate-900 border border-slate-800 text-slate-300">JavaScript (ES6+)</span> <span class="px-2.5 py-1 text-xs rounded-lg bg-slate-900 border border-slate-800 text-slate-300">React.js</span> <span class="px-2.5 py-1 text-xs rounded-lg bg-slate-900 border border-slate-800 text-slate-300">Next.js</span> <span class="px-2.5 py-1 text-xs rounded-lg bg-slate-900 border border-slate-800 text-slate-300">Tailwind CSS</span> <span class="px-2.5 py-1 text-xs rounded-lg bg-slate-900 border border-slate-800 text-slate-300">Bootstrap</span> </div> </div> <!-- Backend Glass Card --> <div class="glass-panel p-5 rounded-2xl border-slate-800"> <div class="flex items-center space-x-2.5 text-purple-400 mb-4"> <i data-lucide="server" class="w-5 h-5"></i> <h4 class="font-bold text-slate-100">Backend</h4> </div> <div class="flex flex-wrap gap-2"> <span class="px-2.5 py-1 text-xs rounded-lg bg-slate-900 border border-slate-800 text-slate-300">Node.js</span> <span class="px-2.5 py-1 text-xs rounded-lg bg-slate-900 border border-slate-800 text-slate-300">Express.js</span> <span class="px-2.5 py-1 text-xs rounded-lg bg-slate-900 border border-slate-800 text-slate-300">PHP (Laravel)</span> <span class="px-2.5 py-1 text-xs rounded-lg bg-slate-900 border border-slate-800 text-slate-300">FastAPI</span> <span class="px-2.5 py-1 text-xs rounded-lg bg-slate-900 border border-slate-800 text-slate-300">RESTful APIs</span> </div> </div> <!-- Databases & DevOps --> <div class="glass-panel p-5 rounded-2xl border-slate-800"> <div class="flex items-center space-x-2.5 text-teal-400 mb-4"> <i data-lucide="database" class="w-5 h-5"></i> <h4 class="font-bold text-slate-100">Database / DevOps</h4> </div> <div class="flex flex-wrap gap-2"> <span class="px-2.5 py-1 text-xs rounded-lg bg-slate-900 border border-slate-800 text-slate-300">MySQL</span> <span class="px-2.5 py-1 text-xs rounded-lg bg-slate-900 border border-slate-800 text-slate-300">PostgreSQL</span> <span class="px-2.5 py-1 text-xs rounded-lg bg-slate-900 border border-slate-800 text-slate-300">MongoDB</span> <span class="px-2.5 py-1 text-xs rounded-lg bg-slate-900 border border-slate-800 text-slate-300">Git / GitHub</span> <span class="px-2.5 py-1 text-xs rounded-lg bg-slate-900 border border-slate-800 text-slate-300">Docker</span> <span class="px-2.5 py-1 text-xs rounded-lg bg-slate-900 border border-slate-800 text-slate-300">Firebase</span> </div> </div> </div> </div> </section> <!-- Projects Portfolio Section --> <section id="projects" class="py-16 md:py-24 border-t border-slate-900"> <div class="text-center max-w-3xl mx-auto mb-12"> <h2 class="text-3xl sm:text-4xl font-bold mb-4 font-outfit"> แฟ้มสะสมผลงาน (Portfolio) </h2> <div class="h-1.5 w-20 bg-gradient-to-r from-cyan-400 to-purple-500 mx-auto rounded-full"></div> <p class="text-slate-400 mt-6 text-sm sm:text-base"> โปรเจกต์ที่ผ่านการพัฒนาด้วยความประณีต รองรับการแสดงผลหน้าจอมือถือและเดสก์ท็อปอย่างสมบูรณ์แบบ </p> </div> <!-- Filter Controls --> <div class="flex flex-wrap items-center justify-center gap-2 mb-12"> <button class="filter-btn px-5 py-2 rounded-xl text-sm font-semibold border border-slate-800 bg-slate-900/60 text-slate-300 hover:border-cyan-500/50 hover:text-cyan-400 transition-all duration-300" data-filter="all">ทั้งหมด</button> <button class="filter-btn px-5 py-2 rounded-xl text-sm font-semibold border border-slate-800 bg-slate-900/60 text-slate-300 hover:border-cyan-500/50 hover:text-cyan-400 transition-all duration-300" data-filter="frontend">Frontend</button> <button class="filter-btn px-5 py-2 rounded-xl text-sm font-semibold border border-slate-800 bg-slate-900/60 text-slate-300 hover:border-purple-500/50 hover:text-purple-400 transition-all duration-300" data-filter="backend">Backend</button> <button class="filter-btn px-5 py-2 rounded-xl text-sm font-semibold border border-slate-800 bg-slate-900/60 text-slate-300 hover:border-teal-500/50 hover:text-teal-400 transition-all duration-300" data-filter="fullstack">Full-Stack</button> </div> <!-- Projects Grid --> <div id="projects-grid" class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8"> <!-- Rendered Dynamically via JS --> </div> </section> <!-- Contact Section --> <section id="contact" class="py-16 md:py-24 border-t border-slate-900"> <div class="text-center max-w-3xl mx-auto mb-16"> <h2 class="text-3xl sm:text-4xl font-bold mb-4 font-outfit"> ติดต่อฉัน (Contact Me) </h2> <div class="h-1.5 w-20 bg-gradient-to-r from-cyan-400 to-purple-500 mx-auto rounded-full"></div> <p class="text-slate-400 mt-6 text-sm sm:text-base"> หากมีข้อเสนอแนะ ข้อซักถาม หรือสนใจร่วมงาน สามารถส่งข้อความหาผมได้โดยตรงผ่านช่องทางด้านล่างครับ </p> </div> <div class="grid grid-cols-1 lg:grid-cols-12 gap-12 items-stretch"> <!-- Contact Channels (Left) --> <div class="lg:col-span-5 space-y-6 flex flex-col justify-between"> <div class="space-y-6"> <h3 class="text-xl sm:text-2xl font-bold text-slate-100 flex items-center gap-3"> <i data-lucide="message-square-plus" class="w-6 h-6 text-cyan-400"></i> พูดคุยและแลกเปลี่ยน </h3> <p class="text-slate-300 leading-relaxed text-sm sm:text-base"> ยินดีรับคำแนะนำ โปรเจกต์ฟรีแลนซ์ และโอกาสร่วมงานทุกประเภท ยินดีที่จะพูดคุยเกี่ยวกับสถาปัตยกรรมเว็บแอปพลิเคชันและการออกแบบระบบที่รองรับการปรับขยาย </p> </div> <!-- Cards representing contact channels --> <div class="space-y-4 pt-6"> <a href="mailto:thban554@gmail.com" class="flex items-center space-x-4 p-4 rounded-2xl glass-panel glass-panel-hover border-slate-800 transition-all duration-300"> <div class="w-12 h-12 rounded-xl bg-cyan-500/10 flex items-center justify-center text-cyan-400"> <i data-lucide="mail" class="w-6 h-6"></i> </div> <div> <span class="text-slate-500 text-xs block font-semibold uppercase">Email</span> <span class="text-slate-200 text-sm sm:text-base font-medium">thban554@gmail.com</span> </div> </a> <a href="tel:097-056-6414" class="flex items-center space-x-4 p-4 rounded-2xl glass-panel glass-panel-hover border-slate-800 transition-all duration-300"> <div class="w-12 h-12 rounded-xl bg-purple-500/10 flex items-center justify-center text-purple-400"> <i data-lucide="phone" class="w-6 h-6"></i> </div> <div> <span class="text-slate-500 text-xs block font-semibold uppercase">Phone</span> <span class="text-slate-200 text-sm sm:text-base font-medium">097-056-6414</span> </div> </a> <a href="https://github.com/thban554" target="_blank" class="flex items-center space-x-4 p-4 rounded-2xl glass-panel glass-panel-hover border-slate-800 transition-all duration-300"> <div class="w-12 h-12 rounded-xl bg-slate-500/15 flex items-center justify-center text-slate-300"> <i data-lucide="github" class="w-6 h-6"></i> </div> <div> <span class="text-slate-500 text-xs block font-semibold uppercase">GitHub</span> <span class="text-slate-200 text-sm sm:text-base font-medium">github.com/thban554</span> </div> </a> </div> </div> <!-- Contact Form (Right) --> <div class="lg:col-span-7"> <form id="contact-form" class="glass-panel p-6 sm:p-8 rounded-2xl border-slate-800 space-y-6 flex flex-col justify-between h-full"> <div class="space-y-4"> <!-- Name Input --> <div> <label for="name" class="block text-sm font-semibold text-slate-300 mb-2">ชื่อของคุณ *</label> <input type="text" id="name" required class="w-full px-4 py-3 rounded-xl bg-slate-950 border border-slate-800 text-slate-200 focus:outline-none focus:border-cyan-500/70 focus:ring-1 focus:ring-cyan-500/30 transition-all duration-300 placeholder:text-slate-600 text-sm sm:text-base" placeholder="ระบุชื่อ-นามสกุล"> </div> <!-- Email Input --> <div> <label for="email" class="block text-sm font-semibold text-slate-300 mb-2">อีเมลติดต่อกลับ *</label> <input type="email" id="email" required class="w-full px-4 py-3 rounded-xl bg-slate-950 border border-slate-800 text-slate-200 focus:outline-none focus:border-cyan-500/70 focus:ring-1 focus:ring-cyan-500/30 transition-all duration-300 placeholder:text-slate-600 text-sm sm:text-base" placeholder="example@email.com"> </div> <!-- Subject Input --> <div> <label for="subject" class="block text-sm font-semibold text-slate-300 mb-2">หัวข้อ *</label> <input type="text" id="subject" required class="w-full px-4 py-3 rounded-xl bg-slate-950 border border-slate-800 text-slate-200 focus:outline-none focus:border-cyan-500/70 focus:ring-1 focus:ring-cyan-500/30 transition-all duration-300 placeholder:text-slate-600 text-sm sm:text-base" placeholder="หัวข้อการติดต่อ"> </div> <!-- Message Textarea --> <div> <label for="message" class="block text-sm font-semibold text-slate-300 mb-2">ข้อความ *</label> <textarea id="message" rows="5" required class="w-full px-4 py-3 rounded-xl bg-slate-950 border border-slate-800 text-slate-200 focus:outline-none focus:border-cyan-500/70 focus:ring-1 focus:ring-cyan-500/30 transition-all duration-300 placeholder:text-slate-600 text-sm sm:text-base resize-none" placeholder="ระบุรายละเอียดข้อความของคุณที่นี่..."></textarea> </div> </div> <!-- Submit Button --> <button type="submit" id="submit-btn" class="w-full mt-4 px-6 py-4 rounded-xl bg-gradient-to-r from-cyan-500 to-purple-600 hover:from-cyan-400 hover:to-purple-500 text-white font-bold transition-all duration-300 shadow-lg hover:shadow-cyan-500/20 flex items-center justify-center gap-2"> <i data-lucide="send" class="w-5 h-5"></i> ส่งข้อความ </button> </form> </div> </div> </section> </main> <!-- Footer --> <footer class="border-t border-slate-900 bg-slate-950/80 backdrop-blur-md py-12 relative z-10"> <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex flex-col md:flex-row items-center justify-between gap-6"> <div class="flex items-center space-x-2"> <div class="w-8 h-8 rounded-lg bg-gradient-to-tr from-cyan-400 to-purple-500 flex items-center justify-center"> <span class="text-white font-bold text-base font-outfit">P</span> </div> <span class="font-outfit font-bold text-slate-200 text-sm">Portfolio © 2026</span> </div> <p class="text-slate-500 text-xs sm:text-sm text-center md:text-right"> Designed & Built with ❤️ using Tailwind CSS & Vanilla JS. All rights reserved. </p> </div> </footer> <!-- Glass Toast Notification --> <div id="toast" class="fixed bottom-6 right-6 z-50 transform translate-y-24 opacity-0 transition-all duration-300 max-w-sm w-full"> <div class="glass-panel p-4 rounded-2xl border-emerald-500/30 bg-slate-900/90 shadow-2xl flex items-start space-x-3"> <div class="w-10 h-10 rounded-xl bg-emerald-500/10 flex items-center justify-center text-emerald-400 flex-shrink-0"> <i data-lucide="check-circle" class="w-6 h-6"></i> </div> <div> <h4 class="font-bold text-slate-100 text-sm">ส่งข้อความสำเร็จ!</h4> <p class="text-slate-400 text-xs mt-1">ได้รับข้อความเรียบร้อยแล้ว ผมจะติดต่อกลับให้เร็วที่สุดครับ</p> </div> <button id="close-toast" class="text-slate-500 hover:text-slate-200 transition-colors ml-auto self-start"> <i data-lucide="x" class="w-4 h-4"></i> </button> </div> </div> <!-- Sticky Bottom Navigation for Mobile --> <div class="fixed bottom-6 left-1/2 -translate-x-1/2 w-[92%] max-w-md bg-slate-950/85 border border-slate-800/80 backdrop-blur-lg rounded-2xl h-16 flex items-center justify-between px-6 z-50 shadow-2xl md:hidden"> <a href="#hero" class="mobile-bottom-link flex flex-col items-center justify-center text-slate-400 hover:text-cyan-400 transition-colors py-1 min-h-[44px]" data-section="hero"> <i data-lucide="home" class="w-5 h-5"></i> <span class="text-[10px] mt-1 font-medium">หน้าแรก</span> </a> <a href="#about" class="mobile-bottom-link flex flex-col items-center justify-center text-slate-400 hover:text-cyan-400 transition-colors py-1 min-h-[44px]" data-section="about"> <i data-lucide="user" class="w-5 h-5"></i> <span class="text-[10px] mt-1 font-medium">เกี่ยวกับฉัน</span> </a> <a href="#projects" class="mobile-bottom-link flex flex-col items-center justify-center text-slate-400 hover:text-cyan-400 transition-colors py-1 min-h-[44px]" data-section="projects"> <i data-lucide="folder-git-2" class="w-5 h-5"></i> <span class="text-[10px] mt-1 font-medium">ผลงาน</span> </a> <a href="#contact" class="mobile-bottom-link flex flex-col items-center justify-center text-slate-400 hover:text-cyan-400 transition-colors py-1 min-h-[44px]" data-section="contact"> <i data-lucide="mail" class="w-5 h-5"></i> <span class="text-[10px] mt-1 font-medium">ติดต่อ</span> </a> <!-- Divider --> <div class="h-8 w-[1px] bg-slate-800/80"></div> <!-- Burger Menu Button on Bottom Nav --> <button id="bottom-menu-btn" class="flex flex-col items-center justify-center text-slate-400 hover:text-cyan-400 transition-colors py-1 min-h-[44px] focus:outline-none"> <i data-lucide="menu" id="bottom-menu-icon" class="w-5 h-5 transition-transform duration-300"></i> <span class="text-[10px] mt-1 font-medium">เมนู</span> </button> </div> <!-- Bottom Menu Drawer Overlay --> <div id="bottom-drawer" class="fixed inset-0 bg-slate-950/60 backdrop-blur-sm z-40 hidden transition-opacity duration-300 opacity-0 md:hidden"></div> <div id="bottom-drawer-content" class="fixed bottom-0 left-0 right-0 bg-slate-900/95 border-t border-slate-800/80 rounded-t-3xl z-50 p-6 pb-12 space-y-4 shadow-2xl transition-all duration-300 transform translate-y-full md:hidden backdrop-blur-lg"> <div class="w-12 h-1.5 bg-slate-800 rounded-full mx-auto mb-2"></div> <div class="flex items-center justify-between pb-3 border-b border-slate-800/60"> <h3 class="font-outfit font-bold text-lg text-white">เมนูเพิ่มเติม</h3> <div class="flex items-center gap-2"> <!-- Theme Toggle Button (Mobile) --> <button id="theme-toggle-mobile" class="p-2 rounded-xl bg-slate-950/40 border border-slate-800/60 text-slate-300 hover:text-cyan-400 transition-all min-h-[44px] flex items-center justify-center" aria-label="Toggle Theme"> <i data-lucide="sun" id="theme-toggle-icon-mobile" class="w-4.5 h-4.5"></i> </button> <button id="close-drawer-btn" class="text-slate-400 hover:text-white transition-colors min-h-[44px] flex items-center justify-center"> <i data-lucide="x" class="w-5 h-5"></i> </button> </div> </div> <div class="grid grid-cols-2 gap-3 py-2"> <a href="#hero" class="drawer-nav-link flex flex-col items-center p-4 rounded-xl bg-slate-950/40 border border-slate-800/60 hover:border-cyan-500/30 text-slate-300 hover:text-cyan-400 transition-all min-h-[44px]" data-section="hero"> <i data-lucide="home" class="w-6 h-6 text-cyan-400"></i> <span class="text-xs font-semibold mt-2">หน้าแรก</span> </a> <a href="#about" class="drawer-nav-link flex flex-col items-center p-4 rounded-xl bg-slate-950/40 border border-slate-800/60 hover:border-cyan-500/30 text-slate-300 hover:text-cyan-400 transition-all min-h-[44px]" data-section="about"> <i data-lucide="user" class="w-6 h-6 text-purple-400"></i> <span class="text-xs font-semibold mt-2">เกี่ยวกับฉัน</span> </a> <a href="#projects" class="drawer-nav-link flex flex-col items-center p-4 rounded-xl bg-slate-950/40 border border-slate-800/60 hover:border-cyan-500/30 text-slate-300 hover:text-cyan-400 transition-all min-h-[44px]" data-section="projects"> <i data-lucide="folder-git-2" class="w-6 h-6 text-emerald-400"></i> <span class="text-xs font-semibold mt-2">ผลงาน</span> </a> <a href="#contact" class="drawer-nav-link flex flex-col items-center p-4 rounded-xl bg-slate-950/40 border border-slate-800/60 hover:border-cyan-500/30 text-slate-300 hover:text-cyan-400 transition-all min-h-[44px]" data-section="contact"> <i data-lucide="mail" class="w-6 h-6 text-pink-400"></i> <span class="text-xs font-semibold mt-2">ติดต่อ</span> </a> </div> <!-- Social channels in Drawer --> <div class="flex items-center justify-around py-3 border-t border-slate-800/60"> <a href="https://github.com/thban554" target="_blank" class="flex items-center gap-2 text-slate-400 hover:text-cyan-400 transition-colors text-xs py-2 min-h-[44px]"> <i data-lucide="github" class="w-4 h-4"></i> GitHub </a> <a href="tel:097-056-6414" class="flex items-center gap-2 text-slate-400 hover:text-cyan-400 transition-colors text-xs py-2 min-h-[44px]"> <i data-lucide="phone" class="w-4 h-4"></i> โทร </a> <a href="mailto:thban554@gmail.com" class="flex items-center gap-2 text-slate-400 hover:text-cyan-400 transition-colors text-xs py-2 min-h-[44px]"> <i data-lucide="mail" class="w-4 h-4"></i> อีเมล </a> </div> </div> <!-- Javascript Logic --> <script src="projects.js"></script> <script> // Initialize Lucide Icons lucide.createIcons(); // Elements const mainHeader = document.getElementById('main-header'); const mobileMenuBtn = document.getElementById('mobile-menu-btn'); const mobileDropdown = document.getElementById('mobile-dropdown'); const menuIcon = document.getElementById('menu-icon'); const projectsGrid = document.getElementById('projects-grid'); const filterBtns = document.querySelectorAll('.filter-btn'); const contactForm = document.getElementById('contact-form'); const toast = document.getElementById('toast'); const closeToast = document.getElementById('close-toast'); const navLinks = document.querySelectorAll('.nav-link'); const mobileNavLinks = document.querySelectorAll('.mobile-nav-link'); const mobileBottomLinks = document.querySelectorAll('.mobile-bottom-link'); const drawerNavLinks = document.querySelectorAll('.drawer-nav-link'); const bottomMenuBtn = document.getElementById('bottom-menu-btn'); const bottomMenuIcon = document.getElementById('bottom-menu-icon'); const bottomDrawer = document.getElementById('bottom-drawer'); const bottomDrawerContent = document.getElementById('bottom-drawer-content'); const closeDrawerBtn = document.getElementById('close-drawer-btn'); const themeToggle = document.getElementById('theme-toggle'); const themeToggleMobile = document.getElementById('theme-toggle-mobile'); const themeToggleIcon = document.getElementById('theme-toggle-icon'); const themeToggleIconMobile = document.getElementById('theme-toggle-icon-mobile'); // Theme Switcher Logic const htmlEl = document.documentElement; // Check local storage or default to dark const currentTheme = localStorage.getItem('theme') || 'dark'; if (currentTheme === 'light') { htmlEl.classList.remove('dark'); setTimeout(() => updateThemeIcons('light'), 50); } else { htmlEl.classList.add('dark'); setTimeout(() => updateThemeIcons('dark'), 50); } function updateThemeIcons(theme) { if (theme === 'dark') { themeToggleIcon.setAttribute('data-lucide', 'sun'); themeToggleIconMobile.setAttribute('data-lucide', 'sun'); } else { themeToggleIcon.setAttribute('data-lucide', 'moon'); themeToggleIconMobile.setAttribute('data-lucide', 'moon'); } lucide.createIcons(); } function toggleTheme() { if (htmlEl.classList.contains('dark')) { htmlEl.classList.remove('dark'); localStorage.setItem('theme', 'light'); updateThemeIcons('light'); } else { htmlEl.classList.add('dark'); localStorage.setItem('theme', 'dark'); updateThemeIcons('dark'); } } themeToggle.addEventListener('click', toggleTheme); themeToggleMobile.addEventListener('click', toggleTheme); // Mobile Drawer Toggle let isDrawerOpen = false; function openDrawer() { isDrawerOpen = true; bottomDrawer.classList.remove('hidden'); // Force reflow void bottomDrawer.offsetWidth; bottomDrawer.classList.remove('opacity-0'); bottomDrawer.classList.add('opacity-100'); bottomDrawerContent.classList.remove('translate-y-full'); bottomDrawerContent.classList.add('translate-y-0'); bottomMenuIcon.setAttribute('data-lucide', 'x'); lucide.createIcons(); } function closeDrawer() { isDrawerOpen = false; bottomDrawer.classList.remove('opacity-100'); bottomDrawer.classList.add('opacity-0'); bottomDrawerContent.classList.remove('translate-y-0'); bottomDrawerContent.classList.add('translate-y-full'); bottomMenuIcon.setAttribute('data-lucide', 'menu'); lucide.createIcons(); setTimeout(() => { if (!isDrawerOpen) { bottomDrawer.classList.add('hidden'); } }, 300); } bottomMenuBtn.addEventListener('click', () => { if (isDrawerOpen) { closeDrawer(); } else { openDrawer(); } }); closeDrawerBtn.addEventListener('click', closeDrawer); bottomDrawer.addEventListener('click', closeDrawer); // Close drawer when clicking any link inside drawerNavLinks.forEach(link => { link.addEventListener('click', closeDrawer); }); mobileBottomLinks.forEach(link => { link.addEventListener('click', closeDrawer); }); // 1. Navbar scroll states window.addEventListener('scroll', () => { if (window.scrollY > 20) { mainHeader.classList.add('bg-slate-950/80', 'backdrop-blur-md', 'border-b', 'border-slate-900', 'shadow-lg'); mainHeader.classList.remove('h-20'); mainHeader.classList.add('h-16'); } else { mainHeader.classList.remove('bg-slate-950/80', 'backdrop-blur-md', 'border-b', 'border-slate-900', 'shadow-lg'); mainHeader.classList.remove('h-16'); mainHeader.classList.add('h-20'); } }); // 2. Mobile Menu Toggle let isMenuOpen = false; mobileMenuBtn.addEventListener('click', () => { isMenuOpen = !isMenuOpen; if (isMenuOpen) { mobileDropdown.classList.remove('hidden'); // Trigger reflow for transition void mobileDropdown.offsetWidth; mobileDropdown.classList.remove('scale-y-95', 'opacity-0'); mobileDropdown.classList.add('scale-y-100', 'opacity-100'); menuIcon.setAttribute('data-lucide', 'x'); lucide.createIcons(); } else { closeMobileMenu(); } }); function closeMobileMenu() { isMenuOpen = false; mobileDropdown.classList.remove('scale-y-100', 'opacity-100'); mobileDropdown.classList.add('scale-y-95', 'opacity-0'); menuIcon.setAttribute('data-lucide', 'menu'); lucide.createIcons(); setTimeout(() => { if (!isMenuOpen) mobileDropdown.classList.add('hidden'); }, 300); } // Close menu when clicking mobile links mobileNavLinks.forEach(link => { link.addEventListener('click', closeMobileMenu); }); // 3. Populate & Filter Projects Grid function renderProjects(filterValue = 'all') { projectsGrid.innerHTML = ''; const filtered = projects.filter(project => { return filterValue === 'all' || project.category === filterValue; }); filtered.forEach(project => { const card = document.createElement('div'); card.className = 'project-card glass-panel rounded-2xl border-slate-800/80 overflow-hidden flex flex-col justify-between group transition-all duration-300 hover:border-cyan-500/30 hover:shadow-xl hover:shadow-cyan-500/5 hover:-translate-y-1'; // Tags elements markup const tagsMarkup = project.tags.map(tag => `<span class="px-2 py-0.5 text-[10px] sm:text-xs rounded bg-slate-900 border border-slate-800 text-slate-400">${tag}</span>` ).join(''); card.innerHTML = ` <div> <!-- Project Image Container --> <div class="relative overflow-hidden aspect-video border-b border-slate-900"> <img src="${project.image}" alt="${project.title}" class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500" loading="lazy"> <div class="absolute inset-0 bg-gradient-to-t from-slate-950/80 to-transparent opacity-60"></div> </div> <!-- Details --> <div class="p-5 space-y-3"> <h3 class="text-lg sm:text-xl font-bold text-slate-100 group-hover:text-cyan-400 transition-colors duration-300">${project.title}</h3> <p class="text-slate-400 text-xs sm:text-sm leading-relaxed">${project.description}</p> </div> </div> <div class="p-5 pt-0 space-y-4"> <!-- Tech Badges --> <div class="flex flex-wrap gap-1.5"> ${tagsMarkup} </div> <!-- Links --> <div class="flex items-center gap-3 pt-2 border-t border-slate-900"> <a href="${project.githubUrl}" target="_blank" class="flex-1 py-2 px-3 rounded-lg bg-slate-900/50 hover:bg-slate-800/80 border border-slate-800 text-xs font-semibold text-slate-300 hover:text-white flex items-center justify-center gap-1.5 transition-all"> <i data-lucide="github" class="w-3.5 h-3.5"></i> Source Code </a> <a href="${project.liveUrl}" target="_blank" class="flex-1 py-2 px-3 rounded-lg bg-cyan-500/10 hover:bg-cyan-500/20 border border-cyan-500/20 hover:border-cyan-500/40 text-xs font-semibold text-cyan-400 flex items-center justify-center gap-1.5 transition-all"> <i data-lucide="external-link" class="w-3.5 h-3.5"></i> Live Demo </a> </div> </div> `; projectsGrid.appendChild(card); }); // Re-trigger icon creation for the newly generated elements lucide.createIcons(); } // Set Active Filter Button Style function updateActiveFilterButton(activeBtn) { filterBtns.forEach(btn => { btn.classList.remove('bg-gradient-to-r', 'from-cyan-500/20', 'to-purple-500/20', 'border-cyan-500/50', 'text-cyan-400'); btn.classList.add('bg-slate-900/60', 'text-slate-300', 'border-slate-800'); }); activeBtn.classList.remove('bg-slate-900/60', 'text-slate-300', 'border-slate-800'); activeBtn.classList.add('bg-gradient-to-r', 'from-cyan-500/20', 'to-purple-500/20', 'border-cyan-500/50', 'text-cyan-400'); } // Setup Filter Button Click Listeners filterBtns.forEach(btn => { btn.addEventListener('click', (e) => { const filterValue = e.target.getAttribute('data-filter'); updateActiveFilterButton(e.target); renderProjects(filterValue); }); }); // Initial Render of Projects renderProjects(); updateActiveFilterButton(filterBtns[0]); // default 'all' // 4. Contact Form Submission contactForm.addEventListener('submit', (e) => { e.preventDefault(); const submitBtn = document.getElementById('submit-btn'); const originalContent = submitBtn.innerHTML; // Show sending loader simulation submitBtn.disabled = true; submitBtn.innerHTML = `<svg class="animate-spin h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path></svg> กำลังส่ง...`; setTimeout(() => { // Success State showToast(); contactForm.reset(); submitBtn.disabled = false; submitBtn.innerHTML = originalContent; }, 1500); }); // 5. Toast Notification System function showToast() { toast.classList.remove('translate-y-24', 'opacity-0'); toast.classList.add('translate-y-0', 'opacity-100'); setTimeout(() => { hideToast(); }, 5000); } function hideToast() { toast.classList.remove('translate-y-0', 'opacity-100'); toast.classList.add('translate-y-24', 'opacity-0'); } closeToast.addEventListener('click', hideToast); // 6. Intersection Observer to Highlight Active Nav Section const sections = document.querySelectorAll('section'); const observerOptions = { root: null, rootMargin: '-30% 0px -60% 0px', // triggers when section is in the middle of viewport threshold: 0 }; const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { const sectionId = entry.target.getAttribute('id'); highlightNav(sectionId); } }); }, observerOptions); sections.forEach(section => observer.observe(section)); function highlightNav(sectionId) { navLinks.forEach(link => { if (link.getAttribute('data-section') === sectionId) { link.classList.add('active-nav-link'); link.classList.remove('text-slate-300'); } else { link.classList.remove('active-nav-link'); link.classList.add('text-slate-300'); } }); mobileNavLinks.forEach(link => { if (link.getAttribute('data-section') === sectionId) { link.classList.add('bg-cyan-500/10', 'text-cyan-400'); link.classList.remove('text-slate-300'); } else { link.classList.remove('bg-cyan-500/10', 'text-cyan-400'); link.classList.add('text-slate-300'); } }); mobileBottomLinks.forEach(link => { if (link.getAttribute('data-section') === sectionId) { link.classList.add('text-cyan-400'); link.classList.remove('text-slate-400'); } else { link.classList.remove('text-cyan-400'); link.classList.add('text-slate-400'); } }); drawerNavLinks.forEach(link => { if (link.getAttribute('data-section') === sectionId) { link.classList.add('border-cyan-500/30', 'bg-slate-900/60', 'text-cyan-400'); link.classList.remove('border-slate-800/60', 'bg-slate-950/40', 'text-slate-300'); } else { link.classList.remove('border-cyan-500/30', 'bg-slate-900/60', 'text-cyan-400'); link.classList.add('border-slate-800/60', 'bg-slate-950/40', 'text-slate-300'); } }); } </script> </body> </html>
| ver. 1.4 |
Github
|
.
| PHP 7.4.33 | Generation time: 0.32 |
proxy
|
phpinfo
|
Settings