Contact
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>NEXUS STORE — 3D Shopping Experience</title>
<link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700;900&family=Rajdhani:wght@300;400;600&display=swap" rel="stylesheet">
<style>
:root {
--neon: #00f5ff;
--neon2: #ff00aa;
--dark: #020812;
--card: rgba(0,245,255,0.05);
--border: rgba(0,245,255,0.2);
--text: #c8f0ff;
}
* { margin:0; padding:0; box-sizing:border-box; }
body {
background: var(--dark);
color: var(--text);
font-family: 'Rajdhani', sans-serif;
overflow-x: hidden;
cursor: crosshair;
}
/* CANVAS BG */
#bg-canvas {
position: fixed;
top:0; left:0;
width:100%; height:100%;
z-index: 0;
pointer-events: none;
}
/* NAV */
nav {
position: fixed;
top:0; left:0; right:0;
z-index: 100;
display: flex;
justify-content: space-between;
align-items: center;
padding: 18px 40px;
background: rgba(2,8,18,0.7);
backdrop-filter: blur(20px);
border-bottom: 1px solid var(--border);
}
.logo {
font-family: 'Orbitron', monospace;
font-size: 1.4rem;
font-weight: 900;
letter-spacing: 4px;
color: var(--neon);
text-shadow: 0 0 20px var(--neon);
}
.logo span { color: var(--neon2); }
.nav-links { display:flex; gap:30px; list-style:none; }
.nav-links a {
color: var(--text);
text-decoration: none;
font-size: 0.85rem;
letter-spacing: 2px;
text-transform: uppercase;
transition: color 0.3s;
}
.nav-links a:hover { color: var(--neon); text-shadow: 0 0 10px var(--neon); }
.cart-btn {
background: transparent;
border: 1px solid var(--neon);
color: var(--neon);
padding: 8px 20px;
font-family: 'Orbitron', monospace;
font-size: 0.75rem;
letter-spacing: 2px;
cursor: pointer;
transition: all 0.3s;
position: relative;
}
.cart-btn:hover { background: var(--neon); color: var(--dark); box-shadow: 0 0 30px var(--neon); }
.cart-count {
position: absolute;
top: -8px; right: -8px;
background: var(--neon2);
color: white;
width: 18px; height: 18px;
border-radius: 50%;
font-size: 0.65rem;
display: flex; align-items:center; justify-content:center;
font-family: 'Orbitron', monospace;
}
/* HERO */
.hero {
position: relative;
z-index: 1;
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
padding: 20px;
}
.hero-tag {
font-size: 0.7rem;
letter-spacing: 6px;
color: var(--neon2);
text-transform: uppercase;
margin-bottom: 20px;
animation: fadeUp 1s ease 0.2s both;
}
.hero h1 {
font-family: 'Orbitron', monospace;
font-size: clamp(2.5rem, 8vw, 7rem);
font-weight: 900;
line-height: 0.9;
margin-bottom: 30px;
animation: fadeUp 1s ease 0.4s both;
}
.hero h1 .glow {
color: var(--neon);
text-shadow: 0 0 40px var(--neon), 0 0 80px var(--neon);
}
.hero h1 .glow2 {
color: var(--neon2);
text-shadow: 0 0 40px var(--neon2), 0 0 80px var(--neon2);
}
.hero p {
font-size: 1.1rem;
max-width: 500px;
color: rgba(200,240,255,0.6);
letter-spacing: 1px;
margin-bottom: 40px;
animation: fadeUp 1s ease 0.6s both;
}
.hero-btns {
display: flex; gap: 16px;
animation: fadeUp 1s ease 0.8s both;
}
.btn-primary {
background: var(--neon);
color: var(--dark);
border: none;
padding: 14px 36px;
font-family: 'Orbitron', monospace;
font-size: 0.8rem;
letter-spacing: 2px;
cursor: pointer;
transition: all 0.3s;
clip-path: polygon(10px 0%, 100% 0%, calc(100% - 10px) 100%, 0% 100%);
}
.btn-primary:hover { box-shadow: 0 0 40px var(--neon); transform: scale(1.05); }
.btn-secondary {
background: transparent;
color: var(--neon2);
border: 1px solid var(--neon2);
padding: 14px 36px;
font-family: 'Orbitron', monospace;
font-size: 0.8rem;
letter-spacing: 2px;
cursor: pointer;
transition: all 0.3s;
clip-path: polygon(10px 0%, 100% 0%, calc(100% - 10px) 100%, 0% 100%);
}
.btn-secondary:hover { background: var(--neon2); color: white; box-shadow: 0 0 40px var(--neon2); }
.scroll-hint {
position: absolute;
bottom: 40px;
display: flex; flex-direction: column; align-items: center; gap: 8px;
animation: fadeUp 1s ease 1.2s both;
}
.scroll-hint span { font-size: 0.65rem; letter-spacing: 4px; color: rgba(200,240,255,0.4); text-transform: uppercase; }
.scroll-line {
width: 1px; height: 50px;
background: linear-gradient(to bottom, var(--neon), transparent);
animation: scrollPulse 2s ease infinite;
}
/* PRODUCTS */
.section {
position: relative;
z-index: 1;
padding: 100px 40px;
max-width: 1400px;
margin: 0 auto;
}
.section-header {
display: flex;
justify-content: space-between;
align-items: flex-end;
margin-bottom: 60px;
}
.section-title {
font-family: 'Orbitron', monospace;
font-size: 2rem;
font-weight: 700;
color: white;
}
.section-title span { color: var(--neon); }
.section-sub { font-size: 0.75rem; letter-spacing: 3px; color: rgba(200,240,255,0.4); text-transform: uppercase; margin-top: 8px; }
.view-all {
color: var(--neon2);
font-size: 0.75rem;
letter-spacing: 2px;
text-transform: uppercase;
text-decoration: none;
border-bottom: 1px solid var(--neon2);
padding-bottom: 2px;
cursor: pointer;
}
.product-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 24px;
}
.product-card {
background: var(--card);
border: 1px solid var(--border);
padding: 24px;
position: relative;
overflow: hidden;
transition: all 0.4s ease;
cursor: pointer;
animation: cardAppear 0.6s ease both;
}
.product-card::before {
content: '';
position: absolute;
top: 0; left: 0; right: 0;
height: 2px;
background: linear-gradient(90deg, transparent, var(--neon), transparent);
transform: scaleX(0);
transition: transform 0.4s;
}
.product-card:hover { transform: translateY(-8px) scale(1.01); border-color: var(--neon); box-shadow: 0 20px 60px rgba(0,245,255,0.15), inset 0 0 40px rgba(0,245,255,0.03); }
.product-card:hover::before { transform: scaleX(1); }
.product-3d-wrap {
width: 100%; height: 200px;
display: flex; align-items: center; justify-content: center;
margin-bottom: 20px;
position: relative;
}
.product-canvas { width: 100%; height: 100%; }
.product-badge {
position: absolute;
top: 16px; right: 16px;
background: var(--neon2);
color: white;
font-size: 0.6rem;
letter-spacing: 2px;
padding: 4px 10px;
text-transform: uppercase;
font-family: 'Orbitron', monospace;
}
.product-name {
font-family: 'Orbitron', monospace;
font-size: 0.9rem;
font-weight: 700;
color: white;
margin-bottom: 6px;
letter-spacing: 1px;
}
.product-desc {
font-size: 0.8rem;
color: rgba(200,240,255,0.5);
margin-bottom: 16px;
line-height: 1.5;
}
.product-footer {
display: flex;
align-items: center;
justify-content: space-between;
}
.product-price {
font-family: 'Orbitron', monospace;
font-size: 1.2rem;
color: var(--neon);
text-shadow: 0 0 10px var(--neon);
}
.product-price .old { font-size: 0.75rem; color: rgba(200,240,255,0.3); text-decoration: line-through; margin-right: 6px; font-family: 'Rajdhani'; text-shadow: none; }
.add-btn {
background: transparent;
border: 1px solid var(--neon);
color: var(--neon);
padding: 8px 16px;
font-family: 'Orbitron', monospace;
font-size: 0.65rem;
letter-spacing: 1px;
cursor: pointer;
transition: all 0.3s;
}
.add-btn:hover { background: var(--neon); color: var(--dark); box-shadow: 0 0 20px var(--neon); }
.add-btn.added { background: var(--neon2); border-color: var(--neon2); color: white; }
/* CART PANEL */
.cart-panel {
position: fixed;
top:0; right:0; bottom:0;
width: 380px;
background: rgba(2,8,18,0.95);
backdrop-filter: blur(30px);
border-left: 1px solid var(--border);
z-index: 200;
transform: translateX(100%);
transition: transform 0.4s cubic-bezier(0.4,0,0.2,1);
display: flex; flex-direction: column;
padding: 30px;
}
.cart-panel.open { transform: translateX(0); }
.cart-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 30px;
padding-bottom: 20px;
border-bottom: 1px solid var(--border);
}
.cart-header h2 {
font-family: 'Orbitron', monospace;
font-size: 1rem;
letter-spacing: 3px;
color: var(--neon);
}
.close-cart {
background: none; border: none; color: var(--text);
font-size: 1.5rem; cursor: pointer; transition: color 0.2s;
}
.close-cart:hover { color: var(--neon2); }
.cart-items { flex:1; overflow-y:auto; }
.cart-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px 0;
border-bottom: 1px solid rgba(0,245,255,0.08);
}
.cart-item-name { font-size: 0.85rem; font-weight: 600; color: white; }
.cart-item-price { font-family: 'Orbitron', monospace; font-size: 0.85rem; color: var(--neon); }
.remove-item { background:none; border:none; color:rgba(200,240,255,0.3); cursor:pointer; font-size:1.1rem; transition:color 0.2s; }
.remove-item:hover { color: var(--neon2); }
.cart-empty { color: rgba(200,240,255,0.3); font-size: 0.85rem; text-align:center; margin-top: 60px; letter-spacing: 1px; }
.cart-total {
padding-top: 20px;
border-top: 1px solid var(--border);
margin-top: 20px;
}
.total-row { display:flex; justify-content:space-between; margin-bottom:20px; }
.total-row span:first-child { font-size:0.75rem; letter-spacing:3px; text-transform:uppercase; color:rgba(200,240,255,0.5); }
.total-row span:last-child { font-family:'Orbitron',monospace; font-size:1.3rem; color:var(--neon); text-shadow:0 0 10px var(--neon); }
.checkout-btn {
width: 100%;
background: linear-gradient(90deg, var(--neon), #00aaff);
border: none;
color: var(--dark);
padding: 16px;
font-family: 'Orbitron', monospace;
font-size: 0.85rem;
letter-spacing: 3px;
cursor: pointer;
transition: all 0.3s;
text-transform: uppercase;
}
.checkout-btn:hover { box-shadow: 0 0 40px var(--neon); transform: scale(1.02); }
/* OVERLAY */
.overlay { position:fixed; inset:0; z-index:150; background:rgba(0,0,0,0.5); opacity:0; pointer-events:none; transition:opacity 0.4s; }
.overlay.active { opacity:1; pointer-events:all; }
/* FOOTER */
footer {
position: relative; z-index:1;
padding: 60px 40px 40px;
border-top: 1px solid var(--border);
display: grid;
grid-template-columns: 2fr 1fr 1fr 1fr;
gap: 40px;
max-width: 1400px;
margin: 0 auto;
}
.footer-brand .logo { font-size:1.1rem; margin-bottom:16px; display:block; }
.footer-brand p { font-size:0.8rem; color:rgba(200,240,255,0.4); line-height:1.7; max-width:260px; }
.footer-col h4 { font-family:'Orbitron',monospace; font-size:0.65rem; letter-spacing:3px; color:var(--neon); text-transform:uppercase; margin-bottom:16px; }
.footer-col a { display:block; color:rgba(200,240,255,0.4); text-decoration:none; font-size:0.8rem; margin-bottom:10px; transition:color 0.2s; letter-spacing:1px; }
.footer-col a:hover { color:var(--neon); }
.footer-bottom {
position:relative; z-index:1;
text-align:center; padding:20px;
font-size:0.7rem; color:rgba(200,240,255,0.2);
letter-spacing:2px; border-top:1px solid rgba(0,245,255,0.05);
}
/* ANIMATIONS */
@keyframes fadeUp { from { opacity:0; transform:translateY(30px); } to { opacity:1; transform:translateY(0); } }
@keyframes scrollPulse { 0%,100% { opacity:1; } 50% { opacity:0.2; } }
@keyframes cardAppear { from { opacity:0; transform:translateY(20px); } to { opacity:1; transform:translateY(0); } }
@keyframes spin3d { from { transform: rotateY(0deg) rotateX(10deg); } to { transform: rotateY(360deg) rotateX(10deg); } }
@media(max-width:768px) {
nav { padding:14px 20px; }
.nav-links { display:none; }
.section { padding:60px 20px; }
footer { grid-template-columns:1fr; }
.cart-panel { width:100%; }
}
</style>
</head>
<body>
<canvas id="bg-canvas"></canvas>
<!-- NAV -->
<nav>
<div class="logo">NEX<span>US</span></div>
<ul class="nav-links">
<li><a href="#">Home</a></li>
<li><a href="#">Products</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Contact</a></li>
</ul>
<button class="cart-btn" onclick="toggleCart()">
CART <span class="cart-count" id="cartCount">0</span>
</button>
</nav>
<!-- HERO -->
<section class="hero">
<div class="hero-tag">▸ Next-gen shopping experience</div>
<h1>
<span class="glow">SHOP</span><br>
THE <span class="glow2">FUTURE</span>
</h1>
<p>Immersive 3D products, cutting-edge tech. Experience shopping like never before.</p>
<div class="hero-btns">
<button class="btn-primary" onclick="document.querySelector('.section').scrollIntoView({behavior:'smooth'})">EXPLORE NOW</button>
<button class="btn-secondary">WATCH DEMO</button>
</div>
<div class="scroll-hint">
<span>Scroll</span>
<div class="scroll-line"></div>
</div>
</section>
<!-- PRODUCTS -->
<div class="section">
<div class="section-header">
<div>
<div class="section-title">FEATURED <span>PRODUCTS</span></div>
<div class="section-sub">// curated collection</div>
</div>
<span class="view-all">View All →</span>
</div>
<div class="product-grid" id="productGrid"></div>
</div>
<!-- CART PANEL -->
<div class="overlay" id="overlay" onclick="toggleCart()"></div>
<div class="cart-panel" id="cartPanel">
<div class="cart-header">
<h2>// CART</h2>
<button class="close-cart" onclick="toggleCart()">✕</button>
</div>
<div class="cart-items" id="cartItems">
<div class="cart-empty">Your cart is empty.<br>Add some products!</div>
</div>
<div class="cart-total">
<div class="total-row">
<span>Total</span>
<span id="cartTotal">$0.00</span>
</div>
<button class="checkout-btn">CHECKOUT →</button>
</div>
</div>
<!-- FOOTER -->
<footer>
<div class="footer-brand">
<span class="logo">NEX<span>US</span></span>
<p>The future of online shopping. Immersive, fast, and extraordinary products delivered to your door.</p>
</div>
<div class="footer-col">
<h4>Shop</h4>
<a href="#">New Arrivals</a>
<a href="#">Best Sellers</a>
<a href="#">Sale</a>
<a href="#">Collections</a>
</div>
<div class="footer-col">
<h4>Support</h4>
<a href="#">FAQ</a>
<a href="#">Shipping</a>
<a href="#">Returns</a>
<a href="#">Contact</a>
</div>
<div class="footer-col">
<h4>Company</h4>
<a href="#">About</a>
<a href="#">Blog</a>
<a href="#">Careers</a>
<a href="#">Press</a>
</div>
</footer>
<div class="footer-bottom">© 2026 NEXUS STORE — ALL RIGHTS RESERVED</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script>
// ===== BACKGROUND 3D SCENE =====
const bgCanvas = document.getElementById('bg-canvas');
const bgRenderer = new THREE.WebGLRenderer({ canvas: bgCanvas, alpha: true, antialias: true });
bgRenderer.setSize(window.innerWidth, window.innerHeight);
bgRenderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
const bgScene = new THREE.Scene();
const bgCamera = new THREE.PerspectiveCamera(60, window.innerWidth/window.innerHeight, 0.1, 1000);
bgCamera.position.z = 30;
// Floating particles
const particleGeo = new THREE.BufferGeometry();
const pCount = 800;
const positions = new Float32Array(pCount * 3);
for (let i = 0; i < pCount * 3; i++) {
positions[i] = (Math.random() - 0.5) * 100;
}
particleGeo.setAttribute('position', new THREE.BufferAttribute(positions, 3));
const particleMat = new THREE.PointsMaterial({ color: 0x00f5ff, size: 0.15, transparent: true, opacity: 0.6 });
const particles = new THREE.Points(particleGeo, particleMat);
bgScene.add(particles);
// Floating torus rings
const rings = [];
for (let i = 0; i < 5; i++) {
const geo = new THREE.TorusGeometry(3 + i*2, 0.05, 8, 60);
const mat = new THREE.MeshBasicMaterial({ color: i%2===0 ? 0x00f5ff : 0xff00aa, transparent: true, opacity: 0.15 });
const ring = new THREE.Mesh(geo, mat);
ring.position.set((Math.random()-0.5)*40, (Math.random()-0.5)*30, (Math.random()-0.5)*20 - 10);
ring.rotation.set(Math.random()*Math.PI, Math.random()*Math.PI, 0);
bgScene.add(ring);
rings.push(ring);
}
let mouseX=0, mouseY=0;
document.addEventListener('mousemove', e => {
mouseX = (e.clientX/window.innerWidth - 0.5) * 2;
mouseY = (e.clientY/window.innerHeight - 0.5) * 2;
});
function animateBg(t) {
requestAnimationFrame(animateBg);
const time = t * 0.001;
particles.rotation.y = time * 0.05;
particles.rotation.x = time * 0.02;
rings.forEach((r,i) => {
r.rotation.x += 0.003 + i*0.001;
r.rotation.z += 0.002;
r.position.y += Math.sin(time + i) * 0.01;
});
bgCamera.position.x += (mouseX * 3 - bgCamera.position.x) * 0.02;
bgCamera.position.y += (-mouseY * 2 - bgCamera.position.y) * 0.02;
bgCamera.lookAt(0, 0, 0);
bgRenderer.render(bgScene, bgCamera);
}
animateBg(0);
window.addEventListener('resize', () => {
bgCamera.aspect = window.innerWidth/window.innerHeight;
bgCamera.updateProjectionMatrix();
bgRenderer.setSize(window.innerWidth, window.innerHeight);
});
// ===== PRODUCTS DATA =====
const products = [
{ id:1, name:'QUANTUM X PRO', desc:'Next-gen neural interface headset with holographic display', price:499, old:699, badge:'NEW', color:0x00f5ff, shape:'sphere' },
{ id:2, name:'VOLT CUBE', desc:'Wireless charging hub with 360° energy field tech', price:129, old:199, badge:'SALE', color:0xff00aa, shape:'box' },
{ id:3, name:'HELIX WATCH', desc:'Biometric smartwatch with quantum encryption', price:349, old:null, badge:null, color:0x00ff88, shape:'torus' },
{ id:4, name:'PLASMA BUDS', desc:'Spatial audio earbuds with AI noise cancellation', price:189, old:249, badge:'HOT', color:0xffaa00, shape:'icosa' },
{ id:5, name:'NEON BLADE', desc:'Ergonomic gaming mouse with plasma RGB matrix', price:89, old:null, badge:null, color:0x8800ff, shape:'cone' },
{ id:6, name:'ARC LENS', desc:'Smart glasses with AR overlay & 4K recording', price:699, old:999, badge:'LIMITED', color:0x00f5ff, shape:'cylinder' },
];
// ===== CART STATE =====
let cart = [];
function toggleCart() {
const panel = document.getElementById('cartPanel');
const overlay = document.getElementById('overlay');
panel.classList.toggle('open');
overlay.classList.toggle('active');
}
function addToCart(id) {
const product = products.find(p => p.id === id);
const existing = cart.find(c => c.id === id);
if (existing) {
existing.qty++;
} else {
cart.push({ ...product, qty: 1 });
}
updateCart();
const btn = document.getElementById('btn-' + id);
if (btn) {
btn.textContent = 'ADDED ✓';
btn.classList.add('added');
setTimeout(() => {
btn.textContent = 'ADD TO CART';
btn.classList.remove('added');
}, 1500);
}
}
function removeFromCart(id) {
cart = cart.filter(c => c.id !== id);
updateCart();
}
function updateCart() {
const count = cart.reduce((s,c) => s+c.qty, 0);
const total = cart.reduce((s,c) => s+c.price*c.qty, 0);
document.getElementById('cartCount').textContent = count;
document.getElementById('cartTotal').textContent = '$' + total.toFixed(2);
const el = document.getElementById('cartItems');
if (cart.length === 0) {
el.innerHTML = '<div class="cart-empty">Your cart is empty.<br>Add some products!</div>';
return;
}
el.innerHTML = cart.map(c => `
<div class="cart-item">
<div>
<div class="cart-item-name">${c.name} ${c.qty > 1 ? 'x'+c.qty : ''}</div>
</div>
<div style="display:flex;align-items:center;gap:12px;">
<span class="cart-item-price">$${(c.price*c.qty).toFixed(2)}</span>
<button class="remove-item" onclick="removeFromCart(${c.id})">✕</button>
</div>
</div>
`).join('');
}
// ===== RENDER PRODUCT CARDS WITH 3D =====
function createProductScene(canvasEl, shape, color) {
const renderer = new THREE.WebGLRenderer({ canvas: canvasEl, alpha: true, antialias: true });
renderer.setSize(canvasEl.offsetWidth || 240, 200);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(45, (canvasEl.offsetWidth||240)/200, 0.1, 100);
camera.position.z = 4;
const ambientLight = new THREE.AmbientLight(0xffffff, 0.3);
scene.add(ambientLight);
const pointLight = new THREE.PointLight(color, 2, 20);
pointLight.position.set(3, 3, 3);
scene.add(pointLight);
const pointLight2 = new THREE.PointLight(0xff00aa, 1, 20);
pointLight2.position.set(-3, -2, 2);
scene.add(pointLight2);
let geo;
if (shape === 'sphere') geo = new THREE.SphereGeometry(1, 32, 32);
else if (shape === 'box') geo = new THREE.BoxGeometry(1.5, 1.5, 1.5);
else if (shape === 'torus') geo = new THREE.TorusGeometry(0.9, 0.35, 16, 60);
else if (shape === 'icosa') geo = new THREE.IcosahedronGeometry(1, 0);
else if (shape === 'cone') geo = new THREE.ConeGeometry(0.8, 1.8, 6);
else if (shape === 'cylinder') geo = new THREE.CylinderGeometry(0.6, 0.8, 1.6, 8);
const mat = new THREE.MeshPhongMaterial({
color: color,
emissive: color,
emissiveIntensity: 0.2,
shininess: 100,
wireframe: false,
transparent: true,
opacity: 0.9,
});
const mesh = new THREE.Mesh(geo, mat);
scene.add(mesh);
// Wireframe overlay
const wireMat = new THREE.MeshBasicMaterial({ color: color, wireframe: true, transparent: true, opacity: 0.15 });
const wire = new THREE.Mesh(geo.clone(), wireMat);
wire.scale.setScalar(1.02);
scene.add(wire);
let hovered = false;
canvasEl.addEventListener('mouseenter', () => hovered = true);
canvasEl.addEventListener('mouseleave', () => hovered = false);
function animateProduct(t) {
requestAnimationFrame(animateProduct);
const time = t * 0.001;
const speed = hovered ? 2 : 1;
mesh.rotation.y = time * speed;
mesh.rotation.x = Math.sin(time * 0.5) * 0.3;
wire.rotation.y = mesh.rotation.y;
wire.rotation.x = mesh.rotation.x;
mesh.position.y = Math.sin(time) * 0.1;
wire.position.y = mesh.position.y;
pointLight.intensity = 2 + Math.sin(time * 3) * 0.5;
renderer.render(scene, camera);
}
animateProduct(0);
}
// Build product cards
const grid = document.getElementById('productGrid');
products.forEach((p, i) => {
const card = document.createElement('div');
card.className = 'product-card';
card.style.animationDelay = (i * 0.1) + 's';
card.innerHTML = `
${p.badge ? `<div class="product-badge">${p.badge}</div>` : ''}
<div class="product-3d-wrap">
<canvas class="product-canvas" id="canvas-${p.id}"></canvas>
</div>
<div class="product-name">${p.name}</div>
<div class="product-desc">${p.desc}</div>
<div class="product-footer">
<div class="product-price">
${p.old ? `<span class="old">$${p.old}</span>` : ''}$${p.price}
</div>
<button class="add-btn" id="btn-${p.id}" onclick="addToCart(${p.id})">ADD TO CART</button>
</div>
`;
grid.appendChild(card);
setTimeout(() => {
const canvas = document.getElementById('canvas-' + p.id);
if (canvas) createProductScene(canvas, p.shape, p.color);
}, 100);
});
</script>
</body>
</html>