Replace the landing with the artifact design and rebuild the admin in Ant Design.
Adds consultation leads, section editors, and the one-time content reset for this release. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
<template>
|
||||
<section class="py-16 cta-section">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="relative overflow-hidden rounded-[36px] bg-gradient-to-l from-sky-50 via-blue-50 to-blue-100/70 dark:from-slate-900 dark:via-[#0c1e3f] dark:to-slate-900 border border-brand-200/80 dark:border-brand-500/30 p-8 sm:p-12 shadow-soft-card">
|
||||
<div class="relative z-10 flex flex-col md:flex-row items-center justify-between gap-8 text-right">
|
||||
<div class="order-3 md:order-1 flex items-center justify-center" aria-hidden="true">
|
||||
<div class="w-28 h-28 sm:w-32 sm:h-32 rounded-3xl bg-white dark:bg-slate-800 shadow-xl border border-white/80 dark:border-slate-700 p-3 flex items-center justify-center transform hover:scale-105 transition-transform duration-500">
|
||||
<div class="w-full h-full rounded-2xl bg-gradient-to-br from-brand-600 via-brand-500 to-sky-400 flex items-center justify-center text-white shadow-inner">
|
||||
<svg class="w-16 h-16" viewBox="0 0 32 32" fill="none">
|
||||
<path d="M6 22L12 8L16 15L20 8L26 22" stroke="white" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" />
|
||||
<circle cx="16" cy="22" r="2.2" fill="white" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="order-2 flex-shrink-0">
|
||||
<button
|
||||
type="button"
|
||||
class="inline-flex items-center gap-2.5 px-8 py-3.5 rounded-full bg-brand-600 hover:bg-brand-700 text-white font-bold text-sm shadow-glow-cta active:scale-95 transition-all duration-300"
|
||||
@click="consult.open()"
|
||||
>
|
||||
<svg class="w-4 h-4 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M10 19l-7-7m0 0l7-7m-7 7h18" />
|
||||
</svg>
|
||||
<span>{{ cta.ctaLabel }}</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="order-1 md:order-3 flex-1 space-y-2">
|
||||
<h2 class="text-2xl sm:text-3xl font-black text-slate-900 dark:text-white tracking-tight">
|
||||
{{ cta.titleLine1 }}
|
||||
<br>
|
||||
{{ cta.titleLine2 }}
|
||||
</h2>
|
||||
<p class="text-slate-600 dark:text-slate-300 text-sm font-normal">
|
||||
{{ cta.body }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const { section } = useSiteContent();
|
||||
const cta = section("cta");
|
||||
const consult = useConsultModal();
|
||||
</script>
|
||||
@@ -0,0 +1,90 @@
|
||||
<template>
|
||||
<section id="features" class="py-24 bg-slate-50/70 dark:bg-[#070d19]/90 relative overflow-hidden customization-section">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="grid grid-cols-1 lg:grid-cols-12 gap-12 items-center">
|
||||
<div class="lg:col-span-7 relative flex justify-center items-center py-6 min-h-[380px]" aria-hidden="true">
|
||||
<div class="w-4/5 sm:w-2/3 bg-white/90 dark:bg-slate-900/80 rounded-2xl border border-slate-200/90 dark:border-slate-800 p-5 shadow-xl -rotate-6 transform transition-transform duration-700 hover:-rotate-3">
|
||||
<div class="flex items-center gap-2 border-b border-slate-100 dark:border-slate-800 pb-2.5 mb-3">
|
||||
<span class="w-2.5 h-2.5 rounded-full bg-slate-300 dark:bg-slate-700" />
|
||||
<span class="w-2.5 h-2.5 rounded-full bg-slate-300 dark:bg-slate-700" />
|
||||
<div class="text-[11px] text-slate-400 dark:text-slate-500 font-bold">{{ features.baseCardLabel }}</div>
|
||||
</div>
|
||||
<div class="space-y-3 opacity-60">
|
||||
<div class="h-3.5 w-1/3 bg-slate-200 dark:bg-slate-700 rounded" />
|
||||
<div class="h-16 w-full bg-slate-100 dark:bg-slate-800 rounded-lg" />
|
||||
<div class="grid grid-cols-3 gap-2">
|
||||
<div class="h-9 bg-slate-100 dark:bg-slate-800 rounded" />
|
||||
<div class="h-9 bg-slate-100 dark:bg-slate-800 rounded" />
|
||||
<div class="h-9 bg-slate-100 dark:bg-slate-800 rounded" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="absolute top-0 right-1/4 z-30 transform -translate-y-6">
|
||||
<svg class="w-28 h-20 text-brand-500" viewBox="0 0 100 60" fill="none">
|
||||
<path d="M10,50 Q50,-10 90,30" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" stroke-dasharray="6 6" />
|
||||
<polygon points="90,30 82,18 96,22" fill="currentColor" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div class="absolute -bottom-4 -right-2 sm:right-6 w-5/6 sm:w-3/4 bg-white/95 dark:bg-slate-900/95 backdrop-blur-md rounded-2xl border border-brand-200 dark:border-brand-500/40 p-6 shadow-2xl rotate-2 hover:rotate-0 transition-transform duration-700">
|
||||
<div class="flex items-center justify-between border-b border-slate-100 dark:border-slate-800 pb-3 mb-4">
|
||||
<div class="flex items-center gap-2.5">
|
||||
<div class="w-7 h-7 rounded-lg bg-brand-600 text-white flex items-center justify-center font-bold text-xs shadow-sm">M</div>
|
||||
<div class="text-xs font-bold text-slate-800 dark:text-slate-100">{{ features.customCardTitle }}</div>
|
||||
</div>
|
||||
<span class="text-[10px] font-bold text-emerald-600 dark:text-emerald-400 bg-emerald-50 dark:bg-emerald-950/60 px-2.5 py-1 rounded-full border border-emerald-100 dark:border-emerald-800/40">{{ features.customCardBadge }}</span>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-3 gap-3 text-right">
|
||||
<div class="col-span-2 space-y-2">
|
||||
<div class="text-xs text-slate-400 dark:text-slate-400 font-medium">{{ features.salesLabel }}</div>
|
||||
<div class="text-xl font-black text-slate-900 dark:text-white">{{ features.salesValue }} <span class="text-xs font-normal text-slate-500 dark:text-slate-400">تومان</span></div>
|
||||
<div class="h-11 bg-gradient-to-l from-brand-50 to-transparent dark:from-brand-950/50 dark:to-transparent border border-brand-100 dark:border-brand-900/60 rounded-xl flex items-center px-3">
|
||||
<span class="text-[10px] text-brand-700 dark:text-brand-300 font-bold">{{ features.linkNote }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="space-y-1 bg-slate-50 dark:bg-slate-800/70 p-2.5 rounded-xl text-center flex flex-col justify-center border border-slate-100 dark:border-slate-800">
|
||||
<div class="text-[10px] text-slate-500 dark:text-slate-400">{{ features.aiLabel }}</div>
|
||||
<div class="text-brand-600 dark:text-brand-400 font-extrabold text-sm">{{ features.aiStatus }}</div>
|
||||
<div class="text-[9px] text-slate-400 dark:text-slate-500">{{ features.aiNote }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="lg:col-span-5 text-right space-y-5 fade-item">
|
||||
<span class="text-xs font-bold text-slate-400 dark:text-slate-500">{{ features.eyebrow }}</span>
|
||||
|
||||
<h2 class="text-3xl sm:text-4xl font-black text-slate-900 dark:text-white leading-snug">
|
||||
{{ features.titleLine1 }}
|
||||
<br>
|
||||
<span>{{ features.titleLine2 }}</span>
|
||||
</h2>
|
||||
|
||||
<p class="text-base text-slate-600 dark:text-slate-300 leading-relaxed font-normal">
|
||||
{{ features.body }}
|
||||
</p>
|
||||
|
||||
<div class="pt-2">
|
||||
<a
|
||||
:href="resolveHref(features.ctaHref)"
|
||||
class="inline-flex items-center gap-2.5 px-6 py-3 rounded-full border border-slate-200 dark:border-slate-700 text-slate-700 dark:text-slate-200 font-bold text-sm hover:border-brand-600 dark:hover:border-brand-400 hover:text-brand-600 dark:hover:text-brand-400 hover:bg-brand-50/50 dark:hover:bg-slate-800/50 transition-all duration-300"
|
||||
>
|
||||
<svg class="w-4 h-4 text-brand-600 dark:text-brand-400" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18" />
|
||||
</svg>
|
||||
<span>{{ features.ctaLabel }}</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const { section } = useSiteContent();
|
||||
const features = section("features");
|
||||
const resolveHref = useSectionHref();
|
||||
</script>
|
||||
@@ -0,0 +1,210 @@
|
||||
<template>
|
||||
<div id="hero-laptop" class="mockup-macbook-wrap relative w-full max-w-[580px] select-none cursor-pointer z-10" :style="transformStyle">
|
||||
<div class="macbook-screen-chassis rounded-[22px] p-2.5 sm:p-3 relative">
|
||||
<div class="mockup-glass-sheen rounded-[16px]" />
|
||||
|
||||
<div class="bg-[#0b0f19] rounded-[16px] overflow-hidden border border-slate-800 relative shadow-2xl">
|
||||
<div class="bg-[#111827] px-3.5 py-2 flex items-center justify-between border-b border-slate-800 text-[10px] text-slate-400">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<span class="w-2.5 h-2.5 rounded-full bg-[#ff5f56] inline-block shadow-sm" />
|
||||
<span class="w-2.5 h-2.5 rounded-full bg-[#ffbd2e] inline-block shadow-sm" />
|
||||
<span class="w-2.5 h-2.5 rounded-full bg-[#27c93f] inline-block shadow-sm" />
|
||||
</div>
|
||||
|
||||
<div class="w-24 h-3 bg-black rounded-b-md -mt-2 mx-auto flex items-center justify-center gap-1.5">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-slate-900 border border-slate-700" />
|
||||
<span class="w-1 h-1 rounded-full bg-emerald-500/80" />
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-1.5 text-slate-300 font-bold">
|
||||
<div class="w-3.5 h-3.5 rounded bg-brand-600 flex items-center justify-center text-[8px] text-white">M</div>
|
||||
<span class="text-[9px] bg-brand-500/20 text-brand-300 px-2 py-0.5 rounded-full font-mono">{{ mockup.domain }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="p-3 sm:p-4 bg-slate-50 dark:bg-slate-950 text-slate-800 dark:text-slate-100 min-h-[320px] flex gap-3 text-right">
|
||||
<div class="w-28 hidden sm:flex flex-col justify-between py-1 px-1 border-l border-slate-200 dark:border-slate-800 text-[11px] text-slate-600 dark:text-slate-400 font-medium">
|
||||
<div class="space-y-1.5">
|
||||
<button
|
||||
v-for="tab in TABS"
|
||||
:key="tab.id"
|
||||
type="button"
|
||||
:aria-pressed="heroTab === tab.id"
|
||||
:class="heroTab === tab.id ? tab.activeClass : 'hover:bg-slate-100 dark:hover:bg-slate-900 text-slate-600 dark:text-slate-400'"
|
||||
class="w-full text-right px-2.5 py-1.5 rounded-lg flex items-center gap-1.5 transition-all duration-200"
|
||||
@click.stop="heroTab = tab.id"
|
||||
>
|
||||
<span class="w-1.5 h-1.5 rounded-full transition-transform duration-200" :class="heroTab === tab.id ? tab.dotClass : 'bg-slate-400'" />
|
||||
{{ tab.label }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="px-2 py-1 text-[9px] text-slate-400 dark:text-slate-500 flex items-center justify-between">
|
||||
<span>{{ mockup.version }}</span>
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-emerald-500" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex-1 space-y-2.5">
|
||||
<div v-if="heroTab === 'dashboard'" class="space-y-2.5">
|
||||
<div class="grid grid-cols-2 gap-2">
|
||||
<div class="bg-white dark:bg-slate-900 p-2.5 rounded-xl border border-slate-200/80 dark:border-slate-800 shadow-sm hover:border-brand-300 dark:hover:border-brand-500/50 transition-colors">
|
||||
<div class="text-[10px] text-slate-400 dark:text-slate-500 font-medium">فروش کل دورهای</div>
|
||||
<div class="text-xs sm:text-sm md:text-base font-extrabold text-slate-800 dark:text-white mt-0.5">
|
||||
{{ mockup.salesValue }} <span class="text-[9px] font-normal text-slate-500 dark:text-slate-400">تومان</span>
|
||||
</div>
|
||||
<div class="text-[9px] text-emerald-600 dark:text-emerald-400 mt-0.5 font-semibold flex items-center gap-1">
|
||||
{{ mockup.salesGrowth }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-white dark:bg-slate-900 p-2.5 rounded-xl border border-slate-200/80 dark:border-slate-800 shadow-sm hover:border-brand-300 dark:hover:border-brand-500/50 transition-colors">
|
||||
<div class="text-[10px] text-slate-400 dark:text-slate-500 font-medium">مشتریان وفادار فعال</div>
|
||||
<div class="text-xs sm:text-sm md:text-base font-extrabold text-slate-800 dark:text-white mt-0.5">
|
||||
{{ mockup.customersValue }} <span class="text-[9px] font-normal text-slate-500 dark:text-slate-400">نفر</span>
|
||||
</div>
|
||||
<div class="text-[9px] text-brand-600 dark:text-brand-400 mt-0.5 font-semibold flex items-center gap-1">
|
||||
{{ mockup.satisfaction }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-white dark:bg-slate-900 p-2.5 rounded-xl border border-slate-200/80 dark:border-slate-800 shadow-sm relative group/chart">
|
||||
<div class="flex items-center justify-between text-[10px] mb-1.5">
|
||||
<span class="font-bold text-slate-700 dark:text-slate-300">روند عملکرد فروش و تحلیل هوش مصنوعی</span>
|
||||
<span class="text-brand-600 dark:text-brand-400 font-bold text-[9px] flex items-center gap-1 bg-brand-50 dark:bg-brand-950 px-2 py-0.5 rounded-full">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-emerald-500 animate-ping" />
|
||||
زنده
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="relative">
|
||||
<svg class="w-full h-20 overflow-visible" viewBox="0 0 300 90" fill="none" aria-hidden="true">
|
||||
<defs>
|
||||
<linearGradient id="heroChartGrad" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#0062f5" stop-opacity="0.32" />
|
||||
<stop offset="100%" stop-color="#0062f5" stop-opacity="0.0" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path d="M0,70 Q40,55 80,35 T160,45 T240,15 T300,25 L300,90 L0,90 Z" fill="url(#heroChartGrad)" />
|
||||
<path d="M0,70 Q40,55 80,35 T160,45 T240,15 T300,25" stroke="#0062f5" stroke-width="2.8" stroke-linecap="round" />
|
||||
|
||||
<circle cx="80" cy="35" r="4" fill="#0062f5" class="cursor-pointer" @mouseenter="chartTooltip = mockup.chartTooltips[0]" />
|
||||
<circle cx="160" cy="45" r="4" fill="#0062f5" class="cursor-pointer" @mouseenter="chartTooltip = mockup.chartTooltips[1]" />
|
||||
<circle cx="240" cy="15" r="5" fill="#0062f5" stroke="#ffffff" stroke-width="2" class="cursor-pointer" @mouseenter="chartTooltip = mockup.chartTooltips[2]" />
|
||||
</svg>
|
||||
|
||||
<div class="absolute top-1 left-2 bg-slate-900/90 text-white text-[9px] px-2 py-0.5 rounded font-mono shadow pointer-events-none">
|
||||
{{ chartTooltip }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else-if="heroTab === 'gold'" class="space-y-2.5">
|
||||
<div class="bg-amber-50/80 dark:bg-amber-950/40 border border-amber-200 dark:border-amber-800/60 rounded-xl p-3 text-right">
|
||||
<div class="flex items-center justify-between text-[11px] mb-2">
|
||||
<span class="font-extrabold text-amber-950 dark:text-amber-200">محاسبهگر نرخ لحظهای و مظنه طلا</span>
|
||||
<span class="text-[9px] bg-amber-200 dark:bg-amber-800 text-amber-900 dark:text-amber-100 px-2 py-0.5 rounded-full font-bold">اتصال مستقیم به اتحادیه</span>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-2 text-[10px]">
|
||||
<div class="bg-white dark:bg-slate-900 p-2 rounded-lg border border-amber-100 dark:border-amber-900/40">
|
||||
<span class="text-slate-400 dark:text-slate-500 block">مظنه ۱۷ عیار:</span>
|
||||
<span class="font-black text-slate-800 dark:text-slate-200 text-xs">۱۸,۷۵۰,۰۰۰ تومان</span>
|
||||
</div>
|
||||
<div class="bg-white dark:bg-slate-900 p-2 rounded-lg border border-amber-100 dark:border-amber-900/40">
|
||||
<span class="text-slate-400 dark:text-slate-500 block">گرم ۱۸ عیار:</span>
|
||||
<span class="font-black text-slate-800 dark:text-slate-200 text-xs">۴,۳۲۰,۰۰۰ تومان</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else-if="heroTab === 'crm'" class="space-y-2.5">
|
||||
<div class="bg-indigo-50/70 dark:bg-indigo-950/40 border border-indigo-200 dark:border-indigo-800/60 rounded-xl p-3 text-right">
|
||||
<div class="flex items-center justify-between text-[11px] mb-2">
|
||||
<span class="font-extrabold text-indigo-950 dark:text-indigo-200">قیف فروش و وضعیت سرنخها</span>
|
||||
<span class="text-[9px] bg-indigo-200 dark:bg-indigo-800 text-indigo-900 dark:text-indigo-100 px-2 py-0.5 rounded-full font-bold">اتوماسیون فعال</span>
|
||||
</div>
|
||||
<div class="space-y-1.5 text-[10px]">
|
||||
<div class="flex items-center justify-between bg-white dark:bg-slate-900 px-2 py-1.5 rounded-lg border border-indigo-100 dark:border-indigo-900/40">
|
||||
<span class="font-semibold text-slate-700 dark:text-slate-300">تماسهای موفق امروز</span>
|
||||
<span class="font-bold text-indigo-600 dark:text-indigo-400">۱۴۲ مورد (+۱۸٪)</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between bg-white dark:bg-slate-900 px-2 py-1.5 rounded-lg border border-indigo-100 dark:border-indigo-900/40">
|
||||
<span class="font-semibold text-slate-700 dark:text-slate-300">پیشفاکتورهای در انتظار تایید</span>
|
||||
<span class="font-bold text-amber-600 dark:text-amber-400">۲۹ قرارداد</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else-if="heroTab === 'financial'" class="space-y-2.5">
|
||||
<div class="bg-cyan-50/70 dark:bg-cyan-950/40 border border-cyan-200 dark:border-cyan-800/60 rounded-xl p-3 text-right">
|
||||
<div class="flex items-center justify-between text-[11px] mb-2">
|
||||
<span class="font-extrabold text-cyan-950 dark:text-cyan-200">تراز مالی و سامانه مودیان</span>
|
||||
<span class="text-[9px] bg-emerald-100 dark:bg-emerald-950 text-emerald-800 dark:text-emerald-300 px-2 py-0.5 rounded-full font-bold">همگامسازی برخط</span>
|
||||
</div>
|
||||
<div class="space-y-1.5 text-[10px]">
|
||||
<div class="flex items-center justify-between bg-white dark:bg-slate-900 px-2 py-1.5 rounded-lg border border-cyan-100 dark:border-cyan-900/40">
|
||||
<span class="text-slate-600 dark:text-slate-400">تسویه تجمیعی کارتخوانها:</span>
|
||||
<span class="font-bold text-slate-900 dark:text-white">۱,۲۸۰,۰۰۰,۰۰۰ تومان</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center justify-between bg-white dark:bg-slate-900 px-3 py-1.5 rounded-lg border border-slate-200 dark:border-slate-800 text-[10px] text-slate-600 dark:text-slate-400">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="w-2 h-2 rounded-full bg-emerald-500 animate-ping" />
|
||||
<span>آخرین تسویه حسابداری متصل به شتاب</span>
|
||||
</div>
|
||||
<span class="font-bold text-slate-800 dark:text-slate-200">موفق (۱ دقیقه پیش)</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="macbook-deck-base h-4 rounded-b-[18px] mx-auto -mt-0.5 flex justify-center items-center relative">
|
||||
<div class="w-24 h-1.5 bg-slate-400/80 rounded-full shadow-inner" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { HeroMockupContent } from "@montech/shared";
|
||||
|
||||
type HeroTab = "dashboard" | "gold" | "crm" | "financial";
|
||||
|
||||
const props = defineProps<{ mockup: HeroMockupContent; transformStyle: string }>();
|
||||
|
||||
const TABS: Array<{ id: HeroTab; label: string; activeClass: string; dotClass: string }> = [
|
||||
{
|
||||
id: "dashboard",
|
||||
label: "داشبورد",
|
||||
activeClass: "bg-brand-50 dark:bg-brand-950 text-brand-600 dark:text-brand-400 font-bold shadow-sm",
|
||||
dotClass: "bg-brand-600 dark:bg-brand-400 scale-125",
|
||||
},
|
||||
{
|
||||
id: "gold",
|
||||
label: "انبارداری طلا",
|
||||
activeClass: "bg-amber-50 dark:bg-amber-950/60 text-amber-700 dark:text-amber-400 font-bold shadow-sm",
|
||||
dotClass: "bg-amber-600 dark:bg-amber-400 scale-125",
|
||||
},
|
||||
{
|
||||
id: "crm",
|
||||
label: "مشتریان (CRM)",
|
||||
activeClass: "bg-indigo-50 dark:bg-indigo-950/60 text-indigo-700 dark:text-indigo-400 font-bold shadow-sm",
|
||||
dotClass: "bg-indigo-600 dark:bg-indigo-400 scale-125",
|
||||
},
|
||||
{
|
||||
id: "financial",
|
||||
label: "گزارش مالی",
|
||||
activeClass: "bg-cyan-50 dark:bg-cyan-950/60 text-cyan-700 dark:text-cyan-400 font-bold shadow-sm",
|
||||
dotClass: "bg-cyan-600 dark:bg-cyan-400 scale-125",
|
||||
},
|
||||
];
|
||||
|
||||
const heroTab = ref<HeroTab>("dashboard");
|
||||
const chartTooltip = ref(props.mockup.chartDefaultTooltip);
|
||||
</script>
|
||||
@@ -0,0 +1,89 @@
|
||||
<template>
|
||||
<div
|
||||
id="hero-mobile"
|
||||
class="mockup-iphone-wrap absolute -bottom-10 -right-2 sm:-right-4 lg:right-2 w-[225px] sm:w-[250px] h-[465px] sm:h-[515px] select-none cursor-pointer z-20"
|
||||
:style="transformStyle"
|
||||
@click="goldBarCount = goldBarCount === baseCount ? baseCount + 1 : baseCount"
|
||||
>
|
||||
<div class="iphone-titanium-bezel rounded-[46px] p-2.5 w-full h-full relative">
|
||||
<div class="mockup-glass-sheen rounded-[38px]" />
|
||||
|
||||
<div class="bg-white dark:bg-slate-950 rounded-[38px] overflow-hidden text-right p-3.5 pt-2 text-slate-800 dark:text-slate-100 text-[10px] w-full h-full flex flex-col justify-between relative border border-slate-100 dark:border-slate-800 shadow-xl">
|
||||
<div>
|
||||
<div class="flex items-center justify-between px-2 text-[9px] text-slate-800 dark:text-slate-200 font-bold mb-1">
|
||||
<span>۰۹:۴۱</span>
|
||||
<div class="flex items-center gap-1 text-[8px]">
|
||||
<span>5G</span>
|
||||
<svg class="w-2.5 h-2.5" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true"><path d="M12 3c-4.97 0-9 4.03-9 9 0 2.12.74 4.07 1.97 5.61L4.35 18.25c-.2.2-.2.51 0 .71.2.2.51.2.71 0l.64-.64C7.26 19.46 9.49 20.1 12 20.1c4.97 0 9-4.03 9-9s-4.03-9-9-9z" /></svg>
|
||||
<span class="w-4 h-2 border border-slate-800 dark:border-slate-300 rounded-sm p-0.5 flex items-center"><span class="w-full h-full bg-slate-800 dark:bg-slate-300 rounded-xs" /></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="w-24 h-4.5 bg-black mx-auto rounded-full mb-2.5 flex items-center justify-between px-2.5 shadow-sm">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-slate-900 border border-slate-800" />
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-emerald-400 animate-pulse" />
|
||||
</div>
|
||||
|
||||
<div class="flex items-center justify-between px-1 mb-2.5">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<span class="w-5 h-5 rounded-lg bg-amber-500 text-white flex items-center justify-center text-[10px] font-bold">M</span>
|
||||
<span class="font-black text-slate-900 dark:text-white text-xs">طلا و جواهر</span>
|
||||
</div>
|
||||
<span class="text-[9px] bg-amber-100 dark:bg-amber-950 text-amber-800 dark:text-amber-300 font-bold px-2 py-0.5 rounded-full">انبار آنلاین</span>
|
||||
</div>
|
||||
|
||||
<div class="bg-gradient-to-l from-amber-50 to-amber-100/70 dark:from-amber-950/30 dark:to-amber-900/20 border border-amber-200/90 dark:border-amber-800/50 rounded-2xl p-2.5 flex items-center gap-2.5 shadow-sm hover:shadow-md transition-shadow mb-2.5">
|
||||
<div class="gold-bar-realistic w-12 h-12 rounded-xl flex flex-col items-center justify-center text-amber-950 font-black text-[10px] tracking-tight relative overflow-hidden flex-shrink-0">
|
||||
<div class="absolute inset-0 bg-gradient-to-t from-black/25 via-transparent to-white/40 pointer-events-none" />
|
||||
<span class="relative z-10 text-[9px] font-extrabold tracking-wider">AU 999</span>
|
||||
<span class="relative z-10 text-[7px] opacity-90 font-mono">100g</span>
|
||||
</div>
|
||||
<div class="text-[9px] leading-tight flex-1">
|
||||
<div class="font-extrabold text-slate-900 dark:text-white text-[10px]">شمش ۱۰۰ گرمی ۲۴ عیار</div>
|
||||
<div class="text-amber-800 dark:text-amber-300 font-semibold mt-1">موجودی صندوق: {{ goldBarCount }} قطعه</div>
|
||||
<div class="text-[8px] text-slate-400 dark:text-slate-500 mt-0.5">شناسه استاندارد زرینبانک</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-slate-50 dark:bg-slate-900 rounded-xl p-2 border border-slate-200/80 dark:border-slate-800 space-y-1.5 mb-2.5">
|
||||
<div class="flex items-center justify-between text-[9px]">
|
||||
<span class="text-slate-500 dark:text-slate-400 font-medium">مظنه ۱۷ اتحادیه:</span>
|
||||
<span class="font-black text-slate-900 dark:text-white">۱۸,۷۵۰,۰۰۰ <span class="text-[8px] font-normal text-slate-400">تومان</span></span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-[9px]">
|
||||
<span class="text-slate-500 dark:text-slate-400 font-medium">تسویه آنی شتاب:</span>
|
||||
<span class="font-black text-emerald-600 dark:text-emerald-400">۴۵۰,۳۰۰,۰۰۰ <span class="text-[8px] font-normal text-slate-400">تومان</span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-1.5">
|
||||
<div class="text-[9px] font-bold text-slate-400 dark:text-slate-500 px-1">آخرین فاکتورهای سیستمی:</div>
|
||||
<div class="bg-white dark:bg-slate-900 rounded-lg p-1.5 border border-slate-100 dark:border-slate-800 flex items-center justify-between text-[9px] shadow-2xs">
|
||||
<span class="text-slate-700 dark:text-slate-300 font-medium">فاکتور ۱۸۴۲ (زرگری شمس)</span>
|
||||
<span class="text-emerald-600 dark:text-emerald-400 font-bold">تایید شد ✓</span>
|
||||
</div>
|
||||
<div class="bg-white dark:bg-slate-900 rounded-lg p-1.5 border border-slate-100 dark:border-slate-800 flex items-center justify-between text-[9px] shadow-2xs">
|
||||
<span class="text-slate-700 dark:text-slate-300 font-medium">حواله سکه بهار آزادی</span>
|
||||
<span class="text-brand-600 dark:text-brand-400 font-bold">در انتظار</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pt-2 border-t border-slate-100 dark:border-slate-800 flex flex-col items-center gap-1.5">
|
||||
<div class="w-full flex justify-around items-center text-slate-400 dark:text-slate-500 text-xs">
|
||||
<span class="text-brand-600 font-black">●</span>
|
||||
<span>■</span>
|
||||
<span>▲</span>
|
||||
<span>⚙</span>
|
||||
</div>
|
||||
<div class="w-24 h-1 bg-slate-800 dark:bg-slate-400 rounded-full mt-0.5" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const props = defineProps<{ baseCount: number; transformStyle: string }>();
|
||||
const goldBarCount = ref(props.baseCount);
|
||||
</script>
|
||||
@@ -0,0 +1,113 @@
|
||||
<template>
|
||||
<section ref="sectionEl" class="relative pt-8 pb-16 lg:pt-14 lg:pb-24 overflow-hidden hero-parallax-section">
|
||||
<div class="absolute top-1/4 right-0 w-[550px] h-[550px] bg-brand-100/50 dark:bg-brand-600/15 rounded-full blur-[140px] pointer-events-none -z-10" />
|
||||
<div class="absolute bottom-10 left-10 w-[500px] h-[500px] bg-sky-100/50 dark:bg-sky-600/10 rounded-full blur-[140px] pointer-events-none -z-10" />
|
||||
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="grid grid-cols-1 lg:grid-cols-12 gap-12 lg:gap-8 items-center">
|
||||
<div class="lg:col-span-5 space-y-6 text-right">
|
||||
<div class="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-slate-100/80 dark:bg-slate-800/80 border border-slate-200/70 dark:border-slate-700/70 text-xs font-semibold text-slate-500 dark:text-slate-300">
|
||||
<span class="w-2 h-2 rounded-full bg-brand-500 animate-pulse" />
|
||||
<span>{{ hero.eyebrow }}</span>
|
||||
</div>
|
||||
|
||||
<h1 class="text-4xl sm:text-5xl lg:text-[54px] font-black text-slate-900 dark:text-white leading-[1.28] tracking-tight">
|
||||
{{ hero.titleLine1 }}
|
||||
<br>
|
||||
<span class="text-transparent bg-clip-text bg-gradient-to-r from-brand-600 via-brand-500 to-sky-400">
|
||||
{{ hero.titleHighlight }}
|
||||
</span>
|
||||
</h1>
|
||||
|
||||
<p class="text-base sm:text-lg text-slate-600 dark:text-slate-300 font-normal leading-relaxed max-w-xl">
|
||||
{{ hero.subtitle }}
|
||||
</p>
|
||||
|
||||
<div class="pt-2 max-w-xl">
|
||||
<form class="relative group" role="search" @submit.prevent="search">
|
||||
<div class="relative flex items-center bg-white dark:bg-slate-900/95 rounded-full p-2 pl-2 shadow-soft-card hover:shadow-hover-card border border-slate-200/90 dark:border-slate-700/80 focus-within:border-brand-500 focus-within:ring-4 focus-within:ring-brand-100/70 dark:focus-within:ring-brand-900/40 transition-all duration-300">
|
||||
<button
|
||||
type="submit"
|
||||
aria-label="جستجوی هوشمند"
|
||||
class="flex-shrink-0 w-12 h-12 rounded-full bg-brand-600 text-white flex items-center justify-center hover:bg-brand-700 active:scale-95 transition-all shadow-md shadow-brand-600/30"
|
||||
>
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M10 19l-7-7m0 0l7-7m-7 7h18" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<input
|
||||
v-model="ai.query.value"
|
||||
type="text"
|
||||
aria-label="نیاز کسبوکار خود را بنویسید"
|
||||
:placeholder="hero.searchPlaceholder"
|
||||
class="w-full bg-transparent text-sm sm:text-base text-slate-800 dark:text-slate-100 placeholder-slate-400 dark:placeholder-slate-500 focus:outline-none pr-3 pl-3 font-normal text-right"
|
||||
>
|
||||
|
||||
<div class="pr-3 pl-2 text-brand-500 flex items-center justify-center" aria-hidden="true">
|
||||
<svg class="w-5 h-5 text-brand-500" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M12 2L14.2 8.3L20.5 10.5L14.2 12.7L12 19L9.8 12.7L3.5 10.5L9.8 8.3L12 2Z" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-3.5 flex flex-wrap items-center gap-2 text-xs text-slate-500 dark:text-slate-400">
|
||||
<span class="font-medium text-slate-400 dark:text-slate-500">{{ hero.suggestionsLabel }}</span>
|
||||
<button
|
||||
v-for="item in hero.suggestions"
|
||||
:key="item.label"
|
||||
type="button"
|
||||
class="px-3 py-1 rounded-full bg-slate-100 dark:bg-slate-800 text-slate-600 dark:text-slate-300 hover:bg-brand-50 dark:hover:bg-brand-950 hover:text-brand-600 dark:hover:text-brand-300 border border-transparent hover:border-brand-200 dark:hover:border-brand-800 transition-all"
|
||||
@click="suggest(item.query)"
|
||||
>
|
||||
{{ item.label }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="lg:col-span-7 relative perspective-stage flex justify-center items-center py-6 min-h-[520px] sm:min-h-[580px]"
|
||||
@mousemove="parallax.onMouseMove"
|
||||
@mouseleave="parallax.onMouseLeave"
|
||||
>
|
||||
<div class="studio-botanical-leaf hidden sm:block" aria-hidden="true">
|
||||
<svg viewBox="0 0 280 280" fill="none" class="w-full h-full text-emerald-950/25 dark:text-emerald-500/15">
|
||||
<path d="M50,220 C35,120 100,40 220,25 C250,90 200,190 95,235 C75,240 60,235 50,220 Z" fill="currentColor" />
|
||||
<path d="M75,195 C110,160 145,120 195,75" stroke="#047857" stroke-width="5" stroke-linecap="round" />
|
||||
<path d="M105,170 C130,175 160,190 180,210" stroke="#047857" stroke-width="4" stroke-linecap="round" />
|
||||
<path d="M130,135 C160,135 185,150 205,165" stroke="#047857" stroke-width="4" stroke-linecap="round" />
|
||||
<path d="M155,100 C185,95 215,105 235,120" stroke="#047857" stroke-width="3" stroke-linecap="round" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div class="device-ground-shadow" />
|
||||
|
||||
<HeroLaptopMockup :mockup="hero.mockup" :transform-style="parallax.laptop.value" />
|
||||
<HeroPhoneMockup :base-count="hero.mockup.goldBarCount" :transform-style="parallax.mobile.value" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const { section } = useSiteContent();
|
||||
const hero = section("hero");
|
||||
const ai = useAiModal();
|
||||
const parallax = useHeroParallax();
|
||||
const sectionEl = ref<HTMLElement | null>(null);
|
||||
|
||||
function search() {
|
||||
if (!ai.query.value.trim()) ai.query.value = hero.value.searchDefaultQuery;
|
||||
ai.open();
|
||||
}
|
||||
|
||||
function suggest(query: string) {
|
||||
ai.query.value = query;
|
||||
search();
|
||||
}
|
||||
|
||||
useHeroScrollParallax(sectionEl);
|
||||
</script>
|
||||
@@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<section class="py-14 border-y border-slate-200/80 dark:border-slate-800/80 bg-white/80 dark:bg-slate-900/80 backdrop-blur-md relative z-10" aria-label="آمار منتک">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||
<div
|
||||
v-for="item in metrics.items"
|
||||
:key="item.label"
|
||||
class="fade-item flex items-center justify-center sm:justify-start gap-4 p-4 rounded-2xl hover:bg-slate-50 dark:hover:bg-slate-800/60 transition-all duration-300"
|
||||
>
|
||||
<div class="w-13 h-13 p-3 rounded-2xl bg-sky-50 dark:bg-sky-950/60 text-sky-600 dark:text-sky-400 flex items-center justify-center flex-shrink-0">
|
||||
<svg class="w-7 h-7" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true">
|
||||
<path v-for="(d, i) in ICON_PATHS[item.icon]" :key="i" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" :d="d" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<div v-if="item.emphasis === 'text'" class="text-xl font-extrabold text-slate-900 dark:text-white">{{ item.value }}</div>
|
||||
<div v-else class="text-3xl font-black text-slate-900 dark:text-white tracking-tight">{{ item.value }}</div>
|
||||
<div class="text-sm text-slate-500 dark:text-slate-400 font-medium">{{ item.label }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { MetricIcon } from "@montech/shared";
|
||||
|
||||
const ICON_PATHS: Record<MetricIcon, string[]> = {
|
||||
gear: [
|
||||
"M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z",
|
||||
"M15 12a3 3 0 11-6 0 3 3 0 016 0z",
|
||||
],
|
||||
users: [
|
||||
"M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z",
|
||||
],
|
||||
box: ["M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4"],
|
||||
};
|
||||
|
||||
const { section } = useSiteContent();
|
||||
const metrics = section("metrics");
|
||||
</script>
|
||||
@@ -0,0 +1,100 @@
|
||||
<template>
|
||||
<div
|
||||
role="button"
|
||||
tabindex="0"
|
||||
:aria-label="`${item.title} — درخواست مشاوره`"
|
||||
class="spotlight-card fade-item group bg-white dark:bg-slate-900/90 rounded-3xl p-6 border border-slate-200/90 dark:border-slate-800 shadow-soft-card hover:shadow-hover-card transition-all duration-300 flex flex-col justify-between text-center cursor-pointer"
|
||||
:class="accent.border"
|
||||
:style="tilt.style.value"
|
||||
@mousemove="tilt.onMouseMove"
|
||||
@mouseleave="tilt.onMouseLeave"
|
||||
@click="select"
|
||||
@keydown.enter.prevent="select"
|
||||
@keydown.space.prevent="select"
|
||||
>
|
||||
<div>
|
||||
<div class="w-20 h-20 mx-auto mb-6 flex items-center justify-center group-hover:scale-110 transition-transform duration-500">
|
||||
<svg class="w-16 h-16 drop-shadow-md" viewBox="0 0 64 64" fill="none" aria-hidden="true">
|
||||
<template v-if="item.icon === 'cube'">
|
||||
<polygon points="32,6 58,20 32,34 6,20" fill="#38b2f8" />
|
||||
<polygon points="6,20 32,34 32,60 6,46" fill="#0062f5" />
|
||||
<polygon points="58,20 32,34 32,60 58,46" fill="#0046b8" />
|
||||
</template>
|
||||
<template v-else-if="item.icon === 'bars'">
|
||||
<rect x="8" y="34" width="12" height="24" rx="3" fill="#38b2f8" />
|
||||
<rect x="26" y="20" width="12" height="38" rx="3" fill="#007dfc" />
|
||||
<rect x="44" y="8" width="12" height="50" rx="3" fill="#0050d8" />
|
||||
</template>
|
||||
<template v-else-if="item.icon === 'avatars'">
|
||||
<circle cx="32" cy="18" r="10" fill="#6366f1" />
|
||||
<path d="M16 46C16 38 23 34 32 34C41 34 48 38 48 46V50H16V46Z" fill="#4f46e5" />
|
||||
<circle cx="48" cy="22" r="7" fill="#818cf8" />
|
||||
<path d="M46 36C49 36 56 39 56 46V48H46V36Z" fill="#6366f1" />
|
||||
</template>
|
||||
<template v-else-if="item.icon === 'cart'">
|
||||
<path d="M10 12H18L24 40H48L54 20H20" stroke="#06b6d4" stroke-width="4.5" stroke-linecap="round" stroke-linejoin="round" />
|
||||
<circle cx="26" cy="50" r="5" fill="#0891b2" />
|
||||
<circle cx="46" cy="50" r="5" fill="#0891b2" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<polygon points="12,42 22,26 44,26 34,42" fill="#fde047" />
|
||||
<polygon points="34,42 44,26 52,32 42,48" fill="#d97706" />
|
||||
<polygon points="12,42 34,42 42,48 20,48" fill="#f59e0b" />
|
||||
<polygon points="20,24 30,8 52,8 42,24" fill="#fef08a" />
|
||||
<polygon points="42,24 52,8 60,14 50,30" fill="#b45309" />
|
||||
<polygon points="20,24 42,24 50,30 28,30" fill="#f59e0b" />
|
||||
</template>
|
||||
</svg>
|
||||
</div>
|
||||
<h3 class="text-lg font-bold text-slate-900 dark:text-white transition-colors" :class="accent.title">{{ item.title }}</h3>
|
||||
<p class="text-xs text-slate-500 dark:text-slate-400 mt-2 font-normal">{{ item.subtitle }}</p>
|
||||
</div>
|
||||
<div class="mt-6 pt-4 flex justify-center">
|
||||
<span class="w-8 h-8 rounded-full bg-slate-50 dark:bg-slate-800 text-slate-400 dark:text-slate-300 group-hover:text-white flex items-center justify-center transition-all duration-300 shadow-sm" :class="accent.bubble">
|
||||
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M10 19l-7-7m0 0l7-7m-7 7h18" /></svg>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { SolutionAccent, SolutionItem } from "@montech/shared";
|
||||
|
||||
const props = defineProps<{ item: SolutionItem }>();
|
||||
|
||||
const ACCENTS: Record<SolutionAccent, { border: string; title: string; bubble: string }> = {
|
||||
brand: {
|
||||
border: "hover:border-brand-300 dark:hover:border-brand-500/50",
|
||||
title: "group-hover:text-brand-600 dark:group-hover:text-brand-400",
|
||||
bubble: "group-hover:bg-brand-600",
|
||||
},
|
||||
sky: {
|
||||
border: "hover:border-sky-300 dark:hover:border-sky-500/50",
|
||||
title: "group-hover:text-sky-600 dark:group-hover:text-sky-400",
|
||||
bubble: "group-hover:bg-sky-500",
|
||||
},
|
||||
indigo: {
|
||||
border: "hover:border-indigo-300 dark:hover:border-indigo-500/50",
|
||||
title: "group-hover:text-indigo-600 dark:group-hover:text-indigo-400",
|
||||
bubble: "group-hover:bg-indigo-600",
|
||||
},
|
||||
cyan: {
|
||||
border: "hover:border-cyan-300 dark:hover:border-cyan-500/50",
|
||||
title: "group-hover:text-cyan-600 dark:group-hover:text-cyan-400",
|
||||
bubble: "group-hover:bg-cyan-500",
|
||||
},
|
||||
amber: {
|
||||
border: "hover:border-amber-300 dark:hover:border-amber-500/50",
|
||||
title: "group-hover:text-amber-600 dark:group-hover:text-amber-400",
|
||||
bubble: "group-hover:bg-amber-500",
|
||||
},
|
||||
};
|
||||
|
||||
const accent = computed(() => ACCENTS[props.item.accent] ?? ACCENTS.brand);
|
||||
const tilt = useCardTilt();
|
||||
const consult = useConsultModal();
|
||||
|
||||
function select() {
|
||||
consult.open({ type: props.item.consultType, source: "solution" });
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<section id="solutions" class="py-24 bg-white dark:bg-[#070d19] relative solutions-section">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="text-center max-w-2xl mx-auto mb-16 space-y-2 fade-item">
|
||||
<span class="text-xs font-bold text-slate-400 dark:text-slate-500">{{ solutions.eyebrow }}</span>
|
||||
<h2 class="text-3xl sm:text-4xl font-black text-slate-900 dark:text-white">{{ solutions.title }}</h2>
|
||||
<p class="text-sm sm:text-base text-slate-500 dark:text-slate-400 font-normal">{{ solutions.subtitle }}</p>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-5 gap-6">
|
||||
<SolutionCard v-for="item in solutions.items" :key="item.title" :item="item" />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const { section } = useSiteContent();
|
||||
const solutions = section("solutions");
|
||||
</script>
|
||||
@@ -0,0 +1,83 @@
|
||||
<template>
|
||||
<section id="testimonials" class="py-24 bg-slate-50/70 dark:bg-[#070d19]/90 overflow-hidden relative">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="grid grid-cols-1 lg:grid-cols-12 gap-12 items-center">
|
||||
<div class="lg:col-span-7 relative flex justify-center items-center py-10 fade-item">
|
||||
<div
|
||||
v-for="(src, i) in decorAvatars"
|
||||
:key="i"
|
||||
class="absolute w-14 h-14 rounded-full bg-white dark:bg-slate-800 shadow-md p-1 border border-slate-200 dark:border-slate-700 opacity-60"
|
||||
:class="i === 0 ? '-right-2 top-4' : '-right-4 bottom-6'"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<SafeImage :src="src" alt="" width="56" height="56" class="w-full h-full rounded-full object-cover" />
|
||||
</div>
|
||||
|
||||
<figure class="relative z-10 w-full max-w-lg bg-white dark:bg-slate-900/95 rounded-3xl p-8 border border-slate-100 dark:border-slate-800 shadow-xl space-y-6 text-right">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-1.5 text-xs font-bold text-brand-600 dark:text-brand-400 bg-brand-50 dark:bg-brand-950/60 px-3 py-1 rounded-full border border-brand-100 dark:border-brand-900/50">
|
||||
<svg class="w-4 h-4 text-brand-600 dark:text-brand-400" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" />
|
||||
</svg>
|
||||
<span>{{ t.badge }}</span>
|
||||
</div>
|
||||
<div class="text-slate-300 dark:text-slate-700" aria-hidden="true">
|
||||
<svg class="w-8 h-8" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M14.017 21v-7.391c0-5.704 3.731-9.57 8.983-10.609l.995 2.151c-2.432.917-3.995 3.638-3.995 5.849h4v10h-9.983zm-14.017 0v-7.391c0-5.704 3.748-9.57 9-10.609l.996 2.151c-2.433.917-3.996 3.638-3.996 5.849h3.983v10h-9.983z" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<blockquote class="text-slate-800 dark:text-slate-100 text-lg font-bold leading-relaxed min-h-[60px]">
|
||||
{{ t.quote }}
|
||||
</blockquote>
|
||||
|
||||
<figcaption class="flex items-center justify-end gap-3 pt-4 border-t border-slate-100 dark:border-slate-800">
|
||||
<div class="text-right">
|
||||
<div class="font-bold text-slate-900 dark:text-white text-sm">{{ t.name }}</div>
|
||||
<div class="text-xs text-slate-400 dark:text-slate-500 font-medium">{{ t.role }}</div>
|
||||
</div>
|
||||
<div class="w-12 h-12 rounded-full overflow-hidden border-2 border-brand-500 shadow-sm">
|
||||
<SafeImage :src="t.avatarUrl" :alt="t.name" width="48" height="48" class="w-full h-full object-cover" />
|
||||
</div>
|
||||
</figcaption>
|
||||
</figure>
|
||||
</div>
|
||||
|
||||
<div class="lg:col-span-5 text-right space-y-5 fade-item">
|
||||
<span class="text-xs font-bold text-slate-400 dark:text-slate-500">{{ t.eyebrow }}</span>
|
||||
|
||||
<h2 class="text-3xl sm:text-4xl font-black text-slate-900 dark:text-white leading-snug">
|
||||
{{ t.titleLine1 }}
|
||||
<br>
|
||||
<span>{{ t.titleLine2 }}</span>
|
||||
</h2>
|
||||
|
||||
<p class="text-base text-slate-600 dark:text-slate-300 leading-relaxed font-normal">
|
||||
{{ t.body }}
|
||||
</p>
|
||||
|
||||
<div class="pt-2">
|
||||
<button
|
||||
type="button"
|
||||
class="inline-flex items-center gap-2.5 px-6 py-3 rounded-full bg-brand-600 text-white font-bold text-sm hover:bg-brand-700 active:scale-95 transition-all duration-300 shadow-md shadow-brand-600/25"
|
||||
@click="consult.open()"
|
||||
>
|
||||
<svg class="w-4 h-4 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18" />
|
||||
</svg>
|
||||
<span>{{ t.ctaLabel }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const { section } = useSiteContent();
|
||||
const t = section("testimonials");
|
||||
const consult = useConsultModal();
|
||||
const decorAvatars = computed(() => t.value.decorAvatars.slice(0, 2));
|
||||
</script>
|
||||
Reference in New Issue
Block a user