
# [Restaurant Name] · Menu + Ordering

A restaurant marketing + ordering site. Menu syncs from Square so the owner edits once. Orders route to the kitchen via Square. The site charges nothing extra.

## Source of truth
Square is the source for menu items, prices, modifiers, and inventory. The site reads Square Catalog at build time and caches. Orders POST to Square Orders API. Reservations link out to OpenTable or Resy.

## Tech stack
Next.js 15 (App Router) + React + Tailwind v4. Square Web SDK for the payment card form, Square Orders API for order creation. Cloudinary for food photography. Resend for confirmation emails. ISR (Incremental Static Regen) for menu pages, revalidating every 5 minutes.

## Deploy
`git push origin main`. Vercel auto-deploys. Square webhook configured to revalidate the menu page on catalog updates.

## File map
- `app/page.tsx` home: hero photo, today's specials, ordering CTA, location/hours
- `app/menu/page.tsx` full menu, categorized, sourced from Square Catalog
- `app/order/page.tsx` cart + checkout
- `app/order/confirmation/[orderId]/page.tsx` post-order screen
- `app/locations/[slug]/page.tsx` per-location page (hours, address, photos, map)
- `app/api/order/route.ts` POST -> Square Orders + Square Payments
- `app/api/webhook/square/route.ts` Square webhook: catalog.updated triggers revalidation
- `lib/square.ts` Square SDK client
- `lib/cart.ts` localStorage cart with modifier support

## .env keys
- `SQUARE_ACCESS_TOKEN`
- `SQUARE_LOCATION_ID`
- `SQUARE_WEBHOOK_SIGNATURE_KEY`
- `SQUARE_ENVIRONMENT` `production` | `sandbox`
- `NEXT_PUBLIC_SQUARE_APPLICATION_ID` (Web SDK)
- `RESEND_API_KEY`
- `RESEND_FROM_EMAIL`

## Hard rules
- Menu prices come from Square. Never hardcode a price in JSX.
- Cart modifiers map to Square modifier IDs. Test that a "no cilantro" modifier reaches the printer.
- Pickup-only for v0. Delivery is a different beast (DoorDash Drive integration is a separate template).
- Tax + tip computed via Square (`calculateOrder`), never client-side. State sales tax + alcohol rules are complex.
- Photos of food are real, shot tight, well-lit. Stock photos of "delicious burger" kill orders.
- Confirmation page shows estimated ready time + pickup instructions (the exact door, parking note).
- Square webhook signature is verified before any state change.

## Recent significant changes
- 2026-05-04: Scaffolded. Locked: Square direct (the restaurant already owns the hardware), pickup-only v0, no third-party marketplace integration (the whole point).

## Next session: start here
1. Get Square access from the restaurant. Sandbox first, production later.
2. Sync menu: confirm `square.catalog.searchCatalogItems` returns the actual items.
3. Build cart + checkout flow with sandbox cards.
4. Test a real $1 order end-to-end. Confirm receipt prints in the kitchen.
5. Set up Square webhook for catalog updates -> Next.js revalidation.
