Skip to content

Commit 1920fe1

Browse files
Enhance portfolio website
1 parent d41eb58 commit 1920fe1

File tree

10 files changed

+396
-53
lines changed

10 files changed

+396
-53
lines changed

icons/android-chrome-192x192.png

8.62 KB
Loading

icons/android-chrome-512x512.png

24.2 KB
Loading

icons/apple-touch-icon.png

7.51 KB
Loading

icons/favicon-16x16.png

572 Bytes
Loading

icons/favicon-32x32.png

1.27 KB
Loading

icons/favicon.ico

15 KB
Binary file not shown.

index.html

Lines changed: 186 additions & 48 deletions
Large diffs are not rendered by default.

manifest.json

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"short_name": "HP Portfolio",
3+
"name": "Harshit Pawar - Developer Portfolio",
4+
"icons": [
5+
{
6+
"src": "/favicon.ico",
7+
"sizes": "64x64 32x32 24x24 16x16",
8+
"type": "image/x-icon"
9+
},
10+
{
11+
"src": "icons/android-chrome-192x192.png",
12+
"sizes": "192x192",
13+
"type": "image/png"
14+
},
15+
{
16+
"src": "icons/android-chrome-512x512.png",
17+
"sizes": "512x512",
18+
"type": "image/png"
19+
}
20+
],
21+
"start_url": ".",
22+
"display": "standalone",
23+
"theme_color": "#0f172a",
24+
"background_color": "#0f172a"
25+
}

script.js

Lines changed: 80 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ document.addEventListener('DOMContentLoaded', () => {
5454

5555
// Setup navigation bar scroll behavior
5656
setupNavScroll();
57+
58+
// Setup contact form handling
59+
setupContactForm();
5760
});
5861

5962
// Create geometric shapes for visual interest
@@ -258,7 +261,7 @@ function addButtonEffects() {
258261

259262
// Typing animation with fixed width container
260263
function initTypeEffect() {
261-
const phrases = ["Developer", "Tech Enthusiast", "Problem Solver", "Continuous Learner"];
264+
const phrases = ["Developer", "FIDE Master", "Tech Enthusiast", "Problem Solver", "Continuous Learner"];
262265
let currentPhraseIndex = 0;
263266
let currentCharIndex = 0;
264267
let isDeleting = false;
@@ -474,8 +477,8 @@ async function fetchGitHubRepos() {
474477
const languageColor = repo.language ? languageColors[repo.language] || '#00d2ff' : '#00d2ff';
475478

476479
repoCard.innerHTML = `
477-
<div class="neon-highlight"></div>
478-
<h3 class="text-xl font-bold text-white mb-2">${repo.name}</h3>
480+
<div class="card-top-accent" style="background-color: ${languageColor}"></div>
481+
<h3 class="text-xl font-bold text-white mb-3">${repo.name}</h3>
479482
<p class="text-base text-gray-300 mb-4 min-h-[60px]">${repo.description || 'No description provided.'}</p>
480483
<div class="flex items-center text-gray-400 text-xs mb-4">
481484
${repo.language ?
@@ -562,3 +565,77 @@ function setupNavScroll() {
562565
mainNav.style.backgroundColor = 'rgba(10, 10, 15, 0.9)';
563566
}
564567
}
568+
569+
// Handle contact form submission
570+
function setupContactForm() {
571+
const contactForm = document.getElementById('contact-form');
572+
const formStatus = document.getElementById('form-status');
573+
574+
if (!contactForm) return;
575+
576+
contactForm.addEventListener('submit', async function(event) {
577+
event.preventDefault();
578+
579+
// Show a subtle loading effect on the submit button
580+
const submitButton = contactForm.querySelector('button[type="submit"]');
581+
const originalButtonText = submitButton.innerHTML;
582+
submitButton.innerHTML = '<i class="fas fa-circle-notch fa-spin mr-2"></i> Sending...';
583+
submitButton.disabled = true;
584+
585+
try {
586+
// Submit the form to Formspree
587+
const formData = new FormData(contactForm);
588+
const response = await fetch(contactForm.action, {
589+
method: contactForm.method,
590+
body: formData,
591+
headers: {
592+
'Accept': 'application/json'
593+
}
594+
});
595+
596+
if (response.ok) {
597+
// Show success message
598+
contactForm.reset();
599+
formStatus.classList.remove('hidden');
600+
601+
// Hide success message after 5 seconds
602+
setTimeout(() => {
603+
formStatus.classList.add('hidden');
604+
}, 5000);
605+
606+
// Add a success animation
607+
const successRipple = document.createElement('div');
608+
successRipple.className = 'success-ripple';
609+
submitButton.parentNode.appendChild(successRipple);
610+
611+
setTimeout(() => {
612+
successRipple.remove();
613+
}, 1000);
614+
} else {
615+
throw new Error('Form submission failed');
616+
}
617+
} catch (error) {
618+
console.error('Form submission error:', error);
619+
formStatus.innerHTML = '<p class="text-[#ff5e62]">Oops! There was a problem. Please try again.</p>';
620+
formStatus.classList.remove('hidden');
621+
} finally {
622+
// Restore the button
623+
submitButton.innerHTML = originalButtonText;
624+
submitButton.disabled = false;
625+
}
626+
});
627+
628+
// Add focus/blur effects on inputs
629+
const formInputs = contactForm.querySelectorAll('input, textarea');
630+
formInputs.forEach(input => {
631+
input.addEventListener('focus', () => {
632+
input.parentElement.classList.add('input-focused');
633+
});
634+
635+
input.addEventListener('blur', () => {
636+
if (!input.value) {
637+
input.parentElement.classList.remove('input-focused');
638+
}
639+
});
640+
});
641+
}

style.css

Lines changed: 105 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,7 @@ p, li, a {
351351
z-index: 1;
352352
background: var(--card-bg);
353353
border: 1px solid rgba(255, 255, 255, 0.05);
354+
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
354355
}
355356

356357
.project-card::before {
@@ -360,21 +361,45 @@ p, li, a {
360361
left: 0;
361362
width: 100%;
362363
height: 100%;
363-
background: linear-gradient(135deg, rgba(255, 94, 98, 0.1), rgba(116, 89, 234, 0.1));
364+
background: linear-gradient(135deg, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.02));
364365
opacity: 0;
365366
transition: opacity 0.4s var(--easing);
366367
z-index: -1;
367368
}
368369

370+
.card-top-accent {
371+
position: absolute;
372+
top: 0;
373+
left: 0;
374+
right: 0;
375+
height: 3px;
376+
opacity: 0.8;
377+
border-radius: 3px 3px 0 0;
378+
}
379+
369380
.project-card:hover {
370381
transform: translateY(-8px);
371-
box-shadow: var(--shadow-lg);
382+
box-shadow: 0 15px 30px rgba(0, 0, 0, 0.3);
383+
border-color: rgba(255, 255, 255, 0.1);
372384
}
373385

374386
.project-card:hover::before {
375387
opacity: 1;
376388
}
377389

390+
.project-card h3 {
391+
position: relative;
392+
display: inline-block;
393+
transition: all 0.3s var(--easing);
394+
}
395+
396+
.project-card:hover h3 {
397+
background: var(--gradient-blue);
398+
-webkit-background-clip: text;
399+
background-clip: text;
400+
-webkit-text-fill-color: transparent;
401+
}
402+
378403
.project-card .language-dot {
379404
width: 10px;
380405
height: 10px;
@@ -443,3 +468,81 @@ p, li, a {
443468
bottom: -2px;
444469
}
445470
}
471+
472+
/* Contact form styling */
473+
#contact-form input,
474+
#contact-form textarea {
475+
background-color: rgba(19, 21, 31, 0.7);
476+
border: 1px solid rgba(255, 255, 255, 0.1);
477+
transition: all 0.3s var(--easing);
478+
}
479+
480+
#contact-form input:focus,
481+
#contact-form textarea:focus {
482+
border-color: var(--accent-3);
483+
box-shadow: 0 0 0 2px rgba(0, 210, 255, 0.1);
484+
outline: none;
485+
}
486+
487+
.input-focused label {
488+
color: var(--accent-3);
489+
}
490+
491+
.success-ripple {
492+
position: absolute;
493+
top: 50%;
494+
left: 50%;
495+
transform: translate(-50%, -50%) scale(0);
496+
width: 150px;
497+
height: 150px;
498+
background: radial-gradient(circle, rgba(0, 210, 255, 0.8) 0%, rgba(0, 210, 255, 0) 70%);
499+
border-radius: 50%;
500+
pointer-events: none;
501+
z-index: 0;
502+
animation: successRipple 1s ease-out forwards;
503+
}
504+
505+
@keyframes successRipple {
506+
0% {
507+
transform: translate(-50%, -50%) scale(0);
508+
opacity: 1;
509+
}
510+
100% {
511+
transform: translate(-50%, -50%) scale(1);
512+
opacity: 0;
513+
}
514+
}
515+
516+
/* Focus items in About section */
517+
.focus-item {
518+
display: flex;
519+
align-items: flex-start;
520+
padding: 0.75rem 1rem;
521+
border-radius: 0.75rem;
522+
transition: all 0.3s var(--easing);
523+
background-color: rgba(255, 255, 255, 0.02);
524+
border: 1px solid transparent;
525+
}
526+
527+
.focus-item:hover {
528+
background-color: rgba(255, 255, 255, 0.05);
529+
border-color: rgba(255, 255, 255, 0.1);
530+
transform: translateY(-2px);
531+
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.2);
532+
}
533+
534+
.focus-item i {
535+
transition: transform 0.3s var(--easing);
536+
}
537+
538+
.focus-item:hover i {
539+
transform: scale(1.2);
540+
}
541+
542+
.focus-item h4 {
543+
transition: color 0.3s var(--easing);
544+
}
545+
546+
.focus-item:hover h4 {
547+
color: var(--accent-3);
548+
}

0 commit comments

Comments
 (0)