Files
website/internal/tmpl/home.tmpl
2025-10-28 14:19:54 +11:00

177 lines
6.2 KiB
Cheetah

{{define "home.tmpl"}}
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Home - Decor By Hannahs</title>
<link rel="stylesheet" href="/static/css/styles.css">
<script>
(function() {
const savedTheme = localStorage.getItem('theme') || 'light';
document.documentElement.setAttribute('data-theme', savedTheme);
})();
</script>
<script src="/static/js/alpine.js" defer></script>
<script src="/static/htmx/htmx.min.js" defer></script>
<script src="/static/js/drawer.js" defer></script>
</head>
<body>
{{template "header" .}}
<main>
<div class="hero" style="position: relative;">
<img src="/assets/party-icons/penguin-wearing-party-hat.png" alt="Party penguin" style="position: absolute; top: 20px; right: 10%; width: 100px; height: 100px; opacity: 0.8; animation: float 3s ease-in-out infinite;">
<img src="/assets/party-icons/jester-hat.png" alt="Jester hat" style="position: absolute; bottom: 20px; left: 10%; width: 80px; height: 80px; opacity: 0.8; animation: float 4s ease-in-out infinite; animation-delay: 1s;">
<h1>Welcome to Decor By Hannahs</h1>
<p>We take care of all the headache for your party decorations so you don't have to</p>
<div style="display: flex; gap: 1rem; justify-content: center; margin-top: 2rem; flex-wrap: wrap;">
<a href="/catalog" class="btn btn-primary">Browse Services</a>
<a href="/booking" class="btn btn-outline">Book Now</a>
</div>
</div>
<style>
@keyframes float {
0%, 100% { transform: translateY(0px); }
50% { transform: translateY(-20px); }
}
</style>
<div class="grid grid-cols-3" style="margin-top: 4rem;">
<div class="card" style="position: relative; overflow: visible;">
<img src="/assets/party-icons/party-hat.png" alt="Party hat" style="position: absolute; top: -50px; left: -45px; width: 80px; height: 80px; transform: rotate(-25deg); z-index: 10;"> <div class="card-header">
<h3 class="card-title">Professional Setup</h3>
<p class="card-description">Expert decoration services</p>
</div>
<div class="card-content">
<p>Our experienced team handles everything from setup to teardown, ensuring your event looks perfect.</p>
</div>
</div>
<div class="card" style="position: relative; overflow: visible;">
<img src="/assets/party-icons/birthday-cake.png" alt="Birthday cake" style="position: absolute; bottom: -15px; left: -15px; width: 70px; height: 70px; z-index: 10;">
<div class="card-header">
<h3 class="card-title">Custom Themes</h3>
<p class="card-description">Tailored to your vision</p>
</div>
<div class="card-content">
<p>Choose from our curated themes or work with us to create something uniquely yours.</p>
</div>
</div>
<div class="card" style="position: relative; overflow: visible;">
<img src="/assets/party-icons/happy-sun-wearing-party-hat.png" alt="Happy sun" style="position: absolute; top: -25px; right: -10px; width: 90px; height: 90px; z-index: 10;">
<div class="card-header">
<h3 class="card-title">Stress-Free Planning</h3>
<p class="card-description">We handle the details</p>
</div>
<div class="card-content">
<p>Focus on enjoying your event while we take care of all the decoration logistics.</p>
</div>
</div>
</div>
{{ if .Photos }}
<div style="margin-top: 4rem;">
<h2 style="font-size: 2rem; font-weight: 700; text-align: center; margin-bottom: 2rem;">See Our Work</h2>
<div class="carousel" id="carousel">
<div class="carousel-container">
<div class="carousel-track" id="carouselTrack">
{{ range .Photos }}
<div class="carousel-slide">
<img src="{{ .URL }}" alt="{{ if .Caption }}{{ .Caption }}{{ else }}Gallery photo{{ end }}" style="width: 100%; height: 500px; object-fit: cover; border-radius: var(--radius);">
{{ if .Caption }}
<p style="text-align: center; margin-top: 1rem; color: hsl(var(--muted-foreground));">{{ .Caption }}</p>
{{ end }}
</div>
{{ end }}
</div>
</div>
<button class="carousel-btn carousel-btn-prev" id="prevBtn" aria-label="Previous slide">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 18 9 12 15 6"></polyline></svg>
</button>
<button class="carousel-btn carousel-btn-next" id="nextBtn" aria-label="Next slide">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"></polyline></svg>
</button>
<div class="carousel-indicators" id="indicators"></div>
</div>
</div>
{{ end }}
</main>
{{template "footer"}}
{{template "theme-script"}}
<script>
(function() {
const track = document.getElementById('carouselTrack');
if (!track) return;
const prevBtn = document.getElementById('prevBtn');
const nextBtn = document.getElementById('nextBtn');
const indicators = document.getElementById('indicators');
const slides = track.querySelectorAll('.carousel-slide');
const totalSlides = slides.length;
let currentSlide = 0;
let autoplayInterval;
if (totalSlides === 0) return;
for (let i = 0; i < totalSlides; i++) {
const btn = document.createElement('button');
btn.className = 'carousel-indicator';
btn.setAttribute('aria-label', `Go to slide ${i + 1}`);
btn.addEventListener('click', () => goToSlide(i));
indicators.appendChild(btn);
}
function updateCarousel() {
track.style.transform = `translateX(-${currentSlide * 100}%)`;
const indicatorBtns = indicators.querySelectorAll('.carousel-indicator');
indicatorBtns.forEach((btn, i) => {
btn.classList.toggle('active', i === currentSlide);
});
}
function goToSlide(index) {
currentSlide = index;
updateCarousel();
resetAutoplay();
}
function nextSlide() {
currentSlide = (currentSlide + 1) % totalSlides;
updateCarousel();
}
function prevSlide() {
currentSlide = (currentSlide - 1 + totalSlides) % totalSlides;
updateCarousel();
resetAutoplay();
}
function startAutoplay() {
autoplayInterval = setInterval(nextSlide, 5000);
}
function resetAutoplay() {
clearInterval(autoplayInterval);
startAutoplay();
}
prevBtn.addEventListener('click', prevSlide);
nextBtn.addEventListener('click', () => {
nextSlide();
resetAutoplay();
});
updateCarousel();
startAutoplay();
})();
</script>
</body>
</html>
{{end}}