feat: skill驱动UI优化 - Geist字体+噪点纹理+浮动pill导航+double-bezel卡片+滚动入场动画

This commit is contained in:
freedakgmail
2026-07-07 07:09:31 +08:00
parent e0cf13255e
commit 8baa46443b
17 changed files with 7770 additions and 35 deletions
+86 -35
View File
@@ -8,7 +8,8 @@
<script src="https://cdn.tailwindcss.com"></script>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@300;400;500;600;700;800&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Geist:wght@300;400;500;600;700;800&display=swap" />
<style>
/* ===== Liquid Glass 主题变量 ===== */
:root {
@@ -16,6 +17,9 @@
--glass-blur: 24px;
--glass-saturate: 1.8;
--transition-theme: background 0.5s ease, color 0.5s ease, border-color 0.5s ease, box-shadow 0.5s ease;
--ease-spring: cubic-bezier(0.32, 0.72, 0, 1);
--ease-bounce: cubic-bezier(0.34, 1.56, 0.64, 1);
--ease-smooth: cubic-bezier(0.22, 1, 0.36, 1);
}
/* ===== 深色模式 ===== */
@@ -136,8 +140,8 @@
--refraction-color: oklch(0.5 0.05 265 / 0.06);
}
* { font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif; }
html { font-size: 110%; }
* { font-family: 'Geist', 'Plus Jakarta Sans', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif; }
html { font-size: 110%; scroll-behavior: smooth; }
body {
position: relative;
min-height: 100vh;
@@ -162,6 +166,15 @@
mask-image: radial-gradient(circle at 50% 20%, black, transparent 78%);
z-index: 0;
}
body::after {
content: "";
position: fixed;
inset: 0;
pointer-events: none;
z-index: 1;
opacity: 0.035;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
.aurora {
position: fixed;
inset: -30%;
@@ -176,17 +189,18 @@
}
main {
position: relative;
z-index: 1;
z-index: 2;
}
/* ===== 液态玻璃核心样式 ===== */
.glass-header {
background: var(--header-bg);
border-bottom: 1px solid var(--header-border);
box-shadow: 0 10px 34px var(--header-shadow);
border: 1px solid var(--header-border);
box-shadow: 0 8px 32px var(--header-shadow), inset 0 1px 0 var(--glass-inset);
backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
-webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
transition: var(--transition-theme);
border-radius: 1rem;
}
.brand-mark {
position: relative;
@@ -250,11 +264,11 @@
overflow: hidden;
border: 1px solid var(--glass-border);
background: var(--glass-bg);
box-shadow: 0 18px 48px var(--glass-shadow), inset 0 1px 0 var(--glass-inset);
box-shadow: 0 18px 48px var(--glass-shadow), inset 0 1px 0 var(--glass-inset), inset 0 0 0 1px var(--refraction-color);
backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
-webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
transform-style: preserve-3d;
transition: transform 0.32s cubic-bezier(0.22, 1, 0.36, 1), box-shadow 0.32s ease, border-color 0.32s ease, background 0.5s ease;
transition: transform 0.5s var(--ease-spring), box-shadow 0.5s var(--ease-spring), border-color 0.4s var(--ease-smooth), background 0.5s ease;
will-change: transform;
}
.portal-card::before {
@@ -278,7 +292,7 @@
.portal-card:hover {
transform: translateY(-9px) rotateX(var(--rx)) rotateY(var(--ry));
border-color: color-mix(in oklch, var(--accent) 48%, var(--glass-border));
box-shadow: 0 26px 70px color-mix(in oklch, var(--accent) 28%, transparent), inset 0 1px 0 var(--glass-inset);
box-shadow: 0 26px 70px color-mix(in oklch, var(--accent) 28%, transparent), inset 0 1px 0 var(--glass-inset), inset 0 0 0 1px color-mix(in oklch, var(--accent) 12%, transparent);
background: var(--glass-bg-hover);
}
.portal-card:hover::before { opacity: 1; }
@@ -287,8 +301,8 @@
position: relative;
color: white;
background: linear-gradient(135deg, var(--accent), var(--accent-2));
box-shadow: 0 12px 30px color-mix(in oklch, var(--accent) 30%, transparent);
transition: transform 0.32s ease, box-shadow 0.32s ease;
box-shadow: 0 12px 30px color-mix(in oklch, var(--accent) 30%, transparent), inset 0 1px 0 rgba(255,255,255,0.2);
transition: transform 0.5s var(--ease-spring), box-shadow 0.5s var(--ease-spring);
}
.icon-wrap::after {
content: "";
@@ -317,15 +331,19 @@
color: var(--accent);
background: color-mix(in oklch, var(--accent) 12%, var(--launch-bg-mix));
border: 1px solid color-mix(in oklch, var(--accent) 18%, transparent);
transition: transform 0.25s ease, background 0.25s ease;
transition: transform 0.4s var(--ease-spring), background 0.3s var(--ease-smooth);
}
.portal-card:hover .launch-link {
transform: translateX(2px);
transform: translateX(3px);
background: color-mix(in oklch, var(--accent) 18%, var(--launch-bg-mix));
}
.portal-card:hover .launch-link .w-4 {
transform: scale(1.1);
transition: transform 0.4s var(--ease-bounce);
}
@keyframes fadeInUp {
from { opacity: 0; transform: translateY(22px) scale(0.98); }
to { opacity: 1; transform: translateY(0) scale(1); }
from { opacity: 0; transform: translateY(28px) scale(0.96); filter: blur(6px); }
to { opacity: 1; transform: translateY(0) scale(1); filter: blur(0); }
}
@keyframes auroraShift {
from { transform: translate3d(-2%, -1%, 0) scale(1); }
@@ -335,9 +353,20 @@
to { transform: rotate(360deg); }
}
.animate-fade-in {
animation: fadeInUp 0.64s cubic-bezier(0.22, 1, 0.36, 1) forwards;
animation: fadeInUp 0.8s var(--ease-spring) forwards;
opacity: 0;
}
.reveal-pending {
opacity: 0;
transform: translateY(40px);
filter: blur(8px);
transition: opacity 0.8s var(--ease-spring), transform 0.8s var(--ease-spring), filter 0.8s var(--ease-spring);
}
.reveal-pending.reveal-in {
opacity: 1;
transform: translateY(0);
filter: blur(0);
}
.carousel-wrapper {
position: relative;
overflow: visible;
@@ -414,7 +443,7 @@
backdrop-filter: blur(12px) saturate(1.5);
-webkit-backdrop-filter: blur(12px) saturate(1.5);
cursor: pointer;
transition: all 0.25s ease;
transition: all 0.4s var(--ease-spring);
}
.carousel-btn:hover {
color: var(--text-primary);
@@ -482,7 +511,7 @@
border: 1px solid var(--btn-border);
backdrop-filter: blur(10px) saturate(1.4);
-webkit-backdrop-filter: blur(10px) saturate(1.4);
transition: all 0.25s ease;
transition: all 0.4s var(--ease-spring);
}
.help-btn:hover {
color: var(--text-primary);
@@ -605,7 +634,7 @@
border: 1px solid var(--btn-border);
backdrop-filter: blur(10px) saturate(1.4);
-webkit-backdrop-filter: blur(10px) saturate(1.4);
transition: all 0.25s ease;
transition: all 0.4s var(--ease-spring);
}
.theme-toggle:hover {
color: var(--text-primary);
@@ -620,6 +649,7 @@
/* ===== 访问计数实时动画 ===== */
.visitor-num {
display: inline-block;
font-variant-numeric: tabular-nums;
transition: transform 0.6s cubic-bezier(0.34, 1.56, 0.64, 1), color 0.4s ease;
}
.visitor-num.bump {
@@ -695,8 +725,8 @@
<div class="aurora" aria-hidden="true"></div>
<!-- Header -->
<header class="glass-header sticky top-0 z-50 h-14">
<div class="container mx-auto max-w-6xl px-4 h-full flex items-center justify-between">
<header class="glass-header sticky top-3 z-50 mx-auto max-w-5xl mt-3">
<div class="px-4 h-12 flex items-center justify-between">
<div class="flex items-center gap-3">
<div class="brand-mark w-9 h-9 rounded-xl flex items-center justify-center text-white">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3l7.5 4.25v8.5L12 20l-7.5-4.25v-8.5L12 3z"/><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8.5 9.2L12 7.25l3.5 1.95v3.6L12 14.75l-3.5-1.95v-3.6z"/></svg>
@@ -726,14 +756,19 @@
</header>
<!-- Main Content -->
<main class="container mx-auto max-w-6xl px-4 py-6 md:py-8">
<main class="container mx-auto max-w-5xl px-4 py-10 md:py-14">
<!-- Hero Section -->
<section class="text-center mb-5 md:mb-6 animate-fade-in">
<h1 class="text-xl md:text-2xl font-extrabold tracking-tight mb-1">
<span class="gradient-text">AI 智能应用中心 / AI Application Hub</span>
<section class="text-center mb-8 md:mb-10 animate-fade-in">
<div class="inline-flex items-center gap-2 rounded-full px-3 py-1 mb-3 text-[10px] uppercase tracking-[0.2em] font-medium" style="background: var(--glass-bg); border: 1px solid var(--glass-border); color: var(--text-secondary); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);">
<span class="h-1.5 w-1.5 rounded-full" style="background: var(--gradient-2); box-shadow: 0 0 8px var(--gradient-2);"></span>
All by AI · 2026
</div>
<h1 class="text-2xl md:text-3xl font-extrabold tracking-tight mb-2" style="text-wrap: balance;">
<span class="gradient-text">AI 智能应用中心</span>
</h1>
<p class="hero-subtitle text-slate-500 text-[10px] md:text-xs mx-auto leading-relaxed whitespace-nowrap overflow-hidden text-ellipsis">
<p class="text-sm font-medium text-slate-400 mb-1">AI Application Hub</p>
<p class="hero-subtitle text-slate-500 text-[11px] md:text-xs mx-auto leading-relaxed whitespace-nowrap overflow-hidden text-ellipsis">
一站式访问所有智能应用,让 AI 赋能企业每一个环节<span class="sep"> · </span>One-stop access to all AI apps, empowering every business workflow
</p>
</section>
@@ -1119,24 +1154,26 @@
card.href = app.url;
card.target = '_blank';
card.rel = 'noopener noreferrer';
card.className = 'portal-card group rounded-[1rem] p-3.5 flex h-[220px] flex-col animate-fade-in';
card.className = 'portal-card group rounded-[1.25rem] p-4 flex h-[230px] flex-col animate-fade-in';
card.style.cssText = `--accent: ${app.accent}; --accent-2: ${app.accent2}; animation-delay: ${i * 0.08}s;`;
card.innerHTML = `
<div class="relative z-10 flex h-full flex-col">
<div class="mb-2 flex items-start justify-between">
<div class="icon-wrap w-9 h-9 rounded-lg flex items-center justify-center">
<div class="mb-2.5 flex items-start justify-between">
<div class="icon-wrap w-10 h-10 rounded-xl flex items-center justify-center">
${getIcon(app.icon)}
</div>
<span class="tag-pill rounded-full px-2 py-0.5 text-[10px] font-bold">${app.tag}</span>
<span class="tag-pill rounded-full px-2.5 py-0.5 text-[10px] font-bold">${app.tag}</span>
</div>
<h3 class="text-sm font-extrabold tracking-tight text-slate-100 transition-colors group-hover:text-white">${app.name}</h3>
<h3 class="text-sm font-extrabold tracking-tight text-slate-100 transition-colors group-hover:text-white" style="transition: color 0.4s var(--ease-smooth);">${app.name}</h3>
<p class="mt-0.5 text-[11px] font-semibold text-slate-400">${app.subtitle}</p>
<p class="mt-1 flex-1 text-[11px] leading-relaxed text-slate-500">${app.desc}</p>
<div class="mt-2.5 flex items-center justify-between gap-2 border-t border-white/10 pt-2">
<p class="mt-1.5 flex-1 text-[11px] leading-relaxed text-slate-500">${app.desc}</p>
<div class="mt-2.5 flex items-center justify-between gap-2 border-t border-white/10 pt-2.5">
<span class="truncate text-[10px] font-medium text-slate-500">${getHostname(app.url)}</span>
<span class="launch-link inline-flex shrink-0 items-center gap-1 rounded-full px-2 py-0.5 text-[10px] font-bold">
<span class="launch-link inline-flex shrink-0 items-center gap-1.5 rounded-full px-2.5 py-1 text-[10px] font-bold">
进入应用 / Launch
<svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 17 17 7"/><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 7h8v8"/></svg>
<span class="inline-flex items-center justify-center w-4 h-4 rounded-full bg-white/10">
<svg class="w-2.5 h-2.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M7 17 17 7"/><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M9 7h8v8"/></svg>
</span>
</span>
</div>
</div>
@@ -1238,6 +1275,20 @@
renderCarousel();
renderMobileList();
const revealObserver = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
entry.target.classList.add('reveal-in');
revealObserver.unobserve(entry.target);
}
});
}, { threshold: 0.1, rootMargin: '0px 0px -40px 0px' });
document.querySelectorAll('.carousel-wrapper, .mobile-app-list, .contact-section').forEach((el) => {
el.classList.add('reveal-pending');
revealObserver.observe(el);
});
/**
* 调用第三方计数 API 获取并递增全局访问量,更新页脚显示。
* 之后定时轮询 get 接口(不递增),检测新访客并艺术化提示。