Fix hero layout: align globe with headline and update README

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
eric 2026-08-28 19:53:42 -05:00
parent 9df4444cc5
commit 63778ba761
2 changed files with 136 additions and 98 deletions

View File

@ -198,14 +198,59 @@ img { max-width: 100%; display: block; }
.hero {
position: relative;
min-height: 100vh;
display: grid;
grid-template-columns: 1fr 1fr;
align-items: start;
gap: 40px;
padding: calc(var(--nav-height) + 40px) 24px 80px;
display: flex;
flex-direction: column;
justify-content: center;
padding: calc(var(--nav-height) + 52px) 24px 80px;
z-index: 1;
overflow: hidden;
}
.hero-bg-shapes {
position: absolute;
inset: 0;
pointer-events: none;
z-index: 0;
}
.hero-inner {
position: relative;
z-index: 1;
width: 100%;
max-width: 1200px;
margin: 0 auto;
z-index: 1;
}
.hero-top {
display: grid;
grid-template-columns: 1fr 1fr;
align-items: center;
gap: 32px 48px;
}
.hero-content {
min-width: 0;
}
.hero-bottom {
margin-top: 40px;
}
.hero-visual {
display: flex;
justify-content: center;
align-items: center;
position: relative;
width: 100%;
overflow: visible;
}
.globe-container {
position: relative;
width: 100%;
max-width: 400px;
margin: 0 auto;
overflow: visible;
}
.hero-bg-shapes .shape {
@ -302,7 +347,7 @@ img { max-width: 100%; display: block; }
.hero-subtitle {
font-size: 1.1rem;
color: var(--text-secondary);
margin-bottom: 36px;
margin-bottom: 0;
max-width: 480px;
line-height: 1.8;
}
@ -310,7 +355,7 @@ img { max-width: 100%; display: block; }
.hero-actions {
display: flex;
gap: 16px;
margin-bottom: 48px;
margin-bottom: 32px;
flex-wrap: wrap;
}
@ -391,23 +436,6 @@ img { max-width: 100%; display: block; }
}
/* Globe Visual */
.hero-visual {
display: flex;
justify-content: center;
align-items: flex-start;
position: relative;
/* 与左侧 hero-badge 等高,使地球与标题「用一行代码 环游世界」顶部对齐 */
padding-top: 58px;
width: 100%;
}
.globe-container {
position: relative;
width: 100%;
max-width: 420px;
margin: 0;
}
.globe-svg {
width: 100%;
height: auto;
@ -481,9 +509,9 @@ img { max-width: 100%; display: block; }
margin-top: 2px;
}
.fc-1 { top: 8%; right: -5%; animation-delay: 0s; }
.fc-2 { top: 42%; left: -12%; animation-delay: -1.5s; }
.fc-3 { bottom: 8%; right: 0; animation-delay: -3s; }
.fc-1 { top: 5%; right: -8%; animation-delay: 0s; }
.fc-2 { top: 38%; left: -14%; animation-delay: -1.5s; }
.fc-3 { bottom: 10%; right: -2%; animation-delay: -3s; }
@keyframes cardFloat {
0%, 100% { transform: translateY(0); }
@ -1120,17 +1148,17 @@ img { max-width: 100%; display: block; }
/* ===== Responsive ===== */
@media (max-width: 1024px) {
.hero {
.hero-top {
grid-template-columns: 1fr;
text-align: center;
padding-top: calc(var(--nav-height) + 20px);
gap: 28px;
}
.hero-subtitle { margin: 0 auto 36px; }
.hero-subtitle { margin: 0 auto; max-width: 100%; }
.hero-actions { justify-content: center; }
.hero-stats { justify-content: center; }
.hero-visual { order: -1; padding-top: 0; margin-bottom: 8px; }
.globe-container { max-width: 300px; margin: 0 auto; }
.hero-visual { order: -1; }
.globe-container { max-width: 280px; }
.dest-grid { grid-template-columns: repeat(2, 1fr); }
.tools-grid { grid-template-columns: repeat(2, 1fr); }

View File

@ -63,6 +63,9 @@ export default function Hero({ stats }: Props) {
<div className="hero-bg-shapes">
<div className="shape shape-1" /><div className="shape shape-2" /><div className="shape shape-3" />
</div>
<div className="hero-inner">
<div className="hero-top">
<div className="hero-content">
<div className="hero-badge reveal">
<span className="badge-dot" />
@ -74,33 +77,8 @@ export default function Hero({ stats }: Props) {
<p className="hero-subtitle reveal">
<span id="typewriter" /><span className="typewriter-cursor">|</span>
</p>
<div className="hero-actions reveal">
<a href="#destinations" className="btn btn-primary">
<span>探索目的地</span>
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M5 12h14M12 5l7 7-7 7" /></svg>
</a>
<a href="#calculator" className="btn btn-ghost"><span>🧮 费用计算</span></a>
<button className="btn btn-ghost hero-matcher-btn" onClick={() => {
window.dispatchEvent(new CustomEvent("open-matcher"));
}}><span>🎯 智能匹配</span></button>
</div>
<div className="hero-stats reveal">
<div className="stat-item">
<span className="stat-number" data-target={stats.countries}>0</span>
<span className="stat-label">🗺️ 可探索国家</span>
</div>
<div className="stat-divider" />
<div className="stat-item">
<span className="stat-number" data-target={stats.avg_cost}>0</span>
<span className="stat-label">💰 平均月生活费 (千元)</span>
</div>
<div className="stat-divider" />
<div className="stat-item">
<span className="stat-number" data-target={stats.satisfaction}>0</span>
<span className="stat-label">😊 生活满意度 %</span>
</div>
</div>
</div>
<div className="hero-visual reveal">
<div className="globe-container">
<svg className="globe-svg" viewBox="0 0 400 400">
@ -133,6 +111,38 @@ export default function Hero({ stats }: Props) {
</div>
</div>
</div>
</div>
<div className="hero-bottom reveal">
<div className="hero-actions">
<a href="#destinations" className="btn btn-primary">
<span>探索目的地</span>
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M5 12h14M12 5l7 7-7 7" /></svg>
</a>
<a href="#calculator" className="btn btn-ghost"><span>🧮 费用计算</span></a>
<button className="btn btn-ghost hero-matcher-btn" onClick={() => {
window.dispatchEvent(new CustomEvent("open-matcher"));
}}><span>🎯 智能匹配</span></button>
</div>
<div className="hero-stats">
<div className="stat-item">
<span className="stat-number" data-target={stats.countries}>0</span>
<span className="stat-label">🗺️ 可探索国家</span>
</div>
<div className="stat-divider" />
<div className="stat-item">
<span className="stat-number" data-target={stats.avg_cost}>0</span>
<span className="stat-label">💰 平均月生活费 (千元)</span>
</div>
<div className="stat-divider" />
<div className="stat-item">
<span className="stat-number" data-target={stats.satisfaction}>0</span>
<span className="stat-label">😊 生活满意度 %</span>
</div>
</div>
</div>
</div>
<div className="scroll-indicator">
<span>向下滚动</span>
<div className="scroll-arrow">