Initial commit

This commit is contained in:
r2xrzh9q2z-lab
2026-02-02 11:00:08 +07:00
commit d53d4417b2
116 changed files with 79533 additions and 0 deletions
+44
View File
@@ -0,0 +1,44 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/versions
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*
# env files (can opt-in for committing if needed)
.env*
# vercel
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts
#vs code
/.vscode
View File
+218
View File
@@ -0,0 +1,218 @@
# VisaService - Website Dịch Vụ Visa
Website dịch vụ visa chuyên nghiệp được xây dựng với Next.js 15, TypeScript và Tailwind CSS. Hỗ trợ tư vấn visa cho hơn 50 quốc gia với tỷ lệ thành công 99%.
## 🚀 Tính Năng
- **8 Trang Chính**: Trang chủ, Giới thiệu, Dịch vụ, Visa, Quốc gia, Bảng giá, Blog, Liên hệ
- **Hệ Thống Đặt Lịch**: Đặt lịch tư vấn với chuyên gia
- **Responsive Design**: Tối ưu cho mọi thiết bị
- **JSON-Based Content**: Dễ dàng quản lý nội dung
- **Interactive Components**: Form, accordion, filter, modal
- **SEO Optimized**: Metadata và structure tối ưu
## 🛠️ Công Nghệ Sử Dụng
- **Framework**: Next.js 15 (App Router)
- **Language**: TypeScript
- **Styling**: Tailwind CSS
- **Icons**: Emoji icons
- **Deployment**: Docker support
## 📁 Cấu Trúc Thư Mục
```
app/
├── components/ # Shared components
│ ├── Header.tsx # Navigation header
│ └── Footer.tsx # Site footer
├── about/ # Trang giới thiệu
│ ├── about.json # Dữ liệu về công ty
│ └── page.tsx # Component trang
├── services/ # Trang dịch vụ
│ ├── services.json # Dữ liệu dịch vụ
│ └── page.tsx # Component trang
├── visa/ # Trang visa
│ ├── visa.json # Dữ liệu các loại visa
│ └── page.tsx # Component trang
├── countries/ # Trang quốc gia
│ ├── countries.json # Dữ liệu quốc gia
│ └── page.tsx # Component trang
├── pricing/ # Trang bảng giá
│ ├── pricing.json # Dữ liệu giá cả
│ └── page.tsx # Component trang
├── blog/ # Trang blog
│ ├── blog.json # Dữ liệu bài viết
│ └── page.tsx # Component trang
├── contact/ # Trang liên hệ
│ ├── contact.json # Thông tin liên hệ
│ └── page.tsx # Component trang
├── appointment/ # Trang đặt lịch
│ ├── appointment.json # Dữ liệu booking
│ └── page.tsx # Component trang
├── layout.tsx # Root layout
├── page.tsx # Trang chủ
└── globals.css # Global styles
```
## 🚀 Hướng Dẫn Chạy Dự Án
### Yêu Cầu Hệ Thống
- Node.js 18+
- npm, yarn, hoặc pnpm
### Cài Đặt và Chạy
1. **Clone repository**
```bash
git clone <repository-url>
cd visa-service-website
```
2. **Cài đặt dependencies**
```bash
npm install
# hoặc
yarn install
# hoặc
pnpm install
```
3. **Chạy development server**
```bash
npm run dev
# hoặc
yarn dev
# hoặc
pnpm dev
```
4. **Mở trình duyệt**
Truy cập [http://localhost:3000](http://localhost:3000) để xem website
### Scripts Có Sẵn
```bash
npm run dev # Chạy development server
npm run build # Build production
npm run start # Chạy production server
npm run lint # Kiểm tra code style
```
## 🐳 Chạy Với Docker
### Development với Docker
```bash
# Build và chạy container
docker-compose up --build
# Chạy ở background
docker-compose up -d
# Dừng container
docker-compose down
```
### Production với Docker
```bash
# Build production image
docker build -t visa-service .
# Chạy container
docker run -p 3000:3000 visa-service
```
## 📝 Tùy Chỉnh Nội Dung
### Cập Nhật Dữ Liệu
Mỗi trang có file JSON riêng chứa dữ liệu:
- `about/about.json` - Thông tin công ty
- `services/services.json` - Danh sách dịch vụ
- `visa/visa.json` - Các loại visa
- `countries/countries.json` - Quốc gia hỗ trợ
- `pricing/pricing.json` - Bảng giá dịch vụ
- `blog/blog.json` - Bài viết blog
- `contact/contact.json` - Thông tin liên hệ
- `appointment/appointment.json` - Cấu hình đặt lịch
### Thêm Trang Mới
1. Tạo thư mục mới trong `app/`
2. Tạo file `data.json` chứa dữ liệu
3. Tạo file `page.tsx` với React component
4. Cập nhật navigation trong `Header.tsx`
### Tùy Chỉnh Styling
- Sử dụng Tailwind CSS classes
- Tùy chỉnh theme trong `tailwind.config.js`
- Global styles trong `app/globals.css`
## 🌐 Deployment
### Vercel (Khuyến nghị)
1. Push code lên GitHub
2. Kết nối repository với Vercel
3. Deploy tự động
### Netlify
1. Build project: `npm run build`
2. Upload thư mục `out/` lên Netlify
### VPS/Server
1. Build project: `npm run build`
2. Chạy: `npm run start`
3. Sử dụng PM2 hoặc Docker cho production
## 📱 Responsive Design
Website được tối ưu cho:
- **Mobile**: < 768px
- **Tablet**: 768px - 1024px
- **Desktop**: > 1024px
## 🔧 Cấu Hình Môi Trường
Tạo file `.env.local` (tùy chọn):
```env
NEXT_PUBLIC_SITE_URL=http://localhost:3000
NEXT_PUBLIC_CONTACT_EMAIL=info@visaservice.com
NEXT_PUBLIC_PHONE=1900-1234
```
## 🤝 Đóng Góp
1. Fork repository
2. Tạo feature branch: `git checkout -b feature/new-feature`
3. Commit changes: `git commit -m 'Add new feature'`
4. Push branch: `git push origin feature/new-feature`
5. Tạo Pull Request
## 📄 License
MIT License - xem file [LICENSE](LICENSE) để biết thêm chi tiết.
## 📞 Hỗ Trợ
- **Email**: info@visaservice.com
- **Phone**: 1900 1234
- **Website**: [visaservice.com](https://visaservice.com)
---
**Phát triển bởi**: VisaService Team
**Phiên bản**: 1.0.0
**Cập nhật**: January 2025
+33
View File
@@ -0,0 +1,33 @@
{
"title": "Về Chúng Tôi",
"subtitle": "Đối tác tin cậy cho dịch vụ visa và du lịch",
"description": "Chúng tôi là công ty hàng đầu trong lĩnh vực tư vấn visa và dịch vụ du lịch, với hơn 10 năm kinh nghiệm phục vụ khách hàng.",
"sections": [
{
"heading": "Sứ Mệnh",
"content": "Mang đến cho khách hàng những trải nghiệm du lịch tuyệt vời và hỗ trợ thủ tục visa một cách nhanh chóng, chính xác."
},
{
"heading": "Tầm Nhìn",
"content": "Trở thành công ty dẫn đầu trong lĩnh vực dịch vụ visa và du lịch tại Việt Nam."
},
{
"heading": "Giá Trị Cốt Lõi",
"content": "Uy tín - Chất lượng - Tận tâm - Chuyên nghiệp"
}
],
"stats": [
{
"number": "10000+",
"label": "Khách hàng hài lòng"
},
{
"number": "50+",
"label": "Quốc gia hỗ trợ visa"
},
{
"number": "99%",
"label": "Tỷ lệ thành công"
}
]
}
+49
View File
@@ -0,0 +1,49 @@
import aboutData from "./about.json";
export default function AboutPage() {
return (
<div className="container mx-auto px-4 py-8">
<div className="max-w-4xl mx-auto">
{/* Header */}
<div className="text-center mb-12">
<h1 className="text-4xl font-bold text-gray-900 mb-4">
{aboutData.title}
</h1>
<p className="text-xl text-gray-600 mb-6">{aboutData.subtitle}</p>
<p className="text-lg text-gray-700 leading-relaxed">
{aboutData.description}
</p>
</div>
{/* Sections */}
<div className="grid md:grid-cols-3 gap-8 mb-12">
{aboutData.sections.map((section, index) => (
<div key={index} className="bg-white p-6 rounded-lg shadow-md">
<h3 className="text-xl font-semibold text-gray-900 mb-4">
{section.heading}
</h3>
<p className="text-gray-700 leading-relaxed">{section.content}</p>
</div>
))}
</div>
{/* Stats */}
<div className="bg-blue-50 rounded-lg p-8">
<h2 className="text-2xl font-bold text-center text-gray-900 mb-8">
Thành Tích Của Chúng Tôi
</h2>
<div className="grid md:grid-cols-3 gap-8">
{aboutData.stats.map((stat, index) => (
<div key={index} className="text-center">
<div className="text-3xl font-bold text-blue-600 mb-2">
{stat.number}
</div>
<div className="text-gray-700">{stat.label}</div>
</div>
))}
</div>
</div>
</div>
</div>
);
}
+255
View File
@@ -0,0 +1,255 @@
{
"title": "Đặt Lịch Tư Vấn",
"subtitle": "Nhận tư vấn miễn phí từ chuyên gia visa của chúng tôi",
"hero": {
"title": "Tư Vấn Visa Miễn Phí",
"description": "Đặt lịch hẹn với chuyên gia để được tư vấn chi tiết về visa và dịch vụ phù hợp nhất cho bạn.",
"benefits": [
"Tư vấn 1-1 với chuyên gia",
"Phân tích hồ sơ miễn phí",
"Báo giá chi tiết",
"Lộ trình xin visa rõ ràng"
]
},
"appointmentTypes": [
{
"id": "consultation",
"name": "Tư Vấn Tổng Quát",
"duration": "30 phút",
"price": "Miễn phí",
"description": "Tư vấn về loại visa phù hợp, yêu cầu cơ bản và quy trình xin visa",
"icon": "💬",
"popular": true
},
{
"id": "document-review",
"name": "Kiểm Tra Hồ Sơ",
"duration": "45 phút",
"price": "500,000 VNĐ",
"description": "Kiểm tra chi tiết hồ sơ hiện tại và đưa ra lời khuyên cải thiện",
"icon": "📋",
"popular": false
},
{
"id": "interview-prep",
"name": "Luyện Phỏng Vấn",
"duration": "60 phút",
"price": "800,000 VNĐ",
"description": "Luyện tập kỹ năng phỏng vấn visa với chuyên gia có kinh nghiệm",
"icon": "🎯",
"popular": false
},
{
"id": "premium",
"name": "Tư Vấn Cao Cấp",
"duration": "90 phút",
"price": "1,200,000 VNĐ",
"description": "Tư vấn toàn diện bao gồm chiến lược, hồ sơ và luyện phỏng vấn",
"icon": "⭐",
"popular": false
}
],
"timeSlots": [
{
"time": "08:00",
"label": "8:00 AM",
"available": true
},
{
"time": "09:00",
"label": "9:00 AM",
"available": true
},
{
"time": "10:00",
"label": "10:00 AM",
"available": false
},
{
"time": "11:00",
"label": "11:00 AM",
"available": true
},
{
"time": "13:00",
"label": "1:00 PM",
"available": true
},
{
"time": "14:00",
"label": "2:00 PM",
"available": true
},
{
"time": "15:00",
"label": "3:00 PM",
"available": false
},
{
"time": "16:00",
"label": "4:00 PM",
"available": true
},
{
"time": "17:00",
"label": "5:00 PM",
"available": true
}
],
"consultants": [
{
"id": "nguyen-van-a",
"name": "Nguyễn Văn A",
"title": "Chuyên gia Visa Mỹ & Canada",
"experience": "8 năm kinh nghiệm",
"specialties": ["Visa Mỹ", "Visa Canada", "Visa du học"],
"languages": ["Tiếng Việt", "English"],
"rating": 4.9,
"reviews": 156,
"avatar": "/images/consultant-1.jpg",
"description": "Chuyên gia hàng đầu về visa Bắc Mỹ với tỷ lệ thành công 98%"
},
{
"id": "tran-thi-b",
"name": "Trần Thị B",
"title": "Chuyên gia Visa Châu Âu",
"experience": "6 năm kinh nghiệm",
"specialties": ["Visa Schengen", "Visa Anh", "Visa du lịch"],
"languages": ["Tiếng Việt", "English", "Français"],
"rating": 4.8,
"reviews": 203,
"avatar": "/images/consultant-2.jpg",
"description": "Chuyên gia visa châu Âu với kinh nghiệm sống và làm việc tại Pháp"
},
{
"id": "le-van-c",
"name": "Lê Văn C",
"title": "Chuyên gia Visa Châu Á",
"experience": "5 năm kinh nghiệm",
"specialties": ["Visa Nhật Bản", "Visa Hàn Quốc", "Visa Singapore"],
"languages": ["Tiếng Việt", "日本語", "한국어"],
"rating": 4.9,
"reviews": 134,
"avatar": "/images/consultant-3.jpg",
"description": "Chuyên gia visa châu Á với khả năng giao tiếp đa ngôn ngữ"
}
],
"formFields": [
{
"name": "fullName",
"label": "Họ và tên",
"type": "text",
"required": true,
"placeholder": "Nhập họ và tên đầy đủ"
},
{
"name": "email",
"label": "Email",
"type": "email",
"required": true,
"placeholder": "example@email.com"
},
{
"name": "phone",
"label": "Số điện thoại",
"type": "tel",
"required": true,
"placeholder": "+84 xxx xxx xxx"
},
{
"name": "visaType",
"label": "Loại visa quan tâm",
"type": "select",
"required": true,
"options": [
"Visa du lịch",
"Visa công tác",
"Visa du học",
"Visa thăm thân",
"Visa lao động",
"Chưa xác định"
]
},
{
"name": "country",
"label": "Quốc gia đích",
"type": "select",
"required": true,
"options": [
"Mỹ",
"Canada",
"Schengen",
"Anh",
"Úc",
"Nhật Bản",
"Hàn Quốc",
"Singapore",
"Khác"
]
},
{
"name": "travelDate",
"label": "Dự kiến ngày đi",
"type": "date",
"required": false,
"placeholder": ""
},
{
"name": "previousVisa",
"label": "Đã từng xin visa nước này?",
"type": "select",
"required": false,
"options": [
"Chưa bao giờ",
"Đã xin và được duyệt",
"Đã xin nhưng bị từ chối",
"Đang trong quá trình xin"
]
},
{
"name": "notes",
"label": "Ghi chú thêm",
"type": "textarea",
"required": false,
"placeholder": "Mô tả thêm về tình huống của bạn..."
}
],
"faqs": [
{
"question": "Tư vấn có thực sự miễn phí không?",
"answer": "Có, buổi tư vấn tổng quát 30 phút đầu tiên hoàn toàn miễn phí. Bạn chỉ cần đặt lịch và tham gia."
},
{
"question": "Tôi có thể hủy hoặc đổi lịch hẹn không?",
"answer": "Có, bạn có thể hủy hoặc đổi lịch hẹn trước 24 giờ mà không mất phí. Liên hệ với chúng tôi để thay đổi."
},
{
"question": "Buổi tư vấn diễn ra như thế nào?",
"answer": "Buổi tư vấn có thể diễn ra trực tiếp tại văn phòng hoặc online qua video call tùy theo lựa chọn của bạn."
},
{
"question": "Tôi cần chuẩn bị gì cho buổi tư vấn?",
"answer": "Bạn nên chuẩn bị các câu hỏi cụ thể và nếu có, mang theo hộ chiếu và các giấy tờ liên quan để được tư vấn chính xác hơn."
}
],
"offices": [
{
"name": "TP. Hồ Chí Minh",
"address": "123 Nguyễn Huệ, Quận 1",
"phone": "+84 28 1234 5678",
"hours": "8:00 - 18:00 (T2-T6), 8:00 - 12:00 (T7)"
},
{
"name": "Hà Nội",
"address": "456 Hoàn Kiếm, Hà Nội",
"phone": "+84 24 1234 5678",
"hours": "8:00 - 18:00 (T2-T6), 8:00 - 12:00 (T7)"
},
{
"name": "Đà Nẵng",
"address": "789 Hải Châu, Đà Nẵng",
"phone": "+84 236 1234 567",
"hours": "8:00 - 18:00 (T2-T6), 8:00 - 12:00 (T7)"
}
]
}
+501
View File
@@ -0,0 +1,501 @@
"use client";
import { useState } from "react";
import appointmentData from "./appointment.json";
export default function AppointmentPage() {
const [selectedType, setSelectedType] = useState("consultation");
const [selectedConsultant, setSelectedConsultant] = useState("");
const [selectedDate, setSelectedDate] = useState("");
const [selectedTime, setSelectedTime] = useState("");
const [selectedOffice, setSelectedOffice] = useState("online");
const [openFaq, setOpenFaq] = useState<number | null>(null);
const [formData, setFormData] = useState({
fullName: "",
email: "",
phone: "",
visaType: "",
country: "",
travelDate: "",
previousVisa: "",
notes: "",
});
const handleInputChange = (
e: React.ChangeEvent<
HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement
>,
) => {
const { name, value } = e.target;
setFormData((prev) => ({
...prev,
[name]: value,
}));
};
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
console.log("Appointment booked:", {
type: selectedType,
consultant: selectedConsultant,
date: selectedDate,
time: selectedTime,
office: selectedOffice,
...formData,
});
alert(
"Đặt lịch thành công! Chúng tôi sẽ liên hệ xác nhận trong thời gian sớm nhất.",
);
};
const toggleFaq = (index: number) => {
setOpenFaq(openFaq === index ? null : index);
};
const selectedAppointmentType = appointmentData.appointmentTypes.find(
(type) => type.id === selectedType,
);
const selectedConsultantData = appointmentData.consultants.find(
(c) => c.id === selectedConsultant,
);
return (
<div className="container mx-auto px-4 py-8">
<div className="max-w-6xl mx-auto">
{/* Header */}
<div className="text-center mb-12">
<h1 className="text-4xl font-bold text-gray-900 mb-4">
{appointmentData.title}
</h1>
<p className="text-xl text-gray-600 mb-8">
{appointmentData.subtitle}
</p>
{/* Benefits */}
<div className="grid md:grid-cols-4 gap-6 max-w-4xl mx-auto">
{appointmentData.hero.benefits.map((benefit, index) => (
<div key={index} className="bg-blue-50 p-4 rounded-lg">
<p className="text-blue-800 font-medium">{benefit}</p>
</div>
))}
</div>
</div>
<div className="grid lg:grid-cols-3 gap-8">
{/* Booking Form */}
<div className="lg:col-span-2">
<div className="bg-white rounded-lg shadow-lg p-6">
<h2 className="text-2xl font-bold text-gray-900 mb-6">
Đt Lịch Hẹn
</h2>
<form onSubmit={handleSubmit} className="space-y-6">
{/* Appointment Type */}
<div>
<label className="block text-sm font-medium text-gray-700 mb-3">
Loại vấn <span className="text-red-500">*</span>
</label>
<div className="grid md:grid-cols-2 gap-4">
{appointmentData.appointmentTypes.map((type) => (
<div
key={type.id}
className={`border rounded-lg p-4 cursor-pointer transition-colors ${
selectedType === type.id
? "border-blue-500 bg-blue-50"
: "border-gray-200 hover:border-gray-300"
}`}
onClick={() => setSelectedType(type.id)}
>
<div className="flex items-center justify-between mb-2">
<div className="flex items-center">
<span className="text-2xl mr-3">{type.icon}</span>
<div>
<h3 className="font-semibold">{type.name}</h3>
{type.popular && (
<span className="bg-green-100 text-green-800 px-2 py-1 rounded text-xs">
Phổ biến
</span>
)}
</div>
</div>
<div className="text-right">
<div className="font-bold text-blue-600">
{type.price}
</div>
<div className="text-sm text-gray-500">
{type.duration}
</div>
</div>
</div>
<p className="text-gray-600 text-sm">
{type.description}
</p>
</div>
))}
</div>
</div>
{/* Consultant Selection */}
<div>
<label className="block text-sm font-medium text-gray-700 mb-3">
Chọn chuyên gia
</label>
<div className="space-y-3">
<div
className={`border rounded-lg p-4 cursor-pointer transition-colors ${
selectedConsultant === ""
? "border-blue-500 bg-blue-50"
: "border-gray-200 hover:border-gray-300"
}`}
onClick={() => setSelectedConsultant("")}
>
<div className="font-medium">
Đ chúng tôi chọn chuyên gia phù hợp
</div>
<div className="text-sm text-gray-600">
Dựa trên loại visa quốc gia bạn quan tâm
</div>
</div>
{appointmentData.consultants.map((consultant) => (
<div
key={consultant.id}
className={`border rounded-lg p-4 cursor-pointer transition-colors ${
selectedConsultant === consultant.id
? "border-blue-500 bg-blue-50"
: "border-gray-200 hover:border-gray-300"
}`}
onClick={() => setSelectedConsultant(consultant.id)}
>
<div className="flex items-center">
<div className="w-12 h-12 bg-gray-200 rounded-full flex items-center justify-center mr-4">
<span className="text-gray-600">👤</span>
</div>
<div className="flex-1">
<div className="font-semibold">
{consultant.name}
</div>
<div className="text-sm text-gray-600">
{consultant.title}
</div>
<div className="flex items-center text-sm text-gray-500">
<span className="mr-2">
{consultant.rating}
</span>
<span className="mr-2">
({consultant.reviews} đánh giá)
</span>
<span>{consultant.experience}</span>
</div>
</div>
</div>
</div>
))}
</div>
</div>
{/* Date & Time */}
<div className="grid md:grid-cols-2 gap-6">
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
Ngày hẹn <span className="text-red-500">*</span>
</label>
<input
type="date"
value={selectedDate}
onChange={(e) => setSelectedDate(e.target.value)}
min={new Date().toISOString().split("T")[0]}
required
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
Giờ hẹn <span className="text-red-500">*</span>
</label>
<select
value={selectedTime}
onChange={(e) => setSelectedTime(e.target.value)}
required
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
>
<option value="">Chọn giờ</option>
{appointmentData.timeSlots.map((slot) => (
<option
key={slot.time}
value={slot.time}
disabled={!slot.available}
>
{slot.label} {!slot.available && "(Đã đặt)"}
</option>
))}
</select>
</div>
</div>
{/* Office Selection */}
<div>
<label className="block text-sm font-medium text-gray-700 mb-3">
Hình thức vấn <span className="text-red-500">*</span>
</label>
<div className="space-y-3">
<div
className={`border rounded-lg p-4 cursor-pointer transition-colors ${
selectedOffice === "online"
? "border-blue-500 bg-blue-50"
: "border-gray-200 hover:border-gray-300"
}`}
onClick={() => setSelectedOffice("online")}
>
<div className="flex items-center">
<span className="text-2xl mr-3">💻</span>
<div>
<div className="font-medium"> vấn online</div>
<div className="text-sm text-gray-600">
Video call qua Zoom/Google Meet
</div>
</div>
</div>
</div>
{appointmentData.offices.map((office, index) => (
<div
key={index}
className={`border rounded-lg p-4 cursor-pointer transition-colors ${
selectedOffice === office.name
? "border-blue-500 bg-blue-50"
: "border-gray-200 hover:border-gray-300"
}`}
onClick={() => setSelectedOffice(office.name)}
>
<div className="flex items-center">
<span className="text-2xl mr-3">🏢</span>
<div>
<div className="font-medium">
Văn phòng {office.name}
</div>
<div className="text-sm text-gray-600">
{office.address}
</div>
<div className="text-sm text-gray-500">
{office.hours}
</div>
</div>
</div>
</div>
))}
</div>
</div>
{/* Personal Information */}
<div className="border-t pt-6">
<h3 className="text-lg font-semibold text-gray-900 mb-4">
Thông Tin Nhân
</h3>
<div className="grid md:grid-cols-2 gap-6">
{appointmentData.formFields.map((field) => (
<div
key={field.name}
className={
field.type === "textarea" ? "md:col-span-2" : ""
}
>
<label className="block text-sm font-medium text-gray-700 mb-2">
{field.label}
{field.required && (
<span className="text-red-500 ml-1">*</span>
)}
</label>
{field.type === "textarea" ? (
<textarea
name={field.name}
value={
formData[field.name as keyof typeof formData]
}
onChange={handleInputChange}
placeholder={field.placeholder}
required={field.required}
rows={4}
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
) : field.type === "select" ? (
<select
name={field.name}
value={
formData[field.name as keyof typeof formData]
}
onChange={handleInputChange}
required={field.required}
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
>
<option value="">
Chọn {field.label.toLowerCase()}
</option>
{field.options?.map((option, index) => (
<option key={index} value={option}>
{option}
</option>
))}
</select>
) : (
<input
type={field.type}
name={field.name}
value={
formData[field.name as keyof typeof formData]
}
onChange={handleInputChange}
placeholder={field.placeholder}
required={field.required}
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
)}
</div>
))}
</div>
</div>
{/* Submit Button */}
<button
type="submit"
className="w-full bg-blue-600 text-white py-3 px-6 rounded-lg hover:bg-blue-700 transition-colors font-medium text-lg"
>
Đt Lịch Hẹn
</button>
</form>
</div>
</div>
{/* Sidebar */}
<div className="space-y-6">
{/* Booking Summary */}
<div className="bg-white rounded-lg shadow-lg p-6">
<h3 className="text-lg font-semibold text-gray-900 mb-4">
Tóm Tắt Đt Lịch
</h3>
{selectedAppointmentType && (
<div className="space-y-3">
<div className="flex justify-between">
<span className="text-gray-600">Loại vấn:</span>
<span className="font-medium">
{selectedAppointmentType.name}
</span>
</div>
<div className="flex justify-between">
<span className="text-gray-600">Thời gian:</span>
<span className="font-medium">
{selectedAppointmentType.duration}
</span>
</div>
<div className="flex justify-between">
<span className="text-gray-600">Phí:</span>
<span className="font-medium text-blue-600">
{selectedAppointmentType.price}
</span>
</div>
{selectedConsultantData && (
<div className="border-t pt-3">
<div className="flex justify-between">
<span className="text-gray-600">Chuyên gia:</span>
<span className="font-medium">
{selectedConsultantData.name}
</span>
</div>
</div>
)}
{selectedDate && selectedTime && (
<div className="border-t pt-3">
<div className="flex justify-between">
<span className="text-gray-600">Ngày giờ:</span>
<span className="font-medium">
{selectedDate} lúc{" "}
{
appointmentData.timeSlots.find(
(s) => s.time === selectedTime,
)?.label
}
</span>
</div>
</div>
)}
{selectedOffice && (
<div className="flex justify-between">
<span className="text-gray-600">Hình thức:</span>
<span className="font-medium">
{selectedOffice === "online"
? "Online"
: `Văn phòng ${selectedOffice}`}
</span>
</div>
)}
</div>
)}
</div>
{/* Contact Info */}
<div className="bg-blue-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-gray-900 mb-4">
Cần Hỗ Trợ?
</h3>
<div className="space-y-3">
<div className="flex items-center">
<span className="text-blue-600 mr-2">📞</span>
<span>1900 1234</span>
</div>
<div className="flex items-center">
<span className="text-blue-600 mr-2"></span>
<span>info@visaservice.com</span>
</div>
<div className="flex items-center">
<span className="text-blue-600 mr-2">💬</span>
<span>Chat trực tuyến 24/7</span>
</div>
</div>
</div>
</div>
</div>
{/* FAQs */}
<div className="mt-16">
<h2 className="text-2xl font-bold text-gray-900 mb-8 text-center">
Câu Hỏi Thường Gặp
</h2>
<div className="max-w-3xl mx-auto space-y-4">
{appointmentData.faqs.map((faq, index) => (
<div
key={index}
className="bg-white rounded-lg shadow-md overflow-hidden"
>
<button
className="w-full p-6 text-left hover:bg-gray-50 transition-colors"
onClick={() => toggleFaq(index)}
>
<div className="flex items-center justify-between">
<h3 className="font-semibold text-gray-900">
{faq.question}
</h3>
<span className="text-gray-400">
{openFaq === index ? "" : "+"}
</span>
</div>
</button>
{openFaq === index && (
<div className="px-6 pb-6">
<p className="text-gray-700">{faq.answer}</p>
</div>
)}
</div>
))}
</div>
</div>
</div>
</div>
);
}
+93
View File
@@ -0,0 +1,93 @@
{
"title": "Blog & Tin Tức",
"subtitle": "Cập nhật thông tin mới nhất về visa và du lịch",
"featured": {
"id": "visa-schengen-2024",
"title": "Hướng Dẫn Xin Visa Schengen 2024 - Cập Nhật Mới Nhất",
"excerpt": "Thủ tục xin visa Schengen đã có những thay đổi quan trọng trong năm 2024. Cùng tìm hiểu chi tiết...",
"image": "/images/schengen-visa.jpg",
"date": "2024-01-15",
"author": "Nguyễn Văn A",
"category": "Visa",
"readTime": "5 phút đọc"
},
"categories": [
{
"name": "Tất cả",
"slug": "all",
"count": 24
},
{
"name": "Visa",
"slug": "visa",
"count": 12
},
{
"name": "Du lịch",
"slug": "travel",
"count": 8
},
{
"name": "Thủ tục",
"slug": "procedures",
"count": 4
}
],
"posts": [
{
"id": "visa-my-2024",
"title": "Thay Đổi Mới Trong Thủ Tục Xin Visa Mỹ 2024",
"excerpt": "Lãnh sự quán Mỹ đã công bố những thay đổi quan trọng trong quy trình xin visa...",
"image": "/images/us-visa.jpg",
"date": "2024-01-10",
"author": "Trần Thị B",
"category": "Visa",
"readTime": "7 phút đọc",
"tags": ["Visa Mỹ", "Thủ tục", "2024"]
},
{
"id": "du-lich-nhat-ban",
"title": "Top 10 Địa Điểm Du Lịch Nhật Bản Không Thể Bỏ Qua",
"excerpt": "Khám phá những điểm đến tuyệt vời nhất tại đất nước mặt trời mọc...",
"image": "/images/japan-travel.jpg",
"date": "2024-01-08",
"author": "Lê Văn C",
"category": "Du lịch",
"readTime": "6 phút đọc",
"tags": ["Nhật Bản", "Du lịch", "Điểm đến"]
},
{
"id": "visa-han-quoc-tips",
"title": "Bí Quyết Xin Visa Hàn Quốc Thành Công 100%",
"excerpt": "Những kinh nghiệm quý báu từ chuyên gia để tăng tỷ lệ thành công...",
"image": "/images/korea-visa.jpg",
"date": "2024-01-05",
"author": "Phạm Thị D",
"category": "Visa",
"readTime": "8 phút đọc",
"tags": ["Visa Hàn Quốc", "Kinh nghiệm", "Thành công"]
},
{
"id": "du-lich-chau-au",
"title": "Lịch Trình Du Lịch Châu Âu 14 Ngày Hoàn Hảo",
"excerpt": "Khám phá 7 quốc gia châu Âu với lịch trình được thiết kế tối ưu...",
"image": "/images/europe-travel.jpg",
"date": "2024-01-03",
"author": "Hoàng Văn E",
"category": "Du lịch",
"readTime": "10 phút đọc",
"tags": ["Châu Âu", "Lịch trình", "14 ngày"]
},
{
"id": "thu-tuc-ho-so",
"title": "Checklist Hồ Sơ Xin Visa - Không Bỏ Sót Gì",
"excerpt": "Danh sách chi tiết các giấy tờ cần thiết cho từng loại visa...",
"image": "/images/documents.jpg",
"date": "2024-01-01",
"author": "Vũ Thị F",
"category": "Thủ tục",
"readTime": "4 phút đọc",
"tags": ["Hồ sơ", "Checklist", "Visa"]
}
]
}
+144
View File
@@ -0,0 +1,144 @@
"use client";
import { useState } from "react";
import blogData from "./blog.json";
export default function BlogPage() {
const [selectedCategory, setSelectedCategory] = useState("all");
const filteredPosts =
selectedCategory === "all"
? blogData.posts
: blogData.posts.filter(
(post) => post.category.toLowerCase() === selectedCategory,
);
return (
<div className="container mx-auto px-4 py-8">
<div className="max-w-6xl mx-auto">
{/* Header */}
<div className="text-center mb-12">
<h1 className="text-4xl font-bold text-gray-900 mb-4">
{blogData.title}
</h1>
<p className="text-xl text-gray-600">{blogData.subtitle}</p>
</div>
{/* Featured Post */}
<div className="mb-12">
<div className="bg-gradient-to-r from-blue-600 to-purple-600 rounded-lg p-8 text-white">
<div className="flex items-center mb-4">
<span className="bg-yellow-400 text-black px-3 py-1 rounded-full text-sm font-medium mr-4">
Nổi bật
</span>
<span className="text-blue-100">
{blogData.featured.category}
</span>
</div>
<h2 className="text-3xl font-bold mb-4">
{blogData.featured.title}
</h2>
<p className="text-blue-100 mb-6 text-lg">
{blogData.featured.excerpt}
</p>
<div className="flex items-center justify-between">
<div className="flex items-center text-blue-100">
<span className="mr-4">👤 {blogData.featured.author}</span>
<span className="mr-4">📅 {blogData.featured.date}</span>
<span> {blogData.featured.readTime}</span>
</div>
<button className="bg-white text-blue-600 px-6 py-2 rounded-lg hover:bg-blue-50 transition-colors">
Đc thêm
</button>
</div>
</div>
</div>
{/* Category Filter */}
<div className="mb-8">
<div className="flex flex-wrap gap-4 justify-center">
{blogData.categories.map((category) => (
<button
key={category.slug}
onClick={() => setSelectedCategory(category.slug)}
className={`px-6 py-2 rounded-full transition-colors ${
selectedCategory === category.slug
? "bg-blue-600 text-white"
: "bg-gray-100 text-gray-700 hover:bg-gray-200"
}`}
>
{category.name} ({category.count})
</button>
))}
</div>
</div>
{/* Blog Posts Grid */}
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8">
{filteredPosts.map((post) => (
<article
key={post.id}
className="bg-white rounded-lg shadow-md overflow-hidden hover:shadow-lg transition-shadow"
>
{/* Post Image */}
<div className="h-48 bg-gray-200 flex items-center justify-center">
<span className="text-gray-400">📷 {post.category}</span>
</div>
{/* Post Content */}
<div className="p-6">
{/* Category & Date */}
<div className="flex items-center justify-between mb-3">
<span className="bg-blue-100 text-blue-800 px-2 py-1 rounded text-sm">
{post.category}
</span>
<span className="text-gray-500 text-sm">{post.date}</span>
</div>
{/* Title */}
<h3 className="text-xl font-semibold text-gray-900 mb-3 line-clamp-2">
{post.title}
</h3>
{/* Excerpt */}
<p className="text-gray-700 mb-4 line-clamp-3">
{post.excerpt}
</p>
{/* Tags */}
<div className="flex flex-wrap gap-2 mb-4">
{post.tags.map((tag, index) => (
<span
key={index}
className="bg-gray-100 text-gray-600 px-2 py-1 rounded text-xs"
>
#{tag}
</span>
))}
</div>
{/* Meta Info */}
<div className="flex items-center justify-between text-sm text-gray-500">
<span>👤 {post.author}</span>
<span> {post.readTime}</span>
</div>
{/* Read More Button */}
<button className="w-full mt-4 bg-blue-600 text-white py-2 px-4 rounded-lg hover:bg-blue-700 transition-colors">
Đc thêm
</button>
</div>
</article>
))}
</div>
{/* Load More */}
<div className="text-center mt-12">
<button className="bg-gray-100 text-gray-700 px-8 py-3 rounded-lg hover:bg-gray-200 transition-colors">
Xem thêm bài viết
</button>
</div>
</div>
</div>
);
}
+191
View File
@@ -0,0 +1,191 @@
import Link from "next/link";
export default function Footer() {
const currentYear = new Date().getFullYear();
const quickLinks = [
{ name: "Về chúng tôi", href: "/about" },
{ name: "Dịch vụ", href: "/services" },
{ name: "Bảng giá", href: "/pricing" },
{ name: "Blog", href: "/blog" },
{ name: "Liên hệ", href: "/contact" },
];
const visaServices = [
{ name: "Visa Mỹ", href: "/visa" },
{ name: "Visa Schengen", href: "/visa" },
{ name: "Visa Nhật Bản", href: "/visa" },
{ name: "Visa Hàn Quốc", href: "/visa" },
{ name: "Visa Canada", href: "/visa" },
];
const countries = [
{ name: "Châu Âu", href: "/countries" },
{ name: "Bắc Mỹ", href: "/countries" },
{ name: "Châu Á", href: "/countries" },
{ name: "Châu Đại Dương", href: "/countries" },
];
return (
<footer className="bg-gray-900 text-white">
<div className="container mx-auto px-4 py-12">
<div className="grid md:grid-cols-2 lg:grid-cols-4 gap-8">
{/* Company Info */}
<div>
<div className="flex items-center space-x-2 mb-6">
<div className="w-10 h-10 bg-blue-600 rounded-lg flex items-center justify-center">
<span className="text-white font-bold text-xl">V</span>
</div>
<div>
<div className="font-bold text-xl">VisaService</div>
<div className="text-sm text-gray-400">Dịch vụ visa uy tín</div>
</div>
</div>
<p className="text-gray-400 mb-6">
Đi tác tin cậy cho dịch vụ visa du lịch với hơn 10 năm kinh
nghiệm. Cam kết mang đến dịch vụ chất lượng cao với tỷ lệ thành
công 99%.
</p>
<div className="flex space-x-4">
<a
href="#"
className="text-gray-400 hover:text-white transition-colors"
>
<span className="sr-only">Facebook</span>
📘
</a>
<a
href="#"
className="text-gray-400 hover:text-white transition-colors"
>
<span className="sr-only">Instagram</span>
📷
</a>
<a
href="#"
className="text-gray-400 hover:text-white transition-colors"
>
<span className="sr-only">YouTube</span>
📺
</a>
<a
href="#"
className="text-gray-400 hover:text-white transition-colors"
>
<span className="sr-only">LinkedIn</span>
💼
</a>
</div>
</div>
{/* Quick Links */}
<div>
<h3 className="font-semibold text-lg mb-6">Liên Kết Nhanh</h3>
<ul className="space-y-3">
{quickLinks.map((link) => (
<li key={link.name}>
<Link
href={link.href}
className="text-gray-400 hover:text-white transition-colors"
>
{link.name}
</Link>
</li>
))}
</ul>
</div>
{/* Visa Services */}
<div>
<h3 className="font-semibold text-lg mb-6">Dịch Vụ Visa</h3>
<ul className="space-y-3">
{visaServices.map((service) => (
<li key={service.name}>
<Link
href={service.href}
className="text-gray-400 hover:text-white transition-colors"
>
{service.name}
</Link>
</li>
))}
</ul>
</div>
{/* Contact Info */}
<div>
<h3 className="font-semibold text-lg mb-6">Thông Tin Liên Hệ</h3>
<div className="space-y-4">
<div className="flex items-start">
<span className="text-blue-400 mr-3 mt-1">📍</span>
<div>
<p className="text-gray-400">
123 Nguyễn Huệ, Quận 1<br />
TP. Hồ Chí Minh
</p>
</div>
</div>
<div className="flex items-center">
<span className="text-blue-400 mr-3">📞</span>
<p className="text-gray-400">+84 28 1234 5678</p>
</div>
<div className="flex items-center">
<span className="text-blue-400 mr-3"></span>
<p className="text-gray-400">info@visaservice.com</p>
</div>
<div className="flex items-start">
<span className="text-blue-400 mr-3 mt-1">🕒</span>
<div>
<p className="text-gray-400">
Thứ 2 - Thứ 6: 8:00 - 18:00
<br />
Thứ 7: 8:00 - 12:00
</p>
</div>
</div>
</div>
</div>
</div>
{/* Bottom Section */}
<div className="border-t border-gray-800 mt-12 pt-8">
<div className="flex flex-col md:flex-row justify-between items-center">
<div className="text-gray-400 text-sm mb-4 md:mb-0">
© {currentYear} VisaService. Tất cả quyền đưc bảo lưu.
</div>
<div className="flex space-x-6 text-sm">
<Link
href="#"
className="text-gray-400 hover:text-white transition-colors"
>
Chính sách bảo mật
</Link>
<Link
href="#"
className="text-gray-400 hover:text-white transition-colors"
>
Điều khoản sử dụng
</Link>
<Link
href="#"
className="text-gray-400 hover:text-white transition-colors"
>
Sitemap
</Link>
</div>
</div>
</div>
</div>
{/* Floating Contact Button */}
<div className="fixed bottom-6 right-6 z-50">
<Link
href="/appointment"
className="bg-green-500 text-white p-4 rounded-full shadow-lg hover:bg-green-600 transition-colors flex items-center justify-center"
>
<span className="text-2xl">💬</span>
</Link>
</div>
</footer>
);
}
+114
View File
@@ -0,0 +1,114 @@
"use client";
import { useState } from "react";
import Link from "next/link";
export default function Header() {
const [isMenuOpen, setIsMenuOpen] = useState(false);
const navigation = [
{ name: "Trang chủ", href: "/" },
{ name: "Về chúng tôi", href: "/about" },
{ name: "Dịch vụ", href: "/services" },
{ name: "Visa", href: "/visa" },
{ name: "Quốc gia", href: "/countries" },
{ name: "Bảng giá", href: "/pricing" },
{ name: "Blog", href: "/blog" },
{ name: "Liên hệ", href: "/contact" },
];
return (
<header className="bg-white shadow-lg sticky top-0 z-50">
<div className="container mx-auto px-4">
<div className="flex items-center justify-between h-16">
{/* Logo */}
<Link href="/" className="flex items-center space-x-2">
<div className="w-10 h-10 bg-blue-600 rounded-lg flex items-center justify-center">
<span className="text-white font-bold text-xl">V</span>
</div>
<div>
<div className="font-bold text-xl text-gray-900">VisaService</div>
<div className="text-xs text-gray-500">Dịch vụ visa uy tín</div>
</div>
</Link>
{/* Desktop Navigation */}
<nav className="hidden lg:flex items-center space-x-8">
{navigation.map((item) => (
<Link
key={item.name}
href={item.href}
className="text-gray-700 hover:text-blue-600 transition-colors font-medium"
>
{item.name}
</Link>
))}
</nav>
{/* CTA Buttons */}
<div className="hidden lg:flex items-center space-x-4">
<Link
href="/appointment"
className="bg-blue-600 text-white px-6 py-2 rounded-lg hover:bg-blue-700 transition-colors font-medium"
>
Đt lịch vấn
</Link>
<div className="flex items-center text-gray-600">
<span className="text-sm">📞</span>
<span className="ml-1 font-medium">1900 1234</span>
</div>
</div>
{/* Mobile Menu Button */}
<button
className="lg:hidden p-2"
onClick={() => setIsMenuOpen(!isMenuOpen)}
>
<div className="w-6 h-6 flex flex-col justify-center items-center">
<span
className={`bg-gray-600 block transition-all duration-300 ease-out h-0.5 w-6 rounded-sm ${isMenuOpen ? "rotate-45 translate-y-1" : "-translate-y-0.5"}`}
></span>
<span
className={`bg-gray-600 block transition-all duration-300 ease-out h-0.5 w-6 rounded-sm my-0.5 ${isMenuOpen ? "opacity-0" : "opacity-100"}`}
></span>
<span
className={`bg-gray-600 block transition-all duration-300 ease-out h-0.5 w-6 rounded-sm ${isMenuOpen ? "-rotate-45 -translate-y-1" : "translate-y-0.5"}`}
></span>
</div>
</button>
</div>
{/* Mobile Menu */}
{isMenuOpen && (
<div className="lg:hidden border-t border-gray-200">
<div className="py-4 space-y-4">
{navigation.map((item) => (
<Link
key={item.name}
href={item.href}
className="block text-gray-700 hover:text-blue-600 transition-colors font-medium"
onClick={() => setIsMenuOpen(false)}
>
{item.name}
</Link>
))}
<div className="pt-4 border-t border-gray-200">
<Link
href="/appointment"
className="block bg-blue-600 text-white px-6 py-3 rounded-lg hover:bg-blue-700 transition-colors font-medium text-center mb-4"
onClick={() => setIsMenuOpen(false)}
>
Đt lịch vấn
</Link>
<div className="flex items-center justify-center text-gray-600">
<span className="text-sm">📞</span>
<span className="ml-1 font-medium">1900 1234</span>
</div>
</div>
</div>
</div>
)}
</div>
</header>
);
}
+89
View File
@@ -0,0 +1,89 @@
{
"title": "Liên Hệ Với Chúng Tôi",
"subtitle": "Chúng tôi luôn sẵn sàng hỗ trợ bạn 24/7",
"contactInfo": {
"address": {
"label": "Địa chỉ",
"value": "123 Nguyễn Huệ, Quận 1, TP.HCM",
"icon": "📍"
},
"phone": {
"label": "Điện thoại",
"value": "+84 28 1234 5678",
"icon": "📞"
},
"email": {
"label": "Email",
"value": "info@visaservice.com",
"icon": "✉️"
},
"hours": {
"label": "Giờ làm việc",
"value": "Thứ 2 - Thứ 6: 8:00 - 18:00\nThứ 7: 8:00 - 12:00",
"icon": "🕒"
}
},
"offices": [
{
"name": "Văn Phòng TP.HCM",
"address": "123 Nguyễn Huệ, Quận 1, TP.HCM",
"phone": "+84 28 1234 5678",
"email": "hcm@visaservice.com"
},
{
"name": "Văn Phòng Hà Nội",
"address": "456 Hoàn Kiếm, Hà Nội",
"phone": "+84 24 1234 5678",
"email": "hanoi@visaservice.com"
},
{
"name": "Văn Phòng Đà Nẵng",
"address": "789 Hải Châu, Đà Nẵng",
"phone": "+84 236 1234 567",
"email": "danang@visaservice.com"
}
],
"formFields": [
{
"name": "fullName",
"label": "Họ và tên",
"type": "text",
"required": true,
"placeholder": "Nhập họ và tên của bạn"
},
{
"name": "email",
"label": "Email",
"type": "email",
"required": true,
"placeholder": "example@email.com"
},
{
"name": "phone",
"label": "Số điện thoại",
"type": "tel",
"required": true,
"placeholder": "+84 xxx xxx xxx"
},
{
"name": "service",
"label": "Dịch vụ quan tâm",
"type": "select",
"required": true,
"options": [
"Tư vấn visa",
"Chuẩn bị hồ sơ",
"Đặt vé máy bay",
"Tour trọn gói",
"Khác"
]
},
{
"name": "message",
"label": "Tin nhắn",
"type": "textarea",
"required": false,
"placeholder": "Mô tả chi tiết nhu cầu của bạn..."
}
]
}
+157
View File
@@ -0,0 +1,157 @@
"use client";
import { useState } from "react";
import contactData from "./contact.json";
export default function ContactPage() {
const [formData, setFormData] = useState({
fullName: "",
email: "",
phone: "",
service: "",
message: "",
});
const handleInputChange = (
e: React.ChangeEvent<
HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement
>,
) => {
const { name, value } = e.target;
setFormData((prev) => ({
...prev,
[name]: value,
}));
};
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
console.log("Form submitted:", formData);
// Handle form submission here
alert(
"Cảm ơn bạn đã liên hệ! Chúng tôi sẽ phản hồi trong thời gian sớm nhất.",
);
};
return (
<div className="container mx-auto px-4 py-8">
<div className="max-w-6xl mx-auto">
{/* Header */}
<div className="text-center mb-12">
<h1 className="text-4xl font-bold text-gray-900 mb-4">
{contactData.title}
</h1>
<p className="text-xl text-gray-600">{contactData.subtitle}</p>
</div>
<div className="grid lg:grid-cols-2 gap-12">
{/* Contact Information */}
<div>
<h2 className="text-2xl font-bold text-gray-900 mb-6">
Thông Tin Liên Hệ
</h2>
{/* Contact Details */}
<div className="space-y-6 mb-8">
{Object.entries(contactData.contactInfo).map(([key, info]) => (
<div key={key} className="flex items-start">
<span className="text-2xl mr-4">{info.icon}</span>
<div>
<h3 className="font-semibold text-gray-900">
{info.label}
</h3>
<p className="text-gray-700 whitespace-pre-line">
{info.value}
</p>
</div>
</div>
))}
</div>
{/* Offices */}
<h3 className="text-xl font-bold text-gray-900 mb-4">Văn Phòng</h3>
<div className="space-y-4">
{contactData.offices.map((office, index) => (
<div key={index} className="bg-gray-50 p-4 rounded-lg">
<h4 className="font-semibold text-gray-900 mb-2">
{office.name}
</h4>
<p className="text-gray-700 text-sm mb-1">
📍 {office.address}
</p>
<p className="text-gray-700 text-sm mb-1">
📞 {office.phone}
</p>
<p className="text-gray-700 text-sm"> {office.email}</p>
</div>
))}
</div>
</div>
{/* Contact Form */}
<div>
<h2 className="text-2xl font-bold text-gray-900 mb-6">
Gửi Tin Nhắn
</h2>
<form onSubmit={handleSubmit} className="space-y-6">
{contactData.formFields.map((field) => (
<div key={field.name}>
<label className="block text-sm font-medium text-gray-700 mb-2">
{field.label}
{field.required && (
<span className="text-red-500 ml-1">*</span>
)}
</label>
{field.type === "textarea" ? (
<textarea
name={field.name}
value={formData[field.name as keyof typeof formData]}
onChange={handleInputChange}
placeholder={field.placeholder}
required={field.required}
rows={4}
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
) : field.type === "select" ? (
<select
name={field.name}
value={formData[field.name as keyof typeof formData]}
onChange={handleInputChange}
required={field.required}
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
>
<option value="">Chọn dịch vụ</option>
{field.options?.map((option, index) => (
<option key={index} value={option}>
{option}
</option>
))}
</select>
) : (
<input
type={field.type}
name={field.name}
value={formData[field.name as keyof typeof formData]}
onChange={handleInputChange}
placeholder={field.placeholder}
required={field.required}
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
)}
</div>
))}
<button
type="submit"
className="w-full bg-blue-600 text-white py-3 px-6 rounded-lg hover:bg-blue-700 transition-colors font-medium"
>
Gửi Tin Nhắn
</button>
</form>
</div>
</div>
</div>
</div>
);
}
+188
View File
@@ -0,0 +1,188 @@
{
"title": "Danh Sách Quốc Gia",
"subtitle": "Chúng tôi hỗ trợ visa cho hơn 50 quốc gia trên thế giới",
"regions": [
{
"name": "Châu Âu",
"countries": [
{
"id": "schengen",
"name": "Schengen",
"flag": "🇪🇺",
"visaTypes": ["Du lịch", "Công tác", "Thăm thân"],
"processingTime": "15-20 ngày",
"validityPeriod": "90 ngày",
"fee": "2,200,000 VNĐ",
"requirements": [
"Hộ chiếu còn hạn trên 6 tháng",
"Ảnh 3.5x4.5cm (2 tấm)",
"Bảo hiểm du lịch",
"Chứng minh tài chính",
"Lịch trình du lịch"
],
"description": "Visa Schengen cho phép du lịch tự do trong 26 quốc gia châu Âu"
},
{
"id": "uk",
"name": "Anh",
"flag": "🇬🇧",
"visaTypes": ["Du lịch", "Công tác", "Học tập"],
"processingTime": "15-25 ngày",
"validityPeriod": "6 tháng",
"fee": "3,800,000 VNĐ",
"requirements": [
"Hộ chiếu còn hạn trên 6 tháng",
"Ảnh passport",
"Chứng minh tài chính",
"Thư mời (nếu có)",
"Bảo hiểm du lịch"
],
"description": "Visa Anh cho phép khám phá vương quốc Anh và Bắc Ireland"
}
]
},
{
"name": "Bắc Mỹ",
"countries": [
{
"id": "usa",
"name": "Mỹ",
"flag": "🇺🇸",
"visaTypes": ["B1/B2", "F1", "J1"],
"processingTime": "3-5 tuần",
"validityPeriod": "10 năm",
"fee": "4,600,000 VNĐ",
"requirements": [
"Hộ chiếu còn hạn trên 6 tháng",
"Form DS-160",
"Ảnh visa Mỹ",
"Chứng minh tài chính",
"Phỏng vấn tại lãnh sự quán"
],
"description": "Visa Mỹ B1/B2 cho phép du lịch và công tác tại Hoa Kỳ"
},
{
"id": "canada",
"name": "Canada",
"flag": "🇨🇦",
"visaTypes": ["TRV", "Study Permit", "Work Permit"],
"processingTime": "4-6 tuần",
"validityPeriod": "10 năm",
"fee": "2,800,000 VNĐ",
"requirements": [
"Hộ chiếu còn hạn trên 6 tháng",
"Ảnh passport",
"Chứng minh tài chính",
"Thư mời (nếu có)",
"Khám sức khỏe (nếu cần)"
],
"description": "Visa Canada cho phép du lịch và làm việc tại Canada"
}
]
},
{
"name": "Châu Á",
"countries": [
{
"id": "japan",
"name": "Nhật Bản",
"flag": "🇯🇵",
"visaTypes": ["Du lịch", "Công tác", "Thăm thân"],
"processingTime": "5-7 ngày",
"validityPeriod": "90 ngày",
"fee": "1,200,000 VNĐ",
"requirements": [
"Hộ chiếu còn hạn trên 6 tháng",
"Ảnh 4.5x4.5cm",
"Chứng minh tài chính",
"Lịch trình du lịch",
"Đặt chỗ khách sạn"
],
"description": "Visa Nhật Bản cho phép khám phá đất nước mặt trời mọc"
},
{
"id": "korea",
"name": "Hàn Quốc",
"flag": "🇰🇷",
"visaTypes": ["C-3", "C-4", "D-2"],
"processingTime": "5-10 ngày",
"validityPeriod": "90 ngày",
"fee": "1,500,000 VNĐ",
"requirements": [
"Hộ chiếu còn hạn trên 6 tháng",
"Ảnh 3.5x4.5cm",
"Chứng minh tài chính",
"Lịch trình du lịch",
"Bảo hiểm du lịch"
],
"description": "Visa Hàn Quốc cho phép du lịch và khám phá văn hóa K-pop"
}
]
},
{
"name": "Châu Đại Dương",
"countries": [
{
"id": "australia",
"name": "Úc",
"flag": "🇦🇺",
"visaTypes": ["Visitor", "Student", "Work"],
"processingTime": "15-30 ngày",
"validityPeriod": "1 năm",
"fee": "4,200,000 VNĐ",
"requirements": [
"Hộ chiếu còn hạn trên 6 tháng",
"Ảnh passport",
"Chứng minh tài chính",
"Bảo hiểm y tế",
"Khám sức khỏe"
],
"description": "Visa Úc cho phép du lịch và khám phá lục địa kangaroo"
},
{
"id": "newzealand",
"name": "New Zealand",
"flag": "🇳🇿",
"visaTypes": ["Visitor", "Student", "Work"],
"processingTime": "20-25 ngày",
"validityPeriod": "9 tháng",
"fee": "3,500,000 VNĐ",
"requirements": [
"Hộ chiếu còn hạn trên 3 tháng",
"Ảnh passport",
"Chứng minh tài chính",
"Bảo hiểm du lịch",
"Lịch trình chi tiết"
],
"description": "Visa New Zealand cho phép khám phá xứ sở cừu và phong cảnh tuyệt đẹp"
}
]
}
],
"popularCountries": [
{
"id": "japan",
"name": "Nhật Bản",
"flag": "🇯🇵",
"reason": "Thủ tục đơn giản, tỷ lệ thành công cao"
},
{
"id": "korea",
"name": "Hàn Quốc",
"flag": "🇰🇷",
"reason": "Văn hóa K-pop, ẩm thực hấp dẫn"
},
{
"id": "schengen",
"name": "Schengen",
"flag": "🇪🇺",
"reason": "Một visa đi được 26 quốc gia"
},
{
"id": "usa",
"name": "Mỹ",
"flag": "🇺🇸",
"reason": "Visa 10 năm, nhiều cơ hội"
}
]
}
+231
View File
@@ -0,0 +1,231 @@
"use client";
import { useState } from "react";
import countriesData from "./countries.json";
export default function CountriesPage() {
const [selectedRegion, setSelectedRegion] = useState("all");
const [selectedCountry, setSelectedCountry] = useState<string | null>(null);
const filteredRegions =
selectedRegion === "all"
? countriesData.regions
: countriesData.regions.filter(
(region) => region.name === selectedRegion,
);
const handleCountryClick = (countryId: string) => {
setSelectedCountry(selectedCountry === countryId ? null : countryId);
};
const getCountryById = (id: string) => {
for (const region of countriesData.regions) {
const country = region.countries.find((c) => c.id === id);
if (country) return country;
}
return null;
};
return (
<div className="container mx-auto px-4 py-8">
<div className="max-w-6xl mx-auto">
{/* Header */}
<div className="text-center mb-12">
<h1 className="text-4xl font-bold text-gray-900 mb-4">
{countriesData.title}
</h1>
<p className="text-xl text-gray-600">{countriesData.subtitle}</p>
</div>
{/* Popular Countries */}
<div className="mb-12">
<h2 className="text-2xl font-bold text-gray-900 mb-6 text-center">
Quốc Gia Phổ Biến
</h2>
<div className="grid md:grid-cols-4 gap-6">
{countriesData.popularCountries.map((country) => (
<div
key={country.id}
className="bg-white rounded-lg shadow-md p-6 text-center hover:shadow-lg transition-shadow cursor-pointer"
onClick={() => handleCountryClick(country.id)}
>
<div className="text-4xl mb-3">{country.flag}</div>
<h3 className="font-semibold text-gray-900 mb-2">
{country.name}
</h3>
<p className="text-gray-600 text-sm">{country.reason}</p>
</div>
))}
</div>
</div>
{/* Region Filter */}
<div className="mb-8">
<div className="flex flex-wrap gap-4 justify-center">
<button
onClick={() => setSelectedRegion("all")}
className={`px-6 py-2 rounded-full transition-colors ${
selectedRegion === "all"
? "bg-blue-600 text-white"
: "bg-gray-100 text-gray-700 hover:bg-gray-200"
}`}
>
Tất cả
</button>
{countriesData.regions.map((region) => (
<button
key={region.name}
onClick={() => setSelectedRegion(region.name)}
className={`px-6 py-2 rounded-full transition-colors ${
selectedRegion === region.name
? "bg-blue-600 text-white"
: "bg-gray-100 text-gray-700 hover:bg-gray-200"
}`}
>
{region.name}
</button>
))}
</div>
</div>
{/* Countries by Region */}
<div className="space-y-12">
{filteredRegions.map((region) => (
<div key={region.name}>
<h2 className="text-2xl font-bold text-gray-900 mb-6">
{region.name}
</h2>
<div className="grid md:grid-cols-2 gap-6">
{region.countries.map((country) => (
<div
key={country.id}
className="bg-white rounded-lg shadow-md overflow-hidden"
>
{/* Country Header */}
<div
className="p-6 cursor-pointer hover:bg-gray-50 transition-colors"
onClick={() => handleCountryClick(country.id)}
>
<div className="flex items-center justify-between">
<div className="flex items-center">
<span className="text-3xl mr-4">{country.flag}</span>
<div>
<h3 className="text-xl font-semibold text-gray-900">
{country.name}
</h3>
<p className="text-gray-600">
{country.description}
</p>
</div>
</div>
<span className="text-gray-400">
{selectedCountry === country.id ? "▼" : "▶"}
</span>
</div>
{/* Quick Info */}
<div className="grid grid-cols-2 gap-4 mt-4 text-sm">
<div>
<span className="text-gray-500">
Thời gian xử :
</span>
<div className="font-medium">
{country.processingTime}
</div>
</div>
<div>
<span className="text-gray-500">Phí visa:</span>
<div className="font-medium text-blue-600">
{country.fee}
</div>
</div>
</div>
</div>
{/* Detailed Info */}
{selectedCountry === country.id && (
<div className="border-t bg-gray-50 p-6">
<div className="grid md:grid-cols-2 gap-6">
{/* Visa Types */}
<div>
<h4 className="font-semibold text-gray-900 mb-3">
Loại visa:
</h4>
<div className="flex flex-wrap gap-2">
{country.visaTypes.map((type, index) => (
<span
key={index}
className="bg-blue-100 text-blue-800 px-2 py-1 rounded text-sm"
>
{type}
</span>
))}
</div>
</div>
{/* Validity */}
<div>
<h4 className="font-semibold text-gray-900 mb-3">
Thời hạn visa:
</h4>
<p className="text-gray-700">
{country.validityPeriod}
</p>
</div>
</div>
{/* Requirements */}
<div className="mt-6">
<h4 className="font-semibold text-gray-900 mb-3">
Yêu cầu hồ :
</h4>
<ul className="space-y-2">
{country.requirements.map((req, index) => (
<li
key={index}
className="flex items-start text-gray-700"
>
<span className="text-green-500 mr-2 mt-1">
</span>
{req}
</li>
))}
</ul>
</div>
{/* CTA */}
<div className="mt-6 flex gap-4">
<button className="bg-blue-600 text-white px-6 py-2 rounded-lg hover:bg-blue-700 transition-colors">
vấn ngay
</button>
<button className="bg-gray-100 text-gray-700 px-6 py-2 rounded-lg hover:bg-gray-200 transition-colors">
Xem chi tiết
</button>
</div>
</div>
)}
</div>
))}
</div>
</div>
))}
</div>
{/* Contact CTA */}
<div className="text-center mt-12 bg-blue-50 rounded-lg p-8">
<h2 className="text-2xl font-bold text-gray-900 mb-4">
Không Tìm Thấy Quốc Gia Bạn Cần?
</h2>
<p className="text-gray-700 mb-6">
Chúng tôi hỗ trợ visa cho hơn 50 quốc gia. Liên hệ đ đưc vấn
chi tiết
</p>
<button className="bg-blue-600 text-white px-8 py-3 rounded-lg hover:bg-blue-700 transition-colors">
Liên hệ vấn
</button>
</div>
</div>
</div>
);
}
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

+11
View File
@@ -0,0 +1,11 @@
@charset "UTF-8";
@import "tailwindcss";
:root {
--body: #fff;
--font-primary: var(--font-inter);
--font-heading: var(--font-space-grotesk);
}
body {
font-family: var(--font-primary);
}
+145
View File
@@ -0,0 +1,145 @@
import type { Metadata } from "next";
import Script from "next/script";
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";
import Header from "./components/Header";
import Footer from "./components/Footer";
import { Inter, Space_Grotesk } from "next/font/google";
const ASSET_URL = process.env.NEXT_PUBLIC_API_URL || "";
const inter = Inter({
subsets: ["latin"],
variable: "--font-inter",
});
const spaceGrotesk = Space_Grotesk({
subsets: ["latin"],
variable: "--font-space-grotesk",
});
export const metadata: Metadata = {
title: "VisaService - Dịch vụ visa uy tín",
description:
"Dịch vụ visa chuyên nghiệp với tỷ lệ thành công 99%. Hỗ trợ visa cho hơn 50 quốc gia.",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
//
return (
<html lang="en" className={`${inter.variable} ${spaceGrotesk.variable}`}>
<body>{children}</body>
</html>
);
}
// <html lang="vi">
// <head>
// {/* Font Awesome 6.4.0 from CDN - for reliable icon support */}
// <link rel="stylesheet" href="../public/assets/css" />
// {/* Bootstrap min.css */}
// <link
// rel="stylesheet"
// href={`${ASSET_URL}/assets/css/bootstrap.min.css`}
// />
// {/* Animate.css */}
// <link rel="stylesheet" href={`${ASSET_URL}/assets/css/animate.css`} />
// {/* Magnific Popup.css */}
// <link
// rel="stylesheet"
// href={`${ASSET_URL}/assets/css/magnific-popup.css`}
// />
// {/* MeanMenu.css */}
// <link rel="stylesheet" href={`${ASSET_URL}/assets/css/meanmenu.css`} />
// {/* Odometer.css */}
// <link rel="stylesheet" href={`${ASSET_URL}/assets/css/odometer.css`} />
// {/* Swiper Bundle.css */}
// <link
// rel="stylesheet"
// href={`${ASSET_URL}/assets/css/swiper-bundle.min.css`}
// />
// {/* Nice Select.css */}
// <link
// rel="stylesheet"
// href={`${ASSET_URL}/assets/css/nice-select.css`}
// />
// {/* Main.css */}
// <link rel="stylesheet" href={`${ASSET_URL}/assets/css/main.css`} />
// </head>
// <body
// className={`${geistSans.variable} ${geistMono.variable} antialiased bg-gray-50`}
// >
// <Header />
// <main className="min-h-screen">{children}</main>
// <Footer />
// {/* Scripts */}
// <Script
// src={`${ASSET_URL}/assets/js/jquery-3.7.1.min.js`}
// strategy="beforeInteractive"
// />
// <Script
// src={`${ASSET_URL}/assets/js/viewport.jquery.js`}
// strategy="afterInteractive"
// />
// <Script
// src={`${ASSET_URL}/assets/js/bootstrap.bundle.min.js`}
// strategy="afterInteractive"
// />
// <Script
// src={`${ASSET_URL}/assets/js/jquery.nice-select.min.js`}
// strategy="afterInteractive"
// />
// <Script
// src={`${ASSET_URL}/assets/js/jquery.waypoints.js`}
// strategy="afterInteractive"
// />
// <Script
// src={`${ASSET_URL}/assets/js/odometer.min.js`}
// strategy="afterInteractive"
// />
// <Script
// src={`${ASSET_URL}/assets/js/swiper-bundle.min.js`}
// strategy="afterInteractive"
// />
// <Script
// src={`${ASSET_URL}/assets/js/jquery.meanmenu.min.js`}
// strategy="afterInteractive"
// />
// <Script
// src={`${ASSET_URL}/assets/js/jquery.magnific-popup.min.js`}
// strategy="afterInteractive"
// />
// <Script
// src={`${ASSET_URL}/assets/js/wow.min.js`}
// strategy="afterInteractive"
// />
// <Script
// src={`${ASSET_URL}/assets/js/circle-progress.js`}
// strategy="afterInteractive"
// />
// <Script
// src={`${ASSET_URL}/assets/js/gsap.js`}
// strategy="afterInteractive"
// />
// <Script
// src={`${ASSET_URL}/assets/js/lenis.min.js`}
// strategy="afterInteractive"
// />
// <Script
// src={`${ASSET_URL}/assets/js/ScrollTrigger.min.js`}
// strategy="afterInteractive"
// />
// <Script
// src={`${ASSET_URL}/assets/js/SplitText.min.js`}
// strategy="afterInteractive"
// />
// <Script
// src={`${ASSET_URL}/assets/js/main.js`}
// strategy="afterInteractive"
// />
// </body>
// </html>
// );
+65
View File
@@ -0,0 +1,65 @@
import Image from "next/image";
export default function Home() {
return (
<div className="flex min-h-screen items-center justify-center bg-zinc-50 font-sans dark:bg-black">
<main className="flex min-h-screen w-full max-w-3xl flex-col items-center justify-between py-32 px-16 bg-white dark:bg-black sm:items-start">
<Image
className="dark:invert"
src="/next.svg"
alt="Next.js logo"
width={100}
height={20}
priority
/>
<div className="flex flex-col items-center gap-6 text-center sm:items-start sm:text-left">
<h1 className="max-w-xs text-3xl font-semibold leading-10 tracking-tight text-black dark:text-zinc-50">
To get started, edit the page.tsx file.
</h1>
<p className="max-w-md text-lg leading-8 text-zinc-600 dark:text-zinc-400">
Looking for a starting point or more instructions? Head over to{" "}
<a
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
className="font-medium text-zinc-950 dark:text-zinc-50"
>
Templates
</a>{" "}
or the{" "}
<a
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
className="font-medium text-zinc-950 dark:text-zinc-50"
>
Learning
</a>{" "}
center.
</p>
</div>
<div className="flex flex-col gap-4 text-base font-medium sm:flex-row">
<a
className="flex h-12 w-full items-center justify-center gap-2 rounded-full bg-foreground px-5 text-background transition-colors hover:bg-[#383838] dark:hover:bg-[#ccc] md:w-[158px]"
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
className="dark:invert"
src="/vercel.svg"
alt="Vercel logomark"
width={16}
height={16}
/>
Deploy Now
</a>
<a
className="flex h-12 w-full items-center justify-center rounded-full border border-solid border-black/[.08] px-5 transition-colors hover:border-transparent hover:bg-black/[.04] dark:border-white/[.145] dark:hover:bg-[#1a1a1a] md:w-[158px]"
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
Documentation
</a>
</div>
</main>
</div>
);
}
+188
View File
@@ -0,0 +1,188 @@
import pricingData from "./pricing.json";
export default function PricingPage() {
return (
<div className="container mx-auto px-4 py-8">
<div className="max-w-6xl mx-auto">
{/* Header */}
<div className="text-center mb-12">
<h1 className="text-4xl font-bold text-gray-900 mb-4">
{pricingData.title}
</h1>
<p className="text-xl text-gray-600 mb-4">{pricingData.subtitle}</p>
<p className="text-sm text-gray-500 bg-yellow-50 p-3 rounded-lg inline-block">
💡 {pricingData.note}
</p>
</div>
{/* Pricing Packages */}
<div className="grid md:grid-cols-3 gap-8 mb-16">
{pricingData.packages.map((pkg) => (
<div
key={pkg.id}
className={`relative bg-white rounded-lg shadow-lg p-6 ${
pkg.popular ? "ring-2 ring-blue-500 transform scale-105" : ""
}`}
>
{/* Popular Badge */}
{pkg.popular && (
<div className="absolute -top-3 left-1/2 transform -translate-x-1/2">
<span className="bg-blue-500 text-white px-4 py-1 rounded-full text-sm font-medium">
Phổ biến nhất
</span>
</div>
)}
{/* Package Header */}
<div className="text-center mb-6">
<h3 className="text-2xl font-bold text-gray-900 mb-2">
{pkg.name}
</h3>
<p className="text-gray-600 mb-4">{pkg.description}</p>
<div className="text-3xl font-bold text-blue-600">
{parseInt(pkg.price).toLocaleString()} {pkg.currency}
</div>
</div>
{/* Features */}
<div className="mb-6">
<h4 className="font-semibold text-gray-900 mb-3">Bao gồm:</h4>
<ul className="space-y-2">
{pkg.features.map((feature, index) => (
<li key={index} className="flex items-center text-gray-700">
<span className="text-green-500 mr-2"></span>
{feature}
</li>
))}
</ul>
</div>
{/* Limitations */}
{pkg.limitations.length > 0 && (
<div className="mb-6">
<h4 className="font-semibold text-gray-900 mb-3">Lưu ý:</h4>
<ul className="space-y-2">
{pkg.limitations.map((limitation, index) => (
<li
key={index}
className="flex items-center text-gray-600 text-sm"
>
<span className="text-orange-500 mr-2"></span>
{limitation}
</li>
))}
</ul>
</div>
)}
{/* CTA Button */}
<button
className={`w-full py-3 px-6 rounded-lg font-medium transition-colors ${
pkg.popular
? "bg-blue-600 text-white hover:bg-blue-700"
: "bg-gray-100 text-gray-900 hover:bg-gray-200"
}`}
>
Chọn gói này
</button>
</div>
))}
</div>
{/* Additional Services */}
<div className="mb-16">
<h2 className="text-2xl font-bold text-gray-900 mb-8 text-center">
Dịch Vụ Bổ Sung
</h2>
<div className="grid md:grid-cols-2 lg:grid-cols-4 gap-6">
{pricingData.additionalServices.map((service, index) => (
<div
key={index}
className="bg-white rounded-lg shadow-md p-6 text-center"
>
<h3 className="font-semibold text-gray-900 mb-2">
{service.name}
</h3>
<div className="text-2xl font-bold text-blue-600 mb-2">
{parseInt(service.price).toLocaleString()} VNĐ
</div>
<div className="text-sm text-gray-500 mb-3">
/{service.unit}
</div>
<p className="text-gray-700 text-sm">{service.description}</p>
</div>
))}
</div>
</div>
{/* Country Pricing */}
<div>
<h2 className="text-2xl font-bold text-gray-900 mb-8 text-center">
Phí Visa Theo Quốc Gia
</h2>
<div className="bg-white rounded-lg shadow-lg overflow-hidden">
<div className="overflow-x-auto">
<table className="w-full">
<thead className="bg-gray-50">
<tr>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Quốc gia
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Phí visa
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Thời gian xử
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Tỷ lệ thành công
</th>
</tr>
</thead>
<tbody className="bg-white divide-y divide-gray-200">
{pricingData.countries.map((country, index) => (
<tr key={index} className="hover:bg-gray-50">
<td className="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">
{country.name}
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
{parseInt(country.visaFee).toLocaleString()} VNĐ
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
{country.processingTime}
</td>
<td className="px-6 py-4 whitespace-nowrap">
<span className="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">
{country.successRate}
</span>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
{/* Contact CTA */}
<div className="text-center mt-12 bg-blue-50 rounded-lg p-8">
<h2 className="text-2xl font-bold text-gray-900 mb-4">
Cần Vấn Chi Tiết?
</h2>
<p className="text-gray-700 mb-6">
Liên hệ với chúng tôi đ đưc vấn miễn phí nhận báo giá phù
hợp nhất
</p>
<div className="flex flex-col sm:flex-row gap-4 justify-center">
<button className="bg-blue-600 text-white px-8 py-3 rounded-lg hover:bg-blue-700 transition-colors">
vấn miễn phí
</button>
<button className="bg-white text-blue-600 border border-blue-600 px-8 py-3 rounded-lg hover:bg-blue-50 transition-colors">
Gọi ngay: 1900 1234
</button>
</div>
</div>
</div>
</div>
);
}
+128
View File
@@ -0,0 +1,128 @@
{
"title": "Bảng Giá Dịch Vụ",
"subtitle": "Giá cả minh bạch, không phí ẩn",
"note": "Giá có thể thay đổi tùy theo từng trường hợp cụ thể. Liên hệ để được tư vấn chi tiết.",
"packages": [
{
"id": "basic",
"name": "Gói Cơ Bản",
"description": "Phù hợp cho khách hàng lần đầu xin visa",
"price": "1,500,000",
"currency": "VNĐ",
"popular": false,
"features": [
"Tư vấn miễn phí",
"Kiểm tra hồ sơ cơ bản",
"Hướng dẫn điền form",
"Hỗ trợ qua email",
"Bảo hành 30 ngày"
],
"limitations": [
"Không bao gồm phí lãnh sự",
"Không dịch thuật",
"Hỗ trợ trong giờ hành chính"
]
},
{
"id": "premium",
"name": "Gói Cao Cấp",
"description": "Dịch vụ toàn diện với nhiều ưu đãi",
"price": "3,500,000",
"currency": "VNĐ",
"popular": true,
"features": [
"Tất cả tính năng gói Cơ Bản",
"Dịch thuật chuyên nghiệp",
"Kiểm tra hồ sơ chi tiết",
"Hỗ trợ 24/7",
"Bảo hành 90 ngày",
"Tư vấn trực tiếp",
"Hỗ trợ booking phỏng vấn"
],
"limitations": ["Không bao gồm phí lãnh sự"]
},
{
"id": "vip",
"name": "Gói VIP",
"description": "Dịch vụ cao cấp nhất với cam kết thành công",
"price": "6,500,000",
"currency": "VNĐ",
"popular": false,
"features": [
"Tất cả tính năng gói Cao Cấp",
"Cam kết thành công 99%",
"Hoàn tiền nếu bị từ chối",
"Tư vấn 1-1 với chuyên gia",
"Ưu tiên xử lý hồ sơ",
"Bảo hành 1 năm",
"Hỗ trợ sau khi có visa",
"Tặng bảo hiểm du lịch"
],
"limitations": []
}
],
"additionalServices": [
{
"name": "Dịch thuật công chứng",
"price": "200,000",
"unit": "trang",
"description": "Dịch thuật và công chứng các loại giấy tờ"
},
{
"name": "Chụp ảnh visa",
"price": "100,000",
"unit": "bộ",
"description": "Chụp ảnh theo tiêu chuẩn từng quốc gia"
},
{
"name": "Đặt lịch phỏng vấn",
"price": "500,000",
"unit": "lần",
"description": "Hỗ trợ đặt lịch phỏng vấn tại lãnh sự quán"
},
{
"name": "Tư vấn phỏng vấn",
"price": "800,000",
"unit": "buổi",
"description": "Luyện tập và tư vấn kỹ năng phỏng vấn"
}
],
"countries": [
{
"name": "Mỹ",
"visaFee": "4,600,000",
"processingTime": "3-5 tuần",
"successRate": "95%"
},
{
"name": "Schengen",
"visaFee": "2,200,000",
"processingTime": "2-3 tuần",
"successRate": "98%"
},
{
"name": "Anh",
"visaFee": "3,800,000",
"processingTime": "3-4 tuần",
"successRate": "96%"
},
{
"name": "Canada",
"visaFee": "2,800,000",
"processingTime": "4-6 tuần",
"successRate": "94%"
},
{
"name": "Úc",
"visaFee": "4,200,000",
"processingTime": "2-4 tuần",
"successRate": "97%"
},
{
"name": "Nhật Bản",
"visaFee": "1,200,000",
"processingTime": "1-2 tuần",
"successRate": "99%"
}
]
}
+73
View File
@@ -0,0 +1,73 @@
import servicesData from "./services.json";
export default function ServicesPage() {
return (
<div className="container mx-auto px-4 py-8">
<div className="max-w-6xl mx-auto">
{/* Header */}
<div className="text-center mb-12">
<h1 className="text-4xl font-bold text-gray-900 mb-4">
{servicesData.title}
</h1>
<p className="text-xl text-gray-600">{servicesData.subtitle}</p>
</div>
{/* Services Grid */}
<div className="grid md:grid-cols-2 lg:grid-cols-2 gap-8">
{servicesData.services.map((service) => (
<div
key={service.id}
className="bg-white rounded-lg shadow-lg p-6 hover:shadow-xl transition-shadow"
>
{/* Service Header */}
<div className="flex items-center mb-4">
<span className="text-4xl mr-4">{service.icon}</span>
<div>
<h3 className="text-xl font-semibold text-gray-900">
{service.name}
</h3>
<p className="text-blue-600 font-medium">{service.price}</p>
</div>
</div>
{/* Description */}
<p className="text-gray-700 mb-6">{service.description}</p>
{/* Features */}
<div className="mb-6">
<h4 className="font-semibold text-gray-900 mb-3">Tính năng:</h4>
<ul className="space-y-2">
{service.features.map((feature, index) => (
<li key={index} className="flex items-center text-gray-700">
<span className="text-green-500 mr-2"></span>
{feature}
</li>
))}
</ul>
</div>
{/* CTA Button */}
<button className="w-full bg-blue-600 text-white py-2 px-4 rounded-lg hover:bg-blue-700 transition-colors">
Tìm Hiểu Thêm
</button>
</div>
))}
</div>
{/* Contact CTA */}
<div className="text-center mt-12 bg-gray-50 rounded-lg p-8">
<h2 className="text-2xl font-bold text-gray-900 mb-4">
Cần Vấn Thêm?
</h2>
<p className="text-gray-700 mb-6">
Liên hệ với chúng tôi đ đưc vấn miễn phí nhận báo giá chi
tiết
</p>
<button className="bg-green-600 text-white px-8 py-3 rounded-lg hover:bg-green-700 transition-colors">
Liên Hệ Ngay
</button>
</div>
</div>
</div>
);
}
+58
View File
@@ -0,0 +1,58 @@
{
"title": "Dịch Vụ Của Chúng Tôi",
"subtitle": "Giải pháp toàn diện cho nhu cầu visa và du lịch",
"services": [
{
"id": "visa-consulting",
"name": "Tư Vấn Visa",
"description": "Tư vấn chuyên sâu về thủ tục visa cho hơn 50 quốc gia",
"icon": "🛂",
"features": [
"Tư vấn miễn phí",
"Hỗ trợ 24/7",
"Đảm bảo thành công",
"Thủ tục nhanh chóng"
],
"price": "Từ 500,000 VNĐ"
},
{
"id": "document-preparation",
"name": "Chuẩn Bị Hồ Sơ",
"description": "Hỗ trợ chuẩn bị và kiểm tra hồ sơ visa chính xác",
"icon": "📋",
"features": [
"Kiểm tra hồ sơ kỹ lưỡng",
"Hướng dẫn chi tiết",
"Dịch thuật chuyên nghiệp",
"Bảo mật thông tin"
],
"price": "Từ 300,000 VNĐ"
},
{
"id": "travel-booking",
"name": "Đặt Vé & Khách Sạn",
"description": "Dịch vụ đặt vé máy bay và khách sạn với giá ưu đãi",
"icon": "✈️",
"features": [
"Giá cạnh tranh",
"Đặt chỗ linh hoạt",
"Hỗ trợ thay đổi",
"Bảo hiểm du lịch"
],
"price": "Phí dịch vụ 2%"
},
{
"id": "tour-packages",
"name": "Tour Trọn Gói",
"description": "Các gói tour du lịch được thiết kế chuyên nghiệp",
"icon": "🌍",
"features": [
"Lịch trình linh hoạt",
"Hướng dẫn viên chuyên nghiệp",
"Bao gồm visa",
"Bảo hiểm toàn diện"
],
"price": "Từ 15,000,000 VNĐ"
}
]
}
+416
View File
@@ -0,0 +1,416 @@
"use client";
import React, { useState, useEffect } from "react";
import Link from "next/link";
import visaData from "../visa.json";
const ASSET_URL = process.env.NEXT_PUBLIC_API_URL || "";
interface CountryDetailsClientProps {
country: {
id: number;
name: string;
icon: string;
services: string[];
};
}
export default function CountryDetailsClient({
country,
}: CountryDetailsClientProps) {
const [showBackToTop, setShowBackToTop] = useState(false);
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
// Get detailed data from visa.json
const countryData = visaData.visaSystem.detailedView.activeCountry;
const relatedCountries =
visaData.visaSystem.detailedView.relatedCountries.map((c: any) => ({
...c,
icon: `${ASSET_URL}/${c.icon}`,
}));
const contactInfo = visaData.visaSystem.contactInfo;
useEffect(() => {
const handleScroll = () => setShowBackToTop(window.scrollY > 100);
window.addEventListener("scroll", handleScroll);
return () => window.removeEventListener("scroll", handleScroll);
}, []);
const scrollToTop = () => window.scrollTo({ top: 0, behavior: "smooth" });
return (
<>
{/* Back to Top */}
<button
onClick={scrollToTop}
className={`fixed bottom-8 right-8 w-12 h-12 rounded-full bg-white shadow-lg flex items-center justify-center cursor-pointer transition-all z-40 ${
showBackToTop ? "opacity-100" : "opacity-0 pointer-events-none"
}`}
>
<svg
className="w-6 h-6 text-blue-600"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M7 11l5-5m0 0l5 5m-5-5v12"
/>
</svg>
</button>
{/* Header Top */}
<div className="bg-gray-900 text-white py-3 hidden lg:block">
<div className="max-w-7xl mx-auto px-8 flex justify-between items-center text-sm">
<ul className="flex gap-8">
<li>
<a href="tel:+093783575222">+09 378 357 5222</a>
</li>
<li>69 Street, 5th Avenue LA, United States</li>
<li>
<a href="mailto:info@example.com">info@example.com</a>
</li>
</ul>
<select className="bg-gray-900 text-white border-0 outline-none cursor-pointer">
<option>English</option>
<option>Bangla</option>
<option>Hindi</option>
</select>
</div>
</div>
{/* Header */}
<header className="sticky top-0 z-20 bg-white shadow-md">
<div className="max-w-7xl mx-auto px-4 lg:px-8 py-4 flex justify-between items-center">
<Link href="/" className="flex-shrink-0">
<img
src={`${ASSET_URL}/assets/img/logo/black-logo.svg`}
alt="logo"
className="h-10"
/>
</Link>
<nav className="hidden lg:flex gap-8">
<Link href="/" className="text-gray-700 hover:text-blue-600">
Home
</Link>
<Link href="/about" className="text-gray-700 hover:text-blue-600">
About Us
</Link>
<Link
href="/country-list"
className="text-gray-700 hover:text-blue-600"
>
VISA
</Link>
<Link href="/contact" className="text-gray-700 hover:text-blue-600">
Contact Us
</Link>
</nav>
<button
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
className="lg:hidden text-2xl"
>
</button>
</div>
</header>
{/* Mobile Menu */}
{isMobileMenuOpen && (
<div className="fixed inset-0 z-30 lg:hidden">
<div
className="absolute inset-0 bg-black/50"
onClick={() => setIsMobileMenuOpen(false)}
></div>
<div className="absolute left-0 top-0 w-80 h-full bg-white p-6 overflow-y-auto">
<button
onClick={() => setIsMobileMenuOpen(false)}
className="float-right text-2xl"
>
</button>
<nav className="space-y-3 mt-8">
<Link href="/" className="block py-2">
Home
</Link>
<Link href="/about" className="block py-2">
About Us
</Link>
<Link href="/country-list" className="block py-2">
Visa
</Link>
<Link href="/contact" className="block py-2">
Contact Us
</Link>
</nav>
</div>
</div>
)}
{/* Breadcrumb */}
<section
className="py-20 px-4 lg:px-8 bg-cover relative"
style={{
backgroundImage: `url('${ASSET_URL}/${countryData.mainImage}')`,
}}
>
<div className="absolute inset-0 bg-black/30"></div>
<div className="max-w-7xl mx-auto relative z-10 text-center text-white">
<h1 className="text-5xl font-bold mb-6">{countryData.title}</h1>
<ul className="flex justify-center gap-4">
<li>
<Link href="/">Home</Link>
</li>
<li></li>
<li>{countryData.name}</li>
</ul>
</div>
</section>
{/* Country Details */}
<section className="py-20 px-4 lg:px-8">
<div className="max-w-7xl mx-auto">
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
{/* Main Content */}
<div className="lg:col-span-2">
<img
src={`${ASSET_URL}/${countryData.mainImage}`}
alt={countryData.name}
className="w-full rounded-lg mb-8"
/>
<h2 className="text-4xl font-bold mb-4">{countryData.name}</h2>
<p className="text-gray-700 mb-4">{countryData.description}</p>
<p className="text-gray-700 mb-4">{countryData.additionalInfo}</p>
<h5 className="text-xl font-semibold mb-6">
{countryData.tagline}
</h5>
{/* Visa Types */}
<div className="grid grid-cols-2 gap-6 mb-8">
{countryData.visaTypes.map((typeGroup: any, idx: number) => (
<React.Fragment key={idx}>
{typeGroup.items.map((item: any, itemIdx: number) => (
<div
key={itemIdx}
className="p-6 border-l-4 border-blue-600"
>
<h5 className="font-bold mb-2">{item.title}</h5>
<p className="text-sm text-gray-600">
{item.description}
</p>
</div>
))}
</React.Fragment>
))}
</div>
{/* Visa Process */}
<h3 className="text-2xl font-bold mb-6">USA Visa Process</h3>
<ul className="space-y-4 mb-8">
{countryData.visaProcess.steps.map((process: any) => (
<li key={process.number} className="flex gap-4">
<span className="font-bold text-blue-600 flex-shrink-0">
{process.number}.
</span>
<span>
<strong>{process.title}</strong> {process.description}
</span>
</li>
))}
</ul>
{/* Gallery */}
<div className="grid grid-cols-2 gap-6 mb-8">
{countryData.gallery.map((image: string, idx: number) => (
<img
key={idx}
src={`${ASSET_URL}/${image}`}
alt={`${countryData.name} gallery`}
className="rounded-lg w-full"
/>
))}
</div>
{/* Visa Types List */}
<h3 className="text-2xl font-bold mb-6">Types of Visas</h3>
{countryData.visaCategories.steps.map(
(subGroup: string[], groupIdx: number) => (
<ul className="visa-list-2" key={groupIdx}>
{/* Map lần 2 để render từng chuỗi trong mảng con */}
{subGroup.map((category: string, idx: number) => (
<li key={idx}>
<i className="fa-solid fa-chevrons-right"></i>
{category}
</li>
))}
</ul>
),
)}
{/* Service Options */}
<h3 className="text-2xl font-bold mb-6">
Our {countryData.name} Visa Service Options
</h3>
<ul className="space-y-4">
{countryData.visaProcess.steps.map((process: any) => (
<li key={process.number} className="flex gap-4">
<span className="font-bold text-blue-600 flex-shrink-0">
{process.number}.
</span>
<span>
<strong>{process.title}</strong> {process.description}
</span>
</li>
))}
</ul>
</div>
{/* Sidebar */}
<div className="lg:col-span-1">
{/* Related Countries */}
<div className="bg-white rounded-lg shadow-lg p-6 mb-6">
{relatedCountries.map((c: any) => (
<div
key={c.id}
className="flex items-center justify-between py-4 border-b last:border-0 cursor-pointer hover:text-blue-600"
>
<div className="flex items-center gap-3">
<img src={c.icon} alt={c.name} className="w-10 h-10" />
<h5 className="font-medium">{c.name}</h5>
</div>
<span className="text-blue-600"></span>
</div>
))}
</div>
{/* Contact Box */}
<div
className="rounded-lg p-6 text-white relative"
style={{
backgroundImage: `url('${ASSET_URL}/assets/img/inner-page/country-details/bg.jpg')`,
backgroundSize: "cover",
}}
>
<div className="absolute inset-0 bg-black/60 rounded-lg"></div>
<div className="relative z-10">
<h3 className="text-2xl font-bold mb-2">
Visa & Immigration
</h3>
<p className="mb-6">Need Help? Book Lab Visit</p>
<div className="space-y-4">
<div className="flex gap-3">
<div className="w-10 h-10 rounded-full bg-blue-600 flex items-center justify-center flex-shrink-0">
📞
</div>
<div>
<span className="text-sm">Call Us:</span>
<p className="font-bold">
<a href={`tel:${contactInfo.phone}`}>
{contactInfo.phone}
</a>
</p>
</div>
</div>
<div className="flex gap-3">
<div className="w-10 h-10 rounded-full bg-blue-600 flex items-center justify-center flex-shrink-0">
</div>
<div>
<span className="text-sm">Mail Us:</span>
<p className="font-bold">
<a href={`mailto:${contactInfo.email}`}>
{contactInfo.email}
</a>
</p>
</div>
</div>
<div className="flex gap-3">
<div className="w-10 h-10 rounded-full bg-blue-600 flex items-center justify-center flex-shrink-0">
📍
</div>
<div>
<span className="text-sm">Location:</span>
<p className="font-bold">{contactInfo.location}</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
{/* Footer */}
<footer
className="py-20 px-4 lg:px-8 bg-cover text-white relative"
style={{
backgroundImage: `url('${ASSET_URL}/assets/img/home-1/footer-bg.jpg')`,
}}
>
<div className="absolute inset-0 bg-black/60"></div>
<div className="max-w-7xl mx-auto relative z-10 text-center">
<h2 className="text-3xl font-bold mb-4">
<a href="tel:+16336547896">+163 3654 7896</a>
</h2>
<h2 className="text-xl mb-8">
69 Street, 5th Avenue LA, United States
</h2>
<Link href="/">
<img
src={`${ASSET_URL}/assets/img/logo/white-logo.svg`}
alt="logo"
className="h-10 mx-auto mb-8"
/>
</Link>
<ul className="flex flex-wrap justify-center gap-8 mb-8">
<li>
<a href="/" className="hover:text-blue-300">
Home
</a>
</li>
<li>
<a href="/about" className="hover:text-blue-300">
About Us
</a>
</li>
<li>
<a href="/country-list" className="hover:text-blue-300">
Visa
</a>
</li>
<li>
<a href="/blog" className="hover:text-blue-300">
Pages
</a>
</li>
<li>
<a href="/contact" className="hover:text-blue-300">
Contact Us
</a>
</li>
</ul>
<div className="flex justify-center gap-6">
<a href="#" className="hover:text-blue-300">
𝕏
</a>
<a href="#" className="hover:text-blue-300">
📷
</a>
<a href="#" className="hover:text-blue-300">
in
</a>
<a href="#" className="hover:text-blue-300">
</a>
</div>
</div>
</footer>
</>
);
}
+283
View File
@@ -0,0 +1,283 @@
"use client";
import { useState, useEffect } from "react";
import React from "react";
import visaData from "../visa.json";
import Breadcrumb from "../components/Breadcrumb";
const ASSET_URL = process.env.NEXT_PUBLIC_API_URL || "";
interface VisaCountryData {
id: number;
name: string;
icon: string;
services: string[];
}
interface CountryDetailsProps {
params: Promise<{
slug: string;
}>;
}
// Helper function to map slugs to country names
const getCountryFromSlug = (slug: string): string => {
const slugToCountry: { [key: string]: string } = {
france: "France",
uk: "UK",
canada: "Canada",
germany: "Germany",
spain: "Spain",
"south-korea": "South Korea",
japan: "Japan",
croatia: "Croatia",
england: "England",
indonesia: "Indonesia",
"united-states-of-america": "United States of America",
};
return slugToCountry[slug] || slug;
};
export default function CountryDetailsPage({ params }: CountryDetailsProps) {
const [country, setCountry] = useState<VisaCountryData | null>(null);
const [loading, setLoading] = useState(true);
const [slug, setSlug] = useState<string>("");
useEffect(() => {
// Unwrap the params Promise
Promise.resolve(params).then((resolvedParams) => {
const currentSlug = resolvedParams.slug;
setSlug(currentSlug);
const countryName = getCountryFromSlug(currentSlug);
const foundCountry = visaData.visaSystem.summaryList.find(
(c) => c.name === countryName,
);
if (foundCountry) {
setCountry(foundCountry);
}
setLoading(false);
});
}, [params]);
if (loading) {
return (
<div className="flex items-center justify-center min-h-screen">
<div className="spinner"></div>
</div>
);
}
if (!country) {
return (
<div className="flex items-center justify-center min-h-screen">
<h1>Country not found</h1>
</div>
);
}
const countryData = visaData.visaSystem.detailedView.activeCountry;
const relatedCountries = visaData.visaSystem.detailedView.relatedCountries;
const contactInfo = visaData.visaSystem.contactInfo;
return (
<>
{/* Breadcrumb-Wrapper Section Start */}
<Breadcrumb
title={countryData.breadcrumb.title}
breadcrumbItems={[
{ label: "Home", href: "/" },
{ label: countryData.name },
]}
backgroundImage={`${ASSET_URL}/${countryData.breadcrumb.image}`}
/>
{/* Country-details Section Start */}
<section className="country-details-section section-padding fix">
<div className="container">
<div className="country-details-wrapper">
<div className="row g-4">
{/* Main Content */}
<div className="col-lg-8">
<div className="country-details-post">
<div className="details-image">
<img
src={`${ASSET_URL}/${countryData.mainImage}`}
alt="img"
/>
</div>
<div className="country-details-content">
<h2>{countryData.name}</h2>
<p>{countryData.description}</p>
<p className="mt-3">{countryData.additionalInfo}</p>
<h5>{countryData.tagline}</h5>
{/* Visa Types */}
<div className="tourist-visa-box">
{/* Render mảng đầu tiên (index 0) */}
{countryData.visaTypes[0] && (
<div className="tourist-box style-2">
{countryData.visaTypes[0].items.map(
(item: any, itemIdx: number) => (
<div key={itemIdx} className="tourist-content">
<h5>{item.title}</h5>
<p>{item.description}</p>
</div>
),
)}
</div>
)}
{/* Render mảng thứ hai (index 1) */}
{countryData.visaTypes[1] && (
<div className="tourist-box">
{countryData.visaTypes[1].items.map(
(item: any, itemIdx: number) => (
<div key={itemIdx} className="tourist-content">
<h5>{item.title}</h5>
<p>{item.description}</p>
</div>
),
)}
</div>
)}
</div>
{/* Visa Process */}
<h3 className="text">{countryData.visaProcess.title}</h3>
<ul className="list-item">
{countryData.visaProcess.steps.map(
(process: any, idx: number) => (
<li key={idx}>
{process.number}. {process.title}
<span>{process.description}</span>
</li>
),
)}
</ul>
{/* Gallery */}
<div className="row g-4 mb-4">
{countryData.gallery.map((image: string, idx: number) => (
<div key={idx} className="col-lg-6">
<div className="thumb">
<img src={`${ASSET_URL}/${image}`} alt="img" />
</div>
</div>
))}
</div>
{/* Visa Categories */}
<h3 className="text mb-3">
{countryData.visaCategories.title}
</h3>
{countryData.visaCategories.steps.map(
(subGroup: string[], groupIdx: number) => (
<ul className="visa-list-2" key={groupIdx}>
{/* Map lần 2 để render từng chuỗi trong mảng con */}
{subGroup.map((category: string, idx: number) => (
<li key={idx}>
<i className="fa-solid fa-chevrons-right"></i>
{category}
</li>
))}
</ul>
),
)}
{/* Service Options */}
<h3 className="text">{countryData.visaService.title}</h3>
<ul className="list-item">
{countryData.visaService.steps.map(
(process: any, idx: number) => (
<li key={idx}>
{process.number}. {process.title}
<span>{process.description}</span>
</li>
),
)}
</ul>
</div>
</div>
</div>
{/* Sidebar */}
<div className="col-lg-4">
<div className="country-details-sideber">
{relatedCountries.map((relCountry: any, idx: number) => (
<div key={idx} className="icon-box-item">
<div className="left-item">
<div className="icon">
<img
src={`${ASSET_URL}/${relCountry.icon}`}
alt="img"
/>
</div>
<h5>{relCountry.name}</h5>
</div>
<i className="fa-solid fa-chevrons-right"></i>
</div>
))}
{/* Contact Box */}
<div
className="visa-contact-box bg-cover"
style={{
backgroundImage: `url(${ASSET_URL}/assets/img/inner-page/country-details/bg.jpg)`,
padding: "30px",
borderRadius: "8px",
color: "white",
}}
>
<div className="content">
<h3>{contactInfo.sectionTitle}</h3>
<p>{contactInfo.helpText}</p>
<div className="icon-item">
<div className="icon">
<i className="fa-solid fa-phone"></i>
</div>
<div className="cont">
<span>{contactInfo.phone.label}: </span>
<h6>
<a href={`tel:${contactInfo.phone.link}`}>
{contactInfo.phone.value}
</a>
</h6>
</div>
</div>
<div className="icon-item">
<div className="icon">
<i className="fa-regular fa-envelope"></i>
</div>
<div className="cont">
<span>{contactInfo.email.label}: </span>
<h6>
<a href={`mailto:${contactInfo.email.link}`}>
{contactInfo.email.value}
</a>
</h6>
</div>
</div>
<div className="icon-item">
<div className="icon">
<i className="fa-regular fa-location-dot"></i>
</div>
<div className="cont">
<span>{contactInfo.location.label}: </span>
<h6>{contactInfo.location.address}</h6>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</>
);
}
+52
View File
@@ -0,0 +1,52 @@
const ASSET_URL = process.env.NEXT_PUBLIC_API_URL || "";
interface BreadcrumbProps {
title: string;
breadcrumbItems: Array<{
label: string;
href?: string;
}>;
backgroundImage?: string;
showShape?: boolean;
}
export default function Breadcrumb({
title,
breadcrumbItems,
backgroundImage = `${ASSET_URL}/assets/img/inner-page/breadcrumb.jpg`,
showShape = true,
}: BreadcrumbProps) {
return (
<section
className="breadcrumb-wrapper fix bg-cover"
style={{
backgroundImage: `url(${backgroundImage})`,
}}
>
{showShape && (
<div className="shape">
<img src={`${ASSET_URL}/assets/img/inner-page/shape.png`} alt="img" />
</div>
)}
<div className="container">
<div className="page-heading">
<h1 className="breadcrumb-title">{title}</h1>
<ul className="breadcrumb-list">
{breadcrumbItems.map((item, index) => (
<li key={index}>
{item.href ? (
<a href={item.href}>{item.label}</a>
) : (
<>
{index > 0 && <i className="fa-solid fa-chevron-right"></i>}
{item.label}
</>
)}
</li>
))}
</ul>
</div>
</div>
</section>
);
}
+411
View File
@@ -0,0 +1,411 @@
import type { Metadata } from "next";
const ASSET_URL = process.env.NEXT_PUBLIC_API_URL || "";
export const metadata: Metadata = {
title: "Visaway Immigration & Visa Consulting HTML Template",
description: "Visaway Immigration & Visa Consulting HTML Template",
authors: [{ name: "Gramentheme" }],
openGraph: {
type: "website",
locale: "en_US",
url: "http://localhost:3000",
},
};
export default function VisaLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<>
{/* Preloader Start */}
<div id="preloader" className="preloader" style={{ display: "none" }}>
<div className="animation-preloader">
<div className="spinner"></div>
<div className="txt-loading">
<span data-text-preloader="V" className="letters-loading">
{" "}
V{" "}
</span>
<span data-text-preloader="I" className="letters-loading">
{" "}
I{" "}
</span>
<span data-text-preloader="S" className="letters-loading">
{" "}
S{" "}
</span>
<span data-text-preloader="A" className="letters-loading">
{" "}
A{" "}
</span>
<span data-text-preloader="W" className="letters-loading">
{" "}
W{" "}
</span>
<span data-text-preloader="A" className="letters-loading">
{" "}
A{" "}
</span>
<span data-text-preloader="Y" className="letters-loading">
{" "}
Y{" "}
</span>
</div>
<p className="text-center">Loading</p>
</div>
<div className="loader">
<div className="row">
<div className="col-3 loader-section section-left">
<div className="bg"></div>
</div>
<div className="col-3 loader-section section-left">
<div className="bg"></div>
</div>
<div className="col-3 loader-section section-right">
<div className="bg"></div>
</div>
<div className="col-3 loader-section section-right">
<div className="bg"></div>
</div>
</div>
</div>
</div>
{/* GT Back To Top Start */}
<button id="back-top" className="back-to-top show">
<i className="fa-regular fa-arrow-up"></i>
</button>
{/* GT MouseCursor Start */}
<div className="mouseCursor cursor-outer"></div>
<div className="mouseCursor cursor-inner"></div>
{/* Header-Top-Section Start */}
<div className="header-top-section">
<div className="container-fluid">
<div className="header-top-wrapper">
<div className="header-left">
<ul className="list">
<li className="style-2">
<span>Help Line</span>
<i className="fa-solid fa-phone"></i>
<a href="tel:+093783575222">+09 378 357 5222</a>
</li>
<li>
<i className="fa-solid fa-location-dot"></i>
69 Street, 5th AvenueLA, United States
</li>
<li>
<i className="fa-solid fa-envelope"></i>
<a href="mailto:info@example.com">info@example.com</a>
</li>
</ul>
</div>
<div className="header-right">
<div className="flag-wrap">
<div className="flag">
<i className="fa-solid fa-globe"></i>
</div>
<div className="nice-select" tabIndex={0}>
<span className="current"> English </span>
<ul className="list">
<li data-value="1" className="option selected focus">
English
</li>
<li data-value="1" className="option">
Bangla
</li>
<li data-value="1" className="option">
Hindi
</li>
</ul>
</div>
</div>
<div className="social-item">
<a href="#">
<i className="fa-brands fa-linkedin"></i>
</a>
<a href="#">
<i className="fa-brands fa-twitter"></i>
</a>
<a href="#">
<i className="fa-brands fa-instagram"></i>
</a>
<a href="#">
<i className="fa-brands fa-youtube"></i>
</a>
</div>
</div>
</div>
</div>
</div>
{/* Offcanvas Area Start */}
<div className="fix-area">
<div className="offcanvas__info">
<div className="offcanvas__wrapper">
<div className="offcanvas__content">
<div className="offcanvas__top mb-5 d-flex justify-content-between align-items-center">
<div className="offcanvas__logo">
<a href="/">
<img
src={`${ASSET_URL}/assets/img/logo/black-logo.svg`}
alt="logo-img"
/>
</a>
</div>
<div className="offcanvas__close">
<button>
<i className="fas fa-times"></i>
</button>
</div>
</div>
<p className="text d-none d-xl-block">
Nullam dignissim, ante scelerisque the is euismod fermentum odio
sem semper the is erat, a feugiat leo urna eget eros. Duis
Aenean a imperdiet risus.
</p>
<div className="mobile-menu fix mb-3"></div>
<div className="offcanvas__contact d-xl-block">
<h4 className="d-xl-block">Contact Info</h4>
<ul className="d-xl-block">
<li className="d-flex align-items-center">
<div className="offcanvas__contact-icon">
<i className="fal fa-map-marker-alt"></i>
</div>
<div className="offcanvas__contact-text">
<a target="_blank" href="#">
Main Street, Melbourne, Australia
</a>
</div>
</li>
<li className="d-flex align-items-center">
<div className="offcanvas__contact-icon mr-15">
<i className="fal fa-envelope"></i>
</div>
<div className="offcanvas__contact-text">
<a href="mailto:info@example.com">
<span>info@example.com</span>
</a>
</div>
</li>
<li className="d-flex align-items-center">
<div className="offcanvas__contact-icon mr-15">
<i className="fal fa-clock"></i>
</div>
<div className="offcanvas__contact-text">
<a target="_blank" href="#">
Mod-friday, 09am -05pm
</a>
</div>
</li>
<li className="d-flex align-items-center">
<div className="offcanvas__contact-icon mr-15">
<i className="far fa-phone"></i>
</div>
<div className="offcanvas__contact-text">
<a href="tel:+11002345909">+11002345909</a>
</div>
</li>
</ul>
<div className="social-icon d-flex align-items-center">
<a href="#">
<i className="fab fa-facebook-f"></i>
</a>
<a href="#">
<i className="fab fa-twitter"></i>
</a>
<a href="#">
<i className="fab fa-youtube"></i>
</a>
<a href="#">
<i className="fab fa-linkedin-in"></i>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
<div className="offcanvas__overlay"></div>
{/* Header Section Start */}
{/* <header id="header-sticky" className="header-1">
<div className="container-fluid">
<div className="mega-menu-wrapper">
<div className="header-main">
<div className="header-left">
<div className="logo">
<a href="/" className="header-logo-2">
<img
src={`${ASSET_URL}/assets/img/logo/black-logo.svg`}
alt="logo-img"
/>
</a>
</div>
<div className="mean__menu-wrapper">
<div className="main-menu">
<nav id="mobile-menu">
<ul>
<li className="has-dropdown active menu-thumb">
<a href="/"> Home </a>
</li>
<li>
<a href="/about">About Us</a>
</li>
<li className="has-dropdown">
<a href="#"> Pages </a>
<ul className="submenu">
<li>
<a href="/services">Services</a>
</li>
<li>
<a href="/visa">Country List</a>
</li>
<li>
<a href="/pricing">Our Pricing</a>
</li>
<li>
<a href="/appointment">Appointment</a>
</li>
</ul>
</li>
<li>
<a href="/visa"> VISA </a>
</li>
<li>
<a href="/blog"> Blog </a>
</li>
<li>
<a href="/contact">Contact Us</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div className="header-right d-flex align-items-center mt-0">
<div className="header-call-item">
<a href="#" className="main-header__search search-toggler">
<i className="fa-regular fa-magnifying-glass"></i>
</a>
<a href="/contact" className="theme-btn">
Apply now
<i className="fa-solid fa-arrow-right"></i>
</a>
<div className="header__hamburger my-auto">
<div className="sidebar__toggle">
<i className="fa-solid fa-bars-staggered"></i>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</header> */}
{/* Search Area Start */}
<div className="search-popup">
<div className="search-popup__overlay search-toggler"></div>
<div className="search-popup__content">
<form
role="search"
method="get"
className="search-popup__form"
action="#"
>
<input
type="text"
id="search"
name="search"
placeholder="Search Here..."
/>
<button
type="submit"
aria-label="search submit"
className="search-btn"
>
<span>
<i className="fa-regular fa-magnifying-glass"></i>
</span>
</button>
</form>
</div>
</div>
{/* Main Content */}
{children}
{/* Footer Section Start */}
{/* <footer
className="footer-section fix bg-cover"
style={{
backgroundImage: `url(${ASSET_URL}/assets/img/home-1/footer-bg.jpg)`,
}}
>
<div className="container">
<div className="footer-wrapper">
<div className="row">
<div className="col-xl-12">
<div className="footer-item">
<h2>
<a href="tel:+16336547896">+163 3654 7896</a>
</h2>
<h2 className="text">
69 Street, 5th AvenueLA, United States
</h2>
<div className="footer-list-item">
<a href="/">
<img
src={`${ASSET_URL}/assets/img/logo/white-logo.svg`}
alt="img"
/>
</a>
<ul className="footer-list">
<li>
<a href="/">Home</a>
</li>
<li>
<a href="/about">About Us</a>
</li>
<li>
<a href="/visa">Visa</a>
</li>
<li>
<a href="/blog">Pages</a>
</li>
<li>
<a href="/blog">Article</a>
</li>
<li>
<a href="/contact">Contact Us</a>
</li>
</ul>
<div className="social-icon">
<a href="#">
<i className="fa-brands fa-twitter"></i>
</a>
<a href="#">
<i className="fa-brands fa-instagram"></i>
</a>
<a href="#">
<i className="fa-brands fa-linkedin"></i>
</a>
<a href="#">
<i className="fa-brands fa-youtube"></i>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</footer> */}
</>
);
}
+98
View File
@@ -0,0 +1,98 @@
"use client";
import visaData from "./visa.json";
import Breadcrumb from "./components/Breadcrumb";
const ASSET_URL = process.env.NEXT_PUBLIC_API_URL || "";
interface VisaCountry {
id: number;
name: string;
icon: string;
services: string[];
}
const visaCountries: VisaCountry[] = visaData.visaSystem.summaryList.map(
(country) => ({
...country,
icon: `${ASSET_URL}/${country.icon}`,
}),
);
export default function VisaListPage() {
const getSlug = (countryName: string): string => {
return countryName.toLowerCase().replace(/\s+/g, "-");
};
return (
<>
{/* Breadcrumb-Wrapper Section Start */}
<Breadcrumb
title={visaData.visaSystem.breadcrumb.list.title}
breadcrumbItems={[
{ label: "Home", href: "/" },
{ label: visaData.visaSystem.breadcrumb.list.title },
]}
backgroundImage={`${ASSET_URL}/${visaData.visaSystem.breadcrumb.list.image}`}
/>
{/* Service Section Start */}
<section className="visa-provide-section section-padding section-bg-1 fix">
<div className="container">
<div className="row g-4">
{visaCountries.map((country) => (
<div key={country.id} className="col-lg-6">
<div className="visa-provide-box mt-0">
<div className="visa-top-item">
<div className="visa-left">
<div className="icon">
<img src={country.icon} alt="img" />
</div>
<div className="content">
<p>Visa Service</p>
<h3>
<a href={`/visa/${getSlug(country.name)}`}>
{country.name}
</a>
</h3>
</div>
</div>
<a
href={`/visa/${getSlug(country.name)}`}
className="theme-btn"
>
Read More
<i className="fa-solid fa-arrow-right"></i>
</a>
</div>
<div className="visa-list-item">
<ul className="list">
<li>
<i className="fa-regular fa-arrow-right"></i>
{country.services[0]}
</li>
<li>
<i className="fa-regular fa-arrow-right"></i>
{country.services[1]}
</li>
</ul>
<ul className="list">
<li>
<i className="fa-regular fa-arrow-right"></i>
{country.services[2]}
</li>
<li>
<i className="fa-regular fa-arrow-right"></i>
{country.services[3]}
</li>
</ul>
</div>
</div>
</div>
))}
</div>
</div>
</section>
</>
);
}
+295
View File
@@ -0,0 +1,295 @@
{
"visaSystem": {
"breadcrumb": {
"list": {
"title": "Country List",
"image": "assets/img/inner-page/breadcrumb.jpg"
}
},
"summaryList": [
{
"id": 1,
"name": "France",
"icon": "assets/img/home-2/visa/03.png",
"services": [
"Student Visa & Admission",
"Work Visa H1B",
"Work permit for Canada",
"Student Visa for Canada"
]
},
{
"id": 2,
"name": "UK",
"icon": "assets/img/home-2/visa/11.png",
"services": [
"Student Visa & Admission",
"Work Visa H1B",
"Work permit for Canada",
"Student Visa for Canada"
]
},
{
"id": 3,
"name": "Canada",
"icon": "assets/img/home-2/visa/02.png",
"services": [
"Student Visa & Admission",
"Work Visa H1B",
"Work permit for Canada",
"Student Visa for Canada"
]
},
{
"id": 4,
"name": "Germany",
"icon": "assets/img/home-2/visa/12.png",
"services": [
"Student Visa & Admission",
"Work Visa H1B",
"Work permit for Canada",
"Student Visa for Canada"
]
},
{
"id": 5,
"name": "Spain",
"icon": "assets/img/home-2/visa/13.png",
"services": [
"Student Visa & Admission",
"Work Visa H1B",
"Work permit for Canada",
"Student Visa for Canada"
]
},
{
"id": 6,
"name": "South Korea",
"icon": "assets/img/home-2/visa/14.png",
"services": [
"Student Visa & Admission",
"Work Visa H1B",
"Work permit for Canada",
"Student Visa for Canada"
]
},
{
"id": 7,
"name": "Japan",
"icon": "assets/img/home-2/visa/15.png",
"services": [
"Student Visa & Admission",
"Work Visa H1B",
"Work permit for Canada",
"Student Visa for Canada"
]
},
{
"id": 8,
"name": "Croatia",
"icon": "assets/img/home-2/visa/16.png",
"services": [
"Student Visa & Admission",
"Work Visa H1B",
"Work permit for Canada",
"Student Visa for Canada"
]
},
{
"id": 9,
"name": "England",
"icon": "assets/img/home-2/visa/17.png",
"services": [
"Student Visa & Admission",
"Work Visa H1B",
"Work permit for Canada",
"Student Visa for Canada"
]
},
{
"id": 10,
"name": "Indonesia",
"icon": "assets/img/home-2/visa/18.png",
"services": [
"Student Visa & Admission",
"Work Visa H1B",
"Work permit for Canada",
"Student Visa for Canada"
]
}
],
"detailedView": {
"activeCountry": {
"id": 1,
"name": "United States of America ",
"title": "COUNTRY USA",
"breadcrumb": {
"title": "COUNTRY USA",
"image": "assets/img/inner-page/breadcrumb.jpg"
},
"mainImage": "assets/img/inner-page/country-details/details-1.jpg",
"description": "The United States is one of the most popular destinations for international students and immigrants, offering world-class universities, diverse cultural experiences, and countless career opportunities...",
"additionalInfo": "Our consultancy provides complete guidance for study visas, work permits, and permanent residency pathways tailored to your goals.",
"tagline": "Over the last 35 Years we made an impact that is strong & we have long way to go.",
"visaTypes": [
{
"category": "Tourist & Work",
"items": [
{
"title": "Tourist Visa",
"description": "Broad term that can refer to various aspects of interconnectedness"
},
{
"title": "Work Permit",
"description": "Broad term that can refer to various aspects of interconnectedness"
}
]
},
{
"category": "Student & Family",
"items": [
{
"title": "Student",
"description": "Broad term that can refer to various aspects of interconnectedness"
},
{
"title": "Tourist Visa",
"description": "Broad term that can refer to various aspects of interconnectedness"
}
]
}
],
"visaProcess": {
"title": "USA Visa Process",
"steps": [
{
"number": "01",
"title": "Consultation & Eligibility Check",
"description": "Our experts review your profile and visa requirements."
},
{
"number": "02",
"title": "Application Preparation",
"description": "We help with document collection, form filling, and statement drafting."
},
{
"number": "03",
"title": "Submission",
"description": "Visa application is submitted online with required fees."
},
{
"number": "04",
"title": "Interview Guidance",
"description": "Get training and mock sessions for embassy interview."
},
{
"number": "05",
"title": "Approval & Travel",
"description": "Once approved, we provide travel and pre-departure guidance."
}
]
},
"gallery": [
"assets/img/inner-page/country-details/details-2.jpg",
"assets/img/inner-page/country-details/details-3.png"
],
"visaCategories": {
"title": "Types of USA Visas",
"steps": [
[
"Student Visa (F1, M1, J1)",
"Work Visa (H1B, L1)",
"Tourist Visa (B1/B2)"
],
["Family/Spouse Visa (K1, IR1, F2A)", "Green Card / Immigrant Visa"]
]
},
"visaService": {
"title": "Our USA Visa Service Options",
"steps": [
{
"number": "01",
"title": "Consultation & Eligibility Check",
"description": "Our experts review your profile and visa requirements."
},
{
"number": "02",
"title": "Application Preparation",
"description": "We help with document collection, form filling, and statement drafting."
},
{
"number": "03",
"title": "Submission",
"description": "Visa application is submitted online with required fees."
},
{
"number": "04",
"title": "Interview Guidance",
"description": "Get training and mock sessions for embassy interview."
},
{
"number": "05",
"title": "Approval & Travel",
"description": "Once approved, we provide travel and pre-departure guidance."
}
]
}
},
"relatedCountries": [
{
"id": 1,
"name": "Canada",
"icon": "assets/img/inner-page/country-details/01.png"
},
{
"id": 2,
"name": "USA",
"icon": "assets/img/inner-page/country-details/02.png"
},
{
"id": 3,
"name": "USA",
"icon": "assets/img/inner-page/country-details/03.png"
},
{
"id": 4,
"name": "Saint Helena",
"icon": "assets/img/inner-page/country-details/05.png"
},
{
"id": 5,
"name": "Iran",
"icon": "assets/img/inner-page/country-details/06.png"
},
{
"id": 6,
"name": "Spain",
"icon": "assets/img/inner-page/country-details/07.png"
},
{
"id": 7,
"name": "Japan",
"icon": "assets/img/inner-page/country-details/08.png"
}
]
},
"contactInfo": {
"sectionTitle": "Visa & Immigration",
"helpText": "Need Help? Book Lab Visit",
"phone": {
"label": "Call Us",
"value": "+009 438 222 9540",
"link": "tel:+0094382229540"
},
"email": {
"label": "Mail Us",
"value": "infor@xridergamil.com",
"link": "mailto:infor@xridergamil.com"
},
"location": {
"label": "Location",
"address": "Toronto, Montreal, City 2026"
}
}
}
}
View File
View File
+18
View File
@@ -0,0 +1,18 @@
import { defineConfig, globalIgnores } from "eslint/config";
import nextVitals from "eslint-config-next/core-web-vitals";
import nextTs from "eslint-config-next/typescript";
const eslintConfig = defineConfig([
...nextVitals,
...nextTs,
// Override default ignores of eslint-config-next.
globalIgnores([
// Default ignores of eslint-config-next:
".next/**",
"out/**",
"build/**",
"next-env.d.ts",
]),
]);
export default eslintConfig;
+7
View File
@@ -0,0 +1,7 @@
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
/* config options here */
};
export default nextConfig;
+6550
View File
File diff suppressed because it is too large Load Diff
+26
View File
@@ -0,0 +1,26 @@
{
"name": "hai-learning",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "eslint"
},
"dependencies": {
"next": "16.1.6",
"react": "19.2.3",
"react-dom": "19.2.3"
},
"devDependencies": {
"@tailwindcss/postcss": "^4",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
"eslint": "^9",
"eslint-config-next": "16.1.6",
"tailwindcss": "^4",
"typescript": "^5"
}
}
+14
View File
@@ -0,0 +1,14 @@
import { useRouter } from "next/router";
export default function LevelSlugPage() {
const router = useRouter();
const { level, slug } = router.query;
return (
<div style={{ padding: 20 }}>
<h1>Lesson page</h1>
<p>Level: {level}</p>
<p>Slug: {slug}</p>
</div>
);
}
+13
View File
@@ -0,0 +1,13 @@
import { useRouter } from "next/router";
export default function LevelPage() {
const router = useRouter();
const { level } = router.query;
return (
<div style={{ padding: 20 }}>
<h1>Level page</h1>
<p>Level: {level}</p>
</div>
);
}
+6
View File
@@ -0,0 +1,6 @@
import type { AppProps } from "next/app";
import "../app/globals.css";
export default function MyApp({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />;
}
+13
View File
@@ -0,0 +1,13 @@
import { Html, Head, Main, NextScript } from "next/document";
export default function Document() {
return (
<Html lang="en">
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
+7
View File
@@ -0,0 +1,7 @@
const config = {
plugins: {
"@tailwindcss/postcss": {},
},
};
export default config;
+31575
View File
File diff suppressed because it is too large Load Diff
+2745
View File
File diff suppressed because it is too large Load Diff
+12633
View File
File diff suppressed because it is too large Load Diff
View File
+94
View File
@@ -0,0 +1,94 @@
@font-face {
font-family: 'icomoon';
src: url('../icomon/icomoon.eot?jkvd7w');
src: url('../icomon/icomoon.eot?jkvd7w#iefix') format('embedded-opentype'),
url('../icomon/icomoon.ttf?jkvd7w') format('truetype'),
url('../icomon/icomoon.woff?jkvd7w') format('woff'),
url('../icomon/icomoon.svg?jkvd7w#icomoon') format('svg');
font-weight: normal;
font-style: normal;
font-display: block;
}
[class^="icon-"], [class*=" icon-"] {
/* use !important to prevent issues with browser extensions that change fonts */
font-family: 'icomoon' !important;
speak: never;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1;
/* Better Font Rendering =========== */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-icon-1:before {
content: "\e900";
}
.icon-icon-2:before {
content: "\e901";
}
.icon-icon-3:before {
content: "\e902";
}
.icon-icon-4:before {
content: "\e903";
}
.icon-icon-5:before {
content: "\e904";
}
.icon-icon-6:before {
content: "\e905";
}
.icon-icon-7:before {
content: "\e906";
}
.icon-icon-8:before {
content: "\e907";
}
.icon-icon-9:before {
content: "\e908";
}
.icon-icon-10:before {
content: "\e909";
}
.icon-icon-11:before {
content: "\e90a";
}
.icon-icon-12:before {
content: "\e90b";
}
.icon-icon-13:before {
content: "\e90c";
}
.icon-icon-14:before {
content: "\e90d";
}
.icon-icon-15:before {
content: "\e90e";
}
.icon-icon-16:before {
content: "\e90f";
}
.icon-icon-17:before {
content: "\e910";
}
.icon-icon-18:before {
content: "\e911";
}
.icon-icon-19:before {
content: "\e912";
}
.icon-icon-20:before {
content: "\e913";
}
.icon-icon-21:before {
content: "\e914";
}
.icon-icon-22:before {
content: "\e915";
}
+351
View File
@@ -0,0 +1,351 @@
/* Magnific Popup CSS */
.mfp-bg {
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1042;
overflow: hidden;
position: fixed;
background: #0b0b0b;
opacity: 0.8; }
.mfp-wrap {
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1043;
position: fixed;
outline: none !important;
-webkit-backface-visibility: hidden; }
.mfp-container {
text-align: center;
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
padding: 0 8px;
box-sizing: border-box; }
.mfp-container:before {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle; }
.mfp-align-top .mfp-container:before {
display: none; }
.mfp-content {
position: relative;
display: inline-block;
vertical-align: middle;
margin: 0 auto;
text-align: left;
z-index: 1045; }
.mfp-inline-holder .mfp-content,
.mfp-ajax-holder .mfp-content {
width: 100%;
cursor: auto; }
.mfp-ajax-cur {
cursor: progress; }
.mfp-zoom-out-cur, .mfp-zoom-out-cur .mfp-image-holder .mfp-close {
cursor: -moz-zoom-out;
cursor: -webkit-zoom-out;
cursor: zoom-out; }
.mfp-zoom {
cursor: pointer;
cursor: -webkit-zoom-in;
cursor: -moz-zoom-in;
cursor: zoom-in; }
.mfp-auto-cursor .mfp-content {
cursor: auto; }
.mfp-close,
.mfp-arrow,
.mfp-preloader,
.mfp-counter {
-webkit-user-select: none;
-moz-user-select: none;
user-select: none; }
.mfp-loading.mfp-figure {
display: none; }
.mfp-hide {
display: none !important; }
.mfp-preloader {
color: #CCC;
position: absolute;
top: 50%;
width: auto;
text-align: center;
margin-top: -0.8em;
left: 8px;
right: 8px;
z-index: 1044; }
.mfp-preloader a {
color: #CCC; }
.mfp-preloader a:hover {
color: $white; }
.mfp-s-ready .mfp-preloader {
display: none; }
.mfp-s-error .mfp-content {
display: none; }
button.mfp-close,
button.mfp-arrow {
overflow: visible;
cursor: pointer;
background: transparent;
border: 0;
-webkit-appearance: none;
display: block;
outline: none;
padding: 0;
z-index: 1046;
box-shadow: none;
touch-action: manipulation; }
button::-moz-focus-inner {
padding: 0;
border: 0; }
.mfp-close {
width: 44px;
height: 44px;
line-height: 44px;
position: absolute;
right: 0;
top: 0;
text-decoration: none;
text-align: center;
opacity: 0.65;
padding: 0 0 18px 10px;
color: $white;
font-style: normal;
font-size: 28px;
font-family: Arial, Baskerville, monospace; }
.mfp-close:hover,
.mfp-close:focus {
opacity: 1; }
.mfp-close:active {
top: 1px; }
.mfp-close-btn-in .mfp-close {
color: #fff; }
.mfp-image-holder .mfp-close,
.mfp-iframe-holder .mfp-close {
color: $white;
right: -6px;
text-align: right;
padding-right: 6px;
width: 100%; }
.mfp-counter {
position: absolute;
top: 0;
right: 0;
color: #CCC;
font-size: 12px;
line-height: 18px;
white-space: nowrap; }
.mfp-arrow {
position: absolute;
opacity: 0.65;
margin: 0;
top: 50%;
margin-top: -55px;
padding: 0;
width: 90px;
height: 110px;
-webkit-tap-highlight-color: transparent; }
.mfp-arrow:active {
margin-top: -54px; }
.mfp-arrow:hover,
.mfp-arrow:focus {
opacity: 1; }
.mfp-arrow:before,
.mfp-arrow:after {
content: '';
display: block;
width: 0;
height: 0;
position: absolute;
left: 0;
top: 0;
margin-top: 35px;
margin-left: 35px;
border: medium inset transparent; }
.mfp-arrow:after {
border-top-width: 13px;
border-bottom-width: 13px;
top: 8px; }
.mfp-arrow:before {
border-top-width: 21px;
border-bottom-width: 21px;
opacity: 0.7; }
.mfp-arrow-left {
left: 0; }
.mfp-arrow-left:after {
border-right: 17px solid $white;
margin-left: 31px; }
.mfp-arrow-left:before {
margin-left: 25px;
border-right: 27px solid #fff; }
.mfp-arrow-right {
right: 0; }
.mfp-arrow-right:after {
border-left: 17px solid $white;
margin-left: 39px; }
.mfp-arrow-right:before {
border-left: 27px solid #fff; }
.mfp-iframe-holder {
padding-top: 40px;
padding-bottom: 40px; }
.mfp-iframe-holder .mfp-content {
line-height: 0;
width: 100%;
max-width: 900px; }
.mfp-iframe-holder .mfp-close {
top: -40px; }
.mfp-iframe-scaler {
width: 100%;
height: 0;
overflow: hidden;
padding-top: 56.25%; }
.mfp-iframe-scaler iframe {
position: absolute;
display: block;
top: 0;
left: 0;
width: 100%;
height: 100%;
box-shadow: 0 0 8px rgba(0, 0, 0, 0.6);
background: #000; }
/* Main image in popup */
img.mfp-img {
width: auto;
max-width: 100%;
height: auto;
display: block;
line-height: 0;
box-sizing: border-box;
padding: 40px 0 40px;
margin: 0 auto; }
/* The shadow behind the image */
.mfp-figure {
line-height: 0; }
.mfp-figure:after {
content: '';
position: absolute;
left: 0;
top: 40px;
bottom: 40px;
display: block;
right: 0;
width: auto;
height: auto;
z-index: -1;
box-shadow: 0 0 8px rgba(0, 0, 0, 0.6);
background: #444; }
.mfp-figure small {
color: #BDBDBD;
display: block;
font-size: 12px;
line-height: 14px; }
.mfp-figure figure {
margin: 0; }
.mfp-bottom-bar {
margin-top: -36px;
position: absolute;
top: 100%;
left: 0;
width: 100%;
cursor: auto; }
.mfp-title {
text-align: left;
line-height: 18px;
color: #F3F3F3;
word-wrap: break-word;
padding-right: 36px; }
.mfp-image-holder .mfp-content {
max-width: 100%; }
.mfp-gallery .mfp-image-holder .mfp-figure {
cursor: pointer; }
@media screen and (max-width: 800px) and (orientation: landscape), screen and (max-height: 300px) {
/**
* Remove all paddings around the image on small screen
*/
.mfp-img-mobile .mfp-image-holder {
padding-left: 0;
padding-right: 0; }
.mfp-img-mobile img.mfp-img {
padding: 0; }
.mfp-img-mobile .mfp-figure:after {
top: 0;
bottom: 0; }
.mfp-img-mobile .mfp-figure small {
display: inline;
margin-left: 5px; }
.mfp-img-mobile .mfp-bottom-bar {
background: rgba(0, 0, 0, 0.6);
bottom: 0;
margin: 0;
top: auto;
padding: 3px 5px;
position: fixed;
box-sizing: border-box; }
.mfp-img-mobile .mfp-bottom-bar:empty {
padding: 0; }
.mfp-img-mobile .mfp-counter {
right: 5px;
top: 3px; }
.mfp-img-mobile .mfp-close {
top: 0;
right: 0;
width: 35px;
height: 35px;
line-height: 35px;
background: rgba(0, 0, 0, 0.6);
position: fixed;
text-align: center;
padding: 0; } }
@media all and (max-width: 900px) {
.mfp-arrow {
-webkit-transform: scale(0.75);
transform: scale(0.75); }
.mfp-arrow-left {
-webkit-transform-origin: 0;
transform-origin: 0; }
.mfp-arrow-right {
-webkit-transform-origin: 100%;
transform-origin: 100%; }
.mfp-container {
padding-left: 6px;
padding-right: 6px; } }
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+148
View File
@@ -0,0 +1,148 @@
/*! #######################################################################
MeanMenu 2.0.7
--------
To be used with jquery.meanmenu.js by Chris Wharton (http://www.meanthemes.com/plugins/meanmenu/)
####################################################################### */
a.meanmenu-reveal {
display: none
}
.mean-container .mean-bar {
float: left;
width: 100%;
position: relative;
background: #070337;
padding: 4px 0;
min-height: 42px;
z-index: 999999
}
.mean-container a.meanmenu-reveal {
width: 22px;
height: 22px;
padding: 13px 13px 11px 13px;
position: absolute;
top: 0;
right: 0;
cursor: pointer;
color: #fff;
text-decoration: none;
font-size: 16px;
text-indent: -9999em;
line-height: 22px;
font-size: 1px;
display: block;
font-family: Arial, Helvetica, sans-serif;
font-weight: 700
}
.mean-container a.meanmenu-reveal span {
display: block;
background: #fff;
height: 3px;
margin-top: 3px
}
.mean-container .mean-nav {
float: left;
width: 100%;
background: #070337;
margin-top: 44px
}
.mean-container .mean-nav ul {
padding: 0;
margin: 0;
width: 100%;
list-style-type: none
}
.mean-container .mean-nav ul li {
position: relative;
float: left;
width: 100%
}
.mean-container .mean-nav ul li a {
display: block;
float: left;
width: 90%;
padding: 10px 5%;
margin: 0;
text-align: left;
color: #fff;
border-top: 1px solid #e0e3ed;
text-decoration: none;
text-transform: uppercase
}
.mean-container .mean-nav ul li li a {
width: 100%;
padding: 10px 0;
text-shadow: none !important;
visibility: visible
}
.mean-container .mean-nav ul li.mean-last a {
border-bottom: 0;
margin-bottom: 0
}
.mean-container .mean-nav ul li li li a {
width: 70%;
padding: 10px 0;
}
.mean-container .mean-nav ul li li li li a {
width: 60%;
padding: 10px 20%
}
.mean-container .mean-nav ul li li li li li a {
width: 50%;
padding: 10px 25%
}
.mean-container .mean-nav ul li a.mean-expand {
margin-top: 1px;
width: 26px;
height: 32px;
text-align: center;
position: absolute;
right: 0;
top: 0;
z-index: 2;
font-weight: 700;
background: transparent;
border: none !important;
font-size: 14px
}
.mean-container .mean-push {
float: left;
width: 100%;
padding: 0;
margin: 0;
clear: both
}
.mean-nav .wrapper {
width: 100%;
padding: 0;
margin: 0
}
.mean-container .mean-bar,
.mean-container .mean-bar * {
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box
}
.mean-remove {
display: none !important
}
+144
View File
@@ -0,0 +1,144 @@
.nice-select {
-webkit-tap-highlight-color: transparent;
background-color: transparent;
border-radius: 5px;
border: solid 1px #3f3877;
box-sizing: border-box;
clear: both;
cursor: pointer;
display: block;
font-family: inherit;
font-size: 18px;
font-weight: normal;
outline: none;
padding: 14px 35px 14px 15px;
position: relative;
text-align: left !important;
-webkit-transition: all 0.2s ease-in-out;
transition: all 0.2s ease-in-out;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
white-space: nowrap;
width: 160px;
}
.nice-select:hover {
border-color: #3f3877; }
.nice-select:active, .nice-select.open, .nice-select:focus {
border-color: #3f3877; }
.nice-select:after {
border-bottom: 2px solid #7b7c98;
border-right: 2px solid #7b7c98;
content: '';
display: block;
height: 12px;
margin-top: -6px;
pointer-events: none;
position: absolute;
right: 14px;
top: 50%;
-webkit-transform-origin: 66% 66%;
-ms-transform-origin: 66% 66%;
transform-origin: 66% 66%;
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
-webkit-transition: all 0.15s ease-in-out;
transition: all 0.15s ease-in-out;
width: 12px; }
.nice-select.open:after {
-webkit-transform: rotate(-135deg);
-ms-transform: rotate(-135deg);
transform: rotate(-135deg); }
.nice-select.open .list {
opacity: 1;
display: block;
pointer-events: auto;
-webkit-transform: scale(1) translateY(0);
-ms-transform: scale(1) translateY(0);
transform: scale(1) translateY(0); }
.nice-select.disabled {
border-color: #3f3877;
color: #3f3877;
pointer-events: none; }
.nice-select.disabled:after {
border-color: #3f3877; }
.nice-select.wide {
width: 100%; }
.nice-select.wide .list {
left: 0 !important;
right: 0 !important; }
.nice-select.right {
float: right; }
.nice-select.right .list {
left: auto;
right: 0; }
.nice-select.small {
font-size: 12px;
height: 36px;
line-height: 34px; }
.nice-select.small:after {
height: 4px;
width: 4px; }
.nice-select.small .option {
line-height: 34px;
min-height: 34px; }
.nice-select .list {
background-color: #150145;
border-radius: 5px;
box-sizing: border-box;
margin-top: 4px;
opacity: 0;
width: 160px;
display: none;
overflow: hidden;
padding: 0;
pointer-events: none;
position: absolute;
right: 0;
-webkit-transform-origin: 50% 0;
-ms-transform-origin: 50% 0;
transform-origin: 50% 0;
-webkit-transform: scale(0.75) translateY(-21px);
-ms-transform: scale(0.75) translateY(-21px);
transform: scale(0.75) translateY(-21px);
-webkit-transition: all 0.2s cubic-bezier(0.5, 0, 0, 1.25), opacity 0.15s ease-out;
transition: all 0.2s cubic-bezier(0.5, 0, 0, 1.25), opacity 0.15s ease-out;
z-index: 9;
margin-bottom: 4px;
}
.nice-select .list li:not(:last-child){
margin-right: 0 !important;
}
.nice-select .option {
cursor: pointer;
font-weight: 500;
font-size: 14px;
line-height: 40px;
list-style: none;
min-height: 40px;
outline: none;
z-index: 9999999;
padding: 0px 10px;
border: 1px solid #121254;
text-align: left;
-webkit-transition: all 0.2s;
transition: all 0.2s;
}
.nice-select .option:hover, .nice-select .option.focus, .nice-select .option.selected.focus {
background-color: #101046; }
.nice-select .option.selected {
font-weight: bold; }
.nice-select .option.disabled {
background-color: transparent;
color: #999;
cursor: default;
}
.no-csspointerevents .nice-select .list {
display: none; }
.no-csspointerevents .nice-select.open .list {
display: block; }
+100
View File
@@ -0,0 +1,100 @@
.odometer.odometer-auto-theme,
.odometer.odometer-theme-default {
display: inline-block;
vertical-align: middle;
position: relative;
}
.odometer.odometer-auto-theme .odometer-digit,
.odometer.odometer-theme-default .odometer-digit {
display: inline-block;
vertical-align: middle;
position: relative;
}
.odometer.odometer-auto-theme .odometer-digit .odometer-digit-spacer,
.odometer.odometer-theme-default .odometer-digit .odometer-digit-spacer {
display: inline-block;
vertical-align: middle;
visibility: hidden;
}
.odometer.odometer-auto-theme .odometer-digit .odometer-digit-inner,
.odometer.odometer-theme-default .odometer-digit .odometer-digit-inner {
text-align: left;
display: block;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
overflow: hidden;
}
.odometer.odometer-auto-theme .odometer-digit .odometer-ribbon,
.odometer.odometer-theme-default .odometer-digit .odometer-ribbon {
display: block;
}
.odometer.odometer-auto-theme .odometer-digit .odometer-ribbon-inner,
.odometer.odometer-theme-default .odometer-digit .odometer-ribbon-inner {
display: block;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
.odometer.odometer-auto-theme .odometer-digit .odometer-value,
.odometer.odometer-theme-default .odometer-digit .odometer-value {
display: block;
-webkit-transform: translateZ(0);
transform: translateZ(0);
}
.odometer.odometer-auto-theme
.odometer-digit
.odometer-value.odometer-last-value,
.odometer.odometer-theme-default
.odometer-digit
.odometer-value.odometer-last-value {
position: absolute;
}
.odometer.odometer-auto-theme.odometer-animating-up .odometer-ribbon-inner,
.odometer.odometer-theme-default.odometer-animating-up .odometer-ribbon-inner {
-webkit-transition: -webkit-transform 2s;
-moz-transition: -moz-transform 2s;
-ms-transition: -ms-transform 2s;
-o-transition: -o-transform 2s;
transition: transform 2s;
}
.odometer.odometer-auto-theme.odometer-animating-up.odometer-animating
.odometer-ribbon-inner,
.odometer.odometer-theme-default.odometer-animating-up.odometer-animating
.odometer-ribbon-inner {
-webkit-transform: translateY(-100%);
-moz-transform: translateY(-100%);
-ms-transform: translateY(-100%);
-o-transform: translateY(-100%);
transform: translateY(-100%);
}
.odometer.odometer-auto-theme.odometer-animating-down .odometer-ribbon-inner,
.odometer.odometer-theme-default.odometer-animating-down
.odometer-ribbon-inner {
-webkit-transform: translateY(-100%);
-moz-transform: translateY(-100%);
-ms-transform: translateY(-100%);
-o-transform: translateY(-100%);
transform: translateY(-100%);
}
.odometer.odometer-auto-theme.odometer-animating-down.odometer-animating
.odometer-ribbon-inner,
.odometer.odometer-theme-default.odometer-animating-down.odometer-animating
.odometer-ribbon-inner {
-webkit-transition: -webkit-transform 2s;
-moz-transition: -moz-transform 2s;
-ms-transition: -ms-transform 2s;
-o-transition: -o-transform 2s;
transition: transform 2s;
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
transform: translateY(0);
}
.odometer.odometer-auto-theme .odometer-value,
.odometer.odometer-theme-default .odometer-value {
text-align: center;
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+48
View File
@@ -0,0 +1,48 @@
$(function() {
// Get the form.
var form = $('#contact-form');
// Get the messages div.
var formMessages = $('.form-message');
// Set up an event listener for the contact form.
$(form).submit(function(e) {
// Stop the browser from submitting the form.
e.preventDefault();
// Serialize the form data.
var formData = $(form).serialize();
// Submit the form using AJAX.
$.ajax({
type: 'POST',
url: $(form).attr('action'),
data: formData
})
.done(function(response) {
// Make sure that the formMessages div has the 'success' class.
$(formMessages).removeClass('error');
$(formMessages).addClass('success');
// Set the message text.
$(formMessages).text(response);
// Clear the form.
$('#contact-form input, #contact-form textarea').val('');
})
.fail(function(data) {
// Make sure that the formMessages div has the 'error' class.
$(formMessages).removeClass('success');
$(formMessages).addClass('error');
// Set the message text.
if (data.responseText !== '') {
$(formMessages).text(data.responseText);
} else {
$(formMessages).text('Oops! An error occurred and your message could not be sent.');
}
});
});
});
File diff suppressed because one or more lines are too long
+215
View File
@@ -0,0 +1,215 @@
/*
* jquery-circle-progress - jQuery Plugin to draw animated circular progress bars
*
* @author https://github.com/kottenator
* @version 0.6.0
*/
$.circleProgress = {
// Default options (you may override them)
defaults: {
/**
* This is the only required option. It should be from 0.0 to 1.0
* @type {float}
*/
value: 0,
/**
* Size of the circle / canvas in pixels
* @type {int}
*/
size: 100,
/**
* Initial angle for 0.0 value in radians
* @type {float}
*/
startAngle: -Math.PI,
/**
* Width of the arc. By default it's calculated as 1/14 of size, but you may set it explicitly in pixels
* type {int|'auto'}
*/
thickness: 'auto',
/**
* Fill of the arc. You may set it to:
* - solid color:
* - { color: '#3aeabb' }
* - { color: 'rgba(255, 255, 255, .3)' }
* - linear gradient (left to right):
* - { gradient: ['#3aeabb', '#fdd250'] }
* - { gradient: ['red', 'green', 'blue'] }
* - image:
* - { image: 'http://i.imgur.com/pT0i89v.png' }
* - { color: 'lime', image: 'http://i.imgur.com/pT0i89v.png' } - color displayed until the image is loaded
*/
fill: {
gradient: ['#3aeabb', '#fdd250']
},
/**
* Color of the "empty" arc. Only a color fill supported by now
* @type {string}
*/
emptyFill: 'rgba(0, 0, 0, .1)',
/**
* Animation config (see jQuery animations: http://api.jquery.com/animate/)
*/
animation: {
duration: 1200,
easing: 'circleProgressEasing'
}
}
};
// Renamed ease-in-out-cubic
$.easing.circleProgressEasing = function(x, t, b, c, d) {
if ((t /= d / 2) < 1)
return c / 2 * t * t * t + b;
return c / 2 * ((t -= 2) * t * t + 2) + b;
};
/**
* Draw animated circular progress bar.
*
* Appends <canvas> to the element or updates already appended one.
*
* If animated, throws 3 events:
*
* - circle-animation-start(jqEvent)
* - circle-animation-progress(jqEvent, animationProgress, stepValue) - multiple event;
* animationProgress: from 0.0 to 1.0;
* stepValue: from 0.0 to value
* - circle-animation-end(jqEvent)
*
* @param options Example: { value: 0.75, size: 50, animation: false };
* you may set any of default options (see above);
* `animation` may be set to false;
* you may also use .circleProgress('widget') to get the canvas
*/
$.fn.circleProgress = function(options) {
if (options == 'widget')
return this.data('circle-progress');
options = $.extend({}, $.circleProgress.defaults, options);
return this.each(function() {
var el = $(this),
size = options.size,
radius = size / 2,
thickness = size / 14,
value = options.value,
startAngle = options.startAngle,
emptyArcFill = options.emptyFill,
arcFill;
if ($.isNumeric(options.thickness))
thickness = options.thickness;
// Prepare canvas
var canvas = el.data('circle-progress');
if (!canvas) {
canvas = $('<canvas>').prependTo(el)[0];
el.data('circle-progress', canvas);
}
canvas.width = size;
canvas.height = size;
var ctx = canvas.getContext('2d');
if (!options.fill)
throw Error("The fill is not specified!");
if (options.fill.color)
arcFill = options.fill.color;
if (options.fill.gradient) {
var gr = options.fill.gradient;
if (gr.length == 1) {
arcFill = gr[0];
} else if (gr.length > 1) {
var lg = ctx.createLinearGradient(0, 0, size, 0);
for (var i = 0; i < gr.length; i++)
lg.addColorStop(i / (gr.length - 1), gr[i]);
arcFill = lg;
}
}
if (options.fill.image) {
var img = new Image();
img.src = options.fill.image;
img.onload = function() {
var bg = $('<canvas>')[0];
bg.width = size;
bg.height = size;
bg.getContext('2d').drawImage(img, 0, 0, size, size);
arcFill = ctx.createPattern(bg, 'no-repeat');
// we need to redraw static value
if (!options.animation)
draw(value);
}
}
if (options.animation)
drawAnimated(value);
else
draw(value);
function draw(v) {
ctx.clearRect(0, 0, size, size);
drawArc(v);
drawEmptyArc(v);
}
function drawArc(v) {
ctx.save();
ctx.beginPath();
ctx.arc(radius, radius, radius - thickness / 2, startAngle, startAngle + Math.PI * 2 * v);
ctx.lineWidth = thickness;
ctx.strokeStyle = arcFill;
ctx.stroke();
ctx.restore();
}
function drawEmptyArc(v) {
ctx.save();
if (v < 1) {
ctx.beginPath();
if (v <= 0)
ctx.arc(radius, radius, radius - thickness / 2, 0, Math.PI * 2);
else
ctx.arc(radius, radius, radius - thickness / 2, startAngle + Math.PI * 2 * v, startAngle);
ctx.lineWidth = thickness;
ctx.strokeStyle = emptyArcFill;
ctx.stroke();
}
ctx.restore();
}
function drawAnimated(v) {
el.trigger('circle-animation-start');
$(canvas).css({
progress: 0
}).animate({
progress: v
},
$.extend({}, options.animation, {
step: function(p) {
draw(p);
el.trigger('circle-animation-progress', [p / v, p]);
},
complete: function() {
el.trigger('circle-animation-end');
}
})
);
}
});
};
+48
View File
@@ -0,0 +1,48 @@
// Set the date we're counting down to
(function () {
const second = 1000,
minute = second * 60,
hour = minute * 60,
day = hour * 24;
let today = new Date(),
dd = String(today.getDate()).padStart(2, "0"),
mm = String(today.getMonth() + 1).padStart(2, "0"),
yyyy = today.getFullYear(),
nextYear = yyyy + 1,
dayMonth = "10/20/",
birthday = dayMonth + yyyy;
today = mm + "/" + dd + "/" + yyyy;
if (today > birthday) {
birthday = dayMonth + nextYear;
}
//end
const countDown = new Date(birthday).getTime(),
x = setInterval(function () {
const now = new Date().getTime(),
distance = countDown - now;
(document.getElementById("day").innerText = Math.floor(
distance / day
)),
(document.getElementById("Hours").innerText = Math.floor(
(distance % day) / hour
)),
(document.getElementById("Minutes").innerText = Math.floor(
(distance % hour) / minute
)),
(document.getElementById("Seconds").innerText = Math.floor(
(distance % minute) / second
));
//do something later when date is reached
if (distance < 0) {
document.getElementById("headline").innerText = "It's my birthday!";
document.getElementById("countdown").style.display = "none";
document.getElementById("content").style.display = "block";
clearInterval(x);
}
//seconds
}, 0);
})();
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
(function($){"use strict";$.fn.counterUp=function(options){var settings=$.extend({time:400,delay:10,offset:100,beginAt:0,formatter:false,context:"window",callback:function(){}},options),s;return this.each(function(){var $this=$(this),counter={time:$(this).data("counterup-time")||settings.time,delay:$(this).data("counterup-delay")||settings.delay,offset:$(this).data("counterup-offset")||settings.offset,beginAt:$(this).data("counterup-beginat")||settings.beginAt,context:$(this).data("counterup-context")||settings.context};var counterUpper=function(){var nums=[];var divisions=counter.time/counter.delay;var num=$(this).attr("data-num")?$(this).attr("data-num"):$this.text();var isComma=/[0-9]+,[0-9]+/.test(num);num=num.replace(/,/g,"");var decimalPlaces=(num.split(".")[1]||[]).length;if(counter.beginAt>num)counter.beginAt=num;var isTime=/[0-9]+:[0-9]+:[0-9]+/.test(num);if(isTime){var times=num.split(":"),m=1;s=0;while(times.length>0){s+=m*parseInt(times.pop(),10);m*=60}}for(var i=divisions;i>=counter.beginAt/num*divisions;i--){var newNum=parseFloat(num/divisions*i).toFixed(decimalPlaces);if(isTime){newNum=parseInt(s/divisions*i);var hours=parseInt(newNum/3600)%24;var minutes=parseInt(newNum/60)%60;var seconds=parseInt(newNum%60,10);newNum=(hours<10?"0"+hours:hours)+":"+(minutes<10?"0"+minutes:minutes)+":"+(seconds<10?"0"+seconds:seconds)}if(isComma){while(/(\d+)(\d{3})/.test(newNum.toString())){newNum=newNum.toString().replace(/(\d+)(\d{3})/,"$1"+","+"$2")}}if(settings.formatter){newNum=settings.formatter.call(this,newNum)}nums.unshift(newNum)}$this.data("counterup-nums",nums);$this.text(counter.beginAt);var f=function(){if(!$this.data("counterup-nums")){settings.callback.call(this);return}$this.html($this.data("counterup-nums").shift());if($this.data("counterup-nums").length){setTimeout($this.data("counterup-func"),counter.delay)}else{$this.data("counterup-nums",null);$this.data("counterup-func",null);settings.callback.call(this)}};$this.data("counterup-func",f);setTimeout($this.data("counterup-func"),counter.delay)};$this.waypoint(function(direction){counterUpper();this.destroy()},{offset:counter.offset+"%",context:counter.context})})}})(jQuery);
File diff suppressed because one or more lines are too long
+90
View File
@@ -0,0 +1,90 @@
/*!
* jQuery meanMenu v2.0.8
* @Copyright (C) 2012-2014 Chris Wharton @ MeanThemes (https://github.com/meanthemes/meanMenu)
*
*/
! function(e) {
"use strict";
e.fn.meanmenu = function(n) {
var a = {
meanMenuTarget: jQuery(this),
meanMenuContainer: "body",
meanMenuClose: "X",
meanMenuCloseSize: "18px",
meanMenuOpen: "<span /><span /><span />",
meanRevealPosition: "right",
meanRevealPositionDistance: "0",
meanRevealColour: "",
meanScreenWidth: "480",
meanNavPush: "",
meanShowChildren: !0,
meanExpandableChildren: !0,
meanRemoveAttrs: !1,
onePage: !1,
meanDisplay: "block",
removeElements: ""
};
n = e.extend(a, n);
var t = window.innerWidth || document.documentElement.clientWidth;
return this.each(function() {
var e = n.meanMenuTarget,
a = n.meanMenuContainer,
r = n.meanMenuClose,
i = n.meanMenuCloseSize,
s = n.meanMenuOpen,
u = n.meanRevealPosition,
m = n.meanRevealPositionDistance,
l = n.meanRevealColour,
o = n.meanScreenWidth,
c = n.meanNavPush,
d = n.meanShowChildren,
v = n.meanExpandableChildren,
h = n.meanExpand,
y = n.meanRemoveAttrs,
j = n.onePage,
Q = n.meanDisplay,
f = n.removeElements,
p = !1;
(navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPod/i) || navigator.userAgent.match(/iPad/i) || navigator.userAgent.match(/Android/i) || navigator.userAgent.match(/Blackberry/i) || navigator.userAgent.match(/Windows Phone/i)) && (p = !0), (navigator.userAgent.match(/MSIE 8/i) || navigator.userAgent.match(/MSIE 7/i)) && jQuery("html").css("overflow-y", "scroll");
var g = "",
C = function() {
if ("center" === u) {
var e = (window.innerWidth || document.documentElement.clientWidth) / 2 - 22 + "px";
g = "left:" + e + ";right:auto;", p ? jQuery(".meanmenu-reveal").animate({
left: e
}) : jQuery(".meanmenu-reveal").css("left", e)
}
},
w = !1,
A = !1;
"right" === u && (g = "right:" + m + ";left:auto;"), "left" === u && (g = "left:" + m + ";right:auto;"), C();
var M = "",
P = function() {
jQuery(".mean-bar,.mean-push").remove(), jQuery(a).removeClass("mean-container"), jQuery(e).css("display", Q), w = !1, A = !1, jQuery(f).removeClass("mean-remove")
},
E = function() {
var n = "background:" + l + ";color:" + l + ";" + g;
if (t <= o) {
jQuery(f).addClass("mean-remove"), A = !0, jQuery(a).addClass("mean-container"), jQuery(".mean-container").prepend('<div class="mean-bar"><a href="#nav" class="meanmenu-reveal" style="' + n + '">Show Navigation</a><nav class="mean-nav"></nav></div>');
var u = jQuery(e).html();
jQuery(".mean-nav").html(u), y && jQuery("nav.mean-nav ul, nav.mean-nav ul *").each(function() {
jQuery(this).is(".mean-remove") ? jQuery(this).attr("class", "mean-remove") : jQuery(this).removeAttr("class"), jQuery(this).removeAttr("id")
}), jQuery(e).before('<div class="mean-push" />'), jQuery(".mean-push").css("margin-top", c), jQuery(e).hide(), jQuery(".meanmenu-reveal").show(), jQuery(".meanmenu-reveal").html(s), M = jQuery(".meanmenu-reveal"), jQuery(".mean-nav ul").hide(), d ? v ? (jQuery(".mean-nav ul ul").each(function() {
jQuery(this).children().length && jQuery(this, "li:first").parent().append('<a class="mean-expand" href="#" style="font-size: ' + i + '">' + h + "</a>")
}), jQuery(".mean-expand").on("click", function(e) {
e.preventDefault(), jQuery(this).hasClass("mean-clicked") ? (jQuery(this).prev("ul").slideUp(300, function() {}), jQuery(this).parent().removeClass("dropdown-opened")) : (jQuery(this).prev("ul").slideDown(300, function() {}), jQuery(this).parent().addClass("dropdown-opened")), jQuery(this).toggleClass("mean-clicked")
})) : jQuery(".mean-nav ul ul").show() : jQuery(".mean-nav ul ul").hide(), jQuery(".mean-nav ul li").last().addClass("mean-last"), M.removeClass("meanclose"), jQuery(M).click(function(e) {
e.preventDefault(), !1 === w ? (M.css("text-align", "center"), M.css("text-indent", "0"), M.css("font-size", i), jQuery(".mean-nav ul:first").slideDown(), w = !0) : (jQuery(".mean-nav ul:first").slideUp(), w = !1), M.toggleClass("meanclose"), jQuery(M).is(".meanmenu-reveal.meanclose") ? M.html(r) : M.html(s), jQuery(f).addClass("mean-remove")
}), j && jQuery(".mean-nav ul > li > a:first-child").on("click", function() {
jQuery(".mean-nav ul:first").slideUp(), w = !1, jQuery(M).toggleClass("meanclose").html(s)
})
} else P()
};
p || jQuery(window).resize(function() {
t = window.innerWidth || document.documentElement.clientWidth, P(), t <= o ? (E(), C()) : P()
}), jQuery(window).resize(function() {
t = window.innerWidth || document.documentElement.clientWidth, p ? (C(), t <= o ? !1 === A && E() : P()) : (P(), t <= o && (E(), C()))
}), E()
})
}
}(jQuery);
+4
View File
@@ -0,0 +1,4 @@
/* jQuery Nice Select - v1.0
https://github.com/hernansartorio/jquery-nice-select
Made by Hernán Sartorio */
!function(e){e.fn.niceSelect=function(t){function s(t){t.after(e("<div></div>").addClass("nice-select").addClass(t.attr("class")||"").addClass(t.attr("disabled")?"disabled":"").attr("tabindex",t.attr("disabled")?null:"0").html('<span class="current"></span><ul class="list"></ul>'));var s=t.next(),n=t.find("option"),i=t.find("option:selected");s.find(".current").html(i.data("display")||i.text()),n.each(function(t){var n=e(this),i=n.data("display");s.find("ul").append(e("<li></li>").attr("data-value",n.val()).attr("data-display",i||null).addClass("option"+(n.is(":selected")?" selected":"")+(n.is(":disabled")?" disabled":"")).html(n.text()))})}if("string"==typeof t)return"update"==t?this.each(function(){var t=e(this),n=e(this).next(".nice-select"),i=n.hasClass("open");n.length&&(n.remove(),s(t),i&&t.next().trigger("click"))}):"destroy"==t?(this.each(function(){var t=e(this),s=e(this).next(".nice-select");s.length&&(s.remove(),t.css("display",""))}),0==e(".nice-select").length&&e(document).off(".nice_select")):console.log('Method "'+t+'" does not exist.'),this;this.hide(),this.each(function(){var t=e(this);t.next().hasClass("nice-select")||s(t)}),e(document).off(".nice_select"),e(document).on("click.nice_select",".nice-select",function(t){var s=e(this);e(".nice-select").not(s).removeClass("open"),s.toggleClass("open"),s.hasClass("open")?(s.find(".option"),s.find(".focus").removeClass("focus"),s.find(".selected").addClass("focus")):s.focus()}),e(document).on("click.nice_select",function(t){0===e(t.target).closest(".nice-select").length&&e(".nice-select").removeClass("open").find(".option")}),e(document).on("click.nice_select",".nice-select .option:not(.disabled)",function(t){var s=e(this),n=s.closest(".nice-select");n.find(".selected").removeClass("selected"),s.addClass("selected");var i=s.data("display")||s.text();n.find(".current").text(i),n.prev("select").val(s.data("value")).trigger("change")}),e(document).on("keydown.nice_select",".nice-select",function(t){var s=e(this),n=e(s.find(".focus")||s.find(".list .option.selected"));if(32==t.keyCode||13==t.keyCode)return s.hasClass("open")?n.trigger("click"):s.trigger("click"),!1;if(40==t.keyCode){if(s.hasClass("open")){var i=n.nextAll(".option:not(.disabled)").first();i.length>0&&(s.find(".focus").removeClass("focus"),i.addClass("focus"))}else s.trigger("click");return!1}if(38==t.keyCode){if(s.hasClass("open")){var l=n.prevAll(".option:not(.disabled)").first();l.length>0&&(s.find(".focus").removeClass("focus"),l.addClass("focus"))}else s.trigger("click");return!1}if(27==t.keyCode)s.hasClass("open")&&s.trigger("click");else if(9==t.keyCode&&s.hasClass("open"))return!1});var n=document.createElement("a").style;return n.cssText="pointer-events:auto","auto"!==n.pointerEvents&&e("html").addClass("no-csspointerevents"),this}}(jQuery);
+662
View File
@@ -0,0 +1,662 @@
/*!
Waypoints - 4.0.1
Copyright © 2011-2016 Caleb Troughton
Licensed under the MIT license.
https://github.com/imakewebthings/waypoints/blob/master/licenses.txt
*/
(function() {
'use strict'
var keyCounter = 0
var allWaypoints = {}
/* http://imakewebthings.com/waypoints/api/waypoint */
function Waypoint(options) {
if (!options) {
throw new Error('No options passed to Waypoint constructor')
}
if (!options.element) {
throw new Error('No element option passed to Waypoint constructor')
}
if (!options.handler) {
throw new Error('No handler option passed to Waypoint constructor')
}
this.key = 'waypoint-' + keyCounter
this.options = Waypoint.Adapter.extend({}, Waypoint.defaults, options)
this.element = this.options.element
this.adapter = new Waypoint.Adapter(this.element)
this.callback = options.handler
this.axis = this.options.horizontal ? 'horizontal' : 'vertical'
this.enabled = this.options.enabled
this.triggerPoint = null
this.group = Waypoint.Group.findOrCreate({
name: this.options.group,
axis: this.axis
})
this.context = Waypoint.Context.findOrCreateByElement(this.options.context)
if (Waypoint.offsetAliases[this.options.offset]) {
this.options.offset = Waypoint.offsetAliases[this.options.offset]
}
this.group.add(this)
this.context.add(this)
allWaypoints[this.key] = this
keyCounter += 1
}
/* Private */
Waypoint.prototype.queueTrigger = function(direction) {
this.group.queueTrigger(this, direction)
}
/* Private */
Waypoint.prototype.trigger = function(args) {
if (!this.enabled) {
return
}
if (this.callback) {
this.callback.apply(this, args)
}
}
/* Public */
/* http://imakewebthings.com/waypoints/api/destroy */
Waypoint.prototype.destroy = function() {
this.context.remove(this)
this.group.remove(this)
delete allWaypoints[this.key]
}
/* Public */
/* http://imakewebthings.com/waypoints/api/disable */
Waypoint.prototype.disable = function() {
this.enabled = false
return this
}
/* Public */
/* http://imakewebthings.com/waypoints/api/enable */
Waypoint.prototype.enable = function() {
this.context.refresh()
this.enabled = true
return this
}
/* Public */
/* http://imakewebthings.com/waypoints/api/next */
Waypoint.prototype.next = function() {
return this.group.next(this)
}
/* Public */
/* http://imakewebthings.com/waypoints/api/previous */
Waypoint.prototype.previous = function() {
return this.group.previous(this)
}
/* Private */
Waypoint.invokeAll = function(method) {
var allWaypointsArray = []
for (var waypointKey in allWaypoints) {
allWaypointsArray.push(allWaypoints[waypointKey])
}
for (var i = 0, end = allWaypointsArray.length; i < end; i++) {
allWaypointsArray[i][method]()
}
}
/* Public */
/* http://imakewebthings.com/waypoints/api/destroy-all */
Waypoint.destroyAll = function() {
Waypoint.invokeAll('destroy')
}
/* Public */
/* http://imakewebthings.com/waypoints/api/disable-all */
Waypoint.disableAll = function() {
Waypoint.invokeAll('disable')
}
/* Public */
/* http://imakewebthings.com/waypoints/api/enable-all */
Waypoint.enableAll = function() {
Waypoint.Context.refreshAll()
for (var waypointKey in allWaypoints) {
allWaypoints[waypointKey].enabled = true
}
return this
}
/* Public */
/* http://imakewebthings.com/waypoints/api/refresh-all */
Waypoint.refreshAll = function() {
Waypoint.Context.refreshAll()
}
/* Public */
/* http://imakewebthings.com/waypoints/api/viewport-height */
Waypoint.viewportHeight = function() {
return window.innerHeight || document.documentElement.clientHeight
}
/* Public */
/* http://imakewebthings.com/waypoints/api/viewport-width */
Waypoint.viewportWidth = function() {
return document.documentElement.clientWidth
}
Waypoint.adapters = []
Waypoint.defaults = {
context: window,
continuous: true,
enabled: true,
group: 'default',
horizontal: false,
offset: 0
}
Waypoint.offsetAliases = {
'bottom-in-view': function() {
return this.context.innerHeight() - this.adapter.outerHeight()
},
'right-in-view': function() {
return this.context.innerWidth() - this.adapter.outerWidth()
}
}
window.Waypoint = Waypoint
}())
;(function() {
'use strict'
function requestAnimationFrameShim(callback) {
window.setTimeout(callback, 1000 / 60)
}
var keyCounter = 0
var contexts = {}
var Waypoint = window.Waypoint
var oldWindowLoad = window.onload
/* http://imakewebthings.com/waypoints/api/context */
function Context(element) {
this.element = element
this.Adapter = Waypoint.Adapter
this.adapter = new this.Adapter(element)
this.key = 'waypoint-context-' + keyCounter
this.didScroll = false
this.didResize = false
this.oldScroll = {
x: this.adapter.scrollLeft(),
y: this.adapter.scrollTop()
}
this.waypoints = {
vertical: {},
horizontal: {}
}
element.waypointContextKey = this.key
contexts[element.waypointContextKey] = this
keyCounter += 1
if (!Waypoint.windowContext) {
Waypoint.windowContext = true
Waypoint.windowContext = new Context(window)
}
this.createThrottledScrollHandler()
this.createThrottledResizeHandler()
}
/* Private */
Context.prototype.add = function(waypoint) {
var axis = waypoint.options.horizontal ? 'horizontal' : 'vertical'
this.waypoints[axis][waypoint.key] = waypoint
this.refresh()
}
/* Private */
Context.prototype.checkEmpty = function() {
var horizontalEmpty = this.Adapter.isEmptyObject(this.waypoints.horizontal)
var verticalEmpty = this.Adapter.isEmptyObject(this.waypoints.vertical)
var isWindow = this.element == this.element.window
if (horizontalEmpty && verticalEmpty && !isWindow) {
this.adapter.off('.waypoints')
delete contexts[this.key]
}
}
/* Private */
Context.prototype.createThrottledResizeHandler = function() {
var self = this
function resizeHandler() {
self.handleResize()
self.didResize = false
}
this.adapter.on('resize.waypoints', function() {
if (!self.didResize) {
self.didResize = true
Waypoint.requestAnimationFrame(resizeHandler)
}
})
}
/* Private */
Context.prototype.createThrottledScrollHandler = function() {
var self = this
function scrollHandler() {
self.handleScroll()
self.didScroll = false
}
this.adapter.on('scroll.waypoints', function() {
if (!self.didScroll || Waypoint.isTouch) {
self.didScroll = true
Waypoint.requestAnimationFrame(scrollHandler)
}
})
}
/* Private */
Context.prototype.handleResize = function() {
Waypoint.Context.refreshAll()
}
/* Private */
Context.prototype.handleScroll = function() {
var triggeredGroups = {}
var axes = {
horizontal: {
newScroll: this.adapter.scrollLeft(),
oldScroll: this.oldScroll.x,
forward: 'right',
backward: 'left'
},
vertical: {
newScroll: this.adapter.scrollTop(),
oldScroll: this.oldScroll.y,
forward: 'down',
backward: 'up'
}
}
for (var axisKey in axes) {
var axis = axes[axisKey]
var isForward = axis.newScroll > axis.oldScroll
var direction = isForward ? axis.forward : axis.backward
for (var waypointKey in this.waypoints[axisKey]) {
var waypoint = this.waypoints[axisKey][waypointKey]
if (waypoint.triggerPoint === null) {
continue
}
var wasBeforeTriggerPoint = axis.oldScroll < waypoint.triggerPoint
var nowAfterTriggerPoint = axis.newScroll >= waypoint.triggerPoint
var crossedForward = wasBeforeTriggerPoint && nowAfterTriggerPoint
var crossedBackward = !wasBeforeTriggerPoint && !nowAfterTriggerPoint
if (crossedForward || crossedBackward) {
waypoint.queueTrigger(direction)
triggeredGroups[waypoint.group.id] = waypoint.group
}
}
}
for (var groupKey in triggeredGroups) {
triggeredGroups[groupKey].flushTriggers()
}
this.oldScroll = {
x: axes.horizontal.newScroll,
y: axes.vertical.newScroll
}
}
/* Private */
Context.prototype.innerHeight = function() {
/*eslint-disable eqeqeq */
if (this.element == this.element.window) {
return Waypoint.viewportHeight()
}
/*eslint-enable eqeqeq */
return this.adapter.innerHeight()
}
/* Private */
Context.prototype.remove = function(waypoint) {
delete this.waypoints[waypoint.axis][waypoint.key]
this.checkEmpty()
}
/* Private */
Context.prototype.innerWidth = function() {
/*eslint-disable eqeqeq */
if (this.element == this.element.window) {
return Waypoint.viewportWidth()
}
/*eslint-enable eqeqeq */
return this.adapter.innerWidth()
}
/* Public */
/* http://imakewebthings.com/waypoints/api/context-destroy */
Context.prototype.destroy = function() {
var allWaypoints = []
for (var axis in this.waypoints) {
for (var waypointKey in this.waypoints[axis]) {
allWaypoints.push(this.waypoints[axis][waypointKey])
}
}
for (var i = 0, end = allWaypoints.length; i < end; i++) {
allWaypoints[i].destroy()
}
}
/* Public */
/* http://imakewebthings.com/waypoints/api/context-refresh */
Context.prototype.refresh = function() {
/*eslint-disable eqeqeq */
var isWindow = this.element == this.element.window
/*eslint-enable eqeqeq */
var contextOffset = isWindow ? undefined : this.adapter.offset()
var triggeredGroups = {}
var axes
this.handleScroll()
axes = {
horizontal: {
contextOffset: isWindow ? 0 : contextOffset.left,
contextScroll: isWindow ? 0 : this.oldScroll.x,
contextDimension: this.innerWidth(),
oldScroll: this.oldScroll.x,
forward: 'right',
backward: 'left',
offsetProp: 'left'
},
vertical: {
contextOffset: isWindow ? 0 : contextOffset.top,
contextScroll: isWindow ? 0 : this.oldScroll.y,
contextDimension: this.innerHeight(),
oldScroll: this.oldScroll.y,
forward: 'down',
backward: 'up',
offsetProp: 'top'
}
}
for (var axisKey in axes) {
var axis = axes[axisKey]
for (var waypointKey in this.waypoints[axisKey]) {
var waypoint = this.waypoints[axisKey][waypointKey]
var adjustment = waypoint.options.offset
var oldTriggerPoint = waypoint.triggerPoint
var elementOffset = 0
var freshWaypoint = oldTriggerPoint == null
var contextModifier, wasBeforeScroll, nowAfterScroll
var triggeredBackward, triggeredForward
if (waypoint.element !== waypoint.element.window) {
elementOffset = waypoint.adapter.offset()[axis.offsetProp]
}
if (typeof adjustment === 'function') {
adjustment = adjustment.apply(waypoint)
}
else if (typeof adjustment === 'string') {
adjustment = parseFloat(adjustment)
if (waypoint.options.offset.indexOf('%') > - 1) {
adjustment = Math.ceil(axis.contextDimension * adjustment / 100)
}
}
contextModifier = axis.contextScroll - axis.contextOffset
waypoint.triggerPoint = Math.floor(elementOffset + contextModifier - adjustment)
wasBeforeScroll = oldTriggerPoint < axis.oldScroll
nowAfterScroll = waypoint.triggerPoint >= axis.oldScroll
triggeredBackward = wasBeforeScroll && nowAfterScroll
triggeredForward = !wasBeforeScroll && !nowAfterScroll
if (!freshWaypoint && triggeredBackward) {
waypoint.queueTrigger(axis.backward)
triggeredGroups[waypoint.group.id] = waypoint.group
}
else if (!freshWaypoint && triggeredForward) {
waypoint.queueTrigger(axis.forward)
triggeredGroups[waypoint.group.id] = waypoint.group
}
else if (freshWaypoint && axis.oldScroll >= waypoint.triggerPoint) {
waypoint.queueTrigger(axis.forward)
triggeredGroups[waypoint.group.id] = waypoint.group
}
}
}
Waypoint.requestAnimationFrame(function() {
for (var groupKey in triggeredGroups) {
triggeredGroups[groupKey].flushTriggers()
}
})
return this
}
/* Private */
Context.findOrCreateByElement = function(element) {
return Context.findByElement(element) || new Context(element)
}
/* Private */
Context.refreshAll = function() {
for (var contextId in contexts) {
contexts[contextId].refresh()
}
}
/* Public */
/* http://imakewebthings.com/waypoints/api/context-find-by-element */
Context.findByElement = function(element) {
return contexts[element.waypointContextKey]
}
window.onload = function() {
if (oldWindowLoad) {
oldWindowLoad()
}
Context.refreshAll()
}
Waypoint.requestAnimationFrame = function(callback) {
var requestFn = window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
requestAnimationFrameShim
requestFn.call(window, callback)
}
Waypoint.Context = Context
}())
;(function() {
'use strict'
function byTriggerPoint(a, b) {
return a.triggerPoint - b.triggerPoint
}
function byReverseTriggerPoint(a, b) {
return b.triggerPoint - a.triggerPoint
}
var groups = {
vertical: {},
horizontal: {}
}
var Waypoint = window.Waypoint
/* http://imakewebthings.com/waypoints/api/group */
function Group(options) {
this.name = options.name
this.axis = options.axis
this.id = this.name + '-' + this.axis
this.waypoints = []
this.clearTriggerQueues()
groups[this.axis][this.name] = this
}
/* Private */
Group.prototype.add = function(waypoint) {
this.waypoints.push(waypoint)
}
/* Private */
Group.prototype.clearTriggerQueues = function() {
this.triggerQueues = {
up: [],
down: [],
left: [],
right: []
}
}
/* Private */
Group.prototype.flushTriggers = function() {
for (var direction in this.triggerQueues) {
var waypoints = this.triggerQueues[direction]
var reverse = direction === 'up' || direction === 'left'
waypoints.sort(reverse ? byReverseTriggerPoint : byTriggerPoint)
for (var i = 0, end = waypoints.length; i < end; i += 1) {
var waypoint = waypoints[i]
if (waypoint.options.continuous || i === waypoints.length - 1) {
waypoint.trigger([direction])
}
}
}
this.clearTriggerQueues()
}
/* Private */
Group.prototype.next = function(waypoint) {
this.waypoints.sort(byTriggerPoint)
var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
var isLast = index === this.waypoints.length - 1
return isLast ? null : this.waypoints[index + 1]
}
/* Private */
Group.prototype.previous = function(waypoint) {
this.waypoints.sort(byTriggerPoint)
var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
return index ? this.waypoints[index - 1] : null
}
/* Private */
Group.prototype.queueTrigger = function(waypoint, direction) {
this.triggerQueues[direction].push(waypoint)
}
/* Private */
Group.prototype.remove = function(waypoint) {
var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
if (index > -1) {
this.waypoints.splice(index, 1)
}
}
/* Public */
/* http://imakewebthings.com/waypoints/api/first */
Group.prototype.first = function() {
return this.waypoints[0]
}
/* Public */
/* http://imakewebthings.com/waypoints/api/last */
Group.prototype.last = function() {
return this.waypoints[this.waypoints.length - 1]
}
/* Private */
Group.findOrCreate = function(options) {
return groups[options.axis][options.name] || new Group(options)
}
Waypoint.Group = Group
}())
;(function() {
'use strict'
var $ = window.jQuery
var Waypoint = window.Waypoint
function JQueryAdapter(element) {
this.$element = $(element)
}
$.each([
'innerHeight',
'innerWidth',
'off',
'offset',
'on',
'outerHeight',
'outerWidth',
'scrollLeft',
'scrollTop'
], function(i, method) {
JQueryAdapter.prototype[method] = function() {
var args = Array.prototype.slice.call(arguments)
return this.$element[method].apply(this.$element, args)
}
})
$.each([
'extend',
'inArray',
'isEmptyObject'
], function(i, method) {
JQueryAdapter[method] = $[method]
})
Waypoint.adapters.push({
name: 'jquery',
Adapter: JQueryAdapter
})
Waypoint.Adapter = JQueryAdapter
}())
;(function() {
'use strict'
var Waypoint = window.Waypoint
function createExtension(framework) {
return function() {
var waypoints = []
var overrides = arguments[0]
if (framework.isFunction(arguments[0])) {
overrides = framework.extend({}, arguments[1])
overrides.handler = arguments[0]
}
this.each(function() {
var options = framework.extend({}, overrides, {
element: this
})
if (typeof options.context === 'string') {
options.context = framework(this).closest(options.context)[0]
}
waypoints.push(new Waypoint(options))
})
return waypoints
}
}
if (window.jQuery) {
window.jQuery.fn.waypoint = createExtension(window.jQuery)
}
if (window.Zepto) {
window.Zepto.fn.waypoint = createExtension(window.Zepto)
}
}())
;
+1
View File
File diff suppressed because one or more lines are too long
+793
View File
@@ -0,0 +1,793 @@
(function($) {
"use strict";
const $documentOn = $(document);
const $windowOn = $(window);
$documentOn.ready( function() {
//>> Mobile Menu Js Start <<//
$('#mobile-menu').meanmenu({
meanMenuContainer: '.mobile-menu',
meanScreenWidth: "1199",
meanExpand: ['<i class="far fa-plus"></i>'],
});
$('#mobile-menus').meanmenu({
meanMenuContainer: '.mobile-menus',
meanScreenWidth: "1920",
meanExpand: ['<i class="far fa-plus"></i>'],
});
//>> Sidebar Toggle Js Start <<//
$(".offcanvas__close,.offcanvas__overlay").on("click", function () {
$(".offcanvas__info").removeClass("info-open");
$(".offcanvas__overlay").removeClass("overlay-open");
});
$(".sidebar__toggle").on("click", function () {
$(".offcanvas__info").addClass("info-open");
$(".offcanvas__overlay").addClass("overlay-open");
});
//>> Body Overlay Js Start <<//
$(".body-overlay").on("click", function () {
$(".offcanvas__area").removeClass("offcanvas-opened");
$(".df-search-area").removeClass("opened");
$(".body-overlay").removeClass("opened");
});
/* ================================
Back To Top Button Js Start
================================ */
// Function to toggle back-to-top button visibility
function toggleBackTop() {
if ($(window).scrollTop() + $(window).height() >= $(document).height()) {
$("#back-top").addClass("show");
} else {
$("#back-top").removeClass("show");
}
}
// On scroll
$windowOn.on('scroll', function() {
toggleBackTop();
});
// On document ready, force hide the button
$(document).ready(function() {
$("#back-top").removeClass("show");
});
// On click
$documentOn.on('click', '#back-top', function() {
$('html, body').animate({ scrollTop: 0 }, 800);
return false;
});
//>> Sticky Header Js Start <<//
$windowOn.on("scroll", function () {
if ($(this).scrollTop() > 250) {
$("#header-sticky").addClass("sticky");
} else {
$("#header-sticky").removeClass("sticky");
}
});
//>> Video Popup Start <<//
$(".img-popup").magnificPopup({
type: "image",
gallery: {
enabled: true,
},
});
$(".img-popup2").magnificPopup({
type: "image",
gallery: {
enabled: true,
},
});
$(".video-popup").magnificPopup({
type: "iframe",
callbacks: {},
});
//>> Wow Animation Start <<//
new WOW().init();
//>> Nice Select Start <<//
$('select').niceSelect();
// circle-progress
if ($(".circle-bar").length) {
$(".circle-bar").each(function () {
let $this = $(this);
let value = $this.data("percent") || 0.99;
$this.circleProgress({
value: value,
size: 150,
thickness: 10,
fill: { color: "#fff" },
emptyFill: "rgba(255,255,255,0.2)"
}).on("circle-animation-progress", function (event, progress, stepValue) {
$(this).find("strong").html(Math.round(stepValue * 100) + "%");
});
$this.append("<strong></strong>");
});
}
//>> Hero Slider Start <<//
var swiper = new Swiper(".hero-slider", {
loop: true,
autoplay: {
delay: 4000,
disableOnInteraction: false,
},
speed: 800,
effect: "slide", // left theke asbe
navigation: {
nextEl: ".swiper-button-next",
prevEl: ".swiper-button-prev",
},
pagination: {
el: ".dot-number",
clickable: true,
renderBullet: function(index, className) {
const dotContent = document.querySelectorAll(
".dot-number .dot-num"
);
return `
<span class="${className}">
${dotContent[index]?.outerHTML || ""}
</span>
`;
},
},
});
//>> Image Slider Start <<//
var swiper = new Swiper(".image-slider", {
loop: true,
autoplay: {
delay: 4000,
disableOnInteraction: false,
},
pagination: {
el: ".dot-number",
clickable: true,
renderBullet: function(index, className) {
const dotContent = document.querySelectorAll(
".dot-number .dot-num"
);
return `
<span class="${className}">
${dotContent[index]?.outerHTML || ""}
</span>
`;
},
},
speed: 800,
effect: "slide",
on: {
slideChangeTransitionStart: function () {
document.querySelectorAll('.hero-image img').forEach(img => {
img.classList.remove('animate__fadeInUp');
});
},
slideChangeTransitionEnd: function () {
let activeImg = document.querySelector('.swiper-slide-active .hero-image img');
if(activeImg){
activeImg.classList.add('animate__animated', 'animate__fadeInUp');
}
}
}
});
//>>Testimonial Slider Start <<//
if($('.testimonial-slider').length > 0) {
const TestimonialSlider = new Swiper(".testimonial-slider", {
spaceBetween: 30,
speed: 1300,
loop: true,
autoplay: {
delay: 2000,
disableOnInteraction: false,
},
breakpoints: {
1199: {
slidesPerView: 2,
},
991: {
slidesPerView: 2,
},
767: {
slidesPerView: 1,
},
575: {
slidesPerView: 1,
},
0: {
slidesPerView: 1,
},
},
});
}
// Create mask divs for each wrapper
document.querySelectorAll(".tp-clip-anim").forEach(wrapper => {
const img = wrapper.querySelector(".tp-anim-img[data-animate='true']");
if (!img) return;
const url = img.src;
// ensure wrapper position relative
wrapper.style.position = "relative";
// IntersectionObserver
const observer = new IntersectionObserver((entries, obs) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
wrapper.querySelectorAll(".mask").forEach(m => m.remove());
// Create 9 masks
for (let i = 0; i < 9; i++) {
const mask = document.createElement("div");
mask.className = `mask mask-${i + 1}`;
Object.assign(mask.style, {
backgroundImage: `url(${url})`,
backgroundSize: "cover",
backgroundPosition: "center",
position: "absolute",
inset: "0"
});
wrapper.appendChild(mask);
}
// observer stop
obs.unobserve(entry.target);
}
});
}, { threshold: 0.2 });
observer.observe(wrapper);
});
//>> Gt Brand Slider Start <<//
if($('.brand-slider').length > 0) {
const BrandSlider = new Swiper(".brand-slider", {
spaceBetween: 30,
speed: 1300,
loop: true,
centeredSlides: true,
autoplay: {
delay: 2000,
disableOnInteraction: false,
},
breakpoints: {
1199: {
slidesPerView: 5,
},
991: {
slidesPerView: 4,
},
767: {
slidesPerView: 3,
},
575: {
slidesPerView: 2,
},
0: {
slidesPerView: 1,
},
},
});
}
//>> Service Slider Start <<//
if($('.service-slider').length > 0) {
const ServiceSlider = new Swiper(".service-slider", {
spaceBetween: 0,
speed: 1300,
loop: true,
autoplay: {
delay: 2000,
disableOnInteraction: false,
},
navigation: {
nextEl: ".array-prev",
prevEl: ".array-next",
},
pagination: {
el: ".service-dot",
},
breakpoints: {
1199: {
slidesPerView: 4,
},
991: {
slidesPerView: 3,
},
767: {
slidesPerView: 2,
},
575: {
slidesPerView: 1,
},
0: {
slidesPerView: 1,
},
},
});
}
//>> Testimonial Slider Start <<//
if($('.testimonial-slider-2').length > 0) {
const TestimonialSlider2 = new Swiper(".testimonial-slider-2", {
spaceBetween: 30,
speed: 1300,
loop: true,
autoplay: {
delay: 2000,
disableOnInteraction: false,
},
breakpoints: {
1199: {
slidesPerView: 1,
},
991: {
slidesPerView: 1,
},
767: {
slidesPerView: 1,
},
575: {
slidesPerView: 1,
},
0: {
slidesPerView: 1,
},
},
});
}
//>> Test Slider Start <<//
if($('.test-slider').length > 0) {
const TestSlider = new Swiper(".test-slider", {
direction: "vertical",
spaceBetween: 30,
speed: 1300,
loop: true,
autoplay: {
delay: 2000,
disableOnInteraction: false,
},
breakpoints: {
1199: {
slidesPerView: 3,
},
991: {
slidesPerView: 2,
},
767: {
slidesPerView: 1,
},
575: {
slidesPerView: 1,
},
0: {
slidesPerView: 1,
},
},
});
}
//>> Visa Slider Start <<//
if($('.visa-slider').length > 0) {
const VisaSlider = new Swiper(".visa-slider", {
spaceBetween: 30,
speed: 1300,
loop: true,
autoplay: {
delay: 2000,
disableOnInteraction: false,
},
navigation: {
nextEl: ".array-prev",
prevEl: ".array-next",
},
breakpoints: {
1199: {
slidesPerView: 4,
},
991: {
slidesPerView: 3,
},
767: {
slidesPerView: 2,
},
575: {
slidesPerView: 1,
},
0: {
slidesPerView: 1,
},
},
});
}
//>> Visa Slider Start <<//
if($('.testimonial-slider-3').length > 0) {
const TestimonialSlider3 = new Swiper(".testimonial-slider-3", {
spaceBetween: 30,
speed: 1300,
loop: true,
autoplay: {
delay: 2000,
disableOnInteraction: false,
},
navigation: {
nextEl: ".array-prev",
prevEl: ".array-next",
},
breakpoints: {
1199: {
slidesPerView: 1,
},
991: {
slidesPerView: 1,
},
767: {
slidesPerView: 1,
},
575: {
slidesPerView: 1,
},
0: {
slidesPerView: 1,
},
},
});
}
//>> Service-item Hover Image Show Slider Start <<//
const serviceItems = document.querySelectorAll(".service-item");
serviceItems.forEach((item) => {
const imageHover = item.querySelector(".image-hover");
item.addEventListener("mousemove", (event) => {
const rect = item.getBoundingClientRect();
const dx = event.clientX - rect.left;
const dy = event.clientY - rect.top;
imageHover.style.transform = `translate(${dx}px, ${dy}px) translate(-50%, -50%)`;
// imageHover.style.transform = `translate(${dx}px, ${dy}px) rotate(28.57deg)`;
imageHover.style.opacity = "1";
imageHover.style.visibility = "visible";
});
item.addEventListener("mouseleave", () => {
imageHover.style.opacity = "0";
imageHover.style.visibility = "hidden";
});
});
/* ================================
Custom Accordion Js Start
================================ */
$(".accordion-single .header-area").on("click", function () {
if ($(this).closest(".accordion-single").hasClass("active")) {
$(this).closest(".accordion-single").removeClass("active");
$(this).next(".content-area").slideUp();
} else {
$(".accordion-single").removeClass("active");
$(this).closest(".accordion-single").addClass("active");
$(".content-area").not($(this).next(".content-area")).slideUp();
$(this).next(".content-area").slideToggle();
}
});
//>> Counter Js Start <<//
$(window).on("scroll", function () {
$(".odometer").each(function () {
var el = $(this);
if (el.offset().top < $(window).scrollTop() + $(window).height()) {
if (!el.hasClass("counted")) {
el.addClass("counted");
el.html(el.attr("data-count"));
}
}
});
});
/* ==================================================
Image Scale
================================================== */
var width = $(window).width();
if (width > 1023) {
if (document.querySelectorAll(".image-scale-animation").length > 0) {
// plugin register করতে হবে একবার শুরুতেই
gsap.registerPlugin(ScrollTrigger);
var step1 = gsap.timeline({
scrollTrigger: {
trigger: ".image-scale-animation",
scrub: 4,
start: "top 100%",
end: "bottom 70%",
},
});
step1.from(".image-scale-animation .image-scale-animation-item", {
scale: 0.1,
duration: 2, // অতিরিক্ত বড় duration দরকার নেই
});
step1.to(".image-scale-animation .image-scale-animation-item", {
scale: 1,
duration: 1.5,
transformOrigin: "center bottom",
});
}
}
/* ==================================================
GSAP Image Reveal
================================================== */
/* ==================================================
GSAP Fade Up
================================================== */
let fadeArray_items = document.querySelectorAll(".fade-up-anim");
if (fadeArray_items.length > 0) {
gsap.registerPlugin(ScrollTrigger);
const fadeArray = gsap.utils.toArray(".fade-up-anim");
fadeArray.forEach((item) => {
let fade_direction = item.getAttribute("data-direction") || "bottom";
let fade_offset = parseInt(item.getAttribute("data-offset")) || 50;
let duration_value = parseFloat(item.getAttribute("data-duration")) || 1.15;
let delay_value = parseFloat(item.getAttribute("data-delay")) || 0.15;
let ease_value = item.getAttribute("data-ease") || "power2.out";
let onscroll_value = item.getAttribute("data-on-scroll") || 1;
let animation_settings = {
opacity: 0,
ease: ease_value,
duration: duration_value,
delay: delay_value,
};
if (fade_direction === "top") animation_settings['y'] = -fade_offset;
if (fade_direction === "left") animation_settings['x'] = -fade_offset;
if (fade_direction === "bottom") animation_settings['y'] = fade_offset;
if (fade_direction === "right") animation_settings['x'] = fade_offset;
if (onscroll_value == 1) {
animation_settings['scrollTrigger'] = {
trigger: item,
start: 'top 85%',
};
}
gsap.from(item, animation_settings);
});
}
/* ==================================================
Smooth Scroll (Lenis)
================================================== */
// Check if gsap and SplitText exist
if (typeof gsap !== "undefined" && typeof SplitText !== "undefined") {
const splitTextEl = document.querySelector(".split-text-right");
if (splitTextEl) { // শুধুমাত্র এলিমেন্ট থাকলে
gsap.registerPlugin(SplitText, ScrollTrigger);
let split = new SplitText(splitTextEl, { type: "chars,words" });
gsap.from(split.chars, {
opacity: 0,
y: 50,
stagger: 0.05,
duration: 1,
ease: "power3.out",
scrollTrigger: {
trigger: splitTextEl,
start: "top 80%",
toggleActions: "play none none reverse"
}
});
}
}
/* ==================================================
Smooth Scroll
================================================== */
const header = document.querySelector('.sticky');
const headerHeight = header ? header.offsetHeight : 0;
document.querySelectorAll('a[href^="#"]:not([data-bs-toggle="tab"])').forEach((el) => {
el.addEventListener('click', (e) => {
e.preventDefault();
const id = el.getAttribute('href')?.slice(1);
if (!id) return;
const target = document.getElementById(id);
if (target) {
const offsetTop = target.offsetTop - headerHeight;
lenis.scrollTo(offsetTop, { duration: 1.2 });
}
});
});
/* ==================================================
Mounth Year
================================================== */
const monthYear = document.getElementById("month-year");
const datesContainer = document.getElementById("dates");
const prevBtn = document.getElementById("prev");
const nextBtn = document.getElementById("next");
let currentDate = new Date(2025, 7);
let selectedDateDiv = null; //
function renderCalendar(date) {
if (!monthYear || !datesContainer) return;
const year = date.getFullYear();
const month = date.getMonth();
const monthNames = [
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"
];
monthYear.textContent = `${monthNames[month]} ${year}`;
datesContainer.innerHTML = "";
const firstDay = new Date(year, month, 1).getDay();
const daysInMonth = new Date(year, month + 1, 0).getDate();
let blanks = firstDay === 0 ? 6 : firstDay - 1;
for (let i = 0; i < blanks; i++) {
const emptyDiv = document.createElement("div");
datesContainer.appendChild(emptyDiv);
}
for (let d = 1; d <= daysInMonth; d++) {
const dayDiv = document.createElement("div");
dayDiv.textContent = d;
// Highlight specific dates (example)
if (year === 2025 && month === 7 && [25,26,27].includes(d)) {
dayDiv.classList.add("highlight");
}
// ✅ Click event for selecting date
dayDiv.addEventListener("click", () => {
// Remove previous active
if (selectedDateDiv) {
selectedDateDiv.classList.remove("active-date");
}
// Add active to current
dayDiv.classList.add("active-date");
selectedDateDiv = dayDiv;
});
datesContainer.appendChild(dayDiv);
}
}
// Navigation buttons
if (prevBtn) {
prevBtn.addEventListener("click", () => {
currentDate.setMonth(currentDate.getMonth() - 1);
renderCalendar(currentDate);
selectedDateDiv = null; // reset selection on month change
});
}
if (nextBtn) {
nextBtn.addEventListener("click", () => {
currentDate.setMonth(currentDate.getMonth() + 1);
renderCalendar(currentDate);
selectedDateDiv = null; // reset selection on month change
});
}
// First render
if (monthYear && datesContainer) {
renderCalendar(currentDate);
}
}); // End Document Ready Function
//>> Counterup Start <<//
//>> Search Start <<//
if ($(".search-toggler").length) {
$(".search-toggler").on("click", function(e) {
e.preventDefault();
$(".search-popup").toggleClass("active");
$("body").toggleClass("locked");
});
}
//>> MouseCursor Start <<//
if ($(".mouseCursor").length > 0) {
function itCursor() {
var myCursor = jQuery(".mouseCursor");
if (myCursor.length) {
if ($("body")) {
const e = document.querySelector(".cursor-inner"),
t = document.querySelector(".cursor-outer");
let n,
i = 0,
o = !1;
(window.onmousemove = function(s) {
o ||
(t.style.transform =
"translate(" + s.clientX + "px, " + s.clientY + "px)"),
(e.style.transform =
"translate(" + s.clientX + "px, " + s.clientY + "px)"),
(n = s.clientY),
(i = s.clientX);
}),
$("body").on(
"mouseenter",
"button, a, .cursor-pointer",
function() {
e.classList.add("cursor-hover"),
t.classList.add("cursor-hover");
}
),
$("body").on(
"mouseleave",
"button, a, .cursor-pointer",
function() {
($(this).is("a", "button") &&
$(this).closest(".cursor-pointer").length) ||
(e.classList.remove("cursor-hover"),
t.classList.remove("cursor-hover"));
}
),
(e.style.visibility = "visible"),
(t.style.visibility = "visible");
}
}
}
itCursor();
}
function loader() {
$windowOn.on('load', function() {
// Animate loader off screen
$(".preloader").addClass('loaded');
$(".preloader").delay(200).fadeOut();
});
}
loader();
})(jQuery); // End jQuery
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+71
View File
@@ -0,0 +1,71 @@
/* ====================================================
* jQuery Is In Viewport.
* https://github.com/frontid/jQueryIsInViewport
* Marcelo Iván Tosco (capynet)
* Inspired on https://stackoverflow.com/a/40658647/1413049
* ==================================================== */
!function ($) {
'use strict'
var Class = function (el, cb) {
this.$el = $(el);
this.cb = cb;
this.watch();
return this;
};
Class.prototype = {
/**
* Checks if the element is in.
*
* @returns {boolean}
*/
isIn: function isIn() {
var _self = this;
var $win = $(window);
var elementTop = _self.$el.offset().top;
var elementBottom = elementTop + _self.$el.outerHeight();
var viewportTop = $win.scrollTop();
var viewportBottom = viewportTop + $win.height();
return elementBottom > viewportTop && elementTop < viewportBottom;
},
/**
* Launch a callback indicating when the element is in and when is out.
*/
watch: function () {
var _self = this;
var _isIn = false;
$(window).on('resize scroll', function () {
if (_self.isIn() && _isIn === false) {
_self.cb.call(_self.$el, 'entered');
_isIn = true;
}
if (_isIn === true && !_self.isIn()) {
_self.cb.call(_self.$el, 'leaved');
_isIn = false;
}
})
}
};
// jQuery plugin.
//-----------------------------------------------------------
$.fn.isInViewport = function (cb) {
return this.each(function () {
var $element = $(this);
var data = $element.data('isInViewport');
if (!data) {
$element.data('isInViewport', (new Class(this, cb)));
}
})
}
}(window.jQuery);
+3
View File
File diff suppressed because one or more lines are too long
+280
View File
@@ -0,0 +1,280 @@
.about-wrapper {
.about-image {
max-width: 375px;
position: relative;
z-index: 9;
@include breakpoint (max-xxl) {
max-width: initial;
}
img {
@include imgw;
border-radius: 16px;
}
.about-image-2 {
position: absolute;
bottom: -170px;
right: -238px;
@include breakpoint (max-xxl) {
max-width: 250px;
right: 0;
bottom: 0;
}
}
.bg-shape {
position: absolute;
z-index: -1;
top: 0;
left: 0;
right: 0;
@include breakpoint (max-xxl) {
display: none;
}
img {
width: initial;
height: initial;
}
}
.plane-shape {
position: absolute;
left: -38px;
bottom: -163px;
z-index: -1;
@include breakpoint (max-xxl) {
display: none;
}
img {
width: initial;
height: initial;
}
}
.top-shape {
position: absolute;
right: -200px;
top: 0;
@include breakpoint (max-xxl) {
display: none;
}
img {
width: initial;
height: initial;
}
}
}
.about-content {
.text {
margin-top: 24px;
padding-left: 40px;
border-left: 3px solid $border-color-2;
margin-bottom: 30px;
@include breakpoint (max-xxl) {
border-left: none;
padding-left: 0;
}
}
.about-item {
@include flex;
justify-content: space-between;
border-top: 1px solid rgba(203, 204, 207, 0.24);
padding-top: 24px;
@include breakpoint (max-lg) {
flex-wrap: wrap;
gap: 30px;
}
.content {
span {
font-size: 20px;
font-weight: 500;
color: $header-color;
display: inline-block;
margin-bottom: 5px;
img {
margin-right: 8px;
}
}
}
}
.list {
border-bottom: 1px solid rgba(203, 204, 207, 0.24);
padding: 24px 0 32px;
margin-bottom: 48px;
@include breakpoint (max-xxl) {
margin-bottom: 30px;
padding: 24px 0 30px;
}
li {
&:not(:last-child) {
margin-bottom: 10px;
}
@include breakpoint (max-xxl) {
font-size: 14px;
}
i {
color: $theme-color-2;
margin-right: 8px;
}
}
}
}
}
.about-section {
position: relative;
z-index: 9;
.top-shape {
position: absolute;
right: 0;
top: -50px;
z-index: -1;
@include breakpoint (max-xxl) {
display: none;
}
}
}
.about-wrapper-3 {
.about-content {
.text {
margin-top: 20px;
max-width: 616px;
border-bottom: 1px solid rgba(203, 204, 207, 0.24);
padding-bottom: 24px;
margin-bottom: 30px;
}
.about-list-item {
display: flex;
gap: 32px;
@include breakpoint (max-xxl) {
flex-wrap: wrap;
gap: 25px;
}
.loading-box {
height: 256px;
width: 214px;
border-radius: 16px;
position: relative;
text-align: center;
.loading-boxs {
height: 200px;
width: 200px;
display: flex;
align-items: center;
justify-content: center;
background: #0a4ebd;
border-radius: 16px;
.circle-bar {
position: relative;
strong {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 28px;
font-weight: bold;
color: $white;
}
}
}
h6 {
color: $white;
font-weight: 500;
font-size: 14px;
}
}
.list-item {
.list {
margin-bottom: 48px;
li {
font-size: 18px;
font-weight: 500;
color: $header-color;
font-family: $heading-font;
@include breakpoint (max-xxl) {
font-size: 16px;
}
&:not(:last-child) {
margin-bottom: 15px;
}
i {
margin-right: 8px;
color: $theme-color-2;
}
}
}
}
}
}
.about-image {
img {
@include imgw;
border-radius: 8px;
}
&.tp-clip-anim {
width: 100%;
display: grid;
align-items: center;
justify-items: center;
overflow: hidden;
position: relative;
& .tp-anim-img {
opacity: 0;
width: 100%;
height: 100%;
}
& .mask {
background-size: cover;
background-position: center;
transform: scale(1.005);
}
>* {
grid-area: 1 / 1 / 2 / 2;
width: 100%;
height: 100%;
max-height: 100%;
}
}
}
}
+915
View File
@@ -0,0 +1,915 @@
//>>>>> Video Animation Start <<<<<//
@-webkit-keyframes rippleOne {
70% {
-webkit-box-shadow: 0 0 0 40px rgba(244, 68, 56, 0);
box-shadow: 0 0 0 40px rgba(244, 68, 56, 0);
}
100% {
-webkit-box-shadow: 0 0 0 0 rgba(244, 68, 56, 0);
box-shadow: 0 0 0 0 rgba(244, 68, 56, 0);
}
}
@keyframes rippleOne {
70% {
-webkit-box-shadow: 0 0 0 40px rgba(244, 68, 56, 0);
box-shadow: 0 0 0 40px rgba(244, 68, 56, 0);
}
100% {
-webkit-box-shadow: 0 0 0 0 rgba(244, 68, 56, 0);
box-shadow: 0 0 0 0 rgba(244, 68, 56, 0);
}
}
//>>>>> Video Animation End <<<<<//
//>>>>> Circle Animation Start <<<<<//
@keyframes cir36 {
100%{
transform: rotate(360deg);
}
}
@keyframes rounded {
50%{
transform: rotate(15deg);
}
}
//>>>>> Circle Animation End <<<<<//
@keyframes up-down {
0% {
transform: translateY(10px);
}
100% {
transform: translateY(-10px);
}
}
//>>>>> Preloader Animation Start <<<<<//
@-webkit-keyframes spinner {
to {
-webkit-transform: rotateZ(360deg);
transform: rotateZ(360deg);
}
}
@keyframes spinner {
to {
-webkit-transform: rotateZ(360deg);
transform: rotateZ(360deg);
}
}
@-webkit-keyframes letters-loading {
0%,
75%,
100% {
opacity: 0;
transform: rotateY(-90deg);
}
25%,
50% {
opacity: 1;
transform: rotateY(0deg);
}
}
@keyframes letters-loading {
0%,
75%,
100% {
opacity: 0;
transform: rotateY(-90deg);
}
25%,
50% {
opacity: 1;
transform: rotateY(0deg);
}
}
//>>>>> Preloader Animation Start <<<<<//
@keyframes loaderspin {
0% {
transform: translate(-50%, -50%) rotate(0deg);
}
100% {
transform: translate(-50%, -50%) rotate(360deg);
}
}
@keyframes tpswing{
0% {
-webkit-transform: rotate(20deg);
-ms-transform:rotate(20deg);
transform: rotate(20deg);
}
100% {
-webkit-transform: rotate(0deg);
-ms-transform:rotate(0deg);
transform: rotate(0deg);
}
}
@keyframes width {
0% {
width: 0%;
}
100% {
width: 100%;
}
}
@-webkit-keyframes width {
0% {
width: 0%;
}
100% {
width: 100%;
}
}
@-webkit-keyframes loaderspin {
0% {
transform: translate(-50%, -50%) rotate(0deg);
}
100% {
transform: translate(-50%, -50%) rotate(360deg);
}
}
@keyframes loaderpulse {
0% {
transform: scale(1);
}
100% {
transform: scale(1.2);
}
}
//>>>>> Preloader Animation End <<<<<//
//animation
@keyframes rounded {
50%{
transform: rotate(20deg);
}
}
@keyframes cir36 {
100% {
transform: rotate(360deg);
}
}
.float-bob-y {
-webkit-animation-name: float-bob-y;
animation-name: float-bob-y;
-webkit-animation-duration: 3s;
animation-duration: 3s;
-webkit-animation-iteration-count: infinite;
animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
animation-timing-function: linear;
}
@-webkit-keyframes float-bob-y {
0% {
-webkit-transform: translateY(-30px);
transform: translateY(-30px);
}
50% {
-webkit-transform: translateY(-10px);
transform: translateY(-10px);
}
100% {
-webkit-transform: translateY(-30px);
transform: translateY(-30px);
}
}
@keyframes float-bob-y {
0% {
-webkit-transform: translateY(-30px);
transform: translateY(-30px);
}
50% {
-webkit-transform: translateY(-10px);
transform: translateY(-10px);
}
100% {
-webkit-transform: translateY(-30px);
transform: translateY(-30px);
}
}
.float-bob-x {
-webkit-animation-name: float-bob-x;
animation-name: float-bob-x;
-webkit-animation-duration: 3s;
animation-duration: 3s;
-webkit-animation-iteration-count: infinite;
animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
animation-timing-function: linear;
}
@-webkit-keyframes float-bob-x {
0% {
-webkit-transform: translateX(-0px);
transform: translateX(30px);
}
50% {
-webkit-transform: translateX(10px);
transform: translateX(10px);
}
100% {
-webkit-transform: translateX(30px);
transform: translateX(30px);
}
}
@keyframes float-bob-x {
0% {
-webkit-transform: translateX(30px);
transform: translateX(30px);
}
50% {
-webkit-transform: translateX(10px);
transform: translateX(10px);
}
100% {
-webkit-transform: translateX(30px);
transform: translateX(30px);
}
}
@keyframes bounce-x {
0% {
-webkit-transform: translateX(0);
transform: translateX(0);
}
50% {
-webkit-transform: translateX(30px);
transform: translateX(30px);
}
100% {
-webkit-transform: translateX(0);
transform: translateX(0);
}
}
.bounce-x {
-webkit-animation: bounce-x 7s infinite linear;
animation: bounce-x 7s infinite linear;
}
@keyframes criss-cross-left {
0% {
left: -20px;
}
50% {
left: 50%;
width: 20px;
height: 20px;
}
100% {
left: 50%;
width: 375px;
height: 375px;
}
}
@keyframes criss-cross-right {
0% {
right: -20px;
}
50% {
right: 50%;
width: 20px;
height: 20px;
}
100% {
right: 50%;
width: 375px;
height: 375px;
}
}
@keyframes rotated2 {
0% {
transform: rotate(0);
}
100% {
transform: rotate(-360deg);
}
}
@keyframes wave {
0% {transform: translateX(0);}
50% {transform: translateX(-25%);}
100% {transform: translateX(-50%);}
}
@keyframes zoom {
0%{
transform:scale(.5);
}
50%{
transform: scale(1);
}
100%{
transform: scale( .5);
}
}
@keyframes translateY2 {
0% {
-webkit-transform: translateY(-30px);
-moz-transform: translateY(-30px);
-ms-transform: translateY(-30px);
-o-transform: translateY(-30px);
transform: translateY(-30px);
}
100% {
-webkit-transform: translateY(20px);
-moz-transform: translateY(20px);
-ms-transform: translateY(20px);
-o-transform: translateY(20px);
transform: translateY(20px);
}
}
@keyframes translateX2{
0% {
-webkit-transform: translateX(-30px);
-moz-transform: translateX(-30px);
-ms-transform: translateX(-30px);
-o-transform: translateX(-30px);
transform: translateX(-30px);
}
100% {
-webkit-transform: translatXY(20px);
-moz-transform: translateX(20px);
-ms-transform: translateX(20px);
-o-transform: translateX(20px);
transform: translateX(20px);
}
}
@keyframes moving {
0% {
transform: translatey(0px);
}
20%{
transform: translateX(-50px);
}
50% {
transform: translatey(-40px);
}
100% {
transform: translatey(0px);
}
}
/*img-animation**********************/
.img-custom-anim-right {
animation: img-anim-right 1.3s forwards cubic-bezier(0.645, 0.045, 0.355, 1) 0.4s;
opacity: 0;
}
@keyframes img-anim-right {
0% {
transform: translateX(5%);
clip-path: inset(0 0 0 100%);
opacity: 0;
}
100% {
transform: translateX(0);
clip-path: inset(0 0 0 0);
opacity: 1;
}
}
.img-custom-anim-left {
animation: img-anim-left 1.3s forwards cubic-bezier(0.645, 0.045, 0.355, 1) 0.4s;
opacity: 0;
}
@keyframes img-anim-left {
0% {
transform: translateX(-5%);
clip-path: inset(0 100% 0 0);
opacity: 0;
}
100% {
transform: translateX(0);
clip-path: inset(0 0 0 0);
opacity: 1;
}
}
.img-custom-anim-top {
animation: img-anim-top 1.3s forwards cubic-bezier(0.645, 0.045, 0.355, 1);
opacity: 0;
}
@keyframes img-anim-top {
0% {
transform: translateY(-5%);
clip-path: inset(0 0 100% 0);
opacity: 0;
}
100% {
transform: translateY(0);
clip-path: inset(0 0 0 0);
opacity: 1;
}
}
@keyframes slideInLeft {
to {
opacity: 1;
transform: translateX(0);
}
}
@keyframes slideInRight {
to {
opacity: 1;
transform: translateX(0);
}
}
@keyframes shine {
0% {
left: -100%;
}
50% {
left: 100%;
}
100% {
left: 100%;
}
}
.animation-infinite {
animation: ShapeAnim 80s linear infinite;
height: 30px;
width: 100%;
background-repeat: repeat;
overflow: hidden;
}
.img-custom-anim-bottom {
animation: img-anim-bottom 1.3s forwards cubic-bezier(0.645, 0.045, 0.355, 1);
opacity: 0;
}
@keyframes img-anim-bottom {
0% {
transform: translateY(5%);
clip-path: inset(100% 0 0 0);
opacity: 0;
}
100% {
transform: translateY(0);
clip-path: inset(0 0 0 0);
opacity: 1;
}
}
@keyframes sparkle {
0% { opacity: 0; transform: scale(0.5); }
50% { opacity: 1; transform: scale(1.5); }
100% { opacity: 0; transform: scale(0.5); }
}
@keyframes borderAnim {
0% {
width: 0;
}
100% {
width: 44px;
}
}
@keyframes slideInLeft {
to {
opacity: 1;
transform: translateX(0);
}
}
@keyframes slideInRight {
to {
opacity: 1;
transform: translateX(0);
}
}
@keyframes shine {
0% {
left: -100%;
}
50% {
left: 100%;
}
100% {
left: 100%;
}
}
@keyframes strokeColorChange1 {
0% {
-webkit-text-stroke-color: rgba(202, 210, 210, 0.10);
}
25% {
-webkit-text-stroke-color: rgba(202, 210, 210, 0.10);
}
50% {
-webkit-text-stroke-color: rgba(194, 223, 147, 0.10);
}
75% {
-webkit-text-stroke-color: rgba(227, 87, 43, 0.10);
}
100% {
-webkit-text-stroke-color: rgba(194, 223, 147, 0.10);
}
}
@keyframes shake {
0%, 100% {
-webkit-transform: translateX(0);
-ms-transform: translateX(0);
transform: translateX(0);
}
10%, 30%, 50%, 70%, 90% {
-webkit-transform: translateX(-5px);
-ms-transform: translateX(-5px);
transform: translateX(-5px);
}
20%, 40%, 60%, 80% {
-webkit-transform: translateX(5px);
-ms-transform: translateX(5px);
transform: translateX(5px);
}
}
@keyframes rotateBorder {
0% {
transform: translate(-50%, -50%) rotate(0deg);
}
100% {
transform: translate(-50%, -50%) rotate(360deg);
}
}
// This is for Progress bar animation also has a js code
@keyframes animate-positive {
0% {
width: 0;
}
}
@keyframes scroll {
0% {
transform: translateX(0);
}
100% {
transform: translateX(-100%);
}
}
@keyframes scrolly {
0% {
transform: translateY(0);
}
100% {
transform: translateY(-60%);
}
}
@keyframes scrolls {
0% {
transform: translateX(0);
}
100% {
transform: translateX(100%);
}
}
@keyframes scroll-left-to-right-loop {
0% {
transform: translateX(-50%);
}
100% {
transform: translateX(0%);
}
}
@-webkit-keyframes zoomOut {
from {
opacity: 1;
}
50% {
opacity: 0;
-webkit-transform: scale3d(.3, .3, .3);
transform: scale3d(.3, .3, .3);
}
to {
opacity: 0;
}
}
@keyframes zoomOut {
from {
opacity: 1;
}
50% {
opacity: 0;
-webkit-transform: scale3d(.3, .3, .3);
transform: scale3d(.3, .3, .3);
}
to {
opacity: 0;
}
}
.zoomOut {
-webkit-animation-name: zoomOut;
animation-name: zoomOut;
}
.img_left_animation {
animation: left-animation 2000ms forwards cubic-bezier(0.40, 0.98, 0.52, 0.99);
opacity: 0
}
@keyframes left-animation {
0% {
clip-path: inset(0 100% 0 0);
opacity: 0
}
100% {
clip-path: inset(0 0 0 0);
opacity: 1
}
}
.img_right_animation {
animation: right-animation 2000ms forwards cubic-bezier(0.40, 0.98, 0.52, 0.99);
opacity: 0
}
@keyframes right-animation {
0% {
clip-path: inset(0 0 0 100%);
opacity: 0
}
100% {
clip-path: inset(0 0 0 0);
opacity: 1
}
}
.img_top_animation {
animation: top-animation 2000ms forwards cubic-bezier(0.40, 0.98, 0.52, 0.99);
opacity: 0
}
@keyframes top-animation {
0% {
clip-path: inset(0 0 100% 0);
opacity: 0
}
100% {
clip-path: inset(0 0 0 0);
opacity: 1
}
}
.img_bottom_animation {
animation: bottom-animation 2000ms forwards cubic-bezier(0.40, 0.98, 0.52, 0.99);
opacity: 0
}
@keyframes bottom-animation {
0% {
clip-path: inset(100% 0 0 0);
opacity: 0
}
100% {
clip-path: inset(0 0 0 0);
opacity: 1
}
}
@keyframes circle {
0% {
transform: scale(0);
opacity: 0.6;
}
100% {
transform: scale(30);
opacity: 0;
}
}
@keyframes icon-bounce {
0%, 100%, 20%, 50%, 80% {
-webkit-transform: translateY(0);
transform: translateY(0);
}
40% {
-webkit-transform: translateY(-10px);
transform: translateY(-10px);
}
60% {
-webkit-transform: translateY(-5px);
transform: translateY(-5px);
}
}
@-webkit-keyframes slideInLeft {
0% {
-webkit-transform: translate3d(-100%, 0, 0);
transform: translate3d(-100%, 0, 0);
visibility: visible;
}
100% {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
@keyframes slideInLeft {
0% {
-webkit-transform: translate3d(-100%, 0, 0);
transform: translate3d(-100%, 0, 0);
visibility: visible;
}
100% {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
.slideInLeft {
-webkit-animation-name: slideInLeft;
animation-name: slideInLeft;
}
@-webkit-keyframes slideInRight {
0% {
-webkit-transform: translate3d(100%, 0, 0);
transform: translate3d(100%, 0, 0);
visibility: visible;
}
100% {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
@keyframes slideInRight {
0% {
-webkit-transform: translate3d(100%, 0, 0);
transform: translate3d(100%, 0, 0);
visibility: visible;
}
100% {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
.slideInRight {
-webkit-animation-name: slideInRight;
animation-name: slideInRight;
}
@-webkit-keyframes slideInUp {
0% {
-webkit-transform: translate3d(0, 100%, 0);
transform: translate3d(0, 100%, 0);
visibility: visible;
}
100% {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
@keyframes slideInUp {
0% {
-webkit-transform: translate3d(0, 100%, 0);
transform: translate3d(0, 100%, 0);
visibility: visible;
}
100% {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
.slideInUp {
-webkit-animation-name: slideInUp;
animation-name: slideInUp;
}
@-webkit-keyframes slideInDown {
0% {
-webkit-transform: translate3d(0, -100%, 0);
transform: translate3d(0, -100%, 0);
visibility: visible;
}
100% {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
@keyframes slideInDown {
0% {
-webkit-transform: translate3d(0, -100%, 0);
transform: translate3d(0, -100%, 0);
visibility: visible;
}
100% {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
.slideInDown {
-webkit-animation-name: slideInDown;
animation-name: slideInDown;
}
.zoom_in {
transform: scale(0.5);
}
.fade_up,
.fade_down,
.zoom_in,
.zoom_out {
opacity: 0;
transition: all 2s;
}
.show {
opacity: 1;
transform: translateY(0) scale(1);
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
@keyframes zoomIn {
0% {
opacity: 0;
-webkit-transform: scale3d(.8, .8, .8);
transform: scale3d(.8, .8, .8);
}
50% {
opacity: 1;
}
}
+70
View File
@@ -0,0 +1,70 @@
.brand-wrapper {
.brand-item {
border-top: 1px solid rgba(203, 204, 207, 0.72);
border-bottom: 1px solid rgba(203, 204, 207, 0.72);
text-align: center;
height: 116px;
position: relative;
&::before {
@include before;
background-color: rgba(203, 204, 207, 0.72);
width: 1px;
left: 0;
}
&::after {
position: absolute;
content: "";
top: 0;
bottom: 0;
background-color: rgba(203, 204, 207, 0.72);
width: 1px;
right: 0;
}
.brand-image {
position: relative;
padding: 30px 0;
&::before {
@include before;
background-color: rgba(203, 204, 207, 0.72);
width: 1px;
left: 0;
height: 100px;
@include breakpoint (max-xl) {
display: none;
}
}
}
}
&.style-1 {
.brand-item {
height: 102px;
.brand-image {
text-align: center;
filter: grayscale(100%);
@include transition;
opacity: .4;
&:hover {
filter: initial;
opacity: 1;
}
}
.swiper-slide.swiper-slide-active{
.brand-image {
filter: initial;
opacity: 1;
}
}
}
}
}
+58
View File
@@ -0,0 +1,58 @@
.theme-btn {
background: transparent;
color: $header-color;
display: inline-block;
font-size: 16px;
font-weight: 500;
padding: 6px 6px 6px 24px;
border-radius: 55px;
line-height: 1;
text-transform: uppercase;
-webkit-transition: all 0.3s ease-in-out;
transition: all 0.3s ease-in-out;
position: relative;
z-index: 1;
font-family: "Space Grotesk", sans-serif;
border: 1px solid $border-color;
@include breakpoint (max-sm) {
padding: 2px 4px 2px 24px;
}
i {
width: 48px;
height: 48px;
line-height: 48px;
text-align: center;
background-color: $theme-color;
color: $white;
margin-left: 20px;
@include transition;
border-radius: 50%;
}
&:hover {
background-color: $theme-color;
color: $white;
i {
background-color: $white;
color: $header-color;
}
}
}
.link-btn {
color: $theme-color-2;
text-transform: capitalize;
font-weight: 500;
font-family: "Space Grotesk", sans-serif;
i {
margin-left: 8px;
}
&:hover {
color: $theme-color;
}
}
+362
View File
@@ -0,0 +1,362 @@
.contact-wrapper-2 {
@include flex;
gap: 325px;
@include breakpoint (max-xxl) {
flex-wrap: wrap;
gap: 30px;
}
.contact-from-box {
padding: 60px 48px;
background-color: $theme-color-2;
border-radius: 24px;
width: 644px;
@include breakpoint (max-xxl) {
padding: 30px;
}
h3 {
color: $white;
font-size: 32px;
text-transform: uppercase;
margin-bottom: 30px;
text-align: center;
@include breakpoint (max-xxl) {
font-size: 25px;
margin-bottom: 20px;
}
@include breakpoint (max-sm) {
font-size: 20px;
}
}
.form-clt {
input,textarea {
width: 100%;
outline: none;
border: none;
background: transparent;
padding: 16px 0;
font-weight: 400;
font-size: 16px;
color: rgba(255, 255, 255, 0.7);
line-height: 1;
border-bottom: 1px solid rgba(203, 204, 207, 0.24);
&::placeholder {
color: rgba(255, 255, 255, 0.7);
}
}
.nice-select {
width: 100% !important;
padding: 0;
padding-bottom: 10px;
padding-top: 20px;
font-size: 16px;
text-transform: capitalize;
border-radius: 0;
background-color: transparent;
border: none;
box-shadow: none;
font-size: 16px;
color: rgba(255, 255, 255, 0.7);
font-weight: 400;
width: initial;
border-bottom: 1px solid rgba(203, 204, 207, 0.24);
&::after {
right: 0;
width: 10px;
height: 8px;
border-bottom: 2px solid transparent;
border-right: 2px solid transparent;
margin-top: 0;
background-color: rgba(255, 255, 255, 0.7);
clip-path: polygon(100% 0, 49% 100%, 0 0);
-webkit-transform: rotate(0eg);
transform: rotate(0deg);
top: 36%;
}
.list {
width: 100%;
background-color: $bg-color;
top: 60%;
font-size: 16px;
color: $header-color;
}
.focus {
background-color: transparent;
font-weight: 400;
color: $text-color;
}
.option {
border: none;
&:hover {
background-color: transparent;
}
}
}
}
.contact-btn {
margin-top: 48px;
text-align: center;
margin-bottom: 48px;
@include breakpoint (max-xxl) {
margin-top: 30px;
margin-bottom: 30px;
}
.theme-btn {
color: $white;
&:hover {
border: 1px solid $theme-color;
}
}
}
h5 {
font-weight: 500;
color: $white;
margin-bottom: 10px;
}
h2 {
font-size: 40px;
border-bottom: 1px solid rgba(203, 204, 207, 0.24);
padding-bottom: 10px;
margin-bottom: 5px;
@include breakpoint (max-xxl) {
font-size: 25px;
}
@include breakpoint (max-sm) {
font-size: 20px;
}
a {
color: $white;
}
}
p {
color: rgba(255, 255, 255, 0.7);
}
}
.video-btn {
width: 88px;
height: 88px;
line-height: 88px;
text-align: center;
background-color: $theme-color;
color: $white;
position: relative;
font-size: 16px;
border-radius: 100px;
z-index: 999;
display: inline-block;
@include breakpoint (max-lg) {
margin-left: 30px;
}
@include breakpoint (max-sm) {
width: 70px;
height: 70px;
line-height: 70px;
margin-left: 15px;
}
&::before {
@include before;
width: 120px;
height: 120px;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
background: rgba(225, 56, 51, 0.24);
border-radius: 100%;
border: 2px solid $white;
@include breakpoint (max-sm) {
width: 100px;
height: 100px;
}
}
}
}
.contact-section-2 {
background-attachment: fixed;
}
.contact-from-wrapper {
background-color: $bg-color;
border-radius: 16px;
padding: 48px;
@include breakpoint (max-xxl) {
padding: 30px;
}
.form-clt {
position: relative;
span {
color: $header-color;
font-size: 18px;
font-weight: 500;
font-family: $heading-font;
margin-bottom: 10px;
display: inline-block;
}
input,textarea {
width: 100%;
border: none;
outline: none;
background: $white;
color: $text-color;
border-radius: 100px;
padding: 18px 20px;
@include breakpoint (max-md){
padding: 14px 20px;
}
@include breakpoint (max-sm){
padding: 12px 18px;
}
&::placeholder {
color: $text-color;
}
}
textarea {
padding-bottom: 100px;
resize: none;
border-radius: 40px;
}
}
.cheak-list-item {
margin-top: 30px;
margin-bottom: 48px;
@include breakpoint (max-xxl) {
margin-bottom: 30px;
}
.cheak-list {
@include flex;
gap: 80px;
margin-bottom: 24px;
@include breakpoint (max-xxl) {
flex-wrap: wrap;
gap: 22px;
}
.form-check {
flex-basis: 200px;
}
.form-check-label {
font-size: 18px;
color: $header-color;
font-weight: 500;
font-family: $heading-font;
}
.form-check .form-check-input {
float: left;
transform: translateY(0px);
border-radius: 100px;
border: 1px solid $text-color;
background-color: $white;
}
.form-check .form-check-input:checked {
background-color: $theme-color-2;
border: 1px solid $theme-color-2;
}
}
}
.theme-btn {
width: 100%;
&.style-2 {
width: initial;
}
}
}
.contact-icon-item {
@include flex;
gap: 24px;
background-color: $bg-color;
border-radius: 16px;
padding: 30px;
@include breakpoint (max-lg) {
flex-wrap: wrap;
}
.icon {
width: 64px;
height: 64px;
line-height: 64px;
text-align: center;
border-radius: 100px;
background-color: $header-color;
color: $white;
@include transition;
font-size: 20px;
}
.content {
p {
margin-bottom: 5px;
}
h6 {
font-size: 18px;
font-weight: 500;
line-height: 144%;
}
}
&:hover {
.icon {
background-color: $theme-color;
}
}
}
.map-items {
.googpemap {
iframe {
width: 100%;
height: 724px;
@include breakpoint (max-sm){
height: 400px;
}
}
}
}
View File
+93
View File
@@ -0,0 +1,93 @@
.faq-wrapper {
.faq-content {
.text {
max-width: 505px;
margin-top: 24px;
margin-bottom: 48px;
}
}
.faq-items {
position: relative;
z-index: 9;
.accordion {
.accordion-item {
border: none;
h5 {
button {
line-height: 1;
font-weight: 600;
padding: 29px 30px;
color: $header-color;
cursor: pointer;
@include breakpoint(max-sm) {
font-size: 18px;
line-height: 1.6;
padding: 22px 20px;
}
}
}
.accordion-body {
padding: 20px 30px;
background-color: $white;
box-shadow: 8px 8px 32px 0 rgba(0, 72, 180, 0.08);
backdrop-filter: blur(5px);
p {
font-size: 16px;
line-height: 24px;
font-weight: 400;
@include breakpoint(max-sm) {
width: 100%;
font-size: 14px;
line-height: 28px;
}
}
}
}
.accordion-button {
background-color: $white;
color: $header-color;
box-shadow: 8px 8px 32px 0 rgba(36, 12, 135, 0.08);
backdrop-filter: blur(5px);
&::after {
content: "\f324";
font-family: "Font Awesome 6 Pro";
background: transparent;
font-weight: 900;
transition: all 0.3s ease-in-out !important;
color: $theme-color-2;
}
&:not(.collapsed) {
background-color: $white;
box-shadow: 8px 8px 32px 0 rgba(36, 12, 135, 0.08);
backdrop-filter: blur(5px);
color: $header-color;
&::after {
content: "\f322";
font-family: "Font Awesome 6 Pro";
background: transparent;
font-weight: 900;
color: $theme-color;
transform: rotate(0);
}
}
}
}
}
}
.faq-section {
border-top: 1px solid rgba(203, 204, 207, 0.24);
}
File diff suppressed because it is too large Load Diff
+683
View File
@@ -0,0 +1,683 @@
.footer-wrapper {
.footer-item {
padding: 100px 0;
position: relative;
text-align: center;
@include breakpoint (max-lg) {
padding: 80px 0;
}
h2 {
font-size: 30px;
color: $white;
@include breakpoint (max-sm) {
font-size: 25px;
}
a {
color: $white;
}
&.text {
font-size: 24px;
}
}
.footer-list-item {
@include flex;
justify-content: space-between;
border-radius: 136px;
background: rgba(255, 255, 255, 0.08);
backdrop-filter: blur(62px);
padding: 20px 24px;
margin-top: 80px;
@include breakpoint (max-xxl) {
margin-top: 30px;
padding: 20px;
}
@include breakpoint (max-lg) {
border-radius: 0;
flex-wrap: wrap;
gap: 20px;
}
.footer-list {
@include flex;
gap: 40px;
@include breakpoint (max-xxl) {
gap: 20px;
}
@include breakpoint (max-sm) {
flex-wrap: wrap;
gap: 15px;
}
li {
font-weight: 500;
font-family: $heading-font;
text-transform: uppercase;
a {
color: $white;
&:hover {
color: $theme-color;
}
}
}
}
.social-icon {
@include flex;
gap: 12px;
a {
width: 40px;
height: 40px;
line-height: 40px;
text-align: center;
border-radius: 100px;
backdrop-filter: blur(46px);
background-color: $bg-color-2;
color: $white;
display: inline-block;
&:hover {
background-color: $theme-color;
}
}
}
}
}
}
.footer-section {
margin: 0 30px;
border-radius: 32px;
@include breakpoint (max-sm) {
margin: 0 15px;
}
}
.footer-bottom {
padding: 24px 0;
text-align: center;
.footer-wrapper {
@include flex;
justify-content: center;
gap: 100px;
@include breakpoint (max-xxl) {
flex-wrap: wrap;
gap: 20px;
}
@include breakpoint (max-sm) {
justify-content: start;
}
p {
color: $header-color;
span {
color: $theme-color;
text-transform: uppercase;
}
}
.bottom-list {
@include flex;
gap: 40px;
@include breakpoint (max-xxl) {
flex-wrap: wrap;
gap: 20px;
}
@include breakpoint (max-sm) {
justify-content: center;
}
li {
a {
&:hover {
color: $theme-color;
}
}
}
}
}
}
.footer-widget-wrapper-2 {
padding: 70px 0 90px;
@include breakpoint (max-lg) {
padding: 50px 0 80px;
}
.single-footer-widget {
margin-top: 30px;
.widget-title {
margin-bottom: 24px;
h3 {
color: $white;
text-transform: uppercase;
}
}
.footer-content {
p {
max-width: 502px;
color: rgba(255, 255, 255, 0.7);
@include breakpoint (max-xxl) {
font-size: 14px;
}
@include breakpoint (max-lg) {
font-size: 16px;
}
}
.social-icon {
@include flex;
gap: 20px;
margin-top: 50px;
@include breakpoint (max-xxl) {
margin-top: 30px;
gap: 13px;
}
@include breakpoint (max-lg) {
gap: 16px;
}
span {
display: inline-block;
margin-right: 4px;
color: $white;
font-weight: 500;
text-transform: uppercase;
font-family: $heading-font;
@include breakpoint (max-xxl) {
font-size: 14px;
}
@include breakpoint (max-lg) {
font-size: 16px;
}
}
a {
font-size: 20px;
color: $theme-color;
&:hover {
color: $theme-color-2;
}
}
}
}
.list {
li {
@include transition;
font-weight: 400;
&:not(:last-child){
margin-bottom: 20px;
}
a {
color: rgba(255, 255, 255, 0.7);
}
&:hover {
margin-left: 5px;
a {
color: $theme-color;
}
}
}
}
.contact-item {
li {
display: flex;
align-items: start;
color: rgba(255, 255, 255, 0.7);
gap: 8px;
&.style-2 {
@include flex;
}
&:not(:last-child) {
margin-bottom: 20px;
}
a {
color: rgba(255, 255, 255, 0.7);
}
i {
color: $theme-color;
}
}
}
}
}
.footer-section-2 {
position: relative;
z-index: 9;
.shape {
position: absolute;
left: 0;
top: 0;
z-index: -1;
}
}
.footer-newsletter {
@include flex;
justify-content: space-between;
margin-top: 100px;
padding: 32px 48px;
background-color: $theme-color-2;
border-radius: 16px;
@include breakpoint (max-xxl) {
flex-wrap: wrap;
gap: 20px;
padding: 30px;
margin-top: 80px;
}
.newsletter-content {
h3 {
color: $white;
}
p {
color: rgba(255, 255, 255, 0.7);
}
}
form {
max-width: 587px;
width: 100%;
}
.form-clt {
position: relative;
.input-icon {
top: 50%;
left: 25px;
transform: translateY(-50%);
position: absolute;
@include breakpoint (max-sm) {
top: 23%;
}
}
input {
width: 100%;
outline: none;
border: none;
background-color: $white;
color: $text-color;
line-height: 1;
padding: 25px 0px 25px 60px;
border-radius: 100px;
max-width: 587px;
@include breakpoint (max-lg) {
padding: 20px 0px 20px 60px;
}
&::placeholder {
color: $text-color;
}
}
.theme-btn {
position: absolute;
top: 4px;
right: 4px;
bottom: 4px;
text-transform: uppercase;
border: 1px solid rgba(203, 204, 207, 0.24);
@include breakpoint (max-xxs){
position: static;
margin-top: 20px;
color: $white;
}
}
}
}
.fotter-bootom-2 {
border-top: 1px solid rgba(203, 204, 207, 0.24);
padding: 20px 0;
.footer-wrapper {
@include flex;
justify-content: center;
gap: 100px;
@include breakpoint (max-xxl) {
flex-wrap: wrap;
gap: 20px;
}
@include breakpoint (max-sm) {
justify-content: start;
}
p {
color: $white;
@include breakpoint (max-sm) {
text-align: center;
}
span {
color: $theme-color;
text-transform: uppercase;
}
}
.bottom-list {
@include flex;
gap: 40px;
@include breakpoint (max-xxl) {
flex-wrap: wrap;
gap: 20px;
}
@include breakpoint (max-sm) {
justify-content: center;
}
li {
a {
color: $white;
&:hover {
color: $theme-color;
}
}
}
}
}
}
.footer-widget-wrapper-3 {
padding: 70px 0 100px;
position: relative;
@include breakpoint (max-xxl) {
padding: 70px 0 100px;
}
@include breakpoint (max-lg) {
padding: 50px 0 80px;
}
&::before {
position: absolute;
content: "";
width: 1px;
height: 424px;
left: 600px;
background-color: rgba(203, 204, 207, 0.24);
top: 0;
bottom: 0;
@include breakpoint (max-xxl) {
display: none;
}
}
.single-footer-widget {
margin-top: 30px;
.widget-title {
margin-bottom: 24px;
h3 {
color: $white;
text-transform: uppercase;
}
}
.footer-content {
h3 {
color: $white;
margin-bottom: 10px;
}
p {
color: $white;
opacity: 0.7;
max-width: 551px;
margin-bottom: 30px;
}
form {
max-width: 551px;
width: 100%;
}
.form-clt {
position: relative;
input {
width: 100%;
outline: none;
border: none;
background-color: $white;
color: $text-color;
line-height: 1;
padding: 25px 0px 25px 25px;
border-radius: 100px;
max-width: 551px;
@include breakpoint (max-xxl) {
padding: 20px 0px 20px 10px;
font-size: 14px;
}
@include breakpoint (max-lg) {
padding: 20px 0px 20px 10px;
font-size: 14px;
}
@include breakpoint (max-sm) {
font-size: 14px;
}
&::placeholder {
color: $text-color;
}
}
.theme-btn {
position: absolute;
top: 4px;
right: 4px;
bottom: 4px;
text-transform: uppercase;
border: 1px solid rgba(203, 204, 207, 0.24);
background-color: $bg-color;
&:hover {
background-color: $theme-color;
color: $white;
}
@include breakpoint (max-xxl){
right: 0;
top: 0;
bottom: 0;
padding: 2px 4px 2px 12px;
font-size: 14px;
i {
margin-left: 10px;
}
}
}
}
h6 {
color: $white;
margin-top: 15px;
span {
color: $theme-color;
text-transform: uppercase;
font-size: 18px;
font-weight: 400;
}
}
}
.contact-content {
p {
color: $white;
opacity: 0.7;
margin-bottom: 24px;
}
h3 {
color: $white;
}
.contact-list {
margin-top: 16px;
li {
@include flex;
gap: 32px;
a {
color: $white;
opacity: 0.7;
}
}
}
}
.list {
li {
@include transition;
font-weight: 400;
&:not(:last-child){
margin-bottom: 20px;
}
a {
color: rgba(255, 255, 255, 0.7);
}
&:hover {
margin-left: 5px;
a {
color: $theme-color;
}
}
}
}
}
}
.footer-top-item {
@include flex;
justify-content: space-between;
border-bottom: 1px solid rgba(203, 204, 207, 0.24);
@include breakpoint (max-lg) {
flex-wrap: wrap;
gap: 30Px;
padding-bottom: 10px;
}
.footer-logo {
background-color: $theme-color-2;
padding: 18px 30px;
}
.top-list {
@include flex;
gap: 40px;
@include breakpoint (max-xxl) {
gap: 20Px;
}
@include breakpoint (max-lg) {
flex-wrap: wrap;
gap: 15Px;
}
li {
a {
font-weight: 500;
text-transform: uppercase;
color: $white;
&:hover {
color: $theme-color;
}
}
}
}
.social-item {
@include flex;
gap: 12px;
a {
width: 40px;
height: 40px;
line-height: 40px;
background-color: $theme-color-2;
border-radius: 100px;
color: $white;
text-align: center;
&:hover {
background-color: $theme-color;
}
}
}
}
File diff suppressed because it is too large Load Diff
+501
View File
@@ -0,0 +1,501 @@
//page scroll bar add
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
/* Track */
::-webkit-scrollbar-track {
box-shadow: inset 0 0 5px $bg-color;
border-radius: 5px;
}
/* Handle */
::-webkit-scrollbar-thumb {
background: $theme-color;
border-radius: 10px;
}
//page scroll bar add
//Basic Code Start
.fix {
overflow: hidden;
}
.ralt{
position: relative;
}
//Basic Code End
//Video Css Start
.ripple {
position: relative;
&::before,&::after {
position: absolute;
left: 50%;
top: 50%;
width: 50px;
height: 50px;
-webkit-transform: translateX(-50%) translateY(-50%);
transform: translateX(-50%) translateY(-50%);
border-radius: 50%;
box-shadow: 0 0 0 0 rgba(255, 193, 7, 0.6);
-webkit-animation: rippleOne 3s infinite;
animation: rippleOne 3s infinite;
}
&::before {
-webkit-animation-delay: 0.9s;
animation-delay: 0.9s;
content: "";
position: absolute;
right: 0;
bottom: 0;
}
&::after {
-webkit-animation-delay: 0.6s;
animation-delay: 0.6s;
content: "";
position: absolute;
right: 0;
bottom: 0;
}
}
//Video Css End
.array-buttons {
@include flex;
gap: 20px;
@include breakpoint (max-xl) {
flex-wrap: wrap;
}
.array-prev {
width: 110px;
height: 48px;
line-height: 45px;
text-align: center;
background-color: transparent;
color: $header-color;
@include transition;
border-radius: 100px;
border: 1px solid $header-color;
font-weight: 600;
i {
margin-left: 5px;
transform: rotate(45deg);
}
&:hover {
background: $theme-color-2;
color: $header-color;
border: 1px solid $theme-color-2;
}
}
.array-next {
width: 110px;
height: 48px;
line-height: 45px;
text-align: center;
background-color: $theme-color-2;
color: $header-color;
@include transition;
border-radius: 100px;
font-weight: 600;
text-transform: uppercase;
i {
margin-left: 5px;
transform: rotate(-45deg);
}
&:hover {
background: $header-color;
color: $white;
}
}
}
.array-buttons-2 {
@include flex;
gap: 20px;
@include breakpoint (max-xl) {
flex-wrap: wrap;
}
.array-prev {
width: 42px;
height: 42px;
line-height: 42px;
text-align: center;
background-color: $header-color;
color: #00E5FF;
@include transition;
border-radius: 100%;
&:hover {
background: $theme-color;
color: $white;
}
}
.array-next {
width: 42px;
height: 42px;
line-height: 42px;
border-radius: 100%;
text-align: center;
background: #2ADDC8;
color: $header-color;
@include transition;
&:hover {
background: $theme-color;
color: $white;
}
}
}
.array-buttons-4 {
@include flex;
gap: 20px;
@include breakpoint (max-xl) {
flex-wrap: wrap;
}
.array-prev {
width: 45px;
height: 45px;
line-height: 45px;
text-align: center;
background: $bg-color;
color: $white;
@include transition;
border-radius: 100%;
}
.array-next {
width: 45px;
height: 45px;
line-height: 45px;
border: 1px solid rgba(65, 65, 65, 1);
border-radius: 100%;
text-align: center;
background: transparent;
color: $white;
@include transition;
&:hover {
background: $bg-color;
border: 1px none;
color: $white;
}
}
}
//pagination default
//pagination default
.swiper-dot {
text-align: center;
margin-top: 30px;
.swiper-pagination-bullet {
width: 10px;
height: 10px;
transition: 0.6s;
border-radius: 30px;
background-color: $theme-color-2;
opacity: 1;
position: relative;
&:not(:last-child){
margin-right: 15px;
}
}
.swiper-pagination-bullet.swiper-pagination-bullet-active {
background-color: $theme-color;
transition: 0.6s;
position: relative;
width: 10px;
height: 10px;
border-radius: 30px;
&::before {
@include before;
width: 10px;
height: 10px;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
border-radius: 30px;
}
}
}
.swiper-dot-2 {
text-align: center;
margin-top: 30px;
.swiper-pagination-bullet {
width: 16px;
height: 16px;
transition: 0.6s;
border-radius: 30px;
background-color: transparent;
border: 2px solid $header-color;
opacity: 1;
position: relative;
&:not(:last-child){
margin-right: 15px;
}
}
.swiper-pagination-bullet.swiper-pagination-bullet-active {
border: 2px solid $header-color;
transition: 0.6s;
position: relative;
width: 16px;
height: 16px;
border-radius: 30px;
&::before {
@include before;
width: 10px;
height: 10px;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
border-radius: 30px;
}
}
}
.bg-cover {
background-repeat: no-repeat;
background-size: cover;
position: relative;
background-position: center;
}
.slide-transtion {
-webkit-transition-timing-function: linear;
transition-timing-function: linear;
}
.brand-slide-element {
width: auto;
display: inline-block;
}
.page-nav-wrap {
margin-top: 60px;
@include breakpoint (max-xl) {
margin-top: 30px;
}
ul {
li {
display: inline-block;
.page-numbers {
&.current {
background: linear-gradient(180deg, #1539EE 0%, #2ADDC8 100%);
color: $white;
border-radius: 10px;
}
display: inline-block;
width: 40px;
height: 40px;
line-height: 40px;
text-align: center;
background-color: transparent;
border: 1px solid $theme-color-2;
color: $header-color;
@include transition;
border-radius: 10px;
font-weight: 600;
transition: all 0.3s ease-in-out;
margin: 0 2px;
&.style-2 {
display: inline-block;
width: 40px;
height: 40px;
line-height: 40px;
text-align: center;
background-color: $theme-color-2;
color: $white;
@include transition;
border-radius: 10px;
border: 1px solid $header-color;
font-weight: 600;
transition: all 0.3s ease-in-out;
}
@media (max-width: 767px) {
margin-top: 10px;
width: 40px;
height: 40px;
line-height: 40px;
font-size: 14px;
}
i {
margin-top: 2px;
color: $white;
@include transition;
}
&:hover {
background: $theme-color-2;
color: $white;
border: 1px solid $theme-color-2;
i {
color: $white;
}
}
}
}
}
}
.sticky-style {
position: sticky !important;
top: 100px;
}
.custom-container {
max-width: 1700px;
margin: 0 auto;
}
.bw-img-anim-left,
.bw-img-anim-right {
transition: clip-path 0.5s ease-out;
}
.split-text {
overflow: hidden;
position: relative;
}
.split-text .line {
overflow: hidden;
display: none;
}
html.lenis, html.lenis body {
height: auto;
}
.smooth-content {
position: relative;
}
.lenis.lenis-smooth {
scroll-behavior: auto !important;
}
//>>>>> Nice Select Css Start <<<<<//
.nice-select {
background-color: transparent;
width: unset;
outline: none;
// border-bottom: 2px solid $border-color !important;
border: none;
border-radius: 0;
padding: 0;
}
.nice-select .current {
margin-right: 12px;
}
.nice-select.open .list {
background: $bg-color;
margin-top: 16px;
width: 100%;
text-transform: capitalize;
color: $text-color;
}
.nice-select .option.selected.focus {
background: $bg-color;
outline: none;
color: $text-color;
text-transform: capitalize;
font-weight: 500;
font-size: 14px;
border: none;
}
.nice-select .option {
border: none;
}
.nice-select .option:hover {
background: transparent;
}
//>>>>> Nice Select Css End <<<<<//
.p-relative {
position: relative;
}
.tp-clip-anim {
position: relative;
overflow: hidden;
.mask {
position: absolute;
inset: 0;
background-size: cover;
background-position: center;
transform: scale(1.1);
opacity: 0;
animation: reveal 1s forwards;
}
// delay for each slice
@for $i from 1 through 9 {
.mask-#{$i} {
clip-path: inset(0 #{(9 - $i) * 11.1%} 0 #{($i - 1) * 11.1%});
animation-delay: #{$i * 0.1}s;
}
}
}
@keyframes reveal {
from {
opacity: 0;
transform: scale(1.2);
}
to {
opacity: 1;
transform: scale(1);
}
}
+622
View File
@@ -0,0 +1,622 @@
.hero-1 {
margin: 0 40px;
border-radius: 32px;
position: relative;
z-index: 9;
@include breakpoint (max-xxl) {
margin: 0 30px;
padding-top: 100px;
padding-bottom: 100px;
}
@include breakpoint (max-lg) {
padding-top: 80px;
padding-bottom: 0;
}
@include breakpoint (max-sm) {
margin: 0 15px;
}
.pagi-item {
right: 60px;
top: 345px;
position: absolute;
z-index: 999;
@include breakpoint (max-xxxl) {
top: 310px;
}
@include breakpoint (max-xxl) {
display: none;
}
.dot-number {
@include flex;
gap: 20px;
.swiper-pagination-bullet {
background: none !important;
width: auto !important;
height: auto !important;
margin: 0 !important;
@include transition;
}
.swiper-pagination-bullet-active {
.dot-num {
span {
color: $white;
font-size: 32px;
font-weight: 700;
@include transition;
}
}
}
.dot-num {
@include transition;
span {
font-size: 18px;
font-weight: 500;
color: rgba(255, 255, 255, 0.50);
@include transition;
}
}
}
}
.left-shape {
position: absolute;
left: 0;
bottom: 0;
@include breakpoint (max-xxl) {
display: none;
}
}
.hero-shape {
position: absolute;
z-index: -1;
right: 10px;
bottom: 0;
margin-right: 0;
@include breakpoint (max-xxxl) {
max-width: 660px;
}
@include breakpoint (max-xxl) {
display: none;
max-width: initial;
}
img {
@include imgw;
}
}
.top-shape {
position: absolute;
top: 0;
right: 0;
@include breakpoint (max-xxl) {
display: none;
}
img {
@include imgw;
}
}
.right-shape {
position: absolute;
right: 0;
top: 0;
@include breakpoint (max-xxl) {
display: none;
}
}
.container-fluid {
padding: 0 124px;
@include breakpoint (max-xl4) {
padding: 0 70px;
}
@include breakpoint (max-xxxl) {
padding: 0 50px;
}
@include breakpoint (max-xxl) {
padding: 0 30px;
}
@include breakpoint (max-sm) {
padding: 0 15px;
}
}
.hero-content {
h6 {
font-size: 18px;
font-weight: 500;
color: $white;
margin-bottom: 20px;
line-height: 1;
padding: 8px 16px;
border-radius: 100px;
display: inline-block;
position: relative;
background-color: $bg-color-2;
}
h1 {
color: $white;
text-transform: uppercase;
margin-bottom: 15px;
.video-btn {
width: 64px;
height: 64px;
line-height: 64px;
display: inline-block;
background-color: $theme-color;
color: $white;
text-align: center;
border-radius: 50%;
font-size: 20px;
margin-left: 60px;
position: relative;
z-index: 1;
transform: translateY(-15px);
@include breakpoint (max-xxxl) {
width: 50px;
height: 50px;
line-height: 50px;
}
@include breakpoint (max-xxl) {
display: none;
}
&::before {
position: absolute;
content: "";
background: rgba(203, 204, 207, 0.24);
width: 48px;
height: 1px;
left: -57px;
top: 30px;
}
&::after {
content: "";
position: absolute;
top: -10px;
left: -10px;
right: -10px;
bottom: -10px;
border: 10px solid rgba(255, 255, 255, 0.12);
border-radius: 50%;
z-index: -1;
}
}
}
p {
max-width: 671px;
color: rgba(255, 255, 255, 0.8);
padding-left: 30px;
border-left: 2px solid $white;
opacity: 0.8;
@include breakpoint (max-xxl) {
border-left: none;
padding-left: 0;
}
}
.hero-button {
@include flex;
gap: 35px;
margin-top: 50px;
@include breakpoint (max-xxl) {
margin-top: 30px;
flex-wrap: wrap;
gap: 25px;
}
.theme-btn {
background-color: $white;
&:hover {
background-color: $theme-color;
border: 1px solid $theme-color;
}
&.style-2 {
border: 1px solid $border-color-2;
background-color: transparent;
color: $white;
i {
background-color: $white;
color: $header-color;
}
&:hover {
background-color: $theme-color;
color: $white;
border: 1px solid $theme-color;
}
}
}
}
}
.hero-image {
margin-top: 20px;
margin-right: -140px;
position: relative;
z-index: 9;
@include breakpoint (max-xxl) {
margin-right: 0;
}
img {
@include imgw;
opacity: 0;
transform: translateY(50px);
transition: all 0.8s ease-in-out;
}
}
.swiper-slide-active {
.hero-image {
img {
opacity: 1;
transform: translateY(0);
}
}
}
}
.hero-2 {
position: relative;
@include breakpoint (max-xxl) {
padding-top: 100px;
padding-bottom: 100px;
}
@include breakpoint (max-lg) {
padding-top: 80px;
padding-bottom: 0;
}
.shape {
position: absolute;
left: 0;
top: 0;
@include breakpoint (max-xxl) {
display: none;
}
}
.container-fluid {
padding: 0 65px;
@include breakpoint (max-xxxl) {
padding: 0 50px;
}
@include breakpoint (max-xxl) {
padding: 0 40px;
}
@include breakpoint (max-xxl) {
padding: 0 30px;
}
@include breakpoint (max-sm) {
padding: 0 15px;
}
}
&::before {
@include before;
background:
linear-gradient(279deg, rgba(21, 26, 38, 0.88) 34.84%, rgba(21, 26, 38, 0) 84.02%);
}
.hero-image {
margin-top: 30px;
position: relative;
margin-left: -75px;
@include breakpoint (max-xxl) {
margin-left: 0;
margin-top: 0;
}
img {
@include imgw;
}
}
.hero-content {
position: relative;
z-index: 999;
h6 {
color: $white;
font-size: 18px;
font-weight: 500;
letter-spacing: 6px;
text-transform: uppercase;
margin-bottom: 20px;
}
h1 {
color: $white;
text-transform: uppercase;
margin-bottom: 20px;
}
p {
color: $white;
max-width: 800px;
padding-left: 24px;
border-left: 3px solid $white;
@include breakpoint (max-xxl) {
border-left: none;
padding-left: 0;
}
}
.hero-button {
@include flex;
gap: 35px;
margin-top: 50px;
@include breakpoint (max-xxl) {
flex-wrap: wrap;
gap: 25px;
}
.theme-btn {
background-color: $white;
&:hover {
background-color: $theme-color;
border: 1px solid $theme-color;
}
&.style-2 {
border: 1px solid $border-color-2;
background-color: transparent;
color: $white;
i {
background-color: $white;
color: $header-color;
}
&:hover {
background-color: $theme-color;
color: $white;
border: 1px solid $theme-color;
}
}
}
}
}
}
.hero-3 {
position: relative;
z-index: 9;
@include breakpoint (max-xxl) {
margin: 0 30px;
padding-top: 100px;
padding-bottom: 100px;
}
@include breakpoint (max-lg) {
padding-top: 80px;
padding-bottom: 0;
}
@include breakpoint (max-sm) {
margin: 0 15px;
}
.pagi-item {
right: 60px;
bottom: 120px;
position: absolute;
z-index: 999;
@include breakpoint (max-xxl) {
display: none;
}
.dot-number {
@include flex;
gap: 20px;
.swiper-pagination-bullet {
background: none !important;
width: auto !important;
height: auto !important;
margin: 0 !important;
@include transition;
}
.swiper-pagination-bullet-active {
.dot-num {
span {
color: $white;
font-size: 32px;
font-weight: 700;
@include transition;
}
}
}
.dot-num {
@include transition;
span {
font-size: 18px;
font-weight: 500;
color: rgba(255, 255, 255, 0.50);
@include transition;
}
}
}
}
.hero-shape {
position: absolute;
z-index: -1;
left: 0;
top: 0;
@include breakpoint (max-xxxl) {
max-width: 660px;
}
@include breakpoint (max-xxl) {
display: none;
max-width: initial;
}
img {
@include imgw;
}
}
.container-fluid {
padding: 0 124px;
@include breakpoint (max-xl4) {
padding: 0 70px;
}
@include breakpoint (max-xxxl) {
padding: 0 50px;
}
@include breakpoint (max-xxl) {
padding: 0 30px;
}
@include breakpoint (max-sm) {
padding: 0 15px;
}
}
.hero-content {
h6 {
font-size: 18px;
font-weight: 500;
color: $theme-color;
margin-bottom: 20px;
}
h1 {
color: $white;
text-transform: uppercase;
margin-bottom: 15px;
}
p {
max-width: 772px;
color: rgba(255, 255, 255, 0.8);
opacity: 0.8;
}
.hero-button {
@include flex;
gap: 35px;
margin-top: 50px;
@include breakpoint (max-xxl) {
margin-top: 30px;
flex-wrap: wrap;
gap: 25px;
}
.theme-btn {
background-color: $white;
&:hover {
background-color: $theme-color;
border: 1px solid $theme-color;
}
&.style-2 {
border: 1px solid $border-color-2;
background-color: transparent;
color: $white;
i {
background-color: $white;
color: $header-color;
}
&:hover {
background-color: $theme-color;
color: $white;
border: 1px solid $theme-color;
}
}
}
}
}
.hero-image {
margin-top: 20px;
position: relative;
z-index: 9;
@include breakpoint (max-xxl) {
margin-right: 0;
}
img {
@include imgw;
opacity: 0;
transform: translateY(50px);
transition: all 0.8s ease-in-out;
}
}
.swiper-slide-active {
.hero-image {
img {
opacity: 1;
transform: translateY(0);
}
}
}
}
View File
+95
View File
@@ -0,0 +1,95 @@
.mean-container a.meanmenu-reveal {
display: none;
}
.mean-container .mean-nav {
background: none;
margin-top: 0;
}
.mean-container .mean-bar {
padding: 0;
min-height: auto;
background: none;
background: none;
}
.mean-container .mean-nav > ul {
padding: 0;
margin: 0;
width: 100%;
list-style-type: none;
display: block !important;
}
.mean-container a.meanmenu-reveal {
display: none !important;
}
.mean-container .mean-nav ul li a {
display: block;
width: 100%;
padding: 10px 0;
color: $black;
font-size: 16px;
font-weight: 600;
line-height: 2;
font-weight: 700;
text-transform: capitalize;
border-bottom: 1px solid rgba(0, 0, 0, 0.20) !important;
border: none;
&:hover {
color: $theme-color-2;
}
}
.mean-container .mean-nav ul li .submenu li a {
border-bottom: none !important;
font-size: 14px;
padding: 6px 0;
color: $header-color;
}
.mean-container .mean-nav ul li a:last-child {
border-bottom: 0;
}
.mean-container .mean-nav ul li a:hover {
color: $theme-color;
}
.mean-container .mean-nav ul li a.mean-expand {
margin-top: 5px;
padding: 0 !important;
}
.mean-container .mean-nav ul li > a > i {
display: none;
}
.mean-container .mean-nav ul li > a.mean-expand i {
display: inline-block;
font-size: 18px;
}
.mean-container .mean-nav > ul > li:first-child > a {
border-top: 0;
}
.mean-container .mean-nav ul li a.mean-expand.mean-clicked i {
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
@include transition;
}
.mean-container .mean-nav ul li .mega-menu li a {
height: 200px;
width: 100%;
padding: 0;
border-top: 0;
margin-bottom: 20px;
}
+130
View File
@@ -0,0 +1,130 @@
@mixin breakpoint($point) {
@if $point==xsmall {
@media (min-width: 450px) {
@content ;
}
}
@else if $point==max-xxsmall {
@media (max-width:450px) {
@content ;
}
}
@if $point==xxs {
@media (min-width: 470px) {
@content ;
}
}
@else if $point==max-xxs {
@media (max-width:470px) {
@content ;
}
}
@if $point==xs {
@media (min-width: 500px) {
@content ;
}
}
@else if $point==max-xs {
@media (max-width: 500px) {
@content ;
}
}
@if $point==sm {
@media (min-width: 576px) {
@content ;
}
}
@else if $point==max-sm {
@media (max-width: 575px) {
@content ;
}
}
@else if $point==md {
@media (min-width: 768px) {
@content ;
}
}
@else if $point==max-md {
@media (max-width: 767px) {
@content ;
}
}
@else if $point==lg {
@media (min-width: 992px) {
@content ;
}
}
@else if $point==max-lg {
@media (max-width: 991px) {
@content ;
}
}
@else if $point==xl {
@media (min-width: 1200px) {
@content ;
}
}
@else if $point==max-xl {
@media (max-width: 1199px) {
@content ;
}
}
@else if $point==xxl {
@media (min-width: 1400px) {
@content ;
}
}
@else if $point==max-xxl {
@media (max-width: 1399px) {
@content ;
}
}
@else if $point==xxxl {
@media (min-width: 1600px) {
@content ;
}
}
@else if $point==max-xxxl {
@media (max-width: 1600px) {
@content ;
}
}
@else if $point==xl4 {
@media (min-width: 1899px) {
@content ;
}
}
@else if $point==max-xl4 {
@media (max-width: 1899px) {
@content ;
}
}
}
@mixin before {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
content: "";
}
@mixin flex {
display: flex;
align-items: center;
}
@mixin transition {
transition: all 0.4s ease-in-out;
}
@mixin imgw {
width: 100%;
height: 100%;
}
+880
View File
@@ -0,0 +1,880 @@
.news-card-item {
margin-top: 30px;
background-color: $bg-color;
border-radius: 16px;
.news-image {
position: relative;
border-top-left-radius: 16px;
border-top-right-radius: 16px;
overflow: hidden;
span {
border-radius: 100px;
background-color: $white;
color: $header-color;
font-size: 14px;
font-weight: 400;
padding: 4px 12px;
position: absolute;
top: 16px;
left: 16px;
z-index: 999;
}
.news-layer-wrapper {
position: absolute;
top: 100%;
left: 0;
width: 100%;
height: 100%;
display: flex;
transition: 0.5s;
.news-layer-image {
width: 25%;
height: 100%;
transition: 0.5s;
background-size: cover;
&:nth-child(1){
background-position: 0;
transition-delay: 0;
}
&:nth-child(2){
background-position: 33.33%;
transition-delay: 0.1s;
}
&:nth-child(3){
background-position: 66.66%;
transition-delay: 0.2s;
}
&:nth-child(4){
background-position: 100%;
transition-delay: 0.3s;
}
}
}
img {
@include imgw;
border-top-left-radius: 16px;
border-top-right-radius: 16px;
transform: scale(1.02);
transition: all 1.5s ease-out;
}
}
.news-content {
padding: 16px 24px 30px;
.list {
@include flex;
gap: 24px;
margin-bottom: 10px;
}
h3 {
a {
background-position: 0 95%;
background-repeat: no-repeat;
background-size: 0% 2px;
display: inline;
&:hover {
color: $theme-color;
background-size: 100% 2px;
background-image: linear-gradient(180deg, $theme-color 0%, $theme-color 100%);
}
}
}
.news-bottom {
@include flex;
justify-content: space-between;
border-top: 1px solid rgba(203, 204, 207, 0.24);
padding-top: 24px;
margin-top: 16px;
.info-item {
@include flex;
gap: 8px;
}
}
}
&:hover {
.news-image {
.news-layer-wrapper {
.news-layer-image {
transform: translateY(-100%);
}
}
img {
-webkit-transform: scale3d(1.1, 1.1, 1);
transform: scale3d(1.1, 1.1, 1);
}
}
}
}
.news-main-item {
border-radius: 16px;
background-color: $bg-color;
padding: 30px;
@include flex;
justify-content: space-between;
margin-top: 30px;
@include breakpoint (max-xxl) {
flex-wrap: wrap;
gap: 30px;
}
.news-left-content {
h2 {
sup {
font-size: 32px;
top: auto;
@include breakpoint (max-lg) {
font-size: 30px;
}
@include breakpoint (max-lg) {
font-size: 25px;
}
}
span {
font-size: 16px;
font-weight: 400;
}
}
h3 {
@include breakpoint (max-xl) {
br {
display: none;
}
}
a {
background-position: 0 95%;
background-repeat: no-repeat;
background-size: 0% 2px;
display: inline;
&:hover {
color: $theme-color;
background-size: 100% 2px;
background-image: linear-gradient(180deg, $theme-color 0%, $theme-color 100%);
}
}
}
.news-post {
@include flex;
justify-content: space-between;
margin-top: 30px;
@include breakpoint (max-lg) {
flex-wrap: wrap;
gap: 20px;
}
span {
text-transform: uppercase;
font-weight: 500;
color: $header-color;
}
}
}
.news-right-content {
@include flex;
gap: 30px;
@include breakpoint (max-lg) {
flex-wrap: wrap;
gap: 20px;
}
.news-image {
overflow: hidden;
transition: scale 0.4s ease, transform 0.4s ease;
@include breakpoint (max-lg) {
flex-basis: 100%;
}
img {
@include imgw;
border-radius: 16px;
}
}
.content {
p {
max-width: 388px;
margin-bottom: 30px;
}
.theme-btn {
padding: 2px 4px 2px 24px;
}
}
}
}
.news-card-items-3 {
@include flex;
border-radius: 16px;
background-color: $white;
margin-top: 30px;
@include breakpoint (max-xxl) {
flex-wrap: wrap;
gap: 30px;
padding: 10px;
}
@include breakpoint (max-lg) {
flex-wrap: initial;
gap: 30px;
padding: 0;
}
@include breakpoint (max-md) {
flex-wrap: wrap;
gap: 30px;
padding: 10px;
}
.news-image {
@include breakpoint (max-xxl) {
flex-basis: 100%;
}
@include breakpoint (max-lg) {
flex-basis: initial;
}
@include breakpoint (max-sm) {
flex-basis: 100%;
}
img {
border-top-left-radius: 16px;
border-bottom-left-radius: 16px;
@include breakpoint (max-xxl) {
@include imgw;
border-radius: 16px;
}
@include breakpoint (max-lg) {
width: initial;
height: initial;
border-top-left-radius: 16px;
border-bottom-left-radius: 16px;
}
@include breakpoint (max-sm) {
@include imgw;
border-radius: 16px;
}
}
}
.news-content {
padding: 25px 25px 25px 30px;
@include breakpoint (max-lg) {
padding: 0 25px;
}
h3 {
a {
background-position: 0 95%;
background-repeat: no-repeat;
background-size: 0% 2px;
display: inline;
&:hover {
color: $theme-color;
background-size: 100% 2px;
background-image: linear-gradient(180deg, $theme-color 0%, $theme-color 100%);
}
}
}
.info-item {
@include flex;
gap: 26px;
margin-top: 15px;
margin-bottom: 25px;
@include breakpoint (max-lg) {
flex-wrap: wrap;
gap: 10px;
}
.info-image {
@include flex;
gap: 8px;
h6 {
font-weight: 500;
text-transform: uppercase;
}
}
}
.theme-btn {
border: none;
padding: 0;
&:hover {
background-color: transparent;
color: $theme-color;
i {
background-color: $header-color;
color: $white;
}
}
}
}
}
.news-standard-wrapper {
.news-standard-post {
margin-bottom: 30px;
.news-image {
img {
@include imgw;
border-radius: 16px;
}
}
.news-content {
margin-top: 24px;
.news-list {
@include flex;
gap: 40px;
margin-bottom: 16px;
@include breakpoint (max-xxl) {
flex-wrap: wrap;
gap: 10px;
}
li {
i {
margin-right: 8px;
}
}
}
h3 {
margin-bottom: 10px;
a {
background-position: 0 95%;
background-repeat: no-repeat;
background-size: 0% 2px;
display: inline;
&:hover {
color: $theme-color;
background-size: 100% 2px;
background-image: linear-gradient(180deg, $theme-color 0%, $theme-color 100%);
}
}
}
p {
margin-bottom: 40px;
@include breakpoint (max-xxl) {
margin-bottom: 30px;
}
}
.theme-btn {
padding: 4px 4px 4px 24px;
}
}
}
}
.main-sideber {
.news-sideber-box {
padding: 30px;
background-color: $bg-color;
border-radius: 16px;
margin-bottom: 32px;
.wid-title {
border-bottom: 1px solid rgba(203, 204, 207, 0.24);
padding-bottom: 16px;
margin-bottom: 24px;
}
.search-widget {
form {
width: 100%;
position: relative;
input {
background-color: $white;
font-size: 16px;
font-weight: 400;
padding: 16px 20px;
width: 100%;
border: none;
color: $text-color;
border-radius: 100px;
}
button {
position: absolute;
right: 3px;
top: 3px;
bottom: 3px;
width: 50px;
height: 50px;
line-height: 50px;
border-radius: 100px;
font-size: 16px;
background-color: $theme-color;
color: $white;
text-align: center;
transition: all .3s ease-in-out;
&:hover {
background-color: $header-color;
}
}
}
}
.news-widget-categories {
ul {
li {
@include flex;
justify-content: space-between;
font-size: 16px;
font-weight: 400;
background-color: $white;
@include transition;
border-radius: 100px;
line-height: 1;
padding: 20px;
position: relative;
@include breakpoint (max-xxl) {
font-size: 14px;
}
i {
margin-right: 5px;
color: $theme-color-2;
}
&::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 0%;
height: 100%;
background: $theme-color;
z-index: 0;
transition: width 0.5s ease;
border-radius: 100px;
}
a {
color: $header-color;
}
span {
@include transition;
color: $header-color;
}
&:not(:last-child){
margin-bottom: 20px;
}
&:hover {
&::before {
width: 100%;
}
i {
color: $white;
}
a {
color: $white;
position: relative;
z-index: 999;
}
span {
color: $white;
position: relative;
z-index: 999;
}
}
}
}
}
.recent-post-area {
.recent-items {
@include flex;
gap: 20px;
&:not(:last-child){
margin-bottom: 20px;
}
.recent-thumb {
img {
border-radius: 8px;
}
}
.recent-content {
h6 {
margin-bottom: 10px;
line-height: 133%;
font-weight: 500;
font-size: 18px;
@include breakpoint (max-xxl) {
font-size: 15px;
}
a {
&:hover {
color: $theme-color;
}
}
}
ul {
li {
color: $text-color;
}
}
}
}
}
.tagcloud {
a {
display: inline-block;
padding: 12px 11px;
line-height: 1;
font-size: 16px;
font-weight: 400;
background: $white;
border-radius: 100px;
margin-right: 5px;
text-transform: capitalize;
margin-bottom: 10px;
color: $text-color;
@include transition;
position: relative;
&::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 0%;
height: 100%;
background: $theme-color;
border-radius: 100px;
z-index: 0;
transition: width 0.5s ease;
}
&:last-child {
margin-right: 0;
}
&:hover {
color: $white;
z-index: 999;
position: relative;
&::before {
width: 100%;
z-index: -1;
}
}
}
}
}
}
.news-details-wrapper {
.news-details-post {
.news-details-image {
img {
@include imgw;
border-radius: 16px;
}
}
.details-content {
margin-top: 24px;
.news-list {
@include flex;
gap: 40px;
margin-bottom: 16px;
@include breakpoint (max-xxl) {
flex-wrap: wrap;
gap: 10px;
}
li {
i {
margin-right: 8px;
}
}
}
h2 {
font-size: 40px;
margin-bottom: 10px;
@include breakpoint (max-xxl) {
font-size: 20px;
}
}
.thumb {
img {
@include imgw;
border-radius: 16px;
}
}
.sideber {
background-color: $theme-color-2;
padding: 24px 30px;
margin-top: 24px;
margin-bottom: 24px;
border-radius: 8px;
h5 {
color: $white;
font-weight: 500;
@include breakpoint (max-xxl) {
font-size: 16px;
}
}
}
.tag-share-wrap {
.tagcloud {
span {
font-size: 20px;
font-weight: 600;
display: inline-block;
margin-right: 8px;
color: $header-color;
font-family: $heading-font;
}
a {
display: inline-block;
padding: 12px 26px;
line-height: 1;
background: $bg-color;
margin-right: 8px;
text-transform: capitalize;
color: $text-color;
font-weight: 400;
@include transition;
border-radius: 30px;
@include breakpoint (max-xl){
padding: 10px 18px;
}
@include breakpoint (max-xl){
margin-bottom: 15px;;
}
&:hover {
background-color: $theme-color;
color: $white;
}
}
}
.social-share {
a {
font-size: 16px;
color: $header-color;
display: inline-block;
width: 36px;
height: 36px;
border-radius: 100px;
line-height: 36px;
text-align: center;
background-color: $bg-color;
&:not(:last-child){
margin-right: 10px;
}
&:hover {
color: $white;
background-color: $theme-color;
}
}
}
}
.comments-area {
margin-top: 40px;
border-top: 1px solid rgba(203, 204, 207, 0.24);
margin-top: 48px;
padding-top: 30px;
margin-bottom: 48px;
border-bottom: 1px solid rgba(203, 204, 207, 0.24);
@include breakpoint (max-xxl) {
margin-bottom: 30px;
}
.comments-heading {
margin-bottom: 30px;
@include breakpoint (max-sm){
margin-bottom: 20px;
}
}
.news-single-comment {
@include breakpoint (max-sm){
flex-wrap: wrap;
gap: 20px;
}
.image {
img {
border-radius: 12px;
}
}
.content {
.head {
.con {
h4 {
margin-bottom: 5px;
}
}
.reply {
font-weight: 500;
font-size: 16px;
color: $theme-color;
padding: 6px 14px;
text-transform: uppercase;
color: $white;
background-color: $header-color;
border-radius: 100px;
&:hover {
background-color: $theme-color;
}
}
}
}
&.style-2 {
margin-left: 90px;
@include breakpoint (max-xxl){
margin-left: 0;
}
}
}
}
.form-clt {
position: relative;
span {
color: $header-color;
font-size: 18px;
font-weight: 500;
font-family: $heading-font;
margin-bottom: 10px;
display: inline-block;
}
input,textarea {
width: 100%;
border: none;
outline: none;
background: $bg-color;
color: $text-color;
border-radius: 100px;
padding: 18px 20px;
@include breakpoint (max-md){
padding: 14px 20px;
}
@include breakpoint (max-sm){
padding: 12px 18px;
}
&::placeholder {
color: $text-color;
}
}
textarea {
padding-bottom: 100px;
resize: none;
border-radius: 40px;
}
}
.theme-btn {
width: 100%;
}
}
}
}
+446
View File
@@ -0,0 +1,446 @@
.preloader {
align-items: center;
cursor: default;
display: flex;
height: 100%;
justify-content: center;
position: fixed;
left: 0;
top: 0;
width: 100%;
z-index: 9999999;
.animation-preloader {
z-index: 1000;
.spinner {
animation: spinner 1s infinite linear;
border-radius: 50%;
border: 3px solid rgba(0, 0, 0, 0.2);
border-top-color: $theme-color;
height: 9em;
margin: 0 auto 3.5em auto;
width: 9em;
@media (max-width: 767px) {
width: 7.5em;
height: 7.5em;
margin: 0 auto 1.5em auto;
}
}
.txt-loading {
font: bold 5em $heading-font, $body-font;
text-align: center;
user-select: none;
@media (max-width: 767px) {
font-size: 2.5em;
}
.letters-loading {
color: $theme-color;
position: relative;
&:nth-child(2):before {
animation-delay: 0.2s;
}
&:nth-child(3):before {
animation-delay: 0.4s;
}
&:nth-child(4):before {
animation-delay: 0.6s;
}
&:nth-child(5):before {
animation-delay: 0.8s;
}
&:nth-child(6):before {
animation-delay: 1s;
}
&:nth-child(7):before {
animation-delay: 1.2s;
}
&:nth-child(8):before {
animation-delay: 1.4s;
}
&::before {
animation: letters-loading 4s infinite;
color: $header-color;
content: attr(data-text-preloader);
left: 0;
opacity: 0;
font-family: $heading-font;
position: absolute;
top: -3px;
transform: rotateY(-90deg);
}
}
}
}
p {
font-size: 15px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 8px;
color: $theme-color;
}
.loader {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
font-size: 0;
z-index: 1;
pointer-events: none;
.row {
height: 100%;
}
.loader-section {
padding: 0px;
.bg {
background-color: $bg-color;
height: 100%;
left: 0;
width: 100%;
transition: all 800ms cubic-bezier(0.77, 0, 0.175, 1);
}
}
}
&.loaded {
.animation-preloader {
opacity: 0;
transition: 0.3s ease-out;
}
.loader-section {
.bg {
width: 0;
transition: 0.7s 0.3s allcubic-bezier(0.1, 0.1, 0.1, 1);
}
}
}
}
.back-to-top {
background-color: $theme-color;
width: 50px;
height: 50px;
line-height: 40px;
border-radius: 100px;
color: $white;
font-size: 16px;
position: fixed;
display: inline-block;
z-index: 9999;
right: 30px;
bottom: 30px;
@include transition;
opacity: 0;
visibility: hidden;
transform: translateY(20px);
@include breakpoint (max-sm) {
display: none;
}
&:hover {
background-color: $white;
color: $theme-color-2;
}
&.show {
opacity: 1;
visibility: visible;
transform: translate(0);
}
}
.cursor-outer {
-webkit-margin-start: -12px;
margin-inline-start: -12px;
margin-top: -12px;
width: 30px;
height: 30px;
border: 1px solid $theme-color;
background-color: $theme-color;
-webkit-box-sizing: border-box;
box-sizing: border-box;
z-index: 10000000;
opacity: 0.34;
-webkit-transition: all 0.4s ease-out 0s;
transition: all 0.4s ease-out 0s;
}
.cursor-outer.cursor-hover {
opacity: 0.14;
}
.cursor-outer.cursor-big {
opacity: 0;
}
.mouseCursor {
position: fixed;
top: 0;
inset-inline-start: 0;
inset-inline-end: 0;
bottom: 0;
pointer-events: none;
border-radius: 50%;
-webkit-transform: translateZ(0);
transform: translateZ(0);
visibility: hidden;
text-align: center;
}
.mouseCursor.cursor-big {
width: 20px;
height: 20px;
-webkit-margin-start: -12px;
margin-inline-start: -12px;
margin-top: -12px;
}
.cursor-inner {
-webkit-margin-start: -3px;
margin-inline-start: -3px;
margin-top: -3px;
width: 10px;
height: 10px;
z-index: 10000001;
background-color: $theme-color;
opacity: 1;
-webkit-transition: all 0.24s ease-out 0s;
transition: all 0.24s ease-out 0s;
span {
color: $text-color;
line-height: 60px;
opacity: 0;
text-transform: uppercase;
letter-spacing: 1px;
font-size: 12px;
}
}
.cursor-inner.cursor-big {
span {
opacity: 1;
}
}
.cursor-inner.cursor-hover {
-webkit-margin-start: -10px;
margin-inline-start: -10px;
margin-top: -10px;
width: 30px;
height: 30px;
background-color: $theme-color;
border: 1px solid #686363;
opacity: 0;
}
.search-popup {
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: -2;
-webkit-transition: all 1s ease;
-khtml-transition: all 1s ease;
-moz-transition: all 1s ease;
-ms-transition: all 1s ease;
-o-transition: all 1s ease;
transition: all 1s ease;
}
.search-popup__overlay {
position: fixed;
width: 224vw;
height: 224vw;
top: calc(90px - 112vw);
right: calc(50% - 112vw);
z-index: 3;
display: block;
-webkit-border-radius: 50%;
-khtml-border-radius: 50%;
-moz-border-radius: 50%;
-ms-border-radius: 50%;
-o-border-radius: 50%;
border-radius: 50%;
-webkit-transform: scale(0);
-khtml-transform: scale(0);
-moz-transform: scale(0);
-ms-transform: scale(0);
-o-transform: scale(0);
transform: scale(0);
-webkit-transform-origin: center;
transform-origin: center;
-webkit-transition: transform 0.8s ease-in-out;
-khtml-transition: transform 0.8s ease-in-out;
-moz-transition: transform 0.8s ease-in-out;
-ms-transition: transform 0.8s ease-in-out;
-o-transition: transform 0.8s ease-in-out;
transition: transform 0.8s ease-in-out;
transition-delay: 0s;
transition-delay: 0.3s;
-webkit-transition-delay: 0.3s;
background-color: #000000;
opacity: 0.7;
cursor: url(../../assets/img/close.png), auto;
}
@media (max-width: 767px) {
.search-popup__overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
transform: none;
width: 100%;
height: 100%;
border-radius: 0;
transform: translateY(-110%);
}
}
.search-popup__content {
position: fixed;
width: 0;
max-width: 560px;
padding: 30px 15px;
left: 50%;
top: 50%;
opacity: 0;
z-index: 3;
-webkit-transform: translate(-50%, -50%);
-khtml-transform: translate(-50%, -50%);
-moz-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
-o-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
-webkit-transition: opacity 0.5s 0s, width 0.8s 0.8s cubic-bezier(0.225, 0.01, 0.475, 1.01), transform 0.2s 0s;
-khtml-transition: opacity 0.5s 0s, width 0.8s 0.8s cubic-bezier(0.225, 0.01, 0.475, 1.01), transform 0.2s 0s;
-moz-transition: opacity 0.5s 0s, width 0.8s 0.8s cubic-bezier(0.225, 0.01, 0.475, 1.01), transform 0.2s 0s;
-ms-transition: opacity 0.5s 0s, width 0.8s 0.8s cubic-bezier(0.225, 0.01, 0.475, 1.01), transform 0.2s 0s;
-o-transition: opacity 0.5s 0s, width 0.8s 0.8s cubic-bezier(0.225, 0.01, 0.475, 1.01), transform 0.2s 0s;
transition: opacity 0.5s 0s, width 0.8s 0.8s cubic-bezier(0.225, 0.01, 0.475, 1.01), transform 0.2s 0s;
transition-delay: 0s, 0.8s, 0s;
transition-delay: 0s, 0.4s, 0s;
transition-delay: 0.2s;
-webkit-transition-delay: 0.2s;
}
.search-popup__form {
position: relative;
}
.search-popup__form input[type=search],
.search-popup__form input[type=text] {
width: 100%;
height: 66px;
border: none;
outline: none;
padding-left: 20px;
background-color: $white;
font-size: 16px;
font-weight: 400;
color: $text-color;
transition: all 500ms ease;
}
.search-popup__form input[type=search]:focus,
.search-popup__form input[type=text]:focus {
color: $header-color;
}
.search-popup__form .search-btn {
padding: 0;
width: 66px;
height: 66px;
display: flex;
justify-content: center;
align-items: center;
position: absolute;
top: 0;
right: -1px;
border-radius: 0;
font-size: 20px;
color: $white;
background-color: $theme-color;
@include transition;
&:hover {
background-color: $black;
}
}
.search-popup__form .eolexi-btn svg {
width: 1em;
height: 1em;
fill: currentColor;
}
.search-popup.active {
z-index: 9999;
}
.search-popup.active .search-popup__overlay {
top: auto;
bottom: calc(90px - 112vw);
-webkit-transform: scale(1);
-khtml-transform: scale(1);
-moz-transform: scale(1);
-ms-transform: scale(1);
-o-transform: scale(1);
transform: scale(1);
transition-delay: 0s;
-webkit-transition-delay: 0s;
opacity: 0.7;
-webkit-transition: transform 1.6s cubic-bezier(0.4, 0, 0, 1);
-khtml-transition: transform 1.6s cubic-bezier(0.4, 0, 0, 1);
-moz-transition: transform 1.6s cubic-bezier(0.4, 0, 0, 1);
-ms-transition: transform 1.6s cubic-bezier(0.4, 0, 0, 1);
-o-transition: transform 1.6s cubic-bezier(0.4, 0, 0, 1);
transition: transform 1.6s cubic-bezier(0.4, 0, 0, 1);
}
@media (max-width: 767px) {
.search-popup.active .search-popup__overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
transform: none;
width: 100%;
height: 100%;
border-radius: 0;
transform: translateY(0%);
}
}
.search-popup.active .search-popup__content {
width: 100%;
opacity: 1;
transition-delay: 0.7s;
-webkit-transition-delay: 0.7s;
}
+309
View File
@@ -0,0 +1,309 @@
/* Pricing Section */
.pricing-wrapper-2 {
.pricing-content {
position: relative;
z-index: 9;
.pricing-text {
margin-top: 25px;
max-width: 548px;
}
.nav {
background-color: $white;
border-radius: 24.5px;
padding: 10px 20px;
margin-top: 40px;
border: none;
@include breakpoint (max-xxl) {
margin-top: 15px;
}
.nav-tabs {
border-bottom: 0;
display: flex;
}
.nav-link {
font-size: 16px;
font-weight: 700;
text-transform: uppercase;
border: 0;
border-radius: 0;
padding: 0 40px;
position: relative;
background: transparent;
z-index: 2;
color: $text-color;
margin-bottom: 0;
&::before {
content: "";
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%) translateX(50%);
background: $theme-color;
width: 43px;
height: 22px;
border-radius: 20px;
}
&::after {
content: "";
position: absolute;
right: -18px;
top: 50%;
transform: translateY(-50%);
width: 17px;
height: 17px;
border-radius: 50%;
background: $white;
z-index: 1;
}
&:first-child {
padding-left: 0;
}
&:last-child {
padding-right: 0;
&::after,
&::before {
display: none;
}
}
&.active {
color: $theme-color-2;
&::after {
right: 0;
}
}
}
}
}
.pricing-right-items {
display: flex;
align-items: center;
.pricing-box-items {
max-width: 417px;
width: 100%;
border-radius: 20px;
background: $header-color;
padding: 40px;
@include breakpoint (max-xxl) {
padding: 30px;
}
@include breakpoint (max-sm) {
padding: 25px;
}
.pricing-header {
position: relative;
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
padding-bottom: 35px;
position: relative;
z-index: 9;
margin-bottom: 32px;
.sub-texts {
top: 40px;
right: 0;
position: absolute;
font-size: 24px;
font-weight: 700;
color: $white;
@include breakpoint (max-sm) {
font-size: 20px;
}
}
h2 {
font-size: 72px;
font-weight: 700;
line-height: 1;
color: $white;
@include breakpoint (max-sm) {
font-size: 50px;
}
sup {
font-size: 32px;
font-weight: 700;
top: -1.5em;
margin-right: -10px;
@include breakpoint (max-sm) {
top: -0.5em;
}
}
sub {
font-size: 20px;
font-weight: 600;
text-transform: capitalize;
margin-left: -10px;
}
}
}
.theme-btn {
background: $theme-color;
color: $white;
border: none;
@include flex;
justify-content: space-between;
i {
background-color: $white;
color: $header-color;
}
&:hover {
background-color: $white;
color: $header-color;
i {
background-color: $theme-color;
color: $white;
}
}
}
ul {
margin-top: 24px;
li {
color: $white;
&:not(:last-child) {
margin-bottom: 15px;
}
@include breakpoint (max-sm) {
font-size: 14px;
}
i {
color: $theme-color-2;
margin-right: 8px;
@include breakpoint (max-sm) {
margin-right: 5px;
}
}
}
}
&.style-2 {
margin-left: -32%;
z-index: -1;
border-radius: 20px;
background: $white;
@media (max-width: 767px) {
margin-left: -70%;
}
.pricing-header {
.sub-texts {
color: $header-color;
}
}
.theme-btn {
width: 100%;
background-color: transparent;
border: 1px solid rgba(203, 204, 207, 0.24);
color: $header-color;
i {
background-color: $theme-color;
color: $white;
}
}
ul {
li {
color: $text-color;
}
}
}
&::after {
display: none;
}
}
}
}
.pricing-card-items-3 {
border-radius: 16px;
background-color: $white;
backdrop-filter: blur(24px);
padding: 40px 48px;
margin-top: 30px;
@include transition;
@include breakpoint (max-xl) {
padding: 30px;
}
.pricing-header {
border-bottom: 1px solid rgba(203, 204, 207, 0.24);
padding-bottom: 16px;
margin-bottom: 24px;
h6 {
text-transform: uppercase;
font-weight: 500;
margin-bottom: 10px;
}
h2 {
color: $theme-color-2;
}
}
.pricing-list-box {
padding: 24px;
background-color: $bg-color;
margin-bottom: 30px;
border-radius: 16px;
li {
color: $header-color;
&:not(:last-child) {
margin-bottom: 15px;
}
i {
color: $theme-color-2;
margin-right: 12px;
}
}
}
.theme-btn {
width: 100%;
@include flex;
justify-content: space-between;
}
&:hover {
transform: translateY(-10px);
}
}
+126
View File
@@ -0,0 +1,126 @@
//>>>>> Section Title Start <<<<<//
.section-title {
position: relative;
z-index: 99;
margin-bottom: 30px;
@include breakpoint (max-md){
margin-bottom: 0;
}
.sub-title {
font-size: 18px;
font-weight: 500;
color: $theme-color-2;
font-family: $heading-font;
margin-bottom: 20px;
text-transform: capitalize;
line-height: 1;
padding: 8px 16px;
border-radius: 100px;
display: inline-block;
position: relative;
background-color: $bg-color;
&.bg-2 {
background-color: $bg-color-2;
color: $white;
}
}
.sub-title-2 {
color: $theme-color-2;
text-transform: uppercase;
font-size: 18px;
font-weight: 500;
font-family: $heading-font;
margin-bottom: 20px;
display: inline-block;
&.theme {
color: $theme-color;
}
}
h2 {
text-transform: uppercase;
span {
text-transform: uppercase;
color: $theme-color;
}
}
}
.section-title-area {
@include flex;
justify-content: space-between;
position: relative;
z-index: 9;
margin-bottom: 30px;
.section-title {
margin-bottom: 0;
}
@include breakpoint (max-lg) {
flex-wrap: wrap;
// justify-content: center;
// text-align: center;
gap: 30px;
}
@include breakpoint (max-md){
margin-bottom: 0;
}
p {
max-width: 523px;
}
}
//>>>>> Section Title End <<<<<//
//>>>>> Basic Css Start <<<<<//
.center {
text-align: center;
margin: 0 auto;
}
.section-bg {
background-color: $bg-color-2;
}
.section-bg-1 {
background-color: $bg-color;
}
.section-bg-2 {
background-color: #F7F7F7;
}
.header-bg {
background-color: $header-color;
}
.footer-bg-2 {
background-color: #151A26;
}
.section-padding {
padding: 120px 0;
@include breakpoint(max-xl){
padding: 100px 0;
}
@include breakpoint(max-lg){
padding: 80px 0;
}
}
//>>>>> Basic Css End <<<<<//
+673
View File
@@ -0,0 +1,673 @@
.service-wrapper {
border-radius: 16px;
@include transition;
padding: 30px 0;
&.active {
@include breakpoint (max-xxl) {
margin-top: 30px;
}
}
.service-item {
@include flex;
justify-content: space-between;
position: relative;
@include breakpoint (max-xxxl) {
flex-wrap: wrap;
gap: 30px;
}
.image-hover {
width: 324px;
height: 196px;
position: absolute;
top: 50%;
inset-inline-start: 0;
background-size: cover;
background-repeat: no-repeat;
background-position-x: 75%;
opacity: 0;
transition: opacity 0.3s, transform 0.4s ease-out;
overflow: hidden;
pointer-events: none;
z-index: 2;
visibility: hidden;
border-radius: 10px;
}
.left-item {
@include flex;
gap: 100px;
@include breakpoint (max-xxxl) {
gap: 30px;
}
.number {
font-size: 20px;
font-weight: 700;
}
h3 {
a {
background-position: 0 95%;
background-repeat: no-repeat;
background-size: 0% 2px;
display: inline;
&:hover {
color: $theme-color;
background-size: 100% 2px;
background-image: linear-gradient(180deg, $theme-color 0%, $theme-color 100%);
}
}
}
}
.right-item {
@include flex;
position: relative;
p {
max-width: 503px;
}
.service-btn {
font-weight: 500;
color: $theme-color;
font-family: $heading-font;
text-transform: capitalize;
opacity: 0;
visibility: hidden;
transition: all 0.3s ease;
@include transition;
position: absolute;
top: 50%;
transform: translateY(-50%);
right: 0;
opacity: 0;
@include breakpoint (max-sm) {
display: none;
}
i {
margin-left: 5px;
}
}
}
}
&:hover {
background-color: $bg-color;
.service-item {
.image-hover {
opacity: 1;
visibility: visible;
}
.right-item {
align-items: center;
p {
margin-right: 80px;
@include breakpoint (max-sm) {
margin-right: 0;
}
}
.service-btn {
opacity: 1;
visibility: visible;
}
}
}
}
}
.service-wrapper-2 {
border-radius: 16px;
border: 1px solid rgba(203, 204, 207, 0.24);
margin-top: 48px;
.service-box-item {
border-right: 1px solid rgba(203, 204, 207, 0.24);
padding: 30px;
position: relative;
height: 100%;
overflow: hidden;
&::before {
@include before;
background: $white;
z-index: 3;
transition: all 0.3s ease-out;
}
.service-image {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
overflow: hidden;
transition: all 0.1s ease-out;
img {
@include imgw;
object-fit: cover;
object-position: center center;
}
&::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(0deg, rgba(21, 26, 38, 0.80) 0%, rgba(21, 26, 38, 0.80) 100%);
}
}
h2 {
font-size: 56px;
-webkit-text-stroke-width: 1px;
-webkit-text-stroke-color: $text-color;
color: transparent;
margin-bottom: 190px;
z-index: 999;
position: relative;
}
h3 {
z-index: 999;
position: relative;
a {
background-position: 0 95%;
background-repeat: no-repeat;
background-size: 0% 2px;
display: inline;
color: $header-color;
&:hover {
color: $theme-color;
background-size: 100% 2px;
background-image: linear-gradient(180deg, $theme-color 0%, $theme-color 100%);
}
}
}
&:hover {
border: none;
&::before {
transform: translate(100%,-100%);
}
h2 {
color: $theme-color !important;
-webkit-text-stroke: initial !important;
z-index: 999;
position: relative;
}
h3 {
z-index: 999;
position: relative;
a {
color: $white;
}
}
.service-image {
opacity: 1;
}
}
}
}
.service-section-2 {
position: relative;
z-index: 9;
.service-wrapper-2 {
.swiper-slide.swiper-slide-active {
.service-box-item {
border: 1px transparent;
&::before {
background: none;
}
.service-image {
opacity: 1;
}
h2 {
color: $theme-color !important;
-webkit-text-stroke: initial !important;
z-index: 999;
position: relative;
}
h3 {
z-index: 999;
position: relative;
a {
color: $white;
}
}
}
}
}
.service-bottom {
@include flex;
justify-content: space-between;
margin-top: 40px;
@include breakpoint (max-xxl){
display: none;
}
.service-pagi-items {
.service-dot {
.swiper-pagination-bullet {
width: 340px;
height: 2px;
border-radius: 0;
background: $border-color-2;
opacity: 1;
transition: 0.6s;
margin: 0 !important;
}
.swiper-pagination-bullet-active {
opacity: 1;
background: $theme-color;
width: 124px;
}
@include breakpoint (max-md){
display: none;
}
}
}
.array-buttons-3 {
@include flex;
gap: 24px;
@include breakpoint (max-sm) {
display: none;
}
.array-prev {
width: 48px;
height: 48px;
line-height: 48px;
text-align: center;
background-color: $bg-color;
color: $header-color;
@include transition;
z-index: 999;
border-radius: 100px;
transform: rotate(320deg);
&:hover {
background-color: $theme-color;
color: $white;
}
}
.array-next {
width: 48px;
height: 48px;
line-height: 48px;
text-align: center;
background-color: $theme-color;
color: $white;
@include transition;
z-index: 999;
border-radius: 100px;
transform: rotate(320deg);
border: 1px solid $theme-color;
&:hover {
background-color: $bg-color;
color: $header-color;
border: 1px solid $bg-color;
}
}
}
}
}
.service-main-item-3 {
@include flex;
justify-content: space-between;
border-radius: 16px;
background-color: $white;
padding: 16px 0px 16px 16px;
margin-top: 24px;
@include breakpoint (max-xxl) {
flex-wrap: wrap;
gap: 30px;
}
.service-left {
@include flex;
gap: 48px;
@include breakpoint (max-xxl) {
gap: 30px;
}
@include breakpoint (max-md) {
flex-wrap: wrap;
gap: 30px;
}
.service-image {
img {
@include imgw;
border-radius: 16px;
}
}
.content {
h3 {
a {
background-position: 0 95%;
background-repeat: no-repeat;
background-size: 0% 2px;
display: inline;
&:hover {
color: $theme-color;
background-size: 100% 2px;
background-image: linear-gradient(180deg, $theme-color 0%, $theme-color 100%);
}
}
}
p {
max-width: 566px;
margin-top: 15px;
}
}
}
.service-button {
transform: rotate(90deg);
margin-right: -15px;
@include breakpoint (max-xxl) {
margin-right: 0;
transform: rotate(0);
}
}
&.style-2 {
padding: 16px 16px 16px 16px;
.service-left {
.content {
text-align: right;
@include breakpoint (max-xxl) {
text-align: left;
}
}
}
.service-button {
margin-left: -15px;
margin-right: 0;
@include breakpoint (max-xxl) {
margin-left: 0;
}
}
}
}
.service-visa-wrapper {
@include flex;
justify-content: space-between;
@include breakpoint (max-xxl) {
border: 1px solid rgba(202, 210, 210, 0.8);
}
@include breakpoint (max-lg) {
flex-wrap: wrap;
}
.service-visa-items {
padding: 48px 48px 48px 40px;
border-top: 1px solid rgba(202, 210, 210, 0.8);
position: relative;
@include breakpoint (max-xxl) {
padding: 30px 30px 30px 30px;
border-top: none;
}
.top-item {
@include flex;
gap: 16px;
margin-bottom: 16px;
.number {
width: 64px;
height: 64px;
line-height: 64px;
text-align: center;
border-radius: 100px;
background-color: $bg-color;
}
h3 {
a {
background-position: 0 95%;
background-repeat: no-repeat;
background-size: 0% 2px;
display: inline;
&:hover {
color: $theme-color;
background-size: 100% 2px;
background-image: linear-gradient(180deg, $theme-color 0%, $theme-color 100%);
}
}
}
}
.service-button {
position: absolute;
top: 90px;
right: -89px;
bottom: 0;
color: $white;
background-color: $theme-color;
transform: rotate(90deg);
padding: 10px 12px;
height: 45px;
width: 224px;
text-align: center;
opacity: 0;
visibility: hidden;
@include transition;
@include breakpoint (max-xxl) {
display: none;
}
}
&.style-2 {
border-left: 1px solid rgba(202, 210, 210, 0.8);
}
&:hover {
.service-button {
opacity: 1;
visibility: visible;
}
}
}
}
.service-details-wrapper {
.service-details-post {
.details-image {
margin-top: 24px;
margin-bottom: 30px;
img {
@include imgw;
border-radius: 24px;
}
}
.text {
font-size: 32px;
@include breakpoint (max-xxl) {
font-size: 25px;
}
}
.service-left-content {
.list-item {
margin-top: 24px;
li {
i {
color: $theme-color-2;
margin-right: 6px;
}
span {
font-size: 20px;
font-weight: 500;
color: $header-color;
font-family: $heading-font;
@include breakpoint (max-xxl) {
font-size: 16px;
}
}
&:not(:last-child) {
margin-bottom: 16px;
}
}
}
}
.thumb {
img {
@include imgw;
border-radius: 24px;
}
}
.faq-items {
position: relative;
z-index: 9;
.accordion {
.accordion-item {
border: none;
h5 {
button {
line-height: 1;
font-weight: 600;
padding: 29px 30px;
color: $header-color;
cursor: pointer;
@include breakpoint(max-sm) {
font-size: 18px;
line-height: 1.6;
padding: 22px 20px;
}
}
}
.accordion-body {
padding: 20px 30px;
background-color: $white;
box-shadow: 8px 8px 32px 0 rgba(0, 72, 180, 0.08);
backdrop-filter: blur(5px);
p {
font-size: 16px;
line-height: 24px;
font-weight: 400;
@include breakpoint(max-sm) {
width: 100%;
font-size: 14px;
line-height: 28px;
}
}
}
}
.accordion-button {
background-color: $white;
color: $header-color;
box-shadow: 8px 8px 32px 0 rgba(36, 12, 135, 0.08);
backdrop-filter: blur(5px);
&::after {
content: "\f324";
font-family: "Font Awesome 6 Pro";
background: transparent;
font-weight: 900;
transition: all 0.3s ease-in-out !important;
color: $theme-color-2;
}
&:not(.collapsed) {
background-color: $white;
box-shadow: 8px 8px 32px 0 rgba(36, 12, 135, 0.08);
backdrop-filter: blur(5px);
color: $header-color;
&::after {
content: "\f322";
font-family: "Font Awesome 6 Pro";
background: transparent;
font-weight: 900;
color: $theme-color;
transform: rotate(0);
}
}
}
}
}
}
}
+370
View File
@@ -0,0 +1,370 @@
.testimonial-wrapper {
margin-top: 60px;
.testimonia-image {
position: relative;
height: 370px;
overflow: hidden;
border-radius: 16px;
@include breakpoint (max-lg) {
height: initial;
}
.video-btn {
width: 64px;
height: 64px;
line-height: 64px;
border-radius: 100px;
text-align: center;
background-color: $theme-color;
color: $white;
display: inline-block;
position: absolute;
left: 35px;
top: 30px;
z-index: 9;
&::before {
@include before;
border-radius: 1000px;
border: 1px solid rgba(203, 204, 207, 0.24);
width: 80px;
height: 80px;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}
}
h5 {
font-weight: 500;
color: $white;
position: absolute;
left: 24px;
bottom: 24px;
z-index: 9;
}
img {
@include imgw;
border-radius: 16px;
object-fit: cover;
}
&::after {
content: "";
position: absolute;
width: 200%;
height: 0%;
left: 50%;
top: 50%;
background-color: rgba(255,255,255,.3);
transform: translate(-50%,-50%) rotate(-45deg);
z-index: 1;
}
&:hover {
&::after {
height: 250%;
transition: all 600ms linear;
background-color: transparent;
}
}
}
.testimonial-box {
border-radius: 16px;
background-color: $bg-color;
padding: 30px 24px;
.star {
color: $theme-color;
margin-bottom: 24px;
}
p {
font-style: italic;
font-weight: 500;
max-width: 307px;
}
.info-item {
@include flex;
gap: 12px;
margin-top: 90px;
@include breakpoint (max-xxl) {
margin-top: 40px;
}
@include breakpoint (max-lg) {
margin-top: 30px;
}
.client-image {
img {
border-radius: 100%;
}
}
}
}
}
.testimonial-wrapper-2 {
margin-top: 60px;
@include breakpoint (max-sm) {
margin-top: 30px;
}
.testimonial-image {
height: 305px;
img {
@include imgw;
border-radius: 16px;
object-fit: cover;
}
}
.testimonial-item {
@include flex;
gap: 30px;
@include breakpoint (max-xxl) {
flex-wrap: wrap;
}
.testimonial-left {
@include transition;
.testimonial-box {
padding: 40px;
background-color: $theme-color-2;
border-radius: 16px;
position: relative;
@include transition;
@include breakpoint (max-xxl) {
padding: 30px;
}
&::before {
position: absolute;
bottom: -23px;
content: "";
left: 32px;
width: 35px;
height: 24px;
background-color: $theme-color-2;
clip-path: polygon(100% 0, 0 0, 100% 100%);
}
.star {
color: $white;
margin-bottom: 10px;
}
p {
max-width: 549px;
font-size: 20px;
font-weight: 500;
font-family: $heading-font;
color: $white;
line-height: 140%;
@include breakpoint (max-xxl) {
font-size: 16px;
}
}
}
.info-item {
@include flex;
gap: 10px;
margin-top: 24px;
margin-left: 80px;
img {
border: 1px solid $theme-color;
border-radius: 100%;
}
.content {
h5 {
font-weight: 500;
}
}
}
}
.right-item {
width: 100px;
.test-slider {
height: 300px;
@include breakpoint (max-xxl) {
height: 80px;
}
}
.client-image {
img {
border-radius: 8px;
transition: all 0.5s ease;
}
}
}
}
}
.testimonial-wrapper-3 {
margin-top: 60px;
.testimonial-thumb {
border-radius: 16px;
img {
@include imgw;
border-radius: 16px;
}
&.tp-clip-anim {
width: 100%;
display: grid;
align-items: center;
justify-items: center;
overflow: hidden;
position: relative;
& .tp-anim-img {
opacity: 0;
width: 100%;
height: 100%;
}
& .mask {
background-size: cover;
background-position: center;
transform: scale(1.005);
}
>* {
grid-area: 1 / 1 / 2 / 2;
width: 100%;
height: 100%;
max-height: 100%;
}
}
}
.testimonial-content {
margin-left: 50px;
position: relative;
@include breakpoint (max-xxl) {
margin-left: 0;
}
.content {
.star {
color: $theme-color;
margin-bottom: 20px;
}
h3 {
font-size: 28px;
line-height: 143%;
border-bottom: 1px solid rgba(203, 204, 207, 0.24);
padding-bottom: 40px;
margin-bottom: 30px;
font-weight: 500;
@include breakpoint (max-xxl) {
font-size: 24px;
}
@include breakpoint (max-lg) {
font-size: 20px;
}
@include breakpoint (max-sm) {
font-size: 16px;
}
}
.info-item {
@include flex;
gap: 20px;
.icon {
width: 56px;
height: 56px;
line-height: 56px;
text-align: center;
border-radius: 100px;
background-color: $theme-color-2;
color: $white;
font-size: 30px;
}
.content {
border-left: 1px solid rgba(203, 204, 207, 0.24);
padding-left: 30px;
}
}
}
.array-buttons-3 {
position: absolute;
right: 0;
bottom: 0;
@include flex;
gap: 24px;
@include breakpoint (max-sm) {
display: none;
}
.array-prev {
width: 48px;
height: 48px;
line-height: 48px;
text-align: center;
background-color: $bg-color;
color: $header-color;
@include transition;
z-index: 999;
border-radius: 100px;
transform: rotate(320deg);
&:hover {
background-color: $theme-color;
color: $white;
}
}
.array-next {
width: 48px;
height: 48px;
line-height: 48px;
text-align: center;
background-color: $theme-color;
color: $white;
@include transition;
z-index: 999;
border-radius: 100px;
transform: rotate(320deg);
border: 1px solid $theme-color;
&:hover {
background-color: $bg-color;
color: $header-color;
border: 1px solid $bg-color;
}
}
}
}
}
+174
View File
@@ -0,0 +1,174 @@
/* --------------------------------------------
Template Default Fonts & Fonts Styles
---------------------------------------------- */
@import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300..700&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap');
$heading-font: 'Space Grotesk', serif;
$body-font: "Inter", sans-serif;
//font-family: "Font Awesome 6 Free";
$fa: "Font Awesome 6 Pro";
body {
font-family: $body-font;
font-size: 16px;
font-weight: 400;
line-height: 24px;
color: $text-color;
background-color: $white;
padding: 0;
margin: 0;
overflow-x: hidden;
text-transform: capitalize;
}
ul {
padding: 0;
margin: 0;
list-style: none;
}
button {
border: none;
background-color: transparent;
padding: 0;
}
input:focus{
color: $white;
outline: none;
}
input{
color: $white;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: $heading-font;
margin: 0px;
padding: 0;
color: $header-color;
@include transition;
text-transform: capitalize;
}
h1 {
font-size: 72px;
font-weight: 700;
line-height: 111%;
@include breakpoint(max-xl4){
font-size: 70px;
}
@include breakpoint(max-xxxl){
font-size: 60px;
}
@include breakpoint(max-xxl){
font-size: 55px;
}
@include breakpoint(max-xl){
font-size: 40px;
}
@include breakpoint(max-lg){
font-size: 40px;
}
@include breakpoint(max-md){
font-size: 32px;
}
@include breakpoint(max-sm){
font-size: 28px;
}
}
h2 {
font-size: 48px;
font-weight: 700;
line-height: 117%;
@include breakpoint(max-xxl){
font-size: 50px;
}
@include breakpoint(max-xl){
font-size: 38px;
}
@include breakpoint(max-lg){
font-size: 38px;
}
@include breakpoint(max-md){
font-size: 35px;
}
@include breakpoint(max-sm){
font-size: 30px;
}
@include breakpoint(max-xxs){
font-size: 25px;
}
}
h3 {
font-size: 24px;
font-weight: 700;
line-height: 133%;
@include breakpoint(max-xl){
font-size: 20px;
}
}
h4 {
font-size: 22px;
font-weight: 700;
line-height: 141%;
@include breakpoint(max-xl){
font-size: 20px;
}
}
h5 {
font-size: 20px;
font-weight: 700;
line-height: 140%;
}
h6 {
font-size: 16px;
font-weight: 600;
}
a {
text-decoration: none;
outline: none !important;
cursor: pointer;
color: $header-color;
@include transition;
}
p {
margin: 0px;
@include transition;
}
span {
margin: 0px;
// @include transition;
}
+31
View File
@@ -0,0 +1,31 @@
:root {
--body: #fff;
--black: #000;
--white: #fff;
--theme: #E13833;
--theme-2: #0048B4;
--header: #151A26;
--text: #535761;
--text-2: #0B4E3D;
--border: #C9C9C9;
--border-2: #CBCCCF;
--bg: #F8F8F9;
--bg-2: #153888;
--box-shadow: 0px 1px 14px 0px rgba(0, 0, 0, 0.13);
}
// Theme Color - Defualt Colors
$black: var(--black);
$white: var(--white);
$theme-color: var(--theme);
$theme-color-2: var(--theme-2);
$text-color: var(--text);
$text-color-2: var(--text-2);
$header-color: var(--header);
$border-color: var(--border);
$border-color-2: var(--border-2);
$bg-color: var(--bg);
$bg-color-2: var(--bg-2);
$shadow: var(--pp-box-shadow);
+565
View File
@@ -0,0 +1,565 @@
.visa-certification-wrapper {
.visa-image {
margin-left: -310px;
@include breakpoint (max-xxl) {
margin-left: 0;
}
img {
@include imgw;
}
}
.visa-certification-content {
margin-left: 17px;
@include breakpoint (max-xxl) {
margin-left: 0;
margin-bottom: 100px;
margin-top: 100px;
}
@include breakpoint (max-lg) {
margin-bottom: 80px;
margin-top: 0;
}
.visa-item {
@include flex;
gap: 48px;
margin-top: 90px;
@include breakpoint (max-xxl) {
margin-top: 30px;
gap: 30px;
}
@include breakpoint (max-lg) {
flex-wrap: wrap;
gap: 30px;
}
.nav {
display: grid;
gap: 30px;
li {
font-size: 20px;
font-weight: 700;
font-family: $heading-font;
@include breakpoint (max-xxl) {
font-size: 12px;
}
@include breakpoint (max-lg) {
font-size: 16px;
}
.nav-link {
color: $header-color;
@include transition;
padding: 16px 40px 16px 16px;
border-radius: 8px;
backdrop-filter: blur(28px);
background-color: $white;
line-height: 1;
@include breakpoint (max-xxl) {
padding: 10px 10px 10px 10px;
}
@include breakpoint (max-lg) {
padding: 16px 40px 16px 16px;
}
i {
width: 24px;
height: 24px;
line-height: 24px;
text-align: center;
background-color: $theme-color;
color: $white;
border-radius: 50px;
font-size: 14px;
transform: rotate(-45deg);
margin-right: 6px;
}
&.active {
position: relative;
background-color: $theme-color;
color: $white;
border-radius: 100px;
i {
background-color: $white;
color: $theme-color;
}
}
}
}
}
.content {
.icon {
margin-bottom: 16px;
}
p {
max-width: 479px;
margin-bottom: 40px;
margin-top: 10px;
}
}
}
}
}
.visa-provide-box {
background-color: $white;
padding: 30px;
border-radius: 16px;
background-color: $white;
margin-top: 30px;
.visa-top-item {
margin-bottom: 30px;
@include flex;
justify-content: space-between;
@include breakpoint (max-xxl) {
flex-wrap: wrap;
gap: 20px;
}
.visa-left {
@include flex;
gap: 16px;
p {
color: $theme-color;
}
h3 {
a {
background-position: 0 95%;
background-repeat: no-repeat;
background-size: 0% 2px;
display: inline;
&:hover {
color: $theme-color;
background-size: 100% 2px;
background-image: linear-gradient(180deg, $theme-color 0%, $theme-color 100%);
}
}
}
}
.theme-btn {
background-color: $bg-color;
&:hover {
background-color: $theme-color;
color: $white;
}
}
}
.visa-list-item {
@include flex;
justify-content: space-between;
@include breakpoint (max-xxl) {
flex-wrap: wrap;
gap: 20px;
}
.list {
li {
font-size: 18px;
font-weight: 500;
font-family: $heading-font;
@include breakpoint (max-xxxl) {
font-size: 16px;
}
&:not(:last-child) {
margin-bottom: 20px;
}
i {
width: 22px;
height: 22px;
line-height: 22px;
text-align: center;
border-radius: 50px;
background-color: $text-color;
color: $white;
margin-right: 8px;
font-size: 12px;
transform: rotate(-45deg);
}
}
}
}
}
.visa-provide-section {
.visa-slider {
margin-left: -400px;
margin-right: -400px;
@include breakpoint (max-xxl) {
margin-right: 0;
margin-left: 0;
margin: 0 10px;
}
}
}
.visa-bottom {
position: relative;
margin-top: 70px;
@include breakpoint (max-xxl) {
display: none;
}
&::before {
background-color: $theme-color-2;
@include before;
width: 410px;
height: 132px;
padding: 16px 16px 16px 294px;
border-radius: 0 100px 100px 0;
@include breakpoint (max-xxxl) {
display: none;
}
}
&::after {
background-color: $theme-color-2;
position: absolute;
content: "";
width: 410px;
height: 132px;
padding: 16px 16px 16px 294px;
border-radius: 100px 0 0 100px;
right: 0;
top: 0;
@include breakpoint (max-xxxl) {
display: none;
}
}
.visa-arrow-item {
@include flex;
justify-content: space-between;
.array-prev {
width: 100px;
height: 100px;
line-height: 100px;
border-radius: 100%;
text-align: center;
background-color: $white;
color: $header-color;
position: relative;
z-index: 9;
margin-top: 16px;
margin-left: -15px;
font-size: 40px;
}
.array-next {
width: 100px;
height: 100px;
line-height: 100px;
border-radius: 100%;
text-align: center;
background-color: $theme-color;
color: $white;
position: relative;
z-index: 9;
margin-top: 16px;
margin-right: -15px;
font-size: 40px;
}
.flag-item {
@include flex;
gap: 24px;
.flag-thumb {
position: relative;
transition: all 0.4s ease-in-out;
width: 120px;
height: 120px;
img {
width: 100%;
height: 100%;
border-radius: 50%;
}
&::before {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
content: "";
background-color: rgba(5, 17, 26, 0.8);
border-radius: 50%;
transition: all 0.4s ease-in-out;
opacity: 0;
visibility: hidden;
}
&::after {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
content: "";
border: 5px solid $white;
border-radius: 50%;
transition: all 0.4s ease-in-out;
opacity: 0;
visibility: hidden;
}
.country-name {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
z-index: 2;
transition: all 0.4s ease-in-out;
opacity: 0;
visibility: hidden;
h4 {
font-size: 14px;
font-weight: 800;
text-transform: capitalize;
text-align: center;
color: $white;
}
}
&:hover {
&::before {
opacity: 1;
visibility: visible;
}
&::after {
opacity: 1;
visibility: visible;
}
.country-name {
opacity: 1;
visibility: visible;
}
}
}
}
}
}
.country-details-wrapper {
.country-details-post {
.details-image {
img {
@include imgw;
border-radius: 24px;
}
}
.country-details-content {
margin-top: 20px;
h2 {
margin-bottom: 10px;
}
h5 {
color: $theme-color-2;
margin-top: 30px;
}
.tourist-visa-box {
border-radius: 16px;
padding: 30px;
background-color: $bg-color;
margin-top: 30px;
margin-bottom: 24px;
.tourist-box {
@include flex;
gap: 50px;
.tourist-content {
h5 {
color: $header-color;
margin-bottom: 5px;
margin-top: 0;
}
}
&.style-2 {
padding-bottom: 15px;
border-bottom: 1px solid rgba(203, 204, 207, 0.7);
margin-bottom: 15px;
}
}
}
.text {
font-size: 32px;
}
.list-item {
margin-top: 20px;
margin-bottom: 30px;
li {
color: $header-color;
font-size: 18px;
font-weight: 500;
font-family: $heading-font;
&:not(:last-child) {
margin-bottom: 15px;
}
span {
font-size: 16px;
font-weight: 400;
color: $text-color;
font-family: $body-font;
}
}
}
.thumb {
img {
@include imgw;
border-radius: 16px;
}
}
.visa-list-2 {
@include flex;
gap: 32px;
margin-bottom: 20px;
li {
font-size: 20px;
font-weight: 500;
color: $header-color;
i {
color: $theme-color-2;
margin-right: 8px;
}
}
}
}
}
.country-details-sideber {
.icon-box-item {
background-color: $bg-color;
border-radius: 8px;
padding: 12px 24px;
@include flex;
justify-content: space-between;
margin-bottom: 8px;
.left-item {
@include flex;
gap: 16px;
}
i {
color: $header-color;
}
}
.visa-contact-box {
border-radius: 24px;
padding: 40px;
margin-top: 30px;
.content {
h3 {
color: $white;
}
p {
color: rgba(255, 255, 255, 0.7);
border-bottom: 1px solid rgba(203, 204, 207, 0.24);
padding-bottom: 16px;
margin-bottom: 24px;
}
.icon-item {
@include flex;
gap: 16px;
margin-bottom: 24px;
.icon {
width: 48px;
height: 48px;
line-height: 48px;
text-align: center;
border-radius: 100px;
background-color: #183074;
color: $white;
}
.cont {
span {
color: rgba(255, 255, 255, 0.7);
}
h6 {
color: $white;
font-size: 18px;
font-weight: 500;
a {
color: $white;
}
}
}
}
}
}
}
}
+102
View File
@@ -0,0 +1,102 @@
/*
Theme Name: Visaway
Author: Gramentheme
Author URI: https://themeforest.net/user/Gramentheme/portfolio
Description: Visaway Immigration & Visa Consulting HTML Template
Service Html Template
Version: 1.0.0
*/
/*CSS Table Of Content Ends Here*/
/*
--------------------------------------------------------------
[Table of Contents]
--------------------------------------------------------------
01. Variables & Mixins
02. Typography
03. Buttons
04. About
05. Animation
06. Brand
07. Contact
08. Cta
09. Faq
10. Feature
11. Footer
12. Header
13. Helping
14. Hero
15. Marquee
16. Meanmenu
17. News
18. Preloader
19. Pricing
20. Section
21. Service
22. Testimonial
23. Visa
--------------------------------------------------------------
*/
//>> Basic Start <<//
//>> Mixins <<//
@import "_mixins";
//>> Variables <<//
@import "_variables";
//>> Buttons <<//
@import "_buttons";
//>> Typography <<//
@import "_typography";
//>> Basic End <<//
//>> Template Section Style Start <<//
//>> About <<//
@import "_about";
//>> Animation <<//
@import "_animation";
//>> Brand <<//
@import "_brand";
//>> Contact <<//
@import "_contact";
//>> Cta <<//
@import "_cta";
//>> Faq <<//
@import "_faq";
//>> Feature <<//
@import "_feature";
//>> Footer <<//
@import "_footer";
//>> Header <<//
@import "_header";
//>> Helping <<//
@import "_helping";
//>> Hero <<//
@import "_hero";
//>> Marquee <<//
@import "_marquee";
//>> MeanMenu <<//
@import "_meanmenu";
//>> News <<//
@import "_news";
//>> _Preloader <<//
@import "_preloader";
//>> _Pricing <<//
@import "_pricing";
//>> Section <<//
@import "_section";
//>> Service <<//
@import "_service";
//>> Testimonial <<//
@import "_testimonial";
//>> Visa <<//
@import "_visa";
//>> Template Section Style End <<//
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More