| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Neutralframes — Minimal Framing for Modern Spaces</title> |
| <script src="https://cdn.tailwindcss.com"></script> |
| <link rel="preconnect" href="https://fonts.googleapis.com"> |
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> |
| <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Playfair+Display:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500&display=swap" rel="stylesheet"> |
| <script> |
| tailwind.config = { |
| theme: { |
| extend: { |
| colors: { |
| neutral: { |
| 50: '#FAFAF8', |
| 100: '#F5F5F0', |
| 200: '#E8E8E0', |
| 300: '#D4D4C8', |
| 400: '#A8A898', |
| 500: '#787868', |
| 600: '#585848', |
| 700: '#404038', |
| 800: '#282820', |
| 900: '#181810', |
| }, |
| cream: '#F5F0EB', |
| warm: '#E8DFD0', |
| sand: '#C4B89A', |
| charcoal: '#2C2C28', |
| }, |
| fontFamily: { |
| sans: ['Inter', 'sans-serif'], |
| display: ['Playfair Display', 'serif'], |
| } |
| } |
| } |
| } |
| </script> |
| <style> |
| * { margin: 0; padding: 0; box-sizing: border-box; } |
| html { scroll-behavior: smooth; } |
| body { font-family: 'Inter', sans-serif; background: #FAFAF8; color: #2C2C28; } |
| |
| |
| ::-webkit-scrollbar { width: 6px; } |
| ::-webkit-scrollbar-track { background: #F5F5F0; } |
| ::-webkit-scrollbar-thumb { background: #A8A898; border-radius: 3px; } |
| ::-webkit-scrollbar-thumb:hover { background: #787868; } |
| |
| |
| @keyframes fadeInUp { |
| from { opacity: 0; transform: translateY(30px); } |
| to { opacity: 1; transform: translateY(0); } |
| } |
| @keyframes fadeIn { |
| from { opacity: 0; } |
| to { opacity: 1; } |
| } |
| @keyframes slideInLeft { |
| from { opacity: 0; transform: translateX(-40px); } |
| to { opacity: 1; transform: translateX(0); } |
| } |
| @keyframes slideInRight { |
| from { opacity: 0; transform: translateX(40px); } |
| to { opacity: 1; transform: translateX(0); } |
| } |
| @keyframes scaleIn { |
| from { opacity: 0; transform: scale(0.95); } |
| to { opacity: 1; transform: scale(1); } |
| } |
| @keyframes float { |
| 0%, 100% { transform: translateY(0px); } |
| 50% { transform: translateY(-8px); } |
| } |
| |
| .animate-fade-in-up { animation: fadeInUp 0.8s ease-out forwards; } |
| .animate-fade-in { animation: fadeIn 0.6s ease-out forwards; } |
| .animate-slide-left { animation: slideInLeft 0.8s ease-out forwards; } |
| .animate-slide-right { animation: slideInRight 0.8s ease-out forwards; } |
| .animate-scale-in { animation: scaleIn 0.6s ease-out forwards; } |
| .animate-float { animation: float 4s ease-in-out infinite; } |
| |
| .delay-100 { animation-delay: 0.1s; } |
| .delay-200 { animation-delay: 0.2s; } |
| .delay-300 { animation-delay: 0.3s; } |
| .delay-400 { animation-delay: 0.4s; } |
| .delay-500 { animation-delay: 0.5s; } |
| .delay-600 { animation-delay: 0.6s; } |
| |
| |
| .reveal { opacity: 0; transform: translateY(30px); transition: all 0.8s cubic-bezier(0.16, 1, 0.3, 1); } |
| .reveal.visible { opacity: 1; transform: translateY(0); } |
| |
| |
| .frame-card { position: relative; overflow: hidden; } |
| .frame-card::after { |
| content: ''; |
| position: absolute; |
| inset: 0; |
| background: linear-gradient(to top, rgba(44,44,40,0.4), transparent 50%); |
| opacity: 0; |
| transition: opacity 0.4s ease; |
| } |
| .frame-card:hover::after { opacity: 1; } |
| .frame-card .overlay-content { |
| position: absolute; |
| bottom: 0; |
| left: 0; |
| right: 0; |
| padding: 1.5rem; |
| z-index: 2; |
| transform: translateY(10px); |
| opacity: 0; |
| transition: all 0.4s ease; |
| } |
| .frame-card:hover .overlay-content { transform: translateY(0); opacity: 1; } |
| |
| |
| .nav-blur { backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px); } |
| |
| |
| @keyframes marquee { |
| 0% { transform: translateX(0); } |
| 100% { transform: translateX(-50%); } |
| } |
| .marquee-track { animation: marquee 30s linear infinite; } |
| .marquee-track:hover { animation-play-state: paused; } |
| |
| |
| .mobile-menu { transform: translateX(100%); transition: transform 0.4s cubic-bezier(0.16, 1, 0.3, 1); } |
| .mobile-menu.open { transform: translateX(0); } |
| |
| |
| .product-item img { transition: transform 0.6s cubic-bezier(0.16, 1, 0.3, 1); } |
| .product-item:hover img { transform: scale(1.05); } |
| |
| |
| ::selection { background: #C4B89A; color: #2C2C28; } |
| |
| |
| .cursor-dot { |
| width: 8px; height: 8px; |
| background: #2C2C28; |
| border-radius: 50%; |
| position: fixed; |
| pointer-events: none; |
| z-index: 9999; |
| transition: transform 0.15s ease; |
| mix-blend-mode: difference; |
| background: white; |
| } |
| |
| |
| .tab-btn.active { color: #2C2C28; border-color: #2C2C28; } |
| .tab-btn { color: #A8A898; border-color: transparent; } |
| |
| |
| .toast { |
| transform: translateY(100px); |
| opacity: 0; |
| transition: all 0.4s cubic-bezier(0.16, 1, 0.3, 1); |
| } |
| .toast.show { |
| transform: translateY(0); |
| opacity: 1; |
| } |
| </style> |
| </head> |
| <body class="overflow-x-hidden"> |
|
|
| |
| <nav id="navbar" class="fixed top-0 left-0 right-0 z-50 nav-blur bg-neutral-50/80 transition-all duration-300"> |
| <div class="max-w-7xl mx-auto px-6 lg:px-8"> |
| <div class="flex items-center justify-between h-16 lg:h-20"> |
| |
| <a href="#" class="flex items-center gap-2 group"> |
| <div class="w-8 h-8 border-2 border-charcoal flex items-center justify-center group-hover:bg-charcoal transition-all duration-300"> |
| <div class="w-3 h-3 border border-charcoal group-hover:border-white transition-all duration-300"></div> |
| </div> |
| <span class="font-display text-xl font-semibold tracking-tight">neutralframes</span> |
| </a> |
|
|
| |
| <div class="hidden md:flex items-center gap-8"> |
| <a href="#collections" class="text-sm font-medium text-neutral-600 hover:text-charcoal transition-colors duration-200">Collections</a> |
| <a href="#frames" class="text-sm font-medium text-neutral-600 hover:text-charcoal transition-colors duration-200">Frames</a> |
| <a href="#about" class="text-sm font-medium text-neutral-600 hover:text-charcoal transition-colors duration-200">About</a> |
| <a href="#journal" class="text-sm font-medium text-neutral-600 hover:text-charcoal transition-colors duration-200">Journal</a> |
| </div> |
|
|
| |
| <div class="flex items-center gap-4"> |
| <button class="hidden md:flex items-center gap-2 text-sm font-medium text-neutral-600 hover:text-charcoal transition-colors" id="searchBtn"> |
| <i data-lucide="search" class="w-4 h-4"></i> |
| </button> |
| <button class="hidden md:flex items-center gap-2 text-sm font-medium text-neutral-600 hover:text-charcoal transition-colors relative" id="cartBtn"> |
| <i data-lucide="shopping-bag" class="w-4 h-4"></i> |
| <span class="absolute -top-1.5 -right-1.5 w-4 h-4 bg-charcoal text-white text-[10px] flex items-center justify-center rounded-full" id="cartCount">0</span> |
| </button> |
| <button class="md:hidden" id="menuToggle"> |
| <i data-lucide="menu" class="w-5 h-5"></i> |
| </button> |
| </div> |
| </div> |
| </div> |
| </nav> |
|
|
| |
| <div class="mobile-menu fixed inset-0 z-50 bg-neutral-50" id="mobileMenu"> |
| <div class="flex items-center justify-between px-6 h-16"> |
| <a href="#" class="flex items-center gap-2"> |
| <div class="w-8 h-8 border-2 border-charcoal flex items-center justify-center"> |
| <div class="w-3 h-3 border border-charcoal"></div> |
| </div> |
| <span class="font-display text-xl font-semibold tracking-tight">neutralframes</span> |
| </a> |
| <button id="menuClose"> |
| <i data-lucide="x" class="w-5 h-5"></i> |
| </button> |
| </div> |
| <div class="flex flex-col items-center justify-center h-[calc(100%-4rem)] gap-8"> |
| <a href="#collections" class="font-display text-3xl font-medium text-charcoal mobile-link">Collections</a> |
| <a href="#frames" class="font-display text-3xl font-medium text-charcoal mobile-link">Frames</a> |
| <a href="#about" class="font-display text-3xl font-medium text-charcoal mobile-link">About</a> |
| <a href="#journal" class="font-display text-3xl font-medium text-charcoal mobile-link">Journal</a> |
| <button class="mt-4 px-8 py-3 bg-charcoal text-white text-sm font-medium rounded-none hover:bg-neutral-800 transition-colors"> |
| Shop Now |
| </button> |
| </div> |
| </div> |
|
|
| |
| <div id="searchModal" class="fixed inset-0 z-50 bg-neutral-50/95 nav-blur hidden items-center justify-center"> |
| <div class="w-full max-w-2xl px-6"> |
| <div class="flex items-center justify-between mb-8"> |
| <span class="text-sm text-neutral-400 uppercase tracking-widest">Search</span> |
| <button id="searchClose"><i data-lucide="x" class="w-5 h-5"></i></button> |
| </div> |
| <input type="text" placeholder="What are you looking for?" class="w-full text-3xl md:text-5xl font-display bg-transparent border-b-2 border-charcoal pb-4 outline-none placeholder:text-neutral-300" id="searchInput"> |
| <div class="mt-8"> |
| <p class="text-sm text-neutral-400 uppercase tracking-widest mb-4">Popular Searches</p> |
| <div class="flex flex-wrap gap-3"> |
| <span class="px-4 py-2 border border-neutral-200 text-sm text-neutral-600 cursor-pointer hover:bg-charcoal hover:text-white hover:border-charcoal transition-all">Oak Frames</span> |
| <span class="px-4 py-2 border border-neutral-200 text-sm text-neutral-600 cursor-pointer hover:bg-charcoal hover:text-white hover:border-charcoal transition-all">Minimal Poster</span> |
| <span class="px-4 py-2 border border-neutral-200 text-sm text-neutral-600 cursor-pointer hover:bg-charcoal hover:text-white hover:border-charcoal transition-all">Black Metal</span> |
| <span class="px-4 py-2 border border-neutral-200 text-sm text-neutral-600 cursor-pointer hover:bg-charcoal hover:text-white hover:border-charcoal transition-all">Gallery Wall</span> |
| <span class="px-4 py-2 border border-neutral-200 text-sm text-neutral-600 cursor-pointer hover:bg-charcoal hover:text-white hover:border-charcoal transition-all">Floating Frame</span> |
| </div> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <section class="min-h-screen flex items-center pt-20"> |
| <div class="max-w-7xl mx-auto px-6 lg:px-8 w-full"> |
| <div class="grid lg:grid-cols-2 gap-12 lg:gap-20 items-center"> |
| |
| <div class="order-2 lg:order-1"> |
| <div class="animate-fade-in-up"> |
| <p class="text-sm uppercase tracking-[0.3em] text-neutral-500 mb-6">Framing since 2018</p> |
| </div> |
| <h1 class="font-display text-5xl md:text-6xl lg:text-7xl xl:text-8xl font-medium leading-[0.95] mb-8 animate-fade-in-up delay-100"> |
| Frames<br> |
| <span class="italic text-neutral-400">for living</span><br> |
| spaces |
| </h1> |
| <p class="text-lg text-neutral-500 leading-relaxed max-w-md mb-10 animate-fade-in-up delay-200"> |
| Handcrafted frames designed to complement your art. Minimal, timeless, and made to last a lifetime. |
| </p> |
| <div class="flex flex-wrap gap-4 animate-fade-in-up delay-300"> |
| <a href="#collections" class="group inline-flex items-center gap-3 px-8 py-4 bg-charcoal text-white text-sm font-medium hover:bg-neutral-700 transition-all duration-300"> |
| Shop Collections |
| <i data-lucide="arrow-right" class="w-4 h-4 group-hover:translate-x-1 transition-transform duration-300"></i> |
| </a> |
| <a href="#about" class="inline-flex items-center gap-3 px-8 py-4 border border-charcoal text-charcoal text-sm font-medium hover:bg-charcoal hover:text-white transition-all duration-300"> |
| Our Story |
| </a> |
| </div> |
|
|
| |
| <div class="flex gap-12 mt-16 animate-fade-in-up delay-400"> |
| <div> |
| <p class="font-display text-3xl font-semibold">12k+</p> |
| <p class="text-sm text-neutral-400 mt-1">Happy Customers</p> |
| </div> |
| <div> |
| <p class="font-display text-3xl font-semibold">50+</p> |
| <p class="text-sm text-neutral-400 mt-1">Frame Styles</p> |
| </div> |
| <div> |
| <p class="font-display text-3xl font-semibold">4.9</p> |
| <p class="text-sm text-neutral-400 mt-1">Average Rating</p> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div class="order-1 lg:order-2 animate-fade-in delay-200"> |
| <div class="relative"> |
| <div class="absolute -top-6 -left-6 w-full h-full border-2 border-sand/40"></div> |
| <img src="http://static.photos/minimal/640x360/42" alt="Minimal frame display" class="w-full aspect-[4/5] object-cover relative z-10"> |
| <div class="absolute -bottom-4 -right-4 bg-cream px-6 py-4 z-20"> |
| <p class="font-display text-sm italic">"Less is more"</p> |
| </div> |
| </div> |
| </div> |
| </div> |
| </div> |
| </section> |
|
|
| |
| <section class="py-12 border-y border-neutral-200 overflow-hidden bg-white"> |
| <div class="flex whitespace-nowrap"> |
| <div class="marquee-track flex items-center gap-8"> |
| <span class="font-display text-2xl text-neutral-300">Oak Collection</span> |
| <span class="text-sand">◆</span> |
| <span class="font-display text-2xl text-neutral-300">Black Metal Series</span> |
| <span class="text-sand">◆</span> |
| <span class="font-display text-2xl text-neutral-300">White Minimal</span> |
| <span class="text-sand">◆</span> |
| <span class="font-display text-2xl text-neutral-300">Walnut Frames</span> |
| <span class="text-sand">◆</span> |
| <span class="font-display text-2xl text-neutral-300">Gallery Sets</span> |
| <span class="text-sand">◆</span> |
| <span class="font-display text-2xl text-neutral-300">Floating Frames</span> |
| <span class="text-sand">◆</span> |
| <span class="font-display text-2xl text-neutral-300">Oak Collection</span> |
| <span class="text-sand">◆</span> |
| <span class="font-display text-2xl text-neutral-300">Black Metal Series</span> |
| <span class="text-sand">◆</span> |
| <span class="font-display text-2xl text-neutral-300">White Minimal</span> |
| <span class="text-sand">◆</span> |
| <span class="font-display text-2xl text-neutral-300">Walnut Frames</span> |
| <span class="text-sand">◆</span> |
| <span class="font-display text-2xl text-neutral-300">Gallery Sets</span> |
| <span class="text-sand">◆</span> |
| <span class="font-display text-2xl text-neutral-300">Floating Frames</span> |
| <span class="text-sand">◆</span> |
| </div> |
| </div> |
| </section> |
|
|
| |
| <section id="collections" class="py-24 lg:py-32"> |
| <div class="max-w-7xl mx-auto px-6 lg:px-8"> |
| <div class="flex flex-col md:flex-row md:items-end justify-between mb-16 reveal"> |
| <div> |
| <p class="text-sm uppercase tracking-[0.3em] text-neutral-400 mb-4">Curated</p> |
| <h2 class="font-display text-4xl md:text-5xl lg:text-6xl font-medium">Collections</h2> |
| </div> |
| <a href="#" class="group inline-flex items-center gap-2 text-sm font-medium text-neutral-500 hover:text-charcoal mt-4 md:mt-0 transition-colors"> |
| View All |
| <i data-lucide="arrow-right" class="w-4 h-4 group-hover:translate-x-1 transition-transform duration-300"></i> |
| </a> |
| </div> |
|
|
| |
| <div class="grid md:grid-cols-3 gap-4 lg:gap-6"> |
| <div class="frame-card md:col-span-2 md:row-span-2 group cursor-pointer reveal"> |
| <img src="http://static.photos/nature/640x360/15" alt="Oak Collection" class="w-full h-full object-cover min-h-[400px] md:min-h-full"> |
| <div class="overlay-content"> |
| <p class="text-white/70 text-sm uppercase tracking-widest mb-1">18 Styles</p> |
| <h3 class="font-display text-2xl text-white font-medium">Oak Collection</h3> |
| </div> |
| </div> |
| <div class="frame-card group cursor-pointer reveal"> |
| <img src="http://static.photos/minimal/320x240/22" alt="Black Metal" class="w-full h-full object-cover min-h-[200px]"> |
| <div class="overlay-content"> |
| <p class="text-white/70 text-sm uppercase tracking-widest mb-1">12 Styles</p> |
| <h3 class="font-display text-xl text-white font-medium">Black Metal</h3> |
| </div> |
| </div> |
| <div class="frame-card group cursor-pointer reveal"> |
| <img src="http://static.photos/white/320x240/88" alt="White Minimal" class="w-full h-full object-cover min-h-[200px]"> |
| <div class="overlay-content"> |
| <p class="text-white/70 text-sm uppercase tracking-widest mb-1">8 Styles</p> |
| <h3 class="font-display text-xl text-white font-medium">White Minimal</h3> |
| </div> |
| </div> |
| </div> |
| </div> |
| </section> |
|
|
| |
| <section id="frames" class="py-24 lg:py-32 bg-white"> |
| <div class="max-w-7xl mx-auto px-6 lg:px-8"> |
| <div class="text-center mb-16 reveal"> |
| <p class="text-sm uppercase tracking-[0.3em] text-neutral-400 mb-4">Handcrafted</p> |
| <h2 class="font-display text-4xl md:text-5xl lg:text-6xl font-medium">Best Sellers</h2> |
| </div> |
|
|
| |
| <div class="flex justify-center gap-4 mb-12 reveal"> |
| <button class="tab-btn active text-sm font-medium border-b-2 pb-2 px-2 transition-all duration-200" data-filter="all">All</button> |
| <button class="tab-btn text-sm font-medium border-b-2 pb-2 px-2 transition-all duration-200" data-filter="wood">Wood</button> |
| <button class="tab-btn text-sm font-medium border-b-2 pb-2 px-2 transition-all duration-200" data-filter="metal">Metal</button> |
| <button class="tab-btn text-sm font-medium border-b-2 pb-2 px-2 transition-all duration-200" data-filter="float">Float</button> |
| </div> |
|
|
| |
| <div class="grid grid-cols-2 lg:grid-cols-4 gap-4 lg:gap-6" id="productGrid"> |
| |
| </div> |
| </div> |
| </section> |
|
|
| |
| <section class="py-24 lg:py-32 bg-charcoal text-white"> |
| <div class="max-w-7xl mx-auto px-6 lg:px-8"> |
| <div class="text-center mb-20 reveal"> |
| <p class="text-sm uppercase tracking-[0.3em] text-neutral-400 mb-4">Why Neutralframes</p> |
| <h2 class="font-display text-4xl md:text-5xl lg:text-6xl font-medium">Built on<br><span class="italic text-neutral-400">principles</span></h2> |
| </div> |
|
|
| <div class="grid md:grid-cols-2 lg:grid-cols-4 gap-8 lg:gap-12"> |
| <div class="reveal"> |
| <div class="w-12 h-12 border border-neutral-500 flex items-center justify-center mb-6"> |
| <i data-lucide="tree-pine" class="w-5 h-5 text-sand"></i> |
| </div> |
| <h3 class="font-display text-xl font-medium mb-3">Sustainable Wood</h3> |
| <p class="text-neutral-400 text-sm leading-relaxed">All our wooden frames are crafted from FSC-certified sustainable forests. Quality that cares.</p> |
| </div> |
| <div class="reveal"> |
| <div class="w-12 h-12 border border-neutral-500 flex items-center justify-center mb-6"> |
| <i data-lucide="hand" class="w-5 h-5 text-sand"></i> |
| </div> |
| <h3 class="font-display text-xl font-medium mb-3">Handcrafted</h3> |
| <p class="text-neutral-400 text-sm leading-relaxed">Each frame is meticulously assembled by skilled artisans who take pride in their craft.</p> |
| </div> |
| <div class="reveal"> |
| <div class="w-12 h-12 border border-neutral-500 flex items-center justify-center mb-6"> |
| <i data-lucide="shield-check" class="w-5 h-5 text-sand"></i> |
| </div> |
| <h3 class="font-display text-xl font-medium mb-3">UV Protection</h3> |
| <p class="text-neutral-400 text-sm leading-relaxed">Premium acrylic glazing with 92% UV protection keeps your artwork safe from fading.</p> |
| </div> |
| <div class="reveal"> |
| <div class="w-12 h-12 border border-neutral-500 flex items-center justify-center mb-6"> |
| <i data-lucide="package" class="w-5 h-5 text-sand"></i> |
| </div> |
| <h3 class="font-display text-xl font-medium mb-3">Safe Shipping</h3> |
| <p class="text-neutral-400 text-sm leading-relaxed">Custom packaging ensures your frames arrive in perfect condition. Free returns within 30 days.</p> |
| </div> |
| </div> |
| </div> |
| </section> |
|
|
| |
| <section id="about" class="py-24 lg:py-32"> |
| <div class="max-w-7xl mx-auto px-6 lg:px-8"> |
| <div class="grid lg:grid-cols-2 gap-16 items-center"> |
| <div class="reveal"> |
| <div class="grid grid-cols-2 gap-4"> |
| <img src="http://static.photos/craft/320x240/55" alt="Crafting process" class="w-full object-cover aspect-square"> |
| <img src="http://static.photos/indoor/320x240/33" alt="Workshop" class="w-full object-cover aspect-square mt-8"> |
| </div> |
| </div> |
| <div class="reveal"> |
| <p class="text-sm uppercase tracking-[0.3em] text-neutral-400 mb-6">Our Story</p> |
| <h2 class="font-display text-4xl md:text-5xl font-medium mb-8 leading-tight"> |
| Framing is<br><span class="italic text-neutral-400">an art form</span> |
| </h2> |
| <p class="text-neutral-500 leading-relaxed mb-6"> |
| Founded in 2018 in a small workshop in Copenhagen, Neutralframes started with a simple idea: frames should disappear into the space, letting the art speak for itself. |
| </p> |
| <p class="text-neutral-500 leading-relaxed mb-10"> |
| Today, we continue that tradition — creating minimal, high-quality frames that complement without competing. Every joint, every edge, every finish is considered with the same care an artist gives their work. |
| </p> |
| <a href="#" class="group inline-flex items-center gap-3 text-sm font-medium border-b-2 border-charcoal pb-1 hover:border-sand transition-colors duration-300"> |
| Read Our Full Story |
| <i data-lucide="arrow-right" class="w-4 h-4 group-hover:translate-x-1 transition-transform duration-300"></i> |
| </a> |
| </div> |
| </div> |
| </div> |
| </section> |
|
|
| |
| <section class="py-24 lg:py-32 bg-cream"> |
| <div class="max-w-7xl mx-auto px-6 lg:px-8"> |
| <div class="text-center mb-16 reveal"> |
| <p class="text-sm uppercase tracking-[0.3em] text-neutral-400 mb-4">Inspiration</p> |
| <h2 class="font-display text-4xl md:text-5xl lg:text-6xl font-medium">Gallery Walls</h2> |
| <p class="text-neutral-500 mt-4 max-w-lg mx-auto">Curated arrangements to transform any wall into a personal gallery.</p> |
| </div> |
|
|
| |
| <div class="grid grid-cols-2 md:grid-cols-4 gap-3 lg:gap-4 reveal"> |
| <div class="col-span-2 row-span-2"> |
| <img src="http://static.photos/indoor/640x360/77" alt="Gallery wall" class="w-full h-full object-cover"> |
| </div> |
| <div> |
| <img src="http://static.photos/minimal/320x240/11" alt="Wall detail" class="w-full h-full object-cover"> |
| </div> |
| <div> |
| <img src="http://static.photos/white/320x240/44" alt="Wall detail" class="w-full h-full object-cover"> |
| </div> |
| <div> |
| <img src="http://static.photos/workspace/320x240/66" alt="Wall detail" class="w-full h-full object-cover"> |
| </div> |
| <div> |
| <img src="http://static.photos/vintage/320x240/99" alt="Wall detail" class="w-full h-full object-cover"> |
| </div> |
| </div> |
| </div> |
| </section> |
|
|
| |
| <section class="py-24 lg:py-32"> |
| <div class="max-w-7xl mx-auto px-6 lg:px-8"> |
| <div class="text-center mb-16 reveal"> |
| <p class="text-sm uppercase tracking-[0.3em] text-neutral-400 mb-4">Testimonials</p> |
| <h2 class="font-display text-4xl md:text-5xl lg:text-6xl font-medium">What people<br><span class="italic text-neutral-400">are saying</span></h2> |
| </div> |
|
|
| <div class="grid md:grid-cols-3 gap-8" id="testimonialGrid"> |
| |
| </div> |
| </div> |
| </section> |
|
|
| |
| <section id="journal" class="py-24 lg:py-32 bg-white"> |
| <div class="max-w-7xl mx-auto px-6 lg:px-8"> |
| <div class="flex flex-col md:flex-row md:items-end justify-between mb-16 reveal"> |
| <div> |
| <p class="text-sm uppercase tracking-[0.3em] text-neutral-400 mb-4">Journal</p> |
| <h2 class="font-display text-4xl md:text-5xl lg:text-6xl font-medium">Latest Stories</h2> |
| </div> |
| <a href="#" class="group inline-flex items-center gap-2 text-sm font-medium text-neutral-500 hover:text-charcoal mt-4 md:mt-0 transition-colors"> |
| All Articles |
| <i data-lucide="arrow-right" class="w-4 h-4 group-hover:translate-x-1 transition-transform duration-300"></i> |
| </a> |
| </div> |
|
|
| <div class="grid md:grid-cols-3 gap-8" id="journalGrid"> |
| |
| </div> |
| </div> |
| </section> |
|
|
| |
| <section class="py-24 lg:py-32 bg-charcoal text-white"> |
| <div class="max-w-2xl mx-auto px-6 lg:px-8 text-center"> |
| <div class="reveal"> |
| <p class="text-sm uppercase tracking-[0.3em] text-neutral-400 mb-6">Stay Updated</p> |
| <h2 class="font-display text-3xl md:text-4xl lg:text-5xl font-medium mb-6">Join the <span class="italic text-sand">frame lovers</span></h2> |
| <p class="text-neutral-400 mb-10">Get early access to new collections, framing tips, and exclusive offers. No spam, unsubscribe anytime.</p> |
| <form id="newsletterForm" class="flex flex-col sm:flex-row gap-3"> |
| <input type="email" placeholder="Your email address" required class="flex-1 px-6 py-4 bg-neutral-800 border border-neutral-600 text-white placeholder:text-neutral-500 outline-none focus:border-sand transition-colors text-sm" id="emailInput"> |
| <button type="submit" class="px-8 py-4 bg-sand text-charcoal text-sm font-medium hover:bg-warm transition-colors duration-300 whitespace-nowrap"> |
| Subscribe |
| </button> |
| </form> |
| <p class="text-xs text-neutral-500 mt-4">By subscribing you agree to our Privacy Policy</p> |
| </div> |
| </div> |
| </section> |
|
|
| |
| <footer class="py-20 bg-neutral-900 text-white"> |
| <div class="max-w-7xl mx-auto px-6 lg:px-8"> |
| <div class="grid grid-cols-2 md:grid-cols-4 gap-10 mb-16"> |
| <div class="col-span-2 md:col-span-1"> |
| <a href="#" class="flex items-center gap-2 mb-6"> |
| <div class="w-8 h-8 border-2 border-sand flex items-center justify-center"> |
| <div class="w-3 h-3 border border-sand"></div> |
| </div> |
| <span class="font-display text-lg font-semibold">neutralframes</span> |
| </a> |
| <p class="text-sm text-neutral-400 leading-relaxed">Minimal frames for modern living. Handcrafted with care in Copenhagen.</p> |
| </div> |
| <div> |
| <h4 class="text-sm font-medium uppercase tracking-wider mb-6">Shop</h4> |
| <ul class="space-y-3"> |
| <li><a href="#" class="text-sm text-neutral-400 hover:text-white transition-colors">All Frames</a></li> |
| <li><a href="#" class="text-sm text-neutral-400 hover:text-white transition-colors">Oak Collection</a></li> |
| <li><a href="#" class="text-sm text-neutral-400 hover:text-white transition-colors">Black Metal</a></li> |
| <li><a href="#" class="text-sm text-neutral-400 hover:text-white transition-colors">White Minimal</a></li> |
| <li><a href="#" class="text-sm text-neutral-400 hover:text-white transition-colors">Gallery Sets</a></li> |
| </ul> |
| </div> |
| <div> |
| <h4 class="text-sm font-medium uppercase tracking-wider mb-6">Company</h4> |
| <ul class="space-y-3"> |
| <li><a href="#" class="text-sm text-neutral-400 hover:text-white transition-colors">About Us</a></li> |
| <li><a href="#" class="text-sm text-neutral-400 hover:text-white transition-colors">Journal</a></li> |
| <li><a href="#" class="text-sm text-neutral-400 hover:text-white transition-colors">Careers</a></li> |
| <li><a href="#" class="text-sm text-neutral-400 hover:text-white transition-colors">Press</a></li> |
| </ul> |
| </div> |
| <div> |
| <h4 class="text-sm font-medium uppercase tracking-wider mb-6">Support</h4> |
| <ul class="space-y-3"> |
| <li><a href="#" class="text-sm text-neutral-400 hover:text-white transition-colors">Help Center</a></li> |
| <li><a href="#" class="text-sm text-neutral-400 hover:text-white transition-colors">Shipping Info</a></li> |
| <li><a href="#" class="text-sm text-neutral-400 hover:text-white transition-colors">Returns</a></li> |
| <li><a href="#" class="text-sm text-neutral-400 hover:text-white transition-colors">Size Guide</a></li> |
| <li><a href="#" class="text-sm text-neutral-400 hover:text-white transition-colors">Contact</a></li> |
| </ul> |
| </div> |
| </div> |
|
|
| <div class="flex flex-col md:flex-row items-center justify-between pt-8 border-t border-neutral-700"> |
| <p class="text-xs text-neutral-500">© 2024 Neutralframes. All rights reserved.</p> |
| <div class="flex gap-6 mt-4 md:mt-0"> |
| <a href="#" class="text-neutral-500 hover:text-white transition-colors"><i data-lucide="instagram" class="w-4 h-4"></i></a> |
| <a href="#" class="text-neutral-500 hover:text-white transition-colors"><i data-lucide="twitter" class="w-4 h-4"></i></a> |
| <a href="#" class="text-neutral-500 hover:text-white transition-colors"><i data-lucide="facebook" class="w-4 h-4"></i></a> |
| <a href="#" class="text-neutral-500 hover:text-white transition-colors"><i data-lucide="linkedin" class="w-4 h-4"></i></a> |
| </div> |
| </div> |
| </div> |
| </footer> |
|
|
| |
| <div id="toast" class="toast fixed bottom-6 right-6 z-50 bg-charcoal text-white px-6 py-4 flex items-center gap-3 shadow-lg"> |
| <i data-lucide="check-circle" class="w-5 h-5 text-sand"></i> |
| <span class="text-sm" id="toastMessage">Item added to cart</span> |
| </div> |
|
|
| <script src="https://unpkg.com/lucide@latest"></script> |
| <script> |
| |
| const products = [ |
| { id: 1, name: 'Oak Thin Frame', price: 49, category: 'wood', image: 'http://static.photos/nature/320x240/10', sizes: ['A4', 'A3', 'A2'] }, |
| { id: 2, name: 'Black Metal Frame', price: 59, category: 'metal', image: 'http://static.photos/black/320x240/20', sizes: ['A4', 'A3', 'A2'] }, |
| { id: 3, name: 'White Float Frame', price: 69, category: 'float', image: 'http://static.photos/white/320x240/30', sizes: ['A4', 'A3'] }, |
| { id: 4, name: 'Walnut Classic', price: 55, category: 'wood', image: 'http://static.photos/vintage/320x240/40', sizes: ['A4', 'A3', 'A2'] }, |
| { id: 5, name: 'Brass Minimal', price: 79, category: 'metal', image: 'http://static.photos/gold/320x240/50', sizes: ['A3', 'A2', 'A1'] }, |
| { id: 6, name: 'Natural Oak Float', price: 65, category: 'float', image: 'http://static.photos/nature/320x240/60', sizes: ['A4', 'A3'] }, |
| { id: 7, name: 'Matte Black', price: 52, category: 'metal', image: 'http://static.photos/black/320x240/70', sizes: ['A4', 'A3', 'A2'] }, |
| { id: 8, name: 'Ash Wood Frame', price: 58, category: 'wood', image: 'http://static.photos/nature/320x240/80', sizes: ['A4', 'A3', 'A2'] }, |
| ]; |
| |
| const testimonials = [ |
| { name: 'Sarah M.', location: 'London', text: 'The quality is exceptional. The oak frame perfectly complements my print without overwhelming it. Exactly what I was looking for.', rating: 5 }, |
| { name: 'Thomas K.', location: 'Berlin', text: 'I\'ve ordered 6 frames now and each one has been perfect. The floating frames give such a clean, modern look to my gallery wall.', rating: 5 }, |
| { name: 'Emily R.', location: 'New York', text: 'Beautiful craftsmanship and fast shipping. The black metal frame is sleek and minimal. My art has never looked better.', rating: 5 }, |
| ]; |
| |
| const journalEntries = [ |
| { title: 'How to Create the Perfect Gallery Wall', date: 'Dec 12, 2024', category: 'Guide', image: 'http://static.photos/indoor/320x240/90', readTime: '5 min read' }, |
| { title: 'Choosing the Right Frame for Your Art', date: 'Nov 28, 2024', category: 'Tips', image: 'http://static.photos/minimal/320x240/85', readTime: '4 min read' }, |
| { title: 'Sustainable Framing: Our Commitment', date: 'Nov 15, 2024', category: 'Story', image: 'http://static.photos/nature/320x240/75', readTime: '6 min read' }, |
| ]; |
| |
| |
| let cart = []; |
| |
| |
| function renderProducts(filter = 'all') { |
| const grid = document.getElementById('productGrid'); |
| const filtered = filter === 'all' ? products : products.filter(p => p.category === filter); |
| |
| grid.innerHTML = filtered.map((product, i) => ` |
| <div class="product-item group reveal visible" style="animation-delay: ${i * 0.05}s"> |
| <div class="relative overflow-hidden bg-neutral-100 mb-4"> |
| <img src="${product.image}" alt="${product.name}" class="w-full aspect-[3/4] object-cover"> |
| <button onclick="addToCart(${product.id})" class="absolute bottom-0 left-0 right-0 bg-charcoal text-white text-sm font-medium py-3 translate-y-full group-hover:translate-y-0 transition-transform duration-300 flex items-center justify-center gap-2"> |
| <i data-lucide="shopping-bag" class="w-4 h-4"></i> |
| Add to Cart |
| </button> |
| </div> |
| <h3 class="text-sm font-medium mb-1">${product.name}</h3> |
| <p class="text-sm text-neutral-400">From $${product.price}</p> |
| </div> |
| `).join(''); |
| |
| lucide.createIcons(); |
| } |
| |
| |
| function renderTestimonials() { |
| const grid = document.getElementById('testimonialGrid'); |
| grid.innerHTML = testimonials.map((t, i) => ` |
| <div class="p-8 bg-neutral-50 reveal"> |
| <div class="flex gap-1 mb-4"> |
| ${Array(t.rating).fill('<i data-lucide="star" class="w-4 h-4 fill-sand text-sand"></i>').join('')} |
| </div> |
| <p class="text-neutral-600 leading-relaxed mb-6 text-sm">"${t.text}"</p> |
| <div> |
| <p class="font-medium text-sm">${t.name}</p> |
| <p class="text-xs text-neutral-400">${t.location}</p> |
| </div> |
| </div> |
| `).join(''); |
| lucide.createIcons(); |
| } |
| |
| |
| function renderJournal() { |
| const grid = document.getElementById('journalGrid'); |
| grid.innerHTML = journalEntries.map((j, i) => ` |
| <a href="#" class="group reveal"> |
| <div class="overflow-hidden mb-4"> |
| <img src="${j.image}" alt="${j.title}" class="w-full aspect-[4/3] object-cover group-hover:scale-105 transition-transform duration-500"> |
| </div> |
| <div class="flex items-center gap-3 mb-3"> |
| <span class="text-xs uppercase tracking-widest text-neutral-400">${j.category}</span> |
| <span class="text-xs text-neutral-300">·</span> |
| <span class="text-xs text-neutral-400">${j.readTime}</span> |
| </div> |
| <h3 class="font-display text-lg font-medium group-hover:text-neutral-500 transition-colors">${j.title}</h3> |
| <p class="text-xs text-neutral-400 mt-2">${j.date}</p> |
| </a> |
| `).join(''); |
| } |
| |
| |
| function addToCart(productId) { |
| const product = products.find(p => p.id === productId); |
| if (product) { |
| cart.push(product); |
| document.getElementById('cartCount').textContent = cart.length; |
| showToast(`${product.name} added to cart`); |
| } |
| } |
| |
| |
| function showToast(message) { |
| const toast = document.getElementById('toast'); |
| const toastMsg = document.getElementById('toastMessage'); |
| toastMsg.textContent = message; |
| toast.classList.add('show'); |
| setTimeout(() => toast.classList.remove('show'), 3000); |
| } |
| |
| |
| document.querySelectorAll('.tab-btn').forEach(btn => { |
| btn.addEventListener('click', () => { |
| document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active')); |
| btn.classList.add('active'); |
| renderProducts(btn.dataset.filter); |
| }); |
| }); |
| |
| |
| document.getElementById('menuToggle').addEventListener('click', () => { |
| document.getElementById('mobileMenu').classList.add('open'); |
| document.body.style.overflow = 'hidden'; |
| }); |
| document.getElementById('menuClose').addEventListener('click', () => { |
| document.getElementById('mobileMenu').classList.remove('open'); |
| document.body.style.overflow = ''; |
| }); |
| document.querySelectorAll('.mobile-link').forEach(link => { |
| link.addEventListener('click', () => { |
| document.getElementById('mobileMenu').classList.remove('open'); |
| document.body.style.overflow = ''; |
| }); |
| }); |
| |
| |
| document.getElementById('searchBtn').addEventListener('click', () => { |
| const modal = document.getElementById('searchModal'); |
| modal.classList.remove('hidden'); |
| modal.classList.add('flex'); |
| setTimeout(() => document.getElementById('searchInput').focus(), 100); |
| }); |
| document.getElementById('searchClose').addEventListener('click', () => { |
| const modal = document.getElementById('searchModal'); |
| modal.classList.add('hidden'); |
| modal.classList.remove('flex'); |
| }); |
| |
| |
| document.getElementById('newsletterForm').addEventListener('submit', (e) => { |
| e.preventDefault(); |
| const email = document.getElementById('emailInput').value; |
| if (email) { |
| showToast('Welcome! You\'ve been subscribed 🎉'); |
| document.getElementById('emailInput').value = ''; |
| } |
| }); |
| |
| |
| const observer = new IntersectionObserver((entries) => { |
| entries.forEach(entry => { |
| if (entry.isIntersecting) { |
| entry.target.classList.add('visible'); |
| } |
| }); |
| }, { threshold: 0.1, rootMargin: '0px 0px -50px 0px' }); |
| |
| function observeReveals() { |
| document.querySelectorAll('.reveal').forEach(el => observer.observe(el)); |
| } |
| |
| |
| let lastScroll = 0; |
| window.addEventListener('scroll', () => { |
| const navbar = document.getElementById('navbar'); |
| const currentScroll = window.pageYOffset; |
| |
| if (currentScroll > 100) { |
| navbar.style.borderBottom = '1px solid rgba(0,0,0,0.05)'; |
| } else { |
| navbar.style.borderBottom = 'none'; |
| } |
| |
| if (currentScroll > lastScroll && currentScroll > 200) { |
| navbar.style.transform = 'translateY(-100%)'; |
| } else { |
| navbar.style.transform = 'translateY(0)'; |
| } |
| navbar.style.transition = 'transform 0.3s ease, border-bottom 0.3s ease'; |
| lastScroll = currentScroll; |
| }); |
| |
| |
| document.querySelectorAll('a[href^="#"]').forEach(anchor => { |
| anchor.addEventListener('click', (e) => { |
| e.preventDefault(); |
| const target = document.querySelector(anchor.getAttribute('href')); |
| if (target) { |
| target.scrollIntoView({ behavior: 'smooth', block: 'start' }); |
| } |
| }); |
| }); |
| |
| |
| document.addEventListener('DOMContentLoaded', () => { |
| lucide.createIcons(); |
| renderProducts(); |
| renderTestimonials(); |
| renderJournal(); |
| observeReveals(); |
| }); |
| </script> |
| <script src="https://deepsite.hf.co/deepsite-badge.js"></script> |
| </body> |
| </html> |