Initial commit of project structure
This commit is contained in:
73
Pottery-website/pages/Atelier.tsx
Normal file
73
Pottery-website/pages/Atelier.tsx
Normal file
@@ -0,0 +1,73 @@
|
||||
import React from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
|
||||
const Atelier: React.FC = () => {
|
||||
return (
|
||||
<div className="bg-stone-50 dark:bg-stone-900 min-h-screen pt-32 pb-24">
|
||||
<div className="max-w-[1920px] mx-auto px-6 md:px-12">
|
||||
{/* Intro */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-12 gap-12 mb-32 items-center">
|
||||
<div className="md:col-span-5 md:col-start-2">
|
||||
<motion.span
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ duration: 1 }}
|
||||
className="block text-xs uppercase tracking-[0.3em] text-stone-400 mb-6"
|
||||
>
|
||||
The Studio
|
||||
</motion.span>
|
||||
<motion.h1
|
||||
initial={{ y: 30, opacity: 0 }}
|
||||
animate={{ y: 0, opacity: 1 }}
|
||||
transition={{ delay: 0.2, duration: 0.8 }}
|
||||
className="font-display text-5xl md:text-7xl lg:text-8xl leading-none text-text-main dark:text-white mb-8"
|
||||
>
|
||||
Formed by<br />Hand & Fire
|
||||
</motion.h1>
|
||||
<motion.p
|
||||
initial={{ y: 30, opacity: 0 }}
|
||||
animate={{ y: 0, opacity: 1 }}
|
||||
transition={{ delay: 0.4, duration: 0.8 }}
|
||||
className="font-body text-lg font-light text-stone-500 leading-relaxed max-w-lg"
|
||||
>
|
||||
Our atelier is a sanctuary of slow creation. Located in the quiet hills, we practice the ancient art of wheel-throwing, honoring the raw beauty of natural clay.
|
||||
</motion.p>
|
||||
</div>
|
||||
<div className="md:col-span-12 lg:col-span-6 relative h-[600px] lg:h-[800px] w-full">
|
||||
<motion.div
|
||||
initial={{ clipPath: 'inset(100% 0 0 0)' }}
|
||||
animate={{ clipPath: 'inset(0% 0 0 0)' }}
|
||||
transition={{ delay: 0.2, duration: 1.5, ease: "easeOut" }}
|
||||
className="h-full w-full"
|
||||
>
|
||||
<img src="/pottery-studio.png" alt="Atelier Studio" className="w-full h-full object-cover" />
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Philosophy Section */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 border-t border-stone-200 dark:border-stone-800 pt-24">
|
||||
{[
|
||||
{ title: "Material", text: "We work exclusively with locally sourced stoneware clay bodies, rich in iron and character." },
|
||||
{ title: "Process", text: "Every piece is wheel-thrown, trimmed, and glazed by hand, ensuring no two objects are identical." },
|
||||
{ title: "Function", text: "Designed to be used and loved. Our ceramics are durable, food-safe, and meant for daily rituals." }
|
||||
].map((item, idx) => (
|
||||
<motion.div
|
||||
key={item.title}
|
||||
initial={{ y: 20, opacity: 0 }}
|
||||
whileInView={{ y: 0, opacity: 1 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ delay: idx * 0.2, duration: 0.8 }}
|
||||
className="p-8 hover:bg-white dark:hover:bg-black transition-colors duration-500"
|
||||
>
|
||||
<h3 className="font-display text-2xl mb-4 text-text-main dark:text-white">{item.title}</h3>
|
||||
<p className="font-body font-light text-stone-500 leading-relaxed">{item.text}</p>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Atelier;
|
||||
68
Pottery-website/pages/Collections.tsx
Normal file
68
Pottery-website/pages/Collections.tsx
Normal file
@@ -0,0 +1,68 @@
|
||||
import React from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { COLLECTIONS } from '../constants';
|
||||
|
||||
const Collections: React.FC = () => {
|
||||
return (
|
||||
<>
|
||||
<section className="pt-32 pb-24 px-6 md:px-12 bg-stone-50 dark:bg-stone-900 min-h-screen">
|
||||
<div className="max-w-[1920px] mx-auto">
|
||||
{/* Header */}
|
||||
<div className="mb-24 text-center">
|
||||
<motion.h1
|
||||
initial={{ y: 20, opacity: 0 }}
|
||||
animate={{ y: 0, opacity: 1 }}
|
||||
transition={{ delay: 0.5, duration: 0.8 }}
|
||||
className="font-display text-5xl md:text-7xl font-light mb-6 text-text-main dark:text-white"
|
||||
>
|
||||
Collections
|
||||
</motion.h1>
|
||||
<motion.p
|
||||
initial={{ y: 20, opacity: 0 }}
|
||||
animate={{ y: 0, opacity: 1 }}
|
||||
transition={{ delay: 0.7, duration: 0.8 }}
|
||||
className="font-body text-stone-500 max-w-xl mx-auto text-lg font-light leading-relaxed"
|
||||
>
|
||||
Curated series of functional objects. Each collection explores a distinct form language and glaze palette.
|
||||
</motion.p>
|
||||
</div>
|
||||
|
||||
{/* Grid */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-x-8 gap-y-16">
|
||||
{COLLECTIONS.map((item, index) => (
|
||||
<motion.div
|
||||
key={item.id}
|
||||
initial={{ y: 40, opacity: 0 }}
|
||||
animate={{ y: 0, opacity: 1 }}
|
||||
transition={{ delay: 0.2 + (index * 0.1), duration: 0.8, ease: "easeOut" }}
|
||||
className="group cursor-pointer"
|
||||
>
|
||||
{/* Image Container with Darker Background for Contrast */}
|
||||
<div className={`relative overflow-hidden mb-6 ${item.aspectRatio || 'aspect-[3/4]'} bg-stone-200 dark:bg-stone-800`}>
|
||||
<motion.img
|
||||
src={item.image}
|
||||
alt={item.title}
|
||||
className="w-full h-full object-cover transition-transform duration-700 group-hover:scale-105 relative z-10"
|
||||
whileHover={{ scale: 1.05 }}
|
||||
/>
|
||||
{/* Overlay on hover */}
|
||||
<div className="absolute inset-0 bg-black/0 group-hover:bg-black/10 transition-colors duration-500 z-20 pointer-events-none" />
|
||||
</div>
|
||||
|
||||
<div className="flex justify-between items-end border-b border-stone-200 dark:border-stone-800 pb-4">
|
||||
<div>
|
||||
<span className="text-xs uppercase tracking-widest text-stone-400 mb-1 block">{item.number}</span>
|
||||
<h3 className="font-display text-2xl text-text-main dark:text-white">{item.title}</h3>
|
||||
</div>
|
||||
<span className="material-symbols-outlined opacity-0 -translate-x-4 group-hover:opacity-100 group-hover:translate-x-0 transition-all duration-300 text-stone-400">arrow_forward</span>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Collections;
|
||||
97
Pottery-website/pages/Editorial.tsx
Normal file
97
Pottery-website/pages/Editorial.tsx
Normal file
@@ -0,0 +1,97 @@
|
||||
import React from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { JOURNAL_ENTRIES } from '../constants';
|
||||
|
||||
const Editorial: React.FC = () => {
|
||||
return (
|
||||
<div className="bg-white dark:bg-black min-h-screen pt-32 pb-24">
|
||||
<div className="max-w-[1920px] mx-auto px-6 md:px-12">
|
||||
<div className="text-center mb-24">
|
||||
<motion.span
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
className="font-display text-xs tracking-[0.3em] uppercase mb-4 block text-stone-400"
|
||||
>
|
||||
The Journal
|
||||
</motion.span>
|
||||
<motion.h1
|
||||
initial={{ y: 20, opacity: 0 }}
|
||||
animate={{ y: 0, opacity: 1 }}
|
||||
transition={{ delay: 0.2 }}
|
||||
className="font-display text-6xl md:text-9xl font-light text-text-main dark:text-white"
|
||||
>
|
||||
Editorial
|
||||
</motion.h1>
|
||||
</div>
|
||||
|
||||
{/* Featured Article */}
|
||||
<div className="relative w-full h-[70vh] mb-24 cursor-pointer group overflow-hidden">
|
||||
<motion.img
|
||||
initial={{ scale: 1.1 }}
|
||||
animate={{ scale: 1 }}
|
||||
transition={{ duration: 1.5 }}
|
||||
src={JOURNAL_ENTRIES[0].image}
|
||||
alt="Featured Article"
|
||||
className="w-full h-full object-cover transition-transform duration-[2s] group-hover:scale-105"
|
||||
/>
|
||||
<div className="absolute inset-0 bg-black/20 group-hover:bg-black/40 transition-colors duration-500" />
|
||||
<div className="absolute bottom-0 left-0 p-8 md:p-16 text-white w-full md:w-2/3">
|
||||
<span className="uppercase tracking-widest text-xs border border-white/30 px-3 py-1 mb-6 inline-block backdrop-blur-sm">Featured Story</span>
|
||||
<h2 className="font-display text-4xl md:text-6xl mb-6 leading-tight">{JOURNAL_ENTRIES[0].title}</h2>
|
||||
<p className="font-body text-lg md:text-xl font-light opacity-90 max-w-xl">{JOURNAL_ENTRIES[0].description}</p>
|
||||
<div className="mt-8 flex items-center space-x-2 text-xs uppercase tracking-widest">
|
||||
<span>Read Article</span>
|
||||
<span className="material-symbols-outlined text-sm">arrow_forward</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Article Grid */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-12 gap-y-20 max-w-5xl mx-auto">
|
||||
{JOURNAL_ENTRIES.slice(1).map((entry, idx) => (
|
||||
<motion.div
|
||||
key={entry.id}
|
||||
initial={{ y: 40, opacity: 0 }}
|
||||
whileInView={{ y: 0, opacity: 1 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ delay: idx * 0.2 }}
|
||||
className="group cursor-pointer"
|
||||
>
|
||||
<div className="aspect-[4/3] overflow-hidden mb-8">
|
||||
<img src={entry.image} alt={entry.title} className="w-full h-full object-cover transition-transform duration-700 group-hover:scale-105" />
|
||||
</div>
|
||||
<div className="flex items-center space-x-4 mb-4 text-xs uppercase tracking-widest text-stone-400">
|
||||
<span>{entry.category}</span>
|
||||
<span className="w-1 h-1 bg-stone-300 rounded-full" />
|
||||
<span>{entry.date}</span>
|
||||
</div>
|
||||
<h3 className="font-display text-3xl mb-4 text-text-main dark:text-white group-hover:underline decoration-1 underline-offset-4">{entry.title}</h3>
|
||||
<p className="font-body font-light text-stone-500">{entry.description}</p>
|
||||
</motion.div>
|
||||
))}
|
||||
{/* Dummy extra entry to fill grid */}
|
||||
<motion.div
|
||||
initial={{ y: 40, opacity: 0 }}
|
||||
whileInView={{ y: 0, opacity: 1 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ delay: 0.4 }}
|
||||
className="group cursor-pointer"
|
||||
>
|
||||
<div className="aspect-[4/3] overflow-hidden mb-8 bg-stone-100 dark:bg-stone-800 flex items-center justify-center">
|
||||
<img src="/collection-tableware.png" alt="Archive" className="w-full h-full object-cover opacity-80 transition-transform duration-700 group-hover:scale-105" />
|
||||
</div>
|
||||
<div className="flex items-center space-x-4 mb-4 text-xs uppercase tracking-widest text-stone-400">
|
||||
<span>Archive</span>
|
||||
<span className="w-1 h-1 bg-stone-300 rounded-full" />
|
||||
<span>2023</span>
|
||||
</div>
|
||||
<h3 className="font-display text-3xl mb-4 text-text-main dark:text-white group-hover:underline decoration-1 underline-offset-4">Explore Past Issues</h3>
|
||||
<p className="font-body font-light text-stone-500">Dive into our archive of stories, guides, and studio updates.</p>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Editorial;
|
||||
24
Pottery-website/pages/Home.tsx
Normal file
24
Pottery-website/pages/Home.tsx
Normal file
@@ -0,0 +1,24 @@
|
||||
import React from 'react';
|
||||
import Hero from '../components/Hero';
|
||||
import FeatureSection from '../components/FeatureSection';
|
||||
import HorizontalScrollSection from '../components/HorizontalScrollSection';
|
||||
import Collections from '../components/Collections';
|
||||
import QuoteSection from '../components/QuoteSection';
|
||||
import JournalSection from '../components/JournalSection';
|
||||
import GallerySection from '../components/GallerySection';
|
||||
|
||||
const Home: React.FC = () => {
|
||||
return (
|
||||
<main>
|
||||
<Hero />
|
||||
<FeatureSection />
|
||||
<HorizontalScrollSection />
|
||||
<Collections />
|
||||
<QuoteSection />
|
||||
<JournalSection />
|
||||
<GallerySection />
|
||||
</main>
|
||||
);
|
||||
};
|
||||
|
||||
export default Home;
|
||||
Reference in New Issue
Block a user