// Castelverdi — Mediterranean pottery atelier const PRODUCTS = [ { id: 'p01', name: 'Caraffa dei Limoni', nameEn: 'Lemon Pitcher', cat: 'Pitchers', price: 780, year: 'Amalfi form', material: 'Hand-painted ceramic, cobalt & lemon', height: '28 cm', edition: 'Edition of 40', desc: 'A tall pitcher in the Amalfitan tradition, cream-glazed and hand-painted with trailing lemon branches. For water, for wine, for olive oil on a long lunch table.' }, { id: 'p02', name: 'Vaso Foglie', nameEn: 'Leaf Vase', cat: 'Vases', price: 920, year: 'Capri form', material: 'Hand-painted ceramic, cobalt leaves', height: '34 cm', edition: 'Edition of 30', desc: 'An elegant vase in the Caprese manner — cobalt foliage drawn freehand across a warm cream ground. Each one slightly different; each one signed on the foot.' }, { id: 'p03', name: 'Ciotola Agrumi', nameEn: 'Citrus Bowl', cat: 'Bowls', price: 340, year: 'Sicilian form', material: 'Hand-painted ceramic', height: '12 cm', edition: 'Open edition', desc: 'A deep footed bowl, painted with a ring of lemons and ultramarine leaves inside. For fruit, for salad, for a spill of ripe tomatoes in August.' }, { id: 'p04', name: 'Brocca Positano', nameEn: 'Positano Jug', cat: 'Pitchers', price: 640, year: 'Costiera form', material: 'Hand-painted ceramic', height: '24 cm', edition: 'Edition of 50', desc: 'A rounder, more informal jug — the one you reach for every morning. Painted with bold cobalt leaves and the occasional yellow fruit.' }, { id: 'p05', name: 'Tazzine (set of IV)', nameEn: 'Espresso Cups, set of four', cat: 'Cups', price: 420, year: 'Neapolitan form', material: 'Hand-painted ceramic', height: '6 cm', edition: 'Open edition', desc: 'Four small espresso cups, each painted a little differently. Cobalt, lemon, terracotta, leaf — one of each. A very small ceremony, four times over.' }, { id: 'p06', name: 'Piatto di Portata', nameEn: 'Serving Platter', cat: 'Plates', price: 560, year: 'Deruta form', material: 'Hand-painted ceramic, large', height: '38 cm', edition: 'Edition of 40', desc: 'A wide platter in the Deruta manner — a full bouquet of lemons and leaves painted to the rim. For aperitivo, antipasti, or hanging on a wall.' }, { id: 'p07', name: 'Anfora Mediterranea', nameEn: 'Mediterranean Amphora', cat: 'Vases', price: 1480, year: 'Etruscan form', material: 'Hand-painted ceramic, large', height: '52 cm', edition: 'Edition of 15', desc: 'A tall, handled amphora — our largest piece. Painted across its body with a continuous garland of citrus. A statement on a garden terrace or entrance hall.' }, { id: 'p08', name: 'Piatto Fondi (VI)', nameEn: 'Pasta Bowls, set of six', cat: 'Plates', price: 680, year: 'Trattoria form', material: 'Hand-painted ceramic, set of 6', height: '6 cm', edition: 'Open edition', desc: 'Six deep bowls in a mixed set — no two the same, all cut from the same cobalt-and-lemon cloth. For a big table, for a proper dinner.' }, { id: 'p09', name: 'Vaso da Fiori', nameEn: 'Flower Vase', cat: 'Vases', price: 480, year: 'Tuscan form', material: 'Hand-painted ceramic', height: '22 cm', edition: 'Open edition', desc: 'A small, simple flower vase — for a single stem of lemon blossom, or a handful of rosemary from the garden.' }, { id: 'p10', name: 'Teiera della Nonna', nameEn: "Grandmother's Teapot", cat: 'Pitchers', price: 540, year: 'Liguria form', material: 'Hand-painted ceramic', height: '18 cm', edition: 'Edition of 40', desc: 'A softly rounded teapot with a confident cobalt spout. Named for the way your grandmother poured, with one hand on the lid.' }, { id: 'p11', name: 'Ciotola Uliveto', nameEn: 'Olive Grove Bowl', cat: 'Bowls', price: 260, year: 'Puglian form', material: 'Hand-painted ceramic, small', height: '9 cm', edition: 'Open edition', desc: 'A small bowl painted with olive branches instead of lemons. Perfect for pitted olives, capers, or almonds at the start of an evening.' }, { id: 'p12', name: 'Servizio Completo (XII)', nameEn: 'Full service, twelve pieces', cat: 'Sets', price: 3200, year: 'Bespoke', material: 'Hand-painted ceramic, full service', height: 'various', edition: 'Edition of 10', desc: 'The complete set — pitcher, platter, six bowls, four cups. Hand-painted over several weeks in a single coordinated pattern. For a wedding, for a house-warming, for the table you always meant to set.' }, ]; const PRODUCT_ICONS = { p01: 'pitcher', p02: 'vase-tall', p03: 'bowl', p04: 'jug', p05: 'cups', p06: 'platter', p07: 'amphora', p08: 'bowls', p09: 'vase-small', p10: 'teapot', p11: 'bowl', p12: 'set', }; const I18N = { en: { nav: { shop: 'Collection', lookbook: 'Lookbook', craft: 'Craft', about: 'Atelier', contact: 'Contact' } }, fr: { nav: { shop: 'Collection', lookbook: 'Lookbook', craft: 'Savoir-Faire', about: 'Atelier', contact: 'Contact' } }, ar: { nav: { shop: 'المجموعة', lookbook: 'المعرض', craft: 'الصنعة', about: 'المرسم', contact: 'تواصل' } }, }; const LOOKBOOK = [ { id: 'l01', title: 'La tavola d\'estate', subtitle: 'A summer table', season: 'Editorial №01', year: 'Estate MMXXVI' }, { id: 'l02', title: 'Una cucina a Positano', subtitle: 'A kitchen in Positano', season: 'Editorial №02', year: 'Primavera MMXXVI' }, { id: 'l03', title: 'Il limoneto', subtitle: 'The lemon grove', season: 'Editorial №03', year: 'Autunno MMXXV' }, ]; function formatMAD(n) { return new Intl.NumberFormat('fr-MA', { style: 'decimal', maximumFractionDigits: 0 }).format(n) + ' DH'; } // --- Hand-painted motifs --- // Lemon sprig const LemonSprig = ({ scale = 1, rotate = 0, style = {} }) => ( {/* Stem */} {/* Leaves */} {/* Lemons */} ); // A single leaf (for decorative scatter) const Leaf = ({ style = {} }) => ( ); // Painted silhouettes — pottery shapes with cobalt leaf + lemon motifs const pottery = { pitcher: ( {/* Body */} {/* Spout */} {/* Handle */} {/* Rim */} {/* Base */} {/* Painted decoration — lemon sprigs */} ), 'vase-tall': ( ), bowl: ( ), jug: ( ), cups: ( {[0,1,2,3].map(i => { const x = 30 + i*56; const fill = ['var(--lemon)','var(--paper)','var(--terracotta)','var(--paper)'][i]; return ( {i !== 0 && i !== 2 && ( )} ); })} ), platter: ( {[0,1,2,3,4,5].map(i => { const a = (i / 6) * Math.PI * 2; const cx = 130 + Math.cos(a) * 70; const cy = 100 + Math.sin(a) * 52; return ( ); })} ), amphora: ( ), bowls: ( {[[50,60,1],[130,60,0],[210,60,1],[50,130,0],[130,130,1],[210,130,0]].map(([cx,cy,hasLemon],i) => ( {hasLemon ? ( ) : ( )} ))} ), 'vase-small': ( ), teapot: ( ), set: ( {/* Pitcher */} {/* Bowl */} {/* Cup */} {/* Plate */} ), }; const Placeholder = ({ icon = 'pitcher', variant = 'default', label, scatter = true }) => { const shape = pottery[icon] || pottery.pitcher; return (
{scatter && ( <>
)}
{React.cloneElement(shape, { style: { width: '100%', height: '100%' } })}
{label && {label}}
); }; // Scroll-reveal — visible-by-default safe function useReveal() { React.useEffect(() => { const els = document.querySelectorAll('.reveal:not(.in)'); if (!els.length || typeof IntersectionObserver === 'undefined') return; let fired = false; const pres = Array.from(els); try { pres.forEach(el => el.classList.add('pre')); const io = new IntersectionObserver((entries) => { fired = true; entries.forEach(e => { if (e.isIntersecting) { e.target.classList.remove('pre'); e.target.classList.add('in'); io.unobserve(e.target); } }); }, { threshold: 0.05, rootMargin: '0px 0px -30px 0px' }); els.forEach(el => io.observe(el)); const fallback = setTimeout(() => { if (!fired) pres.forEach(el => { el.classList.remove('pre'); el.classList.add('in'); }); }, 500); return () => { io.disconnect(); clearTimeout(fallback); }; } catch (err) { pres.forEach(el => { el.classList.remove('pre'); el.classList.add('in'); }); } }); } Object.assign(window, { PRODUCTS, PRODUCT_ICONS, I18N, LOOKBOOK, formatMAD, Placeholder, LemonSprig, Leaf, useReveal });