// XBD Collective — page views const { useState: useStateP, useEffect: useEffectP, useRef: useRefP, useMemo: useMemoP } = React; // ============================================================ // HOME // ============================================================ function HomeView({ t, ar, onNavigate, onOpenProject }) { const projects = window.XBD.projects; const featured = projects.filter(p => p.featured); const F = window.XBD.firm; const [heroIdx, setHeroIdx] = useStateP(0); // Rotating hero useEffectP(() => { const id = setInterval(() => setHeroIdx(i => (i + 1) % featured.length), 6500); return () => clearInterval(id); }, [featured.length]); const heroProj = featured[heroIdx]; return (
{/* ===== HERO — full bleed rotating, with side rail ===== */}
{featured.map((p, i) => (
{p.name}
))} {/* Side rail */}
— Project
{String(heroIdx + 1).padStart(2, "0")}
of {String(featured.length).padStart(2, "0")}
SCROLL
{/* Hero content */}
{t.home.eyebrow}

{t.home.h1Pre}
{t.home.h1Post}

{t.home.sub}
{/* Hero caption (current project) — generous breathing room */}
Now showing
{featured.map((_, i) => (
{/* ===== PRESS / AWARDS MARQUEE ===== */}
{[...Array(2)].map((_, dup) => ( 90+ awards Arabian Property Awards International Property Awards Commercial Interior Design SBID Love That Design Identity Design Awards Rethinking The Future Luxhabitat CovetHouse ))}
{/* ===== INTRO STATEMENT ===== */}
— A note on practice
§ 01

We are an integrated studio — architects, interior designers, landscape, FF&E and project coordinators under one roof in Dubai Design District. From a single residence to a hotel — the same hand, from first sketch to last specification.

{/* ===== SELECTED WORK ===== */}
{/* Asymmetric editorial grid */}
{/* ===== PROCESS BAND ===== */}
{[ { n: "01", t: "Concept", body: "Brief, site analysis, references, and a first design intent — established before fees escalate.", k: "Weeks 1–4" }, { n: "02", t: "Design", body: "Architecture, interiors and landscape developed in parallel. MEP and structure coordinated under one roof.", k: "Months 2–6" }, { n: "03", t: "Coordination", body: "FF&E specification, technical drawings, vendor and contractor coordination. The design intent is locked.", k: "Months 5–10" }, { n: "04", t: "Delivery", body: "On-site review, snagging, and handover. We protect the design intent through to the final fixture.", k: "Months 8–14" } ].map((s, i) => (
{s.n}
{s.t}
{s.body}
{s.k}
))}
{/* ===== SECTORS STRIP ===== */}
{[ { id: "residential", img: featured[0].cover, label: "Residential", n: 7 }, { id: "hospitality", img: "assets/kata-02.webp", label: "Hospitality", n: 4 }, { id: "commercial", img: "assets/taws-01.webp", label: "Commercial", n: 1 }, { id: "retail", img: "assets/juice-01.webp", label: "Retail", n: 1 }, { id: "mixed-use", img: "assets/althuraya-aerial.webp", label: "Mixed-use", n: 1 } ].map((s, i) => ( ))}
{/* ===== FOUNDER PULL QUOTE ===== */}
Ellen Søhoel
Ellen Søhoel
Founder, 2015
"

Architecture, interiors, landscape — they are the same problem at different scales. We started XBD because that is how we wanted to work. Ten years in, that conviction hasn't changed.

— Ellen Søhoel, on founding XBD · attributed
{/* ===== CREDIBILITY ===== */}
Clients (per press, attributed)
{["Emaar","DAMAC","Almal","Rixos","St Regis"].map(c => (
{c}
))}
{/* ===== MATERIALS / PROCESS IMAGE ===== */}
§ 06 · Materials & process

We design the joint, not just the room.

Travertine, oak, plaster, bronze — specified, sourced, supervised on site. Our material library lives in d3, two minutes from the studio floor.
{["Travertine","Smoked oak","Lime plaster","Patinated brass"].map(m => (
Specimen
{m}
))}
{/* ===== CTA BAND ===== */}
Start a project

A villa, a hotel, or a city block —
tell us what you're building.

); } // ============================================================ // PROJECTS INDEX // ============================================================ function ProjectsView({ t, ar, onOpenProject, initialFilter }) { const projects = window.XBD.projects; const [sector, setSector] = useStateP(initialFilter?.sector || "all"); const [scope, setScope] = useStateP("all"); const [view, setView] = useStateP("grid"); // grid | index useEffectP(() => { if (initialFilter?.sector) setSector(initialFilter.sector); }, [initialFilter]); const filtered = useMemoP(() => projects.filter(p => { if (sector !== "all" && p.sector !== sector) return false; if (scope !== "all" && !p.scope.includes(scope)) return false; return true; }), [sector, scope]); return (
{/* Header */}
{t.projects.title}

{filtered.length} {filtered.length === 1 ? "project" : "projects"}

{/* Filters */}
{t.projects.filterSector}:
setSector("all")} /> {window.XBD.sectors.map(s => ( setSector(s.id)} /> ))}
{t.projects.filterScope}:
setScope("all")} /> {window.XBD.scopes.map(s => ( setScope(s.id)} /> ))}
{(sector !== "all" || scope !== "all") && ( )}
{/* Grid */} {view === "grid" ? (
{filtered.map((p, i) => ( ))}
{filtered.length === 0 && (
No projects match this filter.
)}
) : (
Project
Location
Sector
Year
Scope
{filtered.map((p, i) => ( ))}
)}
); } // ============================================================ // CASE STUDY // ============================================================ function CaseStudyView({ t, ar, project, onNavigate, onOpenProject, layout = "editorial" }) { const all = window.XBD.projects; const idx = all.findIndex(p => p.slug === project.slug); const next = all[(idx + 1) % all.length]; const related = all.filter(p => p.sector === project.sector && p.slug !== project.slug).slice(0, 3); const sectorLabel = (window.XBD.sectors.find(s => s.id === project.sector) || {}).label; return (
{/* HERO */}
{project.name}
{sectorLabel} · {project.scope.join(" · ")}

{project.name}

{project.location}
{project.year} · {project.scope.join(" · ")} {project.visualisation ? "· VISUALISATION" : ""}
{/* META STRIP */}
{[ ["Location", project.location], ["Sector", sectorLabel], ["Scope", project.scope.join(" · ")], ["Year", project.year], ["Photography", project.credit] ].map(([k, v]) => (
{k}
{v}
))}
{/* BRIEF + CONCEPT */}
01 · {t.caseStudy.brief}
{project.brief}
{project.concept && (
02 · {t.caseStudy.concept}
{project.concept}
)}
{/* HERO IMAGE — LARGE */} {project.gallery[1] && (
{project.name}
)} {/* MATERIALS */} {project.materials && (
03 · {t.caseStudy.materials}
    {project.materials.map((m, i) => (
  • M{String(i+1).padStart(2,"0")} {m}
  • ))}
)} {/* GALLERY */}
04 · {t.caseStudy.gallery}
{project.gallery.map((src, i) => { // Editorial asymmetric layout const layouts = [ { col: "1 / 5", ratio: "16 / 10" }, { col: "5 / 7", ratio: "4 / 5" }, { col: "1 / 3", ratio: "4 / 5" }, { col: "3 / 7", ratio: "16 / 10" }, { col: "1 / 4", ratio: "3 / 4" }, { col: "4 / 7", ratio: "3 / 4" } ]; const L = layouts[i % layouts.length]; return ( {`${project.name} ); })}
{/* OUTCOME */} {project.outcome && (
05 · {t.caseStudy.outcome}
{project.outcome}
)} {/* PROJECT ENQUIRY */}
Enquire about a similar project

Building something like {project.name}?

WhatsApp
Your enquiry will be tagged: {project.name}
{/* RELATED + NEXT */} {related.length > 0 && (
{related.map((p, i) => ( ))}
)} {/* NEXT PROJECT footer */}
onOpenProject(next)}> {next.name}
{t.caseStudy.next}
{next.name}
{next.location} · {next.year} →
); } // ============================================================ // SERVICES // ============================================================ function ServicesView({ t, ar, onNavigate }) { return (
{t.nav.services || "Services"}

Integrated.
End-to-end.

One studio, one team, one accountability. From the first sketch to the last fixture — coordinated under one roof in Dubai Design District.
{window.XBD.services.map((s, i) => (
{String(i+1).padStart(2,"0")}

{s.title}

{s.body}
))}
); } // ============================================================ // STUDIO // ============================================================ function StudioView({ t, ar, onNavigate }) { const F = window.XBD.firm; return (
{t.studio.title}

A studio of {F.staffClaim},
across three cities.

Ellen Søhoel, Founder
Ellen Søhoel
Founder & Creative Director
Portrait © emma stokwielder productions — rights TBC.
{t.studio.about}

XBD was founded in 2015 by Ellen Søhoel, a Norwegian interior architect drawn to Dubai's early promise. What began as a team of two is now 140+ across Dubai, London and Kochi.

10 years in. 90+ awards. Five sectors. Three cities. One conviction: integrated, in-house, end-to-end — from first sketch to last specification.

Press · attributed
Commercial Interior Design · Love That Design · Luxhabitat · Rethinking The Future · SBID
{/* LEADERSHIP */}
{window.XBD.team.map((m, i) => (
{String(i+1).padStart(2,"0")}
Portrait pending
{m.name}
{m.role}
{m.note &&
{m.note}
}
))}
+ 130 designers, architects, coordinators across Dubai, London and Kochi.
{/* AWARDS */}
{window.XBD.awards.map((a, i) => (
{a.year}
{a.name}
{a.issuer}
{a.project}
))}
{/* OFFICES */}
{F.offices.map((o, i) => (
{String(i+1).padStart(2,"0")} · {o.region}
{o.city}
{o.address}
{o.phone}
))}
); } // ============================================================ // CONTACT // ============================================================ function ContactView({ t, ar, prefillProject }) { const F = window.XBD.firm; const [submitted, setSubmitted] = useStateP(false); const [form, setForm] = useStateP({ name: "", email: "", phone: "", company: "", scope: "interior", sector: "residential", budget: "", message: prefillProject ? `Enquiry about a project similar to ${prefillProject}.\n\n` : "" }); function update(k, v) { setForm(f => ({ ...f, [k]: v })); } function submit(e) { e.preventDefault(); setSubmitted(true); } const inputStyle = { width: "100%", background: "transparent", border: 0, borderBottom: "1px solid var(--hairline)", padding: "14px 0", color: "var(--fg)", fontFamily: "var(--sans)", fontSize: 16, outline: "none", transition: "border-color 240ms" }; const labelStyle = { display: "block", marginBottom: 4, fontFamily: "var(--mono)", fontSize: 11, letterSpacing: "0.14em", color: "var(--fg-mute)", textTransform: "uppercase" }; return (
{t.contact.title}

Start a project.

{/* Form */}
{t.contact.form}
{submitted ? (
Thank you.
Your enquiry is logged and routed to the studio. We respond within two working days — usually with a request for a short call to understand the brief, the site, and your timeline.
) : (
update("name", e.target.value)} onFocus={e => e.target.style.borderColor = "var(--accent)"} onBlur={e => e.target.style.borderColor = "var(--hairline)"}/>
update("email", e.target.value)} onFocus={e => e.target.style.borderColor = "var(--accent)"} onBlur={e => e.target.style.borderColor = "var(--hairline)"}/>
update("phone", e.target.value)} onFocus={e => e.target.style.borderColor = "var(--accent)"} onBlur={e => e.target.style.borderColor = "var(--hairline)"}/>
update("company", e.target.value)} onFocus={e => e.target.style.borderColor = "var(--accent)"} onBlur={e => e.target.style.borderColor = "var(--hairline)"}/>
{window.XBD.sectors.map(s => ( update("sector", s.id)}/> ))}
{window.XBD.scopes.map(s => ( update("scope", s.id)}/> ))}