update
This commit is contained in:
@@ -2,7 +2,6 @@ import Header from "@/components/shared/layout/header/Header";
|
||||
import CareerBanner from "@/components/pages/career/CareerBanner";
|
||||
import OpenPosition from "@/components/pages/career/OpenPosition";
|
||||
import Thrive from "@/components/pages/career/Thrive";
|
||||
import MasonryGallery from "@/components/pages/career/MasonryGallery";
|
||||
import Footer from "@/components/shared/layout/footer/Footer";
|
||||
import CareerScrollProgressButton from "@/components/pages/career/CareerScrollProgressButton";
|
||||
import CareerInitAnimations from "@/components/pages/career/CareerInitAnimations";
|
||||
@@ -15,7 +14,6 @@ const page = () => {
|
||||
<CareerBanner />
|
||||
<OpenPosition />
|
||||
<Thrive />
|
||||
<MasonryGallery />
|
||||
</main>
|
||||
<Footer />
|
||||
<CareerScrollProgressButton />
|
||||
|
||||
@@ -64,8 +64,20 @@ export default function RootLayout({
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body className={`${inter.variable} ${montserrat.variable}`}>
|
||||
<html lang="en" style={{ scrollBehavior: 'auto', overflow: 'auto' }}>
|
||||
<head>
|
||||
<script
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
if ('scrollRestoration' in history) {
|
||||
history.scrollRestoration = 'manual';
|
||||
}
|
||||
window.scrollTo(0, 0);
|
||||
`,
|
||||
}}
|
||||
/>
|
||||
</head>
|
||||
<body className={`${inter.variable} ${montserrat.variable}`} style={{ scrollBehavior: 'auto', overflow: 'auto' }}>
|
||||
<CookieConsentProvider
|
||||
config={{
|
||||
companyName: "EnterpriseSoft Solutions",
|
||||
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -84,7 +84,7 @@ const AboutServiceComponent = () => {
|
||||
{serviceData?.title || "Enterprise Technology Leaders"}
|
||||
</h2>
|
||||
<p>
|
||||
{serviceData?.description || "Founded in 2008, EnterpriseSoft Solutions has emerged as a premier enterprise software company, serving Fortune 500 companies and innovative startups worldwide. Our team of 200+ engineers, architects, and consultants specializes in delivering mission-critical software solutions that drive digital transformation and business growth."}
|
||||
{serviceData?.description || "Founded 2008, EnterpriseSoft Solutions has emerged as a premier enterprise software company, serving Fortune 500 companies and innovative startups worldwide. Our team of 200+ engineers, architects, and consultants specializes in delivering mission-critical software solutions that drive digital transformation and business growth."}
|
||||
</p>
|
||||
<div className="enterprise-features">
|
||||
<div className="row">
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
import { useEffect } from "react";
|
||||
import gsap from "gsap";
|
||||
import { ScrollTrigger } from "gsap/dist/ScrollTrigger";
|
||||
import Image from "next/legacy/image";
|
||||
import Link from "next/link";
|
||||
import thumb from "@/public/images/banner/cp-thumb.png";
|
||||
|
||||
const CareerBanner = () => {
|
||||
useEffect(() => {
|
||||
@@ -38,23 +36,77 @@ const CareerBanner = () => {
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<section className="career-banner fix-top bg-black position-relative overflow-hidden">
|
||||
<section className="career-banner fix-top bg-black position-relative overflow-hidden" style={{ minHeight: '50vh', paddingTop: '100px', paddingBottom: '60px' }}>
|
||||
<div className="container">
|
||||
<div className="row justify-content-end">
|
||||
<div className="col-12 col-lg-11">
|
||||
<div className="row align-items-center">
|
||||
<div className="col-12 col-sm-11 col-md-10 col-xl-8 col-xxl-9">
|
||||
<div className="cp-banner__content">
|
||||
<h2 className="mt-8 fw-7 text-xxl title-anim text-white">
|
||||
Grow your career the way you feel
|
||||
</h2>
|
||||
</div>
|
||||
<div className="row justify-content-center align-items-center">
|
||||
<div className="col-12 col-lg-10">
|
||||
<div className="cp-banner__content text-center">
|
||||
<h2 className="mt-8 fw-7 text-xxl title-anim text-white mb-5">
|
||||
Build Your Career with Enterprise Excellence
|
||||
</h2>
|
||||
<p className="text-quinary fs-5 mb-5" style={{ maxWidth: '700px', margin: '0 auto 2rem' }}>
|
||||
Join our global team of innovators, problem-solvers, and tech leaders building the future of digital solutions
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Job Categories with Icons */}
|
||||
<div className="row justify-content-center mt-5 pt-4">
|
||||
<div className="col-6 col-md-3 text-center mb-4">
|
||||
<div className="job-category-card" style={{
|
||||
padding: '2rem 1rem',
|
||||
background: 'rgba(255,255,255,0.05)',
|
||||
borderRadius: '12px',
|
||||
border: '1px solid rgba(255,255,255,0.1)',
|
||||
transition: 'all 0.3s ease'
|
||||
}}>
|
||||
<div className="icon-wrapper mb-3" style={{ fontSize: '3rem', color: '#00d4ff' }}>
|
||||
<i className="fa-solid fa-code"></i>
|
||||
</div>
|
||||
<div className="col-12 col-sm-1 col-md-2 col-xl-4 col-xxl-3">
|
||||
<div className="cp-banner-thumb dir-rtl">
|
||||
<Image src={thumb} className="mh-300 unset" alt="Image" width={400} height={300} />
|
||||
</div>
|
||||
<h5 className="text-white fw-6 mb-2">Engineering</h5>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-6 col-md-3 text-center mb-4">
|
||||
<div className="job-category-card" style={{
|
||||
padding: '2rem 1rem',
|
||||
background: 'rgba(255,255,255,0.05)',
|
||||
borderRadius: '12px',
|
||||
border: '1px solid rgba(255,255,255,0.1)',
|
||||
transition: 'all 0.3s ease'
|
||||
}}>
|
||||
<div className="icon-wrapper mb-3" style={{ fontSize: '3rem', color: '#ff6b9d' }}>
|
||||
<i className="fa-solid fa-palette"></i>
|
||||
</div>
|
||||
<h5 className="text-white fw-6 mb-2">Design</h5>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-6 col-md-3 text-center mb-4">
|
||||
<div className="job-category-card" style={{
|
||||
padding: '2rem 1rem',
|
||||
background: 'rgba(255,255,255,0.05)',
|
||||
borderRadius: '12px',
|
||||
border: '1px solid rgba(255,255,255,0.1)',
|
||||
transition: 'all 0.3s ease'
|
||||
}}>
|
||||
<div className="icon-wrapper mb-3" style={{ fontSize: '3rem', color: '#ffd93d' }}>
|
||||
<i className="fa-solid fa-chart-line"></i>
|
||||
</div>
|
||||
<h5 className="text-white fw-6 mb-2">Business</h5>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-6 col-md-3 text-center mb-4">
|
||||
<div className="job-category-card" style={{
|
||||
padding: '2rem 1rem',
|
||||
background: 'rgba(255,255,255,0.05)',
|
||||
borderRadius: '12px',
|
||||
border: '1px solid rgba(255,255,255,0.1)',
|
||||
transition: 'all 0.3s ease'
|
||||
}}>
|
||||
<div className="icon-wrapper mb-3" style={{ fontSize: '3rem', color: '#a78bfa' }}>
|
||||
<i className="fa-solid fa-users"></i>
|
||||
</div>
|
||||
<h5 className="text-white fw-6 mb-2">Operations</h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -100,7 +100,7 @@ const JobSingle = ({ job }: JobSingleProps) => {
|
||||
borderRadius: '20px',
|
||||
fontSize: '12px',
|
||||
fontWeight: '500',
|
||||
textTransform: 'uppercase',
|
||||
textTransform: 'none',
|
||||
letterSpacing: '1px',
|
||||
display: 'inline-block'
|
||||
}}>
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
import Image from "next/legacy/image";
|
||||
import one from "@/public/images/masonry/one.png";
|
||||
import two from "@/public/images/masonry/two.png";
|
||||
import three from "@/public/images/masonry/three.png";
|
||||
import four from "@/public/images/masonry/four.png";
|
||||
import five from "@/public/images/masonry/five.png";
|
||||
import six from "@/public/images/masonry/six.png";
|
||||
import seven from "@/public/images/masonry/seven.png";
|
||||
|
||||
const MasonryGallery = () => {
|
||||
return (
|
||||
<div className="mason pt-120 pb-120 fade-wrapper">
|
||||
<div className="container">
|
||||
<div className="row vertical-column-gap">
|
||||
<div className="col-12 col-md-3">
|
||||
<div className="mason-single fade-top">
|
||||
<Image src={one} className="mh-260" alt="Image" width={300} height={260} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-12 col-md-4">
|
||||
<div className="mason-single fade-bottom">
|
||||
<Image src={two} className="mh-260" alt="Image" width={300} height={260} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-12 col-md-3">
|
||||
<div className="mason-single fade-left">
|
||||
<Image src={three} className="mh-260 botter" alt="Image" width={300} height={260} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-12 col-md-2">
|
||||
<div className="mason-single fade-right">
|
||||
<Image src={seven} className="mh-260 botter" alt="Image" width={300} height={260} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-12 col-md-5">
|
||||
<div className="mason-single fade-top">
|
||||
<Image src={five} className="mh-260" alt="Image" width={300} height={260} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-12 col-md-2">
|
||||
<div className="mason-single fade-bottom">
|
||||
<Image src={six} className="mh-260" alt="Image" width={300} height={260} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-12 col-md-5">
|
||||
<div className="mason-single toper fade-right">
|
||||
<Image src={four} className="mh-260" alt="Image" width={300} height={260} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default MasonryGallery;
|
||||
@@ -27,9 +27,9 @@ const Thrive = () => {
|
||||
Flexible workday
|
||||
</h4>
|
||||
<p className="cur-lg text-quinary">
|
||||
Lorem ipsum dolor sit amet consectetur. Elit sit laoreet aliquam
|
||||
porttitor mattis vel feugiat eget. Nunc nunc nunc urna lorem.
|
||||
mattis vel feugiat eget.
|
||||
We understand that productivity thrives in balance. Our flexible work arrangements
|
||||
empower you to structure your day for optimal performance while maintaining work-life
|
||||
harmony. Whether remote, hybrid, or on-site, we trust our teams to deliver excellence.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -42,9 +42,9 @@ const Thrive = () => {
|
||||
Transparency
|
||||
</h4>
|
||||
<p className="cur-lg text-quinary">
|
||||
Lorem ipsum dolor sit amet consectetur. Elit sit laoreet aliquam
|
||||
porttitor mattis vel feugiat eget. Nunc nunc nunc urna lorem.
|
||||
mattis vel feugiat eget.
|
||||
Open communication is the foundation of our culture. We believe in clear goal-setting,
|
||||
honest feedback, and accessible leadership. Every team member has visibility into
|
||||
company objectives, strategic decisions, and how their contributions drive enterprise success.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -55,9 +55,9 @@ const Thrive = () => {
|
||||
<div className="content mt-40">
|
||||
<h4 className="mt-8 title-anim fw-7 text-white mb-16">Support</h4>
|
||||
<p className="cur-lg text-quinary">
|
||||
Lorem ipsum dolor sit amet consectetur. Elit sit laoreet aliquam
|
||||
porttitor mattis vel feugiat eget. Nunc nunc nunc urna lorem.
|
||||
mattis vel feugiat eget.
|
||||
Your success is our priority. From comprehensive onboarding to continuous mentorship,
|
||||
we provide enterprise-grade resources, cutting-edge tools, and dedicated support systems.
|
||||
Our collaborative environment ensures you're never alone in tackling complex challenges.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -70,9 +70,9 @@ const Thrive = () => {
|
||||
Growth Skill
|
||||
</h4>
|
||||
<p className="cur-lg text-quinary">
|
||||
Lorem ipsum dolor sit amet consectetur. Elit sit laoreet aliquam
|
||||
porttitor mattis vel feugiat eget. Nunc nunc nunc urna lorem.
|
||||
mattis vel feugiat eget.
|
||||
Invest in your future with our comprehensive professional development programs. Access
|
||||
industry certifications, advanced training workshops, and leadership development initiatives.
|
||||
We champion continuous learning and provide clear pathways for career advancement.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,16 +1,61 @@
|
||||
"use client";
|
||||
import { ReactNode } from "react";
|
||||
import { ReactNode, useEffect } from "react";
|
||||
import Preloader from "./Preloader";
|
||||
import ScrollToTop from "./ScrollToTop";
|
||||
import { usePathname } from "next/navigation";
|
||||
|
||||
interface LayoutWrapperProps {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
const LayoutWrapper = ({ children }: LayoutWrapperProps) => {
|
||||
const pathname = usePathname();
|
||||
|
||||
useEffect(() => {
|
||||
// Force scroll to top on every pathname change - runs FIRST
|
||||
window.history.scrollRestoration = 'manual';
|
||||
|
||||
// Immediate scroll
|
||||
window.scrollTo(0, 0);
|
||||
document.documentElement.scrollTop = 0;
|
||||
document.body.scrollTop = 0;
|
||||
|
||||
// Disable any smooth scroll temporarily
|
||||
const html = document.documentElement;
|
||||
const body = document.body;
|
||||
const originalHtmlScroll = html.style.scrollBehavior;
|
||||
const originalBodyScroll = body.style.scrollBehavior;
|
||||
|
||||
html.style.scrollBehavior = 'auto';
|
||||
body.style.scrollBehavior = 'auto';
|
||||
|
||||
// Multiple forced scrolls
|
||||
const scrollInterval = setInterval(() => {
|
||||
window.scrollTo(0, 0);
|
||||
document.documentElement.scrollTop = 0;
|
||||
document.body.scrollTop = 0;
|
||||
}, 10);
|
||||
|
||||
// Clean up after 300ms
|
||||
const cleanup = setTimeout(() => {
|
||||
clearInterval(scrollInterval);
|
||||
html.style.scrollBehavior = originalHtmlScroll;
|
||||
body.style.scrollBehavior = originalBodyScroll;
|
||||
}, 300);
|
||||
|
||||
return () => {
|
||||
clearInterval(scrollInterval);
|
||||
clearTimeout(cleanup);
|
||||
};
|
||||
}, [pathname]);
|
||||
|
||||
return (
|
||||
<Preloader>
|
||||
{children}
|
||||
</Preloader>
|
||||
<>
|
||||
<ScrollToTop />
|
||||
<Preloader>
|
||||
{children}
|
||||
</Preloader>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
405
gnx-react/components/shared/layout/Preloader.css
Normal file
405
gnx-react/components/shared/layout/Preloader.css
Normal file
@@ -0,0 +1,405 @@
|
||||
/* Enterprise Preloader Overlay */
|
||||
.gnx-preloader-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background: linear-gradient(135deg, #0f172a 0%, #1e293b 50%, #0f172a 100%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 99999 !important;
|
||||
animation: fadeIn 0.4s ease-in;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Geometric Background Pattern */
|
||||
.gnx-preloader-bg-pattern {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image:
|
||||
linear-gradient(rgba(148, 163, 184, 0.03) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(148, 163, 184, 0.03) 1px, transparent 1px);
|
||||
background-size: 50px 50px;
|
||||
animation: patternMove 20s linear infinite;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.gnx-preloader-bg-pattern::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 600px;
|
||||
height: 600px;
|
||||
background: radial-gradient(circle, rgba(59, 130, 246, 0.1) 0%, transparent 70%);
|
||||
animation: pulse 4s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.gnx-preloader-container {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 2rem;
|
||||
text-align: center;
|
||||
padding: 3rem;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
/* Professional Logo Styling */
|
||||
.gnx-preloader-logo {
|
||||
position: relative;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.gnx-logo-wrapper {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
padding: 2rem;
|
||||
background: linear-gradient(135deg, rgba(30, 41, 59, 0.8) 0%, rgba(15, 23, 42, 0.8) 100%);
|
||||
border-radius: 20px;
|
||||
overflow: visible;
|
||||
border: 1px solid rgba(148, 163, 184, 0.2);
|
||||
box-shadow:
|
||||
0 20px 60px rgba(0, 0, 0, 0.5),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.1);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.gnx-logo-border {
|
||||
position: absolute;
|
||||
top: -2px;
|
||||
left: -2px;
|
||||
right: -2px;
|
||||
bottom: -2px;
|
||||
background: linear-gradient(135deg, #3b82f6, #8b5cf6, #ec4899);
|
||||
border-radius: 22px;
|
||||
opacity: 0.5;
|
||||
z-index: -1;
|
||||
animation: borderGlow 3s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.gnx-logo-image {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
filter: brightness(1.2) contrast(1.1);
|
||||
transition: all 0.3s ease;
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
/* Enterprise Branding */
|
||||
.gnx-enterprise-brand {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.gnx-brand-title {
|
||||
font-size: 1.75rem;
|
||||
font-weight: 700;
|
||||
color: #f1f5f9;
|
||||
letter-spacing: -0.02em;
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;
|
||||
text-shadow: 0 2px 10px rgba(59, 130, 246, 0.3);
|
||||
}
|
||||
|
||||
.gnx-brand-subtitle {
|
||||
font-size: 0.875rem;
|
||||
font-weight: 400;
|
||||
color: #94a3b8;
|
||||
letter-spacing: 0.1em;
|
||||
text-transform: uppercase;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Professional Progress Container */
|
||||
.gnx-progress-container {
|
||||
width: 320px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.gnx-progress-bar {
|
||||
width: 100%;
|
||||
height: 4px;
|
||||
background: rgba(148, 163, 184, 0.1);
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.gnx-progress-fill {
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, #3b82f6 0%, #8b5cf6 50%, #ec4899 100%);
|
||||
border-radius: 4px;
|
||||
transition: width 0.3s ease;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 0 20px rgba(59, 130, 246, 0.5);
|
||||
}
|
||||
|
||||
.gnx-progress-shine {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
transparent,
|
||||
rgba(255, 255, 255, 0.4),
|
||||
transparent
|
||||
);
|
||||
animation: progressShine 2s infinite;
|
||||
}
|
||||
|
||||
.gnx-progress-info {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.gnx-progress-text {
|
||||
font-size: 0.875rem;
|
||||
color: #94a3b8;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.05em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.gnx-progress-percentage {
|
||||
font-size: 1rem;
|
||||
color: #f1f5f9;
|
||||
font-weight: 600;
|
||||
font-family: 'SF Mono', 'Courier New', monospace;
|
||||
min-width: 45px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/* Professional Loading Indicator */
|
||||
.gnx-loading-indicator {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.gnx-spinner {
|
||||
position: relative;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.gnx-spinner-ring {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 2px solid transparent;
|
||||
border-top-color: #3b82f6;
|
||||
border-radius: 50%;
|
||||
animation: spinRing 1.5s cubic-bezier(0.68, -0.55, 0.265, 1.55) infinite;
|
||||
}
|
||||
|
||||
.gnx-spinner-ring:nth-child(1) {
|
||||
border-top-color: #3b82f6;
|
||||
animation-delay: 0s;
|
||||
}
|
||||
|
||||
.gnx-spinner-ring:nth-child(2) {
|
||||
border-top-color: #8b5cf6;
|
||||
animation-delay: 0.2s;
|
||||
width: 75%;
|
||||
height: 75%;
|
||||
top: 12.5%;
|
||||
left: 12.5%;
|
||||
}
|
||||
|
||||
.gnx-spinner-ring:nth-child(3) {
|
||||
border-top-color: #ec4899;
|
||||
animation-delay: 0.4s;
|
||||
width: 50%;
|
||||
height: 50%;
|
||||
top: 25%;
|
||||
left: 25%;
|
||||
}
|
||||
|
||||
/* Corporate Footer */
|
||||
.gnx-preloader-footer {
|
||||
margin-top: 2rem;
|
||||
padding-top: 2rem;
|
||||
border-top: 1px solid rgba(148, 163, 184, 0.1);
|
||||
}
|
||||
|
||||
.gnx-footer-text {
|
||||
font-size: 0.75rem;
|
||||
color: #64748b;
|
||||
font-weight: 400;
|
||||
letter-spacing: 0.05em;
|
||||
margin: 0;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
/* Content visibility */
|
||||
.gnx-content-hidden {
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
left: -9999px;
|
||||
}
|
||||
|
||||
.gnx-content-visible {
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
animation: contentFadeIn 0.5s ease-in;
|
||||
}
|
||||
|
||||
/* Enterprise Animations */
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
backdrop-filter: blur(0px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes contentFadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes patternMove {
|
||||
0% {
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
100% {
|
||||
transform: translate(50px, 50px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0%, 100% {
|
||||
opacity: 0.3;
|
||||
transform: translate(-50%, -50%) scale(1);
|
||||
}
|
||||
50% {
|
||||
opacity: 0.5;
|
||||
transform: translate(-50%, -50%) scale(1.1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes borderGlow {
|
||||
0%, 100% {
|
||||
opacity: 0.3;
|
||||
filter: blur(10px);
|
||||
}
|
||||
50% {
|
||||
opacity: 0.6;
|
||||
filter: blur(15px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes progressShine {
|
||||
0% {
|
||||
left: -100%;
|
||||
}
|
||||
100% {
|
||||
left: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes spinRing {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
/* Responsive Design */
|
||||
@media (max-width: 768px) {
|
||||
.gnx-preloader-container {
|
||||
gap: 1.5rem;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.gnx-logo-wrapper {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.gnx-logo-image {
|
||||
width: 75px !important;
|
||||
height: 56px !important;
|
||||
}
|
||||
|
||||
.gnx-brand-title {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.gnx-brand-subtitle {
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
.gnx-progress-container {
|
||||
width: 260px;
|
||||
}
|
||||
|
||||
.gnx-spinner {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.gnx-preloader-container {
|
||||
gap: 1rem;
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.gnx-logo-wrapper {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.gnx-logo-image {
|
||||
width: 60px !important;
|
||||
height: 45px !important;
|
||||
}
|
||||
|
||||
.gnx-brand-title {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.gnx-brand-subtitle {
|
||||
font-size: 0.625rem;
|
||||
}
|
||||
|
||||
.gnx-progress-container {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.gnx-spinner {
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
}
|
||||
|
||||
.gnx-footer-text {
|
||||
font-size: 0.625rem;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import { usePathname } from "next/navigation";
|
||||
import Image from "next/image";
|
||||
import "./Preloader.css";
|
||||
|
||||
interface PreloaderProps {
|
||||
children: React.ReactNode;
|
||||
@@ -9,377 +10,140 @@ interface PreloaderProps {
|
||||
|
||||
const Preloader = ({ children }: PreloaderProps) => {
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [isMounted, setIsMounted] = useState(false);
|
||||
const [progress, setProgress] = useState(0);
|
||||
const [currentPath, setCurrentPath] = useState("");
|
||||
const pathname = usePathname();
|
||||
|
||||
// Debug mode - set to true to see console logs
|
||||
const DEBUG = false;
|
||||
|
||||
// Skip preloader for faster development/testing (set to true to disable preloader)
|
||||
const SKIP_PRELOADER = false;
|
||||
|
||||
// Fast mode - set to true for even faster loading (200ms total)
|
||||
const FAST_MODE = true;
|
||||
|
||||
// Initial mount - show preloader on first load
|
||||
useEffect(() => {
|
||||
// Only show preloader if path has changed or it's initial load
|
||||
if (currentPath !== pathname) {
|
||||
if (DEBUG) console.log('Preloader: Starting transition from', currentPath, 'to', pathname);
|
||||
setIsLoading(true);
|
||||
setProgress(0);
|
||||
|
||||
// Simulate loading progress - faster and more responsive
|
||||
const progressInterval = setInterval(() => {
|
||||
setProgress((prev) => {
|
||||
if (prev >= 85) {
|
||||
clearInterval(progressInterval);
|
||||
return 85;
|
||||
}
|
||||
return prev + Math.random() * 25 + 10; // Faster progress increments
|
||||
});
|
||||
}, 50); // Reduced interval from 100ms to 50ms for smoother animation
|
||||
setIsMounted(true);
|
||||
setIsLoading(true);
|
||||
setProgress(0);
|
||||
|
||||
// Simulate loading progress
|
||||
const progressInterval = setInterval(() => {
|
||||
setProgress((prev) => {
|
||||
if (prev >= 90) {
|
||||
clearInterval(progressInterval);
|
||||
return 90;
|
||||
}
|
||||
return prev + Math.random() * 15 + 5;
|
||||
});
|
||||
}, 50);
|
||||
|
||||
// Complete loading much faster - adjust timing based on FAST_MODE
|
||||
const loadingDuration = FAST_MODE ? 200 : 400;
|
||||
const fadeOutDuration = FAST_MODE ? 50 : 100;
|
||||
|
||||
const completeTimer = setTimeout(() => {
|
||||
setProgress(100);
|
||||
setTimeout(() => {
|
||||
if (DEBUG) console.log('Preloader: Transition complete');
|
||||
setIsLoading(false);
|
||||
setCurrentPath(pathname);
|
||||
}, fadeOutDuration);
|
||||
}, loadingDuration);
|
||||
|
||||
// Fallback: Force complete after reasonable time
|
||||
const fallbackDuration = FAST_MODE ? 800 : 1500;
|
||||
const fallbackTimer = setTimeout(() => {
|
||||
if (DEBUG) console.log('Preloader: Fallback triggered - force completing');
|
||||
// Complete loading after minimum duration
|
||||
const completeTimer = setTimeout(() => {
|
||||
setProgress(100);
|
||||
setTimeout(() => {
|
||||
setIsLoading(false);
|
||||
setCurrentPath(pathname);
|
||||
setProgress(100);
|
||||
}, fallbackDuration);
|
||||
}, 200);
|
||||
}, 600);
|
||||
|
||||
return () => {
|
||||
clearInterval(progressInterval);
|
||||
clearTimeout(completeTimer);
|
||||
clearTimeout(fallbackTimer);
|
||||
};
|
||||
}
|
||||
}, [pathname, currentPath, DEBUG, FAST_MODE]);
|
||||
return () => {
|
||||
clearInterval(progressInterval);
|
||||
clearTimeout(completeTimer);
|
||||
};
|
||||
}, []);
|
||||
|
||||
// Skip preloader entirely if SKIP_PRELOADER is true
|
||||
if (SKIP_PRELOADER) {
|
||||
return <>{children}</>;
|
||||
}
|
||||
// Handle route changes
|
||||
useEffect(() => {
|
||||
if (!isMounted) return;
|
||||
|
||||
// Don't show preloader if not loading
|
||||
if (!isLoading) {
|
||||
return <>{children}</>;
|
||||
}
|
||||
// Show preloader on route change
|
||||
setIsLoading(true);
|
||||
setProgress(0);
|
||||
|
||||
// Simulate loading progress
|
||||
const progressInterval = setInterval(() => {
|
||||
setProgress((prev) => {
|
||||
if (prev >= 90) {
|
||||
clearInterval(progressInterval);
|
||||
return 90;
|
||||
}
|
||||
return prev + Math.random() * 20 + 10;
|
||||
});
|
||||
}, 40);
|
||||
|
||||
// Complete loading
|
||||
const completeTimer = setTimeout(() => {
|
||||
setProgress(100);
|
||||
setTimeout(() => {
|
||||
setIsLoading(false);
|
||||
}, 150);
|
||||
}, 400);
|
||||
|
||||
return () => {
|
||||
clearInterval(progressInterval);
|
||||
clearTimeout(completeTimer);
|
||||
};
|
||||
}, [pathname, isMounted]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="preloader-overlay">
|
||||
<div className="preloader-container">
|
||||
{/* Logo with shine effect */}
|
||||
<div className="preloader-logo">
|
||||
<div className="logo-wrapper">
|
||||
<Image
|
||||
src="/images/logo.png"
|
||||
alt="GNX Logo"
|
||||
width={80}
|
||||
height={60}
|
||||
className="logo-image"
|
||||
priority
|
||||
/>
|
||||
<div className="shine-effect"></div>
|
||||
{isLoading && (
|
||||
<div className="gnx-preloader-overlay">
|
||||
{/* Geometric background pattern */}
|
||||
<div className="gnx-preloader-bg-pattern"></div>
|
||||
|
||||
<div className="gnx-preloader-container">
|
||||
{/* Logo with professional wrapper */}
|
||||
<div className="gnx-preloader-logo">
|
||||
<div className="gnx-logo-wrapper">
|
||||
<div className="gnx-logo-border"></div>
|
||||
<Image
|
||||
src="/images/logo.png"
|
||||
alt="GNX Logo"
|
||||
width={100}
|
||||
height={75}
|
||||
className="gnx-logo-image"
|
||||
priority
|
||||
unoptimized
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Enterprise branding */}
|
||||
<div className="gnx-enterprise-brand">
|
||||
<h1 className="gnx-brand-title">GNX Enterprise</h1>
|
||||
<p className="gnx-brand-subtitle">Digital Transformation Solutions</p>
|
||||
</div>
|
||||
|
||||
{/* Professional progress indicator */}
|
||||
<div className="gnx-progress-container">
|
||||
<div className="gnx-progress-bar">
|
||||
<div
|
||||
className="gnx-progress-fill"
|
||||
style={{ width: `${progress}%` }}
|
||||
>
|
||||
<div className="gnx-progress-shine"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="gnx-progress-info">
|
||||
<span className="gnx-progress-text">Loading</span>
|
||||
<span className="gnx-progress-percentage">{Math.round(progress)}%</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Professional loading indicator */}
|
||||
<div className="gnx-loading-indicator">
|
||||
<div className="gnx-spinner">
|
||||
<div className="gnx-spinner-ring"></div>
|
||||
<div className="gnx-spinner-ring"></div>
|
||||
<div className="gnx-spinner-ring"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Corporate footer */}
|
||||
<div className="gnx-preloader-footer">
|
||||
<p className="gnx-footer-text">Powered by Advanced Technology</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Progress bar */}
|
||||
<div className="progress-container">
|
||||
<div className="progress-bar">
|
||||
<div
|
||||
className="progress-fill"
|
||||
style={{ width: `${progress}%` }}
|
||||
></div>
|
||||
</div>
|
||||
<div className="progress-text">{Math.round(progress)}%</div>
|
||||
</div>
|
||||
|
||||
{/* Loading text */}
|
||||
<div className="loading-text">
|
||||
<span className="loading-dots">
|
||||
<span>.</span>
|
||||
<span>.</span>
|
||||
<span>.</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Enterprise tagline */}
|
||||
<div className="enterprise-tagline">
|
||||
<span>Enterprise Solutions</span>
|
||||
<span>Excellence in Every Project</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<style jsx>{`
|
||||
.preloader-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(135deg, #0a0a0a 0%, #1a1a1a 50%, #0f0f0f 100%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 9999;
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.preloader-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 2rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.preloader-logo {
|
||||
position: relative;
|
||||
animation: logoFloat 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.logo-wrapper {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
padding: 1.5rem;
|
||||
border-radius: 50%;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
backdrop-filter: blur(20px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
overflow: hidden;
|
||||
transition: all 0.2s ease; /* Faster transitions */
|
||||
}
|
||||
|
||||
.logo-image {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
filter: brightness(1.1);
|
||||
transition: all 0.2s ease; /* Faster transitions */
|
||||
}
|
||||
|
||||
.shine-effect {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
transparent,
|
||||
rgba(255, 255, 255, 0.4),
|
||||
transparent
|
||||
);
|
||||
animation: shine 2s infinite;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.progress-container {
|
||||
width: 200px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
width: 100%;
|
||||
height: 3px;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 2px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.progress-fill {
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, #4f46e5, #7c3aed, #ec4899);
|
||||
border-radius: 2px;
|
||||
transition: width 0.2s ease; /* Faster progress bar animation */
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.progress-fill::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
transparent,
|
||||
rgba(255, 255, 255, 0.6),
|
||||
transparent
|
||||
);
|
||||
animation: progressShine 1.5s infinite;
|
||||
}
|
||||
|
||||
.progress-text {
|
||||
font-size: 0.875rem;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
.loading-text {
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
font-size: 0.875rem;
|
||||
font-weight: 400;
|
||||
letter-spacing: 0.1em;
|
||||
}
|
||||
|
||||
.loading-dots {
|
||||
display: inline-flex;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.loading-dots span {
|
||||
animation: dotPulse 1.4s infinite ease-in-out;
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
|
||||
.loading-dots span:nth-child(1) {
|
||||
animation-delay: -0.32s;
|
||||
}
|
||||
|
||||
.loading-dots span:nth-child(2) {
|
||||
animation-delay: -0.16s;
|
||||
}
|
||||
|
||||
.loading-dots span:nth-child(3) {
|
||||
animation-delay: 0s;
|
||||
}
|
||||
|
||||
.enterprise-tagline {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.25rem;
|
||||
margin-top: 1rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.enterprise-tagline span {
|
||||
font-size: 0.75rem;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
font-weight: 300;
|
||||
letter-spacing: 0.15em;
|
||||
text-transform: uppercase;
|
||||
animation: fadeInUp 0.8s ease-out 0.5s both;
|
||||
}
|
||||
|
||||
.enterprise-tagline span:first-child {
|
||||
animation-delay: 0.7s;
|
||||
}
|
||||
|
||||
.enterprise-tagline span:last-child {
|
||||
animation-delay: 0.9s;
|
||||
}
|
||||
|
||||
@keyframes logoFloat {
|
||||
0%, 100% {
|
||||
transform: translateY(0px);
|
||||
}
|
||||
50% {
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes shine {
|
||||
0% {
|
||||
left: -100%;
|
||||
}
|
||||
100% {
|
||||
left: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes progressShine {
|
||||
0% {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
100% {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes dotPulse {
|
||||
0%, 80%, 100% {
|
||||
opacity: 0.3;
|
||||
transform: scale(0.8);
|
||||
}
|
||||
40% {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Responsive adjustments */
|
||||
@media (max-width: 768px) {
|
||||
.preloader-container {
|
||||
gap: 1.5rem;
|
||||
}
|
||||
|
||||
.logo-wrapper {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.logo-image {
|
||||
width: 60px;
|
||||
height: 45px;
|
||||
}
|
||||
|
||||
.progress-container {
|
||||
width: 150px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.preloader-container {
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.logo-wrapper {
|
||||
padding: 0.75rem;
|
||||
}
|
||||
|
||||
.logo-image {
|
||||
width: 50px;
|
||||
height: 37px;
|
||||
}
|
||||
|
||||
.progress-container {
|
||||
width: 120px;
|
||||
}
|
||||
}
|
||||
`}</style>
|
||||
<div className={isLoading ? "gnx-content-hidden" : "gnx-content-visible"}>
|
||||
{children}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,106 +0,0 @@
|
||||
# Preloader Component Documentation
|
||||
|
||||
## Overview
|
||||
The Preloader component provides a sophisticated, enterprise-grade loading experience for the GNX React application. It features a compact design with the company logo, shine effects, and smooth animations that activate during page transitions.
|
||||
|
||||
## Features
|
||||
|
||||
### 🎨 Enterprise Design
|
||||
- **Compact Layout**: Minimal, professional design that doesn't overwhelm users
|
||||
- **Company Logo**: Features the GNX logo with floating animation
|
||||
- **Shine Effect**: Animated shine effect that sweeps across the logo periodically
|
||||
- **Dark Theme**: Professional dark gradient background with subtle transparency
|
||||
|
||||
### ⚡ Smart Loading Logic
|
||||
- **Initial Load**: Shows for 1.5 seconds on first page load
|
||||
- **Page Transitions**: Activates automatically when navigating between pages
|
||||
- **Progress Bar**: Realistic loading progress with gradient colors
|
||||
- **Smooth Transitions**: Fade-in/out animations for seamless user experience
|
||||
|
||||
### 📱 Responsive Design
|
||||
- **Mobile Optimized**: Scales appropriately on all device sizes
|
||||
- **Touch Friendly**: Optimized for mobile interactions
|
||||
- **Performance**: Lightweight animations that don't impact performance
|
||||
|
||||
## Components
|
||||
|
||||
### 1. Preloader.tsx
|
||||
Main preloader component that handles the loading UI and animations.
|
||||
|
||||
**Key Features:**
|
||||
- Logo with shine effect animation
|
||||
- Progress bar with gradient fill
|
||||
- Loading dots animation
|
||||
- Enterprise tagline
|
||||
- Responsive design
|
||||
|
||||
### 2. LayoutWrapper.tsx
|
||||
Wrapper component that integrates the preloader with the main layout.
|
||||
|
||||
### 3. usePageTransition.ts
|
||||
Custom hook that manages page transition states and progress.
|
||||
|
||||
**Hook Methods:**
|
||||
- `isTransitioning`: Boolean indicating if a transition is active
|
||||
- `progress`: Current loading progress (0-100)
|
||||
- `startTransition()`: Initiates a new page transition
|
||||
- `updateProgress()`: Updates the loading progress
|
||||
- `completeTransition()`: Marks transition as complete
|
||||
|
||||
## Usage
|
||||
|
||||
The preloader is automatically integrated into the main layout and requires no additional setup. It will:
|
||||
|
||||
1. **Show on initial page load** for 1.5 seconds
|
||||
2. **Activate on page navigation** with realistic loading simulation
|
||||
3. **Display progress** with animated progress bar
|
||||
4. **Hide smoothly** when loading is complete
|
||||
|
||||
## Customization
|
||||
|
||||
### Logo
|
||||
To change the logo, update the image path in the Preloader component:
|
||||
```tsx
|
||||
<Image
|
||||
src="/images/logo.png" // Update this path
|
||||
alt="GNX Logo"
|
||||
width={80}
|
||||
height={60}
|
||||
className="logo-image"
|
||||
priority
|
||||
/>
|
||||
```
|
||||
|
||||
### Colors
|
||||
The preloader uses CSS custom properties that can be customized:
|
||||
- Background gradient colors
|
||||
- Progress bar gradient
|
||||
- Text colors and opacity
|
||||
|
||||
### Timing
|
||||
Adjust timing in the usePageTransition hook:
|
||||
- Initial load duration: 1500ms
|
||||
- Transition duration: 600-1000ms (randomized)
|
||||
- Progress update interval: 100ms
|
||||
|
||||
## Performance Considerations
|
||||
|
||||
- **Optimized Animations**: Uses CSS transforms and opacity for smooth performance
|
||||
- **Minimal DOM**: Lightweight component structure
|
||||
- **Smart Loading**: Only shows when necessary (transitions)
|
||||
- **Memory Efficient**: Proper cleanup of timers and intervals
|
||||
|
||||
## Browser Support
|
||||
|
||||
- **Modern Browsers**: Full support for Chrome, Firefox, Safari, Edge
|
||||
- **Mobile Browsers**: Optimized for iOS Safari and Chrome Mobile
|
||||
- **Fallbacks**: Graceful degradation for older browsers
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
Potential improvements for future versions:
|
||||
- Custom loading messages per page
|
||||
- Brand-specific color themes
|
||||
- Loading state indicators for API calls
|
||||
- Accessibility improvements (reduced motion support)
|
||||
- Analytics integration for loading performance
|
||||
40
gnx-react/components/shared/layout/ScrollToTop.tsx
Normal file
40
gnx-react/components/shared/layout/ScrollToTop.tsx
Normal file
@@ -0,0 +1,40 @@
|
||||
"use client";
|
||||
import { useEffect } from "react";
|
||||
import { usePathname } from "next/navigation";
|
||||
|
||||
const ScrollToTop = () => {
|
||||
const pathname = usePathname();
|
||||
|
||||
useEffect(() => {
|
||||
// Aggressive scroll to top - run immediately and synchronously
|
||||
const scrollToTop = () => {
|
||||
window.scrollTo({ top: 0, left: 0, behavior: 'auto' });
|
||||
window.scrollTo(0, 0);
|
||||
document.documentElement.scrollTop = 0;
|
||||
document.body.scrollTop = 0;
|
||||
};
|
||||
|
||||
// 1. Immediate execution
|
||||
scrollToTop();
|
||||
|
||||
// 2. After microtask
|
||||
Promise.resolve().then(scrollToTop);
|
||||
|
||||
// 3. After next frame
|
||||
requestAnimationFrame(scrollToTop);
|
||||
|
||||
// 4. Multiple delayed attempts to override any smooth scroll libraries
|
||||
const timeouts = [0, 10, 50, 100, 150, 200].map(delay =>
|
||||
setTimeout(scrollToTop, delay)
|
||||
);
|
||||
|
||||
return () => {
|
||||
timeouts.forEach(clearTimeout);
|
||||
};
|
||||
}, [pathname]);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
export default ScrollToTop;
|
||||
|
||||
@@ -1,19 +1,106 @@
|
||||
"use client";
|
||||
import { useEffect } from "react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { gsap } from "gsap";
|
||||
import { ScrollTrigger } from "gsap/dist/ScrollTrigger";
|
||||
import Lenis from "lenis";
|
||||
import { usePathname } from "next/navigation";
|
||||
|
||||
const SmoothScroll = () => {
|
||||
const lenisRef = useRef<Lenis | null>(null);
|
||||
const pathname = usePathname();
|
||||
const [isNavigating, setIsNavigating] = useState(false);
|
||||
|
||||
// Handle pathname changes - PRIORITY 1
|
||||
useEffect(() => {
|
||||
setIsNavigating(true);
|
||||
|
||||
// Stop Lenis completely
|
||||
if (lenisRef.current) {
|
||||
lenisRef.current.stop();
|
||||
lenisRef.current.scrollTo(0, { immediate: true, force: true, lock: true });
|
||||
}
|
||||
|
||||
// Force scroll to top with all methods
|
||||
window.scrollTo({ top: 0, left: 0, behavior: 'auto' });
|
||||
window.scrollTo(0, 0);
|
||||
document.documentElement.scrollTop = 0;
|
||||
document.body.scrollTop = 0;
|
||||
|
||||
// Keep forcing scroll for a brief period
|
||||
const forceScroll = () => {
|
||||
window.scrollTo(0, 0);
|
||||
document.documentElement.scrollTop = 0;
|
||||
document.body.scrollTop = 0;
|
||||
};
|
||||
|
||||
// Force scroll every 16ms (one frame) for 200ms
|
||||
const intervalId = setInterval(forceScroll, 16);
|
||||
|
||||
// After navigation is settled, restart Lenis
|
||||
const restartTimeout = setTimeout(() => {
|
||||
clearInterval(intervalId);
|
||||
|
||||
if (lenisRef.current) {
|
||||
lenisRef.current.scrollTo(0, { immediate: true, force: true });
|
||||
lenisRef.current.start();
|
||||
}
|
||||
|
||||
setIsNavigating(false);
|
||||
|
||||
// Final scroll enforcement
|
||||
window.scrollTo(0, 0);
|
||||
document.documentElement.scrollTop = 0;
|
||||
document.body.scrollTop = 0;
|
||||
}, 200);
|
||||
|
||||
return () => {
|
||||
clearInterval(intervalId);
|
||||
clearTimeout(restartTimeout);
|
||||
};
|
||||
}, [pathname]);
|
||||
|
||||
// Initialize Lenis - PRIORITY 2
|
||||
useEffect(() => {
|
||||
gsap.registerPlugin(ScrollTrigger);
|
||||
const lenis = new Lenis();
|
||||
gsap.ticker.add((time) => {
|
||||
lenis.raf(time * 350);
|
||||
|
||||
const lenis = new Lenis({
|
||||
duration: 1.2,
|
||||
easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)),
|
||||
orientation: 'vertical',
|
||||
gestureOrientation: 'vertical',
|
||||
smoothWheel: true,
|
||||
wheelMultiplier: 1,
|
||||
smoothTouch: false,
|
||||
touchMultiplier: 2,
|
||||
infinite: false,
|
||||
});
|
||||
|
||||
lenisRef.current = lenis;
|
||||
|
||||
// Force initial scroll to top
|
||||
lenis.scrollTo(0, { immediate: true, force: true });
|
||||
window.scrollTo(0, 0);
|
||||
|
||||
// Connect to GSAP ticker
|
||||
const tickerCallback = (time: number) => {
|
||||
if (!isNavigating) {
|
||||
lenis.raf(time * 350);
|
||||
}
|
||||
};
|
||||
|
||||
gsap.ticker.add(tickerCallback);
|
||||
gsap.ticker.lagSmoothing(0);
|
||||
ScrollTrigger.update();
|
||||
|
||||
// Sync with ScrollTrigger
|
||||
lenis.on('scroll', ScrollTrigger.update);
|
||||
|
||||
return () => {
|
||||
lenis.destroy();
|
||||
gsap.ticker.remove(tickerCallback);
|
||||
lenisRef.current = null;
|
||||
};
|
||||
}, []);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
|
||||
@@ -4,9 +4,13 @@ import Image from "next/legacy/image";
|
||||
import location from "@/public/images/footer/location.png";
|
||||
import phone from "@/public/images/footer/phone.png";
|
||||
import gmail from "@/public/images/footer/gmail.png";
|
||||
import { useNavigationServices } from "@/lib/hooks/useServices";
|
||||
import { useJobs } from "@/lib/hooks/useCareer";
|
||||
|
||||
const Footer = () => {
|
||||
const currentYear = new Date().getFullYear();
|
||||
const { services: dynamicServices, loading: servicesLoading } = useNavigationServices();
|
||||
const { jobs, loading: jobsLoading } = useJobs();
|
||||
|
||||
// Static header data
|
||||
const headerData = {
|
||||
@@ -96,36 +100,54 @@ const Footer = () => {
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-12 col-lg-2 col-md-6">
|
||||
<div className="footer-section">
|
||||
<h6 className="text-white fm fw-6 mb-24">Solutions</h6>
|
||||
<ul className="footer-links">
|
||||
<li><Link href="services">Incident Management Software</Link></li>
|
||||
<li><Link href="services">Custom Software Development</Link></li>
|
||||
<li><Link href="services">System Integrations & APIs</Link></li>
|
||||
<li><Link href="services">Data Replication</Link></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-12 col-lg-2 col-md-6">
|
||||
<div className="footer-section">
|
||||
<h6 className="text-white fm fw-6 mb-24">Resources</h6>
|
||||
<ul className="footer-links">
|
||||
<li><Link href="/insights">Software Insights</Link></li>
|
||||
<li><Link href="case-study">Development Resources</Link></li>
|
||||
<li><Link href="services">API Documentation</Link></li>
|
||||
<li><Link href="contact-us">Technical Support</Link></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-12 col-lg-2 col-md-6">
|
||||
<div className="footer-section">
|
||||
<h6 className="text-white fm fw-6 mb-24">Services</h6>
|
||||
<ul className="footer-links">
|
||||
<li><Link href="services">Software Consulting</Link></li>
|
||||
<li><Link href="contact-us">Custom Development</Link></li>
|
||||
<li><Link href="case-study">API & Integration Services</Link></li>
|
||||
<li><Link href="contact-us">Data Solutions</Link></li>
|
||||
{servicesLoading ? (
|
||||
<>
|
||||
<li><Link href="/services">Our Services</Link></li>
|
||||
</>
|
||||
) : (
|
||||
dynamicServices.slice(0, 6).map((service) => (
|
||||
<li key={service.slug}>
|
||||
<Link href={`/services/${service.slug}`}>
|
||||
{service.title}
|
||||
</Link>
|
||||
</li>
|
||||
))
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-12 col-lg-2 col-md-6">
|
||||
<div className="footer-section">
|
||||
<h6 className="text-white fm fw-6 mb-24">Latest Jobs</h6>
|
||||
<ul className="footer-links">
|
||||
{jobsLoading ? (
|
||||
<>
|
||||
<li><Link href="/career">View All Jobs</Link></li>
|
||||
</>
|
||||
) : (
|
||||
jobs.slice(0, 4).map((job) => (
|
||||
<li key={job.slug}>
|
||||
<Link href={`/career/${job.slug}`}>
|
||||
{job.title}
|
||||
</Link>
|
||||
</li>
|
||||
))
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-12 col-lg-2 col-md-6">
|
||||
<div className="footer-section">
|
||||
<h6 className="text-white fm fw-6 mb-24">Support</h6>
|
||||
<ul className="footer-links">
|
||||
<li><Link href="/support-center">Support Center</Link></li>
|
||||
<li><Link href="/policy?type=privacy">Privacy Policy</Link></li>
|
||||
<li><Link href="/policy?type=terms">Terms of Use</Link></li>
|
||||
<li><Link href="/policy?type=support">Support Policy</Link></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 2.0 MiB After Width: | Height: | Size: 120 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.0 MiB After Width: | Height: | Size: 120 KiB |
@@ -1231,7 +1231,7 @@
|
||||
.word {
|
||||
.char {
|
||||
&:nth-of-type(1) {
|
||||
text-transform: uppercase !important;
|
||||
text-transform: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ html {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-rendering: optimizeLegibility;
|
||||
scroll-behavior: smooth;
|
||||
scroll-behavior: auto;
|
||||
}
|
||||
|
||||
body {
|
||||
@@ -480,7 +480,7 @@ a {
|
||||
.btn {
|
||||
border-radius: 8px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: 0.5px;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
@@ -662,7 +662,7 @@ a {
|
||||
border-radius: 6px;
|
||||
font-weight: 600;
|
||||
font-size: 12px;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: 0.5px;
|
||||
padding: 8px 16px;
|
||||
transition: all 0.3s ease;
|
||||
@@ -708,7 +708,7 @@ a {
|
||||
.btn {
|
||||
border-radius: 8px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: 0.5px;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ body {
|
||||
overflow-x: clip;
|
||||
max-width: 100vw;
|
||||
min-height: 100vh;
|
||||
text-transform: capitalize;
|
||||
text-transform: none;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 5px;
|
||||
@@ -179,7 +179,7 @@ h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-family: var(--mont);
|
||||
text-transform: capitalize;
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
.odometer {
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
.metric-label {
|
||||
font-size: 0.75rem;
|
||||
color: #64748b;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: 0.05em;
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
color: var(--secondary-600);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
text-transform: capitalize;
|
||||
text-transform: none;
|
||||
z-index: 1;
|
||||
letter-spacing: 0.5px;
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
.btn-line {
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.05em;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
font-size: 12px !important;
|
||||
padding: 8px 16px;
|
||||
border-radius: 4px;
|
||||
|
||||
@@ -153,7 +153,7 @@
|
||||
margin-bottom: 0.75rem;
|
||||
font-size: 0.75rem;
|
||||
color: var(--white);
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: 0.05em;
|
||||
|
||||
i {
|
||||
@@ -349,7 +349,7 @@
|
||||
margin-bottom: 1rem;
|
||||
backdrop-filter: blur(10px);
|
||||
transition: all 0.3s ease;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: 0.05em;
|
||||
|
||||
&:hover {
|
||||
@@ -453,7 +453,7 @@
|
||||
.metric-label {
|
||||
font-size: 0.75rem;
|
||||
color: var(--white) !important;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
}
|
||||
@@ -556,7 +556,7 @@
|
||||
backdrop-filter: blur(10px);
|
||||
transition: all 0.3s ease;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: 0.03em;
|
||||
|
||||
&:hover {
|
||||
|
||||
@@ -277,7 +277,7 @@
|
||||
.stat-label {
|
||||
font-size: 0.875rem;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
}
|
||||
@@ -473,7 +473,7 @@
|
||||
.card-title {
|
||||
font-size: 0.75rem;
|
||||
color: #64748b;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: 0.05em;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
@@ -638,7 +638,7 @@
|
||||
border-radius: 50px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: 1.2px;
|
||||
backdrop-filter: blur(10px);
|
||||
|
||||
@@ -810,7 +810,7 @@
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: 1.2px;
|
||||
}
|
||||
}
|
||||
@@ -842,7 +842,7 @@
|
||||
.scroll-text {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
@@ -1175,7 +1175,7 @@
|
||||
top: 40%;
|
||||
right: 100px;
|
||||
writing-mode: vertical-rl;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
line-height: 0px;
|
||||
flex-direction: row-reverse;
|
||||
color: white;
|
||||
@@ -1366,7 +1366,7 @@
|
||||
top: 40%;
|
||||
right: 100px;
|
||||
writing-mode: vertical-rl;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
line-height: 0px;
|
||||
flex-direction: row-reverse;
|
||||
color: white;
|
||||
@@ -1499,7 +1499,7 @@
|
||||
top: 40%;
|
||||
right: 100px;
|
||||
writing-mode: vertical-rl;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
line-height: 0px;
|
||||
flex-direction: row-reverse;
|
||||
color: white;
|
||||
|
||||
@@ -17,18 +17,6 @@
|
||||
margin-bottom: 40px;
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 100px;
|
||||
height: 2px;
|
||||
background: linear-gradient(90deg, #4a9eff, #00d4ff);
|
||||
border-radius: 1px;
|
||||
}
|
||||
|
||||
.enterprise-logo-container {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
@@ -188,7 +176,7 @@
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
letter-spacing: 0.5px;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
margin-bottom: 20px;
|
||||
position: relative;
|
||||
&::after {
|
||||
@@ -219,7 +207,7 @@
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
letter-spacing: 0.5px;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
margin-bottom: 24px;
|
||||
position: relative;
|
||||
&::after {
|
||||
@@ -388,7 +376,7 @@
|
||||
border-radius: 25px;
|
||||
font-size: 12px;
|
||||
letter-spacing: 0.3px;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
transition: all 0.3s ease;
|
||||
width: auto;
|
||||
height: auto;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||||
|
||||
.primary-navbar {
|
||||
padding: 20px 0px;
|
||||
padding: 15px 0px;
|
||||
transition: all 0.3s ease;
|
||||
height: 80px;
|
||||
display: flex;
|
||||
@@ -270,7 +270,7 @@
|
||||
padding: 12px 24px;
|
||||
border-radius: 6px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: 0.5px;
|
||||
font-size: 13px;
|
||||
transition: all 0.3s ease;
|
||||
@@ -291,8 +291,12 @@
|
||||
}
|
||||
|
||||
.logo-img {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
max-height: 150px;
|
||||
max-height: 90px;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
@@ -405,7 +409,7 @@
|
||||
font-size: 5.5vw;
|
||||
line-height: 1.1;
|
||||
font-weight: 800;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
max-width: 35vw;
|
||||
z-index: 2;
|
||||
color: white;
|
||||
@@ -474,7 +478,7 @@
|
||||
line-height: 1.2;
|
||||
font-size: 16px;
|
||||
width: 100%;
|
||||
text-transform: capitalize;
|
||||
text-transform: none;
|
||||
font-size: 28px;
|
||||
font-weight: 600;
|
||||
justify-content: flex-end;
|
||||
@@ -994,7 +998,8 @@
|
||||
@media (max-width: 767.98px) {
|
||||
.tp-header {
|
||||
.logo-img img {
|
||||
max-height: 120px;
|
||||
max-height: 68px !important;
|
||||
height: 68px !important;
|
||||
}
|
||||
|
||||
.primary-navbar {
|
||||
@@ -1114,7 +1119,8 @@
|
||||
@media (max-width: 575.98px) {
|
||||
.tp-header {
|
||||
.logo-img img {
|
||||
max-height: 90px;
|
||||
max-height: 58px !important;
|
||||
height: 58px !important;
|
||||
}
|
||||
|
||||
.primary-navbar {
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
border-radius: 50px;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: 0.05em;
|
||||
margin-bottom: 1.5rem;
|
||||
font-family: var(--font-family-sans);
|
||||
@@ -160,7 +160,7 @@
|
||||
font-size: 0.875rem;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
margin: 0;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
}
|
||||
@@ -275,7 +275,7 @@
|
||||
border-radius: 50px;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: 0.05em;
|
||||
margin-bottom: 1.5rem;
|
||||
font-family: var(--font-family-sans);
|
||||
@@ -493,7 +493,7 @@
|
||||
border-radius: 50px;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: 0.05em;
|
||||
margin-bottom: 1.5rem;
|
||||
font-family: var(--font-family-sans);
|
||||
@@ -578,7 +578,7 @@
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
font-size: 1rem;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: 0.05em;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
border-radius: 20px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: 0.5px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -138,7 +138,7 @@
|
||||
.author-label {
|
||||
font-size: 12px;
|
||||
color: #6c757d;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: 0.5px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
@@ -608,7 +608,7 @@
|
||||
.bio-label {
|
||||
font-size: 13px;
|
||||
color: #6c757d;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: 0.5px;
|
||||
margin-bottom: 8px;
|
||||
font-weight: 600;
|
||||
|
||||
@@ -508,7 +508,7 @@
|
||||
margin-bottom: 0.625rem;
|
||||
font-size: 0.975rem;
|
||||
letter-spacing: 0.2px;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
font-size: 0.85rem;
|
||||
|
||||
.required {
|
||||
@@ -582,7 +582,7 @@
|
||||
font-size: 1.05rem;
|
||||
font-weight: 600;
|
||||
border-radius: 10px;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: 0.5px;
|
||||
box-shadow: 0 4px 12px rgba(218, 165, 32, 0.3);
|
||||
transition: all 0.3s ease;
|
||||
@@ -754,7 +754,7 @@
|
||||
color: #ffffff;
|
||||
font-weight: 600;
|
||||
font-size: 0.95rem;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
p {
|
||||
&:nth-last-of-type(1) {
|
||||
color: #ffffff80;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1801,7 +1801,7 @@
|
||||
|
||||
.price-period {
|
||||
font-size: 16px;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
}
|
||||
@@ -1837,7 +1837,7 @@
|
||||
|
||||
.stat-label {
|
||||
font-size: 14px;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
}
|
||||
@@ -2063,7 +2063,7 @@
|
||||
border-radius: 25px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
}
|
||||
@@ -2122,7 +2122,7 @@
|
||||
border-radius: 25px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: 1px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
@@ -2313,7 +2313,7 @@
|
||||
|
||||
.price-period {
|
||||
font-size: 16px;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: 1px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
@@ -633,7 +633,7 @@
|
||||
border-radius: 50px;
|
||||
font-size: var(--text-sm);
|
||||
font-weight: var(--font-weight-medium);
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: 1px;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
@@ -728,7 +728,7 @@
|
||||
.highlight-label {
|
||||
font-size: var(--text-sm);
|
||||
opacity: 0.8;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
@@ -854,7 +854,7 @@
|
||||
border-radius: 20px;
|
||||
font-size: var(--text-sm);
|
||||
font-weight: var(--font-weight-medium);
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: 1px;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
@@ -918,7 +918,7 @@
|
||||
.stat-label {
|
||||
font-size: var(--text-sm);
|
||||
color: var(--secondary-500);
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
}
|
||||
@@ -961,7 +961,7 @@
|
||||
.meta-label {
|
||||
font-size: var(--text-sm);
|
||||
color: var(--secondary-500);
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
@@ -1098,7 +1098,7 @@
|
||||
font-size: 0.875rem;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.05em;
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
margin-bottom: 1rem;
|
||||
box-shadow:
|
||||
0 4px 15px rgba(59, 130, 246, 0.3),
|
||||
@@ -1481,7 +1481,7 @@
|
||||
border-radius: 20px;
|
||||
font-size: var(--text-sm);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: 1px;
|
||||
box-shadow: 0 4px 15px rgba(212, 175, 55, 0.3);
|
||||
}
|
||||
@@ -1507,7 +1507,7 @@
|
||||
.price-period {
|
||||
font-size: var(--text-base);
|
||||
color: var(--secondary-500);
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
}
|
||||
@@ -1688,7 +1688,7 @@
|
||||
.price-label {
|
||||
font-size: var(--text-sm);
|
||||
color: var(--secondary-500);
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
@@ -1867,7 +1867,7 @@
|
||||
border-radius: 12px;
|
||||
font-size: var(--text-xs);
|
||||
font-weight: var(--font-weight-medium);
|
||||
text-transform: uppercase;
|
||||
text-transform: none;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,8 +254,8 @@
|
||||
.text-justify { text-align: justify !important; }
|
||||
|
||||
.text-lowercase { text-transform: lowercase !important; }
|
||||
.text-uppercase { text-transform: uppercase !important; }
|
||||
.text-capitalize { text-transform: capitalize !important; }
|
||||
.text-uppercase { text-transform: none !important; }
|
||||
.text-capitalize { text-transform: none !important; }
|
||||
|
||||
.text-decoration-none { text-decoration: none !important; }
|
||||
.text-decoration-underline { text-decoration: underline !important; }
|
||||
|
||||
Reference in New Issue
Block a user