/* LW Design Group — page views */
const { useState: useS, useEffect: useE, useRef: useR, useMemo: useM } = React;
/* ============================================================
HOME
============================================================ */
function HomePage({ go, lang }) {
const t = useT(lang);
const featured = PROJECTS.filter(p => p.featured);
const heroProject = featured[0];
return (
{/* HERO */}
{heroProject.name} · {heroProject.location}
EST. 1999 · Dubai · Hong Kong · São Paulo · Aarhus
Hospitality-led architecture and interior design,
built for owners who want a complete world.
{t.home_lede}
go("projects")}>
{t.cta_view_all} ↗
go("contact")}>
{t.cta_start} ↗
{/* PROPOSITION */}
{t.home_proposition_kicker} / 01
{t.home_proposition}
{DISCIPLINES.map((d, i) => (
))}
{/* FEATURED WORK */}
{/* Editorial layout: big left, two stacked right */}
go("project", { slug: featured[0].slug })} />
{featured.slice(1, 3).map(p => (
go("project", { slug: p.slug })} />
))}
{/* SECTORS strip */}
Sectors / 03
{t.section_sectors}
{SECTORS.map(s => (
go("projects", { sector: s.id })}>
{s.count.toString().padStart(3, "0")}
{s.label}
→
))}
{/* STUDIO image + quote */}
The studio / 04
"Twenty-six years of building hospitality environments has taught us one thing — guests don't remember
a colour, they remember the feeling of being held in a space."
— Jesper Godsk, Founder & CEO (verbatim quote to confirm)
go("studio")}>
About the studio ↗
{/* PRESS strip */}
);
}
function Stat({ n, l }) {
return (
{n}
{l}
);
}
function DisciplineCard({ idx, d }) {
const blurbs = {
interior: "From back-of-house through to the last sconce — the studio's spine.",
architecture: "Established 2003 as LW Architecture. Buildings designed alongside their interiors.",
ffe: "Furniture, fittings and finishes sourced, specified and curated in-house.",
branding: "Spatial branding — the way a venue introduces itself, in light, type and material.",
};
return (
·{idx.toString().padStart(2, "0")}
{d.label}
{blurbs[d.id]}
);
}
/* ============================================================
PROJECTS index (filterable)
============================================================ */
function ProjectsPage({ go, lang, initialFilter }) {
const t = useT(lang);
const [sector, setSector] = useS(initialFilter?.sector || "all");
const [disc, setDisc] = useS(initialFilter?.discipline || "all");
const [sort, setSort] = useS("recent");
const items = useM(() => {
let list = PROJECTS.filter(p =>
(sector === "all" || p.sector === sector) &&
(disc === "all" || p.disciplines.includes(disc))
);
list = list.sort((a, b) => sort === "recent" ? b.year - a.year : a.year - b.year);
return list;
}, [sector, disc, sort]);
return (
The portfolio
Projects.
Sector, discipline, year.
Three hundred plus completed environments since 1999. Below — the work that defines the studio.
Filter by what you're building.
{t.filter_by_sector}
setSector("all")}>{t.filter_all}
{SECTORS.map(s => (
setSector(s.id)}>{s.label}
))}
{t.filter_by_discipline}
setDisc("all")}>All
{DISCIPLINES.map(d => (
setDisc(d.id)}>{d.label}
))}
{items.length} shown
setSort(e.target.value)}>
{t.sort_recent}
{t.sort_oldest}
{items.map((p, i) => (
go("project", { slug: p.slug })} />
))}
{items.length === 0 && (
No projects match — clear a filter.
)}
);
}
function Chip({ active, onClick, children }) {
return (
{children}
);
}
/* ============================================================
PROJECT detail (case study)
============================================================ */
function ProjectPage({ slug, go, lang }) {
const t = useT(lang);
const p = PROJECTS.find(x => x.slug === slug);
const idx = PROJECTS.findIndex(x => x.slug === slug);
const next = PROJECTS[(idx + 1) % PROJECTS.length];
const sector = SECTORS.find(s => s.id === p.sector);
const [lightbox, setLightbox] = useS(null);
useE(() => { window.scrollTo({ top: 0, behavior: "instant" }); }, [slug]);
return (
{/* Hero */}
{/* Title block */}
{sector.label} · {p.year}
{p.name}
{p.subtitle}
DISCIPLINES.find(x => x.id === d)?.label).join(" · ")} />
{/* Narrative — 2-col editorial */}
{p.gallery.length > 1 && (
{p.gallery.slice(1, 3).map((g, i) => (
))}
)}
{/* Gallery */}
{p.gallery.length > 0 && (
{t.case_gallery}
All frames
{p.gallery.map((g, i) => (
setLightbox(g)}>
))}
)}
{/* Next */}
{lightbox && (
setLightbox(null)}>
×
)}
);
}
function CaseSection({ num, label, body, compact }) {
return (
);
}
function MetaRow({ label, value, muted }) {
return (
{label}
{value}
);
}
/* ============================================================
SECTORS overview
============================================================ */
function SectorsPage({ go, lang }) {
const t = useT(lang);
const heroes = {
hospitality: "media/ref-project-bab-al-shams.webp",
fb: "media/ref-project-chic-nonna.webp",
residential: "media/ref-discipline-interior-design.webp",
"mixed-use": "media/ref-project-city-walk.webp",
workplace: "media/ref-studio-25th-02.webp",
wellness: "media/ref-discipline-architecture.webp",
};
return (
The portfolio · by sector
Sectors. Where the work happens.
{SECTORS.map((s, i) => (
/ {(i + 1).toString().padStart(2, "0")}
{s.count} projects
{s.label}
{SECTOR_INTROS[s.id]}
go("projects", { sector: s.id })}>
View {s.label.toLowerCase()} work →
))}
);
}
/* ============================================================
STUDIO
============================================================ */
function StudioPage({ go, lang }) {
return (
The studio · since 1999
Four offices, one studio.
LW began in Dubai in 1999. Twenty-six years on, the studio remains independent — owner-led, hospitality-rooted,
and still small enough that every project is touched by a partner.
(Founding line-up — Waldenström/Hansen vs Doyle/Theilgaard — to be confirmed with the client before publishing.)
Leadership
The people behind the brief.
Roster shown is the most recently-published — client to confirm current titles.
{LEADERSHIP.map(person => (
{person.portrait
?
:
{person.name.split(" ").map(n => n[0]).join("")}
portrait pending
}
{person.name}
{person.role}
))}
Disciplines
What we do under one roof.
{DISCIPLINES.map((d, i) => )}
);
}
/* ============================================================
OFFICES
============================================================ */
function OfficesPage({ go, lang }) {
return (
Where to find us
Offices. Dubai · Hong Kong · São Paulo · Aarhus.
{OFFICES.map((o, i) => (
/ {(i + 1).toString().padStart(2, "0")} · {o.role}
{o.city}
{o.address.map((line, j) => {line} )}
{o.note &&
{o.note}
}
))}
);
}
function MapPlaceholder({ city }) {
/* striped placeholder — client to supply real map embed + coords */
return (
);
}
/* ============================================================
AWARDS
============================================================ */
function AwardsPage({ go, lang }) {
const t = useT(lang);
return (
Recognition
Awards & mentions.
{t.awards_intro}
Year
Award
Issuer
Status
{AWARDS.map((a, i) => (
{a.year}
{a.name}
{a.issuer}
{a.status}
))}
);
}
/* ============================================================
CONTACT (Start a project)
============================================================ */
function ContactPage({ go, lang }) {
const t = useT(lang);
const [form, setForm] = useS({
sector: "hospitality", scope: "", location: "", timeline: "", budget: "",
name: "", company: "", email: "", phone: "", brief: "",
});
const [sent, setSent] = useS(false);
function set(k, v) { setForm(f => ({ ...f, [k]: v })); }
function submit(e) {
e.preventDefault();
setSent(true);
setTimeout(() => window.scrollTo({ top: 0, behavior: "smooth" }), 50);
}
return (
{t.enquiry_title}
Start a project.
{t.enquiry_sub}
{sent ? (
Enquiry received
{t.enquiry_sent}
An LW project director will be in touch within two working days.
{ setSent(false); }}>
Send another
) : (
)}
);
}
function Fieldset({ legend, children }) {
return (
{legend}
{children}
);
}
function Field({ label, value, onChange, placeholder, type = "text", textarea, required }) {
return (
{label}{required && " *"}
{textarea
?
);
}
Object.assign(window, {
HomePage, ProjectsPage, ProjectPage, SectorsPage, StudioPage, OfficesPage, AwardsPage, ContactPage,
});