Skip to content

Commit e324326

Browse files
committed
refactor: update about section and enhance contact form styling
1 parent d24539a commit e324326

3 files changed

Lines changed: 48 additions & 180 deletions

File tree

index.html

Lines changed: 22 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,13 @@ <h1>Fozle Rabbi Shafi</h1>
126126
<section id="about" class="section card reveal">
127127
<h2>About</h2>
128128
<p>
129-
I am currently pursuing a PhD in Computing at Queen's University (started September 2025),
130-
following my MSc in Computing at Queen's University (CGPA: 4.24/4.30) and a BSc in Computer
131-
Science and Engineering from Metropolitan University, Bangladesh (CGPA: 3.90/4.00).
129+
I am a PhD student in Computing at Queen's University specializing in AI-driven cybersecurity.
130+
My research strengthens the security of cyber-physical systems using advanced AI, including
131+
generative AI and deep neural networks, with autonomous vehicles as one key application area.
132132
</p>
133133
<p>
134-
My work sits at the intersection of research and engineering, where I design and ship
135-
AI-powered software with a strong focus on reliability, scalability, and meaningful impact.
134+
Before starting my PhD, I completed my MSc in Computing at Queen's University after more than
135+
five years of industry experience across software engineering roles.
136136
</p>
137137
<div class="grid two-col">
138138
<article class="mini-card">
@@ -301,50 +301,23 @@ <h2>Achievements & Activities</h2>
301301
<section id="contact" class="section card reveal">
302302
<h2>Contact</h2>
303303
<p>Open to collaborations in AI research, LLM applications, and software engineering opportunities.</p>
304-
<p class="privacy-note">Privacy-first form with lightweight bot protection. No analytics or ad trackers are loaded.</p>
305-
306-
<form id="contact-form" class="contact-form" action="https://formsubmit.co/f.shafi@queensu.ca" method="POST" novalidate>
307-
<div class="form-grid">
308-
<label>
309-
Name
310-
<input type="text" name="name" autocomplete="name" required>
311-
</label>
312-
<label>
313-
Email
314-
<input type="email" name="email" autocomplete="email" required>
315-
</label>
316-
</div>
317-
318-
<label>
319-
Subject
320-
<input type="text" name="subject" required>
321-
</label>
322-
323-
<label>
324-
Message
325-
<textarea name="message" rows="6" required></textarea>
326-
</label>
327-
328-
<label id="human-check-label" data-answer="">
329-
<span id="human-check-question">Human check</span>
330-
<input type="number" id="human-check-input" name="human_check" inputmode="numeric" required>
331-
</label>
332-
333-
<input type="text" name="_honey" class="hp-field" tabindex="-1" autocomplete="off" aria-hidden="true">
334-
<input type="hidden" name="_subject" value="Portfolio Contact Form Submission">
335-
<input type="hidden" name="_captcha" value="false">
336-
<input type="hidden" name="_next" value="https://devshafi.github.io/#contact">
337-
<input type="hidden" id="form-started-at" value="">
338-
339-
<button class="btn btn-primary" type="submit">Send Message</button>
340-
<p id="form-status" class="form-status" role="status" aria-live="polite"></p>
341-
</form>
342-
343304
<div class="contact-grid">
344-
<a href="mailto:f.shafi@queensu.ca">f.shafi@queensu.ca</a>
345-
<a href="tel:+16135616661">+1 613 561 6661</a>
346-
<a href="https://www.linkedin.com/in/fozle-rabbi-shafi-07841511a" target="_blank" rel="noopener noreferrer">LinkedIn Profile</a>
347-
<span>Kingston, Ontario, Canada</span>
305+
<a href="mailto:f.shafi@queensu.ca">
306+
<span class="contact-icon email-icon" aria-hidden="true"></span>
307+
<span>f.shafi@queensu.ca</span>
308+
</a>
309+
<a href="tel:+16135616661">
310+
<span class="contact-icon phone-icon" aria-hidden="true"></span>
311+
<span>+1 613 561 6661</span>
312+
</a>
313+
<a href="https://www.linkedin.com/in/fozle-rabbi-shafi-07841511a" target="_blank" rel="noopener noreferrer">
314+
<span class="contact-icon linkedin-icon" aria-hidden="true">in</span>
315+
<span>LinkedIn Profile</span>
316+
</a>
317+
<span>
318+
<span class="contact-icon location-icon" aria-hidden="true">📍</span>
319+
<span>Kingston, Ontario, Canada</span>
320+
</span>
348321
</div>
349322
</section>
350323
</main>
@@ -353,6 +326,6 @@ <h2>Contact</h2>
353326
<p>© <span id="year"></span> Fozle Rabbi Shafi</p>
354327
</footer>
355328

356-
<script src="script.js?v=20260331"></script>
329+
<script src="script.js?v=20260331-2"></script>
357330
</body>
358331
</html>

script.js

Lines changed: 0 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -35,78 +35,3 @@ window.addEventListener('scroll', activateNav);
3535
window.addEventListener('load', activateNav);
3636

3737
document.getElementById('year').textContent = new Date().getFullYear();
38-
39-
const contactForm = document.getElementById('contact-form');
40-
const formStatus = document.getElementById('form-status');
41-
const humanCheckLabel = document.getElementById('human-check-label');
42-
const humanCheckQuestion = document.getElementById('human-check-question');
43-
const humanCheckInput = document.getElementById('human-check-input');
44-
const formStartedAt = document.getElementById('form-started-at');
45-
46-
const createHumanCheck = () => {
47-
const a = Math.floor(Math.random() * 8) + 1;
48-
const b = Math.floor(Math.random() * 8) + 1;
49-
humanCheckQuestion.textContent = `Human check: What is ${a} + ${b}?`;
50-
humanCheckLabel.dataset.answer = String(a + b);
51-
};
52-
53-
if (contactForm && formStatus && humanCheckLabel && humanCheckQuestion && humanCheckInput && formStartedAt) {
54-
formStartedAt.value = String(Date.now());
55-
createHumanCheck();
56-
57-
contactForm.addEventListener('submit', async (event) => {
58-
event.preventDefault();
59-
formStatus.textContent = '';
60-
61-
if (!contactForm.checkValidity()) {
62-
formStatus.textContent = 'Please complete all required fields.';
63-
contactForm.reportValidity();
64-
return;
65-
}
66-
67-
const elapsed = Date.now() - Number(formStartedAt.value);
68-
if (elapsed < 4000) {
69-
formStatus.textContent = 'Please wait a few seconds and try again.';
70-
return;
71-
}
72-
73-
if (humanCheckInput.value.trim() !== humanCheckLabel.dataset.answer) {
74-
formStatus.textContent = 'Human check answer is incorrect.';
75-
createHumanCheck();
76-
humanCheckInput.value = '';
77-
return;
78-
}
79-
80-
const formData = new FormData(contactForm);
81-
const endpoint = `https://formsubmit.co/ajax/${encodeURIComponent('f.shafi@queensu.ca')}`;
82-
83-
try {
84-
const response = await fetch(endpoint, {
85-
method: 'POST',
86-
headers: { Accept: 'application/json' },
87-
body: formData,
88-
});
89-
90-
if (!response.ok) {
91-
let detail = 'Request failed';
92-
try {
93-
const payload = await response.json();
94-
if (payload?.message) {
95-
detail = payload.message;
96-
}
97-
} catch {
98-
// Ignore JSON parse failures and keep default detail
99-
}
100-
throw new Error(detail);
101-
}
102-
103-
formStatus.textContent = 'Thanks! Your message has been sent.';
104-
contactForm.reset();
105-
createHumanCheck();
106-
formStartedAt.value = String(Date.now());
107-
} catch {
108-
formStatus.textContent = 'Direct submit fallback started. If this is your first use, confirm the FormSubmit verification email once.';
109-
contactForm.submit();
110-
}
111-
});
112-
}

styles.css

Lines changed: 26 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -394,72 +394,46 @@ article.card {
394394
border-radius: 10px;
395395
text-decoration: none;
396396
color: #213145;
397+
display: flex;
398+
align-items: center;
399+
gap: 0.55rem;
397400
}
398401

399402
.contact-grid a:hover {
400403
border-color: rgba(255, 122, 24, 0.45);
401404
}
402405

403-
.privacy-note {
404-
color: var(--muted);
405-
font-size: 0.94rem;
406-
}
407-
408-
.contact-form {
409-
margin-top: 1rem;
410-
padding: 1rem;
411-
border: 1px solid var(--stroke);
412-
border-radius: 14px;
413-
background: rgba(255, 255, 255, 0.6);
414-
display: grid;
415-
gap: 0.8rem;
416-
}
417-
418-
.form-grid {
419-
display: grid;
420-
grid-template-columns: repeat(2, minmax(0, 1fr));
421-
gap: 0.75rem;
422-
}
423-
424-
.contact-form label {
425-
display: grid;
426-
gap: 0.35rem;
427-
font-weight: 600;
428-
color: #1a2b40;
429-
font-size: 0.94rem;
406+
.contact-icon {
407+
width: 28px;
408+
height: 28px;
409+
border-radius: 8px;
410+
display: inline-flex;
411+
align-items: center;
412+
justify-content: center;
413+
font-weight: 700;
414+
font-size: 0.9rem;
415+
flex-shrink: 0;
430416
}
431417

432-
.contact-form input,
433-
.contact-form textarea {
434-
width: 100%;
435-
font: inherit;
436-
color: #132033;
437-
background: #ffffff;
438-
border: 1px solid rgba(19, 32, 51, 0.18);
439-
border-radius: 10px;
440-
padding: 0.62rem 0.72rem;
418+
.email-icon {
419+
background: #ffe5d1;
420+
color: #b84c00;
441421
}
442422

443-
.contact-form input:focus,
444-
.contact-form textarea:focus {
445-
outline: none;
446-
border-color: rgba(255, 122, 24, 0.65);
447-
box-shadow: 0 0 0 3px rgba(255, 122, 24, 0.14);
423+
.phone-icon {
424+
background: #d8f9f2;
425+
color: #047a6c;
448426
}
449427

450-
.form-status {
451-
margin: 0;
452-
min-height: 1.25rem;
453-
font-size: 0.92rem;
454-
color: #1f3c5f;
428+
.linkedin-icon {
429+
background: #dbeaff;
430+
color: #0a66c2;
431+
font-family: "Space Grotesk", sans-serif;
455432
}
456433

457-
.hp-field {
458-
position: absolute;
459-
left: -9999px;
460-
width: 1px;
461-
height: 1px;
462-
opacity: 0;
434+
.location-icon {
435+
background: #efe1ff;
436+
color: #6d2fb0;
463437
}
464438

465439
.site-footer {
@@ -543,10 +517,6 @@ article.card {
543517
justify-self: center;
544518
}
545519

546-
.form-grid {
547-
grid-template-columns: 1fr;
548-
}
549-
550520
.timeline {
551521
padding-left: 0.8rem;
552522
}

0 commit comments

Comments
 (0)