Luna Bistro is a Beninese restaurant site vitrine for a fictional spot in Cotonou — brand, menu, gallery, and reservations, in French by default with an English toggle. The brief was to build the strongest pure design piece in the portfolio, with a visual identity that comes from somewhere real instead of a template.
What makes it work
- A gallery lightbox that's actually accessible. Opens by click or keyboard, keeps focus contained while it's open with a real focus trap, and closes three different ways — ×, a backdrop click, or Escape.
- The identity comes from a real place, not a template. Grounded in Dantokpa market signage and Abomey appliqué banners — the appliqué-frieze motif (fish, palm leaf, sun, drum) is a specific reference, not generic decoration.
-
A reservation form that says exactly what's wrong.
Inline validation on guest count and date, with accessible, translated,
aria-liveerror messages — never a silent or English-only failure.
Design at a glance
- dusk indigo · #1B2A4A
- parchment · #F3E6CE
- ink · #241B15
- laterite red · #C1440E
- palm-oil gold · #E8A33D
- lagoon green · #3F6E52
- Menu page — pending capture
- Gallery lightbox — pending capture
- Reservation form — pending capture
Built to last
- Audited 320px through 1440px+, with real 44×44px touch targets
- SEO, Open Graph, and Twitter meta tags, plus an on-brand SVG favicon
- Below-fold images lazy-loaded with layout-shift prevention
- Respects
prefers-reduced-motionthroughout
For developers — the full technical breakdown
01. A real focus trap in the gallery lightbox
- Problem
- Lightboxes are one of the most commonly broken accessible patterns — closeable by mouse only, or trapping focus nowhere at all.
- Choice
- Built a genuine focus trap: opens via click or keyboard, stays contained while open, closes three ways (×, backdrop, Escape).
- Result
- A gallery that works for keyboard-only visitors, not just a decorative click target.
02. Grounding the identity in a specific local reference
- Problem
- “African-inspired” restaurant design usually means interchangeable decoration that could belong to any country.
- Choice
- Built the palette and the appliqué-frieze motif from two named sources: Dantokpa market signage and Abomey appliqué banners.
- Result
- A signature element (fish, palm leaf, sun, drum) that's recognizably from somewhere real.
03. A JS-driven language toggle — deliberately different from this studio's own site
- Problem
- A one-page site needs French/English switching without the overhead of duplicate HTML pages.
- Choice
- A
data-i18ndictionary swapping every string client-side, persisted inlocalStorage, updating<html lang>too. - Result
- Instant switching, no reload — the right call at this scale, even though a longer site (like this studio's own) needs the opposite approach.
Accessibility & performance
- Gallery lightbox: real focus trap, closes via ×, backdrop, or Escape
- Reservation form: accessible, translated,
aria-livevalidation errors - Audited 320–1440px, real 44px touch targets
prefers-reduced-motionrespected throughout- SEO/Open Graph/Twitter meta, on-brand SVG favicon
- Lazy-loaded below-fold images with CLS prevention
What I’d do differently
The language toggle is a single URL — great for instant switching, but it means a search engine can only ever index one language of the page. If this needed to rank in French search results independently of English, I’d split it into real bilingual pages, the way I later did on Nova Home Care and this studio’s own site.
Stack
- HTML5
- CSS3
- Vanilla JavaScript
- IntersectionObserver
- localStorage