// Zen Interiors — shared components: Nav, Footer, primitives, Lightbox
const { useState, useEffect, useRef, useMemo, useCallback } = React;
// Tiny SVG marks ---------------------------------------------------------------
function ZenMark({ size = 28, color = 'currentColor' }) {
// Custom enso-style mark: a single broken ring with a low horizon line.
// Not derived from the client's facebook avatar — this is a placeholder until
// the official SVG logo is supplied (see CLAUDE-DESIGN §5, §10).
return (
);
}
function ArrowRight({ size = 12 }) {
return (
);
}
function ArrowDown({ size = 12 }) {
return (
);
}
function Plus({ size = 12 }) {
return (
);
}
function Close({ size = 14 }) {
return (
);
}
// Navigation -----------------------------------------------------------------
function Nav({ route, navigate, locale, setLocale, openEnquiry }) {
const [scrolled, setScrolled] = useState(false);
const [open, setOpen] = useState(false);
useEffect(() => {
const onScroll = () => setScrolled(window.scrollY > 12);
onScroll();
window.addEventListener('scroll', onScroll, { passive: true });
return () => window.removeEventListener('scroll', onScroll);
}, []);
const items = [
{ label: 'Projects', to: '/projects' },
{ label: 'Sectors', to: '/sectors' },
{ label: 'Services', to: '/services' },
{ label: 'Studio', to: '/about' },
{ label: 'Awards', to: '/awards' },
{ label: 'Journal', to: '/journal' },
{ label: 'Contact', to: '/contact' },
];
const isActive = (to) => route === to || (to !== '/' && route.startsWith(to));
return (
{ e.preventDefault(); navigate('/'); }}
style={{ display: 'inline-flex', alignItems: 'center', gap: 12 }}>
ZEN interiors
{open && (
)}
);
}
function LocaleSwitcher({ locale, setLocale }) {
const locales = ['EN', 'AR', 'RU', 'ZH'];
return (
{locales.map((l, i) => (
{i > 0 && ·}
))}
);
}
// Footer ---------------------------------------------------------------------
function Footer({ navigate, openEnquiry }) {
const c = window.ZEN_CONTACT;
return (
);
}
// Enquiry drawer -------------------------------------------------------------
function EnquiryDrawer({ open, onClose }) {
const [submitted, setSubmitted] = useState(false);
useEffect(() => {
if (open) { document.body.style.overflow = 'hidden'; }
else { document.body.style.overflow = ''; setSubmitted(false); }
}, [open]);
if (!open) return null;
return (
);
}
function Field({ label, required, children }) {
return (
);
}
const inputStyle = {
fontFamily: 'var(--font-sans)',
fontSize: 15,
padding: '12px 14px',
background: 'var(--paper)',
border: '1px solid var(--line-strong)',
color: 'var(--ink)',
outline: 'none',
borderRadius: 0,
};
// Lightbox -------------------------------------------------------------------
function Lightbox({ images, index, onClose, onPrev, onNext }) {
useEffect(() => {
const onKey = (e) => {
if (e.key === 'Escape') onClose();
if (e.key === 'ArrowLeft') onPrev();
if (e.key === 'ArrowRight') onNext();
};
window.addEventListener('keydown', onKey);
document.body.style.overflow = 'hidden';
return () => { window.removeEventListener('keydown', onKey); document.body.style.overflow = ''; };
}, [onClose, onPrev, onNext]);
return (

e.stopPropagation()} />
{String(index + 1).padStart(2, '0')} / {String(images.length).padStart(2, '0')} · PHOTO CREDIT TBC
);
}
// Section block --------------------------------------------------------------
function SectionHeader({ eyebrow, title, italicTail, kicker, link }) {
return (
{eyebrow}
{title}
{italicTail && <> {italicTail}>}
{kicker &&
{kicker}
}
{link}
);
}
// Project card ---------------------------------------------------------------
function ProjectCard({ project, navigate, big }) {
const [hover, setHover] = useState(false);
return (
{ e.preventDefault(); navigate(`/projects/${project.slug}`); }}
onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}
style={{ display: 'block', cursor: 'pointer' }}>
{project.name}
{project.sector} · {project.location}
);
}
// Make these available across babel scripts ---------------------------------
Object.assign(window, {
ZenMark, ArrowRight, ArrowDown, Plus, Close,
Nav, Footer, EnquiryDrawer, Lightbox, SectionHeader, ProjectCard,
Field, inputStyle,
});