diff --git a/app/[locale]/(site)/page.tsx b/app/[locale]/(site)/page.tsx index 5321b9b..00c1739 100644 --- a/app/[locale]/(site)/page.tsx +++ b/app/[locale]/(site)/page.tsx @@ -1,27 +1,36 @@ import type { Metadata } from "next"; -import { - ArrowRight, - BadgeCheck, - Blocks, - BriefcaseBusiness, - ChartNoAxesCombined, - Globe, - Package2, - Search, -} from "lucide-react"; -import Link from "next/link"; import { getLocale, getTranslations } from "next-intl/server"; import { Container } from "@/components/layout/container"; import { HomeHero } from "@/components/layout/home-hero"; -import { StackedMarqueeSection, type MarqueeRow } from "@/components/layout/stacked-marquee-section"; import { MotionFade } from "@/components/motion-fade"; -import { getMarqueeSettings, getSiteSettings, splitMarqueeRowItems } from "@/lib/app-config"; +import { BentoGridSection } from "@/components/home/bento-grid-section"; +import { CapabilitiesSection } from "@/components/home/capabilities-section"; +import { ContactCtaSection } from "@/components/home/contact-cta-section"; +import { MarqueeSection } from "@/components/home/marquee-section"; +import { ProcessSection } from "@/components/home/process-section"; +import { ProjectsSection } from "@/components/home/projects-section"; +import type { + BentoSectionCopy, + CapabilitiesSectionCopy, + ContactCtaSectionCopy, + MarqueeSectionCopy, + ProcessSectionCopy, + ProjectCardCopy, + ProjectsSectionCopy, +} from "@/components/home/types"; import { buildLocalizedMetadata } from "@/lib/metadata"; -import { AppCard } from "@/components/ui/app-card"; -import { Button } from "@/components/ui/button"; -import { CardContent } from "@/components/ui/card"; import { getLocalizedPath, resolveLocale } from "@/lib/locale"; +import { + getMarqueeSettings, + getSiteSettings, + splitMarqueeRowItems, +} from "@/lib/app-config"; +import { + getLocalizedValue, + getPublishedPortfolioProjects, +} from "@/lib/portfolio"; +import { type MarqueeRow } from "@/components/layout/stacked-marquee-section"; type HomePageProps = { params: Promise<{ @@ -29,29 +38,22 @@ type HomePageProps = { }>; }; -const serviceIcons = [ - BriefcaseBusiness, - Globe, - Package2, - Blocks, - Search, - ChartNoAxesCombined, - BadgeCheck, -]; - export const dynamic = "force-dynamic"; export async function generateMetadata({ params }: HomePageProps): Promise { await params; const siteSettings = await getSiteSettings(); - const localeKey = resolveLocale(await getLocale().catch(() => siteSettings.defaultLocale), siteSettings.defaultLocale); + const localeKey = resolveLocale( + await getLocale().catch(() => siteSettings.defaultLocale), + siteSettings.defaultLocale, + ); const t = await getTranslations({ locale: localeKey, namespace: "homepage" }); return await buildLocalizedMetadata({ locale: localeKey, pathname: "/", - title: siteSettings.locales[localeKey].siteName, - description: t("heroText"), + title: t("meta.title"), + description: t("meta.description"), applyTitleTemplate: false, }); } @@ -59,100 +61,184 @@ export async function generateMetadata({ params }: HomePageProps): Promise siteSettings.defaultLocale), siteSettings.defaultLocale); - const [t, marqueeSettings] = await Promise.all([ + const localeKey = resolveLocale( + await getLocale().catch(() => siteSettings.defaultLocale), + siteSettings.defaultLocale, + ); + + const [t, marqueeSettings, publishedProjects] = await Promise.all([ getTranslations({ locale: localeKey, namespace: "homepage" }), getMarqueeSettings(), + getPublishedPortfolioProjects(), ]); - const serviceItems = [ - t("serviceBrand"), - t("serviceWebsite"), - t("serviceStore"), - t("serviceWordPress"), - t("serviceSeo"), - t("serviceTracking"), - t("serviceSystem"), - ]; + + const bentoCopy: BentoSectionCopy = { + eyebrow: t("bento.eyebrow"), + title: t("bento.title"), + description: t("bento.description"), + about: { + eyebrow: t("bento.about.eyebrow"), + title: t("bento.about.title"), + description: t("bento.about.description"), + points: t.raw("bento.about.points") as string[], + }, + coreStack: { + eyebrow: t("bento.coreStack.eyebrow"), + title: t("bento.coreStack.title"), + items: t.raw("bento.coreStack.items") as string[], + }, + availability: { + eyebrow: t("bento.availability.eyebrow"), + title: t("bento.availability.title"), + description: t("bento.availability.description"), + status: t("bento.availability.status"), + }, + currentFocus: { + eyebrow: t("bento.currentFocus.eyebrow"), + title: t("bento.currentFocus.title"), + items: t.raw("bento.currentFocus.items") as string[], + }, + contact: { + eyebrow: t("bento.contact.eyebrow"), + title: t("bento.contact.title"), + description: t("bento.contact.description"), + emailLabel: t("bento.contact.emailLabel"), + emailValue: t("bento.contact.emailValue"), + }, + highlights: { + eyebrow: t("bento.highlights.eyebrow"), + title: t("bento.highlights.title"), + items: t.raw("bento.highlights.items") as Array<{ value: string; label: string }>, + }, + }; + + const marqueeCopy: MarqueeSectionCopy = { + eyebrow: t("marquee.eyebrow"), + title: t("marquee.title"), + description: t("marquee.description"), + }; + + const projectsCopy: ProjectsSectionCopy = { + eyebrow: t("projects.eyebrow"), + title: t("projects.title"), + description: t("projects.description"), + stackLabel: t("projects.stackLabel"), + fallbackItems: t.raw("projects.fallbackItems") as ProjectsSectionCopy["fallbackItems"], + }; + + const capabilitiesCopy: CapabilitiesSectionCopy = { + eyebrow: t("capabilities.eyebrow"), + title: t("capabilities.title"), + description: t("capabilities.description"), + items: t.raw("capabilities.items") as CapabilitiesSectionCopy["items"], + }; + + const processCopy: ProcessSectionCopy = { + eyebrow: t("process.eyebrow"), + title: t("process.title"), + description: t("process.description"), + steps: t.raw("process.steps") as ProcessSectionCopy["steps"], + }; + + const contactCtaCopy: ContactCtaSectionCopy = { + eyebrow: t("contactCta.eyebrow"), + title: t("contactCta.title"), + description: t("contactCta.description"), + contactCta: t("contactCta.contactCta"), + githubCta: t("contactCta.githubCta"), + emailLabel: t("contactCta.emailLabel"), + emailValue: t("contactCta.emailValue"), + availabilityLabel: t("contactCta.availabilityLabel"), + availabilityValue: t("contactCta.availabilityValue"), + githubHref: t("contactCta.githubHref"), + }; + const marqueeLocale = marqueeSettings.locales[localeKey]; - const marqueeRows: MarqueeRow[] = [ + const marqueeRows = [ { direction: "left", duration: 126, items: splitMarqueeRowItems(marqueeLocale.row1) }, { direction: "right", duration: 220, items: splitMarqueeRowItems(marqueeLocale.row2) }, { direction: "left", duration: 168, items: splitMarqueeRowItems(marqueeLocale.row3) }, { direction: "right", duration: 144, items: splitMarqueeRowItems(marqueeLocale.row4) }, - ]; + ] satisfies MarqueeRow[]; + + const portfolioHref = getLocalizedPath(localeKey, "/portfolio", siteSettings.defaultLocale); + const contactHref = getLocalizedPath(localeKey, "/contact", siteSettings.defaultLocale); + const stackSets = t.raw("projects.stackSets") as string[][]; + + const selectedProjects = [ + ...publishedProjects.filter((project) => project.isFeatured), + ...publishedProjects.filter((project) => !project.isFeatured), + ].slice(0, 3); + + const projectCards: ProjectCardCopy[] = selectedProjects.map((project, index) => ({ + title: getLocalizedValue(project.title, localeKey), + summary: getLocalizedValue(project.summary, localeKey), + stack: stackSets[index] ?? stackSets[stackSets.length - 1] ?? [], + href: getLocalizedPath( + localeKey, + `/portfolio/${project.slug}`, + siteSettings.defaultLocale, + ), + cta: t("projects.cta"), + meta: [ + getLocalizedValue(project.category.name, localeKey), + getLocalizedValue(project.serviceLabel, localeKey), + String(project.projectYear), + ], + featured: index === 0, + })); + + const fallbackProjectCards: ProjectCardCopy[] = projectsCopy.fallbackItems.map((item) => ({ + title: item.title, + summary: item.summary, + stack: item.stack, + href: item.href === "/portfolio" ? portfolioHref : item.href === "/contact" ? contactHref : item.href, + cta: t("projects.cta"), + meta: [t("projects.fallbackMeta")], + })); + + const mergedProjectCards = [ + ...projectCards, + ...fallbackProjectCards.slice(0, Math.max(0, 3 - projectCards.length)), + ].slice(0, 3); return ( <> - - - - -
-
-

- {t("servicesEyebrow")} -

-

- {t("servicesTitle")} -

-

- {t("servicesText")} -

-
- - -
-
+ + + + -
- {serviceItems.map((item, index) => { - const Icon = serviceIcons[index]; + + + - return ( - -
- -
-

- {item} -

-
- ); - })} -
-
-
-
+ + + + + + + + + + + + + +
- - ); } diff --git a/components/home/bento-card.tsx b/components/home/bento-card.tsx new file mode 100644 index 0000000..f01a09f --- /dev/null +++ b/components/home/bento-card.tsx @@ -0,0 +1,57 @@ +import type { ReactNode } from "react"; + +import { AppCard } from "@/components/ui/app-card"; +import { cn } from "@/lib/utils"; + +type BentoCardProps = { + eyebrow: string; + title: string; + description?: string; + icon?: ReactNode; + className?: string; + children?: ReactNode; +}; + +export function BentoCard({ + eyebrow, + title, + description, + icon, + className, + children, +}: BentoCardProps) { + return ( + +
+
+
+

+ {eyebrow} +

+
+

+ {title} +

+ {description ? ( +

{description}

+ ) : null} +
+
+ {icon ? ( +
+ {icon} +
+ ) : null} +
+ {children} +
+
+ ); +} diff --git a/components/home/bento-grid-section.tsx b/components/home/bento-grid-section.tsx new file mode 100644 index 0000000..fbb8058 --- /dev/null +++ b/components/home/bento-grid-section.tsx @@ -0,0 +1,125 @@ +import { + Activity, + BriefcaseBusiness, + Layers3, + Mail, + Sparkles, + TimerReset, +} from "lucide-react"; + +import { Badge } from "@/components/ui/badge"; +import { SectionHeading } from "./section-heading"; +import { BentoCard } from "./bento-card"; +import type { BentoSectionCopy } from "./types"; + +type BentoGridSectionProps = { + copy: BentoSectionCopy; +}; + +export function BentoGridSection({ copy }: BentoGridSectionProps) { + return ( +
+ + +
+ } + className="xl:col-span-2 xl:row-span-2" + > +
    + {copy.about.points.map((item) => ( +
  • + {item} +
  • + ))} +
+
+ + } + > +
+ {copy.coreStack.items.map((item) => ( + + {item} + + ))} +
+
+ + } + > + + {copy.availability.status} + + + + } + > +
    + {copy.currentFocus.items.map((item) => ( +
  • + {item} +
  • + ))} +
+
+ + } + > +
+

+ {copy.contact.emailLabel} +

+

+ {copy.contact.emailValue} +

+
+
+ + } + > +
+ {copy.highlights.items.map((item) => ( +
+

+ {item.value} +

+

{item.label}

+
+ ))} +
+
+
+
+ ); +} diff --git a/components/home/capabilities-section.tsx b/components/home/capabilities-section.tsx new file mode 100644 index 0000000..0b76c1c --- /dev/null +++ b/components/home/capabilities-section.tsx @@ -0,0 +1,50 @@ +import { Bot, Database, Globe, ServerCog } from "lucide-react"; + +import { AppCard } from "@/components/ui/app-card"; +import { SectionHeading } from "./section-heading"; +import type { CapabilitiesSectionCopy } from "./types"; + +type CapabilitiesSectionProps = { + copy: CapabilitiesSectionCopy; +}; + +const capabilityIcons = [Globe, Database, ServerCog, Bot]; + +export function CapabilitiesSection({ copy }: CapabilitiesSectionProps) { + return ( +
+ + +
+ {copy.items.map((item, index) => { + const Icon = capabilityIcons[index] ?? Globe; + + return ( + +
+
+ +
+
+

+ {item.title} +

+

{item.description}

+
+
+
+ ); + })} +
+
+ ); +} diff --git a/components/home/contact-cta-section.tsx b/components/home/contact-cta-section.tsx new file mode 100644 index 0000000..6cbe98b --- /dev/null +++ b/components/home/contact-cta-section.tsx @@ -0,0 +1,64 @@ +import { ArrowUpRight, Mail } from "lucide-react"; +import Link from "next/link"; + +import { Button } from "@/components/ui/button"; +import { AppCard } from "@/components/ui/app-card"; +import type { ContactCtaSectionCopy } from "./types"; + +type ContactCtaSectionProps = { + copy: ContactCtaSectionCopy; + contactHref: string; +}; + +export function ContactCtaSection({ + copy, + contactHref, +}: ContactCtaSectionProps) { + return ( +
+ +
+
+

+ {copy.eyebrow} +

+

+ {copy.title} +

+

+ {copy.description} +

+ +
+
+

{copy.emailLabel}

+ + {copy.emailValue} + +
+
+

{copy.availabilityLabel}

+

{copy.availabilityValue}

+
+
+
+ +
+ + +
+
+
+
+ ); +} diff --git a/components/home/hero-section.tsx b/components/home/hero-section.tsx new file mode 100644 index 0000000..e5db3a8 --- /dev/null +++ b/components/home/hero-section.tsx @@ -0,0 +1,113 @@ +import { ArrowRight, MapPin, Sparkles } from "lucide-react"; +import Link from "next/link"; + +import { Button } from "@/components/ui/button"; +import { Badge } from "@/components/ui/badge"; +import { AppCard } from "@/components/ui/app-card"; +import { cn } from "@/lib/utils"; +import type { HeroCopy } from "./types"; + +type HeroSectionProps = { + copy: HeroCopy; + contactHref: string; + portfolioHref: string; +}; + +export function HeroSection({ + copy, + contactHref, + portfolioHref, +}: HeroSectionProps) { + return ( +
+
+
+ + + +
+

+ {copy.name} +

+

+ {copy.headline} +

+

+ {copy.description} +

+
+ +
+ + +
+ +
+ {copy.highlights.map((item) => ( + + {item} + + ))} +
+
+ + +
+
+ + +
+ +
+
+
+
+ ); +} + +type MetricCardProps = { + label: string; + value: string; + strong?: boolean; + icon?: typeof MapPin; +}; + +function MetricCard({ label, value, strong = false, icon: Icon }: MetricCardProps) { + return ( +
+
+ {Icon ? : null} + {label} +
+

+ {value} +

+
+ ); +} diff --git a/components/home/marquee-section.tsx b/components/home/marquee-section.tsx new file mode 100644 index 0000000..acab4fb --- /dev/null +++ b/components/home/marquee-section.tsx @@ -0,0 +1,27 @@ +import { StackedMarqueeSection, type MarqueeRow } from "@/components/layout/stacked-marquee-section"; +import { AppCard } from "@/components/ui/app-card"; +import { SectionHeading } from "./section-heading"; +import type { MarqueeSectionCopy } from "./types"; + +type MarqueeSectionProps = { + copy: MarqueeSectionCopy; + rows: MarqueeRow[]; +}; + +export function MarqueeSection({ copy, rows }: MarqueeSectionProps) { + return ( +
+ + + +
+ +
+
+
+ ); +} diff --git a/components/home/process-section.tsx b/components/home/process-section.tsx new file mode 100644 index 0000000..ec335e4 --- /dev/null +++ b/components/home/process-section.tsx @@ -0,0 +1,42 @@ +import { AppCard } from "@/components/ui/app-card"; +import { SectionHeading } from "./section-heading"; +import type { ProcessSectionCopy } from "./types"; + +type ProcessSectionProps = { + copy: ProcessSectionCopy; +}; + +export function ProcessSection({ copy }: ProcessSectionProps) { + return ( +
+ + +
+ {copy.steps.map((step, index) => ( + +
+

+ {String(index + 1).padStart(2, "0")} +

+
+

+ {step.title} +

+

{step.description}

+
+
+
+ ))} +
+
+ ); +} diff --git a/components/home/projects-section.tsx b/components/home/projects-section.tsx new file mode 100644 index 0000000..a484f2c --- /dev/null +++ b/components/home/projects-section.tsx @@ -0,0 +1,86 @@ +import { ArrowUpRight } from "lucide-react"; +import Link from "next/link"; + +import { Badge } from "@/components/ui/badge"; +import { AppCard } from "@/components/ui/app-card"; +import { SectionHeading } from "./section-heading"; +import type { ProjectCardCopy, ProjectsSectionCopy } from "./types"; + +type ProjectsSectionProps = { + copy: ProjectsSectionCopy; + items: ProjectCardCopy[]; +}; + +export function ProjectsSection({ copy, items }: ProjectsSectionProps) { + return ( +
+ + +
+ {items.map((item, index) => ( + +
+
+ {item.meta.map((metaItem) => ( + + {metaItem} + + ))} +
+ +
+

+ {item.title} +

+

{item.summary}

+
+ +
+

+ {copy.stackLabel} +

+
+ {item.stack.map((stackItem) => ( + + {stackItem} + + ))} +
+
+ +
+ + {item.cta} + + +
+
+
+ ))} +
+
+ ); +} diff --git a/components/home/section-heading.tsx b/components/home/section-heading.tsx new file mode 100644 index 0000000..eee38e9 --- /dev/null +++ b/components/home/section-heading.tsx @@ -0,0 +1,37 @@ +import { cn } from "@/lib/utils"; + +type SectionHeadingProps = { + eyebrow: string; + title: string; + description: string; + align?: "left" | "center"; + className?: string; +}; + +export function SectionHeading({ + eyebrow, + title, + description, + align = "left", + className, +}: SectionHeadingProps) { + return ( +
+

+ {eyebrow} +

+

+ {title} +

+

+ {description} +

+
+ ); +} diff --git a/components/home/types.ts b/components/home/types.ts new file mode 100644 index 0000000..a8f9077 --- /dev/null +++ b/components/home/types.ts @@ -0,0 +1,120 @@ +export type HeroCopy = { + availability: string; + name: string; + headline: string; + description: string; + primaryCta: string; + secondaryCta: string; + locationLabel: string; + locationValue: string; + roleLabel: string; + roleValue: string; + focusLabel: string; + focusValue: string; + highlights: string[]; +}; + +export type BentoSectionCopy = { + eyebrow: string; + title: string; + description: string; + about: { + eyebrow: string; + title: string; + description: string; + points: string[]; + }; + coreStack: { + eyebrow: string; + title: string; + items: string[]; + }; + availability: { + eyebrow: string; + title: string; + description: string; + status: string; + }; + currentFocus: { + eyebrow: string; + title: string; + items: string[]; + }; + contact: { + eyebrow: string; + title: string; + description: string; + emailLabel: string; + emailValue: string; + }; + highlights: { + eyebrow: string; + title: string; + items: Array<{ + value: string; + label: string; + }>; + }; +}; + +export type MarqueeSectionCopy = { + eyebrow: string; + title: string; + description: string; +}; + +export type ProjectCardCopy = { + title: string; + summary: string; + stack: string[]; + href: string; + cta: string; + meta: string[]; + featured?: boolean; +}; + +export type ProjectsSectionCopy = { + eyebrow: string; + title: string; + description: string; + stackLabel: string; + fallbackItems: Array<{ + title: string; + summary: string; + stack: string[]; + href: string; + }>; +}; + +export type CapabilitiesSectionCopy = { + eyebrow: string; + title: string; + description: string; + items: Array<{ + title: string; + description: string; + }>; +}; + +export type ProcessSectionCopy = { + eyebrow: string; + title: string; + description: string; + steps: Array<{ + title: string; + description: string; + }>; +}; + +export type ContactCtaSectionCopy = { + eyebrow: string; + title: string; + description: string; + contactCta: string; + githubCta: string; + emailLabel: string; + emailValue: string; + availabilityLabel: string; + availabilityValue: string; + githubHref: string; +}; diff --git a/messages/ar.json b/messages/ar.json index 28a25cf..e3fb712 100644 --- a/messages/ar.json +++ b/messages/ar.json @@ -36,23 +36,224 @@ "secondaryCta": "العودة للرئيسية" }, "homepage": { - "heroKicker": "مرحبااا، أنا محمد", - "heroTitle": "مطوّر واجهات ويب\nومصمّم جرافيك", - "heroText": "بشتغل على حلول رقمية لمشاكل حقيقية\nبتطلع ممتازة وبتشتغل بكفاءة.", - "servicesEyebrow": "شو فيني قدّم", - "servicesTitle": "حلول رقمية مصممة حسب شغلك، مو قوالب جاهزة.", - "servicesText": "من الهوية والموقع، للمتجر والسيو والتراكنغ، لحد الأنظمة الخاصة الداخلية. الفكرة إنو كل شيء يطلع مرتب، مفهوم، وقابل للنمو.", - "servicesPrimaryCta": "احكيلي عن مشروعك", - "servicesSecondaryCta": "شوف شغلي", - "serviceBrand": "بناء براند واضح ومرتب.", - "serviceWebsite": "موقع إلكتروني يليق بشغلك.", - "serviceStore": "متجر أسهل بالعرض والبيع.", - "serviceWordPress": "إضافة WordPress خاصة فيك.", - "serviceSeo": "تحسين الظهور بمحركات البحث.", - "serviceTracking": "تراكنغ واضح وفهم لحركة الزوار.", - "serviceSystem": "سستم خاص لشركتك أو لفريقك.", - "toPortfolio": "عرض الأعمال", - "toContact": "تواصل معي" + "meta": { + "title": "معرض أعمال مطور Full-stack", + "description": "منتجات رقمية حديثة وأنظمة قابلة للتوسع وتجارب متعددة اللغات مبنية بعقلية منتج واضحة." + }, + "heroVisual": { + "kicker": "مرحبا، أنا محمد", + "title": "مطوّر واجهات ويب\nومصمّم جرافيك", + "description": "أبني حلول رقمية لمشاكل حقيقية\nتبدو قوية وتعمل بكفاءة." + }, + "hero": { + "availability": "متاح لمشاريع مختارة", + "name": "محمد فراواتي", + "headline": "منتجات Full-stack تجمع بين تنفيذ Frontend قوي وأنظمة Backend موثوقة.", + "description": "أصمم وأبني تجارب ويب بمستوى عالي لفرق تحتاج وضوح وسرعة وتنفيذ جاهز للإنتاج من أول الفكرة حتى الإطلاق.", + "primaryCta": "ابدأ مشروعك", + "secondaryCta": "شوف الأعمال المختارة", + "locationLabel": "الموقع", + "locationValue": "برلين، ألمانيا", + "roleLabel": "الدور", + "roleValue": "مطور Full-stack", + "focusLabel": "التركيز الحالي", + "focusValue": "منتجات عالية الأداء وأتمتة وعمل منصات قابلة للصيانة.", + "highlights": [ + "تسليم بثلاث لغات", + "تنفيذ بعقلية منتج", + "شريك تقني لفرق جاهزة للإطلاق" + ] + }, + "bento": { + "eyebrow": "لمحات", + "title": "مبني لفرق تهتم بالجودة والسرعة والقرارات التقنية النظيفة.", + "description": "تنظيم الصفحة يعكس أسلوب شغلي: وضوح أولاً، تنفيذ قوي ثانياً، ومن دون تعقيد زائد بالنص.", + "about": { + "eyebrow": "عني", + "title": "أشتغل بين المنتج والهندسة والتنفيذ.", + "description": "شغلي يجمع بين التفكير المنتج والتنفيذ العملي، حتى يحصل المؤسسون والوكالات والفرق التقنية على مطور قادر ينقل المشروع من المعمارية للتفاصيل النهائية بدون ما يضيع المستوى.", + "points": [ + "أنظمة Frontend مع انضباط UX واضح", + "خدمات Backend وربط أنظمة لسير عمل حقيقي", + "تواصل واضح مع أصحاب القرار التقني وغير التقني", + "تسليم مع قابلية صيانة محسوبة من أول يوم" + ] + }, + "coreStack": { + "eyebrow": "Core stack", + "title": "أدواتي اليومية", + "items": [ + "Next.js", + "TypeScript", + "React", + "Node.js", + "PostgreSQL", + "Tailwind CSS", + "Prisma", + "Docker" + ] + }, + "availability": { + "eyebrow": "التوفر", + "title": "جاهز لتعاونات مركزة", + "description": "أفضل مناسبة لستارت أب ووكالات وفرق تريد شخصاً تقنياً واحداً يدير التنفيذ من البداية للنهاية.", + "status": "فرص جديدة متاحة" + }, + "currentFocus": { + "eyebrow": "التركيز الحالي", + "title": "أكثر شيء أعمل عليه حالياً", + "items": [ + "مواقع تسويقية بمستوى UX قريب من المنتجات", + "لوحات تحكم وأدوات داخلية للإدارة", + "مسارات أتمتة للمحتوى والعمليات" + ] + }, + "contact": { + "eyebrow": "تواصل سريع", + "title": "أقصر طريق للوصول إلي", + "description": "إذا كان الطلب واضحاً من الآن، أرسل السياق والمدة الزمنية وأرجع لك بالخطوة الصحيحة مباشرة.", + "emailLabel": "البريد الإلكتروني", + "emailValue": "hello@moh-sass.dev" + }, + "highlights": { + "eyebrow": "لمحات", + "title": "مبادئ العمل", + "items": [ + { + "value": "3", + "label": "لغات مدعومة" + }, + { + "value": "E2E", + "label": "ملكية تسليم كاملة" + }, + { + "value": "24/7", + "label": "عقلية إنتاج" + } + ] + } + }, + "marquee": { + "eyebrow": "الأدوات المعتمدة", + "title": "Stack عملي مختار على أساس الصيانة والسرعة والقيمة الطويلة المدى.", + "description": "قسم Marquee يستخدم إعدادات الموقع الموجودة مسبقاً حتى تبقى الصفحة متناسقة مع الأدوات والقدرات التي تريد إبرازها." + }, + "projects": { + "eyebrow": "مشاريع مختارة", + "title": "ثلاثة أمثلة على نوع الشغل الذي أحب أن أطلقه.", + "description": "الأعمال المختارة تجمع بين جودة واجهة قوية وبنية تقنية تبقى ثابتة بعد الإطلاق.", + "stackLabel": "Stack", + "cta": "فتح المشروع", + "fallbackMeta": "عمل مختار", + "stackSets": [ + [ + "Next.js", + "TypeScript", + "Design Systems" + ], + [ + "APIs", + "PostgreSQL", + "Automation" + ], + [ + "Tailwind CSS", + "Prisma", + "Infrastructure" + ] + ], + "fallbackItems": [ + { + "title": "إعادة بناء منصة منتج", + "summary": "تحديث عملي لمنصة خدمات مع UX أوضح ومعمارية أقوى ودورات تسليم أسرع.", + "stack": [ + "Next.js", + "TypeScript", + "PostgreSQL" + ], + "href": "/portfolio" + }, + { + "title": "لوحة عمليات داخلية", + "summary": "أداة داخلية تركز على تسريع القرار وتنظيف سير العمل وتقليل التنسيق اليدوي بين الفرق.", + "stack": [ + "React", + "Node.js", + "Automation" + ], + "href": "/portfolio" + }, + { + "title": "نظام مواقع للإطلاقات", + "summary": "أساس قابل لإعادة الاستخدام لإطلاق مواقع بسرعة بدون التنازل عن الجودة التقنية أو التحكم بالمحتوى.", + "stack": [ + "Tailwind CSS", + "CMS", + "Performance" + ], + "href": "/contact" + } + ] + }, + "capabilities": { + "eyebrow": "القدرات", + "title": "تغطية تقنية من الطرف للطرف بدون خسارة تركيز المنتج.", + "description": "كل مجال هنا مبني على شغل إنتاجي فعلي، وليس مجرد تسميات خدمات عامة.", + "items": [ + { + "title": "Frontend Engineering", + "description": "واجهات Responsive وأنظمة تصميم وتفاصيل تفاعل ومعمارية Components قابلة للتوسع." + }, + { + "title": "Backend Systems", + "description": "APIs منظمة وربط أنظمة ونمذجة بيانات ومنطق تطبيقي مصمم لتسليم يمكن الاعتماد عليه." + }, + { + "title": "DevOps & Infrastructure", + "description": "نشر وبيئات وتشغيل ومراقبة أساسية وقرارات Infrastructure تقلل العبء التشغيلي." + }, + { + "title": "Automation & AI Workflows", + "description": "طبقات أتمتة عملية تقلل العمل اليدوي وتربط بين المنتج والمحتوى والعمليات." + } + ] + }, + "process": { + "eyebrow": "آلية العمل", + "title": "مسار مختصر يبقي المشروع متقدماً.", + "description": "العملية مقصودة أن تكون بسيطة: نقلل الغموض مبكراً، نثبت القرارات التقنية، ثم نطلق بانضباط.", + "steps": [ + { + "title": "Discover", + "description": "نحدد الأهداف والقيود والجمهور والنتيجة الحقيقية المطلوبة من المنتج." + }, + { + "title": "Architect", + "description": "نرسم شكل النظام وحدوده التقنية وبنية المحتوى ومسار التنفيذ قبل الدخول في البناء الثقيل." + }, + { + "title": "Build", + "description": "ننّفذ مع عناية قوية بالواجهة ومنطق تطبيق نظيف وبنية قابلة للصيانة عبر كامل الـ stack." + }, + { + "title": "Ship", + "description": "نطلق بثقة ونتأكد من النتيجة ونترك المنتج بحالة مستقرة للمرحلة التالية." + } + ] + }, + "contactCta": { + "eyebrow": "ابدأ الحديث", + "title": "إذا المشروع يحتاج تنفيذ قوي، أقدر أدفعه للأمام.", + "description": "هات الملخص أو الاختناق الحالي أو الاتجاه العام. أقدر أساعد في ضبط النطاق وتصميم النظام وبناء المنتج.", + "contactCta": "تواصل معي", + "githubCta": "GitHub", + "emailLabel": "البريد الإلكتروني", + "emailValue": "hello@moh-sass.dev", + "availabilityLabel": "التوفر", + "availabilityValue": "مفتوح لشغل منتجات مركز", + "githubHref": "https://github.com/mohfarawati" + } }, "portfolioPage": { "title": "الأعمال", diff --git a/messages/de.json b/messages/de.json index 0208f35..b9965b9 100644 --- a/messages/de.json +++ b/messages/de.json @@ -36,23 +36,224 @@ "secondaryCta": "Zur Startseite" }, "homepage": { - "heroKicker": "Hi, ich bin Moh", - "heroTitle": "frontend\ndeveloper\n& designer", - "heroText": "Ich entwickle digitale Lösungen für echte Probleme,\ndie gut aussehen und sauber funktionieren.", - "servicesEyebrow": "Leistungen", - "servicesTitle": "Digitale Arbeit, die sich an deinem Geschäft orientiert und nicht an Vorlagen.", - "servicesText": "Von Markenaufbau und Websites bis zu Shops, SEO, Tracking, WordPress Plugins und internen Systemen geht es immer um dasselbe: mehr Klarheit, bessere Wirkung und eine saubere Grundlage für Wachstum.", - "servicesPrimaryCta": "Erzähl mir von deinem Projekt", - "servicesSecondaryCta": "Meine Arbeiten ansehen", - "serviceBrand": "Markenaufbau mit klarer Richtung.", - "serviceWebsite": "Websites mit sauberer Struktur.", - "serviceStore": "Shops, die klarer verkaufen.", - "serviceWordPress": "Eigene WordPress Plugins.", - "serviceSeo": "Mehr Sichtbarkeit in Suchmaschinen.", - "serviceTracking": "Tracking und bessere Auswertung.", - "serviceSystem": "Interne Systeme für Teams und Firmen.", - "toPortfolio": "Portfolio ansehen", - "toContact": "Kontakt aufnehmen" + "meta": { + "title": "Portfolio fuer Full-stack Entwicklung", + "description": "Moderne digitale Produkte, skalierbare Systeme und mehrsprachige Erlebnisse mit starkem Produktfokus." + }, + "heroVisual": { + "kicker": "Hi, ich bin Moh", + "title": "frontend\ndeveloper\n& designer", + "description": "Ich entwickle digitale Loesungen fuer echte Probleme,\ndie gut aussehen und sauber funktionieren." + }, + "hero": { + "availability": "Verfuegbar fuer ausgewaehlte Projekte", + "name": "Moh Farawati", + "headline": "Full-stack Produkte mit starker Frontend Umsetzung und verlaesslichen Backend Systemen.", + "description": "Ich konzipiere und entwickle hochwertige Web-Erlebnisse fuer Teams, die Klarheit, Geschwindigkeit und produktionsreife Umsetzung von der Strategie bis zum Launch brauchen.", + "primaryCta": "Projekt starten", + "secondaryCta": "Ausgewaehlte Arbeiten", + "locationLabel": "Standort", + "locationValue": "Berlin, Deutschland", + "roleLabel": "Rolle", + "roleValue": "Full-stack Entwickler", + "focusLabel": "Aktueller Fokus", + "focusValue": "Performante Produkte, Automatisierung und wartbare Plattformarbeit.", + "highlights": [ + "3-sprachige Umsetzung", + "Produktorientierte Ausfuehrung", + "Technischer Partner fuer launchbereite Teams" + ] + }, + "bento": { + "eyebrow": "Highlights", + "title": "Gebaut fuer Teams, die Qualitaet, Tempo und saubere technische Entscheidungen ernst nehmen.", + "description": "Die Startseite ist so aufgebaut, wie ich arbeite: erst Klarheit, dann starke Umsetzung, ohne unnoetige Komplexitaet dazwischen.", + "about": { + "eyebrow": "Ueber mich", + "title": "Ich arbeite ueber Produkt, Engineering und Delivery hinweg.", + "description": "Meine Arbeit verbindet Produktdenken mit direkter Umsetzung. So bekommen Gruender, Agenturen und technische Teams einen Entwickler, der von Architektur bis zum finalen Detail liefern kann, ohne an Qualitaet zu verlieren.", + "points": [ + "Frontend Systeme mit klarer UX Disziplin", + "Backend Services und Integrationen fuer reale Prozesse", + "Klare Kommunikation mit technischen und nicht-technischen Stakeholdern", + "Lieferung mit Blick auf Wartbarkeit ab dem ersten Tag" + ] + }, + "coreStack": { + "eyebrow": "Core stack", + "title": "Taegliche Werkzeuge", + "items": [ + "Next.js", + "TypeScript", + "React", + "Node.js", + "PostgreSQL", + "Tailwind CSS", + "Prisma", + "Docker" + ] + }, + "availability": { + "eyebrow": "Verfuegbarkeit", + "title": "Offen fuer fokussierte Zusammenarbeit", + "description": "Am besten passend fuer Startups, Agenturen und Teams, die einen technischen Owner suchen, der die Umsetzung Ende zu Ende treiben kann.", + "status": "Neue Slots offen" + }, + "currentFocus": { + "eyebrow": "Aktueller Fokus", + "title": "Woran ich gerade am meisten baue", + "items": [ + "Marketing Websites mit Produktniveau in der UX", + "Admin Tools und interne Dashboards", + "Automatisierungsablaeufe fuer Content und Operations" + ] + }, + "contact": { + "eyebrow": "Schneller Kontakt", + "title": "Direkter Weg zu mir", + "description": "Wenn das Briefing schon klar ist, schick Kontext und Zeitrahmen und ich melde mich mit dem richtigen naechsten Schritt.", + "emailLabel": "E-Mail", + "emailValue": "hello@moh-sass.dev" + }, + "highlights": { + "eyebrow": "Highlights", + "title": "Arbeitsprinzipien", + "items": [ + { + "value": "3", + "label": "Unterstuetzte Sprachen" + }, + { + "value": "E2E", + "label": "Delivery Ownership" + }, + { + "value": "24/7", + "label": "Produktionsdenken" + } + ] + } + }, + "marquee": { + "eyebrow": "Werkzeuge", + "title": "Ein Arbeits-Stack, ausgewaehlt fuer Wartbarkeit, Geschwindigkeit und langfristigen Hebel.", + "description": "Das Marquee nutzt die bestehende Site-Konfiguration, damit die Startseite mit den hervorgehobenen Tools und Kompetenzen konsistent bleibt." + }, + "projects": { + "eyebrow": "Ausgewaehlte Projekte", + "title": "Drei Beispiele fuer die Art von Arbeit, die ich gerne ausliefere.", + "description": "Ausgewaehlte Projekte verbinden starke Interface-Qualitaet mit technischer Struktur, die auch nach dem Launch stabil bleibt.", + "stackLabel": "Stack", + "cta": "Projekt oeffnen", + "fallbackMeta": "Kuratiertes Projekt", + "stackSets": [ + [ + "Next.js", + "TypeScript", + "Design Systems" + ], + [ + "APIs", + "PostgreSQL", + "Automation" + ], + [ + "Tailwind CSS", + "Prisma", + "Infrastructure" + ] + ], + "fallbackItems": [ + { + "title": "Produktplattform Relaunch", + "summary": "Eine produktionsreife Erneuerung fuer eine Service-Plattform mit klarerer UX, besserer Architektur und schnelleren Lieferzyklen.", + "stack": [ + "Next.js", + "TypeScript", + "PostgreSQL" + ], + "href": "/portfolio" + }, + { + "title": "Operations Dashboard", + "summary": "Interne Tools mit Fokus auf schnellere Entscheidungen, sauberere Workflows und weniger manuelle Abstimmung im Team.", + "stack": [ + "React", + "Node.js", + "Automation" + ], + "href": "/portfolio" + }, + { + "title": "Launch Website System", + "summary": "Eine wiederverwendbare Website Grundlage fuer schnelle Launches ohne Abstriche bei technischer Qualitaet oder redaktioneller Kontrolle.", + "stack": [ + "Tailwind CSS", + "CMS", + "Performance" + ], + "href": "/contact" + } + ] + }, + "capabilities": { + "eyebrow": "Capabilities", + "title": "Technische Abdeckung von Ende zu Ende ohne den Produktfokus zu verlieren.", + "description": "Jeder Bereich ist um echte Produktionsarbeit aufgebaut und nicht um generische Service-Begriffe.", + "items": [ + { + "title": "Frontend Engineering", + "description": "Responsive Interfaces, Design Systems, Interaktionsqualitaet und Komponentenarchitektur fuer skalierbare Produkte." + }, + { + "title": "Backend Systems", + "description": "Strukturierte APIs, Integrationen, Datenmodelle und Applikationslogik fuer verlaessliche Umsetzung." + }, + { + "title": "DevOps & Infrastructure", + "description": "Deployments, Umgebungen, grundlegende Observability und Infrastrukturentscheidungen mit weniger operativer Reibung." + }, + { + "title": "Automation & AI Workflows", + "description": "Praktische Automatisierungsebenen, die manuelle Arbeit reduzieren und Produkt, Content und Operations verbinden." + } + ] + }, + "process": { + "eyebrow": "Prozess", + "title": "Ein kompakter Ablauf, der Projekte in Bewegung haelt.", + "description": "Der Prozess ist absichtlich einfach: Unklarheit frueh reduzieren, solide technische Entscheidungen treffen und diszipliniert ausliefern.", + "steps": [ + { + "title": "Discover", + "description": "Ziele, Grenzen, Zielgruppe und das eigentliche Ergebnis klaeren, das das Produkt erreichen soll." + }, + { + "title": "Architect", + "description": "Systemform, technische Grenzen, Inhaltsstruktur und Lieferweg definieren, bevor die schwere Umsetzung startet." + }, + { + "title": "Build", + "description": "Mit starker UI Qualitaet, sauberer Applikationslogik und wartbarer Struktur ueber den gesamten Stack umsetzen." + }, + { + "title": "Ship", + "description": "Sicher launchen, das Ergebnis validieren und das Produkt stabil fuer die naechste Phase hinterlassen." + } + ] + }, + "contactCta": { + "eyebrow": "Gespraech starten", + "title": "Wenn das Projekt starke Umsetzung braucht, kann ich es voranbringen.", + "description": "Bring das Briefing, den Engpass oder die grobe Richtung mit. Ich kann Scope schaerfen, das System entwerfen und das Produkt bauen.", + "contactCta": "Kontakt aufnehmen", + "githubCta": "GitHub", + "emailLabel": "E-Mail", + "emailValue": "hello@moh-sass.dev", + "availabilityLabel": "Verfuegbarkeit", + "availabilityValue": "Offen fuer fokussierte Produktarbeit", + "githubHref": "https://github.com/mohfarawati" + } }, "portfolioPage": { "title": "Portfolio", diff --git a/messages/en.json b/messages/en.json index 7ec1485..4a3419f 100644 --- a/messages/en.json +++ b/messages/en.json @@ -36,23 +36,224 @@ "secondaryCta": "Back to homepage" }, "homepage": { - "heroKicker": "Hi, I am Moh", - "heroTitle": "frontend\ndeveloper\n& designer", - "heroText": "I craft digital solutions for human problems\nthat look good and work well.", - "servicesEyebrow": "Capabilities", - "servicesTitle": "Digital work shaped around what your business actually needs.", - "servicesText": "From brand direction and websites to stores, SEO, tracking, WordPress plugins, and internal systems, the goal is the same: clearer structure, better performance, and room to grow.", - "servicesPrimaryCta": "Tell me about your project", - "servicesSecondaryCta": "See my work", - "serviceBrand": "Brand systems and visual direction.", - "serviceWebsite": "Business websites with clear structure.", - "serviceStore": "Stores built for easier selling.", - "serviceWordPress": "Custom WordPress plugin development.", - "serviceSeo": "Search visibility and technical SEO.", - "serviceTracking": "Tracking setup and user insights.", - "serviceSystem": "Custom internal systems for teams.", - "toPortfolio": "View portfolio", - "toContact": "Contact me" + "meta": { + "title": "Full-stack developer portfolio", + "description": "Modern digital products, scalable systems, and multilingual experiences built with product focus." + }, + "heroVisual": { + "kicker": "Hi, I am Moh", + "title": "frontend\ndeveloper\n& designer", + "description": "I craft digital solutions for human problems\nthat look good and work well." + }, + "hero": { + "availability": "Available for selected projects", + "name": "Moh Farawati", + "headline": "Full-stack products with sharp frontend execution and reliable backend systems.", + "description": "I design and build premium web experiences for teams that need clarity, speed, and production-ready engineering from strategy to launch.", + "primaryCta": "Start a project", + "secondaryCta": "View selected work", + "locationLabel": "Base", + "locationValue": "Berlin, Germany", + "roleLabel": "Role", + "roleValue": "Full-stack developer", + "focusLabel": "Current focus", + "focusValue": "High-performance products, automation, and maintainable platform work.", + "highlights": [ + "3-language delivery", + "Product-minded execution", + "Technical partner for launch-ready teams" + ] + }, + "bento": { + "eyebrow": "Highlights", + "title": "Built for teams that care about quality, speed, and clean technical decisions.", + "description": "The homepage is structured around the way I work: strategy first, strong execution second, and no wasted surface area in between.", + "about": { + "eyebrow": "About me", + "title": "I work across product, engineering, and delivery.", + "description": "My work combines product thinking with hands-on implementation, so founders, agencies, and technical teams get a developer who can move from architecture to shipped detail without losing quality.", + "points": [ + "Frontend systems with strong UX discipline", + "Backend services and integrations for real workflows", + "Clear communication with technical and non-technical stakeholders", + "Shipping with maintainability in mind from day one" + ] + }, + "coreStack": { + "eyebrow": "Core stack", + "title": "Daily tools", + "items": [ + "Next.js", + "TypeScript", + "React", + "Node.js", + "PostgreSQL", + "Tailwind CSS", + "Prisma", + "Docker" + ] + }, + "availability": { + "eyebrow": "Availability", + "title": "Open for focused collaborations", + "description": "Best fit for startups, agencies, and teams that want one technical owner who can drive implementation end to end.", + "status": "New slots open" + }, + "currentFocus": { + "eyebrow": "Current focus", + "title": "What I am building most", + "items": [ + "Marketing sites with product-grade UX", + "Admin tooling and internal dashboards", + "Automation flows around content and operations" + ] + }, + "contact": { + "eyebrow": "Quick contact", + "title": "Short path to reach me", + "description": "If the brief is already clear, send the context and timeline and I will reply with the right next step.", + "emailLabel": "Email", + "emailValue": "hello@moh-sass.dev" + }, + "highlights": { + "eyebrow": "Highlights", + "title": "Working principles", + "items": [ + { + "value": "3", + "label": "Supported languages" + }, + { + "value": "E2E", + "label": "Delivery ownership" + }, + { + "value": "24/7", + "label": "Production mindset" + } + ] + } + }, + "marquee": { + "eyebrow": "Trusted tools", + "title": "A working stack chosen for maintainability, speed, and long-term leverage.", + "description": "The marquee pulls from the existing site configuration so the homepage stays aligned with the tools and capabilities you want to highlight." + }, + "projects": { + "eyebrow": "Selected projects", + "title": "Three examples of the kind of work I like to ship.", + "description": "Featured work combines strong interface quality with technical structure that stays stable after launch.", + "stackLabel": "Stack", + "cta": "Open project", + "fallbackMeta": "Curated work", + "stackSets": [ + [ + "Next.js", + "TypeScript", + "Design Systems" + ], + [ + "APIs", + "PostgreSQL", + "Automation" + ], + [ + "Tailwind CSS", + "Prisma", + "Infrastructure" + ] + ], + "fallbackItems": [ + { + "title": "Product platform overhaul", + "summary": "A production-minded refresh for a service platform with clearer UX, stronger architecture, and faster delivery cycles.", + "stack": [ + "Next.js", + "TypeScript", + "PostgreSQL" + ], + "href": "/portfolio" + }, + { + "title": "Operations dashboard", + "summary": "Internal tooling focused on decision speed, cleaner workflows, and less manual coordination across teams.", + "stack": [ + "React", + "Node.js", + "Automation" + ], + "href": "/portfolio" + }, + { + "title": "Launch website system", + "summary": "A reusable website foundation for rapid launches without compromising technical quality or editorial control.", + "stack": [ + "Tailwind CSS", + "CMS", + "Performance" + ], + "href": "/contact" + } + ] + }, + "capabilities": { + "eyebrow": "Capabilities", + "title": "End-to-end technical coverage without losing product focus.", + "description": "Each capability area is shaped around production work, not generic service labels.", + "items": [ + { + "title": "Frontend Engineering", + "description": "Responsive interfaces, design systems, interaction polish, and component architecture built for scale." + }, + { + "title": "Backend Systems", + "description": "Structured APIs, integrations, data modeling, and application logic designed for dependable delivery." + }, + { + "title": "DevOps & Infrastructure", + "description": "Deployments, environments, observability basics, and infrastructure decisions that reduce operational drag." + }, + { + "title": "Automation & AI Workflows", + "description": "Practical automation layers that remove manual work and connect product, content, and operational tasks." + } + ] + }, + "process": { + "eyebrow": "Process", + "title": "A compact workflow that keeps projects moving.", + "description": "The process is intentionally simple: reduce ambiguity early, make sound technical decisions, and ship with discipline.", + "steps": [ + { + "title": "Discover", + "description": "Clarify goals, constraints, audience, and the real outcome the product needs to drive." + }, + { + "title": "Architect", + "description": "Define the system shape, technical boundaries, content structure, and delivery path before heavy implementation." + }, + { + "title": "Build", + "description": "Implement with strong UI detail, clean application logic, and maintainable structure across the stack." + }, + { + "title": "Ship", + "description": "Launch with confidence, validate the result, and leave the product in a stable state for the next phase." + } + ] + }, + "contactCta": { + "eyebrow": "Start the conversation", + "title": "If the project needs strong execution, I can help move it forward.", + "description": "Bring the brief, the bottleneck, or the rough direction. I can help shape the scope, design the system, and build the product.", + "contactCta": "Contact me", + "githubCta": "GitHub", + "emailLabel": "Email", + "emailValue": "hello@moh-sass.dev", + "availabilityLabel": "Availability", + "availabilityValue": "Open for focused product work", + "githubHref": "https://github.com/mohfarawati" + } }, "portfolioPage": { "title": "Portfolio",