You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
244 lines
13 KiB
244 lines
13 KiB
import type { CSSProperties } from 'react';
|
|
import { getLocalizedPath, getTranslation, type Locale } from '../i18n/utils';
|
|
import { PLACEHOLDER_IMG } from '../placeholder';
|
|
import { cssVars } from './css';
|
|
import { Icon, statsIcons } from '../icons';
|
|
|
|
export default function Home({ locale }: { locale: Locale }) {
|
|
const t = getTranslation(locale);
|
|
const h = t.home;
|
|
const stats = h.stats.items;
|
|
const pillars = t.home.pillars.items;
|
|
|
|
// 三语辅助:英文 / 繁体 / 简体
|
|
const tr = (en: string, hk: string, zh: string) =>
|
|
locale === 'en' ? en : locale === 'hk' ? hk : zh;
|
|
|
|
const news = t.news.items.slice(0, 3);
|
|
|
|
// 环绕中央玻璃球的轨道粒子:7 圈 · 16 颗发光点,linear 匀速,顺逆交错
|
|
// 半径 110~275px,明确围绕玻璃球(半径约 100px)外侧公转
|
|
const orbits = [
|
|
{ r: 110, d: '11s', rev: false, dots: [{ sz: 5, a: '20deg' }, { sz: 4, a: '200deg' }] },
|
|
{ r: 140, d: '14s', rev: true, dots: [{ sz: 5, a: '120deg' }, { sz: 4, a: '300deg' }] },
|
|
{ r: 170, d: '17s', rev: false, dots: [{ sz: 4, a: '60deg' }, { sz: 4, a: '210deg' }] },
|
|
{ r: 200, d: '20s', rev: true, dots: [{ sz: 4, a: '0deg' }, { sz: 3, a: '120deg' }, { sz: 3, a: '240deg' }] },
|
|
{ r: 228, d: '23s', rev: false, dots: [{ sz: 3, a: '90deg' }, { sz: 3, a: '250deg' }] },
|
|
{ r: 252, d: '26s', rev: true, dots: [{ sz: 3, a: '45deg' }, { sz: 3, a: '190deg' }, { sz: 3, a: '330deg' }] },
|
|
{ r: 275, d: '29s', rev: false, dots: [{ sz: 3, a: '15deg' }, { sz: 3, a: '160deg' }] },
|
|
] as const;
|
|
|
|
return (
|
|
<>
|
|
{/* ===== HERO:品牌背景图(玻璃球/水滴抽象,浅蓝+薰衣草,品牌色)+ 动态粒子 ===== */}
|
|
<section
|
|
className="relative w-full h-[calc(100vh-60px)] min-h-[520px] max-h-[900px] overflow-hidden"
|
|
style={{
|
|
background:
|
|
'linear-gradient(135deg, #0a0e2a 0%, #14182f 50%, #1d2150 100%)',
|
|
}}
|
|
>
|
|
{/* 背景图:玻璃球/水滴主题图,匹配品牌色 */}
|
|
<img
|
|
src="/hero-bg.jpg"
|
|
alt=""
|
|
aria-hidden="true"
|
|
className="absolute inset-0 w-full h-full object-cover"
|
|
loading="eager"
|
|
decoding="async"
|
|
/>
|
|
|
|
{/* 粒子层:环绕中央玻璃球的轨道粒子(7 圈 / 16 颗,linear 匀速环绕) */}
|
|
<div className="hero-orbit pointer-events-none" aria-hidden="true" style={{ left: '70%', top: '46%' }}>
|
|
{orbits.flatMap((o, i) =>
|
|
o.dots.map((d, j) => {
|
|
// 全局 dot 序号,用于 stagger 脉冲相位
|
|
const globalIdx = orbits.slice(0, i).reduce((n, x) => n + x.dots.length, 0) + j;
|
|
return (
|
|
<div
|
|
key={`${i}-${j}`}
|
|
className={`hero-ring${o.rev ? ' is-rev' : ''}`}
|
|
style={{
|
|
animationDuration: o.d,
|
|
animationDirection: o.rev ? 'reverse' : 'normal',
|
|
'--r': `${o.r}px`,
|
|
} as CSSProperties}
|
|
>
|
|
<div className="hero-orbit-slot" style={{ '--a': d.a } as CSSProperties}>
|
|
<span
|
|
className="hero-orbit-dot"
|
|
style={{
|
|
width: d.sz,
|
|
height: d.sz,
|
|
animationDelay: `${-(globalIdx * 0.4).toFixed(2)}s`,
|
|
}}
|
|
/>
|
|
</div>
|
|
</div>
|
|
);
|
|
}),
|
|
)}
|
|
</div>
|
|
|
|
<div className="relative z-10 h-full w-full max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex flex-col justify-end pb-16 md:pb-24">
|
|
<div className="max-w-3xl scroll-reveal">
|
|
<h1 className="text-h1 font-bold leading-[1.1] tracking-tight text-white font-[var(--font-display)]">
|
|
{h.heroTitle}
|
|
</h1>
|
|
<p className="mt-5 text-body md:text-body text-white/90 max-w-xl leading-relaxed">
|
|
{h.sloganIntro}
|
|
</p>
|
|
<a
|
|
href={getLocalizedPath('/about', locale)}
|
|
className="mt-8 inline-flex items-center gap-2 text-body font-semibold text-white border-b border-white/60 pb-1 hover:border-white hover:gap-3 transition-all duration-300 group"
|
|
>
|
|
{h.heroCta}
|
|
<Icon name="arrowRight" className="w-4 h-4 transition-transform duration-300 group-hover:translate-x-1" />
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
{/* ===== 最新资讯(腾讯式三列卡片) ===== */}
|
|
<section className="bg-[var(--bg-primary)]">
|
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-[var(--space-10)]">
|
|
<div className="flex flex-col sm:flex-row sm:items-end justify-between gap-4 mb-8">
|
|
<div className="text-left">
|
|
<span className="section-eyebrow">NEWSROOM</span>
|
|
<h2 className="section-title mt-3">{t.news.title}</h2>
|
|
</div>
|
|
<a href={getLocalizedPath('/news', locale)} className="inline-flex items-center gap-1.5 text-body font-semibold text-[var(--brand-accent)] hover:gap-2.5 transition-all duration-300">
|
|
{tr('View all news', '查看全部新聞', '查看全部新闻')}
|
|
<Icon name="arrowRight" className="w-4 h-4" />
|
|
</a>
|
|
</div>
|
|
<div className="grid sm:grid-cols-2 lg:grid-cols-3 gap-6">
|
|
{news.map((item, idx) => (
|
|
<a key={idx} href={getLocalizedPath('/news', locale)} className="track-card group overflow-hidden flex flex-col scroll-reveal">
|
|
<div className="relative aspect-[16/10] overflow-hidden border-b border-[var(--border-light)]">
|
|
<img src={PLACEHOLDER_IMG} alt={item.title} className="w-full h-full object-cover transition-transform duration-700 group-hover:scale-105" loading="lazy" decoding="async" />
|
|
<span className="absolute top-3 left-3 text-body px-2 py-1 rounded-md bg-white/80 text-[var(--brand-accent)] font-semibold">{item.category}</span>
|
|
</div>
|
|
<div className="p-5">
|
|
<span className="text-body text-[var(--text-muted)] font-mono">{item.date}</span>
|
|
<h3 className="mt-2 text-body font-semibold text-[var(--brand-black)] leading-snug group-hover:text-[var(--brand-accent)] transition-colors duration-200">{item.title}</h3>
|
|
</div>
|
|
</a>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
{/* ===== 大文案 + 向下滚动指示(腾讯式) ===== */}
|
|
<section className="bg-[var(--bg-primary)] pb-[var(--space-10)]">
|
|
<div className="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8 text-center scroll-reveal">
|
|
<p className="text-body md:text-h1 font-bold font-[var(--font-display)] text-[var(--brand-black)] leading-[1.35] tracking-tight">
|
|
{tr(
|
|
'BaskBuddy improves the quality of life for people around the world through innovative technology, products and services.',
|
|
'巴適夥伴透過創新的科技、產品和服務,提升全球各地人們的生活品質。',
|
|
'巴适伙伴通过创新的科技、产品和服务,提升全球各地人们的生活品质。',
|
|
)}
|
|
</p>
|
|
</div>
|
|
<div className="mt-16 flex flex-col items-center text-[var(--text-muted)]">
|
|
<span className="text-body font-mono tracking-[0.3em]">SCROLL</span>
|
|
<span className="mt-3 w-px h-14 bg-gradient-to-b from-[var(--text-muted)] to-transparent animate-pulse" />
|
|
<Icon name="arrowDown" className="w-4 h-4 mt-1 animate-bounce" />
|
|
</div>
|
|
</section>
|
|
|
|
{/* ===== 业务大图入口(黑底 · 文字左侧,对应腾讯 "面向消费者 / 企业 / 未来") ===== */}
|
|
<section className="bg-[var(--brand-black)]">
|
|
{pillars.map((p, i) => (
|
|
<a
|
|
key={p.name}
|
|
href={getLocalizedPath('/business', locale) + '#ecosystem'}
|
|
className="group relative block h-[68vh] min-h-[420px] overflow-hidden"
|
|
>
|
|
<img
|
|
src={p.img}
|
|
alt={p.name}
|
|
className="absolute inset-0 w-full h-full object-cover transition-transform duration-[900ms] group-hover:scale-105"
|
|
loading="lazy"
|
|
decoding="async"
|
|
/>
|
|
{/* 左深右透蒙层:保证左侧白色标题在浅色图上仍清晰 */}
|
|
<div
|
|
className="absolute inset-0 pointer-events-none"
|
|
aria-hidden="true"
|
|
style={{
|
|
background:
|
|
'linear-gradient(90deg, rgba(10, 14, 42, 0.78) 0%, rgba(10, 14, 42, 0.55) 35%, rgba(10, 14, 42, 0.15) 70%, transparent 100%)',
|
|
}}
|
|
/>
|
|
<div className="relative z-10 h-full max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex flex-col justify-center">
|
|
<span className="text-body font-mono tracking-[0.3em] text-[var(--brand-accent)]">0{i + 1}</span>
|
|
<h2 className="mt-3 text-h1 font-bold font-[var(--font-display)] text-white leading-tight">
|
|
{p.name}
|
|
</h2>
|
|
<p className="mt-4 text-body md:text-body text-white/80 max-w-xl leading-relaxed">{p.desc}</p>
|
|
<span className="mt-7 inline-flex items-center gap-2 text-body font-semibold text-white border-b border-white/50 pb-1 w-fit transition-all duration-300 group-hover:gap-3 group-hover:border-white">
|
|
{tr('Learn more', '了解更多', '了解更多')}
|
|
<Icon name="arrowRight" className="w-4 h-4" />
|
|
</span>
|
|
</div>
|
|
</a>
|
|
))}
|
|
</section>
|
|
|
|
{/* ===== 愿景带 + 巴适速度 大数字 ===== */}
|
|
<section className="band !bg-[var(--bg-subtle)]">
|
|
<div className="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8 pt-[var(--space-10)] text-center">
|
|
<span className="section-eyebrow">OUR VISION</span>
|
|
<h2 className="text-h1 md:text-h1 font-bold font-[var(--font-display)] text-[var(--brand-black)] mt-3">
|
|
{tr('Value for Users, Tech for Good', '用戶為本 · 科技向善', '用户为本 · 科技向善')}
|
|
</h2>
|
|
<p className="mt-5 text-body text-[var(--text-secondary)] max-w-3xl mx-auto leading-relaxed">
|
|
{tr(
|
|
'Connect people and services through innovative technology — creating a better life for users and long-term value for society.',
|
|
'以創新技術連接人與服務,為用戶創造美好生活,為社會創造長期價值。',
|
|
'以创新技术连接人与服务,为用户创造美好生活,为社会创造长期价值。',
|
|
)}
|
|
</p>
|
|
</div>
|
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-[var(--space-9)]">
|
|
<div className="stat-band scroll-reveal mt-6">
|
|
{stats.map((sItem, idx) => (
|
|
<div className="stat-cell" key={sItem.label} style={cssVars({ '--track-color': 'var(--accent)' })}>
|
|
<Icon name={statsIcons[idx]} className="w-8 h-8 mx-auto mb-3" style={{ color: 'var(--brand-accent)' }} />
|
|
<div className="stat-num">
|
|
<span className="stat-value">{sItem.value}</span>
|
|
{sItem.suffix && <span className="stat-suffix">{sItem.suffix}</span>}
|
|
</div>
|
|
<div className="stat-label">{sItem.label}</div>
|
|
<div className="stat-sub">{sItem.sub}</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
{/* ===== CTA Band ===== */}
|
|
<section className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 pb-[var(--space-10)]">
|
|
<div className="cta-band scroll-reveal px-8 py-14 md:py-16 text-center">
|
|
<h2 className="relative z-10 text-h1 font-bold font-[var(--font-display)] text-white">{t.contact.subtitle}</h2>
|
|
<p className="relative z-10 mt-3 text-body text-[rgba(255,255,255,0.7)] max-w-xl mx-auto">
|
|
{tr(
|
|
'Whether for a job inquiry or business cooperation, we look forward to meeting you with warmth.',
|
|
'無論是求職諮詢還是商務合作,我們都期待與你溫暖相遇。',
|
|
'无论是求职咨询还是商务合作,我们都期待与你温暖相遇。',
|
|
)}
|
|
</p>
|
|
<div className="relative z-10 mt-8 flex flex-col sm:flex-row items-center justify-center gap-3.5">
|
|
<a href={getLocalizedPath('/contact', locale)} className="btn btn-light btn-lg">
|
|
{t.contact.title}
|
|
</a>
|
|
<a href={getLocalizedPath('/about', locale)} className="btn btn-outline-light btn-lg">
|
|
{tr('About Us', '了解我們', '了解我们')}
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</>
|
|
);
|
|
}
|
|
|