A stunning cyberpunk-themed website with an animated nine-tailed fox background built with Next.js, React, Tailwind CSS, and Framer Motion.
- Animated Kitsune Background - Canvas-based nine-tailed fox with glowing effects
- Cyberpunk Aesthetics - Neon colors, glassmorphism, and futuristic design
- Smooth Animations - Framer Motion powered interactions
- Fully Responsive - Mobile, tablet, and desktop optimized
- Production Ready - Clean code, SEO-friendly, optimized performance
- Node.js 18.x or higher
- npm or yarn or pnpm
git clone https://github.com/yourusername/kitsune-protocol.git
cd kitsune-protocolnpm install
# or
yarn install
# or
pnpm installnpm run dev
# or
yarn dev
# or
pnpm devOpen http://localhost:3000 in your browser.
kitsune-protocol/
├── app/
│ ├── layout.js
│ ├── page.js
│ └── globals.css
├── components/
│ ├── KitsuneBackground.jsx
│ ├── NoiseOverlay.jsx
│ ├── HeroSection.jsx
│ ├── AboutSection.jsx
│ ├── FeaturesSection.jsx
│ ├── AirdropSection.jsx
│ ├── CTASection.jsx
│ └── Footer.jsx
├── public/
├── package.json
├── tailwind.config.js
├── next.config.js
└── README.md
{
"name": "kitsune-protocol",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"react": "^19.0.0",
"react-dom": "^19.0.0",
"next": "^15.1.0",
"framer-motion": "^11.15.0",
"lucide-react": "^0.263.1"
},
"devDependencies": {
"tailwindcss": "^3.4.0",
"postcss": "^8.4.0",
"autoprefixer": "^10.4.0"
}
}/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
'./pages/**/*.{js,ts,jsx,tsx,mdx}',
'./components/**/*.{js,ts,jsx,tsx,mdx}',
'./app/**/*.{js,ts,jsx,tsx,mdx}',
],
theme: {
extend: {
colors: {
'cyber-purple': '#a855f7',
'cyber-cyan': '#06b6d4',
'cyber-pink': '#ec4899',
},
animation: {
'pulse-glow': 'pulse-glow 3s ease-in-out infinite',
'pulse-slow': 'pulse-slow 4s ease-in-out infinite',
},
keyframes: {
'pulse-glow': {
'0%, 100%': {
textShadow: '0 0 20px rgba(168, 85, 247, 0.5), 0 0 40px rgba(168, 85, 247, 0.3)',
},
'50%': {
textShadow: '0 0 30px rgba(168, 85, 247, 0.8), 0 0 60px rgba(168, 85, 247, 0.5)',
},
},
'pulse-slow': {
'0%, 100%': { opacity: '0.2' },
'50%': { opacity: '0.4' },
},
},
},
},
plugins: [],
}/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
}
module.exports = nextConfigmodule.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}import { Inter } from 'next/font/google'
import './globals.css'
const inter = Inter({ subsets: ['latin'] })
export const metadata = {
title: 'Kitsune Protocol | Next-Gen Web3 Infrastructure',
description: 'Enter the Neo-Tokyo metaverse. Claim your place in the next evolution of Web3 with Kitsune Protocol.',
keywords: 'Web3, Blockchain, Cyberpunk, Kitsune, Protocol, Crypto, DeFi',
}
export default function RootLayout({ children }) {
return (
<html lang="en">
<body className={inter.className}>{children}</body>
</html>
)
}@tailwind base;
@tailwind components;
@tailwind utilities;
* {
scrollbar-width: thin;
scrollbar-color: rgba(168, 85, 247, 0.5) rgba(0, 0, 0, 0.3);
}
*::-webkit-scrollbar {
width: 8px;
}
*::-webkit-scrollbar-track {
background: rgba(0, 0, 0, 0.3);
}
*::-webkit-scrollbar-thumb {
background: rgba(168, 85, 247, 0.5);
border-radius: 4px;
}
*::-webkit-scrollbar-thumb:hover {
background: rgba(168, 85, 247, 0.7);
}
@layer base {
body {
@apply bg-black text-white antialiased;
}
}import KitsuneBackground from '@/components/KitsuneBackground'
import NoiseOverlay from '@/components/NoiseOverlay'
import HeroSection from '@/components/HeroSection'
import AboutSection from '@/components/AboutSection'
import FeaturesSection from '@/components/FeaturesSection'
import AirdropSection from '@/components/AirdropSection'
import CTASection from '@/components/CTASection'
import Footer from '@/components/Footer'
export default function Home() {
return (
<main className="min-h-screen bg-black text-white overflow-x-hidden">
<KitsuneBackground />
<NoiseOverlay />
<HeroSection />
<AboutSection />
<FeaturesSection />
<AirdropSection />
<CTASection />
<Footer />
</main>
)
}'use client'
import { useEffect, useRef } from 'react'
import { motion, useScroll, useTransform } from 'framer-motion'
export default function KitsuneBackground() {
const canvasRef = useRef(null)
const { scrollY } = useScroll()
const y = useTransform(scrollY, [0, 1000], [0, 200])
useEffect(() => {
const canvas = canvasRef.current
if (!canvas) return
const ctx = canvas.getContext('2d')
canvas.width = window.innerWidth
canvas.height = window.innerHeight
let animationFrame
let time = 0
// Particle system for mystical effect
const particles = Array.from({ length: 50 }, () => ({
x: Math.random() * canvas.width,
y: Math.random() * canvas.height,
size: Math.random() * 2 + 1,
speedX: Math.random() * 0.5 - 0.25,
speedY: Math.random() * 0.5 - 0.25,
opacity: Math.random() * 0.5 + 0.3
}))
const drawKitsune = () => {
ctx.clearRect(0, 0, canvas.width, canvas.height)
time += 0.01
// Draw mystical particles
particles.forEach(p => {
p.x += p.speedX
p.y += p.speedY
if (p.x < 0 || p.x > canvas.width) p.speedX *= -1
if (p.y < 0 || p.y > canvas.height) p.speedY *= -1
const gradient = ctx.createRadialGradient(p.x, p.y, 0, p.x, p.y, p.size * 3)
gradient.addColorStop(0, `rgba(168, 85, 247, ${p.opacity * (0.5 + Math.sin(time * 2) * 0.3)})`)
gradient.addColorStop(1, 'rgba(168, 85, 247, 0)')
ctx.fillStyle = gradient
ctx.beginPath()
ctx.arc(p.x, p.y, p.size * 3, 0, Math.PI * 2)
ctx.fill()
})
// Draw stylized fox silhouette with glow
const centerX = canvas.width * 0.5
const centerY = canvas.height * 0.6
const scale = Math.min(canvas.width, canvas.height) * 0.0008
const pulse = Math.sin(time) * 0.1 + 1
ctx.save()
ctx.translate(centerX, centerY)
ctx.scale(scale * pulse, scale * pulse)
// Glow effect
ctx.shadowBlur = 40
ctx.shadowColor = '#a855f7'
// Fox body (simplified geometric)
ctx.fillStyle = 'rgba(168, 85, 247, 0.15)'
ctx.strokeStyle = `rgba(168, 85, 247, ${0.4 + Math.sin(time * 2) * 0.2})`
ctx.lineWidth = 3
// Head
ctx.beginPath()
ctx.moveTo(0, -100)
ctx.lineTo(-80, -40)
ctx.lineTo(-60, 20)
ctx.lineTo(60, 20)
ctx.lineTo(80, -40)
ctx.closePath()
ctx.fill()
ctx.stroke()
// Draw 9 tails with individual glow
for (let i = 0; i < 9; i++) {
const angle = (Math.PI / 5) * (i - 4) + Math.sin(time + i * 0.5) * 0.2
const tailLength = 200 + Math.sin(time + i) * 30
ctx.beginPath()
ctx.moveTo(0, 20)
const cp1x = Math.sin(angle) * 100
const cp1y = 80 + Math.cos(time + i * 0.3) * 20
const cp2x = Math.sin(angle) * 150
const cp2y = 130 + Math.cos(time + i * 0.4) * 30
const endX = Math.sin(angle) * tailLength
const endY = 180 + Math.cos(time + i * 0.2) * 40
ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, endX, endY)
const gradient = ctx.createLinearGradient(0, 20, endX, endY)
gradient.addColorStop(0, 'rgba(168, 85, 247, 0.25)')
gradient.addColorStop(0.5, `rgba(236, 72, 153, ${0.15 + Math.sin(time * 3 + i) * 0.1})`)
gradient.addColorStop(1, 'rgba(6, 182, 212, 0.1)')
ctx.strokeStyle = gradient
ctx.lineWidth = 15 - i * 0.8
ctx.stroke()
// Tail tip glow
const tipGradient = ctx.createRadialGradient(endX, endY, 0, endX, endY, 25)
tipGradient.addColorStop(0, `rgba(6, 182, 212, ${0.4 + Math.sin(time * 4 + i) * 0.2})`)
tipGradient.addColorStop(1, 'rgba(6, 182, 212, 0)')
ctx.fillStyle = tipGradient
ctx.beginPath()
ctx.arc(endX, endY, 25, 0, Math.PI * 2)
ctx.fill()
}
// Eyes with glow
ctx.fillStyle = '#06b6d4'
ctx.shadowBlur = 20
ctx.shadowColor = '#06b6d4'
ctx.beginPath()
ctx.arc(-25, -50, 6, 0, Math.PI * 2)
ctx.arc(25, -50, 6, 0, Math.PI * 2)
ctx.fill()
ctx.restore()
animationFrame = requestAnimationFrame(drawKitsune)
}
drawKitsune()
const handleResize = () => {
canvas.width = window.innerWidth
canvas.height = window.innerHeight
}
window.addEventListener('resize', handleResize)
return () => {
cancelAnimationFrame(animationFrame)
window.removeEventListener('resize', handleResize)
}
}, [])
return (
<motion.canvas
ref={canvasRef}
style={{ y }}
className="fixed inset-0 pointer-events-none z-0"
/>
)
}export default function NoiseOverlay() {
return (
<div
className="fixed inset-0 pointer-events-none z-10 opacity-[0.015]"
style={{
backgroundImage: `url("data:image/svg+xml,%3Csvg viewBox='0 0 400 400' 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")`,
}}
/>
)
}'use client'
import { motion } from 'framer-motion'
import { Zap } from 'lucide-react'
export default function HeroSection() {
return (
<section className="relative min-h-screen flex items-center justify-center px-6 overflow-hidden">
<div className="max-w-5xl mx-auto text-center z-20">
<motion.div
initial={{ opacity: 0, y: 30 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8, ease: "easeOut" }}
>
<h1 className="text-6xl md:text-8xl font-black mb-6 tracking-tight">
<span className="block bg-gradient-to-r from-purple-400 via-pink-400 to-cyan-400 bg-clip-text text-transparent animate-pulse-glow">
KITSUNE PROTOCOL
</span>
</h1>
<p className="text-xl md:text-2xl text-cyan-300 mb-12 font-light tracking-wide max-w-2xl mx-auto">
Enter the Neo-Tokyo metaverse. Claim your place in the next evolution of Web3.
</p>
<motion.button
whileHover={{ scale: 1.05, boxShadow: "0 0 40px rgba(168, 85, 247, 0.6)" }}
whileTap={{ scale: 0.98 }}
className="group relative px-12 py-5 bg-gradient-to-r from-purple-600 to-pink-600 rounded-lg overflow-hidden text-lg font-bold tracking-wider"
>
<div className="absolute inset-0 bg-gradient-to-r from-cyan-500 to-purple-500 opacity-0 group-hover:opacity-100 transition-opacity duration-300" />
<span className="relative z-10 flex items-center gap-3">
ENTER PROTOCOL
<Zap className="w-5 h-5" />
</span>
</motion.button>
</motion.div>
</div>
{/* Decorative elements */}
<div className="absolute top-20 left-10 w-64 h-64 bg-purple-600 rounded-full mix-blend-screen filter blur-[100px] opacity-20 animate-pulse-slow" />
<div className="absolute bottom-20 right-10 w-96 h-96 bg-cyan-600 rounded-full mix-blend-screen filter blur-[120px] opacity-20 animate-pulse-slow" style={{ animationDelay: '1s' }} />
</section>
)
}'use client'
import { motion } from 'framer-motion'
export default function AboutSection() {
return (
<section className="relative py-32 px-6 z-20">
<div className="max-w-6xl mx-auto">
<motion.div
initial={{ opacity: 0 }}
whileInView={{ opacity: 1 }}
viewport={{ once: true }}
transition={{ duration: 0.8 }}
>
<h2 className="text-5xl font-bold text-center mb-16 bg-gradient-to-r from-purple-400 to-cyan-400 bg-clip-text text-transparent">
The Protocol
</h2>
<div className="backdrop-blur-xl bg-white/[0.03] border border-purple-500/20 rounded-2xl p-12 shadow-2xl hover:border-purple-500/40 transition-all duration-500">
<p className="text-lg text-gray-300 leading-relaxed mb-6">
Kitsune Protocol bridges ancient wisdom with cutting-edge blockchain technology.
We're building the infrastructure for the next generation of decentralized applications.
</p>
<p className="text-lg text-gray-300 leading-relaxed">
Join an exclusive community of innovators, builders, and visionaries shaping
the future of Web3. Our nine pillars of development ensure security, scalability,
and sovereignty for all participants.
</p>
</div>
</motion.div>
</div>
</section>
)
}'use client'
import { motion } from 'framer-motion'
import { Sparkles, Zap, Shield, Layers } from 'lucide-react'
export default function FeaturesSection() {
const features = [
{
icon: Shield,
title: "Quantum Security",
description: "Military-grade encryption with post-quantum cryptography ensuring your assets remain secure in the evolving threat landscape."
},
{
icon: Layers,
title: "Multi-Chain Architecture",
description: "Seamlessly interact across all major blockchains with our unified protocol layer and instant cross-chain bridges."
},
{
icon: Zap,
title: "Lightning Speed",
description: "Process thousands of transactions per second with sub-second finality using our proprietary consensus mechanism."
},
{
icon: Sparkles,
title: "AI-Powered Governance",
description: "Intelligent contract optimization and automated risk assessment powered by neural network analysis."
}
]
return (
<section className="relative py-32 px-6 z-20">
<div className="max-w-7xl mx-auto">
<h2 className="text-5xl font-bold text-center mb-20 bg-gradient-to-r from-cyan-400 to-purple-400 bg-clip-text text-transparent">
Core Features
</h2>
<div className="grid md:grid-cols-2 lg:grid-cols-4 gap-8">
{features.map((feature, idx) => (
<motion.div
key={idx}
initial={{ opacity: 0, y: 30 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.6, delay: idx * 0.1 }}
whileHover={{ y: -10, boxShadow: "0 0 50px rgba(168, 85, 247, 0.3)" }}
className="group backdrop-blur-xl bg-white/[0.02] border border-purple-500/20 rounded-xl p-8 hover:border-cyan-500/50 transition-all duration-500"
>
<div className="mb-6 inline-block p-4 rounded-lg bg-gradient-to-br from-purple-600/20 to-cyan-600/20 group-hover:from-purple-600/40 group-hover:to-cyan-600/40 transition-all duration-300">
<feature.icon className="w-8 h-8 text-cyan-400" />
</div>
<h3 className="text-xl font-bold mb-4 text-purple-300 group-hover:text-cyan-300 transition-colors">
{feature.title}
</h3>
<p className="text-gray-400 leading-relaxed">
{feature.description}
</p>
</motion.div>
))}
</div>
</div>
</section>
)
}'use client'
import { motion } from 'framer-motion'
export default function AirdropSection() {
const projects = [
{ name: "Genesis NFT Drop", status: "Confirmed", date: "Q1 2026", allocation: "10,000 NFTs" },
{ name: "Governance Token", status: "Confirmed", date: "Q2 2026", allocation: "100M $KTSN" },
{ name: "Testnet Rewards", status: "Active", date: "Ongoing", allocation: "5M $KTSN" },
{ name: "Validator Program", status: "Potential", date: "Q3 2026", allocation: "TBA" },
]
const getStatusColor = (status) => {
switch (status) {
case 'Confirmed': return 'bg-green-500/20 text-green-400 border-green-500/50'
case 'Active': return 'bg-cyan-500/20 text-cyan-400 border-cyan-500/50'
case 'Potential': return 'bg-purple-500/20 text-purple-400 border-purple-500/50'
default: return 'bg-gray-500/20 text-gray-400 border-gray-500/50'
}
}
return (
<section className="relative py-32 px-6 z-20">
<div className="max-w-6xl mx-auto">
<h2 className="text-5xl font-bold text-center mb-20 bg-gradient-to-r from-pink-400 to-purple-400 bg-clip-text text-transparent">
Upcoming Airdrops
</h2>
<motion.div
initial={{ opacity: 0 }}
whileInView={{ opacity: 1 }}
viewport={{ once: true }}
className="backdrop-blur-xl bg-white/[0.03] border border-purple-500/20 rounded-2xl overflow-hidden"
>
<div className="overflow-x-auto">
<table className="w-full">
<thead>
<tr className="border-b border-purple-500/20">
<th className="text-left py-6 px-8 text-cyan-400 font-bold tracking-wider">PROJECT</th>
<th className="text-left py-6 px-8 text-cyan-400 font-bold tracking-wider">STATUS</th>
<th className="text-left py-6 px-8 text-cyan-400 font-bold tracking-wider">DATE</th>
<th className="text-left py-6 px-8 text-cyan-400 font-bold tracking-wider">ALLOCATION</th>
</tr>
</thead>
<tbody>
{projects.map((project, idx) => (
<motion.tr
key={idx}
initial={{ opacity: 0, x: -20 }}
whileInView={{ opacity: 1, x: 0 }}
viewport={{ once: true }}
transition={{ delay: idx * 0.1 }}
className="border-b border-purple-500/10 hover:bg-purple-500/5 transition-colors"
>
<td className="py-6 px-8 font-semibold text-gray-200">{project.name}</td>
<td className="py-6 px-8">
<span className={`px-4 py-2 rounded-full text-xs font-bold border ${getStatusColor(project.status)}`}>
{project.status}
</span>
</td>
<td className="py-6 px-8 text-gray-400">{project.date}</td>
<td className="py-6 px-8 text-purple-300 font-mono">{project.allocation}</td>
</motion.tr>
))}
</tbody>
</table>
</div>
</motion.div>
</div>
</section>
)
}'use client'
import { motion } from 'framer-motion'
export default function CTASection() {
return (
<section className="relative py-32 px-6 z-20">
<div className="max-w-4xl mx-auto text-center">
<motion.div
initial={{ opacity: 0, scale: 0.9 }}
whileInView={{ opacity: 1, scale: 1 }}
viewport={{ once: true }}
transition={{ duration: 0.8 }}
className="backdrop-blur-xl bg-gradient-to-br from-purple-900/30 to-pink-900/30 border border-purple-500/30 rounded-3xl p-16 shadow-2xl"
>
<h2 className="text-5xl font-bold mb-6 bg-gradient-to-r from-purple-300 via-pink-300 to-cyan-300 bg-clip-text text-transparent">
Claim Your Position
</h2>
<p className="text-xl text-gray-300 mb-10 max-w-2xl mx-auto">
Limited slots available for early protocol participants. Join the inner circle and shape the future.
</p>
<motion.button
whileHover={{ scale: 1.05, boxShadow: "0 0 60px rgba(236, 72, 153, 0.6)" }}
whileTap={{ scale: 0.98 }}
className="px-16 py-6 bg-gradient-to-r from-pink-600 via-purple-600 to-cyan-600 rounded-xl text-xl font-bold tracking-wider shadow-2xl hover:shadow-pink-500/50 transition-all duration-300"
>
APPLY FOR EARLY ACCESS
</motion.button>
<p className="mt-8 text-sm text-gray-500 tracking-wider">
⚡ EXCLUSIVE • INVITATION ONLY • LIMITED AVAILABILITY
</p>
</motion.div>
</div>
</section>
)
}'use client'
import { motion } from 'framer-motion'
import { Twitter, Github, Send } from 'lucide-react'
export default function Footer() {
return (
<footer className="relative border-t border-purple-500/20 py-12 px-6 z-20">
<div className="max-w-6xl mx-auto">
<div className="flex flex-col md:flex-row justify-between items-center gap-6">
<div className="text-center md:text-left">
<h3 className="text-2xl font-bold bg-gradient-to-r from-purple-400 to-cyan-400 bg-clip-text text-transparent mb-2">
KITSUNE PROTOCOL
</h3>
<p className="text-gray-500 text-sm">Building the future, one block at a time.</p>
</div>
<div className="flex gap-6">
<motion.a
whileHover={{ scale: 1.2, color: '#06b6d4' }}
href="#"
className="text-gray-400 hover:text-cyan-400 transition-colors"
aria-label="Twitter"
>
<Twitter className="w-6 h-6" />
</motion.a>
<motion.a
whileHover={{ scale: 1.2, color: '#a855f7' }}
href="#"
className="text-gray-400 hover:text-purple-400 transition-colors"
aria-label="GitHub"
>
<Github className="w-6 h-6" />
</motion.a>
<motion.a
whileHover={{ scale: 1.2, color: '#ec4899' }}
href="#"
className="text-gray-400 hover:text-pink-400 transition-colors"
aria-label="Telegram"
>
<Send className="w-6 h-6" />
</motion.a>