Files
zeekay 93fa819e25 style: Update gallery to match hanzo.ai design system
- Rewrite globals.css with oklch color system matching hanzo.ai
- Add Hanzo brand colors (#fd4444 primary, #e03e3e hover, #ff6b6b secondary)
- Replace purple gradients with monochrome + red brand accents
- Update header with neutral nav links and red CTA button
- Update footer with monochrome styling and social icons
- Redesign page.tsx with neutral-900/50 cards, neutral-800 borders
- Add text-gradient, hero-glow, glass-panel utilities
- Use golden ratio typography system
2026-01-23 18:12:11 -08:00

349 lines
15 KiB
TypeScript

'use client';
import Image from 'next/image';
import Link from 'next/link';
import { templates } from './templates-data';
interface TemplateCardProps {
template: typeof templates[0];
}
function TemplateCard({ template }: TemplateCardProps) {
return (
<Link href={`/templates/${template.slug}`}>
<div className="group relative bg-neutral-900/50 rounded-xl border border-neutral-800 overflow-hidden hover:border-neutral-700 transition-all duration-300 hover:shadow-xl hover:-translate-y-1 cursor-pointer">
<div className="relative aspect-video bg-neutral-900 overflow-hidden">
<Image
src={`/screenshots/${template.screenshot}.png`}
alt={template.displayName}
fill
className="object-cover transition-transform duration-500 group-hover:scale-105"
/>
<div className="absolute inset-0 bg-gradient-to-t from-black via-transparent to-transparent opacity-60" />
{/* Tier badge */}
<div className={`absolute top-3 left-3 px-2.5 py-1 rounded-full text-xs font-medium ${
template.tier === 1 ? 'bg-[#fd4444] text-white' :
template.tier === 2 ? 'bg-neutral-700 text-white' : 'bg-neutral-800 text-neutral-300'
}`}>
Tier {template.tier}
</div>
{/* Category badge */}
<div className="absolute top-3 right-3 px-2.5 py-1 bg-neutral-900/80 backdrop-blur-sm rounded-full text-xs font-medium text-neutral-300">
{template.category}
</div>
</div>
<div className="p-5">
<h3 className="text-lg font-medium text-white mb-1.5 group-hover:text-[#fd4444] transition-colors">
{template.displayName}
</h3>
<p className="text-sm text-neutral-500 mb-1.5">{template.framework}</p>
<p className="text-sm text-neutral-600 mb-3">{template.useCase}</p>
<div className="flex">
{[...Array(5)].map((_, i) => (
<span key={i} className={i < template.rating ? 'text-[#fd4444]' : 'text-neutral-700'}>
★
</span>
))}
</div>
</div>
</div>
</Link>
);
}
interface TechBadgeProps {
icon: string;
name: string;
count: string;
}
function TechBadge({ icon, name, count }: TechBadgeProps) {
return (
<div className="bg-neutral-900/50 p-6 rounded-xl border border-neutral-800 hover:border-neutral-700 transition-all hover:-translate-y-1 cursor-pointer">
<div className="text-4xl mb-3 text-center">{icon}</div>
<div className="text-center">
<div className="text-lg font-medium text-white mb-1">{name}</div>
<div className="text-neutral-500 text-sm">{count} templates</div>
</div>
</div>
);
}
interface UseCaseCardProps {
icon: string;
title: string;
description: string;
templates: number;
}
function UseCaseCard({ icon, title, description, templates }: UseCaseCardProps) {
return (
<div className="bg-neutral-900/50 p-6 rounded-xl border border-neutral-800 hover:border-neutral-700 transition-all hover:-translate-y-1 cursor-pointer">
<div className="text-4xl mb-4">{icon}</div>
<h3 className="text-xl font-medium text-white mb-2">{title}</h3>
<p className="text-neutral-500 text-sm mb-4">{description}</p>
<div className="text-[#fd4444] text-sm font-medium">{templates} templates →</div>
</div>
);
}
export default function GalleryHome() {
const tier1Templates = templates.filter(t => t.tier === 1);
const featuredTemplates = tier1Templates.slice(0, 6);
// Calculate component count
const totalComponents = templates.reduce((sum, t) => {
const match = t.components.match(/(\d+)/);
return sum + (match ? parseInt(match[1]) : 0);
}, 0);
return (
<div className="min-h-screen bg-[#0a0a0a] text-white">
{/* Hero Section */}
<section className="relative py-32 px-4 overflow-hidden">
{/* Subtle gradient glow */}
<div className="hero-glow" />
<div className="relative max-w-5xl mx-auto text-center">
<p className="text-sm text-neutral-500 mb-4 tracking-wide uppercase">Open Source Templates</p>
<h1 className="text-5xl md:text-6xl lg:text-7xl font-medium mb-6 tracking-tight">
<span className="text-gradient">Hanzo Templates</span>
</h1>
<p className="text-lg md:text-xl text-neutral-400 mb-4 max-w-2xl mx-auto">
Premium UI/UX templates for your next project
</p>
<p className="text-base text-neutral-500 mb-10">
<span className="text-white font-medium">{templates.length}</span> Production-ready templates
</p>
<div className="flex gap-3 justify-center flex-wrap">
<Link href="/gallery">
<button className="px-6 py-3 bg-[#fd4444] hover:bg-[#e03e3e] rounded-full font-medium text-white transition-colors flex items-center gap-2">
Browse Templates
<svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M14 5l7 7m0 0l-7 7m7-7H3" />
</svg>
</button>
</Link>
<Link href="/docs">
<button className="px-6 py-3 bg-transparent border border-neutral-700 hover:border-neutral-600 hover:bg-white/5 rounded-full font-medium text-white transition-colors">
Documentation
</button>
</Link>
</div>
</div>
</section>
{/* Stats */}
<section className="py-16 px-4 border-y border-neutral-800">
<div className="max-w-5xl mx-auto grid grid-cols-2 md:grid-cols-4 gap-8">
<div className="text-center">
<div className="text-4xl font-medium text-white mb-1">
{templates.length}
</div>
<div className="text-neutral-500 text-sm">Premium Templates</div>
</div>
<div className="text-center">
<div className="text-4xl font-medium text-white mb-1">
14
</div>
<div className="text-neutral-500 text-sm">Categories</div>
</div>
<div className="text-center">
<div className="text-4xl font-medium text-white mb-1">
{totalComponents}+
</div>
<div className="text-neutral-500 text-sm">Components</div>
</div>
<div className="text-center">
<div className="text-4xl font-medium text-white mb-1">
100%
</div>
<div className="text-neutral-500 text-sm">Production Ready</div>
</div>
</div>
</section>
{/* Featured Templates */}
<section className="py-24 px-4">
<div className="max-w-7xl mx-auto">
<div className="text-center mb-12">
<h2 className="text-3xl font-medium mb-3 text-white">
Featured Templates
</h2>
<p className="text-neutral-500">Our highest-rated Tier 1 templates</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-12">
{featuredTemplates.map(template => (
<TemplateCard key={template.id} template={template} />
))}
</div>
<div className="text-center">
<Link href="/gallery">
<button className="px-6 py-3 bg-neutral-900 border border-neutral-800 hover:border-neutral-700 rounded-full font-medium text-white transition-colors">
View All Templates →
</button>
</Link>
</div>
</div>
</section>
{/* Technology Stacks */}
<section className="py-24 px-4 border-y border-neutral-800">
<div className="max-w-5xl mx-auto">
<div className="text-center mb-12">
<h2 className="text-3xl font-medium mb-3 text-white">
Technology Stacks
</h2>
<p className="text-neutral-500">Built with modern web technologies</p>
</div>
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
<TechBadge
icon="⚡"
name="Next.js"
count={templates.filter(t => t.framework.toLowerCase().includes('next')).length.toString()}
/>
<TechBadge
icon="⚛️"
name="React"
count={templates.filter(t => t.framework.toLowerCase().includes('react')).length.toString()}
/>
<TechBadge
icon="🎨"
name="TypeScript"
count={templates.filter(t => t.framework.toLowerCase().includes('typescript') || t.framework.toLowerCase().includes('ts')).length.toString()}
/>
<TechBadge
icon="🌈"
name="HTML/CSS"
count={templates.filter(t => t.framework.toLowerCase().includes('html') || t.framework.toLowerCase().includes('gulp')).length.toString()}
/>
</div>
</div>
</section>
{/* Use Cases */}
<section className="py-24 px-4">
<div className="max-w-6xl mx-auto">
<div className="text-center mb-12">
<h2 className="text-3xl font-medium mb-3 text-white">
Perfect For
</h2>
<p className="text-neutral-500">Whatever you are building, we have a template</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<UseCaseCard
icon="🚀"
title="SaaS Startups"
description="Launch faster with production-ready templates"
templates={templates.filter(t => t.useCase.toLowerCase().includes('saas')).length}
/>
<UseCaseCard
icon="🎨"
title="Creative Agencies"
description="Beautiful portfolios and agency sites"
templates={templates.filter(t =>
t.useCase.toLowerCase().includes('portfolio') ||
t.useCase.toLowerCase().includes('agency') ||
t.useCase.toLowerCase().includes('creative')
).length}
/>
<UseCaseCard
icon="📱"
title="Mobile Apps"
description="Modern app landing pages"
templates={templates.filter(t =>
t.useCase.toLowerCase().includes('app') ||
t.useCase.toLowerCase().includes('mobile')
).length}
/>
<UseCaseCard
icon="📊"
title="Dashboards"
description="Admin panels and analytics platforms"
templates={templates.filter(t => t.useCase.toLowerCase().includes('dashboard')).length}
/>
<UseCaseCard
icon="🛒"
title="E-commerce"
description="Online stores and marketplaces"
templates={templates.filter(t =>
t.useCase.toLowerCase().includes('commerce') ||
t.useCase.toLowerCase().includes('store')
).length}
/>
<UseCaseCard
icon="💬"
title="Social Platforms"
description="Community and social networking"
templates={templates.filter(t => t.useCase.toLowerCase().includes('social')).length}
/>
</div>
</div>
</section>
{/* Features Section */}
<section className="py-24 px-4 border-y border-neutral-800">
<div className="max-w-5xl mx-auto">
<div className="text-center mb-12">
<h2 className="text-3xl font-medium mb-3 text-white">
Why Choose Hanzo Templates?
</h2>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div className="p-6 bg-neutral-900/50 rounded-xl border border-neutral-800">
<div className="text-3xl mb-3">⚡</div>
<h3 className="text-lg font-medium text-white mb-2">Lightning Fast</h3>
<p className="text-neutral-500 text-sm">Built with Next.js 14+ for optimal performance and SEO</p>
</div>
<div className="p-6 bg-neutral-900/50 rounded-xl border border-neutral-800">
<div className="text-3xl mb-3">🎨</div>
<h3 className="text-lg font-medium text-white mb-2">Beautiful Design</h3>
<p className="text-neutral-500 text-sm">Premium UI/UX from top designers worldwide</p>
</div>
<div className="p-6 bg-neutral-900/50 rounded-xl border border-neutral-800">
<div className="text-3xl mb-3">📱</div>
<h3 className="text-lg font-medium text-white mb-2">Fully Responsive</h3>
<p className="text-neutral-500 text-sm">Perfect on mobile, tablet, and desktop devices</p>
</div>
<div className="p-6 bg-neutral-900/50 rounded-xl border border-neutral-800">
<div className="text-3xl mb-3">🔧</div>
<h3 className="text-lg font-medium text-white mb-2">Easy to Customize</h3>
<p className="text-neutral-500 text-sm">Clean code with TypeScript and modern best practices</p>
</div>
</div>
</div>
</section>
{/* CTA */}
<section className="py-24 px-4 relative overflow-hidden">
{/* Subtle glow */}
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[600px] h-[400px] bg-[#fd4444] opacity-10 blur-[120px] rounded-full" />
<div className="relative max-w-3xl mx-auto text-center">
<h2 className="text-4xl md:text-5xl font-medium mb-4 text-white">
Deploy Instantly
</h2>
<p className="text-lg text-neutral-400 mb-10">
One-click deployment to Hanzo Cloud
</p>
<div className="flex gap-3 justify-center flex-wrap">
<a href="https://hanzo.ai" target="_blank" rel="noopener noreferrer">
<button className="px-6 py-3 bg-[#fd4444] hover:bg-[#e03e3e] rounded-full font-medium text-white transition-colors flex items-center gap-2">
Get Started Free
<svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M14 5l7 7m0 0l-7 7m7-7H3" />
</svg>
</button>
</a>
<Link href="/gallery">
<button className="px-6 py-3 bg-transparent border border-neutral-700 hover:border-neutral-600 hover:bg-white/5 rounded-full font-medium text-white transition-colors">
Browse Gallery
</button>
</Link>
</div>
</div>
</section>
</div>
);
}