Spaces:
Running
Running
New hairstyle website
Browse files- README.md +7 -4
- components/footer.js +132 -0
- components/hairstyle-card.js +117 -0
- components/hero.js +135 -0
- components/navbar.js +97 -0
- components/trending-section.js +135 -0
- index.html +122 -19
- script.js +119 -0
- style.css +67 -18
README.md
CHANGED
|
@@ -1,10 +1,13 @@
|
|
| 1 |
---
|
| 2 |
-
title:
|
| 3 |
-
emoji: 🐠
|
| 4 |
colorFrom: pink
|
| 5 |
-
colorTo:
|
|
|
|
| 6 |
sdk: static
|
| 7 |
pinned: false
|
|
|
|
|
|
|
| 8 |
---
|
| 9 |
|
| 10 |
-
|
|
|
|
|
|
| 1 |
---
|
| 2 |
+
title: CurlCraft Studio ✂️
|
|
|
|
| 3 |
colorFrom: pink
|
| 4 |
+
colorTo: gray
|
| 5 |
+
emoji: 🐳
|
| 6 |
sdk: static
|
| 7 |
pinned: false
|
| 8 |
+
tags:
|
| 9 |
+
- deepsite-v3
|
| 10 |
---
|
| 11 |
|
| 12 |
+
# Welcome to your new DeepSite project!
|
| 13 |
+
This project was created with [DeepSite](https://huggingface.co/deepsite).
|
components/footer.js
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
class CustomFooter extends HTMLElement {
|
| 2 |
+
connectedCallback() {
|
| 3 |
+
this.attachShadow({ mode: 'open' });
|
| 4 |
+
this.shadowRoot.innerHTML = `
|
| 5 |
+
<style>
|
| 6 |
+
:host {
|
| 7 |
+
display: block;
|
| 8 |
+
width: 100%;
|
| 9 |
+
font-family: 'Poppins', sans-serif;
|
| 10 |
+
}
|
| 11 |
+
.footer-top {
|
| 12 |
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
| 13 |
+
}
|
| 14 |
+
.newsletter-input {
|
| 15 |
+
border: 2px solid transparent;
|
| 16 |
+
background: rgba(255, 255, 255, 0.1);
|
| 17 |
+
transition: all 0.3s;
|
| 18 |
+
}
|
| 19 |
+
.newsletter-input:focus {
|
| 20 |
+
outline: none;
|
| 21 |
+
border-color: rgba(255, 255, 255, 0.5);
|
| 22 |
+
background: rgba(255, 255, 255, 0.15);
|
| 23 |
+
}
|
| 24 |
+
.social-icon {
|
| 25 |
+
transition: transform 0.3s, color 0.3s;
|
| 26 |
+
}
|
| 27 |
+
.social-icon:hover {
|
| 28 |
+
transform: translateY(-3px);
|
| 29 |
+
color: #fbb6ce;
|
| 30 |
+
}
|
| 31 |
+
</style>
|
| 32 |
+
<footer class="text-gray-600">
|
| 33 |
+
<div class="footer-top text-white py-12">
|
| 34 |
+
<div class="container mx-auto px-4">
|
| 35 |
+
<div class="flex flex-col md:flex-row items-center justify-between">
|
| 36 |
+
<div class="mb-8 md:mb-0 md:w-1/2">
|
| 37 |
+
<h3 class="text-3xl font-bold mb-4">Stay Stylish!</h3>
|
| 38 |
+
<p class="text-white/90 mb-6">Get weekly hair inspiration, styling tips, and exclusive offers.</p>
|
| 39 |
+
<form id="newsletter-form" class="flex flex-col sm:flex-row gap-3">
|
| 40 |
+
<input type="email" placeholder="Your email address" class="newsletter-input px-4 py-3 rounded-full text-white placeholder-white/70 flex-grow" required>
|
| 41 |
+
<button type="submit" class="px-6 py-3 bg-white text-purple-700 font-semibold rounded-full hover:bg-gray-100 transition-colors">
|
| 42 |
+
Subscribe
|
| 43 |
+
</button>
|
| 44 |
+
</form>
|
| 45 |
+
</div>
|
| 46 |
+
<div class="md:w-1/3">
|
| 47 |
+
<h4 class="text-xl font-bold mb-6">Follow Our Craft</h4>
|
| 48 |
+
<div class="flex space-x-6">
|
| 49 |
+
<a href="#" class="social-icon text-white hover:text-pink-200">
|
| 50 |
+
<i data-feather="instagram" class="w-6 h-6"></i>
|
| 51 |
+
</a>
|
| 52 |
+
<a href="#" class="social-icon text-white hover:text-pink-200">
|
| 53 |
+
<i data-feather="facebook" class="w-6 h-6"></i>
|
| 54 |
+
</a>
|
| 55 |
+
<a href="#" class="social-icon text-white hover:text-pink-200">
|
| 56 |
+
<i data-feather="twitter" class="w-6 h-6"></i>
|
| 57 |
+
</a>
|
| 58 |
+
<a href="#" class="social-icon text-white hover:text-pink-200">
|
| 59 |
+
<i data-feather="youtube" class="w-6 h-6"></i>
|
| 60 |
+
</a>
|
| 61 |
+
<a href="#" class="social-icon text-white hover:text-pink-200">
|
| 62 |
+
<i data-feather="pinterest" class="w-6 h-6"></i>
|
| 63 |
+
</a>
|
| 64 |
+
</div>
|
| 65 |
+
</div>
|
| 66 |
+
</div>
|
| 67 |
+
</div>
|
| 68 |
+
</div>
|
| 69 |
+
|
| 70 |
+
<div class="bg-gray-800 text-gray-300 py-8">
|
| 71 |
+
<div class="container mx-auto px-4">
|
| 72 |
+
<div class="flex flex-col md:flex-row justify-between items-center">
|
| 73 |
+
<div class="mb-6 md:mb-0">
|
| 74 |
+
<div class="flex items-center space-x-2 mb-4">
|
| 75 |
+
<div class="w-8 h-8 rounded-full bg-gradient-to-br from-purple-500 to-pink-500 flex items-center justify-center">
|
| 76 |
+
<i data-feather="scissors" class="text-white w-4 h-4"></i>
|
| 77 |
+
</div>
|
| 78 |
+
<span class="text-xl font-bold text-white">CurlCraft<span class="gradient-text">Studio</span></span>
|
| 79 |
+
</div>
|
| 80 |
+
<p class="text-sm">Crafting confidence, one hairstyle at a time.</p>
|
| 81 |
+
</div>
|
| 82 |
+
|
| 83 |
+
<div class="flex flex-wrap justify-center gap-8 mb-6 md:mb-0">
|
| 84 |
+
<div>
|
| 85 |
+
<h5 class="font-bold text-white mb-3">Explore</h5>
|
| 86 |
+
<ul class="space-y-2 text-sm">
|
| 87 |
+
<li><a href="/styles" class="hover:text-white transition-colors">Hairstyles</a></li>
|
| 88 |
+
<li><a href="/stylists" class="hover:text-white transition-colors">Find Stylists</a></li>
|
| 89 |
+
<li><a href="/try-on" class="hover:text-white transition-colors">Virtual Try-On</a></li>
|
| 90 |
+
<li><a href="/products" class="hover:text-white transition-colors">Products</a></li>
|
| 91 |
+
</ul>
|
| 92 |
+
</div>
|
| 93 |
+
<div>
|
| 94 |
+
<h5 class="font-bold text-white mb-3">Company</h5>
|
| 95 |
+
<ul class="space-y-2 text-sm">
|
| 96 |
+
<li><a href="/about" class="hover:text-white transition-colors">About Us</a></li>
|
| 97 |
+
<li><a href="/careers" class="hover:text-white transition-colors">Careers</a></li>
|
| 98 |
+
<li><a href="/press" class="hover:text-white transition-colors">Press</a></li>
|
| 99 |
+
<li><a href="/contact" class="hover:text-white transition-colors">Contact</a></li>
|
| 100 |
+
</ul>
|
| 101 |
+
</div>
|
| 102 |
+
<div>
|
| 103 |
+
<h5 class="font-bold text-white mb-3">Support</h5>
|
| 104 |
+
<ul class="space-y-2 text-sm">
|
| 105 |
+
<li><a href="/help" class="hover:text-white transition-colors">Help Center</a></li>
|
| 106 |
+
<li><a href="/faq" class="hover:text-white transition-colors">FAQ</a></li>
|
| 107 |
+
<li><a href="/privacy" class="hover:text-white transition-colors">Privacy Policy</a></li>
|
| 108 |
+
<li><a href="/terms" class="hover:text-white transition-colors">Terms of Service</a></li>
|
| 109 |
+
</ul>
|
| 110 |
+
</div>
|
| 111 |
+
</div>
|
| 112 |
+
</div>
|
| 113 |
+
|
| 114 |
+
<div class="border-t border-gray-700 mt-8 pt-8 text-center text-sm">
|
| 115 |
+
<p>© ${new Date().getFullYear()} CurlCraft Studio. All rights reserved. ✂️</p>
|
| 116 |
+
<p class="mt-2">Made with <i data-feather="heart" class="w-3 h-3 inline text-red-400"></i> for hair enthusiasts everywhere.</p>
|
| 117 |
+
</div>
|
| 118 |
+
</div>
|
| 119 |
+
</div>
|
| 120 |
+
</footer>
|
| 121 |
+
`;
|
| 122 |
+
|
| 123 |
+
// Initialize feather icons in shadow DOM
|
| 124 |
+
setTimeout(() => {
|
| 125 |
+
if (typeof feather !== 'undefined') {
|
| 126 |
+
feather.replace();
|
| 127 |
+
}
|
| 128 |
+
}, 100);
|
| 129 |
+
}
|
| 130 |
+
}
|
| 131 |
+
|
| 132 |
+
customElements.define('custom-footer', CustomFooter);
|
components/hairstyle-card.js
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
class HairstyleCard extends HTMLElement {
|
| 2 |
+
static get observedAttributes() {
|
| 3 |
+
return ['title', 'image', 'category', 'difficulty', 'description'];
|
| 4 |
+
}
|
| 5 |
+
|
| 6 |
+
constructor() {
|
| 7 |
+
super();
|
| 8 |
+
this.attachShadow({ mode: 'open' });
|
| 9 |
+
}
|
| 10 |
+
|
| 11 |
+
connectedCallback() {
|
| 12 |
+
this.render();
|
| 13 |
+
}
|
| 14 |
+
|
| 15 |
+
attributeChangedCallback(name, oldValue, newValue) {
|
| 16 |
+
if (oldValue !== newValue) {
|
| 17 |
+
this.render();
|
| 18 |
+
}
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
render() {
|
| 22 |
+
const title = this.getAttribute('title') || 'Chic Bob';
|
| 23 |
+
const image = this.getAttribute('image') || 'http://static.photos/beauty/640x360/1';
|
| 24 |
+
const category = this.getAttribute('category') || 'short';
|
| 25 |
+
const difficulty = this.getAttribute('difficulty') || 'medium';
|
| 26 |
+
const description = this.getAttribute('description') || 'A modern take on the classic bob with textured ends.';
|
| 27 |
+
|
| 28 |
+
const difficultyColor = {
|
| 29 |
+
'easy': 'bg-green-100 text-green-800',
|
| 30 |
+
'medium': 'bg-yellow-100 text-yellow-800',
|
| 31 |
+
'hard': 'bg-red-100 text-red-800'
|
| 32 |
+
}[difficulty] || 'bg-gray-100 text-gray-800';
|
| 33 |
+
|
| 34 |
+
this.shadowRoot.innerHTML = `
|
| 35 |
+
<style>
|
| 36 |
+
:host {
|
| 37 |
+
display: block;
|
| 38 |
+
transition: all 0.3s ease;
|
| 39 |
+
}
|
| 40 |
+
.card {
|
| 41 |
+
transform: translateY(0);
|
| 42 |
+
transition: transform 0.3s, box-shadow 0.3s;
|
| 43 |
+
}
|
| 44 |
+
.card:hover {
|
| 45 |
+
transform: translateY(-8px);
|
| 46 |
+
}
|
| 47 |
+
.category-badge {
|
| 48 |
+
transition: background-color 0.3s;
|
| 49 |
+
}
|
| 50 |
+
.save-btn:hover i {
|
| 51 |
+
animation: heartBeat 0.5s;
|
| 52 |
+
}
|
| 53 |
+
@keyframes heartBeat {
|
| 54 |
+
0%, 100% { transform: scale(1); }
|
| 55 |
+
50% { transform: scale(1.2); }
|
| 56 |
+
}
|
| 57 |
+
</style>
|
| 58 |
+
<div class="card bg-white rounded-2xl overflow-hidden shadow-lg hover:shadow-2xl">
|
| 59 |
+
<div class="relative overflow-hidden">
|
| 60 |
+
<img src="${image}" alt="${title}" class="w-full h-48 object-cover transition-transform duration-500 hover:scale-105">
|
| 61 |
+
<button class="save-btn absolute top-4 right-4 bg-white/90 hover:bg-white w-10 h-10 rounded-full flex items-center justify-center shadow-md">
|
| 62 |
+
<i data-feather="heart" class="w-5 h-5 text-gray-700"></i>
|
| 63 |
+
</button>
|
| 64 |
+
<div class="absolute bottom-4 left-4">
|
| 65 |
+
<span class="category-badge px-3 py-1 rounded-full text-xs font-semibold ${this.getCategoryColor(category)}">
|
| 66 |
+
${this.formatCategory(category)}
|
| 67 |
+
</span>
|
| 68 |
+
</div>
|
| 69 |
+
</div>
|
| 70 |
+
<div class="p-6">
|
| 71 |
+
<div class="flex justify-between items-start mb-3">
|
| 72 |
+
<h4 class="text-xl font-bold text-gray-800">${title}</h4>
|
| 73 |
+
<span class="px-3 py-1 rounded-full text-xs font-semibold ${difficultyColor}">
|
| 74 |
+
${difficulty.charAt(0).toUpperCase() + difficulty.slice(1)}
|
| 75 |
+
</span>
|
| 76 |
+
</div>
|
| 77 |
+
<p class="text-gray-600 mb-4">${description}</p>
|
| 78 |
+
<div class="flex items-center justify-between">
|
| 79 |
+
<div class="flex items-center text-gray-500 text-sm">
|
| 80 |
+
<i data-feather="clock" class="w-4 h-4 mr-1"></i>
|
| 81 |
+
<span>45-60 min</span>
|
| 82 |
+
</div>
|
| 83 |
+
<a href="/styles/${category}/${title.toLowerCase().replace(/\s+/g, '-')}" class="text-purple-600 hover:text-purple-800 font-semibold text-sm flex items-center">
|
| 84 |
+
View Details
|
| 85 |
+
<i data-feather="chevron-right" class="w-4 h-4 ml-1"></i>
|
| 86 |
+
</a>
|
| 87 |
+
</div>
|
| 88 |
+
</div>
|
| 89 |
+
</div>
|
| 90 |
+
`;
|
| 91 |
+
|
| 92 |
+
// Initialize feather icons in shadow DOM
|
| 93 |
+
setTimeout(() => {
|
| 94 |
+
if (typeof feather !== 'undefined') {
|
| 95 |
+
feather.replace();
|
| 96 |
+
}
|
| 97 |
+
}, 100);
|
| 98 |
+
}
|
| 99 |
+
|
| 100 |
+
getCategoryColor(category) {
|
| 101 |
+
const colors = {
|
| 102 |
+
'short': 'bg-blue-100 text-blue-800',
|
| 103 |
+
'medium': 'bg-purple-100 text-purple-800',
|
| 104 |
+
'long': 'bg-pink-100 text-pink-800',
|
| 105 |
+
'curly': 'bg-orange-100 text-orange-800',
|
| 106 |
+
'color': 'bg-indigo-100 text-indigo-800',
|
| 107 |
+
'updo': 'bg-teal-100 text-teal-800'
|
| 108 |
+
};
|
| 109 |
+
return colors[category] || 'bg-gray-100 text-gray-800';
|
| 110 |
+
}
|
| 111 |
+
|
| 112 |
+
formatCategory(category) {
|
| 113 |
+
return category.charAt(0).toUpperCase() + category.slice(1);
|
| 114 |
+
}
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
customElements.define('hairstyle-card', HairstyleCard);
|
components/hero.js
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
class CustomHero extends HTMLElement {
|
| 2 |
+
connectedCallback() {
|
| 3 |
+
this.attachShadow({ mode: 'open' });
|
| 4 |
+
this.shadowRoot.innerHTML = `
|
| 5 |
+
<style>
|
| 6 |
+
:host {
|
| 7 |
+
display: block;
|
| 8 |
+
width: 100%;
|
| 9 |
+
font-family: 'Poppins', sans-serif;
|
| 10 |
+
}
|
| 11 |
+
.hero {
|
| 12 |
+
background: linear-gradient(135deg, rgba(168, 85, 247, 0.1) 0%, rgba(236, 72, 153, 0.1) 100%);
|
| 13 |
+
position: relative;
|
| 14 |
+
overflow: hidden;
|
| 15 |
+
}
|
| 16 |
+
.hero::before {
|
| 17 |
+
content: '';
|
| 18 |
+
position: absolute;
|
| 19 |
+
top: -50%;
|
| 20 |
+
right: -20%;
|
| 21 |
+
width: 600px;
|
| 22 |
+
height: 600px;
|
| 23 |
+
background: radial-gradient(circle, rgba(168, 85, 247, 0.15) 0%, rgba(236, 72, 153, 0.05) 70%);
|
| 24 |
+
border-radius: 50%;
|
| 25 |
+
z-index: 0;
|
| 26 |
+
}
|
| 27 |
+
.floating-element {
|
| 28 |
+
animation: float 6s ease-in-out infinite;
|
| 29 |
+
}
|
| 30 |
+
@keyframes float {
|
| 31 |
+
0%, 100% { transform: translateY(0) rotate(0deg); }
|
| 32 |
+
50% { transform: translateY(-20px) rotate(5deg); }
|
| 33 |
+
}
|
| 34 |
+
.typewriter {
|
| 35 |
+
overflow: hidden;
|
| 36 |
+
border-right: 3px solid #a855f7;
|
| 37 |
+
white-space: nowrap;
|
| 38 |
+
animation: typing 3.5s steps(40, end), blink-caret 0.75s step-end infinite;
|
| 39 |
+
}
|
| 40 |
+
@keyframes typing {
|
| 41 |
+
from { width: 0 }
|
| 42 |
+
to { width: 100% }
|
| 43 |
+
}
|
| 44 |
+
@keyframes blink-caret {
|
| 45 |
+
from, to { border-color: transparent }
|
| 46 |
+
50% { border-color: #a855f7; }
|
| 47 |
+
}
|
| 48 |
+
</style>
|
| 49 |
+
<section class="hero py-16 md:py-24">
|
| 50 |
+
<div class="container mx-auto px-4 relative z-10">
|
| 51 |
+
<div class="flex flex-col lg:flex-row items-center">
|
| 52 |
+
<div class="lg:w-1/2 mb-12 lg:mb-0">
|
| 53 |
+
<h1 class="text-4xl md:text-6xl font-bold text-gray-800 mb-6">
|
| 54 |
+
Discover Your
|
| 55 |
+
<span class="block typewriter gradient-text">Signature Style</span>
|
| 56 |
+
</h1>
|
| 57 |
+
<p class="text-gray-600 text-lg mb-8 max-w-2xl">
|
| 58 |
+
Browse thousands of hairstyles, find your perfect match, and connect with expert stylists.
|
| 59 |
+
Your next hair transformation starts here at CurlCraft Studio.
|
| 60 |
+
</p>
|
| 61 |
+
<div class="flex flex-col sm:flex-row gap-4">
|
| 62 |
+
<a href="/styles" class="btn-hover-effect px-8 py-4 bg-gradient-to-r from-purple-600 to-pink-500 text-white font-semibold rounded-full hover:shadow-xl transition-all duration-300 text-center">
|
| 63 |
+
<div class="flex items-center justify-center">
|
| 64 |
+
<i data-feather="search" class="mr-2"></i>
|
| 65 |
+
Explore Hairstyles
|
| 66 |
+
</div>
|
| 67 |
+
</a>
|
| 68 |
+
<a href="/try-on" class="px-8 py-4 border-2 border-purple-500 text-purple-600 font-semibold rounded-full hover:bg-purple-50 transition-colors text-center">
|
| 69 |
+
<div class="flex items-center justify-center">
|
| 70 |
+
<i data-feather="camera" class="mr-2"></i>
|
| 71 |
+
Virtual Try-On
|
| 72 |
+
</div>
|
| 73 |
+
</a>
|
| 74 |
+
</div>
|
| 75 |
+
<div class="mt-12 flex items-center space-x-8">
|
| 76 |
+
<div class="text-center">
|
| 77 |
+
<div class="text-3xl font-bold text-purple-600">5K+</div>
|
| 78 |
+
<div class="text-gray-600">Hairstyles</div>
|
| 79 |
+
</div>
|
| 80 |
+
<div class="text-center">
|
| 81 |
+
<div class="text-3xl font-bold text-pink-500">1.2K+</div>
|
| 82 |
+
<div class="text-gray-600">Expert Stylists</div>
|
| 83 |
+
</div>
|
| 84 |
+
<div class="text-center">
|
| 85 |
+
<div class="text-3xl font-bold text-yellow-500">98%</div>
|
| 86 |
+
<div class="text-gray-600">Satisfaction</div>
|
| 87 |
+
</div>
|
| 88 |
+
</div>
|
| 89 |
+
</div>
|
| 90 |
+
|
| 91 |
+
<div class="lg:w-1/2 relative">
|
| 92 |
+
<div class="relative">
|
| 93 |
+
<img src="http://static.photos/beauty/640x360/5" alt="Hero Hairstyle" class="rounded-3xl shadow-2xl w-full h-auto floating-element">
|
| 94 |
+
<div class="absolute -bottom-6 -left-6 bg-white p-6 rounded-2xl shadow-xl max-w-xs">
|
| 95 |
+
<div class="flex items-center mb-3">
|
| 96 |
+
<div class="w-10 h-10 rounded-full bg-gradient-to-br from-purple-500 to-pink-500 flex items-center justify-center mr-3">
|
| 97 |
+
<i data-feather="award" class="text-white w-5 h-5"></i>
|
| 98 |
+
</div>
|
| 99 |
+
<div>
|
| 100 |
+
<h4 class="font-bold text-gray-800">Style of the Week</h4>
|
| 101 |
+
<p class="text-sm text-gray-600">"Rose Gold Balayage"</p>
|
| 102 |
+
</div>
|
| 103 |
+
</div>
|
| 104 |
+
<p class="text-gray-700 text-sm">Featured by stylist <span class="font-semibold">Alex Morgan</span></p>
|
| 105 |
+
</div>
|
| 106 |
+
<div class="absolute -top-6 -right-6 bg-gradient-to-br from-yellow-400 to-orange-500 text-white p-4 rounded-2xl shadow-xl">
|
| 107 |
+
<div class="text-center">
|
| 108 |
+
<div class="text-2xl font-bold">4.9</div>
|
| 109 |
+
<div class="flex justify-center">
|
| 110 |
+
<i data-feather="star" class="w-4 h-4 fill-current"></i>
|
| 111 |
+
<i data-feather="star" class="w-4 h-4 fill-current"></i>
|
| 112 |
+
<i data-feather="star" class="w-4 h-4 fill-current"></i>
|
| 113 |
+
<i data-feather="star" class="w-4 h-4 fill-current"></i>
|
| 114 |
+
<i data-feather="star" class="w-4 h-4 fill-current"></i>
|
| 115 |
+
</div>
|
| 116 |
+
<div class="text-xs mt-1">Rating</div>
|
| 117 |
+
</div>
|
| 118 |
+
</div>
|
| 119 |
+
</div>
|
| 120 |
+
</div>
|
| 121 |
+
</div>
|
| 122 |
+
</div>
|
| 123 |
+
</section>
|
| 124 |
+
`;
|
| 125 |
+
|
| 126 |
+
// Initialize feather icons in shadow DOM
|
| 127 |
+
setTimeout(() => {
|
| 128 |
+
if (typeof feather !== 'undefined') {
|
| 129 |
+
feather.replace();
|
| 130 |
+
}
|
| 131 |
+
}, 100);
|
| 132 |
+
}
|
| 133 |
+
}
|
| 134 |
+
|
| 135 |
+
customElements.define('custom-hero', CustomHero);
|
components/navbar.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
class CustomNavbar extends HTMLElement {
|
| 2 |
+
connectedCallback() {
|
| 3 |
+
this.attachShadow({ mode: 'open' });
|
| 4 |
+
this.shadowRoot.innerHTML = `
|
| 5 |
+
<style>
|
| 6 |
+
:host {
|
| 7 |
+
display: block;
|
| 8 |
+
width: 100%;
|
| 9 |
+
position: sticky;
|
| 10 |
+
top: 0;
|
| 11 |
+
z-index: 50;
|
| 12 |
+
font-family: 'Poppins', sans-serif;
|
| 13 |
+
}
|
| 14 |
+
.navbar {
|
| 15 |
+
background: rgba(255, 255, 255, 0.95);
|
| 16 |
+
backdrop-filter: blur(10px);
|
| 17 |
+
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
|
| 18 |
+
}
|
| 19 |
+
.nav-link {
|
| 20 |
+
position: relative;
|
| 21 |
+
transition: color 0.3s;
|
| 22 |
+
}
|
| 23 |
+
.nav-link::after {
|
| 24 |
+
content: '';
|
| 25 |
+
position: absolute;
|
| 26 |
+
bottom: -5px;
|
| 27 |
+
left: 0;
|
| 28 |
+
width: 0;
|
| 29 |
+
height: 2px;
|
| 30 |
+
background: linear-gradient(to right, #a855f7, #ec4899);
|
| 31 |
+
transition: width 0.3s;
|
| 32 |
+
}
|
| 33 |
+
.nav-link:hover::after {
|
| 34 |
+
width: 100%;
|
| 35 |
+
}
|
| 36 |
+
.mobile-menu {
|
| 37 |
+
animation: slideDown 0.3s ease-out;
|
| 38 |
+
}
|
| 39 |
+
@keyframes slideDown {
|
| 40 |
+
from { opacity: 0; transform: translateY(-10px); }
|
| 41 |
+
to { opacity: 1; transform: translateY(0); }
|
| 42 |
+
}
|
| 43 |
+
</style>
|
| 44 |
+
<nav class="navbar border-b border-gray-100">
|
| 45 |
+
<div class="container mx-auto px-4 py-4">
|
| 46 |
+
<div class="flex items-center justify-between">
|
| 47 |
+
<div class="flex items-center">
|
| 48 |
+
<a href="/" class="flex items-center space-x-2">
|
| 49 |
+
<div class="w-10 h-10 rounded-full bg-gradient-to-br from-purple-500 to-pink-500 flex items-center justify-center">
|
| 50 |
+
<i data-feather="scissors" class="text-white w-5 h-5"></i>
|
| 51 |
+
</div>
|
| 52 |
+
<span class="text-2xl font-bold text-gray-800">CurlCraft<span class="gradient-text">Studio</span></span>
|
| 53 |
+
</a>
|
| 54 |
+
</div>
|
| 55 |
+
|
| 56 |
+
<div class="hidden md:flex items-center space-x-8">
|
| 57 |
+
<a href="/" class="nav-link text-gray-700 hover:text-purple-600 font-medium">Home</a>
|
| 58 |
+
<a href="/styles" class="nav-link text-gray-700 hover:text-purple-600 font-medium">Hairstyles</a>
|
| 59 |
+
<a href="/stylists" class="nav-link text-gray-700 hover:text-purple-600 font-medium">Stylists</a>
|
| 60 |
+
<a href="/try-on" class="nav-link text-gray-700 hover:text-purple-600 font-medium">Virtual Try-On</a>
|
| 61 |
+
<a href="/blog" class="nav-link text-gray-700 hover:text-purple-600 font-medium">Blog</a>
|
| 62 |
+
<a href="/book" class="btn-hover-effect px-6 py-2 bg-gradient-to-r from-purple-600 to-pink-500 text-white font-semibold rounded-full hover:shadow-lg transition-all duration-300">
|
| 63 |
+
Book Appointment
|
| 64 |
+
</a>
|
| 65 |
+
</div>
|
| 66 |
+
|
| 67 |
+
<button data-menu-toggle class="md:hidden text-gray-700 hover:text-purple-600">
|
| 68 |
+
<i data-feather="menu" class="w-6 h-6"></i>
|
| 69 |
+
</button>
|
| 70 |
+
</div>
|
| 71 |
+
|
| 72 |
+
<div id="mobile-menu" class="hidden md:hidden mobile-menu mt-4 pb-4">
|
| 73 |
+
<div class="flex flex-col space-y-4">
|
| 74 |
+
<a href="/" class="text-gray-700 hover:text-purple-600 font-medium py-2">Home</a>
|
| 75 |
+
<a href="/styles" class="text-gray-700 hover:text-purple-600 font-medium py-2">Hairstyles</a>
|
| 76 |
+
<a href="/stylists" class="text-gray-700 hover:text-purple-600 font-medium py-2">Stylists</a>
|
| 77 |
+
<a href="/try-on" class="text-gray-700 hover:text-purple-600 font-medium py-2">Virtual Try-On</a>
|
| 78 |
+
<a href="/blog" class="text-gray-700 hover:text-purple-600 font-medium py-2">Blog</a>
|
| 79 |
+
<a href="/book" class="px-6 py-2 bg-gradient-to-r from-purple-600 to-pink-500 text-white font-semibold rounded-full text-center">
|
| 80 |
+
Book Appointment
|
| 81 |
+
</a>
|
| 82 |
+
</div>
|
| 83 |
+
</div>
|
| 84 |
+
</div>
|
| 85 |
+
</nav>
|
| 86 |
+
`;
|
| 87 |
+
|
| 88 |
+
// Initialize feather icons in shadow DOM
|
| 89 |
+
setTimeout(() => {
|
| 90 |
+
if (typeof feather !== 'undefined') {
|
| 91 |
+
feather.replace();
|
| 92 |
+
}
|
| 93 |
+
}, 100);
|
| 94 |
+
}
|
| 95 |
+
}
|
| 96 |
+
|
| 97 |
+
customElements.define('custom-navbar', CustomNavbar);
|
components/trending-section.js
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
class TrendingSection extends HTMLElement {
|
| 2 |
+
connectedCallback() {
|
| 3 |
+
this.attachShadow({ mode: 'open' });
|
| 4 |
+
this.shadowRoot.innerHTML = `
|
| 5 |
+
<style>
|
| 6 |
+
:host {
|
| 7 |
+
display: block;
|
| 8 |
+
width: 100%;
|
| 9 |
+
font-family: 'Poppins', sans-serif;
|
| 10 |
+
}
|
| 11 |
+
.filter-btn {
|
| 12 |
+
transition: all 0.3s;
|
| 13 |
+
}
|
| 14 |
+
.filter-btn:hover {
|
| 15 |
+
transform: translateY(-2px);
|
| 16 |
+
}
|
| 17 |
+
.card-container {
|
| 18 |
+
transition: opacity 0.3s, transform 0.3s;
|
| 19 |
+
}
|
| 20 |
+
</style>
|
| 21 |
+
<div>
|
| 22 |
+
<div class="flex flex-wrap justify-center gap-4 mb-10">
|
| 23 |
+
<button data-filter="all" class="filter-btn px-6 py-2 bg-purple-600 text-white font-semibold rounded-full">
|
| 24 |
+
All Styles
|
| 25 |
+
</button>
|
| 26 |
+
<button data-filter="short" class="filter-btn px-6 py-2 bg-gray-200 text-gray-700 font-semibold rounded-full hover:bg-gray-300">
|
| 27 |
+
Short Hair
|
| 28 |
+
</button>
|
| 29 |
+
<button data-filter="medium" class="filter-btn px-6 py-2 bg-gray-200 text-gray-700 font-semibold rounded-full hover:bg-gray-300">
|
| 30 |
+
Medium Length
|
| 31 |
+
</button>
|
| 32 |
+
<button data-filter="long" class="filter-btn px-6 py-2 bg-gray-200 text-gray-700 font-semibold rounded-full hover:bg-gray-300">
|
| 33 |
+
Long Hair
|
| 34 |
+
</button>
|
| 35 |
+
<button data-filter="curly" class="filter-btn px-6 py-2 bg-gray-200 text-gray-700 font-semibold rounded-full hover:bg-gray-300">
|
| 36 |
+
Curly & Textured
|
| 37 |
+
</button>
|
| 38 |
+
<button data-filter="color" class="filter-btn px-6 py-2 bg-gray-200 text-gray-700 font-semibold rounded-full hover:bg-gray-300">
|
| 39 |
+
Bold Colors
|
| 40 |
+
</button>
|
| 41 |
+
</div>
|
| 42 |
+
|
| 43 |
+
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-8">
|
| 44 |
+
<hairstyle-card
|
| 45 |
+
title="Modern Shag"
|
| 46 |
+
image="http://static.photos/beauty/640x360/2"
|
| 47 |
+
category="medium"
|
| 48 |
+
difficulty="medium"
|
| 49 |
+
description="Layered shag with curtain bangs for effortless texture."
|
| 50 |
+
data-category="medium">
|
| 51 |
+
</hairstyle-card>
|
| 52 |
+
|
| 53 |
+
<hairstyle-card
|
| 54 |
+
title="Platinum Pixie"
|
| 55 |
+
image="http://static.photos/beauty/640x360/3"
|
| 56 |
+
category="short"
|
| 57 |
+
difficulty="hard"
|
| 58 |
+
description="Edgy platinum blonde pixie with undercut details."
|
| 59 |
+
data-category="short">
|
| 60 |
+
</hairstyle-card>
|
| 61 |
+
|
| 62 |
+
<hairstyle-card
|
| 63 |
+
title="Mermaid Waves"
|
| 64 |
+
image="http://static.photos/beauty/640x360/4"
|
| 65 |
+
category="long"
|
| 66 |
+
difficulty="easy"
|
| 67 |
+
description="Beachy waves with subtle rose gold highlights."
|
| 68 |
+
data-category="long">
|
| 69 |
+
</hairstyle-card>
|
| 70 |
+
|
| 71 |
+
<hairstyle-card
|
| 72 |
+
title="Curly Afro"
|
| 73 |
+
image="http://static.photos/beauty/640x360/6"
|
| 74 |
+
category="curly"
|
| 75 |
+
difficulty="medium"
|
| 76 |
+
description="Full, defined curls with shape and volume."
|
| 77 |
+
data-category="curly">
|
| 78 |
+
</hairstyle-card>
|
| 79 |
+
|
| 80 |
+
<hairstyle-card
|
| 81 |
+
title="Pastel Bob"
|
| 82 |
+
image="http://static.photos/beauty/640x360/8"
|
| 83 |
+
category="short"
|
| 84 |
+
difficulty="hard"
|
| 85 |
+
description="Short bob with lavender pastel ombre effect."
|
| 86 |
+
data-category="color">
|
| 87 |
+
</hairstyle-card>
|
| 88 |
+
|
| 89 |
+
<hairstyle-card
|
| 90 |
+
title="Braided Updo"
|
| 91 |
+
image="http://static.photos/beauty/640x360/9"
|
| 92 |
+
category="updo"
|
| 93 |
+
difficulty="hard"
|
| 94 |
+
description="Elegant braided updo for special occasions."
|
| 95 |
+
data-category="updo">
|
| 96 |
+
</hairstyle-card>
|
| 97 |
+
|
| 98 |
+
<hairstyle-card
|
| 99 |
+
title="Bronde Balayage"
|
| 100 |
+
image="http://static.photos/beauty/640x360/10"
|
| 101 |
+
category="medium"
|
| 102 |
+
difficulty="medium"
|
| 103 |
+
description="Natural-looking blend of brunette and blonde."
|
| 104 |
+
data-category="medium">
|
| 105 |
+
</hairstyle-card>
|
| 106 |
+
|
| 107 |
+
<hairstyle-card
|
| 108 |
+
title="Bold Red Lob"
|
| 109 |
+
image="http://static.photos/beauty/640x360/11"
|
| 110 |
+
category="medium"
|
| 111 |
+
difficulty="medium"
|
| 112 |
+
description="Vibrant red long bob with blunt cut ends."
|
| 113 |
+
data-category="color">
|
| 114 |
+
</hairstyle-card>
|
| 115 |
+
</div>
|
| 116 |
+
|
| 117 |
+
<div class="text-center mt-12">
|
| 118 |
+
<a href="/styles" class="inline-flex items-center px-8 py-3 border-2 border-purple-500 text-purple-600 font-semibold rounded-full hover:bg-purple-50 transition-colors">
|
| 119 |
+
View All Hairstyles
|
| 120 |
+
<i data-feather="arrow-right" class="ml-2"></i>
|
| 121 |
+
</a>
|
| 122 |
+
</div>
|
| 123 |
+
</div>
|
| 124 |
+
`;
|
| 125 |
+
|
| 126 |
+
// Initialize feather icons in shadow DOM
|
| 127 |
+
setTimeout(() => {
|
| 128 |
+
if (typeof feather !== 'undefined') {
|
| 129 |
+
feather.replace();
|
| 130 |
+
}
|
| 131 |
+
}, 100);
|
| 132 |
+
}
|
| 133 |
+
}
|
| 134 |
+
|
| 135 |
+
customElements.define('custom-trending-section', TrendingSection);
|
index.html
CHANGED
|
@@ -1,19 +1,122 @@
|
|
| 1 |
-
<!
|
| 2 |
-
<html>
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
</
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<title>CurlCraft Studio ✂️ | Discover Your Next Look</title>
|
| 7 |
+
<link rel="icon" type="image/x-icon" href="/static/favicon.ico">
|
| 8 |
+
<link rel="stylesheet" href="style.css">
|
| 9 |
+
<script src="https://cdn.tailwindcss.com"></script>
|
| 10 |
+
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
|
| 11 |
+
<script src="https://unpkg.com/feather-icons"></script>
|
| 12 |
+
<script src="components/navbar.js"></script>
|
| 13 |
+
<script src="components/footer.js"></script>
|
| 14 |
+
<script src="components/hairstyle-card.js"></script>
|
| 15 |
+
<script src="components/hero.js"></script>
|
| 16 |
+
<script src="components/trending-section.js"></script>
|
| 17 |
+
</head>
|
| 18 |
+
<body class="bg-gradient-to-br from-gray-50 to-pink-50 min-h-screen font-sans">
|
| 19 |
+
<custom-navbar></custom-navbar>
|
| 20 |
+
<custom-hero></custom-hero>
|
| 21 |
+
|
| 22 |
+
<main class="container mx-auto px-4 py-12">
|
| 23 |
+
<section class="mb-16">
|
| 24 |
+
<div class="text-center mb-10">
|
| 25 |
+
<h2 class="text-4xl md:text-5xl font-bold text-gray-800 mb-4">Trending Styles This Season</h2>
|
| 26 |
+
<p class="text-gray-600 text-lg max-w-2xl mx-auto">From chic bobs to bold colors, find inspiration from our curated collection.</p>
|
| 27 |
+
</div>
|
| 28 |
+
<custom-trending-section></custom-trending-section>
|
| 29 |
+
</section>
|
| 30 |
+
|
| 31 |
+
<section class="mb-16">
|
| 32 |
+
<div class="flex flex-col md:flex-row items-center justify-between gap-10">
|
| 33 |
+
<div class="md:w-1/2">
|
| 34 |
+
<img src="http://static.photos/beauty/1024x576/7" alt="Hair Salon Stylist" class="rounded-3xl shadow-2xl w-full h-auto object-cover">
|
| 35 |
+
</div>
|
| 36 |
+
<div class="md:w-1/2">
|
| 37 |
+
<h3 class="text-3xl font-bold text-gray-800 mb-6">Virtual Try-On Experience</h3>
|
| 38 |
+
<p class="text-gray-700 mb-6 text-lg">Not sure if bangs are for you? Use our AI-powered virtual try-on tool to see how different hairstyles look on you before making the chop!</p>
|
| 39 |
+
<a href="/try-on" class="inline-flex items-center px-6 py-3 bg-gradient-to-r from-purple-600 to-pink-500 text-white font-semibold rounded-full hover:shadow-lg transition-all duration-300">
|
| 40 |
+
Try It Now
|
| 41 |
+
<i data-feather="arrow-right" class="ml-2"></i>
|
| 42 |
+
</a>
|
| 43 |
+
</div>
|
| 44 |
+
</div>
|
| 45 |
+
</section>
|
| 46 |
+
|
| 47 |
+
<section class="py-12">
|
| 48 |
+
<div class="text-center mb-10">
|
| 49 |
+
<h2 class="text-4xl font-bold text-gray-800 mb-4">Find Your Perfect Stylist</h2>
|
| 50 |
+
<p class="text-gray-600 text-lg max-w-2xl mx-auto">Browse profiles, read reviews, and book appointments with top-rated hair artists in your area.</p>
|
| 51 |
+
</div>
|
| 52 |
+
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
|
| 53 |
+
<div class="bg-white rounded-2xl p-6 shadow-lg hover:shadow-2xl transition-shadow duration-300">
|
| 54 |
+
<div class="w-20 h-20 rounded-full mx-auto mb-4 overflow-hidden border-4 border-pink-200">
|
| 55 |
+
<img src="http://static.photos/people/200x200/101" alt="Stylist Alex" class="w-full h-full object-cover">
|
| 56 |
+
</div>
|
| 57 |
+
<h4 class="text-xl font-bold text-center text-gray-800 mb-2">Alex Morgan</h4>
|
| 58 |
+
<p class="text-gray-600 text-center mb-4">Specializes in balayage & curly cuts</p>
|
| 59 |
+
<div class="flex justify-center text-yellow-400 mb-4">
|
| 60 |
+
<i data-feather="star" class="w-5 h-5 fill-current"></i>
|
| 61 |
+
<i data-feather="star" class="w-5 h-5 fill-current"></i>
|
| 62 |
+
<i data-feather="star" class="w-5 h-5 fill-current"></i>
|
| 63 |
+
<i data-feather="star" class="w-5 h-5 fill-current"></i>
|
| 64 |
+
<i data-feather="star" class="w-5 h-5 fill-current"></i>
|
| 65 |
+
</div>
|
| 66 |
+
<a href="/stylist/alex" class="block text-center text-purple-600 font-semibold hover:text-purple-800">View Profile</a>
|
| 67 |
+
</div>
|
| 68 |
+
<div class="bg-white rounded-2xl p-6 shadow-lg hover:shadow-2xl transition-shadow duration-300">
|
| 69 |
+
<div class="w-20 h-20 rounded-full mx-auto mb-4 overflow-hidden border-4 border-pink-200">
|
| 70 |
+
<img src="http://static.photos/people/200x200/102" alt="Stylist Jamie" class="w-full h-full object-cover">
|
| 71 |
+
</div>
|
| 72 |
+
<h4 class="text-xl font-bold text-center text-gray-800 mb-2">Jamie Chen</h4>
|
| 73 |
+
<p class="text-gray-600 text-center mb-4">Expert in vintage & retro styles</p>
|
| 74 |
+
<div class="flex justify-center text-yellow-400 mb-4">
|
| 75 |
+
<i data-feather="star" class="w-5 h-5 fill-current"></i>
|
| 76 |
+
<i data-feather="star" class="w-5 h-5 fill-current"></i>
|
| 77 |
+
<i data-feather="star" class="w-5 h-5 fill-current"></i>
|
| 78 |
+
<i data-feather="star" class="w-5 h-5 fill-current"></i>
|
| 79 |
+
<i data-feather="star" class="w-5 h-5 fill-current"></i>
|
| 80 |
+
</div>
|
| 81 |
+
<a href="/stylist/jamie" class="block text-center text-purple-600 font-semibold hover:text-purple-800">View Profile</a>
|
| 82 |
+
</div>
|
| 83 |
+
<div class="bg-white rounded-2xl p-6 shadow-lg hover:shadow-2xl transition-shadow duration-300">
|
| 84 |
+
<div class="w-20 h-20 rounded-full mx-auto mb-4 overflow-hidden border-4 border-pink-200">
|
| 85 |
+
<img src="http://static.photos/people/200x200/103" alt="Stylist Taylor" class="w-full h-full object-cover">
|
| 86 |
+
</div>
|
| 87 |
+
<h4 class="text-xl font-bold text-center text-gray-800 mb-2">Taylor Rivers</h4>
|
| 88 |
+
<p class="text-gray-600 text-center mb-4">Master of bold colors & undercuts</p>
|
| 89 |
+
<div class="flex justify-center text-yellow-400 mb-4">
|
| 90 |
+
<i data-feather="star" class="w-5 h-5 fill-current"></i>
|
| 91 |
+
<i data-feather="star" class="w-5 h-5 fill-current"></i>
|
| 92 |
+
<i data-feather="star" class="w-5 h-5 fill-current"></i>
|
| 93 |
+
<i data-feather="star" class="w-5 h-5 fill-current"></i>
|
| 94 |
+
<i data-feather="star" class="w-5 h-5 fill-current"></i>
|
| 95 |
+
</div>
|
| 96 |
+
<a href="/stylist/taylor" class="block text-center text-purple-600 font-semibold hover:text-purple-800">View Profile</a>
|
| 97 |
+
</div>
|
| 98 |
+
</div>
|
| 99 |
+
</section>
|
| 100 |
+
</main>
|
| 101 |
+
|
| 102 |
+
<custom-footer></custom-footer>
|
| 103 |
+
|
| 104 |
+
<script src="script.js"></script>
|
| 105 |
+
<script>
|
| 106 |
+
feather.replace();
|
| 107 |
+
// Simple script to handle newsletter signup
|
| 108 |
+
document.addEventListener('DOMContentLoaded', function() {
|
| 109 |
+
const newsletterForm = document.querySelector('custom-footer')?.shadowRoot?.querySelector('#newsletter-form');
|
| 110 |
+
if (newsletterForm) {
|
| 111 |
+
newsletterForm.addEventListener('submit', function(e) {
|
| 112 |
+
e.preventDefault();
|
| 113 |
+
const email = this.querySelector('input[type="email"]').value;
|
| 114 |
+
alert(`Thank you! You've subscribed with: ${email}. Welcome to the CurlCraft community!`);
|
| 115 |
+
this.reset();
|
| 116 |
+
});
|
| 117 |
+
}
|
| 118 |
+
});
|
| 119 |
+
</script>
|
| 120 |
+
<script src="https://huggingface.co/deepsite/deepsite-badge.js"></script>
|
| 121 |
+
</body>
|
| 122 |
+
</html>
|
script.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Main JavaScript for CurlCraft Studio
|
| 2 |
+
|
| 3 |
+
// Initialize Feather Icons
|
| 4 |
+
document.addEventListener('DOMContentLoaded', function() {
|
| 5 |
+
// Feather icons replacement
|
| 6 |
+
if (typeof feather !== 'undefined') {
|
| 7 |
+
feather.replace();
|
| 8 |
+
}
|
| 9 |
+
|
| 10 |
+
// Mobile menu toggle for navbar component
|
| 11 |
+
document.addEventListener('click', function(event) {
|
| 12 |
+
if (event.target.closest('[data-menu-toggle]')) {
|
| 13 |
+
const navbar = document.querySelector('custom-navbar');
|
| 14 |
+
if (navbar) {
|
| 15 |
+
const shadowRoot = navbar.shadowRoot;
|
| 16 |
+
const mobileMenu = shadowRoot.querySelector('#mobile-menu');
|
| 17 |
+
if (mobileMenu) {
|
| 18 |
+
mobileMenu.classList.toggle('hidden');
|
| 19 |
+
}
|
| 20 |
+
}
|
| 21 |
+
}
|
| 22 |
+
});
|
| 23 |
+
|
| 24 |
+
// Hairstyle filter functionality
|
| 25 |
+
const filterButtons = document.querySelectorAll('[data-filter]');
|
| 26 |
+
const hairstyleCards = document.querySelectorAll('hairstyle-card');
|
| 27 |
+
|
| 28 |
+
filterButtons.forEach(button => {
|
| 29 |
+
button.addEventListener('click', function() {
|
| 30 |
+
const filter = this.getAttribute('data-filter');
|
| 31 |
+
|
| 32 |
+
// Update active button
|
| 33 |
+
filterButtons.forEach(btn => {
|
| 34 |
+
btn.classList.remove('bg-purple-600', 'text-white');
|
| 35 |
+
btn.classList.add('bg-gray-200', 'text-gray-700');
|
| 36 |
+
});
|
| 37 |
+
this.classList.remove('bg-gray-200', 'text-gray-700');
|
| 38 |
+
this.classList.add('bg-purple-600', 'text-white');
|
| 39 |
+
|
| 40 |
+
// Filter cards
|
| 41 |
+
hairstyleCards.forEach(card => {
|
| 42 |
+
const category = card.getAttribute('data-category');
|
| 43 |
+
if (filter === 'all' || category === filter) {
|
| 44 |
+
card.style.display = 'block';
|
| 45 |
+
setTimeout(() => {
|
| 46 |
+
card.style.opacity = '1';
|
| 47 |
+
card.style.transform = 'translateY(0)';
|
| 48 |
+
}, 10);
|
| 49 |
+
} else {
|
| 50 |
+
card.style.opacity = '0';
|
| 51 |
+
card.style.transform = 'translateY(20px)';
|
| 52 |
+
setTimeout(() => {
|
| 53 |
+
card.style.display = 'none';
|
| 54 |
+
}, 300);
|
| 55 |
+
}
|
| 56 |
+
});
|
| 57 |
+
});
|
| 58 |
+
});
|
| 59 |
+
|
| 60 |
+
// Load hairstyles from API
|
| 61 |
+
async function loadHairstyles() {
|
| 62 |
+
try {
|
| 63 |
+
// Using a public API for demonstration
|
| 64 |
+
const response = await fetch('https://api.unsplash.com/search/photos?query=hairstyle&per_page=12&client_id=YOUR_UNSPLASH_ACCESS_KEY');
|
| 65 |
+
const data = await response.json();
|
| 66 |
+
|
| 67 |
+
// In a real implementation, you would update the hairstyle cards with actual data
|
| 68 |
+
console.log('Hairstyles loaded:', data);
|
| 69 |
+
|
| 70 |
+
// Update trending section if it exists
|
| 71 |
+
const trendingSection = document.querySelector('custom-trending-section');
|
| 72 |
+
if (trendingSection && data.results) {
|
| 73 |
+
// You can implement actual data binding here
|
| 74 |
+
}
|
| 75 |
+
} catch (error) {
|
| 76 |
+
console.log('Using placeholder data due to API limit');
|
| 77 |
+
// Fallback to placeholder images
|
| 78 |
+
}
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
+
// Load hairstyles on page load
|
| 82 |
+
loadHairstyles();
|
| 83 |
+
|
| 84 |
+
// Smooth scroll for anchor links
|
| 85 |
+
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
| 86 |
+
anchor.addEventListener('click', function (e) {
|
| 87 |
+
e.preventDefault();
|
| 88 |
+
const targetId = this.getAttribute('href');
|
| 89 |
+
if (targetId === '#') return;
|
| 90 |
+
|
| 91 |
+
const targetElement = document.querySelector(targetId);
|
| 92 |
+
if (targetElement) {
|
| 93 |
+
window.scrollTo({
|
| 94 |
+
top: targetElement.offsetTop - 80,
|
| 95 |
+
behavior: 'smooth'
|
| 96 |
+
});
|
| 97 |
+
}
|
| 98 |
+
});
|
| 99 |
+
});
|
| 100 |
+
|
| 101 |
+
// Newsletter form handling
|
| 102 |
+
const newsletterForms = document.querySelectorAll('form[data-newsletter]');
|
| 103 |
+
newsletterForms.forEach(form => {
|
| 104 |
+
form.addEventListener('submit', function(e) {
|
| 105 |
+
e.preventDefault();
|
| 106 |
+
const email = this.querySelector('input[type="email"]').value;
|
| 107 |
+
|
| 108 |
+
if (email && email.includes('@')) {
|
| 109 |
+
// Simulate API call
|
| 110 |
+
setTimeout(() => {
|
| 111 |
+
alert(`Thank you for subscribing with ${email}! You'll receive style inspiration weekly.`);
|
| 112 |
+
this.reset();
|
| 113 |
+
}, 300);
|
| 114 |
+
} else {
|
| 115 |
+
alert('Please enter a valid email address.');
|
| 116 |
+
}
|
| 117 |
+
});
|
| 118 |
+
});
|
| 119 |
+
});
|
style.css
CHANGED
|
@@ -1,28 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
body {
|
| 2 |
-
|
| 3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
}
|
| 5 |
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
margin-top: 0;
|
| 9 |
}
|
| 10 |
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
|
|
|
| 16 |
}
|
| 17 |
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
border-radius: 16px;
|
| 24 |
}
|
| 25 |
|
| 26 |
-
.
|
| 27 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 28 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* Custom styles for CurlCraft Studio */
|
| 2 |
+
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&family=Playfair+Display:wght@700;800&display=swap');
|
| 3 |
+
|
| 4 |
+
html {
|
| 5 |
+
scroll-behavior: smooth;
|
| 6 |
+
}
|
| 7 |
+
|
| 8 |
body {
|
| 9 |
+
font-family: 'Poppins', sans-serif;
|
| 10 |
+
}
|
| 11 |
+
|
| 12 |
+
h1, h2, h3, h4, .font-display {
|
| 13 |
+
font-family: 'Playfair Display', serif;
|
| 14 |
+
}
|
| 15 |
+
|
| 16 |
+
/* Custom scrollbar */
|
| 17 |
+
::-webkit-scrollbar {
|
| 18 |
+
width: 10px;
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
::-webkit-scrollbar-track {
|
| 22 |
+
background: #f1f1f1;
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
::-webkit-scrollbar-thumb {
|
| 26 |
+
background: linear-gradient(to bottom, #a855f7, #ec4899);
|
| 27 |
+
border-radius: 5px;
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
::-webkit-scrollbar-thumb:hover {
|
| 31 |
+
background: linear-gradient(to bottom, #9333ea, #db2777);
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
/* Animation for hairstyle cards */
|
| 35 |
+
@keyframes float {
|
| 36 |
+
0%, 100% {
|
| 37 |
+
transform: translateY(0);
|
| 38 |
+
}
|
| 39 |
+
50% {
|
| 40 |
+
transform: translateY(-10px);
|
| 41 |
+
}
|
| 42 |
}
|
| 43 |
|
| 44 |
+
.floating-card {
|
| 45 |
+
animation: float 5s ease-in-out infinite;
|
|
|
|
| 46 |
}
|
| 47 |
|
| 48 |
+
/* Gradient text */
|
| 49 |
+
.gradient-text {
|
| 50 |
+
background: linear-gradient(90deg, #a855f7, #ec4899, #f59e0b);
|
| 51 |
+
-webkit-background-clip: text;
|
| 52 |
+
-webkit-text-fill-color: transparent;
|
| 53 |
+
background-clip: text;
|
| 54 |
}
|
| 55 |
|
| 56 |
+
/* Custom button hover effect */
|
| 57 |
+
.btn-hover-effect {
|
| 58 |
+
position: relative;
|
| 59 |
+
overflow: hidden;
|
| 60 |
+
z-index: 1;
|
|
|
|
| 61 |
}
|
| 62 |
|
| 63 |
+
.btn-hover-effect::before {
|
| 64 |
+
content: '';
|
| 65 |
+
position: absolute;
|
| 66 |
+
top: 0;
|
| 67 |
+
left: -100%;
|
| 68 |
+
width: 100%;
|
| 69 |
+
height: 100%;
|
| 70 |
+
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent);
|
| 71 |
+
transition: left 0.7s;
|
| 72 |
+
z-index: -1;
|
| 73 |
}
|
| 74 |
+
|
| 75 |
+
.btn-hover-effect:hover::before {
|
| 76 |
+
left: 100%;
|
| 77 |
+
}
|