11 Commits
Author SHA1 Message Date
Amirmahdi fc30597835 feat: logo 2026-06-21 19:04:29 +03:30
Amirmahdi 3c6a9c79df feat: add enemad to footer 2025-12-09 20:45:47 +03:30
Amirmahdi 23767a713a feat: add blogs 2025-12-05 18:41:17 +03:30
Amirmahdi bece9a2171 fix: link is fixed 2025-12-03 15:18:26 +03:30
Amirmahdi c40356568f feat: rebrans 2025-11-28 17:53:12 +03:30
Amirmahdi abc3f89195 feat: change sitemap 2025-11-19 01:27:24 +03:30
Amirmahdi b6108a04d8 feat: add favicon.ico 2025-11-19 00:53:22 +03:30
Amirmahdi 18da3984ae feat: add sitemap, tag for SEO 2025-11-12 00:25:51 +03:30
Amirmahdi e95983d9b0 feat: drawer in mobile view 2025-11-07 16:31:45 +03:30
Amirmahdi 5b5d1cfa69 feat: add download links 2025-11-07 15:48:54 +03:30
Amirmahdi 3ceec02356 feat: better fotter 2025-11-07 15:43:46 +03:30
32 changed files with 943 additions and 127 deletions
+22
View File
@@ -0,0 +1,22 @@
#!/usr/bin/env bash
# Runs on `git push`. If a tag ref is among what's being pushed, build locally
# and deploy to the server. Normal branch pushes are untouched.
set -euo pipefail
deploy=0
tag=""
while read -r local_ref _local_sha _remote_ref _remote_sha; do
case "$local_ref" in
refs/tags/*)
deploy=1
tag="${local_ref#refs/tags/}"
;;
esac
done
if [ "$deploy" = "1" ]; then
echo "→ Tag '$tag' is being pushed — building locally and deploying to the server…"
exec "$(git rev-parse --show-toplevel)/scripts/deploy.sh"
fi
exit 0
+41 -15
View File
@@ -5,29 +5,55 @@ import Features from './components/Features';
import WhatYouCanDo from './components/WhatYouCanDo'; import WhatYouCanDo from './components/WhatYouCanDo';
import WhyAramland from './components/WhyAramland'; import WhyAramland from './components/WhyAramland';
import FreeTrial from './components/FreeTrial'; import FreeTrial from './components/FreeTrial';
import BlogSection from './components/BlogSection';
// import ScientificBenefits from './components/ScientificBenefits'; // import ScientificBenefits from './components/ScientificBenefits';
import CallToAction from './components/CallToAction'; import CallToAction from './components/CallToAction';
import Footer from './components/Footer'; import Footer from './components/Footer';
import { SEOHead } from './components/SEOHead';
function App() { function App() {
return ( return (
<div className="min-h-screen bg-gradient-to-b from-blue-50 via-white to-green-50" dir="rtl"> <>
<Header />
<main className="max-w-5xl mx-auto px-6 sm:px-8 lg:px-10 py-24 space-y-32">
<Hero /> <SEOHead
<DownloadSection /> title="آرام جان - تمرین تنفسی و مدیتیشن"
<Features /> description="اپلیکیشن آرام جان - همراه شما برای رسیدن به آرامش درونی با مدیتیشن‌های فارسی، تمرین‌های تنفسی و موسیقی آرامش‌بخش"
<WhatYouCanDo /> canonical="/" ogImage="../app/og-image.png" />
<WhyAramland />
<FreeTrial />
{/* <ScientificBenefits /> */}
<CallToAction />
</main>
<Footer /> <div className="min-h-screen bg-gradient-to-b from-blue-50 via-white to-green-50" dir="rtl">
</div> <Header />
<main className="max-w-5xl mx-auto px-6 sm:px-8 lg:px-10 py-24 space-y-32">
<div id="download">
<Hero />
</div>
<div id="features">
<Features />
</div>
<div id="what-you-can-do">
<WhatYouCanDo />
</div>
<div id="why-aramland">
<WhyAramland />
</div>
<BlogSection />
<div id="free-trial">
<FreeTrial />
</div>
<div id="call-to-action">
<CallToAction />
</div>
</main>
<div id='footer'>
<Footer />
</div>
</div>
</>
); );
} }
+127
View File
@@ -0,0 +1,127 @@
// components/BlogSection.jsx
"use client";
import { Calendar, Clock, ArrowLeft } from 'lucide-react';
import Link from 'next/link';
function BlogSection() {
const blogs = [
{
title: "تمرین تنفسی برای کاهش استرس",
subtitle: "تکنیک‌های ساده تنفسی برای کاهش فوری استرس و اضطراب",
link: "https://aaramland.ir/blog/tmryn-tnfsy-bry-khhsh-strs.html",
readTime: "۵ دقیقه",
date: "۱۴۰۴/۱/۱۵",
category: "سلامت روان",
gradient: "from-primary-500/10 to-primary-600/10",
border: "border-primary-500/20"
},
{
title: "مدیتیشن چیست و چگونه شروع کنیم؟",
subtitle: "راهنمای کامل برای شناخت مدیتیشن و شروع این سفر زیبا",
link: "https://aaramland.ir/blog/mdytyshn-chyh.html",
readTime: "۷ دقیقه",
date: "۱۴۰۴/۱۰/۱۰",
category: "آموزش",
gradient: "from-primary-500/10 to-primary-600/10",
border: "border-primary-500/20"
},
{
title: "مدیتیشن چیست و چگونه زندگی‌ات را متحول می‌کند؟",
subtitle: "راهنمای کامل برای شناخت انواع مدیتیشن",
link: "https://aaramland.ir/blog/khls-shdn-z-strs-b-arm-lnd.html",
readTime: "۸ دقیقه",
date: "۱۴۰۴/۱۰/۰۵",
category: "تحول شخصی",
gradient: "from-primary-500/10 to-primary-600/10",
border: "border-primary-500/20"
}
];
return (
<section className="my-24">
{/* Header */}
<div className="text-center mb-16">
<div className="inline-flex items-center gap-2 bg-primary-500/10 text-primary-600 px-4 py-2 rounded-full text-sm font-medium mb-4">
<span className="text-lg">📝</span>
مقالات آموزشی
</div>
<h2 className="text-4xl md:text-5xl font-bold text-gray-900 mb-4">
آخرین <span className="text-primary-500">مقالات</span> آرامش
</h2>
<p className="text-xl text-gray-600 max-w-2xl mx-auto">
یادگیری عمیقتر درباره تکنیکهای آرامش، مدیتیشن و سلامت روان
</p>
</div>
{/* Blog Cards Grid */}
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8 mb-12">
{blogs.map((blog, index) => (
<article
key={index}
className={`bg-gradient-to-br ${blog.gradient} border ${blog.border} rounded-3xl overflow-hidden group hover:shadow-2xl transition-all duration-500 hover:-translate-y-2 animate-fadeInUp`}
style={{ animationDelay: `${index * 100}ms` }}
>
{/* Card Header */}
<div className="p-8">
{/* Category Badge */}
<div className="inline-block bg-primary-500/20 text-primary-600 px-3 py-1 rounded-full text-xs font-medium mb-4">
{blog.category}
</div>
{/* Title */}
<h3 className="text-xl font-bold text-gray-900 mb-3 group-hover:text-primary-600 transition-colors duration-300 line-clamp-2">
{blog.title}
</h3>
{/* Subtitle */}
<p className="text-gray-600 leading-relaxed mb-6 line-clamp-2">
{blog.subtitle}
</p>
{/* Meta Info */}
<div className="flex items-center justify-between text-sm text-gray-500">
<div className="flex items-center gap-4">
<div className="flex items-center gap-1">
<Calendar className="w-4 h-4" />
<span>{blog.date}</span>
</div>
<div className="flex items-center gap-1">
<Clock className="w-4 h-4" />
<span>{blog.readTime} مطالعه</span>
</div>
</div>
</div>
</div>
{/* Read More Button */}
<div className="border-t border-primary-500/10 p-6">
<a
href={blog.link}
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-2 text-primary-600 hover:text-primary-700 font-medium group/link transition-colors duration-300"
>
<span>مطالعه مقاله</span>
<ArrowLeft className="w-4 h-4 group-hover/link:-translate-x-1 transition-transform duration-300" />
</a>
</div>
</article>
))}
</div>
{/* View All Button */}
<div className="text-center">
<Link
href="https://aaramland.ir/blog/"
className="inline-flex items-center gap-2 bg-gradient-to-r from-primary-500 to-primary-600 text-white font-medium py-3 px-8 rounded-2xl hover:shadow-lg transition-all duration-300 transform hover:scale-105 group"
>
<span>مشاهده همه مقالات</span>
<ArrowLeft className="w-5 h-5 group-hover:-translate-x-1 transition-transform duration-300" />
</Link>
</div>
</section>
);
}
export default BlogSection;
+11 -8
View File
@@ -1,31 +1,34 @@
"use client";
import { useScroll } from '../hooks/useScroll';
function CallToAction() { function CallToAction() {
const { scrollToSectionWithHeader } = useScroll();
return ( return (
<div className="relative text-center rounded-3xl p-16 animate-fadeInUp overflow-hidden"> <div className="relative text-center rounded-3xl p-16 animate-fadeInUp overflow-hidden">
{/* Background with gradient */} {/* Background with gradient */}
<div className="absolute inset-0 bg-gradient-to-r from-primary-500 via-primary-600 to-primary-500 opacity-10"></div> <div className="absolute inset-0 bg-gradient-to-r from-primary-500 via-primary-600 to-primary-500 opacity-10"></div>
{/* Animated border */} {/* Animated border */}
<div className="absolute inset-0 rounded-3xl border-2 border-primary-500/20 animate-pulse"></div> <div className="absolute inset-0 rounded-3xl border-2 border-primary-500/20 animate-pulse"></div>
<div className="relative"> <div className="relative">
<h2 className="text-3xl md:text-5xl font-bold text-gray-900 mb-6"> <h2 className="text-3xl md:text-5xl font-bold text-gray-900 mb-6">
آماده برای <span className="text-primary-500">تغییر</span> زندگی؟ آماده برای <span className="text-primary-500">تغییر</span> زندگی؟
</h2> </h2>
<p className="text-xl text-gray-700 mb-8 max-w-2xl mx-auto leading-relaxed"> <p className="text-xl text-gray-700 mb-8 max-w-2xl mx-auto leading-relaxed">
امروز اولین قدم رو بردار و ببین چطور آراملند میتونه کیفیت زندگیات رو متحول کنه امروز اولین قدم رو بردار و ببین چطور آرام جان میتونه کیفیت زندگیات رو متحول کنه
</p> </p>
<div className="flex flex-col sm:flex-row gap-4 justify-center items-center"> <div className="flex flex-col sm:flex-row gap-4 justify-center items-center">
<button className="bg-gradient-to-r from-primary-500 to-primary-600 text-white font-bold py-4 px-8 rounded-2xl hover:shadow-2xl transition-all duration-300 transform hover:scale-105 text-lg shadow-lg hover:shadow-primary-500/40 relative overflow-hidden group"> <button onClick={() => scrollToSectionWithHeader('download')} className="bg-gradient-to-r from-primary-500 to-primary-600 text-white font-bold py-4 px-8 rounded-2xl hover:shadow-2xl transition-all duration-300 transform hover:scale-105 text-lg shadow-lg hover:shadow-primary-500/40 relative overflow-hidden group">
<div className="absolute inset-0 bg-white/20 -translate-x-full group-hover:translate-x-full transition-transform duration-700"></div> <div className="absolute inset-0 bg-white/20 -translate-x-full group-hover:translate-x-full transition-transform duration-700"></div>
<span className="relative">شروع سفر آرامش</span> <span className="relative">شروع سفر آرامش</span>
</button> </button>
<button className="border-2 border-gray-300 text-gray-700 font-bold py-4 px-8 rounded-2xl hover:border-primary-500 hover:text-primary-500 transition-all duration-300"> <button onClick={() => scrollToSectionWithHeader('features')} className="border-2 border-gray-300 text-gray-700 font-bold py-4 px-8 rounded-2xl hover:border-primary-500 hover:text-primary-500 transition-all duration-300">
بیشتر بدانید بیشتر بدانید
</button> </button>
</div> </div>
</div> </div>
</div> </div>
); );
+34 -26
View File
@@ -1,70 +1,78 @@
import { li } from 'framer-motion/client';
import { Download, Globe, PlayCircle } from 'lucide-react'; import { Download, Globe, PlayCircle } from 'lucide-react';
function DownloadSection() { function DownloadSection() {
const downloadOptions = [ const downloadOptions = [
{ {
icon: Download, icon: './images/cafe.png',
title: "کافه بازار", title: "کافه بازار",
description: "دانلود برای اندروید", description: "دانلود برای اندروید",
badge: "پرطرفدار", link: "https://cafebazaar.ir/app/com.approagency.meditation",
gradient: "from-primary-500 to-primary-600", // badge: "پرطرفدار",
gradient: "from-primary-500/10 to-primary-600/10",
border: "border-primary-500/20",
animation: "animate-slideInLeft delay-100" animation: "animate-slideInLeft delay-100"
}, },
{ {
icon: PlayCircle, icon: './images/myket.png',
title: "مایکت", title: "مایکت",
link: "https://myket.ir/app/com.approagency.meditation",
description: "دانلود برای اندروید", description: "دانلود برای اندروید",
gradient: "from-primary-500 to-primary-600", gradient: "from-primary-500/10 to-primary-600/10",
border: "border-primary-500/20",
animation: "animate-fadeInUp delay-200" animation: "animate-fadeInUp delay-200"
}, },
{ {
icon: Globe, icon: './images/appstore.png',
title: "وب سایت", title: "وب سایت",
description: "نسخه وب برای تمام دستگاه‌ها", description: "نسخه وب برای تمام دستگاه‌ها",
badge: "جدید", link: 'https://aaramland.ir/web/',
gradient: "from-primary-500 to-primary-600", badge: "",
animation: "animate-slideInRight delay-300" gradient: "from-primary-500/10 to-primary-600/10",
animation: "animate-slideInRight delay-300",
border: "border-primary-500/20",
} }
]; ];
return ( return (
<div className="relative bg-white rounded-3xl shadow-2xl p-12 mb-20 animate-fadeInUp overflow-hidden"> <div className="relative rounded-3xl p-1 mb-10 animate-fadeInUp overflow-hidden">
{/* Background pattern */} {/* Background pattern */}
<div className="absolute inset-0 opacity-5"> <div className="absolute inset-0 opacity-4">
<div className="absolute inset-0 bg-gradient-to-r from-primary-500 to-primary-600"></div> <div className="absolute inset-0"></div>
</div> </div>
<div className="relative"> <div className="relative">
<div className="text-center mb-12"> <div className="text-center mb-12">
<h2 className="text-3xl md:text-4xl font-bold text-gray-900 mb-4"> <h2 className="text-3xl md:text-4xl font-bold text-gray-900 mb-4 mt-8">
همین حالا <span className="text-primary-500">شروع کنید</span> همین حالا <span className="text-primary-500">شروع کنید</span>
</h2> </h2>
<p className="text-xl text-gray-600 max-w-2xl mx-auto"> <p className="text-xl text-gray-600 max-w-2xl mx-auto">
آراملند را روی دستگاه مورد علاقهتان نصب کنید آرام جان را روی دستگاه مورد علاقهتان نصب کنید
</p> </p>
</div> </div>
<div className="grid md:grid-cols-3 gap-6 max-w-4xl mx-auto"> <div className="grid md:grid-cols-3 gap-6 max-w-4xl mx-auto ">
{downloadOptions.map((option, index) => ( {downloadOptions.map((option, index) => (
<a <a
key={index} key={index}
href="#" href={option.link}
className={`relative flex flex-col items-center justify-center p-8 bg-gradient-to-br ${option.gradient} rounded-3xl shadow-lg hover:shadow-2xl transition-all duration-300 transform hover:-translate-y-2 text-white group ${option.animation} overflow-hidden`} className={`relative flex flex-col items-center justify-center p-8 bg-gradient-to-br ${option.gradient} rounded-3xl hover:shadow-2xl transition-all duration-300 transform hover:-translate-y-2 group ${option.animation} overflow-hidden border ${option.border}`}
> >
{/* Shine effect */} {/* Shine effect */}
<div className="absolute inset-0 bg-gradient-to-r from-transparent via-white/20 to-transparent -translate-x-full group-hover:translate-x-full transition-transform duration-1000"></div> {/* <div className="absolute inset-0 bg-gradient-to-r from-transparent via-white/20 to-transparent -translate-x-full group-hover:translate-x-full transition-transform duration-1000"></div> */}
{option.badge && ( {option.badge && (
<div className="absolute -top-2 -right-2 bg-white text-primary-500 px-3 py-1 rounded-full text-xs font-bold shadow-lg"> <div className="absolute -top-0 right-0 bg-primary-200 px-2 py-2 rounded text-xs font-bold">
{option.badge} {option.badge}
</div> </div>
)} )}
<div className="bg-white/20 p-4 rounded-2xl mb-4 group-hover:scale-110 transition-transform duration-300"> <div className="bg-white p-4 rounded-2xl mb-4 group-hover:scale-110 transition-transform duration-300">
<option.icon className="w-8 h-8" /> <img src={option.icon} alt="Download" className="w-20 h-20 border border-transparent rounded-xl " />
{/* <option.icon className="w-8 h-8" /> */}
</div> </div>
<h3 className="text-xl font-bold mb-2">{option.title}</h3> <h3 className="text-xl text-black font-bold mb-2">{option.title}</h3>
<p className="text-white/90 text-sm">{option.description}</p> <p className="text-sm text-black">{option.description}</p>
</a> </a>
))} ))}
</div> </div>
+1 -1
View File
@@ -27,7 +27,7 @@ function Features() {
]; ];
return ( return (
<div className="my-24"> <div className="my-12">
<div className="text-center mb-16"> <div className="text-center mb-16">
<div className="inline-flex items-center gap-2 bg-primary-500/10 text-primary-500 px-4 py-2 rounded-full text-sm font-medium mb-4"> <div className="inline-flex items-center gap-2 bg-primary-500/10 text-primary-500 px-4 py-2 rounded-full text-sm font-medium mb-4">
<span></span> <span></span>
+163 -3
View File
@@ -1,8 +1,168 @@
"use client";
import { useScroll } from '../hooks/useScroll';
import LotusLogo from './LotusLogo';
function Footer() { function Footer() {
const { scrollToSectionWithHeader } = useScroll();
return ( return (
<footer className="py-12 text-center text-gray-500 border-t border-gray-200"> <footer className="bg-white border-t border-gray-100">
<p className="mb-4">© ۱۴۰۳ آراملند - همراه تو برای یک زندگی آرامتر</p> {/* Main Footer Content */}
<p className="text-sm">ساخته شده با عشق برای مردم ایران</p> <div className="max-w-5xl mx-auto px-6 sm:px-8 lg:px-10 py-16">
<div className="grid md:grid-cols-2 lg:grid-cols-4 gap-8 mb-12">
{/* Brand Column */}
<div className="lg:col-span-2">
<div className="flex items-center gap-3 mb-6">
<LotusLogo className="w-11 h-11 drop-shadow-sm" />
<div className="text-2xl font-bold bg-gradient-to-r from-primary-500 to-primary-600 bg-clip-text text-transparent">
آرام جان
</div>
</div>
<p className="text-gray-600 leading-relaxed mb-6 max-w-md">
همراه شما در مسیر رسیدن به آرامش درونی. با ابزارهای علمی و تخصصی
برای زندگی بهتر و ذهنی آرامتر.
</p>
<div className="flex gap-4">
{/* Social Media Icons - You can add actual links later */}
<div className="w-10 h-10 bg-primary-500/10 rounded-xl flex items-center justify-center cursor-pointer hover:bg-primary-500/20 transition-colors">
<span className="text-primary-500">📱</span>
</div>
<div className="w-10 h-10 bg-primary-500/10 rounded-xl flex items-center justify-center cursor-pointer hover:bg-primary-500/20 transition-colors">
<span className="text-primary-500">💬</span>
</div>
<div className="w-10 h-10 bg-primary-500/10 rounded-xl flex items-center justify-center cursor-pointer hover:bg-primary-500/20 transition-colors">
<span className="text-primary-500">📸</span>
</div>
</div>
</div>
{/* Quick Links */}
<div>
<h3 className="font-bold text-gray-900 mb-6 text-lg">لینکهای سریع</h3>
<ul className="space-y-3">
{[
{ name: 'ویژگی‌ها', section: 'features' },
{ name: 'امکانات', section: 'what-you-can-do' },
{ name: 'چرا آرام جان', section: 'why-aramland' },
{ name: 'ارتباط با تیم', href: 'https://approagency.ir/' }
].map((link) => (
<li key={link.name}>
<a
href={link.href}
onClick={() => scrollToSectionWithHeader(link.section)}
target="_blank"
className="text-gray-600 hover:text-primary-500 transition-colors duration-200"
>
{link.name}
</a>
</li>
))}
</ul>
</div>
{/* Agency Contact */}
<div>
<h3 className="font-bold text-gray-900 mb-6 text-lg">توسعهدهنده</h3>
<div className="space-y-4">
<div className="flex items-center gap-3">
<div className="w-10 h-10 bg-gradient-to-r from-primary-500 to-primary-600 rounded-xl flex items-center justify-center">
<span className="text-white text-sm">AP</span>
</div>
<div>
<p className="font-medium text-gray-900">اپرواجنسی</p>
<p className="text-sm text-gray-500">Approagency</p>
</div>
</div>
<div className="space-y-3">
<a
href="mailto:approagency@gmail.com"
className="flex items-center gap-2 text-gray-600 hover:text-primary-500 transition-colors group"
>
<div className="w-8 h-8 bg-primary-500/10 rounded-lg flex items-center justify-center group-hover:bg-primary-500/20 transition-colors">
<span className="text-primary-500 text-sm"></span>
</div>
<span className="text-sm">approagency@gmail.com</span>
</a>
<a
href="tel:+989362957108"
className="flex items-center gap-2 text-gray-600 hover:text-primary-500 transition-colors group"
>
<div className="w-8 h-8 bg-primary-500/10 rounded-lg flex items-center justify-center group-hover:bg-primary-500/20 transition-colors">
<span className="text-primary-500 text-sm">📞</span>
</div>
<span className="text-sm">۰۹۳۶۲۹۵۷۱۰۸</span>
</a>
</div>
</div>
</div>
</div>
{/* Divider */}
<div className="h-px bg-gradient-to-r from-transparent via-gray-200 to-transparent mb-8"></div>
{/* Bottom Section */}
<div className="flex flex-col md:flex-row justify-between items-center gap-4">
<div className="text-center md:text-right">
<p className="text-gray-600 mb-2">
© 1404 آرام جان - همراه تو برای یک زندگی آرامتر
</p>
<p className="text-gray-500 text-sm">
ساخته شده با عشق برای مردم ایران
</p>
</div>
<div className="flex flex-col md:flex-row items-center gap-6">
{/* Enamad Badge */}
<div className="mt-4 md:mt-0">
<a
referrerPolicy='origin'
target='_blank'
href='https://trustseal.enamad.ir/?id=684477&Code=O0VD9spjoV48pvyakFsJgoY361OXvszk'
className="inline-block"
>
<img
referrerPolicy='origin'
src='https://trustseal.enamad.ir/logo.aspx?id=684477&Code=O0VD9spjoV48pvyakFsJgoY361OXvszk'
alt='Enamad Trust Seal'
style={{cursor: 'pointer'}}
code='O0VD9spjoV48pvyakFsJgoY361OXvszk'
className="h-12 w-auto"
/>
</a>
</div>
{/* Additional Links */}
<div className="flex gap-6 text-sm">
<a href="#" className="text-gray-500 hover:text-primary-500 transition-colors">
حریم خصوصی
</a>
<a href="#" className="text-gray-500 hover:text-primary-500 transition-colors">
شرایط استفاده
</a>
<a href="#" className="text-gray-500 hover:text-primary-500 transition-colors">
پشتیبانی
</a>
</div>
</div>
</div>
</div>
{/* Floating CTA */}
<div className="bg-gradient-to-r from-primary-500/5 to-primary-600/5 border-t border-primary-500/10">
<div className="max-w-5xl mx-auto px-6 sm:px-8 lg:px-10 py-6">
<div className="flex flex-col md:flex-row justify-between items-center gap-4">
<div>
<p className="font-medium text-gray-900">آماده شروع سفر آرامش؟</p>
<p className="text-gray-600 text-sm">همین حالا رایگان شروع کنید</p>
</div>
<button onClick={() => scrollToSectionWithHeader('download')} className="bg-gradient-to-r from-primary-500 to-primary-600 text-white font-medium py-3 px-8 rounded-2xl hover:shadow-lg transition-all duration-300 transform hover:scale-105 whitespace-nowrap">
دانلود اپلیکیشن
</button>
</div>
</div>
</div>
</footer> </footer>
); );
} }
+12 -6
View File
@@ -1,4 +1,7 @@
"use client";
import { useScroll } from '../hooks/useScroll';
function FreeTrial() { function FreeTrial() {
const { scrollToSectionWithHeader } = useScroll();
return ( return (
<div className="relative bg-gradient-to-r from-primary-500 via-primary-600 to-primary-500 rounded-3xl p-12 text-white text-center mb-20 animate-fadeInUp overflow-hidden"> <div className="relative bg-gradient-to-r from-primary-500 via-primary-600 to-primary-500 rounded-3xl p-12 text-white text-center mb-20 animate-fadeInUp overflow-hidden">
{/* Background Pattern */} {/* Background Pattern */}
@@ -26,8 +29,8 @@ function FreeTrial() {
{/* Description */} {/* Description */}
<p className="text-lg md:text-xl text-white/90 mb-8 max-w-2xl mx-auto leading-relaxed animate-fadeInUp delay-300"> <p className="text-lg md:text-xl text-white/90 mb-8 max-w-2xl mx-auto leading-relaxed animate-fadeInUp delay-300">
تمام ویژگیهای پریمیوم رو برای یک هفته کامل تجربه کن، تمام ویژگیهای پریمیوم رو میتونی به طور محدود تجربه کنی
<span className="font-bold text-yellow-300"> بدون نیاز به کارت اعتباری</span> <span className="font-bold text-yellow-300"></span>
</p> </p>
{/* Features */} {/* Features */}
@@ -35,7 +38,10 @@ function FreeTrial() {
{[ {[
"تمامی مدیتیشن‌ها", "تمامی مدیتیشن‌ها",
"موسیقی‌های انحصاری", "موسیقی‌های انحصاری",
"مشاوره هوش مصنوعی" "مشاوره هوش مصنوعی",
"تمرین تنفسی دلخواه",
"اطلاعات آموزشی",
"رابط کاربری ساده",
].map((feature, index) => ( ].map((feature, index) => (
<div key={index} className="flex items-center justify-center gap-2 bg-white/10 backdrop-blur-sm py-3 px-4 rounded-xl"> <div key={index} className="flex items-center justify-center gap-2 bg-white/10 backdrop-blur-sm py-3 px-4 rounded-xl">
<svg className="w-4 h-4 text-yellow-300" fill="currentColor" viewBox="0 0 20 20"> <svg className="w-4 h-4 text-yellow-300" fill="currentColor" viewBox="0 0 20 20">
@@ -47,14 +53,14 @@ function FreeTrial() {
</div> </div>
{/* CTA Button */} {/* CTA Button */}
<button className="bg-white text-primary-500 font-bold py-4 px-12 rounded-2xl hover:shadow-2xl transition-all duration-300 transform hover:scale-105 animate-fadeInUp delay-500 relative overflow-hidden group"> <button onClick={() => scrollToSectionWithHeader('download')} className="bg-white text-primary-500 font-bold py-4 px-12 rounded-2xl hover:shadow-2xl transition-all duration-300 transform hover:scale-105 animate-fadeInUp delay-500 relative overflow-hidden group">
<div className="absolute inset-0 bg-gradient-to-r from-transparent via-white/20 to-transparent -translate-x-full group-hover:translate-x-full transition-transform duration-700"></div> <div className="absolute inset-0 bg-gradient-to-r from-transparent via-white/20 to-transparent -translate-x-full group-hover:translate-x-full transition-transform duration-700"></div>
<span className="relative">شروع دوره آزمایشی رایگان</span> <span className="relative">شروع سفر آرامش</span>
</button> </button>
{/* Footer Note */} {/* Footer Note */}
<p className="text-white/70 text-sm mt-6 animate-fadeInUp delay-600"> <p className="text-white/70 text-sm mt-6 animate-fadeInUp delay-600">
هیچ تعهدی ندارد هر زمان میتوانی لغو کنی میتونی روی گوشیت همیشه داشته باشی
</p> </p>
</div> </div>
</div> </div>
+95 -18
View File
@@ -1,36 +1,113 @@
"use client";
import { useScroll } from '../hooks/useScroll';
import { useState } from 'react';
import { Menu, X } from 'lucide-react';
import LotusLogo from './LotusLogo';
function Header() { function Header() {
const { scrollToSectionWithHeader } = useScroll();
const [isMenuOpen, setIsMenuOpen] = useState(false);
const navigationItems = [
{ name: 'ویژگی‌ها', id: 'features' },
{ name: 'امکانات', id: 'what-you-can-do' },
{ name: 'چرا ما', id: 'why-aramland' },
{ name: 'دانلود', id: 'download' },
{ name: 'ارتباط با ما', id: 'footer' },
{ name: 'بلاگ', id: 'blog' },
];
const handleNavClick = (sectionId) => {
scrollToSectionWithHeader(sectionId);
setIsMenuOpen(false);
};
return ( return (
<nav className="py-6 px-8 sticky top-0 bg-white/80 backdrop-blur-md z-50 border-b border-gray-100"> <nav className="py-4 px-6 sm:px-8 sticky top-0 bg-white/80 backdrop-blur-md z-50 border-b border-gray-100">
<div className="max-w-6xl mx-auto flex justify-between items-center"> <div className="max-w-6xl mx-auto flex justify-between items-center">
{/* Logo */} {/* Logo */}
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<div className="bg-gradient-to-r from-primary-500 to-primary-600 w-8 h-8 rounded-xl flex items-center justify-center"> <LotusLogo className="w-9 h-9 drop-shadow-sm" />
<span className="text-white font-bold text-sm">آ</span> <div className="text-xl sm:text-2xl font-bold bg-gradient-to-r from-primary-500 to-primary-600 bg-clip-text text-transparent">
</div> آرام جان
<div className="text-2xl font-bold bg-gradient-to-r from-primary-500 to-primary-600 bg-clip-text text-transparent">
آراملند
</div> </div>
</div> </div>
{/* Navigation */} {/* Desktop Navigation */}
<div className="hidden md:flex items-center gap-8"> <div className="hidden md:flex items-center gap-6 lg:gap-8">
{['ویژگی‌ها', 'دانلود', 'قیمت‌ها', 'درباره ما'].map((item) => ( {navigationItems.map((item) => (
<a <button
key={item} key={item.id}
href="#" onClick={() => {
className="text-gray-600 hover:text-primary-500 font-medium transition-colors duration-200 relative group" if (item.id === 'blog') {
window.open('https://aramland.approagency.ir/blog/', '_self');
} else {
handleNavClick(item.id);
}
}}
className="text-gray-600 hover:text-primary-500 font-medium transition-colors duration-200 relative group text-sm lg:text-base"
> >
{item} {item.name}
<span className="absolute bottom-0 left-0 w-0 h-0.5 bg-primary-500 group-hover:w-full transition-all duration-300"></span> <span className="absolute bottom-0 left-0 w-0 h-0.5 bg-primary-500 group-hover:w-full transition-all duration-300"></span>
</a> </button>
))} ))}
</div> </div>
{/* CTA Button */} {/* Desktop CTA Button */}
<button className="bg-gradient-to-r from-primary-500 to-primary-600 text-white font-medium py-2 px-6 rounded-xl hover:shadow-lg transition-all duration-300 transform hover:scale-105"> <div className="hidden md:block">
شروع رایگان <button
onClick={() => handleNavClick('download')}
className="bg-gradient-to-r from-primary-500 to-primary-600 text-white font-medium py-2 px-4 lg:py-2 lg:px-6 rounded-xl hover:shadow-lg transition-all duration-300 transform hover:scale-105 text-sm lg:text-base"
>
شروع سفر آرامش
</button>
</div>
{/* Mobile Menu Button */}
<button
className="md:hidden p-2 rounded-lg hover:bg-gray-100 transition-colors"
onClick={() => setIsMenuOpen(!isMenuOpen)}
>
{isMenuOpen ? (
<X className="w-6 h-6 text-gray-600" />
) : (
<Menu className="w-6 h-6 text-gray-600" />
)}
</button> </button>
</div> </div>
{/* Mobile Menu */}
{isMenuOpen && (
<div className="md:hidden absolute top-full left-0 right-0 bg-white/95 backdrop-blur-md border-b border-gray-200 shadow-lg">
<div className="px-6 py-4 space-y-4">
{navigationItems.map((item) => (
<button
key={item.id}
onClick={() => {
if (item.id === 'blog') {
window.open('https://aramland.approagency.ir/blog/', '_self');
} else {
handleNavClick(item.id);
}
}}
className="block w-full text-right py-3 px-4 text-gray-700 hover:text-primary-500 hover:bg-primary-50 rounded-lg transition-all duration-200 font-medium border-b border-gray-100 last:border-b-0"
>
{item.name}
</button>
))}
{/* Mobile CTA Button */}
<div className="pt-4 border-t border-gray-200">
<button
onClick={() => handleNavClick('download')}
className="w-full bg-gradient-to-r from-primary-500 to-primary-600 text-white font-medium py-3 px-4 rounded-xl hover:shadow-lg transition-all duration-300 transform hover:scale-105 text-center"
>
شروع سفر آرامش
</button>
</div>
</div>
</div>
)}
</nav> </nav>
); );
} }
+35 -27
View File
@@ -1,37 +1,45 @@
import { motion } from "framer-motion"; "use client";
import DownloadSection from "./DownloadSection";
import { useScroll } from '../hooks/useScroll';
import LotusLogo from "./LotusLogo";
function Hero() { function Hero() {
const { scrollToSectionWithHeader } = useScroll();
return ( return (
<div className="text-center mb-20 relative"> <div className="text-center mb-10 relative">
{/* Background decoration */} {/* Background decoration */}
<div className="absolute inset-0 overflow-hidden pointer-events-none"> <div className="absolute inset-0 overflow-hidden pointer-events-none rounded-3xl">
<div className="absolute -top-20 -right-20 w-72 h-72 bg-primary-500 opacity-10 rounded-full blur-3xl"></div> <div className="absolute -top-20 -right-20 w-72 h-72 bg-primary-500 opacity-10 rounded-full blur-3xl"></div>
<div className="absolute -bottom-20 -left-20 w-72 h-72 bg-primary-500 opacity-10 rounded-full blur-3xl"></div> <div className="absolute -bottom-20 -left-20 w-72 h-72 bg-primary-400 opacity-10 rounded-full blur-3xl"></div>
</div> </div>
<div className="relative"> <div className="relative">
<div className="mb-8 animate-float"> {/* App logo */}
<div className="relative inline-block"> <div className="mb-6 flex justify-center">
<span className="text-6xl"></span> <div className="relative inline-block animate-float">
<div className="absolute inset-0 bg-gradient-to-r from-primary-500 to-primary-600 opacity-20 blur-xl rounded-full"></div> <div className="absolute inset-0 bg-gradient-to-r from-primary-500 to-primary-600 blur-2xl rounded-full animate-pulseGlow"></div>
<div className="relative w-24 h-24 sm:w-28 sm:h-28 rounded-[26px] overflow-hidden shadow-2xl shadow-primary-500/40">
<LotusLogo className="w-full h-full" />
</div>
</div> </div>
</div> </div>
<h1 className="text-5xl md:text-7xl font-bold text-gray-900 mb-6 leading-tight animate-fadeInUp"> {/* Badge */}
آرامش را در <div className="inline-flex items-center gap-2 bg-primary-500/10 text-primary-600 px-4 py-2 rounded-full text-sm font-medium mb-6 animate-fadeInUp">
<span>🌿</span>
مدیتیشن، تمرین تنفسی و آرامش فارسی
</div>
<h1 className="text-5xl md:text-7xl font-bold text-gray-900 mb-4 leading-tight animate-fadeInUp">
آرامش را در
<span className="bg-gradient-to-r from-primary-500 to-primary-600 bg-clip-text text-transparent"> هر لحظه </span> <span className="bg-gradient-to-r from-primary-500 to-primary-600 bg-clip-text text-transparent"> هر لحظه </span>
تجربه کنید تجربه کنید
</h1> </h1>
<p className="text-lg md:text-xl text-gray-600 max-w-2xl mx-auto animate-fadeInUp delay-100">
<p className="text-xl md:text-2xl text-gray-600 max-w-3xl mx-auto leading-relaxed mb-6 animate-fadeInUp delay-100"> با آرام جان هر روز چند دقیقه برای خودت وقت بگذار؛ ذهنی آرامتر، خوابی عمیقتر و انرژیای تازه.
آراملند دستیار شخصی شما برای یافتن آرامش درونی. با مدیتیشنهای اختصاصی،
موسیقی آرامشبخش و راهنماییهای حرفهای.
</p> </p>
<DownloadSection />
<div className="flex flex-col sm:flex-row gap-4 justify-center items-center animate-fadeInUp delay-200"> <div className="flex flex-col sm:flex-row gap-4 justify-center items-center animate-fadeInUp delay-200">
<button className="bg-gradient-to-r from-primary-500 to-primary-600 text-white font-bold py-4 px-8 rounded-2xl hover:shadow-2xl transition-all duration-300 transform hover:scale-105 text-lg shadow-lg hover:shadow-primary-500/25"> <button onClick={() => scrollToSectionWithHeader('what-you-can-do')} className="bg-gradient-to-r from-primary-500 to-primary-600 border-2 border-transparent text-white font-bold py-4 px-8 rounded-2xl hover:shadow-2xl hover:shadow-primary-500/30 transition-all duration-300 transform hover:scale-105">
شروع کنید رایگان
</button>
<button className="border-2 border-gray-300 text-gray-700 font-bold py-4 px-8 rounded-2xl hover:border-primary-500 hover:text-primary-500 transition-all duration-300">
مشاهده ویژگیها مشاهده ویژگیها
</button> </button>
</div> </div>
@@ -39,12 +47,12 @@ function Hero() {
{/* Trust indicators */} {/* Trust indicators */}
<div className="mt-12 animate-fadeInUp delay-300"> <div className="mt-12 animate-fadeInUp delay-300">
<p className="text-gray-500 text-sm mb-4">مورد اعتماد هزاران کاربر</p> <p className="text-gray-500 text-sm mb-4">مورد اعتماد هزاران کاربر</p>
<div className="flex justify-center items-center gap-8 opacity-60"> <div className="flex justify-center items-center gap-8 opacity-80">
<div className="text-2xl font-bold text-gray-400"> ۴</div> <div className="text-2xl font-bold text-primary-500"> ۴</div>
<div className="h-4 w-px bg-gray-300"></div> <div className="h-4 w-px bg-primary-300"></div>
<div className="text-gray-500">+۱۰۰۰ دانلود</div> <div className="text-primary-500 font-bold">+۱۰۰۰ دانلود</div>
<div className="h-4 w-px bg-gray-300"></div> <div className="h-4 w-px bg-primary-300"></div>
<div className="text-gray-500">۹۸٪ رضایت</div> <div className="text-primary-500 font-bold ">۹۸٪ رضایت</div>
</div> </div>
</div> </div>
</div> </div>
+43
View File
@@ -0,0 +1,43 @@
// Brand mark for آرام جان a layered translucent lotus on a blueindigo
// gradient, matching the app icon. Self-contained SVG so it stays crisp at any
// size and needs no image asset. Size it with `className` (e.g. "w-9 h-9").
function LotusLogo({ className = "w-9 h-9", title = "آرام جان" }) {
const petal = "M50 72 C42 56 42 34 50 22 C58 34 58 56 50 72 Z";
const angles = [-50, -25, 0, 25, 50];
const opacityFor = (a) => {
if (a === 0) return 0.95;
if (Math.abs(a) === 25) return 0.72;
return 0.5;
};
return (
<svg
viewBox="0 0 100 100"
className={className}
xmlns="http://www.w3.org/2000/svg"
role="img"
aria-label={title}
>
<defs>
<linearGradient id="aramjan-lotus-bg" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stopColor="#5fa0ff" />
<stop offset="100%" stopColor="#6a4ff0" />
</linearGradient>
</defs>
<rect width="100" height="100" rx="26" fill="url(#aramjan-lotus-bg)" />
<g fill="#ffffff">
{angles.map((a) => (
<path
key={a}
d={petal}
transform={`rotate(${a} 50 72)`}
fillOpacity={opacityFor(a)}
/>
))}
</g>
</svg>
);
}
export default LotusLogo;
+33
View File
@@ -0,0 +1,33 @@
// components/SEOHead.jsx
export function SEOHead({
title,
description,
canonical,
ogImage
}) {
const siteUrl = 'https://aramland.approagency.ir/';
return (
<>
<title>{title}</title>
<meta name="description" content={description} />
{/* Canonical URL */}
<link rel="canonical" href={`${siteUrl}${canonical}`} />
{/* Open Graph */}
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:url" content={`${siteUrl}${canonical}`} />
<meta property="og:image" content={ogImage || `${siteUrl}/og-image.png`} />
<meta property="og:type" content="website" />
<meta property="og:locale" content="fa_IR" />
{/* Twitter */}
<meta name="twitter:title" content={title} />
<meta name="twitter:description" content={description} />
<meta name="twitter:image" content={ogImage || `${siteUrl}/og-image.png`} />
<meta name="twitter:card" content="summary_large_image" />
</>
);
}
+2 -2
View File
@@ -2,7 +2,7 @@
// const benefits = [ // const benefits = [
// { // {
// title: "تکنیکهای مبتنی بر علم اعصاب", // title: "تکنیکهای مبتنی بر علم اعصاب",
// description: "آراملند از روشهای اثباتشده علمی برای کاهش استرس و افزایش آرامش استفاده میکند", // description: "آرام لند از روشهای اثباتشده علمی برای کاهش استرس و افزایش آرامش استفاده میکند",
// icon: "🧠", // icon: "🧠",
// items: [ // items: [
// "بهبود خلق و خو در کمتر از ۵ دقیقه", // "بهبود خلق و خو در کمتر از ۵ دقیقه",
@@ -124,7 +124,7 @@
// 📊 پشتیبانی شده توسط تحقیقات // 📊 پشتیبانی شده توسط تحقیقات
// </h4> // </h4>
// <p className="text-gray-700 leading-relaxed"> // <p className="text-gray-700 leading-relaxed">
// تمام تکنیکهای استفاده شده در آراملند بر اساس مطالعات علمی معتبر در زمینههای // تمام تکنیکهای استفاده شده در آرام لند بر اساس مطالعات علمی معتبر در زمینههای
// روانشناسی، علوم اعصاب و پزشکی رفتاری طراحی شدهاند. // روانشناسی، علوم اعصاب و پزشکی رفتاری طراحی شدهاند.
// </p> // </p>
// </div> // </div>
+4 -4
View File
@@ -49,7 +49,7 @@ function WhatYouCanDo() {
]; ];
return ( return (
<div className="my-24"> <div className="my-12">
{/* Section Header */} {/* Section Header */}
<div className="text-center mb-16"> <div className="text-center mb-16">
<div className="inline-flex items-center gap-2 bg-primary-500/10 text-primary-500 px-4 py-2 rounded-full text-sm font-medium mb-4"> <div className="inline-flex items-center gap-2 bg-primary-500/10 text-primary-500 px-4 py-2 rounded-full text-sm font-medium mb-4">
@@ -57,7 +57,7 @@ function WhatYouCanDo() {
قابلیتهای اصلی قابلیتهای اصلی
</div> </div>
<h2 className="text-4xl md:text-5xl font-bold text-gray-900 mb-4"> <h2 className="text-4xl md:text-5xl font-bold text-gray-900 mb-4">
هر آنچه برای <span className="text-primary-500">آرامش</span> نیاز داری اینجا زندگی <span className="text-primary-500">آسون تر</span> میشه
</h2> </h2>
<p className="text-xl text-gray-600 max-w-2xl mx-auto"> <p className="text-xl text-gray-600 max-w-2xl mx-auto">
ابزارهای متنوع و تخصصی برای رسیدن به آرامش در هر شرایطی ابزارهای متنوع و تخصصی برای رسیدن به آرامش در هر شرایطی
@@ -109,14 +109,14 @@ function WhatYouCanDo() {
</div> </div>
{/* Bottom CTA */} {/* Bottom CTA */}
<div className="text-center"> {/* <div className="text-center">
<p className="text-gray-600 text-lg mb-6"> <p className="text-gray-600 text-lg mb-6">
بیش از <span className="text-primary-500 font-bold">۱۰۰۰</span> کاربر از این ویژگیها استفاده میکنند بیش از <span className="text-primary-500 font-bold">۱۰۰۰</span> کاربر از این ویژگیها استفاده میکنند
</p> </p>
<button className="bg-gradient-to-r from-primary-500 to-primary-600 text-white font-bold py-3 px-6 rounded-2xl hover:shadow-lg transition-all duration-300 transform hover:scale-105"> <button className="bg-gradient-to-r from-primary-500 to-primary-600 text-white font-bold py-3 px-6 rounded-2xl hover:shadow-lg transition-all duration-300 transform hover:scale-105">
کشف همه قابلیتها کشف همه قابلیتها
</button> </button>
</div> </div> */}
</div> </div>
); );
} }
+6 -6
View File
@@ -60,10 +60,10 @@ function WhyAramland() {
<div className="text-center mb-16"> <div className="text-center mb-16">
<div className="inline-flex items-center gap-2 bg-primary-500/10 text-primary-500 px-4 py-2 rounded-full text-sm font-medium mb-4"> <div className="inline-flex items-center gap-2 bg-primary-500/10 text-primary-500 px-4 py-2 rounded-full text-sm font-medium mb-4">
<span className="text-lg">🚀</span> <span className="text-lg">🚀</span>
برتری آراملند برتری آرام جان
</div> </div>
<h2 className="text-4xl md:text-5xl font-bold text-gray-900 mb-4"> <h2 className="text-4xl md:text-5xl font-bold text-gray-900 mb-4">
چرا <span className="text-primary-500">هزاران نفر</span> آراملند را انتخاب میکنند؟ چرا <span className="text-primary-500">هزاران نفر</span> آرام جان را انتخاب میکنند؟
</h2> </h2>
<p className="text-xl text-gray-600 max-w-2xl mx-auto"> <p className="text-xl text-gray-600 max-w-2xl mx-auto">
تجربهای متفاوت از آرامش، طراحی شده مخصوص فارسیزبانان تجربهای متفاوت از آرامش، طراحی شده مخصوص فارسیزبانان
@@ -81,15 +81,15 @@ function WhyAramland() {
<div className={`bg-gradient-to-br ${stat.gradient} w-20 h-20 rounded-2xl flex items-center justify-center mx-auto mb-4 group-hover:shadow-lg transition-all duration-300`}> <div className={`bg-gradient-to-br ${stat.gradient} w-20 h-20 rounded-2xl flex items-center justify-center mx-auto mb-4 group-hover:shadow-lg transition-all duration-300`}>
<span className="text-2xl text-white">{stat.icon}</span> <span className="text-2xl text-white">{stat.icon}</span>
</div> </div>
{/* Number */} {/* Number */}
<div className="text-4xl font-bold bg-gradient-to-r from-primary-500 to-primary-600 bg-clip-text text-transparent mb-2"> <div className="text-4xl font-bold bg-gradient-to-r from-primary-500 to-primary-600 bg-clip-text text-transparent mb-2">
{stat.number} {stat.number}
</div> </div>
{/* Main Text */} {/* Main Text */}
<h3 className="text-lg font-bold text-gray-900 mb-2">{stat.text}</h3> <h3 className="text-lg font-bold text-gray-900 mb-2">{stat.text}</h3>
{/* Description */} {/* Description */}
<p className="text-gray-600 text-sm leading-relaxed"> <p className="text-gray-600 text-sm leading-relaxed">
{stat.description} {stat.description}
@@ -129,7 +129,7 @@ function WhyAramland() {
<div className="flex flex-col md:flex-row items-center justify-between gap-6"> <div className="flex flex-col md:flex-row items-center justify-between gap-6">
<div className="flex-1"> <div className="flex-1">
<h4 className="text-2xl font-bold text-gray-900 mb-3"> <h4 className="text-2xl font-bold text-gray-900 mb-3">
👥 عضو جامعه هزاران نفری آراملند شوید 👥 عضو جامعه هزاران نفری آرام جان شوید
</h4> </h4>
<p className="text-gray-700 leading-relaxed"> <p className="text-gray-700 leading-relaxed">
به خانوادهای از کاربران خوشحال بپیوندید که هر روز قدمی به سمت آرامش برمیدارند به خانوادهای از کاربران خوشحال بپیوندید که هر روز قدمی به سمت آرامش برمیدارند
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

+46
View File
@@ -68,4 +68,50 @@ body {
color: var(--foreground); color: var(--foreground);
font-family: 'Dana', 'Inter', Arial, Helvetica, sans-serif; font-family: 'Dana', 'Inter', Arial, Helvetica, sans-serif;
font-weight: 400; font-weight: 400;
}
/* ===== Brand motion =====
The markup already references these animation classes; define them here so
the landing page feels alive (entrance reveals, floating logo, soft glow). */
@keyframes fadeInUp {
from { opacity: 0; transform: translateY(30px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes slideInLeft {
from { opacity: 0; transform: translateX(-40px); }
to { opacity: 1; transform: translateX(0); }
}
@keyframes slideInRight {
from { opacity: 0; transform: translateX(40px); }
to { opacity: 1; transform: translateX(0); }
}
@keyframes floatY {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-14px); }
}
@keyframes pulseGlow {
0%, 100% { opacity: .3; transform: scale(1); }
50% { opacity: .6; transform: scale(1.08); }
}
.animate-fadeInUp { animation: fadeInUp 0.7s ease-out both; }
.animate-slideInLeft { animation: slideInLeft 0.7s ease-out both; }
.animate-slideInRight { animation: slideInRight 0.7s ease-out both; }
.animate-float { animation: floatY 5s ease-in-out infinite; }
.animate-pulseGlow { animation: pulseGlow 4s ease-in-out infinite; }
/* Stagger helpers — apply animation-delay on top of the entrance animations */
.delay-100 { animation-delay: .1s; }
.delay-200 { animation-delay: .2s; }
.delay-300 { animation-delay: .3s; }
.delay-400 { animation-delay: .4s; }
@media (prefers-reduced-motion: reduce) {
.animate-fadeInUp,
.animate-slideInLeft,
.animate-slideInRight,
.animate-float,
.animate-pulseGlow {
animation: none;
}
} }
+40
View File
@@ -0,0 +1,40 @@
// hooks/useScroll.js
import { useCallback } from 'react';
export const useScroll = () => {
const scrollToSection = useCallback((sectionId, offset = 0) => {
if (typeof window === 'undefined') return;
const element = document.getElementById(sectionId);
if (element) {
const elementPosition = element.getBoundingClientRect().top;
const offsetPosition = elementPosition + window.pageYOffset - offset;
window.scrollTo({
top: offsetPosition,
behavior: 'smooth'
});
}
}, []);
const scrollToSectionWithHeader = useCallback((sectionId) => {
const headerOffset = 80; // Adjust based on your header height
scrollToSection(sectionId, headerOffset);
}, [scrollToSection]);
const scrollToTop = useCallback(() => {
if (typeof window === 'undefined') return;
window.scrollTo({
top: 0,
behavior: 'smooth'
});
}, []);
return {
scrollToSection,
scrollToSectionWithHeader,
scrollToTop
};
};
+16
View File
@@ -0,0 +1,16 @@
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="آرام جان">
<defs>
<linearGradient id="bg" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#5fa0ff"/>
<stop offset="100%" stop-color="#6a4ff0"/>
</linearGradient>
</defs>
<rect width="100" height="100" rx="22" fill="url(#bg)"/>
<g fill="#ffffff">
<path d="M50 72 C42 56 42 34 50 22 C58 34 58 56 50 72 Z" transform="rotate(-50 50 72)" fill-opacity="0.5"/>
<path d="M50 72 C42 56 42 34 50 22 C58 34 58 56 50 72 Z" transform="rotate(-25 50 72)" fill-opacity="0.72"/>
<path d="M50 72 C42 56 42 34 50 22 C58 34 58 56 50 72 Z" transform="rotate(0 50 72)" fill-opacity="0.95"/>
<path d="M50 72 C42 56 42 34 50 22 C58 34 58 56 50 72 Z" transform="rotate(25 50 72)" fill-opacity="0.72"/>
<path d="M50 72 C42 56 42 34 50 22 C58 34 58 56 50 72 Z" transform="rotate(50 50 72)" fill-opacity="0.5"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 950 B

+103 -8
View File
@@ -2,15 +2,70 @@ import type { Metadata } from 'next';
import './globals.css'; import './globals.css';
export const metadata: Metadata = { export const metadata: Metadata = {
title: 'آرام‌لند | تمرین تنفسی و مدیتیشن', title: 'آرام جان | تمرین تنفسی و مدیتیشن',
description: 'لحظه‌ای آرام بگیر، زندگی را حس کن', description: 'لحظه‌ای آرام بگیر، زندگی را حس کن',
keywords: ['مدیتیشن فارسی', 'آرامش', 'تمرین تنفسی', 'کاهش استرس', 'ذهن‌آگاهی', 'مدیتیشن هدایت شده', 'سلامت روان', 'آرام جان'],
authors: [{ name: 'آرام جان' }],
creator: 'آرام جان',
publisher: 'آرام جان',
metadataBase: new URL('https://aramland.approagency.ir/'),
formatDetection: {
email: false,
address: false,
telephone: false,
},
icons: {
icon: '/icon.svg',
},
alternates: {
canonical: '/',
languages: {
'fa-IR': '/',
},
},
openGraph: {
title: 'آرام جان - دستیار آرامش و مدیتیشن فارسی',
description: 'اپلیکیشن آرام جان - همراه شما برای رسیدن به آرامش درونی با مدیتیشن‌های فارسی و تمرین‌های تنفسی',
url: 'https://aramland.approagency.ir/',
siteName: 'آرام جان',
images: [
{
url: '/og-image.png', // Create this image (1200x630px)
width: 1200,
height: 630,
alt: ' آرام جان - اپلیکیشن مدیتیشن و آرامش - تمرین تنفسی',
},
],
locale: 'fa_IR',
type: 'website',
},
twitter: {
card: 'summary_large_image',
title: 'آرام جان - تمرین تنفسی و مدیتیشن',
description: 'اپلیکیشن آرام جان - همراه شما برای رسیدن به آرامش درونی',
images: ['/og-image.png'],
creator: '@aramland', // Replace with your Twitter handle
},
robots: {
index: true,
follow: true,
googleBot: {
index: true,
follow: true,
'max-video-preview': -1,
'max-image-preview': 'large',
'max-snippet': -1,
},
},
verification: {
// Add your verification codes here
google: 'google-site-verification=HIKgdf_siYdPxbJ2P1792opMprpxci_QjE-quk9kyi8', // From Google Search Console
// yandex: 'your-yandex-verification-code', // If targeting Iran/Russia
},
}; };
<link
rel="icon"
href="/favicon.png"
type="image/<generated>"
sizes="<generated>"
/>
export default function RootLayout({ export default function RootLayout({
children, children,
}: { }: {
@@ -19,7 +74,47 @@ export default function RootLayout({
return ( return (
<html lang="fa" dir="rtl"> <html lang="fa" dir="rtl">
<head> <head>
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta
name="google-site-verification"
content="HIKgdf_siYdPxbJ2P1792opMprpxci_QjE-quk9kyi8"
/>
{/* Favicon — lotus mark (آرام جان) */}
<link rel="icon" href="/icon.svg" type="image/svg+xml" />
<link rel="apple-touch-icon" href="/icon.svg" />
{/* Preload critical resources */}
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />
{/* Structured Data for SEO */}
<script
type="application/ld+json"
dangerouslySetInnerHTML={{
__html: JSON.stringify({
"@context": "https://schema.org",
"@type": "WebApplication",
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.5",
"ratingCount": "1000"
},
"name": "آرام جان",
"description": "اپلیکیشن آرام جان - همراه شما برای رسیدن به آرامش درونی با مدیتیشن‌های فارسی و تمرین‌های تنفسی",
"url": "https://aramland.approagency.ir/",
"applicationCategory": "HealthApplication",
"operatingSystem": "Android, iOS, Web",
"offers": {
"@type": "Offer",
"price": "0",
"priceCurrency": "IRR"
},
"author": {
"@type": "Organization",
"name": "آرام جان"
}
})
}}
/>
</head> </head>
<body className="antialiased"> <body className="antialiased">
{children} {children}
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

+15
View File
@@ -0,0 +1,15 @@
// app/robots.txt
User-agent: *
Allow: /
Disallow: /api/
Disallow: /_next/
Disallow: /private/
Sitemap: https://aramland.approagency.ir/sitemap.xml
# Iranian search engines
User-agent: YoozBot
Allow: /
User-agent: Parsijoo
Allow: /
+42
View File
@@ -0,0 +1,42 @@
// app/sitemap.js
export default function sitemap() {
const baseUrl = 'https://aaramland.ir/';
return [
{
url: baseUrl,
lastModified: new Date(),
changeFrequency: 'weekly',
priority: 1,
},
{
url: `${baseUrl}blog/`,
lastModified: new Date(),
changeFrequency: 'weekly',
priority: 0.9,
},
{
url: `${baseUrl}blog/tmryn-tnfsy-bry-khhsh-strs.html`,
lastModified: new Date(),
changeFrequency: 'weekly',
priority: 0.8,
},
{
url: `${baseUrl}blog/mdytyshn-chyh.html`,
lastModified: new Date(),
changeFrequency: 'weekly',
priority: 0.7,
},
{
url: `${baseUrl}blog/khls-shdn-z-strs-b-arm-lnd.html`,
lastModified: new Date(),
changeFrequency: 'weekly',
priority: 0.6,
},
];
}
// Add this export for static generation
export async function generateSitemaps() {
return [{ id: '0' }];
}
+1 -2
View File
@@ -1,7 +1,6 @@
import type { NextConfig } from "next"; import type { NextConfig } from "next";
const nextConfig: NextConfig = { const nextConfig: NextConfig = {
/* config options here */ output: 'export',
}; };
export default nextConfig; export default nextConfig;
+2 -1
View File
@@ -6,7 +6,8 @@
"dev": "next dev", "dev": "next dev",
"build": "next build", "build": "next build",
"start": "next start", "start": "next start",
"lint": "eslint" "lint": "eslint",
"deploy": "bash scripts/deploy.sh"
}, },
"dependencies": { "dependencies": {
"framer-motion": "^12.23.24", "framer-motion": "^12.23.24",
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 677 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 676 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

+49
View File
@@ -0,0 +1,49 @@
#!/usr/bin/env bash
# Build the static site locally, then replace the server directory with it.
#
# - Builds on THIS machine (npm run build -> ./out).
# - Streams out/ over a single SSH connection (tar pipe) and swaps the
# contents of the target dir on the server. No rsync/sshpass required.
#
# Password handling:
# - If `sshpass` is installed AND DEPLOY_PASSWORD is set (env or .env.deploy),
# the deploy is fully unattended.
# - Otherwise SSH prompts for the password once (interactive).
#
# Config (override via env or .env.deploy):
set -euo pipefail
cd "$(git rev-parse --show-toplevel 2>/dev/null || dirname "$(dirname "$0")")"
# Optional local secrets file (gitignored).
[ -f .env.deploy ] && . ./.env.deploy
DEPLOY_HOST="${DEPLOY_HOST:-185.226.116.88}"
DEPLOY_USER="${DEPLOY_USER:-ubuntu}"
DEPLOY_PATH="${DEPLOY_PATH:-/var/www/aramland-front}"
DEPLOY_PASSWORD="${DEPLOY_PASSWORD:-}"
echo "▸ Building locally (clean)…"
# Remove caches so the production build never type-checks a stale `.next/dev`
# validator (tsconfig includes .next/dev/types) and never ships stale out/ files.
rm -rf .next out
npm run build
if [ ! -d out ]; then
echo "✗ Build did not produce ./out" >&2
exit 1
fi
# Pick the SSH command: unattended with sshpass, else interactive prompt.
ssh_cmd=(ssh -o StrictHostKeyChecking=no "$DEPLOY_USER@$DEPLOY_HOST")
if command -v sshpass >/dev/null 2>&1 && [ -n "$DEPLOY_PASSWORD" ]; then
ssh_cmd=(sshpass -p "$DEPLOY_PASSWORD" "${ssh_cmd[@]}")
else
echo " sshpass/password not available — SSH will prompt for the password."
fi
echo "▸ Uploading to $DEPLOY_USER@$DEPLOY_HOST:$DEPLOY_PATH"
# Replace the directory contents (incl. dotfiles) then extract the new build.
tar -C out -czf - . | "${ssh_cmd[@]}" \
"set -e; mkdir -p '$DEPLOY_PATH'; find '$DEPLOY_PATH' -mindepth 1 -delete; tar -C '$DEPLOY_PATH' -xzf -"
echo "✓ Deployed to $DEPLOY_HOST:$DEPLOY_PATH"