First commit
This commit is contained in:
706
app/globals.css
706
app/globals.css
@@ -1,26 +1,692 @@
|
||||
@import "tailwindcss";
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
:root {
|
||||
--background: #ffffff;
|
||||
--foreground: #171717;
|
||||
}
|
||||
|
||||
@theme inline {
|
||||
--color-background: var(--background);
|
||||
--color-foreground: var(--foreground);
|
||||
--font-sans: var(--font-geist-sans);
|
||||
--font-mono: var(--font-geist-mono);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
@layer base {
|
||||
:root {
|
||||
--background: #0a0a0a;
|
||||
--foreground: #ededed;
|
||||
/* Light Mode - Smart-Admin Copilot Palette */
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 222 47% 11%;
|
||||
--card: 210 40% 98%;
|
||||
--card-foreground: 222 47% 11%;
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 222 47% 11%;
|
||||
--primary: 221 83% 53%;
|
||||
--primary-foreground: 0 0% 100%;
|
||||
--secondary: 168 76% 40%;
|
||||
--secondary-foreground: 0 0% 100%;
|
||||
--accent: 262 83% 58%;
|
||||
--accent-foreground: 0 0% 100%;
|
||||
--muted: 210 40% 96%;
|
||||
--muted-foreground: 215 16% 47%;
|
||||
--destructive: 0 84% 60%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
--border: 214 32% 91%;
|
||||
--input: 214 32% 91%;
|
||||
--ring: 221 83% 53%;
|
||||
--radius: 0.75rem;
|
||||
|
||||
/* Custom Colors */
|
||||
--success: 160 84% 39%;
|
||||
--warning: 38 92% 50%;
|
||||
--royal-blue: 221 83% 53%;
|
||||
--teal: 168 76% 40%;
|
||||
--violet: 262 83% 58%;
|
||||
--emerald: 160 84% 39%;
|
||||
--amber: 38 92% 50%;
|
||||
--deep-slate: 222 47% 11%;
|
||||
--medium-slate: 215 16% 47%;
|
||||
--light-slate: 214 32% 91%;
|
||||
--off-white: 210 40% 98%;
|
||||
}
|
||||
|
||||
.dark {
|
||||
/* Dark Mode - Smart-Admin Copilot Palette */
|
||||
--background: 222 47% 5%;
|
||||
--foreground: 210 40% 98%;
|
||||
--card: 217 33% 17%;
|
||||
--card-foreground: 210 40% 98%;
|
||||
--popover: 217 33% 17%;
|
||||
--popover-foreground: 210 40% 98%;
|
||||
--primary: 217 91% 60%;
|
||||
--primary-foreground: 0 0% 100%;
|
||||
--secondary: 189 94% 43%;
|
||||
--secondary-foreground: 0 0% 100%;
|
||||
--accent: 258 90% 66%;
|
||||
--accent-foreground: 0 0% 100%;
|
||||
--muted: 217 33% 17%;
|
||||
--muted-foreground: 215 20% 65%;
|
||||
--destructive: 0 62% 30%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
--border: 217 33% 25%;
|
||||
--input: 217 33% 25%;
|
||||
--ring: 217 91% 60%;
|
||||
|
||||
/* Custom Dark Colors */
|
||||
--success: 158 64% 52%;
|
||||
--warning: 48 96% 53%;
|
||||
--bright-blue: 217 91% 60%;
|
||||
--cyan: 189 94% 43%;
|
||||
--purple: 258 90% 76%;
|
||||
--green: 158 64% 52%;
|
||||
--dark-slate: 217 33% 17%;
|
||||
--almost-white: 210 40% 98%;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
background: var(--background);
|
||||
color: var(--foreground);
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
@layer base {
|
||||
* {
|
||||
@apply border-border;
|
||||
}
|
||||
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
body {
|
||||
@apply bg-background text-foreground antialiased;
|
||||
font-feature-settings:
|
||||
"rlig" 1,
|
||||
"calt" 1;
|
||||
}
|
||||
}
|
||||
|
||||
@layer utilities {
|
||||
/* Gradient Text */
|
||||
.gradient-text {
|
||||
@apply bg-clip-text text-transparent;
|
||||
background-image: linear-gradient(
|
||||
135deg,
|
||||
hsl(var(--primary)) 0%,
|
||||
hsl(var(--accent)) 50%,
|
||||
hsl(var(--secondary)) 100%
|
||||
);
|
||||
}
|
||||
|
||||
.gradient-text-hero-light {
|
||||
@apply bg-clip-text text-transparent;
|
||||
background-image: linear-gradient(
|
||||
135deg,
|
||||
#0f172a 0%,
|
||||
#1e40af 50%,
|
||||
#0f172a 100%
|
||||
);
|
||||
}
|
||||
|
||||
.gradient-text-hero-dark {
|
||||
@apply bg-clip-text text-transparent;
|
||||
background-image: linear-gradient(
|
||||
135deg,
|
||||
#f8fafc 0%,
|
||||
#93c5fd 50%,
|
||||
#f8fafc 100%
|
||||
);
|
||||
}
|
||||
|
||||
/* Glass Morphism */
|
||||
.glass {
|
||||
@apply backdrop-blur-xl;
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
border: 1px solid rgba(226, 232, 240, 0.5);
|
||||
}
|
||||
|
||||
.dark .glass {
|
||||
background: rgba(30, 41, 59, 0.7);
|
||||
border: 1px solid rgba(51, 65, 85, 0.5);
|
||||
}
|
||||
|
||||
.glass-strong {
|
||||
@apply backdrop-blur-2xl;
|
||||
background: rgba(255, 255, 255, 0.85);
|
||||
border: 1px solid rgba(226, 232, 240, 0.6);
|
||||
}
|
||||
|
||||
.dark .glass-strong {
|
||||
background: rgba(15, 23, 42, 0.85);
|
||||
border: 1px solid rgba(51, 65, 85, 0.6);
|
||||
}
|
||||
|
||||
/* Gradient Backgrounds */
|
||||
.gradient-bg-mesh {
|
||||
background:
|
||||
radial-gradient(
|
||||
ellipse at 20% 20%,
|
||||
rgba(59, 130, 246, 0.15) 0%,
|
||||
transparent 50%
|
||||
),
|
||||
radial-gradient(
|
||||
ellipse at 80% 80%,
|
||||
rgba(139, 92, 246, 0.15) 0%,
|
||||
transparent 50%
|
||||
),
|
||||
radial-gradient(
|
||||
ellipse at 50% 50%,
|
||||
rgba(20, 184, 166, 0.1) 0%,
|
||||
transparent 60%
|
||||
);
|
||||
}
|
||||
|
||||
.dark .gradient-bg-mesh {
|
||||
background:
|
||||
radial-gradient(
|
||||
ellipse at 20% 20%,
|
||||
rgba(59, 130, 246, 0.2) 0%,
|
||||
transparent 50%
|
||||
),
|
||||
radial-gradient(
|
||||
ellipse at 80% 80%,
|
||||
rgba(139, 92, 246, 0.2) 0%,
|
||||
transparent 50%
|
||||
),
|
||||
radial-gradient(
|
||||
ellipse at 50% 50%,
|
||||
rgba(6, 182, 212, 0.15) 0%,
|
||||
transparent 60%
|
||||
);
|
||||
}
|
||||
|
||||
/* Button Gradients */
|
||||
.btn-gradient {
|
||||
background: linear-gradient(135deg, #2563eb 0%, #7c3aed 100%);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.btn-gradient:hover {
|
||||
background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%);
|
||||
transform: scale(1.05);
|
||||
box-shadow: 0 0 40px rgba(59, 130, 246, 0.4);
|
||||
}
|
||||
|
||||
/* Glow Effects */
|
||||
.glow-blue {
|
||||
box-shadow: 0 0 40px rgba(59, 130, 246, 0.4);
|
||||
}
|
||||
|
||||
.glow-violet {
|
||||
box-shadow: 0 0 40px rgba(139, 92, 246, 0.4);
|
||||
}
|
||||
|
||||
.glow-teal {
|
||||
box-shadow: 0 0 40px rgba(20, 184, 166, 0.4);
|
||||
}
|
||||
|
||||
/* Card Gradients */
|
||||
.card-gradient-blue {
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
rgba(37, 99, 235, 0.1) 0%,
|
||||
rgba(139, 92, 246, 0.1) 100%
|
||||
);
|
||||
}
|
||||
|
||||
.card-gradient-teal {
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
rgba(20, 184, 166, 0.1) 0%,
|
||||
rgba(6, 182, 212, 0.1) 100%
|
||||
);
|
||||
}
|
||||
|
||||
.card-gradient-violet {
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
rgba(139, 92, 246, 0.1) 0%,
|
||||
rgba(168, 85, 247, 0.1) 100%
|
||||
);
|
||||
}
|
||||
|
||||
.card-gradient-amber {
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
rgba(245, 158, 11, 0.1) 0%,
|
||||
rgba(249, 115, 22, 0.1) 100%
|
||||
);
|
||||
}
|
||||
|
||||
.card-gradient-emerald {
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
rgba(16, 185, 129, 0.1) 0%,
|
||||
rgba(34, 197, 94, 0.1) 100%
|
||||
);
|
||||
}
|
||||
|
||||
/* Animated Border */
|
||||
.animated-border {
|
||||
position: relative;
|
||||
background:
|
||||
linear-gradient(var(--background), var(--background)) padding-box,
|
||||
linear-gradient(
|
||||
135deg,
|
||||
hsl(var(--primary)),
|
||||
hsl(var(--accent)),
|
||||
hsl(var(--secondary))
|
||||
)
|
||||
border-box;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
/* Noise Texture */
|
||||
.noise-texture {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.noise-texture::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E");
|
||||
opacity: 0.03;
|
||||
pointer-events: none;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* Grid Pattern */
|
||||
.grid-pattern {
|
||||
background-image:
|
||||
linear-gradient(rgba(148, 163, 184, 0.1) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(148, 163, 184, 0.1) 1px, transparent 1px);
|
||||
background-size: 40px 40px;
|
||||
}
|
||||
|
||||
.dark .grid-pattern {
|
||||
background-image:
|
||||
linear-gradient(rgba(71, 85, 105, 0.2) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(71, 85, 105, 0.2) 1px, transparent 1px);
|
||||
}
|
||||
|
||||
/* 3D Transform */
|
||||
.perspective-1000 {
|
||||
perspective: 1000px;
|
||||
}
|
||||
|
||||
.transform-3d {
|
||||
transform-style: preserve-3d;
|
||||
}
|
||||
|
||||
/* Hide scrollbar */
|
||||
.hide-scrollbar {
|
||||
-ms-overflow-style: none;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
||||
.hide-scrollbar::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Custom Animations */
|
||||
@keyframes float {
|
||||
0%,
|
||||
100% {
|
||||
transform: translateY(0px);
|
||||
}
|
||||
50% {
|
||||
transform: translateY(-20px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes float-slow {
|
||||
0%,
|
||||
100% {
|
||||
transform: translateY(0px) translateX(0px);
|
||||
}
|
||||
50% {
|
||||
transform: translateY(-15px) translateX(10px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes pulse-glow {
|
||||
0%,
|
||||
100% {
|
||||
box-shadow: 0 0 20px rgba(59, 130, 246, 0.3);
|
||||
}
|
||||
50% {
|
||||
box-shadow: 0 0 40px rgba(59, 130, 246, 0.6);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes gradient-shift {
|
||||
0% {
|
||||
background-position: 0% 50%;
|
||||
}
|
||||
50% {
|
||||
background-position: 100% 50%;
|
||||
}
|
||||
100% {
|
||||
background-position: 0% 50%;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes shimmer {
|
||||
0% {
|
||||
background-position: -200% 0;
|
||||
}
|
||||
100% {
|
||||
background-position: 200% 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes spin-slow {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes bounce-subtle {
|
||||
0%,
|
||||
100% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
50% {
|
||||
transform: translateY(-5px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slide-up {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(30px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slide-down {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-30px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fade-in {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes scale-in {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: scale(0.9);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes count-up {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes draw-line {
|
||||
from {
|
||||
stroke-dashoffset: 1000;
|
||||
}
|
||||
to {
|
||||
stroke-dashoffset: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes particle-float {
|
||||
0%,
|
||||
100% {
|
||||
transform: translateY(0) translateX(0);
|
||||
opacity: 0.5;
|
||||
}
|
||||
25% {
|
||||
transform: translateY(-30px) translateX(10px);
|
||||
opacity: 0.8;
|
||||
}
|
||||
50% {
|
||||
transform: translateY(-20px) translateX(-10px);
|
||||
opacity: 0.6;
|
||||
}
|
||||
75% {
|
||||
transform: translateY(-40px) translateX(5px);
|
||||
opacity: 0.9;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes ring {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
25% {
|
||||
transform: rotate(15deg);
|
||||
}
|
||||
50% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
75% {
|
||||
transform: rotate(-15deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
}
|
||||
|
||||
/* Animation Classes */
|
||||
.animate-float {
|
||||
animation: float 6s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.animate-float-slow {
|
||||
animation: float-slow 8s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.animate-float-delayed {
|
||||
animation: float 6s ease-in-out infinite;
|
||||
animation-delay: 2s;
|
||||
}
|
||||
|
||||
.animate-pulse-glow {
|
||||
animation: pulse-glow 3s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.animate-gradient-shift {
|
||||
background-size: 200% 200%;
|
||||
animation: gradient-shift 8s ease infinite;
|
||||
}
|
||||
|
||||
.animate-shimmer {
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
transparent,
|
||||
rgba(255, 255, 255, 0.2),
|
||||
transparent
|
||||
);
|
||||
background-size: 200% 100%;
|
||||
animation: shimmer 2s infinite;
|
||||
}
|
||||
|
||||
.animate-spin-slow {
|
||||
animation: spin-slow 20s linear infinite;
|
||||
}
|
||||
|
||||
.animate-bounce-subtle {
|
||||
animation: bounce-subtle 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.animate-slide-up {
|
||||
animation: slide-up 0.6s ease-out forwards;
|
||||
}
|
||||
|
||||
.animate-slide-down {
|
||||
animation: slide-down 0.6s ease-out forwards;
|
||||
}
|
||||
|
||||
.animate-fade-in {
|
||||
animation: fade-in 0.5s ease-out forwards;
|
||||
}
|
||||
|
||||
.animate-scale-in {
|
||||
animation: scale-in 0.5s ease-out forwards;
|
||||
}
|
||||
|
||||
.animate-particle-float {
|
||||
animation: particle-float 10s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.animate-ring {
|
||||
animation: ring 0.5s ease-in-out;
|
||||
}
|
||||
|
||||
/* Stagger Animation Delays */
|
||||
.stagger-1 {
|
||||
animation-delay: 0.1s;
|
||||
}
|
||||
.stagger-2 {
|
||||
animation-delay: 0.2s;
|
||||
}
|
||||
.stagger-3 {
|
||||
animation-delay: 0.3s;
|
||||
}
|
||||
.stagger-4 {
|
||||
animation-delay: 0.4s;
|
||||
}
|
||||
.stagger-5 {
|
||||
animation-delay: 0.5s;
|
||||
}
|
||||
.stagger-6 {
|
||||
animation-delay: 0.6s;
|
||||
}
|
||||
.stagger-7 {
|
||||
animation-delay: 0.7s;
|
||||
}
|
||||
.stagger-8 {
|
||||
animation-delay: 0.8s;
|
||||
}
|
||||
|
||||
/* Scroll Animation Classes */
|
||||
.scroll-animate {
|
||||
opacity: 0;
|
||||
transform: translateY(30px);
|
||||
transition:
|
||||
opacity 0.6s ease-out,
|
||||
transform 0.6s ease-out;
|
||||
}
|
||||
|
||||
.scroll-animate.visible {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.scroll-animate-left {
|
||||
opacity: 0;
|
||||
transform: translateX(-50px);
|
||||
transition:
|
||||
opacity 0.6s ease-out,
|
||||
transform 0.6s ease-out;
|
||||
}
|
||||
|
||||
.scroll-animate-left.visible {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
.scroll-animate-right {
|
||||
opacity: 0;
|
||||
transform: translateX(50px);
|
||||
transition:
|
||||
opacity 0.6s ease-out,
|
||||
transform 0.6s ease-out;
|
||||
}
|
||||
|
||||
.scroll-animate-right.visible {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
.scroll-animate-scale {
|
||||
opacity: 0;
|
||||
transform: scale(0.9);
|
||||
transition:
|
||||
opacity 0.6s ease-out,
|
||||
transform 0.6s ease-out;
|
||||
}
|
||||
|
||||
.scroll-animate-scale.visible {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
/* Hover Effects */
|
||||
.hover-lift {
|
||||
transition:
|
||||
transform 0.3s ease,
|
||||
box-shadow 0.3s ease;
|
||||
}
|
||||
|
||||
.hover-lift:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.dark .hover-lift:hover {
|
||||
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.hover-scale {
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.hover-scale:hover {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.hover-glow {
|
||||
transition: box-shadow 0.3s ease;
|
||||
}
|
||||
|
||||
.hover-glow:hover {
|
||||
box-shadow: 0 0 30px rgba(59, 130, 246, 0.4);
|
||||
}
|
||||
|
||||
/* Focus States */
|
||||
.focus-ring:focus-visible {
|
||||
outline: none;
|
||||
ring: 2px;
|
||||
ring-color: hsl(var(--ring));
|
||||
ring-offset: 2px;
|
||||
ring-offset-color: hsl(var(--background));
|
||||
}
|
||||
|
||||
/* Reduced Motion */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
animation-duration: 0.01ms !important;
|
||||
animation-iteration-count: 1 !important;
|
||||
transition-duration: 0.01ms !important;
|
||||
}
|
||||
|
||||
.scroll-animate,
|
||||
.scroll-animate-left,
|
||||
.scroll-animate-right,
|
||||
.scroll-animate-scale {
|
||||
opacity: 1;
|
||||
transform: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { Metadata } from "next";
|
||||
import { Geist, Geist_Mono } from "next/font/google";
|
||||
import "./globals.css";
|
||||
import { Providers } from "./provider";
|
||||
|
||||
const geistSans = Geist({
|
||||
variable: "--font-geist-sans",
|
||||
@@ -23,11 +24,11 @@ export default function RootLayout({
|
||||
children: React.ReactNode;
|
||||
}>) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<html lang="en" suppressHydrationWarning>
|
||||
<body
|
||||
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
|
||||
>
|
||||
{children}
|
||||
<Providers>{children}</Providers>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
|
||||
212
app/page.tsx
212
app/page.tsx
@@ -1,65 +1,159 @@
|
||||
import Image from "next/image";
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { Navbar } from "@/components/views/Home/Navbar";
|
||||
import { Hero } from "@/components/views/Home/Hero";
|
||||
import { Features } from "@/components/views/Home/Features";
|
||||
import { HowItWorks } from "@/components/views/Home/HowItWorks";
|
||||
import { Stats } from "@/components/views/Home/Stats";
|
||||
import { Footer } from "@/components/views/Home/Footer";
|
||||
import { Sparkles } from "lucide-react";
|
||||
|
||||
//Loading Screen
|
||||
function LoadingScreen({ onComplete }: { onComplete: () => void }) {
|
||||
const [progress, setProgress] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
setProgress((prev) => {
|
||||
if (prev >= 100) {
|
||||
clearInterval(interval);
|
||||
setTimeout(onComplete, 300);
|
||||
return 100;
|
||||
}
|
||||
return prev + Math.random() * 15;
|
||||
});
|
||||
}, 100);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, [onComplete]);
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<div className="flex min-h-screen items-center justify-center bg-zinc-50 font-sans dark:bg-black">
|
||||
<main className="flex min-h-screen w-full max-w-3xl flex-col items-center justify-between py-32 px-16 bg-white dark:bg-black sm:items-start">
|
||||
<Image
|
||||
className="dark:invert"
|
||||
src="/next.svg"
|
||||
alt="Next.js logo"
|
||||
width={100}
|
||||
height={20}
|
||||
priority
|
||||
<div className="fixed inset-0 z-[100] bg-slate-900 flex flex-col items-center justify-center">
|
||||
<div className="relative mb-8">
|
||||
<div className="absolute inset-0 bg-blue-500/30 blur-3xl rounded-full animate-pulse" />
|
||||
<Sparkles
|
||||
className="w-16 h-16 text-blue-500 relative z-10"
|
||||
style={{ animation: "spin-slow 3s linear infinite" }}
|
||||
/>
|
||||
<div className="flex flex-col items-center gap-6 text-center sm:items-start sm:text-left">
|
||||
<h1 className="max-w-xs text-3xl font-semibold leading-10 tracking-tight text-black dark:text-zinc-50">
|
||||
To get started, edit the page.tsx file.
|
||||
</h1>
|
||||
<p className="max-w-md text-lg leading-8 text-zinc-600 dark:text-zinc-400">
|
||||
Looking for a starting point or more instructions? Head over to{" "}
|
||||
<a
|
||||
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
||||
className="font-medium text-zinc-950 dark:text-zinc-50"
|
||||
>
|
||||
Templates
|
||||
</a>{" "}
|
||||
or the{" "}
|
||||
<a
|
||||
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
||||
className="font-medium text-zinc-950 dark:text-zinc-50"
|
||||
>
|
||||
Learning
|
||||
</a>{" "}
|
||||
center.
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex flex-col gap-4 text-base font-medium sm:flex-row">
|
||||
<a
|
||||
className="flex h-12 w-full items-center justify-center gap-2 rounded-full bg-foreground px-5 text-background transition-colors hover:bg-[#383838] dark:hover:bg-[#ccc] md:w-[158px]"
|
||||
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Image
|
||||
className="dark:invert"
|
||||
src="/vercel.svg"
|
||||
alt="Vercel logomark"
|
||||
width={16}
|
||||
height={16}
|
||||
/>
|
||||
Deploy Now
|
||||
</a>
|
||||
<a
|
||||
className="flex h-12 w-full items-center justify-center rounded-full border border-solid border-black/[.08] px-5 transition-colors hover:border-transparent hover:bg-black/[.04] dark:border-white/[.145] dark:hover:bg-[#1a1a1a] md:w-[158px]"
|
||||
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Documentation
|
||||
</a>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<h1 className="text-2xl font-bold gradient-text mb-8">
|
||||
Smart-Admin Copilot
|
||||
</h1>
|
||||
|
||||
<div className="w-64 h-1 bg-slate-800 rounded-full overflow-hidden">
|
||||
<div
|
||||
className="h-full bg-gradient-to-r from-blue-500 via-violet-500 to-teal-500 rounded-full transition-all duration-200"
|
||||
style={{ width: `${Math.min(progress, 100)}%` }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<p className="mt-4 text-sm text-slate-500">
|
||||
Loading amazing experience...
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
//Scroll Progress
|
||||
function ScrollProgressBar() {
|
||||
const [progress, setProgress] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
const handleScroll = () => {
|
||||
const scrollTop = window.scrollY;
|
||||
const docHeight =
|
||||
document.documentElement.scrollHeight - window.innerHeight;
|
||||
const scrollPercent = (scrollTop / docHeight) * 100;
|
||||
setProgress(scrollPercent);
|
||||
};
|
||||
|
||||
window.addEventListener("scroll", handleScroll, { passive: true });
|
||||
return () => window.removeEventListener("scroll", handleScroll);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="fixed top-0 left-0 right-0 z-[60] h-1 bg-transparent">
|
||||
<div
|
||||
className="h-full bg-gradient-to-r from-blue-500 via-violet-500 to-teal-500 transition-all duration-100"
|
||||
style={{ width: `${progress}%` }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
//Back To Top
|
||||
function BackToTop() {
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const handleScroll = () => {
|
||||
setIsVisible(window.scrollY > 500);
|
||||
};
|
||||
|
||||
window.addEventListener("scroll", handleScroll, { passive: true });
|
||||
return () => window.removeEventListener("scroll", handleScroll);
|
||||
}, []);
|
||||
|
||||
const scrollToTop = () => {
|
||||
window.scrollTo({ top: 0, behavior: "smooth" });
|
||||
};
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={scrollToTop}
|
||||
className={`fixed bottom-8 right-8 z-50 w-12 h-12 rounded-full bg-gradient-to-r from-blue-600 to-violet-600 text-white shadow-lg hover:shadow-xl hover:scale-110 transition-all duration-300 flex items-center justify-center ${
|
||||
isVisible
|
||||
? "opacity-100 translate-y-0"
|
||||
: "opacity-0 translate-y-10 pointer-events-none"
|
||||
}`}
|
||||
aria-label="Back to top"
|
||||
>
|
||||
<svg
|
||||
className="w-6 h-6"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M5 10l7-7m0 0l7 7m-7-7v18"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
//Main Page
|
||||
export default function Home() {
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
const handleLoadingComplete = () => {
|
||||
setIsLoading(false);
|
||||
};
|
||||
|
||||
if (isLoading) {
|
||||
return <LoadingScreen onComplete={handleLoadingComplete} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="relative min-h-screen bg-background text-foreground overflow-x-hidden">
|
||||
<ScrollProgressBar />
|
||||
|
||||
<Navbar />
|
||||
|
||||
<main className="relative">
|
||||
<Hero />
|
||||
<Features />
|
||||
<HowItWorks />
|
||||
<Stats />
|
||||
<Footer />
|
||||
</main>
|
||||
|
||||
<BackToTop />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
11
app/provider.tsx
Normal file
11
app/provider.tsx
Normal file
@@ -0,0 +1,11 @@
|
||||
"use client";
|
||||
import { ThemeProvider } from "next-themes";
|
||||
import { ReactNode } from "react";
|
||||
|
||||
export function Providers({ children }: { children: ReactNode }) {
|
||||
return (
|
||||
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
|
||||
{children}
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user