diff --git a/prompt.txt b/prompt.txt
new file mode 100644
index 0000000..ed5a22d
--- /dev/null
+++ b/prompt.txt
@@ -0,0 +1,33 @@
+Create a website for kids and infants clothes store
+nininaderi.com
+
+Create sample content
+Lang:fa
+Directions: rtl
+Use next js
+Color palette is purple cyan red - light theme
+
+Design only homepage
+Use Persian font like iran-yekan or kalameh or iran sans and some cool kids like English font
+Do not use images - show only placeholders with sizes
+Do not use text over the images or banners - even slider
+
+Sections are:
+1.Top header bar
+2. Header
+3. Slider with two banner beside - height should be equal
+4. Featured categories
+5. Four features of our website :
+ارسال رایگان بالاتر از ۵ میلیون تومان
+ضمانت اصالت کالا
+امکان مرجوعی کالا
+رنگ بندی کامل
+
+6. Product Special sale carousel
+7. Two banner
+8. Product Top selling carousel
+9. 3 banner
+10. Yeganeh brand product carousel
+11. About nini Naderi
+12. Latest blog carousel
+13. footer
\ No newline at end of file
diff --git a/src/app/globals.css b/src/app/globals.css
index a2dc41e..bc10306 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -1,26 +1,139 @@
@import "tailwindcss";
:root {
- --background: #ffffff;
- --foreground: #171717;
+ --purple-50: #f6f1ff;
+ --purple-100: #ede4ff;
+ --purple-200: #d8c6ff;
+ --purple-300: #c4a5ff;
+ --purple-500: #8b5cf6;
+ --purple-600: #7c3aed;
+ --purple-700: #6d28d9;
+ --purple-800: #5b21b6;
+ --purple-900: #3b0764;
+ --cyan-50: #ecfeff;
+ --cyan-100: #cffafe;
+ --cyan-200: #a5f3fc;
+ --cyan-300: #67e8f9;
+ --cyan-400: #22d3ee;
+ --cyan-500: #06b6d4;
+ --cyan-600: #0891b2;
+ --rose-50: #fff1f2;
+ --rose-100: #ffe4e6;
+ --rose-200: #fecdd3;
+ --rose-300: #fda4af;
+ --rose-500: #f43f5e;
+ --rose-600: #e11d48;
+ --ink: #2a1838;
+ --muted: #6d5b78;
+ --line: #efe6f5;
+ --paper: #fffafd;
}
@theme inline {
- --color-background: var(--background);
- --color-foreground: var(--foreground);
- --font-sans: var(--font-geist-sans);
- --font-mono: var(--font-geist-mono);
+ --color-purple-50: var(--purple-50);
+ --color-purple-100: var(--purple-100);
+ --color-purple-200: var(--purple-200);
+ --color-purple-300: var(--purple-300);
+ --color-purple-500: var(--purple-500);
+ --color-purple-600: var(--purple-600);
+ --color-purple-700: var(--purple-700);
+ --color-purple-800: var(--purple-800);
+ --color-purple-900: var(--purple-900);
+ --color-cyan-50: var(--cyan-50);
+ --color-cyan-100: var(--cyan-100);
+ --color-cyan-200: var(--cyan-200);
+ --color-cyan-300: var(--cyan-300);
+ --color-cyan-400: var(--cyan-400);
+ --color-cyan-500: var(--cyan-500);
+ --color-cyan-600: var(--cyan-600);
+ --color-rose-50: var(--rose-50);
+ --color-rose-100: var(--rose-100);
+ --color-rose-200: var(--rose-200);
+ --color-rose-300: var(--rose-300);
+ --color-rose-500: var(--rose-500);
+ --color-rose-600: var(--rose-600);
+ --color-ink: var(--ink);
+ --color-muted: var(--muted);
+ --color-line: var(--line);
+ --color-paper: var(--paper);
+ --font-sans: var(--font-vazirmatn), "IranYekan", "IRANSans", Tahoma, sans-serif;
+ --font-display: var(--font-fredoka), "Fredoka", "Comic Sans MS", cursive;
+ --shadow-card: 0 10px 30px -18px rgb(91 33 182 / 0.28);
+ --shadow-soft: 0 8px 24px -16px rgb(42 24 56 / 0.18);
}
-@media (prefers-color-scheme: dark) {
- :root {
- --background: #0a0a0a;
- --foreground: #ededed;
- }
+html {
+ scroll-behavior: smooth;
}
body {
- background: var(--background);
- color: var(--foreground);
- font-family: Arial, Helvetica, sans-serif;
+ background-color: var(--paper);
+ background-image:
+ radial-gradient(ellipse 90% 42% at 10% 8%, rgb(237 228 255 / 0.9), transparent 70%),
+ radial-gradient(ellipse 80% 38% at 92% 6%, rgb(207 250 254 / 0.85), transparent 68%),
+ radial-gradient(ellipse 85% 40% at 78% 28%, rgb(255 228 230 / 0.8), transparent 70%),
+ radial-gradient(ellipse 70% 28% at 18% 36%, rgb(237 228 255 / 0.55), transparent 72%),
+ linear-gradient(to bottom, transparent 0%, transparent 62%, var(--paper) 100%);
+ background-repeat: no-repeat;
+ background-size: 100% 2200px;
+ background-position: top center;
+ color: var(--ink);
+ font-family: var(--font-sans);
+}
+
+.glass-box {
+ background: rgb(255 255 255 / 0.58);
+ backdrop-filter: blur(18px);
+ -webkit-backdrop-filter: blur(18px);
+ border: 1px solid rgb(255 255 255 / 0.72);
+}
+
+.font-display {
+ font-family: var(--font-display);
+}
+
+.font-count {
+ font-family: var(--font-count), var(--font-vazirmatn), sans-serif;
+}
+
+.container-nn {
+ margin-inline: auto;
+ width: 100%;
+ max-width: 1280px;
+ padding-inline: 1rem;
+}
+
+@media (min-width: 768px) {
+ .container-nn {
+ padding-inline: 1.25rem;
+ }
+}
+
+.placeholder-grid {
+ background-image: linear-gradient(135deg, rgb(255 255 255 / 0.22) 0%, transparent 48%);
+ background-repeat: no-repeat;
+}
+
+.hide-scrollbar {
+ -ms-overflow-style: none;
+ scrollbar-width: none;
+}
+
+.hide-scrollbar::-webkit-scrollbar {
+ display: none;
+}
+
+.slider-fade {
+ animation: slider-in 520ms ease;
+}
+
+@keyframes slider-in {
+ from {
+ opacity: 0;
+ transform: translateX(18px);
+ }
+ to {
+ opacity: 1;
+ transform: translateX(0);
+ }
}
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index 9852c15..23af5a8 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -1,29 +1,40 @@
import type { Metadata } from "next";
-import { Geist, Geist_Mono } from "next/font/google";
+import { Baloo_Bhaijaan_2, Fredoka, Vazirmatn } from "next/font/google";
import "./globals.css";
-const geistSans = Geist({
- variable: "--font-geist-sans",
- subsets: ["latin"],
+const vazirmatn = Vazirmatn({
+ subsets: ["arabic", "latin"],
+ variable: "--font-vazirmatn",
+ display: "swap",
});
-const geistMono = Geist_Mono({
- variable: "--font-geist-mono",
+const fredoka = Fredoka({
subsets: ["latin"],
+ variable: "--font-fredoka",
+ display: "swap",
+});
+
+const baloo = Baloo_Bhaijaan_2({
+ subsets: ["arabic", "latin"],
+ variable: "--font-count",
+ display: "swap",
});
export const metadata: Metadata = {
- title: "Create Next App",
- description: "Generated by create next app",
+ title: "نینی نادری | فروشگاه پوشاک نوزاد و کودک",
+ description:
+ "فروشگاه نینی نادری؛ لباس نوزاد، دخترانه و پسرانه با رنگبندی کامل، ضمانت اصالت و ارسال رایگان بالای ۵ میلیون تومان.",
+ metadataBase: new URL("https://nininaderi.com"),
};
export default function RootLayout({ children }: LayoutProps<"/">) {
return (
-
{children}
+ {children}
);
}
diff --git a/src/app/page.tsx b/src/app/page.tsx
index c887311..420f456 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -1,69 +1,49 @@
-import Image from "next/image";
+import { About } from "@/components/About";
+import { DualBanners, TripleBanners } from "@/components/Banners";
+import { BlogCarousel } from "@/components/BlogCarousel";
+import { FeaturedCategories } from "@/components/FeaturedCategories";
+import { Features } from "@/components/Features";
+import { Footer } from "@/components/Footer";
+import { Header } from "@/components/Header";
+import { Hero } from "@/components/Hero";
+import { ProductCarousel } from "@/components/ProductCarousel";
+import { TopHeader } from "@/components/TopHeader";
+import { saleProducts, topProducts, yeganehProducts } from "@/data/content";
export default function Home() {
return (
-
-
-
+
+
+
+
+
+
+
-
-
- To get started, edit the{" "}
-
- page.tsx
- {" "}
- file.
-
-
- Looking for a starting point or more instructions? Head over to{" "}
-
- Templates
- {" "}
- or the{" "}
-
- Learning
- {" "}
- center.
-
-
-
+
+
+
+
+
+
+
);
}
diff --git a/src/components/About.tsx b/src/components/About.tsx
new file mode 100644
index 0000000..07ef2fe
--- /dev/null
+++ b/src/components/About.tsx
@@ -0,0 +1,40 @@
+import { about } from "@/data/content";
+import { Placeholder } from "./Placeholder";
+
+export function About() {
+ return (
+
+
+
+
+
{about.english}
+
{about.title}
+
+
+ {about.paragraphs.map((paragraph) => (
+
{paragraph}
+ ))}
+
+
+ {about.stats.map((stat) => (
+
+
{stat.value}
+
{stat.label}
+
+ ))}
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/Banners.tsx b/src/components/Banners.tsx
new file mode 100644
index 0000000..ea75c18
--- /dev/null
+++ b/src/components/Banners.tsx
@@ -0,0 +1,30 @@
+import { dualBanners, tripleBanners } from "@/data/content";
+import { Placeholder } from "./Placeholder";
+
+export function DualBanners() {
+ return (
+
+
+ {dualBanners.map((banner) => (
+
+
+
+ ))}
+
+
+ );
+}
+
+export function TripleBanners() {
+ return (
+
+
+ {tripleBanners.map((banner) => (
+
+
+
+ ))}
+
+
+ );
+}
diff --git a/src/components/BlogCarousel.tsx b/src/components/BlogCarousel.tsx
new file mode 100644
index 0000000..f25c0ce
--- /dev/null
+++ b/src/components/BlogCarousel.tsx
@@ -0,0 +1,33 @@
+import { posts } from "@/data/content";
+import { Carousel } from "./Carousel";
+import { Placeholder } from "./Placeholder";
+import { SectionHeading } from "./SectionHeading";
+
+export function BlogCarousel() {
+ return (
+
+
+
+ {posts.map((post) => (
+
+
+
+
+ ))}
+
+
+ );
+}
diff --git a/src/components/Carousel.tsx b/src/components/Carousel.tsx
new file mode 100644
index 0000000..97c57c2
--- /dev/null
+++ b/src/components/Carousel.tsx
@@ -0,0 +1,48 @@
+"use client";
+
+import { useRef, type ReactNode } from "react";
+import { IconChevron } from "./Icons";
+
+type Props = {
+ children: ReactNode;
+};
+
+export function Carousel({ children }: Props) {
+ const scroller = useRef(null);
+
+ const move = (direction: 1 | -1) => {
+ const el = scroller.current;
+ if (!el) return;
+ const card = el.querySelector("[data-card]");
+ const amount = (card?.offsetWidth ?? 260) + 16;
+ const rtl = getComputedStyle(el).direction === "rtl";
+ el.scrollBy({ left: amount * direction * (rtl ? -1 : 1), behavior: "smooth" });
+ };
+
+ return (
+
+
+
+
+ {children}
+
+
+ );
+}
diff --git a/src/components/FeaturedCategories.tsx b/src/components/FeaturedCategories.tsx
new file mode 100644
index 0000000..a981efc
--- /dev/null
+++ b/src/components/FeaturedCategories.tsx
@@ -0,0 +1,30 @@
+import { categories } from "@/data/content";
+import { toFaDigits } from "@/lib/format";
+import { Placeholder } from "./Placeholder";
+import { SectionHeading } from "./SectionHeading";
+
+export function FeaturedCategories() {
+ return (
+
+ );
+}
diff --git a/src/components/Features.tsx b/src/components/Features.tsx
new file mode 100644
index 0000000..e6e10a5
--- /dev/null
+++ b/src/components/Features.tsx
@@ -0,0 +1,41 @@
+import { features } from "@/data/content";
+import { IconPalette, IconReturn, IconShield, IconTruck } from "./Icons";
+
+const icons = {
+ truck: IconTruck,
+ shield: IconShield,
+ return: IconReturn,
+ palette: IconPalette,
+};
+
+export function Features() {
+ return (
+
+
+ {features.map((feature, index) => {
+ const Icon = icons[feature.icon];
+ const colors = [
+ "bg-purple-50 text-purple-700",
+ "bg-cyan-50 text-cyan-600",
+ "bg-rose-50 text-rose-600",
+ "bg-purple-50 text-cyan-600",
+ ];
+ return (
+
+
+
+
+
+
{feature.title}
+
{feature.text}
+
+
+ );
+ })}
+
+
+ );
+}
diff --git a/src/components/Footer.tsx b/src/components/Footer.tsx
new file mode 100644
index 0000000..27f6a74
--- /dev/null
+++ b/src/components/Footer.tsx
@@ -0,0 +1,76 @@
+import Link from "next/link";
+import { footer } from "@/data/content";
+import { IconInstagram, IconPhone } from "./Icons";
+import { Placeholder } from "./Placeholder";
+
+export function Footer() {
+ return (
+
+ );
+}
+
+function FooterList({ title, items }: { title: string; items: string[] }) {
+ return (
+
+ );
+}
diff --git a/src/components/Header.tsx b/src/components/Header.tsx
new file mode 100644
index 0000000..c8ffcd6
--- /dev/null
+++ b/src/components/Header.tsx
@@ -0,0 +1,109 @@
+"use client";
+
+import Link from "next/link";
+import { useState } from "react";
+import { navLinks } from "@/data/content";
+import { IconBag, IconClose, IconHeart, IconMenu, IconSearch, IconUser } from "./Icons";
+
+export function Header() {
+ const [open, setOpen] = useState(false);
+
+ return (
+
+
+
+
+
+
+
+ NN
+
+
+ Nini Naderi
+ نینی نادری
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {open ? (
+
+ ) : null}
+
+ );
+}
diff --git a/src/components/Hero.tsx b/src/components/Hero.tsx
new file mode 100644
index 0000000..2c7a3ff
--- /dev/null
+++ b/src/components/Hero.tsx
@@ -0,0 +1,62 @@
+"use client";
+
+import { useEffect, useState } from "react";
+import { sideBanners, slides } from "@/data/content";
+import { Placeholder } from "./Placeholder";
+
+export function Hero() {
+ const [index, setIndex] = useState(0);
+ const slide = slides[index];
+
+ useEffect(() => {
+ const timer = window.setInterval(() => {
+ setIndex((current) => (current + 1) % slides.length);
+ }, 5200);
+ return () => window.clearInterval(timer);
+ }, []);
+
+ return (
+
+
+
+
+
+ {slides.map((item, itemIndex) => (
+
+ ))}
+
+
+
+ {sideBanners.map((banner) => (
+
+
+
+ ))}
+
+
+ );
+}
diff --git a/src/components/Icons.tsx b/src/components/Icons.tsx
new file mode 100644
index 0000000..fd3bd25
--- /dev/null
+++ b/src/components/Icons.tsx
@@ -0,0 +1,161 @@
+type IconProps = { className?: string };
+
+export function IconSearch({ className = "size-5" }: IconProps) {
+ return (
+
+ );
+}
+
+export function IconUser({ className = "size-5" }: IconProps) {
+ return (
+
+ );
+}
+
+export function IconHeart({ className = "size-5" }: IconProps) {
+ return (
+
+ );
+}
+
+export function IconBag({ className = "size-5" }: IconProps) {
+ return (
+
+ );
+}
+
+export function IconPhone({ className = "size-4" }: IconProps) {
+ return (
+
+ );
+}
+
+export function IconTruck({ className = "size-7" }: IconProps) {
+ return (
+
+ );
+}
+
+export function IconShield({ className = "size-7" }: IconProps) {
+ return (
+
+ );
+}
+
+export function IconReturn({ className = "size-7" }: IconProps) {
+ return (
+
+ );
+}
+
+export function IconPalette({ className = "size-7" }: IconProps) {
+ return (
+
+ );
+}
+
+export function IconChevron({ className = "size-5" }: IconProps) {
+ return (
+
+ );
+}
+
+export function IconMenu({ className = "size-6" }: IconProps) {
+ return (
+
+ );
+}
+
+export function IconClose({ className = "size-6" }: IconProps) {
+ return (
+
+ );
+}
+
+export function IconInstagram({ className = "size-4" }: IconProps) {
+ return (
+
+ );
+}
diff --git a/src/components/Placeholder.tsx b/src/components/Placeholder.tsx
new file mode 100644
index 0000000..6439cb6
--- /dev/null
+++ b/src/components/Placeholder.tsx
@@ -0,0 +1,41 @@
+import type { Tone } from "@/data/content";
+
+const tones: Record = {
+ purple: "bg-purple-200 from-purple-300 via-purple-200 to-purple-100 text-purple-800",
+ cyan: "bg-cyan-100 from-cyan-300 via-cyan-200 to-cyan-100 text-cyan-800",
+ rose: "bg-rose-100 from-rose-300 via-rose-200 to-rose-100 text-rose-700",
+};
+
+type Props = {
+ width: number;
+ height: number;
+ tone?: Tone;
+ className?: string;
+ rounded?: string;
+ fill?: boolean;
+ showSize?: boolean;
+};
+
+export function Placeholder({
+ width,
+ height,
+ tone = "purple",
+ className = "",
+ rounded = "rounded-2xl",
+ fill = false,
+ showSize = true,
+}: Props) {
+ return (
+
+ {showSize ? (
+
+ {width} × {height}
+
+ ) : null}
+
+ );
+}
diff --git a/src/components/ProductCard.tsx b/src/components/ProductCard.tsx
new file mode 100644
index 0000000..f5e6bcd
--- /dev/null
+++ b/src/components/ProductCard.tsx
@@ -0,0 +1,67 @@
+import type { Product } from "@/data/content";
+import { formatPrice } from "@/lib/format";
+import { Placeholder } from "./Placeholder";
+
+type Props = {
+ product: Product;
+};
+
+export function ProductCard({ product }: Props) {
+ return (
+
+
+
+
+
{product.brand}
+ {product.badge ? (
+
+ {product.badge}
+
+ ) : null}
+
+
+ {product.title}
+
+
+ {product.colors.map((color) => (
+
+ ))}
+
+
+
+ {product.oldPrice ? (
+
{formatPrice(product.oldPrice)}
+ ) : null}
+
{formatPrice(product.price)}
+
+
+
+
+
+ );
+}
diff --git a/src/components/ProductCarousel.tsx b/src/components/ProductCarousel.tsx
new file mode 100644
index 0000000..c53f95d
--- /dev/null
+++ b/src/components/ProductCarousel.tsx
@@ -0,0 +1,109 @@
+"use client";
+
+import { useEffect, useState } from "react";
+import type { Product } from "@/data/content";
+import { toFaDigits } from "@/lib/format";
+import { Carousel } from "./Carousel";
+import { Placeholder } from "./Placeholder";
+import { ProductCard } from "./ProductCard";
+import { SectionHeading } from "./SectionHeading";
+
+type Props = {
+ id?: string;
+ english: string;
+ title: string;
+ products: Product[];
+ countdown?: boolean;
+ leadBanner?: boolean;
+};
+
+export function ProductCarousel({
+ id,
+ english,
+ title,
+ products,
+ countdown,
+ leadBanner,
+}: Props) {
+ return (
+
+
+ {countdown ? : null}
+
+
+ {leadBanner ? (
+
+
+
+ ) : null}
+ {products.map((product) => (
+
+ ))}
+
+
+ );
+}
+
+function SaleTimer() {
+ const [left, setLeft] = useState({ h: 11, m: 42, s: 18 });
+
+ useEffect(() => {
+ const timer = window.setInterval(() => {
+ setLeft((current) => {
+ let { h, m, s } = current;
+ if (s > 0) s -= 1;
+ else if (m > 0) {
+ s = 59;
+ m -= 1;
+ } else if (h > 0) {
+ s = 59;
+ m = 59;
+ h -= 1;
+ } else {
+ h = 11;
+ m = 59;
+ s = 59;
+ }
+ return { h, m, s };
+ });
+ }, 1000);
+ return () => window.clearInterval(timer);
+ }, []);
+
+ const cells = [
+ { label: "ساعت", value: left.h },
+ { label: "دقیقه", value: left.m },
+ { label: "ثانیه", value: left.s },
+ ];
+
+ return (
+
+ {cells.map((cell, index) => (
+
+ {index > 0 ? (
+
:
+ ) : null}
+
+
+ {toFaDigits(String(cell.value).padStart(2, "0"))}
+
+
{cell.label}
+
+
+ ))}
+
+ );
+}
diff --git a/src/components/SectionHeading.tsx b/src/components/SectionHeading.tsx
new file mode 100644
index 0000000..b160775
--- /dev/null
+++ b/src/components/SectionHeading.tsx
@@ -0,0 +1,29 @@
+import type { ReactNode } from "react";
+
+type Props = {
+ english: string;
+ title: string;
+ href?: string;
+ children?: ReactNode;
+};
+
+export function SectionHeading({ english, title, href = "#", children }: Props) {
+ return (
+
+
+
{english}
+
{title}
+
+
+
+
+ );
+}
diff --git a/src/components/TopHeader.tsx b/src/components/TopHeader.tsx
new file mode 100644
index 0000000..55e9e10
--- /dev/null
+++ b/src/components/TopHeader.tsx
@@ -0,0 +1,21 @@
+import { IconInstagram, IconPhone } from "./Icons";
+
+export function TopHeader() {
+ return (
+
+
+
ارسال رایگان برای خریدهای بالای ۵ میلیون تومان
+
+
+
+ );
+}
diff --git a/src/data/content.ts b/src/data/content.ts
new file mode 100644
index 0000000..bbe14d7
--- /dev/null
+++ b/src/data/content.ts
@@ -0,0 +1,430 @@
+export type Tone = "purple" | "cyan" | "rose";
+
+export type Product = {
+ id: string;
+ title: string;
+ brand: string;
+ price: number;
+ oldPrice?: number;
+ colors: string[];
+ tone: Tone;
+ badge?: string;
+};
+
+export const navLinks = [
+ { href: "#", label: "صفحه اصلی" },
+ { href: "#categories", label: "نوزاد" },
+ { href: "#categories", label: "دخترانه" },
+ { href: "#categories", label: "پسرانه" },
+ { href: "#yeganeh", label: "برند یگانه" },
+ { href: "#sale", label: "فروش ویژه" },
+ { href: "#blog", label: "وبلاگ" },
+];
+
+export const slides = [
+ {
+ id: "s1",
+ tone: "purple" as Tone,
+ kicker: "Summer 1405",
+ title: "کالکشن تابستان نینیها",
+ text: "لباسهای نخی سبک برای بازی، خواب و گردشهای گرم. رنگبندی کامل از یاسی تا فیروزهای.",
+ cta: "مشاهده کالکشن",
+ size: "960 × 420",
+ },
+ {
+ id: "s2",
+ tone: "rose" as Tone,
+ kicker: "Newborn Sale",
+ title: "تخفیف ویژه نوزادی تا ۴۰٪",
+ text: "بادی، سرهمی و ست بیمارستانی برای روزهای اول. نرم روی پوست و آماده هدیه.",
+ cta: "خرید نوزادی",
+ size: "960 × 420",
+ },
+ {
+ id: "s3",
+ tone: "cyan" as Tone,
+ kicker: "Yeganeh",
+ title: "برند یگانه حالا در نینی نادری",
+ text: "دوخت تمیز، پارچه لطیف و ستهای خواهر و برادری که با هم جور میشوند.",
+ cta: "محصولات یگانه",
+ size: "960 × 420",
+ },
+];
+
+export const sideBanners = [
+ {
+ id: "sb1",
+ tone: "cyan" as Tone,
+ title: "ست خواهر و برادری",
+ text: "جفتهای رنگی برای عکسهای خانوادگی",
+ size: "360 × 200",
+ },
+ {
+ id: "sb2",
+ tone: "rose" as Tone,
+ title: "کفش اولین قدم",
+ text: "پاپوش نرم برای نوپاهای کنجکاو",
+ size: "360 × 200",
+ },
+];
+
+export const categories = [
+ { id: "c1", title: "لباس نوزاد", count: 86, tone: "purple" as Tone, size: "160 × 160" },
+ { id: "c2", title: "دخترانه", count: 124, tone: "rose" as Tone, size: "160 × 160" },
+ { id: "c3", title: "پسرانه", count: 118, tone: "cyan" as Tone, size: "160 × 160" },
+ { id: "c4", title: "ست و راحتی", count: 64, tone: "purple" as Tone, size: "160 × 160" },
+ { id: "c5", title: "کفش و پاپوش", count: 41, tone: "cyan" as Tone, size: "160 × 160" },
+ { id: "c6", title: "اکسسوری", count: 37, tone: "rose" as Tone, size: "160 × 160" },
+ { id: "c7", title: "حمام و حوله", count: 22, tone: "purple" as Tone, size: "160 × 160" },
+ { id: "c8", title: "مهمانی", count: 29, tone: "rose" as Tone, size: "160 × 160" },
+];
+
+export const features = [
+ {
+ id: "f1",
+ title: "ارسال رایگان بالاتر از ۵ میلیون تومان",
+ text: "سفارشهای بالای پنج میلیون، رایگان تا در خانه.",
+ icon: "truck" as const,
+ },
+ {
+ id: "f2",
+ title: "ضمانت اصالت کالا",
+ text: "هر تگ و دوخت را قبل از ارسال بررسی میکنیم.",
+ icon: "shield" as const,
+ },
+ {
+ id: "f3",
+ title: "امکان مرجوعی کالا",
+ text: "تا ۷ روز اگر سایز یا رنگ جور نبود برمیگردد.",
+ icon: "return" as const,
+ },
+ {
+ id: "f4",
+ title: "رنگ بندی کامل",
+ text: "از یاسی و سرخابی تا فیروزه؛ برای هر سلیقهای.",
+ icon: "palette" as const,
+ },
+];
+
+export const saleProducts: Product[] = [
+ {
+ id: "p1",
+ title: "سرهمی نخی نوزاد یاسی",
+ brand: "نینی نادری",
+ price: 890000,
+ oldPrice: 1290000,
+ colors: ["#C4B5FD", "#F9A8D4", "#67E8F9"],
+ tone: "purple",
+ badge: "۳۱٪",
+ },
+ {
+ id: "p2",
+ title: "پیراهن چیندار دخترانه",
+ brand: "یگانه",
+ price: 1450000,
+ oldPrice: 1890000,
+ colors: ["#FB7185", "#DDD6FE", "#FDE68A"],
+ tone: "rose",
+ badge: "۲۳٪",
+ },
+ {
+ id: "p3",
+ title: "تیشرت طرح دایناسور",
+ brand: "نینی نادری",
+ price: 620000,
+ oldPrice: 840000,
+ colors: ["#22D3EE", "#34D399", "#F97316"],
+ tone: "cyan",
+ badge: "۲۶٪",
+ },
+ {
+ id: "p4",
+ title: "بادی آستین بلند ارگانیک",
+ brand: "یگانه",
+ price: 540000,
+ oldPrice: 780000,
+ colors: ["#E9D5FF", "#FECDD3", "#A5F3FC"],
+ tone: "purple",
+ badge: "۳۱٪",
+ },
+ {
+ id: "p5",
+ title: "شلوار اسلش راحتی",
+ brand: "نینی نادری",
+ price: 710000,
+ oldPrice: 980000,
+ colors: ["#5B21B6", "#164E63", "#9F1239"],
+ tone: "cyan",
+ badge: "۲۸٪",
+ },
+ {
+ id: "p6",
+ title: "کت بافت پاییزه خردلی",
+ brand: "یگانه",
+ price: 1680000,
+ oldPrice: 2190000,
+ colors: ["#FBBF24", "#C4B5FD", "#FDA4AF"],
+ tone: "rose",
+ badge: "۲۳٪",
+ },
+ {
+ id: "p7",
+ title: "ست بیمارستانی نوزاد",
+ brand: "نینی نادری",
+ price: 1120000,
+ oldPrice: 1590000,
+ colors: ["#F5D0FE", "#BAE6FD", "#FEF3C7"],
+ tone: "purple",
+ badge: "۳۰٪",
+ },
+ {
+ id: "p8",
+ title: "کفش پارچهای نوپا",
+ brand: "یگانه",
+ price: 980000,
+ oldPrice: 1350000,
+ colors: ["#F43F5E", "#06B6D4", "#7C3AED"],
+ tone: "cyan",
+ badge: "۲۷٪",
+ },
+];
+
+export const dualBanners = [
+ {
+ id: "db1",
+ tone: "purple" as Tone,
+ kicker: "Party Edit",
+ title: "کالکشن مهمانی کوچولوها",
+ text: "پیراهن، سارافون و کتهای نرم برای جشن تولد",
+ size: "640 × 280",
+ },
+ {
+ id: "db2",
+ tone: "cyan" as Tone,
+ kicker: "Bedtime",
+ title: "لباس خواب نخی",
+ text: "شبهای آرام با پارچه سبک و دوخت بدون خارش",
+ size: "640 × 280",
+ },
+];
+
+export const topProducts: Product[] = [
+ {
+ id: "t1",
+ title: "ست خواهر برادری راه راه",
+ brand: "یگانه",
+ price: 1980000,
+ colors: ["#7C3AED", "#06B6D4", "#F43F5E"],
+ tone: "purple",
+ badge: "پرفروش",
+ },
+ {
+ id: "t2",
+ title: "سارافون جین دخترانه",
+ brand: "نینی نادری",
+ price: 1320000,
+ colors: ["#93C5FD", "#F9A8D4", "#FDE68A"],
+ tone: "cyan",
+ badge: "پرفروش",
+ },
+ {
+ id: "t3",
+ title: "هودی گوشدار خرسی",
+ brand: "یگانه",
+ price: 1540000,
+ colors: ["#FDBA74", "#C4B5FD", "#67E8F9"],
+ tone: "rose",
+ badge: "پرفروش",
+ },
+ {
+ id: "t4",
+ title: "بادی دکمه فشاری سهتایی",
+ brand: "نینی نادری",
+ price: 870000,
+ colors: ["#FDE68A", "#DDD6FE", "#A7F3D0"],
+ tone: "purple",
+ badge: "پرفروش",
+ },
+ {
+ id: "t5",
+ title: "شلوارک کتان پسرانه",
+ brand: "یگانه",
+ price: 760000,
+ colors: ["#155E75", "#44403C", "#7C3AED"],
+ tone: "cyan",
+ badge: "پرفروش",
+ },
+ {
+ id: "t6",
+ title: "کلاه و دستکش ست",
+ brand: "نینی نادری",
+ price: 390000,
+ colors: ["#FBCFE8", "#C4B5FD", "#A5F3FC"],
+ tone: "rose",
+ badge: "پرفروش",
+ },
+ {
+ id: "t7",
+ title: "پیراهن لینن تابستانه",
+ brand: "یگانه",
+ price: 1410000,
+ colors: ["#FDE68A", "#FECDD3", "#C7D2FE"],
+ tone: "purple",
+ badge: "پرفروش",
+ },
+ {
+ id: "t8",
+ title: "جوراب ساقبلند رنگی",
+ brand: "نینی نادری",
+ price: 210000,
+ colors: ["#F43F5E", "#06B6D4", "#8B5CF6"],
+ tone: "cyan",
+ badge: "پرفروش",
+ },
+];
+
+export const tripleBanners = [
+ {
+ id: "tb1",
+ tone: "rose" as Tone,
+ title: "دخترانه بهاری",
+ text: "گلگلی، چیندار و روشن",
+ size: "420 × 240",
+ },
+ {
+ id: "tb2",
+ tone: "cyan" as Tone,
+ title: "پسرانه اسپرت",
+ text: "هودی، تیشرت و شلوارک بازی",
+ size: "420 × 240",
+ },
+ {
+ id: "tb3",
+ tone: "purple" as Tone,
+ title: "نوزادی ارگانیک",
+ text: "پنبه لطیف برای پوست حساس",
+ size: "420 × 240",
+ },
+];
+
+export const yeganehProducts: Product[] = [
+ {
+ id: "y1",
+ title: "سرهمی یگانه طرح ستاره",
+ brand: "یگانه",
+ price: 1180000,
+ colors: ["#7C3AED", "#F472B6", "#22D3EE"],
+ tone: "purple",
+ badge: "یگانه",
+ },
+ {
+ id: "y2",
+ title: "ست دوتکه یگانه دخترانه",
+ brand: "یگانه",
+ price: 1720000,
+ colors: ["#FB7185", "#C4B5FD", "#FDE68A"],
+ tone: "rose",
+ badge: "یگانه",
+ },
+ {
+ id: "y3",
+ title: "پولوشرت یگانه پسرانه",
+ brand: "یگانه",
+ price: 990000,
+ colors: ["#0891B2", "#1E3A5F", "#F43F5E"],
+ tone: "cyan",
+ badge: "یگانه",
+ },
+ {
+ id: "y4",
+ title: "بادی یگانه بسته دوتایی",
+ brand: "یگانه",
+ price: 860000,
+ colors: ["#E9D5FF", "#A5F3FC", "#FECDD3"],
+ tone: "purple",
+ badge: "یگانه",
+ },
+ {
+ id: "y5",
+ title: "پیراهن یقه ب ب یگانه",
+ brand: "یگانه",
+ price: 1390000,
+ colors: ["#F9A8D4", "#FDE68A", "#C4B5FD"],
+ tone: "rose",
+ badge: "یگانه",
+ },
+ {
+ id: "y6",
+ title: "شلوار جین نرم یگانه",
+ brand: "یگانه",
+ price: 1250000,
+ colors: ["#93C5FD", "#64748B", "#7C3AED"],
+ tone: "cyan",
+ badge: "یگانه",
+ },
+];
+
+export const about = {
+ title: "درباره نینی نادری",
+ english: "About Nini Naderi",
+ paragraphs: [
+ "نینی نادری از یک دغدغه ساده شروع شد: پیدا کردن لباسی که هم روی پوست نوزاد نرم باشد، هم رنگش زنده بماند و هم بعد از چند بار شستوشو از ریخت نیفتد. ما فروشگاه تخصصی پوشاک نوزاد و کودک هستیم؛ از بادی روزهای اول تا کفش اولین قدم.",
+ "برند یگانه یکی از ثابتهای قفسه ماست؛ بهخاطر دوخت تمیز و رنگبندی کاملی که برای خواهر و برادرها جور درمیآید. کنار آن، انتخابهای خود نینی نادری را با پارچههای نخی و سایزبندی دقیق کنار هم چیدهایم.",
+ "هر سفارش با ضمانت اصالت ارسال میشود، امکان مرجوعی دارید و برای خریدهای بالای ۵ میلیون تومان پیک رایگان است. اگر سایز شک دارید، پشتیبانی نینی نادری کمکتان میکند.",
+ ],
+ stats: [
+ { value: "۱۲ سال", label: "همراه خانوادهها" },
+ { value: "+۴۰۰", label: "مدل فعال" },
+ { value: "۲۴ ساعته", label: "پاسخگویی سفارش" },
+ ],
+ imageSize: "560 × 400",
+};
+
+export const posts = [
+ {
+ id: "b1",
+ tone: "purple" as Tone,
+ date: "۲۳ مرداد ۱۴۰۵",
+ title: "چطور سایز لباس نوزاد را درست حدس بزنیم؟",
+ excerpt: "جدول دور سینه، قد و وزن؛ بدون خرید اشتباه و مرجوعی اضافه.",
+ size: "360 × 220",
+ },
+ {
+ id: "b2",
+ tone: "cyan" as Tone,
+ date: "۱۸ مرداد ۱۴۰۵",
+ title: "پارچه نخی بهتر است یا پنبه ارگانیک؟",
+ excerpt: "برای پوست حساس تابستان، کدام بافت خنکتر و کمحساسیتتر است.",
+ size: "360 × 220",
+ },
+ {
+ id: "b3",
+ tone: "rose" as Tone,
+ date: "۹ مرداد ۱۴۰۵",
+ title: "کفش اولین قدم؛ نرم باشد یا محکم؟",
+ excerpt: "پاپوش مناسب نوپا باید قوزک را نگه دارد اما انگشت را آزاد بگذارد.",
+ size: "360 × 220",
+ },
+ {
+ id: "b4",
+ tone: "purple" as Tone,
+ date: "۱ مرداد ۱۴۰۵",
+ title: "ست خواهر و برادری برای عکس تولد",
+ excerpt: "چطور رنگها را با هم هماهنگ کنیم بدون اینکه لباسها شبیه یونیفرم شوند.",
+ size: "360 × 220",
+ },
+];
+
+export const footer = {
+ blurb:
+ "فروشگاه پوشاک نوزاد و کودک نینی نادری. لباس نرم، رنگ زنده، ارسال سریع.",
+ shop: ["نوزاد", "دخترانه", "پسرانه", "برند یگانه", "فروش ویژه"],
+ help: ["پیگیری سفارش", "راهنمای سایز", "مرجوعی کالا", "سوالات پرتکرار", "تماس با ما"],
+ about: ["داستان نینی نادری", "شعب حضوری", "فرصت همکاری", "قوانین و حریم خصوصی"],
+ contact: {
+ phone: "۰۲۱-۹۱۰۰۱۲۳۴",
+ mobile: "۰۹۱۲۳۴۵۶۷۸۹",
+ email: "hello@nininaderi.com",
+ address: "تهران، خیابان شریعتی، بالاتر از میرداماد، پلاک ۲۴۸",
+ },
+};
diff --git a/src/lib/format.ts b/src/lib/format.ts
new file mode 100644
index 0000000..1df65bf
--- /dev/null
+++ b/src/lib/format.ts
@@ -0,0 +1,9 @@
+const FA_DIGITS = ["۰", "۱", "۲", "۳", "۴", "۵", "۶", "۷", "۸", "۹"];
+
+export function toFaDigits(value: number | string) {
+ return String(value).replace(/\d/g, (digit) => FA_DIGITS[Number(digit)]);
+}
+
+export function formatPrice(value: number) {
+ return `${toFaDigits(value.toLocaleString("en-US"))} تومان`;
+}