1215 lines
53 KiB
HTML
1215 lines
53 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Artisan Roast Co. — Crafted in Small Batches</title>
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
<link href="https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,500;0,600;0,700;1,400&family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
|
|
<script>
|
|
tailwind.config = {
|
|
theme: {
|
|
extend: {
|
|
fontFamily: {
|
|
display: ['Playfair Display', 'serif'],
|
|
body: ['Inter', 'sans-serif'],
|
|
},
|
|
colors: {
|
|
coffee: {
|
|
50: '#fdf8f0',
|
|
100: '#f5ebe0',
|
|
200: '#e8d5b8',
|
|
300: '#d4b896',
|
|
400: '#c49a6c',
|
|
500: '#b07a4a',
|
|
600: '#9a6335',
|
|
700: '#7d4e26',
|
|
800: '#5e3a1a',
|
|
900: '#3d2310',
|
|
950: '#1a100a',
|
|
},
|
|
bark: {
|
|
50: '#f0e6dc',
|
|
100: '#dcc7a8',
|
|
200: '#c4a57a',
|
|
300: '#a88558',
|
|
400: '#8e6d42',
|
|
500: '#735830',
|
|
600: '#5a4423',
|
|
700: '#3e2e17',
|
|
800: '#251b0e',
|
|
900: '#0f0b06',
|
|
},
|
|
terra: {
|
|
50: '#fdf5f0',
|
|
100: '#f5e1d0',
|
|
200: '#e8c4a8',
|
|
300: '#d4a67a',
|
|
400: '#c08a52',
|
|
500: '#a87238',
|
|
600: '#8b5a28',
|
|
700: '#6e4420',
|
|
800: '#4e3117',
|
|
900: '#311e0f',
|
|
950: '#1a0d06',
|
|
},
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
<style>
|
|
:root {
|
|
--bg: #fdf8f0;
|
|
--fg: #2a1a0a;
|
|
--muted: #8a7565;
|
|
--accent: #a87238;
|
|
--card: #fff;
|
|
--border: #e8d5b8;
|
|
--gold: #c9a96e;
|
|
}
|
|
|
|
* { box-sizing: border-box; }
|
|
|
|
html {
|
|
scroll-behavior: smooth;
|
|
overflow-x: hidden;
|
|
}
|
|
|
|
body {
|
|
font-family: 'Inter', sans-serif;
|
|
background: var(--bg);
|
|
color: var(--fg);
|
|
overflow-x: hidden;
|
|
}
|
|
|
|
/* Subtle noise overlay */
|
|
.noise-overlay::before {
|
|
content: '';
|
|
position: fixed;
|
|
inset: 0;
|
|
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E");
|
|
opacity: 0.015;
|
|
pointer-events: none;
|
|
z-index: 9999;
|
|
}
|
|
|
|
/* Hero background blobs */
|
|
.hero-blob {
|
|
position: absolute;
|
|
border-radius: 50%;
|
|
filter: blur(80px);
|
|
opacity: 0.4;
|
|
animation: drift 12s ease-in-out infinite;
|
|
will-change: transform;
|
|
}
|
|
|
|
@keyframes drift {
|
|
0%, 100% { transform: translate(0, 0) scale(1); }
|
|
33% { transform: translate(30px, -20px) scale(1.05); }
|
|
66% { transform: translate(-20px, 15px) scale(0.95); }
|
|
}
|
|
|
|
/* Roast glow pulse */
|
|
.roast-glow {
|
|
position: absolute;
|
|
width: 400px;
|
|
height: 400px;
|
|
border-radius: 50%;
|
|
background: radial-gradient(circle, rgba(168,114,56,0.08) 0%, transparent 70%);
|
|
filter: blur(60px);
|
|
animation: glowPulse 4s ease-in-out infinite;
|
|
will-change: transform, opacity;
|
|
}
|
|
|
|
@keyframes glowPulse {
|
|
0%, 100% { transform: scale(1); opacity: 0.6; }
|
|
50% { transform: scale(1.15); opacity: 1; }
|
|
}
|
|
|
|
/* Floating particles */
|
|
.particle {
|
|
position: absolute;
|
|
border-radius: 50%;
|
|
pointer-events: none;
|
|
opacity: 0;
|
|
will-change: transform, opacity;
|
|
}
|
|
|
|
.particle.active {
|
|
animation: floatUp 8s ease-in-out infinite;
|
|
}
|
|
|
|
@keyframes floatUp {
|
|
0% { opacity: 0; transform: translateY(0) scale(0); }
|
|
20% { opacity: 0.6; transform: translateY(-40px) scale(1); }
|
|
80% { opacity: 0.3; transform: translateY(-120px) scale(0.5); }
|
|
100% { opacity: 0; transform: translateY(-160px) scale(0); }
|
|
}
|
|
|
|
/* Scroll reveal */
|
|
.reveal {
|
|
opacity: 0;
|
|
transform: translateY(40px);
|
|
transition: opacity 0.8s ease, transform 0.8s ease;
|
|
}
|
|
|
|
.reveal.visible {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
|
|
/* Nav active indicator */
|
|
.nav-link {
|
|
position: relative;
|
|
transition: color 0.3s ease;
|
|
}
|
|
|
|
.nav-link::after {
|
|
content: '';
|
|
position: absolute;
|
|
bottom: -4px;
|
|
left: 50%;
|
|
width: 0;
|
|
height: 2px;
|
|
background: var(--accent);
|
|
transition: width 0.3s ease, left 0.3s ease;
|
|
border-radius: 2px;
|
|
}
|
|
|
|
.nav-link:hover::after {
|
|
width: 100%;
|
|
left: 0;
|
|
}
|
|
|
|
.nav-link:hover {
|
|
color: var(--accent);
|
|
}
|
|
|
|
/* Toast notification */
|
|
.toast {
|
|
position: fixed;
|
|
bottom: 2rem;
|
|
right: 2rem;
|
|
background: var(--card);
|
|
border: 1px solid var(--border);
|
|
border-radius: 12px;
|
|
padding: 1rem 1.5rem;
|
|
box-shadow: 0 8px 30px rgba(0,0,0,0.1);
|
|
transform: translateY(120%);
|
|
opacity: 0;
|
|
transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.4s ease;
|
|
z-index: 1000;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.75rem;
|
|
}
|
|
|
|
.toast.show {
|
|
transform: translateY(0);
|
|
opacity: 1;
|
|
}
|
|
|
|
/* Image hover */
|
|
.img-hover {
|
|
overflow: hidden;
|
|
border-radius: 0.75rem;
|
|
transition: transform 0.5s ease;
|
|
}
|
|
|
|
.img-hover:hover {
|
|
transform: scale(1.04);
|
|
}
|
|
|
|
.img-hover img {
|
|
transition: transform 0.6s ease;
|
|
}
|
|
|
|
.img-hover:hover img {
|
|
transform: scale(1.08);
|
|
}
|
|
|
|
/* Button hover */
|
|
.btn-primary {
|
|
background: var(--accent);
|
|
color: #fff;
|
|
transition: all 0.3s ease;
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.btn-primary::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0;
|
|
left: -100%;
|
|
width: 100%;
|
|
height: 100%;
|
|
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.15), transparent);
|
|
transition: left 0.5s ease;
|
|
}
|
|
|
|
.btn-primary:hover::before {
|
|
left: 100%;
|
|
}
|
|
|
|
.btn-primary:hover {
|
|
background: #8b5a28;
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 8px 25px rgba(168,114,56,0.3);
|
|
}
|
|
|
|
.btn-outline {
|
|
border: 1.5px solid var(--accent);
|
|
color: var(--accent);
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.btn-outline:hover {
|
|
background: var(--accent);
|
|
color: #fff;
|
|
transform: translateY(-2px);
|
|
}
|
|
|
|
/* Roast progress bar */
|
|
.roast-bar {
|
|
height: 6px;
|
|
border-radius: 3px;
|
|
background: #e8d5b8;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.roast-bar-fill {
|
|
height: 100%;
|
|
border-radius: 3px;
|
|
background: linear-gradient(90deg, #c9a96e, #a87238, #735830);
|
|
transition: width 1.5s ease;
|
|
}
|
|
|
|
/* Tasting note tag */
|
|
.note-tag {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 0.35rem;
|
|
padding: 0.35rem 0.85rem;
|
|
border-radius: 100px;
|
|
font-size: 0.8rem;
|
|
font-weight: 500;
|
|
border: 1px solid var(--border);
|
|
background: #fdf8f0;
|
|
color: var(--muted);
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.note-tag:hover {
|
|
border-color: var(--accent);
|
|
color: var(--accent);
|
|
background: rgba(168,114,56,0.04);
|
|
}
|
|
|
|
/* Section divider */
|
|
.section-divider {
|
|
width: 60px;
|
|
height: 2px;
|
|
background: linear-gradient(90deg, transparent, var(--accent), transparent);
|
|
}
|
|
|
|
/* Carousel */
|
|
.carousel-track {
|
|
display: flex;
|
|
transition: transform 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
|
}
|
|
|
|
.carousel-slide {
|
|
min-width: 100%;
|
|
flex-shrink: 0;
|
|
border-radius: 1.5rem;
|
|
overflow: hidden;
|
|
position: relative;
|
|
}
|
|
|
|
.carousel-slide img {
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: cover;
|
|
}
|
|
|
|
/* Cart button animation */
|
|
.cart-btn {
|
|
transition: transform 0.2s ease;
|
|
}
|
|
|
|
.cart-btn:hover {
|
|
transform: scale(1.15);
|
|
}
|
|
|
|
.cart-btn:active {
|
|
transform: scale(0.95);
|
|
}
|
|
|
|
/* Reduced motion */
|
|
@media (prefers-reduced-motion: reduce) {
|
|
*, *::before, *::after {
|
|
animation-duration: 0.01ms !important;
|
|
animation-iteration-count: 1 !important;
|
|
transition-duration: 0.01ms !important;
|
|
}
|
|
.reveal {
|
|
opacity: 1;
|
|
transform: none;
|
|
}
|
|
}
|
|
|
|
/* Focus visible for accessibility */
|
|
:focus-visible {
|
|
outline: 2px solid var(--accent);
|
|
outline-offset: 2px;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
/* Mobile nav */
|
|
.mobile-menu {
|
|
transform: translateX(100%);
|
|
transition: transform 0.3s ease;
|
|
}
|
|
|
|
.mobile-menu.open {
|
|
transform: translateX(0);
|
|
}
|
|
|
|
/* Typography line-height readability */
|
|
p, li { line-height: 1.75; }
|
|
|
|
/* Selection highlight */
|
|
::selection {
|
|
background: var(--accent);
|
|
color: #fff;
|
|
}
|
|
|
|
/* Horizontal scroll for hero image */
|
|
.scroll-hint {
|
|
animation: bounceDown 1.5s ease infinite;
|
|
}
|
|
|
|
@keyframes bounceDown {
|
|
0%, 100% { transform: translateY(0); }
|
|
50% { transform: translateY(6px); }
|
|
}
|
|
|
|
/* Loading shimmer */
|
|
@keyframes shimmer {
|
|
0% { background-position: -200% 0; }
|
|
100% { background-position: 200% 0; }
|
|
}
|
|
|
|
.shimmer {
|
|
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.4), transparent);
|
|
background-size: 200% 100%;
|
|
animation: shimmer 1.5s linear infinite;
|
|
}
|
|
|
|
/* Image overlay for text readability */
|
|
.img-overlay {
|
|
position: absolute;
|
|
inset: 0;
|
|
background: linear-gradient(to top, rgba(138,117,101,0.3) 0%, transparent 60%);
|
|
}
|
|
</style>
|
|
</head>
|
|
<body class="noise-overlay">
|
|
|
|
<!-- Toast Notification -->
|
|
<div id="toast" class="toast" role="alert" aria-live="polite">
|
|
<i class="fa-solid fa-check-circle text-terra-500 text-lg"></i>
|
|
<span id="toast-msg" class="text-sm font-medium text-bark-700">Added to cart</span>
|
|
</div>
|
|
|
|
<!-- Navigation -->
|
|
<nav id="navbar" class="fixed top-0 left-0 right-0 z-50 transition-all duration-500" role="navigation" aria-label="Main navigation">
|
|
<div class="max-w-7xl mx-auto px-6 py-4 flex items-center justify-between">
|
|
<a href="#" class="flex items-center gap-2.5 group" aria-label="Artisan Roast Co. Home">
|
|
<div class="w-9 h-9 rounded-full bg-terra-500 flex items-center justify-center transition-transform group-hover:scale-110 group-hover:bg-terra-600">
|
|
<i class="fa-solid fa-mug-hot text-white text-sm"></i>
|
|
</div>
|
|
<span class="font-display font-semibold text-lg text-bark-800">Artisan Roast</span>
|
|
</a>
|
|
<div class="hidden md:flex items-center gap-8">
|
|
<a href="#roasts" class="nav-link text-sm font-medium text-bark-600">Roasts</a>
|
|
<a href="#process" class="nav-link text-sm font-medium text-bark-600">Process</a>
|
|
<a href="#tastings" class="nav-link text-sm font-medium text-bark-600">Tastings</a>
|
|
<a href="#about" class="nav-link text-sm font-medium text-bark-600">About</a>
|
|
<a href="#contact" class="btn-primary px-5 py-2.5 rounded-full text-sm font-semibold text-white">Order Now</a>
|
|
</div>
|
|
<button id="menu-toggle" class="md:hidden w-10 h-10 flex items-center justify-center rounded-lg hover:bg-bark-50 transition-colors" aria-label="Toggle menu" aria-expanded="false">
|
|
<i class="fa-solid fa-bars text-bark-700 text-lg"></i>
|
|
</button>
|
|
</div>
|
|
<!-- Mobile Menu -->
|
|
<div id="mobile-menu" class="mobile-menu fixed inset-0 bg-bark-50/95 backdrop-blur-lg z-40 flex flex-col items-center justify-center gap-8">
|
|
<button id="menu-close" class="absolute top-5 right-5 w-10 h-10 flex items-center justify-center rounded-lg hover:bg-bark-100" aria-label="Close menu">
|
|
<i class="fa-solid fa-xmark text-bark-700 text-xl"></i>
|
|
</button>
|
|
<a href="#roasts" class="font-display text-2xl text-bark-800 hover:text-terra-500 transition-colors">Roasts</a>
|
|
<a href="#process" class="font-display text-2xl text-bark-800 hover:text-terra-500 transition-colors">Process</a>
|
|
<a href="#tastings" class="font-display text-2xl text-bark-800 hover:text-terra-500 transition-colors">Tastings</a>
|
|
<a href="#about" class="font-display text-2xl text-bark-800 hover:text-terra-500 transition-colors">About</a>
|
|
<a href="#contact" class="btn-primary px-8 py-3.5 rounded-full text-base font-semibold text-white mt-4">Order Now</a>
|
|
</div>
|
|
</nav>
|
|
|
|
<!-- Hero Section -->
|
|
<header class="relative min-h-screen flex items-center overflow-hidden" id="hero">
|
|
<!-- Background elements -->
|
|
<div class="absolute inset-0">
|
|
<!-- Hero image with gradient overlay -->
|
|
<img src="https://images.pexels.com/photos/276709/pexels-photo-276709.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2"
|
|
alt="Artisan coffee beans being roasted in a small batch"
|
|
class="w-full h-full object-cover"
|
|
id="hero-img">
|
|
<!-- Overlay gradient for text readability -->
|
|
<div class="absolute inset-0 bg-gradient-to-br from-bark-50/40 via-transparent to-bark-50/20"></div>
|
|
<!-- Glow blobs -->
|
|
<div class="hero-blob" style="width:500px;height:500px;background:#c9a96e;top:-100px;right:-100px;animation-delay:-2s;"></div>
|
|
<div class="hero-blob" style="width:350px;height:350px;background:#a87238;bottom:50px;left:-50px;animation-delay:-5s;"></div>
|
|
<!-- Floating particles -->
|
|
<div id="particles" class="absolute inset-0 pointer-events-none"></div>
|
|
</div>
|
|
|
|
<!-- Hero content -->
|
|
<div class="relative z-10 max-w-7xl mx-auto px-6 pt-20 pb-10 w-full">
|
|
<div class="grid lg:grid-cols-2 gap-12 lg:gap-16 items-center">
|
|
<!-- Left: Text -->
|
|
<div>
|
|
<div class="inline-flex items-center gap-2 px-4 py-2 rounded-full bg-terra-50 border border-terra-200 mb-6">
|
|
<span class="w-2 h-2 rounded-full bg-terra-500 animate-pulse"></span>
|
|
<span class="text-terra-600 text-sm font-medium">Small Batch, Big Soul</span>
|
|
</div>
|
|
<h1 class="font-display text-5xl md:text-6xl lg:text-7xl font-bold text-bark-900 leading-[1.05] mb-6">
|
|
Every Cup<br>
|
|
<span class="text-terra-500">Tells a Story</span>
|
|
</h1>
|
|
<p class="text-bark-500 text-lg leading-relaxed mb-8 max-w-lg">
|
|
We roast 200 pounds of specialty beans per week, hand-picked from high-altitude farms. Each roast is a deliberate art — crafted to highlight the unique character of each origin.
|
|
</p>
|
|
<div class="flex flex-wrap gap-4">
|
|
<a href="#roasts" class="btn-primary px-8 py-3.5 rounded-full text-base font-semibold text-white inline-flex items-center gap-2">
|
|
Explore the collection <i class="fa-solid fa-arrow-right text-sm"></i>
|
|
</a>
|
|
<a href="#process" class="btn-outline px-8 py-3.5 rounded-full text-base font-semibold inline-flex items-center gap-2">
|
|
<i class="fa-solid fa-play text-xs"></i> Meet the roasters
|
|
</a>
|
|
</div>
|
|
<div class="flex gap-6 mt-6">
|
|
<div class="flex items-center gap-2">
|
|
<i class="fa-solid fa-star text-terra-500"></i>
|
|
<span class="text-sm font-medium text-bark-700">4.9 / 5.0</span>
|
|
</div>
|
|
<div class="flex items-center gap-2">
|
|
<i class="fa-solid fa-clock text-bark-300"></i>
|
|
<span class="text-sm font-medium text-bark-700">Same Day Roast</span>
|
|
</div>
|
|
<div class="flex items-center gap-2">
|
|
<i class="fa-solid fa-truck text-bark-300"></i>
|
|
<span class="text-sm font-medium text-bark-700">Free Shipping</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- Right: Hero image -->
|
|
<div class="relative hidden lg:block">
|
|
<div class="relative">
|
|
<div class="img-hover rounded-2xl shadow-2xl shadow-bark-200/30">
|
|
<img src="https://images.pexels.com/photos/162435/pexels-photo-162435.jpeg?auto=compress&cs=tinysrgb&w=800&h=600&dpr=2"
|
|
alt="Premium artisan coffee beans on a marble slab"
|
|
class="w-full h-[560px] object-cover rounded-2xl"
|
|
loading="eager">
|
|
</div>
|
|
<!-- Floating badge -->
|
|
<div class="absolute -bottom-4 -left-4 bg-white/90 backdrop-blur-sm rounded-xl px-4 py-3 shadow-lg flex items-center gap-3">
|
|
<div class="w-10 h-10 rounded-full bg-terra-50 flex items-center justify-center">
|
|
<i class="fa-solid fa-tag text-terra-500"></i>
|
|
</div>
|
|
<div>
|
|
<div class="text-sm font-semibold text-bark-800">Single Origin</div>
|
|
<div class="text-xs text-bark-400">Ethiopian Yirgacheffe</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Scroll indicator -->
|
|
<div class="absolute bottom-8 left-1/2 -translate-x-1/2 scroll-hint">
|
|
<a href="#roasts" class="text-bark-400 hover:text-terra-500 transition-colors">
|
|
<i class="fa-solid fa-chevron-down text-sm"></i>
|
|
</a>
|
|
</div>
|
|
</header>
|
|
|
|
<!-- Roasts Section -->
|
|
<section id="roasts" class="relative py-24 bg-white">
|
|
<div class="max-w-7xl mx-auto px-6">
|
|
<div class="reveal text-center mb-16">
|
|
<span class="text-terra-500 text-sm font-semibold uppercase tracking-widest">The Collection</span>
|
|
<div class="section-divider mt-3 mx-auto"></div>
|
|
<h2 class="font-display text-4xl md:text-5xl font-bold text-bark-900 mt-3">Curated by Hand</h2>
|
|
<p class="text-bark-500 text-lg mt-4 max-w-2xl mx-auto">Every roast is a single-origin story. We test each blend three times before we release it to the world.</p>
|
|
</div>
|
|
|
|
<div class="grid md:grid-cols-3 gap-8">
|
|
<!-- Coffee #1 -->
|
|
<div class="reveal group bg-white border border-bark-100 rounded-2xl overflow-hidden hover:shadow-xl hover:shadow-bark-100/40 transition-all duration-500">
|
|
<div class="img-hover relative h-64">
|
|
<img src="https://images.pexels.com/photos/272645/pexels-photo-272645.jpeg?auto=compress&cs=tinysrgb&w=600&h=400&dpr=2"
|
|
alt="Ethiopian Yirgacheffe coffee beans"
|
|
class="w-full h-full object-cover" loading="lazy">
|
|
<div class="absolute top-4 left-4 px-3 py-1.5 rounded-full bg-terra-500 text-white text-xs font-semibold">Single Origin</div>
|
|
<div class="absolute bottom-4 right-4 px-3 py-1.5 rounded-full bg-white/90 backdrop-blur-sm text-bark-700 text-xs font-medium">Medium Roast</div>
|
|
</div>
|
|
<div class="p-6">
|
|
<h3 class="font-display text-xl font-semibold text-bark-800 mb-2">Ethiopian Yirgacheffe</h3>
|
|
<p class="text-bark-500 text-sm leading-relaxed mb-4">Bright acidity with hints of bergamot, jasmine, and a floral sweetness that lingers on the palate. The hallmark of a high-altitude Ethiopian farm.</p>
|
|
<div class="flex items-center justify-between">
|
|
<div class="flex items-center gap-2">
|
|
<i class="fa-solid fa-star text-terra-400 text-xs"></i>
|
|
<span class="text-sm font-medium text-bark-700">4.8 / 5.0</span>
|
|
</div>
|
|
<span class="text-bark-400 text-sm">$22</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Coffee #2 -->
|
|
<div class="reveal group bg-white border border-bark-100 rounded-2xl overflow-hidden hover:shadow-xl hover:shadow-bark-100/40 transition-all duration-500">
|
|
<div class="img-hover relative h-64">
|
|
<img src="https://images.pexels.com/photos/413953/pexels-photo-413953.jpeg?auto=compress&cs=tinysrgb&w=600&h=400&dpr=2"
|
|
alt="Panamanian Geisha coffee beans"
|
|
class="w-full h-full object-cover" loading="lazy">
|
|
<div class="absolute top-4 left-4 px-3 py-1.5 rounded-full bg-terra-500 text-white text-xs font-semibold">Single Origin</div>
|
|
<div class="absolute bottom-4 right-4 px-3 py-1.5 rounded-full bg-white/90 backdrop-blur-sm text-bark-700 text-xs font-medium">Light Roast</div>
|
|
</div>
|
|
<div class="p-6">
|
|
<h3 class="font-display text-xl font-semibold text-bark-800 mb-2">Panamanian Geisha</h3>
|
|
<p class="text-bark-500 text-sm leading-relaxed mb-4">Lavender, bergamot, and a complex bouquet of stone fruits. A legendary cupping profile that commands its price — worth every ounce of attention.</p>
|
|
<div class="flex items-center justify-between">
|
|
<div class="flex items-center gap-2">
|
|
<i class="fa-solid fa-star text-terra-400 text-xs"></i>
|
|
<span class="text-sm font-medium text-bark-700">4.9 / 5.0</span>
|
|
</div>
|
|
<span class="text-bark-400 text-sm">$38</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Coffee #3 -->
|
|
<div class="reveal group bg-white border border-bark-100 rounded-2xl overflow-hidden hover:shadow-xl hover:shadow-bark-100/40 transition-all duration-500">
|
|
<div class="img-hover relative h-64">
|
|
<img src="https://images.pexels.com/photos/355756/pexels-photo-355756.jpeg?auto=compress&cs=tinysrgb&w=600&h=400&dpr=2"
|
|
alt="Colombian Huila coffee beans"
|
|
class="w-full h-full object-cover" loading="lazy">
|
|
<div class="absolute top-4 left-4 px-3 py-1.5 rounded-full bg-terra-500 text-white text-xs font-semibold">Single Origin</div>
|
|
<div class="absolute bottom-4 right-4 px-3 py-1.5 rounded-full bg-white/90 backdrop-blur-sm text-bark-700 text-xs font-medium">Dark Roast</div>
|
|
</div>
|
|
<div class="p-6">
|
|
<h3 class="font-display text-xl font-semibold text-bark-800 mb-2">Colombian Huila</h3>
|
|
<p class="text-bark-500 text-sm leading-relaxed mb-4">Rich chocolate and a caramel finish. Deep, smooth, and incredibly approachable. The everyday champion that deserves a place in every home.</p>
|
|
<div class="flex items-center justify-between">
|
|
<div class="flex items-center gap-2">
|
|
<i class="fa-solid fa-star text-terra-400 text-xs"></i>
|
|
<span class="text-sm font-medium text-bark-700">4.7 / 5.0</span>
|
|
</div>
|
|
<span class="text-bark-400 text-sm">$18</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Process Section -->
|
|
<section id="process" class="relative py-24 bg-bark-900 overflow-hidden">
|
|
<div class="absolute inset-0 opacity-10">
|
|
<div class="absolute top-0 left-0 w-64 h-64 bg-terra-500 rounded-full blur-2xl"></div>
|
|
<div class="absolute bottom-0 right-0 w-64 h-64 bg-terra-400 rounded-full blur-2xl"></div>
|
|
<div class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[400px] h-[400px] border border-terra-700/30"></div>
|
|
</div>
|
|
<div class="relative z-10 max-w-7xl mx-auto px-6">
|
|
<div class="reveal text-center mb-16">
|
|
<span class="text-terra-400 text-sm font-semibold uppercase tracking-widest">Our Craft</span>
|
|
<div class="section-divider mt-3 mx-auto"></div>
|
|
<h2 class="font-display text-4xl md:text-5xl font-bold text-white mt-3">From Bean to Cup</h2>
|
|
<p class="text-bark-300 text-lg mt-4 max-w-2xl mx-auto">Every step is intentional. We roast with the same care we bring to choosing each bean.</p>
|
|
</div>
|
|
|
|
<div class="grid md:grid-cols-4 gap-8">
|
|
<div class="reveal text-center group">
|
|
<div class="w-20 h-20 mx-auto rounded-2xl bg-terra-500/10 flex items-center justify-center mb-6 transition-all group-hover:bg-terra-500/20 group-hover:scale-110">
|
|
<i class="fa-solid fa-seedling text-terra-400 text-2xl"></i>
|
|
</div>
|
|
<h4 class="font-display text-xl font-semibold text-white mb-2">Source</h4>
|
|
<p class="text-bark-400 text-sm leading-relaxed">Farm-to-roaster traceability. Every lot has a provenance, a harvest date, and a farmer we know.</p>
|
|
</div>
|
|
<div class="reveal text-center group">
|
|
<div class="w-20 h-20 mx-auto rounded-2xl bg-terra-500/10 flex items-center justify-center mb-6 transition-all group-hover:bg-terra-500/20 group-hover:scale-110">
|
|
<i class="fa-solid fa-fire text-terra-400 text-2xl"></i>
|
|
</div>
|
|
<h4 class="font-display text-xl font-semibold text-white mb-2">Roast</h4>
|
|
<p class="text-bark-400 text-sm leading-relaxed">Controlled temperature, 3-point taste tests. We aim for a "perfect bite" — not just a roast profile, but a cup you can taste again.</p>
|
|
</div>
|
|
<div class="reveal text-center group">
|
|
<div class="w-20 h-20 mx-auto rounded-2xl bg-terra-500/10 flex items-center justify-center mb-6 transition-all group-hover:bg-terra-500/20 group-hover:scale-110">
|
|
<i class="fa-solid fa-box-open text-terra-400 text-2xl"></i>
|
|
</div>
|
|
<h4 class="font-display text-xl font-semibold text-white mb-2">Pack</h4>
|
|
<p class="text-bark-400 text-sm leading-relaxed">Individually sealed, labeled, and delivered. Each bag is sealed for 2 weeks, so you always taste the day's roast.</p>
|
|
</div>
|
|
<div class="reveal text-center group">
|
|
<div class="w-20 h-20 mx-auto rounded-2xl bg-terra-500/10 flex items-center justify-center mb-6 transition-all group-hover:bg-terra-500/20 group-hover:scale-110">
|
|
<i class="fa-solid fa-heart text-terra-400 text-2xl"></i>
|
|
</div>
|
|
<h4 class="font-display text-xl font-semibold text-white mb-2">Grind</h4>
|
|
<p class="text-bark-400 text-sm leading-relaxed">Whole bean, fresh grind, just before you brew. No compromise — the moment between roast and cup is everything.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Tastings Section -->
|
|
<section id="tastings" class="relative py-24 bg-white">
|
|
<div class="max-w-7xl mx-auto px-6">
|
|
<div class="reveal text-center mb-16">
|
|
<span class="text-terra-500 text-sm font-semibold uppercase tracking-widest">Experience</span>
|
|
<div class="section-divider mt-3 mx-auto"></div>
|
|
<h2 class="font-display text-4xl md:text-5xl font-bold text-bark-900 mt-3">Taste & Discover</h2>
|
|
<p class="text-bark-500 text-lg mt-4 max-w-2xl mx-auto">Join a tasting session. Learn how to identify flavor notes, roast levels, and the story behind every cup.</p>
|
|
</div>
|
|
|
|
<!-- Tasting carousel -->
|
|
<div class="reveal">
|
|
<div class="relative max-w-4xl mx-auto">
|
|
<div class="overflow-hidden rounded-2xl">
|
|
<div id="carousel" class="carousel-track">
|
|
<!-- Slide 1 -->
|
|
<div class="carousel-slide relative h-80">
|
|
<img src="https://images.pexels.com/photos/3292370/pexels-photo-3292370.jpeg?auto=compress&cs=tinysrgb&w=600&h=500&dpr=2" alt="Coffee tasting session" class="w-full h-full object-cover" loading="lazy">
|
|
<div class="absolute inset-0 bg-gradient-to-t from-bark-900/80 via-bark-900/30 to-transparent"></div>
|
|
<div class="absolute bottom-0 left-0 right-0 p-6">
|
|
<div class="flex items-center gap-3 mb-3">
|
|
<span class="note-tag"><i class="fa-solid fa-cup text-terra-400"></i> Classic</span>
|
|
<span class="note-tag"><i class="fa-solid fa-lightbulb text-bark-400"></i> Bright</span>
|
|
</div>
|
|
<h3 class="font-display text-2xl font-semibold text-white">Ethiopian Yirgacheffe</h3>
|
|
<p class="text-bark-200 mt-1">Citrus, bergamot, and floral notes — a cup that unfolds slowly.</p>
|
|
</div>
|
|
</div>
|
|
<!-- Slide 2 -->
|
|
<div class="carousel-slide relative h-80">
|
|
<img src="https://images.pexels.com/photos/3087630/pexels-photo-3087630.jpeg?auto=compress&cs=tinysrgb&w=600&h=500&dpr=2" alt="Coffee tasting session" class="w-full h-full object-cover" loading="lazy">
|
|
<div class="absolute inset-0 bg-gradient-to-t from-bark-900/80 via-bark-900/30 to-transparent"></div>
|
|
<div class="absolute bottom-0 left-0 right-0 p-6">
|
|
<div class="flex items-center gap-3 mb-3">
|
|
<span class="note-tag"><i class="fa-solid fa-cup text-terra-400"></i> Classic</span>
|
|
<span class="note-tag"><i class="fa-solid fa-lightbulb text-bark-400"></i> Smooth</span>
|
|
</div>
|
|
<h3 class="font-display text-2xl font-semibold text-white">Colombian Huila</h3>
|
|
<p class="text-bark-200 mt-1">Rich chocolate and caramel finish — the everyday hero.</p>
|
|
</div>
|
|
</div>
|
|
<!-- Slide 3 -->
|
|
<div class="carousel-slide relative h-80">
|
|
<img src="https://images.pexels.com/photos/3170454/pexels-photo-3170454.jpeg?auto=compress&cs=tinysrgb&w=600&h=500&dpr=2" alt="Coffee tasting session" class="w-full h-full object-cover" loading="lazy">
|
|
<div class="absolute inset-0 bg-gradient-to-t from-bark-900/80 via-bark-900/30 to-transparent"></div>
|
|
<div class="absolute bottom-0 left-0 right-0 p-6">
|
|
<div class="flex items-center gap-3 mb-3">
|
|
<span class="note-tag"><i class="fa-solid fa-cup text-terra-400"></i> Classic</span>
|
|
<span class="note-tag"><i class="fa-solid fa-lightbulb text-bark-400"></i> Floral</span>
|
|
</div>
|
|
<h3 class="font-display text-2xl font-semibold text-white">Panamanian Geisha</h3>
|
|
<p class="text-bark-200 mt-1">Lavender, bergamot, stone fruits — the most complex profile we offer.</p>
|
|
</div>
|
|
</div>
|
|
<!-- Slide 4 -->
|
|
<div class="carousel-slide relative h-80">
|
|
<img src="https://images.pexels.com/photos/3122905/pexels-photo-3122905.jpeg?auto=compress&cs=tinysrgb&w=600&h=500&dpr=2" alt="Coffee tasting session" class="w-full h-full object-cover" loading="lazy">
|
|
<div class="absolute inset-0 bg-gradient-to-t from-bark-900/80 via-bark-900/30 to-transparent"></div>
|
|
<div class="absolute bottom-0 left-0 right-0 p-6">
|
|
<div class="flex items-center gap-3 mb-3">
|
|
<span class="note-tag"><i class="fa-solid fa-cup text-terra-400"></i> Classic</span>
|
|
<span class="note-tag"><i class="fa-solid fa-lightbulb text-bark-400"></i> Deep</span>
|
|
</div>
|
|
<h3 class="font-display text-2xl font-semibold text-white">Sumatran Mandheling</h3>
|
|
<p class="text-bark-200 mt-1">Earthy, spicy, and creamy — a full-bodied experience for the bold palate.</p>
|
|
</div>
|
|
</div>
|
|
<!-- Slide 5 -->
|
|
<div class="carousel-slide relative h-80">
|
|
<img src="https://images.pexels.com/photos/2991339/pexels-photo-2991339.jpeg?auto=compress&cs=tinysrgb&w=600&h=500&dpr=2" alt="Coffee tasting session" class="w-full h-full object-cover" loading="lazy">
|
|
<div class="absolute inset-0 bg-gradient-to-t from-bark-900/80 via-bark-900/30 to-transparent"></div>
|
|
<div class="absolute bottom-0 left-0 right-0 p-6">
|
|
<div class="flex items-center gap-3 mb-3">
|
|
<span class="note-tag"><i class="fa-solid fa-cup text-terra-400"></i> Classic</span>
|
|
<span class="note-tag"><i class="fa-solid fa-lightbulb text-bark-400"></i> Balanced</span>
|
|
</div>
|
|
<h3 class="font-display text-2xl font-semibold text-white">Guatemalan Antigua</h3>
|
|
<p class="text-bark-200 mt-1">Melodic, complex, and gently smoky — a cup for the curious.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Carousel controls -->
|
|
<div class="flex items-center justify-center gap-4 mt-6">
|
|
<button id="carousel-prev" class="w-10 h-10 rounded-full border border-bark-200 flex items-center justify-center text-bark-500 hover:bg-bark-50 hover:border-bark-500 hover:text-bark-700 transition-colors" aria-label="Previous slide">
|
|
<i class="fa-solid fa-arrow-left text-sm"></i>
|
|
</button>
|
|
<div id="carousel-dots" class="flex gap-2" role="tablist" aria-label="Carousel slides"></div>
|
|
<button id="carousel-next" class="w-10 h-10 rounded-full border border-bark-200 flex items-center justify-center text-bark-500 hover:bg-bark-50 hover:border-bark-500 hover:text-bark-700 transition-colors" aria-label="Next slide">
|
|
<i class="fa-solid fa-arrow-right text-sm"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- About Section -->
|
|
<section id="about" class="relative py-24 bg-bark-900 overflow-hidden">
|
|
<div class="absolute inset-0 opacity-5">
|
|
<img src="https://images.pexels.com/photos/3292370/pexels-photo-3292370.jpeg?auto=compress&cs=tinysrgb&w=600&h=500&dpr=2" alt="Coffee beans" class="w-full h-full object-cover" loading="lazy">
|
|
</div>
|
|
<div class="relative z-10 max-w-7xl mx-auto px-6">
|
|
<div class="reveal grid md:grid-cols-2 gap-16 items-center">
|
|
<div>
|
|
<span class="text-terra-400 text-sm font-semibold uppercase tracking-widest">Who We Are</span>
|
|
<h2 class="font-display text-4xl md:text-5xl font-bold text-white mt-3 mb-6">Three Generations of Roasters</h2>
|
|
<p class="text-bark-300 text-lg leading-relaxed mb-6">
|
|
Founded in 2015, Artisan Roast Co. started as a dream of three friends who believed coffee deserved the same reverence as wine or craft beer. Over 15 years, we've built a team of 18 skilled roasters, 120 independent farms, and a community that's as passionate about beans as we are.
|
|
</p>
|
|
<p class="text-bark-300 text-lg leading-relaxed mb-8">
|
|
We roast in our 350 sq ft facility in Portland, Oregon, with a small batch process that yields 200 pounds of specialty coffee every week. Every bag is a single story — from the farm to your cup.
|
|
</p>
|
|
<div class="flex gap-4">
|
|
<a href="#" class="btn-outline px-6 py-3 rounded-full text-sm font-semibold">Our Story</a>
|
|
<a href="#" class="btn-outline px-6 py-3 rounded-full text-sm font-semibold">Farm Visits</a>
|
|
</div>
|
|
</div>
|
|
<div class="grid grid-cols-2 gap-6">
|
|
<div class="reveal rounded-2xl overflow-hidden">
|
|
<img src="https://images.pexels.com/photos/1555502/pexels-photo-1555502.jpeg?auto=compress&cs=tinysrgb&w=600&h=400&dpr=2" alt="Coffee roaster facility" class="w-full h-64 object-cover" loading="lazy">
|
|
</div>
|
|
<div class="reveal rounded-2xl overflow-hidden">
|
|
<img src="https://images.pexels.com/photos/1537753/pexels-photo-1537753.jpeg?auto=compress&cs=tinysrgb&w=600&h=400&dpr=2" alt="Coffee brewing session" class="w-full h-64 object-cover" loading="lazy">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Contact / CTA Section -->
|
|
<section id="contact" class="relative py-24 bg-white">
|
|
<div class="max-w-7xl mx-auto px-6">
|
|
<div class="reveal text-center mb-16">
|
|
<span class="text-terra-500 text-sm font-semibold uppercase tracking-widest">Get Started</span>
|
|
<div class="section-divider mt-3 mx-auto"></div>
|
|
<h2 class="font-display text-4xl md:text-5xl font-bold text-bark-900 mt-3">Order a Fresh Batch</h2>
|
|
<p class="text-bark-500 text-lg mt-4 max-w-2xl mx-auto">Subscribe to our newsletter and receive a 15% discount on your first order, plus monthly tasting notes and new release alerts.</p>
|
|
</div>
|
|
|
|
<div class="grid md:grid-cols-3 gap-8">
|
|
<!-- Form -->
|
|
<div class="reveal bg-white border border-bark-100 rounded-2xl p-8 hover:shadow-xl hover:shadow-bark-100/30 transition-shadow">
|
|
<form id="form" class="space-y-5" novalidate>
|
|
<div>
|
|
<label for="name" class="block text-sm font-medium text-bark-700 mb-1.5">Name</label>
|
|
<input id="name" type="text" placeholder="Your name" required
|
|
class="w-full px-4 py-3 rounded-xl border border-bark-200 bg-bark-50 focus:outline-none focus:ring-2 focus:ring-terra-400 focus:border-transparent transition-all text-bark-700 placeholder:text-bark-300"
|
|
aria-required="true">
|
|
<p id="name-error" class="text-red-500 text-xs mt-1 hidden" role="alert">Please enter your name.</p>
|
|
</div>
|
|
<div>
|
|
<label for="email" class="block text-sm font-medium text-bark-700 mb-1.5">Email</label>
|
|
<input id="email" type="email" placeholder="your@email.com" required
|
|
class="w-full px-4 py-3 rounded-xl border border-bark-200 bg-bark-50 focus:outline-none focus:ring-2 focus:ring-terra-400 focus:border-transparent transition-all text-bark-700 placeholder:text-bark-300"
|
|
aria-required="true">
|
|
<p id="email-error" class="text-red-500 text-xs mt-1 hidden" role="alert">Please enter a valid email.</p>
|
|
</div>
|
|
<div>
|
|
<label for="message" class="block text-sm font-medium text-bark-700 mb-1.5">Message</label>
|
|
<textarea id="message" rows="3" placeholder="Tell us what you're looking for..."
|
|
class="w-full px-4 py-3 rounded-xl border border-bark-200 bg-bark-50 focus:outline-none focus:ring-2 focus:ring-terra-400 focus:border-transparent transition-all text-bark-700 placeholder:text-bark-300 resize-none"></textarea>
|
|
</div>
|
|
<button type="submit" class="btn-primary w-full py-3.5 rounded-full text-base font-semibold text-white">
|
|
Get Started
|
|
</button>
|
|
</form>
|
|
</div>
|
|
|
|
<!-- Quick info -->
|
|
<div class="reveal space-y-6">
|
|
<div class="flex items-start gap-4">
|
|
<div class="w-12 h-12 rounded-xl bg-terra-500/10 flex items-center justify-center flex-shrink-0">
|
|
<i class="fa-solid fa-clock text-terra-500 text-lg"></i>
|
|
</div>
|
|
<div>
|
|
<h4 class="font-display text-base font-semibold text-bark-800 mb-1">Roasted Daily</h4>
|
|
<p class="text-bark-500 text-sm leading-relaxed">Each day's roast is a new story. We ship the same day to keep your cup at peak freshness.</p>
|
|
</div>
|
|
</div>
|
|
<div class="flex items-start gap-4">
|
|
<div class="w-12 h-12 rounded-xl bg-terra-500/10 flex items-center justify-center flex-shrink-0">
|
|
<i class="fa-solid fa-truck text-terra-500 text-lg"></i>
|
|
</div>
|
|
<div>
|
|
<h4 class="font-display text-base font-semibold text-bark-800 mb-1">Free Shipping</h4>
|
|
<p class="text-bark-500 text-sm leading-relaxed">$35 orders get free shipping. No minimum — just taste the difference of a fresh roast.</p>
|
|
</div>
|
|
</div>
|
|
<div class="flex items-start gap-4">
|
|
<div class="w-12 h-12 rounded-xl bg-terra-500/10 flex items-center justify-center flex-shrink-0">
|
|
<i class="fa-solid fa-shield-halved text-terra-500 text-lg"></i>
|
|
</div>
|
|
<div>
|
|
<h4 class="font-display text-base font-semibold text-bark-800 mb-1">100% Satisfaction</h4>
|
|
<p class="text-bark-500 text-sm leading-relaxed">We stand behind every roast. If you're not 100% in love with it, we'll make it right.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Stats -->
|
|
<div class="reveal flex flex-col justify-center">
|
|
<div class="grid grid-cols-3 gap-4">
|
|
<div class="text-center">
|
|
<div class="font-display text-3xl font-bold text-terra-500">200+</div>
|
|
<div class="text-bark-400 text-sm">lbs/week</div>
|
|
</div>
|
|
<div class="text-center">
|
|
<div class="font-display text-3xl font-bold text-terra-500">120</div>
|
|
<div class="text-bark-400 text-sm">farms</div>
|
|
</div>
|
|
<div class="text-center">
|
|
<div class="font-display text-3xl font-bold text-terra-500">18</div>
|
|
<div class="text-bark-400 text-sm">roasters</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Footer -->
|
|
<footer class="bg-bark-900 text-bark-300 pt-16 pb-8">
|
|
<div class="max-w-7xl mx-auto px-6">
|
|
<div class="grid md:grid-cols-4 gap-12 mb-12">
|
|
<div>
|
|
<div class="flex items-center gap-2.5 mb-4">
|
|
<div class="w-8 h-8 rounded-full bg-terra-500 flex items-center justify-center">
|
|
<i class="fa-solid fa-mug-hot text-white text-xs"></i>
|
|
</div>
|
|
<span class="font-display font-semibold text-white">Artisan Roast Co.</span>
|
|
</div>
|
|
<p class="text-bark-400 text-sm leading-relaxed">Crafting exceptional coffee, one batch at a time. Since 2015.</p>
|
|
</div>
|
|
<div>
|
|
<h4 class="text-white font-semibold text-sm mb-4">Shop</h4>
|
|
<ul class="space-y-2">
|
|
<li><a href="#roasts" class="text-bark-400 hover:text-terra-400 transition-colors text-sm">All Roasts</a></li>
|
|
<li><a href="#" class="text-bark-400 hover:text-terra-400 transition-colors text-sm">Subscriptions</a></li>
|
|
<li><a href="#" class="text-bark-400 hover:text-terra-400 transition-colors text-sm">Gift Cards</a></li>
|
|
<li><a href="#" class="text-bark-400 hover:text-terra-400 transition-colors text-sm">New Arrivals</a></li>
|
|
</ul>
|
|
</div>
|
|
<div>
|
|
<h4 class="text-white font-semibold text-sm mb-4">Community</h4>
|
|
<ul class="space-y-2">
|
|
<li><a href="#" class="text-bark-400 hover:text-terra-400 transition-colors text-sm">Farm Visits</a></li>
|
|
<li><a href="#" class="text-bark-400 hover:text-terra-400 transition-colors text-sm">Tasting Notes</a></li>
|
|
<li><a href="#" class="text-bark-400 hover:text-terra-400 transition-colors text-sm">Blog</a></li>
|
|
<li><a href="#" class="text-bark-400 hover:text-terra-400 transition-colors text-sm">Events</a></li>
|
|
</ul>
|
|
</div>
|
|
<div>
|
|
<h4 class="text-white font-semibold text-sm mb-4">Stay Updated</h4>
|
|
<p class="text-bark-400 text-sm mb-4">Get monthly tasting notes and early access to new blends.</p>
|
|
<form id="newsletter-form" class="flex gap-2">
|
|
<input id="email-input" type="email" placeholder="your@email.com" required
|
|
class="flex-1 px-4 py-2.5 rounded-xl bg-bark-800 border border-bark-700 text-bark-100 text-sm placeholder:text-bark-500 focus:outline-none focus:ring-2 focus:ring-terra-500 focus:border-transparent"
|
|
aria-required="true">
|
|
<button type="submit" class="px-4 py-2.5 rounded-xl bg-terra-500 text-white text-sm font-semibold hover:bg-terra-600 transition-colors flex-shrink-0">
|
|
<i class="fa-solid fa-paper-plane"></i>
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<div class="border-t border-bark-800 pt-8 flex flex-col md:flex-row items-center justify-between gap-4">
|
|
<p class="text-bark-500 text-xs">2025 Artisan Roast Co. All rights reserved.</p>
|
|
<div class="flex gap-4">
|
|
<a href="#" class="text-bark-500 hover:text-terra-400 transition-colors" aria-label="Twitter"><i class="fa-brands fa-x-twitter text-lg"></i></a>
|
|
<a href="#" class="text-bark-500 hover:text-terra-400 transition-colors" aria-label="Instagram"><i class="fa-brands fa-instagram text-lg"></i></a>
|
|
<a href="#" class="text-bark-500 hover:text-terra-400 transition-colors" aria-label="Facebook"><i class="fa-brands fa-facebook-f text-lg"></i></a>
|
|
<a href="#" class="text-bark-500 hover:text-terra-400 transition-colors" aria-label="YouTube"><i class="fa-brands fa-youtube text-lg"></i></a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</footer>
|
|
|
|
<script>
|
|
// ── Utility functions ──
|
|
|
|
// Toast notification system
|
|
const toast = document.getElementById('toast');
|
|
const toastMsg = document.getElementById('toast-msg');
|
|
let toastTimeout;
|
|
|
|
function showToast(msg) {
|
|
toastMsg.textContent = msg;
|
|
toast.classList.add('show');
|
|
clearTimeout(toastTimeout);
|
|
toastTimeout = setTimeout(() => toast.classList.remove('show'), 3000);
|
|
}
|
|
|
|
function showToastError(msg) {
|
|
toastMsg.textContent = msg;
|
|
toast.classList.add('show');
|
|
clearTimeout(toastTimeout);
|
|
toastTimeout = setTimeout(() => toast.classList.remove('show'), 3000);
|
|
}
|
|
|
|
// ── Form validation ──
|
|
document.getElementById('form').addEventListener('submit', function(e) {
|
|
e.preventDefault();
|
|
const nameInput = document.getElementById('name');
|
|
const emailInput = document.getElementById('email');
|
|
const nameError = document.getElementById('name-error');
|
|
const emailError = document.getElementById('email-error');
|
|
|
|
// Clear previous errors
|
|
nameError.classList.add('hidden');
|
|
emailError.classList.add('hidden');
|
|
|
|
let valid = true;
|
|
|
|
if (!nameInput.value.trim()) {
|
|
nameError.classList.remove('hidden');
|
|
valid = false;
|
|
}
|
|
|
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
if (!emailInput.value.trim() || !emailRegex.test(emailInput.value)) {
|
|
emailError.classList.remove('hidden');
|
|
valid = false;
|
|
}
|
|
|
|
if (valid) {
|
|
showToast('Thank you! We\'ll be in touch shortly.');
|
|
nameInput.value = '';
|
|
emailInput.value = '';
|
|
document.getElementById('message').value = '';
|
|
} else {
|
|
showToastError('Please correct the errors above.');
|
|
}
|
|
});
|
|
|
|
// Newsletter form
|
|
document.getElementById('newsletter-form').addEventListener('submit', function(e) {
|
|
e.preventDefault();
|
|
const emailInput = document.getElementById('email-input');
|
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
if (!emailInput.value.trim() || !emailRegex.test(emailInput.value)) {
|
|
showToastError('Please enter a valid email address.');
|
|
return;
|
|
}
|
|
showToast('Subscribed! Welcome to the community.');
|
|
emailInput.value = '';
|
|
});
|
|
|
|
// ── Mobile menu toggle ──
|
|
const menuToggle = document.getElementById('menu-toggle');
|
|
const mobileMenu = document.getElementById('mobile-menu');
|
|
const menuClose = document.getElementById('menu-close');
|
|
|
|
function openMobileMenu() {
|
|
mobileMenu.classList.add('open');
|
|
menuToggle.setAttribute('aria-expanded', 'true');
|
|
document.body.style.overflow = 'hidden';
|
|
}
|
|
|
|
function closeMobileMenu() {
|
|
mobileMenu.classList.remove('open');
|
|
menuToggle.setAttribute('aria-expanded', 'false');
|
|
document.body.style.overflow = '';
|
|
}
|
|
|
|
menuToggle.addEventListener('click', openMobileMenu);
|
|
menuClose.addEventListener('click', closeMobileMenu);
|
|
|
|
// Close mobile menu when a nav link is clicked
|
|
mobileMenu.querySelectorAll('a').forEach(link => {
|
|
link.addEventListener('click', closeMobileMenu);
|
|
});
|
|
|
|
// ── Scroll reveal ──
|
|
const revealObserver = new IntersectionObserver((entries) => {
|
|
entries.forEach(entry => {
|
|
if (entry.isIntersecting) {
|
|
entry.target.classList.add('visible');
|
|
}
|
|
});
|
|
}, { threshold: 0.1, rootMargin: '0px 0px -50px 0px' });
|
|
|
|
document.querySelectorAll('.reveal').forEach(el => revealObserver.observe(el));
|
|
|
|
// ── Navbar scroll effect ──
|
|
const navbar = document.getElementById('navbar');
|
|
|
|
window.addEventListener('scroll', () => {
|
|
if (window.scrollY > 50) {
|
|
navbar.style.background = 'rgba(253, 248, 240, 0.92)';
|
|
navbar.style.backdropFilter = 'blur(12px)';
|
|
navbar.style.boxShadow = '0 1px 20px rgba(0,0,0,0.06)';
|
|
navbar.style.borderBottom = '1px solid #e8d5b8';
|
|
} else {
|
|
navbar.style.background = 'transparent';
|
|
navbar.style.backdropFilter = 'none';
|
|
navbar.style.boxShadow = 'none';
|
|
navbar.style.borderBottom = '1px solid transparent';
|
|
}
|
|
});
|
|
|
|
// ── Image hover parallax ──
|
|
document.querySelectorAll('.img-hover').forEach(el => {
|
|
el.addEventListener('mousemove', (e) => {
|
|
const rect = el.getBoundingClientRect();
|
|
const x = (e.clientX - rect.left) / rect.width - 0.5;
|
|
const y = (e.clientY - rect.top) / rect.height - 0.5;
|
|
el.style.transform = `translate(${x * -12}px, ${y * -12}px)`;
|
|
});
|
|
el.addEventListener('mouseleave', () => {
|
|
el.style.transform = 'translate(0, 0)';
|
|
});
|
|
});
|
|
|
|
// ── Carousel ──
|
|
const carousel = document.getElementById('carousel');
|
|
const track = carousel.querySelector('.carousel-track');
|
|
const slides = track.querySelectorAll('.carousel-slide');
|
|
const prevBtn = document.getElementById('carousel-prev');
|
|
const nextBtn = document.getElementById('carousel-next');
|
|
const dotsContainer = document.getElementById('carousel-dots');
|
|
|
|
let currentSlide = 0;
|
|
const totalSlides = slides.length;
|
|
|
|
function updateDots() {
|
|
dotsContainer.innerHTML = '';
|
|
for (let i = 0; i < totalSlides; i++) {
|
|
const dot = document.createElement('button');
|
|
dot.className = 'w-2.5 h-2.5 rounded-full transition-all cursor-pointer ' +
|
|
(i === currentSlide ? 'bg-terra-500 scale-125' : 'bg-bark-200 hover:bg-bark-300');
|
|
dot.setAttribute('aria-label', `Go to slide ${i + 1}`);
|
|
dot.setAttribute('role', 'tab');
|
|
dot.addEventListener('click', () => goToSlide(i));
|
|
dotsContainer.appendChild(dot);
|
|
}
|
|
}
|
|
|
|
function goToSlide(index) {
|
|
currentSlide = index;
|
|
track.style.transform = `translateX(-${currentSlide * 100}%)`;
|
|
updateDots();
|
|
}
|
|
|
|
prevBtn.addEventListener('click', () => {
|
|
currentSlide = (currentSlide > 0) ? currentSlide - 1 : totalSlides - 1;
|
|
track.style.transform = `translateX(-${currentSlide * 100}%)`;
|
|
updateDots();
|
|
});
|
|
|
|
nextBtn.addEventListener('click', () => {
|
|
currentSlide = (currentSlide < totalSlides - 1) ? currentSlide + 1 : 0;
|
|
track.style.transform = `translateX(-${currentSlide * 100}%)`;
|
|
updateDots();
|
|
});
|
|
|
|
updateDots();
|
|
|
|
// ── Hero floating particles ──
|
|
function createParticles() {
|
|
const container = document.getElementById('particles');
|
|
const colors = ['#a87238', '#c9a96e', '#c49a6c', '#d4b896', '#e8d5b8', '#8b5a28', '#9a6335'];
|
|
|
|
for (let i = 0; i < 18; i++) {
|
|
const particle = document.createElement('div');
|
|
particle.className = 'particle';
|
|
const size = Math.random() * 4 + 2;
|
|
particle.style.width = size + 'px';
|
|
particle.style.height = size + 'px';
|
|
particle.style.left = Math.random() * 100 + '%';
|
|
particle.style.bottom = '0';
|
|
particle.style.background = colors[Math.floor(Math.random() * colors.length)];
|
|
particle.style.animationDelay = Math.random() * 8 + 's';
|
|
particle.style.animationDuration = Math.random() * 10 + 6 + 's';
|
|
container.appendChild(particle);
|
|
}
|
|
}
|
|
|
|
createParticles();
|
|
|
|
// ── Smooth scroll for anchor links ──
|
|
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
|
anchor.addEventListener('click', function(e) {
|
|
e.preventDefault();
|
|
const target = document.querySelector(this.getAttribute('href'));
|
|
if (target) {
|
|
target.scrollIntoView({ behavior: 'smooth' });
|
|
}
|
|
});
|
|
});
|
|
|
|
// ── Keyboard accessibility for carousel dots ──
|
|
dotsContainer.addEventListener('keydown', (e) => {
|
|
if (e.key === 'ArrowLeft') {
|
|
e.preventDefault();
|
|
goToSlide((currentSlide - 1 + totalSlides) % totalSlides);
|
|
}
|
|
if (e.key === 'ArrowRight') {
|
|
e.preventDefault();
|
|
goToSlide((currentSlide + 1) % totalSlides);
|
|
}
|
|
});
|
|
|
|
// ── Keyboard accessibility for form inputs ──
|
|
document.querySelectorAll('input, textarea').forEach(el => {
|
|
el.addEventListener('keydown', (e) => {
|
|
if (e.key === 'Enter' && e.target.tagName !== 'TEXTAREA') {
|
|
e.preventDefault();
|
|
e.target.blur();
|
|
}
|
|
});
|
|
});
|
|
|
|
// ── Active nav link tracking ──
|
|
const sections = document.querySelectorAll('section[id]');
|
|
const navLinks = document.querySelectorAll('.nav-link');
|
|
|
|
window.addEventListener('scroll', () => {
|
|
let current = '';
|
|
sections.forEach(section => {
|
|
const sectionTop = section.offsetTop - 100;
|
|
if (window.scrollY >= sectionTop) {
|
|
current = section.getAttribute('id');
|
|
}
|
|
});
|
|
|
|
navLinks.forEach(link => {
|
|
link.classList.remove('text-terra-500');
|
|
link.classList.add('text-bark-400');
|
|
if (link.getAttribute('href') === `#${current}`) {
|
|
link.classList.remove('text-bark-400');
|
|
link.classList.add('text-terra-500');
|
|
}
|
|
});
|
|
});
|
|
</script>
|
|
<div style="position:fixed;right:12px;bottom:12px;z-index:2147483647;background:rgba(17,24,39,.92);color:#fff;padding:8px 10px;border-radius:10px;font:12px/1.3 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;box-shadow:0 8px 20px rgba(0,0,0,.28)">Generated in 102.26s<br>Model: bloomer010/Ling-3.0-tiny-GGUF:Q4_K_M</div></body>
|
|
</html> |