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:
+222
-19
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user