# Restaurant Durrani — Design Benchmarks & DESIGN.md

**Research Date:** 2026-05-24
**Prepared by:** Aria Principal Research Agent
**Project:** Restaurant Durrani — Gelnhausen, Germany — Premium Afghan Cuisine Digital Platform
**Stack:** Next.js (SSG/ISR) on Cloudflare Pages + Payload CMS

---

## Executive Summary

Restaurant Durrani is already #1 of 117 restaurants in Gelnhausen (4.7/5 across 1,556+ Google reviews). The digital platform must match that physical-world authority: a modern premium-hospitality experience that converts mobile visitors to reservations in under 60 seconds, ranks for every Afghan/Halal/celebration keyword in Hessen, and feels international without cliché. Every design decision below is benchmarked from real premium sources and trades off UX, trust, performance, SEO, AI-readability, mobile, and brand.

---

## 1. Brand Language — What "Premium Afghan, Not Kitsch" Looks Like

### Benchmark Sources Analyzed
- **ilili (New York, Pentagram-designed):** Lebanese fine dining brand that achieved "nostalgic and modern" simultaneously. Logo draws from Arabic calligraphy via sharp nib strokes — not decorative Arabic script — paired with a color system named after Lebanese landscape elements. Elegant without exoticism.
- **Onette (Berlin):** Avoided "pastiche" — studied multiple geographic diner traditions to extract universal comfort principles, not visual tropes. Uses antique materials (Lithuanian café curtains) through intentional curation, not decoration.
- **Eleven Madison Park:** Farm-to-table story told through restraint — white space, minimal animation, imagery doing all the heavy lifting. Restraint = Michelin signal.
- **Apple.com:** Simplicity, clarity, one idea per screen, storytelling through product, never a wasted element.

### The Durrani Brand Language Framework

**Mood:** Warm-modern, dignified, grounded. The feeling of entering a beautifully lit room that smells of cardamom and spiced lamb — calming, confident, welcoming. Not loud, not exotic, not theatrical.

**Personality Pillars:**
1. **Authentic, not folksy** — Afghan heritage is present in texture, pattern restraint, and material quality, not in ornate borders or lantern icons.
2. **Family warmth, professional precision** — Customer reviews consistently mention "energetic staff" and "cozy ambiance." The digital brand should feel like you are already being welcomed.
3. **Confidence without intimidation** — Premium without stiffness. Guests include families, couples, business groups, celebration parties.
4. **Local pride, international quality** — Gelnhausen root, world-class aspiration.

**What "Premium Afghan, Not Kitsch" Looks Like — Specific Execution Rules:**
- **NEVER use:** Generic arabesque borders, gold filigree clip art, kitschy carpet textures as backgrounds, stock photo of lanterns in desert, the color combination of red+gold+dark green with NO restraint, animated flying birds or falcons, "exotic" Orientalism framing.
- **DO use:** A single geometric motif derived from Afghan tilework used as a **systematic design token** (e.g., a subtle 6-pointed star or lozenge used as divider, bullet, or texture in extreme moderation). Think: one motif, many uses, always small and functional. This is the ilili "diamond dot" principle.
- **Material palette reference:** Raw linen, warm sandstone, polished terracotta, shadow-dark olive, aged brass — evoke Afghanistan's landscape and craft without picturing them literally.
- **Photography frame:** The food IS the cultural statement. A perfect mantu on a clean stone-grey plate, lit naturally, photographed as fine-dining cuisine is photographed, IS the identity.

**Trade-off:** Going too abstract loses cultural signal, too specific becomes kitschy. Solution: **one grounding motif, used systematically** — like ilili's diamond — that anchors culture without performing it.

---

## 2. Typography System

### Benchmark Sources
- Awwwards hotel/restaurant collection: Cormorant, Avenir, DM Sans, GT fonts cited repeatedly
- Premium restaurant typography: Cormorant Garamond + Lato, Playfair Display + Inter
- Google Fonts 2025-2026: Instrument Serif (high-contrast, editorial), DM Serif Display, Playfair Display
- Apple principle: max 2-3 typefaces; every additional typeface creates noise, not character

### Recommended Typeface System

**Display/Headline — Cormorant Garamond Variable** (Google Fonts, free, variable font)
- **Why:** 45 font files, 9 visual styles, 5 weights. Very high contrast strokes signal luxury. Feels European-heritage without being stiff. Variable font = minimal performance hit (one file, infinite weights).
- **Use for:** Hero headlines, section titles, dish names on menu, pull quotes.
- **Fallback:** Playfair Display (same genre, more widely cached = faster first render)
- **Weights in use:** Light (300) for atmosphere copy, Regular (400) for headings, Semi-Bold (600) for menu section headers.

**Alternative Display: Instrument Serif** (Google Fonts, 2025 release)
- Condensed, high-contrast, works on narrow mobile columns without overflow. Consider if Cormorant feels too classical.

**Body/UI — Inter Variable** (Google Fonts, variable font)
- **Why:** Designed for screen reading. Used by Apple, Linear, Vercel. Extremely legible at 16px on mobile. Full German umlaut support.
- **Use for:** Body copy, navigation labels, form labels, descriptions, button text, all UI chrome.
- **Weights:** Regular (400) body, Medium (500) labels, Semi-Bold (600) CTAs.

**Accent/Hierarchy Element — Small Caps or Tracked Uppercase in Inter**
- Category labels ("VORSPEISEN", "FLEISCHGERICHTE"): Inter Medium at 11-12px, tracking: 0.12em all-caps. No third typeface needed.

### Type Scale (8pt Grid Aligned)

| Token | Size | Line Height | Usage |
|---|---|---|---|
| `text-hero` | 56-80px (fluid) | 1.05 | Hero headline (one per page) |
| `text-display` | 40-56px | 1.1 | Section titles, page H1s |
| `text-heading` | 28-36px | 1.2 | Card headings, dish section titles |
| `text-subheading` | 20-24px | 1.3 | Subsection labels, feature names |
| `text-body-lg` | 18px | 1.65 | Lead paragraphs, about copy |
| `text-body` | 16px | 1.6 | Standard body text |
| `text-body-sm` | 14px | 1.55 | Captions, metadata, legal |
| `text-label` | 11-12px | 1.4 | Category labels (tracked uppercase) |

**Fluid typography (CSS clamp):**
```css
.text-hero { font-size: clamp(2.5rem, 5vw + 1rem, 5rem); line-height: 1.05; }
```

**Price display:** Inter Regular, no currency symbol on first occurrence (fine-dining standard), no dotted leader lines (that is 1985 cafeteria language).

**Trade-offs:**
- Cormorant at light weight (300) can fail 4.5:1 contrast below 20px → restrict light weight to 20px+, only 28px+ for 300 weight.
- Variable fonts: slightly larger initial parse → use `font-display: swap` and preload the woff2.

---

## 3. Spacing System

**Principle: 8pt Grid System**
Every spacing value is a multiple of 8px (4px for micro-spaces).

| Token | Value | Use Case |
|---|---|---|
| `space-1` | 4px | Icon-to-label gap, inline micro |
| `space-2` | 8px | Button internal padding (vertical) |
| `space-3` | 12px | List item gaps |
| `space-4` | 16px | Standard inline spacing |
| `space-6` | 24px | Card internal padding |
| `space-8` | 32px | Component gap (between menu items) |
| `space-10` | 40px | Mobile section padding |
| `space-16` | 64px | Mobile section gap |
| `space-20` | 80px | Desktop section padding |
| `space-24` | 96px | Desktop section gap |
| `space-32` | 128px | Hero padding, major section gap |

**Rule:** Internal spacing ≤ External spacing. Tighter inside components than between them — maintains visual grouping.

**Max content width:** 1280px (desktop). Text-heavy columns: max 720px. Never exceed ~680px for body text (~75 chars/line max for readability).

**Mobile safe area:** Always `env(safe-area-inset-*)` on fixed elements. Bottom CTAs: `padding-bottom: calc(16px + env(safe-area-inset-bottom))`.

---

## 4. Color System

### Decision: Light-Primary, Dark-Mode Supported

**Rationale for Light-First:**
- Food photography performs dramatically better on light backgrounds (colors truer, appetite appeal higher)
- 73% of restaurant bookings on mobile in bright outdoor conditions
- Fine dining heritage: Eleven Madison Park, Noma, Le Bernardin — all light-primary

**Dark Mode as Premium Layer:**
- Serves `@media (prefers-color-scheme: dark)` + manual toggle
- Evening/atmospheric feel mirrors evening dining experience
- Food photography is stunning against very dark warm backgrounds

### Palette Architecture

**Light Mode:**

| Token | Hex | Role |
|---|---|---|
| `--color-background` | `#FAF7F3` | Warm off-white (never pure #FFFFFF — too clinical) |
| `--color-surface` | `#F2EDE6` | Cards, menus, elevated surfaces |
| `--color-surface-raised` | `#EDE7DC` | Hover states, subtle elevation |
| `--color-foreground` | `#1A1611` | Primary text (warm near-black, not #000000) |
| `--color-foreground-muted` | `#5A5248` | Secondary text, captions |
| `--color-foreground-subtle` | `#9A9089` | Disabled states, placeholders |
| `--color-accent` | `#B8892A` | Antique brass/amber gold (primary accent) |
| `--color-accent-warm` | `#C9A35E` | Hover state for accent |
| `--color-accent-deep` | `#8A6415` | Active/pressed accent state |
| `--color-border` | `#DDD4C8` | Default borders, dividers |
| `--color-border-strong` | `#BDB0A2` | Focus states, strong dividers |
| `--color-success` | `#3D7A5A` | Reservation confirmed |
| `--color-error` | `#B03A2E` | Form errors |

**Accent Gold Logic:** `#B8892A` is pulled from Afghan traditional brass and saffron spectrum. Not "#FFD700" — that reads plasticky and cheap. Antique brass reads as material, not decoration.

**Dark Mode:**

| Token | Hex | Role |
|---|---|---|
| `--color-background` | `#120F0B` | Warm near-black |
| `--color-surface` | `#1E1A15` | Card/surface layer |
| `--color-surface-raised` | `#2A2520` | Elevated surfaces |
| `--color-foreground` | `#F2EDE6` | Primary text (warm white, not #FFFFFF) |
| `--color-foreground-muted` | `#B5A898` | Secondary text |
| `--color-accent` | `#C9A35E` | Accent in dark (lighter for contrast) |
| `--color-border` | `#2E2820` | Borders in dark |

**Contrast rule:** All text/background pairs MUST pass WCAG 2.2 AA 4.5:1 (body) or 3:1 (large text ≥18px / bold ≥14px). `#FAF7F3` on `#120F0B` ≈ 18:1 — AAA.

**Trade-off:** Amber gold at `#B8892A` on `#FAF7F3` ≈ 4.6:1 — passes AA but not AAA. Use only for large text or decorative elements at this specific weight. Restrict accent to: primary CTAs, active nav, links, motif, max 2-3 instances per viewport.

---

## 5. Image Direction & Composition

### Photography Direction for Durrani

**Hero Style:**
- Extreme close-up of a single dish (mantu, kebab, bolani) — ingredients visible, texture vivid, steam implied. Shot at 45° on dark slate or warm linen.
- Atmosphere: restaurant interior, bokeh, warm amber lighting, guests laughing or table being set.
- NEVER: stock photos. NEVER: flat-lay food on white background (delivery-app language, not fine dining). NEVER: heavy Instagram filters.

**Art Direction Principles:**
1. Natural or warm controlled artificial light (3000-4000K equivalent)
2. Depth of field — sharp subject, subtly blurred background
3. Negative space — breathing room = premium; overcrowded frame = street food stall
4. Consistent warm color grade across all images (one Lightroom preset applied site-wide)
5. People create warmth and permission — show guests (with consent), not only empty rooms

**Technical Spec:**

| Context | Format | Max Size | Dimensions |
|---|---|---|---|
| Hero desktop | WebP | 350KB | 1920×1080 |
| Hero mobile (art-directed) | WebP | 180KB | 828×1792 |
| Menu item | WebP | 80KB | 800×600 |
| Gallery full | WebP | 200KB | 1200×800 |
| Gallery thumb | WebP | 40KB | 400×300 |
| Team portrait | WebP | 100KB | 600×750 |
| Celebration room | WebP | 150KB | 1200×800 |

**Alt text strategy (AI-readability + a11y):** Describe what + context. Not "food photo." Yes: "Hausgemachte Mantu — gedämpfte Teigtaschen mit Lamm-Hackfleisch, serviert mit Joghurt und Tomaten-Kurkuma-Soße." Serves WCAG 1.1.1, Google image search, and AI vision models simultaneously.

**Trade-off:** Professional food photography costs €500-2000/day but is the single highest-ROI investment. One great photograph converts more than any animation or color scheme. Budget strategy: 1 half-day food photographer, 8-12 hero images shot meticulously = site's entire visual foundation.

---

## 6. Motion Principles & Animation Discipline

**Core Principle: Every animation must earn its place by improving comprehension, guiding attention, or confirming feedback. If it does none of these, it is removed.**

**Performance Rule: Animate ONLY `transform` (translate/scale/rotate) and `opacity` — both GPU-accelerated, run on compositor thread, zero layout reflow.**

### Approved Animation Vocabulary

| Animation Type | Properties | Duration | Easing | Use Case |
|---|---|---|---|---|
| Fade entrance | `opacity: 0 → 1` | 400ms | `ease-out` | Section entry |
| Slide-up entrance | `translateY(24px) → 0` + opacity | 500ms | `cubic-bezier(0.16, 1, 0.3, 1)` | Cards, menu items |
| Scale press | `scale: 1 → 0.97` | 100ms | `ease-in` | Button press feedback |
| Scale hover | `scale: 1 → 1.02` | 200ms | `ease-out` | Card/image hover |
| Underline draw | `scaleX: 0 → 1` | 300ms | `ease-out` | Navigation hover |
| Skeleton pulse | `opacity: 0.4 → 0.8` infinite | 1200ms | `ease-in-out` | Loading states |
| Page transition | `opacity: 0 → 1` | 300ms | `ease` | Route transitions |
| Menu open | Spring physics | 350ms | stiffness:280, damping:25 | Nav dropdown |

### Prohibited Animations
- Parallax scrolling on mobile (causes jank on low-end Android)
- Auto-playing video with audio
- Typewriter / text scramble effects
- Continuous looping animations not user-initiated
- CSS `transition` on `width`, `height`, `padding`, `margin`, `top`, `left` (always triggers layout reflow)
- Rotate/bounce on any structural element

**Scroll-triggered entrance:** Framer Motion `whileInView` with `once: true`. Children staggered 80ms.

**Reduced motion (mandatory):**
```css
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}
```
Also implement via Framer Motion's `useReducedMotion()` hook.

**Performance budget:** Total JS for animation < 15KB gzipped. CSS transitions for simple states; Framer Motion for complex sequences only.

**Trade-off:** No-animation (EMP-style) is safest for perceived performance. Subtle entrance animations improve engagement if they complete in < 600ms and never delay content access. Never animate before content is available.

---

## 7. Mobile Interaction Principles & Edge-to-Edge UX

**Context:** 73% of restaurant bookings on mobile. 53% of users abandon if page loads >3s. +25% reservation conversions with optimized mobile booking.

### Durrani Mobile Design Rules

**Layout Foundation:**
- Mobile-first CSS (min-width breakpoints, not max-width)
- Edge-to-edge images: hero images bleed to device edges
- Body text: minimum 16px (prevents iOS auto-zoom on input focus)
- `<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">`

**Fixed Bottom Action Bar (mobile only, ≤ 768px):**
```
[ Tisch reservieren (60%) ]  [ Online bestellen (40%) ]
```
- `position: fixed; bottom: 0; left: 0; right: 0`
- Height: 64px + `padding-bottom: env(safe-area-inset-bottom)`
- Background: `--color-background` + `backdrop-filter: blur(12px)` + top border
- Primary (Reserve): accent fill. Secondary (Order): ghost/outline.
- Dismiss: downward swipe with dot indicator to re-summon.
- This single component is estimated to account for +20-25% reservation conversion (Spilt Milk Web Design research).

**Touch Target Standards:**
- All buttons: min 48px height, min 120px width
- Navigation links: min 44px height
- Menu category pills: min 40px height, 8px gaps
- Form inputs: min 48px height
- Checkbox/radio: min 44×44px click area via `::before` pseudo-element

**Typography on mobile:**
- Hero text: `clamp(2rem, 8vw, 3.5rem)` — never overflow container
- Body text: 16px minimum, 1.6 line-height
- Never 12px anywhere visible to users

**Trade-off:** Bottom action bar can obscure content on very short viewport → mitigate by making it dismissable. For extremely content-dense screens (menu), auto-hide bar when user is in deep-scroll read mode, re-show on any upward scroll.

---

## 8. Layout Systems & Grid

### 12-Column CSS Grid

- Mobile: single column, 24px gutters
- Tablet (768px+): 6-column grid, 24px gutter, 32px margin
- Desktop (1024px+): 12-column grid, 24px gutter, 48-80px margin
- Wide (1280px+): 12-column, max-width 1280px centered

### Key Layout Patterns

**1. Hero — Full Bleed:**
- `100vw × 100dvh` (use `dvh` not `vh` — prevents iOS Safari address bar jump)
- Image: absolute fill, `object-fit: cover`, art-direction via `<picture>`
- Text overlay: gradient `rgba(0,0,0,0) → rgba(0,0,0,0.7)` from bottom
- Headline: bottom-left on desktop, bottom-center on mobile
- Single CTA below headline

**2. Features — Alternating 2-Column:**
- `grid-cols-2` desktop, `grid-cols-1` mobile
- Image (60%) + Text (40%) alternating left-right
- Text columns max 520px
- Used for: "Unsere Geschichte", "Halal Versprechen", "Feiern"

**3. Menu Grid:**
- Mobile: single column list
- Desktop: 2-column cards or single-column with sticky category sidebar (`position: sticky; top: 88px`)

**4. Gallery — CSS Masonry:**
```css
.gallery { columns: 1; }
@media (min-width: 640px) { .gallery { columns: 2; } }
@media (min-width: 1024px) { .gallery { columns: 3; } }
```
No heavy JS masonry libraries. Natural staggered heights feel editorial.

**5. Celebration Rooms — Card Grid:**
- Mobile: horizontal scroll or stacked
- Desktop: 3-column equal-height grid
- Each card: image (70% height), title, capacity, CTA

**6. Testimonials — Horizontal Scroll on Mobile:**
```css
.testimonials {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
}
.testimonial-card {
  scroll-snap-align: start;
  min-width: 280px;
}
```
Desktop: 3-column or 2-column static grid.

---

## 9. CTA Strategy & Conversion Hierarchy

### Three CTA Tiers

| Tier | Text | Visual | Placement |
|---|---|---|---|
| Primary | "Tisch reservieren" | Filled accent, 48px min height | Hero, mobile bar, Nav |
| Secondary | "Online bestellen" | Outlined/ghost, same size | Hero (2nd), mobile bar, Menu page |
| Tertiary | "Mehr erfahren", "Unsere Speisekarte", "Zimmer anfragen" | Text link or subtle outline | Section bottoms, cards |

### Button Design Spec
- Border-radius: 4px (modern but grounded — not pill, not sharp)
- Primary: `background: var(--color-accent)` + white text + no shadow
- Hover: `background: var(--color-accent-warm)` + `translateY(-1px)` (200ms ease-out)
- Active: `scale(0.97)` (100ms)
- Focus: 3px offset ring in accent color (WCAG 2.4.11 compliant)
- Disabled: 40% opacity, `cursor: not-allowed`

### CTA Hierarchy on Homepage
1. Above-fold hero: "Tisch reservieren" (primary)
2. Hero secondary: "Speisekarte ansehen" (tertiary text link)
3. Mobile sticky bar: "Tisch reservieren" + "Online bestellen" (always visible)
4. After menu preview: "Vollständige Speisekarte"
5. After celebrations section: "Feier anfragen" (distinct tertiary CTA)
6. Footer: "Tisch reservieren" + Contact + "Online bestellen"

### Reservation Flow Principle
- Reservation widget opens in **modal overlay** — not page navigation (page-leave = 40% higher abandonment)
- Modal: `backdrop-filter: blur(8px)`, centered form, close via ESC or ×
- Multi-step if needed: Step 1 (Date/Time/Guests), Step 2 (Contact/Notes), Confirmation

**Trade-off:** German UX culture distrusts overly aggressive sales patterns. Use generous spacing around CTAs. Never stack two primary CTAs adjacently. CTAs should feel like invitations, not demands.

---

## 10. Premium Hospitality UX — Menu, Reservation, Forms

### Menu UX Pattern: Sticky Category Navigation + Inline Scroll

**Mobile:**
```
[ Vorspeisen | Salate | Fleischgerichte | Vegetarisch | Desserts | Getränke ]
(horizontal scroll pill nav, sticky after hero, active pill tracks scroll)
```
- Pill tabs: 40px height, 16px horizontal padding, accent underline for active
- Active pill updates via Intersection Observer
- No PDFs — ever. PDFs: inaccessible, uncrawlable by AI, destroy mobile UX, feel 2005.

**Desktop:** Same horizontal pill nav OR left sticky sidebar (position:sticky, top:88px).

**Dish Item Structure:**
```
[Dish Name — Cormorant, text-subheading]
[Description — Inter, text-body, max 2 lines mobile, expandable]
[Tags: Halal • Vegetarisch • Scharf — small icon pills]
[Price — Inter Regular, right-aligned or below name]
```

**Allergen/Diet Labeling:**
- Visual icon set: Leaf (vegan), V (vegetarian), Flame (scharf), H (halal)
- Max 3 icons per item
- Tooltip on hover / tap explains icon
- Filter bar: "Alle | Halal | Vegetarisch | Vegan | Scharf"
- This is a conversion AND trust signal for Halal-seeking audience — critical for Durrani's brand promise

### Reservation Form (60-Second Rule)

Field order:
1. Datum (calendar UI or next-7-days chips)
2. Uhrzeit (available slot chips: 18:00 | 19:00 | 19:30 | 20:00 — not a dropdown)
3. Personen (stepper: − 2 +)
4. Name
5. Telefon (tel input, German format)
6. Anmerkungen (optional, placeholder: "Allergien, besondere Wünsche...")

**Form UX Details:**
- Custom calendar component (never native browser datepicker — inconsistent on Android)
- Time: chips of available slots, unavailable shown greyed/strikethrough
- `inputmode="numeric"` on phone/count fields
- All fields support browser autofill (`autocomplete` attributes)
- No CAPTCHA (WCAG 3.3.8) — use honeypot hidden field
- Inline validation on blur, not on submit
- Floating label pattern on focus

### Form Microinteractions
- Input focus: border → `--color-accent`, label floats up
- Valid: green checkmark at right edge
- Error: red border + icon + message below (never replace label with error)
- Submit: loading spinner → success checkmark animation

---

## 11. Premium Navigation Patterns

### Desktop Navigation
- Sticky transparent header → solid + `backdrop-filter: blur(12px)` after 60px scroll
- Logo: left-aligned
- Nav links: centered, Inter Medium 15px, 40px height
- Language toggle (DE/EN): top-right, subtle
- "Tisch reservieren" CTA: right-aligned, always visible
- Items: Speisekarte | Über uns | Feiern | Kontakt
- Hover: animated underline `scaleX: 0 → 1` from left (300ms ease-out)

### Mobile Navigation
- Hamburger: 44×44px, right side of header
- Full-screen overlay (not sidebar — sidebar is 2018, full-screen is premium 2025)
- Items: large type (text-heading scale), center-aligned vertically
- Order: Speisekarte → Über uns → Feiern → Kontakt
- Bottom of overlay: "Tisch reservieren" CTA + phone number
- Close: × button + tap-outside
- Animation: fade + `translateY(-8px → 0)` (NOT slide-from-right)

**Active State:** Current page: accent color + optional 2px left accent border in list.

**Scroll behavior:** Desktop header reduces from 72px to 56px after scroll (smooth `padding` transition on a stable element — no layout jump).

**Trade-off:** Full-screen mobile nav uses more screen real estate but signals premium over drawer. Drawer = app-style (less hospitality). Tradeoff: close gesture must be obvious — mitigate with × in top-right and tap-outside support.

---

## 12. Component Language & States

### Core Component Rules
- Border-radius: 4px (buttons/inputs), 8px (cards), 16px (modals), 0 (full-bleed)
- Shadows: `0 1px 3px rgba(0,0,0,0.08)` (cards), `0 8px 32px rgba(0,0,0,0.12)` (modals). No heavy drop shadows.
- No gradients on UI components (only acceptable on hero overlay for text legibility)

### Loading States
- Skeleton screens (not spinners): same layout dimensions, `--color-surface-raised` background, CSS pulse animation
- Show skeleton only after 300ms delay — don't flash skeleton for fast loads
- Apply to: menu list, availability slots, gallery grid, testimonials

### Empty States
- Never blank white rectangle
- Empty menu section: warm message + CTA to contact or see full menu
- No available slots: message + next available date + phone number

### Error States
- Form: inline below field, red accent, icon
- Page-level: full error component with: what went wrong + what to do + phone number
- API error: top-center toast, auto-dismiss 5s, never `alert()`
- 404: on-brand, links to Speisekarte / Reservierung / Startseite

### Success States
- Reservation confirmed: full-screen success view with booking summary card + "Add to Calendar" CTA
- Contact form: inline success replaces form

### Hover/Touch States
- Cards: `scale(1.02)` + shadow increase (200ms ease-out)
- Images within cards: inner image `scale(1.05)`, card stays (overflow: hidden on card)
- Links: underline draws left-to-right (200ms)
- Navigation: underline animation (as above)

---

## 13. Image Size Strategy & Technical Implementation

### Next.js `<Image>` Implementation

```tsx
<Image
  src="/food/mantu-hero.jpg"
  alt="Hausgemachte Mantu — gedämpfte Teigtaschen mit Lamm-Hackfleisch, Joghurt und Tomaten-Kurkuma-Soße"
  width={1920}
  height={1080}
  priority={true}  // LCP image only
  quality={85}
  sizes="(max-width: 768px) 100vw, (max-width: 1280px) 80vw, 1280px"
  placeholder="blur"
  blurDataURL="data:image/jpeg;base64,..."
/>
```

- `priority={true}`: only on the hero (one per page)
- `placeholder="blur"`: generated at build time via `plaiceholder` package — base64 blur-up preview < 40 bytes
- Art-directed hero: use `<picture>` with `<source media="(max-width: 768px)" srcset="...mobile.webp">` for portrait crop on mobile

**Target file sizes:**

| Context | Format | Max Size | Dimensions |
|---|---|---|---|
| Hero desktop | WebP | 350KB | 1920×1080 |
| Hero mobile | WebP | 180KB | 828×1792 |
| Menu item | WebP | 80KB | 800×600 |
| Gallery full | WebP | 200KB | 1200×800 |
| Gallery thumb | WebP | 40KB | 400×300 |
| Team portrait | WebP | 100KB | 600×750 |

**Cloudflare configuration:**
- Enable Cloudflare Image Resizing for dynamic optimization fallback
- `Cache-Control: public, max-age=31536000, immutable` for all static assets

---

## 14. AI-Friendly Content Layout & SEO Architecture

### JSON-LD Schema for Durrani

**Primary — Restaurant schema:**
```json
{
  "@context": "https://schema.org",
  "@type": "Restaurant",
  "name": "Restaurant Durrani",
  "description": "Authentisches afghanisches Restaurant in Gelnhausen — Halal, vegetarisch & vegan. Spezialitäten: Mantu, Kabab, Bolani. Festräume für Feiern.",
  "url": "https://restaurant-durrani.de",
  "telephone": "+49XXXXXXXXX",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "Brentanostraße 9",
    "addressLocality": "Gelnhausen",
    "addressRegion": "Hessen",
    "addressCountry": "DE"
  },
  "servesCuisine": ["Afghan", "Halal", "Vegetarian", "Middle Eastern"],
  "priceRange": "€€",
  "hasMenu": "https://restaurant-durrani.de/speisekarte",
  "acceptsReservations": true,
  "amenityFeature": [
    {"@type": "LocationFeatureSpecification", "name": "Halal", "value": true},
    {"@type": "LocationFeatureSpecification", "name": "Vegetarisch", "value": true},
    {"@type": "LocationFeatureSpecification", "name": "Veranstaltungsräume", "value": true},
    {"@type": "LocationFeatureSpecification", "name": "Parkplatz", "value": true}
  ],
  "aggregateRating": {
    "@type": "AggregateRating",
    "ratingValue": "4.7",
    "reviewCount": "1556",
    "bestRating": "5"
  }
}
```

**Additional schemas:** `MenuItem` for top 5-10 dishes, `Event` for celebration rooms, `BreadcrumbList` on every subpage, `WebSite` + `SearchAction` for sitelinks.

**Why this matters:** GPT-4 answer accuracy improves from 16% to 54% with proper structured data. ChatGPT, Perplexity, Claude, Gemini all parse schema markup. For "bestes afghanisches Restaurant in Hessen" queries — properly structured sites are preferentially cited.

### HTML Semantics for AI Readability
- `<main>`, `<nav>`, `<header>`, `<footer>`, `<section>`, `<article>` — never div soup
- `<h1>` (one per page) → `<h2>` (section) → `<h3>` (subsection) — never skip levels
- Menu: semantic list structure, not generic div containers

**Lead paragraph rule:** Every page's first 100 words answer who/what/where/when/why with key phrases: "Afghani Restaurant Gelnhausen", "Halal zertifiziert", "vegetarische Küche", "Festräume Hessen". This is the AI overview extraction point — it will quote this verbatim.

### Local SEO Keyword Clusters
- "Afghani Restaurant Gelnhausen" (primary — already #1)
- "Halal Restaurant Main-Kinzig-Kreis"
- "Halal Restaurant Frankfurt Umgebung" (regional reach)
- "Vegetarisches Restaurant Gelnhausen"
- "Festsaal mieten Gelnhausen" / "Feier location Gelnhausen"
- "Mantu Gelnhausen", "Kabab Gelnhausen" (dish-specific long tail)

### Content Pages to Create
- `/halal` — Halal certification trust page + keyword signal
- `/feiern` — Celebration rooms: capacity, photos, inquiry form
- `/speisekarte/vegetarisch` — Vegetarian/vegan filter page
- `/blog` (optional, ISR) — "Über Afghani Küche" educational content

### Core Web Vitals Targets (Next.js SSG + Cloudflare)
- LCP: < 2.5s (target 1.5s with priority image + blur placeholder)
- INP: < 200ms (target 100ms with SSG + minimal JS)
- CLS: < 0.1 (target 0.02 with defined image dimensions + font-display:swap)

---

## 15. Accessibility — WCAG 2.2 AA Implementation

### Critical Requirements

**1. Color Contrast (1.4.3):**
- Body text: 4.5:1 minimum. `#1A1611` on `#FAF7F3` ≈ 14:1 — passes AAA easily.
- Accent gold on warm white: verify with browser DevTools before finalizing.
- All text variants must be contrast-tested at target sizes.

**2. Focus Indicators (2.4.11 — new in WCAG 2.2):**
- Every interactive element has visible focus, not obscured by sticky elements
- `scroll-margin-top: 88px` on all sections (prevents sticky header covering focused element)
- Focus ring: 3px solid `var(--color-accent)`, 2px offset

**3. Touch Target Size (2.5.8 — new in WCAG 2.2):**
- Minimum 24×24 CSS pixels. Best practice: 44×44px.
- Use padding to increase click area without changing visual size.

**4. No Cognitive CAPTCHAs (3.3.8 — new in WCAG 2.2):**
- Honeypot only: `<input name="website" style="display:none" tabindex="-1" aria-hidden="true">`

**5. Redundant Entry (3.3.7 — new in WCAG 2.2):**
- Multi-step reservation: auto-populate data from prior steps.

**6. Skip Link:**
- `<a href="#main" class="sr-only focus:not-sr-only">Zum Inhalt springen</a>` — first body element.

**7. Language Attribute:**
- `<html lang="de">` — required for German screen reader pronunciation.

**8. Form Accessibility:**
- Every input: `<label>` with matching `for`/`id`
- Errors: linked via `aria-describedby`
- Required: `aria-required="true"` + visual indicator

**9. Motion:**
- `prefers-reduced-motion` implemented in CSS + Framer Motion `useReducedMotion()`

**Trade-off:** Full WCAG 2.2 AA adds ~15-20% to initial development time but: reduces legal risk (BITV 2.0, EU Web Accessibility Directive applicable in Germany), improves SEO (Google uses accessibility signals as ranking factors), and serves outdoor mobile users where high contrast is critical.

---

## 16. Design Decision Trade-off Matrix

| Decision | UX | Trust | Performance | SEO | AI-Readability | Mobile | Brand |
|---|---|---|---|---|---|---|---|
| Cormorant + Inter pairing | ✅ Clear hierarchy | ✅ Premium signal | ✅ Variable fonts | ✅ Legible crawl | ✅ Standard HTML | ✅ Mobile-scaled | ✅ Distinct + timeless |
| Warm off-white vs. pure white | ✅ Eye comfort | ✅ Welcoming feel | = Neutral | = Neutral | = Neutral | ✅ Better outdoor | ✅ Hospitality warmth |
| Light-first + dark-mode | ✅ Food photo fidelity | ✅ Familiar context | ✅ Less CSS complexity | = Neutral | = Neutral | ✅ Outdoor usability | ✅ Premium flex |
| No PDF menus | ✅ Native mobile UX | ✅ Professional | ✅ No PDF parse | ✅ Crawlable | ✅ Full crawl | ✅ One-tap | ✅ Modern premium |
| Sticky mobile bottom CTA bar | ✅ Always accessible | ✅ Clear intent | ✅ Lightweight fixed | = Neutral | = Neutral | ✅ +25% conversion | = Subtle vs. pushy |
| Skeleton loading states | ✅ Perceived speed | ✅ Professional quality | ✅ No layout shift | = Neutral | = Neutral | ✅ No jank | ✅ Modern standard |
| Full JSON-LD schema | = No UX impact | ✅ Rich snippets | ✅ No render impact | ✅ Rich results | ✅ AI citation | ✅ Voice search | = No brand impact |
| Halal filter on menu | ✅ Confident browsing | ✅ Delivers promise | = Neutral | ✅ Keyword signal | ✅ Parseable | ✅ One-tap filter | ✅ Core brand value |
| German-language slug URLs | ✅ Natural nav | ✅ Local trust | = Neutral | ✅ DE keyword match | ✅ Language clarity | = Neutral | ✅ Local pride |
| 8pt grid spacing | ✅ Visual rhythm | ✅ Craftsmanship | = Neutral | = Neutral | = Neutral | ✅ Touch harmony | ✅ Invisible quality |
| transform/opacity-only animation | ✅ Smooth | ✅ No jank = trust | ✅ GPU composited | = Neutral | = Neutral | ✅ No mobile chop | ✅ Refined motion |
| prefers-reduced-motion support | ✅ Inclusive UX | ✅ Legal compliance | ✅ Simpler code | = Neutral | = Neutral | ✅ Battery-friendly | = Neutral |
| Custom calendar reservation | ✅ Faster booking | ✅ Premium feel | ⚠️ +JS size | = Neutral | = Neutral | ✅ No ugly native | ✅ Crafted |
| Honeypot spam (no CAPTCHA) | ✅ No friction | ✅ WCAG 2.2 | ✅ Zero JS overhead | = Neutral | = Neutral | ✅ Mobile smooth | ✅ Trust-first |
| Art-directed mobile hero | ✅ Correct composition | ✅ No awkward crop | ✅ Smaller file | ✅ Alt text indexed | ✅ Rich alt text | ✅ Purpose-built | ✅ Intentional craft |

---

## 17. Payload CMS Content Modeling

**Collections:**
1. `MenuItems` — name(DE/EN), description(DE/EN), price, category(relation), dietary tags(multi-select), image, isAvailable, sortOrder
2. `MenuCategories` — name(DE/EN), sortOrder, icon(optional)
3. `Gallery` — image, caption, isHero, sortOrder
4. `Testimonials` — author, rating(1-5), text, source(Google/TripAdvisor), date, isVisible
5. `Events` — title, date, description, capacity, image, bookingEmail
6. `OpeningHours` — dayOfWeek, openTime, closeTime, isClosed, note
7. `TeamMembers` — name, role, image, bio

**Globals:**
1. `SiteSettings` — name, phone, email, address, social links
2. `SEODefaults` — default meta title, description, OG image
3. `Announcements` — temporary banner text (holiday hours, etc.)

**Image handling:** Enable `@payloadcms/plugin-cloud-storage` with Cloudflare R2 (S3-compatible). Auto-generate image sizes on upload. Enforce `alt` as required field in Media collection config.

---

## 18. Component Build Priority

**P0 — Must-have before launch:**
1. `<HeroSection>` — full-bleed image, headline, CTA, gradient overlay
2. `<StickyNav>` — transparent → solid on scroll, mobile hamburger
3. `<MobileStickyBar>` — fixed bottom CTA bar (mobile only)
4. `<MenuSection>` — sticky categories, dish list, filter pills
5. `<DishCard>` — name, description, tags, price
6. `<ReservationModal>` — form overlay with date/time/guests
7. `<Footer>` — contact, hours, map link, CTAs
8. `<SkeletonLoader>` — for menu and availability loading

**P1 — High priority:**
9. `<CelebrationSection>` — room cards with photos and capacity
10. `<StorySection>` — alternating 2-col image+text
11. `<TestimonialCarousel>` — horizontal scroll on mobile
12. `<GalleryGrid>` — masonry columns layout
13. `<FormField>` — floating label, validation states, accessible
14. `<SuccessState>` — reservation/order confirmation

**P2 — Polish layer:**
15. `<FilterPills>` — dietary filter for menu
16. `<ImageZoom>` — tap to expand gallery on mobile
17. `<PageTransition>` — route-level fade
18. `<LanguageToggle>` — DE/EN in nav
19. `<ThemeToggle>` — light/dark manual toggle
20. `<HalalBadge>` — inline certified badge for menu items

---

## 19. Implementation Stack Notes

**Next.js + Cloudflare Pages configuration:**
- Fonts: `next/font/google` with `display: 'swap'` and `subsets: ['latin']`
- CSS: CSS custom properties for all design tokens — enables dark mode via single `@media (prefers-color-scheme: dark)` block
- GloriaFood embed: `<Script strategy="lazyOnload">` — never block render for ordering widget
- Analytics: Cloudflare Web Analytics (privacy-first, no cookie banner needed in Germany for first-party analytics)
- Schema: injected via `<Script id="schema" type="application/ld+json">` in page `<head>`
- Sitemap: auto-generated by `next-sitemap` on build
- Blur placeholders: generated via `plaiceholder` package at build time

**Cloudflare Pages checklist:**
- Automatic HTML/CSS/JS minification enabled
- `Cache-Control: public, max-age=31536000, immutable` for all static assets
- HTTP/2 for font delivery
- Cache purge on ISR revalidation via Cloudflare Cache Purge API

---

## Sources Referenced

- [Awwwards Hotel & Restaurant Collection](https://www.awwwards.com/websites/hotel-restaurant/)
- [ilili Branding by Pentagram](https://www.pentagram.com/work/ilili)
- [Aró Digital Strategy: Luxury Hotel Website Trends 2025](https://www.arodigitalstrategy.com/hotelier-hub/latest-articles/website-trends-to-watch-in-2025-beyond)
- [Gourmet Marketing: Hotel Website Design Trends 2025](https://www.gourmetmarketing.net/blog/hotel-website-design-trends-in-2025-what-guests-expect-and-how-to-stay-ahead)
- [NIH Studio: Restaurant Web Design Trends](https://nihstudio.com/restaurant-web-design-trends/)
- [Brandlic: 9 Luxury Color Palettes 2025](https://brandlic.studio/9-luxury-color-palettes-that-define-high-end-design-in-2025/)
- [Framer Blog: 11 Strategic Animation Techniques](https://www.framer.com/blog/website-animation-examples/)
- [Nielsen Norman Group: Menu Design 17 Guidelines](https://www.nngroup.com/articles/menu-design/)
- [AllAccessible: WCAG 2.2 Complete Guide 2025](https://www.allaccessible.org/blog/wcag-22-complete-guide-2025)
- [Digidop: Structured Data for SEO & AI 2025](https://www.digidop.com/blog/structured-data-secret-weapon-seo)
- [Payload CMS: Schema Markup Guide](https://payloadcms.com/posts/guides/add-schema-markup-to-payload--nextjs-for-better-seo)
- [Lexington Themes: Best New Serif Google Fonts 2026](https://lexingtonthemes.com/blog/best-new-serif-google-fonts-2026)
- [Evergreen HQ: Digital Menu Design Trends 2025](https://www.evergreenhq.com/blog/digital-menu-design-trends-15-templates-that-boost-sales-by-40/)
- [Wallpaper: Berlin Cross-Cultural Diners](https://www.wallpaper.com/travel/restaurants/these-berlin-diners-are-a-love-letter-to-cross-cultural-conviviality)
- [Restaurant Guru: Durrani Gelnhausen](https://restaurantguru.com/Restaurant-Durrani-Gelnhausen)
- [Spilt Milk: Reservation System Integration 2025](https://spiltmilkwebdesign.com/reservation-system-integration-for-restaurants-2025-guide/)
- [Malou: Local SEO for Restaurants](https://www.malou.io/en-us/blog/local-seo-for-restaurants)
- [Vibe Coder: Empty/Loading/Error States 2025](https://blog.vibecoder.me/empty-states-loading-states-error-states)
- [Eleven Madison Park](https://www.elevenmadisonpark.com/)
