← back to Jill Website
views/property-detail.ejs
1047 lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><%= property.name %> - Nosara Beachfront Rentals</title>
<meta name="description" content="<%= property.description.substring(0, 160) %>">
<!-- Google Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Playfair+Display:wght@400;600;700&display=swap" rel="stylesheet">
<!-- Font Awesome -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<!-- Stylesheets -->
<link rel="stylesheet" href="/css/style.css">
<link rel="stylesheet" href="/css/adaptive-loading.css">
<style>
/* Property Detail Specific Styles */
.property-header {
background: linear-gradient(135deg, #2c5f8d 0%, #16a085 100%);
color: white;
padding: 6rem 0 3rem;
margin-top: 80px;
}
.property-title {
font-family: 'Playfair Display', serif;
font-size: 3rem;
font-weight: 700;
margin-bottom: 1rem;
}
.property-subtitle {
font-size: 1.2rem;
opacity: 0.9;
margin-bottom: 2rem;
}
.property-quick-info {
display: flex;
gap: 2rem;
flex-wrap: wrap;
padding: 1.5rem 0;
}
.quick-info-item {
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 1.1rem;
}
.quick-info-item i {
font-size: 1.3rem;
}
.gallery-section {
padding: 3rem 0;
background: #f8f9fa;
}
.gallery-main {
position: relative;
width: 100%;
height: 600px;
background: #000;
border-radius: 15px;
overflow: hidden;
margin-bottom: 1.5rem;
}
.gallery-main img {
width: 100%;
height: 100%;
object-fit: cover;
}
.gallery-nav {
position: absolute;
top: 50%;
transform: translateY(-50%);
background: rgba(255, 255, 255, 0.9);
border: none;
width: 50px;
height: 50px;
border-radius: 50%;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.5rem;
color: #2c5f8d;
transition: all 0.3s ease;
z-index: 10;
}
.gallery-nav:hover {
background: white;
transform: translateY(-50%) scale(1.1);
}
.gallery-nav.prev {
left: 20px;
}
.gallery-nav.next {
right: 20px;
}
.gallery-counter {
position: absolute;
bottom: 20px;
right: 20px;
background: rgba(0, 0, 0, 0.7);
color: white;
padding: 0.5rem 1rem;
border-radius: 20px;
font-size: 0.9rem;
}
.gallery-thumbnails {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
gap: 1rem;
}
.thumbnail {
position: relative;
height: 120px;
border-radius: 10px;
overflow: hidden;
cursor: pointer;
border: 3px solid transparent;
transition: all 0.3s ease;
}
.thumbnail:hover {
transform: scale(1.05);
border-color: #2c5f8d;
}
.thumbnail.active {
border-color: #16a085;
}
.thumbnail img {
width: 100%;
height: 100%;
object-fit: cover;
}
.property-content {
padding: 3rem 0;
}
.content-grid {
display: grid;
grid-template-columns: 2fr 1fr;
gap: 3rem;
margin-top: 2rem;
}
.main-content {
background: white;
padding: 2rem;
border-radius: 15px;
box-shadow: 0 5px 20px rgba(0,0,0,0.1);
}
.sidebar {
position: sticky;
top: 100px;
height: fit-content;
}
.booking-card {
background: white;
padding: 2rem;
border-radius: 15px;
box-shadow: 0 5px 20px rgba(0,0,0,0.1);
margin-bottom: 2rem;
}
.price-display {
text-align: center;
margin-bottom: 2rem;
}
.price-amount {
font-size: 3rem;
font-weight: 700;
color: #2c5f8d;
}
.price-label {
font-size: 1rem;
color: #7f8c8d;
}
.section-title {
font-family: 'Playfair Display', serif;
font-size: 2rem;
color: #2c3e50;
margin-bottom: 1.5rem;
padding-bottom: 0.5rem;
border-bottom: 2px solid #ecf0f1;
}
.description-text {
font-size: 1.1rem;
line-height: 1.8;
color: #2c3e50;
margin-bottom: 2rem;
}
.amenities-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 1.5rem;
margin-top: 2rem;
}
.amenity-item {
display: flex;
align-items: center;
gap: 1rem;
padding: 1rem;
background: #f8f9fa;
border-radius: 10px;
transition: all 0.3s ease;
}
.amenity-item:hover {
background: #ecf0f1;
transform: translateX(5px);
}
.amenity-icon {
width: 40px;
height: 40px;
background: linear-gradient(135deg, #2c5f8d, #16a085);
color: white;
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.2rem;
}
.specs-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1.5rem;
margin: 2rem 0;
}
.spec-card {
text-align: center;
padding: 1.5rem;
background: linear-gradient(135deg, #2c5f8d, #16a085);
color: white;
border-radius: 15px;
}
.spec-icon {
font-size: 2.5rem;
margin-bottom: 0.5rem;
}
.spec-value {
font-size: 2rem;
font-weight: 700;
margin-bottom: 0.25rem;
}
.spec-label {
font-size: 0.9rem;
opacity: 0.9;
}
.location-section {
margin-top: 3rem;
padding: 2rem;
background: #f8f9fa;
border-radius: 15px;
}
.btn-book {
width: 100%;
padding: 1.5rem;
background: linear-gradient(135deg, #FF5A5F, #FF385C);
color: white;
border: none;
border-radius: 12px;
font-size: 1.3rem;
font-weight: 700;
cursor: pointer;
transition: all 0.3s ease;
text-decoration: none;
display: block;
text-align: center;
box-shadow: 0 4px 15px rgba(255, 56, 92, 0.3);
position: relative;
overflow: hidden;
}
.btn-book::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
transition: left 0.5s ease;
}
.btn-book:hover::before {
left: 100%;
}
.btn-book:hover {
transform: translateY(-3px);
box-shadow: 0 12px 35px rgba(255, 56, 92, 0.5);
background: linear-gradient(135deg, #FF385C, #FF5A5F);
}
.btn-book i {
font-size: 1.5rem;
margin-right: 0.5rem;
vertical-align: middle;
}
.airbnb-unavailable {
padding: 1.5rem;
background: #f8f9fa;
border: 2px dashed #cbd5e0;
border-radius: 12px;
text-align: center;
color: #718096;
}
.airbnb-unavailable i {
font-size: 2rem;
margin-bottom: 0.5rem;
display: block;
color: #a0aec0;
}
.btn-back {
display: inline-flex;
align-items: center;
gap: 0.5rem;
padding: 0.8rem 1.5rem;
background: white;
color: #2c5f8d;
text-decoration: none;
border-radius: 10px;
font-weight: 600;
transition: all 0.3s ease;
margin-bottom: 2rem;
}
.btn-back:hover {
background: #ecf0f1;
transform: translateX(-5px);
}
/* Inquiry Form Styles */
#inquiry-submit-btn:hover:not(:disabled) {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(44, 95, 141, 0.3);
}
#inquiry-submit-btn:disabled {
opacity: 0.7;
cursor: not-allowed;
}
#inquiry-form input:focus,
#inquiry-form textarea:focus {
outline: none;
border-color: #2c5f8d !important;
box-shadow: 0 0 0 3px rgba(44, 95, 141, 0.1);
}
@media (max-width: 968px) {
.content-grid {
grid-template-columns: 1fr;
}
.sidebar {
position: static;
}
.gallery-main {
height: 400px;
}
.property-title {
font-size: 2rem;
}
#inquiry-form input[type="date"] {
font-size: 16px; /* Prevent iOS zoom */
}
}
@media (max-width: 480px) {
.booking-card {
padding: 1.5rem;
}
}
</style>
</head>
<body>
<!-- Navigation -->
<nav class="navbar">
<div class="nav-container">
<div class="nav-logo">
<h2>Nosara Beachfront</h2>
</div>
<ul class="nav-menu">
<li><a href="/#home" class="nav-link">Home</a></li>
<li><a href="/#properties" class="nav-link">Properties</a></li>
<li><a href="/#experiences" class="nav-link">Experiences</a></li>
<li><a href="/#history" class="nav-link">History</a></li>
<li><a href="/#dining" class="nav-link">Dining</a></li>
<li><a href="/#contact" class="nav-link">Contact</a></li>
</ul>
<div class="hamburger">
<span class="bar"></span>
<span class="bar"></span>
<span class="bar"></span>
</div>
</div>
</nav>
<!-- Property Header -->
<section class="property-header">
<div class="container">
<a href="/" class="btn-back">
<i class="fas fa-arrow-left"></i> Back to Properties
</a>
<h1 class="property-title"><%= property.name %></h1>
<p class="property-subtitle"><i class="fas fa-map-marker-alt"></i> Nosara, Guanacaste, Costa Rica</p>
<div class="property-quick-info">
<% if (property.capacity) { %>
<div class="quick-info-item">
<i class="fas fa-users"></i>
<span>Up to <%= property.capacity %> Guests</span>
</div>
<% } %>
<% if (property.bedrooms) { %>
<div class="quick-info-item">
<i class="fas fa-bed"></i>
<span><%= property.bedrooms %> Bedroom<%= property.bedrooms > 1 ? 's' : '' %></span>
</div>
<% } %>
<% if (property.bathrooms) { %>
<div class="quick-info-item">
<i class="fas fa-bath"></i>
<span><%= property.bathrooms %> Bathroom<%= property.bathrooms > 1 ? 's' : '' %></span>
</div>
<% } %>
<% if (property.size_sqm) { %>
<div class="quick-info-item">
<i class="fas fa-ruler-combined"></i>
<span><%= Math.round(property.size_sqm) %> m²</span>
</div>
<% } %>
</div>
</div>
</section>
<!-- Image Gallery -->
<section class="gallery-section">
<div class="container">
<div class="gallery-main">
<% if (property.images && property.images.length > 0) { %>
<img
id="mainImage"
src="<%= property.images[0] %>"
alt="<%= property.name %> - Luxury beachfront vacation rental in Nosara, Costa Rica with <%= property.bedrooms %> bedroom<%= property.bedrooms > 1 ? 's' : '' %> and <%= property.amenities && property.amenities.length > 0 ? property.amenities[0] : 'premium amenities' %>"
loading="eager">
<% if (property.images.length > 1) { %>
<button class="gallery-nav prev" onclick="changeImage(-1)" aria-label="Previous image">
<i class="fas fa-chevron-left" aria-hidden="true"></i>
</button>
<button class="gallery-nav next" onclick="changeImage(1)" aria-label="Next image">
<i class="fas fa-chevron-right" aria-hidden="true"></i>
</button>
<div class="gallery-counter" aria-live="polite">
<span id="imageCounter">1</span> / <%= property.images.length %>
</div>
<% } %>
<% } %>
</div>
<% if (property.images && property.images.length > 1) { %>
<div class="gallery-thumbnails">
<% property.images.forEach(function(image, index) { %>
<div class="thumbnail <%= index === 0 ? 'active' : '' %>" onclick="selectImage(<%= index %>)">
<img
src="<%= image %>"
alt="<%= property.name %> - View <%= index + 1 %> of <%= property.images.length %> showing <%= index === 0 ? 'exterior' : index === 1 ? 'living area' : index === 2 ? 'bedroom' : 'interior details' %>"
loading="lazy">
</div>
<% }); %>
</div>
<% } %>
</div>
</section>
<!-- Property Content -->
<section class="property-content">
<div class="container">
<div class="content-grid">
<!-- Main Content -->
<div class="main-content">
<!-- Description -->
<h2 class="section-title">About This Property</h2>
<p class="description-text"><%= property.description %></p>
<!-- Property Specs -->
<div class="specs-grid">
<% if (property.capacity) { %>
<div class="spec-card">
<div class="spec-icon"><i class="fas fa-users"></i></div>
<div class="spec-value"><%= property.capacity %></div>
<div class="spec-label">Guests</div>
</div>
<% } %>
<% if (property.bedrooms) { %>
<div class="spec-card">
<div class="spec-icon"><i class="fas fa-bed"></i></div>
<div class="spec-value"><%= property.bedrooms %></div>
<div class="spec-label">Bedrooms</div>
</div>
<% } %>
<% if (property.bathrooms) { %>
<div class="spec-card">
<div class="spec-icon"><i class="fas fa-bath"></i></div>
<div class="spec-value"><%= property.bathrooms %></div>
<div class="spec-label">Bathrooms</div>
</div>
<% } %>
<% if (property.size_sqm) { %>
<div class="spec-card">
<div class="spec-icon"><i class="fas fa-expand-arrows-alt"></i></div>
<div class="spec-value"><%= Math.round(property.size_sqm) %></div>
<div class="spec-label">Square Meters</div>
</div>
<% } %>
</div>
<!-- Amenities -->
<% if (property.amenities && property.amenities.length > 0) { %>
<h2 class="section-title">Luxury Amenities</h2>
<div class="amenities-grid">
<% property.amenities.forEach(function(amenity) { %>
<div class="amenity-item">
<div class="amenity-icon">
<i class="fas fa-check"></i>
</div>
<span><%= amenity %></span>
</div>
<% }); %>
</div>
<% } %>
<!-- Location -->
<div class="location-section">
<h2 class="section-title">Location & Heritage</h2>
<div style="display: flex; align-items: start; gap: 1.5rem; flex-direction: column;">
<div style="flex: 1; width: 100%;">
<h3 style="color: #2c5f8d; margin-bottom: 1rem;">Nosara, Guanacaste, Costa Rica</h3>
<p style="line-height: 1.8; color: #2c3e50;">
Located in one of Costa Rica's most beautiful coastal regions, Nosara offers pristine beaches,
world-class surfing, yoga retreats, and abundant wildlife. The area is known for its natural beauty,
laid-back atmosphere, and eco-conscious community. Perfect for those seeking relaxation, adventure,
or both.
</p>
<ul style="margin-top: 1rem; list-style: none; padding: 0;">
<li style="margin-bottom: 0.5rem;">
<i class="fas fa-check" style="color: #16a085; margin-right: 0.5rem;"></i>
Walking distance to pristine beaches
</li>
<li style="margin-bottom: 0.5rem;">
<i class="fas fa-check" style="color: #16a085; margin-right: 0.5rem;"></i>
Close to restaurants and shops
</li>
<li style="margin-bottom: 0.5rem;">
<i class="fas fa-check" style="color: #16a085; margin-right: 0.5rem;"></i>
Near yoga studios and wellness centers
</li>
<li style="margin-bottom: 0.5rem;">
<i class="fas fa-check" style="color: #16a085; margin-right: 0.5rem;"></i>
Easy access to nature reserves
</li>
</ul>
</div>
<!-- Historical Context -->
<div style="flex: 1; width: 100%; margin-top: 2rem;">
<h3 style="color: #2c5f8d; margin-bottom: 1rem;"><i class="fas fa-landmark" style="margin-right: 0.5rem;"></i>A Place Rich in History</h3>
<p style="line-height: 1.8; color: #2c3e50; margin-bottom: 1rem;">
Nosara's name derives from the indigenous Chorotega word "Noxal-ara," meaning "between the lagoons."
For over 700 years before Spanish contact, this region was home to the Chorotega people, who developed
sophisticated agricultural techniques and created distinctive polychrome pottery that is now displayed in museums worldwide.
</p>
<p style="line-height: 1.8; color: #2c3e50; margin-bottom: 1rem;">
Today, Nosara is recognized as a pioneer in environmental conservation. Since the 1970s, the Nosara Civic
Association has protected critical wildlife corridors and established Costa Rica's first 50-meter coastal buffer zones,
making this community a model for sustainable development throughout Central America.
</p>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; margin-top: 1.5rem;">
<div style="padding: 1rem; background: #f8f9fa; border-radius: 10px; border-left: 3px solid #2c5f8d;">
<div style="font-weight: 700; color: #2c5f8d; margin-bottom: 0.5rem;">800-1550 CE</div>
<div style="font-size: 0.95rem; color: #2c3e50;">Chorotega civilization thrives in the region</div>
</div>
<div style="padding: 1rem; background: #f8f9fa; border-radius: 10px; border-left: 3px solid #16a085;">
<div style="font-weight: 700; color: #16a085; margin-bottom: 0.5rem;">1970s</div>
<div style="font-size: 0.95rem; color: #2c3e50;">Conservation movement begins in Nosara</div>
</div>
<div style="padding: 1rem; background: #f8f9fa; border-radius: 10px; border-left: 3px solid #f39c12;">
<div style="font-weight: 700; color: #f39c12; margin-bottom: 0.5rem;">1984</div>
<div style="font-size: 0.95rem; color: #2c3e50;">Ostional Wildlife Refuge established nearby</div>
</div>
</div>
<div style="margin-top: 1.5rem; padding: 1rem; background: linear-gradient(135deg, rgba(44, 95, 141, 0.1), rgba(22, 160, 133, 0.1)); border-radius: 10px; border: 1px solid #2c5f8d;">
<p style="margin: 0; font-size: 0.95rem; color: #2c3e50;">
<i class="fas fa-info-circle" style="color: #2c5f8d; margin-right: 0.5rem;"></i>
<strong>Cultural Tip:</strong> Visit during late July to experience the Annexation of Guanacaste celebrations,
featuring traditional music, dance, and folkloric festivities commemorating the region's democratic decision to join Costa Rica in 1824.
</p>
</div>
</div>
</div>
</div>
</div>
<!-- Sidebar -->
<div class="sidebar">
<!-- Booking Card -->
<div class="booking-card">
<% if (property.price_per_night) { %>
<div class="price-display">
<div style="color: #7f8c8d; font-size: 0.9rem; margin-bottom: 0.5rem;">From</div>
<div class="price-amount">$<%= Math.round(property.price_per_night) %></div>
<div class="price-label">per night</div>
</div>
<% } %>
<% if (property.airbnb_url) { %>
<a href="<%= property.airbnb_url %>?source=nosarabeachfront&utm_source=website&utm_medium=property_page&utm_campaign=booking_button"
target="_blank"
rel="noopener noreferrer"
class="btn-book"
aria-label="Book <%= property.name %> on Airbnb">
<i class="fab fa-airbnb"></i> Book on Airbnb
</a>
<% } else { %>
<div class="airbnb-unavailable">
<i class="fas fa-exclamation-circle"></i>
<p style="margin: 0.5rem 0 0 0; font-weight: 600;">Booking Currently Unavailable</p>
<p style="margin: 0.5rem 0 0 0; font-size: 0.9rem;">Please contact us directly for availability and booking inquiries.</p>
</div>
<% } %>
<div style="margin-top: 1.5rem; padding-top: 1.5rem; border-top: 2px solid #ecf0f1; text-align: center;">
<p style="color: #7f8c8d; font-size: 0.9rem; margin-bottom: 1rem;">
<i class="fas fa-shield-alt"></i> Secure booking through Airbnb
</p>
<p style="color: #7f8c8d; font-size: 0.9rem;">
<i class="fas fa-headset"></i> 24/7 concierge support
</p>
</div>
</div>
<!-- Contact Card / Inquiry Form -->
<div class="booking-card" id="inquiry-card">
<h3 style="font-size: 1.3rem; margin-bottom: 1rem; color: #2c3e50;">Have Questions?</h3>
<p style="color: #7f8c8d; margin-bottom: 1.5rem;">Send us an inquiry about this property.</p>
<!-- Success/Error Messages -->
<div id="form-message" style="display: none; padding: 1rem; border-radius: 8px; margin-bottom: 1rem; font-size: 0.9rem;"></div>
<!-- Inquiry Form -->
<form id="inquiry-form">
<input type="hidden" name="property_name" value="<%= property.name %>">
<div style="margin-bottom: 1rem;">
<input
type="text"
id="inquiry-name"
name="name"
placeholder="Your Name *"
required
style="width: 100%; padding: 0.75rem; border: 2px solid #ecf0f1; border-radius: 8px; font-size: 0.95rem; transition: border-color 0.3s;"
>
</div>
<div style="margin-bottom: 1rem;">
<input
type="email"
id="inquiry-email"
name="email"
placeholder="Email Address *"
required
style="width: 100%; padding: 0.75rem; border: 2px solid #ecf0f1; border-radius: 8px; font-size: 0.95rem; transition: border-color 0.3s;"
>
</div>
<div style="margin-bottom: 1rem;">
<input
type="tel"
id="inquiry-phone"
name="phone"
placeholder="Phone Number *"
required
style="width: 100%; padding: 0.75rem; border: 2px solid #ecf0f1; border-radius: 8px; font-size: 0.95rem; transition: border-color 0.3s;"
>
</div>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 0.75rem; margin-bottom: 1rem;">
<div>
<label for="inquiry-checkin" style="display: block; font-size: 0.85rem; color: #7f8c8d; margin-bottom: 0.25rem;">Check-in *</label>
<input
type="date"
id="inquiry-checkin"
name="check_in_date"
required
style="width: 100%; padding: 0.75rem; border: 2px solid #ecf0f1; border-radius: 8px; font-size: 0.95rem; transition: border-color 0.3s;"
>
</div>
<div>
<label for="inquiry-checkout" style="display: block; font-size: 0.85rem; color: #7f8c8d; margin-bottom: 0.25rem;">Check-out *</label>
<input
type="date"
id="inquiry-checkout"
name="check_out_date"
required
style="width: 100%; padding: 0.75rem; border: 2px solid #ecf0f1; border-radius: 8px; font-size: 0.95rem; transition: border-color 0.3s;"
>
</div>
</div>
<div style="margin-bottom: 1rem;">
<label for="inquiry-guests" style="display: block; font-size: 0.85rem; color: #7f8c8d; margin-bottom: 0.25rem;">Number of Guests *</label>
<input
type="number"
id="inquiry-guests"
name="guest_count"
min="1"
<% if (property.capacity) { %>max="<%= property.capacity %>"<% } %>
placeholder="Number of guests"
required
style="width: 100%; padding: 0.75rem; border: 2px solid #ecf0f1; border-radius: 8px; font-size: 0.95rem; transition: border-color 0.3s;"
>
</div>
<div style="margin-bottom: 1.5rem;">
<textarea
id="inquiry-message"
name="message"
rows="4"
placeholder="Tell us about your travel plans or any special requests... *"
required
style="width: 100%; padding: 0.75rem; border: 2px solid #ecf0f1; border-radius: 8px; font-size: 0.95rem; resize: vertical; transition: border-color 0.3s;"
></textarea>
</div>
<button
type="submit"
id="inquiry-submit-btn"
style="width: 100%; padding: 1rem; background: linear-gradient(135deg, #2c5f8d, #16a085); color: white; border: none; border-radius: 10px; font-size: 1rem; font-weight: 600; cursor: pointer; transition: all 0.3s ease;"
>
<i class="fas fa-paper-plane"></i> Send Inquiry
</button>
</form>
</div>
</div>
</div>
</div>
</section>
<!-- Footer -->
<footer class="footer">
<div class="container">
<div class="footer-content">
<div class="footer-section">
<h3>Nosara Beachfront</h3>
<p>Your gateway to luxury beachfront living in Costa Rica's most beautiful coastal paradise.</p>
<div class="social-links">
<a href="#" aria-label="Facebook"><i class="fab fa-facebook-f"></i></a>
<a href="#" aria-label="Instagram"><i class="fab fa-instagram"></i></a>
<a href="#" aria-label="Twitter"><i class="fab fa-twitter"></i></a>
</div>
</div>
<div class="footer-section">
<h4>Quick Links</h4>
<ul>
<li><a href="/#home">Home</a></li>
<li><a href="/#properties">Properties</a></li>
<li><a href="/#experiences">Experiences</a></li>
<li><a href="/#contact">Contact</a></li>
</ul>
</div>
<div class="footer-section">
<h4>Resources</h4>
<ul>
<li><a href="#">Travel Guide</a></li>
<li><a href="#">FAQs</a></li>
<li><a href="#">Terms & Conditions</a></li>
<li><a href="#">Privacy Policy</a></li>
</ul>
</div>
</div>
<div class="footer-bottom">
<p>© <%= currentYear %> Nosara Beachfront Rentals. All rights reserved.</p>
</div>
</div>
</footer>
<!-- JavaScript -->
<script>
// Mobile menu toggle
const hamburger = document.querySelector('.hamburger');
const navMenu = document.querySelector('.nav-menu');
hamburger.addEventListener('click', () => {
hamburger.classList.toggle('active');
navMenu.classList.toggle('active');
});
// Close mobile menu when clicking on a link
document.querySelectorAll('.nav-link').forEach(link => {
link.addEventListener('click', () => {
hamburger.classList.remove('active');
navMenu.classList.remove('active');
});
});
// Navbar scroll effect
window.addEventListener('scroll', () => {
const navbar = document.querySelector('.navbar');
const currentScroll = window.pageYOffset;
if (currentScroll > 100) {
navbar.style.background = 'rgba(255, 255, 255, 0.98)';
navbar.style.boxShadow = '0 5px 20px rgba(0,0,0,0.15)';
} else {
navbar.style.background = 'rgba(255, 255, 255, 0.95)';
navbar.style.boxShadow = '0 5px 20px rgba(0,0,0,0.1)';
}
});
// Image Gallery
const images = <%- JSON.stringify(property.images || []) %>;
let currentImageIndex = 0;
function changeImage(direction) {
currentImageIndex += direction;
if (currentImageIndex < 0) {
currentImageIndex = images.length - 1;
} else if (currentImageIndex >= images.length) {
currentImageIndex = 0;
}
updateImage();
}
function selectImage(index) {
currentImageIndex = index;
updateImage();
}
function updateImage() {
document.getElementById('mainImage').src = images[currentImageIndex];
document.getElementById('imageCounter').textContent = currentImageIndex + 1;
// Update thumbnail active state
document.querySelectorAll('.thumbnail').forEach((thumb, index) => {
thumb.classList.toggle('active', index === currentImageIndex);
});
}
// Keyboard navigation for gallery
document.addEventListener('keydown', (e) => {
if (e.key === 'ArrowLeft') {
changeImage(-1);
} else if (e.key === 'ArrowRight') {
changeImage(1);
}
});
// Inquiry Form Handling
const inquiryForm = document.getElementById('inquiry-form');
const formMessage = document.getElementById('form-message');
const submitBtn = document.getElementById('inquiry-submit-btn');
if (inquiryForm) {
// Set minimum date to today
const today = new Date().toISOString().split('T')[0];
document.getElementById('inquiry-checkin').setAttribute('min', today);
document.getElementById('inquiry-checkout').setAttribute('min', today);
// Update checkout min date when checkin changes
document.getElementById('inquiry-checkin').addEventListener('change', function() {
const checkinDate = new Date(this.value);
const nextDay = new Date(checkinDate);
nextDay.setDate(nextDay.getDate() + 1);
const minCheckout = nextDay.toISOString().split('T')[0];
document.getElementById('inquiry-checkout').setAttribute('min', minCheckout);
});
// Form submission
inquiryForm.addEventListener('submit', async function(e) {
e.preventDefault();
// Client-side validation
const formData = new FormData(inquiryForm);
const data = {};
for (let [key, value] of formData.entries()) {
data[key] = value;
}
// Validate dates
const checkin = new Date(data.check_in_date);
const checkout = new Date(data.check_out_date);
const todayDate = new Date();
todayDate.setHours(0, 0, 0, 0);
if (checkin < todayDate) {
showMessage('Check-in date must be today or later', 'error');
return;
}
if (checkout <= checkin) {
showMessage('Check-out date must be after check-in date', 'error');
return;
}
// Validate guest count
const guestCount = parseInt(data.guest_count);
if (guestCount < 1) {
showMessage('Number of guests must be at least 1', 'error');
return;
}
<% if (property.capacity) { %>
if (guestCount > <%= property.capacity %>) {
showMessage('This property accommodates up to <%= property.capacity %> guests', 'error');
return;
}
<% } %>
// Disable submit button and show loading
submitBtn.disabled = true;
submitBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Sending...';
try {
// Submit to API
const response = await fetch('/api/inquiries', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});
const result = await response.json();
if (response.ok && result.success) {
showMessage('Thank you! Your inquiry has been sent successfully. We will contact you soon.', 'success');
inquiryForm.reset();
// Scroll to success message
formMessage.scrollIntoView({ behavior: 'smooth', block: 'center' });
} else {
showMessage(result.message || 'Failed to send inquiry. Please try again.', 'error');
}
} catch (error) {
console.error('Error submitting inquiry:', error);
showMessage('An error occurred. Please try again later.', 'error');
} finally {
// Re-enable submit button
submitBtn.disabled = false;
submitBtn.innerHTML = '<i class="fas fa-paper-plane"></i> Send Inquiry';
}
});
}
function showMessage(message, type) {
formMessage.textContent = message;
formMessage.style.display = 'block';
if (type === 'success') {
formMessage.style.background = '#d4edda';
formMessage.style.color = '#155724';
formMessage.style.border = '1px solid #c3e6cb';
} else {
formMessage.style.background = '#f8d7da';
formMessage.style.color = '#721c24';
formMessage.style.border = '1px solid #f5c6cb';
}
// Auto-hide error messages after 5 seconds
if (type === 'error') {
setTimeout(() => {
formMessage.style.display = 'none';
}, 5000);
}
}
// Add focus styles to form inputs
const formInputs = document.querySelectorAll('#inquiry-form input, #inquiry-form textarea');
formInputs.forEach(input => {
input.addEventListener('focus', function() {
this.style.borderColor = '#2c5f8d';
});
input.addEventListener('blur', function() {
if (!this.value) {
this.style.borderColor = '#ecf0f1';
}
});
});
</script>
<!-- Adaptive Loading Scripts -->
<script src="/js/connection-speed.js"></script>
<script src="/js/adaptive-loading.js"></script>
</body>
</html>