polish: Priority 1 improvements - gradients, stats, metadata, footer

 Visual Enhancements:
- Unique gradients per tool (green-teal for Vert, orange-pink for Paint, indigo-purple for Pastel)
- Added new gradient utilities for better color differentiation

📊 Stats Section:
- New animated stats component showing "3 Tools, 100% Open Source, ∞ Privacy First"
- Glassmorphism cards with hover effects
- Icon badges for each stat

🔍 Enhanced Metadata:
- Comprehensive Open Graph tags for social sharing
- Twitter Card support
- Enhanced SEO with detailed keywords (vert, paint, pastel)
- Added SVG favicon with gradient toolbox icon
- Viewport meta tag and preconnect optimization

🔗 Improved Footer:
- 3-column responsive layout
- GitHub repository link with icon
- Quick links to all tools (Vert, Paint, Pastel)
- Tool count badge
- Updated tech stack mention (Next.js 16 & Tailwind CSS 4)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-07 12:30:08 +01:00
parent 9054aa62b8
commit c7373430f9
7 changed files with 206 additions and 22 deletions

View File

@@ -68,3 +68,15 @@ body {
@utility gradient-cyan-purple { @utility gradient-cyan-purple {
background: linear-gradient(135deg, #2dd4bf 0%, #8b5cf6 100%); background: linear-gradient(135deg, #2dd4bf 0%, #8b5cf6 100%);
} }
@utility gradient-orange-pink {
background: linear-gradient(135deg, #f97316 0%, #ec4899 100%);
}
@utility gradient-green-teal {
background: linear-gradient(135deg, #10b981 0%, #06b6d4 100%);
}
@utility gradient-indigo-purple {
background: linear-gradient(135deg, #6366f1 0%, #a855f7 100%);
}

18
app/icon.svg Normal file
View File

@@ -0,0 +1,18 @@
<svg width="64" height="64" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="64" height="64" rx="12" fill="url(#gradient)"/>
<path d="M20 28 L20 42 L34 42 L34 28 Z" stroke="white" stroke-width="3" fill="none" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M24 28 Q 27 18, 30 28" stroke="white" stroke-width="3" fill="none" stroke-linecap="round"/>
<line x1="22" y1="34" x2="22" y2="39" stroke="white" stroke-width="2.5" stroke-linecap="round"/>
<circle cx="22" cy="32" r="1.5" fill="white"/>
<line x1="27" y1="34" x2="27" y2="40" stroke="white" stroke-width="2.5" stroke-linecap="round"/>
<path d="M24 34 L 27 32 L 30 34" fill="white" stroke="none"/>
<rect x="31" y="34" width="2" height="6" fill="white" rx="1"/>
<path d="M29 34 L 33 32 L 35 34" fill="white" stroke="none"/>
<defs>
<linearGradient id="gradient" x1="0" y1="0" x2="64" y2="64">
<stop offset="0%" stop-color="#667eea"/>
<stop offset="50%" stop-color="#8b5cf6"/>
<stop offset="100%" stop-color="#06b6d4"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -3,8 +3,45 @@ import './globals.css';
export const metadata: Metadata = { export const metadata: Metadata = {
title: 'Kit - Your Creative Toolkit', title: 'Kit - Your Creative Toolkit',
description: 'A curated collection of creative and utility tools for developers and creators', description: 'A curated collection of creative and utility tools for developers and creators. Features file conversion, image editing, and color manipulation.',
keywords: ['tools', 'utilities', 'pastebin', 'paint', 'creative toolkit'], keywords: ['tools', 'utilities', 'file converter', 'image editor', 'color palette', 'creative toolkit', 'vert', 'paint', 'pastel', 'open source'],
authors: [{ name: 'pivoine.art' }],
creator: 'pivoine.art',
publisher: 'pivoine.art',
metadataBase: new URL('https://kit.pivoine.art'),
openGraph: {
title: 'Kit - Your Creative Toolkit',
description: 'A curated collection of creative and utility tools for developers and creators. Privacy-first, open source, and free to use.',
url: 'https://kit.pivoine.art',
siteName: 'Kit',
locale: 'en_US',
type: 'website',
images: [
{
url: '/og-image.png',
width: 1200,
height: 630,
alt: 'Kit - Your Creative Toolkit',
},
],
},
twitter: {
card: 'summary_large_image',
title: 'Kit - Your Creative Toolkit',
description: 'A curated collection of creative and utility tools for developers and creators.',
images: ['/og-image.png'],
},
robots: {
index: true,
follow: true,
googleBot: {
index: true,
follow: true,
'max-video-preview': -1,
'max-image-preview': 'large',
'max-snippet': -1,
},
},
}; };
export default function RootLayout({ export default function RootLayout({
@@ -14,6 +51,10 @@ export default function RootLayout({
}>) { }>) {
return ( return (
<html lang="en"> <html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="preconnect" href="https://kit.pivoine.art" />
</head>
<body className="antialiased"> <body className="antialiased">
{children} {children}
</body> </body>

View File

@@ -1,5 +1,6 @@
import AnimatedBackground from '@/components/AnimatedBackground'; import AnimatedBackground from '@/components/AnimatedBackground';
import Hero from '@/components/Hero'; import Hero from '@/components/Hero';
import Stats from '@/components/Stats';
import ToolsGrid from '@/components/ToolsGrid'; import ToolsGrid from '@/components/ToolsGrid';
import Footer from '@/components/Footer'; import Footer from '@/components/Footer';
@@ -8,6 +9,7 @@ export default function Home() {
<main className="relative min-h-screen"> <main className="relative min-h-screen">
<AnimatedBackground /> <AnimatedBackground />
<Hero /> <Hero />
<Stats />
<ToolsGrid /> <ToolsGrid />
<Footer /> <Footer />
</main> </main>

View File

@@ -3,38 +3,80 @@
import { motion } from 'framer-motion'; import { motion } from 'framer-motion';
export default function Footer() { export default function Footer() {
const currentYear = new Date().getFullYear();
return ( return (
<footer className="relative py-12 px-4 border-t border-gray-800"> <footer className="relative py-16 px-4 border-t border-gray-800">
<div className="max-w-6xl mx-auto"> <div className="max-w-6xl mx-auto">
<motion.div <motion.div
className="text-center" className="grid grid-cols-1 md:grid-cols-3 gap-8 mb-8"
initial={{ opacity: 0 }} initial={{ opacity: 0 }}
whileInView={{ opacity: 1 }} whileInView={{ opacity: 1 }}
viewport={{ once: true }} viewport={{ once: true }}
transition={{ duration: 0.6 }} transition={{ duration: 0.6 }}
> >
{/* Brand */} {/* Brand Column */}
<div className="mb-4"> <div className="text-center md:text-left">
<h3 className="text-xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-purple-400 to-cyan-400"> <h3 className="text-xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-purple-400 to-cyan-400 mb-2">
Kit Kit
</h3> </h3>
<p className="text-gray-500 text-sm">
Your Creative Toolkit
</p>
<div className="mt-4 inline-flex items-center gap-2 px-3 py-1 rounded-full bg-purple-500/10 border border-purple-500/20">
<span className="text-xs font-medium text-purple-400">3 Tools</span>
<span className="text-gray-600"></span>
<span className="text-xs text-gray-500">Open Source</span>
</div>
</div> </div>
{/* Links */} {/* Links Column */}
<div className="flex justify-center gap-8 mb-6 text-sm"> <div className="text-center">
<a <h4 className="text-sm font-semibold text-gray-300 mb-4">Links</h4>
href="https://pivoine.art" <div className="flex flex-col gap-2">
target="_blank" <a
rel="noopener noreferrer" href="https://github.com/valknarness/kit-ui"
className="text-gray-400 hover:text-purple-400 transition-colors" target="_blank"
> rel="noopener noreferrer"
pivoine.art className="text-gray-400 hover:text-purple-400 transition-colors text-sm inline-flex items-center justify-center gap-2"
</a> >
<svg className="w-4 h-4" fill="currentColor" viewBox="0 0 24 24">
<path fillRule="evenodd" d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" clipRule="evenodd" />
</svg>
GitHub
</a>
<a
href="https://pivoine.art"
target="_blank"
rel="noopener noreferrer"
className="text-gray-400 hover:text-purple-400 transition-colors text-sm"
>
pivoine.art
</a>
</div>
</div> </div>
{/* Copyright */} {/* Tools Column */}
<div className="text-center md:text-right">
<h4 className="text-sm font-semibold text-gray-300 mb-4">Tools</h4>
<div className="flex flex-col gap-2 items-center md:items-end">
<a href="https://vert.kit.pivoine.art" className="text-gray-400 hover:text-green-400 transition-colors text-sm">Vert</a>
<a href="https://paint.kit.pivoine.art" className="text-gray-400 hover:text-orange-400 transition-colors text-sm">Paint</a>
<a href="https://pastel.kit.pivoine.art" className="text-gray-400 hover:text-purple-400 transition-colors text-sm">Pastel</a>
</div>
</div>
</motion.div>
{/* Bottom Bar */}
<motion.div
className="pt-8 border-t border-gray-800 text-center"
initial={{ opacity: 0 }}
whileInView={{ opacity: 1 }}
viewport={{ once: true }}
transition={{ duration: 0.6, delay: 0.2 }}
>
<p className="text-gray-500 text-sm"> <p className="text-gray-500 text-sm">
© {new Date().getFullYear()} Kit. Built with Next.js & Tailwind CSS. © {currentYear} Kit. Built with Next.js 16 & Tailwind CSS 4.
</p> </p>
</motion.div> </motion.div>
</div> </div>

69
components/Stats.tsx Normal file
View File

@@ -0,0 +1,69 @@
'use client';
import { motion } from 'framer-motion';
const stats = [
{
number: '3',
label: 'Tools',
icon: (
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" />
</svg>
),
},
{
number: '100%',
label: 'Open Source',
icon: (
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4" />
</svg>
),
},
{
number: '∞',
label: 'Privacy First',
icon: (
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" />
</svg>
),
},
];
export default function Stats() {
return (
<section className="relative py-16 px-4">
<div className="max-w-6xl mx-auto">
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
{stats.map((stat, index) => (
<motion.div
key={stat.label}
className="glass rounded-2xl p-8 text-center"
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.5, delay: index * 0.1 }}
whileHover={{ y: -5 }}
>
<motion.div
className="inline-flex items-center justify-center w-12 h-12 mb-4 rounded-xl bg-gradient-to-br from-purple-500/20 to-cyan-500/20 text-purple-400"
whileHover={{ scale: 1.1, rotate: 5 }}
transition={{ type: 'spring', stiffness: 300 }}
>
{stat.icon}
</motion.div>
<div className="text-4xl font-bold mb-2 bg-clip-text text-transparent bg-gradient-to-r from-purple-400 to-cyan-400">
{stat.number}
</div>
<div className="text-gray-400 text-sm font-medium">
{stat.label}
</div>
</motion.div>
))}
</div>
</div>
</section>
);
}

View File

@@ -8,7 +8,7 @@ const tools = [
title: 'Vert', title: 'Vert',
description: 'Privacy-focused file converter that processes images, audio, and documents locally on your device. No file size limits, completely open source.', description: 'Privacy-focused file converter that processes images, audio, and documents locally on your device. No file size limits, completely open source.',
url: 'https://vert.kit.pivoine.art', url: 'https://vert.kit.pivoine.art',
gradient: 'gradient-purple-blue', gradient: 'gradient-green-teal',
icon: ( icon: (
<svg className="w-12 h-12 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="w-12 h-12 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" />
@@ -19,7 +19,7 @@ const tools = [
title: 'Paint', title: 'Paint',
description: 'An advanced image editor running in your browser. Edit photos, create graphics, and more.', description: 'An advanced image editor running in your browser. Edit photos, create graphics, and more.',
url: 'https://paint.kit.pivoine.art', url: 'https://paint.kit.pivoine.art',
gradient: 'gradient-cyan-purple', gradient: 'gradient-orange-pink',
icon: ( icon: (
<svg className="w-12 h-12 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="w-12 h-12 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M7 21a4 4 0 01-4-4V5a2 2 0 012-2h4a2 2 0 012 2v12a4 4 0 01-4 4zm0 0h12a2 2 0 002-2v-4a2 2 0 00-2-2h-2.343M11 7.343l1.657-1.657a2 2 0 012.828 0l2.829 2.829a2 2 0 010 2.828l-8.486 8.485M7 17h.01" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M7 21a4 4 0 01-4-4V5a2 2 0 012-2h4a2 2 0 012 2v12a4 4 0 01-4 4zm0 0h12a2 2 0 002-2v-4a2 2 0 00-2-2h-2.343M11 7.343l1.657-1.657a2 2 0 012.828 0l2.829 2.829a2 2 0 010 2.828l-8.486 8.485M7 17h.01" />
@@ -30,7 +30,7 @@ const tools = [
title: 'Pastel', title: 'Pastel',
description: 'Modern color manipulation toolkit with palette generation, accessibility testing, and format conversion. Supports hex, RGB, HSL, Lab, and more.', description: 'Modern color manipulation toolkit with palette generation, accessibility testing, and format conversion. Supports hex, RGB, HSL, Lab, and more.',
url: 'https://pastel.kit.pivoine.art', url: 'https://pastel.kit.pivoine.art',
gradient: 'gradient-purple-blue', gradient: 'gradient-indigo-purple',
icon: ( icon: (
<svg className="w-12 h-12 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="w-12 h-12 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M7 21a4 4 0 01-4-4V5a2 2 0 012-2h4a2 2 0 012 2v12a4 4 0 01-4 4zm0 0h12a2 2 0 002-2v-4a2 2 0 00-2-2h-2.343M11 7.343l1.657-1.657a2 2 0 012.828 0l2.829 2.829a2 2 0 010 2.828l-8.486 8.485M7 17h.01" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M7 21a4 4 0 01-4-4V5a2 2 0 012-2h4a2 2 0 012 2v12a4 4 0 01-4 4zm0 0h12a2 2 0 002-2v-4a2 2 0 00-2-2h-2.343M11 7.343l1.657-1.657a2 2 0 012.828 0l2.829 2.829a2 2 0 010 2.828l-8.486 8.485M7 17h.01" />