ux: 投资人风格应用卡片重新设计

- 重新设计卡片为投资人风格布局
- 优化字体、间距、阴影、圆角
- 调整背景纹理和极光效果

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
selfrelease
2026-08-04 18:41:38 +08:00
parent 6cbda69339
commit 474b742dc3
+222 -19
View File
@@ -926,6 +926,202 @@
:root[data-theme="light"] .bg-emerald-400 { background: oklch(0.6 0.2 150) !important; }
:root[data-theme="light"] .from-indigo-500 { --tw-gradient-from: oklch(0.5 0.24 275) !important; }
:root[data-theme="light"] .to-violet-500 { --tw-gradient-to: oklch(0.54 0.2 230) !important; }
/* ===== Investor-facing portfolio refresh ===== */
body {
font-family: "Avenir Next", "PingFang SC", "Microsoft YaHei", sans-serif;
background: var(--bg-base);
}
body::before {
background-size: 64px 64px;
opacity: 0.55;
mask-image: linear-gradient(to bottom, black, transparent 75%);
}
.aurora {
opacity: 0.32;
filter: blur(90px) saturate(0.8);
}
.glass-header {
border-radius: 0.5rem;
box-shadow: 0 12px 40px var(--header-shadow), inset 0 1px 0 var(--glass-inset);
}
.brand-mark {
border-radius: 0.35rem !important;
background: var(--text-heading);
color: var(--bg-base);
box-shadow: none;
}
.brand-mark::after { display: none; }
.portfolio-overview {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
align-items: end;
gap: 2rem;
margin-bottom: 1.75rem;
padding-bottom: 1.25rem;
border-bottom: 1px solid var(--glass-border);
}
.portfolio-kicker {
margin-bottom: 0.35rem;
color: var(--text-muted);
font-size: 0.68rem;
font-weight: 700;
letter-spacing: 0.12em;
text-transform: uppercase;
}
.portfolio-title {
color: var(--text-heading);
font-size: clamp(1.7rem, 4vw, 2.65rem);
line-height: 1.05;
font-weight: 800;
letter-spacing: 0;
text-wrap: balance;
}
.portfolio-metrics {
display: grid;
grid-template-columns: repeat(3, auto);
gap: 1.75rem;
}
.portfolio-metric strong {
display: block;
color: var(--text-heading);
font-size: 1.35rem;
line-height: 1;
font-weight: 750;
font-variant-numeric: tabular-nums;
}
.portfolio-metric span {
display: block;
margin-top: 0.35rem;
color: var(--text-muted);
font-size: 0.65rem;
white-space: nowrap;
}
.carousel-wrapper { padding: 0 2.25rem; }
.group-title,
.mobile-group-title {
display: flex;
align-items: center;
gap: 0.6rem;
color: var(--text-secondary);
font-size: 0.7rem;
font-weight: 700;
letter-spacing: 0.04em;
border-bottom: 0;
}
.group-title::before,
.mobile-group-title::before {
content: "";
width: 1.35rem;
height: 2px;
background: var(--text-heading);
opacity: 0.65;
}
.portal-card {
min-width: 0;
border-radius: 0.45rem !important;
border-color: var(--glass-border);
background: color-mix(in oklch, var(--glass-bg) 86%, transparent);
box-shadow: inset 0 1px 0 var(--glass-inset);
backdrop-filter: blur(16px) saturate(1.1);
-webkit-backdrop-filter: blur(16px) saturate(1.1);
transform: none !important;
color: inherit;
text-decoration: none;
transition: border-color 0.25s ease, background 0.25s ease, box-shadow 0.25s ease;
}
.portal-card::before {
display: none;
}
.portal-card::after { display: none; }
.portal-card:hover {
border-color: color-mix(in oklch, var(--accent) 42%, var(--glass-border));
background: var(--glass-bg-hover);
box-shadow: 0 16px 38px var(--glass-shadow);
text-decoration: none;
}
.portal-card h3,
.portal-card p,
.portal-card span { text-decoration: none; }
.animate-fade-in {
animation: investorCardIn 0.42s var(--ease-smooth) forwards;
}
@keyframes investorCardIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.card-index {
color: var(--text-muted);
font-size: 0.64rem;
font-weight: 700;
font-variant-numeric: tabular-nums;
}
.icon-wrap {
width: 2rem !important;
height: 2rem !important;
border-radius: 0.35rem !important;
color: var(--accent);
background: color-mix(in oklch, var(--accent) 12%, transparent);
border: 1px solid color-mix(in oklch, var(--accent) 20%, transparent);
box-shadow: none;
}
.icon-wrap::after { display: none; }
.icon-wrap svg { width: 1rem; height: 1rem; }
.portal-card:hover .icon-wrap { transform: none; box-shadow: none; }
.card-title {
color: var(--text-heading);
font-size: 0.95rem;
line-height: 1.3;
font-weight: 750;
text-wrap: balance;
}
.card-purpose {
color: var(--text-secondary);
font-size: 0.72rem;
line-height: 1.45;
font-weight: 500;
}
.card-footer {
margin-top: auto;
padding-top: 0.75rem;
border-top: 1px solid var(--glass-border);
}
.tag-pill {
padding: 0 !important;
border: 0;
border-radius: 0;
color: var(--text-muted);
background: transparent;
font-size: 0.62rem !important;
font-weight: 650;
}
.launch-link {
width: 1.75rem;
height: 1.75rem;
padding: 0 !important;
justify-content: center;
border-radius: 0.3rem !important;
color: var(--text-heading);
background: transparent;
border-color: var(--glass-border);
}
.portal-card:hover .launch-link {
transform: translateX(2px);
color: var(--bg-base);
background: var(--text-heading);
}
.carousel-btn,
.theme-toggle,
.help-btn {
border-radius: 0.35rem !important;
}
.carousel-dot { border-radius: 1px; height: 3px; }
.carousel-dot.active { border-radius: 1px; }
@media (max-width: 768px) {
.portfolio-overview { grid-template-columns: 1fr; gap: 1.25rem; }
.portfolio-metrics { width: 100%; justify-content: space-between; gap: 1rem; }
.mobile-app-list .portal-card { min-height: 158px; }
}
</style>
</head>
<body class="antialiased relative">
@@ -946,7 +1142,7 @@
<div class="flex items-center gap-3">
<span class="hidden md:inline-flex items-center gap-2 rounded-full bg-white/5 px-2.5 py-1 text-[11px] font-semibold text-slate-400 ring-1 ring-white/10">
<span class="h-1.5 w-1.5 rounded-full bg-emerald-400 shadow-[0_0_12px_oklch(0.72_0.18_150)]"></span>
20 个智能应用在线 / 20 Apps Online
20 个产品在线 / 20 Products Live
</span>
<button class="theme-toggle w-7 h-7 rounded-full flex items-center justify-center" onclick="toggleTheme()" aria-label="切换主题 / Toggle Theme">
<svg class="moon-icon w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>
@@ -964,8 +1160,17 @@
<!-- Main Content -->
<main class="container mx-auto max-w-5xl px-4 py-10 md:py-14">
<section class="portfolio-overview" aria-labelledby="portfolioTitle">
<div>
<p class="portfolio-kicker">AI product portfolio</p>
<h1 class="portfolio-title" id="portfolioTitle">可落地的 AI 产品矩阵</h1>
</div>
<div class="portfolio-metrics" aria-label="产品组合概览">
<div class="portfolio-metric"><strong>20</strong><span>在线产品</span></div>
<div class="portfolio-metric"><strong>6</strong><span>业务场景</span></div>
<div class="portfolio-metric"><strong>100%</strong><span>可在线体验</span></div>
</div>
</section>
<!-- App Grid -->
<section class="carousel-wrapper" id="carouselWrapper">
@@ -1311,6 +1516,10 @@
}
}
function getPrimaryText(text) {
return text.split(' / ')[0].trim();
}
/**
* 根据鼠标位置更新卡片高光与 3D 倾斜参数。
*/
@@ -1348,32 +1557,26 @@
card.href = app.url;
card.target = '_blank';
card.rel = 'noopener noreferrer';
card.className = 'portal-card group rounded-[1.25rem] p-4 flex h-[230px] flex-col animate-fade-in';
card.className = 'portal-card group p-4 flex h-[164px] 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.5 flex items-start justify-between">
<div class="icon-wrap w-10 h-10 rounded-xl flex items-center justify-center">
<div class="mb-3 flex items-center justify-between">
<div class="icon-wrap flex items-center justify-center">
${getIcon(app.icon)}
</div>
<span class="tag-pill rounded-full px-2.5 py-0.5 text-[10px] font-bold">${app.tag}</span>
<span class="card-index">${String(i + 1).padStart(2, '0')}</span>
</div>
<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.5 flex-1 text-[11px] leading-relaxed text-slate-500 overflow-hidden" style="display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; text-overflow: ellipsis;">${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.5 rounded-full px-2.5 py-1 text-[10px] font-bold">
进入应用 / Launch
<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>
<h3 class="card-title">${app.name}</h3>
<p class="card-purpose mt-1">${getPrimaryText(app.subtitle)}</p>
<div class="card-footer flex items-center justify-between gap-2">
<span class="tag-pill">${getPrimaryText(app.tag)}</span>
<span class="launch-link inline-flex shrink-0 items-center" aria-hidden="true">
<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.5" d="M7 17 17 7"/><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M9 7h8v8"/></svg>
</span>
</div>
</div>
`;
card.addEventListener('mousemove', handleCardMove);
card.addEventListener('mouseleave', resetCardMove);
return card;
}