diff --git a/design/ui_kits/desktop/DesktopShared.jsx b/design/ui_kits/desktop/DesktopShared.jsx
index 9bca961..a540f39 100644
--- a/design/ui_kits/desktop/DesktopShared.jsx
+++ b/design/ui_kits/desktop/DesktopShared.jsx
@@ -80,13 +80,18 @@ function MacWindow({ title, width = 460, children, style }) {
overflow: 'hidden', fontFamily: 'var(--font-sans)', ...style,
}}>
- {title}
+ {/* 标题绝对居中(mac 原生窗口习惯),永不与红绿灯重叠 */}
+ {title}
{children}
diff --git a/design/ui_kits/desktop/SettingsTray.jsx b/design/ui_kits/desktop/SettingsTray.jsx
index 17ea23e..0ef90ca 100644
--- a/design/ui_kits/desktop/SettingsTray.jsx
+++ b/design/ui_kits/desktop/SettingsTray.jsx
@@ -47,16 +47,33 @@ function TrayMenu() {
);
}
+// 设置屏(2026-07-11 改版):分组从「灰字 + 通栏细线」改为卡片体块——
+// 组标题在卡外、每组一张 radius-lg 卡片、卡内行以内嵌分隔线相隔;
+// 载入时分组 4 段轻微上浮淡入(对齐浮层动效语言,120/40ms 级差)。
+const ddSettingsCss = `
+@keyframes dd-set-in { from { opacity: 0; transform: translateY(4px); } }
+.dd-set-group { animation: dd-set-in var(--dur-base) var(--ease-out) both; }
+`;
+if (typeof document !== 'undefined' && !document.getElementById('dd-settings-css')) {
+ const s = document.createElement('style');
+ s.id = 'dd-settings-css';
+ s.textContent = ddSettingsCss;
+ document.head.appendChild(s);
+}
+
function SettingsWindow({ theme, onThemeChange }) {
- const { Switch, SettingRow, HotkeyCombo, Button, Badge, ProgressBar, Select } = window.DuduDesignSystem_2e0172;
+ const { Switch, SettingRow, HotkeyCombo, Button, Badge, ProgressBar, Select, Card } = window.DuduDesignSystem_2e0172;
const [autostart, setAutostart] = React.useState(true);
const [sound, setSound] = React.useState(false);
const [mic, setMic] = React.useState('MacBook Pro 麦克风');
- const Section = ({ title, children }) => (
-
-
{title}
- {children}
+ const Group = ({ title, order = 0, children }) => (
+
);
@@ -64,68 +81,70 @@ function SettingsWindow({ theme, onThemeChange }) {
return (
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+ {themeOptions.map(([val, lab]) => (
+
+ ))}
+
+
+
-
-
-
-
-
-
- {themeOptions.map(([val, lab]) => (
-
- ))}
-
-
-
-
-
-
-
-
-
- wang*** 余额充足
-
-
-
-
- 472 分钟
+
+
+ wang***
+ 余额充足
+
+
+
+ 472
+ 分钟
+
-
-
-
);
}
diff --git a/desktop/src/settings/SettingsApp.jsx b/desktop/src/settings/SettingsApp.jsx
index 2beafb1..1594111 100644
--- a/desktop/src/settings/SettingsApp.jsx
+++ b/desktop/src/settings/SettingsApp.jsx
@@ -2,6 +2,7 @@
import { useEffect, useState } from 'react';
import { Button } from '@dudu/design/components/core/Button';
import { Badge } from '@dudu/design/components/core/Badge';
+import { Card } from '@dudu/design/components/core/Card';
import { HotkeyCombo } from '@dudu/design/components/core/Kbd';
import { ProgressBar } from '@dudu/design/components/core/ProgressBar';
import { Switch } from '@dudu/design/components/forms/Switch';
@@ -12,20 +13,25 @@ import { setThemePref } from '../shared/theme';
const THEME_OPTIONS = [['system', '跟随系统'], ['light', '浅色'], ['dark', '深色']];
-function Section({ title, children }) {
+// 分组卡片(对齐原型 SettingsTray 2026-07-11 改版):组标题在卡外、
+// radius-lg 卡片体块、载入分组轻微上浮淡入(40ms 级差)。
+const groupCss = `
+@keyframes dd-set-in { from { opacity: 0; transform: translateY(4px); } }
+.dd-set-group { animation: dd-set-in var(--dur-base) var(--ease-out) both; }
+`;
+
+function Group({ title, order = 0, children }) {
return (
-
+
{title}
- {children}
+
{children}
);
}
-const Sep = () =>
;
-
export function SettingsApp() {
const [settings, setSettings] = useState({
hotkey: 'CmdOrCtrl+Shift+Space', mic: '', sound: false, autostart: true, theme: 'system',
@@ -70,92 +76,93 @@ export function SettingsApp() {
border: '1px solid var(--border-1)',
overflow: 'hidden', display: 'flex', flexDirection: 'column',
}}>
- {/* 自绘顶条:系统红绿灯悬浮于左上(trafficLightPosition 已对齐),留 76px;整条可拖拽 */}
+
+ {/* 自绘顶条:系统红绿灯悬浮于左上,标题绝对居中(mac 原生习惯,永不重叠);整条可拖拽 */}
- dudu 设置
+ dudu 设置
-
-
-
-
+
+
+
-
-
-
-
-
- update({ sound: v })} />
-
-
-
-
-
- update({ autostart: v })} />
-
-
-
- {THEME_OPTIONS.map(([val, lab]) => (
-
- ))}
-
-
-
-
-
-
- {me ? (
-
- {me.nickname_masked}
-
- {me.account_state === 'ok' ? '余额充足' : me.account_state === 'trial' ? '试用中' : '余额不足'}
-
+
+
+
+
+ update({ sound: v })} />
+
+
+
+
+
+ update({ autostart: v })} />
+
+
+
+ {THEME_OPTIONS.map(([val, lab]) => (
+
+ ))}
- ) : (
-
- )}
-
-
-
-
- {minutes} 分钟
+
+
+
+
+
+ {me ? (
+ <>
+ {me.nickname_masked}
+
+ {me.account_state === 'ok' ? '余额充足' : me.account_state === 'trial' ? '试用中' : '余额不足'}
+
+ >
+ ) : (
+
+ )}
+
+
+
+ {minutes}
+ 分钟
-
-
-
-
-
今日免费试用
-
{trialUsedMin} / 3 分钟
+
+
+
+ 今日免费试用
+ {trialUsedMin} / 3 分钟
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
);