diff --git a/stash-web/src/App.css b/stash-web/src/App.css
index 6a7d9a9..3477ded 100644
--- a/stash-web/src/App.css
+++ b/stash-web/src/App.css
@@ -298,70 +298,9 @@
background-color: var(--su-color-primary);
}
-/* ---------- 应用条目 ---------- */
+/* ---------- 应用条目 / 图文白卡 ---------- */
-.app-card {
- display: flex;
- align-items: center;
- gap: var(--su-space-4);
- padding: var(--su-space-2) 0;
- border-radius: var(--su-radius-sm);
-}
-
-.app-card:hover .app-card-name {
- color: var(--su-color-primary);
-}
-
-.app-card-info {
- display: flex;
- flex-direction: column;
- gap: var(--su-space-1);
- min-width: 0;
-}
-
-/* 旧版应用头像是 48px 圆形,右下角是 10px 小认证标 */
-.app-card-avatar {
- width: 48px;
- height: 48px;
- font-size: var(--su-font-size-lg);
-}
-
-.app-card-avatar > span + span {
- width: 10px;
- height: 10px;
- border-width: 1px;
- /* 6px 不是文字尺寸:这是 10px 圆标里的一枚「✓」字形,按图标对待;
- 设计系统的字阶(12 起)不覆盖这种装饰字形 */
- font-size: 6px;
-}
-
-/* ---------- 图文白卡 ---------- */
-
-.ces-card {
- overflow: hidden;
- transition: transform var(--su-duration-fast) var(--su-ease-in-out);
-}
-
-.ces-card:hover {
- transform: translateY(-2px);
-}
-
-.ces-body {
- display: flex;
- flex-direction: column;
- gap: var(--su-space-1);
- padding: var(--su-space-3);
- text-align: left;
-}
-
-.ces-body--button {
- width: 100%;
- cursor: pointer;
-}
-
-.ces-body--button:hover {
- background-color: var(--su-bg-subtle);
-}
+/* 条目行的版式在 @stash/ui 的 EntryRow,图文卡在 EntryTile,这里不再有手写卡片外壳 */
/* ---------- 详情 ---------- */
@@ -860,7 +799,6 @@
}
@media (prefers-reduced-motion: reduce) {
- .app-card,
.related-item,
.link-button {
transition: none;
diff --git a/stash-web/src/components/admin/AdminNext.tsx b/stash-web/src/components/admin/AdminNext.tsx
index be85e2f..69ea500 100644
--- a/stash-web/src/components/admin/AdminNext.tsx
+++ b/stash-web/src/components/admin/AdminNext.tsx
@@ -178,6 +178,28 @@ export function AdminNext() {
toast.success('侧边栏已保存')
}
+ /** 页头的明暗切换:写回 site.theme,前后台一起变 */
+ const themeSetting = draft?.site.theme ?? document?.settings.site.theme ?? 'auto'
+ const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches
+ const isDark = themeSetting === 'dark' || (themeSetting === 'auto' && prefersDark)
+
+ const toggleTheme = async () => {
+ if (document === null || draft === null) return
+ const next = isDark ? 'light' : 'dark'
+ setSaving(true)
+ const result = await saveSettings(document.version, {
+ ...draft,
+ site: { ...draft.site, theme: next },
+ })
+ setSaving(false)
+ if (!result.ok) {
+ toast.error(result.error)
+ return
+ }
+ setDocument(result.document)
+ setDraft(clone(result.document.settings))
+ }
+
const confirmDelete = async () => {
if (pending === null) return
setDeleting(true)
@@ -209,6 +231,12 @@ export function AdminNext() {