Compare commits

..

23 Commits

Author SHA1 Message Date
sazzadulalambd
5eae6e5094 feat: update homepage copy and service offerings to reflect new rental plan options 2026-06-23 23:42:32 +06:00
sazzadulalambd
e40faf0418 feat: add Forenizence developer credit to footer with responsive layout adjustments 2026-06-23 23:08:00 +06:00
sazzadulalambd
a2ce7c7b49 refactor: update homepage copy, metrics, and coming-soon page z-index styling 2026-06-23 23:03:48 +06:00
sazzadulalambd
ba725c328d chore: update PWA dependencies, add server whitespace, and replace favicon with icon.png 2026-06-23 22:34:41 +06:00
sazzadulalambd
da2f956de9 chore: update package-lock.json dependencies 2026-06-23 01:09:49 +06:00
sazzadulalambd
7a804e84a1 chore: update dependencies, add glob, and configure npm settings 2026-06-23 01:08:03 +06:00
sazzadulalambd
468a6d48ec chore: downgrade project dependencies and remove package-lock.json 2026-06-23 00:40:29 +06:00
sazzadulalambd
a78ba9b343 perf: preload 3D assets and fix mesh material hex code formatting in HeroBackground3D 2026-06-23 00:36:43 +06:00
sazzadulalambd
241c10fe29 chore: downgrade react, @types/node, eslint, and typescript dependencies 2026-06-22 22:37:12 +06:00
sazzadulalambd
34ce6929e5 chore: update package-lock.json dependencies 2026-06-22 22:00:52 +06:00
sazzadulalambd
5c16cb788d chore: update project dependencies to latest versions 2026-06-22 21:52:00 +06:00
sazzadulalambd
cd156b0ff4 refactor: remove unnecessary eslint disable and reformat server configuration for consistency 2026-06-22 21:46:04 +06:00
sazzadulalambd
8c59ac9944 refactor: apply linting rules and consistent formatting to server configuration 2026-06-22 21:20:05 +06:00
sazzadulalambd
637e46b76f chore: clean up existing deployment artifacts before creating new ones 2026-06-22 21:11:58 +06:00
sazzadulalambd
16c9d9e6f3 refactor: simplify deployment script by updating file copy process and documentation 2026-06-22 21:10:23 +06:00
sazzadulalambd
cdc957832f chore: update deployment script to support Next.js standalone mode for cPanel compatibility 2026-06-22 21:01:36 +06:00
sazzadulalambd
65473392ea feat: import mock users on landing page and loosen StatCard icon type definition 2026-06-22 17:40:15 +06:00
sazzadulalambd
4187c591ad feat: add floating WhatsApp support widget to root layout 2026-06-22 17:25:51 +06:00
sazzadulalambd
5fc14ba492 feat: add app download section to landing page and improve hero 3D background responsiveness 2026-06-22 17:24:30 +06:00
sazzadulalambd
f50b982ae1 feat: redesign service cards with 3D icons, enhanced hover effects, and updated action buttons 2026-06-22 17:17:40 +06:00
sazzadulalambd
24b00fefcd feat: add AnimatedCounter component and update stats section with hero asset color adjustment 2026-06-22 17:12:33 +06:00
sazzadulalambd
79d32a9e83 style: update 3D battery model material colors and adjust handle position 2026-06-22 17:04:33 +06:00
sazzadulalambd
7d320ac4a3 feat: replace Crystal component with detailed Battery model in HeroBackground3D 2026-06-22 17:02:11 +06:00
17 changed files with 1846 additions and 1764 deletions

3
.npmrc Normal file
View File

@@ -0,0 +1,3 @@
legacy-peer-deps=true
fund=false
audit=false

View File

@@ -6,6 +6,7 @@ npm run build
# Create a deployment folder
echo "Preparing deployment files..."
rm -rf deploy deploy.zip
mkdir -p deploy
cp -r .next deploy/
cp -r public deploy/

View File

@@ -20,3 +20,6 @@
## Step 5: Documents
- To be built
"@ducanh2912/next-pwa": "^10.2.9",

2999
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -12,13 +12,14 @@
"@ducanh2912/next-pwa": "^10.2.9",
"@react-three/drei": "^10.7.7",
"@react-three/fiber": "^9.6.1",
"date-fns": "^4.1.0",
"date-fns": "^4.4.0",
"glob": "^13.0.6",
"jspdf": "^4.2.1",
"jspdf-autotable": "^5.0.7",
"jspdf-autotable": "^5.0.8",
"lucide-react": "^1.8.0",
"next": "16.2.4",
"react": "19.2.4",
"react-dom": "19.2.4",
"next": "^16.2.9",
"react": "^19.2.7",
"react-dom": "^19.2.7",
"react-hot-toast": "^2.6.0",
"three": "^0.184.0"
},

View File

@@ -1,5 +1,6 @@
const { createServer } = require('http')
const { parse } = require('url')
const next = require('next')
const dev = process.env.NODE_ENV !== 'production'

View File

@@ -998,7 +998,7 @@ function DashboardView({ stats, accounts, monthLabel = 'This Month' }: { stats:
);
}
function StatCard({ label, value, icon: Icon, color }: { label: string; value: number; icon: React.ElementType; color: string }) {
function StatCard({ label, value, icon: Icon, color }: { label: string; value: number; icon: any; color: string }) {
const colors: Record<string, string> = { green: 'bg-green-50 text-green-600', red: 'bg-red-50 text-red-600', blue: 'bg-blue-50 text-blue-600', purple: 'bg-purple-50 text-purple-600', slate: 'bg-slate-100 text-slate-600' };
const showCurrency = label !== 'Transactions';
return (

View File

@@ -94,7 +94,7 @@ export default function ComingSoonPage() {
return (
<div className="min-h-screen bg-slate-900 flex flex-col items-center justify-center p-4 text-center">
<div className="absolute top-6 left-6">
<div className="absolute top-6 left-6 z-50">
<button
onClick={() => router.push('/')}
className="text-slate-400 hover:text-white flex items-center gap-2 transition-colors"
@@ -128,7 +128,7 @@ export default function ComingSoonPage() {
</p>
{/* Mini Game Container */}
<div className="bg-slate-800 p-6 rounded-3xl border border-slate-700 shadow-2xl">
<div className="bg-slate-800 p-6 rounded-3xl border border-slate-700 shadow-2xl z-[9999]">
<div className="flex justify-between items-center mb-6 text-slate-300">
<span className="font-semibold">Moves: <span className="text-accent">{moves}</span></span>
{won && <span className="text-yellow-400 font-bold flex items-center gap-1"><Trophy className="w-5 h-5" /> You Won!</span>}
@@ -145,11 +145,10 @@ export default function ComingSoonPage() {
<button
key={card.id}
onClick={() => handleCardClick(index)}
className={`aspect-square rounded-xl flex items-center justify-center text-2xl transition-all duration-300 transform ${
isVisible
? 'bg-accent/20 border-2 border-accent text-accent scale-100 rotate-0'
: 'bg-slate-700 border-2 border-slate-600 hover:bg-slate-600 scale-95'
} ${card.isMatched ? 'opacity-50' : ''}`}
className={`aspect-square rounded-xl flex items-center justify-center text-2xl transition-all duration-300 transform ${isVisible
? 'bg-accent/20 border-2 border-accent text-accent scale-100 rotate-0'
: 'bg-slate-700 border-2 border-slate-600 hover:bg-slate-600 scale-95'
} ${card.isMatched ? 'opacity-50' : ''}`}
>
{isVisible ? <Icon className="w-8 h-8" /> : '?'}
</button>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

BIN
src/app/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 981 KiB

View File

@@ -28,6 +28,8 @@ export const viewport: Viewport = {
userScalable: false,
};
import WhatsAppFloat from "@/components/ui/WhatsAppFloat";
export default function RootLayout({
children,
}: Readonly<{
@@ -37,6 +39,7 @@ export default function RootLayout({
<html lang="en" className={inter.variable} suppressHydrationWarning>
<body className="min-h-screen bg-slate-50 antialiased" suppressHydrationWarning>
<LayoutContent>{children}</LayoutContent>
<WhatsAppFloat />
<Toaster position="top-right" />
</body>
</html>

View File

@@ -4,8 +4,11 @@ import { useState, useEffect } from 'react';
import { useRouter } from 'next/navigation';
import Image from 'next/image';
import HeroBackground3D from '@/components/ui/3d/HeroBackground3D';
import AnimatedCounter from '@/components/ui/AnimatedCounter';
import CardIcon3D from '@/components/ui/3d/CardIcon3D';
import { Zap, ArrowRight, Bike, Wallet, Leaf, ShieldCheck, MapPin, Truck, ChevronRight, BarChart3, BatteryCharging, Clock, Activity } from 'lucide-react';
import { users } from '@/data/mockData';
export default function LandingPage() {
const router = useRouter();
@@ -59,7 +62,7 @@ export default function LandingPage() {
};
return (
<div className="min-h-screen bg-slate-50 font-sans selection:bg-accent selection:text-white pb-20 lg:pb-0">
<div className="min-h-screen bg-slate-50 font-sans selection:bg-accent selection:text-white">
{/* Dynamic Header */}
<header className={`fixed top-0 left-0 right-0 z-50 transition-all duration-300 ${scrolled ? 'bg-white/90 backdrop-blur-md shadow-sm py-3' : 'bg-transparent py-5'}`}>
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex items-center justify-between">
@@ -99,7 +102,7 @@ export default function LandingPage() {
<span className="text-transparent bg-clip-text bg-gradient-to-r from-accent via-emerald-400 to-accent-light">Go Electric</span> with JAIBEN.
</h1>
<p className="text-slate-300 text-lg sm:text-xl mb-10 drop-shadow-lg">
The largest EV Tech platform enabling the Gig Economy. Rent, Rent-to-Own, or Invest in EVs. Join the sustainable mobility revolution today.
The largest EV Tech platform enabling the Gig Economy. Choose from Single Rent, Rent to Own, or Share an EV. Join the sustainable mobility revolution today.
</p>
<div className="flex flex-col sm:flex-row items-center lg:items-start justify-center lg:justify-start gap-4">
<button
@@ -117,24 +120,34 @@ export default function LandingPage() {
<div className="absolute top-24 -right-24 w-96 h-96 bg-emerald-500/20 rounded-full blur-3xl mix-blend-screen pointer-events-none"></div>
</section>
{/* Stats Section (Overlapping Hero) */}
<section className="relative z-20 max-w-5xl mx-auto px-4 sm:px-6 lg:px-8 -mt-12 mb-20">
<div className="bg-white rounded-2xl shadow-2xl p-6 lg:p-10 grid grid-cols-2 lg:grid-cols-4 gap-8 divide-x divide-slate-100 border border-slate-100">
<div className="text-center px-4">
<div className="text-3xl lg:text-4xl font-black text-accent mb-2">500+</div>
<div className="text-slate-500 font-medium text-sm">Active Riders</div>
</div>
<div className="text-center px-4">
<div className="text-3xl lg:text-4xl font-black text-accent mb-2">200+</div>
<div className="text-slate-500 font-medium text-sm">EV Fleet Size</div>
</div>
<div className="text-center px-4">
<div className="text-3xl lg:text-4xl font-black text-accent mb-2">18%</div>
<div className="text-slate-500 font-medium text-sm">Avg. Investor ROI</div>
</div>
<div className="text-center px-4">
<div className="text-3xl lg:text-4xl font-black text-accent mb-2">50k+</div>
<div className="text-slate-500 font-medium text-sm">Deliveries Done</div>
{/* Stats Section */}
<section className="py-12 lg:py-16 bg-white border-b border-slate-100">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="grid grid-cols-2 md:grid-cols-4 gap-8 divide-x divide-slate-100">
<div className="flex flex-col items-center justify-center text-center px-2">
<h3 className="text-4xl md:text-5xl font-black text-slate-900 mb-2">
<AnimatedCounter end={500} suffix="+" />
</h3>
<p className="text-xs sm:text-sm font-semibold text-slate-500 uppercase tracking-wider">Active Riders</p>
</div>
<div className="flex flex-col items-center justify-center text-center px-2">
<h3 className="text-4xl md:text-5xl font-black text-slate-900 mb-2">
<AnimatedCounter end={200} suffix="+" />
</h3>
<p className="text-xs sm:text-sm font-semibold text-slate-500 uppercase tracking-wider">EV Fleet Size</p>
</div>
<div className="flex flex-col items-center justify-center text-center px-2">
<h3 className="text-4xl md:text-5xl font-black text-slate-900 mb-2 text-accent">
<AnimatedCounter end={18} suffix="%" />
</h3>
<p className="text-xs sm:text-sm font-semibold text-slate-500 uppercase tracking-wider">Avg. Rider Savings</p>
</div>
<div className="flex flex-col items-center justify-center text-center px-2">
<h3 className="text-4xl md:text-5xl font-black text-slate-900 mb-2">
<AnimatedCounter end={50} suffix="k+" />
</h3>
<p className="text-xs sm:text-sm font-semibold text-slate-500 uppercase tracking-wider">Deliveries Done</p>
</div>
</div>
</div>
</section>
@@ -150,74 +163,69 @@ export default function LandingPage() {
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
{/* Service 1 */}
<div className="group bg-white rounded-3xl p-8 shadow-sm hover:shadow-2xl transition-all duration-300 border border-slate-100 relative overflow-hidden flex flex-col h-full">
<div className="absolute top-0 right-0 w-32 h-32 bg-biker/10 rounded-bl-full -mr-8 -mt-8 transition-transform group-hover:scale-110"></div>
<div className="w-16 h-16 bg-biker/10 rounded-2xl flex items-center justify-center mb-6 relative z-10 text-biker group-hover:bg-biker group-hover:text-white transition-colors">
<Bike className="w-8 h-8" />
<div className="group bg-white rounded-3xl p-8 shadow-lg hover:shadow-[0_20px_50px_rgba(0,0,0,0.1)] transition-all duration-500 border border-slate-100 relative overflow-hidden flex flex-col h-full transform hover:-translate-y-2">
<div className="absolute top-0 left-0 w-64 h-64 bg-gradient-to-br from-biker/10 to-transparent rounded-full blur-3xl -ml-16 -mt-16 transition-transform duration-700 group-hover:scale-150"></div>
<div className="w-24 h-24 bg-gradient-to-br from-white to-slate-50 shadow-inner rounded-2xl flex items-center justify-center mb-8 relative z-10 border border-slate-100/50">
<CardIcon3D type="bike" />
</div>
<h4 className="text-2xl font-bold text-slate-900 mb-3 relative z-10">Biker Rentals</h4>
<p className="text-slate-600 mb-8 flex-grow relative z-10">Save on petrol costs and rent a high-performance e-scooter for your daily commute or delivery gigs.</p>
<h4 className="text-2xl font-extrabold text-slate-900 mb-4 relative z-10">Biker Rentals</h4>
<p className="text-slate-600 mb-8 flex-grow relative z-10 leading-relaxed">Save money on fuel. Pick the plan that works for you: Single Rent for quick trips, Rent to Own to keep the bike later, or Share an EV for flexibility.</p>
<button
onClick={() => router.push('/coming-soon')}
disabled={loading}
className="inline-flex items-center gap-2 text-biker font-bold group-hover:translate-x-2 transition-transform relative z-10"
className="inline-flex items-center gap-2 text-white bg-biker px-6 py-3 rounded-full font-bold shadow-lg shadow-biker/30 hover:bg-biker/90 hover:shadow-biker/50 transition-all relative z-10 w-fit"
>
Login as Biker <ChevronRight className="w-5 h-5" />
</button>
</div>
{/* Service 2 */}
{/* Service 2 - FICO Partners - User will redesign this section */}
{/*
<div className="group bg-white rounded-3xl p-8 shadow-sm hover:shadow-2xl transition-all duration-300 border border-slate-100 relative overflow-hidden flex flex-col h-full">
<div className="absolute top-0 right-0 w-32 h-32 bg-investor/10 rounded-bl-full -mr-8 -mt-8 transition-transform group-hover:scale-110"></div>
<div className="w-16 h-16 bg-investor/10 rounded-2xl flex items-center justify-center mb-6 relative z-10 text-investor group-hover:bg-investor group-hover:text-white transition-colors">
<Wallet className="w-8 h-8" />
</div>
<h4 className="text-2xl font-bold text-slate-900 mb-3 relative z-10">FICO Investment</h4>
<p className="text-slate-600 mb-8 flex-grow relative z-10">Invest in fractional EV ownership. Let us manage the fleet while you enjoy guaranteed monthly returns.</p>
{/* <button
onClick={() => handleLogin('investor@email.com')}
disabled={loading}
className="inline-flex items-center gap-2 text-investor font-bold group-hover:translate-x-2 transition-transform relative z-10"
>
Login as Investor <ChevronRight className="w-5 h-5" />
</button> */}
...
</div>
*/}
{/* Service 3 */}
<div className="group bg-white rounded-3xl p-8 shadow-sm hover:shadow-2xl transition-all duration-300 border border-slate-100 relative overflow-hidden flex flex-col h-full">
<div className="absolute top-0 right-0 w-32 h-32 bg-purple-500/10 rounded-bl-full -mr-8 -mt-8 transition-transform group-hover:scale-110"></div>
<div className="w-16 h-16 bg-purple-500/10 rounded-2xl flex items-center justify-center mb-6 relative z-10 text-purple-500 group-hover:bg-purple-500 group-hover:text-white transition-colors">
<Zap className="w-8 h-8" />
<div className="group bg-white rounded-3xl p-8 shadow-lg hover:shadow-[0_20px_50px_rgba(0,0,0,0.1)] transition-all duration-500 border border-slate-100 relative overflow-hidden flex flex-col h-full transform hover:-translate-y-2">
<div className="absolute top-0 right-0 w-64 h-64 bg-gradient-to-bl from-purple-500/10 to-transparent rounded-full blur-3xl -mr-16 -mt-16 transition-transform duration-700 group-hover:scale-150"></div>
<div className="w-24 h-24 bg-gradient-to-br from-white to-slate-50 shadow-inner rounded-2xl flex items-center justify-center mb-8 relative z-10 border border-slate-100/50">
<CardIcon3D type="swap" />
</div>
<h4 className="text-2xl font-bold text-slate-900 mb-3 relative z-10">Swap Stations</h4>
<p className="text-slate-600 mb-8 flex-grow relative z-10">Never wait to charge. Swap your depleted battery for a fully charged one in less than 2 minutes.</p>
<h4 className="text-2xl font-extrabold text-slate-900 mb-4 relative z-10">Swap Stations</h4>
<p className="text-slate-600 mb-8 flex-grow relative z-10 leading-relaxed">Never wait hours to charge your bike. Find a swap station near you, drop off your empty battery, and get a full one in under 2 minutes so you can keep riding.</p>
<button
onClick={() => router.push('/coming-soon')}
disabled={loading}
className="inline-flex items-center gap-2 text-purple-600 font-bold group-hover:translate-x-2 transition-transform relative z-10"
className="inline-flex items-center gap-2 text-white bg-purple-600 px-6 py-3 rounded-full font-bold shadow-lg shadow-purple-600/30 hover:bg-purple-700 hover:shadow-purple-600/50 transition-all relative z-10 w-fit"
>
Login as Swap Station <ChevronRight className="w-5 h-5" />
</button>
</div>
{/* Service 4 (Merchant/Rent to own) */}
<div className="group bg-white rounded-3xl p-8 shadow-sm hover:shadow-2xl transition-all duration-300 border border-slate-100 relative overflow-hidden flex flex-col h-full md:col-span-2 lg:col-span-3 lg:w-2/3 lg:mx-auto">
<div className="absolute top-0 right-0 w-32 h-32 bg-accent/10 rounded-bl-full -mr-8 -mt-8 transition-transform group-hover:scale-110"></div>
<div className="flex flex-col sm:flex-row gap-6 relative z-10">
<div className="w-16 h-16 shrink-0 bg-accent/10 rounded-2xl flex items-center justify-center text-accent group-hover:bg-accent group-hover:text-white transition-colors">
<Truck className="w-8 h-8" />
</div>
<div>
<h4 className="text-2xl font-bold text-slate-900 mb-3">Merchants & Deliveries</h4>
<p className="text-slate-600 mb-6 max-w-xl">Are you a delivery partner or company? Request any amount of riders for your delivery needs. Partner with us for dedicated EV riders.</p>
<button
onClick={() => router.push('/coming-soon')}
className="inline-flex items-center gap-2 text-accent font-bold group-hover:translate-x-2 transition-transform"
>
Partner With Us <ChevronRight className="w-5 h-5" />
</button>
</div>
{/* Service 3 (Merchant/Deliveries) */}
<div className="group bg-white rounded-3xl p-8 shadow-lg hover:shadow-[0_20px_50px_rgba(0,0,0,0.1)] transition-all duration-500 border border-slate-100 relative overflow-hidden flex flex-col h-full transform hover:-translate-y-2">
<div className="absolute top-0 right-0 w-64 h-64 bg-gradient-to-bl from-accent/10 to-transparent rounded-full blur-3xl -mr-16 -mt-16 transition-transform duration-700 group-hover:scale-150"></div>
<div className="w-24 h-24 bg-gradient-to-br from-white to-slate-50 shadow-inner rounded-2xl flex items-center justify-center mb-8 relative z-10 border border-slate-100/50">
<CardIcon3D type="merchant" />
</div>
<h4 className="text-2xl font-extrabold text-slate-900 mb-4 relative z-10">Merchants & Deliveries</h4>
<p className="text-slate-600 mb-8 flex-grow relative z-10 leading-relaxed">Grow your delivery business with ease. Request verified EV riders whenever you need them, deliver more orders smoothly, and help keep the environment green.</p>
<button
onClick={() => router.push('/coming-soon')}
className="inline-flex items-center gap-2 text-white bg-accent px-6 py-3 rounded-full font-bold shadow-lg shadow-accent/30 hover:bg-accent-dark hover:shadow-accent/50 transition-all relative z-10 w-fit"
>
Partner With Us <ChevronRight className="w-5 h-5" />
</button>
</div>
</div>
</div>
@@ -295,7 +303,7 @@ export default function LandingPage() {
<div className="absolute -top-2 -right-2 w-8 h-8 bg-accent rounded-full flex items-center justify-center font-bold text-sm">2</div>
</div>
<h4 className="text-xl font-bold mb-3">Choose Your Plan</h4>
<p className="text-slate-400">Select your EV model and subscription plan (Daily, Weekly, or Rent-to-Own).</p>
<p className="text-slate-400">Select your EV model and preferred plan (Single Rent, Rent to Own, or Share an EV).</p>
</div>
<div className="relative text-center">
@@ -319,6 +327,91 @@ export default function LandingPage() {
</div>
</section>
{/* Download App Section */}
<section className="py-20 bg-accent relative overflow-hidden">
<div className="absolute inset-0 bg-[url('/noise.png')] opacity-10 mix-blend-overlay"></div>
{/* Background decorative circles */}
<div className="absolute top-0 right-0 w-96 h-96 bg-white/10 rounded-full blur-3xl -mr-20 -mt-20"></div>
<div className="absolute bottom-0 left-0 w-64 h-64 bg-emerald-900/30 rounded-full blur-3xl -ml-20 -mb-20"></div>
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10 flex flex-col md:flex-row items-center justify-between gap-12">
<div className="w-full md:w-1/2 text-center md:text-left text-white">
<h2 className="text-3xl md:text-5xl font-extrabold mb-6 leading-tight drop-shadow-sm">Ready to ride? <br />Download the JAIBEN App</h2>
<p className="text-white/90 text-lg mb-8 max-w-lg mx-auto md:mx-0 drop-shadow-sm">Get full access to biker rentals, swap station locations, and real-time earnings directly from your smartphone.</p>
<div className="flex flex-col sm:flex-row items-center justify-center md:justify-start gap-4">
<button
onClick={() => router.push('/coming-soon')}
className="flex items-center gap-3 bg-black text-white px-6 py-3 rounded-xl hover:bg-slate-900 hover:scale-105 transition-all shadow-xl shadow-black/20 w-full sm:w-auto justify-center"
>
<svg viewBox="0 0 512 512" className="w-6 h-6 fill-current"><path d="M325.3 234.3L104.6 13l280.8 161.2-60.1 60.1zM47 0C34 6.8 25.3 19.2 25.3 35.3v441.3c0 16.1 8.7 28.5 21.7 35.3l256.6-256L47 0zm425.2 225.6l-58.9-34.1-65.7 64.5 65.7 64.5 60.1-34.1c18-14.3 18-46.5-1.2-60.8zM104.6 499l280.8-161.2-60.1-60.1L104.6 499z" /></svg>
<div className="flex flex-col text-left">
<span className="text-[10px] leading-none text-slate-300 font-semibold">GET IT ON</span>
<span className="text-lg font-bold leading-none mt-1">Google Play</span>
</div>
</button>
<button
onClick={() => router.push('/coming-soon')}
className="flex items-center gap-3 bg-black text-white px-6 py-3 rounded-xl hover:bg-slate-900 hover:scale-105 transition-all shadow-xl shadow-black/20 w-full sm:w-auto justify-center"
>
<svg viewBox="0 0 384 512" className="w-6 h-6 fill-current"><path d="M318.7 268.7c-.2-36.7 16.4-64.4 50-84.8-18.8-26.9-47.2-41.7-84.7-44.6-35.5-2.8-74.3 20.7-88.5 20.7-15 0-49.4-19.7-76.4-19.7C63.3 141.2 4 184.8 4 273.5q0 39.3 14.4 81.2c12.8 36.7 59 126.7 107.2 125.2 25.2-.6 43-17.9 75.8-17.9 31.8 0 48.3 17.9 76.4 17.9 48.6-.7 90.4-82.5 102.6-119.3-65.2-30.7-61.7-90-61.7-91.9zm-56.6-164.2c27.3-32.4 24.8-61.9 24-72.5-24.1 1.4-52 16.4-67.9 34.9-17.5 19.8-27.8 44.3-25.6 71.9 26.1 2 49.9-11.4 69.5-34.3z" /></svg>
<div className="flex flex-col text-left">
<span className="text-[10px] leading-none text-slate-300 font-semibold">Download on the</span>
<span className="text-lg font-bold leading-none mt-1">App Store</span>
</div>
</button>
</div>
</div>
<div className="w-full md:w-1/2 flex justify-center">
{/* Abstract Phone Mockup */}
<div className="w-64 h-[450px] bg-slate-900 rounded-[3rem] border-[8px] border-slate-800 shadow-[0_30px_60px_rgba(0,0,0,0.4)] relative overflow-hidden flex flex-col -mb-32 md:-mb-40 transform rotate-12 hover:rotate-6 transition-transform duration-500">
<div className="h-6 w-1/2 bg-slate-800 absolute top-0 left-1/2 -translate-x-1/2 rounded-b-xl z-20"></div>
<div className="flex-1 bg-slate-50 p-4 pt-12 relative flex flex-col gap-4">
{/* Mock App Header */}
<div className="flex justify-between items-center">
<div className="w-10 h-10 bg-accent rounded-full flex items-center justify-center">
<Image src="/jaiben.png" alt="Logo" width={24} height={24} className="brightness-0 invert" />
</div>
<div className="w-8 h-8 bg-slate-200 rounded-full"></div>
</div>
{/* Mock App Banner */}
<div className="w-full h-32 bg-gradient-to-br from-accent to-emerald-700 rounded-2xl p-4 shadow-sm relative overflow-hidden">
<div className="w-32 h-32 bg-white/10 rounded-full absolute -right-10 -bottom-10 blur-xl"></div>
<div className="w-1/2 h-3 bg-white/40 rounded-full mb-2 relative z-10"></div>
<div className="w-1/3 h-3 bg-white/20 rounded-full relative z-10"></div>
</div>
{/* Mock App Grid */}
<div className="grid grid-cols-2 gap-3 flex-grow">
<div className="bg-white rounded-xl shadow-sm border border-slate-100 p-3 flex flex-col gap-2">
<div className="w-8 h-8 bg-orange-100 rounded-lg"></div>
<div className="w-full h-2 bg-slate-200 rounded-full"></div>
<div className="w-1/2 h-2 bg-slate-100 rounded-full"></div>
</div>
<div className="bg-white rounded-xl shadow-sm border border-slate-100 p-3 flex flex-col gap-2">
<div className="w-8 h-8 bg-purple-100 rounded-lg"></div>
<div className="w-full h-2 bg-slate-200 rounded-full"></div>
<div className="w-1/2 h-2 bg-slate-100 rounded-full"></div>
</div>
<div className="bg-white rounded-xl shadow-sm border border-slate-100 p-3 flex flex-col gap-2">
<div className="w-8 h-8 bg-blue-100 rounded-lg"></div>
<div className="w-full h-2 bg-slate-200 rounded-full"></div>
<div className="w-1/2 h-2 bg-slate-100 rounded-full"></div>
</div>
<div className="bg-white rounded-xl shadow-sm border border-slate-100 p-3 flex flex-col gap-2">
<div className="w-8 h-8 bg-emerald-100 rounded-lg"></div>
<div className="w-full h-2 bg-slate-200 rounded-full"></div>
<div className="w-1/2 h-2 bg-slate-100 rounded-full"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
{/* Footer */}
<footer className="bg-slate-950 pt-20 pb-10 border-t border-slate-800">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
@@ -345,9 +438,9 @@ export default function LandingPage() {
<div>
<h4 className="text-white font-bold mb-6">Services</h4>
<ul className="space-y-3 text-slate-400">
<li><button onClick={() => router.push('/coming-soon')} className="hover:text-accent transition-colors">EV for Deliveries</button></li>
<li><button onClick={() => router.push('/coming-soon')} className="hover:text-accent transition-colors">Single Rent</button></li>
<li><button onClick={() => router.push('/coming-soon')} className="hover:text-accent transition-colors">Rent to Own</button></li>
<li><button onClick={() => router.push('/coming-soon')} className="hover:text-accent transition-colors">Investor Platform</button></li>
<li><button onClick={() => router.push('/coming-soon')} className="hover:text-accent transition-colors">Share an EV</button></li>
<li><button onClick={() => router.push('/coming-soon')} className="hover:text-accent transition-colors">Swap Stations</button></li>
</ul>
</div>
@@ -364,8 +457,8 @@ export default function LandingPage() {
</div>
<div className="border-t border-slate-800 pt-8 flex flex-col md:flex-row justify-between items-center gap-4">
<p className="text-slate-500 text-sm">
&copy; {new Date().getFullYear()} JAIBEN Mobility Ltd. All rights reserved.
<p className="text-slate-500 text-sm text-center md:text-left">
&copy; {new Date().getFullYear()} JAIBEN Mobility Ltd. All rights reserved. <span className="hidden md:inline">|</span><br className="md:hidden" /> Developed by <a href="https://forenizence.com/" target="_blank" rel="noopener noreferrer" className="hover:text-accent transition-colors font-medium">Forenizence</a>
</p>
<div className="flex gap-6 text-sm text-slate-500">
<a href="#" className="hover:text-white transition-colors">Privacy Policy</a>

View File

@@ -3,20 +3,56 @@ import { useRef } from 'react';
import { Canvas, useFrame } from '@react-three/fiber';
import { Float, Torus, Cylinder, Box, Octahedron, MeshTransmissionMaterial } from '@react-three/drei';
import * as THREE from 'three';
import { useLoader } from '@react-three/fiber';
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader.js';
import { Suspense, useMemo } from 'react';
function ActualBikeIcon() {
const obj = useLoader(OBJLoader, '/uploads_files_3634924_uploads_files_850048_aerox.obj');
const group = useRef<THREE.Group>(null);
const model = useMemo(() => {
const clone = obj.clone();
const box = new THREE.Box3().setFromObject(clone);
const center = box.getCenter(new THREE.Vector3());
const size = box.getSize(new THREE.Vector3());
const maxDim = Math.max(size.x, size.y, size.z);
const scale = 2.0 / maxDim;
clone.scale.setScalar(scale);
clone.position.sub(center.multiplyScalar(scale));
clone.rotation.y = -Math.PI / 4;
const bodyMat = new THREE.MeshStandardMaterial({ color: '#00bc84', roughness: 0.2, metalness: 0.8 });
const darkMat = new THREE.MeshStandardMaterial({ color: '#111111', roughness: 0.9 });
clone.traverse((child) => {
if (child instanceof THREE.Mesh) {
const b = new THREE.Box3().setFromObject(child);
const s = new THREE.Vector3();
b.getSize(s);
const minLocal = Math.min(s.x, s.y, s.z);
const maxLocal = Math.max(s.x, s.y, s.z);
if (minLocal < 0.3 && maxLocal > 0.4) child.material = darkMat;
else child.material = bodyMat;
}
});
return clone;
}, [obj]);
function BikeIcon() {
const mesh = useRef<THREE.Mesh>(null);
useFrame((_, delta) => {
if (mesh.current) {
mesh.current.rotation.y += delta;
mesh.current.rotation.x += delta * 0.5;
if (group.current) {
group.current.rotation.y += delta * 1.5;
}
});
return (
<Float floatIntensity={2} speed={2}>
<Torus ref={mesh} args={[1.2, 0.4, 16, 32]} rotation={[Math.PI / 2, 0, 0]}>
<meshStandardMaterial color="#f97316" roughness={0.1} metalness={0.8} />
</Torus>
<Float floatIntensity={1.5} speed={2}>
<group ref={group}>
<primitive object={model} />
</group>
</Float>
);
}
@@ -38,44 +74,68 @@ function InvestorIcon() {
}
function SwapIcon() {
const mesh = useRef<THREE.Mesh>(null);
const group = useRef<THREE.Group>(null);
useFrame((_, delta) => {
if (mesh.current) {
mesh.current.rotation.x += delta;
mesh.current.rotation.y += delta * 1.2;
if (group.current) {
group.current.rotation.y += delta * 1.2;
}
});
return (
<Float floatIntensity={2} speed={2}>
<Box ref={mesh} args={[1.5, 1.5, 1.5]}>
<MeshTransmissionMaterial
color="#a855f7"
thickness={0.5}
roughness={0.1}
transmission={0.9}
ior={1.5}
/>
</Box>
<Box args={[0.8, 0.8, 0.8]}>
<meshStandardMaterial color="#d8b4fe" emissive="#a855f7" emissiveIntensity={0.5} />
</Box>
<Float floatIntensity={1.5} speed={2}>
<group ref={group} scale={0.7} position={[0, -0.8, 0]}>
{/* Main Station Body */}
<Box args={[1.4, 2.8, 1]} position={[0, 1.4, 0]}>
<meshStandardMaterial color="#e2e8f0" roughness={0.2} metalness={0.8} />
</Box>
{/* Glowing Screen */}
<Box args={[0.9, 0.5, 0.1]} position={[0, 2.2, 0.51]}>
<meshStandardMaterial color="#d8b4fe" emissive="#a855f7" emissiveIntensity={0.8} />
</Box>
{/* Battery Slots Container */}
<Box args={[1.2, 1.2, 0.2]} position={[0, 1.0, 0.45]}>
<meshStandardMaterial color="#1e293b" />
</Box>
{/* Battery 1 inside slot */}
<Box args={[0.3, 0.6, 0.2]} position={[-0.3, 1.2, 0.5]}>
<meshStandardMaterial color="#a855f7" />
</Box>
{/* Battery 2 inside slot */}
<Box args={[0.3, 0.6, 0.2]} position={[0.3, 0.8, 0.5]}>
<meshStandardMaterial color="#a855f7" />
</Box>
</group>
</Float>
);
}
function MerchantIcon() {
const mesh = useRef<THREE.Mesh>(null);
const group = useRef<THREE.Group>(null);
useFrame((_, delta) => {
if (mesh.current) {
mesh.current.rotation.x += delta * 0.5;
mesh.current.rotation.y += delta;
if (group.current) {
group.current.rotation.y += delta * 1.2;
group.current.rotation.z = Math.sin(_.clock.elapsedTime * 3) * 0.05;
}
});
return (
<Float floatIntensity={2} speed={2}>
<Octahedron ref={mesh} args={[1.5]}>
<meshStandardMaterial color="#00bc84" roughness={0.1} metalness={0.7} />
</Octahedron>
<Float floatIntensity={2} speed={2.5}>
<group ref={group} scale={0.9}>
{/* Main Cargo Box */}
<Box args={[1.4, 1.4, 1.4]}>
<meshStandardMaterial color="#fcd34d" roughness={0.8} />
</Box>
{/* Tape / Ribbon 1 */}
<Box args={[1.42, 0.15, 1.42]} position={[0, 0, 0]}>
<meshStandardMaterial color="#00bc84" roughness={0.3} />
</Box>
{/* Tape / Ribbon 2 */}
<Box args={[1.42, 1.42, 0.15]} position={[0, 0, 0]}>
<meshStandardMaterial color="#00bc84" roughness={0.3} />
</Box>
{/* Delivery Logo / Detail */}
<Box args={[0.5, 0.5, 0.05]} position={[0, 0.3, 0.71]}>
<meshStandardMaterial color="#ffffff" emissive="#00bc84" emissiveIntensity={0.3} />
</Box>
</group>
</Float>
);
}
@@ -87,7 +147,9 @@ export default function CardIcon3D({ type }: { type: 'bike' | 'investor' | 'swap
<ambientLight intensity={0.5} />
<directionalLight position={[5, 5, 5]} intensity={1} />
<pointLight position={[-5, -5, -5]} intensity={0.5} />
{type === 'bike' && <BikeIcon />}
<Suspense fallback={null}>
{type === 'bike' && <ActualBikeIcon />}
</Suspense>
{type === 'investor' && <InvestorIcon />}
{type === 'swap' && <SwapIcon />}
{type === 'merchant' && <MerchantIcon />}

View File

@@ -1,7 +1,7 @@
'use client';
import { Suspense, useMemo, useRef } from 'react';
import { Canvas, useFrame, useLoader } from '@react-three/fiber';
import { Canvas, useFrame, useLoader, useThree } from '@react-three/fiber';
import {
Float,
ContactShadows,
@@ -14,6 +14,9 @@ import {
import * as THREE from 'three';
import { OBJLoader } from 'three-stdlib';
useLoader.preload(OBJLoader, '/aerox.obj');
useLoader.preload(THREE.TextureLoader, '/jaiben.png');
const ACCENT = '#00bc84';
const ACCENT_BRIGHT = '#10b981';
@@ -85,37 +88,80 @@ function AeroxModel() {
return clone;
}, [obj]);
const { size } = useThree();
const isMobile = size.width < 1024;
const targetX = isMobile ? 0 : 2.5;
useFrame((state) => {
if (!group.current) return;
const t = state.clock.elapsedTime;
// Continuous turntable so all sides are appreciated.
group.current.rotation.y = t * 0.4;
group.current.position.y = Math.sin(t * 1.5) * 0.08;
// Smoothly animate position X to be responsive
group.current.position.x += (targetX - group.current.position.x) * 0.1;
});
return (
<Float speed={1.2} rotationIntensity={0.1} floatIntensity={0.3}>
<group ref={group} rotation={[0, -0.5, 0]} position={[2.5, -0.1, -1]}>
<group ref={group} rotation={[0, -0.5, 0]} position={[isMobile ? 0 : 2.5, -0.1, -1]}>
<primitive object={model} />
</group>
</Float>
);
}
function Crystal({ position, color, scale = 1 }: { position: [number, number, number]; color: string; scale?: number }) {
const ref = useRef<THREE.Mesh>(null);
function Battery({ position, scale = 1, rotation = [0, 0, 0] }: { position: [number, number, number]; scale?: number; rotation?: [number, number, number] }) {
const group = useRef<THREE.Group>(null);
const logoTexture = useLoader(THREE.TextureLoader, '/jaiben.png');
useFrame((state, delta) => {
if (ref.current) {
ref.current.rotation.y += delta * 0.5;
ref.current.position.y = position[1] + Math.sin(state.clock.elapsedTime + position[0]) * 0.3;
if (group.current) {
group.current.rotation.y += delta * 0.4;
group.current.position.y = position[1] + Math.sin(state.clock.elapsedTime + position[0]) * 0.2;
}
});
return (
<Float speed={3} rotationIntensity={1} floatIntensity={2}>
<mesh ref={ref} position={position} scale={scale}>
<octahedronGeometry args={[0.4, 0]} />
<meshStandardMaterial color={color} emissive={color} emissiveIntensity={0.3} roughness={0.1} metalness={0.3} flatShading />
</mesh>
<Float speed={2} rotationIntensity={0.5} floatIntensity={1}>
<group ref={group} position={position} scale={scale} rotation={new THREE.Euler(...rotation)}>
{/* Main Battery Body */}
<mesh position={[0, 0, 0]} castShadow receiveShadow>
<boxGeometry args={[0.6, 1.2, 0.4]} />
<meshStandardMaterial color="#1e293b" roughness={0.4} metalness={0.8} />
</mesh>
{/* Top Cap */}
<mesh position={[0, 0.65, 0]} castShadow receiveShadow>
<boxGeometry args={[0.62, 0.1, 0.42]} />
<meshStandardMaterial color={ACCENT} roughness={0.3} metalness={0.5} />
</mesh>
{/* Handle */}
<mesh position={[0, 0.70, 0]} castShadow receiveShadow>
<torusGeometry args={[0.15, 0.04, 16, 32, Math.PI]} />
<meshStandardMaterial color="#0d7a33" roughness={0.2} metalness={0.9} />
</mesh>
{/* Glowing Indicator Light */}
<mesh position={[0.2, 0.5, 0.201]}>
<circleGeometry args={[0.03, 16]} />
<meshBasicMaterial color={ACCENT_BRIGHT} />
</mesh>
{/* Logo Decal Plane */}
<mesh position={[0, 0, 0.201]}>
<planeGeometry args={[0.35, 0.35]} />
<meshBasicMaterial map={logoTexture} transparent={true} />
</mesh>
{/* Back Logo Decal Plane */}
<mesh position={[0, 0, -0.201]} rotation={[0, Math.PI, 0]}>
<planeGeometry args={[0.35, 0.35]} />
<meshBasicMaterial map={logoTexture} transparent={true} />
</mesh>
</group>
</Float>
);
}
@@ -140,13 +186,12 @@ function Scene() {
<Suspense fallback={<Loader />}>
<AeroxModel />
<Battery position={[-3.8, 1.6, -1]} scale={1.1} />
<Battery position={[3.8, 1.2, -0.5]} scale={0.8} rotation={[0.2, 0, 0]} />
<Battery position={[3.4, -0.8, 0.6]} scale={0.6} rotation={[-0.2, 0.5, 0]} />
<Battery position={[-4.0, -0.4, 0.8]} scale={0.7} rotation={[0, -0.5, 0.1]} />
</Suspense>
<Crystal position={[-3.8, 1.6, -1]} color={ACCENT_BRIGHT} scale={1.1} />
<Crystal position={[3.8, 1.2, -0.5]} color={ACCENT} scale={0.8} />
<Crystal position={[3.4, -0.8, 0.6]} color="#34d399" scale={0.6} />
<Crystal position={[-4.0, -0.4, 0.8]} color="#34d399" scale={0.7} />
<Sparkles count={90} scale={[11, 7, 7]} size={3} speed={0.4} color={ACCENT_BRIGHT} opacity={0.7} />
<ContactShadows position={[0, -1.06, 0]} opacity={0.55} scale={14} blur={2.5} far={4} color={ACCENT} />

View File

@@ -0,0 +1,45 @@
'use client';
import { useState, useEffect, useRef } from 'react';
export default function AnimatedCounter({ end, duration = 2000, suffix = "" }: { end: number, duration?: number, suffix?: string }) {
const [count, setCount] = useState(0);
const [hasStarted, setHasStarted] = useState(false);
const elementRef = useRef<HTMLSpanElement>(null);
useEffect(() => {
const observer = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting && !hasStarted) {
setHasStarted(true);
}
});
if (elementRef.current) {
observer.observe(elementRef.current);
}
return () => observer.disconnect();
}, [hasStarted]);
useEffect(() => {
if (!hasStarted) return;
let startTime: number | null = null;
const animate = (currentTime: number) => {
if (!startTime) startTime = currentTime;
const progress = Math.min((currentTime - startTime) / duration, 1);
// Ease out cubic function for smooth deceleration
const easeOut = 1 - Math.pow(1 - progress, 3);
const currentCount = Math.floor(easeOut * end);
setCount(currentCount);
if (progress < 1) {
requestAnimationFrame(animate);
}
};
requestAnimationFrame(animate);
}, [end, duration, hasStarted]);
return <span ref={elementRef}>{count}{suffix}</span>;
}

View File

@@ -0,0 +1,69 @@
'use client';
import Image from 'next/image';
import { useState, useEffect } from 'react';
import { X } from 'lucide-react';
export default function WhatsAppFloat() {
const [showTooltip, setShowTooltip] = useState(false);
useEffect(() => {
// Show the tooltip after 3 seconds for better engagement
const timer = setTimeout(() => {
setShowTooltip(true);
}, 3000);
return () => clearTimeout(timer);
}, []);
return (
<div className="fixed bottom-6 right-6 z-50 flex flex-col items-end">
{/* Tooltip Bubble */}
<div
className={`bg-white text-slate-800 p-4 rounded-2xl shadow-[0_10px_40px_rgba(0,0,0,0.15)] mb-4 max-w-[260px] relative origin-bottom-right transition-all duration-500 border border-slate-100 ${
showTooltip ? 'scale-100 opacity-100 translate-y-0' : 'scale-50 opacity-0 translate-y-10 pointer-events-none'
}`}
>
<button
onClick={() => setShowTooltip(false)}
className="absolute top-2 right-2 text-slate-400 hover:text-slate-600 transition-colors"
>
<X className="w-4 h-4" />
</button>
<div className="flex gap-3 items-start">
<div className="w-10 h-10 rounded-full bg-accent/10 flex-shrink-0 flex items-center justify-center p-2 mt-1 shadow-inner">
<Image src="/jaiben.png" alt="JAIBEN Logo" width={24} height={24} className="object-contain" />
</div>
<div>
<h4 className="font-bold text-sm text-slate-900 mb-1">JAIBEN Support</h4>
<p className="text-xs text-slate-600 leading-relaxed">Hi there! 👋 Have questions about EV rentals or partnerships? Send us a message!</p>
</div>
</div>
{/* Triangle pointer */}
<div className="absolute -bottom-2 right-6 w-4 h-4 bg-white border-b border-r border-slate-100 transform rotate-45"></div>
</div>
{/* Floating Button */}
<a
href="https://wa.me/8801789822502?text=Hi%20Jaiben%20Team!%20%F0%9F%91%8B"
target="_blank"
rel="noopener noreferrer"
className="w-16 h-16 bg-[#25D366] hover:bg-[#20bd5a] text-white rounded-full flex items-center justify-center shadow-lg hover:shadow-2xl transition-all duration-300 hover:-translate-y-1 relative group"
onMouseEnter={() => setShowTooltip(true)}
>
{/* Pulsing ring */}
<span className="absolute inset-0 rounded-full border-2 border-[#25D366] animate-ping opacity-50"></span>
{/* Inside icon - JAIBEN logo instead of standard whatsapp logo */}
<div className="w-12 h-12 bg-white rounded-full flex items-center justify-center p-2 shadow-inner relative z-10 transform group-hover:scale-95 transition-transform">
<Image src="/jaiben.png" alt="JAIBEN Logo" width={28} height={28} className="object-contain" />
</div>
{/* Tiny whatsapp badge to show it's whatsapp */}
<div className="absolute -top-1 -right-1 w-7 h-7 bg-white rounded-full flex items-center justify-center shadow-md z-20 border border-slate-100">
<svg viewBox="0 0 24 24" className="w-5 h-5 fill-[#25D366]">
<path d="M12.031 6.172c-3.181 0-5.767 2.586-5.768 5.766-.001 1.298.38 2.27 1.019 3.287l-.582 2.128 2.182-.573c.978.58 1.911.928 3.145.929 3.178 0 5.767-2.587 5.768-5.766.001-3.187-2.575-5.77-5.764-5.771zm3.392 8.244c-.144.405-.837.774-1.17.824-.299.045-.677.063-1.092-.069-.252-.08-.575-.187-.988-.365-1.739-.751-2.874-2.502-2.961-2.617-.087-.116-.708-.94-.708-1.793s.448-1.273.607-1.446c.159-.173.346-.217.462-.217l.332.006c.106.005.249-.04.39.298.144.347.491 1.2.534 1.287.043.087.072.188.014.304-.058.116-.087.188-.173.289l-.26.304c-.087.086-.177.18-.076.354.101.174.449.741.964 1.201.662.591 1.221.774 1.394.86s.274.072.376-.043c.101-.116.433-.506.549-.68.116-.173.231-.145.39-.087s1.011.477 1.184.564.289.13.332.202c.045.072.045.419-.1.824zm-3.423-14.416c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm.029 18.88c-1.161 0-2.305-.292-3.318-.844l-3.677.964.984-3.595c-.607-1.052-.927-2.246-.926-3.468.001-3.825 3.113-6.937 6.937-6.937 3.825.001 6.938 3.113 6.938 6.935.002 3.821-3.11 6.945-6.938 6.945z"/>
</svg>
</div>
</a>
</div>
);
}

BIN
zivrehiG Normal file

Binary file not shown.