feat: skill驱动UI优化 - Geist字体+噪点纹理+浮动pill导航+double-bezel卡片+滚动入场动画
This commit is contained in:
+86
-35
@@ -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 接口(不递增),检测新访客并艺术化提示。
|
||||
|
||||
Reference in New Issue
Block a user