docs(site): consolidate landing page and add macOS download
Publish one bilingual download surface with clearly separated iPhone/iPad App Store and notarized Mac DMG actions.
This commit is contained in:
+123
-59
@@ -12,7 +12,7 @@
|
||||
<meta name="theme-color" content="#f7f7f5" media="(prefers-color-scheme: light)">
|
||||
<link rel="canonical" href="https://hkgood.github.io/OSGKeyboard/">
|
||||
<link rel="alternate" hreflang="zh-Hans" href="https://hkgood.github.io/OSGKeyboard/">
|
||||
<link rel="alternate" hreflang="en" href="https://hkgood.github.io/OSGKeyboard/en/">
|
||||
<link rel="alternate" hreflang="en" href="https://hkgood.github.io/OSGKeyboard/?lang=en">
|
||||
<link rel="alternate" hreflang="x-default" href="https://hkgood.github.io/OSGKeyboard/">
|
||||
<link rel="icon" href="assets/app-icon.png" type="image/png">
|
||||
<link rel="apple-touch-icon" href="assets/app-icon.png">
|
||||
@@ -121,7 +121,7 @@
|
||||
"name": "和 Typeless、Superwhisper 有什么不同?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "OSGKeyboard 开源、本地模式完全免费、支持 iPhone/iPad/Mac,并用 BYOK 接入你已有的 LLM 额度,避免再开一份听写订阅。详见对比页。"
|
||||
"text": "OSGKeyboard 开源、本地模式完全免费、支持 iPhone/iPad/Mac,并用 BYOK 接入你已有的 LLM 额度,避免再开一份听写订阅。见本页产品对比表。"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -329,9 +329,17 @@
|
||||
.btn-ghost:hover { background: var(--bg-soft); }
|
||||
|
||||
/* —— Hero —— */
|
||||
/* Hero stays on the dark beams stage in both light and dark site themes. */
|
||||
.hero {
|
||||
--hero-stage: #070b0a;
|
||||
--hero-ink: #f4f4f2;
|
||||
--hero-muted: #a8a8b0;
|
||||
--hero-faint: #6f6f78;
|
||||
--hero-accent: #4cc46e;
|
||||
--hero-line: rgba(255, 255, 255, 0.14);
|
||||
position: relative;
|
||||
background: var(--hero-wash);
|
||||
background: var(--hero-stage);
|
||||
color: var(--hero-ink);
|
||||
padding: 4.5rem 0 2.5rem;
|
||||
overflow: hidden;
|
||||
isolation: isolate;
|
||||
@@ -370,8 +378,8 @@
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background:
|
||||
linear-gradient(180deg, transparent 58%, var(--hero-wash) 96%),
|
||||
radial-gradient(ellipse 90% 60% at 50% -8%, transparent 40%, color-mix(in srgb, var(--hero-wash) 55%, transparent) 100%);
|
||||
linear-gradient(180deg, transparent 58%, var(--hero-stage) 96%),
|
||||
radial-gradient(ellipse 90% 60% at 50% -8%, transparent 40%, color-mix(in srgb, var(--hero-stage) 55%, transparent) 100%);
|
||||
opacity: 0.72;
|
||||
pointer-events: none;
|
||||
}
|
||||
@@ -392,6 +400,7 @@
|
||||
text-transform: uppercase;
|
||||
color: var(--accent);
|
||||
}
|
||||
.hero .eyebrow { color: var(--hero-accent); }
|
||||
.eyebrow .material-symbols-outlined { font-size: 16px; }
|
||||
h1 {
|
||||
margin: 0 0 1rem;
|
||||
@@ -406,6 +415,7 @@
|
||||
font-size: 1.12rem;
|
||||
color: var(--text-2);
|
||||
}
|
||||
.hero .lead { color: var(--hero-muted); }
|
||||
.hero-cta {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
@@ -414,6 +424,13 @@
|
||||
gap: 0.7rem;
|
||||
margin-bottom: 1.4rem;
|
||||
}
|
||||
.hero .btn-ghost {
|
||||
border-color: var(--hero-line);
|
||||
color: var(--hero-ink);
|
||||
}
|
||||
.hero .btn-ghost:hover {
|
||||
background: rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
.store-badge {
|
||||
display: inline-flex;
|
||||
line-height: 0;
|
||||
@@ -426,11 +443,31 @@
|
||||
width: auto;
|
||||
display: block;
|
||||
}
|
||||
.platform-download {
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 0.35rem;
|
||||
}
|
||||
.platform-label {
|
||||
color: var(--text-2);
|
||||
font-size: 0.72rem;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
.hero .platform-label { color: var(--hero-muted); }
|
||||
.platform-downloads {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-end;
|
||||
justify-content: center;
|
||||
gap: 1rem;
|
||||
}
|
||||
.download-block {
|
||||
text-align: center;
|
||||
padding: 3.5rem 0 1rem;
|
||||
}
|
||||
.download-block .store-badge { margin: 0.4rem 0 1rem; }
|
||||
.download-block .platform-downloads { margin: 0.4rem 0 1rem; }
|
||||
.download-block .store-badge img { height: 52px; }
|
||||
.faq-list {
|
||||
max-width: 720px;
|
||||
@@ -479,12 +516,14 @@
|
||||
font-size: 0.86rem;
|
||||
color: var(--text-3);
|
||||
}
|
||||
.hero .hero-meta { color: var(--hero-faint); }
|
||||
.hero-meta span {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.3rem;
|
||||
}
|
||||
.hero-meta .material-symbols-outlined { font-size: 16px; color: var(--accent); }
|
||||
.hero .hero-meta .material-symbols-outlined { color: var(--hero-accent); }
|
||||
|
||||
/* Marketing device-family composite (replaces CSS mockup frames). */
|
||||
.hero-stage {
|
||||
@@ -880,8 +919,6 @@
|
||||
<button type="button" class="icon-btn" id="themeToggle" aria-label="Toggle theme">
|
||||
<span class="material-symbols-outlined" data-theme-icon>contrast</span>
|
||||
</button>
|
||||
<a class="nav-link-text" href="install/" data-i18n="nav.install">安装</a>
|
||||
<a class="nav-link-text" href="compare/" data-i18n="nav.compare">对比</a>
|
||||
<a class="nav-link" href="https://github.com/hkgood/OSGKeyboard" rel="noopener">
|
||||
<span class="material-symbols-outlined" aria-hidden="true">code</span>
|
||||
<span data-i18n="nav.github">GitHub</span>
|
||||
@@ -906,9 +943,18 @@
|
||||
<h1 data-i18n="hero.title">开口即文字</h1>
|
||||
<p class="lead" data-i18n="hero.lead">免费开源的跨端语音输入。本地识别,自带 API Key 润色,避免重复订阅。iPhone、iPad、Mac — 说完即落字。</p>
|
||||
<div class="hero-cta">
|
||||
<a class="store-badge" id="heroStoreBadge" href="https://apps.apple.com/cn/app/osgkeyboard/id6781553267" rel="noopener" aria-label="Download on the App Store">
|
||||
<img id="heroStoreBadgeImg" src="assets/badges/appstore-zh.svg" width="109" height="40" alt="在 App Store 下载">
|
||||
</a>
|
||||
<div class="platform-download">
|
||||
<span class="platform-label" data-i18n="download.ios">iPhone / iPad</span>
|
||||
<a class="store-badge" id="heroStoreBadge" href="https://apps.apple.com/cn/app/osgkeyboard/id6781553267" rel="noopener" aria-label="Download for iPhone and iPad">
|
||||
<img id="heroStoreBadgeImg" src="assets/badges/appstore-zh.svg" width="109" height="40" alt="下载 iPhone / iPad 版">
|
||||
</a>
|
||||
</div>
|
||||
<div class="platform-download">
|
||||
<span class="platform-label" data-i18n="download.mac">Mac</span>
|
||||
<a class="store-badge" href="https://github.com/hkgood/OSGKeyboard/releases/download/v1.1-mac/OSGKeyboard-1.1.dmg" rel="noopener" aria-label="Download for macOS">
|
||||
<img class="macos-badge-img" src="assets/badges/macos-zh.svg" width="120" height="40" alt="直接下载 macOS 版">
|
||||
</a>
|
||||
</div>
|
||||
<a class="btn btn-ghost" href="https://github.com/hkgood/OSGKeyboard" rel="noopener">
|
||||
<span class="material-symbols-outlined" aria-hidden="true">terminal</span>
|
||||
<span data-i18n="hero.cta.secondary">查看源码</span>
|
||||
@@ -1214,14 +1260,13 @@
|
||||
</article>
|
||||
<article class="faq-item reveal">
|
||||
<h3 data-i18n="faq.4.q">和 Typeless、Superwhisper 有什么不同?</h3>
|
||||
<p data-i18n="faq.4.a">开源、本地免费、手机+Mac 都有,并用 BYOK 复用已有 LLM 额度。详见对比页。</p>
|
||||
<p data-i18n="faq.4.a">开源、本地免费、手机+Mac 都有,并用 BYOK 复用已有 LLM 额度。见上方对比表。</p>
|
||||
</article>
|
||||
</div>
|
||||
<div class="resource-links reveal">
|
||||
<a href="install/" data-i18n="faq.link.install">安装指南 →</a>
|
||||
<a href="compare/" data-i18n="faq.link.compare">产品对比 →</a>
|
||||
<a href="mac-dictation/" data-i18n="faq.link.mac">Mac 全局听写 →</a>
|
||||
<a href="en/" data-i18n="faq.link.en">English site →</a>
|
||||
<a href="#start" data-i18n="faq.link.install">安装三步 →</a>
|
||||
<a href="#vs" data-i18n="faq.link.compare">产品对比 →</a>
|
||||
<a href="#download" data-i18n="faq.link.download">立即下载 →</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -1231,13 +1276,24 @@
|
||||
<div class="wrap reveal">
|
||||
<div class="block-head">
|
||||
<h2 data-i18n="download.title">立即下载</h2>
|
||||
<p data-i18n="download.subtitle">App Store 一键安装;也可从源码自行构建。</p>
|
||||
<p data-i18n="download.subtitle">iPhone / iPad 从 App Store 安装;Mac 直接下载已签名并公证的 DMG。</p>
|
||||
</div>
|
||||
<div class="platform-downloads">
|
||||
<div class="platform-download">
|
||||
<span class="platform-label" data-i18n="download.ios">iPhone / iPad</span>
|
||||
<a class="store-badge" id="footerStoreBadge" href="https://apps.apple.com/cn/app/osgkeyboard/id6781553267" rel="noopener" aria-label="Download for iPhone and iPad">
|
||||
<img id="footerStoreBadgeImg" src="assets/badges/appstore-zh.svg" width="109" height="40" alt="下载 iPhone / iPad 版">
|
||||
</a>
|
||||
</div>
|
||||
<div class="platform-download">
|
||||
<span class="platform-label" data-i18n="download.mac">Mac</span>
|
||||
<a class="store-badge" href="https://github.com/hkgood/OSGKeyboard/releases/download/v1.1-mac/OSGKeyboard-1.1.dmg" rel="noopener" aria-label="Download for macOS">
|
||||
<img class="macos-badge-img" src="assets/badges/macos-zh.svg" width="120" height="40" alt="直接下载 macOS 版">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<a class="store-badge" id="footerStoreBadge" href="https://apps.apple.com/cn/app/osgkeyboard/id6781553267" rel="noopener" aria-label="Download on the App Store">
|
||||
<img id="footerStoreBadgeImg" src="assets/badges/appstore-zh.svg" width="109" height="40" alt="在 App Store 下载">
|
||||
</a>
|
||||
<div class="hero-cta" style="margin-bottom:0">
|
||||
<a class="btn btn-ghost" href="install/" data-i18n="download.install">查看安装步骤</a>
|
||||
<a class="btn btn-ghost" href="#start" data-i18n="download.install">查看安装步骤</a>
|
||||
<a class="btn btn-ghost" href="https://github.com/hkgood/OSGKeyboard" rel="noopener" data-i18n="download.source">GitHub 源码</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1250,8 +1306,8 @@
|
||||
<span data-i18n="footer.copy">© OSGKeyboard · v0.5.4 · 源码可见</span>
|
||||
<span class="footer-links">
|
||||
<a href="#download" data-i18n="footer.download">Download</a>
|
||||
<a href="install/" data-i18n="footer.install">Install</a>
|
||||
<a href="compare/" data-i18n="footer.compare">Compare</a>
|
||||
<a href="#start" data-i18n="footer.install">Install</a>
|
||||
<a href="#vs" data-i18n="footer.compare">Compare</a>
|
||||
<a href="https://github.com/hkgood/OSGKeyboard" rel="noopener" data-i18n="footer.source">Source</a>
|
||||
<a href="privacy/" data-i18n="footer.privacy">Privacy</a>
|
||||
<a href="https://github.com/hkgood/OSGKeyboard/blob/main/LICENSE" rel="noopener" data-i18n="footer.license">License</a>
|
||||
@@ -1263,8 +1319,6 @@
|
||||
const copy = {
|
||||
en: {
|
||||
"nav.github": "GitHub",
|
||||
"nav.install": "Install",
|
||||
"nav.compare": "Compare",
|
||||
"hero.eyebrow": "Free · Open · Cross-platform",
|
||||
"hero.title": "Speak it. It's typed.",
|
||||
"hero.lead": "Free, open-source voice input across iPhone, iPad, and Mac. On-device recognition. Bring your own API key — no double-billing.",
|
||||
@@ -1363,18 +1417,19 @@
|
||||
"faq.3.q": "Which devices are supported?",
|
||||
"faq.3.a": "iPhone / iPad custom keyboard, plus Mac menu-bar global dictation (hold Option). Requires iOS / iPadOS / macOS 26+.",
|
||||
"faq.4.q": "How is it different from Typeless or Superwhisper?",
|
||||
"faq.4.a": "Open source, free local mode, phone + Mac, and BYOK so you reuse LLM credits you already pay for. See the compare page.",
|
||||
"faq.link.install": "Install guide →",
|
||||
"faq.link.compare": "Compare products →",
|
||||
"faq.link.mac": "Mac global dictation →",
|
||||
"faq.link.en": "English site →",
|
||||
"faq.4.a": "Open source, free local mode, phone + Mac, and BYOK so you reuse LLM credits you already pay for. See the comparison table above.",
|
||||
"faq.link.install": "Setup in 3 steps →",
|
||||
"faq.link.compare": "Product comparison →",
|
||||
"faq.link.download": "Download now →",
|
||||
"download.title": "Download now",
|
||||
"download.subtitle": "Install from the App Store — or build from source.",
|
||||
"download.subtitle": "Get iPhone / iPad from the App Store, or download the signed and notarized DMG for Mac.",
|
||||
"download.ios": "iPhone / iPad",
|
||||
"download.mac": "Mac",
|
||||
"download.install": "Installation steps",
|
||||
"download.source": "GitHub source",
|
||||
"footer.copy": "© OSGKeyboard · v0.5.4 · source available",
|
||||
"footer.download": "Download",
|
||||
"footer.install": "Install",
|
||||
"footer.install": "Setup",
|
||||
"footer.compare": "Compare",
|
||||
"footer.source": "Source",
|
||||
"footer.privacy": "Privacy",
|
||||
@@ -1382,8 +1437,6 @@
|
||||
},
|
||||
zh: {
|
||||
"nav.github": "GitHub",
|
||||
"nav.install": "安装",
|
||||
"nav.compare": "对比",
|
||||
"hero.eyebrow": "免费 · 开源 · 跨端",
|
||||
"hero.title": "开口即文字",
|
||||
"hero.lead": "免费开源的跨端语音输入。本地识别,自带 API Key 润色,避免重复订阅。iPhone、iPad、Mac — 说完即落字。",
|
||||
@@ -1482,13 +1535,14 @@
|
||||
"faq.3.q": "支持哪些设备?",
|
||||
"faq.3.a": "iPhone / iPad 自定义键盘,以及 Mac 菜单栏全局听写(按住 Option)。需 iOS / iPadOS / macOS 26+。",
|
||||
"faq.4.q": "和 Typeless、Superwhisper 有什么不同?",
|
||||
"faq.4.a": "开源、本地免费、手机+Mac 都有,并用 BYOK 复用已有 LLM 额度。详见对比页。",
|
||||
"faq.link.install": "安装指南 →",
|
||||
"faq.4.a": "开源、本地免费、手机+Mac 都有,并用 BYOK 复用已有 LLM 额度。见上方对比表。",
|
||||
"faq.link.install": "安装三步 →",
|
||||
"faq.link.compare": "产品对比 →",
|
||||
"faq.link.mac": "Mac 全局听写 →",
|
||||
"faq.link.en": "English site →",
|
||||
"faq.link.download": "立即下载 →",
|
||||
"download.title": "立即下载",
|
||||
"download.subtitle": "App Store 一键安装;也可从源码自行构建。",
|
||||
"download.subtitle": "iPhone / iPad 从 App Store 安装;Mac 直接下载已签名并公证的 DMG。",
|
||||
"download.ios": "iPhone / iPad",
|
||||
"download.mac": "Mac",
|
||||
"download.install": "查看安装步骤",
|
||||
"download.source": "GitHub 源码",
|
||||
"footer.copy": "© OSGKeyboard · v0.5.4 · 源码可见",
|
||||
@@ -1505,12 +1559,16 @@
|
||||
zh: {
|
||||
href: "https://apps.apple.com/cn/app/osgkeyboard/id6781553267",
|
||||
src: "assets/badges/appstore-zh.svg",
|
||||
alt: "在 App Store 下载"
|
||||
alt: "下载 iPhone / iPad 版",
|
||||
macSrc: "assets/badges/macos-zh.svg",
|
||||
macAlt: "直接下载 macOS 版"
|
||||
},
|
||||
en: {
|
||||
href: "https://apps.apple.com/app/osgkeyboard/id6781553267",
|
||||
src: "assets/badges/appstore-en.svg",
|
||||
alt: "Download on the App Store"
|
||||
alt: "Download for iPhone and iPad",
|
||||
macSrc: "assets/badges/macos-en.svg",
|
||||
macAlt: "Download for macOS"
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1526,6 +1584,10 @@
|
||||
img.setAttribute("src", cfg.src);
|
||||
img.setAttribute("alt", cfg.alt);
|
||||
});
|
||||
document.querySelectorAll(".macos-badge-img").forEach((img) => {
|
||||
img.setAttribute("src", cfg.macSrc);
|
||||
img.setAttribute("alt", cfg.macAlt);
|
||||
});
|
||||
}
|
||||
|
||||
function applyLang(lang) {
|
||||
@@ -1577,7 +1639,7 @@
|
||||
});
|
||||
}
|
||||
|
||||
// React Bits–style Beams (vanilla Three.js), preset from shared demo URL
|
||||
// Beams stay on the dark palette regardless of site theme.
|
||||
const beamsHero = (() => {
|
||||
const wrap = document.getElementById("heroAurora");
|
||||
const canvas = document.getElementById("heroAuroraCanvas");
|
||||
@@ -1585,26 +1647,22 @@
|
||||
|
||||
const reduceMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
||||
const isMobile = window.matchMedia("(max-width: 720px)").matches;
|
||||
const palettes = {
|
||||
dark: { light: "#7CFFB2", bg: "#000000" },
|
||||
light: { light: "#2f9a52", bg: "#0a1210" }
|
||||
};
|
||||
const palette = { light: "#7CFFB2", bg: "#000000" };
|
||||
|
||||
let instance = null;
|
||||
let currentMode = "";
|
||||
let ready = false;
|
||||
|
||||
function destroy() {
|
||||
if (!instance) return;
|
||||
try { instance.destroy(); } catch (_) {}
|
||||
instance = null;
|
||||
ready = false;
|
||||
}
|
||||
|
||||
function create(mode) {
|
||||
function create() {
|
||||
if (typeof window.OSGBeamsHero?.create !== "function" || typeof window.THREE === "undefined") {
|
||||
return false;
|
||||
}
|
||||
currentMode = mode;
|
||||
const palette = palettes[mode] || palettes.dark;
|
||||
canvas.style.width = "100%";
|
||||
canvas.style.height = "100%";
|
||||
try {
|
||||
@@ -1623,6 +1681,7 @@
|
||||
heightSegments: isMobile ? 64 : 100
|
||||
});
|
||||
wrap.classList.add("is-ready");
|
||||
ready = true;
|
||||
return true;
|
||||
} catch (err) {
|
||||
console.warn("[beams]", err);
|
||||
@@ -1631,19 +1690,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
function setPalette(mode) {
|
||||
const next = mode === "light" ? "light" : "dark";
|
||||
if (next === currentMode && instance) {
|
||||
const palette = palettes[next];
|
||||
function setPalette() {
|
||||
if (ready && instance) {
|
||||
instance.setLightColor(palette.light);
|
||||
instance.setBackground(palette.bg);
|
||||
return;
|
||||
}
|
||||
create(next);
|
||||
create();
|
||||
}
|
||||
|
||||
function boot() {
|
||||
const ok = create(resolvedTheme());
|
||||
const ok = create();
|
||||
if (!ok) return;
|
||||
|
||||
const io = new IntersectionObserver((entries) => {
|
||||
@@ -1675,7 +1732,8 @@
|
||||
}
|
||||
try { localStorage.setItem("osg-theme", theme); } catch (_) {}
|
||||
applyShots();
|
||||
beamsHero.setPalette(resolvedTheme());
|
||||
// Hero beams intentionally ignore theme — keep dark stage.
|
||||
beamsHero.setPalette();
|
||||
}
|
||||
|
||||
function cycleTheme() {
|
||||
@@ -1739,16 +1797,22 @@
|
||||
});
|
||||
})();
|
||||
|
||||
const urlLang = (() => {
|
||||
try {
|
||||
const q = new URLSearchParams(window.location.search).get("lang");
|
||||
if (q === "en" || q === "zh") return q;
|
||||
} catch (_) {}
|
||||
return null;
|
||||
})();
|
||||
const savedLang = (() => { try { return localStorage.getItem("osg-lang"); } catch (_) { return null; } })();
|
||||
const savedTheme = (() => { try { return localStorage.getItem("osg-theme"); } catch (_) { return null; } })();
|
||||
applyLang(savedLang || ((navigator.language || "").startsWith("zh") ? "zh" : "en"));
|
||||
applyLang(urlLang || savedLang || ((navigator.language || "").startsWith("zh") ? "zh" : "en"));
|
||||
applyTheme(savedTheme || "system");
|
||||
|
||||
try {
|
||||
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", () => {
|
||||
if ((document.documentElement.getAttribute("data-theme") || "system") === "system") {
|
||||
applyShots();
|
||||
beamsHero.setPalette(resolvedTheme());
|
||||
}
|
||||
});
|
||||
} catch (_) {}
|
||||
|
||||
Reference in New Issue
Block a user