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"> <div className="flex flex-col items-center text-center">
{/* Avatar */} {/* Avatar */}
<div className="flex-shrink-0 mb-4"> <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 ? ( {authorInfo.avatar ? (
<img <img
src={authorInfo.avatar} src={authorInfo.avatar}
@@ -56,7 +56,7 @@ export default function AuthorCard({ lang, author }: AuthorCardProps) {
href={authorInfo.website} href={authorInfo.website}
target="_blank" target="_blank"
rel="noopener noreferrer" 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} title={websiteText}
> >
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <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); const t = useTranslations(lang);
return ( 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> <Container>
<motion.div <motion.div
className="flex flex-col md:flex-row justify-between items-center" 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')} &copy; {new Date().getFullYear()} { personalInfo.name }. {t('footer.rights')}
</motion.p> </motion.p>
<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 }} whileHover={{ scale: 1.01 }}
> >
{lang === 'zh' ? '构建 AI 产品?寻找技术合伙人?联系我!' : 'Building AI Products? Need a Technical Co-founder? Contact me!'} {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] }} transition={{ duration: 0.5, ease: [0.22, 1, 0.36, 1] }}
className={`fixed top-0 z-50 w-full transition-all duration-300 ${ className={`fixed top-0 z-50 w-full transition-all duration-300 ${
isScrolled 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' : 'bg-transparent'
}`} }`}
> >
@@ -75,7 +75,7 @@ export default function GlassHeader({ lang: propLang }: GlassHeaderProps) {
<motion.a <motion.a
key={item.key} key={item.key}
href={item.href} 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 }} initial={{ opacity: 0, y: -20 }}
animate={{ opacity: 1, y: 0 }} animate={{ opacity: 1, y: 0 }}
transition={{ transition={{

View File

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

View File

@@ -56,7 +56,7 @@ export default function ShareButtons({ lang, title, url }: ShareButtonsProps) {
return ( return (
<div className="bg-card/50 backdrop-blur-sm rounded-2xl border border-border p-6"> <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"> <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" /> <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> </svg>
{shareText} {shareText}
@@ -87,7 +87,7 @@ export default function ShareButtons({ lang, title, url }: ShareButtonsProps) {
className=" className="
flex items-center justify-center w-12 h-12 rounded-full flex items-center justify-center w-12 h-12 rounded-full
bg-muted text-muted-foreground transition-all duration-200 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 relative
" "
title={copyText} title={copyText}
@@ -106,7 +106,7 @@ export default function ShareButtons({ lang, title, url }: ShareButtonsProps) {
{/* Copy Success Message */} {/* Copy Success Message */}
{copied && ( {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"> <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" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M5 13l4 4L19 7" />
</svg> </svg>

View File

@@ -53,7 +53,7 @@ function SkillItem({ skill }: { skill: SkillItem }) {
const iconUrl = `https://skillicons.dev/icons?i=${skill.icon}`; const iconUrl = `https://skillicons.dev/icons?i=${skill.icon}`;
return ( 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 <img
src={iconUrl} src={iconUrl}
alt={skill.name} alt={skill.name}

View File

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

View File

@@ -76,7 +76,7 @@ const readMoreText = lang === 'zh' ? '阅读更多' : 'Read More';
{posts.length > 0 ? ( {posts.length > 0 ? (
posts.map((post, index) => ( posts.map((post, index) => (
<article class="group"> <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"> <div class="flex flex-col md:flex-row">
{/* Featured Image */} {/* Featured Image */}
<div class="relative overflow-hidden md:w-80 md:flex-shrink-0"> <div class="relative overflow-hidden md:w-80 md:flex-shrink-0">
@@ -91,7 +91,7 @@ const readMoreText = lang === 'zh' ? '阅读更多' : 'Read More';
{/* Content */} {/* Content */}
<div class="p-6 flex-1 flex flex-col justify-between"> <div class="p-6 flex-1 flex flex-col justify-between">
<div> <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}`}> <a href={`${postBaseUrl}${post.slug}`}>
{post.title} {post.title}
</a> </a>
@@ -135,7 +135,7 @@ const readMoreText = lang === 'zh' ? '阅读更多' : 'Read More';
<a <a
href={`${postBaseUrl}${post.slug}`} 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} {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"> <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]"> <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> <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> </svg>
<p class="text-xl text-muted-foreground mb-4"> <p class="text-xl text-muted-foreground mb-4">
@@ -161,7 +161,7 @@ const readMoreText = lang === 'zh' ? '阅读更多' : 'Read More';
</p> </p>
<a <a
href={`/${lang === 'en' ? '' : 'zh/'}`} 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"> <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> <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"> <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"> <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} {title}
</h3> </h3>
<div class="space-y-2"> <div class="space-y-2">
@@ -52,7 +52,7 @@ const title = titles[lang] || titles[defaultLang];
const categoryId = categoryMap.get(cat) || cat.toLowerCase(); const categoryId = categoryMap.get(cat) || cat.toLowerCase();
return ( return (
<a href={`${baseUrl}/categories/${encodeURIComponent(categoryId)}`} <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} {cat}
</a> </a>
); );

View File

@@ -99,13 +99,13 @@ const getReadingTimeText = (minutes: number) => {
: cat.toLowerCase(); : cat.toLowerCase();
return ( 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} {cat}
</a> </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} {category}
</a> </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"> <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"> <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} {title}
</h3> </h3>
<div class="flex flex-wrap gap-2"> <div class="flex flex-wrap gap-2">
@@ -54,7 +54,7 @@ const title = titles[lang] || titles[defaultLang];
const isCurrentTag = tagId === currentTag.toLowerCase(); const isCurrentTag = tagId === currentTag.toLowerCase();
return ( return (
<a href={`${baseUrl}/tags/${encodeURIComponent(tagId)}`} <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} {tagItem}
</a> </a>
); );

View File

@@ -76,7 +76,7 @@ const nextText = lang === 'zh' ? '下一篇' : 'Next Post';
<a <a
href={prevPost.url} href={prevPost.url}
style="width: -webkit-fill-available" 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" tabindex="0"
aria-label={`${prevText}: ${prevPost.frontmatter.title}`} aria-label={`${prevText}: ${prevPost.frontmatter.title}`}
> >
@@ -91,7 +91,7 @@ const nextText = lang === 'zh' ? '下一篇' : 'Next Post';
<a <a
href={nextPost.url} href={nextPost.url}
style="width: -webkit-fill-available" 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" tabindex="0"
aria-label={`${nextText}: ${nextPost.frontmatter.title}`} 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 id="nav-content" class="sticky xl:w-72 w-full top-14">
<div class="flex flex-col gap-3 p-4"> <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"> <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" /> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 10h16M4 14h16M4 18h16" />
</svg> </svg>
{title} {title}
@@ -106,7 +106,7 @@ const title = lang === 'zh' ? '目录' : 'Table of Contents';
// Remove active state from all links // Remove active state from all links
document.querySelectorAll("#toc-list a").forEach((el) => { document.querySelectorAll("#toc-list a").forEach((el) => {
el.classList.remove( 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"); el.classList.add("text-muted-foreground", "border-transparent");
}); });
@@ -115,7 +115,7 @@ const title = lang === 'zh' ? '目录' : 'Table of Contents';
if (link) { if (link) {
link.classList.remove("text-muted-foreground", "border-transparent"); link.classList.remove("text-muted-foreground", "border-transparent");
link.classList.add( 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 component: AlertTriangle
}, },
tip: { tip: {
bg: 'bg-purple-500/10 dark:bg-purple-500/20', bg: 'bg-primary/10 dark:bg-primary/20',
border: 'border-purple-500/50 dark:border-purple-500/30', border: 'border-primary/50 dark:border-primary/30',
title: 'text-purple-700 dark:text-purple-300', title: 'text-primary dark:text-primary/80',
icon: 'text-purple-500', icon: 'text-primary',
component: Lightbulb component: Lightbulb
}, },
note: { note: {

View File

@@ -21,7 +21,7 @@ const lang = Astro.currentLocale as Lang || defaultLang;
<!-- Enhanced background with gradient overlay --> <!-- Enhanced background with gradient overlay -->
<div class="fixed inset-0 -z-10 h-full w-full bg-background"> <div class="fixed inset-0 -z-10 h-full w-full bg-background">
<!-- Additional subtle gradient for about page --> <!-- 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>
</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 id="nav-content" class="sticky xl:w-72 w-full top-14">
<div class="flex flex-col gap-3 p-4"> <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"> <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" /> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 10h16M4 14h16M4 18h16" />
</svg> </svg>
{lang === 'zh' ? '目录' : 'Table of Contents'} {lang === 'zh' ? '目录' : 'Table of Contents'}
@@ -161,7 +161,7 @@ const lang = Astro.currentLocale as Lang || defaultLang;
// Remove active state from all links // Remove active state from all links
document.querySelectorAll("#toc-list a").forEach((el) => { document.querySelectorAll("#toc-list a").forEach((el) => {
el.classList.remove( 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"); el.classList.add("text-muted-foreground", "border-transparent");
}); });
@@ -170,7 +170,7 @@ const lang = Astro.currentLocale as Lang || defaultLang;
if (link) { if (link) {
link.classList.remove("text-muted-foreground", "border-transparent"); link.classList.remove("text-muted-foreground", "border-transparent");
link.classList.add( 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 --> <!-- Enhanced background with gradient overlay for better visual consistency -->
<div class="fixed inset-0 -z-10 h-full w-full bg-background"> <div class="fixed inset-0 -z-10 h-full w-full bg-background">
<!-- Additional subtle gradient for blog pages --> <!-- 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> </div>
<!-- Glass Header with navigation --> <!-- Glass Header with navigation -->

View File

@@ -25,6 +25,8 @@ const t = useTranslations(lang);
<meta name="generator" content={Astro.generator} /> <meta name="generator" content={Astro.generator} />
<meta name="description" content={description} /> <meta name="description" content={description} />
<title>{title}{t('site.title') ? ` | ${t('site.title')}` : ''}</title> <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' && ( import.meta.env.MODE === 'production' && (
<script defer src="https://cloud.umami.is/script.js" data-website-id="a79f759b-74ae-4165-b738-56d123a1c6be"></script> <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> </head>
<body <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 <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> </div>
<slot /> <slot />
@@ -86,4 +88,29 @@ const t = useTranslations(lang);
background-color var(--transition-standard), background-color var(--transition-standard),
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> </style>

View File

@@ -48,8 +48,8 @@ const sortedBlogPosts = sortPostsByDate(blogPosts);
<!-- Header Section --> <!-- Header Section -->
<Container className="pt-24 pb-12"> <Container className="pt-24 pb-12">
<div class="text-center mb-16"> <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"> <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-purple-500">Blog</span> <span class="text-primary">Blog</span>
</h1> </h1>
<p class="text-xl text-muted-foreground max-w-3xl mx-auto"> <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. 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"> <main class="min-h-screen">
<!-- Hire Page Hero --> <!-- Hire Page Hero -->
<section class="py-24 relative overflow-hidden"> <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"> <Container className="relative z-10">
<div class="text-center mb-16"> <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'} {lang === 'zh' ? '专业合作' : 'Professional Collaboration'}
</span> </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'} {lang === 'zh' ? '合作' : 'Hire Me'}
</h1> </h1>
<p class="text-lg text-muted-foreground max-w-2xl mx-auto"> <p class="text-lg text-muted-foreground max-w-2xl mx-auto">
@@ -41,7 +41,7 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
<Container> <Container>
<div class="max-w-4xl mx-auto"> <div class="max-w-4xl mx-auto">
<div class="flex items-center gap-4 mb-8"> <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> <span class="text-2xl">👥</span>
</div> </div>
<h2 class="text-3xl font-bold"> <h2 class="text-3xl font-bold">
@@ -50,7 +50,7 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
</div> </div>
<div class="grid md:grid-cols-2 gap-6"> <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 class="text-lg font-bold mb-3">
{lang === 'zh' ? '初创公司' : 'Startups'} {lang === 'zh' ? '初创公司' : 'Startups'}
</h3> </h3>
@@ -61,7 +61,7 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
</p> </p>
</div> </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 class="text-lg font-bold mb-3">
{lang === 'zh' ? '独立创始人' : 'Indie Hackers'} {lang === 'zh' ? '独立创始人' : 'Indie Hackers'}
</h3> </h3>
@@ -72,7 +72,7 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
</p> </p>
</div> </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 class="text-lg font-bold mb-3">
{lang === 'zh' ? '传统企业' : 'Traditional Businesses'} {lang === 'zh' ? '传统企业' : 'Traditional Businesses'}
</h3> </h3>
@@ -83,7 +83,7 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
</p> </p>
</div> </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 class="text-lg font-bold mb-3">
{lang === 'zh' ? '技术团队' : 'Technical Teams'} {lang === 'zh' ? '技术团队' : 'Technical Teams'}
</h3> </h3>
@@ -114,7 +114,7 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
<div class="space-y-6"> <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="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="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> <span class="text-2xl">⚡</span>
</div> </div>
<div> <div>
@@ -207,7 +207,7 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
</div> </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="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> <span class="text-2xl">⏰</span>
</div> </div>
<h3 class="text-lg font-bold mb-2"> <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"> <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'} {lang === 'zh' ? '远程工作' : 'Remote only'}
</span> </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'} {lang === 'zh' ? '中英双语' : 'Bilingual EN/ZH'}
</span> </span>
</div> </div>
@@ -339,7 +339,7 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
</section> </section>
<!-- Contact CTA --> <!-- 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> <Container>
<div class="max-w-4xl mx-auto text-center"> <div class="max-w-4xl mx-auto text-center">
<h2 class="text-3xl font-bold mb-6"> <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"> <div class="flex flex-col sm:flex-row gap-4 justify-center">
<a <a
href="mailto:zhaoguiyang18@gmail.com" 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> <span>📧</span>
{lang === 'zh' ? '发送邮件' : 'Send Email'} {lang === 'zh' ? '发送邮件' : 'Send Email'}
</a> </a>
<a <a
href={lang === 'zh' ? '/zh/now' : '/now'} 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> <span>📡</span>
{lang === 'zh' ? '了解更多关于我' : 'Learn More About Me'} {lang === 'zh' ? '了解更多关于我' : 'Learn More About Me'}

View File

@@ -5,6 +5,7 @@ import SkillsMarquee from "@/components/SkillsMarquee";
import TypewriterEffect from "@/components/TypewriterEffect"; import TypewriterEffect from "@/components/TypewriterEffect";
import Footer from "@/components/Footer"; import Footer from "@/components/Footer";
import Container from "@/components/ui/Container.astro"; import Container from "@/components/ui/Container.astro";
import MotionWrapper from "@/components/MotionWrapper";
import { useTranslations } from "@/i18n/utils"; import { useTranslations } from "@/i18n/utils";
import type { Lang } from "@/types/i18n"; import type { Lang } from "@/types/i18n";
import { defaultLang } from "@/i18n/ui"; import { defaultLang } from "@/i18n/ui";
@@ -22,22 +23,22 @@ const pageTitle = t('site.title');
<!-- Hero Section - Inlined Content --> <!-- Hero Section - Inlined Content -->
<section class="py-32 relative overflow-hidden min-h-screen flex flex-col justify-center"> <section class="py-32 relative overflow-hidden min-h-screen flex flex-col justify-center">
<!-- Background gradient --> <!-- 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"> <Container className="relative z-10">
<div class="text-center mb-16"> <div class="text-center mb-16">
<!-- Greeting --> <!-- Greeting -->
<div class="flex items-center justify-center mb-6"> <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> <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> </svg>
<span class="text-purple-500 font-mono text-lg"> <span class="text-primary font-mono text-lg">
{t('hero.greeting')} {personalInfo.name} {t('hero.greeting')} {personalInfo.name}
</span> </span>
</div> </div>
<!-- Main title --> <!-- 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} {personalInfo.name}
</h1> </h1>
@@ -58,7 +59,7 @@ const pageTitle = t('site.title');
delayBeforeDelete={3500} delayBeforeDelete={3500}
delayBeforeTyping={1800} delayBeforeTyping={1800}
loop={true} loop={true}
cursorClassName="text-purple-600 dark:text-purple-400" cursorClassName="text-primary dark:text-primary"
className="mr-2 font-medium text-muted-foreground" className="mr-2 font-medium text-muted-foreground"
/> />
<span>👨‍💻</span> <span>👨‍💻</span>
@@ -72,7 +73,7 @@ const pageTitle = t('site.title');
<!-- Job availability notice --> <!-- Job availability notice -->
<div class="mb-8"> <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> <p class="text-md text-muted-foreground">{t('hero.digitalNomad')}</p>
</div> </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"> <div class="flex flex-col sm:flex-row gap-4 justify-center items-center mb-16">
<a <a
href={`/${lang === 'zh' ? 'zh/' : ''}hire`} 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"> <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> <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 <a
href={`/${lang === 'zh' ? 'zh/' : ''}projects`} 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"> <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> <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="p-6 font-mono text-sm">
<div class="space-y-2"> <div class="space-y-2">
<div class="flex items-center"> <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> <span class="text-white">whoami</span>
</div> </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"> <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> <span class="text-white">cat about.txt</span>
</div> </div>
<div class="text-gray-300 ml-4 leading-relaxed"> <div class="text-gray-300 ml-4 leading-relaxed">
@@ -180,15 +181,15 @@ const pageTitle = t('site.title');
</div> </div>
<div class="flex items-center mt-4"> <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> <span class="text-white">ls projects/</span>
</div> </div>
<div class="text-purple-200 ml-4"> <div class="text-primary/70 ml-4">
taskify-app/ e-commerce-platform/ portfolio-site/ taskify-app/ e-commerce-platform/ portfolio-site/
</div> </div>
<div class="flex items-center mt-4"> <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> <span class="text-white animate-pulse">_</span>
</div> </div>
</div> </div>
@@ -201,13 +202,13 @@ const pageTitle = t('site.title');
<SkillsMarquee lang={lang} client:only="react" /> <SkillsMarquee lang={lang} client:only="react" />
<!-- Featured Project: Elynd --> <!-- 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> <Container>
<div class="text-center mb-12"> <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'} {lang === 'zh' ? 'featured 项目' : 'Featured Project'}
</span> </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 Elynd
</h2> </h2>
<p class="text-lg text-muted-foreground max-w-2xl mx-auto"> <p class="text-lg text-muted-foreground max-w-2xl mx-auto">
@@ -218,12 +219,12 @@ const pageTitle = t('site.title');
</div> </div>
<div class="max-w-4xl mx-auto"> <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="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-purple-600/20 via-blue-600/20 to-purple-600/20 flex items-center justify-center relative 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-purple-500/10 [mask-image:linear-gradient(0deg,white,rgba(255,255,255,0.3))]"></div> <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-center z-10">
<div class="text-6xl md:text-8xl mb-4">⚡</div> <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'} {lang === 'zh' ? '让 AI 成为你的共同构建者' : 'Make AI Your Co-Builder'}
</div> </div>
</div> </div>
@@ -231,7 +232,7 @@ const pageTitle = t('site.title');
<div class="p-8"> <div class="p-8">
<div class="grid md:grid-cols-3 gap-6 mb-8"> <div class="grid md:grid-cols-3 gap-6 mb-8">
<div class="text-center"> <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"> <div class="text-sm text-muted-foreground">
{lang === 'zh' ? '从第一天就融入 AI 思维' : 'Built with AI from day one'} {lang === 'zh' ? '从第一天就融入 AI 思维' : 'Built with AI from day one'}
</div> </div>
@@ -252,14 +253,14 @@ const pageTitle = t('site.title');
<div class="flex flex-col sm:flex-row gap-4 justify-center"> <div class="flex flex-col sm:flex-row gap-4 justify-center">
<a <a
href={`/${lang === 'zh' ? 'zh/' : ''}projects`} 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> <span>🚀</span>
{t('hero.ctaSecondary')} {t('hero.ctaSecondary')}
</a> </a>
<a <a
href={`/${lang === 'zh' ? 'zh/' : ''}now`} 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> <span>📡</span>
{lang === 'zh' ? '了解更多' : 'Learn More'} {lang === 'zh' ? '了解更多' : 'Learn More'}
@@ -274,7 +275,7 @@ const pageTitle = t('site.title');
<!-- Services Section - Inlined Content --> <!-- 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"> <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> <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')} {t('services.title')}
</h2> </h2>
@@ -302,7 +303,7 @@ const pageTitle = t('site.title');
</div> </div>
<div class="mt-12 text-center"> <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"> <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> <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> </svg>
@@ -315,13 +316,13 @@ const pageTitle = t('site.title');
<!-- About Section - Inlined Content --> <!-- About Section - Inlined Content -->
<section id="about" class="py-24 relative overflow-hidden"> <section id="about" class="py-24 relative overflow-hidden">
<!-- Background gradient --> <!-- 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"> <Container className="relative z-10">
<div class="text-center mb-16"> <div class="text-center mb-16">
<!-- Section Title --> <!-- Section Title -->
<div class="flex items-center justify-center mb-6"> <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')} {t('about.title')}
</h2> </h2>
</div> </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> <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>
<div class="w-full bg-gray-200 dark:bg-gray-700 rounded-full h-2"> <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>
<div class="flex justify-between items-center"> <div class="flex justify-between items-center">
@@ -421,10 +422,10 @@ const pageTitle = t('site.title');
<div class="flex justify-between items-center"> <div class="flex justify-between items-center">
<span class="text-sm text-gray-700 dark:text-gray-300">DevOps</span> <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>
<div class="w-full bg-gray-200 dark:bg-gray-700 rounded-full h-2"> <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>
<div class="flex justify-between items-center"> <div class="flex justify-between items-center">
@@ -457,11 +458,11 @@ const pageTitle = t('site.title');
<!-- Projects Section - Inlined Content --> <!-- Projects Section - Inlined Content -->
<!-- <section id="projects" class="py-20 relative"> <!-- <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"> <Container className="relative z-10">
<div class="text-center mb-16"> <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 Latest Projects
</h2> </h2>
<p class="text-lg text-muted-foreground max-w-2xl mx-auto"> <p class="text-lg text-muted-foreground max-w-2xl mx-auto">
@@ -470,24 +471,24 @@ const pageTitle = t('site.title');
</div> </div>
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8 items-stretch"> <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"> <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> <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>
<div class="h-48 bg-gradient-to-br from-purple-500/20 to-purple-600/20 relative overflow-hidden"> <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-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="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="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 Taskify App
</div> </div>
</div> </div>
</div> </div>
<div class="p-6 pb-4"> <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"> <h3 class="text-xl group-hover:text-primary transition-colors duration-300 flex items-center gap-2 font-bold mb-4">
<span class="text-purple-500">📱</span> <span class="text-primary">📱</span>
Taskify App Taskify App
</h3> </h3>
</div> </div>
@@ -495,19 +496,19 @@ const pageTitle = t('site.title');
<div class="px-6 flex-grow"> <div class="px-6 flex-grow">
<div class="space-y-3"> <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"> <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> <span>A comprehensive task management application with drag-and-drop functionality.</span>
</div> </div>
<div class="flex items-start gap-2 text-sm text-muted-foreground group-hover:text-foreground transition-colors duration-300"> <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> <span>Built with React, TypeScript, and Tailwind CSS for modern development.</span>
</div> </div>
<div class="flex items-start gap-2 text-sm text-muted-foreground group-hover:text-foreground transition-colors duration-300"> <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> <span>Real-time collaboration features with WebSocket integration for instant updates.</span>
</div> </div>
<div class="flex items-start gap-2 text-sm text-muted-foreground group-hover:text-foreground transition-colors duration-300"> <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> <span>Advanced task filtering, sorting, and project management capabilities.</span>
</div> </div>
</div> </div>
@@ -525,7 +526,7 @@ const pageTitle = t('site.title');
href="https://github.com/zhaoguiyang/taskify-app" href="https://github.com/zhaoguiyang/taskify-app"
target="_blank" target="_blank"
rel="noopener noreferrer" 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> <span>🔗</span>
{t('project.visit')} {t('project.visit')}
@@ -533,23 +534,23 @@ const pageTitle = t('site.title');
</div> </div>
</div> </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"> <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> <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>
<div class="h-48 bg-gradient-to-br from-purple-500/20 to-purple-600/20 relative overflow-hidden"> <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-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="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="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 E-Shop Platform
</div> </div>
</div> </div>
</div> </div>
<div class="p-6 pb-4"> <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"> <h3 class="text-xl group-hover:text-primary transition-colors duration-300 flex items-center gap-2 font-bold mb-4">
<span class="text-purple-500">🛒</span> <span class="text-primary">🛒</span>
E-Shop Platform E-Shop Platform
</h3> </h3>
</div> </div>
@@ -557,19 +558,19 @@ const pageTitle = t('site.title');
<div class="px-6 flex-grow"> <div class="px-6 flex-grow">
<div class="space-y-3"> <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"> <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> <span>Modern e-commerce solution with comprehensive features for online retail.</span>
</div> </div>
<div class="flex items-start gap-2 text-sm text-muted-foreground group-hover:text-foreground transition-colors duration-300"> <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> <span>Built with Next.js, Prisma, and Stripe for seamless payment processing.</span>
</div> </div>
<div class="flex items-start gap-2 text-sm text-muted-foreground group-hover:text-foreground transition-colors duration-300"> <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> <span>Features shopping cart, payment integration, and admin dashboard.</span>
</div> </div>
<div class="flex items-start gap-2 text-sm text-muted-foreground group-hover:text-foreground transition-colors duration-300"> <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> <span>Responsive design with optimized performance and SEO capabilities.</span>
</div> </div>
</div> </div>
@@ -596,23 +597,23 @@ const pageTitle = t('site.title');
</div> </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"> <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> <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>
<div class="h-48 bg-gradient-to-br from-purple-500/20 to-purple-600/20 relative overflow-hidden"> <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-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="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="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 Portfolio Site
</div> </div>
</div> </div>
</div> </div>
<div class="p-6 pb-4"> <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"> <h3 class="text-xl group-hover:text-primary transition-colors duration-300 flex items-center gap-2 font-bold mb-4">
<span class="text-purple-500">🎨</span> <span class="text-primary">🎨</span>
Portfolio Site Portfolio Site
</h3> </h3>
</div> </div>
@@ -620,15 +621,15 @@ const pageTitle = t('site.title');
<div class="px-6 flex-grow"> <div class="px-6 flex-grow">
<div class="space-y-3"> <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"> <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> <span>Responsive personal portfolio website showcasing creative work and projects.</span>
</div> </div>
<div class="flex items-start gap-2 text-sm text-muted-foreground group-hover:text-foreground transition-colors duration-300"> <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> <span>Built with Astro, React, and Tailwind CSS for optimal performance.</span>
</div> </div>
<div class="flex items-start gap-2 text-sm text-muted-foreground group-hover:text-foreground transition-colors duration-300"> <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> <span>Features dark mode support and smooth animations for enhanced UX.</span>
</div> </div>
</div> </div>

View File

@@ -17,14 +17,14 @@ const pageTitle = lang === 'zh' ? '现在' : 'Now';
<main class="min-h-screen"> <main class="min-h-screen">
<!-- Now Page Hero --> <!-- Now Page Hero -->
<section class="py-24 relative overflow-hidden"> <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"> <Container className="relative z-10">
<div class="text-center mb-16"> <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"} {lang === 'zh' ? '关于我现在正在做什么' : "What's happening now"}
</span> </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'} {lang === 'zh' ? '现在' : 'Now'}
</h1> </h1>
<p class="text-lg text-muted-foreground max-w-2xl mx-auto"> <p class="text-lg text-muted-foreground max-w-2xl mx-auto">
@@ -41,7 +41,7 @@ const pageTitle = lang === 'zh' ? '现在' : 'Now';
<Container> <Container>
<div class="max-w-4xl mx-auto"> <div class="max-w-4xl mx-auto">
<div class="flex items-center gap-4 mb-8"> <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> <span class="text-2xl">🔨</span>
</div> </div>
<h2 class="text-3xl font-bold"> <h2 class="text-3xl font-bold">
@@ -49,9 +49,9 @@ const pageTitle = lang === 'zh' ? '现在' : 'Now';
</h2> </h2>
</div> </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="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> <span class="text-3xl">⚡</span>
</div> </div>
<div class="flex-1"> <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.'} : 'An open AI workspace for builders to work smarter. Built from first principles of AI, creating fully open, self-hostable collaboration tools.'}
</p> </p>
<div class="flex flex-wrap gap-2"> <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-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> <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> </div>
@@ -148,7 +148,7 @@ const pageTitle = lang === 'zh' ? '现在' : 'Now';
</section> </section>
<!-- Open to Collaborate 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> <Container>
<div class="max-w-4xl mx-auto text-center"> <div class="max-w-4xl mx-auto text-center">
<div class="flex items-center justify-center gap-4 mb-8"> <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"> <div class="flex flex-col sm:flex-row gap-4 justify-center">
<a <a
href={lang === 'zh' ? '/zh/hire' : '/hire'} 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> <span>💼</span>
{lang === 'zh' ? '查看合作方式' : 'View Collaboration Options'} {lang === 'zh' ? '查看合作方式' : 'View Collaboration Options'}
</a> </a>
<a <a
href="mailto:zhaoguiyang18@gmail.com" 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> <span>📧</span>
{lang === 'zh' ? '发送邮件' : 'Send Email'} {lang === 'zh' ? '发送邮件' : 'Send Email'}

View File

@@ -32,12 +32,12 @@ const experimentProjects = otherProjects.filter(p => p.type === 'experiment');
<!-- Projects Hero Section --> <!-- Projects Hero Section -->
<section class="py-24 relative overflow-hidden"> <section class="py-24 relative overflow-hidden">
<!-- Background gradient --> <!-- 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"> <Container className="relative z-10">
<div class="text-center mb-16"> <div class="text-center mb-16">
<!-- Main title --> <!-- 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')} {t('projects.title')}
</h1> </h1>
@@ -51,23 +51,23 @@ const experimentProjects = otherProjects.filter(p => p.type === 'experiment');
<!-- Featured Project Section --> <!-- Featured Project Section -->
{featuredProject && ( {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> <Container>
<div class="max-w-5xl mx-auto"> <div class="max-w-5xl mx-auto">
<div class="flex items-center gap-4 mb-8"> <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 Featured
</span> </span>
</div> </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="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 class="text-8xl">{featuredProject.icon}</div>
</div> </div>
<div class="p-8"> <div class="p-8">
<div class="flex items-center gap-3 mb-4"> <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}`)} {t(`project.status.${featuredProject.status}`)}
</span> </span>
<span class="px-3 py-1 bg-blue-500/20 text-blue-600 dark:text-blue-400 rounded-full text-sm"> <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>
<div class="flex gap-4"> <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')} {t('project.visit')}
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <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> <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 && ( {productProjects.length > 0 && (
<> <>
<div class="flex items-center gap-4 mb-8"> <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> <span class="text-xl">🛍️</span>
</div> </div>
<h2 class="text-2xl font-bold">{t('project.type.product')}</h2> <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"> <Container className="pt-24 pb-12">
<div class="text-center mb-16"> <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"> <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-purple-500">博客</span> <span class="text-primary">博客</span>
</h1> </h1>
<p class="text-xl text-muted-foreground max-w-3xl mx-auto"> <p class="text-xl text-muted-foreground max-w-3xl mx-auto">
关于 AI 产品、全栈开发和公开构建的思考。探索技术与产品构建的交汇点。 关于 AI 产品、全栈开发和公开构建的思考。探索技术与产品构建的交汇点。

View File

@@ -17,14 +17,14 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
<main class="min-h-screen"> <main class="min-h-screen">
<!-- Hire Page Hero --> <!-- Hire Page Hero -->
<section class="py-24 relative overflow-hidden"> <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"> <Container className="relative z-10">
<div class="text-center mb-16"> <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> </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> </h1>
<p class="text-lg text-muted-foreground max-w-2xl mx-auto"> <p class="text-lg text-muted-foreground max-w-2xl mx-auto">
@@ -39,7 +39,7 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
<Container> <Container>
<div class="max-w-4xl mx-auto"> <div class="max-w-4xl mx-auto">
<div class="flex items-center gap-4 mb-8"> <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> <span class="text-2xl">👥</span>
</div> </div>
<h2 class="text-3xl font-bold"> <h2 class="text-3xl font-bold">
@@ -48,7 +48,7 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
</div> </div>
<div class="grid md:grid-cols-2 gap-6"> <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 class="text-lg font-bold mb-3">
初创公司 初创公司
</h3> </h3>
@@ -57,7 +57,7 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
</p> </p>
</div> </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 class="text-lg font-bold mb-3">
独立创始人 独立创始人
</h3> </h3>
@@ -66,7 +66,7 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
</p> </p>
</div> </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 class="text-lg font-bold mb-3">
传统企业 传统企业
</h3> </h3>
@@ -75,7 +75,7 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
</p> </p>
</div> </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 class="text-lg font-bold mb-3">
技术团队 技术团队
</h3> </h3>
@@ -104,7 +104,7 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
<div class="space-y-6"> <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="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="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> <span class="text-2xl">⚡</span>
</div> </div>
<div> <div>
@@ -187,7 +187,7 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
</div> </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="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> <span class="text-2xl">⏰</span>
</div> </div>
<h3 class="text-lg font-bold mb-2"> <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 class="px-3 py-1 bg-blue-500/20 text-blue-600 dark:text-blue-400 rounded-full text-sm">
远程工作 远程工作
</span> </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> </span>
</div> </div>
@@ -299,7 +299,7 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
</section> </section>
<!-- Contact CTA --> <!-- 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> <Container>
<div class="max-w-4xl mx-auto text-center"> <div class="max-w-4xl mx-auto text-center">
<h2 class="text-3xl font-bold mb-6"> <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"> <div class="flex flex-col sm:flex-row gap-4 justify-center">
<a <a
href="mailto:zhaoguiyang18@gmail.com" 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> <span>📧</span>
发送邮件 发送邮件
</a> </a>
<a <a
href="/zh/now" 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> <span>📡</span>
了解更多关于我 了解更多关于我

View File

@@ -5,6 +5,7 @@ import SkillsMarquee from "@/components/SkillsMarquee";
import TypewriterEffect from "@/components/TypewriterEffect"; import TypewriterEffect from "@/components/TypewriterEffect";
import Footer from "@/components/Footer"; import Footer from "@/components/Footer";
import Container from "@/components/ui/Container.astro"; import Container from "@/components/ui/Container.astro";
import MotionWrapper from "@/components/MotionWrapper";
import { useTranslations } from "@/i18n/utils"; import { useTranslations } from "@/i18n/utils";
import type { Lang } from "@/types/i18n"; import type { Lang } from "@/types/i18n";
import { defaultLang } from "@/i18n/ui"; import { defaultLang } from "@/i18n/ui";
@@ -22,22 +23,22 @@ const pageTitle = t('site.title');
<!-- Hero Section - Inlined Content --> <!-- Hero Section - Inlined Content -->
<section class="py-32 relative overflow-hidden min-h-screen flex flex-col justify-center"> <section class="py-32 relative overflow-hidden min-h-screen flex flex-col justify-center">
<!-- Background gradient --> <!-- 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"> <Container className="relative z-10">
<div class="text-center mb-16"> <div class="text-center mb-16">
<!-- Greeting --> <!-- Greeting -->
<div class="flex items-center justify-center mb-6"> <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> <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> </svg>
<span class="text-purple-500 font-mono text-lg"> <span class="text-primary font-mono text-lg">
{t('hero.greeting')} {personalInfo.name} {t('hero.greeting')} {personalInfo.name}
</span> </span>
</div> </div>
<!-- Main title --> <!-- 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} {personalInfo.name}
</h1> </h1>
@@ -58,7 +59,7 @@ const pageTitle = t('site.title');
delayBeforeDelete={3500} delayBeforeDelete={3500}
delayBeforeTyping={1800} delayBeforeTyping={1800}
loop={true} loop={true}
cursorClassName="text-purple-600 dark:text-purple-400" cursorClassName="text-primary dark:text-primary"
className="mr-2 font-medium text-muted-foreground" className="mr-2 font-medium text-muted-foreground"
/> />
<span>👨‍💻</span> <span>👨‍💻</span>
@@ -72,7 +73,7 @@ const pageTitle = t('site.title');
<!-- Job availability notice --> <!-- Job availability notice -->
<div class="mb-8"> <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> <p class="text-md text-muted-foreground">{t('hero.digitalNomad')}</p>
</div> </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"> <div class="flex flex-col sm:flex-row gap-4 justify-center items-center mb-16">
<a <a
href="/zh/hire" 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"> <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> <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 <a
href="/zh/projects" 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"> <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> <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="p-6 font-mono text-sm">
<div class="space-y-2"> <div class="space-y-2">
<div class="flex items-center"> <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> <span class="text-white">whoami</span>
</div> </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"> <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> <span class="text-white">cat about.txt</span>
</div> </div>
<div class="text-gray-300 ml-4 leading-relaxed"> <div class="text-gray-300 ml-4 leading-relaxed">
@@ -180,15 +181,15 @@ const pageTitle = t('site.title');
</div> </div>
<div class="flex items-center mt-4"> <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> <span class="text-white">ls projects/</span>
</div> </div>
<div class="text-purple-200 ml-4"> <div class="text-primary/70 ml-4">
taskify-app/ e-commerce-platform/ portfolio-site/ taskify-app/ e-commerce-platform/ portfolio-site/
</div> </div>
<div class="flex items-center mt-4"> <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> <span class="text-white animate-pulse">_</span>
</div> </div>
</div> </div>
@@ -201,13 +202,13 @@ const pageTitle = t('site.title');
<SkillsMarquee lang={lang} client:only="react" /> <SkillsMarquee lang={lang} client:only="react" />
<!-- Featured Project: Elynd --> <!-- 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> <Container>
<div class="text-center mb-12"> <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 项目 Featured 项目
</span> </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 Elynd
</h2> </h2>
<p class="text-lg text-muted-foreground max-w-2xl mx-auto"> <p class="text-lg text-muted-foreground max-w-2xl mx-auto">
@@ -216,12 +217,12 @@ const pageTitle = t('site.title');
</div> </div>
<div class="max-w-4xl mx-auto"> <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="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-purple-600/20 via-blue-600/20 to-purple-600/20 flex items-center justify-center relative 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-purple-500/10 [mask-image:linear-gradient(0deg,white,rgba(255,255,255,0.3))]"></div> <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-center z-10">
<div class="text-6xl md:text-8xl mb-4">⚡</div> <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 成为你的共同构建者 让 AI 成为你的共同构建者
</div> </div>
</div> </div>
@@ -229,7 +230,7 @@ const pageTitle = t('site.title');
<div class="p-8"> <div class="p-8">
<div class="grid md:grid-cols-3 gap-6 mb-8"> <div class="grid md:grid-cols-3 gap-6 mb-8">
<div class="text-center"> <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"> <div class="text-sm text-muted-foreground">
从第一天就融入 AI 思维 从第一天就融入 AI 思维
</div> </div>
@@ -250,14 +251,14 @@ const pageTitle = t('site.title');
<div class="flex flex-col sm:flex-row gap-4 justify-center"> <div class="flex flex-col sm:flex-row gap-4 justify-center">
<a <a
href="/zh/projects" 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> <span>🚀</span>
{t('hero.ctaSecondary')} {t('hero.ctaSecondary')}
</a> </a>
<a <a
href="/zh/now" 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> <span>📡</span>
了解更多 了解更多
@@ -272,7 +273,7 @@ const pageTitle = t('site.title');
<!-- Services Section - Inlined Content --> <!-- 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"> <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> <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')} {t('services.title')}
</h2> </h2>
@@ -300,7 +301,7 @@ const pageTitle = t('site.title');
</div> </div>
<div class="mt-12 text-center"> <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"> <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> <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> </svg>
@@ -313,13 +314,13 @@ const pageTitle = t('site.title');
<!-- About Section - Inlined Content --> <!-- About Section - Inlined Content -->
<section id="about" class="py-24 relative overflow-hidden"> <section id="about" class="py-24 relative overflow-hidden">
<!-- Background gradient --> <!-- 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"> <Container className="relative z-10">
<div class="text-center mb-16"> <div class="text-center mb-16">
<!-- Section Title --> <!-- Section Title -->
<div class="flex items-center justify-center mb-6"> <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')} {t('about.title')}
</h2> </h2>
</div> </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> <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>
<div class="w-full bg-gray-200 dark:bg-gray-700 rounded-full h-2"> <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>
<div class="flex justify-between items-center"> <div class="flex justify-between items-center">
@@ -420,10 +421,10 @@ const pageTitle = t('site.title');
<div class="flex justify-between items-center"> <div class="flex justify-between items-center">
<span class="text-sm text-gray-700 dark:text-gray-300">DevOps</span> <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>
<div class="w-full bg-gray-200 dark:bg-gray-700 rounded-full h-2"> <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>
<div class="flex justify-between items-center"> <div class="flex justify-between items-center">
@@ -456,11 +457,11 @@ const pageTitle = t('site.title');
<!-- Projects Section - Inlined Content --> <!-- Projects Section - Inlined Content -->
<!-- <section id="projects" class="py-20 relative"> <!-- <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"> <Container className="relative z-10">
<div class="text-center mb-16"> <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> </h2>
<p class="text-lg text-muted-foreground max-w-2xl mx-auto"> <p class="text-lg text-muted-foreground max-w-2xl mx-auto">
@@ -469,23 +470,23 @@ const pageTitle = t('site.title');
</div> </div>
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8 items-stretch"> <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"> <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> <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>
<div class="h-48 bg-gradient-to-br from-purple-500/20 to-purple-600/20 relative overflow-hidden"> <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-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="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="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 Taskify App
</div> </div>
</div> </div>
</div> </div>
<div class="p-6 pb-4"> <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"> <h3 class="text-xl group-hover:text-primary transition-colors duration-300 flex items-center gap-2 font-bold mb-4">
<span class="text-purple-500">📱</span> <span class="text-primary">📱</span>
Taskify 应用 Taskify 应用
</h3> </h3>
</div> </div>
@@ -493,15 +494,15 @@ const pageTitle = t('site.title');
<div class="px-6 flex-grow"> <div class="px-6 flex-grow">
<div class="space-y-3"> <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"> <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> <span>一个功能完整的任务管理应用程序</span>
</div> </div>
<div class="flex items-start gap-2 text-sm text-muted-foreground group-hover:text-foreground transition-colors duration-300"> <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> <span>使用 React、TypeScript 和 Tailwind CSS 构建</span>
</div> </div>
<div class="flex items-start gap-2 text-sm text-muted-foreground group-hover:text-foreground transition-colors duration-300"> <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> <span>具有拖放功能和实时更新</span>
</div> </div>
</div> </div>
@@ -519,7 +520,7 @@ const pageTitle = t('site.title');
href="https://github.com/zhaoguiyang/taskify-app" href="https://github.com/zhaoguiyang/taskify-app"
target="_blank" target="_blank"
rel="noopener noreferrer" 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> <span>🔗</span>
{t('project.visit')} {t('project.visit')}
@@ -528,23 +529,23 @@ const pageTitle = t('site.title');
</div> </div>
</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"> <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> <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>
<div class="h-48 bg-gradient-to-br from-purple-500/20 to-purple-600/20 relative overflow-hidden"> <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-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="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="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 E-Shop Platform
</div> </div>
</div> </div>
</div> </div>
<div class="p-6 pb-4"> <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"> <h3 class="text-xl group-hover:text-primary transition-colors duration-300 flex items-center gap-2 font-bold mb-4">
<span class="text-purple-500">📱</span> <span class="text-primary">📱</span>
电商平台 电商平台
</h3> </h3>
</div> </div>
@@ -552,15 +553,15 @@ const pageTitle = t('site.title');
<div class="px-6 flex-grow"> <div class="px-6 flex-grow">
<div class="space-y-3"> <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"> <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> <span>现代化的电子商务解决方案</span>
</div> </div>
<div class="flex items-start gap-2 text-sm text-muted-foreground group-hover:text-foreground transition-colors duration-300"> <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> <span>使用 Next.js、Prisma 和 Stripe 构建</span>
</div> </div>
<div class="flex items-start gap-2 text-sm text-muted-foreground group-hover:text-foreground transition-colors duration-300"> <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> <span>具有购物车、支付和管理面板功能</span>
</div> </div>
</div> </div>
@@ -587,23 +588,23 @@ const pageTitle = t('site.title');
</div> </div>
</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"> <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> <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>
<div class="h-48 bg-gradient-to-br from-purple-500/20 to-purple-600/20 relative overflow-hidden"> <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-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="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="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 Portfolio Site
</div> </div>
</div> </div>
</div> </div>
<div class="p-6 pb-4"> <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"> <h3 class="text-xl group-hover:text-primary transition-colors duration-300 flex items-center gap-2 font-bold mb-4">
<span class="text-purple-500">📱</span> <span class="text-primary">📱</span>
个人作品集 个人作品集
</h3> </h3>
</div> </div>
@@ -611,15 +612,15 @@ const pageTitle = t('site.title');
<div class="px-6 flex-grow"> <div class="px-6 flex-grow">
<div class="space-y-3"> <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"> <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> <span>响应式个人作品集网站</span>
</div> </div>
<div class="flex items-start gap-2 text-sm text-muted-foreground group-hover:text-foreground transition-colors duration-300"> <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> <span>使用 Astro、React 和 Tailwind CSS 构建</span>
</div> </div>
<div class="flex items-start gap-2 text-sm text-muted-foreground group-hover:text-foreground transition-colors duration-300"> <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> <span>具有深色模式和平滑动画效果</span>
</div> </div>
</div> </div>

View File

@@ -17,14 +17,14 @@ const pageTitle = lang === 'zh' ? '现在' : 'Now';
<main class="min-h-screen"> <main class="min-h-screen">
<!-- Now Page Hero --> <!-- Now Page Hero -->
<section class="py-24 relative overflow-hidden"> <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"> <Container className="relative z-10">
<div class="text-center mb-16"> <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> </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> </h1>
<p class="text-lg text-muted-foreground max-w-2xl mx-auto"> <p class="text-lg text-muted-foreground max-w-2xl mx-auto">
@@ -39,7 +39,7 @@ const pageTitle = lang === 'zh' ? '现在' : 'Now';
<Container> <Container>
<div class="max-w-4xl mx-auto"> <div class="max-w-4xl mx-auto">
<div class="flex items-center gap-4 mb-8"> <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> <span class="text-2xl">🔨</span>
</div> </div>
<h2 class="text-3xl font-bold"> <h2 class="text-3xl font-bold">
@@ -47,9 +47,9 @@ const pageTitle = lang === 'zh' ? '现在' : 'Now';
</h2> </h2>
</div> </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="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> <span class="text-3xl">⚡</span>
</div> </div>
<div class="flex-1"> <div class="flex-1">
@@ -58,7 +58,7 @@ const pageTitle = lang === 'zh' ? '现在' : 'Now';
一个开放的 AI 工作空间,让构建者能够更智能地工作。从 AI 第一性原理出发,打造完全开放、可自托管的协作工具。 一个开放的 AI 工作空间,让构建者能够更智能地工作。从 AI 第一性原理出发,打造完全开放、可自托管的协作工具。
</p> </p>
<div class="flex flex-wrap gap-2"> <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-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> <span class="px-3 py-1 bg-green-500/20 text-green-600 dark:text-green-400 rounded-full text-sm">开源</span>
</div> </div>
@@ -138,7 +138,7 @@ const pageTitle = lang === 'zh' ? '现在' : 'Now';
</section> </section>
<!-- Open to Collaborate 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> <Container>
<div class="max-w-4xl mx-auto text-center"> <div class="max-w-4xl mx-auto text-center">
<div class="flex items-center justify-center gap-4 mb-8"> <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"> <div class="flex flex-col sm:flex-row gap-4 justify-center">
<a <a
href="/zh/hire" 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> <span>💼</span>
查看合作方式 查看合作方式
</a> </a>
<a <a
href="mailto:zhaoguiyang18@gmail.com" 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> <span>📧</span>
发送邮件 发送邮件

View File

@@ -32,12 +32,12 @@ const experimentProjects = otherProjects.filter(p => p.type === 'experiment');
<!-- Projects Hero Section --> <!-- Projects Hero Section -->
<section class="py-24 relative overflow-hidden"> <section class="py-24 relative overflow-hidden">
<!-- Background gradient --> <!-- 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"> <Container className="relative z-10">
<div class="text-center mb-16"> <div class="text-center mb-16">
<!-- Main title --> <!-- 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')} {t('projects.title')}
</h1> </h1>
@@ -51,23 +51,23 @@ const experimentProjects = otherProjects.filter(p => p.type === 'experiment');
<!-- Featured Project Section --> <!-- Featured Project Section -->
{featuredProject && ( {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> <Container>
<div class="max-w-5xl mx-auto"> <div class="max-w-5xl mx-auto">
<div class="flex items-center gap-4 mb-8"> <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 项目 Featured 项目
</span> </span>
</div> </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="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 class="text-8xl">{featuredProject.icon}</div>
</div> </div>
<div class="p-8"> <div class="p-8">
<div class="flex items-center gap-3 mb-4"> <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}`)} {t(`project.status.${featuredProject.status}`)}
</span> </span>
<span class="px-3 py-1 bg-blue-500/20 text-blue-600 dark:text-blue-400 rounded-full text-sm"> <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>
<div class="flex gap-4"> <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')} {t('project.visit')}
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <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> <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 && ( {productProjects.length > 0 && (
<> <>
<div class="flex items-center gap-4 mb-8"> <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> <span class="text-xl">🛍️</span>
</div> </div>
<h2 class="text-2xl font-bold">{t('project.type.product')}</h2> <h2 class="text-2xl font-bold">{t('project.type.product')}</h2>

View File

@@ -1,5 +1,6 @@
@import "tailwindcss"; @import "tailwindcss";
@import "tw-animate-css"; @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"; @plugin "@tailwindcss/typography";
/* Blog List Component Styles */ /* Blog List Component Styles */
@@ -43,24 +44,24 @@
:root { :root {
--radius: 0.75rem; --radius: 0.75rem;
--background: oklch(1 0 0); --background: #F8FAFC;
--foreground: oklch(0.145 0 0); --foreground: #1E293B;
--card: oklch(1 0 0); --card: #FFFFFF;
--card-foreground: oklch(0.145 0 0); --card-foreground: #1E293B;
--popover: oklch(1 0 0); --popover: #FFFFFF;
--popover-foreground: oklch(0.145 0 0); --popover-foreground: #1E293B;
--primary: oklch(0.205 0 0); --primary: #2563EB;
--primary-foreground: oklch(0.985 0 0); --primary-foreground: #FFFFFF;
--secondary: oklch(0.97 0 0); --secondary: #E4E4E7;
--secondary-foreground: oklch(0.205 0 0); --secondary-foreground: #1E293B;
--muted: oklch(0.97 0 0); --muted: #F4F4F5;
--muted-foreground: oklch(0.556 0 0); --muted-foreground: #71717A;
--accent: oklch(0.97 0 0); --accent: #F97316;
--accent-foreground: oklch(0.205 0 0); --accent-foreground: #FFFFFF;
--destructive: oklch(0.577 0.245 27.325); --destructive: #EF4444;
--border: oklch(0.922 0 0); --border: #E4E4E7;
--input: oklch(0.922 0 0); --input: #E4E4E7;
--ring: oklch(0.708 0 0); --ring: #2563EB;
--chart-1: oklch(0.646 0.222 41.116); --chart-1: oklch(0.646 0.222 41.116);
--chart-2: oklch(0.6 0.118 184.704); --chart-2: oklch(0.6 0.118 184.704);
--chart-3: oklch(0.398 0.07 227.392); --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%); --svg-filter-color: invert(0%) sepia(0%) saturate(0%) hue-rotate(324deg) brightness(96%) contrast(104%);
/* Modern Design Variables */ /* 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-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-sm: 0 2px 8px rgba(0, 0, 0, 0.05);
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.08); --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.08);
--shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.12); --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-bounce: cubic-bezier(0.34, 1.56, 0.64, 1);
--animation-smooth: cubic-bezier(0.65, 0, 0.35, 1); --animation-smooth: cubic-bezier(0.65, 0, 0.35, 1);
--animation-spring: cubic-bezier(0.22, 1, 0.36, 1);
} }
.dark { .dark {
--background: oklch(0.145 0 0); --background: #09090B;
--foreground: oklch(0.985 0 0); --foreground: #F8FAFC;
--card: oklch(0.205 0 0); --card: #18181B;
--card-foreground: oklch(0.985 0 0); --card-foreground: #F8FAFC;
--popover: oklch(0.205 0 0); --popover: #18181B;
--popover-foreground: oklch(0.985 0 0); --popover-foreground: #F8FAFC;
--primary: oklch(0.922 0 0); --primary: #3B82F6;
--primary-foreground: oklch(0.205 0 0); --primary-foreground: #FFFFFF;
--secondary: oklch(0.269 0 0); --secondary: #27272A;
--secondary-foreground: oklch(0.985 0 0); --secondary-foreground: #F8FAFC;
--muted: oklch(0.269 0 0); --muted: #27272A;
--muted-foreground: oklch(0.708 0 0); --muted-foreground: #A1A1AA;
--accent: oklch(0.269 0 0); --accent: #FB923C;
--accent-foreground: oklch(0.985 0 0); --accent-foreground: #09090B;
--destructive: oklch(0.704 0.191 22.216); --destructive: #EF4444;
--border: oklch(1 0 0 / 10%); --border: #27272A;
--input: oklch(1 0 0 / 15%); --input: #27272A;
--ring: oklch(0.556 0 0); --ring: #3B82F6;
--chart-1: oklch(0.488 0.243 264.376); --chart-1: oklch(0.488 0.243 264.376);
--chart-2: oklch(0.696 0.17 162.48); --chart-2: oklch(0.696 0.17 162.48);
--chart-3: oklch(0.769 0.188 70.08); --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%); --svg-filter-color: invert(100%) sepia(0%) saturate(0%) hue-rotate(324deg) brightness(102%) contrast(101%);
/* Dark Mode Modern Design Variables */ /* Dark Mode Modern Design Variables */
--shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.2); --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.3);
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.25); --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.4);
--shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.3); --shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.5);
--shadow-xl: 0 12px 40px rgba(59, 130, 246, 0.2);
} }
@theme inline { @theme inline {
@@ -172,11 +177,12 @@
} }
body { body {
@apply bg-background text-foreground; @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"; font-feature-settings: "ss01", "ss02", "cv01", "cv02";
} }
h1, h2, h3, h4, h5, h6 { h1, h2, h3, h4, h5, h6 {
@apply font-bold tracking-tight; @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; line-height: 1.2;
} }
a { a {
@@ -186,3 +192,148 @@
@apply rounded-md; @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);
}
}