i18n: wire useTranslations for video-maker, image-maker, and pricing heading

- Add videoMaker + imageMaker namespace to en.json and fa.json
  (hero, features x5, use-cases x4, CTA per section)
- Pricing.tsx: replace hardcoded heading with t('pricing.heading')
- VideoMakerHero/Features/UseCases/Cta: full useTranslations wiring
- ImageMakerHero/Features/UseCases/Cta: full useTranslations wiring
- Features/UseCases arrays moved inside components; icons kept as
  module-level constants to avoid per-render allocation
This commit is contained in:
Soroush.Asadi
2026-05-25 07:40:26 +03:30
parent 39a86b93d4
commit 4875e468fe
11 changed files with 305 additions and 268 deletions
+64
View File
@@ -226,6 +226,70 @@
"searchPresets": "Search presets...", "searchPresets": "Search presets...",
"useTemplate": "Use Template" "useTemplate": "Use Template"
}, },
"videoMaker": {
"badge": "Video Maker",
"heroTitle": "AI Video Maker — Create stunning videos in minutes",
"heroDesc": "Script, edit, caption, and export professional videos without a production team. Templates and AI tools handle the heavy lifting.",
"heroCta": "Start Making Videos Free",
"heroBrowse": "Browse video templates",
"featuresHeading": "Everything you need to edit faster",
"featuresSub": "From first draft to final export, FlatRender keeps your workflow in one place.",
"feature0Title": "500+ templates",
"feature0Desc": "Launch promos, explainers, and social clips from studio-quality starting points.",
"feature1Title": "AI script writer",
"feature1Desc": "Turn a brief into scene-by-scene scripts with hooks, CTAs, and on-brand tone.",
"feature2Title": "Auto-subtitles",
"feature2Desc": "Generate accurate captions in dozens of languages with one-click styling.",
"feature3Title": "Music library",
"feature3Desc": "Licensed tracks and sound effects matched to mood, tempo, and video length.",
"feature4Title": "1-click export",
"feature4Desc": "Export MP4 up to 4K with presets for YouTube, Reels, ads, and presentations.",
"useCasesHeading": "Built for every channel",
"useCasesSub": "Pick a format and let templates handle aspect ratio, safe zones, and pacing.",
"useCase0Title": "YouTube",
"useCase0Desc": "Intros, outros, and long-form explainers with chapters and thumbnail-ready frames.",
"useCase1Title": "Instagram Reels",
"useCase1Desc": "Vertical templates, bold captions, and beat-synced cuts built for short-form.",
"useCase2Title": "Ads",
"useCase2Desc": "High-converting promos for Meta, Google, and TikTok with platform-safe ratios.",
"useCase3Title": "Corporate Videos",
"useCase3Desc": "Onboarding, training, and investor updates with consistent brand styling.",
"ctaHeading": "Ready to create your first video?",
"ctaDesc": "Join over a million creators using FlatRender Video Maker — free to start, no credit card required.",
"ctaButton": "Start Making Videos Free"
},
"imageMaker": {
"badge": "Image Maker",
"heroTitle": "AI Image Maker — Design professional visuals instantly",
"heroDesc": "Generate, resize, and brand every asset for social, ads, and print without switching tools or hiring a designer.",
"heroCta": "Start Creating Images Free",
"heroBrowse": "View example gallery",
"featuresHeading": "Design smarter, not harder",
"featuresSub": "FlatRender Image Maker combines AI generation with pro layout tools in one workflow.",
"feature0Title": "AI image generation",
"feature0Desc": "Describe your idea and get on-brand visuals, backgrounds, and product shots in seconds.",
"feature1Title": "Templates",
"feature1Desc": "Start from layouts built for posts, stories, ads, and presentations — fully editable.",
"feature2Title": "Resize for any platform",
"feature2Desc": "One design, every size: Instagram, LinkedIn, banners, and print-ready exports.",
"feature3Title": "Brand kit",
"feature3Desc": "Lock logos, fonts, and colors so every asset stays consistent across your team.",
"feature4Title": "Batch export",
"feature4Desc": "Export dozens of variations at once for campaigns, locales, and A/B tests.",
"useCasesHeading": "Visuals for every use case",
"useCasesSub": "From quick social graphics to polished brand assets — one tool, every format.",
"useCase0Title": "Social Posts",
"useCase0Desc": "Square, portrait, and carousel layouts with bold typography and safe zones.",
"useCase1Title": "Thumbnails",
"useCase1Desc": "High-contrast covers for YouTube, podcasts, and courses that read at any size.",
"useCase2Title": "Banners",
"useCase2Desc": "Website heroes, email headers, and ad banners with responsive crop guides.",
"useCase3Title": "Logos",
"useCase3Desc": "Vector-friendly marks and lockups with transparent exports for any background.",
"ctaHeading": "Start designing your next visual today",
"ctaDesc": "Free plan includes exports and basic templates. Upgrade anytime for AI generation and brand kits.",
"ctaButton": "Start Creating Images Free"
},
"common": { "common": {
"loading": "Loading...", "loading": "Loading...",
"error": "Error", "error": "Error",
+64
View File
@@ -226,6 +226,70 @@
"searchPresets": "جستجوی قالب‌ها...", "searchPresets": "جستجوی قالب‌ها...",
"useTemplate": "استفاده از قالب" "useTemplate": "استفاده از قالب"
}, },
"videoMaker": {
"badge": "ویدیو ساز",
"heroTitle": "ویدیو ساز هوشمند — ویدیوهای خیره‌کننده در چند دقیقه بسازید",
"heroDesc": "بدون تیم تولید، ویدیوهای حرفه‌ای را اسکریپت‌نویسی، ویرایش، زیرنویس و خروجی بگیرید. قالب‌ها و ابزارهای هوش مصنوعی کار سنگین را انجام می‌دهند.",
"heroCta": "رایگان ویدیو بسازید",
"heroBrowse": "مرور قالب‌های ویدیویی",
"featuresHeading": "همه چیز برای ویرایش سریع‌تر",
"featuresSub": "از پیش‌نویس اول تا خروجی نهایی، FlatRender جریان کاری شما را در یک جا نگه می‌دارد.",
"feature0Title": "بیش از ۵۰۰ قالب",
"feature0Desc": "تیزرها، توضیح‌دهنده‌ها و کلیپ‌های اجتماعی را از نقطه شروع‌های باکیفیت استودیویی راه‌اندازی کنید.",
"feature1Title": "نویسنده اسکریپت هوش مصنوعی",
"feature1Desc": "یک بریف را به اسکریپت‌های صحنه به صحنه با قلاب، CTA و لحن متناسب با برند تبدیل کنید.",
"feature2Title": "زیرنویس خودکار",
"feature2Desc": "با یک کلیک، کپشن‌های دقیق به ده‌ها زبان با استایل‌بندی آسان تولید کنید.",
"feature3Title": "کتابخانه موسیقی",
"feature3Desc": "آهنگ‌ها و افکت‌های صوتی مجاز متناسب با حال‌وهوا، ریتم و طول ویدیو.",
"feature4Title": "خروجی یک‌کلیکی",
"feature4Desc": "MP4 تا ۴K با پیش‌تنظیم برای یوتیوب، ریلز، آگهی‌ها و ارائه‌ها خروجی بگیرید.",
"useCasesHeading": "ساخته‌شده برای هر کانال",
"useCasesSub": "یک فرمت انتخاب کنید و بگذارید قالب‌ها نسبت تصویر، ناحیه‌های ایمن و ریتم را مدیریت کنند.",
"useCase0Title": "یوتیوب",
"useCase0Desc": "اینترو، اوترو و توضیح‌دهنده‌های بلند با فصل‌بندی و فریم‌های آماده تامبنیل.",
"useCase1Title": "ریلز اینستاگرام",
"useCase1Desc": "قالب‌های عمودی، کپشن‌های پررنگ و برش‌های هماهنگ با ریتم برای فرمت کوتاه.",
"useCase2Title": "آگهی‌ها",
"useCase2Desc": "تیزرهای پرتبدیل برای Meta، Google و TikTok با نسبت‌های ایمن پلتفرم.",
"useCase3Title": "ویدیوهای شرکتی",
"useCase3Desc": "آنبوردینگ، آموزش و گزارش‌های سرمایه‌گذاران با استایل‌بندی یکنواخت برند.",
"ctaHeading": "آماده‌اید اولین ویدیوتان را بسازید؟",
"ctaDesc": "به بیش از یک میلیون سازنده که از FlatRender Video Maker استفاده می‌کنند بپیوندید — شروع رایگان، بدون نیاز به کارت اعتباری.",
"ctaButton": "رایگان ویدیو بسازید"
},
"imageMaker": {
"badge": "تصویر ساز",
"heroTitle": "تصویر ساز هوشمند — ویژوال‌های حرفه‌ای را فوری طراحی کنید",
"heroDesc": "هر دارایی را برای رسانه اجتماعی، آگهی و چاپ بدون تغییر ابزار یا استخدام طراح تولید، تغییر اندازه و برند کنید.",
"heroCta": "رایگان تصویر بسازید",
"heroBrowse": "مشاهده نمونه‌ها",
"featuresHeading": "هوشمندانه‌تر طراحی کنید، نه سخت‌تر",
"featuresSub": "FlatRender Image Maker تولید هوش مصنوعی را با ابزارهای چیدمان حرفه‌ای در یک جریان کاری ترکیب می‌کند.",
"feature0Title": "تولید تصویر با هوش مصنوعی",
"feature0Desc": "ایده‌تان را توصیف کنید و ویژوال‌های متناسب با برند، پس‌زمینه‌ها و عکس‌های محصول را در ثانیه‌ها دریافت کنید.",
"feature1Title": "قالب‌ها",
"feature1Desc": "از چیدمان‌های ساخته‌شده برای پست، استوری، آگهی و ارائه شروع کنید — کاملاً قابل ویرایش.",
"feature2Title": "تغییر اندازه برای هر پلتفرم",
"feature2Desc": "یک طرح، هر اندازه: اینستاگرام، لینکدین، بنرها و خروجی‌های آماده چاپ.",
"feature3Title": "کیت برند",
"feature3Desc": "لوگوها، فونت‌ها و رنگ‌ها را قفل کنید تا هر دارایی در کل تیم یکنواخت بماند.",
"feature4Title": "خروجی دسته‌ای",
"feature4Desc": "ده‌ها نسخه را یکجا برای کمپین‌ها، لوکال‌ها و تست‌های A/B خروجی بگیرید.",
"useCasesHeading": "ویژوال برای هر کاربرد",
"useCasesSub": "از گرافیک‌های سریع اجتماعی تا دارایی‌های برند صیقلی — یک ابزار، هر فرمت.",
"useCase0Title": "پست‌های اجتماعی",
"useCase0Desc": "چیدمان‌های مربعی، پرتره و کاروسل با تایپوگرافی پررنگ و ناحیه‌های ایمن.",
"useCase1Title": "تامبنیل‌ها",
"useCase1Desc": "جلدهای کنتراست‌بالا برای یوتیوب، پادکست و دوره‌ها که در هر اندازه‌ای خوانا هستند.",
"useCase2Title": "بنرها",
"useCase2Desc": "هیروهای وب‌سایت، هدرهای ایمیل و بنرهای تبلیغاتی با راهنمای برش واکنش‌گرا.",
"useCase3Title": "لوگوها",
"useCase3Desc": "نشان‌ها و لوک‌آپ‌های وکتور با خروجی‌های شفاف برای هر پس‌زمینه‌ای.",
"ctaHeading": "همین امروز اولین ویژوالتان را طراحی کنید",
"ctaDesc": "پلن رایگان شامل خروجی و قالب‌های پایه است. برای تولید هوش مصنوعی و کیت برند هر زمان ارتقا دهید.",
"ctaButton": "رایگان تصویر بسازید"
},
"common": { "common": {
"loading": "در حال بارگذاری...", "loading": "در حال بارگذاری...",
"error": "خطا", "error": "خطا",
+16 -15
View File
@@ -1,30 +1,31 @@
"use client"; "use client";
import Link from "next/link"; import Link from "next/link";
import { useTranslations } from "next-intl";
import { SectionReveal } from "@/components/sections/SectionReveal"; import { SectionReveal } from "@/components/sections/SectionReveal";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
export function ImageMakerCta() { export function ImageMakerCta() {
const t = useTranslations("imageMaker");
return ( return (
<section className="bg-violet-600 py-20 sm:py-24"> <section className="bg-violet-600 py-20 sm:py-24">
<div className="mx-auto max-w-3xl px-4 text-center sm:px-6 lg:px-8"> <div className="mx-auto max-w-3xl px-4 text-center sm:px-6 lg:px-8">
<SectionReveal> <SectionReveal>
<h2 className="font-heading text-3xl font-bold text-white sm:text-4xl"> <h2 className="font-heading text-3xl font-bold text-white sm:text-4xl">
Start designing your next visual today {t("ctaHeading")}
</h2> </h2>
<p className="mt-4 text-lg text-violet-100"> <p className="mt-4 text-lg text-violet-100">
Free plan includes exports and basic templates. Upgrade anytime for AI {t("ctaDesc")}
generation and brand kits. </p>
</p> <Button
<Button size="lg"
size="lg" className="mt-8 bg-white text-violet-600 hover:bg-violet-50"
className="mt-8 bg-white text-violet-600 hover:bg-violet-50" asChild
asChild >
> <Link href="/auth?tab=sign-up">{t("ctaButton")}</Link>
<Link href="/auth?tab=sign-up">Start Creating Images Free</Link> </Button>
</Button>
</SectionReveal> </SectionReveal>
</div> </div>
</section> </section>
@@ -8,82 +8,56 @@ import {
Palette, Palette,
Sparkles, Sparkles,
} from "lucide-react"; } from "lucide-react";
import { useTranslations } from "next-intl";
import { SectionReveal } from "@/components/sections/SectionReveal"; import { SectionReveal } from "@/components/sections/SectionReveal";
interface Feature { const FEATURE_ICONS: LucideIcon[] = [
icon: LucideIcon; Sparkles,
title: string; LayoutTemplate,
description: string; Maximize2,
} Palette,
Files,
const features: Feature[] = [
{
icon: Sparkles,
title: "AI image generation",
description:
"Describe your idea and get on-brand visuals, backgrounds, and product shots in seconds.",
},
{
icon: LayoutTemplate,
title: "Templates",
description:
"Start from layouts built for posts, stories, ads, and presentations—fully editable.",
},
{
icon: Maximize2,
title: "Resize for any platform",
description:
"One design, every size: Instagram, LinkedIn, banners, and print-ready exports.",
},
{
icon: Palette,
title: "Brand kit",
description:
"Lock logos, fonts, and colors so every asset stays consistent across your team.",
},
{
icon: Files,
title: "Batch export",
description:
"Export dozens of variations at once for campaigns, locales, and A/B tests.",
},
]; ];
export function ImageMakerFeatures() { export function ImageMakerFeatures() {
const t = useTranslations("imageMaker");
const features = FEATURE_ICONS.map((Icon, i) => ({
Icon,
title: t(`feature${i}Title` as Parameters<typeof t>[0]),
description: t(`feature${i}Desc` as Parameters<typeof t>[0]),
}));
return ( return (
<section className="bg-neutral-50 py-20 sm:py-28"> <section className="bg-neutral-50 py-20 sm:py-28">
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8"> <div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<SectionReveal className="text-center"> <SectionReveal className="text-center">
<h2 className="font-heading text-3xl font-bold text-neutral-900 sm:text-4xl"> <h2 className="font-heading text-3xl font-bold text-neutral-900 sm:text-4xl">
Design smarter, not harder {t("featuresHeading")}
</h2> </h2>
<p className="mx-auto mt-4 max-w-2xl text-neutral-600"> <p className="mx-auto mt-4 max-w-2xl text-neutral-600">
CreatorStudio Image Maker combines AI generation with pro layout tools {t("featuresSub")}
in one workflow.
</p> </p>
</SectionReveal> </SectionReveal>
<SectionReveal className="mt-12 grid gap-6 sm:grid-cols-2 lg:grid-cols-3"> <SectionReveal className="mt-12 grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
{features.map((feature) => { {features.map(({ Icon, title, description }) => (
const Icon = feature.icon; <article
return ( key={title}
<article className="rounded-xl border border-gray-100 bg-white p-6 shadow-sm"
key={feature.title} >
className="rounded-xl border border-gray-100 bg-white p-6 shadow-sm" <div className="flex h-11 w-11 items-center justify-center rounded-lg bg-violet-600 text-white">
> <Icon className="h-5 w-5" aria-hidden />
<div className="flex h-11 w-11 items-center justify-center rounded-lg bg-violet-600 text-white"> </div>
<Icon className="h-5 w-5" aria-hidden /> <h3 className="mt-4 font-heading text-lg font-semibold text-neutral-900">
</div> {title}
<h3 className="mt-4 font-heading text-lg font-semibold text-neutral-900"> </h3>
{feature.title} <p className="mt-2 text-sm leading-relaxed text-neutral-600">
</h3> {description}
<p className="mt-2 text-sm leading-relaxed text-neutral-600"> </p>
{feature.description} </article>
</p> ))}
</article>
);
})}
</SectionReveal> </SectionReveal>
</div> </div>
</section> </section>
@@ -2,12 +2,15 @@
import Link from "next/link"; import Link from "next/link";
import { motion } from "framer-motion"; import { motion } from "framer-motion";
import { useTranslations } from "next-intl";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { ImageMakerBeforeAfter } from "./ImageMakerBeforeAfter"; import { ImageMakerBeforeAfter } from "./ImageMakerBeforeAfter";
export function ImageMakerHero() { export function ImageMakerHero() {
const t = useTranslations("imageMaker");
return ( return (
<section className="relative overflow-hidden bg-white pb-16 pt-12 sm:pb-20 sm:pt-16"> <section className="relative overflow-hidden bg-white pb-16 pt-12 sm:pb-20 sm:pt-16">
<div className="pointer-events-none absolute -left-32 top-0 h-96 w-96 rounded-full bg-violet-200/40 blur-3xl" /> <div className="pointer-events-none absolute -left-32 top-0 h-96 w-96 rounded-full bg-violet-200/40 blur-3xl" />
@@ -21,14 +24,13 @@ export function ImageMakerHero() {
transition={{ duration: 0.4, ease: "easeOut" }} transition={{ duration: 0.4, ease: "easeOut" }}
> >
<span className="inline-flex rounded-full bg-violet-100 px-3 py-1 text-xs font-semibold text-violet-700"> <span className="inline-flex rounded-full bg-violet-100 px-3 py-1 text-xs font-semibold text-violet-700">
Image Maker {t("badge")}
</span> </span>
<h1 className="mt-4 font-heading text-4xl font-bold tracking-tight text-neutral-900 sm:text-5xl"> <h1 className="mt-4 font-heading text-4xl font-bold tracking-tight text-neutral-900 sm:text-5xl">
AI Image Maker Design professional visuals instantly {t("heroTitle")}
</h1> </h1>
<p className="mt-6 text-lg leading-relaxed text-neutral-600"> <p className="mt-6 text-lg leading-relaxed text-neutral-600">
Generate, resize, and brand every asset for social, ads, and print {t("heroDesc")}
without switching tools or hiring a designer.
</p> </p>
<div className="mt-8 flex flex-col gap-4 sm:flex-row"> <div className="mt-8 flex flex-col gap-4 sm:flex-row">
<Button <Button
@@ -36,10 +38,10 @@ export function ImageMakerHero() {
className="bg-violet-600 hover:bg-violet-700" className="bg-violet-600 hover:bg-violet-700"
asChild asChild
> >
<Link href="/sign-up">Start Creating Images Free</Link> <Link href="/sign-up">{t("heroCta")}</Link>
</Button> </Button>
<Button variant="outline" size="lg" asChild> <Button variant="outline" size="lg" asChild>
<Link href="#gallery">View example gallery</Link> <Link href="#gallery">{t("heroBrowse")}</Link>
</Button> </Button>
</div> </div>
</motion.div> </motion.div>
@@ -7,76 +7,55 @@ import {
RectangleHorizontal, RectangleHorizontal,
Share2, Share2,
} from "lucide-react"; } from "lucide-react";
import { useTranslations } from "next-intl";
import { SectionReveal } from "@/components/sections/SectionReveal"; import { SectionReveal } from "@/components/sections/SectionReveal";
interface UseCase { const USE_CASE_ICONS: LucideIcon[] = [
title: string; Share2,
description: string; ImageIcon,
icon: LucideIcon; RectangleHorizontal,
} Hexagon,
const useCases: UseCase[] = [
{
title: "Social Posts",
description:
"Square, portrait, and carousel layouts with bold typography and safe zones.",
icon: Share2,
},
{
title: "Thumbnails",
description:
"High-contrast covers for YouTube, podcasts, and courses that read at any size.",
icon: ImageIcon,
},
{
title: "Banners",
description:
"Website heroes, email headers, and ad banners with responsive crop guides.",
icon: RectangleHorizontal,
},
{
title: "Logos",
description:
"Vector-friendly marks and lockups with transparent exports for any background.",
icon: Hexagon,
},
]; ];
export function ImageMakerUseCases() { export function ImageMakerUseCases() {
const t = useTranslations("imageMaker");
const useCases = USE_CASE_ICONS.map((Icon, i) => ({
Icon,
title: t(`useCase${i}Title` as Parameters<typeof t>[0]),
description: t(`useCase${i}Desc` as Parameters<typeof t>[0]),
}));
return ( return (
<section className="bg-white py-20 sm:py-28"> <section className="bg-white py-20 sm:py-28">
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8"> <div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<SectionReveal className="text-center"> <SectionReveal className="text-center">
<h2 className="font-heading text-3xl font-bold text-neutral-900 sm:text-4xl"> <h2 className="font-heading text-3xl font-bold text-neutral-900 sm:text-4xl">
Visuals for every use case {t("useCasesHeading")}
</h2> </h2>
<p className="mx-auto mt-4 max-w-2xl text-neutral-600"> <p className="mx-auto mt-4 max-w-2xl text-neutral-600">
From quick social graphics to polished brand assetsone tool, every {t("useCasesSub")}
format.
</p> </p>
</SectionReveal> </SectionReveal>
<SectionReveal className="mt-12 grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-4"> <SectionReveal className="mt-12 grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-4">
{useCases.map((useCase) => { {useCases.map(({ Icon, title, description }) => (
const Icon = useCase.icon; <article
return ( key={title}
<article className="rounded-xl border border-gray-100 bg-white p-6 shadow-sm transition-shadow hover:shadow-md"
key={useCase.title} >
className="rounded-xl border border-gray-100 bg-white p-6 shadow-sm transition-shadow hover:shadow-md" <div className="flex h-12 w-12 items-center justify-center rounded-xl bg-violet-50 text-violet-600">
> <Icon className="h-6 w-6" aria-hidden />
<div className="flex h-12 w-12 items-center justify-center rounded-xl bg-violet-50 text-violet-600"> </div>
<Icon className="h-6 w-6" aria-hidden /> <h3 className="mt-4 font-heading text-lg font-semibold text-neutral-900">
</div> {title}
<h3 className="mt-4 font-heading text-lg font-semibold text-neutral-900"> </h3>
{useCase.title} <p className="mt-2 text-sm leading-relaxed text-neutral-600">
</h3> {description}
<p className="mt-2 text-sm leading-relaxed text-neutral-600"> </p>
{useCase.description} </article>
</p> ))}
</article>
);
})}
</SectionReveal> </SectionReveal>
</div> </div>
</section> </section>
+3 -1
View File
@@ -1,6 +1,7 @@
"use client"; "use client";
import { useState } from "react"; import { useState } from "react";
import { useTranslations } from "next-intl";
import { PricingBillingToggle } from "@/components/sections/PricingBillingToggle"; import { PricingBillingToggle } from "@/components/sections/PricingBillingToggle";
import { PricingCard } from "@/components/sections/PricingCard"; import { PricingCard } from "@/components/sections/PricingCard";
@@ -16,13 +17,14 @@ export interface PricingProps {
} }
export function Pricing({ className }: PricingProps) { export function Pricing({ className }: PricingProps) {
const t = useTranslations("pricing");
const [billing, setBilling] = useState<BillingPeriod>("annual"); const [billing, setBilling] = useState<BillingPeriod>("annual");
return ( return (
<PricingSectionShell className={className}> <PricingSectionShell className={className}>
<SectionReveal className="text-center"> <SectionReveal className="text-center">
<h2 className="font-heading text-3xl font-bold tracking-tight text-neutral-900 sm:text-4xl"> <h2 className="font-heading text-3xl font-bold tracking-tight text-neutral-900 sm:text-4xl">
Choose your FlatRender plan {t("heading")}
</h2> </h2>
</SectionReveal> </SectionReveal>
+16 -15
View File
@@ -1,30 +1,31 @@
"use client"; "use client";
import Link from "next/link"; import Link from "next/link";
import { useTranslations } from "next-intl";
import { SectionReveal } from "@/components/sections/SectionReveal"; import { SectionReveal } from "@/components/sections/SectionReveal";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
export function VideoMakerCta() { export function VideoMakerCta() {
const t = useTranslations("videoMaker");
return ( return (
<section className="bg-primary-600 py-20 sm:py-24"> <section className="bg-primary-600 py-20 sm:py-24">
<div className="mx-auto max-w-3xl px-4 text-center sm:px-6 lg:px-8"> <div className="mx-auto max-w-3xl px-4 text-center sm:px-6 lg:px-8">
<SectionReveal> <SectionReveal>
<h2 className="font-heading text-3xl font-bold text-white sm:text-4xl"> <h2 className="font-heading text-3xl font-bold text-white sm:text-4xl">
Ready to create your first video? {t("ctaHeading")}
</h2> </h2>
<p className="mt-4 text-lg text-primary-100"> <p className="mt-4 text-lg text-primary-100">
Join over a million creators using CreatorStudio Video Makerfree to {t("ctaDesc")}
start, no credit card required. </p>
</p> <Button
<Button size="lg"
size="lg" className="mt-8 bg-white text-primary-600 hover:bg-primary-50"
className="mt-8 bg-white text-primary-600 hover:bg-primary-50" asChild
asChild >
> <Link href="/auth?tab=sign-up">{t("ctaButton")}</Link>
<Link href="/auth?tab=sign-up">Start Making Videos Free</Link> </Button>
</Button>
</SectionReveal> </SectionReveal>
</div> </div>
</section> </section>
@@ -8,82 +8,56 @@ import {
Music, Music,
Subtitles, Subtitles,
} from "lucide-react"; } from "lucide-react";
import { useTranslations } from "next-intl";
import { SectionReveal } from "@/components/sections/SectionReveal"; import { SectionReveal } from "@/components/sections/SectionReveal";
interface Feature { const FEATURE_ICONS: LucideIcon[] = [
icon: LucideIcon; LayoutTemplate,
title: string; FileText,
description: string; Subtitles,
} Music,
Download,
const features: Feature[] = [
{
icon: LayoutTemplate,
title: "500+ templates",
description:
"Launch promos, explainers, and social clips from studio-quality starting points.",
},
{
icon: FileText,
title: "AI script writer",
description:
"Turn a brief into scene-by-scene scripts with hooks, CTAs, and on-brand tone.",
},
{
icon: Subtitles,
title: "Auto-subtitles",
description:
"Generate accurate captions in dozens of languages with one-click styling.",
},
{
icon: Music,
title: "Music library",
description:
"Licensed tracks and sound effects matched to mood, tempo, and video length.",
},
{
icon: Download,
title: "1-click export",
description:
"Export MP4 up to 4K with presets for YouTube, Reels, ads, and presentations.",
},
]; ];
export function VideoMakerFeatures() { export function VideoMakerFeatures() {
const t = useTranslations("videoMaker");
const features = FEATURE_ICONS.map((Icon, i) => ({
Icon,
title: t(`feature${i}Title` as Parameters<typeof t>[0]),
description: t(`feature${i}Desc` as Parameters<typeof t>[0]),
}));
return ( return (
<section className="bg-neutral-50 py-20 sm:py-28"> <section className="bg-neutral-50 py-20 sm:py-28">
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8"> <div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<SectionReveal className="text-center"> <SectionReveal className="text-center">
<h2 className="font-heading text-3xl font-bold text-neutral-900 sm:text-4xl"> <h2 className="font-heading text-3xl font-bold text-neutral-900 sm:text-4xl">
Everything you need to edit faster {t("featuresHeading")}
</h2> </h2>
<p className="mx-auto mt-4 max-w-2xl text-neutral-600"> <p className="mx-auto mt-4 max-w-2xl text-neutral-600">
From first draft to final export, CreatorStudio keeps your workflow in {t("featuresSub")}
one place.
</p> </p>
</SectionReveal> </SectionReveal>
<SectionReveal className="mt-12 grid gap-6 sm:grid-cols-2 lg:grid-cols-3"> <SectionReveal className="mt-12 grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
{features.map((feature) => { {features.map(({ Icon, title, description }) => (
const Icon = feature.icon; <article
return ( key={title}
<article className="rounded-xl border border-gray-100 bg-white p-6 shadow-sm"
key={feature.title} >
className="rounded-xl border border-gray-100 bg-white p-6 shadow-sm" <div className="flex h-11 w-11 items-center justify-center rounded-lg bg-primary-600 text-white">
> <Icon className="h-5 w-5" aria-hidden />
<div className="flex h-11 w-11 items-center justify-center rounded-lg bg-primary-600 text-white"> </div>
<Icon className="h-5 w-5" aria-hidden /> <h3 className="mt-4 font-heading text-lg font-semibold text-neutral-900">
</div> {title}
<h3 className="mt-4 font-heading text-lg font-semibold text-neutral-900"> </h3>
{feature.title} <p className="mt-2 text-sm leading-relaxed text-neutral-600">
</h3> {description}
<p className="mt-2 text-sm leading-relaxed text-neutral-600"> </p>
{feature.description} </article>
</p> ))}
</article>
);
})}
</SectionReveal> </SectionReveal>
</div> </div>
</section> </section>
@@ -2,12 +2,15 @@
import Link from "next/link"; import Link from "next/link";
import { motion } from "framer-motion"; import { motion } from "framer-motion";
import { useTranslations } from "next-intl";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { VideoMakerEditorPreview } from "./VideoMakerEditorPreview"; import { VideoMakerEditorPreview } from "./VideoMakerEditorPreview";
export function VideoMakerHero() { export function VideoMakerHero() {
const t = useTranslations("videoMaker");
return ( return (
<section className="relative overflow-hidden bg-white pb-16 pt-12 sm:pb-20 sm:pt-16"> <section className="relative overflow-hidden bg-white pb-16 pt-12 sm:pb-20 sm:pt-16">
<div className="pointer-events-none absolute -left-32 top-0 h-96 w-96 rounded-full bg-primary-200/40 blur-3xl" /> <div className="pointer-events-none absolute -left-32 top-0 h-96 w-96 rounded-full bg-primary-200/40 blur-3xl" />
@@ -21,21 +24,20 @@ export function VideoMakerHero() {
transition={{ duration: 0.4, ease: "easeOut" }} transition={{ duration: 0.4, ease: "easeOut" }}
> >
<span className="inline-flex rounded-full bg-primary-100 px-3 py-1 text-xs font-semibold text-primary-700"> <span className="inline-flex rounded-full bg-primary-100 px-3 py-1 text-xs font-semibold text-primary-700">
Video Maker {t("badge")}
</span> </span>
<h1 className="mt-4 font-heading text-4xl font-bold tracking-tight text-neutral-900 sm:text-5xl"> <h1 className="mt-4 font-heading text-4xl font-bold tracking-tight text-neutral-900 sm:text-5xl">
AI Video Maker Create stunning videos in minutes {t("heroTitle")}
</h1> </h1>
<p className="mt-6 text-lg leading-relaxed text-neutral-600"> <p className="mt-6 text-lg leading-relaxed text-neutral-600">
Script, edit, caption, and export professional videos without a {t("heroDesc")}
production team. Templates and AI tools handle the heavy lifting.
</p> </p>
<div className="mt-8 flex flex-col gap-4 sm:flex-row"> <div className="mt-8 flex flex-col gap-4 sm:flex-row">
<Button size="lg" asChild> <Button size="lg" asChild>
<Link href="/sign-up">Start Making Videos Free</Link> <Link href="/sign-up">{t("heroCta")}</Link>
</Button> </Button>
<Button variant="outline" size="lg" asChild> <Button variant="outline" size="lg" asChild>
<Link href="#templates">Browse video templates</Link> <Link href="#templates">{t("heroBrowse")}</Link>
</Button> </Button>
</div> </div>
</motion.div> </motion.div>
@@ -2,76 +2,50 @@
import type { LucideIcon } from "lucide-react"; import type { LucideIcon } from "lucide-react";
import { Building2, Megaphone, Smartphone, Tv } from "lucide-react"; import { Building2, Megaphone, Smartphone, Tv } from "lucide-react";
import { useTranslations } from "next-intl";
import { SectionReveal } from "@/components/sections/SectionReveal"; import { SectionReveal } from "@/components/sections/SectionReveal";
interface UseCase { const USE_CASE_ICONS: LucideIcon[] = [Tv, Smartphone, Megaphone, Building2];
title: string;
description: string;
icon: LucideIcon;
}
const useCases: UseCase[] = [
{
title: "YouTube",
description:
"Intros, outros, and long-form explainers with chapters and thumbnail-ready frames.",
icon: Tv,
},
{
title: "Instagram Reels",
description:
"Vertical templates, bold captions, and beat-synced cuts built for short-form.",
icon: Smartphone,
},
{
title: "Ads",
description:
"High-converting promos for Meta, Google, and TikTok with platform-safe ratios.",
icon: Megaphone,
},
{
title: "Corporate Videos",
description:
"Onboarding, training, and investor updates with consistent brand styling.",
icon: Building2,
},
];
export function VideoMakerUseCases() { export function VideoMakerUseCases() {
const t = useTranslations("videoMaker");
const useCases = USE_CASE_ICONS.map((Icon, i) => ({
Icon,
title: t(`useCase${i}Title` as Parameters<typeof t>[0]),
description: t(`useCase${i}Desc` as Parameters<typeof t>[0]),
}));
return ( return (
<section className="bg-white py-20 sm:py-28"> <section className="bg-white py-20 sm:py-28">
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8"> <div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<SectionReveal className="text-center"> <SectionReveal className="text-center">
<h2 className="font-heading text-3xl font-bold text-neutral-900 sm:text-4xl"> <h2 className="font-heading text-3xl font-bold text-neutral-900 sm:text-4xl">
Built for every channel {t("useCasesHeading")}
</h2> </h2>
<p className="mx-auto mt-4 max-w-2xl text-neutral-600"> <p className="mx-auto mt-4 max-w-2xl text-neutral-600">
Pick a format and let templates handle aspect ratio, safe zones, and {t("useCasesSub")}
pacing.
</p> </p>
</SectionReveal> </SectionReveal>
<SectionReveal className="mt-12 grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-4"> <SectionReveal className="mt-12 grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-4">
{useCases.map((useCase) => { {useCases.map(({ Icon, title, description }) => (
const Icon = useCase.icon; <article
return ( key={title}
<article className="rounded-xl border border-gray-100 bg-white p-6 shadow-sm transition-shadow hover:shadow-md"
key={useCase.title} >
className="rounded-xl border border-gray-100 bg-white p-6 shadow-sm transition-shadow hover:shadow-md" <div className="flex h-12 w-12 items-center justify-center rounded-xl bg-primary-50 text-primary-600">
> <Icon className="h-6 w-6" aria-hidden />
<div className="flex h-12 w-12 items-center justify-center rounded-xl bg-primary-50 text-primary-600"> </div>
<Icon className="h-6 w-6" aria-hidden /> <h3 className="mt-4 font-heading text-lg font-semibold text-neutral-900">
</div> {title}
<h3 className="mt-4 font-heading text-lg font-semibold text-neutral-900"> </h3>
{useCase.title} <p className="mt-2 text-sm leading-relaxed text-neutral-600">
</h3> {description}
<p className="mt-2 text-sm leading-relaxed text-neutral-600"> </p>
{useCase.description} </article>
</p> ))}
</article>
);
})}
</SectionReveal> </SectionReveal>
</div> </div>
</section> </section>