enhance loader design

This commit is contained in:
Mohammed Al-yaseen
2025-08-02 02:25:27 +03:00
parent e627594be9
commit e6a3bd1fd5
7 changed files with 514 additions and 540 deletions

View File

@@ -1,185 +0,0 @@
// File: src/components/home/ServicesSection.tsx
"use client";
import {
CloudOutlined,
CodeOutlined,
GlobalOutlined,
LineChartOutlined,
MobileOutlined,
RobotOutlined,
RocketOutlined,
ShoppingOutlined,
} from '@ant-design/icons';
import { Button, Card, Col, Row, Typography } from 'antd';
import { motion } from 'framer-motion';
import React, { useEffect, useState } from 'react';
import styles from './ServicesSelector.module.css';
const { Title, Paragraph } = Typography;
interface ServicesSectionProps {
userPreferences: string[];
}
interface Service {
id: string;
title: string;
description: string;
icon: React.ReactNode;
preferenceMatches: string[];
}
const allServices: Service[] = [
{
id: 'webdev',
title: 'Web Development',
description: 'Custom web applications with cutting-edge technologies and responsive design.',
icon: <CodeOutlined className={styles.serviceIcon} />,
preferenceMatches: ['ecommerce', 'cloud', 'seo']
},
{
id: 'branding',
title: 'Branding & Identity',
description: 'Complete brand identity packages including logos, guidelines, and visual systems.',
icon: <RocketOutlined className={styles.serviceIcon} />,
preferenceMatches: ['branding', 'seo']
},
{
id: 'ecom',
title: 'E-commerce Solutions',
description: 'Full-stack e-commerce platforms with secure payment integration and inventory management.',
icon: <ShoppingOutlined className={styles.serviceIcon} />,
preferenceMatches: ['ecommerce', 'branding']
},
{
id: 'seo',
title: 'SEO & Marketing',
description: 'Data-driven digital marketing strategies to improve visibility and drive conversions.',
icon: <LineChartOutlined className={styles.serviceIcon} />,
preferenceMatches: ['seo', 'branding']
},
{
id: 'mobile',
title: 'Mobile Development',
description: 'Native and cross-platform mobile applications for iOS and Android.',
icon: <MobileOutlined className={styles.serviceIcon} />,
preferenceMatches: ['mobile', 'ai']
},
{
id: 'cloud',
title: 'Cloud Solutions',
description: 'Scalable cloud infrastructures, migrations, and DevOps automation.',
icon: <CloudOutlined className={styles.serviceIcon} />,
preferenceMatches: ['cloud', 'ai']
},
{
id: 'ai',
title: 'AI & Machine Learning',
description: 'Custom AI solutions for automation, prediction, and data analysis.',
icon: <RobotOutlined className={styles.serviceIcon} />,
preferenceMatches: ['ai', 'cloud']
},
{
id: 'global',
title: 'Global IT Consulting',
description: 'Strategic technology consulting to drive digital transformation and innovation.',
icon: <GlobalOutlined className={styles.serviceIcon} />,
preferenceMatches: ['cloud', 'branding', 'seo']
},
];
const ServicesSection: React.FC<ServicesSectionProps> = ({ userPreferences }) => {
const [services, setServices] = useState<Service[]>([]);
useEffect(() => {
// Sort services based on user preferences
if (userPreferences.length > 0) {
const sortedServices = [...allServices].sort((a, b) => {
const aMatches = a.preferenceMatches.filter(pref => userPreferences.includes(pref)).length;
const bMatches = b.preferenceMatches.filter(pref => userPreferences.includes(pref)).length;
return bMatches - aMatches;
});
setServices(sortedServices);
} else {
// If no preferences, show all services in default order
setServices(allServices);
}
}, [userPreferences]);
const containerVariants = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: {
staggerChildren: 0.1
}
}
};
const itemVariants = {
hidden: { y: 50, opacity: 0 },
visible: {
y: 0,
opacity: 1,
transition: { duration: 0.5 }
}
};
return (
<section className={styles.servicesSection}>
<div className={styles.sectionBackground}>
<div className={styles.glowOrb}></div>
</div>
<div className={styles.container}>
<motion.div
initial={{ opacity: 0, y: 30 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6 }}
viewport={{ once: true }}
className={styles.sectionHeader}
>
<Title level={2} className={styles.sectionTitle}>Our Services</Title>
<Paragraph className={styles.sectionSubtitle}>
Innovative technology solutions customized for your business needs
</Paragraph>
</motion.div>
<motion.div
variants={containerVariants}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
>
<Row gutter={[24, 24]}>
{services.map((service) => (
<Col xs={24} sm={12} lg={8} xl={6} key={service.id}>
<motion.div variants={itemVariants}>
<Card
hoverable
className={styles.serviceCard}
cover={
<div className={styles.serviceIconWrapper}>
{service.icon}
</div>
}
>
<Card.Meta
title={service.title}
description={service.description}
/>
<Button type="link" className={styles.learnMoreBtn}>
Learn more
</Button>
</Card>
</motion.div>
</Col>
))}
</Row>
</motion.div>
</div>
</section>
);
};
export default ServicesSection;

View File

@@ -1,102 +0,0 @@
/* File: src/components/home/ServicesSection.module.css */
.servicesSection {
position: relative;
padding: 100px 0;
overflow: hidden;
background-color: #f8f9fa;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 16px;
position: relative;
z-index: 2;
}
.sectionBackground {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
z-index: 1;
}
.glowOrb {
position: absolute;
width: 500px;
height: 500px;
border-radius: 50%;
background: var(--primary-glow);
top: -150px;
right: -100px;
filter: blur(50px);
}
.sectionHeader {
text-align: center;
margin-bottom: 60px;
}
.sectionTitle {
font-size: 2.5rem !important;
font-weight: 700 !important;
margin-bottom: 16px !important;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.sectionSubtitle {
font-size: 1.1rem;
color: #666;
max-width: 600px;
margin: 0 auto;
}
.serviceCard {
height: 100%;
border-radius: 12px;
overflow: hidden;
transition: all 0.3s ease;
border: none;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
}
.serviceCard:hover {
transform: translateY(-8px);
box-shadow: 0 12px 24px rgba(0, 0, 0, 0.1);
}
.serviceIconWrapper {
display: flex;
justify-content: center;
align-items: center;
height: 120px;
background: linear-gradient(135deg, #f5f7fa 0%, #e4e7eb 100%);
}
.serviceIcon {
font-size: 3rem;
color: #6e48aa;
}
.learnMoreBtn {
display: block;
margin-top: 16px;
padding: 0;
font-weight: 500;
}
@media (max-width: 768px) {
.servicesSection {
padding: 60px 0;
}
.sectionTitle {
font-size: 2rem !important;
}
}

View File

@@ -10,23 +10,217 @@
height: 100vh; height: 100vh;
width: 100vw; width: 100vw;
display: flex; display: flex;
flex-direction: column;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
background: linear-gradient(135deg, #42475C 0%, #20222F 100%); background: linear-gradient(135deg, #0F0525 0%, #1a0b3a 50%, #2A0B45 100%);
position: relative;
overflow: hidden;
}
.loaderBackground {
position: absolute;
inset: 0;
overflow: hidden;
}
.loaderOrb1 {
position: absolute;
top: -200px;
left: -200px;
width: 400px;
height: 400px;
background: linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%);
border-radius: 50%;
filter: blur(60px);
animation: float 8s ease-in-out infinite;
opacity: 0.3;
}
.loaderOrb2 {
position: absolute;
top: 50%;
right: -150px;
width: 300px;
height: 300px;
background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%);
border-radius: 50%;
filter: blur(50px);
animation: float 6s ease-in-out infinite reverse;
opacity: 0.2;
}
.loaderOrb3 {
position: absolute;
bottom: -100px;
left: 50%;
width: 250px;
height: 250px;
background: linear-gradient(135deg, #ec4899 0%, #f97316 100%);
border-radius: 50%;
filter: blur(40px);
animation: float 10s ease-in-out infinite;
opacity: 0.25;
}
@keyframes float {
0%, 100% {
transform: translateY(0px) rotate(0deg);
}
50% {
transform: translateY(-30px) rotate(180deg);
}
}
.loaderContent {
position: relative;
z-index: 10;
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
gap: 40px;
}
.logoContainer {
display: flex;
flex-direction: column;
align-items: center;
gap: 20px;
}
.logoIcon {
width: 80px;
height: 80px;
border-radius: 20px;
background: linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%);
display: flex;
align-items: center;
justify-content: center;
position: relative;
animation: logoPulse 2s ease-in-out infinite;
}
.logoInner {
width: 40px;
height: 40px;
border-radius: 10px;
background: white;
animation: logoRotate 3s linear infinite;
}
@keyframes logoPulse {
0%, 100% {
transform: scale(1);
box-shadow: 0 0 30px rgba(139, 92, 246, 0.5);
}
50% {
transform: scale(1.05);
box-shadow: 0 0 50px rgba(139, 92, 246, 0.8);
}
}
@keyframes logoRotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.logoText {
display: flex;
flex-direction: column;
align-items: center;
gap: 4px;
}
.logoTitle {
font-size: 2rem;
font-weight: 700;
color: white;
letter-spacing: 2px;
}
.logoSubtitle {
font-size: 1.2rem;
font-weight: 500;
color: #a855f7;
letter-spacing: 1px;
}
.loaderAnimation {
display: flex;
justify-content: center;
align-items: center;
}
.loaderDots {
display: flex;
gap: 8px;
}
.dot {
width: 12px;
height: 12px;
border-radius: 50%;
background: linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%);
animation: dotBounce 1.4s ease-in-out infinite both;
}
.dot:nth-child(1) {
animation-delay: -0.32s;
}
.dot:nth-child(2) {
animation-delay: -0.16s;
}
.dot:nth-child(3) {
animation-delay: 0s;
}
@keyframes dotBounce {
0%, 80%, 100% {
transform: scale(0.8);
opacity: 0.5;
}
40% {
transform: scale(1);
opacity: 1;
}
} }
.loaderText { .loaderText {
margin-top: 20px; display: flex;
color: white; flex-direction: column;
opacity: 0.8; align-items: center;
animation: pulse 2s infinite; gap: 8px;
} }
@keyframes pulse { .loaderTitle {
0% { opacity: 0.6; } color: white !important;
50% { opacity: 1; } font-size: 1.5rem !important;
100% { opacity: 0.6; } font-weight: 600 !important;
margin: 0 !important;
animation: textFade 2s ease-in-out infinite;
}
.loaderSubtitle {
color: #cbd5e1;
font-size: 0.95rem;
margin: 0;
opacity: 0.8;
animation: textFade 2s ease-in-out infinite 0.5s;
}
@keyframes textFade {
0%, 100% {
opacity: 0.7;
}
50% {
opacity: 1;
}
} }
.section { .section {
@@ -39,4 +233,76 @@
.section { .section {
padding: 60px 16px; padding: 60px 16px;
} }
.loaderContent {
gap: 30px;
}
.logoIcon {
width: 70px;
height: 70px;
}
.logoInner {
width: 35px;
height: 35px;
}
.logoTitle {
font-size: 1.8rem;
}
.logoSubtitle {
font-size: 1.1rem;
}
.loaderTitle {
font-size: 1.3rem !important;
}
.loaderSubtitle {
font-size: 0.9rem;
}
.dot {
width: 10px;
height: 10px;
}
}
@media (max-width: 480px) {
.loaderContent {
gap: 25px;
}
.logoIcon {
width: 60px;
height: 60px;
}
.logoInner {
width: 30px;
height: 30px;
}
.logoTitle {
font-size: 1.6rem;
}
.logoSubtitle {
font-size: 1rem;
}
.loaderTitle {
font-size: 1.2rem !important;
}
.loaderSubtitle {
font-size: 0.85rem;
}
.dot {
width: 8px;
height: 8px;
}
} }

View File

@@ -1,13 +1,12 @@
// File: src/pages/index.tsx // File: src/pages/index.tsx
"use client"; "use client";
import { Spin, Typography } from "antd"; import { Typography } from "antd";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import Footer from "./components/Footer/Footer"; import Footer from "./components/Footer/Footer";
import HeroSection from "./components/Hero/HeroSection"; import HeroSection from "./components/Hero/HeroSection";
import PreferencesSelector from "./components/Preferences/Preferences"; import PreferencesSelector from "./components/Preferences/Preferences";
import ProjectsShowcase from "./components/ProjectsShowcase/ProjectsShowcase"; import ProjectsShowcase from "./components/ProjectsShowcase/ProjectsShowcase";
import ServicesSection from "./components/Services/Services";
import TestimonialsSection from "./components/Testimonials/Testimonials"; import TestimonialsSection from "./components/Testimonials/Testimonials";
import styles from "./page.module.css"; import styles from "./page.module.css";
@@ -17,6 +16,8 @@ export default function Home() {
const [showPreferences, setShowPreferences] = useState(true); const [showPreferences, setShowPreferences] = useState(true);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [userPreferences, setUserPreferences] = useState<string[]>([]); const [userPreferences, setUserPreferences] = useState<string[]>([]);
console.log(userPreferences);
useEffect(() => { useEffect(() => {
// Check if preferences already exist in localStorage // Check if preferences already exist in localStorage
@@ -46,10 +47,40 @@ export default function Home() {
if (loading) { if (loading) {
return ( return (
<div className={styles.loaderContainer}> <div className={styles.loaderContainer}>
<Spin size="large" /> <div className={styles.loaderBackground}>
<Title level={4} className={styles.loaderText}> <div className={styles.loaderOrb1}></div>
Preparing Tech Master Experience... <div className={styles.loaderOrb2}></div>
</Title> <div className={styles.loaderOrb3}></div>
</div>
<div className={styles.loaderContent}>
<div className={styles.logoContainer}>
<div className={styles.logoIcon}>
<div className={styles.logoInner}></div>
</div>
<div className={styles.logoText}>
<span className={styles.logoTitle}>Tech</span>
<span className={styles.logoSubtitle}>Masters</span>
</div>
</div>
<div className={styles.loaderAnimation}>
<div className={styles.loaderDots}>
<div className={styles.dot}></div>
<div className={styles.dot}></div>
<div className={styles.dot}></div>
</div>
</div>
<div className={styles.loaderText}>
<Title level={4} className={styles.loaderTitle}>
Preparing Your Experience
</Title>
<p className={styles.loaderSubtitle}>
Loading innovative solutions and cutting-edge technology
</p>
</div>
</div>
</div> </div>
); );
} }
@@ -65,10 +96,6 @@ export default function Home() {
<HeroSection /> <HeroSection />
</section> </section>
<section id="services">
<ServicesSection userPreferences={userPreferences} />
</section>
<section id="projects"> <section id="projects">
<ProjectsShowcase /> <ProjectsShowcase />
</section> </section>

View File

@@ -289,7 +289,7 @@ export default function ProjectsPage() {
const [selectedCategory, setSelectedCategory] = useState("All"); const [selectedCategory, setSelectedCategory] = useState("All");
const [selectedProject, setSelectedProject] = useState<Project | null>(null); const [selectedProject, setSelectedProject] = useState<Project | null>(null);
const [isModalVisible, setIsModalVisible] = useState(false); const [isModalVisible, setIsModalVisible] = useState(false);
const [visibleProjects, setVisibleProjects] = useState(6); const [visibleProjects, setVisibleProjects] = useState(9);
const filteredProjects = const filteredProjects =
selectedCategory === "All" selectedCategory === "All"
@@ -318,11 +318,14 @@ export default function ProjectsPage() {
if (selectedCategory === category) { if (selectedCategory === category) {
// If clicking on the same category, remove the filter // If clicking on the same category, remove the filter
setSelectedCategory("All"); setSelectedCategory("All");
// When showing all projects, show more initially
setVisibleProjects(9);
} else { } else {
// Otherwise, set the new category // Otherwise, set the new category
setSelectedCategory(category); setSelectedCategory(category);
// When filtering, show fewer projects initially
setVisibleProjects(6);
} }
setVisibleProjects(6);
}; };
const containerVariants = { const containerVariants = {

View File

@@ -264,13 +264,14 @@
/* Service Cards */ /* Service Cards */
.serviceCard { .serviceCard {
background: white; background: white;
border-radius: 20px; border-radius: 24px;
padding: 40px; padding: 0;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); box-shadow: 0 8px 32px rgba(0, 0, 0, 0.08);
transition: all 0.3s ease; transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
position: relative; position: relative;
overflow: hidden; overflow: hidden;
border: none; border: none;
height: 100%;
} }
.serviceCard::before { .serviceCard::before {
@@ -281,26 +282,52 @@
right: 0; right: 0;
height: 4px; height: 4px;
background: linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%); background: linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%);
transform: scaleX(0);
transition: transform 0.3s ease;
}
.serviceCard:hover::before {
transform: scaleX(1);
} }
.serviceCard:hover { .serviceCard:hover {
transform: translateY(-10px); transform: translateY(-8px);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15); box-shadow: 0 20px 40px rgba(139, 92, 246, 0.15);
}
.cardHeader {
padding: 32px 32px 24px;
background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
position: relative;
display: flex;
justify-content: space-between;
align-items: flex-start;
} }
.serviceIconWrapper { .serviceIconWrapper {
width: 80px; width: 70px;
height: 80px; height: 70px;
border-radius: 20px; border-radius: 18px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
margin-bottom: 24px;
transition: all 0.3s ease; transition: all 0.3s ease;
position: relative;
z-index: 1;
} }
.serviceCard:hover .serviceIconWrapper { .serviceCard:hover .serviceIconWrapper {
transform: scale(1.1); transform: scale(1.1) rotate(5deg);
}
.serviceBadge {
background: rgba(139, 92, 246, 0.1);
color: #8b5cf6;
padding: 6px 12px;
border-radius: 20px;
font-size: 0.8rem;
font-weight: 600;
border: 1px solid rgba(139, 92, 246, 0.2);
} }
.serviceIcon { .serviceIcon {
@@ -341,8 +368,12 @@
background: linear-gradient(135deg, #f97316 0%, #ea580c 100%); background: linear-gradient(135deg, #f97316 0%, #ea580c 100%);
} }
.cardContent {
padding: 0 32px 32px;
}
.serviceTitle { .serviceTitle {
font-size: 1.5rem; font-size: 1.4rem;
font-weight: 700; font-weight: 700;
color: #1e293b; color: #1e293b;
margin-bottom: 12px; margin-bottom: 12px;
@@ -352,43 +383,66 @@
.serviceDescription { .serviceDescription {
color: #64748b; color: #64748b;
line-height: 1.6; line-height: 1.6;
margin-bottom: 20px; margin-bottom: 24px;
font-size: 0.95rem; font-size: 0.95rem;
} }
.featuresContainer {
margin-bottom: 24px;
}
.featuresTitle {
font-size: 0.9rem;
font-weight: 600;
color: #475569;
margin-bottom: 12px;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.serviceFeatures { .serviceFeatures {
list-style: none; list-style: none;
padding: 0; padding: 0;
margin: 0 0 24px 0; margin: 0;
} }
.serviceFeature { .serviceFeature {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 8px; gap: 10px;
color: #64748b; color: #64748b;
font-size: 0.9rem; font-size: 0.9rem;
margin-bottom: 8px; margin-bottom: 10px;
padding: 8px 0;
} }
.serviceFeature::before { .featureIcon {
content: '✓'; color: #8b5cf6;
color: #10b981;
font-weight: bold;
font-size: 0.8rem; font-size: 0.8rem;
font-weight: bold;
}
.cardFooter {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 20px;
border-top: 1px solid #f1f5f9;
} }
.learnMoreBtn { .learnMoreBtn {
background: linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%); background: linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%);
border: none; border: none;
color: white; color: white;
padding: 12px 24px; padding: 10px 20px;
border-radius: 25px; border-radius: 20px;
font-weight: 600; font-weight: 600;
font-size: 0.9rem;
transition: all 0.3s ease; transition: all 0.3s ease;
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
gap: 8px; gap: 6px;
height: auto;
} }
.learnMoreBtn:hover { .learnMoreBtn:hover {
@@ -398,6 +452,23 @@
color: white; color: white;
} }
.serviceStats {
display: flex;
flex-direction: column;
gap: 4px;
text-align: right;
}
.serviceStats .statItem {
font-size: 0.75rem;
color: #64748b;
line-height: 1.2;
}
.serviceStats .statItem strong {
color: #8b5cf6;
}
/* Process Section */ /* Process Section */
.processSection { .processSection {
padding: 80px 0; padding: 80px 0;
@@ -597,7 +668,28 @@
} }
.serviceCard { .serviceCard {
padding: 30px 20px; margin: 0 10px;
}
.cardHeader {
padding: 24px 20px 20px;
}
.cardContent {
padding: 0 20px 24px;
}
.cardFooter {
flex-direction: column;
gap: 16px;
align-items: stretch;
}
.serviceStats {
text-align: center;
flex-direction: row;
justify-content: center;
gap: 20px;
} }
.processSteps { .processSteps {
@@ -616,7 +708,24 @@
} }
.serviceCard { .serviceCard {
padding: 25px 15px; margin: 0 5px;
}
.cardHeader {
padding: 20px 16px 16px;
}
.cardContent {
padding: 0 16px 20px;
}
.serviceIconWrapper {
width: 60px;
height: 60px;
}
.serviceIcon {
font-size: 24px;
} }
.servicesTitle, .servicesTitle,

View File

@@ -2,31 +2,21 @@
import { import {
ArrowRightOutlined, ArrowRightOutlined,
BulbOutlined,
CloudOutlined, CloudOutlined,
CodeOutlined, CodeOutlined,
EnvironmentOutlined,
FacebookOutlined,
GlobalOutlined, GlobalOutlined,
InstagramOutlined,
LineChartOutlined, LineChartOutlined,
LinkedinOutlined,
MailOutlined,
MobileOutlined, MobileOutlined,
PhoneOutlined,
RobotOutlined, RobotOutlined,
RocketOutlined, RocketOutlined,
ShoppingOutlined, ShoppingOutlined
TeamOutlined,
TrophyOutlined,
TwitterOutlined,
} from "@ant-design/icons"; } from "@ant-design/icons";
import { Button, Card, Typography } from "antd"; import { Button, Typography } from "antd";
import { motion } from "framer-motion"; import { motion } from "framer-motion";
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import styles from "./page.module.css"; import styles from "./page.module.css";
const { Title, Paragraph, Text } = Typography; const { Title, Paragraph } = Typography;
interface Service { interface Service {
id: string; id: string;
@@ -255,174 +245,6 @@ export default function ServicesPage() {
</div> </div>
</motion.div> </motion.div>
</div> </div>
{/* Hero Footer */}
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8, delay: 0.4 }}
className={styles.heroFooter}
>
<div className={styles.heroFooterContent}>
<div className={styles.footerColumn}>
<div className={styles.footerColumnTitle}>
<TeamOutlined className={styles.footerColumnIcon} />
Company
</div>
<ul className={styles.footerLinks}>
<li className={styles.footerLink}>
<a href="/about">
<ArrowRightOutlined className={styles.footerLinkIcon} />
About Us
</a>
</li>
<li className={styles.footerLink}>
<a href="/services">
<ArrowRightOutlined className={styles.footerLinkIcon} />
Our Services
</a>
</li>
<li className={styles.footerLink}>
<a href="/projects">
<ArrowRightOutlined className={styles.footerLinkIcon} />
Portfolio
</a>
</li>
<li className={styles.footerLink}>
<a href="/contact">
<ArrowRightOutlined className={styles.footerLinkIcon} />
Contact Us
</a>
</li>
</ul>
</div>
<div className={styles.footerColumn}>
<div className={styles.footerColumnTitle}>
<BulbOutlined className={styles.footerColumnIcon} />
Services
</div>
<ul className={styles.footerLinks}>
<li className={styles.footerLink}>
<a href="/services#webdev">
<ArrowRightOutlined className={styles.footerLinkIcon} />
Web Development
</a>
</li>
<li className={styles.footerLink}>
<a href="/services#mobile">
<ArrowRightOutlined className={styles.footerLinkIcon} />
Mobile Apps
</a>
</li>
<li className={styles.footerLink}>
<a href="/services#ai">
<ArrowRightOutlined className={styles.footerLinkIcon} />
AI Solutions
</a>
</li>
<li className={styles.footerLink}>
<a href="/services#cloud">
<ArrowRightOutlined className={styles.footerLinkIcon} />
Cloud Services
</a>
</li>
</ul>
</div>
<div className={styles.footerColumn}>
<div className={styles.footerColumnTitle}>
<TrophyOutlined className={styles.footerColumnIcon} />
Resources
</div>
<ul className={styles.footerLinks}>
<li className={styles.footerLink}>
<a href="/blog">
<ArrowRightOutlined className={styles.footerLinkIcon} />
Blog & Insights
</a>
</li>
<li className={styles.footerLink}>
<a href="/case-studies">
<ArrowRightOutlined className={styles.footerLinkIcon} />
Case Studies
</a>
</li>
<li className={styles.footerLink}>
<a href="/whitepapers">
<ArrowRightOutlined className={styles.footerLinkIcon} />
Whitepapers
</a>
</li>
<li className={styles.footerLink}>
<a href="/webinars">
<ArrowRightOutlined className={styles.footerLinkIcon} />
Webinars
</a>
</li>
</ul>
</div>
<div className={styles.footerColumn}>
<div className={styles.footerColumnTitle}>
<MailOutlined className={styles.footerColumnIcon} />
Contact Info
</div>
<ul className={styles.footerLinks}>
<li className={styles.footerLink}>
<a href="mailto:info@techmaster.com">
<MailOutlined className={styles.footerLinkIcon} />
info@techmaster.com
</a>
</li>
<li className={styles.footerLink}>
<a href="tel:+15551234567">
<PhoneOutlined className={styles.footerLinkIcon} />
+1 (555) 123-4567
</a>
</li>
<li className={styles.footerLink}>
<a href="#">
<EnvironmentOutlined className={styles.footerLinkIcon} />
San Francisco, CA
</a>
</li>
<li className={styles.footerLink}>
<a href="/support">
<ArrowRightOutlined className={styles.footerLinkIcon} />
24/7 Support
</a>
</li>
</ul>
</div>
</div>
<div className={styles.footerBottom}>
<Paragraph className={styles.footerBottomText}>
Ready to transform your business? Let's discuss your next project.
</Paragraph>
<div className={styles.socialLinks}>
<a href="#" className={styles.socialLink}>
<FacebookOutlined />
</a>
<a href="#" className={styles.socialLink}>
<TwitterOutlined />
</a>
<a href="#" className={styles.socialLink}>
<LinkedinOutlined />
</a>
<a href="#" className={styles.socialLink}>
<InstagramOutlined />
</a>
</div>
<div className={styles.copyright}>
© 2024 Tech Master. All rights reserved. | Privacy Policy | Terms
of Service
</div>
</div>
</motion.div>
</section> </section>
{/* Services Section */} {/* Services Section */}
@@ -453,35 +275,69 @@ export default function ServicesPage() {
viewport={{ once: true }} viewport={{ once: true }}
className={styles.servicesGrid} className={styles.servicesGrid}
> >
{services.map((service) => ( {services.map((service, index) => (
<motion.div key={service.id} variants={itemVariants}> <motion.div
<Card className={styles.serviceCard}> key={service.id}
<div variants={itemVariants}
className={`${styles.serviceIconWrapper} ${service.iconClass}`} whileHover={{
> scale: 1.02,
{service.icon} transition: { duration: 0.2 }
}}
>
<div className={styles.serviceCard}>
<div className={styles.cardHeader}>
<div
className={`${styles.serviceIconWrapper} ${service.iconClass}`}
>
{service.icon}
</div>
<div className={styles.serviceBadge}>
Service {String(index + 1).padStart(2, '0')}
</div>
</div> </div>
<Title level={3} className={styles.serviceTitle}> <div className={styles.cardContent}>
{service.title} <Title level={3} className={styles.serviceTitle}>
</Title> {service.title}
</Title>
<Paragraph className={styles.serviceDescription}> <Paragraph className={styles.serviceDescription}>
{service.description} {service.description}
</Paragraph> </Paragraph>
<ul className={styles.serviceFeatures}> <div className={styles.featuresContainer}>
{service.features.map((feature, index) => ( <h4 className={styles.featuresTitle}>Key Features</h4>
<li key={index} className={styles.serviceFeature}> <ul className={styles.serviceFeatures}>
{feature} {service.features.map((feature, index) => (
</li> <motion.li
))} key={index}
</ul> className={styles.serviceFeature}
initial={{ opacity: 0, x: -20 }}
whileInView={{ opacity: 1, x: 0 }}
transition={{ delay: index * 0.1 }}
>
<span className={styles.featureIcon}></span>
{feature}
</motion.li>
))}
</ul>
</div>
<Button type="link" className={styles.learnMoreBtn}> <div className={styles.cardFooter}>
Learn More <ArrowRightOutlined /> <Button type="primary" className={styles.learnMoreBtn}>
</Button> Explore Service <ArrowRightOutlined />
</Card> </Button>
<div className={styles.serviceStats}>
<span className={styles.statItem}>
<strong>24/7</strong> Support
</span>
<span className={styles.statItem}>
<strong>100%</strong> Satisfaction
</span>
</div>
</div>
</div>
</div>
</motion.div> </motion.div>
))} ))}
</motion.div> </motion.div>
@@ -546,7 +402,7 @@ export default function ServicesPage() {
<span className={styles.gradientText}>Project</span>? <span className={styles.gradientText}>Project</span>?
</Title> </Title>
<Paragraph className={styles.ctaSubtitle}> <Paragraph className={styles.ctaSubtitle}>
Let's discuss how we can help bring your vision to life. Our team Let&apos;s discuss how we can help bring your vision to life. Our team
is ready to create something amazing together. is ready to create something amazing together.
</Paragraph> </Paragraph>
<Button size="large" className={styles.ctaButton}> <Button size="large" className={styles.ctaButton}>