/* --- Panos Melekkis · core components --- */ /* React global. Exports to window for cross-script sharing. */ const { useState, useEffect, useRef, useMemo, useCallback } = React; const D = window.PM_DATA; /* ----------------------------- helpers ----------------------------- */ function Arrow({ d = "right" }) { // simple chevron-like arrow inside circles const rotate = { right: 0, "up-right": -45, down: 90, up: -90 }[d] || 0; return ( ); } function useReveal() { // adds 'is-in' to .fi children when scrolled into view useEffect(() => { const els = document.querySelectorAll(".fi:not(.is-in)"); const io = new IntersectionObserver( (entries) => { entries.forEach((e) => { if (e.isIntersecting) { e.target.classList.add("is-in"); io.unobserve(e.target); } }); }, { threshold: 0.12 } ); els.forEach((el) => io.observe(el)); return () => io.disconnect(); }, []); } /* ----------------------------- Nav ----------------------------- */ function Nav({ onBook, currency, setCurrency, navMode }) { // navMode: 'over' (transparent on hero), 'light' (light bg), 'solid' (dark when scrolled past hero) const cls = "nav " + (navMode === "light" ? "is-light" : navMode === "solid" ? "is-solid" : ""); return (
Collections Engagement & Bridal Bespoke
Panos Melekkis
Ateliers
); } function CurrencyChips({ currency, setCurrency, compact = false }) { return (
{D.currencies.map((c) => ( ))}
); } /* ----------------------------- Hero ----------------------------- */ function Hero({ sceneIx, setSceneIx, onBook, onExplore, signature }) { // auto-advance unless user manually picks const [autoPlay, setAutoPlay] = useState(true); useEffect(() => { if (!autoPlay) return; const id = setInterval(() => { setSceneIx((i) => (i + 1) % D.scenes.length); }, 6800); return () => clearInterval(id); }, [autoPlay, setSceneIx]); const scene = D.scenes[sceneIx]; return (
{D.scenes.map((s, i) => (
))}
PM · est. 2008 · Dubai d3 · Limassol

{scene.titleA}{scene.titleEm}{scene.titleB} {signature && ( — Panos Melekkis )}

{scene.sub}

{/* scene rail */}
{D.scenes.map((s, i) => ( ))}
{String(sceneIx + 1).padStart(2, "0")} / {String(D.scenes.length).padStart(2, "0")} Scene · {scene.label} Photography — house archive
); } /* ----------------------------- Credibility strip ----------------------------- */ function CredibilityStrip() { return (
{D.credibility.map((c, i) => (
— {c.eyebrow} {c.label} {c.meta}
))}
); } /* ----------------------------- Collections grid ----------------------------- */ function CollectionsSection({ onOpen, density }) { return (
— The Collections

Eight design stories, cast in 18k.

Each collection is a separate design idea — emeralds on red velvet, black diamonds in pavé, an architectural arch repeated as a chain. Click any collection to read its story and see live prices from the shop.

{D.collections.map((c, i) => ( onOpen(c.id)} /> ))}
); } function CollectionCard({ c, ix, onOpen }) { const span = c.span || 1; const cls = "coll-card " + (span === 2 ? "card-2" : ""); return ( ); } /* ----------------------------- Designer teaser ----------------------------- */ function DesignerSection() { return (
The designer at work
Designed by P. Melekkis GIA · 2008
— The Designer

A gemologist in the room.

Panos graduated from the Gemological Institute of America in Florence in 2008, and opened his first boutique in Limassol the same year. A second design studio followed in Dubai Design District — where each Empire bangle and Quantum Love pendant is now drawn, cast and finished by the designer himself.

No middlemen. No marketing agency. Every centre stone is hand-selected by Panos, and the same gemologist who graded it is the one who designs the setting it sits in.

{D.designerStats.map((s, i) => (
{s.num}
{s.lab}
))}
Read the story
); } /* ----------------------------- Bespoke band ----------------------------- */ function BespokeSection({ onBook }) { return (
A bespoke commission in progress
— Bespoke & Redesign

Custom-made jewellery in an era of mass production.

One-to-one design, gemstone selection by appointment, and the option to redesign heirloom pieces using their original stones. Three steps, two ateliers, one designer.

{D.bespokeSteps.map((s) => (
— Step {s.n}
{s.name}

{s.body}

))}
Bridal journey
); } /* ----------------------------- Bridal section ----------------------------- */ function BridalSection({ onBook, currency }) { // Pull the Love & Engagement collection for inline pricing const ring = D.collections.find((c) => c.id === "love-engagement"); const lowest = ring.priceFrom; return (
— Engagement & Bridal

A single ring. Then everything around it.

Engagement rings priced live in the shop. Wedding bands matched to the centre stone. A bridal consultation is the same person, twice — the gemologist who chooses the centre stone is the designer who sets it.

From {window.PM_fmtPrice(lowest, currency)} · live multi-currency from the shop

— Step One
The Stone

GIA-certified centre diamonds sourced from Antwerp and Surat. Coloured stones — sapphires, emeralds, paraibas — chosen for cut over weight.

— Step Two
The Ring

LR140-series settings as a starting point, or a fully bespoke ring with two hand-drawn revisions included. 18k yellow, rose or white gold.

— Step Three
The Pair

Wedding bands made to match the engagement ring profile. Initials, dates and symbols hand-engraved at the Limassol atelier.

); } /* ----------------------------- Press strip ----------------------------- */ function PressStrip() { return (
— As featured in
{D.press.quote}
{D.press.src}
); } /* ----------------------------- Ateliers ----------------------------- */ function AtelierSection() { return (
— Visit · Two Ateliers

In Dubai d3, and on Makarios Avenue.

The Dubai design studio is by appointment — quiet, private, and a single ring at a time. The Limassol boutique is open during working hours, with the full archive on display.

{D.ateliers.map((a) => ( ))}
); } function AtelierCard({ a }) { return (
— Atelier · {a.city.slice(0, 2).toUpperCase()}
{a.city}
PM
{a.addr}
{a.hours.map((row, i) => ( {row[0]} {row[1]} ))}

{a.note}

Call {a.tel} Email atelier
); } function FauxMap({ city }) { // simple stylized map. No external embeds (offline-safe). // city used to vary lines/labels return ( {/* a few "streets" */} {city.toUpperCase()} N ↑ ); } /* ----------------------------- Footer ----------------------------- */ function Footer({ onBook }) { return ( ); } /* ----------------------------- WhatsApp FAB ----------------------------- */ function WaFab() { return ( CY ); } /* ----------------------------- Mobile bottom bar ----------------------------- */ function MobileBar({ onBook }) { return (
Call · Dubai
); } /* ----------------------------- exports ----------------------------- */ Object.assign(window, { Nav, Hero, CredibilityStrip, CollectionsSection, DesignerSection, BespokeSection, BridalSection, PressStrip, AtelierSection, Footer, WaFab, MobileBar, Arrow, CurrencyChips, useReveal, });