feat: 优化项目网站 UI/UX 并新增项目详情组件

- 重构首页和项目列表页布局,优化视觉层次
- 新增 ProjectDetail、ProjectSidebar、RelatedProjects 组件
- 改进项目卡片样式,增加悬停效果
- 优化标签云和搜索栏交互体验
- 更新全局样式和 Tailwind 配置

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-12-26 16:36:33 +08:00
co-authored by Claude
parent 85fe0b920b
commit 4abe6715bb
19 changed files with 2108 additions and 227 deletions
-2
View File
@@ -1,8 +1,6 @@
{
"extends": ["next/core-web-vitals", "prettier"],
"rules": {
"@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }],
"@typescript-eslint/no-explicit-any": "error",
"no-console": ["warn", { "allow": ["warn", "error"] }]
}
}
+386
View File
@@ -0,0 +1,386 @@
<!DOCTYPE html>
<html lang="en"><head>
<meta charset="utf-8"/>
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
<title>Agent Park - Project Details</title>
<script src="https://cdn.tailwindcss.com?plugins=forms,typography"></script>
<link href="https://fonts.googleapis.com/css2?family=Space+Mono:ital,wght@0,400;0,700;1,400&amp;family=Inter:wght@300;400;500;600;700&amp;display=swap" rel="stylesheet"/>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"/>
<script>
tailwind.config = {
darkMode: "class",
theme: {
extend: {
colors: {
primary: "#FFE100", // The vibrant yellow seen in headers and buttons
"primary-dark": "#e5cb00",
"background-light": "#F6F3EB", // Light beige background
"background-dark": "#121212", // Dark mode background
"surface-light": "#FFFFFF",
"surface-dark": "#1E1E1E",
"text-light": "#000000",
"text-dark": "#E0E0E0",
"border-light": "#000000",
"border-dark": "#333333",
},
fontFamily: {
display: ["Space Mono", "monospace"], // For headers and buttons
body: ["Inter", "sans-serif"], // For body text
},
borderRadius: {
DEFAULT: "0px", // Sharp corners generally seen in the design
'md': "2px",
},
boxShadow: {
'brutal': '4px 4px 0px 0px rgba(0,0,0,1)', // Brutalist shadow style
'brutal-hover': '2px 2px 0px 0px rgba(0,0,0,1)',
'brutal-dark': '4px 4px 0px 0px rgba(255,255,255,0.2)',
}
},
},
};
</script>
<style>::-webkit-scrollbar {
width: 8px;
}
::-webkit-scrollbar-track {
background: transparent;
}
::-webkit-scrollbar-thumb {
background-color: #cbd5e1;
border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
background-color: #94a3b8;
}
.dark ::-webkit-scrollbar-thumb {
background-color: #475569;
}.prose h2, .prose h3 {
font-family: 'Space Mono', monospace;
font-weight: 700;
}
</style>
</head>
<body class="bg-background-light dark:bg-background-dark text-text-light dark:text-text-dark font-body min-h-screen flex flex-col transition-colors duration-200">
<div class="bg-primary text-black text-xs font-bold py-2 text-center uppercase tracking-widest border-b border-border-light dark:border-border-dark font-display">
Discover the future of AI Agents <span class="material-icons text-sm align-middle ml-1">arrow_forward</span>
</div>
<nav class="border-b border-border-light dark:border-border-dark bg-background-light dark:bg-background-dark sticky top-0 z-50">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between items-center h-16">
<div class="flex items-center">
<a class="flex items-center gap-2 group" href="#">
<span class="material-icons text-2xl group-hover:rotate-12 transition-transform">smart_toy</span>
<span class="font-display font-bold text-lg tracking-tight">Agent Park</span>
</a>
</div>
<div class="hidden md:flex items-center space-x-8">
<a class="text-sm font-display font-bold hover:underline decoration-2 underline-offset-4" href="#">HOME</a>
<a class="text-sm font-display font-bold hover:underline decoration-2 underline-offset-4" href="#">PROJECTS</a>
<a class="text-sm font-display font-bold hover:underline decoration-2 underline-offset-4" href="#">BLOG</a>
<a class="text-sm font-display font-bold hover:underline decoration-2 underline-offset-4" href="#">ABOUT</a>
</div>
<div class="hidden md:flex items-center gap-4">
<div class="text-xs font-display font-bold border-r border-border-light dark:border-border-dark pr-4 mr-2">
<span class="cursor-pointer hover:text-gray-600 dark:hover:text-gray-300">中文</span> / <span class="cursor-pointer hover:text-gray-600 dark:hover:text-gray-300">EN</span>
</div>
<a class="font-display text-xs font-bold uppercase border border-border-light dark:border-white px-4 py-2 hover:bg-black hover:text-white dark:hover:bg-white dark:hover:text-black transition-all shadow-[2px_2px_0px_0px_rgba(0,0,0,1)] dark:shadow-[2px_2px_0px_0px_rgba(255,255,255,1)] active:translate-x-[2px] active:translate-y-[2px] active:shadow-none" href="#">
Submit Project
</a>
</div>
<div class="md:hidden flex items-center">
<button class="outline-none mobile-menu-button">
<span class="material-icons">menu</span>
</button>
</div>
</div>
</div>
</nav>
<main class="flex-grow container mx-auto px-4 sm:px-6 lg:px-8 py-12">
<div class="mb-8">
<a class="inline-flex items-center text-sm font-display font-bold text-gray-500 hover:text-black dark:text-gray-400 dark:hover:text-white transition-colors group" href="#">
<span class="material-icons text-base mr-1 group-hover:-translate-x-1 transition-transform">arrow_back</span>
BACK TO PROJECTS
</a>
</div>
<div class="grid grid-cols-1 lg:grid-cols-12 gap-12">
<div class="lg:col-span-8">
<header class="mb-10 relative">
<div class="absolute -top-10 -right-10 w-24 h-24 border border-black dark:border-white opacity-20 rounded-full hidden md:block" style="border-radius: 40% 60% 70% 30% / 40% 50% 60% 50%;"></div>
<h1 class="font-display text-4xl md:text-6xl font-bold mb-6 leading-tight uppercase relative z-10">
AutoGPT X
</h1>
<div class="flex flex-wrap items-center gap-4 text-sm font-mono text-gray-600 dark:text-gray-400 mb-8 pb-8 border-b border-gray-300 dark:border-gray-700">
<div class="flex items-center gap-2">
<span class="material-icons text-base">calendar_today</span>
<span>Added Oct 24, 2023</span>
</div>
<span class="hidden sm:inline text-gray-300">|</span>
<div class="flex items-center gap-2">
<span class="material-icons text-base">category</span>
<span>Autonomous Agent</span>
</div>
<span class="hidden sm:inline text-gray-300">|</span>
<div class="flex items-center gap-2">
<span class="material-icons text-base">code</span>
<span>Open Source</span>
</div>
</div>
<div class="flex flex-wrap gap-3 mb-8">
<span class="px-3 py-1 border border-black dark:border-gray-500 text-xs font-display font-bold uppercase bg-white dark:bg-gray-800">Python</span>
<span class="px-3 py-1 border border-black dark:border-gray-500 text-xs font-display font-bold uppercase bg-white dark:bg-gray-800">LLM</span>
<span class="px-3 py-1 border border-black dark:border-gray-500 text-xs font-display font-bold uppercase bg-white dark:bg-gray-800">Automation</span>
<span class="px-3 py-1 border border-black dark:border-gray-500 text-xs font-display font-bold uppercase bg-white dark:bg-gray-800">GPT-4</span>
</div>
<div class="relative w-full aspect-video border-2 border-black dark:border-gray-600 bg-gray-100 dark:bg-gray-800 mb-10 overflow-hidden shadow-brutal dark:shadow-none">
<img alt="AutoGPT X Interface Abstract Visualization" class="w-full h-full object-cover" src="https://lh3.googleusercontent.com/aida-public/AB6AXuAvvUwvvv9eQigRJYV_SkkRfdJYe8PSpnsqNqriFIrtYb3ZxrfwipLWMSn-m8oQB9oT1LuynQY8q6o3m_GOFZGK0yM2nLxapj0EbrWKj49NN3JdO6I65VMXvnlM56uRAHXh-JKoIaFFlQRUg0hlhLlc7Nc_UfniYNUpu_0CX6OPsJwYhIRaAMeqjgLuWTfLA6cKNtkixtbNr9K7AI5puEIJjPLs7tQuUC5_7NjEiFSbBPFg_pO95-buoa59aO4_Qafu600RkDE9lDQ"/>
<div class="absolute bottom-4 right-4 bg-white dark:bg-black px-2 py-1 text-xs font-mono border border-black dark:border-gray-500">v2.0.1 Stable</div>
</div>
</header>
<article class="prose prose-lg dark:prose-invert max-w-none prose-headings:font-display prose-a:text-blue-600 dark:prose-a:text-blue-400 hover:prose-a:text-blue-800 dark:hover:prose-a:text-blue-300 prose-img:border-2 prose-img:border-black dark:prose-img:border-gray-600 prose-img:shadow-brutal dark:prose-img:shadow-none">
<p class="lead font-display text-xl mb-8">
AutoGPT X is an experimental open-source application showcasing the capabilities of the GPT-4 language model. This program, driven by GPT-4, chains together LLM "thoughts", to autonomously achieve whatever goal you set.
</p>
<h2>Overview</h2>
<p>
Unlike typical AI chatbots that require constant prompting, AutoGPT X takes a single goal and breaks it down into sub-tasks. It utilizes the internet for searching and gathering information, manages long-term and short-term memory, and can execute code or scripts to accomplish complex workflows.
</p>
<p>
As one of the first examples of GPT-4 running fully autonomously, AutoGPT X pushes the boundaries of what is possible with AI agents. It serves as a framework for building sophisticated AI assistants capable of performing real-world tasks with minimal human intervention.
</p>
<h3>Key Features</h3>
<ul class="list-disc pl-6 space-y-2 marker:text-black dark:marker:text-white">
<li><strong>Internet Access:</strong> Searches and gathers information autonomously.</li>
<li><strong>Long-Term Memory:</strong> Retains context over extended sessions.</li>
<li><strong>GPT-4 Powered:</strong> Leverages the reasoning capabilities of state-of-the-art LLMs.</li>
<li><strong>File Management:</strong> Can read and write files to your local system.</li>
<li><strong>Extensible:</strong> Plugin system allows for custom integrations.</li>
</ul>
<h3>Getting Started</h3>
<p>
To install AutoGPT X, you will need Python 3.10 or later. Clone the repository and install the dependencies:
</p>
<pre class="bg-gray-100 dark:bg-gray-800 border border-black dark:border-gray-600 p-4 font-mono text-sm overflow-x-auto"><code>git clone https://github.com/agentpark/autogpt-x.git
cd autogpt-x
pip install -r requirements.txt
python main.py</code></pre>
<blockquote>
"The goal of AutoGPT X is to make GPT-4 fully autonomous."
</blockquote>
<h2>Use Cases</h2>
<p>
Developers and enthusiasts are using AutoGPT X for a variety of tasks, including:
</p>
<ul class="list-disc pl-6 space-y-2 marker:text-black dark:marker:text-white">
<li>Automated market research and report generation.</li>
<li>Code debugging and autonomous software development.</li>
<li>Personal assistant tasks like booking flights or ordering food.</li>
<li>Content creation and social media management.</li>
</ul>
</article>
<div class="mt-12 pt-8 border-t border-gray-300 dark:border-gray-700 flex flex-col sm:flex-row justify-between items-center gap-6">
<div class="flex gap-4">
<button class="p-2 border border-black dark:border-gray-400 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors" title="Share on X">
<span class="material-icons text-lg">share</span>
</button>
<button class="p-2 border border-black dark:border-gray-400 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors" title="Copy Link">
<span class="material-icons text-lg">link</span>
</button>
</div>
<div class="flex items-center gap-2">
<span class="text-sm font-display font-bold text-gray-500">DID THIS AGENT FIX THIS?</span>
<button class="px-4 py-2 bg-primary text-black font-display font-bold text-xs uppercase border border-black hover:bg-yellow-400 transition-colors shadow-[2px_2px_0px_0px_rgba(0,0,0,1)] active:shadow-none active:translate-x-[2px] active:translate-y-[2px]">Yes, it rocks</button>
</div>
</div>
</div>
<aside class="lg:col-span-4 space-y-8">
<div class="bg-white dark:bg-surface-dark border-2 border-black dark:border-gray-600 p-6 shadow-brutal dark:shadow-brutal-dark">
<h3 class="font-display font-bold text-lg mb-6 uppercase border-b-2 border-primary pb-2 inline-block">Project Links</h3>
<div class="space-y-4">
<a class="flex items-center justify-between group p-3 border border-gray-200 dark:border-gray-700 hover:border-black dark:hover:border-white transition-colors bg-gray-50 dark:bg-gray-800" href="#">
<div class="flex items-center gap-3">
<span class="material-icons">language</span>
<span class="font-bold text-sm">Official Website</span>
</div>
<span class="material-icons text-sm group-hover:translate-x-1 transition-transform">arrow_forward</span>
</a>
<a class="flex items-center justify-between group p-3 border border-gray-200 dark:border-gray-700 hover:border-black dark:hover:border-white transition-colors bg-gray-50 dark:bg-gray-800" href="#">
<div class="flex items-center gap-3">
<span class="material-icons">code</span>
<span class="font-bold text-sm">GitHub Repo</span>
</div>
<span class="material-icons text-sm group-hover:translate-x-1 transition-transform">arrow_forward</span>
</a>
<a class="flex items-center justify-between group p-3 border border-gray-200 dark:border-gray-700 hover:border-black dark:hover:border-white transition-colors bg-gray-50 dark:bg-gray-800" href="#">
<div class="flex items-center gap-3">
<span class="material-icons">description</span>
<span class="font-bold text-sm">Documentation</span>
</div>
<span class="material-icons text-sm group-hover:translate-x-1 transition-transform">arrow_forward</span>
</a>
</div>
<div class="mt-8 pt-6 border-t border-gray-200 dark:border-gray-700">
<div class="grid grid-cols-2 gap-4">
<div>
<span class="text-xs text-gray-500 uppercase font-mono block mb-1">License</span>
<span class="font-bold text-sm">MIT</span>
</div>
<div>
<span class="text-xs text-gray-500 uppercase font-mono block mb-1">Pricing</span>
<span class="font-bold text-sm">Free</span>
</div>
<div>
<span class="text-xs text-gray-500 uppercase font-mono block mb-1">Stars</span>
<span class="font-bold text-sm">142k</span>
</div>
<div>
<span class="text-xs text-gray-500 uppercase font-mono block mb-1">Forks</span>
<span class="font-bold text-sm">34k</span>
</div>
</div>
</div>
</div>
<div class="bg-primary border-2 border-black p-6 relative overflow-hidden shadow-brutal dark:shadow-none group cursor-pointer hover:bg-yellow-400 transition-colors">
<div class="absolute top-0 right-0 w-20 h-20 bg-white opacity-20 transform rotate-45 translate-x-10 -translate-y-10"></div>
<div class="absolute bottom-0 left-0 w-16 h-16 bg-black opacity-10 rounded-full transform -translate-x-8 translate-y-8"></div>
<div class="relative z-10 text-center">
<div class="w-12 h-12 bg-white rounded-full border-2 border-black flex items-center justify-center mx-auto mb-4 group-hover:scale-110 transition-transform">
<span class="material-icons text-2xl">rocket_launch</span>
</div>
<h3 class="font-display font-bold text-xl mb-2">Build Your Own Agent?</h3>
<p class="text-sm font-medium mb-6">Start using our API to build custom agents in minutes.</p>
<button class="w-full bg-black text-white font-display font-bold py-3 text-sm uppercase hover:bg-gray-800 transition-colors shadow-none">
Get Started Now
</button>
</div>
</div>
<div class="sticky top-24 bg-background-light dark:bg-background-dark border border-gray-300 dark:border-gray-700 p-6 hidden lg:block">
<h3 class="font-display font-bold text-sm uppercase tracking-widest mb-4 text-gray-500 dark:text-gray-400">On this page</h3>
<ul class="space-y-3 text-sm border-l-2 border-gray-200 dark:border-gray-700 pl-4">
<li><a class="text-black dark:text-white font-bold border-l-2 border-black dark:border-white -ml-[18px] pl-4 block" href="#">Overview</a></li>
<li><a class="text-gray-600 dark:text-gray-400 hover:text-black dark:hover:text-white transition-colors block" href="#">Key Features</a></li>
<li><a class="text-gray-600 dark:text-gray-400 hover:text-black dark:hover:text-white transition-colors block" href="#">Getting Started</a></li>
<li><a class="text-gray-600 dark:text-gray-400 hover:text-black dark:hover:text-white transition-colors block" href="#">Use Cases</a></li>
</ul>
</div>
</aside>
</div>
<section class="mt-20 pt-12 border-t border-black dark:border-gray-700">
<div class="flex justify-between items-end mb-8">
<h2 class="font-display text-3xl font-bold uppercase">Related Projects</h2>
<a class="font-display text-xs font-bold uppercase hover:underline flex items-center gap-1 group" href="#">
View All <span class="material-icons text-sm group-hover:translate-x-1 transition-transform">arrow_forward</span>
</a>
</div>
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
<div class="border-2 border-black dark:border-gray-600 p-6 bg-white dark:bg-surface-dark hover:shadow-brutal hover:-translate-y-1 transition-all duration-200 cursor-pointer flex flex-col h-full dark:hover:shadow-brutal-dark">
<div class="flex justify-between items-start mb-4">
<h3 class="font-display text-xl font-bold">BabyAGI</h3>
<span class="material-icons text-gray-400">psychology</span>
</div>
<p class="text-sm text-gray-600 dark:text-gray-300 mb-6 flex-grow line-clamp-3">
Task-driven autonomous agent that uses OpenAI and Pinecone APIs to create, prioritize, and execute tasks.
</p>
<div class="flex gap-2 mb-6">
<span class="text-[10px] uppercase font-bold border border-gray-300 dark:border-gray-600 px-2 py-1">Python</span>
<span class="text-[10px] uppercase font-bold border border-gray-300 dark:border-gray-600 px-2 py-1">Task</span>
</div>
<div class="mt-auto pt-4 border-t border-gray-100 dark:border-gray-700">
<span class="text-xs font-display font-bold uppercase flex items-center group">
View Details <span class="material-icons text-sm ml-1 group-hover:translate-x-1 transition-transform">arrow_forward</span>
</span>
</div>
</div>
<div class="border-2 border-black dark:border-gray-600 p-6 bg-white dark:bg-surface-dark hover:shadow-brutal hover:-translate-y-1 transition-all duration-200 cursor-pointer flex flex-col h-full dark:hover:shadow-brutal-dark">
<div class="flex justify-between items-start mb-4">
<h3 class="font-display text-xl font-bold">LangChain</h3>
<span class="material-icons text-gray-400">link</span>
</div>
<p class="text-sm text-gray-600 dark:text-gray-300 mb-6 flex-grow line-clamp-3">
Building applications with LLMs through composability. The standard framework for chaining LLM capabilities.
</p>
<div class="flex gap-2 mb-6">
<span class="text-[10px] uppercase font-bold border border-gray-300 dark:border-gray-600 px-2 py-1">Framework</span>
<span class="text-[10px] uppercase font-bold border border-gray-300 dark:border-gray-600 px-2 py-1">Python</span>
</div>
<div class="mt-auto pt-4 border-t border-gray-100 dark:border-gray-700">
<span class="text-xs font-display font-bold uppercase flex items-center group">
View Details <span class="material-icons text-sm ml-1 group-hover:translate-x-1 transition-transform">arrow_forward</span>
</span>
</div>
</div>
<div class="border-2 border-black dark:border-gray-600 p-6 bg-white dark:bg-surface-dark hover:shadow-brutal hover:-translate-y-1 transition-all duration-200 cursor-pointer flex flex-col h-full dark:hover:shadow-brutal-dark">
<div class="flex justify-between items-start mb-4">
<h3 class="font-display text-xl font-bold">GodMode</h3>
<span class="material-icons text-gray-400">bolt</span>
</div>
<p class="text-sm text-gray-600 dark:text-gray-300 mb-6 flex-grow line-clamp-3">
A dedicated web platform to access the powers of AutoGPT and BabyAGI directly from your browser.
</p>
<div class="flex gap-2 mb-6">
<span class="text-[10px] uppercase font-bold border border-gray-300 dark:border-gray-600 px-2 py-1">Web</span>
<span class="text-[10px] uppercase font-bold border border-gray-300 dark:border-gray-600 px-2 py-1">UI</span>
</div>
<div class="mt-auto pt-4 border-t border-gray-100 dark:border-gray-700">
<span class="text-xs font-display font-bold uppercase flex items-center group">
View Details <span class="material-icons text-sm ml-1 group-hover:translate-x-1 transition-transform">arrow_forward</span>
</span>
</div>
</div>
</div>
</section>
</main>
<footer class="bg-background-light dark:bg-background-dark border-t border-border-light dark:border-border-dark py-12">
<div class="container mx-auto px-4 sm:px-6 lg:px-8">
<div class="grid grid-cols-1 md:grid-cols-4 gap-12 mb-12">
<div class="col-span-1 md:col-span-1">
<a class="flex items-center gap-2 mb-4" href="#">
<span class="material-icons text-2xl">smart_toy</span>
<span class="font-display font-bold text-lg tracking-tight">Agent Park</span>
</a>
<p class="text-sm text-gray-600 dark:text-gray-400">
Discover and explore high-quality AI projects from across the web. Curated for developers and enthusiasts.
</p>
</div>
<div>
<h4 class="font-display font-bold text-sm uppercase mb-4">Agent Park</h4>
<ul class="space-y-2 text-sm text-gray-600 dark:text-gray-400">
<li><a class="hover:text-black dark:hover:text-white" href="#">About Us</a></li>
<li><a class="hover:text-black dark:hover:text-white" href="#">Contact</a></li>
<li><a class="hover:text-black dark:hover:text-white" href="#">Careers</a></li>
</ul>
</div>
<div>
<h4 class="font-display font-bold text-sm uppercase mb-4">Resources</h4>
<ul class="space-y-2 text-sm text-gray-600 dark:text-gray-400">
<li><a class="hover:text-black dark:hover:text-white" href="#">Blog</a></li>
<li><a class="hover:text-black dark:hover:text-white" href="#">Newsletter</a></li>
<li><a class="hover:text-black dark:hover:text-white" href="#">Documentation</a></li>
</ul>
</div>
<div>
<h4 class="font-display font-bold text-sm uppercase mb-4">Follow Us</h4>
<div class="flex gap-2">
<a class="w-8 h-8 flex items-center justify-center border border-gray-400 hover:border-black dark:hover:border-white hover:bg-black hover:text-white dark:hover:bg-white dark:hover:text-black transition-colors font-display font-bold" href="#">X</a>
<a class="w-8 h-8 flex items-center justify-center border border-gray-400 hover:border-black dark:hover:border-white hover:bg-black hover:text-white dark:hover:bg-white dark:hover:text-black transition-colors font-display font-bold" href="#">Li</a>
<a class="w-8 h-8 flex items-center justify-center border border-gray-400 hover:border-black dark:hover:border-white hover:bg-black hover:text-white dark:hover:bg-white dark:hover:text-black transition-colors font-display font-bold" href="#">Gh</a>
</div>
</div>
</div>
<div class="border-t border-gray-300 dark:border-gray-800 pt-8 flex flex-col md:flex-row justify-between items-center text-xs font-mono text-gray-500 uppercase">
<p>© 2025 Agent Park. All rights reserved.</p>
<p>Designed for AI Builders</p>
</div>
</div>
</footer>
<script>
// Simple mobile menu toggle
const btn = document.querySelector("button.mobile-menu-button");
const menu = document.querySelector(".mobile-menu");
btn.addEventListener("click", () => {
// In a real scenario, this would toggle a hidden mobile menu div
alert("Mobile menu clicked (implementation simplified for this demo)");
});
</script>
</body></html>
+346
View File
@@ -0,0 +1,346 @@
<!DOCTYPE html>
<html lang="en"><head>
<meta charset="utf-8"/>
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
<title>Agent Park Homepage</title>
<script src="https://cdn.tailwindcss.com?plugins=forms,typography"></script>
<link href="https://fonts.googleapis.com/css2?family=Space+Mono:ital,wght@0,400;0,700;1,400&amp;family=Inter:wght@400;500;600;700&amp;display=swap" rel="stylesheet"/>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"/>
<script>
tailwind.config = {
darkMode: "class",
theme: {
extend: {
colors: {
primary: "#FFD700", // Gold/Yellow from MotherDuck
secondary: "#ff6f00", // Orange accent
"background-light": "#F7F5F0", // Off-white beige from MotherDuck
"background-dark": "#1a1a1a", // Dark charcoal for dark mode
"surface-light": "#FFFFFF",
"surface-dark": "#262626",
"border-light": "#000000",
"border-dark": "#4a4a4a",
"text-light": "#000000",
"text-dark": "#F7F5F0",
},
fontFamily: {
display: ['"Space Mono"', "monospace"], // Monospace for headings like MotherDuck
sans: ['"Inter"', "sans-serif"],
},
boxShadow: {
'neobrutalism': '4px 4px 0px 0px rgba(0,0,0,1)',
'neobrutalism-sm': '2px 2px 0px 0px rgba(0,0,0,1)',
'neobrutalism-hover': '2px 2px 0px 0px rgba(0,0,0,1)',
}
},
},
};
</script>
<style>::-webkit-scrollbar {
width: 8px;
}
::-webkit-scrollbar-track {
background: transparent;
}
::-webkit-scrollbar-thumb {
background-color: #cbd5e1;
border-radius: 4px;
}
.dark ::-webkit-scrollbar-thumb {
background-color: #475569;
}.neo-border {
border: 1px solid black;
}
.dark .neo-border {
border: 1px solid #4a4a4a;
}@keyframes float {
0% { transform: translateY(0px) rotate(0deg); }
50% { transform: translateY(-10px) rotate(2deg); }
100% { transform: translateY(0px) rotate(0deg); }
}
.floating-shape {
animation: float 6s ease-in-out infinite;
}
</style>
</head>
<body class="bg-background-light dark:bg-background-dark text-text-light dark:text-text-dark font-sans antialiased min-h-screen transition-colors duration-200">
<div class="bg-primary w-full py-2 px-4 border-b border-black dark:border-border-dark flex justify-center items-center text-xs font-bold font-display tracking-wide text-black">
<span>DISCOVER THE FUTURE OF AI AGENTS </span>
<span class="material-icons text-sm ml-2">arrow_forward</span>
</div>
<header class="w-full border-b border-black dark:border-border-dark bg-background-light dark:bg-background-dark sticky top-0 z-50">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between items-center h-16">
<div class="flex-shrink-0 flex items-center gap-2">
<span class="material-icons text-3xl text-black dark:text-primary">smart_toy</span>
<span class="font-display font-bold text-xl tracking-tight">Agent Park</span>
</div>
<nav class="hidden md:flex space-x-8 items-center">
<a class="font-display text-sm font-bold hover:text-secondary dark:hover:text-primary transition-colors" href="#">HOME</a>
<a class="font-display text-sm font-bold hover:text-secondary dark:hover:text-primary transition-colors" href="#">PROJECTS</a>
<a class="font-display text-sm font-bold hover:text-secondary dark:hover:text-primary transition-colors" href="#">BLOG</a>
<a class="font-display text-sm font-bold hover:text-secondary dark:hover:text-primary transition-colors" href="#">ABOUT</a>
</nav>
<div class="hidden md:flex items-center space-x-4">
<button class="font-display text-sm font-bold hover:opacity-70">中文 / EN</button>
<a class="bg-white dark:bg-surface-dark border border-black dark:border-white px-4 py-2 font-display text-sm font-bold shadow-neobrutalism hover:shadow-neobrutalism-hover hover:translate-x-[2px] hover:translate-y-[2px] transition-all" href="#">
SUBMIT PROJECT
</a>
</div>
<div class="md:hidden flex items-center">
<button class="text-text-light dark:text-text-dark hover:text-gray-600 focus:outline-none">
<span class="material-icons">menu</span>
</button>
</div>
</div>
</div>
</header>
<main class="relative overflow-hidden">
<div class="absolute top-20 left-10 w-24 h-24 border border-black dark:border-gray-600 rounded-full opacity-20 floating-shape hidden lg:block"></div>
<div class="absolute top-40 right-20 w-32 h-20 border border-black dark:border-gray-600 rounded-[2rem] transform -rotate-12 opacity-20 floating-shape hidden lg:block" style="animation-delay: 1s;"></div>
<section class="max-w-4xl mx-auto px-4 py-20 text-center relative z-10">
<h1 class="font-display text-5xl md:text-7xl font-bold mb-6 tracking-tight leading-tight">
AI PROJECT <br class="hidden md:block"/> NAVIGATOR
</h1>
<p class="text-lg md:text-xl text-gray-600 dark:text-gray-300 mb-10 max-w-2xl mx-auto font-sans">
Discover and explore high-quality AI projects from across the web. Curated for developers and enthusiasts.
</p>
<div class="max-w-2xl mx-auto relative group">
<div class="absolute -inset-1 bg-black dark:bg-primary rounded-lg blur opacity-25 group-hover:opacity-50 transition duration-200"></div>
<div class="relative flex items-center">
<div class="absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none">
<span class="material-icons text-gray-400">search</span>
</div>
<input class="block w-full pl-12 pr-4 py-4 bg-surface-light dark:bg-surface-dark border-2 border-black dark:border-gray-600 text-text-light dark:text-text-dark placeholder-gray-500 focus:ring-0 focus:border-black dark:focus:border-primary font-display shadow-neobrutalism transition-all" placeholder="Search AI projects..." type="text"/>
<button class="absolute inset-y-2 right-2 px-4 bg-primary text-black font-bold font-display text-sm border border-black hover:bg-yellow-400 transition-colors">
SEARCH
</button>
</div>
</div>
</section>
<section class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 mb-16">
<h2 class="font-display text-xl font-bold mb-6 border-b-2 border-black dark:border-gray-700 pb-2 inline-block">BROWSE BY TAGS</h2>
<div class="flex flex-wrap gap-3">
<a class="px-4 py-2 bg-white dark:bg-surface-dark border border-black dark:border-gray-500 font-display text-sm font-bold hover:bg-primary hover:text-black transition-colors shadow-neobrutalism-sm" href="#">
Coding Assistant <span class="ml-1 opacity-60 text-xs">2</span>
</a>
<a class="px-4 py-2 bg-white dark:bg-surface-dark border border-black dark:border-gray-500 font-display text-sm font-bold hover:bg-primary hover:text-black transition-colors shadow-neobrutalism-sm" href="#">
Chat AI <span class="ml-1 opacity-60 text-xs">2</span>
</a>
<a class="px-4 py-2 bg-white dark:bg-surface-dark border border-black dark:border-gray-500 font-display text-sm font-bold hover:bg-primary hover:text-black transition-colors shadow-neobrutalism-sm" href="#">
Data Analysis <span class="ml-1 opacity-60 text-xs">4</span>
</a>
<a class="px-4 py-2 bg-white dark:bg-surface-dark border border-black dark:border-gray-500 font-display text-sm font-bold hover:bg-primary hover:text-black transition-colors shadow-neobrutalism-sm" href="#">
Image Gen <span class="ml-1 opacity-60 text-xs">2</span>
</a>
<a class="px-4 py-2 bg-white dark:bg-surface-dark border border-black dark:border-gray-500 font-display text-sm font-bold hover:bg-primary hover:text-black transition-colors shadow-neobrutalism-sm" href="#">
Automation <span class="ml-1 opacity-60 text-xs">1</span>
</a>
<a class="px-4 py-2 bg-white dark:bg-surface-dark border border-black dark:border-gray-500 font-display text-sm font-bold hover:bg-primary hover:text-black transition-colors shadow-neobrutalism-sm" href="#">
LLMs <span class="ml-1 opacity-60 text-xs">8</span>
</a>
</div>
</section>
<section class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 pb-24">
<div class="flex items-end justify-between mb-8">
<h2 class="font-display text-3xl font-bold">FEATURED PROJECTS</h2>
<a class="hidden md:flex items-center font-display text-sm font-bold hover:underline" href="#">
VIEW ALL <span class="material-icons text-sm ml-1">arrow_forward</span>
</a>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
<article class="bg-white dark:bg-surface-dark border-2 border-black dark:border-gray-600 p-6 shadow-neobrutalism hover:shadow-neobrutalism-hover hover:-translate-y-1 transition-all duration-200 flex flex-col h-full">
<div class="flex justify-between items-start mb-4">
<h3 class="font-display text-2xl font-bold">n8n</h3>
<span class="material-icons text-gray-400">auto_awesome</span>
</div>
<p class="text-gray-600 dark:text-gray-300 mb-6 flex-grow font-sans leading-relaxed">
Open-source workflow automation tool. Connect various services and APIs through a visual interface to build complex automations without code.
</p>
<div class="mt-auto">
<div class="flex flex-wrap gap-2 mb-4">
<span class="bg-gray-100 dark:bg-gray-700 px-2 py-1 text-xs font-mono border border-black dark:border-gray-500">Automation</span>
<span class="bg-gray-100 dark:bg-gray-700 px-2 py-1 text-xs font-mono border border-black dark:border-gray-500">Workflow</span>
</div>
<a class="inline-flex items-center font-display font-bold text-sm hover:text-secondary dark:hover:text-primary group" href="#">
VIEW DETAILS
<span class="material-icons text-sm ml-1 transform group-hover:translate-x-1 transition-transform">arrow_forward</span>
</a>
</div>
</article>
<article class="bg-white dark:bg-surface-dark border-2 border-black dark:border-gray-600 p-6 shadow-neobrutalism hover:shadow-neobrutalism-hover hover:-translate-y-1 transition-all duration-200 flex flex-col h-full">
<div class="flex justify-between items-start mb-4">
<h3 class="font-display text-2xl font-bold">Stable Diffusion</h3>
<span class="material-icons text-gray-400">image</span>
</div>
<p class="text-gray-600 dark:text-gray-300 mb-6 flex-grow font-sans leading-relaxed">
Open-source image generation model. Supports local deployment and custom training, enabling powerful creative workflows.
</p>
<div class="mt-auto">
<div class="flex flex-wrap gap-2 mb-4">
<span class="bg-gray-100 dark:bg-gray-700 px-2 py-1 text-xs font-mono border border-black dark:border-gray-500">Image Gen</span>
<span class="bg-gray-100 dark:bg-gray-700 px-2 py-1 text-xs font-mono border border-black dark:border-gray-500">Open Source</span>
</div>
<a class="inline-flex items-center font-display font-bold text-sm hover:text-secondary dark:hover:text-primary group" href="#">
VIEW DETAILS
<span class="material-icons text-sm ml-1 transform group-hover:translate-x-1 transition-transform">arrow_forward</span>
</a>
</div>
</article>
<article class="bg-white dark:bg-surface-dark border-2 border-black dark:border-gray-600 p-6 shadow-neobrutalism hover:shadow-neobrutalism-hover hover:-translate-y-1 transition-all duration-200 flex flex-col h-full">
<div class="flex justify-between items-start mb-4">
<h3 class="font-display text-2xl font-bold">Midjourney</h3>
<span class="material-icons text-gray-400">palette</span>
</div>
<p class="text-gray-600 dark:text-gray-300 mb-6 flex-grow font-sans leading-relaxed">
Powerful AI image generation tool. Create exquisite images through text descriptions with industry-leading artistic quality.
</p>
<div class="mt-auto">
<div class="flex flex-wrap gap-2 mb-4">
<span class="bg-gray-100 dark:bg-gray-700 px-2 py-1 text-xs font-mono border border-black dark:border-gray-500">Image Gen</span>
<span class="bg-gray-100 dark:bg-gray-700 px-2 py-1 text-xs font-mono border border-black dark:border-gray-500">Art</span>
</div>
<a class="inline-flex items-center font-display font-bold text-sm hover:text-secondary dark:hover:text-primary group" href="#">
VIEW DETAILS
<span class="material-icons text-sm ml-1 transform group-hover:translate-x-1 transition-transform">arrow_forward</span>
</a>
</div>
</article>
<article class="bg-white dark:bg-surface-dark border-2 border-black dark:border-gray-600 p-6 shadow-neobrutalism hover:shadow-neobrutalism-hover hover:-translate-y-1 transition-all duration-200 flex flex-col h-full">
<div class="flex justify-between items-start mb-4">
<h3 class="font-display text-2xl font-bold">ChatGPT</h3>
<span class="material-icons text-gray-400">chat</span>
</div>
<p class="text-gray-600 dark:text-gray-300 mb-6 flex-grow font-sans leading-relaxed">
Large language model developed by OpenAI. Supports conversation, writing, coding, and a wide variety of tasks.
</p>
<div class="mt-auto">
<div class="flex flex-wrap gap-2 mb-4">
<span class="bg-gray-100 dark:bg-gray-700 px-2 py-1 text-xs font-mono border border-black dark:border-gray-500">Chat AI</span>
<span class="bg-gray-100 dark:bg-gray-700 px-2 py-1 text-xs font-mono border border-black dark:border-gray-500">Coding Assistant</span>
</div>
<a class="inline-flex items-center font-display font-bold text-sm hover:text-secondary dark:hover:text-primary group" href="#">
VIEW DETAILS
<span class="material-icons text-sm ml-1 transform group-hover:translate-x-1 transition-transform">arrow_forward</span>
</a>
</div>
</article>
<article class="bg-white dark:bg-surface-dark border-2 border-black dark:border-gray-600 p-6 shadow-neobrutalism hover:shadow-neobrutalism-hover hover:-translate-y-1 transition-all duration-200 flex flex-col h-full">
<div class="flex justify-between items-start mb-4">
<h3 class="font-display text-2xl font-bold">Claude</h3>
<span class="material-icons text-gray-400">psychology</span>
</div>
<p class="text-gray-600 dark:text-gray-300 mb-6 flex-grow font-sans leading-relaxed">
AI assistant developed by Anthropic. Excels at analysis, writing, and coding tasks with a focus on safety and reliability.
</p>
<div class="mt-auto">
<div class="flex flex-wrap gap-2 mb-4">
<span class="bg-gray-100 dark:bg-gray-700 px-2 py-1 text-xs font-mono border border-black dark:border-gray-500">Chat AI</span>
<span class="bg-gray-100 dark:bg-gray-700 px-2 py-1 text-xs font-mono border border-black dark:border-gray-500">Analysis</span>
</div>
<a class="inline-flex items-center font-display font-bold text-sm hover:text-secondary dark:hover:text-primary group" href="#">
VIEW DETAILS
<span class="material-icons text-sm ml-1 transform group-hover:translate-x-1 transition-transform">arrow_forward</span>
</a>
</div>
</article>
<article class="bg-primary border-2 border-black dark:border-gray-600 p-6 shadow-neobrutalism hover:shadow-neobrutalism-hover hover:-translate-y-1 transition-all duration-200 flex flex-col h-full justify-center items-center text-center">
<div class="bg-white p-4 rounded-full border border-black mb-4">
<span class="material-icons text-3xl text-black">add</span>
</div>
<h3 class="font-display text-2xl font-bold text-black mb-2">Submit Your Project</h3>
<p class="text-black mb-6 font-sans text-sm px-4">
Have an AI tool worth sharing? Add it to Agent Park.
</p>
<a class="bg-black text-white px-6 py-2 font-display text-sm font-bold border border-black hover:bg-white hover:text-black transition-colors" href="#">
SUBMIT NOW
</a>
</article>
</div>
<div class="mt-8 text-center md:hidden">
<a class="inline-flex items-center font-display text-sm font-bold border-b-2 border-black dark:border-white pb-1" href="#">
VIEW ALL PROJECTS <span class="material-icons text-sm ml-1">arrow_forward</span>
</a>
</div>
</section>
<section class="border-t-2 border-black dark:border-gray-600">
<div class="grid grid-cols-1 md:grid-cols-2">
<div class="bg-primary p-12 md:p-20 border-b md:border-b-0 md:border-r-2 border-black dark:border-gray-600 flex flex-col justify-center">
<h2 class="font-display text-4xl font-bold text-black mb-4">STAY UPDATED</h2>
<p class="font-sans text-black mb-8 max-w-md">
Get the latest AI tools and trends delivered straight to your inbox. No spam, just intelligence.
</p>
<form class="space-y-4 max-w-md">
<input class="w-full bg-background-light border border-black p-3 font-display text-sm placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-black" placeholder="E-mail" type="email"/>
<div class="flex items-center gap-2">
<input class="border-black text-black focus:ring-0" id="consent" type="checkbox"/>
<label class="text-xs font-bold font-display text-black" for="consent">Subscribe to Agent Park updates</label>
</div>
<button class="bg-white text-black font-display font-bold py-3 px-8 border border-black shadow-neobrutalism hover:translate-x-[2px] hover:translate-y-[2px] hover:shadow-none transition-all">
SUBSCRIBE
</button>
</form>
</div>
<div class="bg-background-light dark:bg-background-dark p-12 md:p-20 relative overflow-hidden flex items-center justify-center">
<div class="relative w-64 h-64">
<div class="absolute inset-0 border-2 border-black dark:border-gray-500 bg-white dark:bg-surface-dark transform rotate-3"></div>
<div class="absolute inset-0 border-2 border-black dark:border-gray-500 bg-primary transform -rotate-3 translate-x-4 translate-y-4 opacity-80 mix-blend-multiply dark:mix-blend-normal dark:opacity-50"></div>
<div class="absolute inset-0 flex items-center justify-center z-10">
<span class="material-icons text-8xl text-black dark:text-white">rocket_launch</span>
</div>
</div>
</div>
</div>
</section>
</main>
<footer class="bg-background-light dark:bg-background-dark border-t border-black dark:border-gray-700 py-12">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="grid grid-cols-2 md:grid-cols-4 gap-8 mb-12">
<div>
<h4 class="font-display font-bold text-lg mb-4">Agent Park</h4>
<ul class="space-y-2 text-sm font-sans text-gray-600 dark:text-gray-400">
<li><a class="hover:text-black dark:hover:text-white" href="#">About Us</a></li>
<li><a class="hover:text-black dark:hover:text-white" href="#">Contact</a></li>
<li><a class="hover:text-black dark:hover:text-white" href="#">Careers</a></li>
</ul>
</div>
<div>
<h4 class="font-display font-bold text-lg mb-4">Resources</h4>
<ul class="space-y-2 text-sm font-sans text-gray-600 dark:text-gray-400">
<li><a class="hover:text-black dark:hover:text-white" href="#">Blog</a></li>
<li><a class="hover:text-black dark:hover:text-white" href="#">Newsletter</a></li>
<li><a class="hover:text-black dark:hover:text-white" href="#">Documentation</a></li>
</ul>
</div>
<div>
<h4 class="font-display font-bold text-lg mb-4">Legal</h4>
<ul class="space-y-2 text-sm font-sans text-gray-600 dark:text-gray-400">
<li><a class="hover:text-black dark:hover:text-white" href="#">Privacy Policy</a></li>
<li><a class="hover:text-black dark:hover:text-white" href="#">Terms of Service</a></li>
</ul>
</div>
<div>
<h4 class="font-display font-bold text-lg mb-4">Follow Us</h4>
<div class="flex space-x-4">
<a class="w-10 h-10 border border-black dark:border-gray-500 flex items-center justify-center hover:bg-primary hover:text-black transition-colors" href="#">
<span class="font-display font-bold">X</span>
</a>
<a class="w-10 h-10 border border-black dark:border-gray-500 flex items-center justify-center hover:bg-primary hover:text-black transition-colors" href="#">
<span class="font-display font-bold">Li</span>
</a>
<a class="w-10 h-10 border border-black dark:border-gray-500 flex items-center justify-center hover:bg-primary hover:text-black transition-colors" href="#">
<span class="font-display font-bold">Gh</span>
</a>
</div>
</div>
</div>
<div class="border-t border-black dark:border-gray-700 pt-8 flex flex-col md:flex-row justify-between items-center">
<p class="text-sm text-gray-500 font-display">© 2025 Agent Park. All rights reserved.</p>
<div class="mt-4 md:mt-0 font-display text-sm font-bold">
DESIGNED FOR AI BUILDERS
</div>
</div>
</div>
</footer>
</body></html>
+335
View File
@@ -0,0 +1,335 @@
<!DOCTYPE html>
<html lang="en"><head>
<meta charset="utf-8"/>
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
<title>Agent Park - AI Project Navigator</title>
<script src="https://cdn.tailwindcss.com?plugins=forms,typography"></script>
<link href="https://fonts.googleapis.com/css2?family=Space+Mono:ital,wght@0,400;0,700;1,400&amp;family=Inter:wght@400;500;600;700&amp;display=swap" rel="stylesheet"/>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons+Outlined" rel="stylesheet"/>
<script>
tailwind.config = {
darkMode: "class",
theme: {
extend: {
colors: {
primary: "#FFD700", // Gold/Yellow from the screenshots
"background-light": "#F5F2EB", // Warm off-white/beige from screenshots
"background-dark": "#121212", // Dark mode background
"surface-light": "#FFFFFF",
"surface-dark": "#1E1E1E",
"border-light": "#000000",
"border-dark": "#333333",
"text-light": "#000000",
"text-dark": "#E0E0E0",
},
fontFamily: {
display: ["'Space Mono'", "monospace"], // Monospace for headings/brand
sans: ["'Inter'", "sans-serif"], // Clean sans for body
},
boxShadow: {
'neo': '4px 4px 0px 0px rgba(0,0,0,1)', // Brutalist shadow
'neo-sm': '2px 2px 0px 0px rgba(0,0,0,1)',
'neo-hover': '6px 6px 0px 0px rgba(0,0,0,1)',
'neo-dark': '4px 4px 0px 0px rgba(255,215,0,0.5)',
},
borderRadius: {
DEFAULT: "0px", // Sharp corners based on the design
},
},
},
};
</script>
<style>.border-thick {
border-width: 2px;
}
</style>
</head>
<body class="bg-background-light dark:bg-background-dark text-text-light dark:text-text-dark font-sans transition-colors duration-300">
<div class="bg-primary text-black text-xs font-display font-bold py-2 text-center border-b-2 border-black">
DISCOVER THE FUTURE OF AI AGENTS <span class="material-icons-outlined text-xs align-middle ml-1">arrow_forward</span>
</div>
<nav class="border-b-2 border-black dark:border-white/20 px-6 py-4 flex justify-between items-center bg-background-light dark:bg-background-dark sticky top-0 z-50">
<div class="flex items-center gap-2">
<span class="material-icons-outlined text-3xl dark:text-primary">smart_toy</span>
<span class="font-display font-bold text-xl tracking-tight">Agent Park</span>
</div>
<div class="hidden md:flex gap-8 font-display text-sm font-bold uppercase tracking-wide">
<a class="hover:underline decoration-2 underline-offset-4" href="#">Home</a>
<a class="underline decoration-2 underline-offset-4" href="#">Projects</a>
<a class="hover:underline decoration-2 underline-offset-4" href="#">Blog</a>
<a class="hover:underline decoration-2 underline-offset-4" href="#">About</a>
</div>
<div class="flex items-center gap-4">
<button class="p-2 hover:bg-black/5 dark:hover:bg-white/10 rounded-full transition-colors" onclick="document.documentElement.classList.toggle('dark')">
<span class="material-icons-outlined block dark:hidden">dark_mode</span>
<span class="material-icons-outlined hidden dark:block text-primary">light_mode</span>
</button>
<span class="font-display text-xs font-bold hidden sm:inline">中文 / EN</span>
<a class="font-display text-xs font-bold border-2 border-black dark:border-white px-4 py-2 hover:bg-black hover:text-white dark:hover:bg-white dark:hover:text-black transition-all shadow-neo-sm hover:shadow-none hover:translate-x-[2px] hover:translate-y-[2px]" href="#">
SUBMIT PROJECT
</a>
</div>
</nav>
<main class="container mx-auto px-4 py-12 md:py-16 max-w-7xl relative">
<div class="absolute top-10 left-0 w-24 h-24 border-2 border-black dark:border-white/20 rounded-full opacity-20 pointer-events-none hidden lg:block"></div>
<div class="absolute top-20 right-10 w-32 h-20 border-2 border-black dark:border-white/20 rounded-[2rem] opacity-20 pointer-events-none transform rotate-12 hidden lg:block"></div>
<div class="text-center mb-16 relative z-10">
<h1 class="font-display text-5xl md:text-7xl font-bold mb-6 leading-tight tracking-tighter">
PROJECT <br class="md:hidden"/>NAVIGATOR
</h1>
<p class="text-lg md:text-xl text-gray-600 dark:text-gray-300 max-w-2xl mx-auto font-light leading-relaxed">
Discover and explore high-quality AI projects from across the web. <br class="hidden md:inline"/>Curated for developers and enthusiasts.
</p>
</div>
<div class="bg-surface-light dark:bg-surface-dark border-2 border-black dark:border-white/20 p-6 md:p-8 mb-12 shadow-neo dark:shadow-none">
<div class="flex flex-col md:flex-row gap-4 mb-8">
<div class="relative flex-grow">
<span class="material-icons-outlined absolute left-4 top-1/2 transform -translate-y-1/2 text-gray-400">search</span>
<input class="w-full pl-12 pr-4 py-3 bg-white dark:bg-black border-2 border-black dark:border-white/30 focus:border-primary focus:ring-0 font-display text-sm placeholder-gray-500" placeholder="Search AI projects..." type="text"/>
</div>
<div class="relative md:w-1/4">
<select class="w-full pl-4 pr-10 py-3 bg-white dark:bg-black border-2 border-black dark:border-white/30 focus:border-primary focus:ring-0 font-display text-sm appearance-none cursor-pointer">
<option>All Categories</option>
<option>Coding Assistant</option>
<option>Image Generation</option>
<option>Automation</option>
<option>LLMs</option>
</select>
<span class="material-icons-outlined absolute right-3 top-1/2 transform -translate-y-1/2 pointer-events-none text-gray-500">expand_more</span>
</div>
<button class="bg-primary border-2 border-black px-8 py-3 font-display font-bold text-sm uppercase hover:bg-yellow-400 transition-colors shadow-neo-sm active:shadow-none active:translate-x-[2px] active:translate-y-[2px] text-black">
Search
</button>
</div>
<div class="border-t-2 border-gray-100 dark:border-gray-800 pt-6">
<h3 class="font-display font-bold uppercase text-sm mb-4 border-b-2 border-black inline-block dark:border-primary pb-1">Browse by Tags</h3>
<div class="flex flex-wrap gap-3">
<button class="px-3 py-1 border border-black dark:border-white/40 bg-white dark:bg-transparent font-display text-xs hover:bg-black hover:text-white dark:hover:bg-primary dark:hover:text-black transition-colors flex items-center gap-2 group">
Coding Assistant <span class="bg-gray-200 dark:bg-gray-800 dark:group-hover:bg-black/20 px-1.5 py-0.5 text-[10px] rounded-sm group-hover:bg-white group-hover:text-black">12</span>
</button>
<button class="px-3 py-1 border border-black dark:border-white/40 bg-white dark:bg-transparent font-display text-xs hover:bg-black hover:text-white dark:hover:bg-primary dark:hover:text-black transition-colors flex items-center gap-2 group">
Chat AI <span class="bg-gray-200 dark:bg-gray-800 dark:group-hover:bg-black/20 px-1.5 py-0.5 text-[10px] rounded-sm group-hover:bg-white group-hover:text-black">8</span>
</button>
<button class="px-3 py-1 border border-black dark:border-white/40 bg-black text-white dark:bg-primary dark:text-black font-display text-xs transition-colors flex items-center gap-2">
Data Analysis <span class="bg-gray-700 text-white dark:bg-black/20 dark:text-black px-1.5 py-0.5 text-[10px] rounded-sm">4</span>
</button>
<button class="px-3 py-1 border border-black dark:border-white/40 bg-white dark:bg-transparent font-display text-xs hover:bg-black hover:text-white dark:hover:bg-primary dark:hover:text-black transition-colors flex items-center gap-2 group">
Image Gen <span class="bg-gray-200 dark:bg-gray-800 dark:group-hover:bg-black/20 px-1.5 py-0.5 text-[10px] rounded-sm group-hover:bg-white group-hover:text-black">21</span>
</button>
<button class="px-3 py-1 border border-black dark:border-white/40 bg-white dark:bg-transparent font-display text-xs hover:bg-black hover:text-white dark:hover:bg-primary dark:hover:text-black transition-colors flex items-center gap-2 group">
Automation <span class="bg-gray-200 dark:bg-gray-800 dark:group-hover:bg-black/20 px-1.5 py-0.5 text-[10px] rounded-sm group-hover:bg-white group-hover:text-black">15</span>
</button>
<button class="px-3 py-1 border border-black dark:border-white/40 bg-white dark:bg-transparent font-display text-xs hover:bg-black hover:text-white dark:hover:bg-primary dark:hover:text-black transition-colors flex items-center gap-2 group">
LLMs <span class="bg-gray-200 dark:bg-gray-800 dark:group-hover:bg-black/20 px-1.5 py-0.5 text-[10px] rounded-sm group-hover:bg-white group-hover:text-black">34</span>
</button>
</div>
</div>
</div>
<div class="flex justify-between items-end mb-8 border-b border-black dark:border-white/20 pb-4">
<h2 class="font-display font-bold text-3xl uppercase tracking-tight">Featured Projects</h2>
<a class="font-display text-xs font-bold uppercase flex items-center gap-1 hover:text-gray-600 dark:hover:text-primary transition-colors" href="#">
View All <span class="material-icons-outlined text-sm">arrow_forward</span>
</a>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
<div class="col-span-1 md:col-span-2 bg-purple-200 dark:bg-purple-900/30 border-2 border-black dark:border-white/20 p-0 flex flex-col md:flex-row shadow-neo hover:shadow-neo-hover hover:-translate-y-1 transition-all duration-300 group overflow-hidden">
<div class="p-8 flex-1 flex flex-col justify-between relative z-10">
<div>
<div class="flex justify-between items-start mb-4">
<span class="bg-black text-white dark:bg-white dark:text-black font-display text-xs px-2 py-1 font-bold">TOP PICK</span>
<span class="material-icons-outlined text-2xl group-hover:rotate-12 transition-transform">auto_awesome</span>
</div>
<h3 class="font-display font-bold text-3xl mb-3">AutoGPT X</h3>
<p class="text-sm md:text-base mb-6 leading-relaxed opacity-90">
An experimental open-source application showcasing the capabilities of the GPT-4 language model. This program, driven by GPT-4, chains together LLM "thoughts", to autonomously achieve whatever goal you set.
</p>
<div class="flex gap-2 flex-wrap mb-6">
<span class="border border-black dark:border-white/50 px-2 py-1 text-[10px] uppercase font-display font-bold bg-white/50 dark:bg-black/50">Automation</span>
<span class="border border-black dark:border-white/50 px-2 py-1 text-[10px] uppercase font-display font-bold bg-white/50 dark:bg-black/50">Agent</span>
</div>
</div>
<a class="inline-flex items-center font-display font-bold text-sm uppercase group-hover:translate-x-2 transition-transform" href="#">
View Details <span class="material-icons-outlined ml-1 text-base">arrow_forward</span>
</a>
</div>
<div class="w-full md:w-2/5 bg-purple-300 dark:bg-purple-800/50 border-t-2 md:border-t-0 md:border-l-2 border-black dark:border-white/20 relative overflow-hidden flex items-center justify-center min-h-[200px]">
<div class="absolute inset-0 bg-[radial-gradient(circle_at_center,_var(--tw-gradient-stops))] from-white/40 to-transparent"></div>
<span class="material-icons-outlined text-9xl opacity-20 rotate-12">psychology</span>
</div>
</div>
<div class="bg-white dark:bg-surface-dark border-2 border-black dark:border-white/20 p-6 shadow-neo hover:shadow-neo-hover hover:-translate-y-1 transition-all duration-300 flex flex-col justify-between group">
<div>
<div class="flex justify-between items-start mb-4 text-gray-400">
<span class="material-icons-outlined text-3xl text-black dark:text-white">hub</span>
</div>
<h3 class="font-display font-bold text-2xl mb-3">n8n</h3>
<p class="text-sm text-gray-600 dark:text-gray-400 mb-6 leading-relaxed">
Open-source workflow automation tool. Connect various services and APIs through a visual interface to build complex automations without code.
</p>
</div>
<div>
<div class="flex gap-2 flex-wrap mb-6">
<span class="bg-gray-100 dark:bg-gray-800 border border-gray-300 dark:border-gray-600 px-2 py-1 text-[10px] uppercase font-display font-bold text-gray-600 dark:text-gray-300">Automation</span>
<span class="bg-gray-100 dark:bg-gray-800 border border-gray-300 dark:border-gray-600 px-2 py-1 text-[10px] uppercase font-display font-bold text-gray-600 dark:text-gray-300">Workflow</span>
</div>
<a class="inline-flex items-center font-display font-bold text-sm uppercase border-b-2 border-transparent hover:border-primary transition-colors pb-0.5" href="#">
View Details <span class="material-icons-outlined ml-1 text-sm">arrow_forward</span>
</a>
</div>
</div>
<div class="bg-white dark:bg-surface-dark border-2 border-black dark:border-white/20 p-6 shadow-neo hover:shadow-neo-hover hover:-translate-y-1 transition-all duration-300 flex flex-col justify-between group">
<div>
<div class="flex justify-between items-start mb-4 text-gray-400">
<span class="material-icons-outlined text-3xl text-black dark:text-white">image</span>
</div>
<h3 class="font-display font-bold text-2xl mb-3">Stable Diffusion</h3>
<p class="text-sm text-gray-600 dark:text-gray-400 mb-6 leading-relaxed">
Open-source image generation model. Supports local deployment and custom training, enabling powerful creative workflows.
</p>
</div>
<div>
<div class="flex gap-2 flex-wrap mb-6">
<span class="bg-gray-100 dark:bg-gray-800 border border-gray-300 dark:border-gray-600 px-2 py-1 text-[10px] uppercase font-display font-bold text-gray-600 dark:text-gray-300">Image Gen</span>
<span class="bg-gray-100 dark:bg-gray-800 border border-gray-300 dark:border-gray-600 px-2 py-1 text-[10px] uppercase font-display font-bold text-gray-600 dark:text-gray-300">Open Source</span>
</div>
<a class="inline-flex items-center font-display font-bold text-sm uppercase border-b-2 border-transparent hover:border-primary transition-colors pb-0.5" href="#">
View Details <span class="material-icons-outlined ml-1 text-sm">arrow_forward</span>
</a>
</div>
</div>
<div class="bg-white dark:bg-surface-dark border-2 border-black dark:border-white/20 p-6 shadow-neo hover:shadow-neo-hover hover:-translate-y-1 transition-all duration-300 flex flex-col justify-between group">
<div>
<div class="flex justify-between items-start mb-4 text-gray-400">
<span class="material-icons-outlined text-3xl text-black dark:text-white">palette</span>
</div>
<h3 class="font-display font-bold text-2xl mb-3">Midjourney</h3>
<p class="text-sm text-gray-600 dark:text-gray-400 mb-6 leading-relaxed">
Powerful AI image generation tool. Create exquisite images through text descriptions with industry-leading artistic quality.
</p>
</div>
<div>
<div class="flex gap-2 flex-wrap mb-6">
<span class="bg-gray-100 dark:bg-gray-800 border border-gray-300 dark:border-gray-600 px-2 py-1 text-[10px] uppercase font-display font-bold text-gray-600 dark:text-gray-300">Image Gen</span>
<span class="bg-gray-100 dark:bg-gray-800 border border-gray-300 dark:border-gray-600 px-2 py-1 text-[10px] uppercase font-display font-bold text-gray-600 dark:text-gray-300">Art</span>
</div>
<a class="inline-flex items-center font-display font-bold text-sm uppercase border-b-2 border-transparent hover:border-primary transition-colors pb-0.5" href="#">
View Details <span class="material-icons-outlined ml-1 text-sm">arrow_forward</span>
</a>
</div>
</div>
<div class="bg-white dark:bg-surface-dark border-2 border-black dark:border-white/20 p-6 shadow-neo hover:shadow-neo-hover hover:-translate-y-1 transition-all duration-300 flex flex-col justify-between group">
<div>
<div class="flex justify-between items-start mb-4 text-gray-400">
<span class="material-icons-outlined text-3xl text-black dark:text-white">chat</span>
</div>
<h3 class="font-display font-bold text-2xl mb-3">ChatGPT</h3>
<p class="text-sm text-gray-600 dark:text-gray-400 mb-6 leading-relaxed">
Large language model developed by OpenAI. Supports conversation, writing, coding, and a wide variety of tasks.
</p>
</div>
<div>
<div class="flex gap-2 flex-wrap mb-6">
<span class="bg-gray-100 dark:bg-gray-800 border border-gray-300 dark:border-gray-600 px-2 py-1 text-[10px] uppercase font-display font-bold text-gray-600 dark:text-gray-300">Chat AI</span>
<span class="bg-gray-100 dark:bg-gray-800 border border-gray-300 dark:border-gray-600 px-2 py-1 text-[10px] uppercase font-display font-bold text-gray-600 dark:text-gray-300">Assistant</span>
</div>
<a class="inline-flex items-center font-display font-bold text-sm uppercase border-b-2 border-transparent hover:border-primary transition-colors pb-0.5" href="#">
View Details <span class="material-icons-outlined ml-1 text-sm">arrow_forward</span>
</a>
</div>
</div>
<div class="bg-primary dark:bg-primary border-2 border-black dark:border-black p-6 shadow-neo hover:shadow-neo-hover hover:-translate-y-1 transition-all duration-300 flex flex-col justify-center items-center text-center group">
<div class="bg-white dark:bg-black rounded-full w-12 h-12 flex items-center justify-center border-2 border-black mb-4">
<span class="material-icons-outlined text-2xl dark:text-primary">add</span>
</div>
<h3 class="font-display font-bold text-2xl mb-2 text-black">Submit Your Project</h3>
<p class="text-sm text-black mb-6 leading-relaxed px-4 font-medium">
Have an AI tool worth sharing? Add it to Agent Park.
</p>
<button class="bg-black text-white dark:bg-black dark:text-primary border-2 border-black dark:border-black px-6 py-2 font-display text-sm font-bold uppercase hover:bg-white hover:text-black dark:hover:bg-white dark:hover:text-black transition-colors">
Submit Now
</button>
</div>
</div>
<div class="mt-16 flex justify-center">
<div class="flex border-2 border-black dark:border-white/20 bg-white dark:bg-surface-dark shadow-neo dark:shadow-none">
<button class="px-4 py-2 border-r border-black dark:border-white/20 hover:bg-gray-100 dark:hover:bg-white/10 transition-colors disabled:opacity-50">
<span class="material-icons-outlined text-sm">arrow_back</span>
</button>
<button class="px-4 py-2 font-display font-bold text-sm bg-primary border-r border-black dark:border-white/20 text-black">1</button>
<button class="px-4 py-2 font-display font-bold text-sm border-r border-black dark:border-white/20 hover:bg-gray-100 dark:hover:bg-white/10 transition-colors">2</button>
<button class="px-4 py-2 font-display font-bold text-sm border-r border-black dark:border-white/20 hover:bg-gray-100 dark:hover:bg-white/10 transition-colors">3</button>
<button class="px-4 py-2 hover:bg-gray-100 dark:hover:bg-white/10 transition-colors">
<span class="material-icons-outlined text-sm">arrow_forward</span>
</button>
</div>
</div>
</main>
<section class="border-t-2 border-black dark:border-white/20 flex flex-col md:flex-row">
<div class="w-full md:w-1/2 bg-primary dark:bg-yellow-600 p-12 md:p-20 border-b-2 md:border-b-0 md:border-r-2 border-black dark:border-white/20">
<h2 class="font-display font-bold text-4xl mb-4 text-black">STAY UPDATED</h2>
<p class="text-black mb-8 font-medium max-w-md">
Get the latest AI tools and trends delivered straight to your inbox. No spam, just intelligence.
</p>
<form class="flex flex-col gap-4 max-w-md">
<input class="w-full px-4 py-3 bg-white border-2 border-black font-display text-sm placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-black" placeholder="E-mail" type="email"/>
<div class="flex items-center gap-2">
<input class="w-4 h-4 border-2 border-black text-black focus:ring-0" id="newsletter-check" type="checkbox"/>
<label class="text-xs font-bold font-display uppercase text-black" for="newsletter-check">Subscribe to Agent Park updates</label>
</div>
<button class="w-32 bg-white text-black border-2 border-black px-6 py-3 font-display font-bold uppercase hover:bg-black hover:text-white transition-colors shadow-[4px_4px_0px_0px_rgba(0,0,0,1)] hover:shadow-none hover:translate-x-[2px] hover:translate-y-[2px]" type="submit">
Subscribe
</button>
</form>
</div>
<div class="w-full md:w-1/2 bg-background-light dark:bg-background-dark p-12 md:p-20 flex items-center justify-center relative overflow-hidden">
<div class="relative w-64 h-64">
<div class="absolute inset-0 border-2 border-black dark:border-white bg-white dark:bg-surface-dark transform rotate-3 z-10 flex items-center justify-center">
<span class="material-icons-outlined text-8xl text-black dark:text-white">rocket_launch</span>
</div>
<div class="absolute inset-0 border-2 border-black dark:border-white bg-primary dark:bg-primary transform -rotate-3 translate-x-2 translate-y-2 z-0"></div>
</div>
</div>
</section>
<footer class="bg-background-light dark:bg-background-dark pt-16 pb-8 border-t-2 border-black dark:border-white/20">
<div class="container mx-auto px-6 max-w-7xl">
<div class="grid grid-cols-1 md:grid-cols-4 gap-12 mb-16">
<div>
<h3 class="font-display font-bold text-xl mb-6">Agent Park</h3>
<ul class="space-y-3 text-sm text-gray-600 dark:text-gray-400">
<li><a class="hover:underline" href="#">About Us</a></li>
<li><a class="hover:underline" href="#">Contact</a></li>
<li><a class="hover:underline" href="#">Careers</a></li>
</ul>
</div>
<div>
<h3 class="font-display font-bold text-xl mb-6">Resources</h3>
<ul class="space-y-3 text-sm text-gray-600 dark:text-gray-400">
<li><a class="hover:underline" href="#">Blog</a></li>
<li><a class="hover:underline" href="#">Newsletter</a></li>
<li><a class="hover:underline" href="#">Documentation</a></li>
</ul>
</div>
<div>
<h3 class="font-display font-bold text-xl mb-6">Legal</h3>
<ul class="space-y-3 text-sm text-gray-600 dark:text-gray-400">
<li><a class="hover:underline" href="#">Privacy Policy</a></li>
<li><a class="hover:underline" href="#">Terms of Service</a></li>
</ul>
</div>
<div>
<h3 class="font-display font-bold text-xl mb-6">Follow Us</h3>
<div class="flex gap-4">
<a class="w-10 h-10 border border-black dark:border-white flex items-center justify-center hover:bg-black hover:text-white dark:hover:bg-white dark:hover:text-black transition-colors font-display font-bold" href="#">X</a>
<a class="w-10 h-10 border border-black dark:border-white flex items-center justify-center hover:bg-black hover:text-white dark:hover:bg-white dark:hover:text-black transition-colors font-display font-bold" href="#">Li</a>
<a class="w-10 h-10 border border-black dark:border-white flex items-center justify-center hover:bg-black hover:text-white dark:hover:bg-white dark:hover:text-black transition-colors font-display font-bold" href="#">Gh</a>
</div>
</div>
</div>
<div class="border-t border-black/20 dark:border-white/20 pt-8 flex flex-col md:flex-row justify-between items-center gap-4">
<p class="font-display text-xs text-gray-500">© 2025 Agent Park. All rights reserved.</p>
<p class="font-display text-xs font-bold uppercase tracking-wider">Designed for AI Builders</p>
</div>
</div>
</footer>
</body></html>
+152 -28
View File
@@ -1,6 +1,6 @@
import { notFound } from "next/navigation"
import { getRequestConfig } from 'next-intl/server'
import { setRequestLocale } from 'next-intl/server'
import Link from "next/link"
const locales = ['zh', 'en']
@@ -24,36 +24,160 @@ export default async function LocaleLayout({
return (
<div className="min-h-screen flex flex-col">
<header className="border-b">
<div className="container mx-auto px-4 py-4">
<nav className="flex items-center justify-between">
<a href={`/${locale}`} className="text-xl font-semibold">
Agent Park
</a>
<div className="flex items-center gap-4">
<a href={`/${locale}`} className="text-sm hover:underline">
</a>
<a href={`/${locale}/projects`} className="text-sm hover:underline">
</a>
<div className="flex gap-2 text-sm">
<a href="/zh" className={locale === 'zh' ? 'font-semibold' : 'hover:underline'}>
</a>
<span>/</span>
<a href="/en" className={locale === 'en' ? 'font-semibold' : 'hover:underline'}>
EN
</a>
</div>
{/* Top announcement bar */}
<div className="bg-primary w-full py-2 px-4 border-b-2 border-black dark:border-gray-600 flex justify-center items-center text-xs font-bold font-display tracking-wide text-black">
<span>DISCOVER THE FUTURE OF AI AGENTS</span>
<span className="material-icons text-sm align-middle ml-1">arrow_forward</span>
</div>
{/* Navigation */}
<header className="w-full border-b-2 border-black dark:border-gray-600 bg-background-light dark:bg-background-dark sticky top-0 z-50">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex justify-between items-center h-16">
{/* Logo */}
<div className="flex-shrink-0 flex items-center gap-2">
<span className="material-icons text-3xl">smart_toy</span>
<Link href={`/${locale}`} className="font-display font-bold text-xl tracking-tight">
Agent Park
</Link>
</div>
</nav>
{/* Desktop Nav */}
<nav className="hidden md:flex space-x-8 items-center">
<Link
className="font-display text-sm font-bold hover:text-secondary dark:hover:text-primary transition-colors"
href={`/${locale}`}
>
HOME
</Link>
<Link
className="font-display text-sm font-bold hover:text-secondary dark:hover:text-primary transition-colors"
href={`/${locale}/projects`}
>
PROJECTS
</Link>
<Link
className="font-display text-sm font-bold hover:text-secondary dark:hover:text-primary transition-colors"
href="#"
>
BLOG
</Link>
<Link
className="font-display text-sm font-bold hover:text-secondary dark:hover:text-primary transition-colors"
href="#"
>
ABOUT
</Link>
</nav>
{/* Right side */}
<div className="hidden md:flex items-center space-x-4">
<button className="font-display text-sm font-bold hover:opacity-70">
/ EN
</button>
<Link
className="bg-white dark:bg-surface-dark border-2 border-black dark:border-white px-4 py-2 font-display text-sm font-bold shadow-neo-sm hover:shadow-none hover:translate-x-[2px] hover:translate-y-[2px] transition-all"
href="#"
>
SUBMIT PROJECT
</Link>
</div>
{/* Mobile menu button */}
<div className="md:hidden flex items-center">
<button className="text-text-light dark:text-text-dark hover:text-gray-600 focus:outline-none">
<span className="material-icons">menu</span>
</button>
</div>
</div>
</div>
</header>
<main className="flex-1">{children}</main>
<footer className="border-t py-6">
<div className="container mx-auto px-4 text-center text-sm text-muted-foreground">
© 2025 Agent Park. All rights reserved.
<main className="flex-1 relative">{children}</main>
{/* Newsletter Section */}
<section className="border-t-2 border-black dark:border-gray-600">
<div className="grid grid-cols-1 md:grid-cols-2">
<div className="bg-primary dark:bg-yellow-600 p-12 md:p-20 border-b-2 md:border-b-0 md:border-r-2 border-black dark:border-gray-600 flex flex-col justify-center">
<h2 className="font-display text-4xl font-bold text-black mb-4">STAY UPDATED</h2>
<p className="font-sans text-black mb-8 max-w-md">
Get the latest AI tools and trends delivered straight to your inbox. No spam, just intelligence.
</p>
<form className="space-y-4 max-w-md">
<input
className="w-full bg-background-light border-2 border-black p-3 font-display text-sm placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-black"
placeholder="E-mail"
type="email"
/>
<div className="flex items-center gap-2">
<input className="w-4 h-4 border-2 border-black text-black focus:ring-0" id="consent" type="checkbox" />
<label className="text-xs font-bold font-display text-black" htmlFor="consent">
Subscribe to Agent Park updates
</label>
</div>
<button
className="bg-white text-black font-display font-bold py-3 px-8 border-2 border-black shadow-neo hover:shadow-none hover:translate-x-[2px] hover:translate-y-[2px] transition-all"
type="submit"
>
SUBSCRIBE
</button>
</form>
</div>
<div className="bg-background-light dark:bg-background-dark p-12 md:p-20 relative overflow-hidden flex items-center justify-center">
<div className="relative w-64 h-64">
<div className="absolute inset-0 border-2 border-black dark:border-gray-500 bg-white dark:bg-surface-dark transform rotate-3"></div>
<div className="absolute inset-0 border-2 border-black dark:border-gray-500 bg-primary dark:bg-primary transform -rotate-3 translate-x-4 translate-y-4 opacity-80"></div>
<div className="absolute inset-0 flex items-center justify-center z-10">
<span className="material-icons text-8xl">rocket_launch</span>
</div>
</div>
</div>
</div>
</section>
{/* Footer */}
<footer className="bg-background-light dark:bg-background-dark border-t-2 border-black dark:border-gray-700 py-12">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="grid grid-cols-2 md:grid-cols-4 gap-8 mb-12">
<div className="col-span-1 md:col-span-1">
<Link className="flex items-center gap-2 mb-4" href={`/${locale}`}>
<span className="material-icons text-2xl">smart_toy</span>
<span className="font-display font-bold text-lg tracking-tight">Agent Park</span>
</Link>
<p className="text-sm text-gray-600 dark:text-gray-400">
Discover and explore high-quality AI projects from across the web. Curated for developers and enthusiasts.
</p>
</div>
<div>
<h4 className="font-display font-bold text-lg mb-4">Resources</h4>
<ul className="space-y-2 text-sm font-sans text-gray-600 dark:text-gray-400">
<li><Link className="hover:text-black dark:hover:text-white" href="#">Blog</Link></li>
<li><Link className="hover:text-black dark:hover:text-white" href="#">Newsletter</Link></li>
<li><Link className="hover:text-black dark:hover:text-white" href="#">Documentation</Link></li>
</ul>
</div>
<div>
<h4 className="font-display font-bold text-lg mb-4">Legal</h4>
<ul className="space-y-2 text-sm font-sans text-gray-600 dark:text-gray-400">
<li><Link className="hover:text-black dark:hover:text-white" href="#">Privacy Policy</Link></li>
<li><Link className="hover:text-black dark:hover:text-white" href="#">Terms of Service</Link></li>
</ul>
</div>
<div>
<h4 className="font-display font-bold text-lg mb-4">Follow Us</h4>
<div className="flex space-x-4">
<Link className="w-10 h-10 border-2 border-black dark:border-gray-500 flex items-center justify-center hover:bg-primary hover:text-black transition-colors font-display font-bold" href="#">X</Link>
<Link className="w-10 h-10 border-2 border-black dark:border-gray-500 flex items-center justify-center hover:bg-primary hover:text-black transition-colors font-display font-bold" href="#">Li</Link>
<Link className="w-10 h-10 border-2 border-black dark:border-gray-500 flex items-center justify-center hover:bg-primary hover:text-black transition-colors font-display font-bold" href="#">Gh</Link>
</div>
</div>
</div>
<div className="border-t border-black dark:border-gray-700 pt-8 flex flex-col md:flex-row justify-between items-center">
<p className="text-sm text-gray-500 font-display">© 2025 Agent Park. All rights reserved.</p>
<div className="mt-4 md:mt-0 font-display text-sm font-bold">
DESIGNED FOR AI BUILDERS
</div>
</div>
</div>
</footer>
</div>
+42 -15
View File
@@ -3,6 +3,7 @@ import { getProjects, getAllTags } from '@/hooks/useProjects'
import { ProjectList } from '@/components/project/ProjectList'
import { TagCloud } from '@/components/project/TagCloud'
import { SearchBar } from '@/components/search/SearchBar'
import { Suspense } from 'react'
interface HomePageProps {
params: Promise<{ locale: string }>
@@ -18,24 +19,50 @@ export default async function HomePage({ params }: HomePageProps) {
])
return (
<div className="container mx-auto px-4 py-8">
<div className="text-center mb-12">
<h1 className="text-4xl font-bold mb-4">{t('title')}</h1>
<p className="text-lg text-muted-foreground">{t('subtitle')}</p>
</div>
<>
{/* Hero Section with floating shapes */}
<main className="relative overflow-hidden">
<div className="absolute top-20 left-10 w-24 h-24 border-2 border-black dark:border-gray-600 rounded-full opacity-20 animate-float hidden lg:block"></div>
<div className="absolute top-40 right-20 w-32 h-20 border-2 border-black dark:border-gray-600 rounded-[2rem] transform -rotate-12 opacity-20 animate-float hidden lg:block" style={{ animationDelay: '1s' }}></div>
<SearchBar locale={locale} />
<section className="max-w-4xl mx-auto px-4 py-20 text-center relative z-10">
<h1 className="font-display text-5xl md:text-7xl font-bold mb-6 tracking-tight leading-tight">
AI PROJECT <br className="hidden md:block" />NAVIGATOR
</h1>
<p className="text-lg md:text-xl text-gray-600 dark:text-gray-300 mb-10 max-w-2xl mx-auto font-sans">
Discover and explore high-quality AI projects from across the web. Curated for developers and enthusiasts.
</p>
<Suspense fallback={<div className="h-16"></div>}>
<SearchBar locale={locale} />
</Suspense>
</section>
<div className="mb-12">
<h2 className="text-2xl font-semibold mb-4">{t('browseByTag')}</h2>
<TagCloud tags={tags} locale={locale} />
</div>
{/* Browse by Tags Section */}
<section className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 mb-16">
<h2 className="font-display text-xl font-bold mb-6 border-b-2 border-black dark:border-gray-700 pb-2 inline-block">
BROWSE BY TAGS
</h2>
<TagCloud tags={tags} locale={locale} />
</section>
<div>
<h2 className="text-2xl font-semibold mb-6">{t('featuredProjects')}</h2>
<ProjectList projects={projectsData.projects} locale={locale} />
</div>
</div>
{/* Featured Projects Section */}
<section className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 pb-24">
<div className="flex items-end justify-between mb-8">
<h2 className="font-display text-3xl font-bold">FEATURED PROJECTS</h2>
<a className="hidden md:flex items-center font-display text-sm font-bold hover:underline" href={`/${locale}/projects`}>
VIEW ALL <span className="ml-1"></span>
</a>
</div>
<ProjectList projects={projectsData.projects} locale={locale} featured />
<div className="mt-8 text-center md:hidden">
<a className="inline-flex items-center font-display text-sm font-bold border-b-2 border-black dark:border-white pb-1" href={`/${locale}/projects`}>
VIEW ALL PROJECTS <span className="ml-1"></span>
</a>
</div>
</section>
</main>
</>
)
}
+62 -38
View File
@@ -1,6 +1,8 @@
import { notFound } from 'next/navigation'
import { getProjectBySlug } from '@/hooks/useProjects'
import { ExternalLinkCard } from '@/components/project/ExternalLinkCard'
import { getProjectBySlug, getProjects } from '@/hooks/useProjects'
import { ProjectDetail } from '@/components/project/ProjectDetail'
import { ProjectSidebar } from '@/components/project/ProjectSidebar'
import { RelatedProjects } from '@/components/project/RelatedProjects'
interface ProjectDetailPageProps {
params: Promise<{ locale: string; id: string }>
@@ -9,60 +11,82 @@ interface ProjectDetailPageProps {
export default async function ProjectDetailPage({
params,
}: ProjectDetailPageProps) {
const { locale, id } = await params
const resolvedParams = await params
const { locale, id } = resolvedParams
// Get project by slug
const project = await getProjectBySlug(id)
if (!project) {
notFound()
}
// Get related projects (same tags, excluding current project)
const relatedProjectsResult = await getProjects({
limit: 3,
})
const relatedProjects = relatedProjectsResult.projects
.filter(p => p.id !== project.id)
.filter(p => p.tags.some(t => project.tags.some(pt => pt.id === t.id)))
.slice(0, 3)
return (
<div className="container mx-auto px-4 py-8">
<div className="max-w-4xl mx-auto">
<main className="min-h-screen bg-background-light dark:bg-background-dark text-text-light dark:text-text-dark font-body transition-colors duration-200">
<div className="container mx-auto px-4 sm:px-6 lg:px-8 py-12">
{/* Back Button */}
<div className="mb-8">
<a
className="inline-flex items-center text-sm font-display font-bold text-gray-500 hover:text-black dark:text-gray-400 dark:hover:text-white transition-colors group"
href={`/${locale}/projects`}
className="text-primary hover:underline text-sm"
>
<span className="material-icons text-base mr-1 group-hover:-translate-x-1 transition-transform">
arrow_back
</span>
BACK TO PROJECTS
</a>
</div>
<div className="mb-8">
<h1 className="text-3xl font-bold mb-4">{project.name}</h1>
{project.nameEn && (
<h2 className="text-xl text-muted-foreground mb-4">{project.nameEn}</h2>
)}
<p className="text-lg text-muted-foreground">{project.description}</p>
{/* Main Grid Layout */}
<div className="grid grid-cols-1 lg:grid-cols-12 gap-12">
{/* Main Content (8 columns) */}
<div className="lg:col-span-8">
<ProjectDetail project={project} locale={locale} />
</div>
{/* Sidebar (4 columns) */}
<aside className="lg:col-span-4">
<ProjectSidebar project={project} locale={locale} />
</aside>
</div>
{project.content && (
<div className="mb-8">
<h3 className="text-xl font-semibold mb-4"></h3>
<div className="prose max-w-none">
<p>{project.content}</p>
</div>
</div>
)}
<div className="mb-8">
<h3 className="text-xl font-semibold mb-4"></h3>
<div className="flex flex-wrap gap-2">
{project.tags.map((tag) => (
<span
key={tag.id}
className="inline-flex items-center px-3 py-1 rounded-full text-sm bg-secondary text-secondary-foreground"
>
{tag.name}
</span>
))}
</div>
</div>
<ExternalLinkCard links={project.links} />
{/* Related Projects Section */}
<RelatedProjects projects={relatedProjects} locale={locale} />
</div>
</div>
</main>
)
}
export async function generateMetadata({ params }: ProjectDetailPageProps) {
const resolvedParams = await params
const { id, locale } = resolvedParams
const project = await getProjectBySlug(id)
if (!project) {
return {
title: 'Project Not Found',
}
}
const displayName = locale === 'en' && project.nameEn ? project.nameEn : project.name
const displayDescription =
locale === 'en' && project.descriptionEn ? project.descriptionEn : project.description
return {
title: `${displayName} - Agent Park`,
description: displayDescription,
}
}
export const revalidate = 300 // ISR: revalidate every 5 minutes
+66 -21
View File
@@ -1,3 +1,4 @@
import { Suspense } from 'react'
import { getTranslations } from 'next-intl/server'
import { getProjects, getAllTags } from '@/hooks/useProjects'
import { ProjectList } from '@/components/project/ProjectList'
@@ -27,45 +28,89 @@ export default async function ProjectsPage({
])
return (
<div className="container mx-auto px-4 py-8">
<div className="mb-8">
<h1 className="text-3xl font-bold mb-4"></h1>
<SearchBar locale={locale} />
<main className="container mx-auto px-4 py-12 md:py-16 max-w-7xl relative">
{/* Decorative shapes */}
<div className="absolute top-10 left-0 w-24 h-24 border-2 border-black dark:border-white/20 rounded-full opacity-20 pointer-events-none hidden lg:block"></div>
<div className="absolute top-20 right-10 w-32 h-20 border-2 border-black dark:border-white/20 rounded-[2rem] opacity-20 pointer-events-none transform rotate-12 hidden lg:block"></div>
{/* Page Header */}
<div className="text-center mb-16 relative z-10">
<h1 className="font-display text-5xl md:text-7xl font-bold mb-6 leading-tight tracking-tighter">
PROJECT <br className="md:hidden" />NAVIGATOR
</h1>
<p className="text-lg md:text-xl text-gray-600 dark:text-gray-300 max-w-2xl mx-auto font-light leading-relaxed">
Discover and explore high-quality AI projects from across the web. <br className="hidden md:inline" />
Curated for developers and enthusiasts.
</p>
</div>
<div className="mb-8">
<h2 className="text-xl font-semibold mb-4">{t('browseByTag')}</h2>
<TagCloud tags={tags} locale={locale} />
{/* Search and Filter Section */}
<div className="bg-surface-light dark:bg-surface-dark border-2 border-black dark:border-white/20 p-6 md:p-8 mb-12 shadow-neo dark:shadow-none">
<Suspense fallback={<div className="h-20"></div>}>
<SearchBar locale={locale} />
</Suspense>
<div className="border-t-2 border-gray-100 dark:border-gray-800 pt-6 mt-8">
<h3 className="font-display font-bold uppercase text-sm mb-4 border-b-2 border-black inline-block dark:border-primary pb-1">
Browse by Tags
</h3>
<TagCloud tags={tags} locale={locale} activeTag={tag} />
</div>
</div>
<div>
<ProjectList projects={projectsData.projects} locale={locale} />
{/* Projects Section */}
<div className="flex justify-between items-end mb-8 border-b border-black dark:border-white/20 pb-4">
<h2 className="font-display font-bold text-3xl uppercase tracking-tight">
{tag ? `Tag: ${tag}` : 'All Projects'}
</h2>
<span className="font-display text-xs font-bold uppercase text-gray-500">
{projectsData.pagination.total} projects
</span>
</div>
{projectsData.pagination.totalPages > 1 && (
<div className="flex justify-center gap-2 mt-8">
<ProjectList projects={projectsData.projects} locale={locale} />
{/* Pagination */}
{projectsData.pagination.totalPages > 1 && (
<div className="mt-16 flex justify-center">
<div className="flex border-2 border-black dark:border-white/20 bg-white dark:bg-surface-dark shadow-neo dark:shadow-none">
{page > 1 && (
<a
href={`?search=${search}&tag=${tag}&page=${page - 1}`}
className="px-4 py-2 border rounded-lg hover:bg-secondary"
className="px-4 py-2 border-r border-black dark:border-white/20 hover:bg-gray-100 dark:hover:bg-white/10 transition-colors"
>
</a>
)}
<span className="px-4 py-2">
{page} / {projectsData.pagination.totalPages}
</span>
{Array.from({ length: Math.min(5, projectsData.pagination.totalPages) }, (_, i) => {
const pageNum = Math.max(1, page - 2) + i
if (pageNum > projectsData.pagination.totalPages) return null
return (
<a
key={pageNum}
href={`?search=${search}&tag=${tag}&page=${pageNum}`}
className={`px-4 py-2 font-display font-bold text-sm border-r border-black dark:border-white/20 ${
pageNum === page
? 'bg-primary text-black'
: 'hover:bg-gray-100 dark:hover:bg-white/10'
} transition-colors`}
>
{pageNum}
</a>
)
})}
{page < projectsData.pagination.totalPages && (
<a
href={`?search=${search}&tag=${tag}&page=${page + 1}`}
className="px-4 py-2 border rounded-lg hover:bg-secondary"
className="px-4 py-2 hover:bg-gray-100 dark:hover:bg-white/10 transition-colors"
>
</a>
)}
</div>
)}
</div>
</div>
</div>
)}
</main>
)
}
+3 -2
View File
@@ -64,10 +64,11 @@ export async function POST(request: NextRequest) {
if (!projectValidation.success) {
results.failed++
const firstError = projectValidation.error.errors[0]
results.errors.push({
index: i,
field: projectValidation.error.errors[0].path.join('.'),
message: projectValidation.error.errors[0].message,
field: firstError?.path.join('.') || 'unknown',
message: firstError?.message || 'Validation failed',
value: projectData,
})
continue
+83 -36
View File
@@ -1,59 +1,106 @@
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Space+Mono:wght@400;700&display=swap');
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 240 10% 3.9%;
--card: 0 0% 100%;
--card-foreground: 240 10% 3.9%;
/* Neo-brutalism theme colors - Light mode */
--background: 40 20% 95%; /* #F5F2EB */
--foreground: 0 0% 0%; /* #000000 */
--card: 0 0% 100%; /* #FFFFFF */
--card-foreground: 0 0% 0%;
--popover: 0 0% 100%;
--popover-foreground: 240 10% 3.9%;
--primary: 240 5.9% 10%;
--primary-foreground: 0 0% 98%;
--popover-foreground: 0 0% 0%;
--primary: 48 100% 50%; /* #FFD700 */
--primary-foreground: 0 0% 0%;
--secondary: 240 4.8% 95.9%;
--secondary-foreground: 240 5.9% 10%;
--secondary-foreground: 0 0% 0%;
--muted: 240 4.8% 95.9%;
--muted-foreground: 240 3.8% 46.1%;
--muted-foreground: 0 0% 40%;
--accent: 240 4.8% 95.9%;
--accent-foreground: 240 5.9% 10%;
--accent-foreground: 0 0% 0%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 0 0% 98%;
--border: 240 5.9% 90%;
--input: 240 5.9% 90%;
--ring: 240 5.9% 10%;
--radius: 0.5rem;
--border: 0 0% 0%; /* #000000 */
--input: 0 0% 0%;
--ring: 0 0% 0%;
--radius: 0rem; /* Sharp corners for neo-brutalism */
}
.dark {
--background: 240 10% 3.9%;
--foreground: 0 0% 98%;
--card: 240 10% 3.9%;
--card-foreground: 0 0% 98%;
--popover: 240 10% 3.9%;
--popover-foreground: 0 0% 98%;
--primary: 0 0% 98%;
--primary-foreground: 240 5.9% 10%;
--secondary: 240 3.7% 15.9%;
--secondary-foreground: 0 0% 98%;
--muted: 240 3.7% 15.9%;
--muted-foreground: 240 5% 64.9%;
--accent: 240 3.7% 15.9%;
--accent-foreground: 0 0% 98%;
/* Neo-brutalism theme colors - Dark mode */
--background: 0 0% 7%; /* #121212 */
--foreground: 40 15% 90%; /* #F5F2EB */
--card: 0 0% 12%; /* #1E1E1E */
--card-foreground: 40 15% 90%;
--popover: 0 0% 12%;
--popover-foreground: 40 15% 90%;
--primary: 48 100% 50%; /* #FFD700 */
--primary-foreground: 0 0% 0%;
--secondary: 0 0% 20%;
--secondary-foreground: 40 15% 90%;
--muted: 0 0% 20%;
--muted-foreground: 40 10% 60%;
--accent: 0 0% 20%;
--accent-foreground: 40 15% 90%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 0 0% 98%;
--border: 240 3.7% 15.9%;
--input: 240 3.7% 15.9%;
--ring: 240 4.9% 83.9%;
--border: 0 0% 29%; /* #4a4a4a */
--input: 0 0% 29%;
--ring: 48 100% 50%;
--radius: 0rem;
}
body {
@apply bg-background-light dark:bg-background-dark text-text-light dark:text-text-dark font-sans antialiased min-h-screen transition-colors duration-200;
}
/* Scrollbar styling */
::-webkit-scrollbar {
width: 8px;
}
::-webkit-scrollbar-track {
background: transparent;
}
::-webkit-scrollbar-thumb {
background-color: #cbd5e1;
border-radius: 4px;
}
.dark ::-webkit-scrollbar-thumb {
background-color: #475569;
}
}
@layer base {
* {
@apply border-border;
@layer components {
/* Neo-brutalism border utility */
.neo-border {
@apply border-2 border-black dark:border-gray-600;
}
body {
@apply bg-background text-foreground;
/* Neo-brutalism card */
.neo-card {
@apply bg-white dark:bg-surface-dark border-2 border-black dark:border-gray-600 shadow-neo dark:shadow-none;
}
/* Neo-brutalism button */
.neo-btn {
@apply border-2 border-black dark:border-gray-500 shadow-neo-sm dark:shadow-none
active:shadow-none active:translate-x-[2px] active:translate-y-[2px]
transition-all duration-200 font-display font-bold uppercase;
}
/* Neo-brutalism input */
.neo-input {
@apply border-2 border-black dark:border-gray-600 bg-white dark:bg-surface-dark
focus:ring-0 focus:border-primary dark:focus:border-primary
font-display;
}
/* Neo-brutalism tag */
.neo-tag {
@apply border border-black dark:border-gray-500 px-2 py-1 text-xs
font-display font-bold uppercase bg-white dark:bg-gray-800;
}
}
+10 -5
View File
@@ -1,9 +1,6 @@
import type { Metadata } from "next"
import { Inter } from "next/font/google"
import "./globals.css"
const inter = Inter({ subsets: ["latin"] })
export const metadata: Metadata = {
title: "Agent Park - AI 项目导航",
description: "发现和探索全网优质 AI 项目",
@@ -15,8 +12,16 @@ export default function RootLayout({
children: React.ReactNode
}>) {
return (
<html lang="zh">
<body className={inter.className}>{children}</body>
<html lang="zh" suppressHydrationWarning>
<head>
{/* Load fonts via CSS */}
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Space+Mono:wght@400;700&display=swap" rel="stylesheet"/>
{/* Material Icons */}
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"/>
</head>
<body className="font-sans antialiased">
{children}
</body>
</html>
)
}
+73 -18
View File
@@ -16,31 +16,86 @@ interface ProjectCardProps {
}>
}
locale: string
featured?: boolean
}
export function ProjectCard({ project, locale }: ProjectCardProps) {
return (
<div className="border rounded-lg p-6 hover:shadow-lg transition-shadow">
<h3 className="text-xl font-semibold mb-2">{project.name}</h3>
<p className="text-muted-foreground mb-4 line-clamp-2">{project.description}</p>
// Icon mapping for projects based on tags
function getProjectIcon(tags: Array<{ name: string }>): string {
const tagNames = tags.map(t => t.name.toLowerCase())
if (tagNames.some(t => t.includes('automation') || t.includes('workflow'))) return '⚙️'
if (tagNames.some(t => t.includes('image') || t.includes('art'))) return '🎨'
if (tagNames.some(t => t.includes('chat') || t.includes('assistant'))) return '💬'
if (tagNames.some(t => t.includes('data') || t.includes('analysis'))) return '📊'
if (tagNames.some(t => t.includes('llm') || t.includes('language'))) return '🧠'
return '✨'
}
<div className="flex flex-wrap gap-2 mb-4">
{project.tags.map((tag) => (
<span
key={tag.id}
className="inline-flex items-center px-2 py-1 rounded text-xs bg-secondary text-secondary-foreground"
>
{tag.name}
</span>
))}
export function ProjectCard({ project, locale, featured = false }: ProjectCardProps) {
const icon = getProjectIcon(project.tags)
const displayName = locale === 'en' && project.nameEn ? project.nameEn : project.name
const displayDescription = locale === 'en' && project.descriptionEn ? project.descriptionEn : project.description
return (
<article
className={`bg-white dark:bg-surface-dark border-2 border-black dark:border-gray-600 p-6 ${
featured ? 'shadow-neo hover:shadow-neo-hover hover:-translate-y-1' : 'shadow-neo-sm'
} transition-all duration-200 flex flex-col h-full group`}
>
{/* Card Header */}
<div className="flex justify-between items-start mb-4">
<h3 className="font-display text-xl md:text-2xl font-bold">{displayName}</h3>
<span className="text-2xl group-hover:rotate-12 transition-transform">{icon}</span>
</div>
{/* Card Description */}
<p className="text-gray-600 dark:text-gray-300 mb-6 flex-grow font-sans leading-relaxed text-sm md:text-base line-clamp-3">
{displayDescription}
</p>
{/* Card Footer */}
<div className="mt-auto">
{/* Tags */}
<div className="flex flex-wrap gap-2 mb-4">
{project.tags.slice(0, 3).map((tag) => (
<span
key={tag.id}
className="bg-gray-100 dark:bg-gray-800 px-2 py-1 text-[10px] uppercase font-display font-bold border border-gray-300 dark:border-gray-600 text-gray-600 dark:text-gray-300"
>
{tag.name}
</span>
))}
</div>
{/* View Details Link */}
<Link
href={`/${locale}/projects/${project.slug}`}
className="inline-flex items-center font-display font-bold text-sm uppercase hover:text-secondary dark:hover:text-primary group"
>
VIEW DETAILS{' '}
<span className="ml-1 transform group-hover:translate-x-1 transition-transform"></span>
</Link>
</div>
</article>
)
}
// Special card for "Submit Your Project" CTA
export function SubmitProjectCard({ locale }: { locale: string }) {
return (
<article className="bg-primary border-2 border-black dark:border-gray-600 p-6 shadow-neo hover:shadow-neo-hover hover:-translate-y-1 transition-all duration-200 flex flex-col h-full justify-center items-center text-center group">
<div className="bg-white dark:bg-black p-4 rounded-full border-2 border-black mb-4 group-hover:scale-110 transition-transform">
<span className="text-3xl dark:text-primary">+</span>
</div>
<h3 className="font-display text-xl md:text-2xl font-bold text-black mb-2">Submit Your Project</h3>
<p className="text-black mb-6 font-sans text-sm px-4">
Have an AI tool worth sharing? Add it to Agent Park.
</p>
<Link
href={`/${locale}/projects/${project.slug}`}
className="text-primary hover:underline text-sm font-medium"
href="#"
className="bg-black text-white dark:bg-black dark:text-primary border-2 border-black dark:border-black px-6 py-2 font-display text-sm font-bold uppercase hover:bg-white hover:text-black dark:hover:bg-white dark:hover:text-black transition-colors"
>
SUBMIT NOW
</Link>
</div>
</article>
)
}
+186
View File
@@ -0,0 +1,186 @@
'use client'
import Link from 'next/link'
interface ProjectDetailProps {
project: {
id: string
name: string
nameEn?: string | null
slug: string
description: string
descriptionEn?: string | null
content?: string | null
contentEn?: string | null
source?: string | null
createdAt: Date
tags: Array<{
id: string
name: string
nameEn?: string | null
slug: string
}>
links: Array<{
id: string
type: string
url: string
title?: string | null
}>
}
locale: string
}
// Helper function to format date
function formatDate(date: Date | string, locale: string): string {
const dateObj = typeof date === 'string' ? new Date(date) : date
const options: Intl.DateTimeFormatOptions = { year: 'numeric', month: 'short', day: 'numeric' }
return dateObj.toLocaleDateString(locale === 'en' ? 'en-US' : 'zh-CN', options)
}
export function ProjectDetail({ project, locale }: ProjectDetailProps) {
const displayName = locale === 'en' && project.nameEn ? project.nameEn : project.name
const displayDescription =
locale === 'en' && project.descriptionEn ? project.descriptionEn : project.description
const displayContent = locale === 'en' && project.contentEn ? project.contentEn : project.content
// Get category from first tag
const category = project.tags[0]?.name || 'AI Agent'
const categoryEn = project.tags[0]?.nameEn || project.tags[0]?.name || 'AI Agent'
const displayCategory = locale === 'en' ? categoryEn : category
const handleShare = () => {
if (typeof window !== 'undefined') {
const url = encodeURIComponent(window.location.href)
const text = encodeURIComponent(`Check out ${displayName} on Agent Park`)
window.open(`https://twitter.com/intent/tweet?url=${url}&text=${text}`, '_blank')
}
}
const handleCopyLink = () => {
if (typeof window !== 'undefined') {
navigator.clipboard.writeText(window.location.href)
}
}
return (
<>
{/* Header Section */}
<header className="mb-10 relative">
{/* Decorative shape */}
<div
className="absolute -top-10 -right-10 w-24 h-24 border border-black dark:border-white opacity-20 rounded-full hidden md:block pointer-events-none"
style={{ borderRadius: '40% 60% 70% 30% / 40% 50% 60% 50%' }}
></div>
<h1 className="font-display text-4xl md:text-6xl font-bold mb-6 leading-tight uppercase relative z-10">
{displayName}
</h1>
{/* Metadata */}
<div className="flex flex-wrap items-center gap-4 text-sm font-mono text-gray-600 dark:text-gray-400 mb-8 pb-8 border-b border-gray-300 dark:border-gray-700">
<div className="flex items-center gap-2">
<span className="material-icons text-base">calendar_today</span>
<span>Added {formatDate(project.createdAt, locale)}</span>
</div>
<span className="hidden sm:inline text-gray-300">|</span>
<div className="flex items-center gap-2">
<span className="material-icons text-base">category</span>
<span>{displayCategory}</span>
</div>
<span className="hidden sm:inline text-gray-300">|</span>
<div className="flex items-center gap-2">
<span className="material-icons text-base">code</span>
<span>Open Source</span>
</div>
</div>
{/* Tags */}
<div className="flex flex-wrap gap-3 mb-8">
{project.tags.map((tag) => (
<span
key={tag.id}
className="px-3 py-1 border border-black dark:border-gray-500 text-xs font-display font-bold uppercase bg-white dark:bg-gray-800"
>
{tag.name}
</span>
))}
</div>
{/* Featured Image/Video Placeholder */}
<div className="relative w-full aspect-video border-2 border-black dark:border-gray-600 bg-gray-100 dark:bg-gray-800 mb-10 overflow-hidden shadow-brutal dark:shadow-brutal-dark flex items-center justify-center">
{project.source ? (
<iframe
src={project.source}
className="w-full h-full"
title={`${displayName} demo`}
allowFullScreen
/>
) : (
<div className="text-center">
<span className="material-icons text-6xl text-gray-400 dark:text-gray-600 mb-2">
smart_toy
</span>
<p className="text-gray-500 dark:text-gray-400 font-display text-sm">Project Preview</p>
</div>
)}
</div>
</header>
{/* Article Content */}
<article className="prose prose-lg dark:prose-invert max-w-none prose-headings:font-display prose-a:text-blue-600 dark:prose-a:text-blue-400 hover:prose-a:text-blue-800 dark:hover:prose-a:text-blue-300 prose-img:border-2 prose-img:border-black dark:prose-img:border-gray-600 prose-img:shadow-brutal dark:prose-img:shadow-none prose-ul:marker:text-black prose-ul:dark:marker:text-white">
{/* Lead paragraph */}
<p className="lead font-display text-xl mb-8">{displayDescription}</p>
{/* Full content */}
{displayContent && (
<div
dangerouslySetInnerHTML={{
__html: displayContent.replace(/\n/g, '<br />'),
}}
/>
)}
{/* Installation section if GitHub link exists */}
{project.links.some((l) => l.type === 'GITHUB') && (
<>
<h3>Getting Started</h3>
<p>To install this project, clone the repository and install dependencies:</p>
<pre className="bg-gray-100 dark:bg-gray-800 border border-black dark:border-gray-600 p-4 font-mono text-sm overflow-x-auto">
<code>{`git clone ${
project.links.find((l) => l.type === 'GITHUB')?.url || 'https://github.com/example/project'
}
cd ${project.slug}
npm install`}</code>
</pre>
</>
)}
</article>
{/* Share and Feedback Section */}
<div className="mt-12 pt-8 border-t border-gray-300 dark:border-gray-700 flex flex-col sm:flex-row justify-between items-center gap-6">
<div className="flex gap-4">
<button
className="p-2 border border-black dark:border-gray-400 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors"
title="Share on X"
onClick={handleShare}
>
<span className="material-icons text-lg">share</span>
</button>
<button
className="p-2 border border-black dark:border-gray-400 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors"
title="Copy Link"
onClick={handleCopyLink}
>
<span className="material-icons text-lg">link</span>
</button>
</div>
<div className="flex items-center gap-2">
<span className="text-sm font-display font-bold text-gray-500">DID THIS AGENT HELP YOU?</span>
<button className="px-4 py-2 bg-primary text-black font-display font-bold text-xs uppercase border border-black hover:bg-yellow-400 transition-colors shadow-[2px_2px_0px_0px_rgba(0,0,0,1)] active:shadow-none active:translate-x-[2px] active:translate-y-[2px]">
Yes, it rocks
</button>
</div>
</div>
</>
)
}
+11 -5
View File
@@ -1,4 +1,4 @@
import { ProjectCard } from './ProjectCard'
import { ProjectCard, SubmitProjectCard } from './ProjectCard'
interface ProjectListProps {
projects: Array<{
@@ -16,22 +16,28 @@ interface ProjectListProps {
}>
}>
locale: string
featured?: boolean
}
export function ProjectList({ projects, locale }: ProjectListProps) {
export function ProjectList({ projects, locale, featured = false }: ProjectListProps) {
if (projects.length === 0) {
return (
<div className="text-center py-12">
<p className="text-muted-foreground"></p>
<p className="text-gray-500 dark:text-gray-400 font-display"></p>
</div>
)
}
return (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
{projects.map((project) => (
<ProjectCard key={project.id} project={project} locale={locale} />
<ProjectCard key={project.id} project={project} locale={locale} featured={featured} />
))}
{/* Add "Submit Your Project" CTA card for featured section */}
{featured && (
<SubmitProjectCard locale={locale} />
)}
</div>
)
}
+156
View File
@@ -0,0 +1,156 @@
import Link from 'next/link'
interface ProjectSidebarProps {
project: {
id: string
name: string
nameEn?: string | null
slug: string
links: Array<{
id: string
type: string
url: string
title?: string | null
}>
}
locale: string
}
// Helper function to get icon and label for link type
function getLinkInfo(type: string): { icon: string; label: string } {
switch (type.toUpperCase()) {
case 'WEBSITE':
return { icon: 'language', label: 'Official Website' }
case 'GITHUB':
return { icon: 'code', label: 'GitHub Repo' }
case 'HUGGINGFACE':
return { icon: 'model_training', label: 'Hugging Face' }
case 'PAPER':
return { icon: 'description', label: 'Paper' }
default:
return { icon: 'link', label: 'External Link' }
}
}
export function ProjectSidebar({ project, locale }: ProjectSidebarProps) {
const displayName = locale === 'en' && project.nameEn ? project.nameEn : project.name
return (
<aside className="space-y-8">
{/* Project Links Card */}
{project.links.length > 0 && (
<div className="bg-white dark:bg-surface-dark border-2 border-black dark:border-gray-600 p-6 shadow-brutal dark:shadow-brutal-dark">
<h3 className="font-display font-bold text-lg mb-6 uppercase border-b-2 border-primary pb-2 inline-block">
Project Links
</h3>
<div className="space-y-4">
{project.links.map((link) => {
const { icon, label } = getLinkInfo(link.type)
return (
<a
key={link.id}
href={link.url}
target="_blank"
rel="noopener noreferrer"
className="flex items-center justify-between group p-3 border border-gray-200 dark:border-gray-700 hover:border-black dark:hover:border-white transition-colors bg-gray-50 dark:bg-gray-800"
>
<div className="flex items-center gap-3">
<span className="material-icons">{icon}</span>
<span className="font-bold text-sm">{link.title || label}</span>
</div>
<span className="material-icons text-sm group-hover:translate-x-1 transition-transform">
arrow_forward
</span>
</a>
)
})}
</div>
{/* Stats Section */}
<div className="mt-8 pt-6 border-t border-gray-200 dark:border-gray-700">
<div className="grid grid-cols-2 gap-4">
<div>
<span className="text-xs text-gray-500 uppercase font-mono block mb-1">License</span>
<span className="font-bold text-sm">MIT</span>
</div>
<div>
<span className="text-xs text-gray-500 uppercase font-mono block mb-1">Pricing</span>
<span className="font-bold text-sm">Free</span>
</div>
<div>
<span className="text-xs text-gray-500 uppercase font-mono block mb-1">Status</span>
<span className="font-bold text-sm">Active</span>
</div>
<div>
<span className="text-xs text-gray-500 uppercase font-mono block mb-1">Type</span>
<span className="font-bold text-sm">Open Source</span>
</div>
</div>
</div>
</div>
)}
{/* CTA Card */}
<div className="bg-primary border-2 border-black p-6 relative overflow-hidden shadow-brutal dark:shadow-none group cursor-pointer hover:bg-yellow-400 transition-colors">
<div className="absolute top-0 right-0 w-20 h-20 bg-white opacity-20 transform rotate-45 translate-x-10 -translate-y-10"></div>
<div className="absolute bottom-0 left-0 w-16 h-16 bg-black opacity-10 rounded-full transform -translate-x-8 translate-y-8"></div>
<div className="relative z-10 text-center">
<div className="w-12 h-12 bg-white rounded-full border-2 border-black flex items-center justify-center mx-auto mb-4 group-hover:scale-110 transition-transform">
<span className="material-icons text-2xl">rocket_launch</span>
</div>
<h3 className="font-display font-bold text-xl mb-2">Build Your Own Agent?</h3>
<p className="text-sm font-medium mb-6">Start using our API to build custom agents in minutes.</p>
<Link
href={`/${locale}/projects`}
className="block w-full bg-black text-white font-display font-bold py-3 text-sm uppercase hover:bg-gray-800 transition-colors shadow-none text-center"
>
Get Started Now
</Link>
</div>
</div>
{/* Table of Contents */}
{locale === 'en' && (
<div className="sticky top-24 bg-background-light dark:bg-background-dark border border-gray-300 dark:border-gray-700 p-6 hidden lg:block">
<h3 className="font-display font-bold text-sm uppercase tracking-widest mb-4 text-gray-500 dark:text-gray-400">
On this page
</h3>
<ul className="space-y-3 text-sm border-l-2 border-gray-200 dark:border-gray-700 pl-4">
<li>
<a
href="#overview"
className="text-black dark:text-white font-bold border-l-2 border-black dark:border-white -ml-[18px] pl-4 block"
>
Overview
</a>
</li>
<li>
<a
href="#features"
className="text-gray-600 dark:text-gray-400 hover:text-black dark:hover:text-white transition-colors block"
>
Key Features
</a>
</li>
<li>
<a
href="#getting-started"
className="text-gray-600 dark:text-gray-400 hover:text-black dark:hover:text-white transition-colors block"
>
Getting Started
</a>
</li>
<li>
<a
href="#use-cases"
className="text-gray-600 dark:text-gray-400 hover:text-black dark:hover:text-white transition-colors block"
>
Use Cases
</a>
</li>
</ul>
</div>
)}
</aside>
)
}
@@ -0,0 +1,93 @@
import Link from 'next/link'
interface RelatedProjectsProps {
projects: Array<{
id: string
name: string
nameEn?: string | null
slug: string
description: string
descriptionEn?: string | null
tags: Array<{
id: string
name: string
nameEn?: string | null
slug: string
}>
}>
locale: string
}
// Icon mapping for projects
function getProjectIcon(tags: Array<{ name: string }>): string {
const tagNames = tags.map((t) => t.name.toLowerCase())
if (tagNames.some((t) => t.includes('automation') || t.includes('workflow'))) return '⚙️'
if (tagNames.some((t) => t.includes('image') || t.includes('art'))) return '🎨'
if (tagNames.some((t) => t.includes('chat') || t.includes('assistant'))) return '💬'
if (tagNames.some((t) => t.includes('data') || t.includes('analysis'))) return '📊'
if (tagNames.some((t) => t.includes('llm') || t.includes('language'))) return '🧠'
return '✨'
}
export function RelatedProjects({ projects, locale }: RelatedProjectsProps) {
if (projects.length === 0) {
return null
}
return (
<section className="mt-20 pt-12 border-t border-black dark:border-gray-700">
<div className="flex justify-between items-end mb-8">
<h2 className="font-display text-3xl font-bold uppercase">Related Projects</h2>
<Link
href={`/${locale}/projects`}
className="font-display text-xs font-bold uppercase hover:underline flex items-center gap-1 group"
>
View All{' '}
<span className="material-icons text-sm group-hover:translate-x-1 transition-transform">arrow_forward</span>
</Link>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
{projects.map((project) => {
const displayName = locale === 'en' && project.nameEn ? project.nameEn : project.name
const displayDescription =
locale === 'en' && project.descriptionEn ? project.descriptionEn : project.description
const icon = getProjectIcon(project.tags)
return (
<Link
key={project.id}
href={`/${locale}/projects/${project.slug}`}
className="border-2 border-black dark:border-gray-600 p-6 bg-white dark:bg-surface-dark hover:shadow-brutal hover:-translate-y-1 transition-all duration-200 cursor-pointer flex flex-col h-full dark:hover:shadow-brutal-dark group"
>
<div className="flex justify-between items-start mb-4">
<h3 className="font-display text-xl font-bold">{displayName}</h3>
<span className="text-2xl group-hover:rotate-12 transition-transform">{icon}</span>
</div>
<p className="text-sm text-gray-600 dark:text-gray-300 mb-6 flex-grow line-clamp-3">
{displayDescription}
</p>
<div className="flex gap-2 mb-6">
{project.tags.slice(0, 2).map((tag) => (
<span
key={tag.id}
className="text-[10px] uppercase font-bold border border-gray-300 dark:border-gray-600 px-2 py-1"
>
{tag.name}
</span>
))}
</div>
<div className="mt-auto pt-4 border-t border-gray-100 dark:border-gray-700">
<span className="text-xs font-display font-bold uppercase flex items-center">
View Details{' '}
<span className="material-icons text-sm ml-1 group-hover:translate-x-1 transition-transform">
arrow_forward
</span>
</span>
</div>
</Link>
)
})}
</div>
</section>
)
}
+31 -16
View File
@@ -11,25 +11,40 @@ interface TagCloudProps {
}
}>
locale: string
activeTag?: string
}
export function TagCloud({ tags, locale }: TagCloudProps) {
export function TagCloud({ tags, locale, activeTag }: TagCloudProps) {
return (
<div className="flex flex-wrap gap-2">
{tags.map((tag) => (
<Link
key={tag.id}
href={`/${locale}/projects?tag=${tag.slug}`}
className="inline-flex items-center px-3 py-1 rounded-full text-sm bg-secondary text-secondary-foreground hover:bg-secondary/80 transition-colors"
>
{tag.name}
{tag._count && tag._count.projects > 0 && (
<span className="ml-2 text-xs text-muted-foreground">
{tag._count.projects}
</span>
)}
</Link>
))}
<div className="flex flex-wrap gap-3">
{tags.map((tag) => {
const count = tag._count?.projects || 0
const isActive = activeTag === tag.slug
const displayName = locale === 'en' && tag.nameEn ? tag.nameEn : tag.name
return (
<Link
key={tag.id}
href={`/${locale}/projects?tag=${tag.slug}`}
className={`px-3 py-1 border-2 font-display text-xs font-bold uppercase transition-all shadow-neo-sm hover:shadow-none hover:translate-x-[2px] hover:translate-y-[2px] flex items-center gap-2 group ${
isActive
? 'bg-black text-white border-black'
: 'bg-white dark:bg-surface-dark border-black dark:border-gray-500 hover:bg-black hover:text-white dark:hover:bg-primary dark:hover:text-black'
}`}
>
{displayName}
{count > 0 && (
<span className={`text-[10px] px-1.5 py-0.5 ${
isActive
? 'bg-gray-700 text-white'
: 'bg-gray-200 dark:bg-gray-800 text-gray-600 dark:text-gray-300 group-hover:bg-white group-hover:text-black'
}`}>
{count}
</span>
)}
</Link>
)
})}
</div>
)
}
+29 -8
View File
@@ -20,14 +20,35 @@ export function SearchBar({ locale }: SearchBarProps) {
}
return (
<form onSubmit={handleSubmit} className="w-full max-w-md mx-auto mb-8">
<input
type="text"
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="搜索 AI 项目..."
className="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-ring"
/>
<form onSubmit={handleSubmit} className="max-w-2xl mx-auto">
<div className="relative group">
{/* Glow effect on hover */}
<div className="absolute -inset-1 bg-black dark:bg-primary rounded-lg blur opacity-25 group-hover:opacity-50 transition duration-200"></div>
<div className="relative flex items-center">
{/* Search icon */}
<div className="absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none">
<span className="text-gray-400">🔍</span>
</div>
{/* Input */}
<input
type="text"
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="Search AI projects..."
className="block w-full pl-12 pr-32 py-4 bg-surface-light dark:bg-surface-dark border-2 border-black dark:border-gray-600 text-text-light dark:text-text-dark placeholder-gray-500 focus:ring-0 focus:border-black dark:focus:border-primary font-display shadow-neo transition-all"
/>
{/* Search button */}
<button
type="submit"
className="absolute inset-y-2 right-2 px-4 bg-primary text-black font-bold font-display text-sm border-2 border-black hover:bg-yellow-400 transition-colors shadow-neo-sm active:shadow-none active:translate-x-[2px] active:translate-y-[2px]"
>
SEARCH
</button>
</div>
</div>
</form>
)
}
+41 -30
View File
@@ -10,44 +10,55 @@ const config: Config = {
theme: {
extend: {
colors: {
border: "hsl(var(--border))",
input: "hsl(var(--input))",
ring: "hsl(var(--ring))",
background: "hsl(var(--background))",
foreground: "hsl(var(--foreground))",
// Neo-brutalism color scheme from design
primary: {
DEFAULT: "hsl(var(--primary))",
foreground: "hsl(var(--primary-foreground))",
DEFAULT: "#FFD700", // Gold/Yellow from MotherDuck
dark: "#e5cb00",
},
secondary: {
DEFAULT: "hsl(var(--secondary))",
foreground: "hsl(var(--secondary-foreground))",
secondary: "#ff6f00", // Orange accent
background: {
light: "#F5F2EB", // Warm off-white/beige
dark: "#121212", // Dark charcoal for dark mode
},
destructive: {
DEFAULT: "hsl(var(--destructive))",
foreground: "hsl(var(--destructive-foreground))",
surface: {
light: "#FFFFFF",
dark: "#1E1E1E",
},
muted: {
DEFAULT: "hsl(var(--muted))",
foreground: "hsl(var(--muted-foreground))",
border: {
light: "#000000",
dark: "#4a4a4a",
},
accent: {
DEFAULT: "hsl(var(--accent))",
foreground: "hsl(var(--accent-foreground))",
},
popover: {
DEFAULT: "hsl(var(--popover))",
foreground: "hsl(var(--popover-foreground))",
},
card: {
DEFAULT: "hsl(var(--card))",
foreground: "hsl(var(--card-foreground))",
text: {
light: "#000000",
dark: "#F5F2EB",
},
},
fontFamily: {
display: ["'Space Mono'", "'Courier New'", "monospace"], // Space Mono for headings
sans: ["var(--font-inter)", "system-ui", "-apple-system", "sans-serif"], // Inter for body
},
boxShadow: {
// Neo-brutalism shadows
neo: "4px 4px 0px 0px rgba(0,0,0,1)",
"neo-sm": "2px 2px 0px 0px rgba(0,0,0,1)",
"neo-hover": "2px 2px 0px 0px rgba(0,0,0,1)",
"neo-dark": "4px 4px 0px 0px rgba(255,215,0,0.5)",
brutal: "4px 4px 0px 0px rgba(0,0,0,1)",
"brutal-hover": "2px 2px 0px 0px rgba(0,0,0,1)",
"brutal-dark": "4px 4px 0px 0px rgba(255,255,255,0.2)",
},
borderRadius: {
lg: "var(--radius)",
md: "calc(var(--radius) - 2px)",
sm: "calc(var(--radius) - 4px)",
DEFAULT: "0px", // Sharp corners for neo-brutalism
md: "2px",
},
animation: {
float: "float 6s ease-in-out infinite",
},
keyframes: {
float: {
"0%, 100%": { transform: "translateY(0px) rotate(0deg)" },
"50%": { transform: "translateY(-10px) rotate(2deg)" },
},
},
},
},