From 9efa488e24239d438d6eb1f3c8eb8a4cda8a17bd Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 24 Jan 2026 23:35:59 +0000 Subject: [PATCH 1/2] Build modern portfolio site with dark mode and glassmorphism design Replace redirect page with a full-featured portfolio site including: - Hero section with animated gradient orbs and typing effect - About section with tech stack and animated stats - Experience timeline with glassmorphism cards - Projects bento grid layout - Learnings/blog section - Contact section with terminal aesthetic - Responsive design with mobile navigation - Dark/light theme toggle with localStorage persistence - Smooth scroll animations and intersection observers --- index.html | 671 ++++++++++++++++++++++++++- script.js | 326 ++++++++++++++ styles.css | 1278 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 2267 insertions(+), 8 deletions(-) create mode 100644 script.js create mode 100644 styles.css diff --git a/index.html b/index.html index d889afd1..d8efbecc 100644 --- a/index.html +++ b/index.html @@ -1,10 +1,665 @@ - - - Redirecting... - - - -

Redirecting...

- + + + + + + + Will Pracht | Software Engineer + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
+ + Available for opportunities +
+

+ Hi, I'm + Will Pracht +

+
+ Software Engineer + | +
+

+ I build exceptional digital experiences that live at the intersection of design and technology. + Passionate about creating elegant solutions to complex problems. +

+ + +
+
+ Scroll to explore +
+ + + + +
+
+
+ + +
+
+
+ +

About Me

+
+
+
+

+ I'm a software engineer who loves turning complex problems into simple, beautiful solutions. + With a passion for clean code and user-centric design, I create digital experiences that make a difference. +

+

+ When I'm not coding, you'll find me exploring new technologies, contributing to open source, + or sharing knowledge with the developer community. I believe in continuous learning and pushing + the boundaries of what's possible. +

+
+
+ 0+ + Years Experience +
+
+ 0+ + Projects Completed +
+
+ 0+ + Technologies +
+
+
+
+

Tech Stack

+
+
+

Languages

+
+ JavaScript + TypeScript + Python + Go + Rust +
+
+
+

Frontend

+
+ React + Next.js + Vue + Tailwind +
+
+
+

Backend

+
+ Node.js + PostgreSQL + MongoDB + GraphQL +
+
+
+

DevOps

+
+ Docker + AWS + CI/CD + Kubernetes +
+
+
+
+
+ +
+
+ + +
+
+
+ +

Experience

+

My professional journey so far

+
+
+
+
+
+
+
+

Senior Software Engineer

+

Tech Company

+
+ 2022 - Present +
+

+ Leading development of scalable microservices architecture. Mentoring junior developers + and driving technical decisions for high-impact projects. +

+
+ React + Node.js + AWS + Kubernetes +
+
+
+
+
+
+
+
+

Software Engineer

+

Startup Inc

+
+ 2020 - 2022 +
+

+ Built full-stack applications from scratch. Implemented CI/CD pipelines and + improved deployment processes, reducing release time by 60%. +

+
+ Vue.js + Python + PostgreSQL + Docker +
+
+
+
+
+
+
+
+

Junior Developer

+

Agency Co

+
+ 2018 - 2020 +
+

+ Developed responsive web applications for various clients. Collaborated with designers + to implement pixel-perfect interfaces. +

+
+ JavaScript + HTML/CSS + WordPress + PHP +
+
+
+
+ + +
+
+ + +
+
+
+ +

Featured Projects

+

A selection of my recent work

+
+
+
+
+
+ + + + + +
+
+
+
+ React + Node.js + MongoDB +
+

Project Alpha

+

+ A full-stack web application with real-time collaboration features. + Built with modern technologies and designed for scale. +

+ +
+
+
+
+
+ Python + FastAPI + ML +
+

ML Pipeline

+

+ Automated machine learning pipeline for data processing and model training. +

+ +
+
+
+
+
+ Go + CLI +
+

DevTool CLI

+

+ Developer productivity CLI tool. +

+ +
+
+
+
+
+ TypeScript + VSCode +
+

VSCode Extension

+

+ Productivity extension for VS Code. +

+ +
+
+ +
+ + +
+
+ + +
+
+
+ +

Learnings & Thoughts

+

Things I've learned along the way

+
+
+
+
+ + + + +
+ January 2025 +

The Art of Writing Clean Code

+

+ Reflections on code readability, maintainability, and the practices that make codebases a joy to work with. +

+ + Read more + + + + + +
+
+
+ + + + + +
+ December 2024 +

Building for Scale

+

+ Lessons learned from scaling applications to handle millions of requests and the architectural patterns that made it possible. +

+ + Read more + + + + + +
+
+
+ + + + + + +
+ November 2024 +

Effective Team Collaboration

+

+ Thoughts on code reviews, pair programming, and building a culture of continuous improvement within engineering teams. +

+ + Read more + + + + + +
+
+
+ + + + + + +
+ October 2024 +

Developer Experience Matters

+

+ Why investing in DX pays dividends and how to build tools that developers actually want to use. +

+ + Read more + + + + + +
+
+ +
+
+ + +
+
+
+ +

Get in Touch

+

Let's build something amazing together

+
+
+
+

+ I'm always open to discussing new projects, creative ideas, or opportunities to be part of your vision. + Feel free to reach out! +

+ +
+
+
+
+ + + +
+ contact.sh +
+
+
+ $ + echo $GREETING +
+
Thanks for visiting my portfolio!
+
+ $ + cat availability.txt +
+
Open to new opportunities
+
+ $ + ./send-message.sh +
+ +
+
+
+ +
+
+ + + + + + + diff --git a/script.js b/script.js new file mode 100644 index 00000000..82c3c117 --- /dev/null +++ b/script.js @@ -0,0 +1,326 @@ +// =================================== +// Portfolio JavaScript +// =================================== + +document.addEventListener('DOMContentLoaded', () => { + initThemeToggle(); + initNavigation(); + initScrollAnimations(); + initCounterAnimation(); + initTypingEffect(); + initSmoothScroll(); + updateFooterYear(); +}); + +// =================================== +// Theme Toggle (Dark/Light Mode) +// =================================== +function initThemeToggle() { + const themeToggle = document.getElementById('theme-toggle'); + const html = document.documentElement; + + // Check for saved theme preference or default to dark + const savedTheme = localStorage.getItem('theme') || 'dark'; + html.setAttribute('data-theme', savedTheme); + + themeToggle.addEventListener('click', () => { + const currentTheme = html.getAttribute('data-theme'); + const newTheme = currentTheme === 'dark' ? 'light' : 'dark'; + + html.setAttribute('data-theme', newTheme); + localStorage.setItem('theme', newTheme); + + // Add a subtle animation + themeToggle.style.transform = 'rotate(360deg)'; + setTimeout(() => { + themeToggle.style.transform = ''; + }, 300); + }); +} + +// =================================== +// Navigation +// =================================== +function initNavigation() { + const nav = document.getElementById('nav'); + const navToggle = document.getElementById('nav-toggle'); + const navLinks = document.getElementById('nav-links'); + const links = navLinks.querySelectorAll('.nav-link'); + + // Scroll behavior - add background on scroll + let lastScroll = 0; + + window.addEventListener('scroll', () => { + const currentScroll = window.pageYOffset; + + if (currentScroll > 50) { + nav.classList.add('scrolled'); + } else { + nav.classList.remove('scrolled'); + } + + lastScroll = currentScroll; + }); + + // Mobile menu toggle + navToggle.addEventListener('click', () => { + navToggle.classList.toggle('active'); + navLinks.classList.toggle('active'); + document.body.style.overflow = navLinks.classList.contains('active') ? 'hidden' : ''; + }); + + // Close mobile menu when clicking a link + links.forEach(link => { + link.addEventListener('click', () => { + navToggle.classList.remove('active'); + navLinks.classList.remove('active'); + document.body.style.overflow = ''; + }); + }); + + // Active link on scroll + const sections = document.querySelectorAll('section[id]'); + + window.addEventListener('scroll', () => { + const scrollY = window.pageYOffset; + + sections.forEach(section => { + const sectionHeight = section.offsetHeight; + const sectionTop = section.offsetTop - 100; + const sectionId = section.getAttribute('id'); + const navLink = document.querySelector(`.nav-link[href="#${sectionId}"]`); + + if (navLink && scrollY > sectionTop && scrollY <= sectionTop + sectionHeight) { + links.forEach(link => link.classList.remove('active')); + navLink.classList.add('active'); + } + }); + }); +} + +// =================================== +// Scroll Animations +// =================================== +function initScrollAnimations() { + const observerOptions = { + root: null, + rootMargin: '0px', + threshold: 0.1 + }; + + const observer = new IntersectionObserver((entries) => { + entries.forEach(entry => { + if (entry.isIntersecting) { + entry.target.classList.add('visible'); + // Optionally unobserve after animation + // observer.unobserve(entry.target); + } + }); + }, observerOptions); + + // Observe elements that should animate + const animateElements = document.querySelectorAll( + '.section-header, .about-text, .about-skills, .timeline-item, ' + + '.project-card, .learning-card, .contact-info, .contact-terminal' + ); + + animateElements.forEach(el => { + el.classList.add('fade-in'); + observer.observe(el); + }); +} + +// =================================== +// Counter Animation +// =================================== +function initCounterAnimation() { + const counters = document.querySelectorAll('.stat-number'); + + const observerOptions = { + root: null, + rootMargin: '0px', + threshold: 0.5 + }; + + const observer = new IntersectionObserver((entries) => { + entries.forEach(entry => { + if (entry.isIntersecting) { + const counter = entry.target; + const target = parseInt(counter.getAttribute('data-count')); + animateCounter(counter, target); + observer.unobserve(counter); + } + }); + }, observerOptions); + + counters.forEach(counter => observer.observe(counter)); +} + +function animateCounter(element, target) { + const duration = 2000; // 2 seconds + const start = 0; + const increment = target / (duration / 16); // 60fps + let current = start; + + const timer = setInterval(() => { + current += increment; + if (current >= target) { + element.textContent = target; + clearInterval(timer); + } else { + element.textContent = Math.floor(current); + } + }, 16); +} + +// =================================== +// Typing Effect +// =================================== +function initTypingEffect() { + const typingElement = document.querySelector('.typing-text'); + if (!typingElement) return; + + const titles = [ + 'Software Engineer', + 'Full Stack Developer', + 'Problem Solver', + 'Open Source Enthusiast', + 'Tech Explorer' + ]; + + let titleIndex = 0; + let charIndex = 0; + let isDeleting = false; + let typingSpeed = 100; + + function type() { + const currentTitle = titles[titleIndex]; + + if (isDeleting) { + typingElement.textContent = currentTitle.substring(0, charIndex - 1); + charIndex--; + typingSpeed = 50; + } else { + typingElement.textContent = currentTitle.substring(0, charIndex + 1); + charIndex++; + typingSpeed = 100; + } + + if (!isDeleting && charIndex === currentTitle.length) { + // Pause at end of word + typingSpeed = 2000; + isDeleting = true; + } else if (isDeleting && charIndex === 0) { + isDeleting = false; + titleIndex = (titleIndex + 1) % titles.length; + typingSpeed = 500; + } + + setTimeout(type, typingSpeed); + } + + // Start typing effect after a delay + setTimeout(type, 1000); +} + +// =================================== +// Smooth Scroll +// =================================== +function initSmoothScroll() { + document.querySelectorAll('a[href^="#"]').forEach(anchor => { + anchor.addEventListener('click', function(e) { + e.preventDefault(); + const targetId = this.getAttribute('href'); + + if (targetId === '#') return; + + const targetElement = document.querySelector(targetId); + + if (targetElement) { + const headerOffset = 80; + const elementPosition = targetElement.getBoundingClientRect().top; + const offsetPosition = elementPosition + window.pageYOffset - headerOffset; + + window.scrollTo({ + top: offsetPosition, + behavior: 'smooth' + }); + } + }); + }); +} + +// =================================== +// Update Footer Year +// =================================== +function updateFooterYear() { + const yearElement = document.getElementById('current-year'); + if (yearElement) { + yearElement.textContent = new Date().getFullYear(); + } +} + +// =================================== +// Parallax Effect (Optional Enhancement) +// =================================== +function initParallax() { + const orbs = document.querySelectorAll('.gradient-orb'); + + window.addEventListener('mousemove', (e) => { + const { clientX, clientY } = e; + const centerX = window.innerWidth / 2; + const centerY = window.innerHeight / 2; + + const moveX = (clientX - centerX) / centerX; + const moveY = (clientY - centerY) / centerY; + + orbs.forEach((orb, index) => { + const speed = (index + 1) * 20; + orb.style.transform = `translate(${moveX * speed}px, ${moveY * speed}px)`; + }); + }); +} + +// =================================== +// Form Validation (For Future Use) +// =================================== +function validateEmail(email) { + const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + return re.test(email); +} + +// =================================== +// Utility: Debounce Function +// =================================== +function debounce(func, wait) { + let timeout; + return function executedFunction(...args) { + const later = () => { + clearTimeout(timeout); + func(...args); + }; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + }; +} + +// =================================== +// Utility: Throttle Function +// =================================== +function throttle(func, limit) { + let inThrottle; + return function executedFunction(...args) { + if (!inThrottle) { + func(...args); + inThrottle = true; + setTimeout(() => inThrottle = false, limit); + } + }; +} + +// =================================== +// Console Easter Egg +// =================================== +console.log('%c Hey there, curious developer! 👋', 'font-size: 20px; font-weight: bold; color: #8b5cf6;'); +console.log('%c Thanks for checking out my portfolio.', 'font-size: 14px; color: #06b6d4;'); +console.log('%c Feel free to connect: https://github.com/willpracht', 'font-size: 12px; color: #a0a0b0;'); diff --git a/styles.css b/styles.css new file mode 100644 index 00000000..b06af3ba --- /dev/null +++ b/styles.css @@ -0,0 +1,1278 @@ +/* =================================== + CSS Variables & Theme Configuration + =================================== */ +:root { + /* Colors - Dark Theme (Default) */ + --bg-primary: #0a0a0f; + --bg-secondary: #12121a; + --bg-tertiary: #1a1a24; + --text-primary: #ffffff; + --text-secondary: #a0a0b0; + --text-muted: #6b6b7b; + --accent-primary: #8b5cf6; + --accent-secondary: #06b6d4; + --accent-gradient: linear-gradient(135deg, #8b5cf6 0%, #06b6d4 100%); + --glass-bg: rgba(255, 255, 255, 0.03); + --glass-border: rgba(255, 255, 255, 0.08); + --glass-shadow: 0 8px 32px rgba(0, 0, 0, 0.3); + --card-hover: rgba(255, 255, 255, 0.05); + + /* Typography */ + --font-primary: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; + --font-mono: 'JetBrains Mono', 'Fira Code', monospace; + + /* Spacing */ + --section-padding: clamp(4rem, 10vw, 8rem); + --container-max: 1200px; + --border-radius: 16px; + --border-radius-sm: 8px; + + /* Transitions */ + --transition-fast: 0.15s ease; + --transition-base: 0.3s ease; + --transition-slow: 0.5s ease; +} + +/* Light Theme */ +[data-theme="light"] { + --bg-primary: #fafafa; + --bg-secondary: #ffffff; + --bg-tertiary: #f0f0f5; + --text-primary: #1a1a2e; + --text-secondary: #4a4a5a; + --text-muted: #8a8a9a; + --glass-bg: rgba(255, 255, 255, 0.7); + --glass-border: rgba(0, 0, 0, 0.08); + --glass-shadow: 0 8px 32px rgba(0, 0, 0, 0.1); + --card-hover: rgba(0, 0, 0, 0.03); +} + +/* =================================== + Reset & Base Styles + =================================== */ +*, *::before, *::after { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +html { + scroll-behavior: smooth; + scroll-padding-top: 80px; +} + +body { + font-family: var(--font-primary); + background-color: var(--bg-primary); + color: var(--text-primary); + line-height: 1.6; + overflow-x: hidden; + transition: background-color var(--transition-base), color var(--transition-base); +} + +::selection { + background: var(--accent-primary); + color: white; +} + +a { + color: inherit; + text-decoration: none; + transition: color var(--transition-fast); +} + +img { + max-width: 100%; + height: auto; + display: block; +} + +button { + font-family: inherit; + cursor: pointer; + border: none; + background: none; +} + +/* =================================== + Utility Classes + =================================== */ +.container { + max-width: var(--container-max); + margin: 0 auto; + padding: 0 clamp(1rem, 5vw, 2rem); +} + +.glass-card { + background: var(--glass-bg); + border: 1px solid var(--glass-border); + border-radius: var(--border-radius); + backdrop-filter: blur(20px); + -webkit-backdrop-filter: blur(20px); + box-shadow: var(--glass-shadow); + transition: transform var(--transition-base), box-shadow var(--transition-base), background var(--transition-base); +} + +.glass-card:hover { + transform: translateY(-4px); + background: var(--card-hover); + box-shadow: 0 12px 40px rgba(139, 92, 246, 0.15); +} + +/* =================================== + Navigation + =================================== */ +.nav { + position: fixed; + top: 0; + left: 0; + right: 0; + z-index: 1000; + padding: 1rem 0; + transition: background-color var(--transition-base), backdrop-filter var(--transition-base); +} + +.nav.scrolled { + background: rgba(10, 10, 15, 0.8); + backdrop-filter: blur(20px); + -webkit-backdrop-filter: blur(20px); + border-bottom: 1px solid var(--glass-border); +} + +[data-theme="light"] .nav.scrolled { + background: rgba(250, 250, 250, 0.8); +} + +.nav-container { + max-width: var(--container-max); + margin: 0 auto; + padding: 0 clamp(1rem, 5vw, 2rem); + display: flex; + align-items: center; + justify-content: space-between; +} + +.nav-logo { + font-size: 1.5rem; + font-weight: 700; + display: flex; + align-items: center; + gap: 0.25rem; +} + +.logo-bracket { + color: var(--accent-primary); + font-family: var(--font-mono); +} + +.nav-links { + display: flex; + gap: 2rem; +} + +.nav-link { + font-size: 0.9rem; + font-weight: 500; + color: var(--text-secondary); + position: relative; + padding: 0.5rem 0; +} + +.nav-link::after { + content: ''; + position: absolute; + bottom: 0; + left: 0; + width: 0; + height: 2px; + background: var(--accent-gradient); + transition: width var(--transition-base); +} + +.nav-link:hover { + color: var(--text-primary); +} + +.nav-link:hover::after { + width: 100%; +} + +.nav-actions { + display: flex; + align-items: center; + gap: 1rem; +} + +.theme-toggle { + width: 40px; + height: 40px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + color: var(--text-secondary); + transition: color var(--transition-fast), background var(--transition-fast); +} + +.theme-toggle:hover { + color: var(--text-primary); + background: var(--glass-bg); +} + +.theme-toggle .sun-icon { + display: none; +} + +.theme-toggle .moon-icon { + display: block; +} + +[data-theme="light"] .theme-toggle .sun-icon { + display: block; +} + +[data-theme="light"] .theme-toggle .moon-icon { + display: none; +} + +.nav-toggle { + display: none; + flex-direction: column; + gap: 5px; + width: 24px; + height: 20px; + position: relative; +} + +.nav-toggle span { + display: block; + width: 100%; + height: 2px; + background: var(--text-primary); + border-radius: 2px; + transition: transform var(--transition-base), opacity var(--transition-base); +} + +.nav-toggle.active span:nth-child(1) { + transform: translateY(7px) rotate(45deg); +} + +.nav-toggle.active span:nth-child(2) { + opacity: 0; +} + +.nav-toggle.active span:nth-child(3) { + transform: translateY(-7px) rotate(-45deg); +} + +/* =================================== + Hero Section + =================================== */ +.hero { + min-height: 100vh; + display: flex; + align-items: center; + justify-content: center; + position: relative; + padding: 6rem 0; + overflow: hidden; +} + +.hero-bg { + position: absolute; + inset: 0; + overflow: hidden; + z-index: -1; +} + +.gradient-orb { + position: absolute; + border-radius: 50%; + filter: blur(80px); + opacity: 0.5; + animation: float 20s ease-in-out infinite; +} + +.orb-1 { + width: 600px; + height: 600px; + background: radial-gradient(circle, rgba(139, 92, 246, 0.4) 0%, transparent 70%); + top: -200px; + right: -200px; + animation-delay: 0s; +} + +.orb-2 { + width: 500px; + height: 500px; + background: radial-gradient(circle, rgba(6, 182, 212, 0.3) 0%, transparent 70%); + bottom: -100px; + left: -100px; + animation-delay: -7s; +} + +.orb-3 { + width: 400px; + height: 400px; + background: radial-gradient(circle, rgba(139, 92, 246, 0.3) 0%, transparent 70%); + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + animation-delay: -14s; +} + +@keyframes float { + 0%, 100% { transform: translate(0, 0) scale(1); } + 25% { transform: translate(30px, -30px) scale(1.05); } + 50% { transform: translate(-20px, 20px) scale(0.95); } + 75% { transform: translate(20px, 10px) scale(1.02); } +} + +.hero-content { + text-align: center; + max-width: 800px; + padding: 0 2rem; +} + +.hero-badge { + display: inline-flex; + align-items: center; + gap: 0.5rem; + padding: 0.5rem 1rem; + background: var(--glass-bg); + border: 1px solid var(--glass-border); + border-radius: 50px; + font-size: 0.85rem; + color: var(--text-secondary); + margin-bottom: 2rem; + animation: fadeInUp 0.8s ease forwards; +} + +.status-dot { + width: 8px; + height: 8px; + background: #22c55e; + border-radius: 50%; + animation: pulse 2s ease-in-out infinite; +} + +@keyframes pulse { + 0%, 100% { opacity: 1; transform: scale(1); } + 50% { opacity: 0.5; transform: scale(1.2); } +} + +.hero-title { + margin-bottom: 1rem; + animation: fadeInUp 0.8s ease forwards; + animation-delay: 0.1s; + opacity: 0; +} + +.greeting { + display: block; + font-size: clamp(1rem, 3vw, 1.25rem); + font-weight: 400; + color: var(--text-secondary); + margin-bottom: 0.5rem; +} + +.name { + display: block; + font-size: clamp(2.5rem, 8vw, 5rem); + font-weight: 800; + background: var(--accent-gradient); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + line-height: 1.1; +} + +.hero-subtitle { + display: flex; + align-items: center; + justify-content: center; + gap: 0.25rem; + font-size: clamp(1.25rem, 4vw, 2rem); + font-weight: 600; + margin-bottom: 1.5rem; + animation: fadeInUp 0.8s ease forwards; + animation-delay: 0.2s; + opacity: 0; +} + +.cursor { + animation: blink 1s step-end infinite; + color: var(--accent-primary); +} + +@keyframes blink { + 0%, 100% { opacity: 1; } + 50% { opacity: 0; } +} + +.hero-description { + font-size: clamp(1rem, 2vw, 1.125rem); + color: var(--text-secondary); + max-width: 600px; + margin: 0 auto 2rem; + line-height: 1.8; + animation: fadeInUp 0.8s ease forwards; + animation-delay: 0.3s; + opacity: 0; +} + +.hero-cta { + display: flex; + gap: 1rem; + justify-content: center; + flex-wrap: wrap; + margin-bottom: 3rem; + animation: fadeInUp 0.8s ease forwards; + animation-delay: 0.4s; + opacity: 0; +} + +.btn { + display: inline-flex; + align-items: center; + gap: 0.5rem; + padding: 0.875rem 1.75rem; + font-size: 0.95rem; + font-weight: 600; + border-radius: var(--border-radius-sm); + transition: all var(--transition-base); +} + +.btn-primary { + background: var(--accent-gradient); + color: white; + box-shadow: 0 4px 20px rgba(139, 92, 246, 0.3); +} + +.btn-primary:hover { + transform: translateY(-2px); + box-shadow: 0 8px 30px rgba(139, 92, 246, 0.4); +} + +.btn-secondary { + background: var(--glass-bg); + border: 1px solid var(--glass-border); + color: var(--text-primary); +} + +.btn-secondary:hover { + background: var(--card-hover); + border-color: var(--accent-primary); +} + +.btn-outline { + background: transparent; + border: 2px solid var(--accent-primary); + color: var(--accent-primary); +} + +.btn-outline:hover { + background: var(--accent-primary); + color: white; +} + +.hero-socials { + display: flex; + gap: 1rem; + justify-content: center; + animation: fadeInUp 0.8s ease forwards; + animation-delay: 0.5s; + opacity: 0; +} + +.social-link { + width: 48px; + height: 48px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 50%; + background: var(--glass-bg); + border: 1px solid var(--glass-border); + color: var(--text-secondary); + transition: all var(--transition-base); +} + +.social-link:hover { + color: var(--accent-primary); + border-color: var(--accent-primary); + transform: translateY(-3px); +} + +.scroll-indicator { + position: absolute; + bottom: 2rem; + left: 50%; + transform: translateX(-50%); + display: flex; + flex-direction: column; + align-items: center; + gap: 0.5rem; + color: var(--text-muted); + font-size: 0.8rem; + animation: fadeIn 1s ease forwards; + animation-delay: 1s; + opacity: 0; +} + +.scroll-arrow { + animation: bounce 2s ease-in-out infinite; +} + +@keyframes bounce { + 0%, 100% { transform: translateY(0); } + 50% { transform: translateY(8px); } +} + +@keyframes fadeIn { + to { opacity: 1; } +} + +@keyframes fadeInUp { + from { + opacity: 0; + transform: translateY(30px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +/* =================================== + Section Styles + =================================== */ +.section { + padding: var(--section-padding) 0; + position: relative; +} + +.section-header { + text-align: center; + margin-bottom: 4rem; +} + +.section-tag { + display: inline-block; + font-family: var(--font-mono); + font-size: 0.875rem; + color: var(--accent-primary); + margin-bottom: 1rem; + opacity: 0.8; +} + +.section-tag-close { + display: block; + text-align: center; + margin-top: 4rem; +} + +.section-title { + font-size: clamp(2rem, 5vw, 3rem); + font-weight: 700; + margin-bottom: 1rem; +} + +.section-subtitle { + font-size: 1.1rem; + color: var(--text-secondary); + max-width: 600px; + margin: 0 auto; +} + +/* =================================== + About Section + =================================== */ +.about-content { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 4rem; + align-items: start; +} + +.about-intro { + font-size: 1.25rem; + color: var(--text-primary); + margin-bottom: 1.5rem; + line-height: 1.8; +} + +.about-text p { + color: var(--text-secondary); + margin-bottom: 1.5rem; + line-height: 1.8; +} + +.about-stats { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 2rem; + margin-top: 2rem; + padding-top: 2rem; + border-top: 1px solid var(--glass-border); +} + +.stat { + text-align: center; +} + +.stat-number { + font-size: 2.5rem; + font-weight: 700; + background: var(--accent-gradient); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +.stat-suffix { + font-size: 2rem; + font-weight: 700; + background: var(--accent-gradient); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +.stat-label { + display: block; + font-size: 0.85rem; + color: var(--text-muted); + margin-top: 0.25rem; +} + +.skills-title { + font-size: 1.25rem; + font-weight: 600; + margin-bottom: 1.5rem; +} + +.skills-grid { + display: grid; + gap: 1.5rem; +} + +.skill-category h4 { + font-size: 0.9rem; + color: var(--text-muted); + margin-bottom: 0.75rem; + text-transform: uppercase; + letter-spacing: 0.05em; +} + +.skill-tags { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; +} + +.skill-tag { + display: inline-block; + padding: 0.5rem 1rem; + background: var(--glass-bg); + border: 1px solid var(--glass-border); + border-radius: 50px; + font-size: 0.85rem; + color: var(--text-secondary); + transition: all var(--transition-base); +} + +.skill-tag:hover { + border-color: var(--accent-primary); + color: var(--accent-primary); +} + +/* =================================== + Experience Section + =================================== */ +.timeline { + max-width: 800px; + margin: 0 auto; + position: relative; +} + +.timeline::before { + content: ''; + position: absolute; + left: 0; + top: 0; + bottom: 0; + width: 2px; + background: var(--glass-border); +} + +.timeline-item { + position: relative; + padding-left: 3rem; + padding-bottom: 3rem; +} + +.timeline-item:last-child { + padding-bottom: 0; +} + +.timeline-marker { + position: absolute; + left: -7px; + top: 0; + width: 16px; + height: 16px; + background: var(--accent-gradient); + border-radius: 50%; + border: 3px solid var(--bg-primary); +} + +.timeline-content { + padding: 1.5rem; +} + +.timeline-header { + display: flex; + justify-content: space-between; + align-items: flex-start; + gap: 1rem; + margin-bottom: 1rem; + flex-wrap: wrap; +} + +.timeline-title { + font-size: 1.25rem; + font-weight: 600; +} + +.timeline-company { + color: var(--accent-primary); + font-size: 0.95rem; + margin-top: 0.25rem; +} + +.timeline-date { + font-size: 0.85rem; + color: var(--text-muted); + font-family: var(--font-mono); +} + +.timeline-description { + color: var(--text-secondary); + margin-bottom: 1rem; + line-height: 1.7; +} + +.timeline-tags { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; +} + +.timeline-tags span { + padding: 0.25rem 0.75rem; + background: rgba(139, 92, 246, 0.1); + border-radius: 50px; + font-size: 0.8rem; + color: var(--accent-primary); +} + +.resume-cta { + text-align: center; + margin-top: 3rem; +} + +/* =================================== + Projects Section (Bento Grid) + =================================== */ +.bento-grid { + display: grid; + grid-template-columns: repeat(4, 1fr); + grid-auto-rows: minmax(200px, auto); + gap: 1.5rem; +} + +.bento-large { + grid-column: span 2; + grid-row: span 2; +} + +.bento-medium { + grid-column: span 2; +} + +.bento-small { + grid-column: span 1; +} + +.project-card { + display: flex; + flex-direction: column; + padding: 1.5rem; + overflow: hidden; +} + +.project-image { + flex: 1; + min-height: 150px; + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 1rem; +} + +.project-placeholder { + width: 100%; + height: 100%; + min-height: 150px; + display: flex; + align-items: center; + justify-content: center; + background: linear-gradient(135deg, rgba(139, 92, 246, 0.1) 0%, rgba(6, 182, 212, 0.1) 100%); + border-radius: var(--border-radius-sm); + color: var(--text-muted); +} + +.project-content { + display: flex; + flex-direction: column; + gap: 0.75rem; +} + +.project-tags { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; +} + +.project-tags span { + padding: 0.25rem 0.75rem; + background: rgba(139, 92, 246, 0.1); + border-radius: 50px; + font-size: 0.75rem; + color: var(--accent-primary); +} + +.project-title { + font-size: 1.25rem; + font-weight: 600; +} + +.project-description { + color: var(--text-secondary); + font-size: 0.9rem; + line-height: 1.6; +} + +.project-links { + display: flex; + gap: 1rem; + margin-top: auto; + padding-top: 1rem; +} + +.project-link { + display: inline-flex; + align-items: center; + gap: 0.5rem; + font-size: 0.9rem; + color: var(--text-secondary); + transition: color var(--transition-fast); +} + +.project-link:hover { + color: var(--accent-primary); +} + +.projects-cta { + text-align: center; + margin-top: 3rem; +} + +/* =================================== + Learnings Section + =================================== */ +.learnings-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); + gap: 1.5rem; +} + +.learning-card { + padding: 2rem; + display: flex; + flex-direction: column; + gap: 1rem; +} + +.learning-icon { + width: 48px; + height: 48px; + display: flex; + align-items: center; + justify-content: center; + background: rgba(139, 92, 246, 0.1); + border-radius: var(--border-radius-sm); + color: var(--accent-primary); +} + +.learning-date { + font-size: 0.8rem; + color: var(--text-muted); + font-family: var(--font-mono); +} + +.learning-title { + font-size: 1.1rem; + font-weight: 600; +} + +.learning-excerpt { + color: var(--text-secondary); + font-size: 0.9rem; + line-height: 1.6; + flex: 1; +} + +.learning-link { + display: inline-flex; + align-items: center; + gap: 0.5rem; + font-size: 0.9rem; + color: var(--accent-primary); + font-weight: 500; + margin-top: auto; +} + +.learning-link:hover { + gap: 0.75rem; +} + +/* =================================== + Contact Section + =================================== */ +.contact-content { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 4rem; + align-items: start; +} + +.contact-intro { + font-size: 1.1rem; + color: var(--text-secondary); + line-height: 1.8; + margin-bottom: 2rem; +} + +.contact-methods { + display: flex; + flex-direction: column; + gap: 1rem; +} + +.contact-method { + display: flex; + align-items: center; + gap: 1rem; + padding: 1.25rem; +} + +.contact-icon { + width: 48px; + height: 48px; + display: flex; + align-items: center; + justify-content: center; + background: rgba(139, 92, 246, 0.1); + border-radius: var(--border-radius-sm); + color: var(--accent-primary); + flex-shrink: 0; +} + +.contact-details { + display: flex; + flex-direction: column; +} + +.contact-label { + font-size: 0.8rem; + color: var(--text-muted); + text-transform: uppercase; + letter-spacing: 0.05em; +} + +.contact-value { + font-weight: 500; + color: var(--text-primary); +} + +/* Terminal */ +.contact-terminal { + overflow: hidden; +} + +.terminal-header { + display: flex; + align-items: center; + gap: 1rem; + padding: 0.75rem 1rem; + background: rgba(0, 0, 0, 0.3); + border-bottom: 1px solid var(--glass-border); +} + +.terminal-buttons { + display: flex; + gap: 0.5rem; +} + +.terminal-btn { + width: 12px; + height: 12px; + border-radius: 50%; +} + +.terminal-btn.red { background: #ff5f57; } +.terminal-btn.yellow { background: #febc2e; } +.terminal-btn.green { background: #28c840; } + +.terminal-title { + font-size: 0.8rem; + color: var(--text-muted); + font-family: var(--font-mono); +} + +.terminal-body { + padding: 1.5rem; + font-family: var(--font-mono); + font-size: 0.9rem; +} + +.terminal-line { + display: flex; + gap: 0.75rem; + margin-bottom: 0.5rem; +} + +.terminal-prompt { + color: var(--accent-primary); +} + +.terminal-command { + color: var(--text-primary); +} + +.terminal-output { + color: var(--text-secondary); + margin-bottom: 1rem; + padding-left: 1.5rem; +} + +.terminal-output.blink { + animation: blink 1s step-end infinite; + color: var(--accent-primary); +} + +/* =================================== + Footer + =================================== */ +.footer { + padding: 4rem 0 2rem; + border-top: 1px solid var(--glass-border); + background: var(--bg-secondary); +} + +.footer-content { + text-align: center; + margin-bottom: 2rem; +} + +.footer-brand { + font-size: 2rem; + font-weight: 700; + margin-bottom: 1rem; +} + +.footer-tagline { + color: var(--text-secondary); + margin-bottom: 1.5rem; +} + +.footer-socials { + display: flex; + justify-content: center; + gap: 1rem; +} + +.footer-socials a { + width: 40px; + height: 40px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 50%; + color: var(--text-secondary); + transition: color var(--transition-fast); +} + +.footer-socials a:hover { + color: var(--accent-primary); +} + +.footer-bottom { + text-align: center; + padding-top: 2rem; + border-top: 1px solid var(--glass-border); + color: var(--text-muted); + font-size: 0.85rem; +} + +.footer-made { + margin-top: 0.5rem; +} + +.heart { + color: var(--accent-primary); +} + +/* =================================== + Responsive Design + =================================== */ +@media (max-width: 1024px) { + .bento-grid { + grid-template-columns: repeat(2, 1fr); + } + + .bento-large { + grid-column: span 2; + grid-row: span 1; + } + + .bento-medium, + .bento-small { + grid-column: span 1; + } +} + +@media (max-width: 768px) { + .nav-links { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: var(--bg-primary); + flex-direction: column; + align-items: center; + justify-content: center; + gap: 2rem; + opacity: 0; + visibility: hidden; + transition: opacity var(--transition-base), visibility var(--transition-base); + } + + .nav-links.active { + opacity: 1; + visibility: visible; + } + + .nav-link { + font-size: 1.5rem; + } + + .nav-toggle { + display: flex; + z-index: 1001; + } + + .about-content, + .contact-content { + grid-template-columns: 1fr; + gap: 3rem; + } + + .about-stats { + grid-template-columns: repeat(3, 1fr); + gap: 1rem; + } + + .stat-number { + font-size: 2rem; + } + + .bento-grid { + grid-template-columns: 1fr; + } + + .bento-large, + .bento-medium, + .bento-small { + grid-column: span 1; + grid-row: span 1; + } + + .timeline::before { + left: 8px; + } + + .timeline-item { + padding-left: 2.5rem; + } + + .timeline-marker { + left: 0; + } + + .timeline-header { + flex-direction: column; + gap: 0.5rem; + } +} + +@media (max-width: 480px) { + .hero-cta { + flex-direction: column; + width: 100%; + } + + .btn { + width: 100%; + justify-content: center; + } + + .about-stats { + grid-template-columns: 1fr; + text-align: center; + } + + .contact-method { + flex-direction: column; + text-align: center; + } +} + +/* =================================== + Scroll Animations + =================================== */ +.fade-in { + opacity: 0; + transform: translateY(30px); + transition: opacity 0.6s ease, transform 0.6s ease; +} + +.fade-in.visible { + opacity: 1; + transform: translateY(0); +} + +/* Stagger animation delay for grid items */ +.learnings-grid .learning-card:nth-child(1) { transition-delay: 0.1s; } +.learnings-grid .learning-card:nth-child(2) { transition-delay: 0.2s; } +.learnings-grid .learning-card:nth-child(3) { transition-delay: 0.3s; } +.learnings-grid .learning-card:nth-child(4) { transition-delay: 0.4s; } + +.bento-grid .project-card:nth-child(1) { transition-delay: 0.1s; } +.bento-grid .project-card:nth-child(2) { transition-delay: 0.15s; } +.bento-grid .project-card:nth-child(3) { transition-delay: 0.2s; } +.bento-grid .project-card:nth-child(4) { transition-delay: 0.25s; } +.bento-grid .project-card:nth-child(5) { transition-delay: 0.3s; } From 6e86070813b74c8b53d576b43b670af7f490455d Mon Sep 17 00:00:00 2001 From: Will Pracht Date: Tue, 27 Jan 2026 15:02:06 -0800 Subject: [PATCH 2/2] Info Updating some of the info from linkedin and github, polishing a little. Need to refine more. Projects need rethought a little. --- index.html | 227 +++++++++++++++++++++++------------------------------ 1 file changed, 100 insertions(+), 127 deletions(-) diff --git a/index.html b/index.html index d8efbecc..eeedfb6a 100644 --- a/index.html +++ b/index.html @@ -75,12 +75,12 @@

Will Pracht

- Software Engineer + Infrastructure & DevOps Engineer |

- I build exceptional digital experiences that live at the intersection of design and technology. - Passionate about creating elegant solutions to complex problems. + Engineer with over fifteen years of experience in the software/web industry, adapting to new technologies + as the job demands, optimizing workflow and process along the way.

@@ -132,26 +132,28 @@

About Me

- I'm a software engineer who loves turning complex problems into simple, beautiful solutions. - With a passion for clean code and user-centric design, I create digital experiences that make a difference. + I'm an Infrastructure and DevOps Engineer at Intel Corporation with over fifteen years of demonstrated + experience in the software/web industry. Throughout my career, I've specialized in adapting to new + technologies as the job demands, while continuously optimizing workflow and process.

- When I'm not coding, you'll find me exploring new technologies, contributing to open source, - or sharing knowledge with the developer community. I believe in continuous learning and pushing - the boundaries of what's possible. + Currently, I support build and release infrastructure for Ethernet firmware and drivers, contribute to + internal provisioning systems, and provide full-stack development for React (TypeScript) and ASP.NET + projects. I also serve as a Scrum Master, mentor junior developers, and lead technical initiatives to + improve tech debt and consolidate systems.

- 0+ + 0+ Years Experience
- 0+ - Projects Completed + 0+ + Companies
- 0+ - Technologies + 0 + Certifications
@@ -161,38 +163,35 @@

Tech Stack

Languages

- JavaScript TypeScript - Python - Go - Rust + JavaScript + C# + HTML/CSS

Frontend

React - Next.js - Vue - Tailwind + AngularJS + ASP.NET MVC
-

Backend

+

Backend & Infrastructure

+ ASP.NET Node.js - PostgreSQL - MongoDB - GraphQL + IIS
-

DevOps

+

DevOps & Tools

- Docker - AWS CI/CD - Kubernetes + Build Infrastructure + Git + Scrum/Agile
@@ -216,20 +215,46 @@

Experience

-

Senior Software Engineer

-

Tech Company

+

Infrastructure and DevOps Engineer

+

Intel Corporation (via KellyOCG)

- 2022 - Present + Jul 2020 - Present

- Leading development of scalable microservices architecture. Mentoring junior developers - and driving technical decisions for high-impact projects. + Supporting build and release infrastructure for Ethernet firmware and drivers. Contributing to development + and process for internal provisioning system. Leading Scrum ceremonies and processes as Scrum Master. + Providing full-stack development for React (TypeScript) and ASP.NET projects. Mentoring junior developers + and interns while improving tech debt and migrating/consolidating systems.

+ TypeScript React - Node.js - AWS - Kubernetes + C# + ASP.NET + DevOps + Scrum Master +
+
+
+
+
+
+
+
+

Senior Frontend Developer

+

Intouch Solutions

+
+ Jun 2019 - Nov 2019 +
+

+ Implemented front-end solutions matching design comps and business requirements, focusing on responsive + design and browser compatibility. Managed project tasks to meet deadlines in a fast-paced, Scrum environment. + Mentored and directed junior developers, improving code quality and development workflow. +

+
+ JavaScript + ASP.NET MVC + Scrum
@@ -239,19 +264,21 @@

Senior Software Engineer

Software Engineer

-

Startup Inc

+

FireMon

- 2020 - 2022 + Dec 2014 - May 2019

- Built full-stack applications from scratch. Implemented CI/CD pipelines and - improved deployment processes, reducing release time by 60%. + Built and maintained front-end build tooling, CI workflow, and handled release management for AngularJS + apps and components. Migrated AngularJS app and component ecosystem from ES5 to TypeScript. Collaborated + with UX, developing a UI kit to standardize aesthetics and functionality. Established and led the front-end + user group, driving the technology roadmap.

- Vue.js - Python - PostgreSQL - Docker + AngularJS + TypeScript + CI/CD + Package Management
@@ -260,20 +287,19 @@

Software Engineer

-

Junior Developer

-

Agency Co

+

Web Developer

+

VML

- 2018 - 2020 + Dec 2013 - Nov 2014

- Developed responsive web applications for various clients. Collaborated with designers - to implement pixel-perfect interfaces. + Built AngularJS applications for various clients, including MLB Players Association, JG Wentworth, and + Duke Energy. Implemented HTML/JavaScript features for internal business insights tool, SEER.

+ AngularJS JavaScript HTML/CSS - WordPress - PHP
@@ -313,86 +339,39 @@

Featured Projects

- Python - FastAPI - ML -
-

ML Pipeline

-

- Automated machine learning pipeline for data processing and model training. -

- -
-
-
-
-
- Go - CLI -
-

DevTool CLI

-

- Developer productivity CLI tool. -

- -
-
-
-
-
- TypeScript - VSCode + HTML + CSS + JavaScript
-

VSCode Extension

+

Portfolio Site

- Productivity extension for VS Code. + Modern portfolio website featuring dark mode, glassmorphism design, and responsive layout. + Built with vanilla JavaScript for optimal performance.