Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions fulllink-website/app/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&family=Cairo:wght@300;400;600;700;900&display=swap');

* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

html {
scroll-behavior: smooth;
}

body {
font-family: 'Inter', sans-serif;
background-color: #0A1628;
color: #ffffff;
overflow-x: hidden;
}

.arabic {
font-family: 'Cairo', sans-serif;
direction: rtl;
}

/* Custom scrollbar */
::-webkit-scrollbar {
width: 8px;
}

::-webkit-scrollbar-track {
background: #0A1628;
}

::-webkit-scrollbar-thumb {
background: #00D4FF;
border-radius: 4px;
}

::-webkit-scrollbar-thumb:hover {
background: #33ddff;
}

/* Glow effects */
.glow-text {
text-shadow: 0 0 10px rgba(0, 212, 255, 0.5),
0 0 20px rgba(0, 212, 255, 0.3),
0 0 30px rgba(0, 212, 255, 0.2);
}

.glow-box {
box-shadow: 0 0 20px rgba(0, 212, 255, 0.3),
0 0 40px rgba(0, 212, 255, 0.2),
inset 0 0 20px rgba(0, 212, 255, 0.1);
}

/* Glass morphism */
.glass {
background: rgba(255, 255, 255, 0.05);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.1);
}

/* Gradient text */
.gradient-text {
background: linear-gradient(135deg, #ffffff 0%, #00D4FF 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}

/* Neon border */
.neon-border {
border: 2px solid #00D4FF;
box-shadow: 0 0 10px rgba(0, 212, 255, 0.5),
inset 0 0 10px rgba(0, 212, 255, 0.2);
}

/* Smooth transitions */
.transition-smooth {
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
19 changes: 19 additions & 0 deletions fulllink-website/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import type { Metadata } from "next";
import "./globals.css";

export const metadata: Metadata = {
title: "Full Link - Connect Your World in One Link",
description: "Smart digital tool that combines all social media profiles, business links, and contact info into one customizable link.",
};

export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body>{children}</body>
</html>
);
}
101 changes: 101 additions & 0 deletions fulllink-website/components/ConnectionFlow.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
"use client";

import { useRef } from 'react';
import { useFrame } from '@react-three/fiber';
import * as THREE from 'three';

function FlowingLine({ start, end, color, delay }: { start: THREE.Vector3; end: THREE.Vector3; color: string; delay: number }) {
const lineRef = useRef<THREE.Line>(null);
const materialRef = useRef<THREE.LineBasicMaterial>(null);

useFrame((state) => {
if (materialRef.current) {
const opacity = (Math.sin(state.clock.getElapsedTime() * 2 + delay) + 1) / 2;
materialRef.current.opacity = opacity * 0.8;
}
});

const points = [];
const segments = 20;

for (let i = 0; i <= segments; i++) {
const t = i / segments;
const x = start.x + (end.x - start.x) * t;
const y = start.y + (end.y - start.y) * t + Math.sin(t * Math.PI) * 0.5;
const z = start.z + (end.z - start.z) * t;
points.push(new THREE.Vector3(x, y, z));
}

const geometry = new THREE.BufferGeometry().setFromPoints(points);

return (
<line ref={lineRef} geometry={geometry}>
<lineBasicMaterial
ref={materialRef}
color={color}
transparent
opacity={0.8}
linewidth={2}
/>
</line>
);
}

function Node({ position, color }: { position: [number, number, number]; color: string }) {
const meshRef = useRef<THREE.Mesh>(null);

useFrame((state) => {
if (meshRef.current) {
const scale = 1 + Math.sin(state.clock.getElapsedTime() * 3) * 0.2;
meshRef.current.scale.set(scale, scale, scale);
}
});

return (
<mesh ref={meshRef} position={position}>
<sphereGeometry args={[0.15, 16, 16]} />
<meshStandardMaterial
color={color}
emissive={color}
emissiveIntensity={1}
metalness={0.8}
roughness={0.2}
/>
<pointLight color={color} intensity={2} distance={2} />
</mesh>
);
}

export default function ConnectionFlow() {
const nodes = [
{ pos: [-3, 2, 0] as [number, number, number], color: '#E4405F' },
{ pos: [-2, -1, 0] as [number, number, number], color: '#25D366' },
{ pos: [0, 2.5, 0] as [number, number, number], color: '#0A66C2' },
{ pos: [2, -1, 0] as [number, number, number], color: '#FF0000' },
{ pos: [3, 1.5, 0] as [number, number, number], color: '#1DA1F2' },
{ pos: [0, 0, 0] as [number, number, number], color: '#00D4FF' },
];

return (
<>
<ambientLight intensity={0.5} />
<pointLight position={[0, 0, 5]} intensity={1} />

{/* Nodes */}
{nodes.map((node, index) => (
<Node key={index} position={node.pos} color={node.color} />
))}

{/* Connecting lines to center */}
{nodes.slice(0, -1).map((node, index) => (
<FlowingLine
key={index}
start={new THREE.Vector3(...node.pos)}
end={new THREE.Vector3(0, 0, 0)}
color={node.color}
delay={index * 0.5}
/>
))}
</>
);
}
129 changes: 129 additions & 0 deletions fulllink-website/components/FloatingCards.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
"use client";

import { motion } from 'framer-motion';
import { useState } from 'react';

interface CardProps {
title: string;
description: string;
icon: string;
delay: number;
}

function Card({ title, description, icon, delay }: CardProps) {
const [isHovered, setIsHovered] = useState(false);

return (
<motion.div
initial={{ opacity: 0, y: 50 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, delay }}
whileHover={{ scale: 1.05, rotateY: 5 }}
onHoverStart={() => setIsHovered(true)}
onHoverEnd={() => setIsHovered(false)}
className="glass rounded-2xl p-8 relative overflow-hidden group cursor-pointer"
>
{/* Glow effect on hover */}
<motion.div
animate={{
opacity: isHovered ? 0.3 : 0,
scale: isHovered ? 1 : 0.8,
}}
className="absolute inset-0 bg-gradient-radial from-electric/30 to-transparent"
/>

{/* Icon */}
<motion.div
animate={{ rotate: isHovered ? 360 : 0 }}
transition={{ duration: 0.6 }}
className="text-6xl mb-4"
>
{icon}
</motion.div>

{/* Content */}
<h3 className="text-2xl font-bold mb-3 gradient-text">{title}</h3>
<p className="text-gray-300 leading-relaxed">{description}</p>

{/* Animated border */}
<motion.div
animate={{
opacity: isHovered ? 1 : 0,
}}
className="absolute inset-0 rounded-2xl border-2 border-electric pointer-events-none"
/>
</motion.div>
);
}

export default function FloatingCards() {
const cards = [
{
title: "One Link",
description: "Combine all your social media, websites, and contact information into a single, powerful link.",
icon: "🔗",
},
{
title: "Customizable",
description: "Design your page to match your brand with custom themes, colors, and layouts.",
icon: "🎨",
},
{
title: "Analytics",
description: "Track clicks, views, and engagement with detailed analytics and insights.",
icon: "📊",
},
{
title: "Fast & Secure",
description: "Lightning-fast loading times with enterprise-grade security for your data.",
icon: "⚡",
},
{
title: "Mobile First",
description: "Optimized for mobile devices to ensure the best experience for your audience.",
icon: "📱",
},
{
title: "Easy Setup",
description: "Get started in minutes with our intuitive interface and simple setup process.",
icon: "✨",
},
];

return (
<section className="min-h-screen py-20 px-4 relative">
{/* Background gradient */}
<div className="absolute inset-0 bg-gradient-to-b from-navy via-navy-light to-navy opacity-50"></div>

<div className="max-w-7xl mx-auto relative z-10">
{/* Section header */}
<motion.div
initial={{ opacity: 0, y: 30 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8 }}
className="text-center mb-16"
>
<h2 className="text-5xl md:text-6xl font-bold mb-6 glow-text">
Why Choose Full Link?
</h2>
<p className="text-xl text-gray-300 max-w-2xl mx-auto">
Everything you need to create a powerful digital presence in one place
</p>
</motion.div>

{/* Cards grid */}
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8">
{cards.map((card, index) => (
<Card
key={index}
title={card.title}
description={card.description}
icon={card.icon}
delay={index * 0.1}
/>
))}
</div>
</div>
</section>
);
}
Loading