style(admin): 管理台全局样式升级——卡片高光、表格统一润色

- .card 圆角 xl→2xl,顶部加内高光(亮色 sheen/暗色 rim-light)
- 卡片内表格:thead 统一紫罗兰渐变底色,tbody 行 hover 统一紫光
  洗色 + 首列内描边,不再依赖各页散落的 hover:bg-white 工具类
- AdminLayout:顶栏 Admin 标签改紫→青渐变胶囊,侧栏 logo 副标
  改渐变文字

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
2026-10-14 17:24:47 +08:00
co-authored by Devin
parent e7a4613bac
commit effe76d83f
2 changed files with 42 additions and 8 deletions
+12 -2
View File
@@ -55,7 +55,7 @@ watch(() => route.path, () => {
<Logo v-else :size="32" /> <Logo v-else :size="32" />
<div class="leading-tight min-w-0"> <div class="leading-tight min-w-0">
<div class="text-sm font-extrabold truncate tracking-tight text-[color:var(--fg)]">{{ site.title }}</div> <div class="text-sm font-extrabold truncate tracking-tight text-[color:var(--fg)]">{{ site.title }}</div>
<div class="text-[11px] font-bold uppercase tracking-widest text-[color:var(--m-orange)] truncate">Admin</div> <div class="admin-tag text-[11px] font-bold uppercase tracking-widest truncate">Admin</div>
</div> </div>
</router-link> </router-link>
@@ -118,7 +118,7 @@ watch(() => route.path, () => {
</div> </div>
<header class="relative z-10 h-14 shrink-0 border-b border-b-[color:var(--ink-soft)] bg-[var(--app-bg)]/60 backdrop-blur-xl flex items-center px-8"> <header class="relative z-10 h-14 shrink-0 border-b border-b-[color:var(--ink-soft)] bg-[var(--app-bg)]/60 backdrop-blur-xl flex items-center px-8">
<div class="text-[10px] uppercase tracking-[0.25em] text-[color:var(--m-orange)] font-extrabold mr-3">Admin</div> <div class="admin-badge text-[10px] uppercase tracking-[0.25em] font-extrabold mr-3 px-2.5 py-1 rounded-lg text-white select-none">Admin</div>
<div class="text-[color:var(--fg-faint)] mr-3">/</div> <div class="text-[color:var(--fg-faint)] mr-3">/</div>
<h1 class="text-sm font-semibold tracking-tight text-[color:var(--fg)]">{{ currentLabel }}</h1> <h1 class="text-sm font-semibold tracking-tight text-[color:var(--fg)]">{{ currentLabel }}</h1>
</header> </header>
@@ -137,6 +137,16 @@ watch(() => route.path, () => {
</template> </template>
<style scoped> <style scoped>
.admin-tag {
background: linear-gradient(120deg, #7c5cfc, #22d3ee);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
.admin-badge {
background: linear-gradient(120deg, #7c5cfc, #5f6cf8 60%, #22d3ee 140%);
box-shadow: 0 4px 14px var(--accent-glow);
}
.admin-link { .admin-link {
position: relative; position: relative;
display: flex; display: flex;
+30 -6
View File
@@ -327,6 +327,28 @@ button:not(:disabled), [role="button"]:not([aria-disabled="true"]) { cursor: poi
own utility so vertical clipping / rounded corners are preserved. */ own utility so vertical clipping / rounded corners are preserved. */
.card:has(> table) { overflow-x: auto; } .card:has(> table) { overflow-x: auto; }
/* ===== Admin table polish =====
Every data table lives in a `.card` and views hand-roll their own
th/td utilities — these rules unify the reading of all of them:
a faint violet band on the header row and a violet wash on row hover.
Scoped to `.theme-text` (the admin main wrapper) so public pages with
over-media tables are untouched; specificity outranks the per-view
Tailwind hover utilities and the light-mode white rescue. */
.theme-text .card table thead {
background: linear-gradient(180deg, rgb(124 92 252 / 0.07), rgb(124 92 252 / 0.025));
}
html.dark .theme-text .card table thead {
background: linear-gradient(180deg, rgb(139 92 246 / 0.13), rgb(139 92 246 / 0.05));
}
.theme-text .card table tbody tr { transition: background-color 0.15s ease; }
.theme-text .card table tbody tr:hover { background-color: rgb(124 92 252 / 0.08); }
html.dark .theme-text .card table tbody tr:hover { background-color: rgb(139 92 246 / 0.11); }
/* Checkbox column + first data column get a hair more air against the
card edge so dense tables don't feel cramped. */
.theme-text .card table tbody tr:hover :is(td, th):first-child {
box-shadow: inset 2px 0 0 rgb(124 92 252 / 0.55);
}
::-webkit-scrollbar { width: 9px; height: 9px; } ::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-thumb { background: rgb(24 21 36 / 0.2); border-radius: 5px; border: 2px solid transparent; background-clip: content-box; } ::-webkit-scrollbar-thumb { background: rgb(24 21 36 / 0.2); border-radius: 5px; border: 2px solid transparent; background-clip: content-box; }
::-webkit-scrollbar-thumb:hover { background: rgb(24 21 36 / 0.38); background-clip: content-box; } ::-webkit-scrollbar-thumb:hover { background: rgb(24 21 36 / 0.38); background-clip: content-box; }
@@ -545,7 +567,7 @@ html.dark .memphis-dots {
background: rgb(255 255 255 / 0.04); background: rgb(255 255 255 / 0.04);
border-color: rgb(255 255 255 / 0.1); border-color: rgb(255 255 255 / 0.1);
color: rgb(255 255 255 / 0.92); color: rgb(255 255 255 / 0.92);
box-shadow: var(--glass-shadow); box-shadow: var(--glass-shadow), inset 0 1px 0 rgb(255 255 255 / 0.07);
} }
.public-dark .field { .public-dark .field {
background: rgb(255 255 255 / 0.04); background: rgb(255 255 255 / 0.04);
@@ -626,14 +648,16 @@ html.dark .memphis-dots {
.public-dark .hover\:bg-slate-100:hover { background: rgb(255 255 255 / 0.06); } .public-dark .hover\:bg-slate-100:hover { background: rgb(255 255 255 / 0.06); }
@layer components { @layer components {
/* surfaces — frosted card with a hairline glass edge + soft shadow */ /* surfaces — frosted card with a hairline glass edge + soft shadow.
The inset top line is the light's "sheen" on the glass — barely
visible on white, reads as a subtle rim-light in dark mode. */
.card { .card {
@apply rounded-xl; @apply rounded-2xl;
background: var(--surface); background: var(--surface);
-webkit-backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(16px);
backdrop-filter: blur(14px); backdrop-filter: blur(16px);
border: 1px solid var(--glass-border); border: 1px solid var(--glass-border);
box-shadow: var(--glass-shadow); box-shadow: var(--glass-shadow), inset 0 1px 0 rgb(255 255 255 / 0.55);
} }
/* buttons — each variant is self-contained (Tailwind v4 can't @apply a custom class) */ /* buttons — each variant is self-contained (Tailwind v4 can't @apply a custom class) */