Back to worldNext: The observatory

08 · In production

Caramelקרמל

A menu site and CMS for a gluten-free café in Akko.

Caramel is a gluten-free café on the fishermen’s square in Akko. Its public menu, in Hebrew and right to left, shows every dish with its price and availability, whether the café is open now, its weekly hours and the way there; the same content is edited from a protected admin portal. Built with Lama, live at caramel.darb.co.il, and Darb REST’s first client.

Nour’s role
Built with Lama · Menu site, CMS, PWA and performance
Status
Live at caramel.darb.co.il. Menu, prices, hours and photos are managed from its admin portal.
The Caramel menu on desktop, in Hebrew: a category rail for meals, cold drinks and hot drinks, then rails of dish cards with photos and prices in shekels, such as a challah schnitzel sandwich for 50.
caramel.darb.co.il, the menu on desktop — captured 2026-09-29.

What is real today

Live

  • The public Hebrew menu at caramel.darb.co.il: categories, dishes and prices, open status, weekly hours and directions
  • The admin portal for the profile, hero media, categories, dishes, hours, social links and SEO
  • Caramel is Darb REST’s first client, served on a Darb address

Not claimed

  • caramel.darb.co.il is a menu: it takes no orders and no payments
  • The ordering counter on this page is built in this portfolio on top of Caramel’s live menu. It prepares a WhatsApp message and stores nothing, and it is in test mode: visitors cannot send an order yet
  • The repository has no automated test suite; its checks are lint, typecheck and build

The problem

Guests of a gluten-free kitchen check before they come: what is on the menu, what it costs, whether a dish is available today and whether the place is open. A photographed printed menu stops being true the day a price or an opening hour changes.

The café has to make those changes itself, the same day, without a developer and without a rebuild of the site.

How it works

  1. 01

    Content lives in the database, not in the code: the restaurant profile, hero media, categories, dishes, opening hours, social links and SEO copy are Supabase rows and storage objects, and the public page reads them at request time, so an edit shows up without a deploy.

  2. 02

    One admin portal edits that same content: signed-in administrators manage order, visibility, availability, prices, photos, overnight opening intervals and SEO fields through authenticated server actions. The browser only ever holds the publishable key.

  3. 03

    Access is enforced in Postgres: row-level security on every application table and on storage, writes only for private.is_admin(), and public reads only while the restaurant profile is active. An inactive profile shows no catalog and is not indexed.

Try it

Caramel’s real menu, read live from its database: the prices, sold-out dishes and opening hours are the café’s own, as they are right now. Add dishes to a tray and go through pickup and payment. The ordering is built in this portfolio and is in test mode, so no order is sent.

Selected capabilities

  • Hebrew, right to left

    An RTL layout with a skip link, a keyboard-operable category rail, native dialogs with labelled titles, visible focus rings and reduced motion respected.

  • Open or closed, computed

    The open state is derived from the weekly hours in the Asia/Jerusalem time zone, including intervals that run past midnight.

  • A menu made for phones

    Category navigation reflected in the URL, horizontal dish rails and a dish dialog with name, price, description and photo. Unavailable dishes stay visible, marked as such.

  • Installable

    A web manifest, app icons and a production service worker. Offline, the page shows a reconnect screen; menu data, prices and admin pages are never cached.

  • Search and sharing

    Metadata from the profile and SEO settings, an Open Graph image, sitemap, robots and Restaurant JSON-LD with hours and social links.

  • Guarded media

    Public storage buckets for dishes, categories, hero media and branding, with MIME and size limits, admin-only writes and upload checks in the browser before anything is stored.

Architecture

One Next.js application with separate route groups for the public site, the CMS and authentication, over a hosted Supabase project.

  1. app/(public)

    The public menu: Server Components read through services/; client islands for the category rail, dish dialogs and media.

  2. app/admin

    The CMS: authorization checked in the protected layout, writes as server actions (features/*/actions.ts) that revalidate the public page.

  3. Supabase

    Postgres with RLS on every table and storage bucket; admin membership lives in a private schema that the Data API does not expose.

  4. Deployment

    The Next.js app on Vercel and a hosted Supabase project, served at caramel.darb.co.il.

  • Next.js 16
  • React 19
  • TypeScript (strict)
  • Tailwind CSS 4
  • Supabase · Postgres · RLS · Storage
  • Motion
  • PWA · service worker

The live product

Captures of the public production site, caramel.darb.co.il. The logo and the footer are left out of frame: both show the café’s phone number.

A dish dialog over the dimmed menu: “חלה שניצל”, 50 shekels, a photo of the sandwich, and previous and next buttons with the position 2 of 27.
A dish opened: name, price and photo, with previous and next.
The hot drinks rail, then “How to get here” with the address on the fishermen’s square in Akko and a Waze button, beside the weekly opening hours with today highlighted.
Directions and weekly hours, today highlighted.
The Caramel menu on a phone: the category rail with meals selected, then rails of dish cards with photos and prices.
The menu on a phone — captured 2026-09-29.
A dish opened on a phone: a large photo of the challah schnitzel sandwich, its name and price, and previous and next buttons.
A dish opened on a phone.