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:
@@ -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">
|
||||||
|
|||||||
@@ -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) {
|
|||||||
© {new Date().getFullYear()} { personalInfo.name }. {t('footer.rights')} ✨
|
© {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!'}
|
||||||
|
|||||||
@@ -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={{
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
@@ -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,
|
||||||
}) => {
|
}) => {
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -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>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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}`}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -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"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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: {
|
||||||
|
|||||||
@@ -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"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 -->
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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'}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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'}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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 产品、全栈开发和公开构建的思考。探索技术与产品构建的交汇点。
|
||||||
|
|||||||
@@ -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>
|
||||||
了解更多关于我
|
了解更多关于我
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
发送邮件
|
发送邮件
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user