indian-dhaba-ghaziabad

byHarsh Tyagi

Build a complete production-ready full-stack restaurant/cafe website directly from this prompt. Do not spend time generating a long PRD or documentation. PROJECT: Premium local Indian Dhaba / Cafe in Ghaziabad focused primarily on direct food delivery. DESIGN: Create a unique, classy, clean and spacious Indian food brand — NOT a copy of KFC, McDonald's, Pizza Hut, Domino's, Swiggy or Zomato. Visual style: - warm cream/ivory background - deep walnut/dark brown text - chilli red primary CTA - muted brass/saffron accents - editorial premium typography - modern Indian Dhaba feel - large appetizing food photography - subtle Indian line-art motifs - no glassmorphism, neon, excessive gradients or crowded sections - mobile-first and fully responsive HOMEPAGE: Header → Hero → Signature Dishes → Bestsellers → Direct Order CTA → Why Choose Us → Kitchen Story → Delivery Area → Footer. Hero: "Straight from the tandoor, still smoking at your door." CTA: ORDER NOW / VIEW MENU Clearly communicate Indian food + Ghaziabad + delivery. FUNCTIONAL PAGES: - Home - Menu - Food detail - Bestsellers - About - Contact - Cart - Checkout / Order - Delivery availability FUNCTIONALITY: - Menu categories - Search/filter - Add to cart - Quantity controls - Cart persistence - Checkout - Customer name/phone/address - Order creation - Delivery availability check - Order success/error states - Loading/empty/error states ADMIN PANEL: Create a secure admin dashboard for: - Login/authentication - Dashboard - Menu CRUD - Categories CRUD - Bestsellers - Orders - Delivery zones - Rooms/settings if applicable - Website settings - Image/media management BACKEND: Use a clean REST API with a persistent database. Create proper models for: - users/admins - menu/categories - orders/order items - delivery zones - settings - rooms if the existing project requires them SECURITY: - Never expose database credentials or secrets in frontend - Environment variables for secrets - Strict CORS for: https://cafe-frontend-alpha.vercel.app https://cafe-admin-gamma.vercel.app - JWT/session authentication for admin - password hashing - request validation - rate limiting - Helmet/security headers - safe error responses - authorization for admin APIs IMPORTANT API: Backend production URL: https://cafe-backend-rfwe.onrender.com Frontend API base: https://cafe-backend-rfwe.onrender.com/api/v1 SEO/PERFORMANCE: - semantic HTML - local SEO for Ghaziabad - metadata + Open Graph - Restaurant/LocalBusiness schema only with real data - optimized WebP/AVIF images - lazy loading - responsive images - optimized fonts - fast mobile performance - accessibility - no horizontal overflow CONTENT RULE: Do NOT invent real restaurant facts, phone numbers, prices, ratings, reviews, address, opening hours or delivery promises. Where real client data is unavailable, use clearly marked editable placeholder content. TECHNICAL RULE: Build the actual working application, not a mockup. Keep architecture clean and deployment-ready. Do not add unnecessary libraries. Do not create fake API responses when real backend/database functionality can be implemented. FINAL: Run build/type checks, fix errors, verify all routes, verify cart/order/admin flows and ensure the project is ready for Vercel + Render deployment. Start implementation immediately.

No preview

Comments (0)

No comments yet. Be the first!

System Requirements

Page 1 of 31

System Requirements Document for indian-dhaba-ghaziabad

1. Introduction

indian-dhaba-ghaziabad is a production-ready, full-stack website for a premium local Indian Dhaba / Cafe in Ghaziabad whose primary business is direct food delivery. The product is a real working application — not a mockup — comprising a customer-facing storefront, a secure administrative dashboard, and a clean REST API backed by a persistent database.

The product intent is to give a neighbourhood dhaba its own first-party ordering channel: customers browse an editorial, hand-built brand experience, discover dishes by category or search, add them to a persistent cart, confirm that their address falls inside a managed delivery zone, and place an order with their name, phone, and address. The restaurant operator, in turn, keeps the storefront truthful through a protected admin dashboard covering menu items, categories, bestsellers, orders, delivery zones, website settings, and image/media assets.

The audience is twofold:

  • Customers — Ghaziabad locals (families, students, office workers) who want food that feels cooked rather than manufactured, and who order directly from the dhaba.
  • Admin — the restaurant operator who owns the accuracy of the menu, delivery coverage, and order queue.

A binding content rule governs the whole product: no real restaurant facts may be invented. Phone numbers, prices, ratings, reviews, address, opening hours, and delivery promises must never be fabricated; where real client data is unavailable, the application uses clearly marked editable placeholder content that the Admin can replace.

Page 2 of 31

2. System Overview

The system is delivered as three cooperating parts:

  1. Customer storefront — a mobile-first, fully responsive public site with Home, Menu, Food detail, Bestsellers, About, Contact, Cart, Delivery availability, and Checkout / Order.
  2. Admin dashboard — a protected, authenticated back office with Dashboard, Menu CRUD, Categories CRUD, Bestsellers, Orders, Delivery zones, Rooms/settings, Website settings, and Image/media management, entered through Login/authentication.
  3. Backend REST API — a clean, versioned API at https://cafe-backend-rfwe.onrender.com/api/v1 with a persistent database and proper models for users/admins, menu/categories, orders/order items, delivery zones, settings, and rooms where the existing project requires them.

Actors. The accepted active-human catalog is exactly two personas: Customer and Admin. The backend, database, and delivery-zone lookup are system processes, not personas.

Accepted behavior. Customers browse categories, search and filter the menu, open dish details, add items to cart with quantity controls, retain the cart across visits, check delivery availability against managed zones, and complete checkout with name, phone, and address — receiving clear success or error states. Admins authenticate, then create, read, update, and delete menu items and categories, curate bestsellers, review orders, manage delivery zones, configure website settings and editable content, and manage image/media assets.

Ownership. All customer-facing and admin-facing surfaces are first-party application pages. The backend REST API and database are system-owned. There is no third-party marketplace, aggregator, or provider-owned ordering surface in scope.

Narrow exclusions. The brand must not copy KFC, McDonald's, Pizza Hut, Domino's, Swiggy, or Zomato. No glassmorphism, neon, excessive gradients, or crowded sections. No invented restaurant facts. No unnecessary libraries. No fake API responses where real backend/database functionality can be implemented. No database credentials or secrets in the frontend.

Page 3 of 31

2a. Product Interpretation and Delivery Boundary

Delivery ownership. The storefront and the admin dashboard are first-party applications deployed to Vercel; the API and database are first-party services deployed to Render. The customer never leaves the product to order: browsing, cart, delivery check, and checkout all happen inside the first-party storefront, and the order is created through the first-party REST API.

Access ownership. The customer storefront is openly reachable — Home, Menu, Food detail, Bestsellers, About, Contact, Cart, Delivery availability, and Checkout / Order require no account. Cart persistence is achieved through client-side persistence of the cart contents, not through a customer account. The admin dashboard is protected: every admin destination (Dashboard, Menu CRUD, Categories CRUD, Bestsellers, Orders, Delivery zones, Rooms/settings, Website settings, Image/media management) requires an authenticated admin session, and the Login/authentication page is the anonymous entry boundary that establishes it. Admin identity is application-owned and provisioned by the operator before first administrative use; the login page itself is reachable without a session, while all protected state remains unavailable until identity is established.

Current vs. future boundary. Everything described in this document is current. No future-horizon features are accepted; nothing in this document should be read as authorizing online payment, customer accounts, loyalty, table reservations, or third-party delivery integrations.

Content boundary. All restaurant-specific facts — address, phone, opening hours, prices, ratings, reviews, and delivery promises — are editable placeholders until the client supplies real data. Structured Restaurant/LocalBusiness schema is emitted only when real data exists; placeholder content must never be published as structured data.

Page 4 of 31

2b. Source Content Inventory

Not applicable — no reference directive in this project declares a content_source. All restaurant-specific content is client-supplied or clearly marked editable placeholder content.

2c. Page Content and Component Coverage

Home

  • Information / state: the public entry surface. Renders the fixed homepage section order — Header → Hero → Signature Dishes → Bestsellers → Direct Order CTA → Why Choose Us → Kitchen Story → Delivery Area → Footer. Hero headline is exactly "Straight from the tandoor, still smoking at your door." with CTAs ORDER NOW and VIEW MENU, and copy that clearly communicates Indian food + Ghaziabad + delivery. Signature Dishes and Bestsellers are populated from the live API; Kitchen Story, Why Choose Us, and Delivery Area render editable placeholder content until the client supplies real copy.
  • Primary actions: ORDER NOW (to Menu), VIEW MENU (to Menu), open a Signature Dish or Bestseller (to Food detail), add a dish to cart, open Cart, open Delivery availability.
  • Supporting actions: header navigation to Menu, Bestsellers, About, Contact, Cart; footer navigation; above-footer dish-name ticker.
  • Domain entities: menu item, category, bestseller flag, website settings, delivery zone (summary).
  • Component responsibilities: Header (brand mark, primary nav, cart indicator); Hero (two-panel split, badge, headline, dual CTA, brass tandoor line-art motif); SignatureDishes (numbered stamp header 01, ruled list of curated dishes); Bestsellers (numbered stamp header 02, horizontal scroll-snap strip of tall photo panels with stamp overlays); DirectOrderCTA (numbered stamp header 03, ORDER NOW); WhyChooseUs (numbered stamp header 04, ruled panels); KitchenStory (numbered stamp header 05, editable placeholder narrative); DeliveryArea (numbered stamp header 06, delivery-zone summary + link to Delivery availability); DishTicker (marquee above footer); Footer (badge, editable placeholder address, ruled block).
  • States: loading — flat cream placeholder blocks for dish panels and strip; empty — if no dishes are published, the section shows a clearly marked editable placeholder panel rather than an empty gap; success — dishes render with name, price, and image; error — if the API is unreachable, sections show a safe, non-technical error panel with a retry action; recovery — retry re-fetches the section data without a full page reload.

Login/authentication

  • Information / state: the anonymous entry boundary for the Admin. Presents the credential form (email/username and password) and the current session state. No protected admin state is rendered here.
  • Primary actions: submit credentials to establish an authenticated admin session; on success, continue to Dashboard.
  • Supporting actions: show/hide password; clear a failed attempt.
  • Domain entities: admin user, session/JWT.
  • Component responsibilities: LoginForm (validated inputs, submit control, inline field errors); AuthErrorBanner (safe, non-technical failure message); SessionRedirect (routes an already-authenticated admin straight to Dashboard).
  • States: loading — submit control disabled with an in-progress indicator; empty — pristine form; success — session established, redirect to Dashboard; error — invalid credentials or rate-limited response shown as a safe message with no internal detail; recovery — the form remains usable and the admin may retry after the rate-limit window.
Page 5 of 31

Menu

  • Information / state: the full food catalog, grouped by category, with search and filter controls and the current filter/search state reflected in the URL and UI.
  • Primary actions: select a category; enter a search term; apply/clear filters; open a dish (to Food detail); add a dish to cart; adjust quantity inline.
  • Supporting actions: clear all filters; jump between categories; open Cart.
  • Domain entities: menu item, category, price, availability flag.
  • Component responsibilities: CategoryNav (category list from the API); SearchFilterBar (search input, filter controls, clear action); MenuList (ruled table-of-contents rows: dish name left, tabular price right, brass line-art row marker); QuantityControl (add / increment / decrement); CartIndicator.
  • States: loading — ruled skeleton rows on cream; empty — no dishes in the selected category or no search matches, with a clear-filters action; success — populated ruled list; error — safe error panel with retry; recovery — retry or clear filters restores a usable list.

Food detail

  • Information / state: a single dish — name, description, price, category, image, and availability — with the current cart quantity for that dish.
  • Primary actions: add to cart; increment/decrement quantity; return to Menu or Bestsellers.
  • Supporting actions: open Cart; view related dishes from the same category.
  • Domain entities: menu item, category, cart line.
  • Component responsibilities: DishHero (large appetizing photograph with width/height set and lazy loading below the fold); DishMeta (name, description, tabular price, category); QuantityControl; AddToCartButton (stamp-shadow chilli-red CTA); RelatedDishes.
  • States: loading — cream placeholder block for the photograph and skeleton text; empty — dish not found, with a link back to Menu; success — full dish detail with cart quantity reflected; error — safe error panel with retry; recovery — retry re-fetches the dish.

Bestsellers

  • Information / state: the customer-facing listing of dishes the Admin has curated as bestsellers, each carrying the small chilli-red BESTSELLER stamp.
  • Primary actions: open a bestseller (to Food detail); add to cart; adjust quantity.
  • Supporting actions: open Menu; open Cart.
  • Domain entities: menu item, bestseller flag.
  • Component responsibilities: BestsellerStrip (horizontal scroll-snap strip of tall photo panels with stamp overlays); QuantityControl; CartIndicator.
  • States: loading — cream placeholder panels; empty — no bestsellers curated yet, with a link to the full Menu; success — curated strip renders; error — safe error panel with retry; recovery — retry re-fetches the curated list.
Page 6 of 31

About

  • Information / state: the restaurant and kitchen story, rendered entirely from editable client-provided content. Until real content is supplied, clearly marked editable placeholder copy is shown.
  • Primary actions: read the story; continue to Menu or Contact.
  • Supporting actions: open Delivery availability; open Cart.
  • Domain entities: website settings (About content).
  • Component responsibilities: StoryPanel (ruled editorial panels, Alfa Slab One section titles); PlaceholderNotice (visible marker that content is editable placeholder); ContinueCTA.
  • States: loading — skeleton ruled panels; empty — placeholder notice with no invented facts; success — client content renders; error — safe error panel with retry; recovery — retry re-fetches settings content.

Contact

  • Information / state: customer-facing contact information rendered from editable client-provided content. No phone number, address, or opening hours are invented; where real data is unavailable, clearly marked editable placeholders are shown.
  • Primary actions: read contact details; continue to Menu or Delivery availability.
  • Supporting actions: open Cart; open About.
  • Domain entities: website settings (contact content).
  • Component responsibilities: ContactPanel (ruled block with placeholder-marked fields); PlaceholderNotice; ContinueCTA.
  • States: loading — skeleton ruled block; empty — placeholder notice with no invented facts; success — client contact content renders; error — safe error panel with retry; recovery — retry re-fetches settings content.

Cart

  • Information / state: the persistent cart — every line with dish name, unit price, quantity, and line total, plus the cart total. Cart contents persist across visits.
  • Primary actions: increment/decrement quantity; remove a line; proceed to Checkout / Order; continue shopping to Menu.
  • Supporting actions: open Delivery availability; clear the cart.
  • Domain entities: cart line, menu item, cart total.
  • Component responsibilities: CartLineList (ruled rows with tabular prices); QuantityControl; RemoveLineAction; CartSummary (total, checkout CTA); EmptyCartPanel.
  • States: loading — brief skeleton while persisted cart rehydrates; empty — empty-cart panel with a clear path back to Menu; success — lines and total render; error — if a persisted line references a dish that no longer exists, the line is flagged and can be removed; recovery — removing the stale line restores a valid cart.
Page 7 of 31

Delivery availability

  • Information / state: the address coverage check against managed delivery zones. The customer enters an address or locality and receives a clear in-zone / out-of-zone result. No delivery promise is invented; the result reflects only the zones the Admin has configured.
  • Primary actions: enter an address or locality; run the availability check; continue to Checkout / Order when in zone.
  • Supporting actions: open Menu; open Cart; retry the check.
  • Domain entities: delivery zone, address input.
  • Component responsibilities: AddressCheckForm (validated input, submit control); AvailabilityResult (in-zone confirmation or out-of-zone message); ContinueToCheckoutCTA; ZonePlaceholderNotice (shown when no zones are configured yet).
  • States: loading — submit control disabled with an in-progress indicator; empty — no zones configured, shown as a clearly marked editable placeholder notice rather than a false promise; success — in-zone result with a path to Checkout / Order; error — out-of-zone result, or a safe error panel if the check fails; recovery — the customer may correct the address and re-run the check.

Checkout / Order

  • Information / state: the order review and submission surface — cart summary plus the customer detail fields name, phone, and address, and the resulting order state.
  • Primary actions: enter name, phone, and address; submit the order; on success, view the order confirmation state.
  • Supporting actions: return to Cart to adjust quantities; re-run the delivery availability check.
  • Domain entities: order, order item, customer details, delivery zone.
  • Component responsibilities: OrderSummary (lines and total); CustomerDetailsForm (validated name, phone, address fields with inline errors); PlaceOrderButton (stamp-shadow chilli-red CTA); OrderSuccessState (order reference and confirmation); OrderErrorState (safe, non-technical failure message with retry).
  • States: loading — submit control disabled with an in-progress indicator; empty — cart empty, with a clear path back to Menu; success — order created and the success state shows the order reference; error — validation failure (inline field errors) or submission failure (safe error state with retry); recovery — the customer corrects the fields or retries submission without losing the cart.

Dashboard

  • Information / state: the protected administrative overview and navigation hub — current counts and status summaries for menu items, categories, bestsellers, orders, and delivery zones, plus navigation to every admin destination.
  • Primary actions: navigate to Menu CRUD, Categories CRUD, Bestsellers, Orders, Delivery zones, Rooms/settings, Website settings, Image/media management; sign out.
  • Supporting actions: refresh the overview.
  • Domain entities: menu item, category, order, delivery zone, settings.
  • Component responsibilities: AdminShell (protected layout with navigation); OverviewPanels (ruled summary panels); SignOutAction.
  • States: loading — skeleton summary panels; empty — zero-state panels with a clear path to create the first menu item or category; success — populated summaries; error — safe error panel with retry; recovery — retry re-fetches summaries; an expired session returns the Admin to Login/authentication.
Page 8 of 31

Menu CRUD

  • Information / state: the protected menu item management surface — a list of all menu items with their category, price, availability, and bestseller status, plus create/edit forms.
  • Primary actions: create a menu item; edit an existing item; delete an item; assign a category; set price and availability; toggle bestseller status.
  • Supporting actions: search/filter the item list; attach an image from Image/media management.
  • Domain entities: menu item, category, media asset.
  • Component responsibilities: MenuItemTable (ruled list with row actions); MenuItemForm (validated fields with inline errors); DeleteConfirmDialog; BestsellerToggle.
  • States: loading — skeleton rows; empty — no menu items yet, with a create action; success — item saved and the list reflects the change; error — validation errors inline, or a safe error panel on failure; recovery — the form retains entered values so the Admin can correct and resubmit.

Categories CRUD

  • Information / state: the protected category management surface — a list of all categories with their ordering and item counts, plus create/edit forms.
  • Primary actions: create a category; rename a category; reorder categories; delete a category.
  • Supporting actions: view the items assigned to a category.
  • Domain entities: category, menu item.
  • Component responsibilities: CategoryTable; CategoryForm (validated fields with inline errors); DeleteConfirmDialog (warns when items are still assigned).
  • States: loading — skeleton rows; empty — no categories yet, with a create action; success — category saved and the list reflects the change; error — validation errors inline, or a safe error panel on failure; recovery — the form retains entered values so the Admin can correct and resubmit.

Orders

  • Information / state: the protected order queue — every placed order with its customer name, phone, address, line items, total, and current status.
  • Primary actions: open an order; review its line items and customer details; update its status.
  • Supporting actions: filter the queue by status; search by customer or order reference.
  • Domain entities: order, order item, customer details, delivery zone.
  • Component responsibilities: OrderQueueTable (ruled list with status column); OrderDetailPanel (line items, customer details, total); OrderStatusControl.
  • States: loading — skeleton rows; empty — no orders yet, shown as a zero-state panel; success — queue and detail render with the current status; error — safe error panel with retry; recovery — retry re-fetches the queue.
Page 9 of 31

Delivery zones

  • Information / state: the protected delivery coverage management surface — every configured zone with its name, covered localities or pincodes, and active status.
  • Primary actions: create a zone; edit a zone; deactivate or delete a zone.
  • Supporting actions: review which zones are currently active for the customer-facing availability check.
  • Domain entities: delivery zone.
  • Component responsibilities: ZoneTable; ZoneForm (validated fields with inline errors); ZoneActiveToggle; DeleteConfirmDialog.
  • States: loading — skeleton rows; empty — no zones configured yet, with a create action and a note that the customer-facing availability check will show a placeholder notice until a zone exists; success — zone saved and the list reflects the change; error — validation errors inline, or a safe error panel on failure; recovery — the form retains entered values so the Admin can correct and resubmit.

Rooms/settings

  • Information / state: the protected rooms/settings management surface, applicable to this project only where the existing project requires rooms. Where rooms are not required, this destination presents the applicable settings it owns and states plainly that no rooms are configured.
  • Primary actions: create a room record where applicable; edit an existing record; delete a record; adjust the settings this destination owns.
  • Supporting actions: review the current configuration.
  • Domain entities: room (where applicable), settings.
  • Component responsibilities: RoomsTable (where applicable); RoomForm (validated fields with inline errors); SettingsPanel; NotApplicableNotice (shown when the project requires no rooms).
  • States: loading — skeleton rows; empty — no rooms configured, with a create action or the not-applicable notice; success — record saved and the list reflects the change; error — validation errors inline, or a safe error panel on failure; recovery — the form retains entered values so the Admin can correct and resubmit.

Website settings

  • Information / state: the protected storefront settings and editable content configuration surface — the values that drive the Home, About, and Contact content, including the clearly marked editable placeholders that stand in for unverified client data.
  • Primary actions: edit storefront settings; replace placeholder content with real client content; save changes.
  • Supporting actions: review which fields are still placeholders.
  • Domain entities: website settings.
  • Component responsibilities: SettingsForm (grouped, validated fields with inline errors); PlaceholderFieldMarker (visibly flags fields still holding placeholder content); SaveAction.
  • States: loading — skeleton form; empty — fields render with their current placeholder values; success — settings saved and the storefront reflects the change; error — validation errors inline, or a safe error panel on failure; recovery — the form retains entered values so the Admin can correct and resubmit.
Page 10 of 31

Image/media management

  • Information / state: the protected image and media asset surface — every uploaded asset with its preview, filename, dimensions, and where it is used.
  • Primary actions: upload an image; replace an image; delete an unused image; attach an image to a menu item.
  • Supporting actions: search or filter assets; review which assets are in use.
  • Domain entities: media asset, menu item.
  • Component responsibilities: MediaGrid (ruled asset grid with previews); UploadControl (validated file type and size); AssetUsageList; DeleteConfirmDialog (blocks deletion of in-use assets).
  • States: loading — skeleton asset tiles; empty — no assets yet, with an upload action; success — asset uploaded and the grid reflects it; error — rejected file type or size shown as an inline message, or a safe error panel on failure; recovery — the Admin may select a different file and retry.

3. Functional Requirements

Page 11 of 31

Customer — Discovery

FR-1 — Browse the homepage. As a Customer, I should land on a Home page that presents the fixed section order Header → Hero → Signature Dishes → Bestsellers → Direct Order CTA → Why Choose Us → Kitchen Story → Delivery Area → Footer, so that I immediately understand this is an Indian dhaba in Ghaziabad that delivers.

  • Provenance: explicit.
  • Lifecycle: trigger — I open the site; observable result — the hero headline "Straight from the tandoor, still smoking at your door." with ORDER NOW and VIEW MENU CTAs, followed by the remaining sections in order; access — anonymous; failure/recovery — if the API is unreachable, sections show a safe error panel with retry; continuation — I choose ORDER NOW or VIEW MENU.

FR-2 — Understand the brand and location. As a Customer, I should see copy that clearly communicates Indian food, Ghaziabad, and delivery, so that I know what is being sold, where it is cooked, and that it comes to me.

  • Provenance: explicit.
  • Lifecycle: trigger — I read the hero and Delivery Area sections; observable result — the hero badge and copy state Ghaziabad and direct delivery; access — anonymous; failure/recovery — if settings content is unavailable, a clearly marked editable placeholder is shown rather than an invented claim; continuation — I proceed to the Menu.

FR-3 — Browse the menu by category. As a Customer, I should browse the Menu grouped by category, so that I can find the kind of dish I want.

  • Provenance: explicit.
  • Lifecycle: trigger — I open Menu or select a category; observable result — the ruled menu list shows the dishes in that category with names and tabular prices; access — anonymous; failure/recovery — a safe error panel with retry; continuation — I open a dish or add it to cart.

FR-4 — Search and filter the menu. As a Customer, I should search and filter the menu, so that I can narrow a large catalog to what I want.

  • Provenance: explicit.
  • Lifecycle: trigger — I type a search term or apply a filter; observable result — the list narrows and the active search/filter state is visible; access — anonymous; failure/recovery — if no dish matches, an empty state with a clear-filters action is shown; continuation — I clear the filters or open a matching dish.

FR-5 — Open a food detail page. As a Customer, I should open a dish's detail page, so that I can evaluate it before ordering.

  • Provenance: explicit.
  • Lifecycle: trigger — I select a dish from Menu, Bestsellers, or Home; observable result — the Food detail page shows the dish's name, description, price, category, image, and availability; access — anonymous; failure/recovery — if the dish is not found, an empty state links me back to Menu; continuation — I add the dish to cart or return to browsing.

FR-6 — Browse bestsellers. As a Customer, I should browse a Bestsellers page of dishes the restaurant has curated, so that I can start from what the kitchen is known for.

  • Provenance: explicit.
  • Lifecycle: trigger — I open Bestsellers; observable result — the curated strip renders with the chilli-red BESTSELLER stamp on each dish; access — anonymous; failure/recovery — if no bestsellers are curated, an empty state links me to the full Menu; continuation — I open a bestseller or add it to cart.

FR-7 — Read the About page. As a Customer, I should read the restaurant and kitchen story, so that I can decide whether this is a place I trust.

  • Provenance: explicit.
  • Lifecycle: trigger — I open About; observable result — the story renders from editable client-provided content, with a visible marker where content is still placeholder; access — anonymous; failure/recovery — if settings content is unavailable, a safe error panel with retry; continuation — I continue to Menu or Contact.

FR-8 — Read the Contact page. As a Customer, I should read the restaurant's contact information, so that I can reach the restaurant if I need to.

  • Provenance: explicit.
  • Lifecycle: trigger — I open Contact; observable result — contact details render from editable client-provided content, with a visible marker where content is still placeholder; access — anonymous; failure/recovery — if settings content is unavailable, a safe error panel with retry; continuation — I continue to Menu or Delivery availability.
Page 12 of 31

Customer — Cart

FR-9 — Add a dish to the cart. As a Customer, I should add a dish to my cart, so that I can build an order.

  • Provenance: explicit.
  • Lifecycle: trigger — I press ADD TO CART on a dish; observable result — the dish appears in the cart and the cart indicator updates; access — anonymous; failure/recovery — if the request fails, a safe error message is shown and the dish is not added; continuation — I continue browsing or open Cart.

FR-10 — Control quantities. As a Customer, I should increment and decrement the quantity of each cart line, so that I can order the right amount.

  • Provenance: explicit.
  • Lifecycle: trigger — I press increment or decrement on a cart line; observable result — the line quantity and the cart total update immediately; access — anonymous; failure/recovery — decrementing to zero removes the line, and the empty-cart state appears if no lines remain; continuation — I proceed to Checkout / Order or continue shopping.

FR-11 — Keep my cart across visits. As a Customer, I should find my cart still populated when I return, so that I do not have to rebuild my order.

  • Provenance: explicit.
  • Lifecycle: trigger — I return to the site after leaving; observable result — the cart rehydrates with the same lines and quantities; access — anonymous, with no customer account required; failure/recovery — if a persisted line references a dish that no longer exists, that line is flagged and can be removed; continuation — I remove the stale line and continue to Checkout / Order.

FR-12 — Review the cart. As a Customer, I should review my cart with line totals and a cart total, so that I can confirm my order before submitting it.

  • Provenance: explicit.
  • Lifecycle: trigger — I open Cart; observable result — every line shows dish name, unit price, quantity, and line total, with the cart total below; access — anonymous; failure/recovery — an empty cart shows an empty-cart panel with a path back to Menu; continuation — I proceed to Checkout / Order or return to Menu.
Page 13 of 31

Customer — Delivery and Ordering

FR-13 — Check delivery availability. As a Customer, I should check whether my address is inside a delivery zone, so that I know whether the restaurant can deliver to me before I commit.

  • Provenance: explicit.
  • Lifecycle: trigger — I enter my address or locality on Delivery availability and run the check; observable result — a clear in-zone or out-of-zone result based only on the zones the Admin has configured; access — anonymous; failure/recovery — if no zones are configured, a clearly marked editable placeholder notice is shown instead of a false promise, and if the check fails a safe error panel with retry is shown; continuation — when in zone, I continue to Checkout / Order; when out of zone, I may correct my address and re-run the check.

FR-14 — Enter my customer details. As a Customer, I should enter my name, phone, and address at checkout, so that the restaurant knows who ordered and where to deliver.

  • Provenance: explicit.
  • Lifecycle: trigger — I reach Checkout / Order; observable result — the form accepts name, phone, and address with inline validation; access — anonymous; failure/recovery — invalid fields show inline errors and the form retains my entries; continuation — I submit the order.

FR-15 — Place an order. As a Customer, I should submit my order, so that the restaurant receives it.

  • Provenance: explicit.
  • Lifecycle: trigger — I press the place-order control with a valid cart and valid details; observable result — an order and its order items are created through the REST API and persisted in the database; access — anonymous; failure/recovery — a submission failure shows a safe, non-technical error state with a retry action that preserves my cart and details; continuation — I see the order success state.

FR-16 — See order success or error states. As a Customer, I should see a clear success state when my order is placed and a clear error state when it is not, so that I know whether my food is coming.

  • Provenance: explicit.
  • Lifecycle: trigger — my order submission resolves; observable result — the success state shows my order reference and confirmation, and the error state shows a safe message with a retry action; access — anonymous; failure/recovery — retrying from the error state re-submits without losing my cart; continuation — after success I may return to Menu or Home.

FR-17 — See loading, empty, and error states throughout. As a Customer, I should see honest loading, empty, and error states on every data-driven surface, so that I am never shown a blank screen or a fabricated result.

  • Provenance: explicit.
  • Lifecycle: trigger — any data fetch on Home, Menu, Food detail, Bestsellers, About, Contact, Cart, Delivery availability, or Checkout / Order; observable result — a cream skeleton while loading, a meaningful empty state when there is no data, and a safe error panel with retry on failure; access — anonymous; failure/recovery — retry re-fetches without a full page reload; continuation — I continue from the recovered state.
Page 14 of 31

Admin — Access

FR-18 — Establish admin access before first use. As an Admin, I should have my administrative account provisioned by the operator before I first sign in, so that protected administration is bound to the correct person.

  • Provenance: required_inference.
  • Lifecycle: trigger — the operator provisions the admin account; observable result — an admin user record exists with a hashed password and no protected state is reachable without it; access — provisioning is an operator action outside the customer storefront; failure/recovery — if no admin account exists, Login/authentication cannot establish a session and no protected destination is reachable; continuation — I sign in through Login/authentication.

FR-19 — Sign in to the admin dashboard. As an Admin, I should sign in through Login/authentication, so that I can reach the protected dashboard.

  • Provenance: explicit (Login/authentication) with required_inference for the returning-verification mechanics.
  • Lifecycle: trigger — I submit my credentials on Login/authentication; observable result — an authenticated admin session is established and I am taken to Dashboard; access — Login/authentication is reachable anonymously, while every protected destination remains unavailable until the session exists; failure/recovery — invalid credentials or a rate-limited response produce a safe, non-technical message and the form stays usable for retry; continuation — I reach Dashboard, or I retry after the rate-limit window.

FR-20 — Stay signed in and sign out. As an Admin, I should have my session persist while I work and be able to sign out, so that I am not re-authenticating on every action and can end my session deliberately.

  • Provenance: required_inference.
  • Lifecycle: trigger — I navigate between admin destinations, or I choose sign out; observable result — my session persists across admin navigation, and signing out ends it and returns me to Login/authentication; access — protected; failure/recovery — an expired or invalid session returns me to Login/authentication rather than showing protected state; continuation — I sign in again.
Page 15 of 31

Admin — Storefront Management

FR-21 — View the dashboard overview. As an Admin, I should see an overview of menu items, categories, bestsellers, orders, and delivery zones, so that I can see the state of the storefront at a glance.

  • Provenance: explicit.
  • Lifecycle: trigger — I open Dashboard after signing in; observable result — summary panels show current counts and statuses with navigation to every admin destination; access — protected; failure/recovery — a safe error panel with retry, and an expired session returns me to Login/authentication; continuation — I navigate to the destination I need.

FR-22 — Manage menu items. As an Admin, I should create, read, update, and delete menu items, so that the storefront menu is accurate.

  • Provenance: explicit.
  • Lifecycle: trigger — I create, edit, or delete a menu item on Menu CRUD; observable result — the item is persisted through the REST API and the storefront menu reflects the change; access — protected; failure/recovery — validation errors appear inline and the form retains my entries so I can correct and resubmit; continuation — I return to the item list or continue editing.

FR-23 — Manage categories. As an Admin, I should create, read, update, and delete categories, so that customers can browse the menu by the groupings the restaurant actually uses.

  • Provenance: explicit.
  • Lifecycle: trigger — I create, rename, reorder, or delete a category on Categories CRUD; observable result — the category is persisted and the storefront category navigation reflects the change; access — protected; failure/recovery — deleting a category that still has items assigned warns me first, and validation errors appear inline with my entries retained; continuation — I return to the category list.

FR-24 — Curate bestsellers. As an Admin, I should mark dishes as bestsellers, so that the Bestsellers page and the homepage Bestsellers section show what the kitchen is known for.

  • Provenance: explicit.
  • Lifecycle: trigger — I toggle bestseller status on a menu item; observable result — the dish appears in or disappears from the customer-facing Bestsellers listing; access — protected; failure/recovery — a failed toggle shows a safe error and leaves the previous state intact; continuation — I continue curating or return to Dashboard.

FR-25 — Review and manage orders. As an Admin, I should review the order queue and each order's details, so that I can act on incoming orders.

  • Provenance: explicit.
  • Lifecycle: trigger — I open Orders; observable result — the queue lists every placed order with customer name, phone, address, line items, total, and status, and I can open an order to see its full detail and update its status; access — protected; failure/recovery — a safe error panel with retry; continuation — I return to the queue or update another order.

FR-26 — Manage delivery zones. As an Admin, I should create, edit, deactivate, and delete delivery zones, so that the customer-facing delivery availability check reflects real coverage.

  • Provenance: explicit.
  • Lifecycle: trigger — I create, edit, deactivate, or delete a zone on Delivery zones; observable result — the zone is persisted and the customer-facing availability check uses the updated coverage; access — protected; failure/recovery — validation errors appear inline with my entries retained, and deleting a zone asks for confirmation; continuation — I return to the zone list.

FR-27 — Manage rooms/settings where applicable. As an Admin, I should manage rooms/settings where the existing project requires them, so that any room records the project needs stay accurate.

  • Provenance: explicit, scoped by "if applicable" / "if the existing project requires them."
  • Lifecycle: trigger — I open Rooms/settings; observable result — where the project requires rooms, I can create, edit, and delete room records; where it does not, the destination states plainly that no rooms are configured and presents the settings it owns; access — protected; failure/recovery — validation errors appear inline with my entries retained; continuation — I return to the list or Dashboard.

FR-28 — Manage website settings and editable content. As an Admin, I should edit the storefront settings and the editable content that drives Home, About, and Contact, so that I can replace placeholder content with real client data.

  • Provenance: explicit.
  • Lifecycle: trigger — I edit settings on Website settings and save; observable result — the settings persist and the storefront reflects them, and fields still holding placeholder content remain visibly marked; access — protected; failure/recovery — validation errors appear inline with my entries retained; continuation — I review the storefront or continue editing.

FR-29 — Manage images and media. As an Admin, I should upload, replace, and delete image and media assets and attach them to menu items, so that the storefront's food photography is current.

  • Provenance: explicit.
  • Lifecycle: trigger — I upload, replace, or delete an asset on Image/media management, or attach one to a menu item; observable result — the asset is stored and available to the storefront, and in-use assets show where they are used; access — protected; failure/recovery — a rejected file type or size shows an inline message and I may select a different file, and deleting an in-use asset is blocked with an explanation; continuation — I return to the asset grid.
Page 16 of 31

Cross-cutting

FR-30 — Serve the storefront and admin from the production API. As the system, I should serve all storefront and admin data from the REST API at https://cafe-backend-rfwe.onrender.com/api/v1, so that the frontend never fabricates data.

  • Provenance: explicit.
  • Lifecycle: trigger — any data-driven surface loads; observable result — data comes from the real backend and database; access — the storefront is anonymous, admin endpoints require an authenticated admin session; failure/recovery — failures surface as the safe error states defined above; continuation — retry.

FR-31 — Enforce security controls. As the system, I should enforce the specified security controls, so that the application is safe to operate in production.

  • Provenance: explicit.
  • Lifecycle: trigger — any request to the API; observable result — secrets live only in environment variables and never reach the frontend, CORS is strictly limited to https://cafe-frontend-alpha.vercel.app and https://cafe-admin-gamma.vercel.app, admin authentication uses JWT/session with hashed passwords, requests are validated, rate limiting is applied, Helmet/security headers are set, error responses are safe and non-technical, and every admin API is authorized; access — as specified per endpoint; failure/recovery — rejected requests return safe errors without internal detail; continuation — the client retries or corrects the request.

FR-32 — Meet SEO and performance requirements. As the system, I should meet the specified SEO and performance requirements, so that the site is discoverable locally and fast on mobile.

  • Provenance: explicit.
  • Lifecycle: trigger — a page is crawled or loaded; observable result — semantic HTML, local SEO for Ghaziabad, metadata and Open Graph tags, optimized WebP/AVIF images with lazy loading and responsive sizes, optimized fonts, fast mobile performance, accessibility, and no horizontal overflow; Restaurant/LocalBusiness schema is emitted only when real data exists; access — anonymous; failure/recovery — where real data is unavailable, no structured data is emitted rather than fabricated data; continuation — normal browsing.

4. User Personas

Page 17 of 31

Customer

Product context. A Ghaziabad local — a family member ordering dinner, a student ordering in, or an office worker ordering lunch — who wants Indian dhaba/cafe food that feels cooked rather than manufactured, delivered directly. They arrive on a phone, often on a slow connection, and they decide quickly.

Primary goal. Find the dishes they want, confirm the restaurant delivers to their address, and place an order with their name, phone, and address — without creating an account and without being misled by invented claims.

Distinct accepted responsibilities. The Customer is the only persona who browses the public catalog, searches and filters it, opens dish details, builds and persists a cart, adjusts quantities, runs the delivery availability check, and submits an order. They are the sole initiator of the order lifecycle.

Relevant inputs and decisions. Which category to browse; what to search for; which dish to open; how many of each dish to order; whether their address is inside a delivery zone; whether to submit or go back and adjust the cart. Their inputs are their search terms, filter selections, quantities, and their name, phone, and address.

Interactions with other accepted participants. The Customer's order is received by the Admin, who reviews it in the Orders queue. The Customer never interacts with the Admin directly inside the product; the handoff is the persisted order. The Customer's delivery availability result depends entirely on the zones the Admin has configured, and the menu they browse depends entirely on the items and categories the Admin has published.

Observable success. The Customer sees an in-zone result for their address, submits checkout, and receives an order success state showing their order reference. Their cart persists if they leave and return.

What makes this role different. The Customer is anonymous and stateless from the system's perspective — no account, no login, no profile. Their continuity is carried by the persisted cart and the created order, not by an identity. Every surface they touch is public.

Page 18 of 31

Admin

Product context. The restaurant operator — the person who actually runs the dhaba and owns the truth of what is on the menu, where the kitchen delivers, and what orders have come in. They work from a desktop or laptop, in short bursts between kitchen work, and they need changes to take effect on the storefront immediately.

Primary goal. Keep the storefront accurate: the right dishes in the right categories at the right prices, the right dishes marked as bestsellers, the right delivery zones active, real client content in place of placeholders, and the order queue reviewed.

Distinct accepted responsibilities. The Admin is the only persona who authenticates, and the only one who creates, reads, updates, and deletes menu items and categories; curates bestsellers; reviews and manages orders; manages delivery zones; manages rooms/settings where applicable; edits website settings and editable content; and manages image and media assets.

Relevant inputs and decisions. Dish names, descriptions, prices, categories, availability, and images; category names and ordering; which dishes are bestsellers; which localities or pincodes each delivery zone covers and whether it is active; the real client content that replaces each placeholder; which media assets to upload, replace, or delete. Their key decisions are what to publish, what to unpublish, and which zones to keep active.

Interactions with other accepted participants. The Admin receives the Customer's orders in the Orders queue and acts on them. The Admin's publishing decisions directly determine what the Customer can browse, what the Customer can add to cart, and whether the Customer's address returns an in-zone result. The Admin never sees the Customer's browsing session — only the persisted order.

Observable success. A saved menu item appears on the storefront menu; a saved category appears in the customer's category navigation; a toggled bestseller appears on the Bestsellers page; a saved zone changes the customer's availability result; a saved setting replaces a placeholder on Home, About, or Contact; a reviewed order shows its current status in the queue.

What makes this role different. The Admin is authenticated, stateful, and privileged: every destination they use is protected, every write they make is authorized server-side, and their changes are the single source of truth for everything the Customer sees. Their work is editorial and operational rather than transactional.

Page 19 of 31

5. Core User Flows

Flow 1 — Customer discovers the dhaba and browses the menu

  1. The Customer opens the site on a phone and lands on Home. The hero shows the headline "Straight from the tandoor, still smoking at your door." with ORDER NOW and VIEW MENU, and the badge and copy state Indian food, Ghaziabad, and direct delivery.
  2. The Customer scrolls through Signature Dishes, Bestsellers, Direct Order CTA, Why Choose Us, Kitchen Story, and Delivery Area in that order. Dish panels load from the API; if the API is unreachable, each section shows a safe error panel with a retry action rather than a blank gap.
  3. The Customer presses VIEW MENU and arrives on Menu. The ruled list renders dishes grouped by category with tabular prices.
  4. The Customer selects a category, then types a search term into the search field. The list narrows and the active search and filter state is visible. If nothing matches, an empty state offers a clear-filters action.
  5. The Customer selects a dish and arrives on Food detail, which shows the dish's name, description, price, category, image, and availability.
  6. Next step: the Customer adds the dish to cart, or returns to Menu to keep browsing.

Flow 2 — Customer builds a persistent cart

  1. On Food detail, the Customer presses ADD TO CART. The dish appears in the cart and the cart indicator updates. If the request fails, a safe error message appears and the dish is not added.
  2. The Customer continues browsing and adds a second dish from Menu using the inline quantity control.
  3. The Customer opens Cart and reviews every line — dish name, unit price, quantity, and line total — with the cart total below.
  4. The Customer presses increment on one line and decrement on another. The quantities and the total update immediately. Decrementing a line to zero removes it.
  5. The Customer leaves the site and returns later. Cart rehydrates with the same lines and quantities, because the cart persists across visits without any customer account. If a persisted line references a dish that no longer exists, that line is flagged and can be removed.
  6. Next step: the Customer proceeds to check delivery availability, or continues shopping.
Page 20 of 31

Flow 3 — Customer checks delivery availability

  1. The Customer opens Delivery availability and enters their address or locality.
  2. The Customer runs the check. The result is computed against the delivery zones the Admin has configured — nothing else.
  3. In zone: the Customer sees an in-zone confirmation and a clear path to Checkout / Order.
  4. Out of zone: the Customer sees an out-of-zone message and may correct the address and re-run the check.
  5. No zones configured: the Customer sees a clearly marked editable placeholder notice explaining that delivery coverage has not been published yet — never an invented delivery promise.
  6. Check fails: the Customer sees a safe error panel with a retry action.
  7. Next step: the Customer continues to Checkout / Order, or returns to Menu.

Flow 4 — Customer places an order

  1. The Customer opens Checkout / Order with a populated cart. The order summary shows the lines and the total.
  2. The Customer enters their name, phone, and address. Invalid fields show inline errors and the form retains what was entered.
  3. The Customer presses the place-order control. The control is disabled with an in-progress indicator while the request is in flight.
  4. The order and its order items are created through the REST API at https://cafe-backend-rfwe.onrender.com/api/v1 and persisted in the database.
  5. Success: the Customer sees the order success state with their order reference and confirmation. Next step: return to Menu or Home.
  6. Failure: the Customer sees a safe, non-technical error state with a retry action. Retrying re-submits without losing the cart or the entered details.
  7. Empty cart: if the cart is empty, the Customer sees an empty state with a clear path back to Menu.
Page 21 of 31

Flow 5 — Admin signs in and reaches the dashboard

  1. The operator has already provisioned the Admin's account with a hashed password. No protected state is reachable without it.
  2. The Admin opens Login/authentication — the anonymous entry boundary — and enters their credentials.
  3. The Admin submits. The control is disabled with an in-progress indicator while the request is in flight.
  4. Success: an authenticated admin session is established and the Admin arrives on Dashboard, which shows summary panels for menu items, categories, bestsellers, orders, and delivery zones, with navigation to every admin destination.
  5. Failure: invalid credentials or a rate-limited response produce a safe, non-technical message. The form stays usable and the Admin may retry after the rate-limit window.
  6. The Admin works across admin destinations; the session persists across admin navigation. An expired or invalid session returns the Admin to Login/authentication rather than showing protected state.
  7. Next step: the Admin navigates to the destination they need, or signs out to end the session.

Flow 6 — Admin publishes a menu item and a category

  1. From Dashboard, the Admin opens Categories CRUD and creates a category. Validation errors appear inline and the form retains entries so the Admin can correct and resubmit. The saved category appears in the list and in the customer's category navigation.
  2. The Admin opens Menu CRUD and creates a menu item: name, description, price, category, and availability. The Admin attaches an image chosen from Image/media management.
  3. The Admin saves. The item is persisted through the REST API and appears in the storefront menu under the assigned category.
  4. The Admin toggles bestseller status on the item. The dish appears on the customer-facing Bestsellers page and in the homepage Bestsellers section.
  5. Failure: validation errors appear inline with entries retained; a failed bestseller toggle shows a safe error and leaves the previous state intact.
  6. Next step: the Admin returns to the item list or continues editing.

Flow 7 — Admin configures delivery coverage

  1. From Dashboard, the Admin opens Delivery zones and creates a zone with its name, covered localities or pincodes, and active status.
  2. The Admin saves. The zone is persisted and the customer-facing Delivery availability check immediately uses the updated coverage.
  3. The Admin deactivates a zone. Customers in that area now receive an out-of-zone result.
  4. Empty state: if no zones are configured, the zone list shows a create action and notes that the customer-facing availability check will show a placeholder notice until a zone exists.
  5. Failure: validation errors appear inline with entries retained; deleting a zone asks for confirmation first.
  6. Next step: the Admin returns to the zone list or Dashboard.
Page 22 of 31

Flow 8 — Admin reviews an incoming order

  1. The Customer's order from Flow 4 is persisted and appears in the Admin's Orders queue.
  2. The Admin opens Orders and sees the queue with each order's customer name, phone, address, line items, total, and status.
  3. The Admin opens a specific order and reviews its line items and customer details in the detail panel.
  4. The Admin updates the order's status. The queue reflects the change.
  5. Failure: a safe error panel with retry; retry re-fetches the queue.
  6. Next step: the Admin returns to the queue or opens another order.

Flow 9 — Admin replaces placeholder content and manages media

  1. From Dashboard, the Admin opens Website settings. Fields still holding placeholder content are visibly marked.
  2. The Admin replaces the placeholder values that drive Home, About, and Contact with real client content and saves. The storefront reflects the change, and any field still holding placeholder content remains marked.
  3. The Admin opens Image/media management, uploads a new food photograph, and attaches it to a menu item. The asset appears in the grid with its preview and usage.
  4. The Admin attempts to delete an asset that is in use. The deletion is blocked with an explanation of where the asset is used.
  5. Failure: a rejected file type or size shows an inline message and the Admin may select a different file; validation errors on settings appear inline with entries retained.
  6. Next step: the Admin reviews the storefront or continues editing.

Flow 10 — Admin manages rooms/settings where applicable

  1. From Dashboard, the Admin opens Rooms/settings.
  2. Where the existing project requires rooms: the Admin creates, edits, or deletes room records, with validation errors inline and entries retained on failure.
  3. Where the project does not require rooms: the destination states plainly that no rooms are configured and presents the settings it owns.
  4. Next step: the Admin returns to the list or Dashboard.
Page 23 of 31

6. Visuals Colors and Theme

The creative direction is authoritative for this section. The muse is Aaron Draplin; the headline idea is bold, honest, hand-built dhaba swagger — thick strokes, badge marks, workwear colour, plain-spoken all-caps labels, and poster-like ruled panels. This is deliberately the opposite of the smooth fast-food template and the blue-white marketplace look.

Colour tokens (light mode)

RoleHexUsage
Background#F5EDDDWarm cream/ivory page ground, ~70% of every screen — spacious, paper-like
Surface#EFE3CDRuled panels and card grounds so nothing floats on pure white
Text#2B1A0FDeep walnut — all display type, rules, and badge outlines
Primary#C1271CChilli red — reserved strictly for CTAs (ORDER NOW, ADD TO CART, checkout submit) and the tiny BESTSELLER stamp; never decoration
Accent#C08A2EMuted brass/saffron — hairline rules, section numbers, price ticks, line-art motif strokes, hover underlines
Muted#7A6A54Muted taupe — metadata, captions, disabled states
Page 24 of 31

Typography

  • Headings: Alfa Slab One, heavy slab weight, all-caps for section titles and the hero, tight tracking (-0.01em), oversized and stacked.
  • Body: Oswald for all body, labels, prices, and UI in medium/semibold weights, often uppercase with wide letter-spacing (0.08em) for micro-labels such as SIGNATURE, GHAZIABAD, DELIVERY.
  • No italic. No thin weights anywhere.
  • Scale: 1.333 modular.
    • Display hero: clamp(52px, 9vw, 128px)
    • Section title: clamp(34px, 5vw, 64px)
    • Card title: clamp(20px, 2.4vw, 28px)
    • Body: 16–18px
    • Micro-label: 11–12px uppercase, 0.08em tracking
    • Price numerals: Oswald semibold, tabular

Shape language

Hard-edged rectangular panels with 2px solid walnut outlines. Badge/stamp motifs (circular and shield-shaped) with 3px strokes. Chunky ruled dividers. No soft radii above 4px anywhere. Buttons are rectangular with a 3px offset shadow — like a stamped block — rather than a rounded pill. Indian line-art motifs (tandoor, chilli, mortar-pestle, jalebi curl, star anise) are drawn as 2px brass-stroke icons with the same weight as the rules.

Page 25 of 31

Layout

Poster-like stacked sections on a 12-column grid with a strong left rule column. Section headers sit as badge/panel rows: a small numbered stamp (01, 02, 03) in brass, then a walnut-ruled bar carrying the section title in Alfa Slab One. The hero is a two-panel composition: type panel on the left, full-bleed food photograph on the right, separated by a hard vertical rule. The menu grid is a ruled table-of-contents style list, not a grid of identical cards. The bestsellers row is a horizontal scroll-snap strip of tall photo panels with stamp overlays. The footer is a chunky ruled block with badge, address placeholder, and a marquee ticker of dish names above it.

Imagery

Large, appetizing, top-down and 45° food photography on warm cream or dark walnut grounds — tandoori platters, dal makhani in a copper handi, fresh naan pulled from the tandoor, chai in a kulhad. Photography is the hero; food is never illustrated. Supporting imagery is thick-line vector line-art in brass stroke on cream (tandoor, chilli, mortar, wheat sheaf, clay pot). No stock people, no lifestyle clichés, no gradients, no glass. All images are served as WebP/AVIF with width/height set, loading="lazy" below the fold, and a flat cream placeholder block while loading.

Page 26 of 31

Readability and overflow

Headlines, wordmarks, labels, numbers, card text, and controls stay entirely inside the viewport and their container at 375px, 768px, and 1280px, wrapping or scaling (for example font-size: clamp(...) with its mobile size) to fit, and no other element covers any part of them. Imagery, decoration, and motion may be cropped, bled off an edge, rotated, overlapped, or cut exactly as the direction asks, as long as they cover no readable text or control. Moving and scrollable content (the dish ticker, the bestsellers strip) may cross the viewport or container edge by design and is judged by whether it actually moves or scrolls and whether every item becomes fully readable as it passes. Under prefers-reduced-motion it stops and shows whole items, wrapping into rows or sitting in a horizontally scrollable row (overflow-x: auto).

7. Signature Design Concept

The Stamped Dhaba Hero — a two-panel hard-split hero on cream (#F5EDDD), not a centred SaaS hero.

  • Left panel (about 42% width on desktop, full width on mobile, stacked): a small brass badge reading GHAZIABAD · DIRECT DELIVERY with a thin ruled underline, then the headline "Straight from the tandoor, still smoking at your door." set in Alfa Slab One at clamp(52px, 9vw, 128px), stacked across 3–4 lines, walnut (#2B1A0F), flush-left, with the word tandoor underlined in chilli red as a single typographic gesture.
  • Below the headline, two rectangular buttons side by side: ORDER NOW (solid chilli red #C1271C, cream text, 3px offset walnut shadow) and VIEW MENU (cream ground, 2px walnut outline, walnut text).
  • Right panel: a full-bleed, edge-to-edge food photograph — a tandoori platter with visible steam — that bleeds off the right and bottom edges of the viewport, with a hard 2px walnut vertical rule where the two panels meet.
  • A thin brass hairline runs the full width under the entire hero, and a small brass line-art tandoor motif sits at the bottom-left of the type panel.
  • No gradient, no blob, no glass card, no centred stack.

The concept recomposes only accepted content and controls: the exact headline, the two exact CTAs, the Ghaziabad/delivery communication, and the food photography. It introduces no new behaviour, page, or destination.

Page 27 of 31

8. Interaction Model & Motion Direction

Interaction Model: Static Motion Tempo: restrained Hero Dimensionality: flat

The direction's tempo is restrained and mechanical, and its hero dimensionality is flat; this section copies that decision rather than re-deciding it.

Landing Hero Motion Brief

  • Focal subject: the full-bleed tandoori platter photograph in the right panel, with visible steam, bleeding off the right and bottom edges.
  • Input → transformation → outcome thesis: as the Home page loads, the type panel's badge, headline, and the two CTAs settle into place with a 150–220ms snap transition and no bounce, while the photograph holds still — the outcome is a composed, poster-like first frame in which the headline and both CTAs are fully readable and the food photograph carries the appetite.
  • Motion vocabulary: restrained and mechanical — 150–220ms snap transitions, no bounce, no parallax. On scroll, panels slide up 12px and fade in once (IntersectionObserver), and stamp badges rotate −3° in on entry. Hover on a dish panel swaps its stamp from brass to chilli red and nudges it 2px. One continuous ticker marquee of dish names runs above the footer, pausing on hover.
  • Composed first frame: cream ground; brass GHAZIABAD · DIRECT DELIVERY badge with ruled underline; the stacked Alfa Slab One headline flush-left with tandoor underlined in chilli red; ORDER NOW and VIEW MENU side by side as hard rectangles with the 3px walnut offset shadow; the 2px walnut vertical rule; the full-bleed tandoori platter on the right; the brass hairline beneath; the brass line-art tandoor motif at the bottom-left of the type panel.
  • Reduced-motion state: under prefers-reduced-motion, all entry transitions and the −3° badge rotation are removed and the hero renders as a static composed frame; the dish-name ticker stops entirely and its items wrap into rows so every dish name is fully readable.

No user-requested 3D/WebGL hero exists, and the direction's hero dimensionality is flat, so no Canvas/R3F/Drei scene is required.

Page 28 of 31

9. Non-Functional Requirements

NFR-1 — Secrets never reach the frontend. Database credentials and all secrets live only in environment variables on the backend; they are never exposed in frontend code or bundles. Provenance: explicit. Rationale: prevents credential leakage to any visitor.

NFR-2 — Strict CORS. The API accepts cross-origin requests only from https://cafe-frontend-alpha.vercel.app and https://cafe-admin-gamma.vercel.app. Provenance: explicit. Rationale: limits which origins can call the API.

NFR-3 — Admin authentication and authorization. Admin authentication uses JWT/session; passwords are hashed; every admin API is authorized server-side. Provenance: explicit. Rationale: protects all management operations and the order queue.

NFR-4 — Request validation, rate limiting, and security headers. All requests are validated, rate limiting is applied, and Helmet/security headers are set. Provenance: explicit. Rationale: reduces abuse and common web attack surface.

NFR-5 — Safe error responses. Error responses are safe and non-technical, exposing no internal detail, stack traces, or credentials. Provenance: explicit. Rationale: prevents information disclosure.

NFR-6 — Semantic HTML and accessibility. Pages use semantic HTML and are accessible. Provenance: explicit. Rationale: assistive-technology support and crawlability.

NFR-7 — Local SEO for Ghaziabad. Pages carry local SEO for Ghaziabad plus metadata and Open Graph tags. Provenance: explicit. Rationale: local discoverability.

NFR-8 — Structured data only with real data. Restaurant/LocalBusiness schema is emitted only when real data exists; placeholder content is never published as structured data. Provenance: explicit. Rationale: avoids publishing fabricated business facts.

NFR-9 — Image optimization. Images are served as WebP/AVIF with width/height set, lazy loading below the fold, and responsive sizes. Provenance: explicit. Rationale: mobile performance and layout stability.

NFR-10 — Optimized fonts and fast mobile performance. Fonts are optimized and mobile performance is fast. Provenance: explicit. Rationale: the audience is mobile-first.

NFR-11 — Mobile-first, fully responsive, no horizontal overflow. The site is mobile-first and fully responsive with no horizontal overflow. Provenance: explicit. Rationale: the primary device is a phone.

NFR-12 — Persistent database. The backend uses a persistent database, not in-memory or fabricated data. Provenance: explicit. Rationale: orders, menu, zones, and settings must survive restarts.

NFR-13 — Clean, deployment-ready architecture. The architecture stays clean and deployment-ready, with no unnecessary libraries. Provenance: explicit. Rationale: maintainability and a small dependency surface.

NFR-14 — Deployment targets. The frontend and admin deploy to Vercel; the backend deploys to Render. Provenance: explicit. Rationale: the specified production topology.

NFR-15 — Build and route verification. Build and type checks pass, all routes are verified, and the cart, order, and admin flows are verified before deployment. Provenance: explicit. Rationale: the deliverable is a working application, not a mockup.

Page 29 of 31

10. Tech Stack

Source-specified choices are preserved exactly.

  • Frontend and Admin: React, deployed to Vercel.
  • Backend: a clean REST API deployed to Render, served at https://cafe-backend-rfwe.onrender.com with the frontend API base https://cafe-backend-rfwe.onrender.com/api/v1.
  • Database: a persistent database backing the models for users/admins, menu/categories, orders/order items, delivery zones, settings, and rooms where the existing project requires them.
  • Security middleware: JWT/session authentication, password hashing, request validation, rate limiting, and Helmet/security headers.
  • Deployment: Vercel for the frontend and admin; Render for the backend.

[Default — not specified by user] The backend framework is not named in the source; a Python/FastAPI service is used, as it satisfies the clean REST API, request validation, and security-middleware requirements without adding unnecessary libraries.

[Default — not specified by user] Containerization with Docker/docker-compose is used for local development parity. Kubernetes is not used, because the specified deployment targets (Vercel + Render) do not require it.

11. Assumptions and Constraints

Assumptions

  • A-1. The two personas — Customer and Admin — are the complete active-human set for this product. No other human role is in scope.
  • A-2. The customer storefront requires no customer account; cart persistence is achieved without one.
  • A-3. The Admin account is provisioned by the operator before first administrative use; the product does not include self-service admin signup.
  • A-4. Rooms are in scope only if the existing project requires them; where it does not, the Rooms/settings destination states that plainly and presents the settings it owns.
  • A-5. All restaurant-specific facts — address, phone, opening hours, prices, ratings, reviews, and delivery promises — are editable placeholder content until the client supplies real data.
Page 30 of 31

Constraints

  • C-1. Do not spend time generating a long PRD or documentation.
  • C-2. Do not copy KFC, McDonald's, Pizza Hut, Domino's, Swiggy, or Zomato.
  • C-3. No glassmorphism, neon, excessive gradients, or crowded sections.
  • C-4. Do NOT invent real restaurant facts, phone numbers, prices, ratings, reviews, address, opening hours, or delivery promises; use clearly marked editable placeholder content where real client data is unavailable.
  • C-5. Never expose database credentials or secrets in the frontend.
  • C-6. Use environment variables for secrets.
  • C-7. Strict CORS limited to https://cafe-frontend-alpha.vercel.app and https://cafe-admin-gamma.vercel.app.
  • C-8. JWT/session authentication for admin; password hashing; request validation; rate limiting; Helmet/security headers; safe error responses; authorization for admin APIs.
  • C-9. Restaurant/LocalBusiness schema only with real data.
  • C-10. Do not add unnecessary libraries.
  • C-11. Do not create fake API responses when real backend/database functionality can be implemented.
  • C-12. Build the actual working application, not a mockup.
  • C-13. Mobile-first and fully responsive; no horizontal overflow.
  • C-14. Deployment target: Vercel (frontend/admin) + Render (backend).
  • C-15. The generic indigo/blue-on-white SaaS template is forbidden for this project.
Page 31 of 31

12. Glossary

  • Admin — the restaurant operator persona; the only authenticated persona, responsible for menu, categories, bestsellers, orders, delivery zones, rooms/settings, website settings, and media.
  • Bestseller — a menu item the Admin has marked as curated; it appears on the Bestsellers page and the homepage Bestsellers section with the chilli-red BESTSELLER stamp.
  • Cart — the Customer's persistent, account-free collection of selected dishes and quantities, retained across visits.
  • Category — a grouping of menu items used for browsing on the Menu page.
  • Customer — the anonymous Ghaziabad local persona who browses, builds a cart, checks delivery availability, and places an order.
  • Delivery availability — the customer-facing check that determines whether an entered address falls inside a configured delivery zone.
  • Delivery zone — an Admin-managed coverage record (name, covered localities or pincodes, active status) that the delivery availability check consults.
  • Editable placeholder content — clearly marked stand-in content used wherever real client data is unavailable; it is never published as structured data and is never presented as a real restaurant fact.
  • Food detail — the page presenting a single dish's name, description, price, category, image, and availability.
  • Menu item — a dish record with name, description, price, category, availability, image, and bestseller status.
  • Order — the persisted record created when a Customer submits checkout, comprising customer name, phone, and address, plus its order items and total.
  • Order item — a single line of an order, referencing a menu item and a quantity.
  • Rooms/settings — the protected admin destination for room records where the existing project requires them, and for the settings it owns where it does not.
  • Session — the authenticated admin state established through Login/authentication and carried as a JWT/session.
  • Website settings — the Admin-managed storefront configuration and editable content that drives Home, About, and Contact.

No completed page designs yet.

Completed design pages will appear here when they are ready to preview.

Login/authentication: 1. Submit admin credentials
Login/authentication: 2. Retry after failed sign-in
Dashboard: 3. View overview summaries
Categories CRUD: 4. Create category
Categories CRUD: 5. Rename or reorder category
Categories CRUD: 6. Delete category with confirmation
Categories CRUD: 7. Correct inline validation errors
Menu CRUD: 8. Create menu item
Menu CRUD: 9. Assign category and set price
Menu CRUD: Edit existing item
Menu CRUD: Delete menu item
Menu CRUD: 10. Correct inline validation errors
Menu CRUD: 11. Toggle bestseller status
Image/media management: 12. Upload image asset
Image/media management: 13. Attach asset to menu item
Image/media management: 14. Block deleting in-use asset
Image/media management: 15. Retry with valid file
Bestsellers: 16. Verify curated bestsellers
Delivery zones: 1. Create delivery zone
Delivery zones: 2. Deactivate zone
Delivery zones: 3. Delete zone with confirmation
Delivery zones: 4. Correct inline validation errors
Orders: 1. Review order queue
Orders: 2. Open order and review details
Orders: 3. Update order status
Orders: 4. Filter or search queue
Website settings: 17. Replace placeholder content
Website settings: 18. Save storefront settings
Website settings: 19. Correct inline validation errors
Rooms/settings: 20. Create or edit room record
Rooms/settings: 21. View not-applicable notice and settings
Dashboard: 22. Sign out

No completed page designs yet.

Completed design pages will appear here when they are ready to preview.

Login/authentication: 1. Submit admin credentials
Login/authentication: 2. Retry after failed sign-in
Dashboard: 3. View overview summaries
Categories CRUD: 4. Create category
Categories CRUD: 5. Rename or reorder category
Categories CRUD: 6. Delete category with confirmation
Categories CRUD: 7. Correct inline validation errors
Menu CRUD: 8. Create menu item
Menu CRUD: 9. Assign category and set price
Menu CRUD: Edit existing item
Menu CRUD: Delete menu item
Menu CRUD: 10. Correct inline validation errors
Menu CRUD: 11. Toggle bestseller status
Image/media management: 12. Upload image asset
Image/media management: 13. Attach asset to menu item
Image/media management: 14. Block deleting in-use asset
Image/media management: 15. Retry with valid file
Bestsellers: 16. Verify curated bestsellers
Delivery zones: 1. Create delivery zone
Delivery zones: 2. Deactivate zone
Delivery zones: 3. Delete zone with confirmation
Delivery zones: 4. Correct inline validation errors
Orders: 1. Review order queue
Orders: 2. Open order and review details
Orders: 3. Update order status
Orders: 4. Filter or search queue
Website settings: 17. Replace placeholder content
Website settings: 18. Save storefront settings
Website settings: 19. Correct inline validation errors
Rooms/settings: 20. Create or edit room record
Rooms/settings: 21. View not-applicable notice and settings
Dashboard: 22. Sign out