Skip to content
Concept

Luna Bistro

A bilingual restaurant site vitrine grounded in Dantokpa market signage and Abomey appliqué — not generic “African-inspired” decoration.

Role
Design & development, solo
Year
2026
Stack
HTML5, CSS3, vanilla JS
Status
Complete

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-live error 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
DisplayBevan
BodyWork Sans
AccentCaveat — chalkboard menu prices, “spécialité du jour”
  • 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-motion throughout

Want a restaurant or hospitality site with this much craft behind it?

See it live Start a project
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-i18n dictionary swapping every string client-side, persisted in localStorage, 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-live validation errors
  • Audited 320–1440px, real 44px touch targets
  • prefers-reduced-motion respected 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