fix(site): refine landing page visual hierarchy
CI / Validate manifests (push) Has been cancelled
CI / SwiftLint (push) Has been cancelled
CI / iOS / Extension (push) Has been cancelled
CI / macOS (push) Has been cancelled

This commit is contained in:
Rocky
2026-08-20 13:47:50 +08:00
parent 498f407585
commit 8fee4d8492
4 changed files with 1090 additions and 678 deletions
+1 -1
View File
@@ -7,5 +7,5 @@
<path d="M17.5 29.5h8M21.5 24v5.5M17.5 20.5h8"/> <path d="M17.5 29.5h8M21.5 24v5.5M17.5 20.5h8"/>
</g> </g>
<text x="40" y="14" fill="#fff" font-family="-apple-system, BlinkMacSystemFont, sans-serif" font-size="7.2">DOWNLOAD NOW</text> <text x="40" y="14" fill="#fff" font-family="-apple-system, BlinkMacSystemFont, sans-serif" font-size="7.2">DOWNLOAD NOW</text>
<text x="40" y="29" fill="#fff" font-family="-apple-system, BlinkMacSystemFont, sans-serif" font-size="15.5" font-weight="600">macOS version</text> <text x="40" y="29" fill="#fff" font-family="-apple-system, BlinkMacSystemFont, sans-serif" font-size="14" font-weight="600">macOS version</text>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 851 B

After

Width:  |  Height:  |  Size: 849 B

+889 -543
View File
File diff suppressed because it is too large Load Diff
+44 -43
View File
@@ -10,6 +10,9 @@
const languageButton = document.getElementById("languageToggle"); const languageButton = document.getElementById("languageToggle");
const themeButton = document.getElementById("themeToggle"); const themeButton = document.getElementById("themeToggle");
const themeIcon = themeButton?.querySelector(".material-symbols-rounded"); const themeIcon = themeButton?.querySelector(".material-symbols-rounded");
const menuButton = document.getElementById("menuToggle");
const menuIcon = menuButton?.querySelector(".material-symbols-rounded");
const mobileNav = document.getElementById("mobileNav");
const reduceMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches; const reduceMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
const themeMedia = window.matchMedia("(prefers-color-scheme: dark)"); const themeMedia = window.matchMedia("(prefers-color-scheme: dark)");
const supportedLanguages = new Set(["zh", "en"]); const supportedLanguages = new Set(["zh", "en"]);
@@ -56,18 +59,6 @@
element.setAttribute("content", element.dataset[`${lang}Content`] || ""); element.setAttribute("content", element.dataset[`${lang}Content`] || "");
}); });
document.querySelectorAll("[data-shot]").forEach((image) => {
const theme = root.dataset.theme || "light";
image.src = `assets/screenshots/${lang}/${theme}/${image.dataset.shot}`;
});
document.querySelectorAll("[data-media-name]").forEach((media) => {
const name = media.dataset.mediaName;
const extension = media.dataset.mediaExtension || "mp4";
media.src = `assets/whats-new/${name}-${lang}.${extension}`;
media.load?.();
});
document.title = lang === "zh" document.title = lang === "zh"
? "OSGKeyboard — 语音、打字与 AI 助手键盘" ? "OSGKeyboard — 语音、打字与 AI 助手键盘"
: "OSGKeyboard — Voice, typing, and an AI assistant keyboard"; : "OSGKeyboard — Voice, typing, and an AI assistant keyboard";
@@ -80,6 +71,16 @@
); );
} }
if (menuButton) {
const isOpen = menuButton.getAttribute("aria-expanded") === "true";
menuButton.setAttribute(
"aria-label",
lang === "zh"
? (isOpen ? "关闭导航" : "打开导航")
: (isOpen ? "Close navigation" : "Open navigation")
);
}
if (persist) { if (persist) {
localStorage.setItem("osg-site-language", lang); localStorage.setItem("osg-site-language", lang);
const url = new URL(window.location.href); const url = new URL(window.location.href);
@@ -97,6 +98,21 @@
return saved === "light" || saved === "dark" ? saved : null; return saved === "light" || saved === "dark" ? saved : null;
} }
function setMenuOpen(isOpen) {
if (!menuButton || !mobileNav) return;
const open = Boolean(isOpen);
menuButton.setAttribute("aria-expanded", String(open));
mobileNav.hidden = !open;
if (menuIcon) menuIcon.textContent = open ? "close" : "menu";
const lang = root.dataset.lang || "zh";
menuButton.setAttribute(
"aria-label",
lang === "zh"
? (open ? "关闭导航" : "打开导航")
: (open ? "Close navigation" : "Open navigation")
);
}
function applyTheme(theme, persist) { function applyTheme(theme, persist) {
const resolved = theme === "dark" ? "dark" : "light"; const resolved = theme === "dark" ? "dark" : "light";
root.dataset.theme = resolved; root.dataset.theme = resolved;
@@ -114,13 +130,8 @@
themeButton.setAttribute("aria-label", label); themeButton.setAttribute("aria-label", label);
} }
document.querySelectorAll("[data-shot]").forEach((image) => { beams?.setBackground("#0b0d0c");
const lang = root.dataset.lang || "zh"; beams?.setLightColor(resolved === "dark" ? "#7faf8a" : "#6eaa7d");
image.src = `assets/screenshots/${lang}/${resolved}/${image.dataset.shot}`;
});
beams?.setBackground(resolved === "dark" ? "#020805" : "#020805");
beams?.setLightColor(resolved === "dark" ? "#72F49D" : "#61E987");
if (persist) localStorage.setItem("osg-site-theme", resolved); if (persist) localStorage.setItem("osg-site-theme", resolved);
} }
@@ -134,12 +145,12 @@
beamWidth: 4.5, beamWidth: 4.5,
beamHeight: 6, beamHeight: 6,
beamNumber: 26, beamNumber: 26,
lightColor: "#72F49D", lightColor: "#7faf8a",
speed: 4.5, speed: 4.5,
noiseIntensity: 2.65, noiseIntensity: 2.65,
scale: 0.62, scale: 0.62,
rotation: 208, rotation: 208,
background: "#020805", background: "#0b0d0c",
reduceMotion reduceMotion
}); });
} catch (error) { } catch (error) {
@@ -148,33 +159,11 @@
} }
} }
function initializeVideos() {
document.querySelectorAll("video[autoplay]").forEach((video) => {
if (reduceMotion) {
video.autoplay = false;
video.pause();
return;
}
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
video.play().catch(() => {});
} else {
video.pause();
}
});
}, { threshold: 0.15 });
observer.observe(video);
});
}
const initialLanguage = preferredLanguage(); const initialLanguage = preferredLanguage();
const initialTheme = storedTheme() || (themeMedia.matches ? "dark" : "light"); const initialTheme = storedTheme() || (themeMedia.matches ? "dark" : "light");
applyLanguage(initialLanguage, false); applyLanguage(initialLanguage, false);
applyTheme(initialTheme, false); applyTheme(initialTheme, false);
initializeBeams(); initializeBeams();
initializeVideos();
languageButton?.addEventListener("click", () => { languageButton?.addEventListener("click", () => {
applyLanguage(root.dataset.lang === "zh" ? "en" : "zh", true); applyLanguage(root.dataset.lang === "zh" ? "en" : "zh", true);
@@ -185,6 +174,18 @@
applyTheme(root.dataset.theme === "dark" ? "light" : "dark", true); applyTheme(root.dataset.theme === "dark" ? "light" : "dark", true);
}); });
menuButton?.addEventListener("click", () => {
setMenuOpen(menuButton.getAttribute("aria-expanded") !== "true");
});
mobileNav?.querySelectorAll("a").forEach((link) => {
link.addEventListener("click", () => setMenuOpen(false));
});
document.addEventListener("keydown", (event) => {
if (event.key === "Escape") setMenuOpen(false);
});
themeMedia.addEventListener("change", (event) => { themeMedia.addEventListener("change", (event) => {
if (!storedTheme()) applyTheme(event.matches ? "dark" : "light", false); if (!storedTheme()) applyTheme(event.matches ? "dark" : "light", false);
}); });
+156 -91
View File
@@ -33,8 +33,8 @@
data-zh-content="一个键盘,完成听写、中英打字、AI 问答与剪贴板技能。默认端侧识别,也支持 BYOK 和可选托管积分。" data-zh-content="一个键盘,完成听写、中英打字、AI 问答与剪贴板技能。默认端侧识别,也支持 BYOK 和可选托管积分。"
data-en-content="One keyboard for dictation, Chinese and English typing, AI answers, and clipboard skills. On-device by default, with BYOK and optional managed credits." data-en-content="One keyboard for dictation, Chinese and English typing, AI answers, and clipboard skills. On-device by default, with BYOK and optional managed credits."
> >
<meta property="og:image" content="https://hkgood.github.io/OSGKeyboard/assets/hero-devices.png"> <meta property="og:image" content="https://hkgood.github.io/OSGKeyboard/assets/app-icon.png">
<meta name="twitter:card" content="summary_large_image"> <meta name="twitter:card" content="summary">
<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700;800&family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@20..48,300..700,0..1,0&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700;800&family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@20..48,300..700,0..1,0&display=swap" rel="stylesheet">
@@ -126,15 +126,25 @@
<span>OSGKeyboard</span> <span>OSGKeyboard</span>
</a> </a>
<div class="nav-links"> <div class="nav-links">
<a href="#assistant" data-zh="助手" data-en="Assistant">助手</a> <a href="#assistant" data-zh="产品" data-en="Product">产品</a>
<a href="#typing" data-zh="打字" data-en="Typing">打字</a> <a href="#typing" data-zh="能力" data-en="Capabilities">能力</a>
<a href="#skills" data-zh="技能" data-en="Skills">技能</a>
<a href="#engines" data-zh="服务" data-en="Services">服务</a>
<a href="#account" data-zh="账号" data-en="Account">账号</a>
<a href="#privacy" data-zh="隐私" data-en="Privacy">隐私</a> <a href="#privacy" data-zh="隐私" data-en="Privacy">隐私</a>
<a href="#start" data-zh="开始使用" data-en="Get started">开始使用</a> <a href="#platforms" data-zh="平台" data-en="Platforms">平台</a>
<a href="#start" data-zh="开始" data-en="Get started">开始</a>
</div> </div>
<div class="nav-actions"> <div class="nav-actions">
<button
class="icon-button mobile-menu-button"
id="menuToggle"
type="button"
aria-expanded="false"
aria-controls="mobileNav"
aria-label="打开导航"
data-zh-label="打开导航"
data-en-label="Open navigation"
>
<span class="material-symbols-rounded" aria-hidden="true">menu</span>
</button>
<button class="language-button" id="languageToggle" type="button" aria-label="Switch to English">EN</button> <button class="language-button" id="languageToggle" type="button" aria-label="Switch to English">EN</button>
<button <button
class="icon-button" class="icon-button"
@@ -146,6 +156,13 @@
</button> </button>
</div> </div>
</nav> </nav>
<nav class="mobile-nav" id="mobileNav" aria-label="Mobile" hidden>
<a href="#assistant" data-zh="产品" data-en="Product">产品</a>
<a href="#typing" data-zh="能力" data-en="Capabilities">能力</a>
<a href="#privacy" data-zh="隐私" data-en="Privacy">隐私</a>
<a href="#platforms" data-zh="平台" data-en="Platforms">平台</a>
<a href="#start" data-zh="开始" data-en="Start">开始</a>
</nav>
</header> </header>
<main id="main"> <main id="main">
@@ -164,7 +181,7 @@
</p> </p>
<h1> <h1>
<span data-zh="不止听写。" data-en="Beyond dictation.">不止听写。</span><br> <span data-zh="不止听写。" data-en="Beyond dictation.">不止听写。</span><br>
<span class="gradient-text" data-zh="这是你的输入助手。" data-en="Your input assistant.">这是你的输入助手。</span> <span class="hero-accent" data-zh="你的输入助手。" data-en="Your input assistant.">你的输入助手。</span>
</h1> </h1>
<p <p
class="hero-copy" class="hero-copy"
@@ -214,37 +231,53 @@
>iOS / iPadOS 26+ · macOS 15+(公开 DMG 为历史版 1.1)· 核心功能无需 OSG 账号</p> >iOS / iPadOS 26+ · macOS 15+(公开 DMG 为历史版 1.1)· 核心功能无需 OSG 账号</p>
</div> </div>
<div class="hero-visual" aria-label="OSGKeyboard product preview"> <div
<div class="floating-chip one"> class="hero-visual"
<span class="material-symbols-rounded" aria-hidden="true">graphic_eq</span> aria-label="OSGKeyboard 功能示意"
data-zh-label="OSGKeyboard 功能示意"
data-en-label="OSGKeyboard capability illustration"
>
<div class="illustration-label" data-zh="功能示意" data-en="Product illustration">功能示意</div>
<div class="input-console">
<div class="console-toolbar">
<span class="console-brand">OSG</span>
<div class="mode-tabs" aria-hidden="true">
<span class="mode-tab is-active" data-zh="助手" data-en="Assistant">助手</span>
<span class="mode-tab" data-zh="中文" data-en="中文">中文</span>
<span class="mode-tab">EN</span>
</div>
<span class="material-symbols-rounded console-menu" aria-hidden="true">more_horiz</span>
</div>
<div class="console-content">
<p class="console-kicker" data-zh="当前输入" data-en="Current input">当前输入</p>
<p
class="console-transcript"
data-zh="把刚才的内容整理得更清楚,同时保留我的语气。"
data-en="Make that clearer while keeping it in my voice."
>把刚才的内容整理得更清楚,同时保留我的语气。</p>
<div class="console-result">
<span class="result-label" data-zh="准备插入" data-en="Ready to insert">准备插入</span>
<span class="result-copy" data-zh="内容已经整理好,并保留了原本的表达方式。" data-en="The text is clearer and still sounds like you.">内容已经整理好,并保留了原本的表达方式。</span>
</div>
</div>
<div class="console-footer">
<span class="console-action">
<span class="material-symbols-rounded" aria-hidden="true">undo</span>
</span>
<span class="console-mic">
<span class="material-symbols-rounded" aria-hidden="true">mic</span>
</span>
<span class="console-action">
<span class="material-symbols-rounded" aria-hidden="true">arrow_upward</span>
</span>
</div>
</div>
<div class="hero-caption">
<span data-zh="轻点听写" data-en="Tap to dictate">轻点听写</span> <span data-zh="轻点听写" data-en="Tap to dictate">轻点听写</span>
</div> <span aria-hidden="true">·</span>
<div class="phone-frame"> <span data-zh="长按提问" data-en="Hold to ask">长按提问</span>
<img <span aria-hidden="true">·</span>
src="assets/screenshots/zh/light/iphone-keyboard_idle.png" <span data-zh="安全插入" data-en="Insert safely">安全插入</span>
data-shot="iphone-keyboard_idle.png"
data-zh-alt="OSGKeyboard iPhone 助手界面"
data-en-alt="OSGKeyboard assistant on iPhone"
alt="OSGKeyboard iPhone 助手界面"
>
</div>
<div class="video-card">
<video
src="assets/whats-new/ai-voice-assistant-zh.mp4"
data-media-name="ai-voice-assistant"
autoplay
muted
loop
playsinline
preload="metadata"
aria-label="统一助手键盘演示"
data-zh-label="统一助手键盘演示"
data-en-label="Unified assistant keyboard demo"
></video>
</div>
<div class="floating-chip two">
<span class="material-symbols-rounded" aria-hidden="true">auto_awesome</span>
<span data-zh="长按问 AI" data-en="Hold to ask AI">长按问 AI</span>
</div> </div>
</div> </div>
</div> </div>
@@ -303,20 +336,25 @@
</li> </li>
</ul> </ul>
</div> </div>
<div class="media-shell"> <div class="workflow-visual" aria-label="Assistant workflow">
<video <div class="workflow-step">
src="assets/whats-new/edit-last-input-zh.mp4" <span class="workflow-number">01</span>
data-media-name="edit-last-input" <span class="material-symbols-rounded" aria-hidden="true">mic</span>
autoplay <strong data-zh="表达意图" data-en="Express intent">表达意图</strong>
muted <small data-zh="轻点听写,长按提问" data-en="Tap to dictate, hold to ask">轻点听写,长按提问</small>
loop </div>
playsinline <div class="workflow-step">
preload="metadata" <span class="workflow-number">02</span>
aria-label="编辑上次输入演示" <span class="material-symbols-rounded" aria-hidden="true">auto_fix_high</span>
data-zh-label="编辑上次输入演示" <strong data-zh="理解并处理" data-en="Understand and process">理解并处理</strong>
data-en-label="Edit last input demo" <small data-zh="润色、问答或编辑" data-en="Polish, answer, or edit">润色、问答或编辑</small>
></video> </div>
<span class="media-label" data-zh="编辑上次输入" data-en="Edit last input">编辑上次输入</span> <div class="workflow-step">
<span class="workflow-number">03</span>
<span class="material-symbols-rounded" aria-hidden="true">text_fields</span>
<strong data-zh="确认上下文" data-en="Verify context">确认上下文</strong>
<small data-zh="安全插入当前输入框" data-en="Insert safely into the field">安全插入当前输入框</small>
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -373,20 +411,41 @@
<section class="section section-dark" id="skills"> <section class="section section-dark" id="skills">
<div class="section-inner"> <div class="section-inner">
<div class="feature-stage"> <div class="feature-stage">
<div class="media-shell"> <div class="clipboard-visual">
<video <div class="clipboard-source">
src="assets/whats-new/clipboard-skills-zh.mp4" <span class="material-symbols-rounded" aria-hidden="true">content_copy</span>
data-media-name="clipboard-skills" <div>
autoplay <small data-zh="刚刚复制" data-en="Just copied">刚刚复制</small>
muted <p data-zh="明天下午三点和产品团队确认新版上线计划。" data-en="Confirm the launch plan with the product team tomorrow at 3 PM.">明天下午三点和产品团队确认新版上线计划。</p>
loop </div>
playsinline </div>
preload="metadata" <p class="visual-label" data-zh="下一步" data-en="Next actions">下一步</p>
aria-label="剪贴板技能演示" <div class="skill-chip-grid">
data-zh-label="剪贴板技能演示" <span class="skill-chip is-primary">
data-en-label="Clipboard skills demo" <span class="material-symbols-rounded" aria-hidden="true">reply</span>
></video> <span data-zh="回复" data-en="Reply">回复</span>
<span class="media-label" data-zh="剪贴板快捷技能" data-en="Clipboard quick skills">剪贴板快捷技能</span> </span>
<span class="skill-chip">
<span class="material-symbols-rounded" aria-hidden="true">summarize</span>
<span data-zh="总结" data-en="Summarize">总结</span>
</span>
<span class="skill-chip">
<span class="material-symbols-rounded" aria-hidden="true">translate</span>
<span data-zh="翻译" data-en="Translate">翻译</span>
</span>
<span class="skill-chip">
<span class="material-symbols-rounded" aria-hidden="true">task_alt</span>
<span data-zh="待办" data-en="Tasks">待办</span>
</span>
<span class="skill-chip">
<span class="material-symbols-rounded" aria-hidden="true">event</span>
<span data-zh="日程" data-en="Events">日程</span>
</span>
<span class="skill-chip">
<span class="material-symbols-rounded" aria-hidden="true">near_me</span>
<span data-zh="导航" data-en="Navigate">导航</span>
</span>
</div>
</div> </div>
<div class="feature-copy"> <div class="feature-copy">
<p class="eyebrow" data-zh="AI Agent 与剪贴板" data-en="AI Agent and clipboard">AI Agent 与剪贴板</p> <p class="eyebrow" data-zh="AI Agent 与剪贴板" data-en="AI Agent and clipboard">AI Agent 与剪贴板</p>
@@ -439,16 +498,24 @@
</li> </li>
</ul> </ul>
</div> </div>
<div class="media-shell"> <div class="styles-visual">
<img <div class="style-selector">
src="assets/whats-new/polish-styles-zh.png" <span class="style-option" data-zh="轻度清理" data-en="Light cleanup">轻度清理</span>
data-media-name="polish-styles" <span class="style-option is-selected" data-zh="清晰结构" data-en="Clear structure">清晰结构</span>
data-media-extension="png" <span class="style-option" data-zh="正式表达" data-en="Formal">正式表达</span>
data-zh-alt="OSGKeyboard 润色风格" <span class="style-option" data-zh="日常聊天" data-en="Casual chat">日常聊天</span>
data-en-alt="OSGKeyboard polish styles" </div>
alt="OSGKeyboard 润色风格" <div class="style-preview">
> <small data-zh="润色预览" data-en="Polish preview">润色预览</small>
<span class="media-label" data-zh="内置与自定义润色风格" data-en="Built-in and custom polish styles">内置与自定义润色风格</span> <p
data-zh="先明确结论,再补充原因和下一步,让信息更容易理解。"
data-en="Lead with the conclusion, then add context and next steps."
>先明确结论,再补充原因和下一步,让信息更容易理解。</p>
<div class="preview-meta">
<span data-zh="保留原意" data-en="Meaning preserved">保留原意</span>
<span data-zh="结构更清晰" data-en="Clearer structure">结构更清晰</span>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -611,13 +678,12 @@
data-zh="在微信、备忘录、邮件、Notion、Cursor 等任意输入框使用。iPad 提供铺满宽度的工作区、地球键与编辑控制。" data-zh="在微信、备忘录、邮件、Notion、Cursor 等任意输入框使用。iPad 提供铺满宽度的工作区、地球键与编辑控制。"
data-en="Use it in Messages, Notes, Mail, Notion, Cursor, and any other text field. iPad adds a full-width workspace, globe key, and editing controls." data-en="Use it in Messages, Notes, Mail, Notion, Cursor, and any other text field. iPad adds a full-width workspace, globe key, and editing controls."
>在微信、备忘录、邮件、Notion、Cursor 等任意输入框使用。iPad 提供铺满宽度的工作区、地球键与编辑控制。</p> >在微信、备忘录、邮件、Notion、Cursor 等任意输入框使用。iPad 提供铺满宽度的工作区、地球键与编辑控制。</p>
<img <div class="platform-specs">
src="assets/screenshots/zh/light/ipad-home.png" <span data-zh="语音助手" data-en="Voice assistant">语音助手</span>
data-shot="ipad-home.png" <span data-zh="中文全拼 / 双拼" data-en="Full / double pinyin">中文全拼 / 双拼</span>
data-zh-alt="OSGKeyboard iPad 主界面" <span data-zh="英文纠错与补全" data-en="English correction and completion">英文纠错与补全</span>
data-en-alt="OSGKeyboard home on iPad" <span data-zh="剪贴板与技能" data-en="Clipboard and skills">剪贴板与技能</span>
alt="OSGKeyboard iPad 主界面" </div>
>
</article> </article>
<article class="platform-card"> <article class="platform-card">
<span class="platform-pill"> <span class="platform-pill">
@@ -629,13 +695,12 @@
data-zh="菜单栏 App 以底部胶囊浮层反馈实时转写。Apple Silicon 可下载 Qwen3 MLX 本地模型;也支持 Apple Speech 回退与 AI 润色。" data-zh="菜单栏 App 以底部胶囊浮层反馈实时转写。Apple Silicon 可下载 Qwen3 MLX 本地模型;也支持 Apple Speech 回退与 AI 润色。"
data-en="The menu-bar app shows live transcription in a bottom pill. Apple Silicon Macs can download a local Qwen3 MLX model; Apple Speech fallback and optional AI polish are also available." data-en="The menu-bar app shows live transcription in a bottom pill. Apple Silicon Macs can download a local Qwen3 MLX model; Apple Speech fallback and optional AI polish are also available."
>菜单栏 App 以底部胶囊浮层反馈实时转写。Apple Silicon 可下载 Qwen3 MLX 本地模型;也支持 Apple Speech 回退与 AI 润色。</p> >菜单栏 App 以底部胶囊浮层反馈实时转写。Apple Silicon 可下载 Qwen3 MLX 本地模型;也支持 Apple Speech 回退与 AI 润色。</p>
<img <div class="platform-specs">
src="assets/screenshots/zh/light/mac-recording.png" <span data-zh="Option 全局热键" data-en="Option global hotkey">Option 全局热键</span>
data-shot="mac-recording.png" <span data-zh="Qwen3 MLX 本地识别" data-en="Local Qwen3 MLX">Qwen3 MLX 本地识别</span>
data-zh-alt="OSGKeyboard Mac 全局听写浮层" <span data-zh="实时听写浮层" data-en="Live dictation overlay">实时听写浮层</span>
data-en-alt="OSGKeyboard global dictation overlay on Mac" <span data-zh="润色与翻译" data-en="Polish and translation">润色与翻译</span>
alt="OSGKeyboard Mac 全局听写浮层" </div>
>
</article> </article>
</div> </div>
</div> </div>