fix(web): 控制台界面细节与 uhd_web 控件规范对齐

- 顶栏搜索移进右侧玻璃胶囊;输入框改淡玻璃(边线 0.46 → 0.16,悬停加深,聚焦 / 出错保留光晕)
- 新增 SegmentedControl(滑动 seg-thumb),替换站点、下载、订阅、文件、智能体列表及对话框里的实心选中块;Tabs 改为同一枚滑块
- 开关型按钮统一 outline + aria-pressed 选中外观;页头 / 工具栏次操作描边、图标钮描边圆;文件排序改 Select;下载总速度加标签
- 分页一页放得下时只留总数、空列表不渲染、按容器宽度收起按钮
- 运行状态存储区重排;智能体列表页与会话页共用外壳路由,标题与左栏不再重挂载
- 站点卡片「⋯」不再单独换行;设置导航、状态计数、多选条件改玻璃选中态

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Cxwgnn2pbzQ7rXv3rq7fei
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-10-08 12:02:48 +08:00
1 parent 8ff1817845
commit c9b4ceb301
32 files changed
+753 -639

No files matched your search

@@ -13,9 +13,9 @@ import {
DialogTitle,
} from "~/components/ui/dialog.tsx";
import { Input } from "~/components/ui/input.tsx";
import { SegmentedControl } from "~/components/ui/segmented.tsx";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "~/components/ui/select.tsx";
import { errorMessage } from "~/lib/api.ts";
import { cn } from "~/lib/utils.ts";
// 站点内添加 RSS:站点固定,账号 / 解析器 / 轮询由服务端按站点带出;只填地址、用途、可选备注。
// 保存后立即抓一次,在对话框里等结果(条目数或错误)。
@@ -163,28 +163,14 @@ export function SiteFeedDialog({
</p>
) : null}
<div className="mb-3" role="radiogroup" aria-label="用途">
<div className="mb-3">
<p className="mb-1.5 text-caption font-medium text-foreground">用途</p>
<div className="inline-flex flex-wrap gap-1 rounded-xl border border-border p-1">
{PURPOSES.map((p) => (
// biome-ignore lint/a11y/useSemanticElements: 分段按钮,radio 语义由 role 表达
<button
key={p.value}
type="button"
role="radio"
aria-checked={purpose === p.value}
onClick={() => setPurpose(p.value)}
className={cn(
"rounded-lg px-3 py-1.5 text-caption transition-colors",
purpose === p.value
? "bg-foreground text-background"
: "text-muted-foreground hover:bg-accent hover:text-foreground",
)}
>
{p.label}
</button>
))}
</div>
<SegmentedControl
label="用途"
value={purpose}
onChange={setPurpose}
options={PURPOSES.map((p) => ({ value: p.value, label: p.label }))}
/>
<p className="mt-1.5 text-caption text-muted-foreground">
{PURPOSES.find((p) => p.value === purpose)?.hint}
</p>