Creating visually appealing image grids can significantly enhance the user experience on your website. Whether you're showcasing a portfolio, a product gallery, or a collection of memories, the right image grid can make all the difference.
In this article, we'll explore 10 stunning image grid examples that can inspire your next design project. Each example demonstrates unique ways to organize and display images effectively.
CODE1
Here's the code:
CODETEXT1
CODE2
Here's the code:
CODETEXT2
CODE3
Here's the code:
CODETEXT3
CODE4
Here's the code:
CODETEXT4
CODE5
Here's the code:
CODETEXT5
Designers and developers, elevate your projects with Subframe's drag-and-drop interface and intuitive, responsive canvas. Create pixel-perfect image grids effortlessly, ensuring a seamless user experience every time.
Loved by professionals, Subframe makes stunning UI accessible to all. Start for free today!
CODE6
Here's the code:
CODETEXT6
CODE7
Here's the code:
CODETEXT7
CODE8
Here's the code:
CODETEXT8
CODE9
Here's the code:
CODETEXT9
CODE10
Here's the code:
CODETEXT10
Ready to elevate your design game? With Subframe, you can create pixel-perfect UIs, including stunning image grids, in minutes. Our drag-and-drop interface ensures efficiency and precision.
Don't wait! Start for free and begin designing immediately. Experience the ease and power of Subframe today!
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Modern Collection</title> <style> /* Base styles */ * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; } body { background-color: #ffffff; color: #333; padding: 15px; width: 100%; height: 100%; max-width: 700px; margin: 0 auto; overflow-x: hidden; } .container { max-width: 100%; margin: 0 auto; } header { margin-bottom: 20px; position: relative; } h1 { font-size: 24px; font-weight: 700; letter-spacing: -0.5px; margin-bottom: 8px; } .controls { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; } .search-box { position: relative; flex: 1; max-width: 250px; } .search-box input { width: 100%; padding: 10px 15px; border: 1px solid #eaeaea; border-radius: 8px; font-size: 14px; background-color: #f9f9f9; transition: all 0.2s ease; } .search-box input:focus { outline: none; border-color: #ccc; box-shadow: 0 0 0 3px rgba(0,0,0,0.05); } .search-box::after { content: "⌕"; position: absolute; right: 12px; top: 50%; transform: translateY(-50%); color: #888; font-size: 16px; } .filter-dropdown { position: relative; margin-left: 10px; } .filter-btn { background: white; border: 1px solid #eaeaea; padding: 10px 15px; border-radius: 8px; font-size: 14px; cursor: pointer; display: flex; align-items: center; gap: 5px; transition: all 0.2s ease; } .filter-btn:hover { background-color: #f9f9f9; } .filter-btn::after { content: "⌄"; font-size: 12px; } /* Masonry grid styles */ .masonry-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); grid-gap: 15px; grid-auto-flow: dense; } .grid-item { position: relative; border-radius: 8px; overflow: hidden; transition: transform 0.3s ease, box-shadow 0.3s ease; cursor: pointer; background-color: white; box-shadow: 0 4px 12px rgba(0,0,0,0.05); } .grid-item:hover { transform: translateY(-5px); box-shadow: 0 10px 20px rgba(0,0,0,0.1); z-index: 2; } .grid-item:nth-child(4n+1) { grid-row: span 2; } .grid-item:nth-child(5n) { grid-column: span 2; } .product-image { width: 100%; height: 100%; object-fit: cover; display: block; transition: all 0.3s ease; } .product-info { position: absolute; bottom: 0; left: 0; right: 0; background: linear-gradient(to top, rgba(255,255,255,0.95), rgba(255,255,255,0)); padding: 15px; transform: translateY(100%); transition: transform 0.3s ease; display: flex; flex-direction: column; justify-content: flex-end; } .grid-item:hover .product-info { transform: translateY(0); } .grid-item:hover .product-image { filter: brightness(0.95); } .product-name { font-size: 14px; font-weight: 600; margin-bottom: 5px; color: #222; } .product-price { font-size: 16px; font-weight: 700; color: #333; margin-bottom: 8px; } .quick-add { display: inline-block; background-color: #222; color: white; border: none; padding: 8px 12px; border-radius: 6px; font-size: 12px; font-weight: 500; cursor: pointer; transition: all 0.2s ease; opacity: 0; transform: translateY(10px); width: fit-content; } .grid-item:hover .quick-add { opacity: 1; transform: translateY(0); } .quick-add:hover { background-color: #000; } .cart-indicator { position: fixed; top: 15px; right: 15px; background-color: #222; color: white; width: 24px; height: 24px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 12px; opacity: 0; transition: all 0.3s ease; z-index: 100; pointer-events: none; } .cart-indicator.show { animation: pulse 0.4s ease-out; opacity: 1; } .product-tag { position: absolute; top: 10px; left: 10px; background-color: rgba(255,255,255,0.9); color: #333; padding: 4px 8px; border-radius: 4px; font-size: 10px; font-weight: 600; box-shadow: 0 2px 4px rgba(0,0,0,0.1); z-index: 2; } .product-tag.new { background-color: #007bff; color: white; } .product-tag.sale { background-color: #e74c3c; color: white; } .product-tag.bestseller { background-color: #f1c40f; color: #333; } .loader { width: 100%; height: 3px; background-color: #f1f1f1; position: relative; margin-bottom: 20px; border-radius: 3px; overflow: hidden; } .loader::after { content: ''; position: absolute; top: 0; left: 0; height: 100%; width: 30%; background-color: #222; animation: loading 1.5s infinite ease-in-out; border-radius: 3px; } @keyframes loading { 0% { left: -30%; } 100% { left: 100%; } } @keyframes pulse { 0% { transform: scale(0.8); } 50% { transform: scale(1.2); } 100% { transform: scale(1); } } .cart-added { position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%) translateY(100px); background-color: #222; color: white; padding: 10px 20px; border-radius: 8px; font-size: 14px; box-shadow: 0 5px 15px rgba(0,0,0,0.2); z-index: 100; opacity: 0; transition: all 0.3s ease; } .cart-added.show { transform: translateX(-50%) translateY(0); opacity: 1; } /* Responsive styles */ @media (max-width: 600px) { .masonry-grid { grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); grid-gap: 10px; } .controls { flex-direction: column; align-items: flex-start; } .search-box { max-width: 100%; width: 100%; margin-bottom: 10px; } .filter-dropdown { margin-left: 0; } h1 { font-size: 20px; } } @media (max-width: 400px) { .masonry-grid { grid-template-columns: repeat(2, 1fr); } } </style> </head> <body> <div class="container"> <header> <h1>Modern Collection</h1> <p>Curated home essentials with a minimalist approach</p> </header> <div class="controls"> <div class="search-box"> <input type="text" placeholder="Search products..."> </div> <div class="filter-dropdown"> <button class="filter-btn">Sort by: Featured</button> </div> </div> <div class="loader"></div> <div class="masonry-grid"> <!-- Grid items will be inserted here by JavaScript --> </div> <div class="cart-indicator">1</div> <div class="cart-added">Added to cart</div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Product data const products = [ { name: "Scandinavian Oak Chair", price: "$149", image: "https://images.unsplash.com/photo-1598300042247-d088f8ab3a91?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80", tag: "bestseller" }, { name: "Minimalist Table Lamp", price: "$89", image: "https://images.unsplash.com/photo-1507473885765-e6ed057f782c?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80", tag: "new" }, { name: "Ceramic Vase Set", price: "$65", image: "https://images.unsplash.com/photo-1612196808214-2e557c604e52?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80" }, { name: "Natural Fiber Rug", price: "$199", image: "https://images.unsplash.com/photo-1586023492125-27b2c045efd7?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80", tag: "sale" }, { name: "Leather Accent Pillow", price: "$79", image: "https://images.unsplash.com/photo-1616046229478-9901c5536a45?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80" }, { name: "Brushed Brass Planter", price: "$49", image: "https://images.unsplash.com/photo-1602816785550-15fef4d710a6?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80", tag: "new" }, { name: "Modern Coffee Table", price: "$329", image: "https://images.unsplash.com/photo-1532372320572-cda25653a694?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80", tag: "bestseller" }, { name: "Handcrafted Ceramic Mug", price: "$24", image: "https://images.unsplash.com/photo-1614849962791-c9c1e0c8c14e?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80" }, { name: "Woven Wall Hanging", price: "$119", image: "https://images.unsplash.com/photo-1601628828688-632f38a5a7d0?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80", tag: "sale" }, { name: "Marble Wall Clock", price: "$89", image: "https://images.unsplash.com/photo-1563920443079-783e5c786b83?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80" } ]; const masonryGrid = document.querySelector('.masonry-grid'); const cartIndicator = document.querySelector('.cart-indicator'); const cartAddedNotification = document.querySelector('.cart-added'); const loader = document.querySelector('.loader'); let cartCount = 0; // Simulate loading time setTimeout(() => { loader.style.display = 'none'; renderProducts(); }, 800); function renderProducts() { products.forEach(product => { const gridItem = document.createElement('div'); gridItem.className = 'grid-item'; let tagHTML = ''; if (product.tag) { tagHTML = `<div class="product-tag ${product.tag}">${product.tag}</div>`; } gridItem.innerHTML = ` ${tagHTML} <img src="${product.image}" alt="${product.name}" class="product-image"> <div class="product-info"> <div class="product-name">${product.name}</div> <div class="product-price">${product.price}</div> <button class="quick-add">+ Add to Cart</button> </div> `; masonryGrid.appendChild(gridItem); const addButton = gridItem.querySelector('.quick-add'); addButton.addEventListener('click', function(e) { e.stopPropagation(); addToCart(product); }); }); } function addToCart(product) { cartCount++; cartIndicator.textContent = cartCount; cartIndicator.classList.add('show'); cartAddedNotification.textContent = `Added ${product.name} to cart`; cartAddedNotification.classList.add('show'); setTimeout(() => { cartAddedNotification.classList.remove('show'); }, 2000); } // Search functionality const searchInput = document.querySelector('.search-box input'); searchInput.addEventListener('input', function() { const searchTerm = this.value.toLowerCase(); document.querySelectorAll('.grid-item').forEach(item => { const productName = item.querySelector('.product-name').textContent.toLowerCase(); if (productName.includes(searchTerm)) { item.style.display = 'block'; } else { item.style.display = 'none'; } }); }); // Filter dropdown simulation const filterBtn = document.querySelector('.filter-btn'); filterBtn.addEventListener('click', function() { const options = ['Featured', 'Price: Low to High', 'Price: High to Low', 'Newest']; const currentOption = this.textContent.replace('Sort by: ', ''); const currentIndex = options.indexOf(currentOption); const nextIndex = (currentIndex + 1) % options.length; this.textContent = `Sort by: ${options[nextIndex]}`; // Simulate reordering (just a visual effect for demo) const items = Array.from(document.querySelectorAll('.grid-item')); items.forEach(item => item.remove()); if (nextIndex === 1) { // Low to High items.sort((a, b) => { const priceA = parseInt(a.querySelector('.product-price').textContent.replace('$', '')); const priceB = parseInt(b.querySelector('.product-price').textContent.replace('$', '')); return priceA - priceB; }); } else if (nextIndex === 2) { // High to Low items.sort((a, b) => { const priceA = parseInt(a.querySelector('.product-price').textContent.replace('$', '')); const priceB = parseInt(b.querySelector('.product-price').textContent.replace('$', '')); return priceB - priceA; }); } else { // Randomize for other options just for demo items.sort(() => Math.random() - 0.5); } items.forEach(item => masonryGrid.appendChild(item)); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Vision Scope Photography</title> <style> :root { --bg-color: #121212; --text-color: #f5f5f5; --accent-color: #e63946; --overlay-color: rgba(0, 0, 0, 0.7); --grid-gap: 8px; --transition-speed: 0.3s; } * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Helvetica Neue', Arial, sans-serif; background-color: var(--bg-color); color: var(--text-color); width: 100%; height: 100%; overflow-x: hidden; } .container { max-width: 700px; height: 700px; margin: 0 auto; padding: 20px; display: flex; flex-direction: column; overflow-y: auto; scrollbar-width: thin; scrollbar-color: var(--accent-color) var(--bg-color); } .container::-webkit-scrollbar { width: 6px; } .container::-webkit-scrollbar-track { background: var(--bg-color); } .container::-webkit-scrollbar-thumb { background-color: var(--accent-color); border-radius: 6px; } header { margin-bottom: 20px; } h1 { font-size: 2.5rem; font-weight: 900; letter-spacing: -1px; margin-bottom: 5px; position: relative; display: inline-block; } h1::after { content: ''; position: absolute; width: 30%; height: 4px; background: var(--accent-color); bottom: -6px; left: 0; transform-origin: left; transform: scaleX(1); transition: transform 0.3s ease; } h1:hover::after { transform: scaleX(1.5); } .subtitle { font-size: 1rem; font-weight: 300; opacity: 0.7; margin-bottom: 20px; } .filter-container { display: flex; justify-content: flex-start; margin-bottom: 20px; flex-wrap: wrap; gap: 10px; } .filter-btn { background: transparent; border: 1px solid #333; color: var(--text-color); padding: 6px 12px; border-radius: 30px; cursor: pointer; font-size: 0.85rem; transition: all var(--transition-speed) ease; } .filter-btn:hover, .filter-btn.active { background: var(--accent-color); border-color: var(--accent-color); transform: translateY(-2px); box-shadow: 0 4px 8px rgba(230, 57, 70, 0.3); } .filter-btn.active { font-weight: bold; } .gallery { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--grid-gap); margin-bottom: 30px; } .gallery-item { position: relative; overflow: hidden; aspect-ratio: 1/1; border-radius: 2px; cursor: pointer; transition: transform 0.4s cubic-bezier(0.19, 1, 0.22, 1); } .gallery-item:hover { transform: scale(1.02); z-index: 1; } .gallery-item img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform 0.8s cubic-bezier(0.19, 1, 0.22, 1); } .gallery-item:hover img { transform: scale(1.1); } .gallery-item::before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: var(--overlay-color); opacity: 0; transition: opacity var(--transition-speed) ease; z-index: 1; } .gallery-item:hover::before { opacity: 1; } .item-info { position: absolute; bottom: 0; left: 0; width: 100%; padding: 15px; color: var(--text-color); z-index: 2; transform: translateY(20px); opacity: 0; transition: all 0.4s cubic-bezier(0.19, 1, 0.22, 1); } .gallery-item:hover .item-info { transform: translateY(0); opacity: 1; } .item-title { font-size: 1rem; font-weight: 700; margin-bottom: 4px; } .item-category { font-size: 0.8rem; opacity: 0.8; } .lightbox { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.9); display: flex; align-items: center; justify-content: center; z-index: 1000; opacity: 0; pointer-events: none; transition: opacity 0.3s ease; } .lightbox.active { opacity: 1; pointer-events: all; } .lightbox-content { position: relative; max-width: 90%; max-height: 80vh; } .lightbox-image { display: block; max-width: 100%; max-height: 80vh; border: 2px solid rgba(255, 255, 255, 0.1); box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3); } .lightbox-close { position: absolute; top: -40px; right: 0; width: 30px; height: 30px; display: flex; align-items: center; justify-content: center; background: var(--accent-color); color: white; border: none; border-radius: 50%; cursor: pointer; font-weight: bold; transition: all 0.2s ease; } .lightbox-close:hover { transform: scale(1.1); } .lightbox-info { position: absolute; bottom: -60px; left: 0; width: 100%; color: white; } .lightbox-title { font-size: 1.2rem; font-weight: bold; margin-bottom: 5px; } .lightbox-description { font-size: 0.9rem; opacity: 0.8; } .lightbox-nav { position: absolute; top: 50%; width: 100%; display: flex; justify-content: space-between; transform: translateY(-50%); padding: 0 20px; } .lightbox-prev, .lightbox-next { background: rgba(0, 0, 0, 0.5); color: white; border: none; width: 40px; height: 40px; border-radius: 50%; display: flex; align-items: center; justify-content: center; cursor: pointer; transition: all 0.2s ease; } .lightbox-prev:hover, .lightbox-next:hover { background: var(--accent-color); } @media (max-width: 600px) { .gallery { grid-template-columns: repeat(2, 1fr); } h1 { font-size: 2rem; } .subtitle { font-size: 0.9rem; } } @media (max-width: 400px) { .gallery { grid-template-columns: 1fr; } } /* Loading animation */ .loader { width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; position: fixed; top: 0; left: 0; background-color: var(--bg-color); z-index: 9999; transition: opacity 0.5s ease, visibility 0.5s ease; } .loader.hidden { opacity: 0; visibility: hidden; } .loader-circle { width: 50px; height: 50px; border: 3px solid rgba(255, 255, 255, 0.1); border-top-color: var(--accent-color); border-radius: 50%; animation: spin 1s ease-in-out infinite; } @keyframes spin { to { transform: rotate(360deg); } } /* Cursor effect */ .custom-cursor { position: fixed; width: 20px; height: 20px; border-radius: 50%; background-color: var(--accent-color); opacity: 0.5; pointer-events: none; z-index: 9999; mix-blend-mode: difference; transform: translate(-50%, -50%) scale(1); transition: transform 0.1s ease; } .gallery-item:hover ~ .custom-cursor { transform: translate(-50%, -50%) scale(1.5); } </style> </head> <body> <div class="loader"> <div class="loader-circle"></div> </div> <div class="custom-cursor"></div> <div class="container"> <header> <h1>Vision Scope</h1> <p class="subtitle">Capturing ephemeral moments in time across diverse landscapes and cultures</p> </header> <div class="filter-container"> <button class="filter-btn active" data-filter="all">All</button> <button class="filter-btn" data-filter="landscape">Landscape</button> <button class="filter-btn" data-filter="portrait">Portrait</button> <button class="filter-btn" data-filter="street">Street</button> <button class="filter-btn" data-filter="abstract">Abstract</button> </div> <div class="gallery"> <!-- Gallery items will be inserted here by JavaScript --> </div> </div> <div class="lightbox"> <div class="lightbox-content"> <button class="lightbox-close">×</button> <img src="" alt="" class="lightbox-image"> <div class="lightbox-info"> <h3 class="lightbox-title"></h3> <p class="lightbox-description"></p> </div> <div class="lightbox-nav"> <button class="lightbox-prev">←</button> <button class="lightbox-next">→</button> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Photography portfolio data const portfolioItems = [ { id: 1, title: "Misty Mountain Ridge", category: "landscape", image: "https://images.unsplash.com/photo-1506905925346-21bda4d32df4?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=600&q=80", description: "Dawn breaks over the Cascade Mountains, revealing layers of ridges disappearing into morning fog." }, { id: 2, title: "Urban Reflections", category: "abstract", image: "https://images.unsplash.com/photo-1594794312433-05a69a98b7a0?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=600&q=80", description: "Glass facade architecture creating mesmerizing patterns as sunlight bounces across downtown buildings." }, { id: 3, title: "Market Vendor", category: "portrait", image: "https://images.unsplash.com/photo-1551843073-4a9a5b6fcd5f?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=600&q=80", description: "A weathered face tells stories of generations at this Bangkok floating market stall." }, { id: 4, title: "Twilight Crosswalk", category: "street", image: "https://images.unsplash.com/photo-1519575706483-221027bfbb31?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=600&q=80", description: "Tokyo's Shibuya crossing at blue hour, when pedestrians become moving light paintings." }, { id: 5, title: "Desert Solitude", category: "landscape", image: "https://images.unsplash.com/photo-1473580044384-7ba9967e16a0?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=600&q=80", description: "Namibia's ancient dunes create a rhythmic pattern of light and shadow at sunset." }, { id: 6, title: "Childhood Wonder", category: "portrait", image: "https://images.unsplash.com/photo-1518826778770-a729fb53327c?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=600&q=80", description: "A young girl's first encounter with ocean waves along the Amalfi Coast." }, { id: 7, title: "Rain-Soaked Street", category: "street", image: "https://images.unsplash.com/photo-1493954342427-e1c860191f8f?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=600&q=80", description: "New York after rainfall, umbrellas creating moving canvases against neon reflections." }, { id: 8, title: "Geometric Shadows", category: "abstract", image: "https://images.unsplash.com/photo-1518640467707-6811f4a6ab73?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=600&q=80", description: "Barcelona's modern architecture creates a study in intersecting lines and negative space." }, { id: 9, title: "Aurora Whispers", category: "landscape", image: "https://images.unsplash.com/photo-1531366936337-7c912a4589a7?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=600&q=80", description: "Iceland's winter night sky dances with green and purple light above volcanic terrain." }, ]; // Initialize gallery const gallery = document.querySelector('.gallery'); const lightbox = document.querySelector('.lightbox'); const lightboxImage = document.querySelector('.lightbox-image'); const lightboxTitle = document.querySelector('.lightbox-title'); const lightboxDescription = document.querySelector('.lightbox-description'); const lightboxClose = document.querySelector('.lightbox-close'); const lightboxPrev = document.querySelector('.lightbox-prev'); const lightboxNext = document.querySelector('.lightbox-next'); const filterButtons = document.querySelectorAll('.filter-btn'); let currentImageIndex = 0; let filteredItems = [...portfolioItems]; // Load images with a delay to simulate loading setTimeout(() => { document.querySelector('.loader').classList.add('hidden'); renderGallery(portfolioItems); }, 1000); // Render gallery items function renderGallery(items) { gallery.innerHTML = ''; items.forEach(item => { const galleryItem = document.createElement('div'); galleryItem.classList.add('gallery-item'); galleryItem.dataset.category = item.category; galleryItem.innerHTML = ` <img src="${item.image}" alt="${item.title}"> <div class="item-info"> <h3 class="item-title">${item.title}</h3> <p class="item-category">${item.category.charAt(0).toUpperCase() + item.category.slice(1)}</p> </div> `; galleryItem.addEventListener('click', () => { openLightbox(item, items); }); gallery.appendChild(galleryItem); }); // Add animation to gallery items const allItems = document.querySelectorAll('.gallery-item'); allItems.forEach((item, index) => { setTimeout(() => { item.style.opacity = '0'; item.style.transform = 'translateY(20px)'; item.style.transition = 'opacity 0.5s ease, transform 0.5s ease'; setTimeout(() => { item.style.opacity = '1'; item.style.transform = 'translateY(0)'; }, 50); }, index * 100); }); } // Filter functionality filterButtons.forEach(button => { button.addEventListener('click', () => { // Update active state filterButtons.forEach(btn => btn.classList.remove('active')); button.classList.add('active'); const filterValue = button.dataset.filter; if (filterValue === 'all') { filteredItems = [...portfolioItems]; } else { filteredItems = portfolioItems.filter(item => item.category === filterValue); } renderGallery(filteredItems); }); }); // Lightbox functionality function openLightbox(item, items) { lightboxImage.src = item.image; lightboxTitle.textContent = item.title; lightboxDescription.textContent = item.description; lightbox.classList.add('active'); document.body.style.overflow = 'hidden'; // Set current index currentImageIndex = items.findIndex(i => i.id === item.id); } function closeLightbox() { lightbox.classList.remove('active'); document.body.style.overflow = ''; } function navigateLightbox(direction) { currentImageIndex = (currentImageIndex + direction + filteredItems.length) % filteredItems.length; const newItem = filteredItems[currentImageIndex]; // Create a new image element to preload const preloadImage = new Image(); preloadImage.src = newItem.image; preloadImage.onload = function() { // Apply a transition effect lightboxImage.style.opacity = '0'; lightboxTitle.style.opacity = '0'; lightboxDescription.style.opacity = '0'; setTimeout(() => { lightboxImage.src = newItem.image; lightboxTitle.textContent = newItem.title; lightboxDescription.textContent = newItem.description; lightboxImage.style.opacity = '1'; lightboxTitle.style.opacity = '1'; lightboxDescription.style.opacity = '1'; }, 300); }; } lightboxClose.addEventListener('click', closeLightbox); lightboxPrev.addEventListener('click', () => navigateLightbox(-1)); lightboxNext.addEventListener('click', () => navigateLightbox(1)); // Close lightbox when clicking outside of content lightbox.addEventListener('click', function(e) { if (e.target === lightbox) { closeLightbox(); } }); // Keyboard navigation document.addEventListener('keydown', function(e) { if (!lightbox.classList.contains('active')) return; if (e.key === 'Escape') { closeLightbox(); } else if (e.key === 'ArrowLeft') { navigateLightbox(-1); } else if (e.key === 'ArrowRight') { navigateLightbox(1); } }); // Custom cursor const cursor = document.querySelector('.custom-cursor'); document.addEventListener('mousemove', (e) => { cursor.style.left = e.clientX + 'px'; cursor.style.top = e.clientY + 'px'; }); document.addEventListener('mousedown', () => { cursor.style.transform = 'translate(-50%, -50%) scale(0.8)'; }); document.addEventListener('mouseup', () => { cursor.style.transform = 'translate(-50%, -50%) scale(1)'; }); // Hide cursor when leaving window document.addEventListener('mouseleave', () => { cursor.style.opacity = '0'; }); document.addEventListener('mouseenter', () => { cursor.style.opacity = '0.5'; }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>PIXEL8 Creative Showcase</title> <style> :root { --accent-1: #FF3366; --accent-2: #33CCFF; --accent-3: #FFCC00; --accent-4: #66FF99; --dark: #1A1A2E; --light: #F7F7F9; --transition: all 0.4s cubic-bezier(0.16, 1, 0.3, 1); } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; } body { background-color: var(--light); color: var(--dark); overflow-x: hidden; width: 100%; height: 100%; font-size: 16px; line-height: 1.6; } .container { width: 100%; max-width: 700px; height: 700px; margin: 0 auto; padding: 1rem; position: relative; overflow-y: auto; overflow-x: hidden; scrollbar-width: thin; scrollbar-color: var(--accent-1) var(--light); } .container::-webkit-scrollbar { width: 6px; } .container::-webkit-scrollbar-track { background: var(--light); } .container::-webkit-scrollbar-thumb { background-color: var(--accent-1); border-radius: 20px; } header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 2rem; position: sticky; top: 0; z-index: 100; padding: 1rem 0; background-color: rgba(247, 247, 249, 0.9); backdrop-filter: blur(10px); } .logo { font-weight: 800; font-size: 1.5rem; background: linear-gradient(90deg, var(--accent-1), var(--accent-2)); -webkit-background-clip: text; -webkit-text-fill-color: transparent; letter-spacing: -1px; display: flex; align-items: center; } .logo::before { content: ""; display: inline-block; width: 10px; height: 10px; background: var(--accent-3); margin-right: 8px; transform: rotate(45deg); animation: rotate 6s infinite linear; } @keyframes rotate { 0% { transform: rotate(45deg); } 100% { transform: rotate(405deg); } } .filters { display: flex; gap: 0.8rem; flex-wrap: wrap; } .filter-btn { background: none; border: none; cursor: pointer; font-size: 0.85rem; font-weight: 600; color: var(--dark); opacity: 0.6; transition: var(--transition); position: relative; padding: 0.25rem 0.5rem; } .filter-btn::after { content: ""; position: absolute; width: 0; height: 2px; bottom: 0; left: 0; background-color: currentColor; transition: var(--transition); } .filter-btn:hover { opacity: 1; } .filter-btn:hover::after { width: 100%; } .filter-btn.active { opacity: 1; } .filter-btn.active::after { width: 100%; background-color: var(--accent-1); } .grid { display: grid; grid-template-columns: repeat(12, 1fr); gap: 1.5rem; margin-bottom: 3rem; } .project { border-radius: 8px; overflow: hidden; position: relative; transition: var(--transition); opacity: 1; transform: translateY(0); cursor: pointer; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1); } .project.hidden { opacity: 0; transform: translateY(20px); pointer-events: none; position: absolute; z-index: -1; } .project-1 { grid-column: 1 / 9; grid-row: 1 / 3; transform: rotate(-2deg); } .project-2 { grid-column: 8 / 13; grid-row: 1 / 4; transform: rotate(2deg); z-index: 2; } .project-3 { grid-column: 1 / 6; grid-row: 3 / 6; transform: rotate(1deg); } .project-4 { grid-column: 5 / 13; grid-row: 4 / 7; transform: rotate(-1deg); z-index: 1; } .project-5 { grid-column: 1 / 8; grid-row: 6 / 9; transform: rotate(-1.5deg); z-index: 3; } .project-6 { grid-column: 7 / 13; grid-row: 7 / 10; transform: rotate(1.5deg); } .project:hover { transform: scale(1.02) rotate(0); z-index: 10; box-shadow: 0 12px 32px rgba(0, 0, 0, 0.15); } .project-img { width: 100%; height: 100%; object-fit: cover; transition: var(--transition); } .project:hover .project-img { transform: scale(1.05); } .project-content { position: absolute; bottom: 0; left: 0; width: 100%; padding: 1.5rem; background: linear-gradient(to top, rgba(0, 0, 0, 0.8), transparent); color: white; transform: translateY(30%); opacity: 0; transition: var(--transition); } .project:hover .project-content { transform: translateY(0); opacity: 1; } .project-title { font-size: 1.2rem; font-weight: 700; margin-bottom: 0.5rem; background: linear-gradient(90deg, #fff, var(--accent-4)); -webkit-background-clip: text; -webkit-text-fill-color: transparent; letter-spacing: -0.5px; } .project-category { font-size: 0.8rem; font-weight: 600; display: inline-block; padding: 0.2rem 0.8rem; border-radius: 20px; margin-bottom: 0.5rem; } .project-desc { font-size: 0.85rem; max-width: 90%; opacity: 0.9; } .digital .project-category { background-color: var(--accent-1); color: white; } .branding .project-category { background-color: var(--accent-2); color: var(--dark); } .print .project-category { background-color: var(--accent-3); color: var(--dark); } .motion .project-category { background-color: var(--accent-4); color: var(--dark); } .cursor { width: 40px; height: 40px; border-radius: 50%; border: 2px solid var(--accent-1); position: fixed; transform: translate(-50%, -50%); pointer-events: none; z-index: 9999; mix-blend-mode: difference; transition: all 0.1s ease; display: none; } @media (min-width: 600px) { .cursor { display: block; } } @media (max-width: 600px) { .grid { grid-template-columns: 1fr; gap: 1rem; } .project { grid-column: 1 / -1 !important; grid-row: auto !important; aspect-ratio: 16/9; transform: none !important; } .project-content { transform: translateY(0); opacity: 1; padding: 1rem; } .project-title { font-size: 1rem; } .project-desc { display: none; } .filters { gap: 0.5rem; } .filter-btn { font-size: 0.75rem; padding: 0.2rem 0.4rem; } } .footer { text-align: center; margin-top: 2rem; font-size: 0.8rem; opacity: 0.7; } .section-title { font-size: 2rem; font-weight: 800; margin-bottom: 1.5rem; letter-spacing: -1px; position: relative; display: inline-block; } .section-title::after { content: ""; position: absolute; width: 50%; height: 6px; background: var(--accent-1); bottom: -10px; left: 0; border-radius: 3px; } </style> </head> <body> <div class="cursor"></div> <div class="container"> <header> <div class="logo">PIXEL8</div> <div class="filters"> <button class="filter-btn active" data-filter="all">All</button> <button class="filter-btn" data-filter="digital">Digital</button> <button class="filter-btn" data-filter="branding">Branding</button> <button class="filter-btn" data-filter="print">Print</button> <button class="filter-btn" data-filter="motion">Motion</button> </div> </header> <h1 class="section-title">Featured Work</h1> <div class="grid"> <div class="project project-1 digital" data-category="digital"> <img src="https://images.unsplash.com/photo-1541462608143-67571c6738dd?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2070&q=80" alt="Digital Project" class="project-img"> <div class="project-content"> <span class="project-category">Digital</span> <h3 class="project-title">Nebula AI Dashboard</h3> <p class="project-desc">A futuristic interface redesign for an AI platform that analyzes user behavior patterns.</p> </div> </div> <div class="project project-2 branding" data-category="branding"> <img src="https://images.unsplash.com/photo-1634942537034-2531766767d1?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2069&q=80" alt="Branding Project" class="project-img"> <div class="project-content"> <span class="project-category">Branding</span> <h3 class="project-title">Lumina Cosmetics</h3> <p class="project-desc">Complete brand identity for a sustainable cosmetics line that emphasizes natural ingredients.</p> </div> </div> <div class="project project-3 print" data-category="print"> <img src="https://images.unsplash.com/photo-1586075010923-2dd4570fb338?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2487&q=80" alt="Print Project" class="project-img"> <div class="project-content"> <span class="project-category">Print</span> <h3 class="project-title">Kinetic Typography Mag</h3> <p class="project-desc">Experimental magazine design featuring innovative layouts and typographic treatments.</p> </div> </div> <div class="project project-4 motion" data-category="motion"> <img src="https://images.unsplash.com/photo-1550745165-9bc0b252726f?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2070&q=80" alt="Motion Project" class="project-img"> <div class="project-content"> <span class="project-category">Motion</span> <h3 class="project-title">Pulse Music Visualizer</h3> <p class="project-desc">A reactive music visualization system that transforms audio into dynamic geometric patterns.</p> </div> </div> <div class="project project-5 digital" data-category="digital"> <img src="https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2064&q=80" alt="Digital Project" class="project-img"> <div class="project-content"> <span class="project-category">Digital</span> <h3 class="project-title">Quantum E-Commerce</h3> <p class="project-desc">Cutting-edge mobile shopping experience with spatial product visualization features.</p> </div> </div> <div class="project project-6 branding" data-category="branding"> <img src="https://images.unsplash.com/photo-1600132806370-bf17e65e942f?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2094&q=80" alt="Branding Project" class="project-img"> <div class="project-content"> <span class="project-category">Branding</span> <h3 class="project-title">Vertex Architecture</h3> <p class="project-desc">Bold and geometric visual identity for a forward-thinking architectural studio.</p> </div> </div> </div> <div class="footer"> © 2023 PIXEL8 Creative Agency — Breaking boundaries through design </div> </div> <script> // Custom cursor const cursor = document.querySelector('.cursor'); document.addEventListener('mousemove', (e) => { cursor.style.left = e.pageX + 'px'; cursor.style.top = e.pageY + 'px'; }); document.addEventListener('mousedown', () => { cursor.style.transform = 'translate(-50%, -50%) scale(0.8)'; }); document.addEventListener('mouseup', () => { cursor.style.transform = 'translate(-50%, -50%) scale(1)'; }); // Project hover effect document.querySelectorAll('.project').forEach(project => { project.addEventListener('mouseenter', () => { cursor.style.transform = 'translate(-50%, -50%) scale(1.5)'; cursor.style.opacity = '0.5'; }); project.addEventListener('mouseleave', () => { cursor.style.transform = 'translate(-50%, -50%) scale(1)'; cursor.style.opacity = '1'; }); }); // Filter functionality const filterButtons = document.querySelectorAll('.filter-btn'); const projects = document.querySelectorAll('.project'); filterButtons.forEach(button => { button.addEventListener('click', () => { // Update active button filterButtons.forEach(btn => btn.classList.remove('active')); button.classList.add('active'); const filter = button.getAttribute('data-filter'); // Filter projects with staggered animation projects.forEach((project, index) => { setTimeout(() => { if (filter === 'all' || project.classList.contains(filter)) { project.classList.remove('hidden'); } else { project.classList.add('hidden'); } }, index * 50); }); }); }); // Animate projects on load window.addEventListener('load', () => { projects.forEach((project, index) => { project.style.opacity = '0'; project.style.transform = 'translateY(30px) rotate(0deg)'; setTimeout(() => { project.style.opacity = '1'; if (project.classList.contains('project-1')) project.style.transform = 'translateY(0) rotate(-2deg)'; if (project.classList.contains('project-2')) project.style.transform = 'translateY(0) rotate(2deg)'; if (project.classList.contains('project-3')) project.style.transform = 'translateY(0) rotate(1deg)'; if (project.classList.contains('project-4')) project.style.transform = 'translateY(0) rotate(-1deg)'; if (project.classList.contains('project-5')) project.style.transform = 'translateY(0) rotate(-1.5deg)'; if (project.classList.contains('project-6')) project.style.transform = 'translateY(0) rotate(1.5deg)'; }, 100 + index * 100); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>PixelPulse Social Feed</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; } :root { --primary: #0095f6; --secondary: #833ab4; --accent: #fd1d1d; --light: #fcfcfc; --dark: #262626; --medium: #8e8e8e; --border: #dbdbdb; --overlay: rgba(0, 0, 0, 0.3); } body { background-color: var(--light); color: var(--dark); overflow-x: hidden; height: 100vh; width: 100%; } .container { max-width: 700px; height: 700px; margin: 0 auto; padding: 0; overflow: hidden; display: flex; flex-direction: column; } .header { display: flex; align-items: center; justify-content: space-between; padding: 15px; border-bottom: 1px solid var(--border); position: relative; z-index: 10; background: var(--light); } .logo { display: flex; align-items: center; font-weight: 700; font-size: 24px; color: var(--dark); background: linear-gradient(45deg, var(--primary), var(--secondary), var(--accent)); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; } .logo svg { margin-right: 8px; fill: url(#logo-gradient); } .nav-icons { display: flex; gap: 15px; } .icon-btn { background: none; border: none; cursor: pointer; color: var(--dark); font-size: 20px; display: flex; align-items: center; justify-content: center; width: 40px; height: 40px; border-radius: 50%; transition: all 0.3s ease; } .icon-btn:hover { background-color: rgba(0, 0, 0, 0.05); transform: scale(1.1); } .feed-container { flex: 1; overflow-y: auto; padding: 10px; position: relative; scrollbar-width: none; -ms-overflow-style: none; } .feed-container::-webkit-scrollbar { display: none; } .feed-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2px; transition: all 0.5s ease; margin-bottom: 20px; } .feed-item { position: relative; aspect-ratio: 1/1; overflow: hidden; cursor: pointer; border-radius: 3px; } .feed-item img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275); } .feed-item:hover img { transform: scale(1.08); } .feed-item:hover .item-overlay { opacity: 1; } .item-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: var(--overlay); opacity: 0; transition: opacity 0.3s ease; display: flex; align-items: center; justify-content: center; gap: 15px; color: white; font-weight: 600; } .item-stat { display: flex; align-items: center; gap: 5px; } .item-type { position: absolute; top: 10px; right: 10px; width: 20px; height: 20px; color: white; z-index: 2; } .loading-spinner { display: none; justify-content: center; padding: 20px 0; } .spinner { width: 40px; height: 40px; border: 3px solid rgba(0, 0, 0, 0.1); border-top-color: var(--primary); border-radius: 50%; animation: spin 1s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } .story-container { display: flex; overflow-x: auto; padding: 10px 5px; gap: 15px; scrollbar-width: none; -ms-overflow-style: none; border-bottom: 1px solid var(--border); } .story-container::-webkit-scrollbar { display: none; } .story { display: flex; flex-direction: column; align-items: center; cursor: pointer; } .story-avatar { width: 65px; height: 65px; border-radius: 50%; padding: 3px; background: linear-gradient(45deg, var(--primary), var(--secondary), var(--accent)); margin-bottom: 5px; transition: transform 0.3s ease; } .story-avatar img { width: 100%; height: 100%; border-radius: 50%; border: 2px solid white; object-fit: cover; } .story:hover .story-avatar { transform: scale(1.1); } .story-username { font-size: 12px; color: var(--dark); max-width: 65px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: center; } .modal { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.8); z-index: 100; opacity: 0; transition: opacity 0.3s ease; } .modal.active { display: flex; opacity: 1; } .modal-content { display: flex; max-width: 900px; width: 90%; height: 80%; margin: auto; background: white; border-radius: 4px; overflow: hidden; position: relative; } .modal-img { flex: 1; background: black; display: flex; align-items: center; justify-content: center; } .modal-img img { max-width: 100%; max-height: 100%; object-fit: contain; } .modal-sidebar { width: 340px; display: flex; flex-direction: column; border-left: 1px solid var(--border); } .modal-header { display: flex; align-items: center; padding: 14px; border-bottom: 1px solid var(--border); } .modal-user-avatar { width: 32px; height: 32px; border-radius: 50%; margin-right: 12px; } .modal-username { font-weight: 600; font-size: 14px; } .modal-comments { flex: 1; overflow-y: auto; padding: 16px; } .modal-comment { display: flex; margin-bottom: 16px; } .comment-avatar { width: 32px; height: 32px; border-radius: 50%; margin-right: 12px; } .comment-content { flex: 1; } .comment-username { font-weight: 600; font-size: 14px; margin-right: 5px; } .comment-text { font-size: 14px; } .comment-time { font-size: 10px; color: var(--medium); margin-top: 5px; } .modal-actions { padding: 8px 16px; border-top: 1px solid var(--border); } .action-icons { display: flex; justify-content: space-between; margin-bottom: 10px; } .action-group { display: flex; gap: 16px; } .action-btn { background: none; border: none; cursor: pointer; font-size: 24px; color: var(--dark); transition: all 0.2s ease; } .action-btn:hover { transform: scale(1.1); } .action-btn.liked { color: var(--accent); animation: heartPulse 0.4s ease; } @keyframes heartPulse { 0% { transform: scale(1); } 50% { transform: scale(1.3); } 100% { transform: scale(1); } } .likes-count { font-weight: 600; font-size: 14px; margin: 10px 0; } .post-time { font-size: 10px; color: var(--medium); margin: 10px 0; } .comment-input { display: flex; align-items: center; border-top: 1px solid var(--border); padding: 10px 16px; } .comment-input input { flex: 1; border: none; outline: none; font-size: 14px; padding: 8px 0; } .comment-input button { background: none; border: none; color: var(--primary); font-weight: 600; font-size: 14px; padding: 0 8px; cursor: pointer; opacity: 0.5; transition: opacity 0.2s ease; } .comment-input button.active { opacity: 1; } .close-modal { position: absolute; top: 15px; right: 15px; color: white; background: none; border: none; font-size: 30px; cursor: pointer; z-index: 101; } .filter-tabs { display: flex; justify-content: center; padding: 8px 0; background: var(--light); border-bottom: 1px solid var(--border); } .filter-tab { padding: 8px 16px; font-size: 14px; color: var(--medium); cursor: pointer; position: relative; } .filter-tab.active { color: var(--dark); font-weight: 600; } .filter-tab.active::after { content: ''; position: absolute; bottom: -8px; left: 0; width: 100%; height: 1px; background: var(--dark); } .floating-btn { position: absolute; bottom: 20px; right: 20px; width: 60px; height: 60px; border-radius: 50%; background: linear-gradient(45deg, var(--primary), var(--secondary)); color: white; display: flex; align-items: center; justify-content: center; font-size: 24px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); cursor: pointer; transition: transform 0.3s ease, box-shadow 0.3s ease; z-index: 10; } .floating-btn:hover { transform: translateY(-5px) scale(1.05); box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2); } .notification { position: fixed; top: 20px; left: 50%; transform: translateX(-50%) translateY(-100px); background: var(--dark); color: white; padding: 12px 24px; border-radius: 4px; font-size: 14px; z-index: 1000; opacity: 0; transition: transform 0.3s ease, opacity 0.3s ease; } .notification.active { transform: translateX(-50%) translateY(0); opacity: 1; } @media (max-width: 700px) { .feed-grid { grid-template-columns: repeat(2, 1fr); } .story-avatar { width: 55px; height: 55px; } .modal-content { flex-direction: column; width: 95%; } .modal-sidebar { width: 100%; } .modal-img { height: 50%; } } @media (max-width: 500px) { .feed-grid { grid-template-columns: repeat(1, 1fr); } } /* Animation for new items */ @keyframes fadeInUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } .feed-item { animation: fadeInUp 0.5s forwards; } /* Double tap animation */ @keyframes doubleTapHeart { 0% { opacity: 0; transform: translate(-50%, -50%) scale(0); } 50% { opacity: 1; transform: translate(-50%, -50%) scale(1.2); } 100% { opacity: 0; transform: translate(-50%, -50%) scale(1); } } .double-tap-heart { position: absolute; top: 50%; left: 50%; color: white; font-size: 80px; transform: translate(-50%, -50%) scale(0); opacity: 0; z-index: 5; pointer-events: none; } .double-tap-heart.active { animation: doubleTapHeart 0.8s ease forwards; } </style> </head> <body> <div class="container"> <div class="header"> <div class="logo"> <svg width="24" height="24" viewBox="0 0 24 24"> <defs> <linearGradient id="logo-gradient" x1="0%" y1="100%" x2="100%" y2="0%"> <stop offset="0%" stop-color="#0095f6" /> <stop offset="50%" stop-color="#833ab4" /> <stop offset="100%" stop-color="#fd1d1d" /> </linearGradient> </defs> <path d="M12,4.622c2.403,0,2.688,0.009,3.637,0.052c0.877,0.04,1.354,0.187,1.671,0.31c0.42,0.163,0.72,0.358,1.035,0.673 c0.315,0.315,0.51,0.615,0.673,1.035c0.123,0.317,0.27,0.794,0.31,1.671c0.043,0.949,0.052,1.234,0.052,3.637 s-0.009,2.688-0.052,3.637c-0.04,0.877-0.187,1.354-0.31,1.671c-0.163,0.42-0.358,0.72-0.673,1.035 c-0.315,0.315-0.615,0.51-1.035,0.673c-0.317,0.123-0.794,0.27-1.671,0.31c-0.949,0.043-1.233,0.052-3.637,0.052 s-2.688-0.009-3.637-0.052c-0.877-0.04-1.354-0.187-1.671-0.31c-0.42-0.163-0.72-0.358-1.035-0.673 c-0.315-0.315-0.51-0.615-0.673-1.035c-0.123-0.317-0.27-0.794-0.31-1.671C4.631,14.688,4.622,14.403,4.622,12 s0.009-2.688,0.052-3.637c0.04-0.877,0.187-1.354,0.31-1.671c0.163-0.42,0.358-0.72,0.673-1.035 c0.315-0.315,0.615-0.51,1.035-0.673c0.317-0.123,0.794-0.27,1.671-0.31C9.312,4.631,9.597,4.622,12,4.622 M12,3 C9.556,3,9.249,3.01,8.289,3.054C7.331,3.098,6.677,3.25,6.105,3.472C5.513,3.702,5.011,4.01,4.511,4.511 c-0.5,0.5-0.808,1.002-1.038,1.594C3.25,6.677,3.098,7.331,3.054,8.289C3.01,9.249,3,9.556,3,12c0,2.444,0.01,2.751,0.054,3.711 c0.044,0.958,0.196,1.612,0.418,2.185c0.23,0.592,0.538,1.094,1.038,1.594c0.5,0.5,1.002,0.808,1.594,1.038 c0.572,0.222,1.227,0.375,2.185,0.418C9.249,20.99,9.556,21,12,21s2.751-0.01,3.711-0.054c0.958-0.044,1.612-0.196,2.185-0.418 c0.592-0.23,1.094-0.538,1.594-1.038c0.5-0.5,0.808-1.002,1.038-1.594c0.222-0.572,0.375-1.227,0.418-2.185 C20.99,14.751,21,14.444,21,12s-0.01-2.751-0.054-3.711c-0.044-0.958-0.196-1.612-0.418-2.185c-0.23-0.592-0.538-1.094-1.038-1.594 c-0.5-0.5-1.002-0.808-1.594-1.038c-0.572-0.222-1.227-0.375-2.185-0.418C14.751,3.01,14.444,3,12,3L12,3z M12,7.378 c-2.552,0-4.622,2.069-4.622,4.622S9.448,16.622,12,16.622s4.622-2.069,4.622-4.622S14.552,7.378,12,7.378z M12,15 c-1.657,0-3-1.343-3-3s1.343-3,3-3s3,1.343,3,3S13.657,15,12,15z M16.804,6.116c-0.596,0-1.08,0.484-1.08,1.08 s0.484,1.08,1.08,1.08c0.596,0,1.08-0.484,1.08-1.08S17.401,6.116,16.804,6.116z"></path> </svg> PixelPulse </div> <div class="nav-icons"> <button class="icon-btn"> <i class="fas fa-search"></i> </button> <button class="icon-btn"> <i class="far fa-bell"></i> </button> <button class="icon-btn"> <i class="far fa-user"></i> </button> </div> </div> <div class="filter-tabs"> <div class="filter-tab active" data-filter="all">For You</div> <div class="filter-tab" data-filter="trending">Trending</div> <div class="filter-tab" data-filter="following">Following</div> </div> <div class="story-container"> <div class="story"> <div class="story-avatar"> <img src="https://source.unsplash.com/random/100x100?face=1" alt="User"> </div> <div class="story-username">yourstory</div> </div> <div class="story"> <div class="story-avatar"> <img src="https://source.unsplash.com/random/100x100?face=2" alt="User"> </div> <div class="story-username">adventure_time</div> </div> <div class="story"> <div class="story-avatar"> <img src="https://source.unsplash.com/random/100x100?face=3" alt="User"> </div> <div class="story-username">travel_junkie</div> </div> <div class="story"> <div class="story-avatar"> <img src="https://source.unsplash.com/random/100x100?face=4" alt="User"> </div> <div class="story-username">foodie_central</div> </div> <div class="story"> <div class="story-avatar"> <img src="https://source.unsplash.com/random/100x100?face=5" alt="User"> </div> <div class="story-username">art_gallery</div> </div> <div class="story"> <div class="story-avatar"> <img src="https://source.unsplash.com/random/100x100?face=6" alt="User"> </div> <div class="story-username">design_hub</div> </div> <div class="story"> <div class="story-avatar"> <img src="https://source.unsplash.com/random/100x100?face=7" alt="User"> </div> <div class="story-username">tech_trends</div> </div> </div> <div class="feed-container"> <div class="feed-grid"> <!-- Dynamically populated --> </div> <div class="loading-spinner"> <div class="spinner"></div> </div> </div> <div class="floating-btn"> <i class="fas fa-plus"></i> </div> </div> <div class="modal"> <button class="close-modal">×</button> <div class="modal-content"> <div class="modal-img"> <img src="" alt="Post"> <div class="double-tap-heart"> <i class="fas fa-heart"></i> </div> </div> <div class="modal-sidebar"> <div class="modal-header"> <img class="modal-user-avatar" src="" alt="User"> <div class="modal-username"></div> </div> <div class="modal-comments"> <!-- Dynamically populated --> </div> <div class="modal-actions"> <div class="action-icons"> <div class="action-group"> <button class="action-btn like-btn"> <i class="far fa-heart"></i> </button> <button class="action-btn"> <i class="far fa-comment"></i> </button> <button class="action-btn"> <i class="far fa-paper-plane"></i> </button> </div> <button class="action-btn"> <i class="far fa-bookmark"></i> </button> </div> <div class="likes-count"> <span class="likes-number">0</span> likes </div> <div class="post-time">Posted 2 hours ago</div> </div> <div class="comment-input"> <input type="text" placeholder="Add a comment..."> <button disabled>Post</button> </div> </div> </div> </div> <div class="notification"> Post saved to your collection! </div> <script src="https://kit.fontawesome.com/a076d05399.js" crossorigin="anonymous"></script> <script> document.addEventListener('DOMContentLoaded', () => { // Fallback for Font Awesome if CDN fails if (!document.querySelector('i.fas')) { const fontAwesomeLink = document.createElement('link'); fontAwesomeLink.rel = 'stylesheet'; fontAwesomeLink.href = 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css'; document.head.appendChild(fontAwesomeLink); } // Initial feed data const initialFeedItems = [ { id: 1, imageUrl: 'https://source.unsplash.com/random/500x500?travel', type: 'image', likes: 846, comments: 32, username: 'travel_junkie', userAvatar: 'https://source.unsplash.com/random/100x100?face=3', caption: 'Exploring hidden gems in Bali! The waterfall was absolutely breathtaking. #wanderlust #bali', category: 'trending' }, { id: 2, imageUrl: 'https://source.unsplash.com/random/500x500?food', type: 'image', likes: 1204, comments: 45, username: 'foodie_central', userAvatar: 'https://source.unsplash.com/random/100x100?face=4', caption: 'Homemade pasta is always worth the effort. Made this mushroom fettuccine from scratch! #foodporn', category: 'trending' }, { id: 3, imageUrl: 'https://source.unsplash.com/random/500x500?art', type: 'image', likes: 723, comments: 18, username: 'art_gallery', userAvatar: 'https://source.unsplash.com/random/100x100?face=5', caption: 'New mixed media piece I finished yesterday. Inspired by urban landscapes. #contemporaryart', category: 'following' }, { id: 4, imageUrl: 'https://source.unsplash.com/random/500x500?design', type: 'video', likes: 1598, comments: 67, username: 'design_hub', userAvatar: 'https://source.unsplash.com/random/100x100?face=6', caption: 'The evolution of minimalist design through the decades. Swipe to see the full progression! #designhistory', category: 'all' }, { id: 5, imageUrl: 'https://source.unsplash.com/random/500x500?tech', type: 'image', likes: 932, comments: 41, username: 'tech_trends', userAvatar: 'https://source.unsplash.com/random/100x100?face=7', caption: 'My new workspace setup is finally complete! Productivity levels at 100%. #workfromhome #techsetup', category: 'following' }, { id: 6, imageUrl: 'https://source.unsplash.com/random/500x500?fitness', type: 'video', likes: 1105, comments: 29, username: 'fitness_daily', userAvatar: 'https://source.unsplash.com/random/100x100?face=8', caption: 'Quick 15-minute HIIT routine you can do anywhere with no equipment! #homeworkout #fitness', category: 'all' }, { id: 7, imageUrl: 'https://source.unsplash.com/random/500x500?nature', type: 'image', likes: 2458, comments: 83, username: 'nature_lover', userAvatar: 'https://source.unsplash.com/random/100x100?face=9', caption: 'The northern lights dancing above the Norwegian fjords. A truly magical experience. #auroraborealis', category: 'trending' }, { id: 8, imageUrl: 'https://source.unsplash.com/random/500x500?fashion', type: 'carousel', likes: 1847, comments: 57, username: 'style_icon', userAvatar: 'https://source.unsplash.com/random/100x100?face=10', caption: 'Three ways to style a classic white button-down for any occasion. Which is your favorite? #fashiontips', category: 'following' }, { id: 9, imageUrl: 'https://source.unsplash.com/random/500x500?pet', type: 'image', likes: 3102, comments: 124, username: 'pet_paradise', userAvatar: 'https://source.unsplash.com/random/100x100?face=11', caption: 'Just adopted this sweet girl from the shelter yesterday. Meet Luna! 🐾 #adoptdontshop #rescuedog', category: 'all' } ]; // Comment data const commentsData = { 1: [ {username: 'adventurelover', text: 'Wow! Which waterfall is this? I'm heading to Bali next month!', avatar: 'https://source.unsplash.com/random/100x100?face=12', time: '1 hour ago'}, {username: 'islandhopper', text: 'The colors in this photo are incredible. What filter did you use?', avatar: 'https://source.unsplash.com/random/100x100?face=13', time: '45 minutes ago'}, {username: 'nomad_life', text: 'Adding this to my bucket list right now! 😍', avatar: 'https://source.unsplash.com/random/100x100?face=14', time: '15 minutes ago'} ], 2: [ {username: 'pasta_lover', text: 'Recipe please! This looks absolutely divine. 🍝', avatar: 'https://source.unsplash.com/random/100x100?face=15', time: '2 hours ago'}, {username: 'chef_at_home', text: 'Beautiful plating! What type of mushrooms did you use?', avatar: 'https://source.unsplash.com/random/100x100?face=16', time: '1 hour ago'}, {username: 'italian_food', text: 'Nothing beats homemade pasta. Great job! 👨🍳', avatar: 'https://source.unsplash.com/random/100x100?face=17', time: '30 minutes ago'} ], 3: [ {username: 'gallery_owner', text: 'I'd love to feature this in our upcoming urban art exhibition!', avatar: 'https://source.unsplash.com/random/100x100?face=18', time: '3 hours ago'}, {username: 'art_collector', text: 'The texture in this piece is fascinating. What materials did you use?', avatar: 'https://source.unsplash.com/random/100x100?face=19', time: '2 hours ago'} ], 4: [ {username: 'design_student', text: 'This is so helpful for my design history class! Thank you for sharing.', avatar: 'https://source.unsplash.com/random/100x100?face=20', time: '4 hours ago'}, {username: 'retro_lover', text: 'The 60s minimalism will always be my favorite era.', avatar: 'https://source.unsplash.com/random/100x100?face=21', time: '3 hours ago'}, {username: 'interior_design', text: 'Great overview! Would love to see how color palettes evolved too.', avatar: 'https://source.unsplash.com/random/100x100?face=22', time: '1 hour ago'} ], 5: [ {username: 'gadget_geek', text: 'What monitor stand is that? I need it in my life!', avatar: 'https://source.unsplash.com/random/100x100?face=23', time: '5 hours ago'}, {username: 'remote_worker', text: 'Ergonomics on point! How's that chair for long working sessions?', avatar: 'https://source.unsplash.com/random/100x100?face=24', time: '4 hours ago'} ], 6: [ {username: 'home_workout', text: 'Just tried this and I'm sweating buckets! Great routine.', avatar: 'https://source.unsplash.com/random/100x100?face=25', time: '6 hours ago'}, {username: 'fitness_newbie', text: 'Is there a modified version for beginners?', avatar: 'https://source.unsplash.com/random/100x100?face=26', time: '5 hours ago'}, {username: 'trainer_tips', text: 'Love the compound movements! Great efficiency in a short time.', avatar: 'https://source.unsplash.com/random/100x100?face=27', time: '3 hours ago'} ], 7: [ {username: 'aurora_chaser', text: 'What time of year did you capture this? Planning a trip!', avatar: 'https://source.unsplash.com/random/100x100?face=28', time: '7 hours ago'}, {username: 'night_photographer', text: 'Incredible shot! What settings did you use for this low light?', avatar: 'https://source.unsplash.com/random/100x100?face=29', time: '6 hours ago'}, {username: 'travel_agent', text: 'Would you mind if we featured this on our Norway tour page? With credit of course!', avatar: 'https://source.unsplash.com/random/100x100?face=30', time: '4 hours ago'} ], 8: [ {username: 'minimalist_fashion', text: 'The third style is so versatile! Perfect for office to evening.', avatar: 'https://source.unsplash.com/random/100x100?face=31', time: '8 hours ago'}, {username: 'wardrobe_essentials', text: 'A white button-down is truly the MVP of any closet.', avatar: 'https://source.unsplash.com/random/100x100?face=32', time: '7 hours ago'} ], 9: [ {username: 'dog_lover', text: 'Luna is absolutely gorgeous! Those eyes are melting my heart. 🐶', avatar: 'https://source.unsplash.com/random/100x100?face=33', time: '9 hours ago'}, {username: 'rescue_volunteer', text: 'Thank you for adopting! Shelter dogs give the best love.', avatar: 'https://source.unsplash.com/random/100x100?face=34', time: '8 hours ago'}, {username: 'pet_photographer', text: 'What a photogenic pup! Would love to do a free photoshoot for your new family member!', avatar: 'https://source.unsplash.com/random/100x100?face=35', time: '5 hours ago'} ] }; const feedGrid = document.querySelector('.
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Curated Properties</title> <style> :root { --primary: #4a6741; --secondary: #b8a88f; --light: #f5f2ed; --dark: #373232; --accent: #c17c74; --transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1); } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background-color: var(--light); color: var(--dark); min-height: 100vh; padding: 15px; overflow-x: hidden; } .container { max-width: 670px; margin: 0 auto; } header { padding: 0 0 20px; } h1 { font-size: 28px; font-weight: 700; color: var(--primary); margin-bottom: 10px; letter-spacing: -0.5px; position: relative; } h1::after { content: ""; position: absolute; bottom: -5px; left: 0; width: 60px; height: 3px; background-color: var(--secondary); } .filters { display: flex; flex-wrap: wrap; gap: 10px; margin: 20px 0; } .filter-btn { background-color: transparent; border: 1px solid var(--secondary); color: var(--dark); padding: 8px 16px; border-radius: 20px; cursor: pointer; font-size: 14px; transition: var(--transition); position: relative; overflow: hidden; } .filter-btn::before { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background-color: var(--secondary); opacity: 0.2; transition: var(--transition); } .filter-btn:hover::before { left: 0; } .filter-btn.active { background-color: var(--primary); color: white; border-color: var(--primary); } .grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 18px; margin-top: 20px; } .listing { background-color: white; border-radius: 12px; overflow: hidden; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05); transition: var(--transition); position: relative; transform-style: preserve-3d; perspective: 1000px; } .listing:hover { transform: translateY(-5px); box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1); } .image-wrapper { position: relative; padding-top: 75%; overflow: hidden; } .listing-image { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; transition: var(--transition); } .listing:hover .listing-image { transform: scale(1.08); } .category { position: absolute; top: 10px; left: 10px; background-color: var(--dark); color: white; font-size: 11px; padding: 4px 8px; border-radius: 4px; text-transform: uppercase; font-weight: 600; letter-spacing: 0.5px; } .category.residential { background-color: var(--primary); } .category.commercial { background-color: var(--accent); } .category.luxury { background-color: var(--secondary); } .info { padding: 15px; position: relative; } .price { font-weight: 700; font-size: 18px; color: var(--primary); margin-bottom: 4px; } .address { font-size: 13px; color: var(--dark); margin-bottom: 10px; line-height: 1.4; } .specs { display: flex; justify-content: space-between; font-size: 12px; color: var(--dark); border-top: 1px solid #eee; padding-top: 10px; } .spec { display: flex; align-items: center; gap: 4px; } .details { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(255, 255, 255, 0.95); padding: 15px; opacity: 0; pointer-events: none; transition: var(--transition); transform: rotateY(30deg); display: flex; flex-direction: column; justify-content: space-between; } .listing:hover .details { opacity: 1; pointer-events: all; transform: rotateY(0); } .detail-title { font-weight: 600; margin-bottom: 5px; color: var(--primary); font-size: 14px; } .detail-text { font-size: 12px; line-height: 1.5; color: var(--dark); margin-bottom: 10px; } .cta { display: inline-block; background-color: var(--primary); color: white; text-decoration: none; padding: 8px 12px; border-radius: 4px; font-size: 12px; font-weight: 600; text-align: center; transition: var(--transition); border: none; cursor: pointer; } .cta:hover { background-color: var(--accent); } .search-container { position: relative; margin-bottom: 15px; } .search-input { width: 100%; padding: 12px 15px 12px 40px; border: 1px solid #e0e0e0; border-radius: 30px; outline: none; font-size: 14px; transition: var(--transition); background-color: white; } .search-input:focus { border-color: var(--secondary); box-shadow: 0 0 0 2px rgba(184, 168, 143, 0.2); } .search-icon { position: absolute; top: 50%; left: 15px; transform: translateY(-50%); color: var(--dark); opacity: 0.5; } .empty-state { grid-column: 1 / -1; text-align: center; padding: 30px; background-color: white; border-radius: 12px; display: none; } .empty-state-icon { font-size: 40px; color: var(--secondary); margin-bottom: 15px; } .empty-state-text { font-size: 14px; color: var(--dark); } .loader { display: flex; justify-content: center; margin: 20px 0; height: 40px; align-items: center; } .loader .dot { width: 10px; height: 10px; margin: 0 5px; background-color: var(--secondary); border-radius: 50%; animation: bounce 1.4s infinite ease-in-out both; } .loader .dot:nth-child(1) { animation-delay: -0.32s; } .loader .dot:nth-child(2) { animation-delay: -0.16s; } @keyframes bounce { 0%, 80%, 100% { transform: scale(0); } 40% { transform: scale(1); } } @media (max-width: 600px) { .grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 15px; } h1 { font-size: 24px; } .price { font-size: 16px; } .specs { font-size: 10px; } } .load-more { display: block; margin: 30px auto 10px; background-color: transparent; color: var(--primary); border: 1px solid var(--primary); padding: 10px 20px; border-radius: 30px; cursor: pointer; font-weight: 600; transition: var(--transition); } .load-more:hover { background-color: var(--primary); color: white; } .fading-in { animation: fadeIn 0.5s ease forwards; } @keyframes fadeIn { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } </style> </head> <body> <div class="container"> <header> <h1>Curated Properties</h1> <div class="search-container"> <svg class="search-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M21 21L15 15M17 10C17 13.866 13.866 17 10 17C6.13401 17 3 13.866 3 10C3 6.13401 6.13401 3 10 3C13.866 3 17 6.13401 17 10Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> <input type="text" class="search-input" placeholder="Search by location, price, or features"> </div> <div class="filters"> <button class="filter-btn active" data-filter="all">All Properties</button> <button class="filter-btn" data-filter="residential">Residential</button> <button class="filter-btn" data-filter="commercial">Commercial</button> <button class="filter-btn" data-filter="luxury">Luxury</button> </div> </header> <div class="grid" id="listings-grid"> <!-- Listings will be inserted here via JavaScript --> <div class="empty-state"> <div class="empty-state-icon">🏠</div> <div class="empty-state-text">No properties match your criteria. Try adjusting your filters.</div> </div> </div> <div class="loader"> <div class="dot"></div> <div class="dot"></div> <div class="dot"></div> </div> <button class="load-more">View More Properties</button> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Sample data for real estate listings const listings = [ { id: 1, image: 'https://images.unsplash.com/photo-1580587771525-78b9dba3b914?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=600&q=80', price: '$1,450,000', address: '238 Westridge Lane, Boulder, CO', beds: 4, baths: 3.5, sqft: 2860, category: 'residential', description: 'Modern mountain retreat with panoramic views of the Flatirons. Features natural stone finishes, chef\'s kitchen with custom cabinetry, and a private outdoor living space.', year: 2019, lotSize: '0.4 acres', garage: '2-car attached' }, { id: 2, image: 'https://images.unsplash.com/photo-1582063289852-62e3ba2747f8?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=600&q=80', price: '$789,000', address: '492 Oak Hill Road, Portland, OR', beds: 3, baths: 2, sqft: 1950, category: 'residential', description: 'Charming craftsman bungalow in historic Sellwood district. Original hardwood floors, built-in cabinetry, and a tastefully renovated kitchen with quartz countertops.', year: 1922, lotSize: '0.15 acres', garage: 'Detached' }, { id: 3, image: 'https://images.unsplash.com/photo-1581404635299-f473ede8f9d6?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=600&q=80', price: '$2,975,000', address: '1745 Shoreline Dr, Naples, FL', beds: 5, baths: 5.5, sqft: 4750, category: 'luxury', description: 'Waterfront estate with private dock access. Featuring marble floors, gourmet kitchen, wine cellar, and a resort-style pool with Gulf views. Smart home technology throughout.', year: 2021, lotSize: '0.8 acres', garage: '3-car' }, { id: 4, image: 'https://images.unsplash.com/photo-1572120360610-d971b9d7767c?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=600&q=80', price: '$1,195,000', address: '3822 Hillcrest Ave, Austin, TX', beds: 4, baths: 3, sqft: 2640, category: 'residential', description: 'Mid-century modern gem completely renovated with sustainable materials. Open floor plan with walls of glass overlooking a native landscape garden and lap pool.', year: 1962, lotSize: '0.28 acres', garage: '2-car' }, { id: 5, image: 'https://images.unsplash.com/photo-1627911206243-0640ef3e75e4?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=600&q=80', price: '$1,750/sq ft', address: '220 Technology Square, Cambridge, MA', beds: null, baths: null, sqft: 5200, category: 'commercial', description: 'Prime office space in the heart of Kendall Square\'s biotech hub. Features modern conference rooms, open workspaces, and high-end finishes. LEED Gold certified building.', year: 2018, lotSize: null, garage: 'Underground parking' }, { id: 6, image: 'https://images.unsplash.com/photo-1499916078039-922301b0eb83?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=600&q=80', price: '$3,495,000', address: '75 Beacon Hill Road, Aspen, CO', beds: 6, baths: 7, sqft: 5890, category: 'luxury', description: 'Spectacular ski-in/ski-out mountain chalet with breathtaking views. Features reclaimed timber beams, floor-to-ceiling stone fireplace, chef\'s kitchen, and an outdoor hot tub.', year: 2017, lotSize: '1.2 acres', garage: '2-car heated' }, { id: 7, image: 'https://images.unsplash.com/photo-1605276374104-dee2a0ed3cd6?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=600&q=80', price: '$875,000', address: '112 Fernwood Drive, Nashville, TN', beds: 3, baths: 2.5, sqft: 2100, category: 'residential', description: 'Designer townhome in the heart of 12South district. Modern farmhouse aesthetic with custom millwork, gourmet kitchen with waterfall island, and a rooftop terrace.', year: 2020, lotSize: 'N/A', garage: '2-car attached' }, { id: 8, image: 'https://images.unsplash.com/photo-1486406146926-c627a92ad1ab?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=600&q=80', price: '$68/sq ft/yr', address: '1200 Market Street, Philadelphia, PA', beds: null, baths: null, sqft: 12500, category: 'commercial', description: 'Class A retail space in historic building with high foot traffic. Exposed brick walls, high ceilings, and updated MEP systems. Adjacent to major transportation hub.', year: 1905, lotSize: null, garage: 'Nearby parking garage' } ]; const grid = document.getElementById('listings-grid'); const filterButtons = document.querySelectorAll('.filter-btn'); const searchInput = document.querySelector('.search-input'); const loader = document.querySelector('.loader'); const loadMoreButton = document.querySelector('.load-more'); const emptyState = document.querySelector('.empty-state'); let currentFilter = 'all'; let visibleListings = 6; // Number of listings to show initially // Initialize the grid populateGrid(); // Hide loader after initial load setTimeout(() => { loader.style.display = 'none'; }, 1000); // Filter button click event filterButtons.forEach(button => { button.addEventListener('click', function() { const filter = this.getAttribute('data-filter'); // Update active state filterButtons.forEach(btn => btn.classList.remove('active')); this.classList.add('active'); currentFilter = filter; visibleListings = 6; // Reset visible listings count // Show loader when changing filters loader.style.display = 'flex'; setTimeout(() => { populateGrid(); loader.style.display = 'none'; }, 500); }); }); // Search functionality searchInput.addEventListener('input', debounce(function() { visibleListings = 6; // Reset visible listings count populateGrid(); }, 300)); // Load more button click event loadMoreButton.addEventListener('click', function() { visibleListings += 3; populateGrid(); // Add animation to new items const allListings = document.querySelectorAll('.listing'); for (let i = allListings.length - 3; i < allListings.length; i++) { if (allListings[i]) { allListings[i].classList.add('fading-in'); } } }); // Function to populate the grid based on filters and search function populateGrid() { // Clear the grid except for the empty state while (grid.firstChild && grid.firstChild !== emptyState) { grid.removeChild(grid.firstChild); } const searchTerm = searchInput.value.toLowerCase(); // Filter listings based on category and search term let filteredListings = listings.filter(listing => { const matchesCategory = currentFilter === 'all' || listing.category === currentFilter; const matchesSearch = listing.address.toLowerCase().includes(searchTerm) || listing.price.toLowerCase().includes(searchTerm) || (listing.description && listing.description.toLowerCase().includes(searchTerm)); return matchesCategory && matchesSearch; }); // Determine if we should show the empty state if (filteredListings.length === 0) { emptyState.style.display = 'block'; loadMoreButton.style.display = 'none'; return; } else { emptyState.style.display = 'none'; } // Slice to only show visible number of listings const listingsToShow = filteredListings.slice(0, visibleListings); // Create and append listing elements listingsToShow.forEach(listing => { const listingElement = createListingElement(listing); grid.appendChild(listingElement); }); // Show/hide load more button if (filteredListings.length > visibleListings) { loadMoreButton.style.display = 'block'; } else { loadMoreButton.style.display = 'none'; } // Add the empty state back to the grid if it was removed if (!grid.contains(emptyState)) { grid.appendChild(emptyState); } } // Function to create a listing element function createListingElement(listing) { const listingDiv = document.createElement('div'); listingDiv.className = 'listing'; // Determine which specs to show based on category let specsHtml = ''; if (listing.category === 'residential' || listing.category === 'luxury') { specsHtml = ` <div class="spec">${listing.beds} Beds</div> <div class="spec">${listing.baths} Baths</div> <div class="spec">${listing.sqft.toLocaleString()} sqft</div> `; } else if (listing.category === 'commercial') { specsHtml = `<div class="spec">${listing.sqft.toLocaleString()} sqft</div>`; } listingDiv.innerHTML = ` <div class="image-wrapper"> <img src="${listing.image}" alt="Property ${listing.id}" class="listing-image"> <div class="category ${listing.category}">${capitalizeFirstLetter(listing.category)}</div> </div> <div class="info"> <div class="price">${listing.price}</div> <div class="address">${listing.address}</div> <div class="specs">${specsHtml}</div> <div class="details"> <div> <div class="detail-title">Property Details</div> <div class="detail-text">${listing.description}</div> <div class="detail-title">Year Built</div> <div class="detail-text">${listing.year}</div> ${listing.lotSize ? ` <div class="detail-title">Lot Size</div> <div class="detail-text">${listing.lotSize}</div> ` : ''} ${listing.garage ? ` <div class="detail-title">Garage</div> <div class="detail-text">${listing.garage}</div> ` : ''} </div> <button class="cta">Schedule a Viewing</button> </div> </div> `; // Add event listener for CTA button const ctaButton = listingDiv.querySelector('.cta'); ctaButton.addEventListener('click', function(e) { e.stopPropagation(); ctaButton.textContent = 'Request Sent!'; ctaButton.style.backgroundColor = '#4CAF50'; setTimeout(() => { ctaButton.textContent = 'Schedule a Viewing'; ctaButton.style.backgroundColor = ''; }, 2000); }); return listingDiv; } // Helper function to capitalize first letter function capitalizeFirstLetter(string) { return string.charAt(0).toUpperCase() + string.slice(1); } // Debounce function for search input function debounce(func, delay) { let timeoutId; return function() { const context = this; const args = arguments; clearTimeout(timeoutId); timeoutId = setTimeout(() => { func.apply(context, args); }, delay); }; } }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Tranquil Travels - Destination Showcase</title> <style> :root { --primary-blue: #1a5f7a; --secondary-blue: #57c5b6; --highlight-green: #159895; --light-green: #daefe8; --off-white: #f9f9f9; --transition: all 0.4s cubic-bezier(0.33, 1, 0.68, 1); --shadow: 0 8px 20px rgba(26, 95, 122, 0.15); } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Poppins', -apple-system, BlinkMacSystemFont, sans-serif; } body { background-color: var(--off-white); color: #333; display: flex; flex-direction: column; align-items: center; min-height: 100vh; padding: 20px; overflow-x: hidden; width: 100%; max-width: 700px; margin: 0 auto; } .container { width: 100%; max-width: 700px; margin: 0 auto; } header { text-align: center; margin-bottom: 25px; width: 100%; } h1 { font-size: 32px; color: var(--primary-blue); margin-bottom: 5px; position: relative; display: inline-block; } h1::after { content: ''; position: absolute; width: 40%; height: 3px; background: var(--secondary-blue); bottom: -8px; left: 30%; border-radius: 2px; } .subheading { font-size: 16px; color: #666; margin-top: 15px; max-width: 600px; margin-left: auto; margin-right: auto; } .filter-container { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; margin-bottom: 25px; padding: 0 10px; } .filter-btn { background-color: white; border: 2px solid var(--light-green); color: var(--primary-blue); padding: 8px 16px; border-radius: 50px; font-size: 14px; font-weight: 500; cursor: pointer; transition: var(--transition); position: relative; overflow: hidden; } .filter-btn::before { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent); transition: 0.5s; } .filter-btn:hover::before { left: 100%; } .filter-btn:hover, .filter-btn.active { background-color: var(--highlight-green); color: white; transform: translateY(-2px); box-shadow: var(--shadow); border-color: var(--highlight-green); } .destination-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 20px; width: 100%; margin-bottom: 20px; } .destination-card { position: relative; height: 250px; border-radius: 12px; overflow: hidden; box-shadow: var(--shadow); transform: translateY(0); transition: var(--transition); cursor: pointer; } .destination-card:hover { transform: translateY(-5px); box-shadow: 0 15px 25px rgba(26, 95, 122, 0.25); } .destination-card img { width: 100%; height: 100%; object-fit: cover; transition: var(--transition); } .destination-card:hover img { transform: scale(1.1); } .card-overlay { position: absolute; bottom: 0; left: 0; right: 0; background: linear-gradient(to top, rgba(0,0,0,0.8) 0%, transparent 100%); padding: 20px; color: white; transform: translateY(100%); transition: var(--transition); display: flex; flex-direction: column; justify-content: flex-end; height: 100%; } .destination-card:hover .card-overlay { transform: translateY(0); } .card-title { font-size: 18px; font-weight: 600; margin-bottom: 5px; opacity: 0; transform: translateY(20px); transition: var(--transition); transition-delay: 0.1s; } .card-subtitle { font-size: 14px; font-weight: 400; margin-bottom: 10px; color: rgba(255,255,255,0.8); opacity: 0; transform: translateY(20px); transition: var(--transition); transition-delay: 0.2s; } .card-description { font-size: 12px; line-height: 1.4; color: rgba(255,255,255,0.9); opacity: 0; transform: translateY(20px); transition: var(--transition); transition-delay: 0.3s; } .destination-card:hover .card-title, .destination-card:hover .card-subtitle, .destination-card:hover .card-description { opacity: 1; transform: translateY(0); } .tags { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; opacity: 0; transform: translateY(20px); transition: var(--transition); transition-delay: 0.4s; } .destination-card:hover .tags { opacity: 1; transform: translateY(0); } .tag { font-size: 10px; padding: 4px 8px; background-color: rgba(255,255,255,0.2); border-radius: 30px; backdrop-filter: blur(5px); } .placeholder-text { text-align: center; padding: 40px 0; font-size: 18px; color: #999; width: 100%; font-style: italic; display: none; } .loading-animation { width: 100%; height: 250px; display: flex; justify-content: center; align-items: center; } .loading-circle { display: inline-block; width: 15px; height: 15px; background-color: var(--secondary-blue); border-radius: 50%; margin: 0 5px; animation: bounce 1.4s infinite ease-in-out both; } .loading-circle:nth-child(1) { animation-delay: -0.32s; } .loading-circle:nth-child(2) { animation-delay: -0.16s; } @keyframes bounce { 0%, 80%, 100% { transform: scale(0); } 40% { transform: scale(1); } } @media (max-width: 600px) { .destination-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 15px; } .destination-card { height: 200px; } h1 { font-size: 26px; } .subheading { font-size: 14px; } .card-title { font-size: 16px; } .card-subtitle { font-size: 12px; } .card-description { font-size: 10px; } } @media (max-width: 400px) { .destination-grid { grid-template-columns: 1fr; } .filter-btn { font-size: 12px; padding: 6px 12px; } } </style> </head> <body> <div class="container"> <header> <h1>Tranquil Travels</h1> <p class="subheading">Discover serene getaways that blend natural beauty with authentic cultural experiences. Filter by region or travel interest.</p> </header> <div class="filter-container"> <button class="filter-btn active" data-filter="all">All Destinations</button> <button class="filter-btn" data-filter="asia">Asia</button> <button class="filter-btn" data-filter="europe">Europe</button> <button class="filter-btn" data-filter="americas">Americas</button> <button class="filter-btn" data-filter="adventure">Adventure</button> <button class="filter-btn" data-filter="cultural">Cultural</button> <button class="filter-btn" data-filter="beach">Beach</button> </div> <div class="destination-grid"> <div class="loading-animation"> <div class="loading-circle"></div> <div class="loading-circle"></div> <div class="loading-circle"></div> </div> </div> <div class="placeholder-text">No destinations match your selected filters.</div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Destinations data with regions and themes const destinations = [ { id: 1, name: "Kyoto Gardens", location: "Kyoto, Japan", image: "https://images.unsplash.com/photo-1545569341-9eb8b30979d9?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1770&q=80", description: "Ancient temples nestled among maple trees, offering peaceful meditation spaces and seasonal tea ceremonies.", regions: ["asia"], themes: ["cultural"] }, { id: 2, name: "Amalfi Coast", location: "Campania, Italy", image: "https://images.unsplash.com/photo-1612698093158-e07ac200d44e?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1770&q=80", description: "Cliff-hugging villages with pastel-colored houses overlooking the azure Mediterranean waters.", regions: ["europe"], themes: ["beach", "cultural"] }, { id: 3, name: "Banff National Park", location: "Alberta, Canada", image: "https://images.unsplash.com/photo-1609981135026-7bed9f1363ae?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1770&q=80", description: "Pristine alpine lakes reflect snow-capped mountains in this wilderness sanctuary for hikers and photographers.", regions: ["americas"], themes: ["adventure"] }, { id: 4, name: "Santorini", location: "Greece", image: "https://images.unsplash.com/photo-1570077188670-e3a8d69ac5ff?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1974&q=80", description: "Iconic blue-domed churches perched on volcanic cliffs, offering breathtaking sunset views over the Aegean Sea.", regions: ["europe"], themes: ["beach", "cultural"] }, { id: 5, name: "Bali Highlands", location: "Bali, Indonesia", image: "https://images.unsplash.com/photo-1537953773345-d172ccf13cf1?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1770&q=80", description: "Terraced rice fields cascade down lush hillsides, dotted with ancient water temples and traditional villages.", regions: ["asia"], themes: ["cultural", "adventure"] }, { id: 6, name: "Patagonia", location: "Argentina & Chile", image: "https://images.unsplash.com/photo-1531002423613-b7d296a58afc?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1867&q=80", description: "Dramatic granite peaks and glacial lakes create an otherworldly landscape for trekkers and wildlife enthusiasts.", regions: ["americas"], themes: ["adventure"] }, { id: 7, name: "Kerala Backwaters", location: "Kerala, India", image: "https://images.unsplash.com/photo-1602216056096-3b40cc0c9944?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1832&q=80", description: "Serene palm-fringed waterways explored via traditional houseboats, offering glimpses of rural life along the shores.", regions: ["asia"], themes: ["cultural"] }, { id: 8, name: "Tulum", location: "Quintana Roo, Mexico", image: "https://images.unsplash.com/photo-1569446881371-e16a19410c6e?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1965&q=80", description: "Ancient Mayan ruins perched above turquoise Caribbean waters, surrounded by pristine beaches and cenotes.", regions: ["americas"], themes: ["beach", "cultural"] } ]; const grid = document.querySelector('.destination-grid'); const placeholder = document.querySelector('.placeholder-text'); const filterButtons = document.querySelectorAll('.filter-btn'); let activeFilter = 'all'; // Remove loading animation after brief delay setTimeout(() => { grid.innerHTML = ''; renderDestinations(destinations); }, 1500); // Create destination cards function renderDestinations(items) { grid.innerHTML = ''; let filteredItems = items; if (activeFilter !== 'all') { filteredItems = items.filter(item => { if (activeFilter === 'asia' || activeFilter === 'europe' || activeFilter === 'americas') { return item.regions.includes(activeFilter); } else { return item.themes.includes(activeFilter); } }); } if (filteredItems.length === 0) { placeholder.style.display = 'block'; return; } placeholder.style.display = 'none'; filteredItems.forEach(item => { const card = document.createElement('div'); card.className = 'destination-card'; // Generate tags from themes const tagElements = item.themes.map(theme => `<span class="tag">${theme.charAt(0).toUpperCase() + theme.slice(1)}</span>` ).join(''); card.innerHTML = ` <img src="${item.image}" alt="${item.name}"> <div class="card-overlay"> <h3 class="card-title">${item.name}</h3> <p class="card-subtitle">${item.location}</p> <p class="card-description">${item.description}</p> <div class="tags">${tagElements}</div> </div> `; grid.appendChild(card); }); // Add animation to cards const cards = document.querySelectorAll('.destination-card'); cards.forEach((card, index) => { card.style.opacity = '0'; card.style.transform = 'translateY(20px)'; setTimeout(() => { card.style.transition = 'all 0.5s ease'; card.style.opacity = '1'; card.style.transform = 'translateY(0)'; }, 100 * index); }); } // Filter functionality filterButtons.forEach(button => { button.addEventListener('click', function() { const filter = this.dataset.filter; activeFilter = filter; // Update active button styles filterButtons.forEach(btn => btn.classList.remove('active')); this.classList.add('active'); // Re-render with filter renderDestinations(destinations); }); }); // Add ripple effect to buttons filterButtons.forEach(button => { button.addEventListener('mousedown', function(e) { const x = e.clientX - e.target.getBoundingClientRect().left; const y = e.clientY - e.target.getBoundingClientRect().top; const ripple = document.createElement('span'); ripple.classList.add('ripple'); ripple.style.left = `${x}px`; ripple.style.top = `${y}px`; this.appendChild(ripple); setTimeout(() => { ripple.remove(); }, 600); }); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Montserrat', sans-serif; } body { background-color: #fcf9f7; color: #333; width: 100%; height: 100%; display: flex; flex-direction: column; align-items: center; overflow-x: hidden; padding: 15px; } header { width: 100%; text-align: center; margin-bottom: 20px; } h1 { font-size: 2.2rem; font-weight: 700; color: #e07a5f; margin-bottom: 5px; position: relative; display: inline-block; } h1::after { content: ''; position: absolute; width: 30%; height: 3px; background-color: #e07a5f; bottom: -10px; left: 35%; border-radius: 2px; transition: width 0.3s ease, left 0.3s ease; } h1:hover::after { width: 80%; left: 10%; } .subtitle { font-size: 1rem; color: #81b29a; font-weight: 500; margin-top: 15px; } .grid-container { display: grid; grid-template-columns: repeat(3, 1fr); grid-auto-rows: 180px; gap: 15px; width: 100%; max-width: 670px; margin-top: 10px; } .grid-item { position: relative; overflow: hidden; border-radius: 12px; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.08); cursor: pointer; transition: transform 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275); } .grid-item:nth-child(1) { grid-column: span 2; grid-row: span 1; } .grid-item:nth-child(4) { grid-column: span 1; grid-row: span 2; } .grid-item:nth-child(5) { grid-column: span 2; grid-row: span 1; } .grid-item img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.6s ease, filter 0.4s ease; } .overlay { position: absolute; bottom: 0; left: 0; right: 0; background: linear-gradient(to top, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0) 100%); color: white; padding: 15px; transform: translateY(100%); transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275); display: flex; flex-direction: column; height: 100%; justify-content: flex-end; } .grid-item:hover .overlay { transform: translateY(0); } .grid-item:hover img { transform: scale(1.05); filter: brightness(0.8); } .grid-item:hover { transform: translateY(-5px); box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15); } .recipe-title { font-size: 1.1rem; font-weight: 700; margin-bottom: 5px; text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.3); } .ingredients { font-size: 0.8rem; font-weight: 300; opacity: 0; transform: translateY(10px); transition: opacity 0.4s ease, transform 0.4s ease; transition-delay: 0.1s; text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5); } .grid-item:hover .ingredients { opacity: 1; transform: translateY(0); } .tag { position: absolute; top: 15px; right: 15px; background-color: #f2cc8f; color: #2f2f2f; font-size: 0.7rem; font-weight: 600; padding: 5px 10px; border-radius: 30px; z-index: 2; opacity: 0; transform: translateX(20px); transition: opacity 0.3s ease, transform 0.3s ease; } .grid-item:hover .tag { opacity: 1; transform: translateX(0); } /* Featured Recipe Section */ .featured { width: 100%; max-width: 670px; margin-top: 20px; padding: 15px; background-color: white; border-radius: 12px; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05); display: none; animation: fadeIn 0.5s ease forwards; position: relative; } @keyframes fadeIn { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } .featured-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; } .featured-title { color: #e07a5f; font-size: 1.3rem; } .close-btn { background: none; border: none; color: #81b29a; font-size: 1.5rem; cursor: pointer; transition: transform 0.2s ease; } .close-btn:hover { transform: scale(1.1); color: #e07a5f; } .featured-content { display: flex; flex-direction: column; gap: 10px; } .thumbnail { width: 100%; height: 180px; border-radius: 8px; overflow: hidden; } .thumbnail img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.3s ease; } .thumbnail:hover img { transform: scale(1.05); } .recipe-details { padding: 10px 0; } .recipe-details h3 { color: #333; margin-bottom: 10px; } .quick-facts { display: flex; gap: 15px; margin-bottom: 15px; font-size: 0.8rem; } .fact { display: flex; align-items: center; gap: 5px; color: #81b29a; } .fact i { font-size: 1.1rem; } .ingredients-list { margin-bottom: 15px; } .ingredients-list h4 { margin-bottom: 8px; color: #e07a5f; } .ingredients-list ul { list-style-type: none; display: grid; grid-template-columns: repeat(2, 1fr); gap: 5px; } .ingredients-list li { font-size: 0.85rem; padding-left: 16px; position: relative; } .ingredients-list li::before { content: '•'; position: absolute; left: 0; color: #f2cc8f; } .method-hint { font-size: 0.85rem; font-style: italic; color: #666; } .read-more { align-self: flex-start; margin-top: 10px; background-color: #81b29a; color: white; border: none; border-radius: 30px; padding: 8px 15px; font-size: 0.85rem; cursor: pointer; transition: background-color 0.3s ease, transform 0.2s ease; } .read-more:hover { background-color: #6b9080; transform: translateY(-2px); } /* Filter controls */ .filters { display: flex; gap: 10px; margin-bottom: 15px; flex-wrap: wrap; justify-content: center; } .filter-btn { background-color: #f8edeb; border: 1px solid #e07a5f; border-radius: 30px; padding: 6px 12px; font-size: 0.8rem; color: #e07a5f; cursor: pointer; transition: all 0.3s ease; } .filter-btn:hover, .filter-btn.active { background-color: #e07a5f; color: white; } @media (max-width: 600px) { .grid-container { grid-template-columns: repeat(2, 1fr); } .grid-item:nth-child(1), .grid-item:nth-child(5) { grid-column: span 2; } .grid-item:nth-child(4) { grid-column: span 1; grid-row: span 1; } h1 { font-size: 1.8rem; } .subtitle { font-size: 0.9rem; } .featured-content { flex-direction: column; } .thumbnail { height: 160px; } .ingredients-list ul { grid-template-columns: 1fr; } } @media (max-width: 400px) { .grid-container { grid-template-columns: 1fr; grid-auto-rows: 160px; } .grid-item:nth-child(1), .grid-item:nth-child(4), .grid-item:nth-child(5) { grid-column: span 1; grid-row: span 1; } } </style> <link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;500;600;700&display=swap" rel="stylesheet"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css"> </head> <body> <header> <h1>Savory Chronicles</h1> <p class="subtitle">A visual diary of my culinary adventures</p> </header> <div class="filters"> <button class="filter-btn active" data-filter="all">All</button> <button class="filter-btn" data-filter="breakfast">Breakfast</button> <button class="filter-btn" data-filter="lunch">Lunch</button> <button class="filter-btn" data-filter="dinner">Dinner</button> <button class="filter-btn" data-filter="dessert">Dessert</button> </div> <div class="grid-container"> <div class="grid-item" data-category="breakfast"> <img src="https://images.unsplash.com/photo-1532980400857-e8d9d275d858?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=774&q=80" alt="Avocado Toast"> <div class="tag">Breakfast</div> <div class="overlay"> <div class="recipe-title">Rustic Avocado Toast</div> <div class="ingredients">Sourdough bread, ripe avocados, cherry tomatoes, microgreens, red pepper flakes</div> </div> </div> <div class="grid-item" data-category="dessert"> <img src="https://images.unsplash.com/photo-1551024601-bec78aea704b?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=864&q=80" alt="Chocolate Souffle"> <div class="tag">Dessert</div> <div class="overlay"> <div class="recipe-title">Chocolate Soufflé</div> <div class="ingredients">Dark chocolate, eggs, butter, vanilla extract, cocoa powder</div> </div> </div> <div class="grid-item" data-category="lunch"> <img src="https://images.unsplash.com/photo-1547592180-85f173990554?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=870&q=80" alt="Poke Bowl"> <div class="tag">Lunch</div> <div class="overlay"> <div class="recipe-title">Rainbow Poke Bowl</div> <div class="ingredients">Sushi rice, fresh tuna, avocado, cucumber, mango, edamame</div> </div> </div> <div class="grid-item" data-category="dinner"> <img src="https://images.unsplash.com/photo-1518492104633-130d0cc84637?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=774&q=80" alt="Pasta"> <div class="tag">Dinner</div> <div class="overlay"> <div class="recipe-title">Truffle Pappardelle</div> <div class="ingredients">Fresh pappardelle, wild mushrooms, black truffle, cream, parmesan</div> </div> </div> <div class="grid-item" data-category="dinner"> <img src="https://images.unsplash.com/photo-1600891964092-4316c288032e?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=870&q=80" alt="Steak"> <div class="tag">Dinner</div> <div class="overlay"> <div class="recipe-title">Pan-Seared Ribeye</div> <div class="ingredients">Ribeye steak, rosemary, garlic, butter, sea salt, black pepper</div> </div> </div> <div class="grid-item" data-category="breakfast"> <img src="https://images.unsplash.com/photo-1504113888839-1c8eb50233d3?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1015&q=80" alt="Pancakes"> <div class="tag">Breakfast</div> <div class="overlay"> <div class="recipe-title">Fluffy Blueberry Pancakes</div> <div class="ingredients">Buttermilk, fresh blueberries, maple syrup, lemon zest, vanilla</div> </div> </div> <div class="grid-item" data-category="dessert"> <img src="https://images.unsplash.com/photo-1587314168485-3236d6710814?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=778&q=80" alt="Strawberry Tart"> <div class="tag">Dessert</div> <div class="overlay"> <div class="recipe-title">Strawberry Basil Tart</div> <div class="ingredients">Shortcrust pastry, mascarpone, fresh strawberries, basil, honey</div> </div> </div> <div class="grid-item" data-category="lunch"> <img src="https://images.unsplash.com/photo-1603903631776-95bbf8d53d7d?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=894&q=80" alt="Salmon"> <div class="tag">Lunch</div> <div class="overlay"> <div class="recipe-title">Citrus Glazed Salmon</div> <div class="ingredients">Fresh salmon fillet, orange, lemon, honey, soy sauce, ginger</div> </div> </div> </div> <div class="featured"> <div class="featured-header"> <h2 class="featured-title">Featured Recipe</h2> <button class="close-btn">×</button> </div> <div class="featured-content"> <div class="thumbnail"> <img id="featured-img" src="" alt="Featured Recipe"> </div> <div class="recipe-details"> <h3 id="featured-title"></h3> <div class="quick-facts"> <div class="fact"> <i class="fas fa-clock"></i> <span id="prep-time"></span> </div> <div class="fact"> <i class="fas fa-fire"></i> <span id="calories"></span> </div> <div class="fact"> <i class="fas fa-utensils"></i> <span id="servings"></span> </div> </div> <div class="ingredients-list"> <h4>Ingredients</h4> <ul id="ingredients-detail"></ul> </div> <p class="method-hint">This rustic breakfast combines creamy avocado with crunchy sourdough toast for a quick and satisfying meal with a Mediterranean twist.</p> <button class="read-more">Full Recipe</button> </div> </div> </div> <script> const gridItems = document.querySelectorAll('.grid-item'); const filterButtons = document.querySelectorAll('.filter-btn'); const featured = document.querySelector('.featured'); const closeBtn = document.querySelector('.close-btn'); const featuredImage = document.getElementById('featured-img'); const featuredTitle = document.getElementById('featured-title'); const prepTime = document.getElementById('prep-time'); const calories = document.getElementById('calories'); const servings = document.getElementById('servings'); const ingredientsList = document.getElementById('ingredients-detail'); // Recipe details mapping const recipeDetails = { "Rustic Avocado Toast": { time: "15 mins", cals: "320 kcal", servs: "2 servings", ingredients: [ "2 slices sourdough bread", "1 ripe avocado", "1 cup cherry tomatoes", "1/4 cup microgreens", "Red pepper flakes", "Olive oil", "Flaky sea salt", "Fresh lemon juice" ] }, "Chocolate Soufflé": { time: "45 mins", cals: "410 kcal", servs: "4 servings", ingredients: [ "200g dark chocolate", "6 eggs, separated", "50g butter", "1 tsp vanilla extract", "3 tbsp cocoa powder", "50g sugar", "Pinch of salt", "Powdered sugar for dusting" ] }, "Rainbow Poke Bowl": { time: "30 mins", cals: "450 kcal", servs: "2 servings", ingredients: [ "1 cup sushi rice", "200g fresh tuna", "1 avocado", "1/2 cucumber", "1/2 mango", "1/2 cup edamame", "Sesame seeds", "Soy sauce & wasabi" ] }, "Truffle Pappardelle": { time: "35 mins", cals: "580 kcal", servs: "2 servings", ingredients: [ "250g fresh pappardelle", "200g wild mushrooms", "5g black truffle", "100ml heavy cream", "30g parmesan cheese", "2 garlic cloves", "Fresh thyme", "Olive oil & salt" ] }, "Pan-Seared Ribeye": { time: "25 mins", cals: "640 kcal", servs: "2 servings", ingredients: [ "2 ribeye steaks", "2 sprigs rosemary", "4 garlic cloves", "50g butter", "Sea salt", "Black pepper", "Olive oil", "Flaky salt to finish" ] }, "Fluffy Blueberry Pancakes": { time: "25 mins", cals: "480 kcal", servs: "4 servings", ingredients: [ "2 cups buttermilk", "2 cups fresh blueberries", "Maple syrup", "1 tsp lemon zest", "1 tsp vanilla extract", "2 cups flour", "2 eggs", "1 tsp baking powder" ] }, "Strawberry Basil Tart": { time: "1 hour 15 mins", cals: "420 kcal", servs: "8 servings", ingredients: [ "1 shortcrust pastry", "250g mascarpone", "400g fresh strawberries", "10 fresh basil leaves", "3 tbsp honey", "1 tsp vanilla extract", "Zest of 1 lemon", "Confectioners' sugar" ] }, "Citrus Glazed Salmon": { time: "30 mins", cals: "390 kcal", servs: "2 servings", ingredients: [ "2 salmon fillets", "1 orange", "1 lemon", "2 tbsp honey", "1 tbsp soy sauce", "1 tsp grated ginger", "Fresh dill", "Black pepper" ] } }; // Apply filter functionality filterButtons.forEach(button => { button.addEventListener('click', () => { // Reset active state filterButtons.forEach(btn => btn.classList.remove('active')); button.classList.add('active'); const filter = button.getAttribute('data-filter'); gridItems.forEach(item => { if (filter === 'all' || item.getAttribute('data-category') === filter) { item.style.display = 'block'; } else { item.style.display = 'none'; } }); }); }); // Grid item click to show featured gridItems.forEach(item => { item.addEventListener('click', () => { // Get recipe title const title = item.querySelector('.recipe-title').textContent; const imgSrc = item.querySelector('img').src; // Populate featured section featuredImage.src = imgSrc; featuredTitle.textContent = title; // Get recipe details const details = recipeDetails[title]; prepTime.textContent = details.time; calories.textContent = details.cals; servings.textContent = details.servs; // Clear and populate ingredients ingredientsList.innerHTML = ''; details.ingredients.forEach(ingredient => { const li = document.createElement('li'); li.textContent = ingredient; ingredientsList.appendChild(li); }); // Show featured with animation featured.style.display = 'block'; // Scroll to featured featured.scrollIntoView({ behavior: 'smooth', block: 'start' }); }); }); // Close featured closeBtn.addEventListener('click', () => { featured.style.display = 'none'; }); // Add animation to grid items on load document.addEventListener('DOMContentLoaded', () => { gridItems.forEach((item, index) => { setTimeout(() => { item.style.opacity = '0'; item.style.animation = `fadeIn 0.5s ease forwards ${index * 0.1}s`; }, 100); }); }); // Read more button - just for demo functionality document.querySelector('.read-more').addEventListener('click', function(e) { e.preventDefault(); alert('Full recipe coming soon!'); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Tech Product Showcase Grid</title> <style> :root { --primary-color: #0a1929; --secondary-color: #102a43; --accent-color: #00c9ff; --accent-hover: #00a3cc; --text-color: #f0f4f8; --text-secondary: #bcccdc; --success-color: #00d084; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; } body { background-color: var(--primary-color); color: var(--text-color); min-height: 100vh; display: flex; flex-direction: column; justify-content: center; align-items: center; padding: 1rem; overflow-x: hidden; } .container { max-width: 700px; width: 100%; height: 700px; overflow-y: auto; padding: 1rem; scrollbar-width: thin; scrollbar-color: var(--accent-color) var(--secondary-color); } .container::-webkit-scrollbar { width: 6px; } .container::-webkit-scrollbar-track { background: var(--secondary-color); border-radius: 3px; } .container::-webkit-scrollbar-thumb { background-color: var(--accent-color); border-radius: 3px; } header { text-align: center; margin-bottom: 2rem; position: relative; } h1 { font-size: 2rem; margin-bottom: 0.5rem; letter-spacing: -0.5px; font-weight: 700; background: linear-gradient(120deg, var(--accent-color), #7f5af0); -webkit-background-clip: text; background-clip: text; color: transparent; } .subtitle { color: var(--text-secondary); font-size: 0.9rem; margin-bottom: 1rem; } .product-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 1.5rem; } .product-card { background-color: var(--secondary-color); border-radius: 12px; overflow: hidden; position: relative; transition: transform 0.3s, box-shadow 0.3s; box-shadow: 0 6px 15px rgba(0, 0, 0, 0.3); height: 280px; cursor: pointer; } .product-card:hover { transform: translateY(-5px); box-shadow: 0 12px 20px rgba(0, 0, 0, 0.4); } .product-card:hover .product-info { opacity: 1; transform: translateY(0); } .product-card:hover .product-header { transform: translateY(-50px); opacity: 0; } .product-image { width: 100%; height: 160px; object-fit: cover; transition: transform 0.5s; } .product-card:hover .product-image { transform: scale(1.1); } .product-header { padding: 1rem; transition: transform 0.3s, opacity 0.3s; position: absolute; bottom: 0; left: 0; width: 100%; background: linear-gradient(0deg, var(--secondary-color) 70%, transparent); } .product-title { font-size: 1rem; font-weight: 600; margin-bottom: 0.25rem; } .product-subtitle { font-size: 0.8rem; color: var(--text-secondary); } .product-info { position: absolute; bottom: 0; left: 0; width: 100%; padding: 1rem; background: rgba(10, 25, 41, 0.9); backdrop-filter: blur(5px); transform: translateY(20px); opacity: 0; transition: transform 0.3s, opacity 0.3s; display: flex; flex-direction: column; height: 120px; } .spec-list { list-style: none; margin-bottom: 0.5rem; } .spec-item { font-size: 0.8rem; margin-bottom: 0.2rem; display: flex; align-items: center; } .spec-item::before { content: "•"; color: var(--accent-color); margin-right: 5px; } .cta-button { background-color: var(--accent-color); color: var(--primary-color); border: none; border-radius: 6px; padding: 0.5rem 1rem; font-size: 0.8rem; font-weight: 600; cursor: pointer; transition: background-color 0.2s, transform 0.2s; margin-top: auto; display: inline-flex; align-items: center; justify-content: center; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); } .cta-button:hover { background-color: var(--accent-hover); transform: translateY(-2px); } .cta-button i { margin-left: 0.5rem; } .ribbon { position: absolute; top: 10px; right: -30px; background-color: var(--success-color); color: var(--primary-color); font-size: 0.7rem; font-weight: 600; padding: 0.25rem 2rem; transform: rotate(45deg); z-index: 2; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); } .sorting { display: flex; align-items: center; justify-content: center; margin-bottom: 1.5rem; gap: 0.5rem; } .sort-button { background: none; border: 1px solid var(--text-secondary); color: var(--text-secondary); padding: 0.4rem 0.8rem; border-radius: 20px; font-size: 0.8rem; cursor: pointer; transition: all 0.2s; } .sort-button:hover, .sort-button.active { background-color: var(--accent-color); color: var(--primary-color); border-color: var(--accent-color); } .product-pulse { position: absolute; top: 15px; left: 15px; width: 12px; height: 12px; border-radius: 50%; background-color: var(--accent-color); z-index: 2; } .product-pulse::before { content: ''; position: absolute; width: 100%; height: 100%; border-radius: 50%; background-color: var(--accent-color); opacity: 0.7; animation: pulse 2s infinite; } @keyframes pulse { 0% { transform: scale(1); opacity: 0.7; } 70% { transform: scale(2); opacity: 0; } 100% { transform: scale(1); opacity: 0; } } .product-modal { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(10, 25, 41, 0.9); backdrop-filter: blur(5px); display: flex; justify-content: center; align-items: center; z-index: 1000; opacity: 0; pointer-events: none; transition: opacity 0.3s; padding: 1rem; } .product-modal.show { opacity: 1; pointer-events: auto; } .modal-content { background-color: var(--secondary-color); border-radius: 12px; max-width: 600px; width: 100%; padding: 1.5rem; position: relative; box-shadow: 0 15px 30px rgba(0, 0, 0, 0.3); transform: translateY(20px); opacity: 0; transition: transform 0.3s, opacity 0.3s; } .product-modal.show .modal-content { transform: translateY(0); opacity: 1; } .modal-close { position: absolute; top: 15px; right: 15px; background: none; border: none; color: var(--text-secondary); font-size: 1.5rem; cursor: pointer; transition: color 0.2s; } .modal-close:hover { color: var(--accent-color); } .modal-image { width: 100%; height: 200px; object-fit: contain; border-radius: 8px; margin-bottom: 1rem; background-color: var(--primary-color); padding: 1rem; } .modal-title { font-size: 1.5rem; margin-bottom: 0.5rem; } .modal-specs { margin: 1rem 0; display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.5rem; } .modal-spec-item { font-size: 0.9rem; display: flex; align-items: flex-start; } .modal-spec-label { color: var(--text-secondary); margin-right: 0.5rem; min-width: 100px; } .modal-cta { margin-top: 1rem; text-align: center; } .modal-buttons { display: flex; gap: 1rem; margin-top: 1rem; } .modal-button { flex: 1; padding: 0.75rem; border-radius: 6px; font-weight: 600; cursor: pointer; transition: all 0.2s; } .modal-button.primary { background-color: var(--accent-color); color: var(--primary-color); border: none; } .modal-button.secondary { background: none; border: 1px solid var(--accent-color); color: var(--accent-color); } .modal-button:hover { transform: translateY(-2px); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); } .modal-button.primary:hover { background-color: var(--accent-hover); } .modal-button.secondary:hover { background-color: rgba(0, 201, 255, 0.1); } .price-tag { font-size: 1.2rem; font-weight: 700; color: var(--accent-color); margin: 0.5rem 0; } .availability { display: inline-flex; align-items: center; font-size: 0.8rem; margin-bottom: 0.5rem; } .availability.in-stock { color: var(--success-color); } .availability.in-stock::before { content: "●"; margin-right: 0.25rem; } @media (max-width: 480px) { .product-grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 1rem; } .product-card { height: 240px; } .product-image { height: 120px; } .sorting { flex-wrap: wrap; } .modal-specs { grid-template-columns: 1fr; } .modal-buttons { flex-direction: column; } } /* Loading animation */ .loading-screen { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: var(--primary-color); display: flex; justify-content: center; align-items: center; z-index: 2000; transition: opacity 0.5s, visibility 0.5s; } .loading-screen.hidden { opacity: 0; visibility: hidden; } .loader { width: 60px; height: 60px; border: 3px solid transparent; border-top-color: var(--accent-color); border-radius: 50%; animation: spin 1s linear infinite; } .loader::before, .loader::after { content: ""; position: absolute; border: 3px solid transparent; border-radius: 50%; } .loader::before { top: 5px; left: 5px; right: 5px; bottom: 5px; border-top-color: #7f5af0; animation: spin 2s linear infinite; } .loader::after { top: 15px; left: 15px; right: 15px; bottom: 15px; border-top-color: var(--success-color); animation: spin 1.5s linear infinite; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } /* Tooltip styles */ .tooltip { position: relative; display: inline-block; } .tooltip .tooltiptext { visibility: hidden; width: 120px; background-color: var(--secondary-color); color: var(--text-color); text-align: center; border-radius: 6px; padding: 5px; position: absolute; z-index: 1; bottom: 125%; left: 50%; transform: translateX(-50%); opacity: 0; transition: opacity 0.3s; font-size: 0.75rem; box-shadow: 0 3px 10px rgba(0, 0, 0, 0.2); } .tooltip .tooltiptext::after { content: ""; position: absolute; top: 100%; left: 50%; margin-left: -5px; border-width: 5px; border-style: solid; border-color: var(--secondary-color) transparent transparent transparent; } .tooltip:hover .tooltiptext { visibility: visible; opacity: 1; } /* Floating action button */ .fab { position: fixed; bottom: 20px; right: 20px; width: 50px; height: 50px; border-radius: 50%; background-color: var(--accent-color); display: flex; justify-content: center; align-items: center; color: var(--primary-color); box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3); cursor: pointer; transition: transform 0.2s, background-color 0.2s; z-index: 10; } .fab:hover { transform: scale(1.1); background-color: var(--accent-hover); } /* Badge count */ .badge { position: absolute; top: -5px; right: -5px; background-color: #ff3860; color: white; font-size: 0.7rem; width: 20px; height: 20px; border-radius: 50%; display: flex; justify-content: center; align-items: center; font-weight: bold; } </style> </head> <body> <div class="loading-screen"> <div class="loader"></div> </div> <div class="container"> <header> <h1>NeoTech Innovations</h1> <p class="subtitle">Next-gen computing solutions for tomorrow's problems</p> <div class="sorting"> <button class="sort-button active" data-category="all">All Products</button> <button class="sort-button" data-category="computing">Computing</button> <button class="sort-button" data-category="mobile">Mobile</button> <button class="sort-button" data-category="audio">Audio</button> </div> </header> <div class="product-grid"> <!-- Products will be dynamically inserted here --> </div> </div> <div class="product-modal"> <div class="modal-content"> <button class="modal-close">×</button> <img class="modal-image" src="" alt="Product"> <h2 class="modal-title"></h2> <div class="availability in-stock">In Stock</div> <p class="modal-description"></p> <div class="price-tag"></div> <div class="modal-specs"> <!-- Specs will be filled dynamically --> </div> <div class="modal-buttons"> <button class="modal-button primary">Add to Cart</button> <button class="modal-button secondary">Save for Later</button> </div> </div> </div> <div class="fab tooltip"> <span class="tooltiptext">View Cart</span> <div class="badge">2</div> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="9" cy="21" r="1"></circle><circle cx="20" cy="21" r="1"></circle><path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"></path></svg> </div> <script> // Product data const products = [ { id: 1, name: "QuantumBook Pro", category: "computing", subtitle: "Ultra-thin laptop", image: "https://images.unsplash.com/photo-1496181133206-80ce9b88a853?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=500&q=80", specs: [ "5nm Quantum Processor", "32GB Neural RAM", "1TB Molecular SSD", "16.2\" Retina XDR" ], price: "$2,299", description: "The QuantumBook Pro redefines mobile computing with its revolutionary 5nm quantum processor delivering unprecedented performance while consuming 45% less power than previous generations.", isNew: true, fullSpecs: { "Processor": "Quantum Core i9, 14-core", "Memory": "32GB LPDDR5-6400", "Storage": "1TB Molecular-State Drive", "Display": "16.2\" Liquid Retina XDR (3456 × 2234)", "Graphics": "Neural Engine Pro 32-core", "Battery": "100Wh, up to '22 hours", "Weight": "2.1 lbs (0.95 kg)" } }, { id: 2, name: "NeuroPhone Z", category: "mobile", subtitle: "Neural interface smartphone", image: "https://images.unsplash.com/photo-1592899677977-9c10ca588bbd?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=500&q=80", specs: [ "Neural Response Interface", "7.1\" Flex OLED", "3-day Graphene Battery", "Molecular Camera System" ], price: "$1,149", description: "The NeuroPhone Z introduces our patented Neural Response Interface, allowing intuitive control through micro-gestures and thought patterns for a truly hands-free experience.", isNew: true, fullSpecs: { "Processor": "BioCore A16, 6-core", "Memory": "16GB Unified", "Storage": "512GB NVMe", "Display": "7.1\" Dynamic AMOLED (2400 × 1080)", "Camera": "108MP Molecular System", "Battery": "Graphene 6000mAh", "Biometrics": "3D Neural Scanner" } }, { id: 3, name: "SonicCloud Buds", category: "audio", subtitle: "Spatial audio earbuds", image: "https://images.unsplash.com/photo-1606220588913-b3aacb4d2f37?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=500&q=80", specs: [ "360° Spatial Audio", "40hrs Battery Life", "Adaptive EQ Profiling", "Neural Noise Cancellation" ], price: "$249", description: "SonicCloud Buds create a personalized soundscape that adapts in real-time to your environment, featuring our proprietary Neural Noise Cancellation that learns and blocks specific unwanted sounds.", isNew: false, fullSpecs: { "Driver": "13mm Graphene Dynamic", "Frequency Response": "5Hz-40kHz (extended range)", "Battery Life": "10hrs (buds), 30hrs (case)", "Connectivity": "Bluetooth 6.0, Ultra-Wideband", "Water Resistance": "IPX7 (fully waterproof)", "Features": "Real-time translation, health monitoring", "Charging": "Wireless Qi, USB-C" } }, { id: 4, name: "Vision Pro Desktop", category: "computing", subtitle: "AR workstation", image: "https://images.unsplash.com/photo-1593640408182-31c70c8268f5?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=500&q=80", specs: [ "Holographic Interface", "128-core Processor Grid", "64TB Neural Storage", "Quantum Cooling System" ], price: "$3,499", description: "The Vision Pro Desktop combines a physical workstation with an integrated AR environment, projecting unlimited virtual screens that follow you around your workspace with zero latency.", isNew: false, fullSpecs: { "Processor": "Quantum Grid 128-core", "Memory": "128GB DDR6", "Storage": "4TB PCIe 5.0 NVMe", "Graphics": "RTX 5090 Ti, 32GB GDDR7", "Holographic System": "8K per eye projection", "Cooling": "Quantum Liquid System", "Connectivity": "Thunderbolt 5, Wi-Fi 7" } }, { id: 5, name: "NeuroPad Mini", category: "mobile", subtitle: "Neural tablet", image: "https://images.unsplash.com/photo-1544244015-0df4b3ffc6b0?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=500&q=80", specs: [ "Tactile Feedback Display", "Neural Stylus Pro", "Bio-adaptive Interface", "360° Spatial Cameras" ], price: "$899", description: "The NeuroPad Mini features our revolutionary tactile feedback display, creating physical texture sensations for digital content through microscopic surface deformations.", isNew: false, fullSpecs: { "Processor": "NeurCore A15 Bionic", "Memory": "16GB LPDDR5X", "Storage": "1TB NVMe", "Display": "11\" Tactile Liquid Retina", "Cameras": "4D LiDAR System", "Battery": "15 hours continuous use", "Biometrics": "In-screen Neural ID" } }, { id: 6, name: "AcoustiSphere X", category: "audio", subtitle: "Spatial smart speaker", image: "https://images.unsplash.com/photo-1545454675-3531b543be5d?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=500&q=80", specs: [ "Holographic Sound Field", "Room-sensing Calibration", "8K Audio Resolution", "Ambient Intelligence" ], price: "$399", description: "The AcoustiSphere X creates a true holographic sound field, placing individual audio elements anywhere in 3D space with pinpoint accuracy that follows you as you move around.", isNew: true, fullSpecs: { "Drivers": "12 beam-forming speakers", "Subwoofer": "8\" downward-firing", "Amplifier": "1500W total output", "Frequency Response": "16Hz-25kHz", "Room Calibration": "360° spatial mapping", "Connectivity": "Wi-Fi 6E, Bluetooth 5.3, HDMI eARC", "Assistant": "NeoVoice with offline processing" } } ]; document.addEventListener('DOMContentLoaded', function() { // Wait for a short moment to simulate loading setTimeout(() => { // Hide loading screen document.querySelector('.loading-screen').classList.add('hidden'); // Render products renderProducts('all'); // Add event listeners for sorting buttons document.querySelectorAll('.sort-button').forEach(button => { button.addEventListener('click', function() { // Remove active class from all buttons document.querySelectorAll('.sort-button').forEach(btn => { btn.classList.remove('active'); }); // Add active class to clicked button this.classList.add('active'); // Render products based on selected category renderProducts(this.dataset.category); }); }); // Modal close button document.querySelector('.modal-close').addEventListener('click', function() { document.querySelector('.product-modal').classList.remove('show'); }); // Close modal when clicking outside content document.querySelector('.product-modal').addEventListener('click', function(event) { if (event.target === this) { this.classList.remove('show'); } }); // Modal buttons document.querySelectorAll('.modal-button').forEach(button => { button.addEventListener('click', function() { // Show notification (if this was a real app) const notification = document.createElement('div'); notification.style.position = 'fixed'; notification.style.bottom = '20px'; notification.style.left = '50%'; notification.style.transform = 'translateX(-50%)'; notification.style.backgroundColor = 'var(--success-color)'; notification.style.color = 'var(--primary-color)'; notification.style.padding = '0.75rem 1.5rem'; notification.style.borderRadius = '4px'; notification.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.2)'; notification.style.zIndex = '1000'; notification.style.transition = 'opacity 0.3s, transform 0.3s'; notification.innerText = this.classList.contains('primary') ? 'Added to cart!' : 'Saved for later!'; document.body.appendChild(notification); // Remove notification after 3 seconds setTimeout(() => { notification.style.opacity = '0'; notification.style.transform = 'translateX(-50%) translateY(20px)'; setTimeout(() => { notification.remove(); }, 300); }, 3000); // Close modal document.querySelector('.product-modal').classList.remove('show'); }); }); // FAB button document.querySelector('.fab').addEventListener('click', function() { alert('Cart functionality would open here'); }); }, 1000); }); // Function to render products based on category function renderProducts(category) { const grid = document.querySelector('.product-grid'); grid.innerHTML = ''; // Filter products based on category const filteredProducts = category === 'all' ? products : products.filter(product => product.category === category); // Add products to grid filteredProducts.forEach(product => { const card = document.createElement('div'); card.className = 'product-card'; card.dataset.id = product.id; let cardContent = ` <img src="${product.image}" alt="${product.name}" class="product-image"> <div class="product-pulse"></div> ${product.isNew ? '<div class="ribbon">NEW</div>' : ''} <div class="product-header"> <h3 class="product-title">${product.name}</h3> <p class="product-subtitle">${product.subtitle}</p> </div> <div class="product-info"> <ul class="spec-list"> `; // Add specs product.specs.forEach(spec => { cardContent += `<li class="spec-item">${spec}</li>`; }); cardContent += ` </ul> <button class="cta-button">View Details</button> </div> `; card.innerHTML = cardContent; grid.appendChild(card); // Add click event to open modal card.addEventListener('click', function() { openProductModal(product.id); }); }); // Add animation to cards document.querySelectorAll('.product-card').forEach((card, index) => { card.style.opacity = '0'; card.style.transform = 'translateY(20px)'; card.style.transition = 'opacity 0.3s ease, transform 0.3s ease'; setTimeout(() => { card.style.opacity = '1'; card.style.transform = 'translateY(0)'; }, 50 * index); }); } // Function to open product modal function openProductModal(productId) { const product = products.find(p => p.id === productId); const modal = document.querySelector('.product-modal'); // Fill modal with product details modal.querySelector('.modal-image').src = product.image; modal.querySelector('.modal-image').alt = product.name; modal.querySelector('.modal-title').textContent = product.name; modal.querySelector('.modal-description').textContent = product.description; modal.querySelector('.price-tag').textContent = product.price; // Fill specs const specsContainer = modal.querySelector('.modal-specs'); specsContainer.innerHTML = ''; for (const [key, value] of Object.entries(product.fullSpecs)) { const specItem = document.createElement('div'); specItem.className = 'modal-spec-item'; specItem.innerHTML = ` <span class="modal-spec-label">${key}:</span> <span class="modal-spec-value">${value}</span> `; specsContainer.appendChild(specItem); } // Show modal modal.classList.add('show'); } </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>EPHEMERE – SS24 Lookbook</title> <style> @import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,700;1,400&family=Montserrat:wght@300;400;500;600&display=swap'); * { margin: 0; padding: 0; box-sizing: border-box; } :root { --primary-color: #1a1a1a; --secondary-color: #f0f0f0; --accent-color: #ff3366; --text-color: #333; --spacing-unit: 8px; } body { font-family: 'Montserrat', sans-serif; background-color: var(--secondary-color); color: var(--text-color); width: 100%; height: 100%; overflow-x: hidden; padding: calc(var(--spacing-unit) * 2); } .container { max-width: 700px; margin: 0 auto; height: 680px; overflow-y: auto; padding-right: 10px; scrollbar-width: thin; } .container::-webkit-scrollbar { width: 4px; } .container::-webkit-scrollbar-track { background: var(--secondary-color); } .container::-webkit-scrollbar-thumb { background-color: #ccc; border-radius: 4px; } header { text-align: center; margin-bottom: calc(var(--spacing-unit) * 4); position: relative; } h1 { font-family: 'Playfair Display', serif; font-size: 2.5rem; font-weight: 400; letter-spacing: 3px; margin-bottom: calc(var(--spacing-unit) * 1); color: var(--primary-color); } .season { font-weight: 300; letter-spacing: 2px; margin-bottom: calc(var(--spacing-unit) * 3); color: var(--primary-color); font-size: 0.9rem; } .accent-line { width: 40px; height: 3px; background-color: var(--accent-color); margin: 0 auto; margin-bottom: calc(var(--spacing-unit) * 4); } .intro { font-size: 0.85rem; line-height: 1.6; max-width: 80%; margin: 0 auto; margin-bottom: calc(var(--spacing-unit) * 4); color: #666; } .lookbook-grid { display: grid; grid-template-columns: repeat(12, 1fr); grid-gap: calc(var(--spacing-unit) * 3); margin-bottom: calc(var(--spacing-unit) * 6); } .lookbook-item { position: relative; overflow: hidden; border-radius: 2px; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05); background-color: white; cursor: pointer; transition: transform 0.4s ease, box-shadow 0.4s ease; } .lookbook-item:hover { transform: translateY(-5px); box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1); } .lookbook-item.large { grid-column: span 6; grid-row: span 2; height: 400px; } .lookbook-item.medium { grid-column: span 6; height: 280px; } .lookbook-item.small { grid-column: span 4; height: 240px; } .lookbook-image { width: 100%; height: 100%; object-fit: cover; transition: transform 0.6s ease; filter: grayscale(80%); } .lookbook-item:hover .lookbook-image { transform: scale(1.05); filter: grayscale(0%); } .lookbook-caption { position: absolute; bottom: 0; left: 0; width: 100%; padding: calc(var(--spacing-unit) * 2); background: rgba(255, 255, 255, 0.9); transform: translateY(100%); transition: transform 0.4s ease; } .lookbook-item:hover .lookbook-caption { transform: translateY(0); } .item-number { font-family: 'Playfair Display', serif; font-style: italic; color: var(--accent-color); font-size: 0.9rem; margin-bottom: calc(var(--spacing-unit) * 0.5); } .item-title { font-family: 'Playfair Display', serif; margin-bottom: calc(var(--spacing-unit) * 1); font-size: 1.1rem; color: var(--primary-color); } .item-desc { font-size: 0.8rem; margin-bottom: calc(var(--spacing-unit) * 1); line-height: 1.4; } .price { font-weight: 600; color: var(--primary-color); font-size: 0.9rem; } .tag { position: absolute; top: calc(var(--spacing-unit) * 2); right: calc(var(--spacing-unit) * 2); background-color: var(--accent-color); color: white; padding: calc(var(--spacing-unit) * 0.5) calc(var(--spacing-unit) * 1); font-size: 0.7rem; letter-spacing: 1px; text-transform: uppercase; opacity: 0; transform: translateY(-10px); transition: opacity 0.4s ease, transform 0.4s ease; } .lookbook-item:hover .tag { opacity: 1; transform: translateY(0); } .view-details { display: inline-block; color: var(--accent-color); font-size: 0.8rem; margin-top: calc(var(--spacing-unit) * 1); text-decoration: none; font-weight: 500; letter-spacing: 0.5px; transition: all 0.3s ease; border-bottom: 1px solid transparent; } .view-details:hover { border-bottom: 1px solid var(--accent-color); } @media (max-width: 700px) { .lookbook-grid { grid-template-columns: repeat(6, 1fr); } .lookbook-item.large { grid-column: span 6; height: 350px; } .lookbook-item.medium { grid-column: span 6; height: 250px; } .lookbook-item.small { grid-column: span 3; height: 200px; } h1 { font-size: 2rem; } .container { height: auto; max-height: 680px; } } @media (max-width: 480px) { .lookbook-item.small { grid-column: span 6; height: 200px; } } /* Special element: collection highlight */ .collection-highlight { position: relative; margin: calc(var(--spacing-unit) * 6) 0; padding: calc(var(--spacing-unit) * 3); background-color: #fff; border-left: 3px solid var(--accent-color); } .highlight-title { font-family: 'Playfair Display', serif; font-size: 1.4rem; margin-bottom: calc(var(--spacing-unit) * 2); color: var(--primary-color); position: relative; } .highlight-title::after { content: ''; position: absolute; bottom: -8px; left: 0; width: 30px; height: 2px; background-color: var(--accent-color); } .highlight-quote { font-style: italic; margin-bottom: calc(var(--spacing-unit) * 2); color: #666; line-height: 1.6; } /* Signature animation */ .designer-signature { font-family: 'Playfair Display', serif; font-style: italic; text-align: right; color: var(--primary-color); position: relative; overflow: hidden; } .signature-line { display: inline-block; position: relative; } .signature-line::after { content: ''; position: absolute; bottom: 0; left: 0; width: 100%; height: 1px; background-color: var(--accent-color); transform: scaleX(0); transform-origin: right; transition: transform 0.6s ease; } .collection-highlight:hover .signature-line::after { transform: scaleX(1); transform-origin: left; } </style> </head> <body> <div class="container"> <header> <h1>EPHEMERE</h1> <div class="season">SPRING / SUMMER 2024</div> <div class="accent-line"></div> <p class="intro">A celebration of transience and renewal. This collection explores fleeting moments through delicate silhouettes and meticulous craftsmanship. Each piece embodies our commitment to sustainable luxury and timeless elegance.</p> </header> <div class="lookbook-grid"> <div class="lookbook-item large"> <img src="https://images.unsplash.com/photo-1584093091778-e7f4e76e8063?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80" alt="Structured linen blazer with tailored pants" class="lookbook-image"> <div class="lookbook-caption"> <div class="item-number">Look 01</div> <h3 class="item-title">Odette Structured Linen Ensemble</h3> <p class="item-desc">Expertly tailored blazer in natural linen with matching high-waisted trousers. Handcrafted mother-of-pearl buttons.</p> <div class="price">€895</div> <a href="#" class="view-details">View details</a> </div> <div class="tag">Statement Piece</div> </div> <div class="lookbook-item medium"> <img src="https://images.unsplash.com/photo-1599354607459-a537aa20e948?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80" alt="Pleated silk maxi dress" class="lookbook-image"> <div class="lookbook-caption"> <div class="item-number">Look 02</div> <h3 class="item-title">Soleil Pleated Silk Maxi</h3> <p class="item-desc">Flowing pleated silk in ethereal ivory. Asymmetrical neckline with delicate draping.</p> <div class="price">€750</div> <a href="#" class="view-details">View details</a> </div> <div class="tag">New Arrival</div> </div> <div class="lookbook-item medium"> <img src="https://images.unsplash.com/photo-1603251579431-8041402bdeda?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80" alt="Oversized cashmere sweater" class="lookbook-image"> <div class="lookbook-caption"> <div class="item-number">Look 03</div> <h3 class="item-title">Clément Organic Cashmere Pullover</h3> <p class="item-desc">Sustainably-sourced cashmere knit with modern boxy silhouette. Perfect transitional piece.</p> <div class="price">€680</div> <a href="#" class="view-details">View details</a> </div> <div class="tag">Sustainable</div> </div> <div class="lookbook-item small"> <img src="https://images.unsplash.com/photo-1612722432474-b971cdcea546?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80" alt="Minimalist leather tote" class="lookbook-image"> <div class="lookbook-caption"> <div class="item-number">Accessory 01</div> <h3 class="item-title">Mathilde Structured Tote</h3> <p class="item-desc">Vegetable-tanned leather with minimal hardware. Handcrafted in our Parisian atelier.</p> <div class="price">€590</div> <a href="#" class="view-details">View details</a> </div> <div class="tag">Artisanal</div> </div> <div class="lookbook-item small"> <img src="https://images.unsplash.com/photo-1525507119028-ed4c629a60a3?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80" alt="Sculptural earrings" class="lookbook-image"> <div class="lookbook-caption"> <div class="item-number">Accessory 02</div> <h3 class="item-title">Vague Sculptural Earrings</h3> <p class="item-desc">Recycled silver with organic wave-inspired form. Statement piece with subtle movement.</p> <div class="price">€320</div> <a href="#" class="view-details">View details</a> </div> <div class="tag">Exclusive</div> </div> <div class="lookbook-item small"> <img src="https://images.unsplash.com/photo-1543087903-1ac2ec7aa8c5?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80" alt="Modern ankle boots" class="lookbook-image"> <div class="lookbook-caption"> <div class="item-number">Accessory 03</div> <h3 class="item-title">Simone Leather Ankle Boot</h3> <p class="item-desc">Italian calf leather with architectural heel. Subtle texture contrast for elevated everyday wear.</p> <div class="price">€495</div> <a href="#" class="view-details">View details</a> </div> <div class="tag">Best Seller</div> </div> </div> <div class="collection-highlight"> <h2 class="highlight-title">Designer's Note</h2> <p class="highlight-quote">"This season, I wanted to capture beauty in impermanence. Each garment embraces a duality – structured yet ethereal, minimal yet expressive. The collection explores how clothing becomes an intimate part of our personal narratives."</p> <div class="designer-signature"> <span class="signature-line">Claudine Vernier, Creative Director</span> </div> </div> <div class="lookbook-grid"> <div class="lookbook-item medium"> <img src="https://images.unsplash.com/photo-1583759136431-9d70db2eb04d?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80" alt="Draped evening gown" class="lookbook-image"> <div class="lookbook-caption"> <div class="item-number">Look 04</div> <h3 class="item-title">Cécile Draped Evening Dress</h3> <p class="item-desc">Fluid silk charmeuse with asymmetrical draping. Architectural bodice with open back detail.</p> <div class="price">€1,250</div> <a href="#" class="view-details">View details</a> </div> <div class="tag">Editorial</div> </div> <div class="lookbook-item medium"> <img src="https://images.unsplash.com/photo-1551232864-3f0890e580d9?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80" alt="Embroidered cotton blouse" class="lookbook-image"> <div class="lookbook-caption"> <div class="item-number">Look 05</div> <h3 class="item-title">Margot Embroidered Cotton Blouse</h3> <p class="item-desc">Organic cotton poplin with handcrafted embroidery. Balloon sleeves with delicate cuff detail.</p> <div class="price">€420</div> <a href="#" class="view-details">View details</a> </div> <div class="tag">Limited Edition</div> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Staggered animation for lookbook items const lookbookItems = document.querySelectorAll('.lookbook-item'); lookbookItems.forEach((item, index) => { setTimeout(() => { item.style.opacity = '0'; item.style.transform = 'translateY(20px)'; item.style.transition = 'opacity 0.8s ease, transform 0.8s ease'; setTimeout(() => { item.style.opacity = '1'; item.style.transform = 'translateY(0)'; }, 100); }, index * 100); }); // Add interaction for lookbook items lookbookItems.forEach(item => { item.addEventListener('mouseenter', function() { lookbookItems.forEach(otherItem => { if (otherItem !== item) { otherItem.style.opacity = '0.7'; } }); }); item.addEventListener('mouseleave', function() { lookbookItems.forEach(otherItem => { otherItem.style.opacity = '1'; }); }); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> :root { --muted-bg: #f4f1ee; --text-primary: #333333; --border-color: #d8d2cc; --hover-shadow: rgba(0, 0, 0, 0.12); --accent: #b5a698; --accent-dark: #8c7b6b; --transition: all 0.4s cubic-bezier(0.165, 0.84, 0.44, 1); } * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Cormorant Garamond', 'Times New Roman', serif; background-color: var(--muted-bg); color: var(--text-primary); height: 100%; line-height: 1.6; padding: 0; overflow-x: hidden; } .container { width: 100%; max-width: 700px; height: 700px; margin: 0 auto; padding: 20px; overflow-y: auto; position: relative; } header { text-align: left; margin-bottom: 20px; position: relative; z-index: 2; } h1 { font-size: 28px; font-weight: 500; letter-spacing: 1px; margin-bottom: 8px; color: var(--text-primary); } h2 { font-size: 16px; font-weight: 400; color: var(--accent-dark); letter-spacing: 0.5px; margin-bottom: 20px; } p { font-size: 15px; margin-bottom: 25px; max-width: 650px; line-height: 1.7; } .gallery-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 15px; margin-top: 20px; } .artwork { position: relative; border: 1px solid var(--border-color); background-color: white; padding: 8px; transition: var(--transition); cursor: pointer; overflow: hidden; height: 210px; display: flex; flex-direction: column; } .artwork:hover { transform: translateY(-4px); box-shadow: 0 8px 20px var(--hover-shadow); } .artwork-image { width: 100%; height: 150px; object-fit: cover; margin-bottom: 8px; transition: var(--transition); } .artwork:hover .artwork-image { transform: scale(1.05); } .info { padding: 0px 2px; flex-grow: 1; display: flex; flex-direction: column; justify-content: space-between; } .title { font-size: 14px; font-weight: 500; } .artist { font-size: 12px; color: var(--accent-dark); font-style: italic; } .modal { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(244, 241, 238, 0.95); display: flex; justify-content: center; align-items: center; z-index: 100; opacity: 0; pointer-events: none; transition: opacity 0.3s ease; backdrop-filter: blur(5px); } .modal.active { opacity: 1; pointer-events: all; } .modal-content { max-width: 80%; max-height: 80%; position: relative; padding: 20px; background-color: white; border: 1px solid var(--border-color); box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.1); display: flex; flex-direction: column; align-items: center; } .modal-image { max-width: 100%; max-height: 400px; object-fit: contain; margin-bottom: 15px; } .modal-info { text-align: center; max-width: 500px; } .modal-info .title { font-size: 22px; margin-bottom: 5px; } .modal-info .artist { font-size: 16px; margin-bottom: 15px; } .modal-info .description { font-size: 15px; line-height: 1.6; margin-bottom: 10px; } .close-modal { position: absolute; top: 10px; right: 10px; background: transparent; border: none; font-size: 24px; cursor: pointer; color: var(--accent-dark); transition: var(--transition); } .close-modal:hover { color: var(--text-primary); transform: rotate(90deg); } .filter-nav { display: flex; gap: 15px; margin-bottom: 20px; flex-wrap: wrap; } .filter-btn { background-color: transparent; border: 1px solid var(--border-color); padding: 6px 12px; font-size: 13px; cursor: pointer; transition: var(--transition); font-family: inherit; color: var(--text-primary); } .filter-btn:hover, .filter-btn.active { background-color: var(--accent); color: white; border-color: var(--accent); } .exhibition-date { position: absolute; top: 25px; right: 20px; background-color: var(--accent); color: white; padding: 6px 12px; font-size: 14px; letter-spacing: 0.5px; } .loading-dots { position: absolute; bottom: 15px; left: 50%; transform: translateX(-50%); display: flex; gap: 6px; justify-content: center; margin-top: 15px; } .dot { width: 8px; height: 8px; background-color: var(--accent); border-radius: 50%; opacity: 0.5; animation: loadingPulse 1.5s infinite ease-in-out; } .dot:nth-child(2) { animation-delay: 0.2s; } .dot:nth-child(3) { animation-delay: 0.4s; } @keyframes loadingPulse { 0%, 100% { opacity: 0.5; transform: scale(1); } 50% { opacity: 1; transform: scale(1.2); } } @media (max-width: 600px) { .gallery-grid { grid-template-columns: repeat(2, 1fr); gap: 10px; } h1 { font-size: 24px; } p { font-size: 14px; } .exhibition-date { position: static; display: inline-block; margin-bottom: 15px; } } /* Custom scrollbar */ .container::-webkit-scrollbar { width: 6px; } .container::-webkit-scrollbar-track { background: var(--muted-bg); } .container::-webkit-scrollbar-thumb { background-color: var(--accent); border-radius: 10px; } </style> </head> <body> <div class="container"> <header> <h1>Chromatic Dialogues</h1> <h2>Contemporary Expressions in Form & Color</h2> <div class="exhibition-date">April 18 - June 30, 2023</div> <p>This exhibition brings together works from emerging and established artists exploring the boundaries of contemporary visual dialogue. Selected pieces traverse various mediums while maintaining a cohesive exploration of how form and color interact in modern artistic expression.</p> </header> <div class="filter-nav"> <button class="filter-btn active" data-filter="all">All Works</button> <button class="filter-btn" data-filter="painting">Painting</button> <button class="filter-btn" data-filter="photography">Photography</button> <button class="filter-btn" data-filter="mixed-media">Mixed Media</button> </div> <div class="gallery-grid"> <!-- Artwork items will be inserted here via JavaScript --> </div> <div class="loading-dots"> <div class="dot"></div> <div class="dot"></div> <div class="dot"></div> </div> </div> <div class="modal" id="artwork-modal"> <div class="modal-content"> <button class="close-modal">×</button> <img src="" alt="" class="modal-image"> <div class="modal-info"> <h3 class="title"></h3> <p class="artist"></p> <p class="description"></p> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Artwork data const artworks = [ { id: 1, title: "Suspended Reverie", artist: "Elena Morales", category: "painting", image: "https://images.unsplash.com/photo-1549887534-1541e9326642?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=765&q=80", description: "Acrylic on canvas exploring the liminal space between conscious thought and dream states. Morales utilizes layered transparencies and bold color fields to create a sense of depth and emotional resonance." }, { id: 2, title: "Urban Geometry #7", artist: "Marco Tanaka", category: "photography", image: "https://images.unsplash.com/photo-1518998053901-5348d3961a04?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=774&q=80", description: "Digital photography capturing the intersecting architectural planes of Tokyo's financial district. Tanaka's signature high-contrast approach emphasizes the mathematical precision of contemporary urban design." }, { id: 3, title: "Fragments of Memory", artist: "Sophia Chen", category: "mixed-media", image: "https://images.unsplash.com/photo-1579541591970-e5795a602dd0?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=765&q=80", description: "Mixed media assemblage incorporating found objects, paper ephemera, and photographic transfers. Chen's work explores personal histories and collective memory through material juxtaposition." }, { id: 4, title: "Threshold", artist: "James Nwokoye", category: "painting", image: "https://images.unsplash.com/photo-1615639164215-2386683e3729?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=774&q=80", description: "Oil on panel using a restricted palette of earth tones and deep blues. Nwokoye's work investigates boundaries and transitions through metaphorical doorways and passages." }, { id: 5, title: "Chromatic Field Study", artist: "Ana Villareal", category: "painting", image: "https://images.unsplash.com/photo-1584448097639-99cf648e8def?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=774&q=80", description: "Watercolor and gouache on handmade paper exploring color theory principles through atmospheric gradients. Villareal's meticulous technique creates luminous transitions between complementary hues." }, { id: 6, title: "Liminal Space #3", artist: "David Kwon", category: "photography", image: "https://images.unsplash.com/photo-1581563438399-aeb01150297c?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2360&q=80", description: "Large-format photograph documenting transitional architectural spaces. Part of Kwon's ongoing series examining how designed environments shape human psychology and movement." }, { id: 7, title: "Constructed Remnants", artist: "Leila Hassan", category: "mixed-media", image: "https://images.unsplash.com/photo-1580136579312-94651dfd596d?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=774&q=80", description: "Textile assemblage incorporating repurposed fabric, thread, and metal elements. Hassan's practice centers on material transformation and questions of sustainability in contemporary art-making." }, { id: 8, title: "Synthesis Study", artist: "Omar Rivera", category: "painting", image: "https://images.unsplash.com/photo-1578301978693-85fa9c0320b9?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=774&q=80", description: "Acrylic and graphite on wood panel exploring the intersection of analog and digital mark-making. Rivera's precise compositions balance geometric structure with intuitive gestural elements." }, { id: 9, title: "Temporal Echoes", artist: "Camila Rodriguez", category: "photography", image: "https://images.unsplash.com/photo-1569235186275-626cb53b83ce?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=928&q=80", description: "Time-lapse photography series investigating the relationship between natural light and architectural space throughout the day. Rodriguez captures subtle perceptual shifts in familiar environments." } ]; const galleryGrid = document.querySelector('.gallery-grid'); const modal = document.getElementById('artwork-modal'); const modalImage = modal.querySelector('.modal-image'); const modalTitle = modal.querySelector('.title'); const modalArtist = modal.querySelector('.artist'); const modalDescription = modal.querySelector('.description'); const closeModalBtn = modal.querySelector('.close-modal'); const filterBtns = document.querySelectorAll('.filter-btn'); // Populate gallery grid function renderGallery(artworksToRender) { galleryGrid.innerHTML = ''; artworksToRender.forEach(artwork => { const artworkElement = document.createElement('div'); artworkElement.classList.add('artwork'); artworkElement.setAttribute('data-id', artwork.id); artworkElement.setAttribute('data-category', artwork.category); artworkElement.innerHTML = ` <img src="${artwork.image}" alt="${artwork.title}" class="artwork-image"> <div class="info"> <div class="title">${artwork.title}</div> <div class="artist">${artwork.artist}</div> </div> `; galleryGrid.appendChild(artworkElement); }); } // Initialize gallery renderGallery(artworks); // Filter functionality filterBtns.forEach(btn => { btn.addEventListener('click', function() { filterBtns.forEach(b => b.classList.remove('active')); this.classList.add('active'); const filter = this.getAttribute('data-filter'); if (filter === 'all') { renderGallery(artworks); } else { const filteredArtworks = artworks.filter(artwork => artwork.category === filter); renderGallery(filteredArtworks); } }); }); // Modal functionality galleryGrid.addEventListener('click', function(e) { const artworkElement = e.target.closest('.artwork'); if (!artworkElement) return; const artworkId = parseInt(artworkElement.getAttribute('data-id')); const artwork = artworks.find(a => a.id === artworkId); if (artwork) { modalImage.src = artwork.image; modalImage.alt = artwork.title; modalTitle.textContent = artwork.title; modalArtist.textContent = artwork.artist; modalDescription.textContent = artwork.description; modal.classList.add('active'); document.body.style.overflow = 'hidden'; } }); closeModalBtn.addEventListener('click', function() { modal.classList.remove('active'); document.body.style.overflow = 'auto'; }); modal.addEventListener('click', function(e) { if (e.target === modal) { modal.classList.remove('active'); document.body.style.overflow = 'auto'; } }); // Animate items on load setTimeout(() => { const artworkItems = document.querySelectorAll('.artwork'); artworkItems.forEach((item, index) => { setTimeout(() => { item.style.opacity = '1'; item.style.transform = 'translateY(0)'; }, index * 100); }); // Hide loading dots document.querySelector('.loading-dots').style.display = 'none'; }, 800); // Add initial hiding of artworks const artworkItems = document.querySelectorAll('.artwork'); artworkItems.forEach(item => { item.style.opacity = '0'; item.style.transform = 'translateY(15px)'; item.style.transition = 'opacity 0.5s ease, transform 0.5s ease'; }); }); </script> </body> </html>