import { formatPrice } from "../../src/lib/utils"; import type { Dictionary } from "../../src/lib/i18n/dictionaries"; import type { MegaMenuRoot } from "../../src/lib/mega-menu"; import { SEARCH_SORT_OPTIONS, type SearchSort } from "../../src/lib/search-sort"; import { displayNameWithoutShade, variantGalleryImages, type ColorVariant, } from "../../src/lib/color-variants"; import { productCategoryLink, withPersianCategory, persianCategoryLabel } from "../../src/lib/categories/kiko"; import { loveYourEyesPillHtml } from "../../src/lib/promos/love-your-eyes"; import { headSeoTags, STORE_FAQS } from "../../src/lib/seo"; function esc(s: unknown) { return String(s ?? "") .replaceAll("&", "&") .replaceAll("<", "<") .replaceAll(">", ">") .replaceAll('"', """); } /** English/original product name with Persian category beside it. */ function productDisplayTitle( p: { name: string; nameFa?: string | null; category?: string | null }, hasVariants = false ) { const base = displayNameWithoutShade(p.name, hasVariants); return withPersianCategory(base, p.category); } function icon(name: "bag" | "menu" | "x" | "chevron" | "chevron-end" | "chevron-start") { if (name === "bag") { // Lucide-style shopping bag (matches original storefront) return ``; } if (name === "menu") { return ``; } if (name === "x") { return ``; } if (name === "chevron-end") { // Points toward the right edge (hide in RTL layout) return ``; } if (name === "chevron-start") { return ``; } return ``; } const INSTAGRAM_URL = "https://www.instagram.com/kikomiko.ir/"; const INSTAGRAM_LABEL = "اینستاگرام ما"; function instagramFooterIcon() { return ` `; } const CONTACT_ADDRESS_LABEL = "Italy, Torino, Via Luigi Capriolo 58, 10139"; const CONTACT_ADDRESS_HREF = "https://www.google.com/maps/search/?api=1&query=" + encodeURIComponent("Via Luigi Capriolo 58, 10139 Torino, Italy"); const CONTACT_SUPPORT = [ { display: "۰۹۱۲۱۸۵۹۷۱۲", tel: "+989121859712" }, { display: "۰۹۳۸۷۲۴۷۲۳۵", tel: "+989387247235" }, ] as const; const CONTACT_WHATSAPP_DISPLAY = "+۳۹۳۵۲۵۶۶۶۰۷"; const CONTACT_WHATSAPP_HREF = "https://wa.me/39352566607"; export function contactPageBody() { const promises = [ "محصولات اورجینال KIKO Milano", "واردات مستقیم از ایتالیا", "تضمین اصالت کالا", "ارسال به سراسر ایران", ]; return `

کیکومیکو

با کیکومیکو در ارتباط باشید

ما اینجا هستیم تا تجربه‌ای مطمئن‌تر و لذت‌بخش‌تر از خرید محصولات KIKO Milano داشته باشید.

اگر درباره محصولات، انتخاب شید و رنگ، وضعیت سفارش، ارسال، اصالت کالا یا هر موضوع دیگری سوالی دارید، تیم کیکومیکو با خوشحالی پاسخگوی شماست.

پشتیبانی واتس‌اپ

همه روزه از ۹ صبح تا ۱۲ شب

پشتیبانی تلفنی

از ۹ صبح تا ۵–۷ بعد از ظهر

راه‌های تماس

چطور پیام بدهید؟

سوال یا درخواست خود را از طریق واتس‌اپ برای ما ارسال کنید. پیام شما در سریع‌ترین زمان ممکن بررسی و پاسخ داده خواهد شد.

همینطور برای پیگیری سفارش می‌توانید از طریق تماس تلفنی یا واتس‌اپ کیکومیکو با ما در ارتباط باشید.

کیکومیکو

زیبایی اصیل ایتالیایی، در ایران.

    ${promises .map( (item) => `
  • ${esc(item)}
  • ` ) .join("")}
`; } export function aboutPageBody() { return `

کیکومیکو

درباره کیکو میکو

کیکو میکو فروشگاه تخصصی محصولات KIKO Milano در ایران است. هدف ما این است که دسترسی به محصولات و جدیدترین کالکشن‌های کیکو میلانو ایتالیا را برای علاقه‌مندان به لوازم آرایشی در ایران ساده‌تر کنیم.

محصولات کیکو میکو مستقیماً از ایتالیا تهیه و به ایران وارد می‌شوند. به همین دلیل می‌توانید بسیاری از محصولات محبوب، کالکشن‌های جدید، محصولات فصلی و نسخه‌های Limited Edition برند KIKO Milano را بدون نیاز به خرید مستقیم از فروشگاه‌های خارجی سفارش دهید.

در فروشگاه کیکو میکو می‌توانید انواع لوازم آرایشی KIKO Milano از جمله رژ لب، لیپ گلاس، ریمل، خط چشم، مداد چشم، سایه چشم، محصولات آرایش صورت، رژگونه، برنزر، هایلایتر، محصولات مراقبت از لب، براش و اکسسوری‌های آرایشی کیکو را پیدا کنید.

خرید محصولات KIKO Milano از ایتالیا

یکی از تفاوت‌های اصلی کیکو میکو این است که محصولات از ایتالیا خریداری شده و سپس برای مشتریان داخل ایران ارسال می‌شوند. به همین دلیل امکان ارائه محصولات و کالکشن‌هایی وجود دارد که ممکن است در بازار ایران به‌راحتی در دسترس نباشند.

با توجه به اینکه سفارش‌ها از ایتالیا وارد ایران می‌شوند، زمان تحویل سفارش معمولاً بین یک تا سه هفته کاری است. این بازه شامل تهیه محصول، ارسال بین‌المللی و مراحل ورود کالا به ایران می‌شود.

در بعضی شرایط مانند تأخیر در حمل‌ونقل بین‌المللی، تعطیلات، شرایط گمرکی یا عوامل خارج از کنترل، ممکن است زمان تحویل کمی بیشتر شود. تلاش ما این است که سفارش‌ها در سریع‌ترین زمان ممکن تهیه و ارسال شوند و مشتری از روند سفارش خود اطلاع داشته باشد.

جدیدترین کالکشن‌های کیکو میلانو

KIKO Milano به‌صورت مداوم کالکشن‌ها و محصولات جدیدی عرضه می‌کند. در کیکو میکو تلاش می‌کنیم جدیدترین محصولات و کالکشن‌های KIKO Milano را نیز در کنار محصولات محبوب و پرفروش این برند در اختیار شما قرار دهیم.

اگر محصول خاصی از کیکو، یک رنگ مشخص یا محصولی از یک کالکشن جدید مدنظر شما باشد، می‌توانید موجودی و امکان تهیه آن از ایتالیا را نیز بررسی کنید.

چرا کیکو میکو؟

کیکو میکو برای کسانی ساخته شده که به دنبال خرید محصولات کیکو میلانو در ایران هستند و می‌خواهند به تنوع بیشتری از محصولات KIKO Milano ایتالیا دسترسی داشته باشند.

از محصولات آرایش چشم و لب گرفته تا آرایش صورت، اکسسوری‌ها و کالکشن‌های محدود، هدف ما ایجاد یک مسیر ساده‌تر برای سفارش محصولات این برند از ایتالیا و دریافت آن‌ها در ایران است.

کیکومیکو

کیکو میکو؛ محصولات KIKO Milano، از ایتالیا تا ایران.

`; } export function authenticityPageBody() { return `

کیکومیکو

اصالت کالا

کیکومیکو فروشگاه تخصصی و واردکننده مستقل محصولات اورجینال KIKO Milano از ایتالیا به ایران است؛ متعلق به برند کیکو میلانو نیستیم، اما محصولات را از کانال‌های معتبر ایتالیا تهیه می‌کنیم.

هدف ما این است که هنگام خرید لوازم آرایشی کیکو در ایران، بدانید از کجا آمده‌اند، چطور تضمین اصالت می‌دهیم، و اگر سوالی داشتید چطور با ما در تماس باشید.

محصولات را چطور تهیه می‌کنیم؟

سفارش‌ها از ایتالیا تهیه می‌شوند؛ از فروشگاه‌ها و کانال‌های رسمی KIKO Milano در ایتالیا خریداری و سپس برای مشتریان داخل ایران ارسال می‌گردند.

به همین دلیل بسیاری از محصولات، شیدها و کالکشن‌های محدودی که در بازار ایران به‌راحتی پیدا نمی‌شوند، از طریق کیکومیکو قابل سفارش هستند.

تضمین اصالت کالا یعنی چه؟

ما متعهدیم محصولات عرضه‌شده اورجینال KIKO Milano باشند. اگر ثابت شود کالای دریافتی غیراصل است، پس از بررسی از طریق تماس با ما، مطابق قوانین فروشگاه اقدام به تعویض یا استرداد می‌کنیم.

برای پیگیری هرگونه نگرانی درباره اصالت، بسته‌بندی یا کد محصول، با پشتیبانی واتس‌اپ یا تلفن در صفحه تماس در ارتباط باشید.

زمان ارسال از ایتالیا

چون سفارش‌ها از ایتالیا وارد ایران می‌شوند، زمان تحویل معمولاً بین یک تا سه هفته کاری است. این بازه شامل تهیه محصول، ارسال بین‌المللی و مراحل ورود کالا به ایران می‌شود.

در شرایط خاص مانند تأخیر حمل‌ونقل، تعطیلات یا عوامل گمرکی، ممکن است زمان تحویل کمی بیشتر شود؛ تلاش ما اطلاع‌رسانی شفاف و ارسال در کوتاه‌ترین زمان ممکن است.

سوال درباره اصالت دارید؟

جزئیات آدرس، شماره پشتیبانی ایران و واتس‌اپ ایتالیا در صفحه تماس با ما آمده است. پیام یا تماس شما درباره اصالت کالا در اولویت بررسی قرار می‌گیرد.

کیکومیکو

واردکننده مستقل محصولات اورجینال KIKO Milano از ایتالیا.

`; } /** Persian label for catalog sync timestamp (prices/stock from KIKO Italy). */ export function formatCatalogSyncTime(iso: string) { const d = new Date(iso); if (Number.isNaN(d.getTime())) return null; return new Intl.DateTimeFormat("fa-IR", { dateStyle: "medium", timeStyle: "short", timeZone: "Asia/Tehran", }).format(d); } export function layout(opts: { title: string; dict: Dictionary; megaMenu: MegaMenuRoot[]; body: string; description?: string; whatsapp?: string; ordersEndpoint?: string; /** ISO timestamp from data/site.json generatedAt */ catalogUpdatedAt?: string; /** EUR→toman sell rate used for catalog pricing (from data/site.json) */ eurToTomanRate?: number; /** Extra tags injected into (preload, etc.) */ headExtra?: string; /** Site-relative path for canonical + Open Graph (e.g. /collection/). */ canonicalPath?: string; ogImage?: string | null; noindex?: boolean; nofollow?: boolean; ogType?: "website" | "product"; }) { const { title, dict, megaMenu, body, description, whatsapp, ordersEndpoint, catalogUpdatedAt, eurToTomanRate, headExtra = "", canonicalPath, ogImage, noindex, nofollow, ogType, } = opts; const seoTags = canonicalPath ? headSeoTags({ path: canonicalPath, title, description, image: ogImage, noindex, nofollow, ogType, }) : ""; const year = new Date().getFullYear(); const wa = whatsapp || process.env.WHATSAPP_NUMBER || "393520566607"; const orders = ordersEndpoint || process.env.ORDERS_ENDPOINT || ""; const googlePlacesKey = (process.env.GOOGLE_PLACES_API_KEY || "").trim(); const eurRateAttr = typeof eurToTomanRate === "number" && Number.isFinite(eurToTomanRate) && eurToTomanRate > 0 ? ` data-eur-rate="${esc(String(Math.round(eurToTomanRate)))}"` : ""; const megaPanes = megaMenu .map((root) => { const children = root.children .map( (c, index) => `
  • |${String(index + 1).padStart(2, "0")}| ${esc(c.label)}(${esc(c.count)})
  • ` ) .join(""); const featured = root.featured .map( (p) => ` ${p.heroImage ? `${esc(productDisplayTitle(p))}` : `
    `}

    ${esc(productDisplayTitle(p))}

    ${esc(formatPrice(p.price))}

    ` ) .join(""); return ``; }) .join(""); const sideNav = [ `${esc(dict.nav.home)}`, ...megaMenu.map( (r) => `` ), `${esc(dict.withDiscount)}`, `درباره ما`, `اصالت کالا`, `تماس با ما`, `${INSTAGRAM_LABEL}`, ].join(""); const mobileNav = [ `${esc(dict.nav.home)}`, ...megaMenu.map( (r) => `
    ${esc(r.label)} ${ r.children.length ? `` : "" }
    ${r.children.map((c) => `${esc(c.label)} (${esc(c.count)})`).join("")}
    ` ), `${esc(dict.withDiscount)}`, `درباره ما`, `اصالت کالا`, `تماس با ما`, `${INSTAGRAM_LABEL}`, ].join(""); return ` ${catalogUpdatedAt ? `` : ""} ${esc(title)} ${description ? `` : ""} ${seoTags} ${headExtra}
    ${body}
    ${siteFooter(dict, megaMenu, year, catalogUpdatedAt, eurToTomanRate)} `; } function siteFooter( dict: Dictionary, megaMenu: MegaMenuRoot[], year: number, catalogUpdatedAt?: string, eurToTomanRate?: number ) { const shopLinks = [ { href: "/", label: dict.nav.home }, { href: "/collection/", label: dict.seeAllProducts }, { href: "/offers/", label: dict.withDiscount }, { href: "/about/", label: "درباره ما" }, { href: "/authenticity/", label: "اصالت کالا" }, { href: "/contact/", label: "تماس با ما" }, { href: INSTAGRAM_URL, label: INSTAGRAM_LABEL, external: true }, { href: "/cart/", label: dict.cart }, ]; const menuCols = megaMenu .map((root) => { const rootHref = root.href.endsWith("/") ? root.href : `${root.href}/`; const children = [ `
  • مشاهده همه
  • `, ...root.children.map((c) => { const href = c.href.endsWith("/") ? c.href : `${c.href}/`; return `
  • ${esc(c.label)}
  • `; }), ].join(""); return ``; }) .join(""); const syncLabel = catalogUpdatedAt ? formatCatalogSyncTime(catalogUpdatedAt) : null; const rateOk = typeof eurToTomanRate === "number" && Number.isFinite(eurToTomanRate) && eurToTomanRate > 0; const syncParts = [ syncLabel ? `` : "", rateOk ? `` : "", ].filter(Boolean); const syncHtml = syncParts.join("\n "); return ``; } export function sortSelect(current: SearchSort, opts?: { hash?: string; preserve?: Record }) { const hidden = Object.entries(opts?.preserve || {}) .filter(([, v]) => v) .map(([k, v]) => ``) .join(""); const options = SEARCH_SORT_OPTIONS.map( (o) => `` ).join(""); return ``; } function filterIconSvg() { return ``; } export type ProductListingFiltersOpts = { megaMenu: MegaMenuRoot[]; productCount: number; currentSort?: SearchSort; /** Category root slug when on a category page */ categorySlug?: string | null; currentSub?: string | null; mode: "collection" | "category" | "search" | "offers" | "home"; preserve?: Record; hash?: string; /** Prefer client-side apply (static builds) */ clientMode?: boolean; }; /** KIKO-style filter trigger + overlay for product listing pages. */ export function productListingFilters(opts: ProductListingFiltersOpts) { const sort = opts.currentSort || "newest"; const countFa = opts.productCount.toLocaleString("fa-IR"); const client = opts.clientMode ? "1" : "0"; const preserveJson = esc(JSON.stringify(opts.preserve || {})); const categoryOptions: string[] = []; if (opts.mode === "category" && opts.categorySlug) { const root = opts.megaMenu.find((r) => r.key === opts.categorySlug); if (root) { const rootSelected = !opts.currentSub ? " is-selected" : ""; categoryOptions.push( `` ); for (const child of root.children) { const selected = opts.currentSub && (opts.currentSub === child.label || opts.currentSub === child.key || child.href.includes(encodeURIComponent(opts.currentSub))) ? " is-selected" : ""; categoryOptions.push( `` ); } // Allow jumping to other roots for (const other of opts.megaMenu) { if (other.key === opts.categorySlug) continue; categoryOptions.push( `` ); } } } else { for (const root of opts.megaMenu) { categoryOptions.push( `` ); for (const child of root.children) { categoryOptions.push( `` ); } } } const sortOptions = SEARCH_SORT_OPTIONS.map((o) => { const selected = o.value === sort ? " is-selected" : ""; return ``; }).join(""); const stockAccordion = opts.mode === "offers" ? "" : `
    موجودی
    `; const legacySort = sortSelect(sort, { hash: opts.hash, preserve: opts.preserve, }); return `

    ${countFa} محصول

    ${legacySort}
    `; } function productHref(slug: string, trailingSlash = false) { return `/products/${esc(slug)}${trailingSlash ? "/" : ""}`; } function cardIsInStock(p: { stock?: number; colorVariants?: ColorVariant[]; }): boolean { if (p.colorVariants && p.colorVariants.length > 1) { return p.colorVariants.some((v) => v.stock > 0); } return (p.stock ?? 0) > 0; } function stockBadgeHtml(p: { stock?: number; colorVariants?: ColorVariant[]; }) { if (cardIsInStock(p)) return ""; return `نا موجود`; } function cardShadeDots( variants: ColorVariant[] | undefined, activeSlug: string | undefined, opts?: { trailingSlash?: boolean } ) { if (!variants || variants.length < 2) return ""; // Mobile cards: show up to 5 shades, then +N عدد for the rest const shown = variants.slice(0, 5); const extra = variants.length - shown.length; const slash = opts?.trailingSlash ? "/" : ""; return `
    ${shown .map((v) => { const active = activeSlug && v.slug === activeSlug ? " is-active" : ""; const bg = v.heroImage ? `background-image:url('${esc(v.heroImage)}')` : ""; const href = `/products/${esc(v.slug)}${slash}`; return ``; }) .join("")} ${extra > 0 ? `+${extra.toLocaleString("fa-IR")} عدد` : ""}
    `; } type CardFilterMeta = { featured?: boolean; updatedAt?: Date | string | null; ratingAvg?: number; reviewCount?: number; reviews?: Array<{ rating: number }>; _count?: { reviews?: number }; compareAtPrice?: number | null; discountPercent?: number; }; function cardRating(p: CardFilterMeta) { if (typeof p.ratingAvg === "number") return p.ratingAvg; if (p.reviews?.length) { const sum = p.reviews.reduce((a, r) => a + r.rating, 0); return sum / p.reviews.length; } return 0; } function cardReviewCount(p: CardFilterMeta) { if (typeof p.reviewCount === "number") return p.reviewCount; if (typeof p._count?.reviews === "number") return p._count.reviews; return p.reviews?.length ?? 0; } function cardUpdatedMs(p: CardFilterMeta) { if (!p.updatedAt) return 0; const t = new Date(p.updatedAt).getTime(); return Number.isFinite(t) ? t : 0; } function cardPriceBounds(p: { price: number; colorVariants?: ColorVariant[]; }) { const prices = [Number(p.price) || 0]; for (const v of p.colorVariants || []) { const n = Number(v.price); if (Number.isFinite(n)) prices.push(n); } return { min: Math.min(...prices), max: Math.max(...prices) }; } function cardFilterDataAttrs( p: { name: string; price: number; category: string | null; stock?: number; colorVariants?: ColorVariant[]; } & CardFilterMeta ) { const discount = p.discountPercent ?? (p.compareAtPrice && p.compareAtPrice > p.price ? Math.round((1 - p.price / p.compareAtPrice) * 100) : 0); const { min, max } = cardPriceBounds(p); return [ `data-category="${esc(p.category || "")}"`, `data-category-fa="${esc(persianCategoryLabel(p.category, p.name) || "")}"`, `data-price="${p.price}"`, `data-price-min="${min}"`, `data-price-max="${max}"`, `data-name="${esc(p.name)}"`, `data-updated="${cardUpdatedMs(p)}"`, `data-rating="${cardRating(p)}"`, `data-reviews="${cardReviewCount(p)}"`, `data-featured="${p.featured ? 1 : 0}"`, `data-in-stock="${cardIsInStock(p) ? 1 : 0}"`, `data-discount="${discount}"`, ].join(" "); } function discountPercent(price: number, compareAt: number | null | undefined) { if (!compareAt || compareAt <= price) return 0; return Math.round((1 - price / compareAt) * 100); } /** Highest visible discount for a listing card (canonical + shade dots). */ function listingDiscountPercent( p: CardFilterMeta & { price: number; colorVariants?: ColorVariant[] } ) { if (p.discountPercent && p.discountPercent >= 1) return p.discountPercent; let best = discountPercent(p.price, p.compareAtPrice ?? null); for (const v of p.colorVariants || []) { best = Math.max(best, discountPercent(v.price, v.compareAtPrice ?? null)); } return best; } /** Badge + strike price — used on category, home, search, and offers cards. */ function cardDiscountBadgeHtml(pct: number) { if (pct < 1) return ""; return `−${pct}%`; } /** PDP gallery with optional discount pill on the hero image. */ export function pdpGallerySection(images: string[], discountPct: number) { if (!images.length) return ""; const badge = discountPct >= 1 ? `−${discountPct}%` : ``; return ``; } function cardPriceHtml(price: number, compareAt?: number | null) { const pct = discountPercent(price, compareAt); if (pct < 1 || !compareAt) { return `

    ${esc(formatPrice(price))}

    `; } return `

    ${esc(formatPrice(price))} ${esc(formatPrice(compareAt))}

    `; } export function productGridCard( p: { id: string; name: string; nameFa?: string | null; slug: string; price: number; heroImage: string | null; category: string | null; stock?: number; colorVariants?: ColorVariant[]; } & CardFilterMeta, opts?: { trailingSlash?: boolean } ) { const hasVariants = (p.colorVariants?.length || 0) > 1; const title = productDisplayTitle(p, hasVariants); const href = productHref(p.slug, opts?.trailingSlash); const pct = listingDiscountPercent(p); return ``; } /** Compact top matches on the search results page (first 4 hits). */ export function searchQuickPreviewCard( p: { name: string; slug: string; price: number; heroImage: string | null; category?: string | null; colorVariants?: ColorVariant[]; }, opts?: { trailingSlash?: boolean } ) { const hasVariants = (p.colorVariants?.length || 0) > 1; const title = productDisplayTitle(p, hasVariants); const href = productHref(p.slug, opts?.trailingSlash); return ` ${ p.heroImage ? `${esc(title)}` : "" } ${esc(title)} ${esc(formatPrice(p.price))} `; } /** Related products on PDP — same shade-dot behavior as listing cards. */ export function relatedProductCard( p: { id: string; name: string; nameFa?: string | null; slug: string; price: number; compareAtPrice?: number | null; heroImage: string | null; category: string | null; tagline?: string | null; stock?: number; colorVariants?: ColorVariant[]; }, opts?: { trailingSlash?: boolean } ) { const hasVariants = (p.colorVariants?.length || 0) > 1; const title = productDisplayTitle(p, hasVariants); const href = productHref(p.slug, opts?.trailingSlash); const pct = listingDiscountPercent(p); return ``; } export function listProductCard( p: { id: string; name: string; nameFa?: string | null; slug: string; price: number; heroImage: string | null; category?: string | null; tagline?: string | null; stock?: number; colorVariants?: ColorVariant[]; } & CardFilterMeta, opts?: { trailingSlash?: boolean } ) { // Same card chrome as home grid: shade dots, aligned price, add-to-cart return productGridCard( { id: p.id, name: p.name, nameFa: p.nameFa, slug: p.slug, price: p.price, heroImage: p.heroImage, category: p.category ?? null, stock: p.stock, colorVariants: p.colorVariants, featured: p.featured, updatedAt: p.updatedAt, ratingAvg: p.ratingAvg, reviewCount: p.reviewCount, reviews: p.reviews, _count: p._count, compareAtPrice: p.compareAtPrice, discountPercent: p.discountPercent, }, opts ); } /** Horizontal “most selling” strip before the full collection grid. */ export function bestsellersSection( title: string, products: Array<{ id: string; name: string; slug: string; price: number; compareAtPrice?: number | null; heroImage: string | null; category: string | null; discountPercent?: number; colorVariants?: ColorVariant[]; } & CardFilterMeta>, opts?: { trailingSlash?: boolean } ) { if (!products.length) return ""; return `

    ${esc(title)}

    ${products.map((p) => productGridCard(p, opts)).join("")}
    `; } export function offerProductCard( p: { id: string; name: string; slug: string; price: number; compareAtPrice?: number | null; heroImage: string | null; category: string | null; stock?: number; discountPercent?: number; colorVariants?: ColorVariant[]; } & CardFilterMeta, opts?: { trailingSlash?: boolean } ) { return productGridCard(p, opts); } /** Discounted products slider with under-rail dots. */ export function offersSliderSection( title: string, products: Array<{ id: string; name: string; slug: string; price: number; compareAtPrice?: number | null; heroImage: string | null; category: string | null; discountPercent?: number; colorVariants?: ColorVariant[]; }>, opts?: { trailingSlash?: boolean } ) { if (!products.length) return ""; return `

    ${esc(title)}

    ${products.map((p) => offerProductCard(p, opts)).join("")}
    `; } /** Luxury editorial hero — now rendered inside sticky scrub (kept for compatibility) */ export function luxuryHeroHtml() { return ""; } /** Sticky scroll-scrub: motion video (left) + 3 editorial story cards (right) */ export function atelierHeroHtml(_images: string[] = []) { const stories: Array<{ id: string; titleHtml: string; body: string; cta: string; href: string; }> = [ { id: "0", titleHtml: "درخشش تکرار نشدنی که
    از ایتالیا می‌آید", body: "بافت‌های شفاف، نور نرم روی پوست — زیبایی که مثل خاطره‌ای از میلان می‌ماند.", cta: "ورود به دنیای کالکشن", href: "/collection/", }, { id: "1", titleHtml: "اورجینال،
    بی‌واسطه و ناب", body: "مستقیم از فروشگاه رسمی KIKO — هر شید، همان جادویی که در ایتالیا لمس می‌شود.", cta: "کشف محصولات اورجینال", href: "/collection/", }, { id: "2", titleHtml: "لحظه‌هایی که
    می‌درخشند", body: "از برق لب تا نگاه ماندگار — محبوب‌ترین انتخاب‌ها برای روزهای روشن و شب‌های خاص.", cta: "دیدن پرفروش‌ترین‌ها", href: "#bestsellers", }, ]; const cards = stories .map( (s, i) => `` ) .join(""); const dots = stories .map( (_, i) => `` ) .join(""); return `
    ${cards}

    اسکرول کنید تا موشن پخش شود

    `; } /** Trust / selling points */ export function trustSection() { const items = [ { t: "واردات مستقیم از ایتالیا", d: "بدون واسطه، از مبدأ تا درب منزل" }, { t: "تضمین اصالت کالا", d: "واردات از ایتالیا با تعهد به اصالت KIKO" }, { t: "ارسال سریع", d: "بسته‌بندی امن و تحویل به‌موقع" }, { t: "پشتیبانی تخصصی", d: "مشاوره زیبایی توسط تیم متخصص" }, ]; return `
    ${items .map( (i) => `

    ${i.t}

    ${i.d}

    ` ) .join("")}
    `; } /** Why us — advantages */ export function whyUsSection() { const rows = [ { n: "۰۱", t: "متخصص کیکو میلانو", d: "تمرکز کامل ما روی برند KIKO است؛ شناخت عمیق شیدها، فرمول‌ها و کالکشن‌های جدید.", }, { n: "۰۲", t: "قیمت رقابتی", d: "با واردات مستقیم، ارزش واقعی محصول اروپایی را با قیمت منصفانه دریافت می‌کنید.", }, { n: "۰۳", t: "تجربه خرید لوکس", d: "از انتخاب رنگ تا بسته‌بندی، هر جزئیات برای حسی شبیه بوتیک‌های زیبایی طراحی شده است.", }, ]; return `

    چرا کیکومیکو؟

    اعتماد، اصالت و زیبایی — سه اصل تجربه خرید شما.

    ${rows .map( (r) => `
    ${r.n}

    ${r.t}

    ${r.d}

    ` ) .join("")}
    `; } /** Persian customer reviews */ export function reviewsSection() { const reviews = [ { q: "سایه چشم متالیک‌شون روی پلک پخش نمی‌شه و رنگش دقیقاً همون چیزیه که تو عکس دیدم. بسته‌بندی هم خیلی شیک بود.", n: "الهام ن.", c: "کرج", }, { q: "برای اولین بار شید کانسیلر رو درست انتخاب کردم؛ عکسای سایت واقعی بودن و مشاوره واتساپ هم خیلی کمکم کرد.", n: "یاسمن ف.", c: "مشهد", }, { q: "پک مراقبت پوست که سفارش دادم اورجینال رسید، پلمب سالم. حس می‌کنم مستقیم از بوتیک میلان اومده.", n: "آیدا ح.", c: "رشت", }, ]; return `

    تجربه واقعی

    ${reviews .map( (r) => `

    «${esc(r.q)}»

    ${esc(r.n)} · ${esc(r.c)}
    ` ) .join("")}
    `; } /** FAQ accordion — pure HTML details */ export function faqSection() { return `

    سوالات متداول

    ${STORE_FAQS .map( (f) => `
    ${f.q}

    ${f.a}

    ` ) .join("")}
    `; } /** * Collaboration / campaign slider — Cavalli, Candy Crush, Club K. * Visually distinct from the full-bleed promo hero under the atelier section. */ export function collabBannersSection(opts?: { trailingSlash?: boolean }) { const slash = opts?.trailingSlash ? "/" : ""; const slides: Array<{ id: string; theme: "cavalli" | "candy" | "club"; titleHtml: string; sub: string; cta: string; href: string; durationMs: number; media: { src: string; mobileSrc?: string; alt: string }; }> = [ { id: "club-k", theme: "club", titleHtml: "Club K × KIKO", sub: "کالکشن Club K — ارزون ترین لوازم آرایشی که میتونی از کیکو بخری", cta: "خرید محصولات Club K", href: `/search/?q=${encodeURIComponent("Club K")}`, durationMs: 7000, media: { alt: "Club K by KIKO Milano", src: "https://images.kikocosmetics.com/lf2wbbijeo86/5DskZohflWHTTr99mVUKjU/a895a497ac86bf484d6f2cac7f6c4bcc/Launch_ClubK_HP_Slider_Desktop.jpg?w=1920&fm=webp&q=90", mobileSrc: "https://images.kikocosmetics.com/lf2wbbijeo86/4tclBcGmSsaaMO87jj5jlp/5d1eeb0e56e3f644c8c307c13908503f/Launch_ClubK_HP_Slider-Mobile.jpg?w=1080&fm=webp&q=90", }, }, { id: "candy-crush", theme: "candy", titleHtml: "Candy Crush × KIKO", sub: "کالکشن محدود کندی کراش — رنگ و بازی", cta: "خرید کالکشن کندی کراش", href: `/search/?q=${encodeURIComponent("Candy Crush")}`, durationMs: 7000, media: { alt: "Candy Crush x KIKO Milano limited edition", src: "/images/collab/candy-crush-banner.jpg", mobileSrc: "/images/collab/candy-crush-banner-mobile.jpg", }, }, { id: "cavalli-fusion", theme: "cavalli", titleHtml: "Roberto Cavalli × KIKO", sub: "جاست کاوالی فیوژن گلو — نسخه لیمیت ادیشن", cta: "خرید کالکشن کاوالی", href: "/search/?q=just+cavalli", durationMs: 7000, media: { alt: "Just Cavalli x KIKO Milano limited edition", src: "https://images.kikocosmetics.com/lf2wbbijeo86/6iTfXHCAkMpJo8KbpMtua0/113a1ec89f923f6339c2c7d8457eac7d/LimitedEdition_JustCavali_HP_Slider_Desktop_Products_03.webp?w=1920&fm=webp&q=90", mobileSrc: "https://images.kikocosmetics.com/lf2wbbijeo86/2LayvhGDaFD0rDvendGRxi/3a29ed6812d0b7910e29c3d70b651c60/LimitedEdition_JustCavallixKIKO_HP_Slider_Mobile.gif?w=1080&fm=webp&q=90", }, }, ]; const slidesHtml = slides .map((s, i) => { const media = ` ${ s.media.mobileSrc ? `` : "" } ${esc(s.media.alt)} `; return ``; }) .join(""); const dots = slides .map( (_, i) => `` ) .join(""); return `

    همکاری کیکو با سایر برندها - نسخه‌های لیمیت ادیشن

    ${slidesHtml}
    ${dots}
    `; } /** Magazine-style beauty inspiration (static, CSS-only) */ export function beautyInspirationBanner() { return `

    آرایش ایتالیایی،
    سبک ایرانی

    از بافت‌های شفاف لب تا سایه‌های مخملی چشم — کالکشن‌هایی که برای درخشش روزمره و شب‌های خاص ساخته شده‌اند.

    کشف کالکشن
    `; } /** KIKO homepage “Shop by Category”: Lips, Eyes, Face, Skin, Accessories */ export function kikoShopByCategoryItems( megaMenu: Array<{ key: string; featured: Array<{ heroImage: string | null; category: string | null }>; children?: Array<{ key: string; href: string }>; }> ): Array<{ label: string; href: string; img?: string | null }> { const makeup = megaMenu.find((m) => m.key === "make-up"); const skin = megaMenu.find((m) => m.key === "skin-care"); const acc = megaMenu.find((m) => m.key === "accessories"); const imgFor = ( root: | { featured: Array<{ heroImage: string | null; category: string | null }> } | undefined, needles: string | string[] ) => { const list = Array.isArray(needles) ? needles : [needles]; const featured = root?.featured ?? []; for (const needle of list) { const upper = needle.toUpperCase(); const hit = featured.find((p) => (p.category || "").toUpperCase().includes(upper) ); if (hit?.heroImage) return hit.heroImage; } return featured.find((p) => p.heroImage)?.heroImage ?? null; }; return [ { label: "لب", href: "/category/make-up/sub/lips-make-up/", img: imgFor(makeup, ["LIPS MAKE-UP", "LIPS", "LIP"]), }, { label: "چشم", href: "/category/make-up/sub/eyes-make-up/", img: imgFor(makeup, ["EYES MAKE-UP", "EYES", "EYE"]), }, { label: "صورت", href: "/category/make-up/sub/face-make-up/", img: imgFor(makeup, ["FACE MAKE-UP", "FACE"]), }, { label: "مراقبت پوست", href: "/category/skin-care/", img: imgFor(skin, ["SKIN CARE", "SKIN", "FACE CARE"]), }, { label: "اکسسوری", href: "/category/accessories/", img: imgFor(acc, ["ACCESSORIES", "ACCESSORY", "TOOLS"]), }, ]; } /** KIKO-style homepage promo carousel (4 slots — video + campaign stills) */ export function promoHeroSliderHtml() { const slides: Array<{ id: string; tone: "burgundy" | "frost" | "frost-dark"; titleHtml: string; sub: string; cta: string; href: string; durationMs: number; media: | { kind: "image"; src: string; mobileSrc?: string } | { kind: "video"; src: string; poster?: string }; }> = [ { id: "kiko-sale", tone: "frost", titleHtml: "حراج کیکو", sub: "تا ۷۰٪ تخفیف", cta: "خرید کنید", href: "/offers/", durationMs: 6500, media: { kind: "image", src: "https://images.kikocosmetics.com/lf2wbbijeo86/1YlokesjJQV77nKOfSbOpb/9d442692328ba645e37cfd75534e3cab/SummerSale_Bestseller_hp_slider_desktop.webp?w=1920&fm=webp", mobileSrc: "https://images.kikocosmetics.com/lf2wbbijeo86/2l2GIj2z5o76TxQVr7KP8p/ded199ce8a5a7c65cc7dd45e95c5de29/SummerSale_Bestseller_hp_slider_mobile.webp?w=900&fm=webp", }, }, { id: "matte-diaries", tone: "burgundy", titleHtml: "کالکشن محدود
    Matte Diaries", sub: "Not Shiny. Not Sorry.", cta: "خرید کنید", href: `/search/?q=${encodeURIComponent("Matte Diaries")}`, durationMs: 7000, media: { kind: "image", src: "https://images.kikocosmetics.com/lf2wbbijeo86/2ql2Sb1MDpfjVtUHCYLeKb/59b0faa4737f6f1fc457540c09de7a47/MatteDiaries_HP_Slider_Mobile.gif?w=1600&fm=webp", }, }, { id: "madonna", tone: "frost", titleHtml: "LET THE SHOW BEGIN", sub: "کمپین جدید کیکو اینجاست.", cta: "کشف کنید", href: "/collection/", durationMs: 8000, media: { kind: "video", src: "https://videos.kikocosmetics.com/lf2wbbijeo86/2fvGzw53OyqL2Ij40WnXMY/0e60e3ea00e28156a2d7396bbd29ce13/KIKO_BRAND_CAMPAIGN_6s_HP_MOBILE_TEASER_9MB.mp4", }, }, { id: "just-cavalli", tone: "frost-dark", titleHtml: "Just Cavalli X Kiko Milano", sub: "کالکشن محدود تابستانی", cta: "خرید کنید", href: "/search/?q=just+cavalli", durationMs: 6500, media: { kind: "image", src: "https://images.kikocosmetics.com/lf2wbbijeo86/6iTfXHCAkMpJo8KbpMtua0/113a1ec89f923f6339c2c7d8457eac7d/LimitedEdition_JustCavali_HP_Slider_Desktop_Products_03.webp?w=1920&fm=webp", mobileSrc: "https://images.kikocosmetics.com/lf2wbbijeo86/2LayvhGDaFD0rDvendGRxi/3a29ed6812d0b7910e29c3d70b651c60/LimitedEdition_JustCavallixKIKO_HP_Slider_Mobile.gif?w=900&fm=webp", }, }, ]; const slidesHtml = slides .map((s, i) => { const media = s.media.kind === "video" ? `` : ` ${ s.media.mobileSrc ? `` : "" } ${esc(`${s.titleHtml.replace(/<[^>]+>/g, `; return ``; }) .join(""); const bars = slides .map( (_s, i) => `` ) .join(""); return `
    ${slidesHtml}
    ${bars}
    `; } /** Top Categories — KIKO Italy “Top Categorie” smear tiles */ export function topCategoriesSection(categories: Array<{ label: string; href: string; img?: string | null }>) { if (!categories.length) return ""; const items = categories.map((cat, i) => ` ${esc(cat.label)} `).join(""); return `

    برترین دسته‌بندی‌ها

    ${items}
    `; } /** Trust strip (compact) — kept for compatibility; prefer trustSection() */ export function perksStrip() { return trustSection(); } /** Editorial promo banner between rails and collection */ export function promoBanner(opts: { title: string; titleBold: string; sub: string; ctaLabel: string; ctaHref: string; img?: string }) { return `

    ${opts.title} ${opts.titleBold}

    ${opts.sub}

    ${opts.ctaLabel}
    ${opts.img ? `
    ${opts.titleBold}
    ` : ""}
    `; } /** * Love Your Eyes (2+1) promo PLP — retired; kept only if needed for redirects. * Prefer omitting the route entirely (promo ended). */ export function loveYourEyesPromoBody( _products: Array[0]>, _opts?: { trailingSlash?: boolean; emptyLabel?: string } ) { return ""; } function atelierIcon(name: "italy" | "shield" | "ship" | "pay" | "support" | "trust") { const common = `class="atelier-ico" viewBox="0 0 24 24" aria-hidden="true"`; if (name === "italy") { return ``; } if (name === "shield") { return ``; } if (name === "ship") { return ``; } if (name === "pay") { return ``; } if (name === "support") { return ``; } return ``; } /** * Luxury Italian showroom hero — floating product compositions + exhibition features. * No phone. No device video. Scroll advances scenes only. */ /** Editorial intro after campaign video — HTML/CSS only */ export function italyIntroSections(images: string[] = []) { const img = (i: number) => images[i] || ""; const bubble = (src: string, alt: string) => `
    ${src ? `${esc(alt)}` : `KIKO`}
    `; const steps = [ { n: "1/", title: "اصالت میلان", product: "ORIGINAL FROM ITALY", body: "هر محصول مستقیم از اکوسیستم KIKO Milano انتخاب می‌شود؛ همان رنگ‌ها، بافت‌ها و استاندارد اروپایی که در ایتالیا عرضه می‌شود.", href: "/category/make-up", image: img(0), flip: false, }, { n: "2/", title: "انتخاب هوشمند", product: "CURATED DISCOUNTS", body: "به‌جای گشتن در هزاران SKU، کالکشن تخفیف‌دار و پرفروش را برای شما فیلتر کرده‌ایم تا خرید از ایتالیا سریع و مطمئن باشد.", href: "/#collection", image: img(1), flip: true, }, { n: "3/", title: "تجربه زیبایی", product: "MADE FOR YOUR RITUAL", body: "از آرایش تا مراقبت پوست؛ محصولات را مثل ابزار تناسب پوست در نظر بگیرید—روال روزمره با کیفیت میلان، به زبان و قیمت تومان.", href: "/category/skin-care", image: img(2), flip: false, }, ]; const stepHtml = steps .map( (s) => `` ) .join(""); return `

    فلسفه ما

    محصولات کیکو را مثل ابزار تناسب پوست، مستقیم از ایتالیا انتخاب می‌کنیم

    ${bubble(img(0), "KIKO Milano")}

    مراحل ضروری

    سه قدم ساده برای خرید مطمئن محصولات اصل KIKO از ایتالیا

    ${stepHtml}
    `; } function parseJson(raw: string, fallback: T): T { try { return JSON.parse(raw) as T; } catch { return fallback; } } export function renderBlocks( blocks: Array<{ type: string; content: string }>, productImages: string[] ) { return blocks .filter((b) => b.type !== "HERO") .map((block) => { const c = parseJson>(block.content, {}); if (block.type === "FAQ") { const items = (c.items as Array<{ question: string; answer: string }>) || []; return `
    ${c.title ? `

    ${esc(c.title)}

    ` : `

    پرسش‌ها

    `}
    ${items .map( (item) => `
    ${esc(item.question)}

    ${esc(item.answer)}

    ` ) .join("")}
    `; } if (block.type === "FEATURES" || block.type === "BENEFITS") { const features = (c.features as Array<{ title: string; description: string }>) || (c.items as Array<{ title: string; description: string }>) || []; return `
    ${c.title ? `

    ${esc(c.title)}

    ` : ""}
    ${features .map( (f) => `

    ${esc(f.title)}

    ${esc(f.description)}

    ` ) .join("")}
    `; } if (block.type === "GALLERY") { const images = (c.images as string[])?.length ? (c.images as string[]) : productImages; return `
    `; } if (block.type === "IMAGE_TEXT") { return `
    ${c.image ? `${esc(c.title || ` : ""}
    ${c.title ? `

    ${esc(c.title)}

    ` : ""}

    ${esc(c.body || "")}

    ${c.ctaText && c.ctaLink ? `

    ${esc(c.ctaText)}

    ` : ""}
    `; } if (block.type === "CTA") { return `

    ${esc(c.headline || "")}

    ${c.subheadline ? `

    ${esc(c.subheadline)}

    ` : ""} ${c.buttonText && c.buttonLink ? `

    ${esc(c.buttonText)}

    ` : ""}
    `; } if (block.type === "SPECIFICATIONS") { const rows = (c.items as Array<{ label: string; value: string }>) || (c.rows as Array<{ label: string; value: string }>) || []; return `
    ${c.title ? `

    ${esc(c.title)}

    ` : ""}
    ${rows .map( (r) => `
    ${esc(r.label)}
    ${esc(r.value)}
    ` ) .join("")}
    `; } if (block.type === "TESTIMONIAL" || block.type === "TRUST") { const items = (c.items as Array<{ quote?: string; text?: string; author?: string; title?: string; name?: string; description?: string }>) || []; return `
    ${c.title ? `

    ${esc(c.title)}

    ` : ""}
    ${items .map((t) => { const body = t.quote || t.text || t.description || ""; const who = t.author || t.name || ""; return `

    ${esc(body)}

    ${who ? `
    ${esc(who)}${t.title ? ` — ${esc(t.title)}` : ""}
    ` : ""}
    `; }) .join("")}
    `; } return ""; }) .join("\n"); } export function buyPanel(opts: { product: { id: string; slug: string; name: string; nameFa?: string | null; category?: string | null; tagline: string | null; price: number; compareAtPrice: number | null; heroImage: string | null; stock: number; lowStockThreshold: number; }; dict: Dictionary; colorVariants?: ColorVariant[]; trailingSlash?: boolean; }) { const { product: p, dict, colorVariants } = opts; const inStock = p.stock > 0; const discount = p.compareAtPrice && p.compareAtPrice > p.price ? Math.round(((p.compareAtPrice - p.price) / p.compareAtPrice) * 100) : null; const variants = colorVariants || []; const hasVariants = variants.length > 1; const current = variants.find((v) => v.id === p.id) || variants.find((v) => v.slug === p.slug); const title = productDisplayTitle(p, hasVariants); const categoryLink = productCategoryLink(p.name, p.category); const shadePicker = !hasVariants ? "" : `

    ${esc(dict.color)} ${esc(current?.shade || "")}

    ${variants .map((v) => { const active = v.id === p.id || v.slug === p.slug; const bg = v.heroImage ? `background-image:url('${esc(v.heroImage)}')` : ""; const oos = v.stock <= 0 ? " is-oos" : ""; const variantName = v.name.replace(/\s+/g, " ").trim(); const variantTitle = withPersianCategory(variantName, p.category); const variantIntro = `${persianCategoryLabel(p.category, variantName)} کیکو میلانو مدل ${variantName}${v.shade ? `، رنگ ${v.shade}` : ""}.`; return ``; }) .join("")}
    `; return `

    ${esc(dict.exclusive)}

    ${loveYourEyesPillHtml(p.slug)}

    ${esc(title)}

    ${categoryLink ? `

    دسته‌بندی: ${esc(categoryLink.label)}

    ` : ""} ${p.tagline ? `

    ${esc(p.tagline)}

    ` : ""}
    ${esc(formatPrice(p.price))} ${ p.compareAtPrice && p.compareAtPrice > p.price ? `${esc(formatPrice(p.compareAtPrice))}−${discount}%` : "" }

    ${ !inStock ? esc(dict.outOfStock) : inStock && p.stock <= p.lowStockThreshold ? `${esc(dict.limitedStock)} ${p.stock}` : "" }

    ${shadePicker}
    • ${esc(dict.authenticity)}
    `; }