ondc-campaign-sdk
Version:
[](https://www.npmjs.com/package/ondc-campaign-sdk) [](LICENSE) [ • 40.3 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.renderPremiumElegantTemplate = renderPremiumElegantTemplate;
function renderPremiumElegantTemplate(campaignData, styleConfig = {}, templateConfig = {}) {
if (!campaignData || !campaignData.products || campaignData.products.length === 0) {
return renderNoContentState();
}
const defaultStyle = {
primaryGradient: "linear-gradient(135deg, #667eea 0%, #764ba2 100%)",
secondaryGradient: "linear-gradient(135deg, #f093fb 0%, #f5576c 100%)",
accentColor: "#ff6b6b",
textPrimary: "#2d3748",
textSecondary: "#718096",
glassBackground: "rgba(255, 255, 255, 0.25)",
shadowColor: "rgba(0, 0, 0, 0.1)"
};
const defaultTemplateConfig = {
showFloatingNav: true,
enableParallax: true,
animationIntensity: 'medium',
heroStyle: 'gradient',
cardStyle: 'glass'
};
const mergedStyle = { ...defaultStyle, ...styleConfig };
const mergedConfig = { ...defaultTemplateConfig, ...templateConfig };
const categories = extractUniqueCategories(campaignData.products);
const featuredProducts = getFeaturedProducts(campaignData.products, 6);
const bannerImages = createBannerCollection(campaignData);
return `
${generatePremiumCSS(mergedStyle, mergedConfig)}
<div class="premium-elegant-template" id="premium-campaign">
${generateFloatingNavigation(categories, mergedConfig)}
${generateHeroSection(campaignData, bannerImages, mergedConfig)}
${generateCategoryShowcase(categories, mergedConfig)}
${generateFeaturedSection(featuredProducts, campaignData, mergedConfig)}
${generateCategoryGrid(campaignData.products, categories, mergedConfig)}
${generateFooterSection()}
</div>
${generatePremiumJavaScript(mergedConfig)}
`;
}
function renderNoContentState() {
return `
<div class="no-content-state">
<div class="floating-elements">
<div class="float-element"></div>
<div class="float-element"></div>
<div class="float-element"></div>
</div>
<div class="content-center">
<div class="icon-wrapper">
<svg width="120" height="120" viewBox="0 0 24 24" fill="none" stroke="url(#iconGradient)" stroke-width="1" stroke-linecap="round" stroke-linejoin="round">
<defs>
<linearGradient id="iconGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#667eea"/>
<stop offset="100%" style="stop-color:#764ba2"/>
</linearGradient>
</defs>
<circle cx="12" cy="12" r="10"/>
<path d="M8 14s1.5 2 4 2 4-2 4-2"/>
<line x1="9" y1="9" x2="9.01" y2="9"/>
<line x1="15" y1="9" x2="15.01" y2="9"/>
</svg>
</div>
<h2>Campaign Loading...</h2>
<p>Preparing your exclusive shopping experience</p>
</div>
<style>
.no-content-state {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
position: relative;
overflow: hidden;
}
.floating-elements {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
}
.float-element {
position: absolute;
width: 20px;
height: 20px;
background: rgba(255,255,255,0.1);
border-radius: 50%;
animation: float 6s ease-in-out infinite;
}
.float-element:nth-child(1) { top: 20%; left: 20%; animation-delay: 0s; }
.float-element:nth-child(2) { top: 60%; left: 80%; animation-delay: 2s; }
.float-element:nth-child(3) { top: 80%; left: 40%; animation-delay: 4s; }
@keyframes float {
0%, 100% { transform: translateY(0px) scale(1); }
50% { transform: translateY(-20px) scale(1.1); }
}
.content-center {
text-align: center;
color: white;
z-index: 1;
}
.icon-wrapper {
margin-bottom: 2rem;
animation: pulse 2s infinite;
}
@keyframes pulse {
0% { opacity: 1; }
50% { opacity: 0.7; }
100% { opacity: 1; }
}
.content-center h2 {
font-size: 2.5rem;
margin-bottom: 1rem;
font-weight: 300;
}
.content-center p {
font-size: 1.2rem;
opacity: 0.9;
}
</style>
</div>
`;
}
function extractUniqueCategories(products) {
const categoriesSet = new Set();
products.forEach(product => {
if (product.categoryName && Array.isArray(product.categoryName)) {
product.categoryName.forEach((category) => categoriesSet.add(category));
}
});
return Array.from(categoriesSet);
}
function getFeaturedProducts(products, count) {
return [...products]
.sort((a, b) => (b.discountPercentage || 0) - (a.discountPercentage || 0))
.slice(0, count);
}
function createBannerCollection(campaignData) {
const banners = [];
if (campaignData.banner)
banners.push(campaignData.banner);
banners.push("https://images.unsplash.com/photo-1441986300917-64674bd600d8?w=1600&h=600&fit=crop");
banners.push("https://images.unsplash.com/photo-1523726491678-bf852e717f6a?w=1600&h=600&fit=crop");
return banners;
}
function generateFloatingNavigation(categories, config) {
if (!config.showFloatingNav)
return '';
const navItems = categories.slice(0, 5).map(category => `<a href="#section-${encodeURIComponent(category)}" class="nav-item" data-category="${category}">${category}</a>`).join('');
return `
<nav class="floating-nav" id="floatingNav">
<div class="nav-container">
<div class="nav-brand">✨ Premium</div>
<div class="nav-items">
<a href="#hero" class="nav-item active">Home</a>
${navItems}
<a href="#featured" class="nav-item">Featured</a>
</div>
<div class="nav-toggle" id="navToggle">
<span></span><span></span><span></span>
</div>
</div>
</nav>
`;
}
function generateHeroSection(campaignData, banners, config) {
const slides = banners.map((banner, index) => `
<div class="hero-slide ${index === 0 ? 'active' : ''}" data-index="${index}">
<div class="slide-image" style="background-image: url('${banner}')"></div>
<div class="slide-overlay"></div>
</div>
`).join('');
return `
<section class="hero-section" id="hero">
<div class="hero-slider">
${slides}
</div>
<div class="hero-content">
<div class="hero-text">
<span class="hero-badge">Premium Collection</span>
<h1 class="hero-title">${campaignData.campaignName || 'Exclusive Shopping Experience'}</h1>
<p class="hero-description">${campaignData.description || 'Discover curated products with unmatched quality and style'}</p>
<div class="hero-actions">
<button class="btn-primary" onclick="document.getElementById('featured').scrollIntoView({behavior: 'smooth'})">
Explore Collection
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M5 12h14M12 5l7 7-7 7"/>
</svg>
</button>
<button class="btn-secondary">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<polygon points="5 3 19 12 5 21 5 3"/>
</svg>
Watch Story
</button>
</div>
</div>
</div>
<div class="hero-navigation">
${banners.map((_, index) => `
<button class="hero-dot ${index === 0 ? 'active' : ''}" data-slide="${index}"></button>
`).join('')}
</div>
<div class="scroll-indicator">
<div class="scroll-line"></div>
<span>Scroll to explore</span>
</div>
</section>
`;
}
function generateCategoryShowcase(categories, config) {
if (categories.length === 0)
return '';
const categoryCards = categories.map((category, index) => {
const gradients = [
'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)',
'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)',
'linear-gradient(135deg, #43e97b 0%, #38f9d7 100%)',
'linear-gradient(135deg, #fa709a 0%, #fee140 100%)'
];
return `
<div class="category-card" data-category="${category}" style="--delay: ${index * 0.1}s">
<div class="category-background" style="background: ${gradients[index % gradients.length]}"></div>
<div class="category-content">
<div class="category-icon">
<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
<rect x="3" y="3" width="18" height="18" rx="2" ry="2"/>
<circle cx="8.5" cy="8.5" r="1.5"/>
<polyline points="21 15 16 10 5 21"/>
</svg>
</div>
<h3 class="category-name">${category}</h3>
<span class="category-arrow">→</span>
</div>
</div>
`;
}).join('');
return `
<section class="category-showcase">
<div class="container">
<div class="section-header">
<h2 class="section-title">Shop by Category</h2>
<p class="section-subtitle">Explore our carefully curated collections</p>
</div>
<div class="category-grid">
${categoryCards}
</div>
</div>
</section>
`;
}
function generateFeaturedSection(products, campaignData, config) {
const productCards = products.map((product, index) => generatePremiumProductCard(product, index, config, true)).join('');
return `
<section class="featured-section" id="featured">
<div class="container">
<div class="section-header">
<h2 class="section-title">Featured Products</h2>
<p class="section-subtitle">Handpicked items just for you</p>
</div>
<div class="products-grid featured-grid">
${productCards}
</div>
</div>
</section>
`;
}
function generateCategoryGrid(products, categories, config) {
return categories.map((category, sectionIndex) => {
const categoryProducts = products.filter(product => product.categoryName &&
Array.isArray(product.categoryName) &&
product.categoryName.includes(category)).slice(0, 8);
if (categoryProducts.length === 0)
return '';
const productCards = categoryProducts.map((product, index) => generatePremiumProductCard(product, index, config, false)).join('');
return `
<section class="category-section" id="section-${encodeURIComponent(category)}" data-category="${category}">
<div class="container">
<div class="section-header">
<h2 class="section-title">${category}</h2>
<a href="#" class="view-all-link">View All →</a>
</div>
<div class="products-grid">
${productCards}
</div>
</div>
</section>
`;
}).join('');
}
function generateFooterSection() {
return `
<footer class="premium-footer">
<div class="footer-background">
<div class="footer-shapes">
<div class="shape shape-1"></div>
<div class="shape shape-2"></div>
<div class="shape shape-3"></div>
</div>
</div>
<div class="container">
<div class="footer-content">
<div class="footer-brand">
<h3>✨ Premium Campaign</h3>
<p>Crafted with love using ONDC Campaign SDK</p>
</div>
<div class="footer-links">
<div class="link-group">
<h4>Explore</h4>
<a href="#featured">Featured</a>
<a href="#categories">Categories</a>
<a href="#deals">Deals</a>
</div>
<div class="link-group">
<h4>Support</h4>
<a href="#help">Help Center</a>
<a href="#contact">Contact Us</a>
<a href="#returns">Returns</a>
</div>
</div>
</div>
<div class="footer-bottom">
<p>© 2024 Premium Collection. Powered by ONDC Campaign SDK.</p>
</div>
</div>
</footer>
`;
}
function generatePremiumProductCard(product, index, config, isFeatured = false) {
const productName = product.productName || '';
const productId = product.productId || '';
const imageUrl = product.imgUrl || (product.galleryImages && product.galleryImages.length > 0 ? product.galleryImages[0].url : '');
const discountPercent = product.discountPercentage || 0;
const regularPrice = product.regularPrice || 0;
const discountedPrice = product.discountedPrice || regularPrice;
const brandName = product.brandName || '';
const rating = product.productRatings || 0;
const formattedRegularPrice = `₹${regularPrice.toLocaleString('en-IN')}`;
const formattedDiscountedPrice = `₹${discountedPrice.toLocaleString('en-IN')}`;
const animationDelay = config.animationIntensity !== 'subtle' ?
`style="animation-delay: ${index * 0.15}s;"` : '';
const productNameSlug = productName
.toLowerCase()
.replace(/[^a-z0-9\s-]/g, '')
.replace(/\s+/g, '-')
.replace(/-+/g, '-');
const productUrl = `https://shop.samhita.org/product/${productNameSlug}/${productId}`;
const cardClass = isFeatured ? 'product-card featured-card' : 'product-card';
const cardStyle = config.cardStyle;
return `
<div class="${cardClass} ${cardStyle}-style" ${animationDelay} data-product-id="${productId}">
<div class="product-image-container">
<div class="product-image" style="background-image: url('${imageUrl}')">
<div class="image-overlay"></div>
${discountPercent > 0 ?
`<div class="discount-badge">
<span>-${discountPercent}%</span>
</div>` : ''}
<div class="product-actions">
<button class="action-btn wishlist-btn" aria-label="Add to wishlist">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78L12 21.23l8.84-8.84a5.5 5.5 0 0 0 0-7.78z"/>
</svg>
</button>
<button class="action-btn quick-view-btn" aria-label="Quick view">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/>
<circle cx="12" cy="12" r="3"/>
</svg>
</button>
</div>
</div>
</div>
<div class="product-details">
${brandName ? `<div class="product-brand">${brandName}</div>` : ''}
<h3 class="product-name">
<a href="${productUrl}" target="_blank">${productName}</a>
</h3>
${rating > 0 ? `
<div class="product-rating">
<div class="stars">
${Array(5).fill('').map((_, i) => `<span class="star ${i < rating ? 'filled' : ''}">★</span>`).join('')}
</div>
<span class="rating-value">${rating.toFixed(1)}</span>
</div>
` : ''}
<div class="product-price">
${discountedPrice < regularPrice ?
`<span class="current-price">${formattedDiscountedPrice}</span>
<span class="original-price">${formattedRegularPrice}</span>` :
`<span class="current-price">${formattedRegularPrice}</span>`}
</div>
<button class="add-to-cart-btn" data-product-id="${productId}" data-url="${productUrl}">
<span>Add to Cart</span>
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="9" cy="21" r="1"/>
<circle cx="20" cy="21" r="1"/>
<path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"/>
</svg>
</button>
</div>
</div>
`;
}
function generatePremiumCSS(style, config) {
return `
<style>
:root {
--primary-gradient: ${style.primaryGradient};
--secondary-gradient: ${style.secondaryGradient};
--accent: ${style.accentColor};
--text-primary: ${style.textPrimary};
--text-secondary: ${style.textSecondary};
--glass-bg: ${style.glassBackground};
--shadow-color: ${style.shadowColor};
--animation-intensity: ${config.animationIntensity === 'intense' ? '1' : config.animationIntensity === 'medium' ? '0.7' : '0.3'};
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
line-height: 1.6;
color: var(--text-primary);
overflow-x: hidden;
}
.container {
max-width: 1400px;
margin: 0 auto;
padding: 0 2rem;
}
/* Floating Navigation */
.floating-nav {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 1000;
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(20px);
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
transition: all 0.3s ease;
}
.nav-container {
max-width: 1400px;
margin: 0 auto;
padding: 1rem 2rem;
display: flex;
align-items: center;
justify-content: space-between;
}
.nav-brand {
font-size: 1.5rem;
font-weight: 700;
background: var(--primary-gradient);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.nav-items {
display: flex;
gap: 2rem;
}
.nav-item {
color: var(--text-primary);
text-decoration: none;
font-weight: 500;
padding: 0.5rem 1rem;
border-radius: 25px;
transition: all 0.3s ease;
position: relative;
}
.nav-item:hover,
.nav-item.active {
background: var(--primary-gradient);
color: white;
transform: translateY(-2px);
}
.nav-toggle {
display: none;
flex-direction: column;
cursor: pointer;
gap: 4px;
}
.nav-toggle span {
width: 25px;
height: 3px;
background: var(--text-primary);
border-radius: 3px;
transition: all 0.3s ease;
}
/* Hero Section */
.hero-section {
height: 100vh;
position: relative;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
}
.hero-slider {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.hero-slide {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
transition: opacity 1s ease;
}
.hero-slide.active {
opacity: 1;
}
.slide-image {
width: 100%;
height: 100%;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
.slide-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(135deg, rgba(102, 126, 234, 0.8) 0%, rgba(118, 75, 162, 0.8) 100%);
}
.hero-content {
position: relative;
z-index: 10;
text-align: center;
color: white;
max-width: 800px;
padding: 0 2rem;
}
.hero-badge {
display: inline-block;
padding: 0.5rem 1.5rem;
background: rgba(255, 255, 255, 0.2);
border-radius: 25px;
font-size: 0.9rem;
font-weight: 500;
margin-bottom: 1.5rem;
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.3);
}
.hero-title {
font-size: 4rem;
font-weight: 700;
margin-bottom: 1.5rem;
line-height: 1.2;
animation: fadeInUp 1s ease var(--animation-intensity);
}
.hero-description {
font-size: 1.3rem;
margin-bottom: 3rem;
opacity: 0.9;
animation: fadeInUp 1s ease calc(var(--animation-intensity) + 0.2s);
}
.hero-actions {
display: flex;
gap: 1.5rem;
justify-content: center;
flex-wrap: wrap;
animation: fadeInUp 1s ease calc(var(--animation-intensity) + 0.4s);
}
.btn-primary,
.btn-secondary {
padding: 1rem 2rem;
border-radius: 50px;
font-weight: 600;
font-size: 1.1rem;
border: none;
cursor: pointer;
display: flex;
align-items: center;
gap: 0.5rem;
transition: all 0.3s ease;
text-decoration: none;
}
.btn-primary {
background: white;
color: var(--text-primary);
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
}
.btn-primary:hover {
transform: translateY(-3px);
box-shadow: 0 15px 40px rgba(0, 0, 0, 0.3);
}
.btn-secondary {
background: transparent;
color: white;
border: 2px solid rgba(255, 255, 255, 0.5);
backdrop-filter: blur(10px);
}
.btn-secondary:hover {
background: rgba(255, 255, 255, 0.2);
transform: translateY(-3px);
}
.hero-navigation {
position: absolute;
bottom: 30px;
left: 50%;
transform: translateX(-50%);
display: flex;
gap: 1rem;
z-index: 10;
}
.hero-dot {
width: 12px;
height: 12px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.5);
border: none;
cursor: pointer;
transition: all 0.3s ease;
}
.hero-dot.active {
background: white;
transform: scale(1.3);
}
.scroll-indicator {
position: absolute;
bottom: 80px;
right: 30px;
color: white;
font-size: 0.9rem;
display: flex;
align-items: center;
gap: 1rem;
opacity: 0.8;
z-index: 10;
}
.scroll-line {
width: 2px;
height: 40px;
background: linear-gradient(to bottom, transparent, white, transparent);
animation: scroll-pulse 2s infinite;
}
/* Category Showcase */
.category-showcase {
padding: 6rem 0;
background: linear-gradient(135deg, #f8f9ff 0%, #f0f4ff 100%);
}
.section-header {
text-align: center;
margin-bottom: 4rem;
}
.section-title {
font-size: 3rem;
font-weight: 700;
margin-bottom: 1rem;
background: var(--primary-gradient);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.section-subtitle {
font-size: 1.2rem;
color: var(--text-secondary);
max-width: 600px;
margin: 0 auto;
}
.category-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 2rem;
}
.category-card {
position: relative;
height: 200px;
border-radius: 20px;
overflow: hidden;
cursor: pointer;
transition: all 0.5s ease;
animation: fadeInUp 0.8s ease both;
animation-delay: var(--delay);
}
.category-card:hover {
transform: translateY(-10px) scale(1.02);
}
.category-background {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
transition: all 0.5s ease;
}
.category-card:hover .category-background {
transform: scale(1.1);
}
.category-content {
position: relative;
z-index: 2;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
color: white;
text-align: center;
padding: 2rem;
}
.category-icon {
margin-bottom: 1rem;
opacity: 0.9;
}
.category-name {
font-size: 1.5rem;
font-weight: 600;
margin-bottom: 1rem;
}
.category-arrow {
font-size: 1.5rem;
opacity: 0.8;
transition: all 0.3s ease;
}
.category-card:hover .category-arrow {
transform: translateX(5px);
}
/* Products Grid */
.featured-section,
.category-section {
padding: 6rem 0;
}
.category-section:nth-child(even) {
background: rgba(248, 249, 255, 0.5);
}
.products-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
gap: 2rem;
}
.featured-grid {
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
}
.view-all-link {
color: var(--accent);
text-decoration: none;
font-weight: 600;
display: flex;
align-items: center;
gap: 0.5rem;
transition: all 0.3s ease;
}
.view-all-link:hover {
transform: translateX(5px);
}
/* Product Cards */
.product-card {
background: white;
border-radius: 20px;
overflow: hidden;
transition: all 0.5s ease;
animation: fadeInUp 0.8s ease both;
position: relative;
}
.glass-style {
background: var(--glass-bg);
backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 0.3);
}
.elevated-style {
box-shadow: 0 10px 40px var(--shadow-color);
}
.neumorphism-style {
background: #f0f0f0;
box-shadow: 20px 20px 40px #d1d1d1, -20px -20px 40px #ffffff;
}
.product-card:hover {
transform: translateY(-15px);
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.15);
}
.featured-card {
transform: scale(1.05);
}
.product-image-container {
position: relative;
height: 280px;
overflow: hidden;
}
.product-image {
width: 100%;
height: 100%;
background-size: cover;
background-position: center;
transition: all 0.5s ease;
}
.product-card:hover .product-image {
transform: scale(1.1);
}
.image-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(to bottom, transparent 60%, rgba(0,0,0,0.7));
opacity: 0;
transition: all 0.3s ease;
}
.product-card:hover .image-overlay {
opacity: 1;
}
.discount-badge {
position: absolute;
top: 1rem;
right: 1rem;
background: var(--accent);
color: white;
padding: 0.5rem 1rem;
border-radius: 15px;
font-weight: 600;
font-size: 0.9rem;
z-index: 3;
}
.product-actions {
position: absolute;
top: 1rem;
left: 1rem;
display: flex;
flex-direction: column;
gap: 0.5rem;
opacity: 0;
transform: translateX(-20px);
transition: all 0.3s ease;
z-index: 3;
}
.product-card:hover .product-actions {
opacity: 1;
transform: translateX(0);
}
.action-btn {
width: 40px;
height: 40px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.9);
border: none;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease;
backdrop-filter: blur(10px);
}
.action-btn:hover {
background: white;
transform: scale(1.1);
}
.product-details {
padding: 1.5rem;
}
.product-brand {
font-size: 0.9rem;
color: var(--text-secondary);
margin-bottom: 0.5rem;
font-weight: 500;
}
.product-name {
margin-bottom: 1rem;
}
.product-name a {
font-size: 1.2rem;
font-weight: 600;
color: var(--text-primary);
text-decoration: none;
line-height: 1.4;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
transition: color 0.3s ease;
}
.product-name a:hover {
color: var(--accent);
}
.product-rating {
display: flex;
align-items: center;
gap: 0.5rem;
margin-bottom: 1rem;
}
.stars {
display: flex;
gap: 2px;
}
.star {
color: #ddd;
font-size: 1.1rem;
}
.star.filled {
color: #ffc107;
}
.rating-value {
font-size: 0.9rem;
color: var(--text-secondary);
font-weight: 500;
}
.product-price {
display: flex;
align-items: center;
gap: 1rem;
margin-bottom: 1.5rem;
}
.current-price {
font-size: 1.5rem;
font-weight: 700;
color: var(--accent);
}
.original-price {
font-size: 1.1rem;
color: var(--text-secondary);
text-decoration: line-through;
}
.add-to-cart-btn {
width: 100%;
padding: 1rem;
background: var(--primary-gradient);
color: white;
border: none;
border-radius: 15px;
font-weight: 600;
font-size: 1rem;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
transition: all 0.3s ease;
}
.add-to-cart-btn:hover {
transform: translateY(-2px);
box-shadow: 0 10px 25px rgba(102, 126, 234, 0.3);
}
/* Footer */
.premium-footer {
position: relative;
background: linear-gradient(135deg, #2d3748 0%, #1a202c 100%);
color: white;
padding: 4rem 0 2rem;
overflow: hidden;
}
.footer-background {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0.1;
}
.footer-shapes {
position: relative;
width: 100%;
height: 100%;
}
.shape {
position: absolute;
border-radius: 50%;
background: white;
}
.shape-1 {
width: 200px;
height: 200px;
top: -100px;
right: -100px;
}
.shape-2 {
width: 150px;
height: 150px;
bottom: -75px;
left: -75px;
}
.shape-3 {
width: 100px;
height: 100px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.footer-content {
position: relative;
z-index: 2;
display: grid;
grid-template-columns: 2fr 1fr 1fr;
gap: 3rem;
margin-bottom: 2rem;
}
.footer-brand h3 {
font-size: 1.8rem;
margin-bottom: 1rem;
}
.footer-brand p {
opacity: 0.8;
font-size: 1.1rem;
}
.link-group h4 {
margin-bottom: 1rem;
font-size: 1.2rem;
}
.link-group a {
display: block;
color: rgba(255, 255, 255, 0.8);
text-decoration: none;
margin-bottom: 0.5rem;
transition: color 0.3s ease;
}
.link-group a:hover {
color: white;
}
.footer-bottom {
position: relative;
z-index: 2;
text-align: center;
padding-top: 2rem;
border-top: 1px solid rgba(255, 255, 255, 0.2);
opacity: 0.8;
}
/* Animations */
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes scroll-pulse {
0%, 100% {
opacity: 0.6;
}
50% {
opacity: 1;
}
}
/* Responsive Design */
@media (max-width: 1200px) {
.hero-title {
font-size: 3rem;
}
.section-title {
font-size: 2.5rem;
}
}
@media (max-width: 768px) {
.nav-items {
display: none;
}
.nav-toggle {
display: flex;
}
.hero-title {
font-size: 2.5rem;
}
.hero-description {
font-size: 1.1rem;
}
.hero-actions {
flex-direction: column;
align-items: center;
}
.btn-primary,
.btn-secondary {
width: 100%;
max-width: 300px;
}
.category-grid {
grid-template-columns: 1fr;
}
.products-grid,
.featured-grid {
grid-template-columns: 1fr;
}
.footer-content {
grid-template-columns: 1fr;
text-align: center;
}
.container {
padding: 0 1rem;
}
}
@media (max-width: 480px) {
.hero-title {
font-size: 2rem;
}
.section-title {
font-size: 2rem;
}
.product-card {
margin: 0 1rem;
}
}
</style>
`;
}
function generatePremiumJavaScript(config) {
return `
<script>
(function() {
// Hero Slider
const heroSlides = document.querySelectorAll('.hero-slide');
const heroDots = document.querySelectorAll('.hero-dot');
let currentSlide = 0;
const slideCount = heroSlides.length;
function goToSlide(index) {
heroSlides.forEach(slide => slide.classList.remove('active'));
heroDots.forEach(dot => dot.classList.remove('active'));
heroSlides[index].classList.add('active');
heroDots[index].classList.add('active');
currentSlide = index;
}
function nextSlide() {
goToSlide((currentSlide + 1) % slideCount);
}
// Auto-advance slides
setInterval(nextSlide, 5000);
// Dot navigation
heroDots.forEach((dot, index) => {
dot.addEventListener('click', () => goToSlide(index));
});
// Floating Navigation
const nav = document.getElementById('floatingNav');
const navToggle = document.getElementById('navToggle');
window.addEventListener('scroll', () => {
if (window.scrollY > 100) {
nav.style.background = 'rgba(255, 255, 255, 0.98)';
nav.style.boxShadow = '0 10px 30px rgba(0, 0, 0, 0.1)';
} else {
nav.style.background = 'rgba(255, 255, 255, 0.95)';
nav.style.boxShadow = 'none';
}
});
// Smooth scroll for navigation
document.querySelectorAll('.nav-item[href^="#"]').forEach(link => {
link.addEventListener('click', (e) => {
e.preventDefault();
const target = document.querySelector(link.getAttribute('href'));
if (target) {
target.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
});
});
// Category cards click
document.querySelectorAll('.category-card').forEach(card => {
card.addEventListener('click', () => {
const category = card.getAttribute('data-category');
const section = document.getElementById(\`section-\${encodeURIComponent(category)}\`);
if (section) {
section.scrollIntoView({ behavior: 'smooth' });
}
});
});
// Product interactions
document.querySelectorAll('.wishlist-btn').forEach(btn => {
btn.addEventListener('click', (e) => {
e.stopPropagation();
btn.innerHTML = '<svg width="20" height="20" viewBox="0 0 24 24" fill="red" stroke="red" stroke-width="2"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78L12 21.23l8.84-8.84a5.5 5.5 0 0 0 0-7.78z"/></svg>';
});
});
document.querySelectorAll('.add-to-cart-btn').forEach(btn => {
btn.addEventListener('click', () => {
const productId = btn.getAttribute('data-product-id');
const url = btn.getAttribute('data-url');
// Add loading state
btn.innerHTML = '<span>Adding...</span>';
btn.style.opacity = '0.7';
// Simulate add to cart (replace with actual API call)
setTimeout(() => {
btn.innerHTML = '<span>Added!</span>';
setTimeout(() => {
window.open(url, '_blank');
}, 500);
}, 1000);
});
});
// Intersection Observer for animations
const observerOptions = {
threshold: 0.1,
rootMargin: '0px 0px -50px 0px'
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.style.animationPlayState = 'running';
}
});
}, observerOptions);
// Observe animated elements
document.querySelectorAll('.product-card, .category-card').forEach(el => {
observer.observe(el);
});
// Parallax effect for hero section
${config.enableParallax ? `
window.addEventListener('scroll', () => {
const scrolled = window.pageYOffset;
const heroSlider = document.querySelector('.hero-slider');
if (heroSlider) {
heroSlider.style.transform = \`translateY(\${scrolled * 0.5}px)\`;
}
});
` : ''}
// Mobile menu toggle
if (navToggle) {
navToggle.addEventListener('click', () => {
const navItems = document.querySelector('.nav-items');
navItems.style.display = navItems.style.display === 'flex' ? 'none' : 'flex';
});
}
})();
</script>
`;
}