diff --git a/.gitignore b/.gitignore index 676841b..5e10cc7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,14 +1,8 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - # dependencies /node_modules /.pnp -.pnp.* -.yarn/* -!.yarn/patches -!.yarn/plugins -!.yarn/releases -!.yarn/versions +.pnp.js +.yarn/install-state.gz # testing /coverage @@ -28,28 +22,13 @@ npm-debug.log* yarn-debug.log* yarn-error.log* -.pnpm-debug.log* -# env files (can opt-in for committing if needed) -.env* +# local env files +.env*.local # vercel .vercel # typescript *.tsbuildinfo -next-env.d.ts - -# Developer / deployment instructions -# Contains sensitive production credentials (Gitea admin password, DB password, secrets, SSH keys, etc.) -# This file MUST NEVER be committed or pushed. -developer_instructions.txt - -# Video optimization artifacts and temp files -# Generated by optimize-food-videos.sh, optimize-videos.sh, extract-video-posters.sh, ffmpeg passes etc. -# These should not pollute the working tree or be committed. -public/videos/*-optimized.* -public/videos/*-optimized.mp4 -public/videos/*-optimized.webm -error*.jpeg -ffmpeg2pass*.log +next-env.d.ts \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md deleted file mode 100644 index 8bd0e39..0000000 --- a/AGENTS.md +++ /dev/null @@ -1,5 +0,0 @@ - -# This is NOT the Next.js you know - -This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` before writing any code. Heed deprecation notices. - diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index 43c994c..0000000 --- a/CLAUDE.md +++ /dev/null @@ -1 +0,0 @@ -@AGENTS.md diff --git a/README.md b/README.md index 187dad4..a1c21f2 100644 --- a/README.md +++ b/README.md @@ -1,100 +1,69 @@ -# Shahikitchen — Animated Restaurant Website +# Kött Gård — Premium Halal Meat Delivery -This directory contains the official website for **Shahi Kitchen**, a popular Indian & Pakistani restaurant in Gothenburg (Göteborg), Sweden. +A modern, premium e-commerce website for 100% Halal meat delivery. Built with Next.js, TypeScript, and Tailwind CSS. -**Domain**: [shahikitchen.se](https://shahikitchen.se) +## Features ---- +- **Premium Design** — Green, white, and gold color palette with luxurious typography +- **Multi-language** — Swedish (default), English, and Urdu with RTL support +- **Product Customization** + - Chicken: Choose quantity in pieces (4, 8, 10, 12, 14) + - Beef & Lamb: Choose cutting style (Nihari, Karahi, Qeema, Boneless, Steak) + - Fish: Standard professional cut +- **Full E-commerce Flow** — Shop, product details, cart, secure checkout +- **User Accounts** — Registration, login, order history +- **Wishlist** — Save favorite products +- **Responsive** — Mobile-first design +- **SEO Optimized** — Meta tags, semantic HTML, Open Graph -## About Shahi Kitchen - -Shahi Kitchen is an authentic Indian and Pakistani restaurant specializing in flavorful curries, tandoori dishes, biryanis, haleem, fresh naan, and traditional sweets. The restaurant is particularly well-known for its generous **lunch buffet**, which offers excellent value and is popular among locals in the Gothenburg area. - -### Key Information - -| Detail | Information | -|---------------------|--------------------------------------------------| -| **Full Name** | Shahi Kitchen (Shahikitchen / Shahi Kitchen Sisjön) | -| **Cuisine** | Indian & Pakistani (Halal options available) | -| **Address** | Datavägen 10A, 436 32 Askim, Sweden | -| **Area** | Sisjön / Askim (suburb of Gothenburg) | -| **Phone** | 031-28 89 10 / 0739-381089 (Imran) | -| **Email** | hello@shahikitchen.se | -| **Opened** | Around 2016 | -| **Specialties** | Lunch buffet, Biryani, Lamb Karahi, Curries, Sweets (Shahi Sweets) | - -### Current Online Presence - -- **Instagram**: [@shahikitchen](https://www.instagram.com/Shahikitchen/) -- **Facebook**: [facebook.com/shahikitchengbg](https://www.facebook.com/shahikitchengbg/) -- **Reviews**: ~4.1/5 on Google (600+ reviews) -- **Note**: As of 2026, the domain `shahikitchen.se` is parked. This project will give the restaurant a proper modern website. - ---- - -## Tech Stack - -- **Next.js 15** (App Router) + TypeScript -- **Tailwind CSS** -- **GSAP** — for advanced scroll and UI animations -- **React Three Fiber** — for 3D experiences (dishes) -- **Spline** (optional) — for high-quality hosted 3D scenes -- **Framer Motion** (optional alternative to GSAP for simpler animations) - ---- - -## Project Structure (Planned) - -``` -shahikitchen/ -├── app/ -│ ├── layout.tsx -│ ├── page.tsx # Homepage (Hero + Menu + About + Contact) -│ └── globals.css -├── components/ -│ ├── MenuSection.tsx -│ ├── Dish3D.tsx # React Three Fiber or Spline component -│ ├── ReservationForm.tsx -│ └── ... -├── lib/ -│ └── menu-data.ts # Menu items -├── public/ -│ └── images/ -└── ... -``` - ---- - -## Development - -### Getting Started +## Getting Started ```bash -# Install dependencies npm install - -# Run development server npm run dev ``` -Open [http://localhost:3000](http://localhost:3000) in your browser. +Open [http://localhost:3000](http://localhost:3000). -### Planned Features (in order) +### Demo Account -1. ✅ Create Next.js project -2. ⏳ Build normal restaurant homepage (Hero, Navigation, About) -3. ⏳ Add menu items (name, description, price) -4. ⏳ Style with Tailwind CSS -5. ⏳ Add animations (GSAP / Framer Motion) -6. ⏳ Add 3D dishes (React Three Fiber + Spline) -7. ⏳ Reservation / Contact form -8. ⏳ Mobile responsive -9. ⏳ Deploy to Vercel +- Email: `demo@kottgard.se` +- Password: `demo123` ---- +### Languages -## License +Use the language bar or globe icon to switch between: +- **Svenska** (Swedish) — default +- **English** +- **اردو** (Urdu) — RTL +- **العربية** (Arabic) — RTL +- **فارسی** (Persian) — RTL +- **Türkçe** (Turkish) -This project is being built for Shahi Kitchen. All rights reserved. - - +## Tech Stack + +- **Framework:** Next.js 13 (App Router) +- **Language:** TypeScript +- **Styling:** Tailwind CSS +- **State:** Zustand (persisted cart, auth, wishlist, locale) +- **i18n:** Custom translation system with locale store +- **Icons:** Lucide React + +## Project Structure (Clean Architecture) + +``` +src/ +├── domain/ # Entities + business rules (no React/Next) +├── application/ # Use cases, ports, container.ts +├── infrastructure/ # Zustand, product data, i18n adapters +├── presentation/ # useCart, useAuth, useCatalog hooks +├── app/ # Next.js pages (thin UI) +├── components/ # React UI components +├── i18n/ # Translation dictionaries (en, sv, ur) +├── hooks/ # useTranslation +├── lib/ # Backward-compatible facades +├── store/ # Backward-compatible re-exports +└── types/ # Re-exports domain entities +``` + +See **[docs/CLEAN-ARCHITECTURE.md](docs/CLEAN-ARCHITECTURE.md)** for the full step-by-step guide. \ No newline at end of file diff --git a/app/catering/page.tsx b/app/catering/page.tsx deleted file mode 100644 index f9609bb..0000000 --- a/app/catering/page.tsx +++ /dev/null @@ -1,107 +0,0 @@ -'use client'; - -import Navbar from '@/components/Navbar'; -import Footer from '@/components/Footer'; -import PageHeader from '@/components/PageHeader'; -import CateringPackageCard from '@/components/CateringPackageCard'; -import { - cateringPackages, - CATERING_DISH_CATALOG, - CATERING_CATEGORY_ORDER, -} from '@/lib/catering-data'; -import { useLanguage } from '@/lib/language-context'; -import { getTranslation } from '@/lib/translations'; -import { container } from '@/infrastructure/di/container'; -import { Sparkles } from 'lucide-react'; - -export default function CateringPage() { - const { language } = useLanguage(); - const t = getTranslation(language); - - const handleSendInquiry = () => { - container.messagingGateway.openWhatsApp(t.catering.inquiryMessage); - }; - - return ( -
- - -
- - - {/* Packages grid */} -
-
- {cateringPackages.map((pkg, index) => ( - - ))} -
-
- - {/* Full dish catalog reference */} -
-
-
-
- - {t.catering.catalogBadge} -
-
-
-

- {t.catering.catalogTitle} -

-

- {t.catering.catalogSubtitle} -

-
- -
-
- -
- {CATERING_CATEGORY_ORDER.map((category) => { - const dishes = CATERING_DISH_CATALOG.filter((d) => d.category === category); - const categoryLabel = - (t.catering.categories as Record)?.[category] ?? category; - - return ( -
-

- {categoryLabel} -

-
    - {dishes.map((dish) => ( -
  • - {dish.name} -
  • - ))} -
-
- ); - })} -
-
-
-
- -
- ); -} \ No newline at end of file diff --git a/app/favicon.ico b/app/favicon.ico deleted file mode 100644 index 87d7dbb..0000000 Binary files a/app/favicon.ico and /dev/null differ diff --git a/app/globals.css b/app/globals.css deleted file mode 100644 index 00e4b31..0000000 --- a/app/globals.css +++ /dev/null @@ -1,482 +0,0 @@ -/** - * ============================================================================= - * GLOBAL DESIGN SYSTEM — Shahi Kitchen - * ============================================================================= - * - * Shahi cream + gold visual identity for Shahi Kitchen. - * Bright, warm, appetizing, and luxurious without being dark. - */ - -@import "tailwindcss"; - -:root { - /* === Refined Shahi Light Palette - Warm Cream + Gold === */ - - /* Backgrounds */ - --bg: #F8F5F0; - --bg-elevated: #F5F1E9; - --surface: #FFFFFF; - --surface-subtle: #F2EDE4; - - /* Gold System */ - --gold: #B38B4D; - --gold-dark: #8C6B3A; - --gold-light: #C9A46B; - --gold-muted: #d4a73d; - - /* Emerald for contrast */ - --emerald: #0f5a4a; - --emerald-deep: #0a4a3d; - - /* Text */ - --text: #2C2520; - --text-muted: #6B665F; - --text-light: #8A8478; - - /* Borders */ - --border: #EDE6D9; - - /* Typography */ - --font-display: var(--font-playfair); - --font-sans: var(--font-geist-sans); - --font-mono: var(--font-geist-mono); - --font-arabic: var(--font-arabic); - - /* Motion */ - --ease: cubic-bezier(0.25, 1, 0.5, 1); - - /* Layout — language banner (48px) + navbar (68px) */ - --header-height: 116px; - --page-top-gap: 1rem; -} - -/* Anchor links (/#menu, /#experience) land below the fixed header */ -.scroll-mt-header { - scroll-margin-top: var(--header-height); -} - -/* Base */ -body, -.shahi-body { - font-family: var(--font-sans); - background-color: var(--bg); - color: var(--text); - background-image: - radial-gradient(ellipse 80% 50% at 50% -20%, rgba(201, 154, 46, 0.08), transparent), - radial-gradient(ellipse 60% 40% at 100% 100%, rgba(15, 90, 74, 0.04), transparent); - background-attachment: fixed; -} - -/* RTL typography */ -html[dir="rtl"] body { - font-family: var(--font-arabic), var(--font-sans); -} - -html[dir="rtl"] h1, -html[dir="rtl"] h2, -html[dir="rtl"] h3, -html[dir="rtl"] h4 { - font-family: var(--font-arabic), var(--font-display); - letter-spacing: 0; -} - -h1, h2, h3, h4 { - font-family: var(--font-display); - font-weight: 600; - letter-spacing: -0.025em; - color: var(--text); -} - -/* Premium Buttons */ -.btn-primary { - background: linear-gradient(135deg, var(--gold), var(--gold-muted)); - color: #241806; - font-weight: 700; - transition: all 0.2s var(--ease); -} - -.btn-primary:hover { - transform: translateY(-1px); -} - -.btn-outline { - border: 1px solid var(--gold); - color: var(--gold-dark); - background: transparent; - font-weight: 600; - transition: all 0.2s var(--ease); -} - -.btn-outline:hover { - background: var(--gold); - color: #241806; -} - -/* Glass effect helper */ -.glass { - background: rgba(255, 253, 248, 0.72); - backdrop-filter: blur(20px); -} - -/* Luxury card style */ -.luxury-card { - border-radius: 2rem; - transition: transform 0.4s var(--ease), box-shadow 0.4s var(--ease); -} - -.luxury-card:hover { - transform: translateY(-4px); - box-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.12); -} - -/* Signature dish cards */ -.signature-card { - box-shadow: 0 4px 24px -4px rgb(16 23 36 / 0.06); - transition: transform 0.35s var(--ease), box-shadow 0.35s var(--ease), border-color 0.35s var(--ease); -} - -.signature-card:hover { - box-shadow: 0 20px 40px -12px rgb(179 139 77 / 0.18); - border-color: rgba(201, 154, 46, 0.45); -} - -/* Section ornament */ -.section-ornament { - position: relative; -} - -.section-ornament::before { - content: ''; - position: absolute; - top: 0; - left: 50%; - transform: translateX(-50%); - width: 80px; - height: 3px; - background: linear-gradient(90deg, transparent, var(--gold-muted), transparent); - border-radius: 2px; -} - -/* Hero overlay text */ -.hero-glass { - background: linear-gradient( - 135deg, - rgba(255, 253, 248, 0.92) 0%, - rgba(255, 250, 240, 0.88) 50%, - rgba(248, 245, 240, 0.85) 100% - ); - backdrop-filter: blur(20px); - border: 1px solid rgba(201, 154, 46, 0.2); - box-shadow: - 0 25px 50px -12px rgba(16, 23, 36, 0.15), - inset 0 1px 0 rgba(255, 255, 255, 0.8); -} - -/* ============================================================================= - * FOOTER — Matches header cream + gold palette - * ============================================================================= */ -.shahi-footer { - background: linear-gradient( - 180deg, - #fffcf7 0%, - #fbf7ef 55%, - #f5f0e6 100% - ); - color: #101724; - border-top: 1px solid rgba(201, 154, 46, 0.25); - box-shadow: 0 -4px 24px -4px rgba(16, 23, 36, 0.06); -} - -.footer-top-rail { - height: 4px; - background: linear-gradient( - 90deg, - transparent 0%, - #8a6a25 15%, - #c99a2e 35%, - #f4d47f 50%, - #c99a2e 65%, - #8a6a25 85%, - transparent 100% - ); -} - -.footer-main { - position: relative; -} - -.footer-glow { - position: absolute; - border-radius: 50%; - pointer-events: none; - filter: blur(80px); -} - -.footer-glow--gold { - top: -40px; - right: 10%; - width: 280px; - height: 280px; - background: rgba(201, 154, 46, 0.08); -} - -.footer-glow--emerald { - bottom: 0; - left: -5%; - width: 320px; - height: 320px; - background: rgba(15, 90, 74, 0.05); -} - -.footer-heading-line { - display: inline-block; - width: 20px; - height: 2px; - background: linear-gradient(90deg, #c99a2e, #f4d47f); - border-radius: 1px; -} - -.footer-info-card { - border-radius: 1rem; - border: 1px solid rgba(201, 154, 46, 0.22); - background: rgba(255, 255, 255, 0.72); - padding: 1rem 1.125rem; - backdrop-filter: blur(8px); - transition: border-color 0.25s var(--ease), background 0.25s var(--ease), box-shadow 0.25s var(--ease); -} - -.footer-info-card:hover { - border-color: rgba(201, 154, 46, 0.45); - background: #ffffff; - box-shadow: 0 4px 16px -6px rgba(16, 23, 36, 0.08); -} - -.footer-link { - color: #3d4654; - transition: color 0.2s var(--ease), transform 0.2s var(--ease); -} - -.footer-link:hover { - color: #0f5a4a; -} - -html[dir="rtl"] .footer-link:hover { - transform: translateX(-2px); -} - -html[dir="ltr"] .footer-link:hover { - transform: translateX(2px); -} - -.footer-social-btn { - display: flex; - align-items: center; - justify-content: center; - width: 2.75rem; - height: 2.75rem; - border-radius: 0.875rem; - border: 1px solid rgba(201, 154, 46, 0.35); - background: rgba(255, 255, 255, 0.85); - color: #8a6a25; - transition: all 0.25s var(--ease); -} - -.footer-social-btn:hover { - background: linear-gradient(135deg, #c99a2e, #e8c56a); - color: #241806; - border-color: #c99a2e; - transform: translateY(-2px); - box-shadow: 0 8px 24px -4px rgba(201, 154, 46, 0.35); -} - -.footer-logo-ring { - border-color: rgba(201, 154, 46, 0.35); - background: #ffffff; - box-shadow: 0 4px 20px -6px rgba(16, 23, 36, 0.1); -} - -.footer-bottom { - background: rgba(255, 255, 255, 0.55); - border-top: 1px solid rgba(201, 154, 46, 0.2); -} - -.footer-cta { - backdrop-filter: blur(12px); - background: linear-gradient( - 135deg, - rgba(255, 255, 255, 0.92) 0%, - rgba(255, 252, 247, 0.88) 100% - ); - border-color: rgba(201, 154, 46, 0.35); -} - -/* Language banner subtle shine */ -.lang-banner { - position: relative; - overflow: hidden; -} - -.lang-banner::after { - content: ''; - position: absolute; - inset: 0; - background: linear-gradient( - 90deg, - transparent 0%, - rgba(255, 255, 255, 0.06) 50%, - transparent 100% - ); - pointer-events: none; -} - -/* Mesmerizing shimmer animation for premium buttons (used in Navbar) */ -@keyframes shimmer { - 0% { transform: translateX(-100%); } - 100% { transform: translateX(200%); } -} - -/* Continuous menu reel marquee for 43" displays - items move LEFT (enter from right, exit left), seamless loop with 2x duplication */ -@keyframes menu-reel { - 0% { transform: translateX(0); } - 100% { transform: translateX(-50%); } -} - -.menu-reel-track { - will-change: transform; - animation: menu-reel linear infinite; - /* Force GPU layer for stable poster/video during transform */ - transform: translateZ(0); - backface-visibility: hidden; -} - -/* Homepage signature menu — dishes scroll left to right */ -@keyframes signature-menu-reel-ltr { - 0% { transform: translateX(-50%); } - 100% { transform: translateX(0); } -} - -.signature-menu-reel-track { - will-change: transform; - animation: signature-menu-reel-ltr linear infinite; - transform: translateZ(0); - backface-visibility: hidden; -} - -.signature-menu-reel:hover .signature-menu-reel-track { - animation-play-state: paused; -} - -@media (prefers-reduced-motion: reduce) { - .signature-menu-reel-track { - animation: none; - flex-wrap: wrap; - width: 100% !important; - justify-content: center; - } -} - -/* ============================================================================= - * KIOSK / FULLSCREEN DISPLAY PAGES (screen1 & screen2) - * Professional clean TV/window look: no scrollbars ever, even in browser - * fullscreen (F11) or kiosk mode. User zooms browser (in/out) to adjust - * visible reel density instead of scrolling. Content sized to fit 100vh. - * ============================================================================= */ -html.screen-kiosk, -body.screen-kiosk { - overflow: hidden !important; - overscroll-behavior: none; - /* Hide scrollbars cross-browser */ - scrollbar-width: none; /* Firefox */ - -ms-overflow-style: none; /* IE/Edge */ -} - -html.screen-kiosk::-webkit-scrollbar, -body.screen-kiosk::-webkit-scrollbar { - display: none; /* Chrome/Safari/Opera */ -} - -.screen-root { - height: 100vh; - overflow: hidden; - display: flex; - flex-direction: column; - /* Extra insurance: hide any descendant scrollbars */ - scrollbar-width: none; - -ms-overflow-style: none; -} - -.screen-root::-webkit-scrollbar, -.screen-root *::-webkit-scrollbar { - display: none; -} - -/* Subtle polish for pure display (no accidental text selection or pointer) */ -.screen-root { - cursor: default; -} - -/* ============================================================================= - * VERTICAL REEL for screen3 order columns - * Orders move UP (from below to above) in a loop, like screen2 horizontal but vertical. - * Cards have fixed px height; viewport h-full of available column space (after header) => - * fills entire screen height with no white space (max top to bottom). - * Zoom in browser: fewer items visible per column (larger cards relative). - * Zoom out: more items visible per column (smaller cards relative). - * When > visible count, the track loops seamlessly (duplicated list + 50% translateY). - * ============================================================================= */ -@keyframes order-reel-up { - 0% { transform: translateY(0); } - 100% { transform: translateY(-50%); } -} - -.order-reel-track { - display: flex; - flex-direction: column; - will-change: transform; - animation: order-reel-up linear infinite; - /* Force GPU layer for stable animation */ - transform: translateZ(0); - backface-visibility: hidden; -} - -.reel-viewport { - overflow: hidden; - /* Height 100% of available (flex h-full after section header) to fill screen. - Fixed card heights + zoom changes visible count dynamically. */ -} - -/* Menu page — smooth category filter scrolling */ -.menu-category-scroll { - scroll-behavior: smooth; - scrollbar-width: none; - -ms-overflow-style: none; -} - -.menu-category-scroll::-webkit-scrollbar { - display: none; -} - -@media (min-width: 1024px) { - .menu-category-scroll { - scrollbar-width: thin; - scrollbar-color: #d4c9b8 transparent; - } - - .menu-category-scroll::-webkit-scrollbar { - display: block; - width: 5px; - } - - .menu-category-scroll::-webkit-scrollbar-track { - background: transparent; - } - - .menu-category-scroll::-webkit-scrollbar-thumb { - background: #d4c9b8; - border-radius: 999px; - } - - .menu-category-scroll::-webkit-scrollbar-thumb:hover { - background: #c99a2e; - } -} diff --git a/app/layout.tsx b/app/layout.tsx deleted file mode 100644 index 2fd67c1..0000000 --- a/app/layout.tsx +++ /dev/null @@ -1,123 +0,0 @@ -/** - * ROOT LAYOUT — Shahi Kitchen (shahikitchen.se) - * - * This is the single root layout for the entire Next.js App Router application. - * - * RESPONSIBILITIES: - * - Set up global metadata (title, description, favicon) for SEO and social sharing - * - Load the premium typography system: - * • Playfair Display (display/serif) → used for headings via --font-playfair - * • Geist Sans (system UI) → body text - * • Geist Mono → code / tabular data - * - Initialize the GLOBAL CART SYSTEM: - * • CartProvider wraps the whole tree so any page/component can use `useCart()` - * • CartDrawer is rendered once at the root (slide-in basket panel) - * • Sonner provides beautiful toast notifications used by the cart - * - * ARCHITECTURAL NOTES: - * - We deliberately render and at the root level instead of - * inside individual pages. This guarantees only ONE instance exists and prevents - * duplicate drawers/toasts when navigating. - * - The cream/gold Shahi theme tokens live in globals.css and are referenced via - * Tailwind arbitrary values (e.g. bg-[#F8F5F0]). - * - * FUTURE DEVELOPERS: - * - To add a new global provider (theme, analytics, etc.), wrap it here. - * - WhatsApp number for orders is currently hardcoded in CartDrawer.tsx (46739381089). - * - If you ever split the cart into a separate modal library, keep the provider here. - */ - -import type { Metadata } from "next"; -import { Playfair_Display, Geist, Geist_Mono, Noto_Sans_Arabic } from "next/font/google"; -import "./globals.css"; -import { Toaster } from "sonner"; -import CartDrawer from "@/components/CartDrawer"; -import WishlistDrawer from "@/components/WishlistDrawer"; -import { CartProvider } from "@/presentation/providers/cart-provider"; -import { WishlistProvider } from "@/presentation/providers/wishlist-provider"; -import { LanguageProvider } from "@/presentation/providers/language-provider"; - -const playfair = Playfair_Display({ - variable: "--font-playfair", - subsets: ["latin"], - weight: ["400", "500", "600", "700"], - style: ["normal", "italic"], -}); - -const geistSans = Geist({ - variable: "--font-geist-sans", - subsets: ["latin"], - weight: ["400", "500", "600", "700"], -}); - -const geistMono = Geist_Mono({ - variable: "--font-geist-mono", - subsets: ["latin"], - weight: ["400", "500", "600"], -}); - -const notoArabic = Noto_Sans_Arabic({ - variable: "--font-arabic", - subsets: ["arabic"], - weight: ["400", "500", "600", "700"], -}); - -/** - * Next.js Metadata API (static) - * These values power: - * - Browser tab title - * - Search engine results - * - Social cards (Open Graph / Twitter) when shared - * - * For dynamic per-page metadata, use `generateMetadata()` in page files. - */ -export const metadata: Metadata = { - title: "Shahi Kitchen | Authentic Indian & Pakistani Restaurant in Gothenburg", - description: "Experience Shahi flavors at Shahi Kitchen in Askim, Gothenburg. Authentic Indian & Pakistani cuisine, famous lunch buffet, and traditional sweets since 2016.", - icons: { - icon: "/favicon.ico", - }, -}; - -/** - * RootLayout - * - * The ONLY place in the app where we initialize: - * 1. CartProvider → gives every descendant access to `useCart()` hook - * 2. CartDrawer → the actual slide-in basket UI (controlled via context) - * 3. Toaster → global toast surface used by cart (Sonner library) - * - * IMPORTANT: - * - Never wrap the entire app in another CartProvider — it will break the singleton. - * - The body uses the Shahi cream background (#F8F5F0) as the base canvas. - * - `antialiased` + font variables are applied once at the root for consistency. - */ -export default function RootLayout({ - children, -}: Readonly<{ - children: React.ReactNode; -}>) { - return ( - - - - - - {children} - - - - - - - - - ); -} diff --git a/app/locations/page.tsx b/app/locations/page.tsx deleted file mode 100644 index edfd503..0000000 --- a/app/locations/page.tsx +++ /dev/null @@ -1,144 +0,0 @@ -/** - * LOCATIONS PAGE - * - * Dedicated page for the restaurant's two physical branches. - * - * ARCHITECTURE: - * - Two branches are modeled as distinct concepts: - * 1. Shahi Kitchen Askim (Sisjön) → Full restaurant + famous lunch buffet - * 2. Shahi Sweets Backaplan → Sweets, snacks, café, halwa puri etc. - * - Both are operated by the same team (explicitly stated at the bottom) - * - Google Maps embeds are intentionally simple (lazy loaded) - * - * FUTURE: - * - When real online ordering launches, this page could show "Order from Askim" - * vs "Order from Backaplan" with different delivery radii. - * - Both branches now have the same opening hours. - */ - -'use client'; - -import Navbar from "@/components/Navbar"; -import Footer from "@/components/Footer"; -import PageHeader from "@/components/PageHeader"; -import { useLanguage } from "@/lib/language-context"; -import { getTranslation } from "@/lib/translations"; - -export default function LocationsPage() { - const { language } = useLanguage(); - const t = getTranslation(language); - return ( -
- - - - -
- - - -
- {/* Branch 1: Askim */} -
-
RESTAURANT & BUFFET
-

Shahi Kitchen – Askim (Sisjön)

- -
-
-
ADDRESS
-
Datavägen 10A
436 32 Askim, Gothenburg
-
- -
-
PHONE
- 031-28 89 10 - 0739-381089 -
- -
-
OPENING HOURS
-
Monday – Sunday • 11:00 – 21:00
-
- -
-
WHAT TO EXPECT
-
Full restaurant experience with our popular lunch buffet, à la carte, and traditional Pakistani & Indian dishes.
-
-
- -
-