// pages-projects.jsx — Projects index + case study + sectors hub const { useState: useStateP, useEffect: useEffectP, useMemo: useMemoP } = React; function ProjectsIndex({ navigate, initialFilter }) { const [filter, setFilter] = useStateP(initialFilter || "all"); const [view, setView] = useStateP("grid"); const filtered = useMemoP(() => { if (filter === "all") return PROJECTS; return PROJECTS.filter(p => p.sector === filter); }, [filter]); useEffectP(() => { if (initialFilter) setFilter(initialFilter); }, [initialFilter]); return (
— Index of work · {PROJECTS.length} entries

Projects

Filter by sector. Cards marked Study are concepts or 3D-visualisation work; the rest are delivered turnkey or design-only engagements.
{/* toolbar */}
{SECTORS.map(s => ( ))}
View /
{/* grid */} {view === "grid" && (
{filtered.map((p, i) => (
navigate({ name: "case", id: p.id })}>
{p.studyOnly && (
Study · 3D
)}
{String(i + 1).padStart(2, "0")} —
{p.title}
{p.sector} · {p.year}
{p.location} · {p.area}
))}
)} {/* list */} {view === "list" && (
{filtered.map((p, i) => (
navigate({ name: "case", id: p.id })}>
{String(i + 1).padStart(2, "0")} —
{p.title}
{p.location}
{p.scope}
{p.area}
))}
)}
{/* note bar */}
Editorial note — photographer credit & client release confirmed before each name is published.
); } // ---------- Case study ---------- function CaseStudy({ project, navigate, openLightbox }) { if (!project) return null; const gallery = (CASE_GALLERIES[project.id] || [ project.cover, "media/project-villa-7.webp", "media/project-villa-15.webp", "media/project-dsc-0281-hdr.webp", ]); const nextProject = PROJECTS[(PROJECTS.findIndex(p => p.id === project.id) + 1) % PROJECTS.length]; return (
{/* Case hero */}

{project.title.split(" — ").map((part, i) => ( {i > 0 &&  — } {part} ))}

{project.location}
{project.year}
{project.area}
{project.studyOnly ? "Study · Visualisation" : "Delivered"}
{/* Meta row */}
Sector
{project.sector}
Location
{project.location}
Scope
{project.scope}
Year
{project.year}
Area
{project.area}
{/* Concept */}
◇ — Concept

{project.concept}

Brief: a residence that "felt at rest". The owners — based in London and Dubai — wanted to drop into the apartment after a flight and not feel marketed at. The starting condition was a developer shell with marble that, frankly, fought us. We softened the floor with rugs, quieted the joinery, and let the sky carry the room.

The plan was redrawn lightly — two walls relocated, a fireplace removed — with the architect-of-record. Approvals were processed in parallel so the build sequence held. Renders below were issued before any joinery was cut.

openLightbox(gallery, 0)} style={{ cursor: "pointer", display: "inline-flex", marginTop: 24 }} > Open gallery — {gallery.length} frames
{/* Gallery */}
openLightbox(gallery, 0)} />
openLightbox(gallery, 1)} />
openLightbox(gallery, 2)} />
openLightbox(gallery, 3)} />
openLightbox(gallery, 4)} />
openLightbox(gallery, 0)} />
{/* Materials */}
{MATERIALS.map((m, i) => (

{m.title}

{m.note}

))}
Full BOQ and supplier list issued to client at handover.
{/* Process for this project */}
Process — from brief to handover.} aside="How this particular project ran. One project manager, photoreal renders pre-commitment, in-house approvals." />
{/* Outcome + next */}
◇ — Outcome

Built and handed over in 22 weeks from contract sign-off, including DDA approvals and snagging. Photographer credit on file with the studio.

The owners moved in the following month. A small punch list closed within 14 days. The apartment was used for a private editorial shoot in May 2024, with client and photographer release available on request.

); } // ---------- Sectors hub page ---------- function Sectors({ navigate }) { return (
— Sectors served · 6 hubs

Sectors.

The work is filed by sector — residential and commercial — and by where the studio's craft is most visible. Each hub leads to a filtered project index.

{SECTOR_CARDS.map((s, i) => (
navigate({ name: "projects", filter: s.id })} >
— {String(i + 1).padStart(2, "0")}

{s.label}

{s.count} →
))}
); } window.ProjectsIndex = ProjectsIndex; window.CaseStudy = CaseStudy; window.Sectors = Sectors;