refactor(styles): enhance glass effects, card designs, and transitions across components
- Replaced `client:only="react"` with `client:load transition:persist="header"` for `GlassHeader` to improve page transitions and header consistency. - Updated card and surface designs with refined colors, borders, and shadows for a cleaner, modern look. - Adjusted CSS variables for better contrast and distinct layers. - Applied consistent blur and backdrop styles across components for visual cohesion.
This commit is contained in:
@@ -126,10 +126,10 @@ export default function GlassHeader({ lang: propLang }: GlassHeaderProps) {
|
||||
<div className={`md:hidden overflow-hidden transition-all duration-300 ease-out ${
|
||||
isMenuOpen ? 'max-h-80 opacity-100' : 'max-h-0 opacity-0'
|
||||
}`}>
|
||||
<div className={`py-4 px-4 border-t border-border/10 glass-effect ${
|
||||
<div className={`py-4 px-4 border-t border-border/10 glass-effect shadow-xl ${
|
||||
isScrolled
|
||||
? 'bg-white/80 dark:bg-black/80 shadow-sm'
|
||||
: 'bg-white/85 dark:bg-black/85'
|
||||
? 'bg-white/90 dark:bg-black/80'
|
||||
: 'bg-white/95 dark:bg-black/85'
|
||||
}`}>
|
||||
<nav className="flex flex-col space-y-3 text-sm font-medium">
|
||||
{navItems.map((item) => {
|
||||
|
||||
@@ -47,7 +47,7 @@ const statusColor = statusClassMap[project.status as keyof typeof statusClassMap
|
||||
<article
|
||||
data-project-card
|
||||
data-type={project.type}
|
||||
class="group flex flex-col overflow-hidden rounded-3xl border border-border/50 bg-card/50 backdrop-blur-sm transition-all duration-500 hover:-translate-y-2 hover:shadow-2xl hover:shadow-primary/5"
|
||||
class="group flex flex-col overflow-hidden rounded-3xl border border-border/40 bg-card/60 backdrop-blur-md transition-all duration-500 hover:-translate-y-2 hover:shadow-2xl hover:shadow-primary/5"
|
||||
>
|
||||
{/* 顶部封面图区域 */}
|
||||
<div class="relative aspect-[16/10] overflow-hidden">
|
||||
|
||||
@@ -76,7 +76,7 @@ const readMoreText = lang === 'zh' ? '阅读更多' : 'Read More';
|
||||
{posts.length > 0 ? (
|
||||
posts.map((post, index) => (
|
||||
<article class="group">
|
||||
<div class="bg-card/50 backdrop-blur-sm rounded-2xl overflow-hidden border border-border hover:border-primary/50 transition-all duration-300 hover:transform hover:scale-[1.02]">
|
||||
<div class="bg-card/60 backdrop-blur-md rounded-2xl overflow-hidden border border-border/40 hover:border-primary/50 transition-all duration-300 hover:transform hover:scale-[1.02] hover:shadow-xl hover:shadow-primary/5">
|
||||
<div class="flex flex-col md:flex-row">
|
||||
{/* Featured Image */}
|
||||
<div class="relative overflow-hidden md:w-80 md:flex-shrink-0">
|
||||
|
||||
@@ -41,7 +41,7 @@ const titles = {
|
||||
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/60 backdrop-blur-md rounded-2xl p-6 border border-border/40">
|
||||
<h3 class="text-xl font-semibold text-card-foreground mb-4 flex items-center">
|
||||
<Tag className="w-5 h-5 mr-2 text-primary" />
|
||||
{title}
|
||||
@@ -61,6 +61,6 @@ const title = titles[lang] || titles[defaultLang];
|
||||
<div class="flex flex-col items-center justify-center py-6">
|
||||
<p class="text-muted-foreground text-center">{lang === 'zh' ? '暂无分类' : 'No categories yet'}</p>
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
@@ -127,7 +127,7 @@ const getReadingTimeText = (minutes: number) => {
|
||||
: tag.toLowerCase();
|
||||
|
||||
return (
|
||||
<a href={`/${lang === 'en' ? '' : 'zh/'}blog/tags/${encodeURIComponent(tagRoute)}`} class="inline-flex items-center px-2.5 py-1 rounded-md text-xs font-medium bg-gray-100 text-gray-700 hover:bg-gray-200 dark:bg-gray-800 dark:text-gray-300 dark:hover:bg-gray-700 transition-colors border border-gray-200 dark:border-gray-600">
|
||||
<a href={`/${lang === 'en' ? '' : 'zh/'}blog/tags/${encodeURIComponent(tagRoute)}`} class="inline-flex items-center px-2.5 py-1 rounded-md text-xs font-medium bg-muted text-muted-foreground hover:bg-accent hover:text-accent-foreground transition-colors border border-border">
|
||||
# {tag}
|
||||
</a>
|
||||
);
|
||||
|
||||
@@ -41,7 +41,7 @@ const titles = {
|
||||
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/60 backdrop-blur-md rounded-2xl p-6 border border-border/40">
|
||||
<h3 class="text-xl font-semibold text-card-foreground mb-4 flex items-center">
|
||||
<Hash className='w-5 h-5 mr-2 text-primary' />
|
||||
{title}
|
||||
|
||||
@@ -22,7 +22,7 @@ const lang = Astro.currentLocale as Lang || defaultLang;
|
||||
</div>
|
||||
|
||||
<!-- Glass Header with navigation -->
|
||||
<GlassHeader lang={lang} client:load />
|
||||
<GlassHeader lang={lang} client:load transition:persist="header" />
|
||||
|
||||
<!-- Main content with proper spacing for fixed header -->
|
||||
<div class="pt-16">
|
||||
|
||||
@@ -43,7 +43,7 @@ const finalReadingTime = readTime ? parseInt(readTime.replace(/\D/g, '')) : unde
|
||||
|
||||
<Layout title={title} description={description}>
|
||||
<!-- Glass Header with navigation -->
|
||||
<GlassHeader lang={lang} client:load />
|
||||
<GlassHeader lang={lang} client:load transition:persist="header" />
|
||||
|
||||
<!-- Main content with proper spacing for fixed header -->
|
||||
<div class="pt-16 sm:pt-20">
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
---
|
||||
import { ClientRouter } from "astro:transitions";
|
||||
import BackToTop from "@/components/ui/back-to-top";
|
||||
import { useTranslations } from "@/i18n/utils";
|
||||
import type { Lang } from "@/types/i18n";
|
||||
@@ -26,6 +27,7 @@ const t = useTranslations(lang);
|
||||
<meta name="description" content={description} />
|
||||
<title>{title} | {t("site.title")}</title>
|
||||
<!-- View Transitions for smooth page transitions -->
|
||||
<ClientRouter />
|
||||
<meta name="view-transition" content="same-origin" />
|
||||
{
|
||||
import.meta.env.MODE === 'production' && (
|
||||
|
||||
@@ -37,7 +37,7 @@ const pageTitle = t("about.title");
|
||||
---
|
||||
|
||||
<Layout title={pageTitle}>
|
||||
<GlassHeader client:only="react" lang={lang} />
|
||||
<GlassHeader client:load transition:persist="header" lang={lang} />
|
||||
|
||||
<main class="min-h-screen relative overflow-hidden pt-16 sm:pt-20">
|
||||
<!-- Background Decor -->
|
||||
|
||||
@@ -14,7 +14,7 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
|
||||
---
|
||||
|
||||
<Layout title={pageTitle}>
|
||||
<GlassHeader lang={lang} client:only="react" />
|
||||
<GlassHeader lang={lang} client:load transition:persist="header" />
|
||||
<main class="min-h-screen">
|
||||
<!-- Hire Page Hero -->
|
||||
<section class="py-24 relative overflow-hidden">
|
||||
|
||||
@@ -43,7 +43,7 @@ const keyFacts = [
|
||||
---
|
||||
|
||||
<Layout title={pageTitle}>
|
||||
<GlassHeader client:only="react" lang={lang} />
|
||||
<GlassHeader client:load transition:persist="header" lang={lang} />
|
||||
|
||||
<main class="min-h-screen">
|
||||
<div class="relative overflow-hidden">
|
||||
|
||||
@@ -14,7 +14,7 @@ const pageTitle = lang === 'zh' ? '现在' : 'Now';
|
||||
---
|
||||
|
||||
<Layout title={pageTitle}>
|
||||
<GlassHeader lang={lang} client:only="react" />
|
||||
<GlassHeader lang={lang} client:load transition:persist="header" />
|
||||
<main class="min-h-screen relative overflow-hidden">
|
||||
<!-- 背景装饰 -->
|
||||
<div class="absolute inset-0 -z-10">
|
||||
|
||||
@@ -26,7 +26,7 @@ const filterOptions = [
|
||||
---
|
||||
|
||||
<Layout title={pageTitle}>
|
||||
<GlassHeader lang={lang} client:only="react" />
|
||||
<GlassHeader lang={lang} client:load transition:persist="header" />
|
||||
<main class="min-h-screen relative overflow-hidden">
|
||||
<div
|
||||
aria-hidden="true"
|
||||
|
||||
@@ -37,7 +37,7 @@ const pageTitle = t("about.title");
|
||||
---
|
||||
|
||||
<Layout title={pageTitle}>
|
||||
<GlassHeader client:only="react" lang={lang} />
|
||||
<GlassHeader client:load transition:persist="header" lang={lang} />
|
||||
|
||||
<main class="min-h-screen relative overflow-hidden pt-16 sm:pt-20">
|
||||
<!-- Background Decor -->
|
||||
|
||||
@@ -14,7 +14,7 @@ const pageTitle = lang === 'zh' ? '合作' : 'Hire Me';
|
||||
---
|
||||
|
||||
<Layout title={pageTitle}>
|
||||
<GlassHeader lang={lang} client:only="react" />
|
||||
<GlassHeader lang={lang} client:load transition:persist="header" />
|
||||
<main class="min-h-screen">
|
||||
<!-- Hire Page Hero -->
|
||||
<section class="py-24 relative overflow-hidden">
|
||||
|
||||
@@ -42,7 +42,7 @@ const keyFacts = [
|
||||
---
|
||||
|
||||
<Layout title={pageTitle}>
|
||||
<GlassHeader client:only="react" lang={lang} />
|
||||
<GlassHeader client:load transition:persist="header" lang={lang} />
|
||||
|
||||
<main class="min-h-screen">
|
||||
<div class="relative overflow-hidden">
|
||||
|
||||
@@ -14,7 +14,7 @@ const pageTitle = lang === 'zh' ? '现在' : 'Now';
|
||||
---
|
||||
|
||||
<Layout title={pageTitle}>
|
||||
<GlassHeader lang={lang} client:only="react" />
|
||||
<GlassHeader lang={lang} client:load transition:persist="header" />
|
||||
<main class="min-h-screen relative overflow-hidden">
|
||||
<!-- 背景装饰 -->
|
||||
<div class="absolute inset-0 -z-10">
|
||||
|
||||
@@ -26,7 +26,7 @@ const filterOptions = [
|
||||
---
|
||||
|
||||
<Layout title={pageTitle}>
|
||||
<GlassHeader lang={lang} client:only="react" />
|
||||
<GlassHeader lang={lang} client:load transition:persist="header" />
|
||||
<main class="min-h-screen relative overflow-hidden">
|
||||
<div
|
||||
aria-hidden="true"
|
||||
|
||||
@@ -44,23 +44,23 @@
|
||||
|
||||
:root {
|
||||
--radius: 0.75rem;
|
||||
--background: #F1F5F9; /* 更柔和的蓝灰色,不再是纯白或过于扎眼的浅色 */
|
||||
--foreground: #1E293B;
|
||||
--background: #F8FAFC; /* 稍微浅一点,增加与卡片的区分度 */
|
||||
--foreground: #0F172A; /* 更深的颜色,提高对比度 */
|
||||
--card: #FFFFFF;
|
||||
--card-foreground: #1E293B;
|
||||
--card-foreground: #0F172A;
|
||||
--popover: #FFFFFF;
|
||||
--popover-foreground: #1E293B;
|
||||
--popover-foreground: #0F172A;
|
||||
--primary: #2563EB;
|
||||
--primary-foreground: #FFFFFF;
|
||||
--secondary: #E4E4E7;
|
||||
--secondary-foreground: #1E293B;
|
||||
--muted: #F4F4F5;
|
||||
--muted-foreground: #71717A;
|
||||
--secondary: #F1F5F9;
|
||||
--secondary-foreground: #0F172A;
|
||||
--muted: #F1F5F9;
|
||||
--muted-foreground: #64748B;
|
||||
--accent: #F97316;
|
||||
--accent-foreground: #FFFFFF;
|
||||
--destructive: #EF4444;
|
||||
--border: #E4E4E7;
|
||||
--input: #E4E4E7;
|
||||
--border: #E2E8F0;
|
||||
--input: #E2E8F0;
|
||||
--ring: #2563EB;
|
||||
--chart-1: oklch(0.646 0.222 41.116);
|
||||
--chart-2: oklch(0.6 0.118 184.704);
|
||||
@@ -82,22 +82,22 @@
|
||||
--gradient-primary: linear-gradient(135deg, #2563EB, #F97316);
|
||||
--gradient-secondary: linear-gradient(135deg, #3B82F6, #10B981);
|
||||
--gradient-accent: linear-gradient(135deg, #F97316, #FB923C);
|
||||
--shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.05);
|
||||
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.08);
|
||||
--shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.12);
|
||||
--shadow-xl: 0 12px 40px rgba(37, 99, 235, 0.15);
|
||||
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
||||
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
|
||||
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
|
||||
--shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
|
||||
--animation-bounce: cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||
--animation-smooth: cubic-bezier(0.65, 0, 0.35, 1);
|
||||
--animation-spring: cubic-bezier(0.22, 1, 0.36, 1);
|
||||
|
||||
/* Global UI Design Tokens */
|
||||
--ui-hero-overlay: linear-gradient(135deg, rgb(30 58 138 / 0.2), rgb(37 99 235 / 0.1), rgb(154 52 18 / 0.2));
|
||||
--ui-title-gradient: linear-gradient(90deg, #111827 0%, var(--primary) 50%, #ea580c 100%);
|
||||
--ui-surface-bg: rgb(248 250 252 / 0.75);
|
||||
--ui-surface-border: rgb(228 228 231 / 0.7);
|
||||
--ui-surface-shadow: var(--shadow-sm);
|
||||
--ui-surface-blur: 10px;
|
||||
--ui-section-soft-bg: rgb(37 99 235 / 0.05);
|
||||
--ui-hero-overlay: linear-gradient(135deg, rgb(30 58 138 / 0.05), rgb(37 99 235 / 0.03), rgb(154 52 18 / 0.05));
|
||||
--ui-title-gradient: linear-gradient(90deg, #0F172A 0%, #2563EB 50%, #ea580c 100%);
|
||||
--ui-surface-bg: rgb(255 255 255 / 0.8);
|
||||
--ui-surface-border: rgb(226 232 240 / 0.8);
|
||||
--ui-surface-shadow: 0 4px 12px -2px rgb(0 0 0 / 0.05);
|
||||
--ui-surface-blur: 12px;
|
||||
--ui-section-soft-bg: rgb(37 99 235 / 0.03);
|
||||
}
|
||||
|
||||
.dark {
|
||||
|
||||
Reference in New Issue
Block a user