Restore home lifestyle/voices with i18n and polish about/static CTAs.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
eric 2026-09-04 09:48:20 -05:00
parent ab9d8f6670
commit 863643aa33
8 changed files with 346 additions and 164 deletions

View File

@ -1,62 +1,11 @@
import Link from "next/link";
import type { Metadata } from "next"; import type { Metadata } from "next";
import SiteShell from "@/components/SiteShell"; import AboutClient from "@/components/AboutClient";
export const metadata: Metadata = { export const metadata: Metadata = {
title: "关于 nomadro", title: "关于 nomadro · About",
description: "nomadro —— 用一行代码环游世界,数字游民旅居指南", description: "nomadro —— 用一行代码环游世界,数字游民旅居指南",
}; };
export default function AboutPage() { export default function AboutPage() {
return ( return <AboutClient />;
<SiteShell>
<div className="legal-page about-page">
<nav className="detail-nav">
<Link href="/">← 返回首页</Link>
</nav>
<article className="legal-content">
<span className="section-tag">🌏 ABOUT</span>
<h1>关于 nomadro</h1>
<p className="legal-updated">用一行代码环游世界</p>
<section>
<h2>我们是谁</h2>
<p>
nomadro 是一个面向数字游民的旅居决策平台。我们把目的地数据、签证信息、费用估算、时区协作与社区经验集中在一起,帮你更快做出「下一站去哪」的决定。
</p>
</section>
<section>
<h2>能做什么</h2>
<ul className="about-list">
<li>🗺️ 探索全球热门游民城市与对比工具</li>
<li>🧮 计算生活成本、机票与启动金目标</li>
<li>📋 签证匹配、保险与上网方案参考</li>
<li>🗓️ 规划多城行程并分享给伙伴</li>
<li>🗣️ 落地短语、行李清单与活动日历</li>
</ul>
</section>
<section>
<h2>联系我们</h2>
<p>
合作与反馈:
<a href="mailto:hello@nomadro.com"> hello@nomadro.com</a>
</p>
<p>
开源仓库:
<a href="https://gitea.dsx2020.com/eric/nomadweb" target="_blank" rel="noopener noreferrer">
gitea.dsx2020.com/eric/nomadweb
</a>
</p>
</section>
<div className="about-actions">
<Link href="/#destinations" className="btn btn-primary">开始探索 🌍</Link>
<Link href="/login" className="btn btn-ghost">加入社区</Link>
</div>
</article>
</div>
</SiteShell>
);
} }

View File

@ -8,6 +8,14 @@ export const metadata: Metadata = {
}; };
const LOGS = [ const LOGS = [
{
date: "2026-09-04",
tag: "首页/关于页",
items: [
"首页恢复「游民一天」与「游民心声」区块,中英文化并直达七天指南/活动/社区",
"关于页改为可切换语言,CTA 指向下一站、社区与旅居计划;静态帮助页主按钮高亮",
],
},
{ {
date: "2026-09-04", date: "2026-09-04",
tag: "学院/博客/社区/电子书", tag: "学院/博客/社区/电子书",

View File

@ -0,0 +1,68 @@
"use client";
import Link from "next/link";
import SiteShell from "@/components/SiteShell";
import { useI18n } from "@/lib/i18n";
export default function AboutClient() {
const { t } = useI18n();
const A = t.aboutPage;
return (
<SiteShell>
<div className="legal-page about-page">
<nav className="detail-nav">
<Link href="/">← {t.common.backHome}</Link>
</nav>
<article className="legal-content">
<span className="section-tag">{A.tag}</span>
<h1>{A.title}</h1>
<p className="legal-updated">{A.subtitle}</p>
<section>
<h2>{A.whoTitle}</h2>
<p>{A.whoBody}</p>
</section>
<section>
<h2>{A.whatTitle}</h2>
<ul className="about-list">
<li>{A.what1}</li>
<li>{A.what2}</li>
<li>{A.what3}</li>
<li>{A.what4}</li>
<li>{A.what5}</li>
</ul>
</section>
<section>
<h2>{A.contactTitle}</h2>
<p>
{A.contactBody}
<a href="mailto:hello@nomadro.com"> hello@nomadro.com</a>
</p>
<p>
{A.repoBody}
<a href="https://gitea.dsx2020.com/eric/nomadweb" target="_blank" rel="noopener noreferrer">
{" "}
gitea.dsx2020.com/eric/nomadweb
</a>
</p>
</section>
<div className="about-actions">
<Link href="/next-stop" className="btn btn-primary">
{A.ctaExplore}
</Link>
<Link href="/community" className="btn btn-ghost">
{A.ctaCommunity}
</Link>
<Link href="/plan" className="btn btn-ghost">
{A.ctaPlan}
</Link>
</div>
</article>
</div>
</SiteShell>
);
}

View File

@ -1,102 +1,97 @@
"use client"; "use client";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { useToast } from "@/lib/toast"; import Link from "next/link";
import { api } from "@/lib/api"; import { useI18n } from "@/lib/i18n";
import NewsletterSubscribe from "@/components/NewsletterSubscribe";
import type { Testimonial } from "@/lib/types"; import type { Testimonial } from "@/lib/types";
export default function Community({ testimonials }: { testimonials: Testimonial[] }) { export default function Community({ testimonials }: { testimonials: Testimonial[] }) {
const { toast } = useToast(); const { t } = useI18n();
const C = t.homeCommunity;
const [active, setActive] = useState(0); const [active, setActive] = useState(0);
const [paused, setPaused] = useState(false); const [paused, setPaused] = useState(false);
useEffect(() => { useEffect(() => {
if (testimonials.length <= 1 || paused) return; if (testimonials.length <= 1 || paused) return;
const t = setInterval(() => setActive((i) => (i + 1) % testimonials.length), 4500); const id = setInterval(() => setActive((i) => (i + 1) % testimonials.length), 4500);
return () => clearInterval(t); return () => clearInterval(id);
}, [testimonials.length, paused]); }, [testimonials.length, paused]);
const handleSubscribe = async (e: React.FormEvent<HTMLFormElement>) => { const cur = testimonials[active];
e.preventDefault();
const form = e.currentTarget;
const email = (form.elements.namedItem("email") as HTMLInputElement).value;
try {
await api.subscribe(email);
toast("订阅成功!欢迎加入 nomadro 社区 🎉");
form.reset();
} catch { /* ignore */ }
};
const t = testimonials[active];
return ( return (
<> <section className="section community" id="voices">
<section className="section community" id="community"> <div className="container">
<div className="container"> <div className="section-header reveal">
<div className="section-header reveal"> <span className="section-tag">{C.tag}</span>
<span className="section-tag">🤝 COMMUNITY</span> <h2>{C.title}</h2>
<h2>游民心声</h2> <p>{C.subtitle}</p>
<p>来自全球数字游民的真实故事</p>
</div>
{t && (
<div
className="testimonial-carousel reveal"
onMouseEnter={() => setPaused(true)}
onMouseLeave={() => setPaused(false)}
>
<div className="testimonial-featured" key={t.id}>
<div className="testimonial-avatar">{t.avatar}</div>
<div className="testimonial-content">
<div className="testimonial-stars">{"⭐".repeat(t.rating)}</div>
<p>&ldquo;{t.content}&rdquo;</p>
<div className="testimonial-author">
<strong>{t.author}</strong>
<span>{t.role}</span>
</div>
</div>
</div>
<div className="testimonial-dots">
{testimonials.map((item, i) => (
<button
key={item.id}
className={`testimonial-dot${i === active ? " active" : ""}`}
onClick={() => setActive(i)}
aria-label={`评价 ${i + 1}`}
/>
))}
</div>
</div>
)}
<div className="testimonials testimonials-grid">
{testimonials.map((item) => (
<div key={item.id} className="testimonial-card reveal">
<div className="testimonial-avatar">{item.avatar}</div>
<div className="testimonial-content">
<div className="testimonial-stars">{"⭐".repeat(item.rating)}</div>
<p>&ldquo;{item.content}&rdquo;</p>
<div className="testimonial-author">
<strong>{item.author}</strong>
<span>{item.role}</span>
</div>
</div>
</div>
))}
</div>
<div className="cta-banner reveal">
<div className="cta-content">
<h2>准备好开始你的旅居之旅了吗? 🌍</h2>
<p>加入 50,000+ 数字游民社区,获取目的地指南、签证攻略与独家优惠</p>
</div>
<form className="cta-form" onSubmit={handleSubscribe}>
<input type="email" name="email" placeholder="输入你的邮箱 📧" required />
<button type="submit" className="btn btn-primary"><span>免费订阅</span><span>🚀</span></button>
</form>
</div>
</div> </div>
</section>
</> {cur && (
<div
className="testimonial-carousel reveal"
onMouseEnter={() => setPaused(true)}
onMouseLeave={() => setPaused(false)}
>
<div className="testimonial-featured" key={cur.id}>
<div className="testimonial-avatar">{cur.avatar}</div>
<div className="testimonial-content">
<div className="testimonial-stars">{"⭐".repeat(cur.rating)}</div>
<p>&ldquo;{cur.content}&rdquo;</p>
<div className="testimonial-author">
<strong>{cur.author}</strong>
<span>{cur.role}</span>
</div>
</div>
</div>
<div className="testimonial-dots">
{testimonials.map((item, i) => (
<button
key={item.id}
type="button"
className={`testimonial-dot${i === active ? " active" : ""}`}
onClick={() => setActive(i)}
aria-label={`${i + 1}`}
/>
))}
</div>
</div>
)}
<div className="testimonials testimonials-grid">
{testimonials.map((item) => (
<div key={item.id} className="testimonial-card reveal">
<div className="testimonial-avatar">{item.avatar}</div>
<div className="testimonial-content">
<div className="testimonial-stars">{"⭐".repeat(item.rating)}</div>
<p>&ldquo;{item.content}&rdquo;</p>
<div className="testimonial-author">
<strong>{item.author}</strong>
<span>{item.role}</span>
</div>
</div>
</div>
))}
</div>
<div className="cta-banner reveal">
<div className="cta-content">
<h2>{C.ctaTitle}</h2>
<p>{C.ctaDesc}</p>
<div className="dating-empty-actions" style={{ marginTop: 12, justifyContent: "flex-start" }}>
<Link href="/community" className="btn btn-primary btn-sm">
{t.nav.community}
</Link>
<Link href="/meetups" className="btn btn-sm">
{t.nav.meetups}
</Link>
</div>
</div>
<NewsletterSubscribe source="home-voices" />
</div>
</div>
</section>
); );
} }

View File

@ -46,6 +46,8 @@ const NomadTips = lazy(() => import("./NomadTips"));
const FeedbackWidget = lazy(() => import("./FeedbackWidget")); const FeedbackWidget = lazy(() => import("./FeedbackWidget"));
const OnboardingTour = lazy(() => import("./OnboardingTour")); const OnboardingTour = lazy(() => import("./OnboardingTour"));
const ToolsStrip = lazy(() => import("./ToolsStrip")); const ToolsStrip = lazy(() => import("./ToolsStrip"));
const Lifestyle = lazy(() => import("./Lifestyle"));
const Community = lazy(() => import("./Community"));
const KeyboardShortcuts = lazy(() => import("./KeyboardShortcuts")); const KeyboardShortcuts = lazy(() => import("./KeyboardShortcuts"));
const PwaInstallHint = lazy(() => import("./PwaInstallHint")); const PwaInstallHint = lazy(() => import("./PwaInstallHint"));
const RecentlyViewed = lazy(() => import("./RecentlyViewed")); const RecentlyViewed = lazy(() => import("./RecentlyViewed"));
@ -166,6 +168,10 @@ export default function HomeClient(props: Props) {
<ToolsStrip /> <ToolsStrip />
</WhenVisible> </WhenVisible>
<WhenVisible minHeight={420}>
<Lifestyle />
</WhenVisible>
<div className="container home-ring-wrap"> <div className="container home-ring-wrap">
<RingNext title={t.ring.continue} steps={rings.afterDiscover} /> <RingNext title={t.ring.continue} steps={rings.afterDiscover} />
</div> </div>
@ -176,6 +182,11 @@ export default function HomeClient(props: Props) {
<WhenVisible minHeight={220}> <WhenVisible minHeight={220}>
<BlogSection posts={props.blog} limit={3} /> <BlogSection posts={props.blog} limit={3} />
</WhenVisible> </WhenVisible>
{props.testimonials.length > 0 && (
<WhenVisible minHeight={320}>
<Community testimonials={props.testimonials} />
</WhenVisible>
)}
<WhenVisible minHeight={200}> <WhenVisible minHeight={200}>
<FAQSection faqs={props.faqs} limit={5} /> <FAQSection faqs={props.faqs} limit={5} />
</WhenVisible> </WhenVisible>

View File

@ -1,41 +1,59 @@
"use client"; "use client";
import { useState } from "react"; import { useState } from "react";
import Link from "next/link";
import { useI18n } from "@/lib/i18n";
const ITEMS = [ const ITEM_KEYS = ["morning", "work", "explore", "collab", "social"] as const;
{ time: "🌅 07:00", icon: "🧘", title: "晨间仪式", desc: "瑜伽、冥想或海边跑步,用身心唤醒开启新的一天", tip: "推荐:清迈河边晨跑、巴厘岛海滩瑜伽" },
{ time: "☕ 09:00", icon: "💻", title: "深度工作", desc: "在 Co-working Space 或咖啡馆专注 4 小时,完成核心任务", tip: "推荐:Punspace 清迈、Outsite 里斯本" },
{ time: "🍜 13:00", icon: "🍽️", title: "本地探索", desc: "品尝地道美食,与当地人交流,感受文化碰撞", tip: "推荐:清迈夜市、巴塞罗那 Tapas 之旅" },
{ time: "🌇 17:00", icon: "📞", title: "跨时区协作", desc: "与全球团队视频会议,灵活安排跨时区沟通", tip: "工具:Calendly 排时区、World Time Buddy" },
{ time: "🌙 20:00", icon: "🎉", title: "社群社交", desc: "参加 Nomad Meetup,结识来自世界各地的同行者", tip: "平台:Nomad List Meetups、Facebook 群组" },
];
export default function Lifestyle() { export default function Lifestyle() {
const { t } = useI18n();
const L = t.lifestyle;
const [active, setActive] = useState(0); const [active, setActive] = useState(0);
const items = ITEM_KEYS.map((key) => ({
key,
time: L[`time_${key}` as keyof typeof L] as string,
icon: L[`icon_${key}` as keyof typeof L] as string,
title: L[`title_${key}` as keyof typeof L] as string,
desc: L[`desc_${key}` as keyof typeof L] as string,
tip: L[`tip_${key}` as keyof typeof L] as string,
}));
const cur = items[active];
return ( return (
<section className="section lifestyle" id="lifestyle"> <section className="section lifestyle" id="lifestyle">
<div className="container"> <div className="container">
<div className="section-header reveal"> <div className="section-header reveal">
<span className="section-tag">💻 NOMAD LIFE</span> <span className="section-tag">{L.tag}</span>
<h2>数字游民的一天</h2> <h2>{L.title}</h2>
<p>自由不等于散漫,高效工作才能尽情探索 — 点击卡片查看详情</p> <p>{L.subtitle}</p>
</div> </div>
<div className="lifestyle-layout reveal"> <div className="lifestyle-layout reveal">
<div className="timeline"> <div className="timeline">
<div className="timeline-line"> <div className="timeline-line">
<svg viewBox="0 0 4 600" preserveAspectRatio="none"> <svg viewBox="0 0 4 600" preserveAspectRatio="none">
<line x1="2" y1="0" x2="2" y2="600" stroke="url(#timelineGrad)" strokeWidth="3" strokeDasharray="8 6" className="timeline-svg-line" /> <line
x1="2"
y1="0"
x2="2"
y2="600"
stroke="url(#timelineGrad)"
strokeWidth="3"
strokeDasharray="8 6"
className="timeline-svg-line"
/>
<defs> <defs>
<linearGradient id="timelineGrad" x1="0" y1="0" x2="0" y2="1"> <linearGradient id="timelineGrad" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stopColor="#FF6B6B" /><stop offset="50%" stopColor="#FFE66D" /><stop offset="100%" stopColor="#4ECDC4" /> <stop offset="0%" stopColor="#FF6B6B" />
<stop offset="50%" stopColor="#FFE66D" />
<stop offset="100%" stopColor="#4ECDC4" />
</linearGradient> </linearGradient>
</defs> </defs>
</svg> </svg>
</div> </div>
{ITEMS.map((item, i) => ( {items.map((item, i) => (
<div <div
key={item.time} key={item.key}
className={`timeline-item${active === i ? " active" : ""}`} className={`timeline-item${active === i ? " active" : ""}`}
onClick={() => setActive(i)} onClick={() => setActive(i)}
role="button" role="button"
@ -54,21 +72,30 @@ export default function Lifestyle() {
<div className="lifestyle-detail"> <div className="lifestyle-detail">
<div className="lifestyle-detail-card"> <div className="lifestyle-detail-card">
<span className="lifestyle-detail-icon">{ITEMS[active].icon}</span> <span className="lifestyle-detail-icon">{cur.icon}</span>
<span className="lifestyle-detail-time">{ITEMS[active].time}</span> <span className="lifestyle-detail-time">{cur.time}</span>
<h3>{ITEMS[active].title}</h3> <h3>{cur.title}</h3>
<p>{ITEMS[active].desc}</p> <p>{cur.desc}</p>
<div className="lifestyle-tip"> <div className="lifestyle-tip">
<span>💡</span> <span>💡</span>
<p>{ITEMS[active].tip}</p> <p>{cur.tip}</p>
</div>
<div className="dating-empty-actions" style={{ marginTop: 16 }}>
<Link href="/digital/day/1" className="btn btn-primary btn-sm">
{L.ctaDay}
</Link>
<Link href="/meetups" className="btn btn-sm">
{L.ctaMeetups}
</Link>
</div> </div>
<div className="lifestyle-dots"> <div className="lifestyle-dots">
{ITEMS.map((_, i) => ( {items.map((item, i) => (
<button <button
key={i} key={item.key}
type="button"
className={`lifestyle-dot${active === i ? " active" : ""}`} className={`lifestyle-dot${active === i ? " active" : ""}`}
onClick={() => setActive(i)} onClick={() => setActive(i)}
aria-label={`第 ${i + 1} 项`} aria-label={`${i + 1}`}
/> />
))} ))}
</div> </div>

View File

@ -1,13 +1,15 @@
"use client"; "use client";
import Link from "next/link"; import Link from "next/link";
import { useI18n } from "@/lib/i18n";
import type { StaticPageDef } from "@/lib/staticPages"; import type { StaticPageDef } from "@/lib/staticPages";
export default function StaticPage({ page }: { page: StaticPageDef }) { export default function StaticPage({ page }: { page: StaticPageDef }) {
const { t } = useI18n();
return ( return (
<div className="legal-page"> <div className="legal-page">
<nav className="detail-nav"> <nav className="detail-nav">
<Link href="/">← 返回首页</Link> <Link href="/">← {t.common.backHome}</Link>
</nav> </nav>
<article className="legal-content reveal"> <article className="legal-content reveal">
<span className="section-tag">{page.tag}</span> <span className="section-tag">{page.tag}</span>
@ -19,15 +21,19 @@ export default function StaticPage({ page }: { page: StaticPageDef }) {
{s.body && <p>{s.body}</p>} {s.body && <p>{s.body}</p>}
{s.list && ( {s.list && (
<ul className="about-list"> <ul className="about-list">
{s.list.map((item) => <li key={item}>{item}</li>)} {s.list.map((item) => (
<li key={item}>{item}</li>
))}
</ul> </ul>
)} )}
</section> </section>
))} ))}
{page.cta && page.cta.length > 0 && ( {page.cta && page.cta.length > 0 && (
<div className="about-actions"> <div className="about-actions">
{page.cta.map((c) => ( {page.cta.map((c, i) => (
<Link key={c.href} href={c.href} className="btn btn-primary">{c.label}</Link> <Link key={c.href} href={c.href} className={`btn${i === 0 ? " btn-primary" : " btn-ghost"}`}>
{c.label}
</Link>
))} ))}
</div> </div>
)} )}

View File

@ -147,6 +147,65 @@ export const zh = {
sortCostDesc: "💰 价格从高到低", sortCostDesc: "💰 价格从高到低",
sortSpeed: "📶 网速排序", sortSpeed: "📶 网速排序",
}, },
lifestyle: {
tag: "💻 NOMAD LIFE",
title: "数字游民的一天",
subtitle: "自由不等于散漫,高效工作才能尽情探索 — 点击卡片查看详情",
ctaDay: "七天落地指南",
ctaMeetups: "去参加活动",
time_morning: "🌅 07:00",
icon_morning: "🧘",
title_morning: "晨间仪式",
desc_morning: "瑜伽、冥想或海边跑步,用身心唤醒开启新的一天",
tip_morning: "推荐:清迈河边晨跑、巴厘岛海滩瑜伽",
time_work: "☕ 09:00",
icon_work: "💻",
title_work: "深度工作",
desc_work: "在 Co-working Space 或咖啡馆专注 4 小时,完成核心任务",
tip_work: "推荐:Punspace 清迈、Outsite 里斯本",
time_explore: "🍜 13:00",
icon_explore: "🍽️",
title_explore: "本地探索",
desc_explore: "品尝地道美食,与当地人交流,感受文化碰撞",
tip_explore: "推荐:清迈夜市、巴塞罗那 Tapas 之旅",
time_collab: "🌇 17:00",
icon_collab: "📞",
title_collab: "跨时区协作",
desc_collab: "与全球团队视频会议,灵活安排跨时区沟通",
tip_collab: "工具:Calendly 排时区、World Time Buddy",
time_social: "🌙 20:00",
icon_social: "🎉",
title_social: "社群社交",
desc_social: "参加 Nomad Meetup,结识来自世界各地的同行者",
tip_social: "平台:nomadro 活动、同城社群",
},
homeCommunity: {
tag: "🤝 COMMUNITY",
title: "游民心声",
subtitle: "来自全球数字游民的真实故事",
ctaTitle: "准备好开始你的旅居之旅了吗?",
ctaDesc: "订阅周报,或直接走进社区与活动",
},
aboutPage: {
tag: "🌏 ABOUT",
title: "关于 nomadro",
subtitle: "用一行代码环游世界",
whoTitle: "我们是谁",
whoBody:
"nomadro 是一个面向数字游民的旅居决策平台。我们把目的地数据、签证信息、费用估算、时区协作与社区经验集中在一起,帮你更快做出「下一站去哪」的决定。",
whatTitle: "能做什么",
what1: "🗺️ 探索全球热门游民城市与对比工具",
what2: "🧮 计算生活成本、机票与启动金目标",
what3: "📋 签证匹配、保险与上网方案参考",
what4: "🗓️ 规划多城行程并分享给伙伴",
what5: "🗣️ 落地短语、行李清单与活动日历",
contactTitle: "联系我们",
contactBody: "合作与反馈:",
repoBody: "开源仓库:",
ctaExplore: "智能下一站",
ctaCommunity: "加入社区",
ctaPlan: "打开计划",
},
common: { common: {
backHome: "← 返回首页", backHome: "← 返回首页",
browseDest: "浏览目的地", browseDest: "浏览目的地",
@ -1483,6 +1542,65 @@ export const en: { [K in keyof typeof zh]: typeof zh[K] extends string ? string
sortCostDesc: "💰 Cost high → low", sortCostDesc: "💰 Cost high → low",
sortSpeed: "📶 Wi‑Fi speed", sortSpeed: "📶 Wi‑Fi speed",
}, },
lifestyle: {
tag: "💻 NOMAD LIFE",
title: "A day in nomad life",
subtitle: "Freedom still needs rhythm — tap a card for detail",
ctaDay: "7-day landing guide",
ctaMeetups: "Find meetups",
time_morning: "🌅 07:00",
icon_morning: "🧘",
title_morning: "Morning ritual",
desc_morning: "Yoga, meditation, or a run by the water to wake body and mind",
tip_morning: "Try: riverside run in Chiang Mai, beach yoga in Bali",
time_work: "☕ 09:00",
icon_work: "💻",
title_work: "Deep work",
desc_work: "Four focused hours in a coworking space or café for core tasks",
tip_work: "Try: Punspace Chiang Mai, Outsite Lisbon",
time_explore: "🍜 13:00",
icon_explore: "🍽️",
title_explore: "Local explore",
desc_explore: "Eat local food, talk to people, feel the culture shift",
tip_explore: "Try: Chiang Mai night market, Barcelona tapas walk",
time_collab: "🌇 17:00",
icon_collab: "📞",
title_collab: "Cross-timezone sync",
desc_collab: "Video with a global team — schedule around the clock",
tip_collab: "Tools: Calendly time zones, World Time Buddy",
time_social: "🌙 20:00",
icon_social: "🎉",
title_social: "Community night",
desc_social: "Join a nomad meetup and meet people from everywhere",
tip_social: "Platforms: nomadro events, local groups",
},
homeCommunity: {
tag: "🤝 COMMUNITY",
title: "Nomad voices",
subtitle: "Real stories from digital nomads worldwide",
ctaTitle: "Ready for your next move?",
ctaDesc: "Subscribe to the weekly brief, or jump into community and events",
},
aboutPage: {
tag: "🌏 ABOUT",
title: "About nomadro",
subtitle: "Travel the world with one line of code",
whoTitle: "Who we are",
whoBody:
"nomadro is a move-decision platform for digital nomads. We bring destination data, visas, cost estimates, timezone collaboration, and community experience into one place so you can decide where to go next faster.",
whatTitle: "What you can do",
what1: "🗺️ Explore top nomad cities and comparison tools",
what2: "🧮 Estimate living costs, flights, and startup runway",
what3: "📋 Visa matching, insurance, and connectivity references",
what4: "🗓️ Plan multi-city trips and share with partners",
what5: "🗣️ Landing phrases, packing lists, and event calendars",
contactTitle: "Contact",
contactBody: "Partnerships & feedback:",
repoBody: "Open source:",
ctaExplore: "Smart next stop",
ctaCommunity: "Join community",
ctaPlan: "Open plan",
},
common: { common: {
backHome: "← Back home", backHome: "← Back home",
browseDest: "Destinations", browseDest: "Destinations",