# HOM arch studio — AI / Project Context Persian (fa, RTL) brochure website for **استودیو معماری هوم** (architecture + interior design group). Keep this file current whenever routes, slots, data sources or design rules change. ## Source of truth - Live domain: `https://homgroup.com` (`NEXT_PUBLIC_WEBSITE_DOMAIN`, default `homgroup.com`) - Backend docs: https://api.meshkee.com/docs/website (OpenAPI: `/docs/website/openapi.json`) - API base: `https://api.meshkee.com/api/v1` (`NEXT_PUBLIC_MESHKEE_API_BASE`) - Tenant: `GET /tenants/homgroup.com` — **not registered yet** (404 as of 2026-10-11). Every Meshkee read has a local fallback, so the site renders fully without the tenant. - Prompt reference: `https://api.meshkee.com/api/v1/public/ai-prompts/studio-hom/basic-create/36caa331616c4b1cd382f8cb` - Original brief: homepage + about + contact only; `lang=fa`, `dir=rtl`, flat design, palette from the logo. ## Stack - Next.js 15 App Router + React 19 + TypeScript, no Tailwind — all styles in `src/app/globals.css` - `output: "standalone"` in `next.config.ts` (**required** for the Meshkee websites VM; deploy drops `node_modules`) - `npm run build` runs `prebuild` → `scripts/generate-sitemap-config.mjs` (scans `src/app` for static pages) - `npm run lint` = `tsc --noEmit` - Font: IranYekan (local, `public/fonts/`, weights 300/400/500/700) via `next/font/local` → `--font-yekan` ## Design language (flat) - Palette: bg `#ffffff`, surface `#f4f3f1`, text `#111111`, muted `#6b6b6b`, hairline `#e2e0dc`, accent red `#e3002b` (the logo dot) - Flat only: no shadows, no border-radius, 1px hairlines, solid fills. Red appears as a small square “dot” (eyebrows, hero title) and on hover. - Latin labels use `.latin` (uppercase, letter-spaced, LTR). One dark section (`.section--dark`) for the process. - Header is sticky, white, hairline bottom; mobile burger menu under 900px. - Logo: `public/images/logo.png` (cropped from `assets/logo/logo.jpeg`); favicon `src/app/icon.png` ## Routes | Route | Purpose | | --- | --- | | `/` | Hero (title + CMS hero image), intro, 4 services, 6 selected projects, studio block, 4-step process (dark), stats, CTA | | `/about` | Page hero image, story (3 paragraphs from `business-info.about` or fallback), 3-image gallery, values, services list, stats, CTA | | `/contact` | Facts (phones, email, Instagram, address), contact image, form → `POST /api/contact` | | `/api/contact` | Proxies to `POST /tenants/{domain}/contact-submissions` (`title`, `name`, `text` required; `email`, `cellNumber` optional) | | `/meshkee/static-image-slots` | Slot catalog (`STATIC_IMAGE_SLOTS`) for the dashboard “Refresh slots” | | `/meshkee/sitemap-config.json` | Static pages for the Meshkee-generated sitemap | No `/login`, `/register`, `/cart`, `/checkout`, no local `sitemap.xml` / `robots.txt` (nginx proxies those to the API). ## Meshkee integration (`src/lib/`) - `config.ts` — domain / API base / portal URLs - `meshkee.ts` — `meshkeeGet` (ISR 300s, returns fallback on any error), `getBusinessInfo`, `getFavicon` - `static-images.ts` — slot catalog + `getPageSlots(pageKey)` (parses `{ items: [{ key, aspectRatio, images[] }] }`), `slotImages`, `slotRatio` - `content.ts` — resolves name / logo / phones / emails / address / Instagram / about from `business-info` with fallbacks from `src/data/site.ts`; `parseHeadTag`, `stripScripts`, digit helpers - Root layout: `metaTags` → `` in ``; `schema.jsonLd` → `` when `schema.enabled`; `trustBadges[].embedHtml` → footer (scripts stripped) - Favicon: `GET /website/favicon` → `metadata.icons`; falls back to `src/app/icon.png` ### Static image slots Fetch per page: `GET /tenants/{domain}/website/static-images?pageKey=…`. Empty/fail → local images from `gallery` in `src/data/site.ts`. `url` → ``, `linkUrl` → wrap in ``, `titleFa`/`titleEn`/`subtext` → captions where the UI shows them. Use the API `aspectRatio` first, catalog second. **If a frame’s size or ratio changes in development, update `STATIC_IMAGE_SLOTS` in the same change.** | key | page | kind | itemCount | aspectRatio | width | UI | | --- | --- | --- | --- | --- | --- | --- | | `hero` | home | single | 1 | `16:9` | 1920 | Hero frame; `titleFa` shown in the caption row | | `projects` | home | list | null | `4:5` | 1200 | Selected projects grid; `titleFa` = title, `titleEn` = Latin subtitle, `subtext` = meta (e.g. category · year). When empty → 6 local `projects` | | `studio-image` | home | single | 1 | `4:3` | 1400 | “نگاه ما” block image | | `about-hero` | about | single | 1 | `16:9` | 1920 | About page hero | | `about-gallery` | about | list | 3 | `1:1` | 900 | 3-up square gallery | | `contact-image` | contact | single | 1 | `4:5` | 1200 | Image under the contact facts | ## Local content / fallbacks (`src/data/site.ts`) - `site` — names (`استودیو معماری هوم` / `HOM arch studio`), tagline, description, placeholder phone `۰۹۱۲ ۰۰۰ ۰۰۰۰`, email `info@homgroup.com`, Instagram `@hom.archstudio`, address `تهران`, 3 about paragraphs. **Replace placeholders once the business profile exists in Meshkee** (they are overridden automatically by `business-info` when present). - `services` (4), `processSteps` (4), `stats` (4), `projects` (6), `gallery` (image paths), `NAV_LINKS` - Images: `public/images/*.jpg` — resized (≤1800px, q82) from `assets/images/` (originals kept out of git). Mapping: `facade-sunset*` ← IMG_1455/1456/1458, `courtyard-brick*` ← IMG_0356/0357, `kitchen-cream*` ← IMG_0374/0375, `study-terracotta*` ← IMG_0376/0377, `kitchen-oak*` ← IMG_0394/0396, `facade-louver` ← IMG_0400, `garden-gate` ← IMG_1037 ## SEO - Unique `` / description per page (`metadata` in each `page.tsx`; template `%s | {name}`) - One `<h1>` per page; content images have `alt` - Static pages published through `/meshkee/sitemap-config.json`; do not add `app/sitemap.ts` / `app/robots.ts` ## Components (`src/components/`) `Header` (client; sticky, burger), `Footer`, `CmsMeta` (+ `JsonLd`), `SlotImage` (flat frame for slot/fallback images), `ContactForm` (client; posts to `/api/contact`, Persian status messages) ## Deploy Standard Meshkee websites VM flow: push → Super Admin **Deploy**. Deploy log must say `standalone build detected`; PM2 script `.next/standalone/server.js`. ## Changelog - 2026-10-11 — Initial build: home / about / contact, Meshkee business-info + static-image slots + contact form, standalone runtime, sitemap-config generator.