feat(web): 为 Sleep Heart 官网补上多语言切换

已部署站点需要按访客语言展示导航与协议正文,因此把文案抽到语言包并加上语言选择。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
DESKTOP-L8OUL9F\gfl0034 2026-10-12 01:46:06 +08:00
parent f941bf4454
commit 1bbf3b97c7
19 changed files with 383 additions and 99 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -72,14 +72,78 @@ a { color: var(--cyan); }
flex: 0 0 auto;
}
.top-tools {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px 16px;
margin-inline-start: auto;
max-width: 100%;
}
.nav, .foot-links {
display: flex;
flex-wrap: wrap;
gap: 6px 14px;
margin-left: auto;
max-width: 100%;
}
.foot-links { margin-inline-start: auto; }
.lang-label {
display: flex;
align-items: center;
gap: 6px;
color: var(--muted);
font-size: 0.85rem;
max-width: 100%;
}
.lang-label select {
max-width: 100%;
min-width: 0;
background: #12243d;
color: var(--text);
border: 1px solid var(--line);
border-radius: 999px;
padding: 6px 10px;
font: inherit;
}
.lang-label { display: inline-flex; max-width: 100%; }
.lang-select {
color: var(--text);
background: #12243c;
border: 1px solid var(--line);
border-radius: 999px;
padding: 8px 12px;
font: inherit;
max-width: 100%;
}
.visually-hidden {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
[dir="rtl"] .nav,
[dir="rtl"] .foot-links {
margin-left: 0;
margin-right: auto;
}
[dir="rtl"] .steps li { padding: 10px 46px 10px 10px; }
[dir="rtl"] .steps li::before { left: auto; right: 10px; }
.nav a, .foot-links a {
color: var(--text);
text-decoration: none;
@ -196,9 +260,12 @@ h1 { font-size: clamp(1.7rem, 4vw, 2.4rem); }
.foot strong { color: var(--text); }
.foot p { margin: 4px 0 0; }
[dir="rtl"] .panel ul, [dir="rtl"] .panel ol { padding-left: 0; padding-right: 1.2rem; }
@media (max-width: 800px) {
.grid { grid-template-columns: 1fr; }
.nav, .foot-links { margin-left: 0; width: 100%; }
.top-tools, .foot-links, .lang-label, .nav { margin-inline-start: 0; width: 100%; }
.lang-label select, .lang-select { width: 100%; }
}
@media (max-width: 420px) {

166
health-web/assets/site.js Normal file
View File

@ -0,0 +1,166 @@
(function () {
var CODES = ["zh-Hans", "zh-Hant", "en", "ja", "ko", "es", "fr", "de", "pt", "ru", "ar", "th", "vi", "id", "it"];
var NAMES = {
"zh-Hans": "简体中文",
"zh-Hant": "繁體中文",
en: "English",
ja: "日本語",
ko: "한국어",
es: "Español",
fr: "Français",
de: "Deutsch",
pt: "Português",
ru: "Русский",
ar: "العربية",
th: "ไทย",
vi: "Tiếng Việt",
id: "Bahasa Indonesia",
it: "Italiano"
};
var STORAGE = "sleepheart-lang";
function match(lang) {
var l = (lang || "").toLowerCase().replace(/_/g, "-");
if (l.indexOf("zh") === 0) {
if (l.indexOf("tw") >= 0 || l.indexOf("hk") >= 0 || l.indexOf("mo") >= 0 || l.indexOf("hant") >= 0) return "zh-Hant";
return "zh-Hans";
}
var base = l.split("-")[0];
return CODES.indexOf(base) >= 0 ? base : "";
}
function preferred() {
var saved = "";
try { saved = localStorage.getItem(STORAGE) || ""; } catch (e) {}
if (CODES.indexOf(saved) >= 0) return saved;
var list = navigator.languages || [navigator.language || ""];
for (var i = 0; i < list.length; i++) {
var hit = match(list[i]);
if (hit) return hit;
}
return "zh-Hans";
}
function esc(s) {
return String(s).replace(/[&<>"']/g, function (c) {
return { "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" }[c];
});
}
function repl(s, a, b) { return String(s).split(a).join(b); }
function linkify(s, ui) {
var html = esc(s);
html = repl(html, "{email}", '<a href="mailto:asd272940236@foxmail.com">asd272940236@foxmail.com</a>');
html = repl(html, "{home}", '<a href="/">' + esc(ui.backHome) + "</a>");
html = repl(html, "{delete}", '<a href="/delete">' + esc(ui.navDelete) + "</a>");
html = repl(html, "{privacyDoc}", '<a href="/privacy">' + esc(ui.privacyDoc) + "</a>");
html = repl(html, "{privacy}", '<a href="/privacy">' + esc(ui.navPrivacy) + "</a>");
html = repl(html, "{terms}", '<a href="/terms">' + esc(ui.navTerms) + "</a>");
return html;
}
function renderDoc(blocks, ui) {
var html = "";
var list = "";
function closeList() {
if (!list) return;
html += list === "ol" ? "</ol>" : "</ul>";
list = "";
}
blocks.forEach(function (block) {
var tag = block[0];
var inner = linkify(block[1], ui);
if (tag === "step" || tag === "li") {
var kind = tag === "step" ? "ol" : "ul";
if (list && list !== kind) closeList();
if (!list) {
html += kind === "ol" ? '<ol class="steps">' : "<ul>";
list = kind;
}
html += "<li>" + inner + "</li>";
return;
}
closeList();
if (tag === "meta") html += '<p class="meta">' + inner + "</p>";
else if (tag === "lead") html += '<p class="lead">' + inner + "</p>";
else if (tag === "note") html += '<p class="note">' + inner + "</p>";
else html += "<" + tag + ">" + inner + "</" + tag + ">";
});
closeList();
return html;
}
function apply(pack) {
var page = document.body.getAttribute("data-page") || "home";
var ui = pack.ui;
document.documentElement.lang = pack.htmlLang;
document.documentElement.dir = pack.dir || "ltr";
if (pack.titles && pack.titles[page]) document.title = pack.titles[page];
var desc = document.querySelector('meta[name="description"]');
if (desc && pack.desc && pack.desc[page]) desc.setAttribute("content", pack.desc[page]);
document.querySelectorAll("[data-i18n]").forEach(function (el) {
var key = el.getAttribute("data-i18n");
if (ui[key] == null) return;
if (el.getAttribute("data-i18n-mode") === "html") el.innerHTML = linkify(ui[key], ui);
else el.textContent = ui[key];
});
document.querySelectorAll("[data-i18n-alt]").forEach(function (el) {
var key = el.getAttribute("data-i18n-alt");
if (ui[key] != null) el.setAttribute("alt", ui[key]);
});
var doc = document.getElementById("doc");
if (doc && pack[page]) doc.innerHTML = renderDoc(pack[page], ui);
var select = document.getElementById("lang-select");
if (select) {
select.value = pack.code;
select.setAttribute("aria-label", ui.langLabel);
}
var label = document.querySelector(".lang-label span");
if (label) label.textContent = ui.langLabel;
var nav = document.querySelector(".nav");
if (nav) nav.setAttribute("aria-label", ui.navAria);
var foot = document.querySelector(".foot-links");
if (foot) foot.setAttribute("aria-label", ui.footAria);
}
function load(code) {
if (window.SH_PACKS && window.SH_PACKS[code]) return Promise.resolve(window.SH_PACKS[code]);
return new Promise(function (resolve, reject) {
var s = document.createElement("script");
s.src = "/assets/i18n/" + code + ".js?v=20261011lang";
s.onload = function () {
if (window.SH_PACKS && window.SH_PACKS[code]) resolve(window.SH_PACKS[code]);
else reject(new Error("missing pack"));
};
s.onerror = function () { reject(new Error("load")); };
document.head.appendChild(s);
});
}
function boot() {
var select = document.getElementById("lang-select");
if (select && !select.options.length) {
CODES.forEach(function (code) {
var opt = document.createElement("option");
opt.value = code;
opt.textContent = NAMES[code];
select.appendChild(opt);
});
select.addEventListener("change", function () {
var code = select.value;
try { localStorage.setItem(STORAGE, code); } catch (e) {}
load(code).then(apply).catch(function () {
if (window.SH_PACKS && window.SH_PACKS["zh-Hans"]) apply(window.SH_PACKS["zh-Hans"]);
});
});
}
var code = preferred();
load(code).then(apply).catch(function () {
if (window.SH_PACKS && window.SH_PACKS["zh-Hans"]) apply(window.SH_PACKS["zh-Hans"]);
});
}
if (document.readyState === "loading") document.addEventListener("DOMContentLoaded", boot);
else boot();
})();

View File

@ -6,27 +6,33 @@
<title>注销 — Sleep Heart</title>
<meta name="description" content="Sleep Heart 应用内注销账号的真实入口和实际效果。" />
<link rel="icon" href="/assets/icon.png" type="image/png" />
<link rel="stylesheet" href="/assets/site.css" />
<link rel="stylesheet" href="/assets/site.css?v=20261011lang" />
</head>
<body>
<body data-page="delete">
<header class="top">
<div class="wrap top-inner">
<a class="brand" href="/">
<img src="/assets/icon.png" width="40" height="40" alt="" />
<span>Sleep Heart</span>
</a>
<nav class="nav" aria-label="页面">
<a href="/">首页</a>
<a href="/download">下载</a>
<a href="/delete" aria-current="page">注销</a>
<a href="/privacy">隐私协议</a>
<a href="/terms">用户协议</a>
</nav>
<div class="top-tools">
<nav class="nav" aria-label="页面">
<a href="/" data-i18n="navHome">首页</a>
<a href="/download" data-i18n="navDownload">下载</a>
<a href="/delete" data-i18n="navDelete" aria-current="page">注销</a>
<a href="/privacy" data-i18n="navPrivacy">隐私协议</a>
<a href="/terms" data-i18n="navTerms">用户协议</a>
</nav>
<label class="lang-label">
<span data-i18n="langLabel">语言</span>
<select id="lang-select"></select>
</label>
</div>
</div>
</header>
<main>
<div class="wrap">
<article class="panel">
<article class="panel" id="doc">
<h1>注销账号</h1>
<p class="lead">注销在 Sleep Heart 应用里完成。本网站不提供在线注销表单。</p>
<h2>入口</h2>
@ -55,16 +61,18 @@
<div class="wrap foot-inner">
<div>
<strong>Sleep Heart</strong>
<p>上海微雨如酥网络设计有限公司</p>
<p data-i18n="company">上海微雨如酥网络设计有限公司</p>
</div>
<nav class="foot-links" aria-label="页脚">
<a href="/">首页</a>
<a href="/download">下载</a>
<a href="/delete" aria-current="page">注销</a>
<a href="/privacy">隐私协议</a>
<a href="/terms">用户协议</a>
<a href="/" data-i18n="navHome">首页</a>
<a href="/download" data-i18n="navDownload">下载</a>
<a href="/delete" data-i18n="navDelete" aria-current="page">注销</a>
<a href="/privacy" data-i18n="navPrivacy">隐私协议</a>
<a href="/terms" data-i18n="navTerms">用户协议</a>
</nav>
</div>
</footer>
<script src="/assets/i18n/zh-Hans.js?v=20261011lang"></script>
<script src="/assets/site.js?v=20261011lang"></script>
</body>
</html>

View File

@ -6,27 +6,33 @@
<title>下载 — Sleep Heart</title>
<meta name="description" content="Sleep Heart 下载说明。应用即将上线,此处不放置未核实的应用商店地址。" />
<link rel="icon" href="/assets/icon.png" type="image/png" />
<link rel="stylesheet" href="/assets/site.css" />
<link rel="stylesheet" href="/assets/site.css?v=20261011lang" />
</head>
<body>
<body data-page="download">
<header class="top">
<div class="wrap top-inner">
<a class="brand" href="/">
<img src="/assets/icon.png" width="40" height="40" alt="" />
<span>Sleep Heart</span>
</a>
<nav class="nav" aria-label="页面">
<a href="/">首页</a>
<a href="/download" aria-current="page">下载</a>
<a href="/delete">注销</a>
<a href="/privacy">隐私协议</a>
<a href="/terms">用户协议</a>
</nav>
<div class="top-tools">
<nav class="nav" aria-label="页面">
<a href="/" data-i18n="navHome">首页</a>
<a href="/download" data-i18n="navDownload" aria-current="page">下载</a>
<a href="/delete" data-i18n="navDelete">注销</a>
<a href="/privacy" data-i18n="navPrivacy">隐私协议</a>
<a href="/terms" data-i18n="navTerms">用户协议</a>
</nav>
<label class="lang-label">
<span data-i18n="langLabel">语言</span>
<select id="lang-select"></select>
</label>
</div>
</div>
</header>
<main>
<div class="wrap">
<article class="panel">
<article class="panel" id="doc">
<h1>下载</h1>
<p class="lead">Sleep Heart 是 iPhone 应用,应用内展示名为 SleepHeart。</p>
<p class="note">应用即将上线。目前没有已核实、可以公开打开的 App Store 或安卓应用市场地址,本页不放置商店链接。</p>
@ -39,16 +45,18 @@
<div class="wrap foot-inner">
<div>
<strong>Sleep Heart</strong>
<p>上海微雨如酥网络设计有限公司</p>
<p data-i18n="company">上海微雨如酥网络设计有限公司</p>
</div>
<nav class="foot-links" aria-label="页脚">
<a href="/">首页</a>
<a href="/download" aria-current="page">下载</a>
<a href="/delete">注销</a>
<a href="/privacy">隐私协议</a>
<a href="/terms">用户协议</a>
<a href="/" data-i18n="navHome">首页</a>
<a href="/download" data-i18n="navDownload" aria-current="page">下载</a>
<a href="/delete" data-i18n="navDelete">注销</a>
<a href="/privacy" data-i18n="navPrivacy">隐私协议</a>
<a href="/terms" data-i18n="navTerms">用户协议</a>
</nav>
</div>
</footer>
<script src="/assets/i18n/zh-Hans.js?v=20261011lang"></script>
<script src="/assets/site.js?v=20261011lang"></script>
</body>
</html>

View File

@ -6,66 +6,71 @@
<title>Sleep Heart</title>
<meta name="description" content="Sleep Heart 官网:睡眠声监测、指尖心率估算、助眠音乐与呼吸训练。测量结果仅供个人参考,不是医疗诊断。" />
<link rel="icon" href="/assets/icon.png" type="image/png" />
<link rel="stylesheet" href="/assets/site.css" />
<link rel="stylesheet" href="/assets/site.css?v=20261011lang" />
</head>
<body>
<body data-page="home">
<header class="top">
<div class="wrap top-inner">
<a class="brand" href="/">
<img src="/assets/icon.png" width="40" height="40" alt="" />
<span>Sleep Heart</span>
</a>
<nav class="nav" aria-label="页面">
<a href="/" aria-current="page">首页</a>
<a href="/download">下载</a>
<a href="/delete">注销</a>
<a href="/privacy">隐私协议</a>
<a href="/terms">用户协议</a>
</nav>
<div class="top-tools">
<nav class="nav" aria-label="页面">
<a href="/" data-i18n="navHome" aria-current="page">首页</a>
<a href="/download" data-i18n="navDownload">下载</a>
<a href="/delete" data-i18n="navDelete">注销</a>
<a href="/privacy" data-i18n="navPrivacy">隐私协议</a>
<a href="/terms" data-i18n="navTerms">用户协议</a>
</nav>
<label class="lang-label">
<span data-i18n="langLabel">语言</span>
<select id="lang-select"></select>
</label>
</div>
</div>
</header>
<main>
<div class="wrap">
<section class="hero">
<img src="/assets/icon.png" width="148" height="148" alt="Sleep Heart 图标" />
<img src="/assets/icon.png" width="148" height="148" alt="Sleep Heart 图标" data-i18n-alt="iconAlt" />
<div>
<h1>Sleep Heart</h1>
<p class="lead">在这台 iPhone 上查看夜间声音环境、估算指尖心率,并记下你自己填写的日常健康数字。可以听助眠音乐,按节奏做呼吸练习,登录后也可以在广场发帖。</p>
<p class="lead" data-i18n="lead">在这台 iPhone 上查看夜间声音环境、估算指尖心率,并记下你自己填写的日常健康数字。可以听助眠音乐,按节奏做呼吸练习,登录后也可以在广场发帖。</p>
<div class="actions">
<a class="btn btn-primary" href="/download">下载</a>
<a class="btn btn-ghost" href="/privacy">隐私协议</a>
<a class="btn btn-ghost" href="/terms">用户协议</a>
<a class="btn btn-primary" href="/download" data-i18n="navDownload">下载</a>
<a class="btn btn-ghost" href="/privacy" data-i18n="navPrivacy">隐私协议</a>
<a class="btn btn-ghost" href="/terms" data-i18n="navTerms">用户协议</a>
</div>
<p class="note">测量和监测结果只供个人参考,不是医疗诊断,不能代替血压计、血糖仪、血氧仪、体温计或就医。</p>
<p class="note" data-i18n="note">测量和监测结果只供个人参考,不是医疗诊断,不能代替血压计、血糖仪、血氧仪、体温计或就医。</p>
</div>
</section>
<section class="section">
<h2>可以做什么</h2>
<h2 data-i18n="homeH2">可以做什么</h2>
<div class="grid">
<article class="card">
<h3>音乐</h3>
<p>播放助眠内容。场景包括自然白噪、深度冥想、呼吸疗愈、治愈乐器和脑波音乐。播放方式有顺序、随机、循环和勾选播放。</p>
<h3 data-i18n="musicT">音乐</h3>
<p data-i18n="musicP">播放助眠内容。场景包括自然白噪、深度冥想、呼吸疗愈、治愈乐器和脑波音乐。播放方式有顺序、随机、循环和勾选播放。</p>
</article>
<article class="card">
<h3>心率</h3>
<p>用后置相机和闪光灯做指尖光学估算。画面在本机处理,不会上传。同一页可以手填体重、步数、血压、血糖、经期、血氧、体温和饮水。</p>
<h3 data-i18n="heartT">心率</h3>
<p data-i18n="heartP">用后置相机和闪光灯做指尖光学估算。画面在本机处理,不会上传。同一页可以手填体重、步数、血压、血糖、经期、血氧、体温和饮水。</p>
</article>
<article class="card">
<h3>睡眠</h3>
<p>打开监测后使用麦克风,在本机识别夜间声音并保存可回放的短片段。录音和识别结果只留在这台 iPhone,不会上传。</p>
<h3 data-i18n="sleepT">睡眠</h3>
<p data-i18n="sleepP">打开监测后使用麦克风,在本机识别夜间声音并保存可回放的短片段。录音和识别结果只留在这台 iPhone,不会上传。</p>
</article>
<article class="card">
<h3>发现</h3>
<p>进入广场和呼吸训练。呼吸练习有箱式、4-7-8、舒缓吸呼和共振四种节奏,可以静音,也可以用喜欢的音乐做背景。</p>
<h3 data-i18n="discoverT">发现</h3>
<p data-i18n="discoverP">进入广场和呼吸训练。呼吸练习有箱式、4-7-8、舒缓吸呼和共振四种节奏,可以静音,也可以用喜欢的音乐做背景。</p>
</article>
<article class="card">
<h3>我的</h3>
<p>管理账号、会员、主题、语言和意见反馈。已登录后,注销入口在「设置」里的「账号与安全」。</p>
<h3 data-i18n="profileT">我的</h3>
<p data-i18n="profileP">管理账号、会员、主题、语言和意见反馈。已登录后,注销入口在「设置」里的「账号与安全」。</p>
</article>
<article class="card">
<h3>会员</h3>
<p>会员音频可完整播放并收藏,本地音频导入不限数量,指尖心率测量不限次数。不购买也可以使用免费音频、本机健康记录、睡眠声监测和呼吸训练。</p>
<h3 data-i18n="vipT">会员</h3>
<p data-i18n="vipP">会员音频可完整播放并收藏,本地音频导入不限数量,指尖心率测量不限次数。不购买也可以使用免费音频、本机健康记录、睡眠声监测和呼吸训练。</p>
</article>
</div>
</section>
@ -75,16 +80,18 @@
<div class="wrap foot-inner">
<div>
<strong>Sleep Heart</strong>
<p>上海微雨如酥网络设计有限公司</p>
<p data-i18n="company">上海微雨如酥网络设计有限公司</p>
</div>
<nav class="foot-links" aria-label="页脚">
<a href="/">首页</a>
<a href="/download">下载</a>
<a href="/delete">注销</a>
<a href="/privacy">隐私协议</a>
<a href="/terms">用户协议</a>
<a href="/" data-i18n="navHome">首页</a>
<a href="/download" data-i18n="navDownload">下载</a>
<a href="/delete" data-i18n="navDelete">注销</a>
<a href="/privacy" data-i18n="navPrivacy">隐私协议</a>
<a href="/terms" data-i18n="navTerms">用户协议</a>
</nav>
</div>
</footer>
<script src="/assets/i18n/zh-Hans.js?v=20261011lang"></script>
<script src="/assets/site.js?v=20261011lang"></script>
</body>
</html>

View File

@ -6,27 +6,33 @@
<title>隐私协议 — Sleep Heart</title>
<meta name="description" content="Sleep Heart 软件隐私权政策。上海微雨如酥网络设计有限公司。" />
<link rel="icon" href="/assets/icon.png" type="image/png" />
<link rel="stylesheet" href="/assets/site.css" />
<link rel="stylesheet" href="/assets/site.css?v=20261011lang" />
</head>
<body>
<body data-page="privacy">
<header class="top">
<div class="wrap top-inner">
<a class="brand" href="/">
<img src="/assets/icon.png" width="40" height="40" alt="" />
<span>Sleep Heart</span>
</a>
<nav class="nav" aria-label="页面">
<a href="/">首页</a>
<a href="/download">下载</a>
<a href="/delete">注销</a>
<a href="/privacy" aria-current="page">隐私协议</a>
<a href="/terms">用户协议</a>
<div class="top-tools">
<nav class="nav" aria-label="页面">
<a href="/" data-i18n="navHome">首页</a>
<a href="/download" data-i18n="navDownload">下载</a>
<a href="/delete" data-i18n="navDelete">注销</a>
<a href="/privacy" data-i18n="navPrivacy" aria-current="page">隐私协议</a>
<a href="/terms" data-i18n="navTerms">用户协议</a>
</nav>
<label class="lang-label">
<span data-i18n="langLabel">语言</span>
<select id="lang-select"></select>
</label>
</div>
</div>
</header>
<main>
<div class="wrap">
<article class="panel">
<article class="panel" id="doc">
<h1>Sleep Heart 软件隐私权政策</h1>
<p class="meta">适用于 Sleep Heart 网站(health.wyrs365.com)及 Sleep Heart 应用。</p>
<p>上海微雨如酥网络设计有限公司(以下简称「本公司」或「我们」)非常重视用户个人信息及隐私权的保护,因此我们制订了涵盖如何收集、存储、使用、共享和保护用户信息以及访问、更新、删除和保护这些信息方式的隐私政策。</p>
@ -126,16 +132,18 @@
<div class="wrap foot-inner">
<div>
<strong>Sleep Heart</strong>
<p>上海微雨如酥网络设计有限公司</p>
<p data-i18n="company">上海微雨如酥网络设计有限公司</p>
</div>
<nav class="foot-links" aria-label="页脚">
<a href="/">首页</a>
<a href="/download">下载</a>
<a href="/delete">注销</a>
<a href="/privacy" aria-current="page">隐私协议</a>
<a href="/terms">用户协议</a>
<a href="/" data-i18n="navHome">首页</a>
<a href="/download" data-i18n="navDownload">下载</a>
<a href="/delete" data-i18n="navDelete">注销</a>
<a href="/privacy" data-i18n="navPrivacy" aria-current="page">隐私协议</a>
<a href="/terms" data-i18n="navTerms">用户协议</a>
</nav>
</div>
</footer>
<script src="/assets/i18n/zh-Hans.js?v=20261011lang"></script>
<script src="/assets/site.js?v=20261011lang"></script>
</body>
</html>

View File

@ -6,27 +6,33 @@
<title>用户协议 — Sleep Heart</title>
<meta name="description" content="Sleep Heart 软件用户服务协议。上海微雨如酥网络设计有限公司。" />
<link rel="icon" href="/assets/icon.png" type="image/png" />
<link rel="stylesheet" href="/assets/site.css" />
<link rel="stylesheet" href="/assets/site.css?v=20261011lang" />
</head>
<body>
<body data-page="terms">
<header class="top">
<div class="wrap top-inner">
<a class="brand" href="/">
<img src="/assets/icon.png" width="40" height="40" alt="" />
<span>Sleep Heart</span>
</a>
<nav class="nav" aria-label="页面">
<a href="/">首页</a>
<a href="/download">下载</a>
<a href="/delete">注销</a>
<a href="/privacy">隐私协议</a>
<a href="/terms" aria-current="page">用户协议</a>
<div class="top-tools">
<nav class="nav" aria-label="页面">
<a href="/" data-i18n="navHome">首页</a>
<a href="/download" data-i18n="navDownload">下载</a>
<a href="/delete" data-i18n="navDelete">注销</a>
<a href="/privacy" data-i18n="navPrivacy">隐私协议</a>
<a href="/terms" data-i18n="navTerms" aria-current="page">用户协议</a>
</nav>
<label class="lang-label">
<span data-i18n="langLabel">语言</span>
<select id="lang-select"></select>
</label>
</div>
</div>
</header>
<main>
<div class="wrap">
<article class="panel">
<article class="panel" id="doc">
<h1>Sleep Heart 软件用户服务协议</h1>
<p class="meta">适用于 Sleep Heart 网站(health.wyrs365.com)及 Sleep Heart 应用。</p>
<p class="meta">本版本发布时间:2026年10月2日</p>
@ -103,16 +109,18 @@
<div class="wrap foot-inner">
<div>
<strong>Sleep Heart</strong>
<p>上海微雨如酥网络设计有限公司</p>
<p data-i18n="company">上海微雨如酥网络设计有限公司</p>
</div>
<nav class="foot-links" aria-label="页脚">
<a href="/">首页</a>
<a href="/download">下载</a>
<a href="/delete">注销</a>
<a href="/privacy">隐私协议</a>
<a href="/terms" aria-current="page">用户协议</a>
<a href="/" data-i18n="navHome">首页</a>
<a href="/download" data-i18n="navDownload">下载</a>
<a href="/delete" data-i18n="navDelete">注销</a>
<a href="/privacy" data-i18n="navPrivacy">隐私协议</a>
<a href="/terms" data-i18n="navTerms" aria-current="page">用户协议</a>
</nav>
</div>
</footer>
<script src="/assets/i18n/zh-Hans.js?v=20261011lang"></script>
<script src="/assets/site.js?v=20261011lang"></script>
</body>
</html>