# Ayoubi Gallery — AI / Project Context
## Source of truth
- Live domain: `https://ayoubi.jewelry`
- Design language: black ground, ivory type, gold lines, Doran + Cinzel, flat surfaces
- Backend: https://api.meshkee.com/docs/website
- Domain: `ayoubi.jewelry` (`NEXT_PUBLIC_WEBSITE_DOMAIN`)
- API base: `https://api.meshkee.com/api/v1` (`NEXT_PUBLIC_MESHKEE_API_BASE`)
- Tenant business id: `42` (`GET /tenants/ayoubi.jewelry`, nameFa: گالری ایوبی فخیم)
- Enabled modules: `products`, `blog`, `finance`. `specialProductsSource`: `store_item`
- Prompt reference: `https://api.meshkee.com/api/v1/public/ai-prompts/ayoubi-gallery/backend/253d39eea2a4047c39296d1a`
## Stack
- Next.js 15 App Router + React 19 + TypeScript
- `output: "standalone"` in `next.config.ts` (required for the Meshkee websites VM)
- Language: `fa`, direction: `rtl`
- Fonts: Doran (`--font-doran`), Cinzel (`--font-cinzel`)
- Styling: `src/app/globals.css` only (no Tailwind)
## Color palette
- Background: `#070708` (`--bg`)
- Elevated: `#101012`
- Ivory text: `#f3eee6` (`--fg`)
- Muted: `rgba(243, 238, 230, 0.62)`
- Gold: `#c9a86a` (`--accent`)
- Hairline: `rgba(243, 238, 230, 0.14)`
- Flat: no shadows, square corners, 1px borders
- Header is fixed. Frosted over the home video; solid `#000` after scroll (`.header--solid`)
- Header tools: account menu, cart (badge + popup), phone, Instagram
## Auth (customer dashboard)
- Do **not** add `/login`, `/register`, `/cart`, or `/checkout` on this site
- Anonymous account icon → `https://customer.ayoubi.jewelry`
- Logged in (cookie `meshkee_customer_access_token`, may be chunked): show `{firstName|nameFa|name} عزیز`
- Dropdown: `پروفایل من`, `خروج`, and if admin `مدیریت وبسایت` → `https://business.ayoubi.jewelry`
- Session: `src/lib/auth.ts` + `src/lib/authUser.ts` via `GET /auth/me`
## Shopping cart (mini-cart only)
- Header cart icon + quantity badge + popup (`CartButton` + `CartProvider` + `guestCart.ts`)
- Persist `meshkee-guest-cart` in localStorage + cookie on `.ayoubi.jewelry`
- Add-to-cart only when `GET .../store-items/by-product/{productId}` returns in-stock variants
- Line `id` = `storeItemVariantId`; price = `discountedPrice ?? price`
- Continue: logged in → `customer.../checkout/cart?guestCart=…`; else login with that redirect
- Never call `/businesses/{id}/cart*` from this site
## Pages
| Route | Purpose |
| --- | --- |
| `/` | Video hero, category studio, local/CMS gallery, follow, carousel, parallax, visit |
| `/products` | Catalog from Meshkee products API + jewelry category filters + pagination |
| `/products/[id]/[nameFaSlug]` | Product detail (canonical); redirect if slug drifts |
| `/products/category/[id]/[nameFaSlug]` | Category product list |
| `/portfolio` | Portfolio list (API; empty until CMS content) |
| `/portfolio/[slug]` | Portfolio detail: lightbox gallery, zoom, similar row |
| `/blog` | Blog list (API; empty until CMS content) |
| `/blog/[slug]` | Blog detail |
| `/about` | درباره گالری |
| `/contact` | Contact facts + form → `POST /api/contact` → Meshkee contact-submissions |
## Product detail requirements
- Media gallery with hover zoom (desktop) + lightbox
- Tabs: توضیحات، مشخصات فنی (via `.../technical-info` join), دیدگاهها
- Comments: form only when authenticated; else login link to customer portal
- Similar products from `relatedProducts`
- Emit `product.schema.jsonLd` when present
## Homepage (visual gallery)
- Local images in `public/assets/images/` / `gallery` in `src/data/site.ts` as fallbacks
- CMS slots: `categories`, `four-banner`, `masonry-image`, `instagram-image`, `last-banner` (see Static image slots)
- Homepage masonry is atmospheric; purchasable catalog is `/products`
## Brand copy (fallback)
- Name: گالری طلا و جواهر ایوبی فخیم / Ayoubi Fakhim Jewelry
- Tagline: این طلا همیشه مده
- Address: قم - سالاریه - اریکه ملل
- Phones: ۰۹۹۹ ۱۲۹ ۶۶۶۶ (`09991296666`), ۰۹۳۷ ۱۴۴ ۸۹۰۵ (`09371448905`)
- Instagram: https://www.instagram.com/ayoubifakhim/
- Logo / favicon fallback: `public/Ayoobi-logo.png`
## Meshkee helpers
- `src/lib/meshkee.ts` — business-info, favicon
- `src/lib/catalog.ts` — products, categories, blogs, portfolios, comments, store-items, `/auth/me`
- `src/lib/slug.ts` — canonical product/category/blog/portfolio hrefs
- Favicon: `GET /website/favicon` → `metadata.icons`, else `/Ayoobi-logo.png`
### Static image slots
Catalog: `GET /meshkee/static-image-slots` from `STATIC_IMAGE_SLOTS` in `src/lib/static-images.ts`.
Fetch per page: `GET /tenants/{domain}/website/static-images?pageKey=…`.
Empty/fail → keep local placeholders. `url` → `
`; `linkUrl` → wrap in ``.
Use `titleFa` / `titleEn` / `subtext` to match the original UI labels.
Apply `slot.aspectRatio` from the API (fallback to catalog). **If an on-page frame’s size or aspect ratio changes in development, update the matching `STATIC_IMAGE_SLOTS` entry in the same change.**
| key | kind | itemCount | aspectRatio | width | UI |
| --- | --- | --- | --- | --- | --- |
| `categories` | list | null | `1:1` | 320 | Category row — `titleFa`/`titleEn` beside image (icon fallback) |
| `four-banner` | list | 4 | `3:4` | 1440 | Sticky “از فلز تا پوشیدن” — Fa/En/subtext + image |
| `masonry-image` | list | null | `3:4` | 960 | Masonry gallery (free display height) |
| `instagram-image` | single | 1 | `4:5` | 480 | Follow frame photo + optional Fa/En/subtext |
| `last-banner` | single | 1 | `16:9` | 1600 | Parallax end banner |
| `about-portrait` | single | 1 | `3:4` | 900 | About portrait |
Helpers: `src/lib/home-slots.ts`, `SlotImage`.
### Tags & badges
From `business-info`: `metaTags` as `{ html }` **or** `{ name, content }` → root `` via `CmsMeta`. `trustBadges[].embedHtml` → footer (scripts stripped). Empty → omit; do not hardcode eNamad/Samandehi.
### SEO
- Do not ship local `sitemap.xml` / `robots.txt` / `app/sitemap.ts` / `app/robots.ts`
- Static pages: `GET /meshkee/sitemap-config.json`
- One H1 per page; content images have alt; use `seoMetaTitle` / `seoMetaDescription` when set
- Organization JSON-LD from business-info; product/blog detail emit their own `schema.jsonLd`
## Important paths
- Layout / providers: `src/app/layout.tsx`, `src/components/providers/*`
- Header / footer: `src/components/Header.tsx`, `AccountMenu.tsx`, `CartButton.tsx`, `Footer.tsx`
- Catalog UI: `MediaGallery.tsx`, `ProductTabs.tsx`, `AddToCart.tsx`, `CatalogCard.tsx`, `CommentSection.tsx`
- Contact: `src/components/ContactForm.tsx` + toast, `src/app/api/contact/route.ts`