// Agora shared components: nav, footer, product tile, route line, badges. const { useState, useEffect, useRef, useMemo } = React; // ---------- ICONS (Lucide-style, inline SVG, 1.5 stroke) ---------- const Icon = ({ name, size = 18, stroke = 1.5, ...rest }) => { const props = { width: size, height: size, viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: stroke, strokeLinecap: 'round', strokeLinejoin: 'round', ...rest }; switch (name) { case 'search': return ; case 'heart': return ; case 'heart-fill': return ; case 'bag': return ; case 'user': return ; case 'globe': return ; case 'chevron-down': return ; case 'chevron-left': return ; case 'chevron-right': return ; case 'arrow-right': return ; case 'plus': return ; case 'minus': return ; case 'x': return ; case 'check': return ; case 'filter': return ; case 'sliders': return ; case 'shield': return ; case 'sparkles': return ; case 'plane': return ; case 'gavel': return ; case 'box': return ; case 'tag': return ; case 'star': return ; case 'star-fill': return ; case 'eye': return ; case 'clock': return ; case 'map-pin': return ; case 'truck': return ; case 'menu': return ; case 'grid': return ; case 'list': return ; case 'external': return ; case 'send': return ; case 'message': return ; case 'edit': return ; case 'trash': return ; case 'cards': return ; case 'spark': return ; case 'circle-check': return ; case 'pause': return ; case 'arrow-up-right': return ; default: return null; } }; // ---------- LUXURY PRODUCT TILE (CSS placeholder w/ subtle gradient + hardware glint) ---------- const ProductTile = ({ item, square = false, showWatermark = true, children, style }) => { const p = item?.palette || { a: '#E8E4DD', b: '#BDB7AC', hw: '#9A9590', label: '—' }; // Subtle vignette + radial highlight + hardware metallic dot const bg = { backgroundColor: p.b, backgroundImage: [ `radial-gradient(ellipse at 30% 25%, ${p.a} 0%, ${p.a} 18%, transparent 55%)`, `radial-gradient(ellipse at 70% 80%, ${p.b} 10%, transparent 70%)`, `linear-gradient(135deg, ${p.a} 0%, ${p.b} 100%)`, ].join(', '), }; return (
{/* Hardware glint */}
{/* Stitching arc — purely suggestive */}
{showWatermark && item?.brand && (
{item.brand.split(' ')[0].toLowerCase()}
)} {children}
); }; // ---------- PRODUCT CARD (catalog grid) ---------- const ProductCard = ({ item, onClick, dense = false }) => { const [hover, setHover] = useState(false); const [liked, setLiked] = useState(false); return (
setHover(true)} onMouseLeave={()=>setHover(false)} onClick={onClick} style={{ cursor:'pointer', borderRadius: 0, border:0, borderTop:'1px solid var(--ap-border)' }} >
{item.new && New} {item.acceptOffers && Offers}
{ e.stopPropagation(); setLiked(!liked); }} title={liked ? 'Saved' : 'Save'} >
 Auth {item.city}
{item.brand}
€{item.eur.toLocaleString()}
{item.title}
{item.cond}
); }; // ---------- ROUTE LINE (Tokyo → Berlin) ---------- const RouteLine = ({ from, to = 'Berlin', compact = false }) => (
{from} {to}
); // ---------- AGORA WORDMARK ---------- const Wordmark = ({ size = 22, compact = false }) => (
{/* Brand mark — circle with serif "a" */}
a
{!compact && ( agora )}
); // ---------- TOP NAV ---------- const TopNav = ({ route, setRoute, onSearch, watchlistCount = 0, cartCount = 0 }) => { const [searchOpen, setSearchOpen] = useState(false); const isActive = (r) => route?.name === r; return ( <> {/* Thin promo strip — quiet trust promises, Apple-style */}
{/* LEFT: wordmark + search */}
setRoute({ name:'home' })} style={{ cursor:'pointer' }}>
{/* CENTER: categories */}
{/* RIGHT: utility icons */}
setRoute({ name:'watchlist' })} style={{ cursor:'pointer', position:'relative' }}> {watchlistCount > 0 && {watchlistCount}}
LK
{/* Sub-nav: categories — clean, centered, just categories */}
{window.AG_DATA.categories.map(c => ( setRoute({ name:'browse', cat: c.id })} style={{ cursor:'pointer', fontSize: 10, color: route?.name==='browse' && route?.cat===c.id ? 'var(--ag-ink)':'var(--ap-fg-muted)' }}> {c.label} ))}
{searchOpen && setSearchOpen(false)} setRoute={(r)=>{ setRoute(r); setSearchOpen(false); }}/>} ); }; // ---------- PROMO STRIP (above main nav) ---------- const PROMO_MESSAGES = [ { icon: 'shield', text: 'Every piece authenticated at one of three hubs. Free, always.' }, { icon: 'truck', text: 'DDP shipping included — customs & duties pre-cleared to your door.' }, { icon: 'box', text: '14-day returns from delivery. Buyer protection on every transaction.' }, { icon: 'globe', text: '1,284 sellers across Tokyo, Paris, Milan, Seoul, New York & more.' }, ]; const PromoStrip = () => { const [idx, setIdx] = useState(0); useEffect(() => { const t = setInterval(() => setIdx(i => (i + 1) % PROMO_MESSAGES.length), 5000); return () => clearInterval(t); }, []); return (
{PROMO_MESSAGES.map((m, i) => (
))}
{PROMO_MESSAGES.map((_, i) => ( ))}
); }; // ---------- COMMAND PALETTE (Cmd+K search-led nav) ---------- const CommandPalette = ({ onClose, setRoute }) => { const [q, setQ] = useState(''); const inputRef = useRef(); useEffect(()=>{ inputRef.current?.focus(); const esc = (e)=>{ if (e.key==='Escape') onClose(); }; window.addEventListener('keydown', esc); return ()=>window.removeEventListener('keydown', esc); }, []); const data = window.AG_DATA; const ql = q.toLowerCase(); const items = data.items.filter(it => !q || it.brand.toLowerCase().includes(ql) || it.title.toLowerCase().includes(ql)).slice(0, 8); const brands = data.brands.filter(b => !q || b.toLowerCase().includes(ql)).slice(0, 6); return (
e.stopPropagation()} style={{ width: 720, background:'#fff', borderRadius: 4, boxShadow:'var(--ap-shadow-modal)', overflow:'hidden' }} className="ag-fade-in">
setQ(e.target.value)} placeholder="Search brands, items, sellers…" style={{ flex:1, border:0, outline:'none', fontSize: 16, fontFamily:'var(--ag-font-sans)' }}/> Esc
Items
{items.map(it => (
setRoute({ name:'product', id: it.id })} className="ag-flex ag-gap-3" style={{ padding:'10px 22px', cursor:'pointer', alignItems:'center' }} onMouseEnter={(e)=>e.currentTarget.style.background='var(--ap-bg-2)'} onMouseLeave={(e)=>e.currentTarget.style.background='transparent'}>
{it.brand}
{it.title}
€{it.eur.toLocaleString()}
))}
Brands
{brands.map(b => setRoute({ name:'browse', cat:'all', brand: b })}>{b})}
); }; // ---------- FOOTER ---------- const Footer = ({ setRoute }) => ( ); // ---------- EXPORTS ---------- Object.assign(window, { Icon, ProductTile, ProductCard, RouteLine, Wordmark, TopNav, Footer, CommandPalette });