refactor: update styles and animations across pages for improved consistency and aesthetics

- Changed background gradients and color schemes in `now.astro` and `projects.astro` to use primary colors.
- Updated text styles and backgrounds to enhance readability and visual appeal.
- Added new font imports for better typography.
- Introduced custom animations and hover effects in `global.css` for enhanced user interaction.
- Adjusted CSS variables for a more cohesive design across light and dark modes.
This commit is contained in:
zguiyang
2026-03-13 14:39:09 +08:00
parent 30b097cc74
commit 0d050b0c14
28 changed files with 491 additions and 296 deletions

View File

@@ -2,9 +2,10 @@
import Layout from "@/layouts/Layout.astro";
import GlassHeader from "@/components/GlassHeader";
import SkillsMarquee from "@/components/SkillsMarquee";
import TypewriterEffect from "@/components/TypewriterEffect";
import TypewriterEffect from "@/components/TypewriterEffect";
import Footer from "@/components/Footer";
import Container from "@/components/ui/Container.astro";
import MotionWrapper from "@/components/MotionWrapper";
import { useTranslations } from "@/i18n/utils";
import type { Lang } from "@/types/i18n";
import { defaultLang } from "@/i18n/ui";
@@ -22,22 +23,22 @@ const pageTitle = t('site.title');
<!-- Hero Section - Inlined Content -->
<section class="py-32 relative overflow-hidden min-h-screen flex flex-col justify-center">
<!-- Background gradient -->
<div class="absolute inset-0 bg-gradient-to-br from-purple-900/20 via-purple-800/10 to-purple-700/20 dark:from-purple-900/30 dark:via-purple-800/20 dark:to-purple-700/30"></div>
<div class="absolute inset-0 bg-gradient-to-br from-blue-900/20 via-primary/10 to-orange-900/20 dark:from-blue-900/30 dark:via-primary/20 dark:to-orange-900/30"></div>
<Container className="relative z-10">
<div class="text-center mb-16">
<!-- Greeting -->
<div class="flex items-center justify-center mb-6">
<svg class="h-6 w-6 mr-2 text-purple-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<svg class="h-6 w-6 mr-2 text-primary" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"></path>
</svg>
<span class="text-purple-500 font-mono text-lg">
<span class="text-primary font-mono text-lg">
{t('hero.greeting')} {personalInfo.name}
</span>
</div>
<!-- Main title -->
<h1 class="text-6xl md:text-8xl font-bold mb-6 bg-gradient-to-r from-gray-900 via-purple-600 to-purple-800 dark:from-white dark:via-purple-200 dark:to-purple-300 bg-clip-text text-transparent">
<h1 class="text-6xl md:text-8xl font-bold mb-6 bg-gradient-to-r from-gray-900 via-blue-600 to-orange-600 dark:from-white dark:via-blue-200 dark:to-orange-300 bg-clip-text text-transparent">
{personalInfo.name}
</h1>
@@ -58,7 +59,7 @@ const pageTitle = t('site.title');
delayBeforeDelete={3500}
delayBeforeTyping={1800}
loop={true}
cursorClassName="text-purple-600 dark:text-purple-400"
cursorClassName="text-primary dark:text-primary"
className="mr-2 font-medium text-muted-foreground"
/>
<span>👨‍💻</span>
@@ -72,7 +73,7 @@ const pageTitle = t('site.title');
<!-- Job availability notice -->
<div class="mb-8">
<p class="text-lg font-medium text-purple-500 mb-2">{t('hero.lookingForJob')}</p>
<p class="text-lg font-medium text-primary mb-2">{t('hero.lookingForJob')}</p>
<p class="text-md text-muted-foreground">{t('hero.digitalNomad')}</p>
</div>
@@ -80,7 +81,7 @@ const pageTitle = t('site.title');
<div class="flex flex-col sm:flex-row gap-4 justify-center items-center mb-16">
<a
href={`/${lang === 'zh' ? 'zh/' : ''}hire`}
class="bg-purple-500 hover:bg-purple-600 text-white px-8 py-3 rounded-lg font-semibold transition-colors flex items-center gap-2"
class="bg-primary hover:bg-primary/90 text-white px-8 py-3 rounded-lg font-semibold transition-colors flex items-center gap-2"
>
<svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"></path>
@@ -90,7 +91,7 @@ const pageTitle = t('site.title');
<a
href={`/${lang === 'zh' ? 'zh/' : ''}projects`}
class="border border-purple-500 text-purple-500 hover:bg-purple-500 hover:text-white px-8 py-3 rounded-lg font-semibold transition-colors flex items-center gap-2"
class="border border-primary text-primary hover:bg-primary hover:text-white px-8 py-3 rounded-lg font-semibold transition-colors flex items-center gap-2"
>
<svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 8l7.89 4.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"></path>
@@ -157,13 +158,13 @@ const pageTitle = t('site.title');
<div class="p-6 font-mono text-sm">
<div class="space-y-2">
<div class="flex items-center">
<span class="text-purple-400 mr-2">$</span>
<span class="text-primary mr-2">$</span>
<span class="text-white">whoami</span>
</div>
<div class="text-purple-300 ml-4">Joy Zhao</div>
<div class="text-primary/80 ml-4">Joy Zhao</div>
<div class="flex items-center mt-4">
<span class="text-purple-400 mr-2">$</span>
<span class="text-primary mr-2">$</span>
<span class="text-white">cat about.txt</span>
</div>
<div class="text-gray-300 ml-4 leading-relaxed">
@@ -180,15 +181,15 @@ const pageTitle = t('site.title');
</div>
<div class="flex items-center mt-4">
<span class="text-purple-400 mr-2">$</span>
<span class="text-primary mr-2">$</span>
<span class="text-white">ls projects/</span>
</div>
<div class="text-purple-200 ml-4">
<div class="text-primary/70 ml-4">
taskify-app/ e-commerce-platform/ portfolio-site/
</div>
<div class="flex items-center mt-4">
<span class="text-purple-400 mr-2">$</span>
<span class="text-primary mr-2">$</span>
<span class="text-white animate-pulse">_</span>
</div>
</div>
@@ -201,13 +202,13 @@ const pageTitle = t('site.title');
<SkillsMarquee lang={lang} client:only="react" />
<!-- Featured Project: Elynd -->
<section class="py-24 bg-gradient-to-br from-purple-900/20 via-purple-800/10 to-blue-900/20 dark:from-purple-900/30 dark:via-purple-800/20 dark:to-blue-900/30">
<section class="py-24 bg-gradient-to-br from-blue-900/20 via-primary/10 to-blue-900/20 dark:from-blue-900/30 dark:via-primary/20 dark:to-blue-900/30">
<Container>
<div class="text-center mb-12">
<span class="inline-block px-4 py-1 bg-purple-500/20 text-purple-600 dark:text-purple-400 rounded-full text-sm font-medium mb-4">
<span class="inline-block px-4 py-1 bg-primary/20 text-primary dark:text-primary rounded-full text-sm font-medium mb-4">
{lang === 'zh' ? 'featured 项目' : 'Featured Project'}
</span>
<h2 class="text-4xl md:text-5xl font-bold mb-4 bg-gradient-to-r from-purple-400 via-blue-400 to-purple-400 bg-clip-text text-transparent">
<h2 class="text-4xl md:text-5xl font-bold mb-4 bg-gradient-to-r from-blue-400 via-primary to-blue-400 bg-clip-text text-transparent">
Elynd
</h2>
<p class="text-lg text-muted-foreground max-w-2xl mx-auto">
@@ -218,12 +219,12 @@ const pageTitle = t('site.title');
</div>
<div class="max-w-4xl mx-auto">
<div class="bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-2xl border border-purple-500/20 overflow-hidden">
<div class="h-64 md:h-80 bg-gradient-to-br from-purple-600/20 via-blue-600/20 to-purple-600/20 flex items-center justify-center relative overflow-hidden">
<div class="absolute inset-0 bg-grid-purple-500/10 [mask-image:linear-gradient(0deg,white,rgba(255,255,255,0.3))]"></div>
<div class="bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-2xl border border-primary/20 overflow-hidden">
<div class="h-64 md:h-80 bg-gradient-to-br from-primary/20 via-blue-600/20 to-primary/20 flex items-center justify-center relative overflow-hidden">
<div class="absolute inset-0 bg-grid-primary/10 [mask-image:linear-gradient(0deg,white,rgba(255,255,255,0.3))]"></div>
<div class="text-center z-10">
<div class="text-6xl md:text-8xl mb-4">⚡</div>
<div class="text-2xl md:text-3xl font-bold text-purple-400">
<div class="text-2xl md:text-3xl font-bold text-primary">
{lang === 'zh' ? '让 AI 成为你的共同构建者' : 'Make AI Your Co-Builder'}
</div>
</div>
@@ -231,7 +232,7 @@ const pageTitle = t('site.title');
<div class="p-8">
<div class="grid md:grid-cols-3 gap-6 mb-8">
<div class="text-center">
<div class="text-3xl font-bold text-purple-400 mb-2">AI-First</div>
<div class="text-3xl font-bold text-primary mb-2">AI-First</div>
<div class="text-sm text-muted-foreground">
{lang === 'zh' ? '从第一天就融入 AI 思维' : 'Built with AI from day one'}
</div>
@@ -252,14 +253,14 @@ const pageTitle = t('site.title');
<div class="flex flex-col sm:flex-row gap-4 justify-center">
<a
href={`/${lang === 'zh' ? 'zh/' : ''}projects`}
class="bg-purple-500 hover:bg-purple-600 text-white px-6 py-3 rounded-lg font-semibold transition-colors inline-flex items-center justify-center gap-2"
class="bg-primary hover:bg-primary/90 text-white px-6 py-3 rounded-lg font-semibold transition-colors inline-flex items-center justify-center gap-2"
>
<span>🚀</span>
{t('hero.ctaSecondary')}
</a>
<a
href={`/${lang === 'zh' ? 'zh/' : ''}now`}
class="border border-purple-500 text-purple-500 hover:bg-purple-500 hover:text-white px-6 py-3 rounded-lg font-semibold transition-colors inline-flex items-center justify-center gap-2"
class="border border-primary text-primary hover:bg-primary hover:text-white px-6 py-3 rounded-lg font-semibold transition-colors inline-flex items-center justify-center gap-2"
>
<span>📡</span>
{lang === 'zh' ? '了解更多' : 'Learn More'}
@@ -274,7 +275,7 @@ const pageTitle = t('site.title');
<!-- Services Section - Inlined Content -->
<section id="services" class="py-20 bg-gradient-to-br from-slate-50 to-blue-50 dark:from-slate-900 dark:to-slate-800">
<Container>
<h2 class="text-4xl font-bold text-center mb-16 bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent">
<h2 class="text-4xl font-bold text-center mb-16 bg-gradient-to-r from-blue-600 to-primary bg-clip-text text-transparent">
{t('services.title')}
</h2>
@@ -302,7 +303,7 @@ const pageTitle = t('site.title');
</div>
<div class="mt-12 text-center">
<a href="/services" class="inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 bg-purple-500 text-white shadow hover:bg-purple-600 h-10 px-8 py-2">
<a href="/services" class="inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 bg-primary text-white shadow hover:bg-primary/90 h-10 px-8 py-2">
<svg class="h-5 w-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path>
</svg>
@@ -315,13 +316,13 @@ const pageTitle = t('site.title');
<!-- About Section - Inlined Content -->
<section id="about" class="py-24 relative overflow-hidden">
<!-- Background gradient -->
<div class="absolute inset-0 bg-gradient-to-br from-blue-900/10 via-purple-800/5 to-indigo-700/10 dark:from-blue-900/20 dark:via-purple-800/10 dark:to-indigo-700/20"></div>
<div class="absolute inset-0 bg-gradient-to-br from-blue-900/10 via-primary/5 to-indigo-700/10 dark:from-blue-900/20 dark:via-primary/10 dark:to-indigo-700/20"></div>
<Container className="relative z-10">
<div class="text-center mb-16">
<!-- Section Title -->
<div class="flex items-center justify-center mb-6">
<h2 class="text-3xl md:text-4xl font-bold bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent">
<h2 class="text-3xl md:text-4xl font-bold bg-gradient-to-r from-blue-600 to-primary bg-clip-text text-transparent">
{t('about.title')}
</h2>
</div>
@@ -408,7 +409,7 @@ const pageTitle = t('site.title');
<span class="px-2 py-1 text-xs bg-blue-100 dark:bg-blue-900/30 text-blue-800 dark:text-blue-300 rounded">90%</span>
</div>
<div class="w-full bg-gray-200 dark:bg-gray-700 rounded-full h-2">
<div class="bg-gradient-to-r from-blue-500 to-purple-500 h-2 rounded-full" style="width: 90%"></div>
<div class="bg-gradient-to-r from-blue-500 to-primary h-2 rounded-full" style="width: 90%"></div>
</div>
<div class="flex justify-between items-center">
@@ -421,10 +422,10 @@ const pageTitle = t('site.title');
<div class="flex justify-between items-center">
<span class="text-sm text-gray-700 dark:text-gray-300">DevOps</span>
<span class="px-2 py-1 text-xs bg-purple-100 dark:bg-purple-900/30 text-purple-800 dark:text-purple-300 rounded">75%</span>
<span class="px-2 py-1 text-xs bg-primary/10 dark:bg-primary/10 text-primary/80 dark:text-primary/80 rounded">75%</span>
</div>
<div class="w-full bg-gray-200 dark:bg-gray-700 rounded-full h-2">
<div class="bg-gradient-to-r from-purple-500 to-pink-500 h-2 rounded-full" style="width: 75%"></div>
<div class="bg-gradient-to-r from-primary to-orange-500 h-2 rounded-full" style="width: 75%"></div>
</div>
<div class="flex justify-between items-center">
@@ -457,11 +458,11 @@ const pageTitle = t('site.title');
<!-- Projects Section - Inlined Content -->
<!-- <section id="projects" class="py-20 relative">
<div class="absolute inset-0 bg-gradient-to-b from-transparent via-purple-900/5 to-transparent"></div>
<div class="absolute inset-0 bg-gradient-to-b from-transparent via-primary/5 to-transparent"></div>
<Container className="relative z-10">
<div class="text-center mb-16">
<h2 class="text-4xl md:text-5xl font-bold mb-4 bg-gradient-to-r from-purple-400 to-purple-600 bg-clip-text text-transparent">
<h2 class="text-4xl md:text-5xl font-bold mb-4 bg-gradient-to-r from-blue-400 to-primary bg-clip-text text-transparent">
Latest Projects
</h2>
<p class="text-lg text-muted-foreground max-w-2xl mx-auto">
@@ -470,24 +471,24 @@ const pageTitle = t('site.title');
</div>
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8 items-stretch">
<div class="group overflow-hidden border border-purple-500/20 hover:border-purple-500/40 h-full flex flex-col transition-transform duration-500 hover:scale-105 bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-xl relative" style="will-change: transform; transform: translateZ(0);">
<div class="group overflow-hidden border border-primary/20 hover:border-primary/40 h-full flex flex-col transition-transform duration-500 hover:scale-105 bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-xl relative" style="will-change: transform; transform: translateZ(0);">
<div class="absolute top-4 right-4 z-10">
<span class="px-3 py-1 bg-blue-100 dark:bg-blue-800 text-blue-800 dark:text-blue-200 text-xs rounded-full font-medium border border-blue-200 dark:border-blue-700">{t('project.tag.business')}</span>
</div>
<div class="h-48 bg-gradient-to-br from-purple-500/20 to-purple-600/20 relative overflow-hidden">
<div class="absolute inset-0 bg-gradient-to-br from-purple-500/10 to-purple-600/10 group-hover:from-purple-500/20 group-hover:to-purple-600/20 transition-colors duration-500"></div>
<div class="h-48 bg-gradient-to-br from-primary/20 to-primary/20 relative overflow-hidden">
<div class="absolute inset-0 bg-gradient-to-br from-primary/10 to-primary/10 group-hover:from-primary/20 group-hover:to-primary/20 transition-colors duration-500"></div>
<div class="absolute bottom-4 left-4 right-4">
<div class="bg-black/50 backdrop-blur-sm rounded px-3 py-1 text-xs font-mono text-purple-400">
<div class="bg-black/50 backdrop-blur-sm rounded px-3 py-1 text-xs font-mono text-primary">
Taskify App
</div>
</div>
</div>
<div class="p-6 pb-4">
<h3 class="text-xl group-hover:text-purple-400 transition-colors duration-300 flex items-center gap-2 font-bold mb-4">
<span class="text-purple-500">📱</span>
<h3 class="text-xl group-hover:text-primary transition-colors duration-300 flex items-center gap-2 font-bold mb-4">
<span class="text-primary">📱</span>
Taskify App
</h3>
</div>
@@ -495,19 +496,19 @@ const pageTitle = t('site.title');
<div class="px-6 flex-grow">
<div class="space-y-3">
<div class="flex items-start gap-2 text-sm text-muted-foreground group-hover:text-foreground transition-colors duration-300">
<span class="text-purple-500 mt-1">•</span>
<span class="text-primary mt-1">•</span>
<span>A comprehensive task management application with drag-and-drop functionality.</span>
</div>
<div class="flex items-start gap-2 text-sm text-muted-foreground group-hover:text-foreground transition-colors duration-300">
<span class="text-purple-500 mt-1">•</span>
<span class="text-primary mt-1">•</span>
<span>Built with React, TypeScript, and Tailwind CSS for modern development.</span>
</div>
<div class="flex items-start gap-2 text-sm text-muted-foreground group-hover:text-foreground transition-colors duration-300">
<span class="text-purple-500 mt-1">•</span>
<span class="text-primary mt-1">•</span>
<span>Real-time collaboration features with WebSocket integration for instant updates.</span>
</div>
<div class="flex items-start gap-2 text-sm text-muted-foreground group-hover:text-foreground transition-colors duration-300">
<span class="text-purple-500 mt-1">•</span>
<span class="text-primary mt-1">•</span>
<span>Advanced task filtering, sorting, and project management capabilities.</span>
</div>
</div>
@@ -525,7 +526,7 @@ const pageTitle = t('site.title');
href="https://github.com/zhaoguiyang/taskify-app"
target="_blank"
rel="noopener noreferrer"
class="flex items-center gap-2 text-sm text-purple-400 hover:text-purple-300 transition-colors group/link"
class="flex items-center gap-2 text-sm text-primary hover:text-primary/80 transition-colors group/link"
>
<span>🔗</span>
{t('project.visit')}
@@ -533,23 +534,23 @@ const pageTitle = t('site.title');
</div>
</div>
</div>
<div class="group overflow-hidden border border-purple-500/20 hover:border-purple-500/40 h-full flex flex-col transition-transform duration-500 hover:scale-105 bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-xl relative" style="will-change: transform; transform: translateZ(0);">
<div class="group overflow-hidden border border-primary/20 hover:border-primary/40 h-full flex flex-col transition-transform duration-500 hover:scale-105 bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-xl relative" style="will-change: transform; transform: translateZ(0);">
<div class="absolute top-4 right-4 z-10">
<span class="px-3 py-1 bg-green-100 dark:bg-green-800 text-green-800 dark:text-green-200 text-xs rounded-full font-medium border border-green-200 dark:border-green-700">{t('project.tag.opensource')}</span>
</div>
<div class="h-48 bg-gradient-to-br from-purple-500/20 to-purple-600/20 relative overflow-hidden">
<div class="absolute inset-0 bg-gradient-to-br from-purple-500/10 to-purple-600/10 group-hover:from-purple-500/20 group-hover:to-purple-600/20 transition-colors duration-500"></div>
<div class="h-48 bg-gradient-to-br from-primary/20 to-primary/20 relative overflow-hidden">
<div class="absolute inset-0 bg-gradient-to-br from-primary/10 to-primary/10 group-hover:from-primary/20 group-hover:to-primary/20 transition-colors duration-500"></div>
<div class="absolute bottom-4 left-4 right-4">
<div class="bg-black/50 backdrop-blur-sm rounded px-3 py-1 text-xs font-mono text-purple-400">
<div class="bg-black/50 backdrop-blur-sm rounded px-3 py-1 text-xs font-mono text-primary">
E-Shop Platform
</div>
</div>
</div>
<div class="p-6 pb-4">
<h3 class="text-xl group-hover:text-purple-400 transition-colors duration-300 flex items-center gap-2 font-bold mb-4">
<span class="text-purple-500">🛒</span>
<h3 class="text-xl group-hover:text-primary transition-colors duration-300 flex items-center gap-2 font-bold mb-4">
<span class="text-primary">🛒</span>
E-Shop Platform
</h3>
</div>
@@ -557,19 +558,19 @@ const pageTitle = t('site.title');
<div class="px-6 flex-grow">
<div class="space-y-3">
<div class="flex items-start gap-2 text-sm text-muted-foreground group-hover:text-foreground transition-colors duration-300">
<span class="text-purple-500 mt-1">•</span>
<span class="text-primary mt-1">•</span>
<span>Modern e-commerce solution with comprehensive features for online retail.</span>
</div>
<div class="flex items-start gap-2 text-sm text-muted-foreground group-hover:text-foreground transition-colors duration-300">
<span class="text-purple-500 mt-1">•</span>
<span class="text-primary mt-1">•</span>
<span>Built with Next.js, Prisma, and Stripe for seamless payment processing.</span>
</div>
<div class="flex items-start gap-2 text-sm text-muted-foreground group-hover:text-foreground transition-colors duration-300">
<span class="text-purple-500 mt-1">•</span>
<span class="text-primary mt-1">•</span>
<span>Features shopping cart, payment integration, and admin dashboard.</span>
</div>
<div class="flex items-start gap-2 text-sm text-muted-foreground group-hover:text-foreground transition-colors duration-300">
<span class="text-purple-500 mt-1">•</span>
<span class="text-primary mt-1">•</span>
<span>Responsive design with optimized performance and SEO capabilities.</span>
</div>
</div>
@@ -596,23 +597,23 @@ const pageTitle = t('site.title');
</div>
</div>
<div class="group overflow-hidden border border-purple-500/20 hover:border-purple-500/40 h-full flex flex-col transition-transform duration-500 hover:scale-105 bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-xl relative" style="will-change: transform; transform: translateZ(0);">
<div class="group overflow-hidden border border-primary/20 hover:border-primary/40 h-full flex flex-col transition-transform duration-500 hover:scale-105 bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-xl relative" style="will-change: transform; transform: translateZ(0);">
<div class="absolute top-4 right-4 z-10">
<span class="px-3 py-1 bg-amber-100 dark:bg-amber-800 text-amber-800 dark:text-amber-200 text-xs rounded-full font-medium border border-amber-200 dark:border-amber-700">{t('project.tag.personal')}</span>
</div>
<div class="h-48 bg-gradient-to-br from-purple-500/20 to-purple-600/20 relative overflow-hidden">
<div class="absolute inset-0 bg-gradient-to-br from-purple-500/10 to-purple-600/10 group-hover:from-purple-500/20 group-hover:to-purple-600/20 transition-colors duration-500"></div>
<div class="h-48 bg-gradient-to-br from-primary/20 to-primary/20 relative overflow-hidden">
<div class="absolute inset-0 bg-gradient-to-br from-primary/10 to-primary/10 group-hover:from-primary/20 group-hover:to-primary/20 transition-colors duration-500"></div>
<div class="absolute bottom-4 left-4 right-4">
<div class="bg-black/50 backdrop-blur-sm rounded px-3 py-1 text-xs font-mono text-purple-400">
<div class="bg-black/50 backdrop-blur-sm rounded px-3 py-1 text-xs font-mono text-primary">
Portfolio Site
</div>
</div>
</div>
<div class="p-6 pb-4">
<h3 class="text-xl group-hover:text-purple-400 transition-colors duration-300 flex items-center gap-2 font-bold mb-4">
<span class="text-purple-500">🎨</span>
<h3 class="text-xl group-hover:text-primary transition-colors duration-300 flex items-center gap-2 font-bold mb-4">
<span class="text-primary">🎨</span>
Portfolio Site
</h3>
</div>
@@ -620,15 +621,15 @@ const pageTitle = t('site.title');
<div class="px-6 flex-grow">
<div class="space-y-3">
<div class="flex items-start gap-2 text-sm text-muted-foreground group-hover:text-foreground transition-colors duration-300">
<span class="text-purple-500 mt-1">•</span>
<span class="text-primary mt-1">•</span>
<span>Responsive personal portfolio website showcasing creative work and projects.</span>
</div>
<div class="flex items-start gap-2 text-sm text-muted-foreground group-hover:text-foreground transition-colors duration-300">
<span class="text-purple-500 mt-1">•</span>
<span class="text-primary mt-1">•</span>
<span>Built with Astro, React, and Tailwind CSS for optimal performance.</span>
</div>
<div class="flex items-start gap-2 text-sm text-muted-foreground group-hover:text-foreground transition-colors duration-300">
<span class="text-purple-500 mt-1">•</span>
<span class="text-primary mt-1">•</span>
<span>Features dark mode support and smooth animations for enhanced UX.</span>
</div>
</div>