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

@@ -24,7 +24,7 @@ export default function AuthorCard({ lang, author }: AuthorCardProps) {
<div className="flex flex-col items-center text-center">
{/* Avatar */}
<div className="flex-shrink-0 mb-4">
<div className="w-20 h-20 bg-gradient-to-br from-purple-500 to-blue-500 rounded-full flex items-center justify-center text-white font-bold text-2xl shadow-lg border-4 border-background">
<div className="w-20 h-20 bg-gradient-to-br from-primary to-blue-500 rounded-full flex items-center justify-center text-white font-bold text-2xl shadow-lg border-4 border-background">
{authorInfo.avatar ? (
<img
src={authorInfo.avatar}
@@ -56,7 +56,7 @@ export default function AuthorCard({ lang, author }: AuthorCardProps) {
href={authorInfo.website}
target="_blank"
rel="noopener noreferrer"
className="flex items-center justify-center w-8 h-8 rounded-full bg-muted text-muted-foreground hover:bg-purple-500/10 hover:text-purple-500 transition-all duration-200"
className="flex items-center justify-center w-8 h-8 rounded-full bg-muted text-muted-foreground hover:bg-primary/10 hover:text-primary transition-all duration-200"
title={websiteText}
>
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">

View File

@@ -19,7 +19,7 @@ export default function Footer({ lang: propLang }: FooterProps) {
const t = useTranslations(lang);
return (
<footer className="border-t border-purple-500/10 py-6 bg-gradient-to-b from-background to-muted/20 backdrop-blur-sm">
<footer className="border-t border-primary/10 py-6 bg-gradient-to-b from-background to-muted/20 backdrop-blur-sm">
<Container>
<motion.div
className="flex flex-col md:flex-row justify-between items-center"
@@ -36,7 +36,7 @@ export default function Footer({ lang: propLang }: FooterProps) {
&copy; {new Date().getFullYear()} { personalInfo.name }. {t('footer.rights')}
</motion.p>
<motion.p
className="text-sm text-purple-500 font-medium text-center md:text-left"
className="text-sm text-primary font-medium text-center md:text-left"
whileHover={{ scale: 1.01 }}
>
{lang === 'zh' ? '构建 AI 产品?寻找技术合伙人?联系我!' : 'Building AI Products? Need a Technical Co-founder? Contact me!'}

View File

@@ -42,7 +42,7 @@ export default function GlassHeader({ lang: propLang }: GlassHeaderProps) {
transition={{ duration: 0.5, ease: [0.22, 1, 0.36, 1] }}
className={`fixed top-0 z-50 w-full transition-all duration-300 ${
isScrolled
? 'backdrop-blur-md backdrop-filter bg-white/80 dark:bg-black/80 border-b border-border/30 shadow-lg shadow-black/5 dark:shadow-black/20'
? 'backdrop-blur-xl backdrop-saturate-150 bg-white/70 dark:bg-black/70 border-b border-border/50 shadow-lg shadow-black/5 dark:shadow-primary/5'
: 'bg-transparent'
}`}
>
@@ -75,7 +75,7 @@ export default function GlassHeader({ lang: propLang }: GlassHeaderProps) {
<motion.a
key={item.key}
href={item.href}
className="transition-colors duration-150 hover:text-foreground/80 text-foreground/60 px-3 py-2 rounded-md hover:bg-foreground/5"
className="transition-colors duration-150 hover:text-primary text-foreground/70 px-3 py-2 rounded-md hover:bg-primary/5"
initial={{ opacity: 0, y: -20 }}
animate={{ opacity: 1, y: 0 }}
transition={{

View File

@@ -5,31 +5,46 @@ import type { MotionProps } from "framer-motion";
interface MotionWrapperProps extends Omit<MotionProps, 'custom'> {
children: React.ReactNode;
delay?: number;
direction?: 'up' | 'down' | 'left' | 'right' | 'none';
duration?: number;
}
export default function MotionWrapper({
children,
delay = 0,
direction = 'up',
duration = 0.6,
...props
}: MotionWrapperProps) {
return (
<motion.div
initial="hidden"
whileInView="visible"
viewport={{ once: true, margin: "-100px" }}
variants={{
hidden: { opacity: 0, y: 20 },
visible: {
const directions = {
up: { y: 30, x: 0 },
down: { y: -30, x: 0 },
left: { x: 30, y: 0 },
right: { x: -30, y: 0 },
none: { x: 0, y: 0 }
};
const initial = {
opacity: 0,
...directions[direction]
};
const whileInView = {
opacity: 1,
x: 0,
y: 0,
transition: {
duration: 0.6,
duration,
delay,
ease: [0.43, 0.13, 0.23, 0.96]
}
}
}}
custom={delay}
};
return (
<motion.div
initial={initial}
whileInView={whileInView}
viewport={{ once: true, margin: "-100px" }}
{...props}
>
{children}

View File

@@ -56,7 +56,7 @@ export default function ShareButtons({ lang, title, url }: ShareButtonsProps) {
return (
<div className="bg-card/50 backdrop-blur-sm rounded-2xl border border-border p-6">
<h3 className="text-lg font-semibold text-foreground mb-4 flex items-center">
<svg className="w-5 h-5 mr-2 text-purple-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<svg className="w-5 h-5 mr-2 text-primary" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M8.684 13.342C8.886 12.938 9 12.482 9 12c0-.482-.114-.938-.316-1.342m0 2.684a3 3 0 110-2.684m0 2.684l6.632 3.316m-6.632-6l6.632-3.316m0 0a3 3 0 105.367-2.684 3 3 0 00-5.367 2.684zm0 9.316a3 3 0 105.367 2.684 3 3 0 00-5.367-2.684z" />
</svg>
{shareText}
@@ -87,7 +87,7 @@ export default function ShareButtons({ lang, title, url }: ShareButtonsProps) {
className="
flex items-center justify-center w-12 h-12 rounded-full
bg-muted text-muted-foreground transition-all duration-200
hover:bg-purple-500/10 hover:text-purple-500
hover:bg-primary/10 hover:text-primary
relative
"
title={copyText}
@@ -106,7 +106,7 @@ export default function ShareButtons({ lang, title, url }: ShareButtonsProps) {
{/* Copy Success Message */}
{copied && (
<div className="mt-3 text-sm text-purple-500 flex items-center">
<div className="mt-3 text-sm text-primary flex items-center">
<svg className="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M5 13l4 4L19 7" />
</svg>

View File

@@ -53,7 +53,7 @@ function SkillItem({ skill }: { skill: SkillItem }) {
const iconUrl = `https://skillicons.dev/icons?i=${skill.icon}`;
return (
<div className="flex items-center gap-3 px-4 py-2 bg-muted/80 backdrop-blur-sm rounded-lg border border-purple-500/10 shadow-sm whitespace-nowrap flex-shrink-0">
<div className="flex items-center gap-3 px-4 py-2 bg-muted/80 backdrop-blur-sm rounded-lg border border-primary/10 shadow-sm whitespace-nowrap flex-shrink-0">
<img
src={iconUrl}
alt={skill.name}

View File

@@ -51,7 +51,7 @@ const TypewriterEffect: React.FC<TypewriterEffectProps> = ({
delayBeforeDelete = 2000,
delayBeforeTyping = 700,
loop = true,
cursorClassName = 'text-purple-500',
cursorClassName = 'text-primary',
className = '',
showCursor = true,
}) => {

View File

@@ -76,7 +76,7 @@ const readMoreText = lang === 'zh' ? '阅读更多' : 'Read More';
{posts.length > 0 ? (
posts.map((post, index) => (
<article class="group">
<div class="bg-card/50 backdrop-blur-sm rounded-2xl overflow-hidden border border-border hover:border-purple-500/50 transition-all duration-300 hover:transform hover:scale-[1.02]">
<div class="bg-card/50 backdrop-blur-sm rounded-2xl overflow-hidden border border-border hover:border-primary/50 transition-all duration-300 hover:transform hover:scale-[1.02]">
<div class="flex flex-col md:flex-row">
{/* Featured Image */}
<div class="relative overflow-hidden md:w-80 md:flex-shrink-0">
@@ -91,7 +91,7 @@ const readMoreText = lang === 'zh' ? '阅读更多' : 'Read More';
{/* Content */}
<div class="p-6 flex-1 flex flex-col justify-between">
<div>
<h2 class="text-xl font-bold text-card-foreground mb-3 group-hover:text-purple-500 transition-colors duration-200">
<h2 class="text-xl font-bold text-card-foreground mb-3 group-hover:text-primary transition-colors duration-200">
<a href={`${postBaseUrl}${post.slug}`}>
{post.title}
</a>
@@ -135,7 +135,7 @@ const readMoreText = lang === 'zh' ? '阅读更多' : 'Read More';
<a
href={`${postBaseUrl}${post.slug}`}
class="text-purple-500 hover:text-purple-400 font-medium flex items-center group"
class="text-primary hover:text-primary font-medium flex items-center group"
>
{readMoreText}
<svg class="w-4 h-4 ml-1 group-hover:translate-x-1 transition-transform duration-200" fill="none" stroke="currentColor" viewBox="0 0 24 24">
@@ -150,7 +150,7 @@ const readMoreText = lang === 'zh' ? '阅读更多' : 'Read More';
))
) : (
<div class="flex flex-col items-center justify-center py-20 text-center bg-card/30 backdrop-blur-sm rounded-2xl border border-border p-8 min-h-[300px]">
<svg class="w-16 h-16 text-purple-500/70 mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<svg class="w-16 h-16 text-primary/70 mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"></path>
</svg>
<p class="text-xl text-muted-foreground mb-4">
@@ -161,7 +161,7 @@ const readMoreText = lang === 'zh' ? '阅读更多' : 'Read More';
</p>
<a
href={`/${lang === 'en' ? '' : 'zh/'}`}
class="px-4 py-2 bg-purple-500/10 hover:bg-purple-500/20 text-purple-500 rounded-full transition-colors duration-200 flex items-center"
class="px-4 py-2 bg-primary/10 hover:bg-primary/20 text-primary rounded-full transition-colors duration-200 flex items-center"
>
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"></path>

View File

@@ -43,7 +43,7 @@ const title = titles[lang] || titles[defaultLang];
<div class="bg-card/50 backdrop-blur-sm rounded-2xl p-6 border border-border">
<h3 class="text-xl font-semibold text-card-foreground mb-4 flex items-center">
<Tag className="w-5 h-5 mr-2 text-purple-500" />
<Tag className="w-5 h-5 mr-2 text-primary" />
{title}
</h3>
<div class="space-y-2">
@@ -52,7 +52,7 @@ const title = titles[lang] || titles[defaultLang];
const categoryId = categoryMap.get(cat) || cat.toLowerCase();
return (
<a href={`${baseUrl}/categories/${encodeURIComponent(categoryId)}`}
class={`block transition-colors duration-200 ${categoryId === currentCategory.toLowerCase() ? 'text-purple-500 font-medium' : 'text-muted-foreground hover:text-purple-500'}`}>
class={`block transition-colors duration-200 ${categoryId === currentCategory.toLowerCase() ? 'text-primary font-medium' : 'text-muted-foreground hover:text-primary'}`}>
{cat}
</a>
);

View File

@@ -99,13 +99,13 @@ const getReadingTimeText = (minutes: number) => {
: cat.toLowerCase();
return (
<a href={`/${lang === 'en' ? '' : 'zh/'}blog/categories/${encodeURIComponent(catId)}`} class="inline-flex items-center px-3 py-1.5 rounded-full text-xs font-medium bg-gradient-to-r from-purple-500 to-purple-600 text-white shadow-sm hover:shadow-md transition-all duration-200 hover:scale-105">
<a href={`/${lang === 'en' ? '' : 'zh/'}blog/categories/${encodeURIComponent(catId)}`} class="inline-flex items-center px-3 py-1.5 rounded-full text-xs font-medium bg-gradient-to-r from-primary to-primary text-white shadow-sm hover:shadow-md transition-all duration-200 hover:scale-105">
{cat}
</a>
);
})
) : (
<a href={`/${lang === 'en' ? '' : 'zh/'}blog/categories/${encodeURIComponent(categoryId?.toString() || category.toLowerCase())}`} class="inline-flex items-center px-3 py-1.5 rounded-full text-xs font-medium bg-gradient-to-r from-purple-500 to-purple-600 text-white shadow-sm hover:shadow-md transition-all duration-200 hover:scale-105">
<a href={`/${lang === 'en' ? '' : 'zh/'}blog/categories/${encodeURIComponent(categoryId?.toString() || category.toLowerCase())}`} class="inline-flex items-center px-3 py-1.5 rounded-full text-xs font-medium bg-gradient-to-r from-primary to-primary text-white shadow-sm hover:shadow-md transition-all duration-200 hover:scale-105">
{category}
</a>
)}

View File

@@ -43,7 +43,7 @@ const title = titles[lang] || titles[defaultLang];
<div class="bg-card/50 backdrop-blur-sm rounded-2xl p-6 border border-border">
<h3 class="text-xl font-semibold text-card-foreground mb-4 flex items-center">
<Hash className='w-5 h-5 mr-2 text-purple-500' />
<Hash className='w-5 h-5 mr-2 text-primary' />
{title}
</h3>
<div class="flex flex-wrap gap-2">
@@ -54,7 +54,7 @@ const title = titles[lang] || titles[defaultLang];
const isCurrentTag = tagId === currentTag.toLowerCase();
return (
<a href={`${baseUrl}/tags/${encodeURIComponent(tagId)}`}
class={`inline-block px-3 py-1 text-sm rounded-full transition-all duration-200 ${isCurrentTag ? 'bg-purple-500/20 text-purple-500 font-medium' : 'bg-muted text-muted-foreground hover:bg-purple-500/20 hover:text-purple-500'}`}>
class={`inline-block px-3 py-1 text-sm rounded-full transition-all duration-200 ${isCurrentTag ? 'bg-primary/20 text-primary font-medium' : 'bg-muted text-muted-foreground hover:bg-primary/20 hover:text-primary'}`}>
{tagItem}
</a>
);

View File

@@ -76,7 +76,7 @@ const nextText = lang === 'zh' ? '下一篇' : 'Next Post';
<a
href={prevPost.url}
style="width: -webkit-fill-available"
class="relative flex min-w-1/2 items-center justify-start gap-2 font-semibold dark:text-white text-black text-left text-pretty text-sm sm:text-base lg:text-lg leading-relaxed hover:text-purple-500 hover:[text-shadow:1px_1px_11px_rgba(168,85,247,0.7)] transition-all duration-300 before:absolute before:-top-6 before:left-0 before:text-xs sm:before:text-sm before:font-light before:content-['Previous_Post'] hover:before:text-purple-400"
class="relative flex min-w-1/2 items-center justify-start gap-2 font-semibold dark:text-white text-black text-left text-pretty text-sm sm:text-base lg:text-lg leading-relaxed hover:text-primary hover:[text-shadow:1px_1px_11px_rgba(168,85,247,0.7)] transition-all duration-300 before:absolute before:-top-6 before:left-0 before:text-xs sm:before:text-sm before:font-light before:content-['Previous_Post'] hover:before:text-primary"
tabindex="0"
aria-label={`${prevText}: ${prevPost.frontmatter.title}`}
>
@@ -91,7 +91,7 @@ const nextText = lang === 'zh' ? '下一篇' : 'Next Post';
<a
href={nextPost.url}
style="width: -webkit-fill-available"
class="relative flex min-w-1/2 items-center justify-end gap-2 font-semibold dark:text-white text-black text-right text-pretty text-sm sm:text-base lg:text-lg leading-relaxed hover:text-purple-500 hover:[text-shadow:1px_1px_11px_rgba(168,85,247,0.7)] transition-all duration-300 before:absolute before:-top-6 before:right-0 before:text-xs sm:before:text-sm before:font-light before:content-['Next_Post'] hover:before:text-purple-400"
class="relative flex min-w-1/2 items-center justify-end gap-2 font-semibold dark:text-white text-black text-right text-pretty text-sm sm:text-base lg:text-lg leading-relaxed hover:text-primary hover:[text-shadow:1px_1px_11px_rgba(168,85,247,0.7)] transition-all duration-300 before:absolute before:-top-6 before:right-0 before:text-xs sm:before:text-sm before:font-light before:content-['Next_Post'] hover:before:text-primary"
tabindex="0"
aria-label={`${nextText}: ${nextPost.frontmatter.title}`}
>

View File

@@ -14,7 +14,7 @@ const title = lang === 'zh' ? '目录' : 'Table of Contents';
<div id="nav-content" class="sticky xl:w-72 w-full top-14">
<div class="flex flex-col gap-3 p-4">
<h3 class="dark:text-zinc-200 text-blacktext font-bold tracking-wide text-sm sm:text-base uppercase flex items-center">
<svg class="w-4 h-4 sm:w-5 sm:h-5 mr-2 text-purple-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<svg class="w-4 h-4 sm:w-5 sm:h-5 mr-2 text-primary" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 10h16M4 14h16M4 18h16" />
</svg>
{title}
@@ -106,7 +106,7 @@ const title = lang === 'zh' ? '目录' : 'Table of Contents';
// Remove active state from all links
document.querySelectorAll("#toc-list a").forEach((el) => {
el.classList.remove(
"bg-purple-500/10", "text-purple-500", "border-l-purple-500", "font-medium"
"bg-primary/10", "text-primary", "border-l-primary", "font-medium"
);
el.classList.add("text-muted-foreground", "border-transparent");
});
@@ -115,7 +115,7 @@ const title = lang === 'zh' ? '目录' : 'Table of Contents';
if (link) {
link.classList.remove("text-muted-foreground", "border-transparent");
link.classList.add(
"bg-purple-500/10", "text-purple-500", "border-l-purple-500", "font-medium"
"bg-primary/10", "text-primary", "border-l-primary", "font-medium"
);
}
}

View File

@@ -69,10 +69,10 @@ const styles = {
component: AlertTriangle
},
tip: {
bg: 'bg-purple-500/10 dark:bg-purple-500/20',
border: 'border-purple-500/50 dark:border-purple-500/30',
title: 'text-purple-700 dark:text-purple-300',
icon: 'text-purple-500',
bg: 'bg-primary/10 dark:bg-primary/20',
border: 'border-primary/50 dark:border-primary/30',
title: 'text-primary dark:text-primary/80',
icon: 'text-primary',
component: Lightbulb
},
note: {

View File

@@ -21,7 +21,7 @@ const lang = Astro.currentLocale as Lang || defaultLang;
<!-- Enhanced background with gradient overlay -->
<div class="fixed inset-0 -z-10 h-full w-full bg-background">
<!-- Additional subtle gradient for about page -->
<div class="absolute inset-0 bg-gradient-to-br from-purple-50/30 via-transparent to-blue-50/20 dark:from-purple-950/20 dark:via-transparent dark:to-blue-950/10">
<div class="absolute inset-0 bg-gradient-to-br from-blue-50/30 via-transparent to-blue-50/20 dark:from-blue-950/20 dark:via-transparent dark:to-blue-950/10">
</div>
</div>
@@ -62,7 +62,7 @@ const lang = Astro.currentLocale as Lang || defaultLang;
<div id="nav-content" class="sticky xl:w-72 w-full top-14">
<div class="flex flex-col gap-3 p-4">
<h3 class="dark:text-zinc-200 text-blacktext font-bold tracking-wide text-sm sm:text-base uppercase flex items-center">
<svg class="w-4 h-4 sm:w-5 sm:h-5 mr-2 text-purple-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<svg class="w-4 h-4 sm:w-5 sm:h-5 mr-2 text-primary" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 10h16M4 14h16M4 18h16" />
</svg>
{lang === 'zh' ? '目录' : 'Table of Contents'}
@@ -161,7 +161,7 @@ const lang = Astro.currentLocale as Lang || defaultLang;
// Remove active state from all links
document.querySelectorAll("#toc-list a").forEach((el) => {
el.classList.remove(
"bg-purple-500/10", "text-purple-500", "border-l-purple-500", "font-medium"
"bg-primary/10", "text-primary", "border-l-primary", "font-medium"
);
el.classList.add("text-muted-foreground", "border-transparent");
});
@@ -170,7 +170,7 @@ const lang = Astro.currentLocale as Lang || defaultLang;
if (link) {
link.classList.remove("text-muted-foreground", "border-transparent");
link.classList.add(
"bg-purple-500/10", "text-purple-500", "border-l-purple-500", "font-medium"
"bg-primary/10", "text-primary", "border-l-primary", "font-medium"
);
}
}

View File

@@ -18,7 +18,7 @@ const lang = Astro.currentLocale as Lang || defaultLang;
<!-- Enhanced background with gradient overlay for better visual consistency -->
<div class="fixed inset-0 -z-10 h-full w-full bg-background">
<!-- Additional subtle gradient for blog pages -->
<div class="absolute inset-0 bg-gradient-to-br from-purple-50/30 via-transparent to-blue-50/20 dark:from-purple-950/20 dark:via-transparent dark:to-blue-950/10"></div>
<div class="absolute inset-0 bg-gradient-to-br from-blue-50/30 via-transparent to-blue-50/20 dark:from-blue-950/20 dark:via-transparent dark:to-blue-950/10"></div>
</div>
<!-- Glass Header with navigation -->

View File

@@ -25,6 +25,8 @@ const t = useTranslations(lang);
<meta name="generator" content={Astro.generator} />
<meta name="description" content={description} />
<title>{title}{t('site.title') ? ` | ${t('site.title')}` : ''}</title>
<!-- View Transitions for smooth page transitions -->
<meta name="view-transition" content="same-origin" />
{
import.meta.env.MODE === 'production' && (
<script defer src="https://cloud.umami.is/script.js" data-website-id="a79f759b-74ae-4165-b738-56d123a1c6be"></script>
@@ -32,10 +34,10 @@ const t = useTranslations(lang);
}
</head>
<body
class="min-h-screen bg-background font-sans antialiased selection:bg-purple-500/20 selection:text-purple-500"
class="min-h-screen bg-background font-sans antialiased selection:bg-primary/20 selection:text-primary"
>
<div
class="fixed inset-0 -z-10 h-full w-full bg-background bg-[radial-gradient(ellipse_80%_80%_at_50%_-20%,rgba(120,119,198,0.3),rgba(255,255,255,0))]"
class="fixed inset-0 -z-10 h-full w-full bg-background bg-[radial-gradient(ellipse_80%_80%_at_50%_-20%,rgba(37,99,235,0.15),rgba(255,255,255,0))]"
>
</div>
<slot />
@@ -86,4 +88,29 @@ const t = useTranslations(lang);
background-color var(--transition-standard),
color var(--transition-standard);
}
/* Page transition animations */
@keyframes pageIn {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
main {
animation: pageIn 0.4s ease-out forwards;
}
/* Reduced motion support */
@media (prefers-reduced-motion: reduce) {
main {
animation: none;
opacity: 1;
transform: none;
}
}
</style>

View File

@@ -48,8 +48,8 @@ const sortedBlogPosts = sortPostsByDate(blogPosts);
<!-- Header Section -->
<Container className="pt-24 pb-12">
<div class="text-center mb-16">
<h1 class="text-5xl md:text-6xl font-bold bg-gradient-to-r from-foreground via-purple-600 to-purple-800 dark:from-foreground dark:via-purple-200 dark:to-purple-300 bg-clip-text text-transparent mb-6">
<span class="text-purple-500">Blog</span>
<h1 class="text-5xl md:text-6xl font-bold bg-gradient-to-r from-foreground via-primary to-primary dark:from-foreground dark:via-blue-200 dark:to-orange-300 bg-clip-text text-transparent mb-6">
<span class="text-primary">Blog</span>
</h1>
<p class="text-xl text-muted-foreground max-w-3xl mx-auto">
Thoughts on AI products, full-stack development, and building in public. Exploring the intersection of technology and product building.

View File

@@ -17,14 +17,14 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
<main class="min-h-screen">
<!-- Hire Page Hero -->
<section class="py-24 relative overflow-hidden">
<div class="absolute inset-0 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"></div>
<div class="absolute inset-0 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"></div>
<Container className="relative z-10">
<div class="text-center mb-16">
<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' ? '专业合作' : 'Professional Collaboration'}
</span>
<h1 class="text-5xl md:text-6xl 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-5xl md:text-6xl font-bold mb-6 bg-gradient-to-r from-gray-900 via-primary to-primary dark:from-white dark:via-blue-200 dark:to-orange-300 bg-clip-text text-transparent">
{lang === 'zh' ? '合作' : 'Hire Me'}
</h1>
<p class="text-lg text-muted-foreground max-w-2xl mx-auto">
@@ -41,7 +41,7 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
<Container>
<div class="max-w-4xl mx-auto">
<div class="flex items-center gap-4 mb-8">
<div class="w-12 h-12 bg-purple-500/20 rounded-xl flex items-center justify-center">
<div class="w-12 h-12 bg-primary/20 rounded-xl flex items-center justify-center">
<span class="text-2xl">👥</span>
</div>
<h2 class="text-3xl font-bold">
@@ -50,7 +50,7 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
</div>
<div class="grid md:grid-cols-2 gap-6">
<div class="bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-2xl border border-purple-500/20 p-6">
<div class="bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-2xl border border-primary/20 p-6">
<h3 class="text-lg font-bold mb-3">
{lang === 'zh' ? '初创公司' : 'Startups'}
</h3>
@@ -61,7 +61,7 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
</p>
</div>
<div class="bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-2xl border border-purple-500/20 p-6">
<div class="bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-2xl border border-primary/20 p-6">
<h3 class="text-lg font-bold mb-3">
{lang === 'zh' ? '独立创始人' : 'Indie Hackers'}
</h3>
@@ -72,7 +72,7 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
</p>
</div>
<div class="bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-2xl border border-purple-500/20 p-6">
<div class="bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-2xl border border-primary/20 p-6">
<h3 class="text-lg font-bold mb-3">
{lang === 'zh' ? '传统企业' : 'Traditional Businesses'}
</h3>
@@ -83,7 +83,7 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
</p>
</div>
<div class="bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-2xl border border-purple-500/20 p-6">
<div class="bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-2xl border border-primary/20 p-6">
<h3 class="text-lg font-bold mb-3">
{lang === 'zh' ? '技术团队' : 'Technical Teams'}
</h3>
@@ -114,7 +114,7 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
<div class="space-y-6">
<div class="bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-2xl border border-blue-500/20 p-8">
<div class="flex items-start gap-4">
<div class="w-12 h-12 bg-gradient-to-br from-purple-600 to-blue-600 rounded-xl flex items-center justify-center flex-shrink-0">
<div class="w-12 h-12 bg-gradient-to-br from-primary to-blue-600 rounded-xl flex items-center justify-center flex-shrink-0">
<span class="text-2xl">⚡</span>
</div>
<div>
@@ -207,7 +207,7 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
</div>
<div class="bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-2xl border border-green-500/20 p-6 text-center">
<div class="w-12 h-12 bg-purple-500/20 rounded-xl flex items-center justify-center mx-auto mb-4">
<div class="w-12 h-12 bg-primary/20 rounded-xl flex items-center justify-center mx-auto mb-4">
<span class="text-2xl">⏰</span>
</div>
<h3 class="text-lg font-bold mb-2">
@@ -329,7 +329,7 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
<span class="px-3 py-1 bg-blue-500/20 text-blue-600 dark:text-blue-400 rounded-full text-sm">
{lang === 'zh' ? '远程工作' : 'Remote only'}
</span>
<span class="px-3 py-1 bg-purple-500/20 text-purple-600 dark:text-purple-400 rounded-full text-sm">
<span class="px-3 py-1 bg-primary/20 text-primary dark:text-primary rounded-full text-sm">
{lang === 'zh' ? '中英双语' : 'Bilingual EN/ZH'}
</span>
</div>
@@ -339,7 +339,7 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
</section>
<!-- Contact CTA -->
<section class="py-16 relative bg-gradient-to-br from-purple-900/20 to-blue-900/20 dark:from-purple-900/30 dark:to-blue-900/30">
<section class="py-16 relative bg-gradient-to-br from-blue-900/20 to-blue-900/20 dark:from-blue-900/30 dark:to-blue-900/30">
<Container>
<div class="max-w-4xl mx-auto text-center">
<h2 class="text-3xl font-bold mb-6">
@@ -353,14 +353,14 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
<div class="flex flex-col sm:flex-row gap-4 justify-center">
<a
href="mailto:zhaoguiyang18@gmail.com"
class="bg-purple-500 hover:bg-purple-600 text-white px-8 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-8 py-3 rounded-lg font-semibold transition-colors inline-flex items-center justify-center gap-2"
>
<span>📧</span>
{lang === 'zh' ? '发送邮件' : 'Send Email'}
</a>
<a
href={lang === 'zh' ? '/zh/now' : '/now'}
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 inline-flex items-center justify-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 inline-flex items-center justify-center gap-2"
>
<span>📡</span>
{lang === 'zh' ? '了解更多关于我' : 'Learn More About Me'}

View File

@@ -5,6 +5,7 @@ import SkillsMarquee from "@/components/SkillsMarquee";
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>

View File

@@ -17,14 +17,14 @@ const pageTitle = lang === 'zh' ? '现在' : 'Now';
<main class="min-h-screen">
<!-- Now Page Hero -->
<section class="py-24 relative overflow-hidden">
<div class="absolute inset-0 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"></div>
<div class="absolute inset-0 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"></div>
<Container className="relative z-10">
<div class="text-center mb-16">
<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' ? '关于我现在正在做什么' : "What's happening now"}
</span>
<h1 class="text-5xl md:text-6xl 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-5xl md:text-6xl font-bold mb-6 bg-gradient-to-r from-gray-900 via-primary to-primary dark:from-white dark:via-blue-200 dark:to-orange-300 bg-clip-text text-transparent">
{lang === 'zh' ? '现在' : 'Now'}
</h1>
<p class="text-lg text-muted-foreground max-w-2xl mx-auto">
@@ -41,7 +41,7 @@ const pageTitle = lang === 'zh' ? '现在' : 'Now';
<Container>
<div class="max-w-4xl mx-auto">
<div class="flex items-center gap-4 mb-8">
<div class="w-12 h-12 bg-purple-500/20 rounded-xl flex items-center justify-center">
<div class="w-12 h-12 bg-primary/20 rounded-xl flex items-center justify-center">
<span class="text-2xl">🔨</span>
</div>
<h2 class="text-3xl font-bold">
@@ -49,9 +49,9 @@ const pageTitle = lang === 'zh' ? '现在' : 'Now';
</h2>
</div>
<div class="bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-2xl border border-purple-500/20 p-8">
<div class="bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-2xl border border-primary/20 p-8">
<div class="flex items-start gap-6">
<div class="w-16 h-16 bg-gradient-to-br from-purple-600 to-blue-600 rounded-xl flex items-center justify-center flex-shrink-0">
<div class="w-16 h-16 bg-gradient-to-br from-primary to-blue-600 rounded-xl flex items-center justify-center flex-shrink-0">
<span class="text-3xl">⚡</span>
</div>
<div class="flex-1">
@@ -62,7 +62,7 @@ const pageTitle = lang === 'zh' ? '现在' : 'Now';
: 'An open AI workspace for builders to work smarter. Built from first principles of AI, creating fully open, self-hostable collaboration tools.'}
</p>
<div class="flex flex-wrap gap-2">
<span class="px-3 py-1 bg-purple-500/20 text-purple-600 dark:text-purple-400 rounded-full text-sm">AI Product</span>
<span class="px-3 py-1 bg-primary/20 text-primary dark:text-primary rounded-full text-sm">AI Product</span>
<span class="px-3 py-1 bg-blue-500/20 text-blue-600 dark:text-blue-400 rounded-full text-sm">TypeScript</span>
<span class="px-3 py-1 bg-green-500/20 text-green-600 dark:text-green-400 rounded-full text-sm">Open Source</span>
</div>
@@ -148,7 +148,7 @@ const pageTitle = lang === 'zh' ? '现在' : 'Now';
</section>
<!-- Open to Collaborate Section -->
<section class="py-16 relative bg-gradient-to-br from-purple-900/10 to-blue-900/10 dark:from-purple-900/20 dark:to-blue-900/20">
<section class="py-16 relative bg-gradient-to-br from-blue-900/10 to-blue-900/10 dark:from-blue-900/20 dark:to-blue-900/20">
<Container>
<div class="max-w-4xl mx-auto text-center">
<div class="flex items-center justify-center gap-4 mb-8">
@@ -169,14 +169,14 @@ const pageTitle = lang === 'zh' ? '现在' : 'Now';
<div class="flex flex-col sm:flex-row gap-4 justify-center">
<a
href={lang === 'zh' ? '/zh/hire' : '/hire'}
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>
{lang === 'zh' ? '查看合作方式' : 'View Collaboration Options'}
</a>
<a
href="mailto:zhaoguiyang18@gmail.com"
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' ? '发送邮件' : 'Send Email'}

View File

@@ -32,12 +32,12 @@ const experimentProjects = otherProjects.filter(p => p.type === 'experiment');
<!-- Projects Hero Section -->
<section class="py-24 relative overflow-hidden">
<!-- 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-primary/20 dark:from-blue-900/30 dark:via-primary/20 dark:to-primary/30"></div>
<Container className="relative z-10">
<div class="text-center mb-16">
<!-- Main title -->
<h1 class="text-5xl md:text-6xl 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-5xl md:text-6xl font-bold mb-6 bg-gradient-to-r from-gray-900 via-primary to-primary dark:from-white dark:via-blue-200 dark:to-orange-300 bg-clip-text text-transparent">
{t('projects.title')}
</h1>
@@ -51,23 +51,23 @@ const experimentProjects = otherProjects.filter(p => p.type === 'experiment');
<!-- Featured Project Section -->
{featuredProject && (
<section class="py-12 bg-gradient-to-br from-purple-900/10 to-blue-900/10 dark:from-purple-900/20 dark:to-blue-900/20">
<section class="py-12 bg-gradient-to-br from-blue-900/10 to-blue-900/10 dark:from-blue-900/20 dark:to-blue-900/20">
<Container>
<div class="max-w-5xl mx-auto">
<div class="flex items-center gap-4 mb-8">
<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">
<span class="inline-block px-4 py-1 bg-primary/20 text-primary dark:text-primary rounded-full text-sm font-medium">
Featured
</span>
</div>
<div class="bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-2xl border border-purple-500/30 overflow-hidden">
<div class="bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-2xl border border-primary/30 overflow-hidden">
<div class="grid lg:grid-cols-2">
<div class="h-64 lg:h-auto 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="h-64 lg:h-auto bg-gradient-to-br from-primary/20 via-blue-600/20 to-primary/20 flex items-center justify-center relative overflow-hidden">
<div class="text-8xl">{featuredProject.icon}</div>
</div>
<div class="p-8">
<div class="flex items-center gap-3 mb-4">
<span class="px-3 py-1 bg-purple-500/20 text-purple-600 dark:text-purple-400 rounded-full text-sm">
<span class="px-3 py-1 bg-primary/20 text-primary dark:text-primary rounded-full text-sm">
{t(`project.status.${featuredProject.status}`)}
</span>
<span class="px-3 py-1 bg-blue-500/20 text-blue-600 dark:text-blue-400 rounded-full text-sm">
@@ -101,7 +101,7 @@ const experimentProjects = otherProjects.filter(p => p.type === 'experiment');
</div>
<div class="flex gap-4">
<a href={featuredProject.link} class="bg-purple-500 hover:bg-purple-600 text-white px-6 py-2 rounded-lg font-medium transition-colors inline-flex items-center gap-2">
<a href={featuredProject.link} class="bg-primary hover:bg-primary/90 text-white px-6 py-2 rounded-lg font-medium transition-colors inline-flex items-center gap-2">
{t('project.visit')}
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14 5l7 7m0 0l-7 7m7-7H3"></path>
@@ -131,7 +131,7 @@ const experimentProjects = otherProjects.filter(p => p.type === 'experiment');
{productProjects.length > 0 && (
<>
<div class="flex items-center gap-4 mb-8">
<div class="w-10 h-10 bg-purple-500/20 rounded-lg flex items-center justify-center">
<div class="w-10 h-10 bg-primary/20 rounded-lg flex items-center justify-center">
<span class="text-xl">🛍️</span>
</div>
<h2 class="text-2xl font-bold">{t('project.type.product')}</h2>

View File

@@ -60,8 +60,8 @@ const tags = extractTags(allPostsArray);
<!-- 头部区域 -->
<Container className="pt-24 pb-12">
<div class="text-center mb-16">
<h1 class="text-5xl md:text-6xl font-bold bg-gradient-to-r from-foreground via-purple-600 to-purple-800 dark:from-foreground dark:via-purple-200 dark:to-purple-300 bg-clip-text text-transparent mb-6">
<span class="text-purple-500">博客</span>
<h1 class="text-5xl md:text-6xl font-bold bg-gradient-to-r from-foreground via-primary to-primary dark:from-foreground dark:via-blue-200 dark:to-orange-300 bg-clip-text text-transparent mb-6">
<span class="text-primary">博客</span>
</h1>
<p class="text-xl text-muted-foreground max-w-3xl mx-auto">
关于 AI 产品、全栈开发和公开构建的思考。探索技术与产品构建的交汇点。

View File

@@ -17,14 +17,14 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
<main class="min-h-screen">
<!-- Hire Page Hero -->
<section class="py-24 relative overflow-hidden">
<div class="absolute inset-0 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"></div>
<div class="absolute inset-0 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"></div>
<Container className="relative z-10">
<div class="text-center mb-16">
<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">
专业合作
</span>
<h1 class="text-5xl md:text-6xl 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-5xl md:text-6xl font-bold mb-6 bg-gradient-to-r from-gray-900 via-primary to-primary dark:from-white dark:via-blue-200 dark:to-orange-300 bg-clip-text text-transparent">
合作
</h1>
<p class="text-lg text-muted-foreground max-w-2xl mx-auto">
@@ -39,7 +39,7 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
<Container>
<div class="max-w-4xl mx-auto">
<div class="flex items-center gap-4 mb-8">
<div class="w-12 h-12 bg-purple-500/20 rounded-xl flex items-center justify-center">
<div class="w-12 h-12 bg-primary/20 rounded-xl flex items-center justify-center">
<span class="text-2xl">👥</span>
</div>
<h2 class="text-3xl font-bold">
@@ -48,7 +48,7 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
</div>
<div class="grid md:grid-cols-2 gap-6">
<div class="bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-2xl border border-purple-500/20 p-6">
<div class="bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-2xl border border-primary/20 p-6">
<h3 class="text-lg font-bold mb-3">
初创公司
</h3>
@@ -57,7 +57,7 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
</p>
</div>
<div class="bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-2xl border border-purple-500/20 p-6">
<div class="bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-2xl border border-primary/20 p-6">
<h3 class="text-lg font-bold mb-3">
独立创始人
</h3>
@@ -66,7 +66,7 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
</p>
</div>
<div class="bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-2xl border border-purple-500/20 p-6">
<div class="bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-2xl border border-primary/20 p-6">
<h3 class="text-lg font-bold mb-3">
传统企业
</h3>
@@ -75,7 +75,7 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
</p>
</div>
<div class="bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-2xl border border-purple-500/20 p-6">
<div class="bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-2xl border border-primary/20 p-6">
<h3 class="text-lg font-bold mb-3">
技术团队
</h3>
@@ -104,7 +104,7 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
<div class="space-y-6">
<div class="bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-2xl border border-blue-500/20 p-8">
<div class="flex items-start gap-4">
<div class="w-12 h-12 bg-gradient-to-br from-purple-600 to-blue-600 rounded-xl flex items-center justify-center flex-shrink-0">
<div class="w-12 h-12 bg-gradient-to-br from-primary to-blue-600 rounded-xl flex items-center justify-center flex-shrink-0">
<span class="text-2xl">⚡</span>
</div>
<div>
@@ -187,7 +187,7 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
</div>
<div class="bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-2xl border border-green-500/20 p-6 text-center">
<div class="w-12 h-12 bg-purple-500/20 rounded-xl flex items-center justify-center mx-auto mb-4">
<div class="w-12 h-12 bg-primary/20 rounded-xl flex items-center justify-center mx-auto mb-4">
<span class="text-2xl">⏰</span>
</div>
<h3 class="text-lg font-bold mb-2">
@@ -289,7 +289,7 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
<span class="px-3 py-1 bg-blue-500/20 text-blue-600 dark:text-blue-400 rounded-full text-sm">
远程工作
</span>
<span class="px-3 py-1 bg-purple-500/20 text-purple-600 dark:text-purple-400 rounded-full text-sm">
<span class="px-3 py-1 bg-primary/20 text-primary dark:text-primary rounded-full text-sm">
中英双语
</span>
</div>
@@ -299,7 +299,7 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
</section>
<!-- Contact CTA -->
<section class="py-16 relative bg-gradient-to-br from-purple-900/20 to-blue-900/20 dark:from-purple-900/30 dark:to-blue-900/30">
<section class="py-16 relative bg-gradient-to-br from-blue-900/20 to-blue-900/20 dark:from-blue-900/30 dark:to-blue-900/30">
<Container>
<div class="max-w-4xl mx-auto text-center">
<h2 class="text-3xl font-bold mb-6">
@@ -311,14 +311,14 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
<div class="flex flex-col sm:flex-row gap-4 justify-center">
<a
href="mailto:zhaoguiyang18@gmail.com"
class="bg-purple-500 hover:bg-purple-600 text-white px-8 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-8 py-3 rounded-lg font-semibold transition-colors inline-flex items-center justify-center gap-2"
>
<span>📧</span>
发送邮件
</a>
<a
href="/zh/now"
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 inline-flex items-center justify-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 inline-flex items-center justify-center gap-2"
>
<span>📡</span>
了解更多关于我

View File

@@ -5,6 +5,7 @@ import SkillsMarquee from "@/components/SkillsMarquee";
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="/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="/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">
Featured 项目
</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-blue-400 to-blue-400 bg-clip-text text-transparent">
Elynd
</h2>
<p class="text-lg text-muted-foreground max-w-2xl mx-auto">
@@ -216,12 +217,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">
让 AI 成为你的共同构建者
</div>
</div>
@@ -229,7 +230,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">
从第一天就融入 AI 思维
</div>
@@ -250,14 +251,14 @@ const pageTitle = t('site.title');
<div class="flex flex-col sm:flex-row gap-4 justify-center">
<a
href="/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="/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>
了解更多
@@ -272,7 +273,7 @@ const pageTitle = t('site.title');
<!-- Services Section - Inlined Content -->
<section id="services" class="py-20 px-4 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>
@@ -300,7 +301,7 @@ const pageTitle = t('site.title');
</div>
<div class="mt-12 text-center">
<a href="/zh/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="/zh/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>
@@ -313,13 +314,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>
@@ -407,7 +408,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">
@@ -420,10 +421,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">
@@ -456,11 +457,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">
我的项目
</h2>
<p class="text-lg text-muted-foreground max-w-2xl mx-auto">
@@ -469,23 +470,23 @@ 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-all duration-500 hover:scale-105 bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-xl relative">
<div class="group overflow-hidden border border-primary/20 hover:border-primary/40 h-full flex flex-col transition-all duration-500 hover:scale-105 bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-xl relative">
<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-all 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-all 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 应用
</h3>
</div>
@@ -493,15 +494,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>一个功能完整的任务管理应用程序</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>使用 React、TypeScript 和 Tailwind CSS 构建</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>具有拖放功能和实时更新</span>
</div>
</div>
@@ -519,7 +520,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')}
@@ -528,23 +529,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-all duration-500 hover:scale-105 bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-xl relative">
<div class="group overflow-hidden border border-primary/20 hover:border-primary/40 h-full flex flex-col transition-all duration-500 hover:scale-105 bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-xl relative">
<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-all 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-all 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>
电商平台
</h3>
</div>
@@ -552,15 +553,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>现代化的电子商务解决方案</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>使用 Next.js、Prisma 和 Stripe 构建</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>具有购物车、支付和管理面板功能</span>
</div>
</div>
@@ -587,23 +588,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-all duration-500 hover:scale-105 bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-xl relative">
<div class="group overflow-hidden border border-primary/20 hover:border-primary/40 h-full flex flex-col transition-all duration-500 hover:scale-105 bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-xl relative">
<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-all 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-all 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>
个人作品集
</h3>
</div>
@@ -611,15 +612,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>响应式个人作品集网站</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>使用 Astro、React 和 Tailwind CSS 构建</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>具有深色模式和平滑动画效果</span>
</div>
</div>

View File

@@ -17,14 +17,14 @@ const pageTitle = lang === 'zh' ? '现在' : 'Now';
<main class="min-h-screen">
<!-- Now Page Hero -->
<section class="py-24 relative overflow-hidden">
<div class="absolute inset-0 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"></div>
<div class="absolute inset-0 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"></div>
<Container className="relative z-10">
<div class="text-center mb-16">
<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">
关于我现在正在做什么
</span>
<h1 class="text-5xl md:text-6xl 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-5xl md:text-6xl font-bold mb-6 bg-gradient-to-r from-gray-900 via-primary to-primary dark:from-white dark:via-blue-200 dark:to-orange-300 bg-clip-text text-transparent">
现在
</h1>
<p class="text-lg text-muted-foreground max-w-2xl mx-auto">
@@ -39,7 +39,7 @@ const pageTitle = lang === 'zh' ? '现在' : 'Now';
<Container>
<div class="max-w-4xl mx-auto">
<div class="flex items-center gap-4 mb-8">
<div class="w-12 h-12 bg-purple-500/20 rounded-xl flex items-center justify-center">
<div class="w-12 h-12 bg-primary/20 rounded-xl flex items-center justify-center">
<span class="text-2xl">🔨</span>
</div>
<h2 class="text-3xl font-bold">
@@ -47,9 +47,9 @@ const pageTitle = lang === 'zh' ? '现在' : 'Now';
</h2>
</div>
<div class="bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-2xl border border-purple-500/20 p-8">
<div class="bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-2xl border border-primary/20 p-8">
<div class="flex items-start gap-6">
<div class="w-16 h-16 bg-gradient-to-br from-purple-600 to-blue-600 rounded-xl flex items-center justify-center flex-shrink-0">
<div class="w-16 h-16 bg-gradient-to-br from-primary to-blue-600 rounded-xl flex items-center justify-center flex-shrink-0">
<span class="text-3xl">⚡</span>
</div>
<div class="flex-1">
@@ -58,7 +58,7 @@ const pageTitle = lang === 'zh' ? '现在' : 'Now';
一个开放的 AI 工作空间,让构建者能够更智能地工作。从 AI 第一性原理出发,打造完全开放、可自托管的协作工具。
</p>
<div class="flex flex-wrap gap-2">
<span class="px-3 py-1 bg-purple-500/20 text-purple-600 dark:text-purple-400 rounded-full text-sm">AI 产品</span>
<span class="px-3 py-1 bg-primary/20 text-primary dark:text-primary rounded-full text-sm">AI 产品</span>
<span class="px-3 py-1 bg-blue-500/20 text-blue-600 dark:text-blue-400 rounded-full text-sm">TypeScript</span>
<span class="px-3 py-1 bg-green-500/20 text-green-600 dark:text-green-400 rounded-full text-sm">开源</span>
</div>
@@ -138,7 +138,7 @@ const pageTitle = lang === 'zh' ? '现在' : 'Now';
</section>
<!-- Open to Collaborate Section -->
<section class="py-16 relative bg-gradient-to-br from-purple-900/10 to-blue-900/10 dark:from-purple-900/20 dark:to-blue-900/20">
<section class="py-16 relative bg-gradient-to-br from-blue-900/10 to-blue-900/10 dark:from-blue-900/20 dark:to-blue-900/20">
<Container>
<div class="max-w-4xl mx-auto text-center">
<div class="flex items-center justify-center gap-4 mb-8">
@@ -157,14 +157,14 @@ const pageTitle = lang === 'zh' ? '现在' : 'Now';
<div class="flex flex-col sm:flex-row gap-4 justify-center">
<a
href="/zh/hire"
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>
查看合作方式
</a>
<a
href="mailto:zhaoguiyang18@gmail.com"
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>
发送邮件

View File

@@ -32,12 +32,12 @@ const experimentProjects = otherProjects.filter(p => p.type === 'experiment');
<!-- Projects Hero Section -->
<section class="py-24 relative overflow-hidden">
<!-- 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-primary/20 dark:from-blue-900/30 dark:via-primary/20 dark:to-primary/30"></div>
<Container className="relative z-10">
<div class="text-center mb-16">
<!-- Main title -->
<h1 class="text-5xl md:text-6xl 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-5xl md:text-6xl font-bold mb-6 bg-gradient-to-r from-gray-900 via-primary to-primary dark:from-white dark:via-blue-200 dark:to-orange-300 bg-clip-text text-transparent">
{t('projects.title')}
</h1>
@@ -51,23 +51,23 @@ const experimentProjects = otherProjects.filter(p => p.type === 'experiment');
<!-- Featured Project Section -->
{featuredProject && (
<section class="py-12 bg-gradient-to-br from-purple-900/10 to-blue-900/10 dark:from-purple-900/20 dark:to-blue-900/20">
<section class="py-12 bg-gradient-to-br from-blue-900/10 to-blue-900/10 dark:from-blue-900/20 dark:to-blue-900/20">
<Container>
<div class="max-w-5xl mx-auto">
<div class="flex items-center gap-4 mb-8">
<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">
<span class="inline-block px-4 py-1 bg-primary/20 text-primary dark:text-primary rounded-full text-sm font-medium">
Featured 项目
</span>
</div>
<div class="bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-2xl border border-purple-500/30 overflow-hidden">
<div class="bg-white/10 dark:bg-gray-800/50 backdrop-blur-sm rounded-2xl border border-primary/30 overflow-hidden">
<div class="grid lg:grid-cols-2">
<div class="h-64 lg:h-auto 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="h-64 lg:h-auto bg-gradient-to-br from-primary/20 via-blue-600/20 to-primary/20 flex items-center justify-center relative overflow-hidden">
<div class="text-8xl">{featuredProject.icon}</div>
</div>
<div class="p-8">
<div class="flex items-center gap-3 mb-4">
<span class="px-3 py-1 bg-purple-500/20 text-purple-600 dark:text-purple-400 rounded-full text-sm">
<span class="px-3 py-1 bg-primary/20 text-primary dark:text-primary rounded-full text-sm">
{t(`project.status.${featuredProject.status}`)}
</span>
<span class="px-3 py-1 bg-blue-500/20 text-blue-600 dark:text-blue-400 rounded-full text-sm">
@@ -101,7 +101,7 @@ const experimentProjects = otherProjects.filter(p => p.type === 'experiment');
</div>
<div class="flex gap-4">
<a href={featuredProject.link} class="bg-purple-500 hover:bg-purple-600 text-white px-6 py-2 rounded-lg font-medium transition-colors inline-flex items-center gap-2">
<a href={featuredProject.link} class="bg-primary hover:bg-primary/90 text-white px-6 py-2 rounded-lg font-medium transition-colors inline-flex items-center gap-2">
{t('project.visit')}
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14 5l7 7m0 0l-7 7m7-7H3"></path>
@@ -131,7 +131,7 @@ const experimentProjects = otherProjects.filter(p => p.type === 'experiment');
{productProjects.length > 0 && (
<>
<div class="flex items-center gap-4 mb-8">
<div class="w-10 h-10 bg-purple-500/20 rounded-lg flex items-center justify-center">
<div class="w-10 h-10 bg-primary/20 rounded-lg flex items-center justify-center">
<span class="text-xl">🛍️</span>
</div>
<h2 class="text-2xl font-bold">{t('project.type.product')}</h2>

View File

@@ -1,5 +1,6 @@
@import "tailwindcss";
@import "tw-animate-css";
@import url('https://fonts.googleapis.com/css2?family=Archivo:ital,wght@0,400;0,500;0,600;0,700;0,800;1,400;1,500&family=Space+Grotesk:wght@300;400;500;600;700&display=swap');
@plugin "@tailwindcss/typography";
/* Blog List Component Styles */
@@ -43,24 +44,24 @@
:root {
--radius: 0.75rem;
--background: oklch(1 0 0);
--foreground: oklch(0.145 0 0);
--card: oklch(1 0 0);
--card-foreground: oklch(0.145 0 0);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.145 0 0);
--primary: oklch(0.205 0 0);
--primary-foreground: oklch(0.985 0 0);
--secondary: oklch(0.97 0 0);
--secondary-foreground: oklch(0.205 0 0);
--muted: oklch(0.97 0 0);
--muted-foreground: oklch(0.556 0 0);
--accent: oklch(0.97 0 0);
--accent-foreground: oklch(0.205 0 0);
--destructive: oklch(0.577 0.245 27.325);
--border: oklch(0.922 0 0);
--input: oklch(0.922 0 0);
--ring: oklch(0.708 0 0);
--background: #F8FAFC;
--foreground: #1E293B;
--card: #FFFFFF;
--card-foreground: #1E293B;
--popover: #FFFFFF;
--popover-foreground: #1E293B;
--primary: #2563EB;
--primary-foreground: #FFFFFF;
--secondary: #E4E4E7;
--secondary-foreground: #1E293B;
--muted: #F4F4F5;
--muted-foreground: #71717A;
--accent: #F97316;
--accent-foreground: #FFFFFF;
--destructive: #EF4444;
--border: #E4E4E7;
--input: #E4E4E7;
--ring: #2563EB;
--chart-1: oklch(0.646 0.222 41.116);
--chart-2: oklch(0.6 0.118 184.704);
--chart-3: oklch(0.398 0.07 227.392);
@@ -78,34 +79,37 @@
--svg-filter-color: invert(0%) sepia(0%) saturate(0%) hue-rotate(324deg) brightness(96%) contrast(104%);
/* Modern Design Variables */
--gradient-primary: linear-gradient(135deg, #8B5CF6, #EC4899);
--gradient-primary: linear-gradient(135deg, #2563EB, #F97316);
--gradient-secondary: linear-gradient(135deg, #3B82F6, #10B981);
--gradient-accent: linear-gradient(135deg, #F97316, #FB923C);
--shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.05);
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.08);
--shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.12);
--shadow-xl: 0 12px 40px rgba(37, 99, 235, 0.15);
--animation-bounce: cubic-bezier(0.34, 1.56, 0.64, 1);
--animation-smooth: cubic-bezier(0.65, 0, 0.35, 1);
--animation-spring: cubic-bezier(0.22, 1, 0.36, 1);
}
.dark {
--background: oklch(0.145 0 0);
--foreground: oklch(0.985 0 0);
--card: oklch(0.205 0 0);
--card-foreground: oklch(0.985 0 0);
--popover: oklch(0.205 0 0);
--popover-foreground: oklch(0.985 0 0);
--primary: oklch(0.922 0 0);
--primary-foreground: oklch(0.205 0 0);
--secondary: oklch(0.269 0 0);
--secondary-foreground: oklch(0.985 0 0);
--muted: oklch(0.269 0 0);
--muted-foreground: oklch(0.708 0 0);
--accent: oklch(0.269 0 0);
--accent-foreground: oklch(0.985 0 0);
--destructive: oklch(0.704 0.191 22.216);
--border: oklch(1 0 0 / 10%);
--input: oklch(1 0 0 / 15%);
--ring: oklch(0.556 0 0);
--background: #09090B;
--foreground: #F8FAFC;
--card: #18181B;
--card-foreground: #F8FAFC;
--popover: #18181B;
--popover-foreground: #F8FAFC;
--primary: #3B82F6;
--primary-foreground: #FFFFFF;
--secondary: #27272A;
--secondary-foreground: #F8FAFC;
--muted: #27272A;
--muted-foreground: #A1A1AA;
--accent: #FB923C;
--accent-foreground: #09090B;
--destructive: #EF4444;
--border: #27272A;
--input: #27272A;
--ring: #3B82F6;
--chart-1: oklch(0.488 0.243 264.376);
--chart-2: oklch(0.696 0.17 162.48);
--chart-3: oklch(0.769 0.188 70.08);
@@ -122,9 +126,10 @@
--svg-filter-color: invert(100%) sepia(0%) saturate(0%) hue-rotate(324deg) brightness(102%) contrast(101%);
/* Dark Mode Modern Design Variables */
--shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.2);
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.25);
--shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.3);
--shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.3);
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.4);
--shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.5);
--shadow-xl: 0 12px 40px rgba(59, 130, 246, 0.2);
}
@theme inline {
@@ -172,11 +177,12 @@
}
body {
@apply bg-background text-foreground;
font-family: "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans SC", "Inter", "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
font-family: "Space Grotesk", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans SC", "Inter", "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
font-feature-settings: "ss01", "ss02", "cv01", "cv02";
}
h1, h2, h3, h4, h5, h6 {
@apply font-bold tracking-tight;
font-family: "Archivo", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans SC", "Inter", "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
line-height: 1.2;
}
a {
@@ -186,3 +192,148 @@
@apply rounded-md;
}
}
/* Animation utilities */
@layer utilities {
.animate-fade-in {
animation: fadeIn 0.6s ease-out forwards;
}
.animate-fade-in-up {
animation: fadeInUp 0.6s ease-out forwards;
}
.animate-slide-in-left {
animation: slideInLeft 0.5s ease-out forwards;
}
.animate-slide-in-right {
animation: slideInRight 0.5s ease-out forwards;
}
.animate-scale-in {
animation: scaleIn 0.4s ease-out forwards;
}
.animate-bounce-in {
animation: bounceIn 0.6s cubic-bezier(0.22, 1, 0.36, 1) forwards;
}
.hover-lift {
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.hover-lift:hover {
transform: translateY(-5px);
box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1);
}
.dark .hover-lift:hover {
box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.3);
}
.gradient-text-primary {
background: linear-gradient(135deg, #2563EB, #F97316);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.gradient-text-accent {
background: linear-gradient(135deg, #F97316, #FB923C);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
/* Scroll reveal animations */
.reveal {
opacity: 0;
transform: translateY(20px);
transition: opacity 0.6s ease-out, transform 0.6s ease-out;
}
.reveal.active {
opacity: 1;
transform: translateY(0);
}
/* Reduced motion support */
@media (prefers-reduced-motion: reduce) {
.animate-fade-in,
.animate-fade-in-up,
.animate-slide-in-left,
.animate-slide-in-right,
.animate-scale-in,
.animate-bounce-in,
.reveal {
animation: none;
opacity: 1;
transform: none;
}
}
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes slideInLeft {
from {
opacity: 0;
transform: translateX(-20px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
@keyframes slideInRight {
from {
opacity: 0;
transform: translateX(20px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
@keyframes scaleIn {
from {
opacity: 0;
transform: scale(0.95);
}
to {
opacity: 1;
transform: scale(1);
}
}
@keyframes bounceIn {
from {
opacity: 0;
transform: scale(0.9);
}
to {
opacity: 1;
transform: scale(1);
}
}