// Bishop Design — shared UI primitives
const { useState, useEffect, useRef } = React;
// ---------- Locale ----------
const L = {
en: {
nav: { projects: "Projects", sectors: "Sectors", studio: "Studio", awards: "Awards", contact: "Contact" },
cta: "Start a project",
eyebrow: "Bishop Design — Dubai & Miami, since 2004",
heroLine1: "Revolutionary",
heroLine2: "Design",
heroSub: "International multi-award-winning interior design and architecture studio. Hospitality, residential, commercial and retail — across the region and on a global scale.",
sectors: "Sectors",
sectorIntro: "Five disciplines, one studio.",
work: "Selected Work",
workIntro: "A deeper look at the projects that shaped the studio.",
seeAll: "See all 88 projects",
awards: "Recognition",
awardsIntro: "100+ awards regionally and internationally.",
startBig1: "Start a project",
startBig2: "with the studio.",
startSub: "Tell us about your site, your operator and your brief. We typically respond within two working days.",
},
ar: {
nav: { projects: "المشاريع", sectors: "القطاعات", studio: "الاستوديو", awards: "الجوائز", contact: "تواصل" },
cta: "ابدأ مشروعًا",
eyebrow: "بيشوب ديزاين — دبي وميامي، منذ ٢٠٠٤",
heroLine1: "تصميم",
heroLine2: "ثوري",
heroSub: "استوديو تصميم داخلي وعمارة حائز على جوائز دولية متعددة. الضيافة، السكني، التجاري والتجزئة — في المنطقة وعلى المستوى العالمي.",
sectors: "القطاعات",
sectorIntro: "خمسة تخصصات، استوديو واحد.",
work: "أعمال مختارة",
workIntro: "نظرة أعمق على المشاريع التي شكّلت الاستوديو.",
seeAll: "عرض جميع المشاريع الـ ٨٨",
awards: "تقدير",
awardsIntro: "أكثر من ١٠٠ جائزة إقليمية ودولية.",
startBig1: "ابدأ مشروعًا",
startBig2: "مع الاستوديو.",
startSub: "حدثنا عن موقعك، مشغلك، ومتطلباتك. عادةً ما نرد خلال يومَي عمل.",
},
};
function useLocaleStrings(locale) {
return L[locale] || L.en;
}
// ---------- Logo ----------
function Logo({ onClick, big }) {
return (
{ e.preventDefault(); onClick && onClick(); }} className="logo-mark" style={{ display: "inline-block" }}>
BISHOP
By Paul Bishop
);
}
// ---------- Nav ----------
function Nav({ route, navigate, mode = "auto", locale, setLocale }) {
const [scrolled, setScrolled] = useState(false);
useEffect(() => {
const onScroll = () => setScrolled(window.scrollY > 40);
onScroll();
window.addEventListener("scroll", onScroll, { passive: true });
return () => window.removeEventListener("scroll", onScroll);
}, []);
const t = useLocaleStrings(locale);
const darkOver = mode === "dark";
const dataMode = (darkOver && !scrolled) ? "dark" : "light";
return (
);
}
// ---------- Footer ----------
function Footer({ navigate }) {
return (
);
}
// ---------- Cards ----------
function ProjectCard({ project, ratio = "tall", onClick }) {
return (
{ e.preventDefault(); onClick && onClick(project); }}>
e.stopPropagation()} />