diff --git a/category.html b/category.html new file mode 100644 index 00000000..773e9667 --- /dev/null +++ b/category.html @@ -0,0 +1,111 @@ + + + + + + Kategoriler – DolapX + + + + + + + + + +
+
+ Tümü + Giyim + Elektronik + Aksesuar + Kitap +
+ +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+

Ürünler

+
+
+
+
+ + + + + + + diff --git a/index.html b/index.html new file mode 100644 index 00000000..43512431 --- /dev/null +++ b/index.html @@ -0,0 +1,104 @@ + + + + + + DolapX – İkinci El Alışveriş | Popüler ve Yeni Ürünler + + + + + + + + + + + +
+
+
+ + +
+
+ +
+
+
+

Popüler Ürünler

+ Tümünü Gör +
+ +
+
+ +
+
+
+

Yeni Eklenenler

+ Tümünü Gör +
+
+
+
+
+ + + + + + + diff --git a/main.js b/main.js new file mode 100644 index 00000000..1696758c --- /dev/null +++ b/main.js @@ -0,0 +1,472 @@ +// Core state and utilities +const STORAGE_KEYS = { + products: "mp_products", + favorites: "mp_favorites", + users: "mp_users" +}; + +function getFromStorage(key, fallback) { + try { + const raw = localStorage.getItem(key); + return raw ? JSON.parse(raw) : fallback; + } catch (_) { + return fallback; + } +} + +function setInStorage(key, value) { + localStorage.setItem(key, JSON.stringify(value)); +} + +function formatPrice(amount) { + return new Intl.NumberFormat("tr-TR", { style: "currency", currency: "TRY", maximumFractionDigits: 0 }).format(amount); +} + +function q(sel, root = document) { return root.querySelector(sel); } +function qa(sel, root = document) { return Array.from(root.querySelectorAll(sel)); } + +function getQueryParam(name) { + const url = new URL(window.location.href); + return url.searchParams.get(name); +} + +// Dummy data +function seedDummyData() { + const existing = getFromStorage(STORAGE_KEYS.products, null); + if (existing) return; // Seed once + const now = Date.now(); + const users = [ + { id: 1, name: "Zeynep Kaya", city: "İstanbul", avatar: "https://images.unsplash.com/photo-1544005313-94ddf0286df2?q=80&w=300&auto=format&fit=crop" }, + { id: 2, name: "Mert Demir", city: "Ankara", avatar: "https://images.unsplash.com/photo-1547425260-76bcadfb4f2c?q=80&w=300&auto=format&fit=crop" } + ]; + const images = { + clothing: [ + "https://images.unsplash.com/photo-1520975916090-3105956dac38?q=80&w=800&auto=format&fit=crop", + "https://images.unsplash.com/photo-1503342217505-b0a15cf70489?q=80&w=800&auto=format&fit=crop", + "https://images.unsplash.com/photo-1509631179647-0177331693ae?q=80&w=800&auto=format&fit=crop" + ], + electronics: [ + "https://images.unsplash.com/photo-1517336714731-489689fd1ca8?q=80&w=800&auto=format&fit=crop", + "https://images.unsplash.com/photo-1510557880182-3d4d3cba35a5?q=80&w=800&auto=format&fit=crop", + "https://images.unsplash.com/photo-1518770660439-4636190af475?q=80&w=800&auto=format&fit=crop" + ], + accessories: [ + "https://images.unsplash.com/photo-1520523839897-bd0b52f945a0?q=80&w=800&auto=format&fit=crop", + "https://images.unsplash.com/photo-1537832816519-689ad163238b?q=80&w=800&auto=format&fit=crop", + "https://images.unsplash.com/photo-1490367532201-b9bc1dc483f6?q=80&w=800&auto=format&fit=crop" + ], + books: [ + "https://images.unsplash.com/photo-1516979187457-637abb4f9353?q=80&w=800&auto=format&fit=crop", + "https://images.unsplash.com/photo-1526318472351-c75fcf070305?q=80&w=800&auto=format&fit=crop", + "https://images.unsplash.com/photo-1524995997946-a1c2e315a42f?q=80&w=800&auto=format&fit=crop" + ] + }; + const categories = ["Giyim", "Elektronik", "Aksesuar", "Kitap"]; + const locations = ["İstanbul", "Ankara", "İzmir", "Bursa", "Antalya"]; + + const products = []; + let idCounter = 1000; + for (let i = 0; i < 12; i++) { + const category = categories[i % categories.length]; + const imgSet = category === "Giyim" ? images.clothing : category === "Elektronik" ? images.electronics : category === "Aksesuar" ? images.accessories : images.books; + const basePrice = category === "Elektronik" ? 2500 : category === "Giyim" ? 250 : category === "Aksesuar" ? 180 : 75; + const price = Math.round(basePrice * (0.7 + Math.random() * 1.6)); + const sellerId = i % 2 === 0 ? 1 : 2; + const createdAt = now - i * 86400000; + products.push({ + id: idCounter++, + title: `${category} Ürün ${i + 1}`, + price, + category, + condition: ["Yeni", "Çok iyi", "İyi"][i % 3], + location: locations[i % locations.length], + description: `${category} kategorisinden temiz ikinci el ürün. Hızlı teslimat, sorunsuz.`, + images: imgSet, + sellerId, + createdAt, + popularity: Math.floor(Math.random() * 1000), + stock: 1 + (i % 3), + soldCount: Math.floor(Math.random() * 5) + }); + } + + setInStorage(STORAGE_KEYS.products, products); + setInStorage(STORAGE_KEYS.users, users); + setInStorage(STORAGE_KEYS.favorites, []); +} + +function getAllProducts() { + return getFromStorage(STORAGE_KEYS.products, []); +} + +function saveAllProducts(products) { + setInStorage(STORAGE_KEYS.products, products); +} + +function getAllUsers() { + return getFromStorage(STORAGE_KEYS.users, []); +} + +function getCurrentUser() { + const users = getAllUsers(); + return users[0] || { id: 1, name: "Kullanıcı", city: "İstanbul", avatar: "https://via.placeholder.com/64" }; +} + +function getFavorites() { + return getFromStorage(STORAGE_KEYS.favorites, []); +} + +function toggleFavorite(productId) { + const favs = new Set(getFavorites()); + if (favs.has(productId)) favs.delete(productId); else favs.add(productId); + setInStorage(STORAGE_KEYS.favorites, Array.from(favs)); +} + +function isFavorite(productId) { + return getFavorites().includes(productId); +} + +// Rendering helpers +function productCardTemplate(product) { + const favActive = isFavorite(product.id) ? " active" : ""; + return ` +
+ + + ${product.title} + +
+
${product.title}
+
${formatPrice(product.price)}
+
${product.location} · ${product.condition}
+
+
+ `; +} + +function mountFavoritesHandlers(root) { + qa('.favorite-btn', root).forEach(btn => { + btn.addEventListener('click', (e) => { + e.preventDefault(); + e.stopPropagation(); + const card = e.currentTarget.closest('.product-card'); + const id = Number(card?.dataset.id); + if (!id) return; + toggleFavorite(id); + e.currentTarget.classList.toggle('active'); + }); + }); +} + +// Navbar search (simple redirect with query) +function initSearch() { + const form = q('#nav-search-form'); + if (!form) return; + form.addEventListener('submit', (e) => { + e.preventDefault(); + const qv = q('#nav-search-input')?.value?.trim(); + const url = new URL(window.location.origin + '/category.html'); + if (qv) url.searchParams.set('q', qv); + window.location.href = url.toString(); + }); +} + +// Home page +function initHome() { + const products = getAllProducts(); + const popular = [...products].sort((a, b) => b.popularity - a.popularity).slice(0, 8); + const newest = [...products].sort((a, b) => b.createdAt - a.createdAt).slice(0, 8); + + const popularGrid = q('#popular-products'); + const newGrid = q('#new-products'); + if (popularGrid) { + popularGrid.innerHTML = popular.map(productCardTemplate).join(''); + mountFavoritesHandlers(popularGrid); + } + if (newGrid) { + newGrid.innerHTML = newest.map(productCardTemplate).join(''); + mountFavoritesHandlers(newGrid); + } +} + +// Category page +function applyFilters(baseProducts) { + const min = Number(q('#filter-min')?.value || 0) || 0; + const max = Number(q('#filter-max')?.value || Infinity) || Infinity; + const condition = q('#filter-condition')?.value || ''; + const location = q('#filter-location')?.value || ''; + const text = (q('#filter-text')?.value || '').toLowerCase(); + + return baseProducts.filter(p => { + if (p.price < min || p.price > max) return false; + if (condition && p.condition !== condition) return false; + if (location && p.location !== location) return false; + if (text && !(`${p.title} ${p.description}`.toLowerCase().includes(text))) return false; + return true; + }); +} + +function initCategory() { + const all = getAllProducts(); + const url = new URL(window.location.href); + const category = url.searchParams.get('category'); + const qtext = url.searchParams.get('q') || ''; + if (q('#filter-text')) q('#filter-text').value = qtext; + + let base = category ? all.filter(p => p.category === category) : all; + const grid = q('#category-products'); + const render = () => { + const data = applyFilters(base); + grid.innerHTML = data.map(productCardTemplate).join(''); + mountFavoritesHandlers(grid); + }; + + // Category pills + qa('.pill').forEach(pill => { + pill.addEventListener('click', () => { + qa('.pill').forEach(p => p.classList.remove('active')); + pill.classList.add('active'); + const c = pill.dataset.category; + base = c ? all.filter(p => p.category === c) : all; + render(); + const u = new URL(window.location.href); + if (c) u.searchParams.set('category', c); else u.searchParams.delete('category'); + history.replaceState(null, '', u.toString()); + }); + }); + + // Filters events + ['filter-min','filter-max','filter-condition','filter-location','filter-text'].forEach(id => { + const el = q('#' + id); + if (el) el.addEventListener('input', render); + if (el && (id === 'filter-condition' || id === 'filter-location')) el.addEventListener('change', render); + }); + + // Initial pill active + if (category) { + const active = q(`.pill[data-category="${category}"]`); + if (active) active.classList.add('active'); + } + + render(); +} + +// Product page +function initProduct() { + const id = Number(getQueryParam('id')) || getAllProducts()[0]?.id; + const product = getAllProducts().find(p => p.id === id); + if (!product) return; + + q('#p-title').textContent = product.title; + q('#p-price').textContent = formatPrice(product.price); + q('#p-desc').textContent = product.description; + q('#p-meta').textContent = `${product.location} · ${product.condition}`; + const seller = getAllUsers().find(u => u.id === product.sellerId); + if (seller) { + q('#seller-name').textContent = seller.name; + q('#seller-city').textContent = seller.city; + const av = q('#seller-avatar'); if (av) av.src = seller.avatar; + } + + const main = q('#gallery-main'); + const thumbs = q('#gallery-thumbs'); + if (main && thumbs) { + main.src = product.images[0]; + thumbs.innerHTML = product.images.map((src, i) => `${product.title} görsel ${i+1}`).join(''); + qa('img', thumbs).forEach((img, i) => { + img.addEventListener('click', () => { + qa('img', thumbs).forEach(t => t.classList.remove('active')); + img.classList.add('active'); + main.src = product.images[i]; + }); + }); + } + + const favBtn = q('#fav-btn'); + if (favBtn) { + if (isFavorite(product.id)) favBtn.classList.add('active'); + favBtn.addEventListener('click', () => { + toggleFavorite(product.id); + favBtn.classList.toggle('active'); + }); + } + + const msgBtn = q('#msg-btn'); + if (msgBtn) { + msgBtn.addEventListener('click', () => { + alert('Satıcıya mesaj gönderildi! (Demo)'); + }); + } +} + +// Profile page +function initProfile() { + const user = getCurrentUser(); + q('#profile-name').textContent = user.name; + q('#profile-city').textContent = user.city; + const av = q('#profile-avatar'); if (av) av.src = user.avatar; + + const products = getAllProducts(); + const favorites = getFavorites(); + const myPurchases = products.filter((_, i) => i % 5 === 0).slice(0, 6); + const mySales = products.filter(p => p.sellerId === user.id).slice(0, 6); + const favProducts = products.filter(p => favorites.includes(p.id)); + + const sections = [ + ['#purchases', myPurchases], + ['#sales', mySales], + ['#favorites', favProducts] + ]; + sections.forEach(([sel, list]) => { + const root = q(sel); + if (root) { + root.innerHTML = list.map(productCardTemplate).join(''); + mountFavoritesHandlers(root); + } + }); + + // Tabs + qa('.tab').forEach(tab => { + tab.addEventListener('click', () => { + qa('.tab').forEach(t => t.classList.remove('active')); + tab.classList.add('active'); + const target = tab.dataset.target; + qa('.tab-panel').forEach(p => p.classList.add('hidden')); + q(target)?.classList.remove('hidden'); + }); + }); +} + +// Seller dashboard +function initSellerDashboard() { + const user = getCurrentUser(); + let products = getAllProducts(); + const mine = () => products.filter(p => p.sellerId === user.id); + + function renderList() { + const grid = q('#seller-products'); + grid.innerHTML = mine().map(p => ` +
+ ${p.title} +
+
${p.title}
+
${formatPrice(p.price)}
+
Stok: ${p.stock} · Satış: ${p.soldCount}
+
+ + + + +
+
+
+ `).join(''); + + // Handlers + qa('.edit-btn', grid).forEach(btn => btn.addEventListener('click', (e) => { + const id = Number(e.currentTarget.closest('.product-card').dataset.id); + loadToForm(products.find(p => p.id === id)); + })); + qa('[data-action]', grid).forEach(btn => btn.addEventListener('click', (e) => { + const card = e.currentTarget.closest('.product-card'); + const id = Number(card.dataset.id); + const action = e.currentTarget.getAttribute('data-action'); + if (action === 'delete') { + if (!confirm('Silinsin mi?')) return; + products = products.filter(p => p.id !== id); + } else if (action === 'stock+') { + products = products.map(p => p.id === id ? { ...p, stock: p.stock + 1 } : p); + } else if (action === 'stock-−' || action === 'stock-–' || action === 'stock-—' || action === 'stock-−') { + // visually similar hyphens safety + products = products.map(p => p.id === id ? { ...p, stock: Math.max(0, p.stock - 1) } : p); + } else if (action === 'stock-') { + products = products.map(p => p.id === id ? { ...p, stock: Math.max(0, p.stock - 1) } : p); + } + saveAllProducts(products); + renderList(); + })); + } + + function clearForm() { + ['title','price','category','condition','location','images','description','id'].forEach(name => { + const el = q(`#f-${name}`); + if (el) el.value = ''; + }); + } + + function loadToForm(p) { + if (!p) return; + q('#f-id').value = p.id; + q('#f-title').value = p.title; + q('#f-price').value = p.price; + q('#f-category').value = p.category; + q('#f-condition').value = p.condition; + q('#f-location').value = p.location; + q('#f-images').value = p.images.join(','); + q('#f-description').value = p.description; + window.scrollTo({ top: 0, behavior: 'smooth' }); + } + + q('#product-form').addEventListener('submit', (e) => { + e.preventDefault(); + const idVal = q('#f-id').value.trim(); + const data = { + id: idVal ? Number(idVal) : Math.floor(Math.random()*1e9), + title: q('#f-title').value.trim(), + price: Number(q('#f-price').value || 0), + category: q('#f-category').value, + condition: q('#f-condition').value, + location: q('#f-location').value, + images: q('#f-images').value.split(',').map(s => s.trim()).filter(Boolean), + description: q('#f-description').value.trim(), + sellerId: user.id, + createdAt: Date.now(), + popularity: 0, + stock: 1, + soldCount: 0 + }; + if (idVal) { + products = products.map(p => p.id === data.id ? { ...p, ...data } : p); + } else { + products = [data, ...products]; + } + saveAllProducts(products); + renderList(); + clearForm(); + alert('Ürün kaydedildi!'); + }); + + q('#btn-clear').addEventListener('click', () => clearForm()); + + // Stats + function renderStats() { + const list = mine(); + const totalProducts = list.length; + const totalSales = list.reduce((a, p) => a + p.soldCount, 0); + const totalIncome = list.reduce((a, p) => a + p.soldCount * p.price, 0); + q('#stat-products').textContent = String(totalProducts); + q('#stat-sales').textContent = String(totalSales); + q('#stat-income').textContent = formatPrice(totalIncome); + } + + const observer = new MutationObserver(() => renderStats()); + observer.observe(q('#seller-products'), { childList: true, subtree: true }); + + renderList(); + renderStats(); +} + +// Initialization +document.addEventListener('DOMContentLoaded', () => { + seedDummyData(); + initSearch(); + const page = document.body.dataset.page; + if (page === 'home') initHome(); + if (page === 'category') initCategory(); + if (page === 'product') initProduct(); + if (page === 'profile') initProfile(); + if (page === 'seller-dashboard') initSellerDashboard(); +}); + diff --git a/product.html b/product.html new file mode 100644 index 00000000..7f6b38a1 --- /dev/null +++ b/product.html @@ -0,0 +1,93 @@ + + + + + + Ürün Detayı – DolapX + + + + + + + + + +
+
+
+ +
+

+
+

+
+
+ +
+
+ + + + + + + diff --git a/profile.html b/profile.html new file mode 100644 index 00000000..db54cf84 --- /dev/null +++ b/profile.html @@ -0,0 +1,82 @@ + + + + + + Profil – DolapX + + + + + + + +
+
+ Profil +
+
+
+
+
+ +
+
Satın Alınanlar
+
Satılanlar
+
Favoriler
+
+ +
+
+
+ + +
+ + + + + + + diff --git a/seller-dashboard.html b/seller-dashboard.html new file mode 100644 index 00000000..55c9aa67 --- /dev/null +++ b/seller-dashboard.html @@ -0,0 +1,122 @@ + + + + + + Satıcı Paneli – DolapX + + + + + + + +
+
+
+

Ürün Ekle/Düzenle

+
+ + + + + + + + +
+ + +
+
+
+
+

Özet

+
+
Ürün
0
+
Satış
0
+
Gelir
0₺
+
+
+
+ +
+
+

Ürünlerim

+
+
+
+
+ + + + + + + diff --git a/style.css b/style.css new file mode 100644 index 00000000..9e419f88 --- /dev/null +++ b/style.css @@ -0,0 +1,364 @@ +:root { + --primary: #1976d2; + --primary-dark: #125ea5; + --bg: #f7f9fc; + --text: #1f2937; + --muted: #6b7280; + --card: #ffffff; + --border: #e5e7eb; + --success: #16a34a; + --danger: #dc2626; + --warning: #f59e0b; +} + +* { + box-sizing: border-box; +} + +html, body { + padding: 0; + margin: 0; + font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, "Apple Color Emoji", "Segoe UI Emoji"; + color: var(--text); + background: var(--bg); +} + +img { + max-width: 100%; + display: block; +} + +a { + color: inherit; + text-decoration: none; +} + +.container { + width: 100%; + max-width: 1200px; + margin: 0 auto; + padding: 0 16px; +} + +/* Navbar */ +.navbar { + position: sticky; + top: 0; + z-index: 100; + background: #fff; + border-bottom: 1px solid var(--border); +} + +.navbar-inner { + display: flex; + align-items: center; + justify-content: space-between; + gap: 16px; + height: 64px; +} + +.brand { + display: flex; + align-items: center; + gap: 10px; + font-weight: 700; + font-size: 20px; + color: var(--primary); +} + +.brand-logo { + width: 32px; + height: 32px; + background: var(--primary); + border-radius: 8px; +} + +.nav-left, .nav-right { + display: flex; + align-items: center; + gap: 12px; +} + +.nav-links { + display: flex; + align-items: center; + gap: 10px; +} + +.dropdown { + position: relative; +} + +.dropdown-toggle { + padding: 8px 12px; + border-radius: 8px; + border: 1px solid var(--border); + background: #fff; +} + +.dropdown-menu { + position: absolute; + top: 110%; + left: 0; + min-width: 220px; + background: #fff; + border: 1px solid var(--border); + border-radius: 10px; + box-shadow: 0 10px 30px rgba(0,0,0,0.08); + padding: 8px; + display: none; +} + +.dropdown:hover .dropdown-menu { + display: block; +} + +.dropdown-menu a { + display: block; + padding: 10px 12px; + border-radius: 8px; +} + +.dropdown-menu a:hover { + background: var(--bg); +} + +.search { + flex: 1; + display: flex; + align-items: center; + gap: 8px; + max-width: 560px; +} + +.search input { + flex: 1; + height: 40px; + border: 1px solid var(--border); + border-radius: 10px; + padding: 0 12px; +} + +.btn { + display: inline-flex; + align-items: center; + justify-content: center; + height: 40px; + padding: 0 14px; + border-radius: 10px; + border: 1px solid var(--border); + background: #fff; + cursor: pointer; + transition: transform 0.06s ease, background 0.2s ease, color 0.2s ease, border-color 0.2s ease; +} + +.btn:hover { + transform: translateY(-1px); +} + +.btn-primary { + background: var(--primary); + border-color: var(--primary); + color: #fff; +} + +.btn-primary:hover { background: var(--primary-dark); border-color: var(--primary-dark); } + +.btn-outline { background: #fff; color: var(--primary); border-color: var(--primary); } +.btn-outline:hover { background: rgba(25,118,210,0.06); } + +/* Hero / Banners */ +.hero { + background: linear-gradient(180deg, #fff, var(--bg)); + padding: 36px 0; +} + +.hero-grid { + display: grid; + grid-template-columns: 1.2fr 1fr; + gap: 16px; +} + +.banner { + background: #fff; + border: 1px solid var(--border); + border-radius: 16px; + padding: 20px; + display: flex; + align-items: center; + justify-content: space-between; + overflow: hidden; +} + +.banner h2 { margin: 0 0 6px; } +.banner p { margin: 0 0 12px; color: var(--muted); } + +.banner img { width: 180px; height: auto; } + +.section { + padding: 20px 0 28px; +} + +.section-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 14px; +} + +.section-title { + font-size: 20px; + font-weight: 700; +} + +/* Product grid/cards */ +.product-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); + gap: 16px; +} + +.product-card { + background: #fff; + border: 1px solid var(--border); + border-radius: 14px; + overflow: hidden; + display: flex; + flex-direction: column; + position: relative; +} + +.product-thumb { + width: 100%; + aspect-ratio: 1/1; + object-fit: cover; +} + +.product-body { padding: 12px; display: flex; flex-direction: column; gap: 6px; } +.product-title { font-weight: 600; font-size: 15px; min-height: 38px; } +.product-price { font-weight: 700; color: var(--primary); } +.product-desc { color: var(--muted); font-size: 13px; } + +.favorite-btn { + position: absolute; + top: 10px; + right: 10px; + width: 36px; + height: 36px; + border-radius: 50%; + background: rgba(255,255,255,0.9); + border: 1px solid var(--border); +} + +.favorite-btn.active { background: #fff; color: #e11d48; border-color: #fecdd3; } + +/* Filters */ +.filters { + background: #fff; + border: 1px solid var(--border); + border-radius: 16px; + padding: 12px; + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 12px; + margin-bottom: 16px; +} + +.filters .field { + display: flex; + flex-direction: column; + gap: 6px; +} + +.filters label { font-size: 13px; color: var(--muted); } +.filters input, .filters select { height: 40px; border: 1px solid var(--border); border-radius: 10px; padding: 0 10px; } + +.pills { display: flex; gap: 8px; flex-wrap: wrap; margin: 8px 0 16px; } +.pill { padding: 6px 10px; border: 1px solid var(--border); border-radius: 20px; background: #fff; cursor: pointer; font-size: 13px; } +.pill.active { background: rgba(25,118,210,0.08); color: var(--primary); border-color: var(--primary); } + +/* Product page */ +.product-page { + display: grid; + grid-template-columns: 1.1fr 0.9fr; + gap: 20px; +} + +.gallery { + background: #fff; + border: 1px solid var(--border); + border-radius: 16px; + padding: 12px; +} + +.gallery-main { width: 100%; aspect-ratio: 4/3; object-fit: cover; border-radius: 10px; } +.thumbs { display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px; margin-top: 8px; } +.thumbs img { width: 100%; aspect-ratio: 1/1; object-fit: cover; border-radius: 8px; cursor: pointer; border: 2px solid transparent; } +.thumbs img.active { border-color: var(--primary); } + +.product-info, .seller-card { + background: #fff; + border: 1px solid var(--border); + border-radius: 16px; + padding: 14px; +} + +.product-actions { display: flex; gap: 10px; margin-top: 10px; } + +/* Profile */ +.profile-header { + display: flex; + align-items: center; + gap: 16px; + background: #fff; + border: 1px solid var(--border); + border-radius: 16px; + padding: 14px; + margin-bottom: 16px; +} + +.avatar { width: 64px; height: 64px; border-radius: 50%; object-fit: cover; } + +.tabs { display: flex; gap: 8px; border-bottom: 1px solid var(--border); margin-bottom: 12px; } +.tab { padding: 10px 12px; cursor: pointer; border-bottom: 2px solid transparent; } +.tab.active { color: var(--primary); border-color: var(--primary); } + +/* Seller dashboard */ +.dashboard-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; } +.card { background: #fff; border: 1px solid var(--border); border-radius: 16px; padding: 14px; } +.stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; } +.stat { background: #f8fafc; border: 1px solid var(--border); border-radius: 12px; padding: 12px; } +.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; } +.form-grid .full { grid-column: span 2; } +.form-grid input, .form-grid select, .form-grid textarea { height: 40px; border: 1px solid var(--border); border-radius: 10px; padding: 0 10px; width: 100%; } +.form-grid textarea { height: 100px; padding: 10px; resize: vertical; } + +/* Footer */ +.footer { + margin-top: 32px; + background: #fff; + border-top: 1px solid var(--border); +} + +.footer-inner { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 16px 0; } +.social { display: flex; gap: 8px; } +.social a { width: 36px; height: 36px; border: 1px solid var(--border); border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; } + +/* Utilities */ +.muted { color: var(--muted); } +.hidden { display: none !important; } + +/* Responsive */ +@media (max-width: 1024px) { + .hero-grid { grid-template-columns: 1fr; } + .product-page { grid-template-columns: 1fr; } + .dashboard-grid { grid-template-columns: 1fr; } +} + +@media (max-width: 640px) { + .navbar-inner { height: 58px; } + .nav-links { display: none; } + .filters { grid-template-columns: 1fr 1fr; } + .stats { grid-template-columns: 1fr; } +} + diff --git a/tezgah.zip b/tezgah.zip new file mode 100644 index 00000000..e32ec3f4 Binary files /dev/null and b/tezgah.zip differ diff --git a/tezgah/index.html b/tezgah/index.html new file mode 100644 index 00000000..b7eca281 --- /dev/null +++ b/tezgah/index.html @@ -0,0 +1,245 @@ + + + + + +Tezgah + + + + + + +
+
+ + +
+
+ +
+ + +
+
+

Yeni Eklenenler

+
+
+
+
+ + + + + + + + + + + + + + + diff --git a/tezgah/main.js b/tezgah/main.js new file mode 100644 index 00000000..370211be --- /dev/null +++ b/tezgah/main.js @@ -0,0 +1,264 @@ +const FAVORITES_KEY = "tezgah:favorites"; +const PRODUCTS_KEY = "tezgah:products"; +const CART_KEY = "tezgah:cart"; +const USER_KEY = "tezgah:user"; + +const state = { category: "all", query: "", favorites: new Set(), user: null, cart: {} }; +const trCurrency = new Intl.NumberFormat("tr-TR", { style: "currency", currency: "TRY", maximumFractionDigits: 0 }); + +let products = [ + {id:1,title:"Apple iPhone 12 128GB",price:18999,desc:"Çiziksiz, kutulu, faturalı",img:"https://images.unsplash.com/photo-1605648916361-9f343605f61e?q=80&w=1932&auto=format&fit=crop",category:"Elektronik",isPopular:true,createdAt:"2025-08-12"}, + {id:2,title:"Xiaomi Redmi Note 11",price:6499,desc:"Az kullanılmış, batarya sağlığı iyi",img:"https://images.unsplash.com/photo-1511707171634-5f897ff02aa9?q=80&w=1974&auto=format&fit=crop",category:"Elektronik",isPopular:false,createdAt:"2025-09-01"}, + {id:3,title:"Dell XPS 13",price:25999,desc:"13 inç, i7, 16GB RAM",img:"https://images.unsplash.com/photo-1517336714731-489689fd1ca8?q=80&w=2070&auto=format&fit=crop",category:"Elektronik",isPopular:true,createdAt:"2025-08-28"}, + {id:4,title:"Ahşap Çalışma Masası",price:3499,desc:"120x60 cm, doğal meşe",img:"https://images.unsplash.com/photo-1493809842364-78817add7ffb?q=80&w=2070&auto=format&fit=crop",category:"Mobilya",isPopular:true,createdAt:"2025-09-07"}, + {id:5,title:"Ergonomik Ofis Koltuğu",price:2299,desc:"Bel destekli, file kumaş",img:"https://images.unsplash.com/photo-1582582621959-48d0b1f72f83?q=80&w=1974&auto=format&fit=crop",category:"Mobilya",isPopular:false,createdAt:"2025-08-31"}, + {id:6,title:"Nike Koşu Ayakkabısı",price:1399,desc:"42 numara, temiz",img:"https://images.unsplash.com/photo-1542291026-7eec264c27ff?q=80&w=1974&auto=format&fit=crop",category:"Spor",isPopular:true,createdAt:"2025-09-03"}, + {id:7,title:"Klasik Romanlar Seti",price:499,desc:"10 kitap, iyi durumda",img:"https://images.unsplash.com/photo-1519681393784-d120267933ba?q=80&w=2067&auto=format&fit=crop",category:"Kitap",isPopular:false,createdAt:"2025-08-26"}, + {id:8,title:"Sony WH-1000XM4 Kulaklık",price:7999,desc:"Gürültü engelleme, sorunsuz",img:"https://images.unsplash.com/photo-1518442072030-744dff31cfc3?q=80&w=2070&auto=format&fit=crop",category:"Elektronik",isPopular:true,createdAt:"2025-09-05"}, + {id:9,title:"IKEA Raf Sistemi",price:899,desc:"Modüler, beyaz",img:"https://images.unsplash.com/photo-1493666438817-866a91353ca9?q=80&w=1974&auto=format&fit=crop",category:"Mobilya",isPopular:false,createdAt:"2025-08-21"}, + {id:10,title:"Vintage Deri Ceket",price:1799,desc:"M beden, kahverengi",img:"https://images.unsplash.com/photo-1516826957135-700dedea698c?q=80&w=2059&auto=format&fit=crop",category:"Moda",isPopular:true,createdAt:"2025-09-06"}, + {id:11,title:"Nintendo Switch",price:10999,desc:"2 kol, 3 oyun hediye",img:"https://images.unsplash.com/photo-1585079542156-2755d9c8affd?q=80&w=1974&auto=format&fit=crop",category:"Oyun",isPopular:true,createdAt:"2025-09-02"}, + {id:12,title:"Philips Airfryer",price:2799,desc:"Kutulu, az kullanılmış",img:"https://images.unsplash.com/photo-1598514982597-139a3d67f9af?q=80&w=1974&auto=format&fit=crop",category:"Ev Aletleri",isPopular:false,createdAt:"2025-08-25"}, + {id:13,title:"Canon EOS M50",price:14999,desc:"18-55mm lens ile",img:"https://images.unsplash.com/photo-1526178611450-1a1b3c79c2d0?q=80&w=1974&auto=format&fit=crop",category:"Elektronik",isPopular:true,createdAt:"2025-08-30"}, + {id:14,title:"Xiaomi Robot Süpürge",price:5899,desc:"Haritalama özellikli",img:"https://images.unsplash.com/photo-1588742848067-dc86c9f1ae1d?q=80&w=1974&auto=format&fit=crop",category:"Ev Aletleri",isPopular:false,createdAt:"2025-09-04"}, + {id:15,title:"Adidas Sweatshirt",price:699,desc:"L beden, siyah",img:"https://images.unsplash.com/photo-1490481651871-ab68de25d43d?q=80&w=1974&auto=format&fit=crop",category:"Moda",isPopular:false,createdAt:"2025-08-29"}, + {id:16,title:"Logitech MX Master 3S",price:2499,desc:"Kablosuz mouse",img:"https://images.unsplash.com/photo-1595044426077-c972f08f90ef?q=80&w=1974&auto=format&fit=crop",category:"Elektronik",isPopular:true,createdAt:"2025-09-08"} +]; + +function lsGet(key, fallback) { try { const raw = localStorage.getItem(key); return raw ? JSON.parse(raw) : fallback; } catch (e) { return fallback; } } +function lsSet(key, value) { try { localStorage.setItem(key, JSON.stringify(value)); } catch (e) {} } + +function loadFavorites(){ + try{ + const raw=localStorage.getItem(FAVORITES_KEY); + if(!raw){state.favorites=new Set();return} + const arr=JSON.parse(raw); + state.favorites=new Set(Array.isArray(arr)?arr:[]) + }catch(e){state.favorites=new Set()} +} +function saveFavorites(){ try{localStorage.setItem(FAVORITES_KEY,JSON.stringify([...state.favorites]))}catch(e){} } + +function loadProducts() { const stored = lsGet(PRODUCTS_KEY, null); if (stored && Array.isArray(stored) && stored.length) { products = stored; } else { lsSet(PRODUCTS_KEY, products); } } +function saveProducts() { lsSet(PRODUCTS_KEY, products); } + +function loadUser() { state.user = lsGet(USER_KEY, null); } +function saveUser() { lsSet(USER_KEY, state.user); } + +function loadCart() { state.cart = lsGet(CART_KEY, {}); } +function saveCart() { lsSet(CART_KEY, state.cart); } + +function formatPrice(v){return trCurrency.format(v)} + +function populateCategories(){ + const select=document.getElementById("categorySelect"); + select.innerHTML = ``; + const cats=[...new Set(products.map(p=>p.category))].sort((a,b)=>a.localeCompare(b,"tr")); + for(const c of cats){ const opt=document.createElement("option"); opt.value=c; opt.textContent=c; select.appendChild(opt) } + select.value = state.category || "all"; +} + +function getFiltered(){ + const q=state.query.trim().toLowerCase(); + return products.filter(p=>{ + const categoryOk=state.category==="all"||p.category===state.category; + if(!categoryOk) return false; + if(!q) return true; + const hay=(p.title+" "+p.desc).toLowerCase(); + return hay.includes(q) + }) +} + +function renderAll(){ + const filtered=getFiltered(); + const popular=filtered.filter(p=>p.isPopular); + const newest=[...filtered].sort((a,b)=>new Date(b.createdAt)-new Date(a.createdAt)).slice(0,8); + renderGrid("popularGrid",popular); + renderGrid("newGrid",newest) +} + +function renderGrid(containerId,items){ + const el=document.getElementById(containerId); + if (!items.length) { el.innerHTML = `
Sonuç bulunamadı.
`; return; } + el.innerHTML=items.map(p=>cardTemplate(p)).join("") +} +function cardTemplate(p){ + const fav=state.favorites.has(p.id); + return ` +
+
+ ${p.title} + +
+
+

${p.title}

+

${p.desc}

+
+ ${formatPrice(p.price)} + ${p.category} +
+
+
+ ` +} + +function onFavoriteToggle(id){ + if(state.favorites.has(id)) state.favorites.delete(id); else state.favorites.add(id); + saveFavorites(); + renderAll(); + const btn=document.getElementById("detailFavBtn"); + if (btn && Number(btn.dataset.id)===id) { btn.classList.toggle("active", state.favorites.has(id)); } +} + +function openModal(el){ el.classList.add("open"); el.setAttribute("aria-hidden","false"); } +function closeModalById(id){ const el = document.getElementById(id); if (el){ el.classList.remove("open"); el.setAttribute("aria-hidden","true"); } } +function openProductModal(id){ + const p = products.find(x=>x.id===id); if(!p) return; + document.getElementById("detailImg").src = p.img; + document.getElementById("detailImg").alt = p.title; + document.getElementById("detailTitle").textContent = p.title; + document.getElementById("detailDesc").textContent = p.desc; + document.getElementById("detailCategory").textContent = p.category; + document.getElementById("detailPrice").textContent = formatPrice(p.price); + const favBtn = document.getElementById("detailFavBtn"); + favBtn.dataset.id = String(p.id); + favBtn.classList.toggle("active", state.favorites.has(p.id)); + document.getElementById("detailQty").value = 1; + openModal(document.getElementById("productModal")); +} + +function updateCartCountBadge(){ const count = Object.values(state.cart).reduce((a,b)=>a+b,0); const badge = document.getElementById("cartCount"); if (badge) badge.textContent = String(count); } +function addToCart(productId, quantity=1){ const id = String(productId); const q = Math.max(1, Number(quantity) || 1); state.cart[id] = (state.cart[id] || 0) + q; saveCart(); updateCartCountBadge(); renderCart(); } +function updateCartQty(productId, qty){ const id = String(productId); const q = Math.max(1, Number(qty) || 1); state.cart[id] = q; saveCart(); updateCartCountBadge(); renderCart(); } +function removeFromCart(productId){ const id = String(productId); delete state.cart[id]; saveCart(); updateCartCountBadge(); renderCart(); } +function clearCart(){ state.cart = {}; saveCart(); updateCartCountBadge(); renderCart(); } +function cartTotals(){ let subtotal = 0; for (const [id, qty] of Object.entries(state.cart)){ const p = products.find(x=>x.id===Number(id)); if (p) subtotal += p.price * qty; } const shipping = subtotal > 0 ? 0 : 0; const total = subtotal + shipping; return {subtotal, shipping, total}; } +function renderCart(){ + const list = document.getElementById("cartItems"); + const {subtotal, shipping, total} = cartTotals(); + const subtotalEl = document.getElementById("cartSubtotal"); + const shipEl = document.getElementById("cartShipping"); + const totalEl = document.getElementById("cartTotal"); + if (!list) return; + const entries = Object.entries(state.cart); + if (!entries.length){ list.innerHTML = `
Sepetiniz boş.
`; } + else { + list.innerHTML = entries.map(([id, qty])=>{ const p = products.find(x=>x.id===Number(id)); if (!p) return ""; return ` +
+ \"${p.title}\" +
+

${p.title}

+
${p.category}
+
${formatPrice(p.price)}
+
+
+
+ + + +
+ +
+
` }).join(""); + } + if (subtotalEl) subtotalEl.textContent = formatPrice(subtotal); + if (shipEl) shipEl.textContent = formatPrice(shipping); + if (totalEl) totalEl.textContent = formatPrice(total); +} + +function openDrawer(el){ el.classList.add("open"); el.setAttribute("aria-hidden","false"); } +function closeDrawerById(id){ const el = document.getElementById(id); if (el){ el.classList.remove("open"); el.setAttribute("aria-hidden","true"); } } + +function updateAuthUI(){ const profileBtn = document.getElementById("profileBtn"); if (state.user){ profileBtn.textContent = "Profil"; document.getElementById("authView").classList.add("hidden"); document.getElementById("profileView").classList.remove("hidden"); document.getElementById("profileName").textContent = state.user.name; document.getElementById("profileEmail").textContent = state.user.email; } else { profileBtn.textContent = "Giriş"; document.getElementById("authView").classList.remove("hidden"); document.getElementById("profileView").classList.add("hidden"); } } + +function renderSellerTable(){ const tbody = document.getElementById("sellerTableBody"); if (!tbody) return; const rows = products.slice().sort((a,b)=>b.id-a.id).map(p=>`${p.id}${p.title}${p.category}${formatPrice(p.price)}${p.isPopular ? "Evet":"Hayır"}${p.createdAt}`).join(""); tbody.innerHTML = rows || `Henüz ürün yok.`; } +function fillProductForm(p){ document.getElementById("productId").value = p?.id || ""; document.getElementById("productTitle").value = p?.title || ""; document.getElementById("productDesc").value = p?.desc || ""; document.getElementById("productPrice").value = p?.price != null ? p.price : ""; document.getElementById("productCategory").value = p?.category || ""; document.getElementById("productPopular").checked = !!p?.isPopular; document.getElementById("productImg").value = p?.img || ""; } + +function attachEvents(){ + const categorySelect=document.getElementById("categorySelect"); + const searchInput=document.getElementById("searchInput"); + categorySelect.addEventListener("change",e=>{state.category=e.target.value;renderAll()}); + searchInput.addEventListener("input",e=>{state.query=e.target.value;renderAll()}); + + document.addEventListener("click",e=>{ + const favBtn=e.target.closest("[data-fav]"); + if(favBtn){ const id=Number(favBtn.getAttribute("data-fav")); onFavoriteToggle(id); e.stopPropagation(); return; } + const viewTarget = e.target.closest("[data-view]"); if (viewTarget){ const id = Number(viewTarget.getAttribute("data-view")); openProductModal(id); return; } + const closer = e.target.closest("[data-close]"); if (closer){ const id = closer.getAttribute("data-close"); closeModalById(id); closeDrawerById(id); return; } + }); + + const detail = document.getElementById("productModal"); + detail.addEventListener("click", (e)=>{ + const incBtn = e.target.closest("[data-qty='1']"); + const decBtn = e.target.closest("[data-qty='-1']"); + const qtyInput = document.getElementById("detailQty"); + if (incBtn){ qtyInput.value = String(Math.max(1, Number(qtyInput.value||1)+1)); } + if (decBtn){ qtyInput.value = String(Math.max(1, Number(qtyInput.value||1)-1)); } + }); + document.getElementById("detailFavBtn").addEventListener("click",()=>{ const id = Number(document.getElementById("detailFavBtn").dataset.id); onFavoriteToggle(id); }); + document.getElementById("detailAddCart").addEventListener("click",()=>{ const id = Number(document.getElementById("detailFavBtn").dataset.id); const qty = Number(document.getElementById("detailQty").value||1); addToCart(id, qty); closeModalById("productModal"); openDrawer(document.getElementById("cartDrawer")); }); + + document.getElementById("cartBtn").addEventListener("click",()=>{ renderCart(); openDrawer(document.getElementById("cartDrawer")); }); + + const cartPanel = document.getElementById("cartDrawer"); + cartPanel.addEventListener("click",(e)=>{ + const inc = e.target.closest("[data-cart-inc]"); + const dec = e.target.closest("[data-cart-dec]"); + const rem = e.target.closest("[data-cart-remove]"); + if (inc){ const id = Number(inc.getAttribute("data-cart-inc")); updateCartQty(id, (state.cart[id]+1)); } + if (dec){ const id = Number(dec.getAttribute("data-cart-dec")); updateCartQty(id, Math.max(1, state.cart[id]-1)); } + if (rem){ const id = Number(rem.getAttribute("data-cart-remove")); removeFromCart(id); } + }); + cartPanel.addEventListener("input",(e)=>{ + const qtyInput = e.target.closest("[data-cart-qty]"); + if (qtyInput){ const id = Number(qtyInput.getAttribute("data-cart-qty")); const val = Number(qtyInput.value||1); updateCartQty(id, Math.max(1, val)); } + }); + document.getElementById("clearCartBtn").addEventListener("click",clearCart); + document.getElementById("checkoutBtn").addEventListener("click",()=>{ + const entries = Object.entries(state.cart); + if (!entries.length) { alert("Sepetiniz boş."); return; } + const total = cartTotals().total; + alert(`Ödeme başarılı! Toplam: ${formatPrice(total)}\nSiparişiniz alınmıştır.`); + clearCart(); + closeDrawerById("cartDrawer"); + }); + + document.getElementById("profileBtn").addEventListener("click",()=>{ updateAuthUI(); openModal(document.getElementById("authModal")); }); + + document.getElementById("loginForm").addEventListener("submit",(e)=>{ e.preventDefault(); const name = document.getElementById("loginName").value.trim(); const email = document.getElementById("loginEmail").value.trim(); if (!name || !email) return; state.user = {name, email}; saveUser(); updateAuthUI(); }); + + document.getElementById("logoutBtn").addEventListener("click",()=>{ state.user = null; saveUser(); updateAuthUI(); }); + + document.getElementById("sellerBtn").addEventListener("click",()=>{ if (!state.user){ updateAuthUI(); openModal(document.getElementById("authModal")); return; } renderSellerTable(); fillProductForm(null); openModal(document.getElementById("sellerModal")); }); + + document.getElementById("newProductBtn").addEventListener("click",()=>{ fillProductForm(null); }); + + document.getElementById("productForm").addEventListener("submit",(e)=>{ + e.preventDefault(); + const idVal = document.getElementById("productId").value; + const title = document.getElementById("productTitle").value.trim(); + const desc = document.getElementById("productDesc").value.trim(); + const price = Number(document.getElementById("productPrice").value||0); + const category = document.getElementById("productCategory").value.trim(); + const isPopular = document.getElementById("productPopular").checked; + const img = document.getElementById("productImg").value.trim(); + if (!title || !desc || !category || !img || price<=0) return; + if (idVal){ const id = Number(idVal); const idx = products.findIndex(p=>p.id===id); if (idx>-1){ products[idx] = {...products[idx], title, desc, price, category, isPopular, img}; } } + else { const newId = (products.reduce((m,p)=>Math.max(m,p.id), 0) || 0) + 1; products.push({ id:newId, title, desc, price, category, isPopular, img, createdAt: new Date().toISOString().slice(0,10) }); } + saveProducts(); populateCategories(); renderAll(); renderSellerTable(); fillProductForm(null); + }); + + document.getElementById("resetFormBtn").addEventListener("click",()=>{ fillProductForm(null); }); + + document.getElementById("sellerTable").addEventListener("click",(e)=>{ + const editBtn = e.target.closest("[data-edit]"); + const delBtn = e.target.closest("[data-delete]"); + if (editBtn){ const id = Number(editBtn.getAttribute("data-edit")); const p = products.find(x=>x.id===id); if (p) fillProductForm(p); } + if (delBtn){ const id = Number(delBtn.getAttribute("data-delete")); if (confirm(`#${id} ürün silinsin mi?`)){ products = products.filter(x=>x.id!==id); saveProducts(); populateCategories(); renderAll(); renderSellerTable(); } } + }); +} + +function init(){ loadFavorites(); loadProducts(); loadUser(); loadCart(); populateCategories(); attachEvents(); renderAll(); updateAuthUI(); updateCartCountBadge(); renderCart(); } + +document.addEventListener("DOMContentLoaded",init); diff --git a/tezgah/style.css b/tezgah/style.css new file mode 100644 index 00000000..f9a540b9 --- /dev/null +++ b/tezgah/style.css @@ -0,0 +1,307 @@ +:root{ + --bg:#0b1220; + --surface:#0f172a; + --muted:#64748b; + --text:#e6edf3; + --primary:#6c8cff; + --primary-600:#5b7cfa; + --accent:#ef4444; + --card:#0b132a; + --ring:rgba(108,140,255,.35); + --shadow:0 10px 30px rgba(2,8,23,.45); + --radius:14px; + --radius-sm:10px +} +*{box-sizing:border-box} +html,body{height:100%} +body{ + margin:0; + font-family:ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,Helvetica Neue,Arial,"Apple Color Emoji","Segoe UI Emoji"; + color:var(--text); + background: + radial-gradient(1000px 600px at -10% -10%,rgba(108,140,255,.08),transparent 50%), + radial-gradient(1000px 600px at 110% -10%,rgba(239,68,68,.08),transparent 50%), + linear-gradient(180deg,#070c19 0%, #0a1122 100%); + background-attachment: fixed +} +.container{ + width:100%; + max-width:1200px; + padding:0 20px; + margin:0 auto +} +.logo{ + display:inline-flex; + align-items:center; + gap:10px; + font-weight:800; + letter-spacing:.3px; + color:#fff; + text-decoration:none; + font-size:22px +} +.logo::before{ + content:""; + width:22px;height:22px; + border-radius:8px; + background: conic-gradient(from 180deg at 50% 50%, #6c8cff, #9b8cff, #ef4444, #6c8cff); + box-shadow:0 6px 18px rgba(108,140,255,.45), inset 0 0 24px rgba(255,255,255,.25) +} +.site-header{ + position:sticky;top:0;z-index:50; + background:rgba(10,17,34,.7); + backdrop-filter:saturate(140%) blur(10px); + border-bottom:1px solid rgba(255,255,255,.06) +} +.navbar{ + display:flex;align-items:center;justify-content:space-between; + height:70px;gap:16px +} +.nav-controls{ + display:flex;align-items:center;gap:12px;flex:1;max-width:680px;margin:0 16px +} +.category select{ + appearance:none; + background:var(--surface); + color:var(--text); + border:1px solid rgba(255,255,255,.08); + border-radius:12px; + height:44px; + padding:0 40px 0 14px; + outline:none; + transition:.2s border-color,.2s box-shadow,.2s background; + cursor:pointer +} +.category{position:relative} +.category::after{ + content:"▾"; + position:absolute;right:12px;top:50%;transform:translateY(-50%); + color:var(--muted);pointer-events:none +} +.category select:focus{border-color:var(--primary);box-shadow:0 0 0 6px var(--ring)} +.search{ + position:relative;flex:1 +} +.search input{ + width:100%; + height:44px; + background:var(--surface); + border:1px solid rgba(255,255,255,.08); + border-radius:12px; + color:var(--text); + outline:none; + padding:0 14px 0 14px; + transition:.2s border-color,.2s box-shadow +} +.search input::placeholder{color:rgba(230,237,243,.5)} +.search input:focus{border-color:var(--primary);box-shadow:0 0 0 6px var(--ring)} +.nav-actions{display:flex;align-items:center;gap:10px} +.btn{ + height:42px;display:inline-flex;align-items:center;justify-content:center; + padding:0 14px;border-radius:12px; + background:linear-gradient(180deg,var(--primary) 0%, var(--primary-600) 100%); + color:#020617;text-decoration:none;font-weight:700;border:none;cursor:pointer; + box-shadow:0 10px 24px rgba(108,140,255,.35), inset 0 -2px 0 rgba(0,0,0,.2); + transition:transform .12s ease, filter .2s ease, box-shadow .2s ease +} +.btn:hover{filter:saturate(115%);transform:translateY(-1px);box-shadow:0 16px 34px rgba(108,140,255,.4), inset 0 -2px 0 rgba(0,0,0,.25)} +.btn:active{transform:translateY(0)} +.btn.ghost{ + background:transparent;color:var(--text);border:1px solid rgba(255,255,255,.12); + box-shadow:none +} +.btn.ghost:hover{border-color:rgba(255,255,255,.2);background:rgba(255,255,255,.04)} +.btn.light{ + background:#fff;color:#0b1220;box-shadow:0 8px 26px rgba(255,255,255,.2) +} +.hero{padding:26px 0 10px} +.banners{ + display:grid;grid-template-columns:1fr 1fr;gap:16px +} +.banner{ + position:relative;min-height:220px;border-radius:var(--radius); + background-size:cover;background-position:center; + overflow:hidden;box-shadow:var(--shadow) +} +.banner::after{ + content:"";position:absolute;inset:0; + background:linear-gradient(180deg,rgba(0,0,0,.2) 0%, rgba(2,6,23,.8) 100%) +} +.banner-content{ + position:absolute;inset:0;display:flex;flex-direction:column;justify-content:flex-end;gap:6px; + padding:20px +} +.banner h2{margin:0;font-size:22px;line-height:1.2} +.banner p{margin:0 0 10px;color:rgba(230,237,243,.8)} +.section{padding:26px 0 6px} +.section-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:14px} +.section h3{margin:0;font-size:20px} +.product-grid{ + display:grid; + grid-template-columns:repeat(auto-fill,minmax(220px,1fr)); + gap:14px +} +.card{ + background:linear-gradient(180deg, rgba(255,255,255,.02) 0%, rgba(255,255,255,.01) 100%); + border:1px solid rgba(255,255,255,.06); + border-radius:var(--radius-sm); + overflow:hidden; + box-shadow:0 6px 20px rgba(2,8,23,.35); + transition:transform .16s ease, box-shadow .2s ease, border-color .2s ease; + cursor:pointer +} +.card:hover{transform:translateY(-3px);box-shadow:0 16px 40px rgba(2,8,23,.6);border-color:rgba(255,255,255,.14)} +.card-img{ + position:relative; + aspect-ratio:16/11; + background:var(--surface); + overflow:hidden +} +.card-img img{ + width:100%;height:100%;object-fit:cover;display:block; + transform:scale(1.02); + transition:transform .25s ease +} +.card:hover .card-img img{transform:scale(1.06)} +.favorite-btn{ + position:absolute;right:10px;top:10px; + width:38px;height:38px;border-radius:12px;border:1px solid rgba(255,255,255,.14); + display:inline-flex;align-items:center;justify-content:center; + background:rgba(2,6,23,.5); + backdrop-filter: blur(6px); + cursor:pointer; + transition:transform .12s ease, background .2s ease, border-color .2s ease +} +.favorite-btn:hover{transform:scale(1.05);background:rgba(2,6,23,.7);border-color:rgba(255,255,255,.24)} +.favorite-btn svg{fill:transparent;stroke:#fff;stroke-width:1.6} +.favorite-btn.active svg{fill:var(--accent);stroke:var(--accent)} +.card-body{padding:12px 12px 14px} +.card-title{ + margin:0 0 6px;font-size:15px;font-weight:700;letter-spacing:.2px; + white-space:nowrap;overflow:hidden;text-overflow:ellipsis +} +.card-desc{ + margin:0 0 10px;color:var(--muted);font-size:13px; + display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;min-height:36px +} +.card-foot{ + display:flex;align-items:center;justify-content:space-between +} +.price{ + font-weight:800;font-size:16px; + background:linear-gradient(90deg,#fff, #c3d0ff); + -webkit-background-clip:text;background-clip:text;color:transparent +} +.icon-btn{ + position:relative; + width:42px;height:42px;border-radius:12px;border:1px solid rgba(255,255,255,.12); + display:inline-flex;align-items:center;justify-content:center; + background:rgba(255,255,255,.02);color:#fff;text-decoration:none; + transition:.2s transform,.2s background,.2s border-color +} +.icon-btn:hover{transform:translateY(-2px);background:rgba(255,255,255,.06);border-color:rgba(255,255,255,.2)} +.badge{ + position:absolute;top:-6px;right:-6px; + min-width:18px;height:18px;border-radius:10px; + background:var(--accent);color:#fff; + font-size:11px;display:inline-flex;align-items:center;justify-content:center; + padding:0 5px;border:1px solid rgba(255,255,255,.2);box-shadow:0 2px 10px rgba(0,0,0,.3) +} +.site-footer{ + margin-top:34px;padding:34px 0;border-top:1px solid rgba(255,255,255,.06); + background:rgba(8,14,30,.5);backdrop-filter:saturate(140%) blur(8px) +} +.footer-inner{display:flex;align-items:flex-start;justify-content:space-between;gap:20px} +.footer-brand p{margin:8px 0 0;color:rgba(230,237,243,.7)} +.footer-social{display:flex;gap:10px} + +.modal{position:fixed;inset:0;display:grid;place-items:center;opacity:0;visibility:hidden;transition:.2s opacity,.2s visibility;z-index:80} +.modal.open{opacity:1;visibility:visible} +.modal-overlay{position:absolute;inset:0;background:rgba(2,6,23,.6);backdrop-filter:blur(6px)} +.modal-card{ + position:relative;z-index:1;background:linear-gradient(180deg, rgba(255,255,255,.03) 0%, rgba(255,255,255,.02) 100%); + border:1px solid rgba(255,255,255,.08);border-radius:16px;padding:18px;box-shadow:0 30px 80px rgba(0,0,0,.6); + width:min(920px,94vw);max-height:88vh;overflow:auto;transform:translateY(10px);animation:pop .2s ease forwards +} +.modal-card.small{width:min(420px,94vw)} +.modal-card.large{width:min(1100px,96vw)} +.modal-close{ + position:absolute;top:8px;right:8px;width:36px;height:36px;border-radius:10px;border:1px solid rgba(255,255,255,.12); + background:rgba(255,255,255,.04);color:#fff;cursor:pointer +} +@keyframes pop{to{transform:translateY(0)}} + +.product-detail{display:grid;grid-template-columns:1.2fr 1fr;gap:16px} +.detail-media img{width:100%;border-radius:14px;display:block;box-shadow:var(--shadow)} +.detail-info h3{margin:0 0 8px} +.detail-desc{color:rgba(230,237,243,.8);margin:0 0 12px} +.detail-meta{display:flex;align-items:center;gap:10px;margin-bottom:12px} +.chip{display:inline-flex;align-items:center;gap:6px;padding:6px 10px;border-radius:999px;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.1);color:#fff;font-size:12px} +.detail-actions{display:flex;align-items:center;gap:10px} +.qty{display:inline-flex;align-items:center;gap:6px;background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.1);border-radius:12px;padding:4px} +.qty input{width:52px;height:34px;border:0;background:transparent;color:#fff;text-align:center;outline:none} +.qty-btn{width:34px;height:34px;border-radius:10px;border:1px solid rgba(255,255,255,.1);background:rgba(255,255,255,.06);color:#fff;cursor:pointer} + +.form-grid{display:grid;grid-template-columns:1fr;gap:12px;margin-top:8px} +.form-row{display:grid;grid-template-columns:1fr 1fr auto;gap:12px} +label span{display:block;margin-bottom:6px;color:rgba(230,237,243,.8);font-size:13px} +input[type="text"], input[type="email"], input[type="number"], input[type="url"], textarea{ + width:100%;height:42px;padding:0 12px;border-radius:12px;border:1px solid rgba(255,255,255,.12); + background:var(--surface);color:var(--text);outline:none;transition:.2s border-color,.2s box-shadow +} +textarea{height:auto;padding:10px} +input:focus, textarea:focus{border-color:var(--primary);box-shadow:0 0 0 6px var(--ring)} +.checkbox{display:flex;align-items:center;gap:8px;padding-top:22px} +.form-actions{display:flex;gap:10px;justify-content:flex-end} + +.table-wrap{margin-top:16px;border:1px solid rgba(255,255,255,.08);border-radius:14px;overflow:auto} +.table{width:100%;border-collapse:separate;border-spacing:0} +.table th,.table td{padding:12px 10px;border-bottom:1px solid rgba(255,255,255,.06);white-space:nowrap} +.table thead th{position:sticky;top:0;background:rgba(15,23,42,.9);backdrop-filter:blur(4px);z-index:1} +.table tbody tr:hover{background:rgba(255,255,255,.03)} + +.seller-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:6px} +.seller-actions{display:flex;gap:10px} + +.drawer{position:fixed;inset:0;display:grid;grid-template-columns:1fr auto;opacity:0;visibility:hidden;transition:.2s opacity,.2s visibility;z-index:90} +.drawer.open{opacity:1;visibility:visible} +.drawer-overlay{background:rgba(2,6,23,.55);backdrop-filter:blur(6px)} +.drawer-panel{ + width:min(480px,96vw);background:linear-gradient(180deg, rgba(255,255,255,.03) 0%, rgba(255,255,255,.02) 100%); + border-left:1px solid rgba(255,255,255,.08);box-shadow:-30px 0 80px rgba(0,0,0,.6); + transform:translateX(20px);animation:slideIn .2s ease forwards;padding:16px;display:flex;flex-direction:column +} +.drawer-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:10px} +.cart-items{display:flex;flex-direction:column;gap:10px;overflow:auto;min-height:120px;max-height:60vh;padding-right:4px} +.cart-item{display:grid;grid-template-columns:56px 1fr auto;gap:10px;align-items:center;background:rgba(255,255,255,.03);border:1px solid rgba(255,255,255,.08);border-radius:12px;padding:8px} +.cart-item img{width:56px;height:56px;object-fit:cover;border-radius:10px} +.cart-item h4{margin:0;font-size:14px} +.cart-item .muted{color:var(--muted);font-size:12px} +.cart-qty{display:inline-flex;align-items:center;gap:6px;background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.1);border-radius:10px;padding:4px} +.cart-qty input{width:40px;height:30px;border:0;background:transparent;color:#fff;text-align:center;outline:none} +.cart-qty button{width:30px;height:30px;border-radius:8px;border:1px solid rgba(255,255,255,.1);background:rgba(255,255,255,.06);color:#fff;cursor:pointer} +.cart-summary{margin-top:12px;border-top:1px solid rgba(255,255,255,.08);padding-top:12px} +.cart-line{display:flex;align-items:center;justify-content:space-between;margin:6px 0} +.cart-line.small span{color:var(--muted)} +.cart-line.total strong{font-size:18px} +.cart-actions{display:flex;gap:10px;justify-content:flex-end;margin-top:10px} +@keyframes slideIn{to{transform:translateX(0)}} + +.hidden{display:none} +.profile-box{padding:12px;border:1px solid rgba(255,255,255,.08);border-radius:12px;background:rgba(255,255,255,.03)} + +@media (max-width:1024px){ + .nav-controls{max-width:none} + .product-detail{grid-template-columns:1fr} +} +@media (max-width:900px){ + .banners{grid-template-columns:1fr} +} +@media (max-width:720px){ + .navbar{height:66px} + .nav-controls{gap:10px;margin:0 8px} + .category select{height:40px} + .search input{height:40px} + .btn{height:40px;padding:0 12px} + .footer-inner{flex-direction:column} +}