225 lines
8.5 KiB
TypeScript
225 lines
8.5 KiB
TypeScript
"use client";
|
|
|
|
import { motion } from "framer-motion";
|
|
import { ArrowRight, Check, Lock, Sparkles } from "lucide-react";
|
|
import GlassCard from "@/components/ui/GlassCard";
|
|
import GlowButton from "@/components/ui/GlowButton";
|
|
import { fadeUp, stagger, viewportConfig } from "@/lib/animations";
|
|
import type { Locale } from "@/lib/dictionaries";
|
|
import type { PlansDict } from "./pricing";
|
|
|
|
interface PlansContentProps {
|
|
locale: Locale;
|
|
plans: PlansDict;
|
|
}
|
|
|
|
export default function PlansContent({ locale, plans }: PlansContentProps) {
|
|
const t = plans;
|
|
|
|
return (
|
|
<>
|
|
{/* Hero */}
|
|
<section className="relative isolate flex min-h-[40svh] items-center overflow-hidden pt-32">
|
|
<div className="pointer-events-none absolute inset-0 grid-bg [mask-image:radial-gradient(ellipse_at_center,#000_30%,transparent_70%)] opacity-30" />
|
|
|
|
<div className="relative mx-auto w-full max-w-7xl px-6 lg:px-8">
|
|
<motion.div
|
|
initial="hidden"
|
|
animate="visible"
|
|
variants={stagger(0.1)}
|
|
className="mx-auto max-w-3xl text-center"
|
|
>
|
|
<motion.span
|
|
variants={fadeUp}
|
|
className="mb-6 inline-flex items-center gap-2 rounded-full border border-purple-400/30 bg-purple-500/10 px-3.5 py-1.5 font-mono text-xs tracking-tight text-purple-300 backdrop-blur-md"
|
|
>
|
|
<Lock className="h-3 w-3" strokeWidth={2} />
|
|
{t.badge}
|
|
</motion.span>
|
|
|
|
<motion.h1
|
|
variants={fadeUp}
|
|
className="font-display text-display-xl font-medium tracking-tight"
|
|
>
|
|
<span className="text-gradient-fade">{t.title}</span>{" "}
|
|
<span className="text-gradient-purple">{t.titleAccent}</span>
|
|
</motion.h1>
|
|
|
|
<motion.p
|
|
variants={fadeUp}
|
|
className="mx-auto mt-6 max-w-2xl text-base leading-relaxed text-text-secondary sm:text-lg"
|
|
>
|
|
{t.subtitle}
|
|
</motion.p>
|
|
|
|
<motion.p
|
|
variants={fadeUp}
|
|
className="mx-auto mt-4 max-w-xl font-mono text-xs text-text-secondary/70"
|
|
>
|
|
</motion.p>
|
|
</motion.div>
|
|
</div>
|
|
</section>
|
|
|
|
{/* Project tiers */}
|
|
<section className="relative w-full pb-12 pt-16 sm:pb-16">
|
|
<div className="relative mx-auto w-full max-w-7xl px-6 lg:px-8">
|
|
<motion.h2
|
|
initial="hidden"
|
|
whileInView="visible"
|
|
viewport={viewportConfig}
|
|
variants={fadeUp}
|
|
className="mb-10 text-center font-display text-display-lg font-medium tracking-tight text-gradient-fade"
|
|
>
|
|
{t.tiersTitle}
|
|
</motion.h2>
|
|
|
|
<motion.div
|
|
initial="hidden"
|
|
whileInView="visible"
|
|
viewport={viewportConfig}
|
|
variants={stagger(0.1)}
|
|
className="grid grid-cols-1 gap-5 lg:grid-cols-3"
|
|
>
|
|
{t.tiers.map((tier) => (
|
|
<motion.div key={tier.name} variants={fadeUp} className="group h-full">
|
|
<GlassCard
|
|
variant={tier.highlighted ? "strong" : "default"}
|
|
className={`relative flex h-full flex-col p-8 ${
|
|
tier.highlighted
|
|
? "border-purple-400/40 shadow-glow-md"
|
|
: ""
|
|
}`}
|
|
>
|
|
{tier.highlighted && (
|
|
<span className="absolute -top-3 left-1/2 inline-flex -translate-x-1/2 items-center gap-1.5 rounded-full border border-purple-400/40 bg-purple-500/20 px-3 py-1 font-mono text-[10px] uppercase tracking-widest text-purple-200 backdrop-blur-md">
|
|
<Sparkles className="h-3 w-3" />
|
|
{t.popularBadge}
|
|
</span>
|
|
)}
|
|
|
|
<h3 className="text-lg font-medium text-text-primary">
|
|
{tier.name}
|
|
</h3>
|
|
|
|
<div className="mt-4 flex items-baseline gap-2">
|
|
<span className="font-display text-3xl font-medium tracking-tight text-text-primary">
|
|
{tier.price}
|
|
</span>
|
|
<span className="font-mono text-xs text-text-secondary">
|
|
{tier.period}
|
|
</span>
|
|
</div>
|
|
|
|
<p className="mt-4 text-sm leading-relaxed text-text-secondary">
|
|
{tier.description}
|
|
</p>
|
|
|
|
<div className="mt-6 space-y-2.5">
|
|
{tier.features.map((feature) => (
|
|
<div key={feature} className="flex items-start gap-2.5 text-sm">
|
|
<span className="mt-0.5 flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-purple-500/15 text-purple-300">
|
|
<Check className="h-3 w-3" strokeWidth={2.5} />
|
|
</span>
|
|
<span className="text-text-secondary">{feature}</span>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</GlassCard>
|
|
</motion.div>
|
|
))}
|
|
</motion.div>
|
|
</div>
|
|
</section>
|
|
|
|
{/* Care plans */}
|
|
<section className="relative w-full py-12 sm:py-16">
|
|
<div className="relative mx-auto w-full max-w-7xl px-6 lg:px-8">
|
|
<motion.div
|
|
initial="hidden"
|
|
whileInView="visible"
|
|
viewport={viewportConfig}
|
|
variants={stagger(0.06)}
|
|
className="mx-auto mb-10 max-w-2xl text-center"
|
|
>
|
|
<motion.h2
|
|
variants={fadeUp}
|
|
className="font-display text-display-lg font-medium tracking-tight text-gradient-fade"
|
|
>
|
|
{t.careTitle}
|
|
</motion.h2>
|
|
<motion.p
|
|
variants={fadeUp}
|
|
className="mt-4 text-base leading-relaxed text-text-secondary"
|
|
>
|
|
{t.careSubtitle}
|
|
</motion.p>
|
|
</motion.div>
|
|
|
|
<motion.div
|
|
initial="hidden"
|
|
whileInView="visible"
|
|
viewport={viewportConfig}
|
|
variants={stagger(0.1)}
|
|
className="grid grid-cols-1 gap-5 sm:grid-cols-3"
|
|
>
|
|
{t.care.map((plan) => (
|
|
<motion.div key={plan.name} variants={fadeUp} className="h-full">
|
|
<GlassCard className="flex h-full flex-col p-6">
|
|
<div className="flex items-baseline justify-between gap-3">
|
|
<h3 className="text-base font-medium text-text-primary">
|
|
{plan.name}
|
|
</h3>
|
|
<span className="font-display text-xl font-medium tracking-tight text-purple-300">
|
|
{plan.price}
|
|
</span>
|
|
</div>
|
|
<div className="mt-5 space-y-2.5">
|
|
{plan.features.map((feature) => (
|
|
<div key={feature} className="flex items-start gap-2.5 text-sm">
|
|
<span className="mt-0.5 flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-purple-500/15 text-purple-300">
|
|
<Check className="h-3 w-3" strokeWidth={2.5} />
|
|
</span>
|
|
<span className="text-text-secondary">{feature}</span>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</GlassCard>
|
|
</motion.div>
|
|
))}
|
|
</motion.div>
|
|
</div>
|
|
</section>
|
|
|
|
{/* Disclaimer + CTA */}
|
|
<section className="relative w-full pb-24 pt-8 sm:pb-32">
|
|
<div className="relative mx-auto w-full max-w-3xl px-6 text-center lg:px-8">
|
|
<motion.div
|
|
initial="hidden"
|
|
whileInView="visible"
|
|
viewport={viewportConfig}
|
|
variants={stagger(0.08)}
|
|
>
|
|
<motion.p
|
|
variants={fadeUp}
|
|
className="text-sm leading-relaxed text-text-secondary"
|
|
>
|
|
{t.disclaimer}
|
|
</motion.p>
|
|
<motion.div variants={fadeUp} className="mt-8 flex justify-center">
|
|
<GlowButton
|
|
href={`/${locale}/contact`}
|
|
variant="primary"
|
|
size="lg"
|
|
icon={<ArrowRight className="h-4 w-4" />}
|
|
>
|
|
{t.cta}
|
|
</GlowButton>
|
|
</motion.div>
|
|
</motion.div>
|
|
</div>
|
|
</section>
|
|
</>
|
|
);
|
|
}
|