Compare commits
2 Commits
4df044c9c5
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
| b7d4d6d1ee | |||
| 1b0cdedc14 |
+100
-15
@@ -125,64 +125,147 @@
|
||||
<!-- FAQ Section -->
|
||||
<section class="faq-section" aria-labelledby="faq-heading">
|
||||
<h2 id="faq-heading">Frequently Asked Questions</h2>
|
||||
|
||||
|
||||
<div class="faq-item">
|
||||
<div class="faq-question" role="button" aria-expanded="false" aria-controls="faq-answer-1">
|
||||
<div
|
||||
class="faq-question"
|
||||
role="button"
|
||||
aria-expanded="false"
|
||||
aria-controls="faq-answer-1"
|
||||
>
|
||||
<h4>What makes your teas different from supermarket teas?</h4>
|
||||
<span class="faq-toggle">+</span>
|
||||
</div>
|
||||
<div id="faq-answer-1" class="faq-answer">
|
||||
<p>Our teas are sourced directly from traditional tea gardens and artisan farmers around the world. Unlike supermarket teas that may sit in warehouses for months, our teas are freshly harvested, properly stored, and shipped directly to you. We work closely with tea masters who have perfected their craft over generations, ensuring you receive authentic, premium-quality teas with exceptional flavor profiles.</p>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
|
||||
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
|
||||
enim ad minim veniam, quis nostrud exercitation ullamco laboris
|
||||
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
|
||||
reprehenderit in voluptate velit esse cillum dolore eu fugiat
|
||||
nulla pariatur. Excepteur sint occaecat cupidatat non proident,
|
||||
sunt in culpa qui officia deserunt mollit anim id est laborum.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="faq-item">
|
||||
<div class="faq-question" role="button" aria-expanded="false" aria-controls="faq-answer-2">
|
||||
<div
|
||||
class="faq-question"
|
||||
role="button"
|
||||
aria-expanded="false"
|
||||
aria-controls="faq-answer-2"
|
||||
>
|
||||
<h4>How should I store my tea to maintain freshness?</h4>
|
||||
<span class="faq-toggle">+</span>
|
||||
</div>
|
||||
<div id="faq-answer-2" class="faq-answer">
|
||||
<p>To maintain optimal freshness, store your tea in an airtight container away from light, heat, and moisture. We recommend keeping tea in a cool, dark place like a pantry or cupboard. Avoid storing tea near strong odors, as tea can absorb surrounding scents. Properly stored, most teas will maintain their quality for 6-12 months, while pu-erh teas can actually improve with age when stored correctly.</p>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
|
||||
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
|
||||
enim ad minim veniam, quis nostrud exercitation ullamco laboris
|
||||
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
|
||||
reprehenderit in voluptate velit esse cillum dolore eu fugiat
|
||||
nulla pariatur. Excepteur sint occaecat cupidatat non proident,
|
||||
sunt in culpa qui officia deserunt mollit anim id est laborum.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="faq-item">
|
||||
<div class="faq-question" role="button" aria-expanded="false" aria-controls="faq-answer-3">
|
||||
<h4>What is the best water temperature for brewing different types of tea?</h4>
|
||||
<div
|
||||
class="faq-question"
|
||||
role="button"
|
||||
aria-expanded="false"
|
||||
aria-controls="faq-answer-3"
|
||||
>
|
||||
<h4>
|
||||
What is the best water temperature for brewing different types of
|
||||
tea?
|
||||
</h4>
|
||||
<span class="faq-toggle">+</span>
|
||||
</div>
|
||||
<div id="faq-answer-3" class="faq-answer">
|
||||
<p>Water temperature is crucial for optimal tea brewing. Here's our guide: Green teas: 160-180°F (71-82°C), White teas: 175-185°F (79-85°C), Oolong teas: 185-205°F (85-96°C), Black teas: 200-212°F (93-100°C), Pu-erh teas: 200-212°F (93-100°C), Herbal infusions: 200-212°F (93-100°C). Using water that's too hot can burn delicate teas, while water that's too cool won't extract the full flavor profile.</p>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
|
||||
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
|
||||
enim ad minim veniam, quis nostrud exercitation ullamco laboris
|
||||
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
|
||||
reprehenderit in voluptate velit esse cillum dolore eu fugiat
|
||||
nulla pariatur. Excepteur sint occaecat cupidatat non proident,
|
||||
sunt in culpa qui officia deserunt mollit anim id est laborum.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="faq-item">
|
||||
<div class="faq-question" role="button" aria-expanded="false" aria-controls="faq-answer-4">
|
||||
<div
|
||||
class="faq-question"
|
||||
role="button"
|
||||
aria-expanded="false"
|
||||
aria-controls="faq-answer-4"
|
||||
>
|
||||
<h4>Do you offer organic teas?</h4>
|
||||
<span class="faq-toggle">+</span>
|
||||
</div>
|
||||
<div id="faq-answer-4" class="faq-answer">
|
||||
<p>Yes! Many of our teas are certified organic, and we work with farms that practice sustainable, chemical-free cultivation methods. Look for the organic certification label on our product pages. Even our non-certified teas are sourced from farms that prioritize environmental stewardship and sustainable farming practices, as we believe great tea starts with healthy soil and happy plants.</p>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
|
||||
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
|
||||
enim ad minim veniam, quis nostrud exercitation ullamco laboris
|
||||
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
|
||||
reprehenderit in voluptate velit esse cillum dolore eu fugiat
|
||||
nulla pariatur. Excepteur sint occaecat cupidatat non proident,
|
||||
sunt in culpa qui officia deserunt mollit anim id est laborum.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="faq-item">
|
||||
<div class="faq-question" role="button" aria-expanded="false" aria-controls="faq-answer-5">
|
||||
<h4>How long does shipping take, and do you ship internationally?</h4>
|
||||
<div
|
||||
class="faq-question"
|
||||
role="button"
|
||||
aria-expanded="false"
|
||||
aria-controls="faq-answer-5"
|
||||
>
|
||||
<h4>
|
||||
How long does shipping take, and do you ship internationally?
|
||||
</h4>
|
||||
<span class="faq-toggle">+</span>
|
||||
</div>
|
||||
<div id="faq-answer-5" class="faq-answer">
|
||||
<p>We offer fast shipping throughout the United States, with most orders arriving within 3-5 business days. We also ship internationally to many countries, though delivery times vary by destination (typically 7-14 business days). All orders include tracking information, and we carefully package our teas to ensure they arrive in perfect condition. Free shipping is available on orders over $50 within the US.</p>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
|
||||
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
|
||||
enim ad minim veniam, quis nostrud exercitation ullamco laboris
|
||||
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
|
||||
reprehenderit in voluptate velit esse cillum dolore eu fugiat
|
||||
nulla pariatur. Excepteur sint occaecat cupidatat non proident,
|
||||
sunt in culpa qui officia deserunt mollit anim id est laborum.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="faq-item">
|
||||
<div class="faq-question" role="button" aria-expanded="false" aria-controls="faq-answer-6">
|
||||
<div
|
||||
class="faq-question"
|
||||
role="button"
|
||||
aria-expanded="false"
|
||||
aria-controls="faq-answer-6"
|
||||
>
|
||||
<h4>Can I return or exchange tea if I'm not satisfied?</h4>
|
||||
<span class="faq-toggle">+</span>
|
||||
</div>
|
||||
<div id="faq-answer-6" class="faq-answer">
|
||||
<p>Your satisfaction is our top priority. If you're not completely happy with your tea, please contact us within 30 days of purchase. While we cannot accept returns of opened tea due to food safety regulations, we'll work with you to find a solution - whether that's a replacement, store credit, or refund depending on the circumstances. We want every cup of tea you brew to bring you joy!</p>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
|
||||
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
|
||||
enim ad minim veniam, quis nostrud exercitation ullamco laboris
|
||||
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
|
||||
reprehenderit in voluptate velit esse cillum dolore eu fugiat
|
||||
nulla pariatur. Excepteur sint occaecat cupidatat non proident,
|
||||
sunt in culpa qui officia deserunt mollit anim id est laborum.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -195,5 +278,7 @@
|
||||
tea experts.
|
||||
</p>
|
||||
</footer>
|
||||
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<meta charset="UTF-8" />
|
||||
<title>Contact Us - Global Tea Emporium</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
<script src="script.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<meta charset="UTF-8" />
|
||||
<title>Global Tea Emporium - Premium Authentic Teas Worldwide</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
<script src="script.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Skip to main content link for screen readers -->
|
||||
|
||||
@@ -1,295 +1,197 @@
|
||||
// Global Tea Emporium - JavaScript Functionality
|
||||
// Global Tea Emporium - Optimized JavaScript
|
||||
|
||||
// Image Gallery Functionality
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
console.log('Gallery script loading...');
|
||||
|
||||
const galleryImages = [
|
||||
{
|
||||
src: 'images/green-tea-leaves.webp',
|
||||
alt: 'Premium Green Tea Leaves',
|
||||
caption: 'Premium Green Tea Leaves - Hand-picked from our finest gardens'
|
||||
},
|
||||
{
|
||||
src: 'images/Indian Black Teas.webp',
|
||||
alt: 'Indian Black Tea Selection',
|
||||
caption: 'Authentic Indian Black Teas - Rich and robust flavors from Assam and Darjeeling'
|
||||
},
|
||||
{
|
||||
src: 'images/Oolong Selections.jpg',
|
||||
alt: 'Oolong Tea Collection',
|
||||
caption: 'Traditional Oolong Selections - Complex flavors from Taiwan and China'
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
// ===== FAQ ACCORDION =====
|
||||
const faqQuestions = document.querySelectorAll(".faq-question");
|
||||
|
||||
faqQuestions.forEach((question) => {
|
||||
question.addEventListener("click", function () {
|
||||
const answer = this.nextElementSibling;
|
||||
const toggle = this.querySelector(".faq-toggle");
|
||||
const isExpanded = this.getAttribute("aria-expanded") === "true";
|
||||
|
||||
// Close all other FAQ items
|
||||
faqQuestions.forEach((otherQuestion) => {
|
||||
if (otherQuestion !== this) {
|
||||
const otherAnswer = otherQuestion.nextElementSibling;
|
||||
const otherToggle = otherQuestion.querySelector(".faq-toggle");
|
||||
|
||||
otherQuestion.setAttribute("aria-expanded", "false");
|
||||
otherAnswer.classList.remove("active");
|
||||
otherToggle.classList.remove("active");
|
||||
}
|
||||
];
|
||||
});
|
||||
|
||||
let currentImageIndex = 0;
|
||||
const galleryImage = document.getElementById('gallery-image');
|
||||
const galleryCaption = document.getElementById('gallery-caption');
|
||||
const prevBtn = document.getElementById('prev-btn');
|
||||
const nextBtn = document.getElementById('next-btn');
|
||||
const thumbnails = document.querySelectorAll('.thumbnail');
|
||||
|
||||
// Check if gallery elements exist
|
||||
if (!galleryImage || !galleryCaption) {
|
||||
console.log('Gallery image or caption not found');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('Gallery elements found:', {
|
||||
image: !!galleryImage,
|
||||
caption: !!galleryCaption,
|
||||
prevBtn: !!prevBtn,
|
||||
nextBtn: !!nextBtn,
|
||||
thumbnails: thumbnails.length
|
||||
// Toggle current FAQ item
|
||||
this.setAttribute("aria-expanded", !isExpanded);
|
||||
answer.classList.toggle("active");
|
||||
toggle.classList.toggle("active");
|
||||
});
|
||||
|
||||
function updateGallery(index) {
|
||||
console.log('Updating gallery to index:', index);
|
||||
currentImageIndex = index;
|
||||
galleryImage.src = galleryImages[index].src;
|
||||
galleryImage.alt = galleryImages[index].alt;
|
||||
galleryCaption.textContent = galleryImages[index].caption;
|
||||
|
||||
// Update active thumbnail
|
||||
thumbnails.forEach((thumb, i) => {
|
||||
thumb.classList.toggle('active', i === index);
|
||||
});
|
||||
}
|
||||
|
||||
function nextImage() {
|
||||
console.log('Next image clicked');
|
||||
const newIndex = (currentImageIndex + 1) % galleryImages.length;
|
||||
updateGallery(newIndex);
|
||||
}
|
||||
|
||||
function prevImage() {
|
||||
console.log('Previous image clicked');
|
||||
const newIndex = (currentImageIndex - 1 + galleryImages.length) % galleryImages.length;
|
||||
updateGallery(newIndex);
|
||||
}
|
||||
|
||||
// Event listeners for gallery controls
|
||||
if (prevBtn) {
|
||||
console.log('Adding prev button listener');
|
||||
prevBtn.addEventListener('click', prevImage);
|
||||
} else {
|
||||
console.log('Prev button not found');
|
||||
}
|
||||
|
||||
if (nextBtn) {
|
||||
console.log('Adding next button listener');
|
||||
nextBtn.addEventListener('click', nextImage);
|
||||
} else {
|
||||
console.log('Next button not found');
|
||||
}
|
||||
|
||||
// Thumbnail click events
|
||||
thumbnails.forEach((thumbnail) => {
|
||||
thumbnail.addEventListener('click', () => {
|
||||
const index = parseInt(thumbnail.getAttribute('data-index'));
|
||||
console.log('Thumbnail clicked, index:', index);
|
||||
if (!isNaN(index)) {
|
||||
updateGallery(index);
|
||||
}
|
||||
});
|
||||
// Add keyboard navigation
|
||||
question.addEventListener("keydown", function (e) {
|
||||
if (e.key === "Enter" || e.key === " ") {
|
||||
e.preventDefault();
|
||||
this.click();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Auto-advance gallery every 5 seconds
|
||||
setInterval(nextImage, 5000);
|
||||
console.log('Gallery initialized successfully');
|
||||
}); // End of DOMContentLoaded for gallery
|
||||
// ===== IMAGE GALLERY =====
|
||||
const galleryImages = [
|
||||
{
|
||||
src: "images/green-tea-leaves.webp",
|
||||
alt: "Premium Green Tea Leaves",
|
||||
caption: "Premium Green Tea Leaves - Hand-picked from our finest gardens",
|
||||
},
|
||||
{
|
||||
src: "images/Indian Black Teas.webp",
|
||||
alt: "Indian Black Tea Selection",
|
||||
caption:
|
||||
"Authentic Indian Black Teas - Rich and robust flavors from Assam and Darjeeling",
|
||||
},
|
||||
{
|
||||
src: "images/Oolong Selections.jpg",
|
||||
alt: "Oolong Tea Collection",
|
||||
caption:
|
||||
"Traditional Oolong Selections - Complex flavors from Taiwan and China",
|
||||
},
|
||||
];
|
||||
|
||||
// Enhanced Contact Form Validation
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const contactForm = document.querySelector('.contact-form');
|
||||
|
||||
if (contactForm) {
|
||||
const formGroups = contactForm.querySelectorAll('.form-group');
|
||||
|
||||
// Real-time validation function
|
||||
function validateField(field) {
|
||||
const formGroup = field.closest('.form-group');
|
||||
const errorSpan = formGroup.querySelector('.error-message');
|
||||
let isValid = true;
|
||||
let errorMessage = '';
|
||||
const galleryImage = document.getElementById("gallery-image");
|
||||
const galleryCaption = document.getElementById("gallery-caption");
|
||||
const thumbnails = document.querySelectorAll(".thumbnail");
|
||||
let currentIndex = 0;
|
||||
|
||||
// Remove previous validation classes
|
||||
formGroup.classList.remove('error', 'success');
|
||||
if (!galleryImage || !galleryCaption) return;
|
||||
|
||||
// Validate required fields
|
||||
if (field.hasAttribute('required') && !field.value.trim()) {
|
||||
isValid = false;
|
||||
errorMessage = 'This field is required.';
|
||||
} else if (field.type === 'email' && field.value) {
|
||||
// Email validation
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
if (!emailRegex.test(field.value)) {
|
||||
isValid = false;
|
||||
errorMessage = 'Please enter a valid email address.';
|
||||
}
|
||||
} else if (field.type === 'tel' && field.value) {
|
||||
// Phone validation (basic)
|
||||
const phoneRegex = /^[\d\s\-\+\(\)]+$/;
|
||||
if (!phoneRegex.test(field.value)) {
|
||||
isValid = false;
|
||||
errorMessage = 'Please enter a valid phone number.';
|
||||
}
|
||||
} else if (field.tagName === 'TEXTAREA' && field.value.length < 10 && field.hasAttribute('required')) {
|
||||
// Message length validation
|
||||
isValid = false;
|
||||
errorMessage = 'Message must be at least 10 characters long.';
|
||||
}
|
||||
// Update gallery display
|
||||
function updateGallery(index) {
|
||||
currentIndex = index;
|
||||
const image = galleryImages[index];
|
||||
galleryImage.src = image.src;
|
||||
galleryImage.alt = image.alt;
|
||||
galleryCaption.textContent = image.caption;
|
||||
|
||||
// Display validation results
|
||||
if (errorSpan) {
|
||||
errorSpan.textContent = errorMessage;
|
||||
}
|
||||
|
||||
if (isValid && field.value.trim()) {
|
||||
formGroup.classList.add('success');
|
||||
} else if (!isValid) {
|
||||
formGroup.classList.add('error');
|
||||
}
|
||||
thumbnails.forEach((thumb, i) => {
|
||||
thumb.classList.toggle("active", i === index);
|
||||
});
|
||||
}
|
||||
|
||||
return isValid;
|
||||
// Navigation functions
|
||||
const nextImage = () =>
|
||||
updateGallery((currentIndex + 1) % galleryImages.length);
|
||||
const prevImage = () =>
|
||||
updateGallery(
|
||||
(currentIndex - 1 + galleryImages.length) % galleryImages.length
|
||||
);
|
||||
|
||||
// Event listeners
|
||||
document.getElementById("next-btn")?.addEventListener("click", nextImage);
|
||||
document.getElementById("prev-btn")?.addEventListener("click", prevImage);
|
||||
|
||||
thumbnails.forEach((thumb, index) => {
|
||||
thumb.addEventListener("click", () => updateGallery(index));
|
||||
});
|
||||
|
||||
// Auto-advance every 10 seconds
|
||||
setInterval(nextImage, 10000);
|
||||
|
||||
// ===== CONTACT FORM =====
|
||||
const contactForm = document.querySelector(".contact-form");
|
||||
if (contactForm) {
|
||||
const validateField = (field) => {
|
||||
const group = field.closest(".form-group");
|
||||
const error = group?.querySelector(".error-message");
|
||||
let isValid = true;
|
||||
let message = "";
|
||||
|
||||
group?.classList.remove("error", "success");
|
||||
|
||||
if (field.required && !field.value.trim()) {
|
||||
isValid = false;
|
||||
message = "This field is required.";
|
||||
} else if (
|
||||
field.type === "email" &&
|
||||
field.value &&
|
||||
!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(field.value)
|
||||
) {
|
||||
isValid = false;
|
||||
message = "Please enter a valid email address.";
|
||||
} else if (
|
||||
field.type === "tel" &&
|
||||
field.value &&
|
||||
!/^[\d\s\-\+\(\)]+$/.test(field.value)
|
||||
) {
|
||||
isValid = false;
|
||||
message = "Please enter a valid phone number.";
|
||||
}
|
||||
|
||||
if (error) error.textContent = message;
|
||||
group?.classList.add(
|
||||
isValid && field.value.trim() ? "success" : isValid ? "" : "error"
|
||||
);
|
||||
return isValid;
|
||||
};
|
||||
|
||||
contactForm.querySelectorAll("input, textarea").forEach((field) => {
|
||||
field.addEventListener("blur", () => validateField(field));
|
||||
field.addEventListener("input", () => {
|
||||
if (field.closest(".form-group")?.classList.contains("error")) {
|
||||
validateField(field);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Add real-time validation to all form fields
|
||||
formGroups.forEach(group => {
|
||||
const input = group.querySelector('input, textarea');
|
||||
if (input) {
|
||||
input.addEventListener('blur', () => validateField(input));
|
||||
input.addEventListener('input', () => {
|
||||
if (group.classList.contains('error')) {
|
||||
validateField(input);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
contactForm.addEventListener("submit", (e) => {
|
||||
e.preventDefault();
|
||||
const fields = contactForm.querySelectorAll("input, textarea");
|
||||
const isValid = Array.from(fields).every(validateField);
|
||||
|
||||
contactForm.addEventListener('submit', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
let isFormValid = true;
|
||||
const formData = new FormData(contactForm);
|
||||
const data = Object.fromEntries(formData);
|
||||
|
||||
// Validate all fields
|
||||
formGroups.forEach(group => {
|
||||
const input = group.querySelector('input, textarea');
|
||||
if (input && !validateField(input)) {
|
||||
isFormValid = false;
|
||||
}
|
||||
});
|
||||
if (isValid) {
|
||||
const submitBtn = contactForm.querySelector(".submit-btn");
|
||||
const originalText = submitBtn.textContent;
|
||||
submitBtn.textContent = "Sending...";
|
||||
submitBtn.disabled = true;
|
||||
|
||||
if (!isFormValid) {
|
||||
// Focus on first error field
|
||||
const firstError = contactForm.querySelector('.form-group.error input, .form-group.error textarea');
|
||||
if (firstError) {
|
||||
firstError.focus();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Simulate form submission with loading state
|
||||
const submitBtn = contactForm.querySelector('.submit-btn');
|
||||
const originalText = submitBtn.textContent;
|
||||
submitBtn.textContent = 'Sending...';
|
||||
submitBtn.disabled = true;
|
||||
|
||||
setTimeout(() => {
|
||||
alert(`Thank you for your message, ${data.name}! We'll get back to you soon at ${data.email}.`);
|
||||
contactForm.reset();
|
||||
formGroups.forEach(group => group.classList.remove('error', 'success'));
|
||||
submitBtn.textContent = originalText;
|
||||
submitBtn.disabled = false;
|
||||
}, 2000);
|
||||
});
|
||||
setTimeout(() => {
|
||||
const formData = new FormData(contactForm);
|
||||
const data = Object.fromEntries(formData);
|
||||
alert(`Thank you, ${data.name}! We'll contact you at ${data.email}.`);
|
||||
contactForm.reset();
|
||||
fields.forEach((f) =>
|
||||
f.closest(".form-group")?.classList.remove("error", "success")
|
||||
);
|
||||
submitBtn.textContent = originalText;
|
||||
submitBtn.disabled = false;
|
||||
}, 2000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ===== HOVER EFFECTS =====
|
||||
document
|
||||
.querySelectorAll(".services-list li, .value-item, .timeline-item")
|
||||
.forEach((item) => {
|
||||
item.addEventListener("mouseenter", () => {
|
||||
item.style.transform = "translateY(-2px)";
|
||||
item.style.transition = "transform 0.3s ease";
|
||||
});
|
||||
item.addEventListener("mouseleave", () => {
|
||||
item.style.transform = "translateY(0)";
|
||||
});
|
||||
});
|
||||
|
||||
// ===== ACTIVE NAVIGATION =====
|
||||
const currentPage = location.pathname.split("/").pop();
|
||||
document.querySelectorAll(".main-nav a").forEach((link) => {
|
||||
const linkPage = link.getAttribute("href");
|
||||
if (
|
||||
linkPage === currentPage ||
|
||||
(currentPage === "" && linkPage === "index.html")
|
||||
) {
|
||||
link.style.backgroundColor = "#daa520";
|
||||
link.style.color = "#5d4037";
|
||||
}
|
||||
});
|
||||
|
||||
// FAQ Accordion Functionality
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const faqQuestions = document.querySelectorAll('.faq-question');
|
||||
|
||||
faqQuestions.forEach(question => {
|
||||
question.addEventListener('click', function() {
|
||||
const answer = this.nextElementSibling;
|
||||
const toggle = this.querySelector('.faq-toggle');
|
||||
const isExpanded = this.getAttribute('aria-expanded') === 'true';
|
||||
|
||||
// Close all other FAQ items
|
||||
faqQuestions.forEach(otherQuestion => {
|
||||
if (otherQuestion !== this) {
|
||||
const otherAnswer = otherQuestion.nextElementSibling;
|
||||
const otherToggle = otherQuestion.querySelector('.faq-toggle');
|
||||
|
||||
otherQuestion.setAttribute('aria-expanded', 'false');
|
||||
otherAnswer.classList.remove('active');
|
||||
otherToggle.classList.remove('active');
|
||||
}
|
||||
});
|
||||
|
||||
// Toggle current FAQ item
|
||||
this.setAttribute('aria-expanded', !isExpanded);
|
||||
answer.classList.toggle('active');
|
||||
toggle.classList.toggle('active');
|
||||
});
|
||||
|
||||
// Add keyboard navigation
|
||||
question.addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
e.preventDefault();
|
||||
this.click();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Smooth scrolling for navigation links
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const navLinks = document.querySelectorAll('.main-nav a');
|
||||
|
||||
navLinks.forEach(link => {
|
||||
link.addEventListener('click', function(e) {
|
||||
// Check if it's an internal link
|
||||
if (this.hostname === window.location.hostname) {
|
||||
// Add a subtle animation effect
|
||||
this.style.transform = 'scale(0.95)';
|
||||
setTimeout(() => {
|
||||
this.style.transform = 'scale(1)';
|
||||
}, 150);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Add hover effects to service items
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const serviceItems = document.querySelectorAll('.services-list li, .value-item, .timeline-item');
|
||||
|
||||
serviceItems.forEach(item => {
|
||||
item.addEventListener('mouseenter', function() {
|
||||
this.style.transform = 'translateY(-2px)';
|
||||
this.style.transition = 'transform 0.3s ease';
|
||||
});
|
||||
|
||||
item.addEventListener('mouseleave', function() {
|
||||
this.style.transform = 'translateY(0)';
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Active navigation highlighting
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const currentPage = window.location.pathname.split('/').pop();
|
||||
const navLinks = document.querySelectorAll('.main-nav a');
|
||||
|
||||
navLinks.forEach(link => {
|
||||
const linkPage = link.getAttribute('href');
|
||||
if (linkPage === currentPage || (currentPage === '' && linkPage === 'index.html')) {
|
||||
link.style.backgroundColor = '#daa520';
|
||||
link.style.color = '#5d4037';
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user