精简首页预览版本并优化响应式布局

This commit is contained in:
inxs
2026-08-23 13:58:41 +08:00
parent 2fcc63f94f
commit f569863ee3
4 changed files with 31 additions and 1781 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -6,14 +6,11 @@ import {
ArrowLeft,
ArrowRight,
CheckCircle,
Globe,
Headset,
List,
MagnifyingGlass,
MapPin,
PauseCircle,
PlayCircle,
UsersThree,
X,
} from '@phosphor-icons/react';
import {
@@ -1819,9 +1816,6 @@ function routeDetailPillars(safari: SafariCardItem, language: SiteLanguage = 'zh
}
function selectPage(path: string) {
if (path === '/preview/classic') return <HomePage variant="classic" />;
if (path === '/preview/v1') return <HomePage variant="v1" />;
if (path === '/preview/v2') return <EditorialHomePage />;
if (path === '/safari-faqs' || path === '/faqs') return <SafariFaqsPage />;
if (path.startsWith('/our-guides')) return <GuidesPage />;
if (path.startsWith('/meet-the-team')) return <TeamPage />;
@@ -1855,269 +1849,6 @@ function selectPage(path: string) {
return <HomePage />;
}
function EditorialHomePage() {
const { content, language } = useTravelSite();
const editorialRef = useRef<HTMLElement | null>(null);
const home = content.home;
const editorialExperiences = [
{ number: '01', title: pickText('山野', 'Wild Karst', language), eyebrow: pickText('徒步 · 骑行 · 洞穴', 'Hike · Cycle · Caves', language), image: '/client-assets/karst-hike-ridge.jpg', href: '/experiences/karst-hiking/' },
{ number: '02', title: pickText('村寨', 'Village Life', language), eyebrow: pickText('日常 · 家宴 · 手作', 'Homes · Tables · Craft', language), image: '/client-assets/villages-xijiang-dusk.jpg', href: '/experiences/indigenous-ethnic-villages/' },
{ number: '03', title: pickText('水世界', 'Water Worlds', language), eyebrow: pickText('瀑布 · 峡谷 · 河流', 'Falls · Canyons · Rivers', language), image: '/client-assets/waterfall-huangguoshu-curtain.jpg', href: '/experiences/iconic-waterfall-clusters/' },
{ number: '04', title: pickText('贵州味道', 'Taste Guizhou', language), eyebrow: pickText('家宴 · 市场 · 山野咖啡', 'Tables · Markets · Coffee', language), image: '/client-assets/culinary-long-table-banquet.jpg', href: '/experiences/culinary-cultural-journeys/' },
];
const editorialRoutes = home.safaris.cards.slice(0, 3);
const fieldImages = [
'/client-assets/team-field-day.webp',
'/client-assets/culture-batik-making.jpg',
'/client-assets/river-packraft-shore.jpg',
'/client-assets/ancient-towns-zhenyuan-night.jpg',
'/client-assets/culinary-long-table-banquet.jpg',
];
useGSAP(
() => {
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
const heroTimeline = gsap.timeline({ defaults: { ease: 'power3.out' } });
heroTimeline
.from('.oc-v2-hero > img', { scale: 1.13, autoAlpha: 0.4, duration: 1.8, ease: 'power2.out' })
.from('.oc-v2-hero-copy > p', { y: 20, autoAlpha: 0, duration: 0.6 }, '-=1.18')
.from('.oc-v2-hero h1', { y: 90, autoAlpha: 0, duration: 1.05 }, '-=.85')
.from('.oc-v2-hero-bottom > *', { y: 32, autoAlpha: 0, duration: 0.7, stagger: 0.12 }, '-=.58')
.from('.oc-v2-hero-scroll', { scale: 0.65, autoAlpha: 0, duration: 0.55 }, '-=.45');
gsap.to('.oc-v2-hero > img', {
yPercent: 10,
scale: 1.08,
ease: 'none',
scrollTrigger: { trigger: '.oc-v2-hero', start: 'top top+=90', end: 'bottom top', scrub: 0.7 },
});
gsap.to('.oc-v2-hero-scroll svg', {
y: 8,
duration: 1.15,
repeat: -1,
yoyo: true,
ease: 'sine.inOut',
});
gsap.utils.toArray<HTMLElement>('.oc-v2-section-intro, .oc-v2-field-heading').forEach((heading) => {
gsap.from(heading.children, {
y: 58,
autoAlpha: 0,
duration: 0.9,
stagger: 0.12,
ease: 'power3.out',
scrollTrigger: { trigger: heading, start: 'top 78%', once: true },
});
});
gsap.from('.oc-v2-experience-card', {
y: 86,
clipPath: 'inset(0 0 100% 0)',
duration: 1.05,
stagger: 0.11,
ease: 'power4.out',
scrollTrigger: { trigger: '.oc-v2-experience-grid', start: 'top 76%', once: true },
});
gsap.from('.oc-v2-experience-card > img', {
scale: 1.18,
duration: 1.5,
stagger: 0.11,
ease: 'power3.out',
scrollTrigger: { trigger: '.oc-v2-experience-grid', start: 'top 76%', once: true },
});
gsap.from('.oc-v2-feature-image', {
clipPath: 'inset(0 100% 0 0)',
duration: 1.25,
ease: 'power4.inOut',
scrollTrigger: { trigger: '.oc-v2-feature', start: 'top 72%', once: true },
});
gsap.from('.oc-v2-feature-image img', {
scale: 1.16,
duration: 1.6,
ease: 'power3.out',
scrollTrigger: { trigger: '.oc-v2-feature', start: 'top 72%', once: true },
});
gsap.from('.oc-v2-feature-copy > *', {
y: 58,
autoAlpha: 0,
duration: 0.82,
stagger: 0.1,
ease: 'power3.out',
scrollTrigger: { trigger: '.oc-v2-feature-copy', start: 'top 74%', once: true },
});
gsap.from('.oc-v2-route-card', {
y: 90,
clipPath: 'inset(100% 0 0 0)',
duration: 1.08,
stagger: 0.13,
ease: 'power4.out',
scrollTrigger: { trigger: '.oc-v2-route-grid', start: 'top 76%', once: true },
});
gsap.from('.oc-v2-route-card img', {
scale: 1.16,
duration: 1.55,
stagger: 0.13,
ease: 'power3.out',
scrollTrigger: { trigger: '.oc-v2-route-grid', start: 'top 76%', once: true },
});
gsap.from('.oc-v2-field-collage figure, .oc-v2-field-note', {
y: 76,
scale: 0.96,
autoAlpha: 0,
duration: 0.9,
stagger: 0.1,
ease: 'power3.out',
scrollTrigger: { trigger: '.oc-v2-field-collage', start: 'top 76%', once: true },
});
gsap.to('.oc-v2-field-collage figure.is-1 img', {
yPercent: 10,
scale: 1.08,
ease: 'none',
scrollTrigger: { trigger: '.oc-v2-field-collage', start: 'top bottom', end: 'bottom top', scrub: 0.8 },
});
gsap.from('.oc-v2-local-media img:first-child', {
clipPath: 'inset(0 0 100% 0)',
scale: 1.1,
duration: 1.25,
ease: 'power4.out',
scrollTrigger: { trigger: '.oc-v2-local', start: 'top 72%', once: true },
});
gsap.from('.oc-v2-local-media img:last-child', {
x: 70,
y: 60,
rotate: 2,
autoAlpha: 0,
duration: 0.95,
ease: 'power3.out',
scrollTrigger: { trigger: '.oc-v2-local', start: 'top 65%', once: true },
});
gsap.from('.oc-v2-local-copy > *', {
y: 52,
autoAlpha: 0,
duration: 0.78,
stagger: 0.09,
ease: 'power3.out',
scrollTrigger: { trigger: '.oc-v2-local-copy', start: 'top 74%', once: true },
});
gsap.from('.oc-v2-final > div > *', {
y: 66,
autoAlpha: 0,
duration: 0.9,
stagger: 0.13,
ease: 'power3.out',
scrollTrigger: { trigger: '.oc-v2-final', start: 'top 66%', once: true },
});
gsap.fromTo('.oc-v2-final > img', { scale: 1.06 }, {
scale: 1.16,
ease: 'none',
scrollTrigger: { trigger: '.oc-v2-final', start: 'top bottom', end: 'bottom top', scrub: 0.9 },
});
},
{ scope: editorialRef, dependencies: [language], revertOnUpdate: true },
);
return (
<main ref={editorialRef} className="oc-home-v2" data-no-translate>
<section className="oc-v2-hero" aria-labelledby="v2-hero-title">
<img src={asset(home.hero.imageUrl)} alt={pickText('贵州喀斯特山野中的万趣私家旅行', 'A private WanderQ journey in the karst landscape of Guizhou', language)} />
<div className="oc-v2-hero-shade" aria-hidden="true" />
<div className="oc-v2-hero-copy">
<p>{pickText('贵州,中国西南 · 私家旅行', 'Guizhou, Southwest China · Private travel', language)}</p>
<h1 id="v2-hero-title">
{pickText('大地,', 'Earth', language)}<br />
<em>{pickText('邀请你走近。', 'invites you closer.', language)}</em>
</h1>
<div className="oc-v2-hero-bottom">
<span>{pickText('山水不是背景,生活也不是表演。跟随真正生活在这里的人,去往贵州更深处。', 'Landscapes are not a backdrop, and local life is not a performance. Travel deeper with people who live here.', language)}</span>
<a href="/contact/">{pickText('设计我的旅程', 'Design my journey', language)} <ArrowRight size={18} aria-hidden="true" /></a>
</div>
</div>
<a className="oc-v2-hero-scroll" href="#v2-discover" aria-label={pickText('向下探索', 'Scroll to discover', language)}>
<ArrowRight size={20} weight="light" aria-hidden="true" />
</a>
</section>
<section className="oc-v2-discover" id="v2-discover" aria-labelledby="v2-discover-title">
<div className="oc-v2-section-intro">
<span>01 / {pickText('选择一种靠近方式', 'Choose how to get closer', language)}</span>
<div>
<h2 id="v2-discover-title">{pickText('贵州不只有一个入口。', 'There is more than one way into Guizhou.', language)}</h2>
<p>{pickText('从喀斯特山野、村寨日常、水世界或贵州餐桌出发。每一种体验都可以成为一条私家路线的起点。', 'Begin with wild karst, village life, water worlds or the local table. Each can become the first chapter of a private route.', language)}</p>
</div>
</div>
<div className="oc-v2-experience-grid">
{editorialExperiences.map((item, index) => (
<a className={`oc-v2-experience-card is-${index + 1}`} href={item.href} key={item.number}>
<img src={item.image} alt={item.title} />
<span>{item.number}</span>
<div><small>{item.eyebrow}</small><h3>{item.title}</h3></div>
<ArrowRight size={20} aria-hidden="true" />
</a>
))}
</div>
</section>
<section className="oc-v2-feature" aria-labelledby="v2-feature-title">
<div className="oc-v2-feature-image">
<img src="/client-assets/brand-real-guizhou.webp" alt={pickText('贵州村寨真实生活', 'Everyday life in a Guizhou village', language)} />
<span>{pickText('贵州 · 黔东南', 'Southeast Guizhou', language)}</span>
</div>
<div className="oc-v2-feature-copy">
<span>02 / {pickText('本期故事', 'Featured story', language)}</span>
<h2 id="v2-feature-title">{pickText('去一个地方,也理解一个地方。', 'Go somewhere. Understand it, too.', language)}</h2>
<p>{pickText('在村寨里留下一晚,在家常饭桌上多坐一会,听懂一门手艺和一栋木楼背后的生活。我们把“看见”变成真正的相遇。', 'Stay a night in the village. Linger at the family table. Understand the life behind a craft and a timber home. We turn seeing into meeting.', language)}</p>
<a href="/experiences/village-immersion/">{pickText('阅读村寨故事', 'Read the village story', language)} <ArrowRight size={16} aria-hidden="true" /></a>
<div className="oc-v2-feature-facts">
<div><b>100%</b><span>{pickText('私家定制', 'private planning', language)}</span></div>
<div><b>24/7</b><span>{pickText('在地协调', 'local support', language)}</span></div>
<div><b>EN / </b><span>{pickText('双语支持', 'bilingual support', language)}</span></div>
</div>
</div>
</section>
<section className="oc-v2-routes" aria-labelledby="v2-routes-title">
<div className="oc-v2-section-intro is-light">
<span>03 / {pickText('旅行灵感', 'Journey inspiration', language)}</span>
<div><h2 id="v2-routes-title">{pickText('三条路线,都是讨论的开始。', 'Three routes. Each starts a conversation.', language)}</h2><p>{pickText('先选一个接近你的方向,再按日期、兴趣、体力和住宿偏好重新编排。', 'Choose the direction closest to you, then reshape it around dates, interests, energy and stays.', language)}</p></div>
</div>
<div className="oc-v2-route-grid">
{editorialRoutes.map((route, index) => (
<a href={resolveMergedExperienceHref(route.href)} className={`oc-v2-route-card is-${index + 1}`} key={route.id}>
<img src={asset(route.imageUrl)} alt={oc(route.title, language)} />
<div><span>{String(index + 1).padStart(2, '0')} · {oc(route.nights, language)}</span><h3>{oc(route.title, language)}</h3><p>{oc(route.copy, language)}</p><b>{pickText('打开路线', 'Open journey', language)} <ArrowRight size={15} aria-hidden="true" /></b></div>
</a>
))}
</div>
</section>
<section className="oc-v2-field" aria-labelledby="v2-field-title">
<div className="oc-v2-field-heading"><span>04 / {pickText('来自现场', 'From the field', language)}</span><h2 id="v2-field-title">{pickText('真实旅行,没有摆拍的模板。', 'Real journeys. No staged template.', language)}</h2></div>
<div className="oc-v2-field-collage">
{fieldImages.map((image, index) => <figure className={`is-${index + 1}`} key={image}><img src={image} alt={pickText(`贵州旅行现场 ${index + 1}`, `Guizhou journey moment ${index + 1}`, language)} />{index === 0 ? <figcaption>{pickText('万趣本地团队,在贵州。', 'The WanderQ team, here in Guizhou.', language)}</figcaption> : null}</figure>)}
<div className="oc-v2-field-note"><PlayCircle size={52} weight="thin" aria-hidden="true" /><p>{pickText('一顿饭、一条山路、一场手作,也可能是旅程里最久被记住的部分。', 'A meal, a mountain road or time at the craft table can become the longest-held memory.', language)}</p></div>
</div>
</section>
<section className="oc-v2-local" aria-labelledby="v2-local-title">
<div className="oc-v2-local-media"><img src="/client-assets/team-wanderq-group.webp" alt={pickText('万趣贵州本地团队', 'The Guizhou-based WanderQ team', language)} /><img src="/client-assets/team-field-day.webp" alt={pickText('万趣团队旅行现场', 'WanderQ team in the field', language)} /></div>
<div className="oc-v2-local-copy"><span>05 / {pickText('为什么是万趣', 'Why WanderQ', language)}</span><h2 id="v2-local-title">{pickText('离现场近一点,旅程就从容一点。', 'Closer to the field. Calmer on the road.', language)}</h2><p>{pickText('我们在贵州本地规划与执行。熟悉山路、天气、水位与村寨节奏,也理解境外客人需要怎样清楚、可靠的英文旅行支持。', 'We plan and operate from Guizhou—close to the roads, weather, water and village rhythms, with clear English-language support for international guests.', language)}</p><ul><li>{pickText('一组客人,一套私家方案', 'One private plan for one party', language)}</li><li>{pickText('合规入境接待与透明报价', 'Compliant inbound reception and clear pricing', language)}</li><li>{pickText('行程期间 24 小时在地协调', '24-hour local coordination while travelling', language)}</li></ul><a href="/our-story/">{pickText('认识本地团队', 'Meet the local team', language)} <ArrowRight size={16} aria-hidden="true" /></a></div>
</section>
<section className="oc-v2-final" aria-labelledby="v2-final-title">
<img src="/client-assets/ancient-towns-zhenyuan-night.jpg" alt={pickText('贵州镇远古城夜景', 'Zhenyuan ancient town at night', language)} />
<div><span>{pickText('下一段旅程,从一场对话开始。', 'Your next journey starts with a conversation.', language)}</span><h2 id="v2-final-title">{pickText('贵州,等你走进。', 'Guizhou is waiting.', language)}</h2><a href="/contact/">{pickText('开始规划', 'Start planning', language)} <ArrowRight size={18} aria-hidden="true" /></a></div>
</section>
</main>
);
}
function Header({
language,
menuOpen,
@@ -2687,19 +2418,17 @@ function SearchOverlay({ onClose }: { onClose: () => void }) {
);
}
function HomePage({ variant = 'v1' }: { variant?: 'classic' | 'v1' }) {
function HomePage() {
const { content, language } = useTravelSite();
const prototypeRef = useRef<HTMLElement | null>(null);
const home = content.home;
const heroSlides = useMemo(
() => variant === 'v1'
? [
'/client-assets/atlas-hero-waterfall.webp',
'/client-assets/hero-real-travelers.webp',
'/client-assets/hero-miao-home-meal.webp',
]
: [home.hero.imageUrl, ...home.hero.awardUrls].filter(Boolean),
[home.hero.awardUrls, home.hero.imageUrl, variant],
() => [
'/client-assets/atlas-hero-waterfall.webp',
'/client-assets/hero-real-travelers.webp',
'/client-assets/hero-miao-home-meal.webp',
],
[],
);
const [heroIndex, setHeroIndex] = useState(0);
const [heroPaused, setHeroPaused] = useState(false);
@@ -2707,7 +2436,6 @@ function HomePage({ variant = 'v1' }: { variant?: 'classic' | 'v1' }) {
useGSAP(
() => {
if (variant === 'classic') return;
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
const heroTimeline = gsap.timeline({ defaults: { ease: 'power3.out' } });
@@ -2759,7 +2487,7 @@ function HomePage({ variant = 'v1' }: { variant?: 'classic' | 'v1' }) {
scrollTrigger: { trigger: '.oc-atlas-plan', start: 'top 72%', once: true },
});
},
{ scope: prototypeRef, dependencies: [language, variant], revertOnUpdate: true },
{ scope: prototypeRef, dependencies: [language], revertOnUpdate: true },
);
useEffect(() => {
@@ -2770,29 +2498,6 @@ function HomePage({ variant = 'v1' }: { variant?: 'classic' | 'v1' }) {
return () => window.clearInterval(timer);
}, [heroPaused, heroSlides.length]);
const trustSignals = [
{
icon: MapPin,
title: pickText('贵州本地团队', 'Guizhou-based team', language),
copy: pickText('熟悉山路、天气与在地节奏', 'Local knowledge of roads, weather and daily rhythms', language),
},
{
icon: UsersThree,
title: pickText('纯玩私家小团', 'Private journeys only', language),
copy: pickText('按人数、兴趣与节奏定制', 'Designed around your people, interests and pace', language),
},
{
icon: Globe,
title: pickText('英文旅行支持', 'English trip support', language),
copy: pickText('双语沟通与文化说明', 'Bilingual planning and cultural context', language),
},
{
icon: Headset,
title: pickText('24 小时在地支持', '24/7 on-ground support', language),
copy: pickText('行程期间持续响应与协调', 'Responsive coordination throughout your journey', language),
},
];
const prototypeJourneySteps = [
{
number: '01',
@@ -2811,134 +2516,9 @@ function HomePage({ variant = 'v1' }: { variant?: 'classic' | 'v1' }) {
},
];
const brandValues = [
{
number: '01',
title: pickText('合规入境接待', 'Compliant inbound reception', language),
copy: pickText('为境外游客提供清晰、正规的入境接待流程。', 'A clear, compliant reception process for international travelers.', language),
},
{
number: '02',
title: pickText('懂贵州,也会讲贵州', 'Local stories, not scripts', language),
copy: pickText('讲清这里的文化与生活,不做背书式流水线导游。', 'Guizhou specialists who explain the culture, not a memorized script.', language),
},
{
number: '03',
title: pickText('熟悉山路与天气', 'Locals who know the road', language),
copy: pickText('熟悉贵州山路、天气与现场变化,及时响应。', 'Local knowledge of mountain roads, weather and changing conditions.', language),
},
{
number: '04',
title: pickText('不赶场的真实旅行', 'A slower, more human pace', language),
copy: pickText('拒绝赶场式打卡,把时间留给山水、村寨与真实生活。', 'No checklist travel—more time for landscapes, villages and daily life.', language),
},
{
number: '05',
title: pickText('一人一行程,价格透明', 'One journey, clearly priced', language),
copy: pickText('按你的兴趣与节奏设计行程,清楚说明价格与服务。', 'A private itinerary shaped around you, with pricing explained clearly.', language),
},
];
const inquiryPrompts = [
{
number: '01',
title: pickText('什么时候,和谁一起', 'When, and with whom', language),
copy: pickText('大致日期和同行人数就够了,不需要现在完全确定。', 'Rough dates and party size are enough. Nothing needs to be fixed yet.', language),
},
{
number: '02',
title: pickText('你为什么想来贵州', 'Why Guizhou', language),
copy: pickText('户外、山水、村寨、人文或美食,告诉我们你最在意的部分。', 'Adventure, landscapes, villages, culture, or food—tell us what matters most.', language),
},
{
number: '03',
title: pickText('怎样的节奏最适合你', 'How you like to travel', language),
copy: pickText('轻松一些、充实一些,或者两者之间,再加上你的住宿期待。', 'Easy days, fuller days, or a mix—plus the kind of stays that feel right.', language),
},
];
return (
<main ref={prototypeRef} className={variant === 'v1' ? 'oc-home-atlas' : 'oc-home-classic'} data-no-translate>
{variant === 'classic' ? (
<>
<section className="oc-home-hero">
<img
key={activeHero}
className="oc-hero-media"
src={asset(activeHero)}
alt={language === 'zh' ? '万趣贵州私家旅行现场' : 'A private WanderQ journey in Guizhou'}
/>
{home.hero.tripAdvisorUrl ? <img className="oc-trip" src={asset(home.hero.tripAdvisorUrl)} alt="Tripadvisor" /> : null}
<div className="oc-hero-copy">
<p>{oc(home.hero.kicker, language)}</p>
<h1>{oc(home.hero.title, language)}</h1>
<p className="oc-hero-summary">
{pickText('越过景点清单,跟随本地人走进山水、村寨与真实生活。', 'Go beyond the sights with local people, landscapes and everyday life.', language)}
</p>
<a className="oc-orange-btn" href={home.hero.ctaHref}>
{oc(home.hero.ctaLabel, language)}
<ArrowRight size={18} aria-hidden="true" />
</a>
<div className="oc-hero-dots" aria-label={language === 'zh' ? '首屏图片轮播控制' : 'Hero slideshow controls'}>
{heroSlides.map((slide, index) => (
<button
type="button"
className={`oc-hero-dot${index === heroIndex ? ' is-active' : ''}`}
aria-label={language === 'zh' ? `查看第 ${index + 1} 张首屏图` : `Show hero slide ${index + 1}`}
aria-current={index === heroIndex ? 'true' : undefined}
onClick={() => setHeroIndex(index)}
key={slide}
/>
))}
<button
type="button"
className="oc-hero-playback"
aria-label={heroPaused ? (language === 'zh' ? '继续轮播' : 'Resume slideshow') : (language === 'zh' ? '暂停轮播' : 'Pause slideshow')}
onClick={() => setHeroPaused((current) => !current)}
>
{heroPaused ? <PlayCircle size={22} weight="light" aria-hidden="true" /> : <PauseCircle size={22} weight="light" aria-hidden="true" />}
</button>
</div>
</div>
</section>
<section className="oc-home-trust" aria-label={language === 'zh' ? '万趣服务保障' : 'WanderQ service assurances'}>
<div className="oc-container oc-home-trust-grid">
{trustSignals.map(({ icon: Icon, title, copy }) => (
<article className="oc-home-trust-item" key={title}>
<Icon size={25} weight="light" aria-hidden="true" />
<div><strong>{title}</strong><span>{copy}</span></div>
</article>
))}
</div>
</section>
<section className="oc-home-brand-story" aria-labelledby="home-brand-story-title">
<div className="oc-container">
<div className="oc-brand-story-layout">
<figure className="oc-brand-story-media">
<img src="/client-assets/brand-real-guizhou.webp" alt={language === 'zh' ? '贵州村寨中的真实生活' : 'Everyday life in a Guizhou village'} />
</figure>
<div className="oc-brand-story-copy">
<span className="oc-brand-eyebrow">{language === 'zh' ? '为什么选择万趣' : 'Why WanderQ'}</span>
<h2 id="home-brand-story-title">{pickText('越过旅行泡泡,走进真实贵州', 'Travel beyond the bubble.', language)}</h2>
<p>{pickText('万趣的核心不是“售卖旅游产品”,而是创造能够改变人与地方关系的旅行体验。我们拒绝景点清单式打卡,让旅行者真正靠近贵州的山水、日常生活与当地人。', 'WanderQ is not here to sell a checklist of sights. We create private journeys that bring you closer to the landscapes, everyday life and people of Guizhou.', language)}</p>
<blockquote>{pickText('“把脚步留给山风、瀑声与村寨灯火,其余的交给我们。”', '“Leave your footsteps to mountain winds, waterfalls and village lights. Leave the rest to us.”', language)}</blockquote>
</div>
</div>
<div className="oc-brand-values" aria-label={language === 'zh' ? '万趣核心价值' : 'WanderQ core values'}>
{brandValues.map((value) => (
<article className="oc-brand-value" key={value.number}>
<span>{value.number}</span><h3>{value.title}</h3><p>{value.copy}</p>
</article>
))}
</div>
</div>
</section>
</>
) : (
<>
<section className="oc-atlas-hero" aria-labelledby="atlas-hero-title">
<main ref={prototypeRef} className="oc-home-atlas" data-no-translate>
<section className="oc-atlas-hero" aria-labelledby="atlas-hero-title">
<div className="oc-atlas-hero-copy">
<p className="oc-atlas-coordinate">26°0329°13 N&nbsp;&nbsp;&nbsp;103°36109°35 E</p>
<h1 id="atlas-hero-title">
@@ -3062,11 +2642,6 @@ function HomePage({ variant = 'v1' }: { variant?: 'classic' | 'v1' }) {
</figure>
</section>
</>
)}
{variant === 'v1' && (
<>
<section className="oc-atlas-team" aria-labelledby="atlas-team-title">
<div className="oc-atlas-team-copy oc-atlas-reveal">
<p>{pickText('扎根贵州 · 面向世界', 'LOCAL ROOTS, GLOBAL STANDARDS', language)}</p>
@@ -3101,98 +2676,6 @@ function HomePage({ variant = 'v1' }: { variant?: 'classic' | 'v1' }) {
<small>{pickText('双语沟通 · 私家定制 · 本地支持', 'Bilingual planning · Private travel · Local support', language)}</small>
</address>
</section>
</>
)}
<section className="oc-home-team oc-container" id="about-advantages" aria-labelledby="home-team-title">
<div className="oc-home-team-layout">
<div className="oc-home-team-media">
<img
className="oc-home-team-main-image"
src="/client-assets/team-field-day.webp"
alt={language === 'zh' ? '贵州户外旅行现场的万趣团队与客人' : 'WanderQ team and guests during an outdoor day in Guizhou'}
/>
<img
className="oc-home-team-field-image"
src="/client-assets/team-wanderq-group.webp"
alt={language === 'zh' ? '万趣团队与旅行行业伙伴' : 'WanderQ team with travel-industry partners'}
/>
</div>
<div className="oc-home-team-copy">
<span className="oc-brand-eyebrow">{language === 'zh' ? '贵州本地团队' : 'Guizhou-based team'}</span>
<h2 id="home-team-title">{oc(home.journey.title, language)}</h2>
<p className="oc-home-team-intro">
{pickText(
'我们在贵州本地判断路线、沟通现场并照应行程。山路、天气、语言和临时变化,不需要你独自面对。',
'We judge routes, coordinate the field, and support each journey from Guizhou—so mountain roads, weather, language, and last-minute changes are never yours to handle alone.',
language,
)}
</p>
<div className="oc-home-team-services">
{home.journey.cards.map((item, index) => (
<article className="oc-home-team-service" key={item.id}>
<span>{String(index + 1).padStart(2, '0')}</span>
<div>
<h3>{oc(item.title, language)}</h3>
<p>{oc(item.copy, language)}</p>
</div>
</article>
))}
</div>
<a className="oc-outline-btn oc-home-team-cta" href="/contact/">
{language === 'zh' ? '和本地团队聊聊' : 'Talk with our local team'}
<ArrowRight size={18} aria-hidden="true" />
</a>
</div>
</div>
</section>
<section className="oc-home-final-cta" aria-labelledby="home-final-cta-title">
<div className="oc-container oc-home-final-cta-layout">
<div className="oc-home-final-cta-copy">
<span className="oc-home-final-eyebrow">{oc(content.footerCta.eyebrowLabel, language)}</span>
<h2 id="home-final-cta-title">
{language === 'zh' ? (
<><br /><em></em></>
) : (
<>Start with what<br /><em>matters to you.</em></>
)}
</h2>
<p>
{pickText(
'大致日期就够了。告诉我们谁会同行,以及你最想感受的贵州。本地团队会把这些信息整理成一个清楚的旅行方向。',
'Rough dates are enough. Tell us who is traveling and the part of Guizhou you most want to feel. Our local team will shape that into one clear journey direction.',
language,
)}
</p>
<a className="oc-orange-btn oc-home-final-cta-button" href={content.footerCta.href}>
{pickText('告诉我们你的大致想法', 'Share my rough plan', language)}
<ArrowRight size={18} aria-hidden="true" />
</a>
<small className="oc-home-final-cta-note">
{pickText('不需要固定行程 · 直接和贵州本地团队沟通', 'No fixed itinerary needed · Direct conversation with our Guizhou team', language)}
</small>
</div>
<div className="oc-home-inquiry-prompts" aria-label={language === 'zh' ? '咨询时可以提供的信息' : 'Helpful details for your inquiry'}>
<span className="oc-home-inquiry-prompts-label">
{pickText('开始时,这三件事就够了', 'Three things are enough to begin', language)}
</span>
{inquiryPrompts.map((prompt) => (
<article className="oc-home-inquiry-prompt" key={prompt.number}>
<span>{prompt.number}</span>
<div>
<h3>{prompt.title}</h3>
<p>{prompt.copy}</p>
</div>
</article>
))}
</div>
</div>
</section>
</main>
);
}

View File

@@ -941,23 +941,6 @@ body:has(.oc-home-atlas) .oc-footer-legal-meta {
body:has(.oc-home-atlas) .oc-header-actions { grid-column: 2; }
body:has(.oc-home-atlas) .oc-header-cta { display: none; }
.oc-atlas-hero {
grid-template-columns: 1fr 54px;
grid-template-rows: auto minmax(480px, 62svh) 48px;
}
.oc-atlas-hero-copy {
grid-column: 1;
padding: 54px 38px 48px;
}
.oc-atlas-hero-media { grid-column: 1; grid-row: 2; }
.oc-atlas-stamp { grid-column: 2; grid-row: 1 / 3; }
.oc-atlas-hero-rail { grid-row: 3; }
.oc-atlas-hero-rail > span:nth-child(2),
.oc-atlas-hero-rail > span:nth-child(3) { display: none; }
.oc-atlas-hero-rail { grid-template-columns: 1fr auto; }
.oc-atlas-experience-stage {
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 18px;
@@ -1008,6 +991,27 @@ body:has(.oc-home-atlas) .oc-footer-legal-meta {
.oc-atlas-contact small { width: 100%; }
}
@media (max-width: 700px) {
.oc-atlas-hero {
grid-template-columns: 1fr 54px;
grid-template-rows: auto minmax(480px, 62svh) 48px;
}
.oc-atlas-hero-copy {
grid-column: 1;
padding: 54px 38px 48px;
}
.oc-atlas-hero-media { grid-column: 1; grid-row: 2; }
.oc-atlas-stamp { grid-column: 2; grid-row: 1 / 3; }
.oc-atlas-hero-rail {
grid-row: 3;
grid-template-columns: 1fr auto;
}
.oc-atlas-hero-rail > span:nth-child(2),
.oc-atlas-hero-rail > span:nth-child(3) { display: none; }
}
@media (max-width: 620px) {
body:has(.oc-home-atlas) .oc-header { padding-inline: 18px; }
body:has(.oc-home-atlas) .oc-logo img { width: 116px; }

View File

@@ -28,10 +28,6 @@
transform: translateY(-2px);
}
.oc-home-v1 .oc-outline-btn,
.oc-home-v1 .oc-home-final-cta .oc-orange-btn {
border-radius: 999px;
}
/* Shared framed content receives one calm, consistent surface treatment. */
.oc-site :is(
@@ -55,78 +51,6 @@
overflow: hidden;
}
/* Homepage: remove the long pauses between the five core story beats. */
.oc-home-v1 .oc-home-experiences {
margin-top: 0;
padding-top: clamp(56px, 4.8vw, 72px);
padding-bottom: clamp(62px, 5.4vw, 82px);
}
.oc-home-v1 .oc-home-experiences .oc-section-title {
margin-bottom: 32px;
}
.oc-home-v1 .oc-experience-stack {
gap: clamp(14px, 1.45vw, 24px);
}
.oc-home-v1 .oc-experience-band {
height: 620px;
min-height: 620px;
grid-template-rows: 342px 278px;
border-radius: var(--oc-card-radius-lg);
box-shadow: var(--oc-card-shadow);
}
.oc-home-v1 .oc-experience-band:hover {
box-shadow: var(--oc-card-shadow-hover);
}
.oc-home-v1 .oc-home-experiences > .oc-center {
margin-top: 30px;
}
.oc-prototype-story {
column-gap: clamp(54px, 6vw, 92px);
padding-top: clamp(64px, 5.2vw, 78px);
padding-bottom: clamp(64px, 5vw, 76px);
}
.oc-prototype-story-image {
min-height: 660px;
border-radius: var(--oc-card-radius-lg);
}
.oc-home-v1 .oc-home-team {
padding-top: clamp(68px, 5.6vw, 84px);
padding-bottom: clamp(72px, 5.8vw, 88px);
}
.oc-home-v1 .oc-home-team-layout {
gap: clamp(46px, 5.5vw, 82px);
}
.oc-home-v1 .oc-home-team-media {
min-height: 610px;
}
.oc-home-v1 .oc-home-team-main-image {
height: 540px;
border-radius: var(--oc-card-radius-lg);
}
.oc-home-v1 .oc-home-team-field-image {
height: 210px;
border-radius: 16px;
}
.oc-home-v1 .oc-home-final-cta {
padding-block: clamp(78px, 6.4vw, 98px);
}
.oc-home-v1 .oc-home-final-cta-layout {
gap: clamp(52px, 6vw, 88px);
}
/* Experience archive: create distinct cards instead of one rigid tiled wall. */
.oc-experience-editorial .oc-menu-page-hero {
@@ -286,24 +210,6 @@
}
@media (max-width: 820px) {
.oc-home-v1 .oc-home-experiences {
padding-top: 58px;
padding-bottom: 62px;
}
.oc-home-v1 .oc-experience-stack {
gap: 18px;
}
.oc-home-v1 .oc-experience-band {
height: auto;
min-height: 390px;
}
.oc-home-v1 .oc-home-team {
padding-top: 62px;
padding-bottom: 68px;
}
.oc-experience-series-nav {
padding-bottom: 62px;
@@ -336,49 +242,6 @@
padding-inline: 21px;
}
.oc-home-v1 .oc-home-experiences {
padding-top: 50px;
padding-bottom: 54px;
}
.oc-home-v1 .oc-home-experiences .oc-section-title {
margin-bottom: 28px;
}
.oc-home-v1 .oc-home-experiences > .oc-center {
margin-top: 24px;
}
.oc-prototype-story {
padding-top: 52px;
padding-bottom: 58px;
}
.oc-prototype-story-image {
min-height: 410px;
margin-bottom: 42px;
}
.oc-home-v1 .oc-home-team {
padding-top: 54px;
padding-bottom: 60px;
}
.oc-home-v1 .oc-home-team-layout {
gap: 38px;
}
.oc-home-v1 .oc-home-team-media {
min-height: 410px;
}
.oc-home-v1 .oc-home-team-main-image {
height: 330px;
}
.oc-home-v1 .oc-home-final-cta {
padding-block: 62px 66px;
}
.oc-experience-editorial .oc-menu-page-hero {
padding-bottom: 80px;