feat: refresh product website experience

The website previously buried platform downloads and presented the desktop assistant, Agent Runtime, and broader work capabilities with competing priorities. It now leads with the desktop assistant and AI programming workbench positioning, surfaces cross-platform and domestic Linux compatibility, and uses a responsive interactive product preview with synchronized tilt and soft lighting.

Release note: GoodBuddy 官网现在更清晰地展示桌面助手、Agent Runtime、跨平台与国产化支持,并提供更直观的动态产品预览。
This commit is contained in:
mesalogo
2026-08-17 01:05:46 +08:00
parent 2b556e38bd
commit e235522c0d
5 changed files with 429 additions and 818 deletions
+10 -1
View File
@@ -4,6 +4,15 @@
正式站点地址:<https://mesalogo.github.io/goodbuddy/> 正式站点地址:<https://mesalogo.github.io/goodbuddy/>
首页将 GoodBuddy 定位为“桌面助手|AI 编程工具台”,优先展示三大桌面
系统与双架构下载入口、统一 Agent Runtime,以及知识库、魔法笔记、
智能心跳、桌面上下文和远程消息通道等桌面助手能力。下载区位于主要
功能说明之前,并明确列出统信 UOS、银河麒麟、海光、兆芯、鲲鹏和飞腾
对应的 Linux x64 / arm64 包。页面不重复设置底部下载推广区。
首屏产品界面默认正面展示,在精确指针设备上使用克制的 3D 倾斜、
柔和跟随光效和同步浮动标签;触屏设备保持静态布局,系统启用“减少动态
效果”时不运行该交互。
## 部署 ## 部署
`.github/workflows/pages.yml` 会在 `main` 分支中的官网文件发生变化后, `.github/workflows/pages.yml` 会在 `main` 分支中的官网文件发生变化后,
@@ -34,7 +43,7 @@ node --check sites/app.js
## 下载入口 ## 下载入口
官网正文不展示具体版本号,所有下载入口直接指向 GitHub 最新正式 官网正文不展示具体版本号,三个系统下载按钮直接指向 GitHub 最新正式
Release Release
```text ```text
+48
View File
@@ -7,7 +7,11 @@
const navigation = document.querySelector("[data-navigation]"); const navigation = document.querySelector("[data-navigation]");
const themeToggle = document.querySelector("[data-theme-toggle]"); const themeToggle = document.querySelector("[data-theme-toggle]");
const themeColor = document.querySelector('meta[name="theme-color"]'); const themeColor = document.querySelector('meta[name="theme-color"]');
const tiltStage = document.querySelector("[data-tilt-stage]");
const tiltCard = tiltStage?.querySelector("[data-tilt-card]");
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)"); const systemTheme = window.matchMedia("(prefers-color-scheme: dark)");
const finePointer = window.matchMedia("(hover: hover) and (pointer: fine)");
const reducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)");
const getSavedTheme = () => { const getSavedTheme = () => {
try { try {
@@ -90,6 +94,50 @@
window.addEventListener("scroll", setHeaderState, { passive: true }); window.addEventListener("scroll", setHeaderState, { passive: true });
if (tiltStage instanceof HTMLElement && tiltCard instanceof HTMLElement) {
let tiltFrame = 0;
const resetTilt = () => {
window.cancelAnimationFrame(tiltFrame);
tiltStage.classList.remove("is-tilting");
tiltStage.style.setProperty("--spotlight-x", "50%");
tiltStage.style.setProperty("--spotlight-y", "50%");
tiltCard.style.setProperty("--spotlight-x", "50%");
tiltCard.style.setProperty("--spotlight-y", "50%");
tiltStage.style.setProperty("--scene-tilt-x", "0deg");
tiltStage.style.setProperty("--scene-tilt-y", "0deg");
};
const updateTilt = (event) => {
if (!finePointer.matches || reducedMotion.matches) {
resetTilt();
return;
}
const bounds = tiltStage.getBoundingClientRect();
const x = Math.min(Math.max((event.clientX - bounds.left) / bounds.width, 0), 1);
const y = Math.min(Math.max((event.clientY - bounds.top) / bounds.height, 0), 1);
window.cancelAnimationFrame(tiltFrame);
tiltFrame = window.requestAnimationFrame(() => {
const spotlightX = `${(x * 100).toFixed(1)}%`;
const spotlightY = `${(y * 100).toFixed(1)}%`;
tiltStage.classList.add("is-tilting");
tiltStage.style.setProperty("--spotlight-x", spotlightX);
tiltStage.style.setProperty("--spotlight-y", spotlightY);
tiltCard.style.setProperty("--spotlight-x", spotlightX);
tiltCard.style.setProperty("--spotlight-y", spotlightY);
tiltStage.style.setProperty("--scene-tilt-x", `${((0.5 - y) * 8).toFixed(2)}deg`);
tiltStage.style.setProperty("--scene-tilt-y", `${((x - 0.5) * 11).toFixed(2)}deg`);
});
};
tiltStage.addEventListener("pointermove", updateTilt, { passive: true });
tiltStage.addEventListener("pointerleave", resetTilt);
finePointer.addEventListener("change", resetTilt);
reducedMotion.addEventListener("change", resetTilt);
}
const sections = [...document.querySelectorAll("main section[id]")]; const sections = [...document.querySelectorAll("main section[id]")];
const navLinks = [...document.querySelectorAll('.site-navigation a[href^="#"]')]; const navLinks = [...document.querySelectorAll('.site-navigation a[href^="#"]')];
+171 -288
View File
@@ -5,11 +5,11 @@
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<meta <meta
name="description" name="description"
content="GoodBuddy 是桌面 AI 助手,支持项目知识库、魔法笔记、远程消息通道和受控工具执行。" content="GoodBuddy 是跨平台桌面助手与 AI 编程工具台,以统一 Agent Runtime 连接直连模型、OpenCode、Continue 与 DeepSeek Harness。"
/> />
<link rel="canonical" href="https://mesalogo.github.io/goodbuddy/" /> <link rel="canonical" href="https://mesalogo.github.io/goodbuddy/" />
<meta name="theme-color" content="#f6f8fb" /> <meta name="theme-color" content="#f6f8fb" />
<title>GoodBuddy|桌面 AI 助手</title> <title>GoodBuddy|桌面助手与 AI 编程工具台</title>
<link rel="icon" href="./assets/favicon.svg" type="image/svg+xml" /> <link rel="icon" href="./assets/favicon.svg" type="image/svg+xml" />
<link rel="stylesheet" href="./styles.css" /> <link rel="stylesheet" href="./styles.css" />
<script> <script>
@@ -57,10 +57,9 @@
</button> </button>
<nav class="site-navigation" id="site-navigation" aria-label="主导航" data-navigation> <nav class="site-navigation" id="site-navigation" aria-label="主导航" data-navigation>
<a href="#features">功能</a>
<a href="#release">亮点</a>
<a href="#download">下载</a> <a href="#download">下载</a>
<a href="#security">安全</a> <a href="#features">Agent Runtime</a>
<a href="#assistant">桌面助手</a>
</nav> </nav>
<div class="header-actions"> <div class="header-actions">
@@ -92,35 +91,30 @@
<div class="hero-copy"> <div class="hero-copy">
<div class="eyebrow"> <div class="eyebrow">
<span class="status-dot" aria-hidden="true"></span> <span class="status-dot" aria-hidden="true"></span>
桌面 AI 助手 Windows · macOS · Linux
</div> </div>
<h1 id="hero-title">桌面上使用 AI<br /><span>工作过程看得见</span></h1> <h1 id="hero-title">桌面助手<br /><span>也是 AI 编程工具台</span></h1>
<p class="hero-lead"> <p class="hero-lead">
GoodBuddy 可以连接模型、知识库和工具。知识按全局或项目管理, GoodBuddy 管理对话、知识、笔记与任务,也通过独创的统一 Agent Runtime
工具执行前可以确认,运行记录随时可查 接入直连模型、OpenCode、Continue 和 DeepSeek Harness
无需反复配置命令行,选择工具和项目即可开始。
</p> </p>
<div class="hero-actions"> <div class="hero-actions">
<a class="button button--primary" href="#features">查看功能</a> <a class="button button--primary" href="#download">立即下载</a>
<a <a class="button button--secondary" href="#features">了解 Agent Runtime</a>
class="button button--secondary"
href="https://github.com/mesalogo/goodbuddy/releases/latest"
target="_blank"
rel="noreferrer"
data-release-link
>前往官方下载页<span class="sr-only">(在新窗口打开)</span></a>
</div> </div>
<ul class="hero-facts" aria-label="产品特性概览"> <ul class="hero-facts" aria-label="产品特性概览">
<li> <li>
<svg viewBox="0 0 20 20" aria-hidden="true"><path d="m5 10 3 3 7-7" /></svg> <svg viewBox="0 0 20 20" aria-hidden="true"><path d="m5 10 3 3 7-7" /></svg>
支持 Windows / macOS / Linux 3 大桌面系统,x64 / arm64
</li> </li>
<li> <li>
<svg viewBox="0 0 20 20" aria-hidden="true"><path d="m5 10 3 3 7-7" /></svg> <svg viewBox="0 0 20 20" aria-hidden="true"><path d="m5 10 3 3 7-7" /></svg>
全局和项目知识分开管理 4 类 Agent Runtime 统一接入
</li> </li>
<li> <li>
<svg viewBox="0 0 20 20" aria-hidden="true"><path d="m5 10 3 3 7-7" /></svg> <svg viewBox="0 0 20 20" aria-hidden="true"><path d="m5 10 3 3 7-7" /></svg>
工具执行前可确认 图形化配置,执行仍受控
</li> </li>
</ul> </ul>
</div> </div>
@@ -128,15 +122,16 @@
<div <div
class="product-stage" class="product-stage"
role="img" role="img"
aria-label="GoodBuddy 桌面应用界面示意:在项目范围内对话、引用知识并审批工具调用" aria-label="GoodBuddy 桌面应用界面示意:在统一 Agent Runtime 中选择 AI 编程工具并受控执行"
data-tilt-stage
> >
<div class="stage-glow stage-glow--one"></div> <div class="stage-glow stage-glow--one"></div>
<div class="stage-glow stage-glow--two"></div> <div class="stage-glow stage-glow--two"></div>
<div class="app-window"> <div class="app-window" data-tilt-card>
<div class="window-bar"> <div class="window-bar">
<div class="window-dots" aria-hidden="true"><span></span><span></span><span></span></div> <div class="window-dots" aria-hidden="true"><span></span><span></span><span></span></div>
<div class="window-title">GoodBuddy</div> <div class="window-title">GoodBuddy</div>
<div class="window-status"><span></span> 本地工作区</div> <div class="window-status"><span></span> Runtime 已连接</div>
</div> </div>
<div class="app-layout"> <div class="app-layout">
<aside class="app-sidebar" aria-hidden="true"> <aside class="app-sidebar" aria-hidden="true">
@@ -157,32 +152,32 @@
<div class="app-content"> <div class="app-content">
<div class="app-content-header"> <div class="app-content-header">
<div> <div>
<strong>产品官网维护</strong> <strong>修复跨平台构建</strong>
<span>项目:GoodBuddy 官网</span> <span>项目:桌面客户端</span>
</div> </div>
<div class="mode-pill">计划模式</div> <div class="mode-pill">Continue · 执行</div>
</div> </div>
<div class="message-area"> <div class="message-area">
<div class="message message--user">检查官网内容与下载入口是否需要更新</div> <div class="message message--user">修复构建问题,并验证三个桌面系统</div>
<div class="message message--assistant"> <div class="message message--assistant">
<div class="assistant-label"> <div class="assistant-label">
<span class="assistant-avatar">G</span> <span class="assistant-avatar">G</span>
<strong>GoodBuddy</strong> <strong>GoodBuddy</strong>
</div> </div>
<p>我会先检查站点内容和发布页,不修改文件</p> <p>已通过 Agent Runtime 载入项目、Skills 和受控工具</p>
<div class="tool-card"> <div class="tool-card">
<div class="tool-icon"> <div class="tool-icon">
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M4 6h16M4 12h10M4 18h7" /></svg> <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M4 6h16M4 12h10M4 18h7" /></svg>
</div> </div>
<div><strong>读取项目知识</strong><span>范围:GoodBuddy 官网</span></div> <div><strong>准备编程环境</strong><span>Continue · 项目范围 · 受控工具</span></div>
<span class="tool-state">完成</span> <span class="tool-state">就绪</span>
</div> </div>
<div class="plan-lines" aria-hidden="true"><span></span><span></span><span></span></div> <div class="plan-lines" aria-hidden="true"><span></span><span></span><span></span></div>
</div> </div>
</div> </div>
<div class="composer"> <div class="composer">
<span>继续补充要求</span> <span>描述你想完成的编程任务</span>
<div class="composer-actions"><span>计划</span><b></b></div> <div class="composer-actions"><span>执行</span><b></b></div>
</div> </div>
</div> </div>
</div> </div>
@@ -191,207 +186,27 @@
<span class="floating-icon"> <span class="floating-icon">
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 3 5 6v5c0 4.5 2.8 8.6 7 10 4.2-1.4 7-5.5 7-10V6l-7-3Z" /><path d="m9 12 2 2 4-4" /></svg> <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 3 5 6v5c0 4.5 2.8 8.6 7 10 4.2-1.4 7-5.5 7-10V6l-7-3Z" /><path d="m9 12 2 2 4-4" /></svg>
</span> </span>
<span><strong>执行前确认</strong><small>查看工具名称和影响</small></span> <span><strong>统一 Agent Runtime</strong><small>直连模型 · OpenCode · Continue · DSH</small></span>
</div> </div>
<div class="floating-card floating-card--scope"> <div class="floating-card floating-card--scope">
<span class="scope-dot"></span> <span class="scope-dot"></span>
<span><strong>项目范围</strong><small>知识和任务按项目区分</small></span> <span><strong>跨平台可用</strong><small>Windows · macOS · Linux</small></span>
</div> </div>
</div> </div>
</div> </div>
</section> </section>
<section class="proof-strip" aria-label="核心设计原则"> <section class="proof-strip" aria-label="平台与 Runtime 支持概览">
<div class="section-inner proof-grid"> <div class="section-inner proof-grid">
<div><strong>3 </strong><span>问答 / 计划 / 执行模式</span></div> <div><strong>3 大系统</strong><span>Windows / macOS / Linux</span></div>
<div><strong>2 </strong><span>全局与项目知识范围</span></div> <div><strong>2 种架构</strong><span>x64 / arm64</span></div>
<div><strong>可查看</strong><span>工具调用与活动记录</span></div> <div><strong>4 类 Runtime</strong><span>多种 AI 编程路径</span></div>
<div><strong>6 组</strong><span>系统与架构组合</span></div> <div><strong>1 个入口</strong><span>选择、配置、运行、审计</span></div>
</div> </div>
</section> </section>
<section class="section features-section" id="features" aria-labelledby="features-title"> <section class="section download-section" id="download" aria-label="跨平台下载">
<div class="section-inner"> <div class="section-inner">
<div class="section-heading">
<div>
<p class="kicker">主要功能</p>
<h2 id="features-title">GoodBuddy 可以做什么</h2>
</div>
<p>
管理对话和知识,运行任务,并在需要时调用经过确认的工具。
</p>
</div>
<div class="feature-grid">
<article class="feature-card feature-card--wide">
<div class="feature-icon">
<svg viewBox="0 0 24 24" aria-hidden="true">
<path d="M12 3 5 6v5c0 4.5 2.8 8.6 7 10 4.2-1.4 7-5.5 7-10V6l-7-3Z" />
<path d="M9 12h6M12 9v6" />
</svg>
</div>
<span class="feature-number">01</span>
<h3>Agent 运行模式</h3>
<p>问答和计划模式不执行工具。执行模式通过审批控制调用工具,并支持取消、超时和输出限制。</p>
<div class="mode-row" aria-label="三种工作模式">
<span>问答 <small>只读</small></span>
<span>计划 <small>只读</small></span>
<span class="is-accent">执行 <small>需审批</small></span>
</div>
</article>
<article class="feature-card">
<div class="feature-icon">
<svg viewBox="0 0 24 24" aria-hidden="true">
<path d="M4 6.5C4 5.1 5.1 4 6.5 4H10l2 2h5.5C18.9 6 20 7.1 20 8.5v9c0 1.4-1.1 2.5-2.5 2.5h-11A2.5 2.5 0 0 1 4 17.5v-11Z" />
<path d="M8 11h8M8 15h5" />
</svg>
</div>
<span class="feature-number">02</span>
<h3>知识库按范围管理</h3>
<p>全局知识和项目知识分开保存。搜索结果和引用会显示来源。</p>
</article>
<article class="feature-card">
<div class="feature-icon">
<svg viewBox="0 0 24 24" aria-hidden="true">
<path d="M4 13h3l2-6 4 12 2-6h5" />
<path d="M4 4h16v16H4z" />
</svg>
</div>
<span class="feature-number">03</span>
<h3>定时任务和运行记录</h3>
<p>可以创建周期计划,查看每次运行的状态、结果和活动记录。</p>
</article>
<article class="feature-card">
<div class="feature-icon">
<svg viewBox="0 0 24 24" aria-hidden="true">
<path d="M7 13.5 13.5 7a3.2 3.2 0 0 1 4.5 4.5l-8 8a5 5 0 1 1-7-7l8-8" />
</svg>
</div>
<span class="feature-number">04</span>
<h3>文档和图片</h3>
<p>单次最多添加 8 个附件,支持同时传入 5 张图片。</p>
</article>
<article class="feature-card">
<div class="feature-icon">
<svg viewBox="0 0 24 24" aria-hidden="true">
<path d="M4 5h16v14H4z" />
<path d="m4 16 5-5 3 3 2-2 6 6" />
<circle cx="15.5" cy="8.5" r="1.5" />
</svg>
</div>
<span class="feature-number">05</span>
<h3>生成图片</h3>
<p>支持 auto、low、medium、high 四档质量。生成结果会保存到本地。</p>
</article>
<article class="feature-card feature-card--wide feature-card--accent">
<div class="feature-icon">
<svg viewBox="0 0 24 24" aria-hidden="true">
<circle cx="12" cy="12" r="3" />
<path d="M12 3v3M12 18v3M3 12h3M18 12h3M5.6 5.6l2.1 2.1M16.3 16.3l2.1 2.1M18.4 5.6l-2.1 2.1M7.7 16.3l-2.1 2.1" />
</svg>
</div>
<span class="feature-number">06</span>
<h3>模型、MCP 与运行时</h3>
<p>模型连接、MCP 工具和运行时都在桌面端配置。API 密钥只保存在主进程。</p>
<div class="provider-pills" aria-label="支持的连接类型">
<span>模型提供商</span><span>MCP</span><span>OpenCode</span><span>Continue</span>
</div>
</article>
</div>
</div>
</section>
<section class="section release-section" id="release" aria-labelledby="release-title">
<div class="section-inner">
<div class="release-heading">
<div class="version-lockup" aria-hidden="true">
<span>HIGHLIGHTS</span>
<strong>NOW</strong>
</div>
<div>
<p class="kicker">近期新增</p>
<h2 id="release-title">笔记、消息通道和运行时改进</h2>
<p>下面这些功能已经包含在当前正式版本中。</p>
</div>
</div>
<ol class="release-list">
<li class="release-item">
<div class="release-index">01</div>
<div class="release-copy">
<div class="release-label">魔法笔记</div>
<h3>魔法笔记</h3>
<p>在本地管理笔记和待办,支持范围、筛选、富文本编辑和 AI 评论。</p>
</div>
<div class="release-visual route-visual" aria-hidden="true">
<span class="route-node route-node--main">笔记</span>
<span class="route-line route-line--one"></span>
<span class="route-line route-line--two"></span>
<span class="route-node route-node--sub-one">待办</span>
<span class="route-node route-node--sub-two">AI 评论</span>
</div>
</li>
<li class="release-item">
<div class="release-index">02</div>
<div class="release-copy">
<div class="release-label release-label--preview">远程通道</div>
<h3>微信、企业微信和钉钉</h3>
<p>每个消息通道使用独立会话和系统项目,并记录发送者范围、运行模式和活动。</p>
</div>
<div class="release-visual channel-visual" aria-label="渠道状态">
<span><b>钉钉</b><small>独立会话</small></span>
<span><b>企业微信</b><small>范围控制</small></span>
<span class="is-experimental"><b>微信 ClawBot</b><small>扫码连接</small></span>
</div>
</li>
<li class="release-item">
<div class="release-index">03</div>
<div class="release-copy">
<div class="release-label">安全媒体</div>
<h3>远程消息中的图片和文件</h3>
<p>微信私聊支持图片与文件,单条消息最多 4 个附件。回复不会自动发送工作区中的已有文件。</p>
</div>
<div class="release-visual attachment-visual" aria-hidden="true">
<div class="attachment-stack"><span></span><span></span><span></span></div>
<div><strong>4</strong><small>单条附件</small></div>
<div><strong>12MB</strong><small>合计上限</small></div>
</div>
</li>
<li class="release-item">
<div class="release-index">04</div>
<div class="release-copy">
<div class="release-label">Agent Runtime</div>
<h3>运行时与 Skills</h3>
<p>OpenCode 与 Continue 共用更一致的 Skills、系统消息和工具配置,并保留环境白名单、取消、超时和审批控制。</p>
</div>
<div class="release-visual quality-visual" aria-label="运行时能力">
<span>Skills</span><span>Tools</span><span>OpenCode</span><span class="is-selected">Continue</span>
</div>
</li>
</ol>
</div>
</section>
<section class="section download-section" id="download" aria-labelledby="download-title">
<div class="section-inner">
<div class="section-heading section-heading--center">
<div>
<p class="kicker">下载</p>
<h2 id="download-title">下载 GoodBuddy</h2>
</div>
<p>
最新 Release 提供经过校验的跨平台安装包与哈希清单。进入官方下载页,按系统与架构选择安装包。
</p>
</div>
<div class="download-grid"> <div class="download-grid">
<article class="download-card"> <article class="download-card">
<div class="platform-icon"> <div class="platform-icon">
@@ -406,7 +221,7 @@
target="_blank" target="_blank"
rel="noreferrer" rel="noreferrer"
data-release-link data-release-link
>选择 Windows 安装包<span class="sr-only">(在新窗口打开)</span></a> >下载 Windows <span class="sr-only">(在新窗口打开)</span></a>
</article> </article>
<article class="download-card"> <article class="download-card">
<div class="platform-icon"> <div class="platform-icon">
@@ -421,7 +236,7 @@
target="_blank" target="_blank"
rel="noreferrer" rel="noreferrer"
data-release-link data-release-link
>选择 macOS 安装包<span class="sr-only">(在新窗口打开)</span></a> >下载 macOS <span class="sr-only">(在新窗口打开)</span></a>
</article> </article>
<article class="download-card"> <article class="download-card">
<div class="platform-icon"> <div class="platform-icon">
@@ -437,99 +252,167 @@
target="_blank" target="_blank"
rel="noreferrer" rel="noreferrer"
data-release-link data-release-link
>选择 Linux 安装包<span class="sr-only">(在新窗口打开)</span></a> >下载 Linux <span class="sr-only">(在新窗口打开)</span></a>
</article> </article>
</div> </div>
<div class="release-notice" role="status"> <aside class="domestic-support" aria-labelledby="domestic-support-title">
<svg viewBox="0 0 24 24" aria-hidden="true">
<circle cx="12" cy="12" r="9" /><path d="M12 11v5M12 8h.01" />
</svg>
<div> <div>
<strong>下载与校验</strong> <p class="kicker">国产化适配</p>
<span>下载入口始终指向最新正式 Release;安装前请按系统与架构选择文件,并核对 SHA-256 清单。</span> <h3 id="domestic-support-title">统信 UOS、银河麒麟,覆盖国产 x64 与 ARM64</h3>
<p>使用对应的 Linux x64 或 arm64 安装包。</p>
</div> </div>
<div class="domestic-support__items">
<div><span>国产系统</span><strong>统信 UOS · 银河麒麟</strong></div>
<div>
<span>国产 CPU</span>
<strong>海光 · 兆芯(x64<br />鲲鹏 · 飞腾(ARM64</strong>
</div>
</div>
</aside>
</div>
</section>
<section class="section features-section" id="features" aria-labelledby="features-title">
<div class="section-inner">
<div class="section-heading">
<div>
<p class="kicker">独创 Agent Runtime</p>
<h2 id="features-title">不同工具,同一种使用方式</h2>
</div>
<p>
把 Runtime 选择、模型连接、Skills、MCP 和权限控制集中到桌面界面。
</p>
</div>
<div class="feature-grid">
<article class="feature-card feature-card--wide feature-card--accent">
<div class="feature-icon">
<svg viewBox="0 0 24 24" aria-hidden="true">
<circle cx="12" cy="12" r="3" />
<path d="M12 3v3M12 18v3M3 12h3M18 12h3M5.6 5.6l2.1 2.1M16.3 16.3l2.1 2.1M18.4 5.6l-2.1 2.1M7.7 16.3l-2.1 2.1" />
</svg>
</div>
<span class="feature-number">01</span>
<h3>一个入口,连接多种 Agent Runtime</h3>
<p>按任务选择直连模型、OpenCode、Continue 或 DeepSeek Harness,不必为每种工具重新适应一套入口。</p>
<div class="provider-pills" aria-label="支持的 Agent Runtime">
<span>直连模型</span><span>OpenCode</span><span>Continue</span><span>DeepSeek Harness</span>
</div>
</article>
<article class="feature-card">
<div class="feature-icon">
<svg viewBox="0 0 24 24" aria-hidden="true">
<path d="M4 5h16v14H4zM8 22h8M12 19v3" />
<path d="M7 9h2M11 9h2M15 9h2M7 13h10" />
</svg>
</div>
<span class="feature-number">02</span>
<h3>覆盖主流桌面系统</h3>
<p>Windows、macOS、Linux 同步提供 x64 与 arm64 架构版本。</p>
</article>
<article class="feature-card">
<div class="feature-icon">
<svg viewBox="0 0 24 24" aria-hidden="true">
<path d="M5 4h14v16H5zM8 8h8M8 12h5" />
<path d="m14 16 2 2 3-4" />
</svg>
</div>
<span class="feature-number">03</span>
<h3>更低的入门门槛</h3>
<p>在图形界面中选择 Runtime、模型、工作模式和项目,不用先记住复杂命令。</p>
</article>
<article class="feature-card">
<div class="feature-icon">
<svg viewBox="0 0 24 24" aria-hidden="true">
<path d="M12 3 5 6v5c0 4.5 2.8 8.6 7 10 4.2-1.4 7-5.5 7-10V6l-7-3Z" />
<path d="M9 12h6M12 9v6" />
</svg>
</div>
<span class="feature-number">04</span>
<h3>能力统一,边界不打折</h3>
<p>Skills、MCP 和工具按 Runtime 分配;Ask 保持只读,Execute 继续经过审批和审计。</p>
<div class="mode-row" aria-label="两种工作模式">
<span>Ask <small>只读</small></span>
<span class="is-accent">Execute <small>受控执行</small></span>
</div>
</article>
<article class="feature-card">
<div class="feature-icon">
<svg viewBox="0 0 24 24" aria-hidden="true">
<path d="M4 6.5C4 5.1 5.1 4 6.5 4H10l2 2h5.5C18.9 6 20 7.1 20 8.5v9c0 1.4-1.1 2.5-2.5 2.5h-11A2.5 2.5 0 0 1 4 17.5v-11Z" />
<path d="M8 11h8M8 15h5" />
</svg>
</div>
<span class="feature-number">05</span>
<h3>项目上下文集中管理</h3>
<p>对话、知识、任务和运行记录按项目组织,切换 Runtime 不必丢掉工作上下文。</p>
</article>
<article class="feature-card feature-card--wide">
<div class="feature-icon">
<svg viewBox="0 0 24 24" aria-hidden="true">
<path d="M4 13h3l2-6 4 12 2-6h5" />
<path d="M4 4h16v16H4z" />
</svg>
</div>
<span class="feature-number">06</span>
<h3>从运行到结果,全程可追踪</h3>
<p>统一查看工具调用、取消、超时、Token 用量和活动记录,知道 Runtime 做了什么。</p>
</article>
</div> </div>
</div> </div>
</section> </section>
<section class="section security-section" id="security" aria-labelledby="security-title"> <section class="section assistant-section" id="assistant" aria-labelledby="assistant-title">
<div class="section-inner security-grid"> <div class="section-inner assistant-grid">
<div class="security-intro"> <div class="assistant-intro">
<div class="security-shield" aria-hidden="true"> <div class="assistant-mark" aria-hidden="true">
<svg viewBox="0 0 48 48"> <svg viewBox="0 0 48 48">
<path d="M24 5 9 11v11c0 9.7 6 18.2 15 21 9-2.8 15-11.3 15-21V11L24 5Z" /> <path d="M9 25a11 11 0 1 1 22 0v10H20A11 11 0 0 1 9 25Z" />
<path d="m17.5 24 4.5 4.5 9-10" /> <path d="M21 25a11 11 0 1 1 22 0 11 11 0 0 1-22 0Z" />
</svg> </svg>
</div> </div>
<p class="kicker">安全设计</p> <p class="kicker">桌面助手</p>
<h2 id="security-title">主要安全边界</h2> <h2 id="assistant-title">对话、知识、笔记与任务,都在桌面上</h2>
<p> <p>
渲染界面不能直接读取密钥或调用 Node。工具和子运行时通过主进程受控访问系统能力。 GoodBuddy 把资料、待办和长期任务放进同一个桌面工作区,
日常协作与 AI 编程共享项目上下文。
</p> </p>
<a <a
class="text-link" class="text-link"
href="https://github.com/mesalogo/goodbuddy" href="#download"
target="_blank"
rel="noreferrer"
> >
在 GitHub 查看项目 选择你的桌面版本
<span aria-hidden="true"></span> <span aria-hidden="true"></span>
<span class="sr-only">(在新窗口打开)</span>
</a> </a>
</div> </div>
<div class="security-list"> <div class="assistant-list">
<article> <article>
<span class="security-number">01</span> <span class="assistant-number">01</span>
<div><h3>密钥仅存主进程</h3><p>API 密钥写入加密设置存储,不会暴露给渲染界面</p></div> <div><h3>资料变成可问的知识</h3><p>导入文件、目录和网页,用全文、向量和知识图谱一起检索</p></div>
</article> </article>
<article> <article>
<span class="security-number">02</span> <span class="assistant-number">02</span>
<div><h3>IPC 输入经过校验</h3><p>预加载层只暴露明确的方法。IPC 输入使用共享模式校验,并检查发送方</p></div> <div><h3>笔记、待办和长期跟进</h3><p>魔法笔记管理灵感与待办,智能心跳持续回顾、沉淀记忆并提出后续任务</p></div>
</article> </article>
<article> <article>
<span class="security-number">03</span> <span class="assistant-number">03</span>
<div><h3>子运行时受限</h3><p>OpenCode 与 Continue 使用环境白名单、沙箱检查和工具审批</p></div> <div><h3>直接理解你的桌面</h3><p>按需加入文件、截图、应用窗口、剪贴板和离线语音,不用来回搬运内容</p></div>
</article> </article>
<article> <article>
<span class="security-number">04</span> <span class="assistant-number">04</span>
<div><h3>工具执行可追踪</h3><p>工具名称、状态、取消、超时和输出限制都会记录在活动中</p></div> <div><h3>离开电脑也能继续</h3><p>通过微信、企业微信和钉钉连接独立会话,把任务交给桌面上的 GoodBuddy</p></div>
</article> </article>
</div> </div>
</div> </div>
</section> </section>
<section class="section final-cta" aria-labelledby="cta-title">
<div class="section-inner">
<div class="cta-card">
<div class="cta-orbit" aria-hidden="true"><span></span><span></span></div>
<div>
<p class="kicker">下载</p>
<h2 id="cta-title">选择适合你系统的安装包</h2>
<p>发布页提供安装文件、便携版和 SHA-256 校验清单。</p>
</div>
<div class="cta-actions">
<a
class="button button--primary"
href="https://github.com/mesalogo/goodbuddy/releases/latest"
target="_blank"
rel="noreferrer"
data-release-link
>前往官方下载页<span class="sr-only">(在新窗口打开)</span></a>
<a
class="button button--secondary"
href="https://github.com/mesalogo/goodbuddy"
target="_blank"
rel="noreferrer"
>
查看 GitHub
<span class="sr-only">(在新窗口打开)</span>
</a>
</div>
</div>
</div>
</section>
</main> </main>
<footer class="site-footer"> <footer class="site-footer">
@@ -542,11 +425,11 @@
</svg> </svg>
<span>GoodBuddy</span> <span>GoodBuddy</span>
</a> </a>
<p>桌面 AI 助手与 Agent 工作空间。</p> <p>桌面助手|AI 编程工具台</p>
<div class="footer-links"> <div class="footer-links">
<a href="#features">功能</a> <a href="#download">下载</a>
<a href="#release">亮点</a> <a href="#features">Agent Runtime</a>
<a href="#security">安全</a> <a href="#assistant">桌面助手</a>
<a href="https://github.com/mesalogo/goodbuddy" target="_blank" rel="noreferrer"> <a href="https://github.com/mesalogo/goodbuddy" target="_blank" rel="noreferrer">
GitHub<span class="sr-only">(在新窗口打开)</span> GitHub<span class="sr-only">(在新窗口打开)</span>
</a> </a>
+23 -8
View File
@@ -67,22 +67,37 @@ report(/class="skip-link"\s+href="#main-content"/.test(html), "缺少跳到主
report(/<main\s+id="main-content">/.test(html), "缺少 main-content 主区域"); report(/<main\s+id="main-content">/.test(html), "缺少 main-content 主区域");
report(/aria-label="主导航"/.test(html), "主导航缺少可访问名称"); report(/aria-label="主导航"/.test(html), "主导航缺少可访问名称");
report(/data-theme-toggle/.test(html), "缺少主题切换控件"); report(/data-theme-toggle/.test(html), "缺少主题切换控件");
report(/data-tilt-stage/.test(html), "首屏产品界面缺少倾斜交互区域");
report(/data-tilt-card/.test(html), "首屏产品界面缺少倾斜卡片");
report(/prefers-reduced-motion:\s*reduce/.test(css), "缺少减少动态效果规则"); report(/prefers-reduced-motion:\s*reduce/.test(css), "缺少减少动态效果规则");
report(/\[data-theme="dark"\]/.test(css), "缺少深色主题令牌"); report(/\[data-theme="dark"\]/.test(css), "缺少深色主题令牌");
report(/--scene-tilt-x/.test(css), "缺少产品界面横向倾斜变量");
report(/--spotlight-x/.test(css), "缺少产品界面动态光效变量");
report(
/\.floating-card[\s\S]*rotateX\(var\(--scene-tilt-x\)\)/.test(css),
"浮动标签必须跟随产品界面倾斜",
);
report(/requestAnimationFrame/.test(appJs), "产品界面倾斜交互必须按帧更新");
for (const breakpoint of ["1199px", "959px", "719px"]) { for (const breakpoint of ["1199px", "959px", "719px"]) {
report(css.includes(`max-width: ${breakpoint}`), `缺少 ${breakpoint} 响应式断点`); report(css.includes(`max-width: ${breakpoint}`), `缺少 ${breakpoint} 响应式断点`);
} }
const requiredCopy = [ const requiredCopy = [
"在本地管理笔记和待办", "桌面助手",
"AI 编程工具台",
"Windows、macOS、Linux",
"统信 UOS",
"银河麒麟",
"海光 · 兆芯(x64",
"鲲鹏 · 飞腾(ARM64",
"独创的统一 Agent Runtime",
"直连模型、OpenCode、Continue",
"DeepSeek Harness",
"魔法笔记",
"智能心跳",
"文件、截图、应用窗口、剪贴板和离线语音",
"微信、企业微信和钉钉", "微信、企业微信和钉钉",
"单条消息最多 4 个附件",
"OpenCode 与 Continue",
"单次最多添加 8 个附件,支持同时传入 5 张图片",
"auto、low、medium、high",
"下载入口始终指向最新正式 Release",
"主要安全边界",
]; ];
for (const copy of requiredCopy) { for (const copy of requiredCopy) {
@@ -98,7 +113,7 @@ report(
const releaseLinks = [ const releaseLinks = [
...html.matchAll(/<a\b(?=[^>]*data-release-link)[^>]*>/g), ...html.matchAll(/<a\b(?=[^>]*data-release-link)[^>]*>/g),
].map((match) => match[0]); ].map((match) => match[0]);
report(releaseLinks.length >= 5, "缺少完整的官方下载入口"); report(releaseLinks.length >= 3, "缺少三个桌面系统的官方下载入口");
for (const link of releaseLinks) { for (const link of releaseLinks) {
report( report(
/href="https:\/\/github\.com\/mesalogo\/goodbuddy\/releases\/latest"/.test(link), /href="https:\/\/github\.com\/mesalogo\/goodbuddy\/releases\/latest"/.test(link),
+177 -521
View File
@@ -553,11 +553,36 @@ p {
} }
.product-stage { .product-stage {
--scene-tilt-x: 0deg;
--scene-tilt-y: 0deg;
--spotlight-x: 50%;
--spotlight-y: 50%;
position: relative; position: relative;
z-index: 1; z-index: 1;
min-height: 540px; min-height: 540px;
} }
.product-stage::before {
position: absolute;
z-index: -1;
inset: -96px;
background: radial-gradient(
circle 270px at var(--spotlight-x) var(--spotlight-y),
color-mix(in srgb, var(--accent) 18%, transparent) 0,
color-mix(in srgb, var(--accent) 8%, transparent) 42%,
transparent 74%
);
content: "";
filter: blur(36px);
opacity: 0;
pointer-events: none;
transition: opacity var(--motion-normal) ease-out;
}
.product-stage.is-tilting::before {
opacity: 1;
}
.stage-glow { .stage-glow {
position: absolute; position: absolute;
border-radius: 50%; border-radius: 50%;
@@ -583,6 +608,8 @@ p {
} }
.app-window { .app-window {
--window-scale: 1;
--window-translate-x: 0%;
position: absolute; position: absolute;
top: 22px; top: 22px;
left: 0; left: 0;
@@ -592,8 +619,47 @@ p {
border-radius: 18px; border-radius: 18px;
background: var(--surface-raised); background: var(--surface-raised);
box-shadow: var(--shadow-dialog); box-shadow: var(--shadow-dialog);
transform: perspective(1400px) rotateY(-5deg) rotateX(2deg); transform:
transform-origin: left center; translateX(var(--window-translate-x))
perspective(1400px)
scale(var(--window-scale))
rotateX(var(--scene-tilt-x))
rotateY(var(--scene-tilt-y));
transform-origin: center center;
transform-style: preserve-3d;
transition:
transform var(--motion-slow) ease-out,
box-shadow var(--motion-normal) ease-out;
will-change: transform;
}
.app-window::after {
position: absolute;
z-index: 5;
inset: -18px;
border-radius: inherit;
background: radial-gradient(
circle 260px at var(--spotlight-x) var(--spotlight-y),
color-mix(in srgb, var(--text-on-accent) 18%, transparent),
color-mix(in srgb, var(--accent) 7%, transparent) 34%,
transparent 76%
);
content: "";
filter: blur(18px);
opacity: 0;
pointer-events: none;
transition: opacity var(--motion-normal) ease-out;
}
.product-stage.is-tilting .app-window {
box-shadow:
0 36px 90px color-mix(in srgb, var(--text-primary) 18%, transparent),
0 0 34px color-mix(in srgb, var(--accent) 16%, transparent);
transition-duration: 70ms;
}
.product-stage.is-tilting .app-window::after {
opacity: 0.72;
} }
.window-bar { .window-bar {
@@ -920,6 +986,24 @@ p {
background: var(--surface-overlay); background: var(--surface-overlay);
box-shadow: var(--shadow-card); box-shadow: var(--shadow-card);
backdrop-filter: blur(14px); backdrop-filter: blur(14px);
transform:
perspective(1400px)
rotateX(var(--scene-tilt-x))
rotateY(var(--scene-tilt-y))
translateZ(28px);
transform-origin: center;
transform-style: preserve-3d;
transition:
transform var(--motion-slow) ease-out,
box-shadow var(--motion-normal) ease-out;
will-change: transform;
}
.product-stage.is-tilting .floating-card {
box-shadow:
0 18px 38px color-mix(in srgb, var(--text-primary) 15%, transparent),
0 0 22px color-mix(in srgb, var(--accent) 12%, transparent);
transition-duration: 70ms;
} }
.floating-card > span:last-child { .floating-card > span:last-child {
@@ -1140,317 +1224,8 @@ p {
color: var(--accent); color: var(--accent);
} }
.release-section { .download-section {
border-block: 1px solid var(--border-subtle); padding-top: var(--space-20);
background: var(--surface-raised);
}
.release-heading {
display: grid;
grid-template-columns: 240px 1fr;
align-items: center;
gap: var(--space-16);
margin-bottom: var(--space-12);
}
.release-heading > div:last-child {
max-width: 680px;
}
.release-heading h2 {
margin-bottom: var(--space-4);
}
.release-heading p:last-child {
margin-bottom: 0;
}
.version-lockup {
position: relative;
display: flex;
height: 160px;
flex-direction: column;
align-items: center;
justify-content: center;
overflow: hidden;
border: 1px solid var(--border-default);
border-radius: var(--radius-large);
background:
linear-gradient(140deg, color-mix(in srgb, var(--accent) 15%, transparent), color-mix(in srgb, var(--accent-mint) 14%, transparent)),
var(--surface-subtle);
}
.version-lockup::before,
.version-lockup::after {
position: absolute;
width: 150px;
height: 150px;
border: 1px solid color-mix(in srgb, var(--accent) 25%, transparent);
border-radius: 50%;
content: "";
}
.version-lockup::before {
top: -100px;
right: -50px;
}
.version-lockup::after {
bottom: -110px;
left: -30px;
}
.version-lockup span {
color: var(--text-muted);
font-family: "SFMono-Regular", Consolas, monospace;
font-size: var(--font-caption);
letter-spacing: 0.24em;
}
.version-lockup strong {
font-size: 3.4rem;
letter-spacing: -0.07em;
}
.release-list {
padding: 0;
margin: 0;
border-top: 1px solid var(--border-default);
list-style: none;
}
.release-item {
display: grid;
grid-template-columns: 56px minmax(280px, 0.8fr) minmax(340px, 1.2fr);
align-items: center;
gap: var(--space-8);
min-height: 210px;
padding-block: var(--space-8);
border-bottom: 1px solid var(--border-default);
}
.release-index {
align-self: start;
padding-top: 5px;
color: var(--text-muted);
font-family: "SFMono-Regular", Consolas, monospace;
font-size: 0.6875rem;
}
.release-copy h3 {
margin: var(--space-3) 0;
font-size: 1.45rem;
}
.release-copy p {
margin-bottom: 0;
}
.release-label {
display: inline-flex;
padding: 4px 9px;
border: 1px solid color-mix(in srgb, var(--accent) 28%, var(--border-default));
border-radius: var(--radius-pill);
background: var(--accent-subtle);
color: var(--accent);
font-size: var(--font-caption);
font-weight: 800;
letter-spacing: 0.06em;
text-transform: uppercase;
}
.release-label--preview {
border-color: color-mix(in srgb, var(--warning) 30%, var(--border-default));
background: color-mix(in srgb, var(--warning) 10%, var(--surface-subtle));
color: var(--warning);
}
.release-visual {
min-height: 130px;
padding: var(--space-6);
border: 1px solid var(--border-subtle);
border-radius: var(--radius-card);
background: var(--surface-subtle);
}
.route-visual {
position: relative;
}
.route-node {
position: absolute;
z-index: 2;
display: grid;
min-width: 64px;
min-height: 34px;
padding: var(--space-2);
place-items: center;
border: 1px solid var(--border-control);
border-radius: var(--radius-control);
background: var(--surface-raised);
color: var(--text-secondary);
font-size: 0.6875rem;
font-weight: 700;
}
.route-node--main {
top: 47px;
left: var(--space-6);
border-color: var(--accent-selected);
background: var(--accent-subtle);
color: var(--accent);
}
.route-node--sub-one {
top: 18px;
right: var(--space-6);
}
.route-node--sub-two {
right: var(--space-6);
bottom: 18px;
}
.route-line {
position: absolute;
left: 96px;
width: calc(100% - 185px);
height: 1px;
background: var(--border-control);
transform-origin: left center;
}
.route-line--one {
top: 62px;
transform: rotate(-11deg);
}
.route-line--two {
top: 72px;
transform: rotate(11deg);
}
.channel-visual {
display: grid;
grid-template-columns: repeat(3, 1fr);
align-items: center;
gap: var(--space-2);
}
.channel-visual span {
display: flex;
min-height: 72px;
flex-direction: column;
align-items: center;
justify-content: center;
border: 1px solid var(--border-default);
border-radius: var(--radius-control);
background: var(--surface-raised);
}
.channel-visual b {
font-size: 0.75rem;
}
.channel-visual small {
color: var(--warning);
font-size: var(--font-caption);
}
.channel-visual .is-experimental {
border-style: dashed;
}
.channel-visual .is-experimental small {
color: var(--text-muted);
}
.attachment-visual {
display: grid;
grid-template-columns: 1fr auto auto;
align-items: center;
gap: var(--space-8);
}
.attachment-stack {
position: relative;
height: 76px;
}
.attachment-stack span {
position: absolute;
top: 8px;
left: 28%;
width: 66px;
height: 66px;
border: 1px solid var(--border-control);
border-radius: var(--radius-control);
background:
linear-gradient(145deg, color-mix(in srgb, var(--accent) 22%, transparent), color-mix(in srgb, var(--accent-mint) 20%, transparent)),
var(--surface-raised);
}
.attachment-stack span:nth-child(2) {
transform: translateX(-15px) rotate(-8deg);
}
.attachment-stack span:nth-child(3) {
transform: translateX(15px) rotate(8deg);
}
.attachment-visual > div:not(:first-child) {
display: flex;
flex-direction: column;
align-items: center;
}
.attachment-visual strong {
font-size: 1.8rem;
}
.attachment-visual small {
color: var(--text-muted);
font-size: var(--font-caption);
}
.quality-visual {
display: grid;
grid-template-columns: repeat(4, 1fr);
align-items: center;
gap: var(--space-2);
}
.quality-visual span {
display: grid;
min-height: 38px;
place-items: center;
border: 1px solid var(--border-default);
border-radius: var(--radius-control);
background: var(--surface-raised);
color: var(--text-muted);
font-family: "SFMono-Regular", Consolas, monospace;
font-size: var(--font-caption);
}
.quality-visual .is-selected {
border-color: var(--accent-selected);
background: var(--accent-subtle);
color: var(--accent);
font-weight: 800;
}
.section-heading--center {
display: flex;
max-width: 780px;
flex-direction: column;
align-items: center;
gap: 0;
margin-inline: auto;
text-align: center;
}
.section-heading--center p {
max-width: 680px;
} }
.download-grid { .download-grid {
@@ -1509,69 +1284,83 @@ p {
margin-top: var(--space-2); margin-top: var(--space-2);
} }
.release-notice { .domestic-support {
display: flex; display: grid;
max-width: 760px; grid-template-columns: minmax(260px, 0.9fr) minmax(420px, 1.1fr);
align-items: center; align-items: center;
gap: var(--space-8);
padding: var(--space-6);
margin-top: var(--space-6);
border: 1px solid color-mix(in srgb, var(--accent) 24%, var(--border-default));
border-radius: var(--radius-card);
background:
radial-gradient(circle at 100% 0, color-mix(in srgb, var(--accent-mint) 11%, transparent), transparent 42%),
var(--surface-raised);
}
.domestic-support h3 {
margin-bottom: var(--space-2);
}
.domestic-support > div:first-child > p:last-child {
margin-bottom: 0;
font-size: 0.75rem;
}
.domestic-support__items {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: var(--space-3); gap: var(--space-3);
padding: var(--space-4); }
margin: var(--space-8) auto 0;
.domestic-support__items div {
display: flex;
min-height: 72px;
flex-direction: column;
justify-content: center;
padding: var(--space-3) var(--space-4);
border: 1px solid var(--border-default); border: 1px solid var(--border-default);
border-radius: var(--radius-control); border-radius: var(--radius-control);
background: var(--surface-subtle); background: var(--surface-subtle);
} }
.release-notice svg { .domestic-support__items span {
width: 22px;
flex: 0 0 auto;
fill: none;
stroke: var(--text-muted);
stroke-linecap: round;
stroke-linejoin: round;
stroke-width: 1.8;
}
.release-notice div {
display: flex;
flex-direction: column;
}
.release-notice strong {
font-size: 0.75rem;
}
.release-notice span {
color: var(--text-muted); color: var(--text-muted);
font-size: 0.6875rem; font-size: var(--font-caption);
} }
.security-section { .domestic-support__items strong {
margin-top: var(--space-1);
font-size: 0.8125rem;
}
.assistant-section {
border-block: 1px solid color-mix(in srgb, var(--text-on-inverse) 12%, transparent); border-block: 1px solid color-mix(in srgb, var(--text-on-inverse) 12%, transparent);
background: var(--surface-inverse); background: var(--surface-inverse);
color: var(--text-on-inverse); color: var(--text-on-inverse);
} }
.security-grid { .assistant-grid {
display: grid; display: grid;
grid-template-columns: minmax(0, 0.8fr) minmax(520px, 1.2fr); grid-template-columns: minmax(0, 0.8fr) minmax(520px, 1.2fr);
gap: 96px; gap: 96px;
} }
.security-intro { .assistant-intro {
position: sticky; position: sticky;
top: 112px; top: 112px;
align-self: start; align-self: start;
} }
.security-intro h2 { .assistant-intro h2 {
color: var(--text-on-inverse); color: var(--text-on-inverse);
} }
.security-intro p:not(.kicker) { .assistant-intro p:not(.kicker) {
color: color-mix(in srgb, var(--text-on-inverse) 70%, transparent); color: color-mix(in srgb, var(--text-on-inverse) 70%, transparent);
} }
.security-shield { .assistant-mark {
display: grid; display: grid;
width: 76px; width: 76px;
height: 76px; height: 76px;
@@ -1583,7 +1372,7 @@ p {
color: var(--accent-cyan); color: var(--accent-cyan);
} }
.security-shield svg { .assistant-mark svg {
width: 42px; width: 42px;
fill: none; fill: none;
stroke: currentColor; stroke: currentColor;
@@ -1607,11 +1396,11 @@ p {
text-underline-offset: 4px; text-underline-offset: 4px;
} }
.security-list { .assistant-list {
border-top: 1px solid color-mix(in srgb, var(--text-on-inverse) 18%, transparent); border-top: 1px solid color-mix(in srgb, var(--text-on-inverse) 18%, transparent);
} }
.security-list article { .assistant-list article {
display: grid; display: grid;
grid-template-columns: 42px 1fr; grid-template-columns: 42px 1fr;
gap: var(--space-6); gap: var(--space-6);
@@ -1619,112 +1408,23 @@ p {
border-bottom: 1px solid color-mix(in srgb, var(--text-on-inverse) 18%, transparent); border-bottom: 1px solid color-mix(in srgb, var(--text-on-inverse) 18%, transparent);
} }
.security-number { .assistant-number {
padding-top: 4px; padding-top: 4px;
color: color-mix(in srgb, var(--text-on-inverse) 42%, transparent); color: color-mix(in srgb, var(--text-on-inverse) 42%, transparent);
font-family: "SFMono-Regular", Consolas, monospace; font-family: "SFMono-Regular", Consolas, monospace;
font-size: 0.6875rem; font-size: 0.6875rem;
} }
.security-list h3 { .assistant-list h3 {
margin-bottom: var(--space-3); margin-bottom: var(--space-3);
color: var(--text-on-inverse); color: var(--text-on-inverse);
} }
.security-list p { .assistant-list p {
margin-bottom: 0; margin-bottom: 0;
color: color-mix(in srgb, var(--text-on-inverse) 67%, transparent); color: color-mix(in srgb, var(--text-on-inverse) 67%, transparent);
} }
.final-cta {
padding-block: var(--space-20);
}
.cta-card {
position: relative;
display: grid;
grid-template-columns: 1fr auto;
align-items: center;
gap: var(--space-12);
padding: var(--space-16);
overflow: hidden;
border: 1px solid color-mix(in srgb, var(--accent) 20%, var(--border-default));
border-radius: var(--radius-large);
background:
radial-gradient(circle at 85% 10%, color-mix(in srgb, var(--accent-mint) 14%, transparent), transparent 26%),
radial-gradient(circle at 0 100%, color-mix(in srgb, var(--accent) 15%, transparent), transparent 32%),
var(--surface-raised);
}
.cta-card > div:not(.cta-orbit) {
position: relative;
z-index: 2;
}
.cta-card h2 {
max-width: 760px;
margin-bottom: var(--space-4);
font-size: clamp(2rem, 4vw, 3.4rem);
}
.cta-card p:last-child {
margin-bottom: 0;
}
.cta-actions {
display: flex;
min-width: 170px;
flex-direction: column;
gap: var(--space-3);
}
.cta-orbit,
.cta-orbit::before,
.cta-orbit::after {
position: absolute;
border: 1px solid color-mix(in srgb, var(--accent) 15%, transparent);
border-radius: 50%;
}
.cta-orbit {
top: -190px;
right: -100px;
width: 500px;
height: 500px;
}
.cta-orbit::before {
inset: 55px;
content: "";
}
.cta-orbit::after {
inset: 115px;
content: "";
}
.cta-orbit span {
position: absolute;
border-radius: 50%;
background: var(--accent);
box-shadow: 0 0 20px color-mix(in srgb, var(--accent) 60%, transparent);
}
.cta-orbit span:first-child {
top: 100px;
left: 28px;
width: 8px;
height: 8px;
}
.cta-orbit span:last-child {
right: 80px;
bottom: 62px;
width: 12px;
height: 12px;
background: var(--accent-mint);
}
.site-footer { .site-footer {
padding-block: var(--space-12); padding-block: var(--space-12);
border-top: 1px solid var(--border-subtle); border-top: 1px solid var(--border-subtle);
@@ -1788,16 +1488,16 @@ p {
} }
.app-window { .app-window {
--window-scale: 0.9;
width: 620px; width: 620px;
transform: scale(0.9) perspective(1400px) rotateY(-4deg) rotateX(2deg); transform-origin: center top;
transform-origin: left top;
} }
.floating-card--approval { .floating-card--approval {
right: -10px; right: -10px;
} }
.security-grid { .assistant-grid {
gap: var(--space-16); gap: var(--space-16);
} }
} }
@@ -1853,8 +1553,8 @@ p {
} }
.app-window { .app-window {
--window-scale: 0.93;
width: 680px; width: 680px;
transform: scale(0.93);
transform-origin: center top; transform-origin: center top;
} }
@@ -1900,15 +1600,6 @@ p {
grid-column: span 2; grid-column: span 2;
} }
.release-item {
grid-template-columns: 40px minmax(230px, 0.8fr) minmax(300px, 1.2fr);
gap: var(--space-4);
}
.release-visual {
padding: var(--space-4);
}
.download-grid { .download-grid {
grid-template-columns: 1fr; grid-template-columns: 1fr;
max-width: 680px; max-width: 680px;
@@ -1920,30 +1611,24 @@ p {
align-items: center; align-items: center;
} }
.domestic-support {
grid-template-columns: 1fr;
}
.button--download { .button--download {
grid-column: auto; grid-column: auto;
width: auto; width: auto;
margin-top: 0; margin-top: 0;
} }
.security-grid { .assistant-grid {
grid-template-columns: 1fr; grid-template-columns: 1fr;
} }
.security-intro { .assistant-intro {
position: static; position: static;
max-width: 720px; max-width: 720px;
} }
.cta-card {
grid-template-columns: 1fr;
padding: var(--space-12);
}
.cta-actions {
min-width: 0;
flex-direction: row;
}
} }
@media (max-width: 719px) { @media (max-width: 719px) {
@@ -2047,9 +1732,10 @@ p {
} }
.app-window { .app-window {
--window-scale: 0.59;
--window-translate-x: -50%;
left: 50%; left: 50%;
width: 680px; width: 680px;
transform: translateX(-50%) scale(0.59);
transform-origin: top center; transform-origin: top center;
} }
@@ -2118,48 +1804,6 @@ p {
margin-bottom: var(--space-6); margin-bottom: var(--space-6);
} }
.release-heading {
grid-template-columns: 1fr;
gap: var(--space-8);
}
.version-lockup {
width: 100%;
max-width: 320px;
}
.release-item {
grid-template-columns: 32px 1fr;
padding-block: var(--space-8);
}
.release-visual {
grid-column: 1 / -1;
min-width: 0;
margin-top: var(--space-2);
}
.channel-visual {
grid-template-columns: 1fr;
}
.attachment-visual {
grid-template-columns: 1fr 1fr;
}
.attachment-stack {
grid-column: 1 / -1;
}
.quality-visual {
grid-template-columns: repeat(2, 1fr);
}
.section-heading--center {
text-align: left;
align-items: flex-start;
}
.download-card { .download-card {
grid-template-columns: auto 1fr; grid-template-columns: auto 1fr;
} }
@@ -2169,32 +1813,28 @@ p {
width: 100%; width: 100%;
} }
.release-notice { .domestic-support {
align-items: flex-start; padding: var(--space-4);
} }
.security-grid { .domestic-support__items {
grid-template-columns: 1fr;
}
.assistant-grid {
gap: var(--space-12); gap: var(--space-12);
} }
.security-shield { .assistant-mark {
width: 64px; width: 64px;
height: 64px; height: 64px;
} }
.security-list article { .assistant-list article {
grid-template-columns: 32px 1fr; grid-template-columns: 32px 1fr;
gap: var(--space-3); gap: var(--space-3);
} }
.cta-card {
padding: var(--space-8) var(--space-6);
}
.cta-actions {
flex-direction: column;
}
.footer-inner { .footer-inner {
grid-template-columns: 1fr; grid-template-columns: 1fr;
gap: var(--space-4); gap: var(--space-4);
@@ -2228,4 +1868,20 @@ p {
.button:not(.is-disabled):hover { .button:not(.is-disabled):hover {
transform: none; transform: none;
} }
.product-stage::before,
.app-window::after {
display: none;
}
.app-window {
transform:
translateX(var(--window-translate-x))
perspective(1400px)
scale(var(--window-scale)) !important;
}
.floating-card {
transform: none !important;
}
} }