diff --git a/.cursor/rules/meshkee-static-images.mdc b/.cursor/rules/meshkee-static-images.mdc
new file mode 100644
index 0000000..d11a26c
--- /dev/null
+++ b/.cursor/rules/meshkee-static-images.mdc
@@ -0,0 +1,15 @@
+---
+description: Keep Meshkee static-image slots and their storefront catalog synchronized
+alwaysApply: true
+---
+
+# Meshkee Static Images
+
+- Use the canonical contract at `https://api.meshkee.com/docs/website`; do not invent upload or dashboard APIs.
+- Fetch static-image slots from `/api/v1/tenants/aradarisman.com/website/static-images`. Match placeholders by `slot.key`.
+- Use every image for `kind: "list"` and only the first image for `kind: "single"`.
+- Render `image.url`, use `titleFa` / `subtext` for copy, and wrap in a link when `linkUrl` is present.
+- Keep local placeholder images when a slot is empty or the API request fails.
+- Keep `src/app/meshkee/static-image-slots/route.ts` synchronized with every static-image placeholder.
+- Whenever a placeholder's rendered dimensions or crop ratio change, update that slot's `aspectRatio` and `recommendedWidth` in the catalog and the component container (`aspectRatioToCss`).
+- Update `CONTEXT.md` and `CLAUDE.md` when a prompt changes routes, API integrations, slot keys, or other project architecture.
diff --git a/CLAUDE.md b/CLAUDE.md
index 970aa52..4a94e0e 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -30,7 +30,7 @@ can fill with their own images from the Meshkee dashboard. Current mapping:
| Slot key | Kind | Component | Fallback when empty/unset |
|-------------------|--------|--------------------|----------------------------------------|
| `slider` | list | `HeroSlider` | 3 local photos in `hero-slider-*.jpg` with authored copy |
-| `categories` | list | `CategoryShowcase` | icon-based cards derived from live product categories |
+| `categories` | list | `CategoryShowcase` | photo cards derived from live product categories |
| `four-icon-image` | list(4)| `Features` | 4 local icons + authored copy, per-index override |
| `about-us` | single | `About` | local `hero-2.jpg` |
| `brands` | list | `Partners` | 6 local partner logos |
@@ -44,9 +44,21 @@ Each `StaticImageItem` carries `url`, optional `titleFa`/`subtext`/
(`"21:9"` etc, via `aspectRatioToCss`) for slot-driven image containers
instead of hardcoding a Tailwind aspect class — if you resize/recrop a
*local* fallback image during development, update the corresponding
-component's fallback styling to match, since slot-driven and fallback
-images render through the same container and must not look broken when
-swapped.
+component's fallback styling **and** the catalog entry in
+`src/app/meshkee/static-image-slots/route.ts` to match, since slot-driven
+and fallback images render through the same container and must not look
+broken when swapped.
-`aradarisman.com` currently has **zero** slots configured, so the site
-renders through the fallback path everywhere — this is expected, not a bug.
+### Dashboard catalog (required for Refresh)
+
+The Meshkee dashboard **Refresh** button does not invent slots. It imports
+keys from this site:
+
+`GET https://aradarisman.com/meshkee/static-image-slots`
+
+That route is `src/app/meshkee/static-image-slots/route.ts`. Until it is
+deployed and the dashboard Refresh is clicked, `/tenants/aradarisman.com/website/static-images`
+returns `{ items: [] }` and the storefront correctly shows fallbacks.
+
+Do not invent upload/CMS APIs. Owners add images in the Meshkee dashboard
+after Refresh has imported the catalog.
diff --git a/CONTEXT.md b/CONTEXT.md
new file mode 100644
index 0000000..de537b0
--- /dev/null
+++ b/CONTEXT.md
@@ -0,0 +1,38 @@
+# Arad Arisman Website Context
+
+## Project
+
+- Persian RTL storefront for Arad Arisman (livestock/poultry feed supplements).
+- Next.js 16 App Router, React 19, TypeScript, Tailwind 4, `src/app`.
+- Apex domain: `aradarisman.com`.
+- Local images live in `public/images`.
+
+## Meshkee API
+
+- Canonical docs: `https://api.meshkee.com/docs/website`
+- API base: `https://api.meshkee.com/api/v1`
+- Tenant domain: `aradarisman.com` (`TENANT_DOMAIN` in `src/lib/meshkee.ts`)
+- All public fetches go through `src/lib/meshkee.ts`. Do not call the API from components.
+- Do not invent dashboard/CMS/upload endpoints.
+
+## Homepage static-image slots
+
+Consumers read `GET /tenants/aradarisman.com/website/static-images` and match by `key`. Empty or failed slots keep local placeholders.
+
+| Key | Kind | itemCount | Aspect | Width | Component |
+|---|---|---|---|---|---|
+| `slider` | list (duplicatable) | null | 16:9 | 1920 | `HeroSlider` (full-viewport `h-svh`; catalog ratio is the recommended crop) |
+| `categories` | list (duplicatable) | null | 3:5 | 720 | `CategoryShowcase` |
+| `four-icon-image` | list | 4 | 1:1 | 128 | `Features` |
+| `about-us` | single | 1 | 4:3 | 960 | `About` |
+| `brands` | list (duplicatable) | null | 1:1 | 200 | `Partners` |
+
+Dashboard import catalog: `GET /meshkee/static-image-slots` (`src/app/meshkee/static-image-slots/route.ts`).
+
+If a rendered image size or crop ratio changes, update both the component container (`aspectRatioToCss`) and the matching catalog entry.
+
+## Other conventions
+
+- Category tiles from live products (`getCategorySummary`) because the raw `/categories` taxonomy has duplicate display names.
+- Blog field names are inferred; accessors fall back across `nameFa` / `titleFa` / `title`, etc.
+- Next.js `images.remotePatterns` allows `c804387.parspack.net` (Meshkee media CDN).
diff --git a/src/app/meshkee/static-image-slots/route.ts b/src/app/meshkee/static-image-slots/route.ts
new file mode 100644
index 0000000..00ea86b
--- /dev/null
+++ b/src/app/meshkee/static-image-slots/route.ts
@@ -0,0 +1,63 @@
+/**
+ * Slot catalog the Meshkee business dashboard imports via Refresh.
+ * Keep this in sync with the homepage placeholders. If a rendered crop or
+ * size changes, update `aspectRatio` / `recommendedWidth` here too.
+ */
+const slots = [
+ {
+ key: "slider",
+ label: "اسلایدر صفحه اصلی",
+ kind: "list",
+ pageKey: "home",
+ aspectRatio: "16:9",
+ itemCount: null,
+ recommendedWidth: 1920,
+ },
+ {
+ key: "categories",
+ label: "دستهبندی محصولات",
+ kind: "list",
+ pageKey: "home",
+ aspectRatio: "3:5",
+ itemCount: null,
+ recommendedWidth: 720,
+ },
+ {
+ key: "four-icon-image",
+ label: "چهار آیکون ویژگیها",
+ kind: "list",
+ pageKey: "home",
+ aspectRatio: "1:1",
+ itemCount: 4,
+ recommendedWidth: 128,
+ },
+ {
+ key: "about-us",
+ label: "تصویر درباره ما",
+ kind: "single",
+ pageKey: "home",
+ aspectRatio: "4:3",
+ itemCount: 1,
+ recommendedWidth: 960,
+ },
+ {
+ key: "brands",
+ label: "لوگوهای برند و نماد اعتماد",
+ kind: "list",
+ pageKey: "home",
+ aspectRatio: "1:1",
+ itemCount: null,
+ recommendedWidth: 200,
+ },
+] as const;
+
+export function GET() {
+ return Response.json(
+ { slots },
+ {
+ headers: {
+ "Cache-Control": "public, max-age=300, stale-while-revalidate=3600",
+ },
+ }
+ );
+}
diff --git a/src/components/About.tsx b/src/components/About.tsx
index d9bbd8c..cf41c43 100644
--- a/src/components/About.tsx
+++ b/src/components/About.tsx
@@ -1,6 +1,6 @@
import Image from "next/image";
import Container from "./Container";
-import { getStaticImageSlot } from "@/lib/meshkee";
+import { aspectRatioToCss, getStaticImageSlot } from "@/lib/meshkee";
export default async function About() {
const slot = await getStaticImageSlot("about-us");
@@ -9,18 +9,30 @@ export default async function About() {
const imageSrc = slotImage?.url || "/images/hero-2.jpg";
const imageAlt = slotImage?.titleFa || "محصولات آراد آریسمان";
const objectPositionClass = slotImage ? "object-center" : "object-left";
+ const image = (
+
+ );
return (
-