feat(ui): 全站统一首页墨黑中性风格,固定亮色并移除光暗切换
- 全站紫/青/粉写死色值与 CSS 变量改为墨黑中性色板 - 移除 aurora 光斑/星点装饰,登录弹窗改纯白卡片 - theme.js 固定亮色并清除历史 dark 选择,删除前台/后台/画布切换按钮 - 模型页空状态文案对齐「保存渠道即自动同步」 Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
@@ -17,7 +17,7 @@ const html = computed(() => marked.parse(announcement.content.trim() || '暂无
|
|||||||
<div class="px-6 py-4 border-b border-b-[color:var(--ink-soft)] flex items-center justify-between gap-3 shrink-0">
|
<div class="px-6 py-4 border-b border-b-[color:var(--ink-soft)] flex items-center justify-between gap-3 shrink-0">
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<span class="w-7 h-7 rounded-lg text-white grid place-items-center"
|
<span class="w-7 h-7 rounded-lg text-white grid place-items-center"
|
||||||
style="background: linear-gradient(135deg, #7c5cfc, #22d3ee); box-shadow: 0 4px 12px var(--accent-glow)">
|
style="background: linear-gradient(135deg, #18181b, #52525b); box-shadow: 0 4px 12px var(--accent-glow)">
|
||||||
<Icon name="spark" class="w-4 h-4" />
|
<Icon name="spark" class="w-4 h-4" />
|
||||||
</span>
|
</span>
|
||||||
<h2 class="text-base font-extrabold">公告</h2>
|
<h2 class="text-base font-extrabold">公告</h2>
|
||||||
@@ -30,7 +30,7 @@ const html = computed(() => marked.parse(announcement.content.trim() || '暂无
|
|||||||
<div class="px-6 py-4 border-t border-t-[color:var(--ink-soft)] flex justify-end shrink-0">
|
<div class="px-6 py-4 border-t border-t-[color:var(--ink-soft)] flex justify-end shrink-0">
|
||||||
<button @click="dismissAnnouncement"
|
<button @click="dismissAnnouncement"
|
||||||
class="rounded-lg text-white border border-white/20 px-5 py-2 text-sm font-extrabold hover:-translate-y-0.5 active:translate-y-0.5 transition-all"
|
class="rounded-lg text-white border border-white/20 px-5 py-2 text-sm font-extrabold hover:-translate-y-0.5 active:translate-y-0.5 transition-all"
|
||||||
style="background: linear-gradient(120deg, #7c5cfc, #22d3ee); box-shadow: 0 8px 20px var(--accent-glow)">
|
style="background: linear-gradient(120deg, #18181b, #52525b); box-shadow: 0 8px 20px var(--accent-glow)">
|
||||||
我知道了
|
我知道了
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -55,7 +55,7 @@ const html = computed(() => marked.parse(announcement.content.trim() || '暂无
|
|||||||
.ann-body :deep(li) { margin: 0.2em 0; }
|
.ann-body :deep(li) { margin: 0.2em 0; }
|
||||||
.ann-body :deep(a) { color: var(--m-orange); text-decoration: underline; }
|
.ann-body :deep(a) { color: var(--m-orange); text-decoration: underline; }
|
||||||
.ann-body :deep(strong) { font-weight: 700; color: var(--fg); }
|
.ann-body :deep(strong) { font-weight: 700; color: var(--fg); }
|
||||||
.ann-body :deep(code) { background: rgb(124 92 252 / 0.12); padding: 0.1em 0.35em; border-radius: 0.3rem; font-size: 0.85em; }
|
.ann-body :deep(code) { background: rgb(24 24 27 / 0.12); padding: 0.1em 0.35em; border-radius: 0.3rem; font-size: 0.85em; }
|
||||||
.ann-body :deep(pre) { background: #111; color: #f5f5f5; padding: 0.8em; border-radius: 0.5rem; overflow-x: auto; margin: 0.6em 0; }
|
.ann-body :deep(pre) { background: #111; color: #f5f5f5; padding: 0.8em; border-radius: 0.5rem; overflow-x: auto; margin: 0.6em 0; }
|
||||||
.ann-body :deep(pre code) { background: none; padding: 0; }
|
.ann-body :deep(pre code) { background: none; padding: 0; }
|
||||||
.ann-body :deep(blockquote) { border-left: 3px solid var(--m-orange); padding-left: 0.9em; color: var(--fg-3); margin: 0.6em 0; }
|
.ann-body :deep(blockquote) { border-left: 3px solid var(--m-orange); padding-left: 0.9em; color: var(--fg-3); margin: 0.6em 0; }
|
||||||
|
|||||||
@@ -161,12 +161,9 @@ async function submit() {
|
|||||||
<template>
|
<template>
|
||||||
<transition name="modal">
|
<transition name="modal">
|
||||||
<div v-if="auth.loginOpen" class="fixed inset-0 z-50 grid place-items-center px-4">
|
<div v-if="auth.loginOpen" class="fixed inset-0 z-50 grid place-items-center px-4">
|
||||||
<div class="absolute inset-0 bg-black/70 backdrop-blur-md" @click="closeLogin"></div>
|
<div class="absolute inset-0 bg-black/40 backdrop-blur-sm" @click="closeLogin"></div>
|
||||||
|
|
||||||
<div class="card relative z-10 w-full max-w-[26rem]">
|
<div class="card relative z-10 w-full max-w-[26rem]">
|
||||||
<!-- ambient aurora washes -->
|
|
||||||
<div class="pointer-events-none absolute -top-24 -right-16 h-56 w-56 rounded-full bg-[#8b5cf6]/30 blur-3xl"></div>
|
|
||||||
<div class="pointer-events-none absolute -bottom-24 -left-16 h-56 w-56 rounded-full bg-[#22d3ee]/25 blur-3xl"></div>
|
|
||||||
|
|
||||||
<div class="relative p-7">
|
<div class="relative p-7">
|
||||||
<button class="absolute top-4 right-4 grid h-7 w-7 place-items-center rounded-lg text-[color:var(--fg-3)] hover:text-[color:var(--fg)] hover:bg-[var(--hover)] transition-colors"
|
<button class="absolute top-4 right-4 grid h-7 w-7 place-items-center rounded-lg text-[color:var(--fg-3)] hover:text-[color:var(--fg)] hover:bg-[var(--hover)] transition-colors"
|
||||||
@@ -263,11 +260,9 @@ async function submit() {
|
|||||||
<style scoped>
|
<style scoped>
|
||||||
.card {
|
.card {
|
||||||
border-radius: 1.2rem;
|
border-radius: 1.2rem;
|
||||||
background: var(--menu-bg);
|
background: #ffffff;
|
||||||
-webkit-backdrop-filter: blur(20px);
|
|
||||||
backdrop-filter: blur(20px);
|
|
||||||
color: var(--fg);
|
color: var(--fg);
|
||||||
border: 1px solid var(--glass-border);
|
border: 1px solid rgb(24 24 27 / 0.08);
|
||||||
box-shadow: var(--glass-shadow-lg);
|
box-shadow: var(--glass-shadow-lg);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
@@ -277,7 +272,7 @@ html.dark .card {
|
|||||||
|
|
||||||
.logo-halo {
|
.logo-halo {
|
||||||
position: relative;
|
position: relative;
|
||||||
filter: drop-shadow(0 6px 14px rgb(124 92 252 / 0.4));
|
filter: drop-shadow(0 6px 14px rgb(24 24 27 / 0.4));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* segmented tab control */
|
/* segmented tab control */
|
||||||
@@ -296,7 +291,7 @@ html.dark .card {
|
|||||||
.tab:hover { color: var(--fg); }
|
.tab:hover { color: var(--fg); }
|
||||||
.tab-on {
|
.tab-on {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background: linear-gradient(120deg, #7c5cfc, #5f6cf8);
|
background: linear-gradient(120deg, #18181b, #27272a);
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
box-shadow: 0 4px 14px var(--accent-glow);
|
box-shadow: 0 4px 14px var(--accent-glow);
|
||||||
}
|
}
|
||||||
@@ -317,8 +312,8 @@ html.dark .card {
|
|||||||
}
|
}
|
||||||
html.dark .fld { background: rgb(255 255 255 / 0.05); }
|
html.dark .fld { background: rgb(255 255 255 / 0.05); }
|
||||||
.fld:focus {
|
.fld:focus {
|
||||||
border-color: rgb(124 92 252 / 0.65);
|
border-color: rgb(24 24 27 / 0.65);
|
||||||
box-shadow: 0 0 0 3px rgb(124 92 252 / 0.18);
|
box-shadow: 0 0 0 3px rgb(24 24 27 / 0.18);
|
||||||
}
|
}
|
||||||
.fld::placeholder { color: var(--fg-faint); }
|
.fld::placeholder { color: var(--fg-faint); }
|
||||||
/* Keep autofill on-theme in dark (otherwise it paints white/yellow). */
|
/* Keep autofill on-theme in dark (otherwise it paints white/yellow). */
|
||||||
@@ -345,11 +340,11 @@ html.dark .fld:-webkit-autofill:focus {
|
|||||||
display: inline-flex; align-items: center; justify-content: center;
|
display: inline-flex; align-items: center; justify-content: center;
|
||||||
font-size: 0.75rem; font-weight: 800; white-space: nowrap;
|
font-size: 0.75rem; font-weight: 800; white-space: nowrap;
|
||||||
color: var(--fg);
|
color: var(--fg);
|
||||||
background: var(--hover); border: 1px solid rgb(124 92 252 / 0.4);
|
background: var(--hover); border: 1px solid rgb(24 24 27 / 0.4);
|
||||||
box-shadow: 0 2px 10px rgb(124 92 252 / 0.14);
|
box-shadow: 0 2px 10px rgb(24 24 27 / 0.14);
|
||||||
transition: background 0.15s, box-shadow 0.15s, transform 0.15s, opacity 0.15s;
|
transition: background 0.15s, box-shadow 0.15s, transform 0.15s, opacity 0.15s;
|
||||||
}
|
}
|
||||||
.code-btn:hover:not(:disabled) { transform: translateY(-1px); box-shadow: 0 4px 14px rgb(124 92 252 / 0.22); }
|
.code-btn:hover:not(:disabled) { transform: translateY(-1px); box-shadow: 0 4px 14px rgb(24 24 27 / 0.22); }
|
||||||
.code-btn:active:not(:disabled) { transform: scale(0.96) translateY(1px); box-shadow: none; }
|
.code-btn:active:not(:disabled) { transform: scale(0.96) translateY(1px); box-shadow: none; }
|
||||||
/* Disabled (sending / countdown): just dim — keep the theme text color so it
|
/* Disabled (sending / countdown): just dim — keep the theme text color so it
|
||||||
never washes out to invisible white on the light card. */
|
never washes out to invisible white on the light card. */
|
||||||
@@ -361,7 +356,7 @@ html.dark .fld:-webkit-autofill:focus {
|
|||||||
display: flex; align-items: center; justify-content: center; gap: 0.5rem;
|
display: flex; align-items: center; justify-content: center; gap: 0.5rem;
|
||||||
padding: 0.72rem 0; border-radius: 0.65rem; font-size: 0.9rem; font-weight: 800;
|
padding: 0.72rem 0; border-radius: 0.65rem; font-size: 0.9rem; font-weight: 800;
|
||||||
letter-spacing: 0.02em; color: white; margin-top: 0.35rem;
|
letter-spacing: 0.02em; color: white; margin-top: 0.35rem;
|
||||||
background: linear-gradient(120deg, #7c5cfc, #5f6cf8 55%, #22d3ee 140%);
|
background: linear-gradient(120deg, #18181b, #27272a 55%, #52525b 140%);
|
||||||
border: 1px solid rgb(255 255 255 / 0.16);
|
border: 1px solid rgb(255 255 255 / 0.16);
|
||||||
box-shadow: 0 8px 22px var(--accent-glow);
|
box-shadow: 0 8px 22px var(--accent-glow);
|
||||||
transition: transform 0.13s, box-shadow 0.13s, filter 0.15s;
|
transition: transform 0.13s, box-shadow 0.13s, filter 0.15s;
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ onUnmounted(clearTimers)
|
|||||||
<p class="text-sm text-[color:var(--fg-3)] mt-1">二维码已失效,订单已取消</p>
|
<p class="text-sm text-[color:var(--fg-3)] mt-1">二维码已失效,订单已取消</p>
|
||||||
<p class="text-xs text-[color:var(--fg-faint)] mt-1">如需充值请重新下单</p>
|
<p class="text-xs text-[color:var(--fg-faint)] mt-1">如需充值请重新下单</p>
|
||||||
<button @click="finish" class="mt-5 rounded-lg text-white border border-white/20 px-5 py-2 text-sm font-extrabold hover:-translate-y-0.5 active:translate-y-0.5 transition-all"
|
<button @click="finish" class="mt-5 rounded-lg text-white border border-white/20 px-5 py-2 text-sm font-extrabold hover:-translate-y-0.5 active:translate-y-0.5 transition-all"
|
||||||
style="background: linear-gradient(120deg, #7c5cfc, #22d3ee); box-shadow: 0 8px 20px var(--accent-glow)">关闭</button>
|
style="background: linear-gradient(120deg, #18181b, #52525b); box-shadow: 0 8px 20px var(--accent-glow)">关闭</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- pending -->
|
<!-- pending -->
|
||||||
@@ -147,7 +147,7 @@ onUnmounted(clearTimers)
|
|||||||
<!-- jump (no qrcode): the cashier opened in a new tab — just monitor -->
|
<!-- jump (no qrcode): the cashier opened in a new tab — just monitor -->
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<div class="flex flex-col items-center justify-center py-7 mb-2">
|
<div class="flex flex-col items-center justify-center py-7 mb-2">
|
||||||
<div class="w-12 h-12 rounded-full border-[3px] border-[rgb(124_92_252/0.2)] border-t-[#7c5cfc] animate-spin mb-3"></div>
|
<div class="w-12 h-12 rounded-full border-[3px] border-[rgb(124_92_252/0.2)] border-t-[#18181b] animate-spin mb-3"></div>
|
||||||
<p class="text-sm font-medium text-[color:var(--fg)]">支付监控中…</p>
|
<p class="text-sm font-medium text-[color:var(--fg)]">支付监控中…</p>
|
||||||
<p class="text-xs text-[color:var(--fg-faint)] mt-1">已打开支付页面,完成后自动到账</p>
|
<p class="text-xs text-[color:var(--fg-faint)] mt-1">已打开支付页面,完成后自动到账</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -240,8 +240,8 @@ defineExpose({ startEdit, commitNote })
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.cv-node.is-selected {
|
.cv-node.is-selected {
|
||||||
border-color: rgb(124 92 252 / 0.7);
|
border-color: rgb(24 24 27 / 0.7);
|
||||||
box-shadow: var(--glass-shadow-lg), 0 0 0 3px rgb(124 92 252 / 0.25), 0 10px 30px var(--accent-glow);
|
box-shadow: var(--glass-shadow-lg), 0 0 0 3px rgb(24 24 27 / 0.25), 0 10px 30px var(--accent-glow);
|
||||||
}
|
}
|
||||||
.cv-node:active {
|
.cv-node:active {
|
||||||
cursor: grabbing;
|
cursor: grabbing;
|
||||||
@@ -337,8 +337,8 @@ html.dark .cv-node--note {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
background:
|
background:
|
||||||
radial-gradient(130% 130% at 15% 0%, rgb(124 92 252 / 0.14), transparent 55%),
|
radial-gradient(130% 130% at 15% 0%, rgb(24 24 27 / 0.14), transparent 55%),
|
||||||
radial-gradient(130% 130% at 85% 100%, rgb(34 211 238 / 0.12), transparent 55%),
|
radial-gradient(130% 130% at 85% 100%, rgb(24 24 27 / 0.12), transparent 55%),
|
||||||
var(--surface);
|
var(--surface);
|
||||||
}
|
}
|
||||||
.cv-node__gen::after {
|
.cv-node__gen::after {
|
||||||
@@ -371,7 +371,7 @@ html.dark .cv-node--note {
|
|||||||
width: 34px;
|
width: 34px;
|
||||||
height: 34px;
|
height: 34px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
border: 3px solid rgb(124 92 252 / 0.2);
|
border: 3px solid rgb(24 24 27 / 0.2);
|
||||||
border-top-color: var(--m-orange);
|
border-top-color: var(--m-orange);
|
||||||
border-right-color: var(--m-orange-2);
|
border-right-color: var(--m-orange-2);
|
||||||
animation: cv-spin 0.9s linear infinite;
|
animation: cv-spin 0.9s linear infinite;
|
||||||
@@ -417,7 +417,7 @@ html.dark .cv-node--note {
|
|||||||
}
|
}
|
||||||
.cv-port:hover::after, .cv-port:focus-visible::after, .cv-port.is-active::after {
|
.cv-port:hover::after, .cv-port:focus-visible::after, .cv-port.is-active::after {
|
||||||
transform: scale(1.3);
|
transform: scale(1.3);
|
||||||
box-shadow: 0 0 0 4px rgb(124 92 252 / 0.25), 0 2px 10px var(--accent-glow);
|
box-shadow: 0 0 0 4px rgb(24 24 27 / 0.25), 0 2px 10px var(--accent-glow);
|
||||||
}
|
}
|
||||||
.cv-port.is-active::after { background: var(--m-orange); }
|
.cv-port.is-active::after { background: var(--m-orange); }
|
||||||
.cv-port:focus-visible { outline: 2px solid var(--m-orange); outline-offset: -2px; border-radius: 50%; }
|
.cv-port:focus-visible { outline: 2px solid var(--m-orange); outline-offset: -2px; border-radius: 50%; }
|
||||||
|
|||||||
@@ -811,7 +811,7 @@ defineExpose({
|
|||||||
stroke: rgb(95 108 248 / 0.85);
|
stroke: rgb(95 108 248 / 0.85);
|
||||||
stroke-width: 2.4;
|
stroke-width: 2.4;
|
||||||
stroke-dasharray: 10 6;
|
stroke-dasharray: 10 6;
|
||||||
filter: drop-shadow(0 0 5px rgb(124 92 252 / 0.3));
|
filter: drop-shadow(0 0 5px rgb(24 24 27 / 0.3));
|
||||||
}
|
}
|
||||||
.cv-edge--hot {
|
.cv-edge--hot {
|
||||||
stroke: var(--m-orange);
|
stroke: var(--m-orange);
|
||||||
@@ -843,8 +843,8 @@ defineExpose({
|
|||||||
}
|
}
|
||||||
.cv-marquee {
|
.cv-marquee {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
border: 2px dashed rgb(124 92 252 / 0.5);
|
border: 2px dashed rgb(24 24 27 / 0.5);
|
||||||
background: rgb(124 92 252 / 0.08);
|
background: rgb(24 24 27 / 0.08);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import { useRoute } from 'vue-router'
|
|||||||
import Icon from '../components/Icon.vue'
|
import Icon from '../components/Icon.vue'
|
||||||
import Logo from '../components/Logo.vue'
|
import Logo from '../components/Logo.vue'
|
||||||
import { site } from '../site'
|
import { site } from '../site'
|
||||||
import { isDark, toggleTheme } from '../theme'
|
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|
||||||
@@ -90,12 +89,6 @@ watch(() => route.path, () => {
|
|||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<div class="p-3 border-t border-t-[color:var(--ink-soft)] space-y-1">
|
<div class="p-3 border-t border-t-[color:var(--ink-soft)] space-y-1">
|
||||||
<button type="button" @click="toggleTheme"
|
|
||||||
class="w-full flex items-center gap-2.5 rounded-lg px-3 py-2 text-xs text-[color:var(--fg-2)] hover:bg-[var(--hover)] hover:text-[color:var(--fg)] transition-colors">
|
|
||||||
<svg v-if="isDark" class="w-3.5 h-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"/></svg>
|
|
||||||
<svg v-else class="w-3.5 h-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z"/></svg>
|
|
||||||
{{ isDark ? '亮色模式' : '暗色模式' }}
|
|
||||||
</button>
|
|
||||||
<router-link to="/user"
|
<router-link to="/user"
|
||||||
class="flex items-center gap-2.5 rounded-lg px-3 py-2 text-xs text-[color:var(--fg-2)] hover:bg-[var(--hover)] hover:text-[color:var(--fg)] transition-colors">
|
class="flex items-center gap-2.5 rounded-lg px-3 py-2 text-xs text-[color:var(--fg-2)] hover:bg-[var(--hover)] hover:text-[color:var(--fg)] transition-colors">
|
||||||
<Icon name="spark" class="w-3.5 h-3.5" /> 用户端
|
<Icon name="spark" class="w-3.5 h-3.5" /> 用户端
|
||||||
@@ -106,16 +99,6 @@ watch(() => route.path, () => {
|
|||||||
|
|
||||||
<!-- ===== Main ===== -->
|
<!-- ===== Main ===== -->
|
||||||
<div class="flex-1 min-w-0 flex flex-col relative">
|
<div class="flex-1 min-w-0 flex flex-col relative">
|
||||||
<!-- aurora backdrop: drifting gradient orbs + faint grain -->
|
|
||||||
<div aria-hidden="true" class="pointer-events-none absolute inset-0 overflow-hidden">
|
|
||||||
<div class="memphis-dots absolute inset-0 opacity-40"></div>
|
|
||||||
<div class="absolute -top-40 left-1/4 w-[40rem] h-[40rem] rounded-full opacity-[0.45]"
|
|
||||||
style="background: radial-gradient(circle, rgb(139 92 246 / 0.3), transparent 60%); filter: blur(110px)"></div>
|
|
||||||
<div class="absolute top-1/2 -right-48 w-[36rem] h-[36rem] rounded-full opacity-[0.4]"
|
|
||||||
style="background: radial-gradient(circle, rgb(34 211 238 / 0.24), transparent 60%); filter: blur(110px)"></div>
|
|
||||||
<div class="absolute bottom-0 -left-24 w-[32rem] h-[32rem] rounded-full opacity-[0.35]"
|
|
||||||
style="background: radial-gradient(circle, rgb(232 121 249 / 0.2), transparent 60%); filter: blur(110px)"></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="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="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>
|
||||||
@@ -123,7 +106,7 @@ watch(() => route.path, () => {
|
|||||||
<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>
|
||||||
|
|
||||||
<main :class="['theme-text flex-1 overflow-y-auto overscroll-y-none relative z-10', { 'public-dark': isDark }]">
|
<main :class="['theme-text flex-1 overflow-y-auto overscroll-y-none relative z-10']">
|
||||||
<div class="px-8 py-7">
|
<div class="px-8 py-7">
|
||||||
<router-view v-slot="{ Component }">
|
<router-view v-slot="{ Component }">
|
||||||
<transition name="fade" mode="out-in">
|
<transition name="fade" mode="out-in">
|
||||||
@@ -138,13 +121,13 @@ watch(() => route.path, () => {
|
|||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.admin-tag {
|
.admin-tag {
|
||||||
background: linear-gradient(120deg, #7c5cfc, #22d3ee);
|
background: linear-gradient(120deg, #18181b, #52525b);
|
||||||
-webkit-background-clip: text;
|
-webkit-background-clip: text;
|
||||||
background-clip: text;
|
background-clip: text;
|
||||||
color: transparent;
|
color: transparent;
|
||||||
}
|
}
|
||||||
.admin-badge {
|
.admin-badge {
|
||||||
background: linear-gradient(120deg, #7c5cfc, #5f6cf8 60%, #22d3ee 140%);
|
background: linear-gradient(120deg, #18181b, #27272a 60%, #52525b 140%);
|
||||||
box-shadow: 0 4px 14px var(--accent-glow);
|
box-shadow: 0 4px 14px var(--accent-glow);
|
||||||
}
|
}
|
||||||
.admin-link {
|
.admin-link {
|
||||||
@@ -159,10 +142,10 @@ watch(() => route.path, () => {
|
|||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
|
transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
|
||||||
}
|
}
|
||||||
.admin-link:hover { background: var(--hover); color: var(--fg); border-color: rgb(124 92 252 / 0.3); }
|
.admin-link:hover { background: var(--hover); color: var(--fg); border-color: rgb(24 24 27 / 0.3); }
|
||||||
.admin-link.active {
|
.admin-link.active {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background: linear-gradient(120deg, #7c5cfc, #5f6cf8);
|
background: linear-gradient(120deg, #18181b, #27272a);
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
box-shadow: 0 4px 14px var(--accent-glow);
|
box-shadow: 0 4px 14px var(--accent-glow);
|
||||||
}
|
}
|
||||||
@@ -178,8 +161,8 @@ watch(() => route.path, () => {
|
|||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
|
transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
|
||||||
}
|
}
|
||||||
.admin-sublink:hover { background: var(--hover); color: var(--fg); border-color: rgb(124 92 252 / 0.3); }
|
.admin-sublink:hover { background: var(--hover); color: var(--fg); border-color: rgb(24 24 27 / 0.3); }
|
||||||
.admin-sublink.active { color: var(--m-orange); background: var(--hover); border-color: rgb(124 92 252 / 0.35); font-weight: 700; }
|
.admin-sublink.active { color: var(--m-orange); background: var(--hover); border-color: rgb(24 24 27 / 0.35); font-weight: 700; }
|
||||||
|
|
||||||
.fade-enter-active, .fade-leave-active { transition: opacity 0.15s ease, transform 0.15s ease; }
|
.fade-enter-active, .fade-leave-active { transition: opacity 0.15s ease, transform 0.15s ease; }
|
||||||
.fade-enter-from { opacity: 0; transform: translateY(4px); }
|
.fade-enter-from { opacity: 0; transform: translateY(4px); }
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
import { computed, ref, watch, onMounted, onUnmounted } from 'vue'
|
import { computed, ref, watch, onMounted, onUnmounted } from 'vue'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import { auth, isAuthed, isAdmin, openLogin, openRegister, logout } from '../auth'
|
import { auth, isAuthed, isAdmin, openLogin, openRegister, logout } from '../auth'
|
||||||
import { isDark, toggleTheme } from '../theme'
|
|
||||||
import { site } from '../site'
|
import { site } from '../site'
|
||||||
import Icon from '../components/Icon.vue'
|
import Icon from '../components/Icon.vue'
|
||||||
import Logo from '../components/Logo.vue'
|
import Logo from '../components/Logo.vue'
|
||||||
@@ -77,7 +76,7 @@ async function onLogout() {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="theme-x min-h-screen bg-[var(--app-bg)] text-[color:var(--fg-2)] selection:bg-orange-400/30"
|
<div class="theme-x min-h-screen bg-[var(--app-bg)] text-[color:var(--fg-2)] selection:bg-orange-400/30"
|
||||||
:class="{ 'home-bg': isHome && !isDark }">
|
:class="{ 'home-bg': isHome }">
|
||||||
<!-- ===== Top bar:悬浮胶囊,滚动展开为通栏 ===== -->
|
<!-- ===== Top bar:悬浮胶囊,滚动展开为通栏 ===== -->
|
||||||
<header class="top-nav fixed top-0 inset-x-0 z-40" :class="{ scrolled }">
|
<header class="top-nav fixed top-0 inset-x-0 z-40" :class="{ scrolled }">
|
||||||
<div class="nav-inner mx-auto flex items-center gap-3">
|
<div class="nav-inner mx-auto flex items-center gap-3">
|
||||||
@@ -105,13 +104,6 @@ async function onLogout() {
|
|||||||
余额 <span class="text-[color:var(--fg)] font-semibold">{{ creditsLabel }}</span>
|
余额 <span class="text-[color:var(--fg)] font-semibold">{{ creditsLabel }}</span>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
|
||||||
<!-- theme(登录后可见,游客态与 vivid 一致只留登录入口) -->
|
|
||||||
<button v-if="isAuthed()" type="button" @click="toggleTheme" class="round-btn"
|
|
||||||
:title="isDark ? '切换到亮色' : '切换到暗色'">
|
|
||||||
<svg v-if="isDark" class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"/></svg>
|
|
||||||
<svg v-else class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z"/></svg>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<!-- 公告 -->
|
<!-- 公告 -->
|
||||||
<button v-if="isAuthed() && announcement.content.trim()" type="button"
|
<button v-if="isAuthed() && announcement.content.trim()" type="button"
|
||||||
@click="openAnnouncement" class="round-btn" title="公告">
|
@click="openAnnouncement" class="round-btn" title="公告">
|
||||||
@@ -171,17 +163,6 @@ async function onLogout() {
|
|||||||
|
|
||||||
<!-- ===== Main column ===== -->
|
<!-- ===== Main column ===== -->
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<!-- aurora backdrop: drifting gradient orbs + faint grain (首页用平铺浅色底,不渲染) -->
|
|
||||||
<div v-if="!isHome" aria-hidden="true" class="pointer-events-none absolute inset-0 overflow-hidden">
|
|
||||||
<div class="memphis-dots absolute inset-0 opacity-50"></div>
|
|
||||||
<div class="absolute -top-40 left-1/4 w-[42rem] h-[42rem] rounded-full opacity-[0.5]"
|
|
||||||
style="background: radial-gradient(circle, rgb(139 92 246 / 0.35), transparent 60%); filter: blur(100px)"></div>
|
|
||||||
<div class="absolute top-1/3 -right-48 w-[38rem] h-[38rem] rounded-full opacity-[0.45]"
|
|
||||||
style="background: radial-gradient(circle, rgb(34 211 238 / 0.3), transparent 60%); filter: blur(100px)"></div>
|
|
||||||
<div class="absolute bottom-0 -left-24 w-[34rem] h-[34rem] rounded-full opacity-[0.4]"
|
|
||||||
style="background: radial-gradient(circle, rgb(232 121 249 / 0.28), transparent 60%); filter: blur(100px)"></div>
|
|
||||||
<div class="anime-stars"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Route label header — the home page brings its own hero instead. -->
|
<!-- Route label header — the home page brings its own hero instead. -->
|
||||||
<header v-if="!isHome" class="relative z-10 mx-auto max-w-[1400px] px-4 md:px-8 pt-[104px] pb-4">
|
<header v-if="!isHome" class="relative z-10 mx-auto max-w-[1400px] px-4 md:px-8 pt-[104px] pb-4">
|
||||||
@@ -189,8 +170,7 @@ async function onLogout() {
|
|||||||
</header>
|
</header>
|
||||||
|
|
||||||
<main :class="['relative z-10 mx-auto max-w-[1400px] pb-24',
|
<main :class="['relative z-10 mx-auto max-w-[1400px] pb-24',
|
||||||
isHome ? 'pt-0 px-0' : 'px-4 md:px-8 pt-2',
|
isHome ? 'pt-0 px-0' : 'px-4 md:px-8 pt-2',]">
|
||||||
{ 'public-dark': isDark }]">
|
|
||||||
<router-view v-slot="{ Component, route: viewRoute }">
|
<router-view v-slot="{ Component, route: viewRoute }">
|
||||||
<component :is="Component" v-if="viewRoute.path === '/canvas'" />
|
<component :is="Component" v-if="viewRoute.path === '/canvas'" />
|
||||||
<transition v-else name="fade" mode="out-in">
|
<transition v-else name="fade" mode="out-in">
|
||||||
@@ -264,7 +244,7 @@ html.dark .nav-inner { box-shadow: 0 8px 30px -14px rgb(0 0 0 / 0.5); }
|
|||||||
.top-link.on {
|
.top-link.on {
|
||||||
color: var(--m-orange);
|
color: var(--m-orange);
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
background: rgb(124 92 252 / 0.12);
|
background: rgb(24 24 27 / 0.12);
|
||||||
}
|
}
|
||||||
|
|
||||||
.brand-spark {
|
.brand-spark {
|
||||||
@@ -291,11 +271,11 @@ html.dark .nav-inner { box-shadow: 0 8px 30px -14px rgb(0 0 0 / 0.5); }
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: color 0.15s ease, background 0.15s ease, border-color 0.15s ease;
|
transition: color 0.15s ease, background 0.15s ease, border-color 0.15s ease;
|
||||||
}
|
}
|
||||||
.m-link:hover { color: var(--fg); background: var(--hover); border-color: rgb(124 92 252 / 0.3); }
|
.m-link:hover { color: var(--fg); background: var(--hover); border-color: rgb(24 24 27 / 0.3); }
|
||||||
.m-link.m-on {
|
.m-link.m-on {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
background: linear-gradient(120deg, #7c5cfc, #5f6cf8);
|
background: linear-gradient(120deg, #18181b, #27272a);
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
box-shadow: 0 4px 14px var(--accent-glow);
|
box-shadow: 0 4px 14px var(--accent-glow);
|
||||||
}
|
}
|
||||||
@@ -313,7 +293,7 @@ html.dark .nav-inner { box-shadow: 0 8px 30px -14px rgb(0 0 0 / 0.5); }
|
|||||||
border: 1px solid var(--ink-soft);
|
border: 1px solid var(--ink-soft);
|
||||||
transition: color 0.15s ease, background 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease, border-color 0.15s ease;
|
transition: color 0.15s ease, background 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease, border-color 0.15s ease;
|
||||||
}
|
}
|
||||||
.round-btn:hover { color: var(--fg); background: var(--hover); border-color: rgb(124 92 252 / 0.4); box-shadow: 0 4px 14px rgb(124 92 252 / 0.16); transform: translateY(-1px); }
|
.round-btn:hover { color: var(--fg); background: var(--hover); border-color: rgb(24 24 27 / 0.4); box-shadow: 0 4px 14px rgb(24 24 27 / 0.16); transform: translateY(-1px); }
|
||||||
/* 首页整页淡紫渐变底(铺满整个页面高度) */
|
/* 首页整页淡紫渐变底(铺满整个页面高度) */
|
||||||
.home-bg {
|
.home-bg {
|
||||||
background: #fafaf8 !important;
|
background: #fafaf8 !important;
|
||||||
@@ -343,7 +323,7 @@ html.dark .nav-inner { box-shadow: 0 8px 30px -14px rgb(0 0 0 / 0.5); }
|
|||||||
font-size: 13.5px;
|
font-size: 13.5px;
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background: linear-gradient(120deg, #7c5cfc, #5f6cf8 55%, #22d3ee 140%);
|
background: linear-gradient(120deg, #18181b, #27272a 55%, #52525b 140%);
|
||||||
border: 1px solid rgb(255 255 255 / 0.16);
|
border: 1px solid rgb(255 255 255 / 0.16);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
box-shadow: 0 6px 18px var(--accent-glow);
|
box-shadow: 0 6px 18px var(--accent-glow);
|
||||||
@@ -372,8 +352,8 @@ html.dark .nav-inner { box-shadow: 0 8px 30px -14px rgb(0 0 0 / 0.5); }
|
|||||||
}
|
}
|
||||||
.name-btn:hover {
|
.name-btn:hover {
|
||||||
background: var(--hover);
|
background: var(--hover);
|
||||||
border-color: rgb(124 92 252 / 0.4);
|
border-color: rgb(24 24 27 / 0.4);
|
||||||
box-shadow: 0 4px 14px rgb(124 92 252 / 0.16);
|
box-shadow: 0 4px 14px rgb(24 24 27 / 0.16);
|
||||||
transform: translateY(-1px);
|
transform: translateY(-1px);
|
||||||
}
|
}
|
||||||
.name-txt {
|
.name-txt {
|
||||||
|
|||||||
+69
-73
@@ -9,34 +9,34 @@ video {
|
|||||||
|
|
||||||
:root {
|
:root {
|
||||||
font-family: "Inter", ui-sans-serif, system-ui, -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif;
|
font-family: "Inter", ui-sans-serif, system-ui, -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif;
|
||||||
--tw-ring-color: rgb(124 92 252 / 0.25);
|
--tw-ring-color: rgb(24 24 27 / 0.25);
|
||||||
|
|
||||||
/* ===== Theme palette — LIGHT (default): frosted glass / aurora =====
|
/* ===== Theme palette — LIGHT (default): frosted glass / aurora =====
|
||||||
Drives the app chrome (rails/header) and the public marketing pages.
|
Drives the app chrome (rails/header) and the public marketing pages.
|
||||||
The `.dark` class on <html> flips these to the dark values below.
|
The `.dark` class on <html> flips these to the dark values below.
|
||||||
Text over generated images keeps a literal text-white (handled in markup). */
|
Text over generated images keeps a literal text-white (handled in markup). */
|
||||||
--app-bg: #eef0f8; /* cool porcelain */
|
--app-bg: #fafaf8; /* warm paper */
|
||||||
--fg: #181524; /* primary heading/text */
|
--fg: #181524; /* primary heading/text */
|
||||||
--fg-2: rgb(24 21 36 / 0.66); /* body / secondary */
|
--fg-2: rgb(24 21 36 / 0.66); /* body / secondary */
|
||||||
--fg-3: rgb(24 21 36 / 0.48); /* muted */
|
--fg-3: rgb(24 21 36 / 0.48); /* muted */
|
||||||
--fg-faint: rgb(24 21 36 / 0.36); /* labels / hints */
|
--fg-faint: rgb(24 21 36 / 0.36); /* labels / hints */
|
||||||
--surface: rgb(255 255 255 / 0.66); /* frosted card on page bg */
|
--surface: rgb(255 255 255 / 0.9); /* frosted card on page bg */
|
||||||
--surface-solid: #ffffff; /* opaque version where blur is unwanted */
|
--surface-solid: #ffffff; /* opaque version where blur is unwanted */
|
||||||
--surface-2: rgb(24 21 36 / 0.045); /* subtle inset panel (counter cells) */
|
--surface-2: rgb(24 21 36 / 0.045); /* subtle inset panel (counter cells) */
|
||||||
--hairline: rgb(24 21 36 / 0.1); /* faint borders / separators */
|
--hairline: rgb(24 21 36 / 0.1); /* faint borders / separators */
|
||||||
--hover: rgb(124 92 252 / 0.1); /* hover wash — violet tint */
|
--hover: rgb(24 24 27 / 0.06); /* hover wash — violet tint */
|
||||||
/* ink = the hairline edge color; shadow-ink = the soft shadow tint.
|
/* ink = the hairline edge color; shadow-ink = the soft shadow tint.
|
||||||
Kept under their legacy names so existing markup keeps working — only the
|
Kept under their legacy names so existing markup keeps working — only the
|
||||||
values changed from memphis-solid to glass-subtle. */
|
values changed from memphis-solid to glass-subtle. */
|
||||||
--ink: rgb(24 21 36 / 0.14);
|
--ink: rgb(24 21 36 / 0.14);
|
||||||
--ink-soft: rgb(24 21 36 / 0.09);
|
--ink-soft: rgb(24 21 36 / 0.09);
|
||||||
--shadow-ink: rgb(88 80 200 / 0.14);
|
--shadow-ink: rgb(24 24 27 / 0.12);
|
||||||
/* aurora accent crayons — primary violet + soft pastel companions */
|
/* aurora accent crayons — primary violet + soft pastel companions */
|
||||||
--m-orange: #7c5cfc;
|
--m-orange: #18181b;
|
||||||
--m-orange-2: #22d3ee;
|
--m-orange-2: #52525b;
|
||||||
--m-yellow: #ece7fe;
|
--m-yellow: #f4f4f5;
|
||||||
--m-pink: #fad9f0;
|
--m-pink: #f4f4f5;
|
||||||
--m-blue: #d8eefb;
|
--m-blue: #f4f4f5;
|
||||||
--m-mint: #d9f4e8;
|
--m-mint: #d9f4e8;
|
||||||
/* solid CTA button that sits on the page bg — inverts per theme */
|
/* solid CTA button that sits on the page bg — inverts per theme */
|
||||||
--btn-solid-bg: #181524;
|
--btn-solid-bg: #181524;
|
||||||
@@ -45,9 +45,9 @@ video {
|
|||||||
--menu-bg: rgb(255 255 255 / 0.82); /* dropdown / popover panel */
|
--menu-bg: rgb(255 255 255 / 0.82); /* dropdown / popover panel */
|
||||||
/* shared glass treatments */
|
/* shared glass treatments */
|
||||||
--glass-border: rgb(255 255 255 / 0.55);
|
--glass-border: rgb(255 255 255 / 0.55);
|
||||||
--glass-shadow: 0 8px 28px rgb(80 74 190 / 0.1), 0 2px 8px rgb(24 21 36 / 0.05);
|
--glass-shadow: 0 8px 28px rgb(24 24 27 / 0.07), 0 2px 8px rgb(24 21 36 / 0.04);
|
||||||
--glass-shadow-lg: 0 16px 44px rgb(80 74 190 / 0.16), 0 4px 12px rgb(24 21 36 / 0.06);
|
--glass-shadow-lg: 0 16px 44px rgb(24 24 27 / 0.12), 0 4px 12px rgb(24 21 36 / 0.05);
|
||||||
--accent-glow: rgb(124 92 252 / 0.35);
|
--accent-glow: rgb(24 24 27 / 0.25);
|
||||||
}
|
}
|
||||||
|
|
||||||
html.dark {
|
html.dark {
|
||||||
@@ -60,24 +60,24 @@ html.dark {
|
|||||||
--surface-solid: #14131f;
|
--surface-solid: #14131f;
|
||||||
--surface-2: rgb(255 255 255 / 0.05);
|
--surface-2: rgb(255 255 255 / 0.05);
|
||||||
--hairline: rgb(255 255 255 / 0.1);
|
--hairline: rgb(255 255 255 / 0.1);
|
||||||
--hover: rgb(139 92 246 / 0.16);
|
--hover: rgb(24 24 27 / 0.16);
|
||||||
--ink: rgb(255 255 255 / 0.14);
|
--ink: rgb(255 255 255 / 0.14);
|
||||||
--ink-soft: rgb(255 255 255 / 0.09);
|
--ink-soft: rgb(255 255 255 / 0.09);
|
||||||
--shadow-ink: rgb(0 0 0 / 0.4);
|
--shadow-ink: rgb(0 0 0 / 0.4);
|
||||||
--m-orange: #8b5cf6;
|
--m-orange: #27272a;
|
||||||
--m-orange-2: #22d3ee;
|
--m-orange-2: #52525b;
|
||||||
--m-yellow: #a78bfa;
|
--m-yellow: #71717a;
|
||||||
--m-pink: #f0a6d8;
|
--m-pink: #f0a6d8;
|
||||||
--m-blue: #6cd0f2;
|
--m-blue: #6cd0f2;
|
||||||
--m-mint: #5fd9ac;
|
--m-mint: #5fd9ac;
|
||||||
--btn-solid-bg: #8b5cf6;
|
--btn-solid-bg: #27272a;
|
||||||
--btn-solid-bg-h: #7c3aed;
|
--btn-solid-bg-h: #18181b;
|
||||||
--btn-solid-fg: #fff;
|
--btn-solid-fg: #fff;
|
||||||
--menu-bg: rgb(24 23 36 / 0.86);
|
--menu-bg: rgb(24 23 36 / 0.86);
|
||||||
--glass-border: rgb(255 255 255 / 0.12);
|
--glass-border: rgb(255 255 255 / 0.12);
|
||||||
--glass-shadow: 0 8px 28px rgb(0 0 0 / 0.35), 0 2px 8px rgb(0 0 0 / 0.2);
|
--glass-shadow: 0 8px 28px rgb(0 0 0 / 0.35), 0 2px 8px rgb(0 0 0 / 0.2);
|
||||||
--glass-shadow-lg: 0 18px 50px rgb(0 0 0 / 0.5), 0 4px 14px rgb(0 0 0 / 0.3);
|
--glass-shadow-lg: 0 18px 50px rgb(0 0 0 / 0.5), 0 4px 14px rgb(0 0 0 / 0.3);
|
||||||
--accent-glow: rgb(139 92 246 / 0.45);
|
--accent-glow: rgb(24 24 27 / 0.45);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Smooth the flip so toggling doesn't hard-cut. */
|
/* Smooth the flip so toggling doesn't hard-cut. */
|
||||||
@@ -87,16 +87,16 @@ body, .theme-x { transition: background-color 0.25s ease, color 0.25s ease; }
|
|||||||
.cta-band {
|
.cta-band {
|
||||||
position: relative;
|
position: relative;
|
||||||
background:
|
background:
|
||||||
radial-gradient(120% 160% at 0% 0%, rgb(124 92 252 / 0.2), transparent 55%),
|
radial-gradient(120% 160% at 0% 0%, rgb(24 24 27 / 0.2), transparent 55%),
|
||||||
radial-gradient(120% 160% at 100% 100%, rgb(34 211 238 / 0.16), transparent 55%),
|
radial-gradient(120% 160% at 100% 100%, rgb(24 24 27 / 0.16), transparent 55%),
|
||||||
var(--surface);
|
var(--surface);
|
||||||
border: 1px solid var(--glass-border);
|
border: 1px solid var(--glass-border);
|
||||||
box-shadow: var(--glass-shadow-lg);
|
box-shadow: var(--glass-shadow-lg);
|
||||||
}
|
}
|
||||||
html.dark .cta-band {
|
html.dark .cta-band {
|
||||||
background:
|
background:
|
||||||
radial-gradient(120% 160% at 0% 0%, rgb(139 92 246 / 0.22), transparent 55%),
|
radial-gradient(120% 160% at 0% 0%, rgb(24 24 27 / 0.22), transparent 55%),
|
||||||
radial-gradient(120% 160% at 100% 100%, rgb(34 211 238 / 0.14), transparent 55%),
|
radial-gradient(120% 160% at 100% 100%, rgb(24 24 27 / 0.14), transparent 55%),
|
||||||
rgb(255 255 255 / 0.04);
|
rgb(255 255 255 / 0.04);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,7 +124,7 @@ html:not(.dark) .theme-text :is([class*="bg-slate-900"], [class*="bg-slate-800"]
|
|||||||
shell and washes out on white. In LIGHT mode, darken to the -600 tone. The
|
shell and washes out on white. In LIGHT mode, darken to the -600 tone. The
|
||||||
matcher also catches the /80 opacity variants. Badges keep their pale tinted
|
matcher also catches the /80 opacity variants. Badges keep their pale tinted
|
||||||
bg (bg-*-500/10) which reads fine on white. */
|
bg (bg-*-500/10) which reads fine on white. */
|
||||||
html:not(.dark) .theme-text :is([class*="text-sky-300"], [class*="text-sky-200"]) { color: rgb(79 70 229); }
|
html:not(.dark) .theme-text :is([class*="text-sky-300"], [class*="text-sky-200"]) { color: rgb(24 24 27); }
|
||||||
html:not(.dark) .theme-text :is([class*="text-orange-300"], [class*="text-orange-200"]) { color: rgb(124 58 237); }
|
html:not(.dark) .theme-text :is([class*="text-orange-300"], [class*="text-orange-200"]) { color: rgb(124 58 237); }
|
||||||
html:not(.dark) .theme-text :is([class*="text-rose-300"], [class*="text-rose-200"]) { color: rgb(225 29 72); }
|
html:not(.dark) .theme-text :is([class*="text-rose-300"], [class*="text-rose-200"]) { color: rgb(225 29 72); }
|
||||||
html:not(.dark) .theme-text :is([class*="text-emerald-300"], [class*="text-emerald-200"]) { color: rgb(5 150 105); }
|
html:not(.dark) .theme-text :is([class*="text-emerald-300"], [class*="text-emerald-200"]) { color: rgb(5 150 105); }
|
||||||
@@ -144,7 +144,7 @@ html:not(.dark) .theme-text :is(.fp, .pg, .act, .filter-pill, .kind-btn, .preset
|
|||||||
color: var(--fg); background: var(--hover);
|
color: var(--fg); background: var(--hover);
|
||||||
}
|
}
|
||||||
html:not(.dark) .theme-text :is(.fp-on, .pg-on, .seg-on, .opt-on) {
|
html:not(.dark) .theme-text :is(.fp-on, .pg-on, .seg-on, .opt-on) {
|
||||||
background: linear-gradient(120deg, #7c5cfc, #5f6cf8); color: #fff;
|
background: linear-gradient(120deg, #18181b, #27272a); color: #fff;
|
||||||
box-shadow: 0 4px 16px var(--accent-glow);
|
box-shadow: 0 4px 16px var(--accent-glow);
|
||||||
}
|
}
|
||||||
/* Tag chips (TagInput) — near-white orange text is unreadable on white; keep
|
/* Tag chips (TagInput) — near-white orange text is unreadable on white; keep
|
||||||
@@ -157,7 +157,7 @@ html:not(.dark) .theme-text .chip .chip-x:hover { color: #fff; background: rgb(2
|
|||||||
neutral `.filter-pill`/`.kind-btn` rescue paints selected == unselected and
|
neutral `.filter-pill`/`.kind-btn` rescue paints selected == unselected and
|
||||||
the highlight vanishes on a white page. Equal-or-higher specificity, later. */
|
the highlight vanishes on a white page. Equal-or-higher specificity, later. */
|
||||||
html:not(.dark) .theme-text :is(.filter-pill, .kind-btn).on {
|
html:not(.dark) .theme-text :is(.filter-pill, .kind-btn).on {
|
||||||
background: linear-gradient(120deg, #7c5cfc, #5f6cf8); color: #fff;
|
background: linear-gradient(120deg, #18181b, #27272a); color: #fff;
|
||||||
box-shadow: 0 4px 16px var(--accent-glow);
|
box-shadow: 0 4px 16px var(--accent-glow);
|
||||||
}
|
}
|
||||||
/* Selected COLORED filter pills — their scoped (dark) selected colors get
|
/* Selected COLORED filter pills — their scoped (dark) selected colors get
|
||||||
@@ -167,7 +167,7 @@ html:not(.dark) .theme-text :is(.filter-pill, .kind-btn).on {
|
|||||||
html:not(.dark) .theme-text .fp-emerald { background: rgb(16 185 129 / 0.14); color: rgb(4 120 87); box-shadow: inset 0 0 0 1px rgb(16 185 129 / 0.45); }
|
html:not(.dark) .theme-text .fp-emerald { background: rgb(16 185 129 / 0.14); color: rgb(4 120 87); box-shadow: inset 0 0 0 1px rgb(16 185 129 / 0.45); }
|
||||||
html:not(.dark) .theme-text .fp-rose { background: rgb(244 63 94 / 0.12); color: rgb(190 18 60); box-shadow: inset 0 0 0 1px rgb(244 63 94 / 0.45); }
|
html:not(.dark) .theme-text .fp-rose { background: rgb(244 63 94 / 0.12); color: rgb(190 18 60); box-shadow: inset 0 0 0 1px rgb(244 63 94 / 0.45); }
|
||||||
html:not(.dark) .theme-text .fp-amber { background: rgb(245 158 11 / 0.16); color: rgb(180 83 9); box-shadow: inset 0 0 0 1px rgb(245 158 11 / 0.5); }
|
html:not(.dark) .theme-text .fp-amber { background: rgb(245 158 11 / 0.16); color: rgb(180 83 9); box-shadow: inset 0 0 0 1px rgb(245 158 11 / 0.5); }
|
||||||
html:not(.dark) .theme-text .fp-orange { background: rgb(139 92 246 / 0.14); color: rgb(109 40 217); box-shadow: inset 0 0 0 1px rgb(139 92 246 / 0.45); }
|
html:not(.dark) .theme-text .fp-orange { background: rgb(24 24 27 / 0.14); color: rgb(24 24 27); box-shadow: inset 0 0 0 1px rgb(24 24 27 / 0.45); }
|
||||||
html:not(.dark) .theme-text .fp-pink { background: rgb(244 114 182 / 0.14); color: rgb(190 24 93); box-shadow: inset 0 0 0 1px rgb(244 114 182 / 0.45); }
|
html:not(.dark) .theme-text .fp-pink { background: rgb(244 114 182 / 0.14); color: rgb(190 24 93); box-shadow: inset 0 0 0 1px rgb(244 114 182 / 0.45); }
|
||||||
html:not(.dark) .theme-text .fp-slate { background: rgb(100 116 139 / 0.14); color: rgb(51 65 85); box-shadow: inset 0 0 0 1px rgb(100 116 139 / 0.45); }
|
html:not(.dark) .theme-text .fp-slate { background: rgb(100 116 139 / 0.14); color: rgb(51 65 85); box-shadow: inset 0 0 0 1px rgb(100 116 139 / 0.45); }
|
||||||
html:not(.dark) .theme-text .fp-sky { background: rgb(14 165 233 / 0.14); color: rgb(3 105 161); box-shadow: inset 0 0 0 1px rgb(14 165 233 / 0.45); }
|
html:not(.dark) .theme-text .fp-sky { background: rgb(14 165 233 / 0.14); color: rgb(3 105 161); box-shadow: inset 0 0 0 1px rgb(14 165 233 / 0.45); }
|
||||||
@@ -193,7 +193,7 @@ html:not(.dark) .theme-text .fp-teal { background: rgb(20 184 166 / 0.14); color
|
|||||||
.chk { border-color: var(--ink); }
|
.chk { border-color: var(--ink); }
|
||||||
.chk:hover:not(:checked) { border-color: var(--m-orange); }
|
.chk:hover:not(:checked) { border-color: var(--m-orange); }
|
||||||
.chk:checked {
|
.chk:checked {
|
||||||
background: linear-gradient(135deg, #7c5cfc, #22d3ee);
|
background: linear-gradient(135deg, #18181b, #52525b);
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
box-shadow: 0 2px 10px var(--accent-glow);
|
box-shadow: 0 2px 10px var(--accent-glow);
|
||||||
}
|
}
|
||||||
@@ -206,7 +206,7 @@ html:not(.dark) .theme-text .fp-teal { background: rgb(20 184 166 / 0.14); color
|
|||||||
transform: rotate(45deg);
|
transform: rotate(45deg);
|
||||||
margin-top: -0.12rem;
|
margin-top: -0.12rem;
|
||||||
}
|
}
|
||||||
.chk:focus-visible { outline: 2px solid rgb(124 92 252 / 0.5); outline-offset: 1px; }
|
.chk:focus-visible { outline: 2px solid rgb(24 24 27 / 0.5); outline-offset: 1px; }
|
||||||
/* Account identity tags (AccountsView: 子号 / 母号 / 普号 / 限额). The colors live
|
/* Account identity tags (AccountsView: 子号 / 母号 / 普号 / 限额). The colors live
|
||||||
here rather than as inline dark-palette utilities, which were invisible on the
|
here rather than as inline dark-palette utilities, which were invisible on the
|
||||||
light theme: light values first, html.dark override after. */
|
light theme: light values first, html.dark override after. */
|
||||||
@@ -222,11 +222,11 @@ html:not(.dark) .theme-text .fp-teal { background: rgb(20 184 166 / 0.14); color
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
.acct-tag-sub { background: rgb(14 165 233 / 0.14); color: rgb(3 105 161); box-shadow: inset 0 0 0 1px rgb(14 165 233 / 0.4); }
|
.acct-tag-sub { background: rgb(14 165 233 / 0.14); color: rgb(3 105 161); box-shadow: inset 0 0 0 1px rgb(14 165 233 / 0.4); }
|
||||||
.acct-tag-master { background: rgb(139 92 246 / 0.14); color: rgb(109 40 217); box-shadow: inset 0 0 0 1px rgb(139 92 246 / 0.4); }
|
.acct-tag-master { background: rgb(24 24 27 / 0.14); color: rgb(24 24 27); box-shadow: inset 0 0 0 1px rgb(24 24 27 / 0.4); }
|
||||||
.acct-tag-free { background: rgb(100 116 139 / 0.14); color: rgb(51 65 85); box-shadow: inset 0 0 0 1px rgb(100 116 139 / 0.4); }
|
.acct-tag-free { background: rgb(100 116 139 / 0.14); color: rgb(51 65 85); box-shadow: inset 0 0 0 1px rgb(100 116 139 / 0.4); }
|
||||||
.acct-tag-limit { background: rgb(245 158 11 / 0.16); color: rgb(180 83 9); box-shadow: inset 0 0 0 1px rgb(245 158 11 / 0.4); }
|
.acct-tag-limit { background: rgb(245 158 11 / 0.16); color: rgb(180 83 9); box-shadow: inset 0 0 0 1px rgb(245 158 11 / 0.4); }
|
||||||
html.dark .acct-tag-sub { background: rgb(14 165 233 / 0.18); color: rgb(125 211 252); box-shadow: inset 0 0 0 1px rgb(56 189 248 / 0.35); }
|
html.dark .acct-tag-sub { background: rgb(14 165 233 / 0.18); color: rgb(125 211 252); box-shadow: inset 0 0 0 1px rgb(56 189 248 / 0.35); }
|
||||||
html.dark .acct-tag-master { background: rgb(139 92 246 / 0.22); color: rgb(196 181 253); box-shadow: inset 0 0 0 1px rgb(167 139 250 / 0.35); }
|
html.dark .acct-tag-master { background: rgb(24 24 27 / 0.22); color: rgb(161 161 170); box-shadow: inset 0 0 0 1px rgb(167 139 250 / 0.35); }
|
||||||
html.dark .acct-tag-free { background: rgb(148 163 184 / 0.22); color: rgb(226 232 240); box-shadow: inset 0 0 0 1px rgb(148 163 184 / 0.35); }
|
html.dark .acct-tag-free { background: rgb(148 163 184 / 0.22); color: rgb(226 232 240); box-shadow: inset 0 0 0 1px rgb(148 163 184 / 0.35); }
|
||||||
html.dark .acct-tag-limit { background: rgb(245 158 11 / 0.18); color: rgb(252 211 77); box-shadow: inset 0 0 0 1px rgb(251 191 36 / 0.35); }
|
html.dark .acct-tag-limit { background: rgb(245 158 11 / 0.18); color: rgb(252 211 77); box-shadow: inset 0 0 0 1px rgb(251 191 36 / 0.35); }
|
||||||
/* Capability chips (ModelsView): all variants need bg + ring + color reset in light mode.
|
/* Capability chips (ModelsView): all variants need bg + ring + color reset in light mode.
|
||||||
@@ -283,7 +283,7 @@ html:not(.dark) .media-card :is([class*="border-white/"], [class*="ring-white/"]
|
|||||||
html:not(.dark) .media-card :is([class*="text-emerald-3"], [class*="text-emerald-2"]) { color: rgb(110 231 183) !important; }
|
html:not(.dark) .media-card :is([class*="text-emerald-3"], [class*="text-emerald-2"]) { color: rgb(110 231 183) !important; }
|
||||||
html:not(.dark) .media-card :is([class*="text-rose-3"], [class*="text-rose-2"]) { color: rgb(251 207 232) !important; }
|
html:not(.dark) .media-card :is([class*="text-rose-3"], [class*="text-rose-2"]) { color: rgb(251 207 232) !important; }
|
||||||
html:not(.dark) .media-card :is([class*="text-sky-3"], [class*="text-sky-2"]) { color: rgb(147 197 253) !important; }
|
html:not(.dark) .media-card :is([class*="text-sky-3"], [class*="text-sky-2"]) { color: rgb(147 197 253) !important; }
|
||||||
html:not(.dark) .media-card :is([class*="text-orange-3"], [class*="text-orange-2"]) { color: rgb(196 181 253) !important; }
|
html:not(.dark) .media-card :is([class*="text-orange-3"], [class*="text-orange-2"]) { color: rgb(161 161 170) !important; }
|
||||||
html:not(.dark) .media-card :is([class*="text-sky-3"], [class*="text-sky-2"]) { color: rgb(125 211 252) !important; }
|
html:not(.dark) .media-card :is([class*="text-sky-3"], [class*="text-sky-2"]) { color: rgb(125 211 252) !important; }
|
||||||
html:not(.dark) .media-card :is([class*="text-amber-3"], [class*="text-amber-2"]) { color: rgb(252 211 77) !important; }
|
html:not(.dark) .media-card :is([class*="text-amber-3"], [class*="text-amber-2"]) { color: rgb(252 211 77) !important; }
|
||||||
|
|
||||||
@@ -311,7 +311,7 @@ body {
|
|||||||
/* Aurora ambient gradient + grain (used by PublicLayout via .ambient-bg) */
|
/* Aurora ambient gradient + grain (used by PublicLayout via .ambient-bg) */
|
||||||
}
|
}
|
||||||
|
|
||||||
::selection { background: rgb(139 92 246 / 0.32); color: inherit; }
|
::selection { background: rgb(24 24 27 / 0.32); color: inherit; }
|
||||||
html:not(.dark) ::selection { color: #181524; }
|
html:not(.dark) ::selection { color: #181524; }
|
||||||
|
|
||||||
/* Tailwind v4 / preflight leaves <button> on the default arrow cursor, so
|
/* Tailwind v4 / preflight leaves <button> on the default arrow cursor, so
|
||||||
@@ -335,18 +335,18 @@ button:not(:disabled), [role="button"]:not([aria-disabled="true"]) { cursor: poi
|
|||||||
over-media tables are untouched; specificity outranks the per-view
|
over-media tables are untouched; specificity outranks the per-view
|
||||||
Tailwind hover utilities and the light-mode white rescue. */
|
Tailwind hover utilities and the light-mode white rescue. */
|
||||||
.theme-text .card table thead {
|
.theme-text .card table thead {
|
||||||
background: linear-gradient(180deg, rgb(124 92 252 / 0.07), rgb(124 92 252 / 0.025));
|
background: linear-gradient(180deg, rgb(24 24 27 / 0.07), rgb(24 24 27 / 0.025));
|
||||||
}
|
}
|
||||||
html.dark .theme-text .card table thead {
|
html.dark .theme-text .card table thead {
|
||||||
background: linear-gradient(180deg, rgb(139 92 246 / 0.13), rgb(139 92 246 / 0.05));
|
background: linear-gradient(180deg, rgb(24 24 27 / 0.13), rgb(24 24 27 / 0.05));
|
||||||
}
|
}
|
||||||
.theme-text .card table tbody tr { transition: background-color 0.15s ease; }
|
.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); }
|
.theme-text .card table tbody tr:hover { background-color: rgb(24 24 27 / 0.08); }
|
||||||
html.dark .theme-text .card table tbody tr:hover { background-color: rgb(139 92 246 / 0.11); }
|
html.dark .theme-text .card table tbody tr:hover { background-color: rgb(24 24 27 / 0.11); }
|
||||||
/* Checkbox column + first data column get a hair more air against the
|
/* Checkbox column + first data column get a hair more air against the
|
||||||
card edge so dense tables don't feel cramped. */
|
card edge so dense tables don't feel cramped. */
|
||||||
.theme-text .card table tbody tr:hover :is(td, th):first-child {
|
.theme-text .card table tbody tr:hover :is(td, th):first-child {
|
||||||
box-shadow: inset 2px 0 0 rgb(124 92 252 / 0.55);
|
box-shadow: inset 2px 0 0 rgb(24 24 27 / 0.55);
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar { width: 9px; height: 9px; }
|
::-webkit-scrollbar { width: 9px; height: 9px; }
|
||||||
@@ -359,16 +359,12 @@ html.dark ::-webkit-scrollbar-thumb:hover { background: rgb(255 255 255 / 0.32);
|
|||||||
/* ===== Ambient background — aurora wash used by the public shell ===== */
|
/* ===== Ambient background — aurora wash used by the public shell ===== */
|
||||||
.ambient-bg {
|
.ambient-bg {
|
||||||
background-color: var(--app-bg);
|
background-color: var(--app-bg);
|
||||||
background-image:
|
}
|
||||||
radial-gradient(60rem 40rem at 12% -10%, rgb(124 92 252 / 0.14), transparent 60%),
|
|
||||||
radial-gradient(52rem 36rem at 92% 8%, rgb(34 211 238 / 0.11), transparent 60%),
|
|
||||||
radial-gradient(46rem 32rem at 8% 96%, rgb(240 171 252 / 0.1), transparent 60%);
|
|
||||||
}
|
|
||||||
html.dark .ambient-bg {
|
html.dark .ambient-bg {
|
||||||
background-image:
|
background-image:
|
||||||
radial-gradient(60rem 40rem at 12% -10%, rgb(139 92 246 / 0.2), transparent 60%),
|
radial-gradient(60rem 40rem at 12% -10%, rgb(24 24 27 / 0.2), transparent 60%),
|
||||||
radial-gradient(52rem 36rem at 92% 8%, rgb(34 211 238 / 0.13), transparent 60%),
|
radial-gradient(52rem 36rem at 92% 8%, rgb(24 24 27 / 0.13), transparent 60%),
|
||||||
radial-gradient(46rem 32rem at 8% 96%, rgb(232 121 249 / 0.1), transparent 60%);
|
radial-gradient(46rem 32rem at 8% 96%, rgb(24 24 27 / 0.1), transparent 60%);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ===== Glass / aurora design kit =====
|
/* ===== Glass / aurora design kit =====
|
||||||
@@ -378,7 +374,7 @@ html.dark .ambient-bg {
|
|||||||
|
|
||||||
/* Gradient headline text — violet → cyan swipe. */
|
/* Gradient headline text — violet → cyan swipe. */
|
||||||
.anime-grad-text {
|
.anime-grad-text {
|
||||||
background: linear-gradient(100deg, #7c5cfc 0%, #a855f7 45%, #22d3ee 100%);
|
background: linear-gradient(100deg, #18181b 0%, #3f3f46 45%, #52525b 100%);
|
||||||
-webkit-background-clip: text;
|
-webkit-background-clip: text;
|
||||||
background-clip: text;
|
background-clip: text;
|
||||||
-webkit-text-fill-color: transparent;
|
-webkit-text-fill-color: transparent;
|
||||||
@@ -386,7 +382,7 @@ html.dark .ambient-bg {
|
|||||||
padding: 0 0.05em;
|
padding: 0 0.05em;
|
||||||
}
|
}
|
||||||
html.dark .anime-grad-text {
|
html.dark .anime-grad-text {
|
||||||
background: linear-gradient(100deg, #a78bfa 0%, #e879f9 45%, #67e8f9 100%);
|
background: linear-gradient(100deg, #71717a 0%, #e879f9 45%, #67e8f9 100%);
|
||||||
-webkit-background-clip: text;
|
-webkit-background-clip: text;
|
||||||
background-clip: text;
|
background-clip: text;
|
||||||
}
|
}
|
||||||
@@ -432,7 +428,7 @@ html.dark .anime-grad-text {
|
|||||||
color: #fff;
|
color: #fff;
|
||||||
border: 1px solid rgb(255 255 255 / 0.18);
|
border: 1px solid rgb(255 255 255 / 0.18);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background: linear-gradient(120deg, #7c5cfc, #5f6cf8 55%, #22d3ee);
|
background: linear-gradient(120deg, #18181b, #27272a 55%, #52525b);
|
||||||
box-shadow: 0 8px 24px var(--accent-glow);
|
box-shadow: 0 8px 24px var(--accent-glow);
|
||||||
transition: transform 0.15s ease, box-shadow 0.15s ease, filter 0.15s ease;
|
transition: transform 0.15s ease, box-shadow 0.15s ease, filter 0.15s ease;
|
||||||
}
|
}
|
||||||
@@ -458,7 +454,7 @@ html.dark .anime-grad-text {
|
|||||||
/* Selected pill — gradient fill with a glow. */
|
/* Selected pill — gradient fill with a glow. */
|
||||||
.chip-on {
|
.chip-on {
|
||||||
color: #fff !important;
|
color: #fff !important;
|
||||||
background: linear-gradient(120deg, #7c5cfc, #5f6cf8) !important;
|
background: linear-gradient(120deg, #18181b, #27272a) !important;
|
||||||
border: 1px solid transparent !important;
|
border: 1px solid transparent !important;
|
||||||
box-shadow: 0 4px 16px var(--accent-glow) !important;
|
box-shadow: 0 4px 16px var(--accent-glow) !important;
|
||||||
}
|
}
|
||||||
@@ -470,11 +466,11 @@ html.dark .anime-grad-text {
|
|||||||
inset: 0;
|
inset: 0;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
background-image:
|
background-image:
|
||||||
radial-gradient(1.5px 1.5px at 12% 22%, rgb(139 92 246 / 0.7), transparent),
|
radial-gradient(1.5px 1.5px at 12% 22%, rgb(24 24 27 / 0.7), transparent),
|
||||||
radial-gradient(1.5px 1.5px at 78% 12%, rgb(34 211 238 / 0.7), transparent),
|
radial-gradient(1.5px 1.5px at 78% 12%, rgb(24 24 27 / 0.7), transparent),
|
||||||
radial-gradient(1px 1px at 42% 62%, rgb(139 92 246 / 0.6), transparent),
|
radial-gradient(1px 1px at 42% 62%, rgb(24 24 27 / 0.6), transparent),
|
||||||
radial-gradient(1.5px 1.5px at 88% 72%, rgb(232 121 249 / 0.6), transparent),
|
radial-gradient(1.5px 1.5px at 88% 72%, rgb(24 24 27 / 0.6), transparent),
|
||||||
radial-gradient(1px 1px at 24% 84%, rgb(34 211 238 / 0.55), transparent),
|
radial-gradient(1px 1px at 24% 84%, rgb(24 24 27 / 0.55), transparent),
|
||||||
radial-gradient(1px 1px at 62% 34%, rgb(167 139 250 / 0.55), transparent);
|
radial-gradient(1px 1px at 62% 34%, rgb(167 139 250 / 0.55), transparent);
|
||||||
animation: twinkle 4.5s ease-in-out infinite;
|
animation: twinkle 4.5s ease-in-out infinite;
|
||||||
}
|
}
|
||||||
@@ -540,7 +536,7 @@ html.dark .memphis-dots {
|
|||||||
font-size: 1.8rem;
|
font-size: 1.8rem;
|
||||||
font-weight: 900;
|
font-weight: 900;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background: linear-gradient(135deg, #7c5cfc, #22d3ee);
|
background: linear-gradient(135deg, #18181b, #52525b);
|
||||||
border: 1px solid rgb(255 255 255 / 0.2);
|
border: 1px solid rgb(255 255 255 / 0.2);
|
||||||
border-radius: 1.2rem;
|
border-radius: 1.2rem;
|
||||||
box-shadow: 0 12px 32px var(--accent-glow);
|
box-shadow: 0 12px 32px var(--accent-glow);
|
||||||
@@ -580,9 +576,9 @@ html.dark .memphis-dots {
|
|||||||
a violet glow ring, matching the light theme's focus affordance. */
|
a violet glow ring, matching the light theme's focus affordance. */
|
||||||
.public-dark .field:focus,
|
.public-dark .field:focus,
|
||||||
.public-dark .field:focus-visible {
|
.public-dark .field:focus-visible {
|
||||||
border-color: rgb(139 92 246 / 0.7);
|
border-color: rgb(24 24 27 / 0.7);
|
||||||
background: rgb(255 255 255 / 0.06);
|
background: rgb(255 255 255 / 0.06);
|
||||||
box-shadow: 0 0 0 3px rgb(139 92 246 / 0.25);
|
box-shadow: 0 0 0 3px rgb(24 24 27 / 0.25);
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
.public-dark .btn-soft {
|
.public-dark .btn-soft {
|
||||||
@@ -590,11 +586,11 @@ html.dark .memphis-dots {
|
|||||||
border-color: rgb(255 255 255 / 0.12);
|
border-color: rgb(255 255 255 / 0.12);
|
||||||
color: rgb(255 255 255 / 0.85);
|
color: rgb(255 255 255 / 0.85);
|
||||||
}
|
}
|
||||||
.public-dark .btn-soft:hover { background: rgb(139 92 246 / 0.25); color: white; }
|
.public-dark .btn-soft:hover { background: rgb(24 24 27 / 0.25); color: white; }
|
||||||
.public-dark .btn-ghost { color: rgb(255 255 255 / 0.65); border-color: transparent; }
|
.public-dark .btn-ghost { color: rgb(255 255 255 / 0.65); border-color: transparent; }
|
||||||
.public-dark .btn-ghost:hover { background: rgb(139 92 246 / 0.18); color: white; }
|
.public-dark .btn-ghost:hover { background: rgb(24 24 27 / 0.18); color: white; }
|
||||||
.public-dark .btn-primary {
|
.public-dark .btn-primary {
|
||||||
background: linear-gradient(120deg, #7c5cfc, #5f6cf8); color: #fff;
|
background: linear-gradient(120deg, #18181b, #27272a); color: #fff;
|
||||||
box-shadow: 0 6px 18px var(--accent-glow);
|
box-shadow: 0 6px 18px var(--accent-glow);
|
||||||
}
|
}
|
||||||
.public-dark .btn-primary:hover { filter: brightness(1.08); }
|
.public-dark .btn-primary:hover { filter: brightness(1.08); }
|
||||||
@@ -622,7 +618,7 @@ html.dark .memphis-dots {
|
|||||||
/* Tables in dark */
|
/* Tables in dark */
|
||||||
.public-dark .th { color: rgb(255 255 255 / 0.4); }
|
.public-dark .th { color: rgb(255 255 255 / 0.4); }
|
||||||
.public-dark .row { border-color: rgb(255 255 255 / 0.06); }
|
.public-dark .row { border-color: rgb(255 255 255 / 0.06); }
|
||||||
.public-dark .row:hover { background: rgb(139 92 246 / 0.07); }
|
.public-dark .row:hover { background: rgb(24 24 27 / 0.07); }
|
||||||
|
|
||||||
/* Inline code blocks (pill highlight) — only for inline <code>, NOT code inside
|
/* Inline code blocks (pill highlight) — only for inline <code>, NOT code inside
|
||||||
a <pre> block (docs examples), which would get an unwanted full-width tint. */
|
a <pre> block (docs examples), which would get an unwanted full-width tint. */
|
||||||
@@ -665,7 +661,7 @@ html.dark .memphis-dots {
|
|||||||
@apply inline-flex items-center justify-center gap-1.5 rounded-lg text-sm font-bold
|
@apply inline-flex items-center justify-center gap-1.5 rounded-lg text-sm font-bold
|
||||||
disabled:opacity-50 disabled:cursor-not-allowed px-3.5 py-2;
|
disabled:opacity-50 disabled:cursor-not-allowed px-3.5 py-2;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background: linear-gradient(120deg, #7c5cfc, #5f6cf8 60%, #22d3ee 140%);
|
background: linear-gradient(120deg, #18181b, #27272a 60%, #52525b 140%);
|
||||||
border: 1px solid rgb(255 255 255 / 0.16);
|
border: 1px solid rgb(255 255 255 / 0.16);
|
||||||
box-shadow: 0 6px 18px var(--accent-glow);
|
box-shadow: 0 6px 18px var(--accent-glow);
|
||||||
transition: transform 0.13s ease, box-shadow 0.13s ease, filter 0.13s ease;
|
transition: transform 0.13s ease, box-shadow 0.13s ease, filter 0.13s ease;
|
||||||
@@ -685,10 +681,10 @@ html.dark .memphis-dots {
|
|||||||
.btn-soft:hover:not(:disabled) {
|
.btn-soft:hover:not(:disabled) {
|
||||||
color: var(--fg);
|
color: var(--fg);
|
||||||
background: var(--hover);
|
background: var(--hover);
|
||||||
border-color: rgb(124 92 252 / 0.45);
|
border-color: rgb(24 24 27 / 0.45);
|
||||||
box-shadow: 0 4px 14px rgb(124 92 252 / 0.16);
|
box-shadow: 0 4px 14px rgb(24 24 27 / 0.16);
|
||||||
}
|
}
|
||||||
html.dark .btn-soft:hover:not(:disabled) { border-color: rgb(139 92 246 / 0.5); box-shadow: 0 4px 14px rgb(139 92 246 / 0.22); }
|
html.dark .btn-soft:hover:not(:disabled) { border-color: rgb(24 24 27 / 0.5); box-shadow: 0 4px 14px rgb(24 24 27 / 0.22); }
|
||||||
.btn-soft:active:not(:disabled) { transform: scale(0.97) translateY(1px); box-shadow: none; }
|
.btn-soft:active:not(:disabled) { transform: scale(0.97) translateY(1px); box-shadow: none; }
|
||||||
.btn-ghost {
|
.btn-ghost {
|
||||||
@apply inline-flex items-center justify-center gap-1.5 rounded-lg text-xs font-medium
|
@apply inline-flex items-center justify-center gap-1.5 rounded-lg text-xs font-medium
|
||||||
@@ -700,7 +696,7 @@ html.dark .memphis-dots {
|
|||||||
.btn-ghost:hover:not(:disabled) {
|
.btn-ghost:hover:not(:disabled) {
|
||||||
color: var(--fg);
|
color: var(--fg);
|
||||||
background: var(--hover);
|
background: var(--hover);
|
||||||
border-color: rgb(124 92 252 / 0.3);
|
border-color: rgb(24 24 27 / 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* text link / quiet action */
|
/* text link / quiet action */
|
||||||
@@ -717,12 +713,12 @@ html.dark .memphis-dots {
|
|||||||
transition: border-color 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
|
transition: border-color 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
|
||||||
}
|
}
|
||||||
.field:focus, .field:focus-visible {
|
.field:focus, .field:focus-visible {
|
||||||
border-color: rgb(124 92 252 / 0.65);
|
border-color: rgb(24 24 27 / 0.65);
|
||||||
box-shadow: 0 0 0 3px rgb(124 92 252 / 0.18);
|
box-shadow: 0 0 0 3px rgb(24 24 27 / 0.18);
|
||||||
}
|
}
|
||||||
html.dark .field:focus, html.dark .field:focus-visible {
|
html.dark .field:focus, html.dark .field:focus-visible {
|
||||||
border-color: rgb(139 92 246 / 0.7);
|
border-color: rgb(24 24 27 / 0.7);
|
||||||
box-shadow: 0 0 0 3px rgb(139 92 246 / 0.25);
|
box-shadow: 0 0 0 3px rgb(24 24 27 / 0.25);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Native <select> using .field: drop the OS arrow for a custom chevron that
|
/* Native <select> using .field: drop the OS arrow for a custom chevron that
|
||||||
@@ -758,7 +754,7 @@ html.dark .memphis-dots {
|
|||||||
.th { @apply text-left px-4 py-3 text-[11px] font-bold uppercase tracking-wider; color: var(--fg-faint); }
|
.th { @apply text-left px-4 py-3 text-[11px] font-bold uppercase tracking-wider; color: var(--fg-faint); }
|
||||||
.td { @apply px-4 py-3.5 align-middle; }
|
.td { @apply px-4 py-3.5 align-middle; }
|
||||||
.row { @apply border-t transition-colors; border-color: var(--hairline); }
|
.row { @apply border-t transition-colors; border-color: var(--hairline); }
|
||||||
.row:hover { background: rgb(124 92 252 / 0.06); }
|
.row:hover { background: rgb(24 24 27 / 0.06); }
|
||||||
|
|
||||||
/* avatar chip for identity columns */
|
/* avatar chip for identity columns */
|
||||||
.avatar {
|
.avatar {
|
||||||
|
|||||||
+4
-43
@@ -1,46 +1,7 @@
|
|||||||
// Light/dark theme state. Default is LIGHT. The choice persists in localStorage
|
// 固定亮色主题:不再提供光/暗切换,并清掉历史上保存的暗色选择。
|
||||||
// and is reflected as a `dark` class on <html>, which drives the CSS-variable
|
|
||||||
// palette in style.css (and the conditional `.public-dark` override layer).
|
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
|
|
||||||
const KEY = 'gw_theme'
|
localStorage.removeItem('gw_theme')
|
||||||
const mql = window.matchMedia ? window.matchMedia('(prefers-color-scheme: dark)') : null
|
document.documentElement.classList.remove('dark')
|
||||||
|
|
||||||
function systemTheme() {
|
export const isDark = ref(false)
|
||||||
return mql && mql.matches ? 'dark' : 'light'
|
|
||||||
}
|
|
||||||
|
|
||||||
// Precedence: an explicit user choice (localStorage) wins; otherwise follow the
|
|
||||||
// OS's light/dark setting.
|
|
||||||
const saved = localStorage.getItem(KEY)
|
|
||||||
const initial = saved === 'dark' || saved === 'light' ? saved : systemTheme()
|
|
||||||
|
|
||||||
export const theme = ref(initial)
|
|
||||||
export const isDark = ref(initial === 'dark')
|
|
||||||
|
|
||||||
function apply(t) {
|
|
||||||
isDark.value = t === 'dark'
|
|
||||||
const el = document.documentElement
|
|
||||||
el.classList.toggle('dark', t === 'dark')
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply at module load so the first paint already matches the resolved choice.
|
|
||||||
apply(theme.value)
|
|
||||||
|
|
||||||
// While the user hasn't made an explicit choice, keep tracking the OS setting
|
|
||||||
// live (e.g. they flip macOS/Windows to dark mode with the tab open).
|
|
||||||
if (mql) {
|
|
||||||
mql.addEventListener('change', () => {
|
|
||||||
if (!localStorage.getItem(KEY)) {
|
|
||||||
theme.value = systemTheme()
|
|
||||||
apply(theme.value)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Flip light ⇄ dark and persist as the user's explicit choice. */
|
|
||||||
export function toggleTheme() {
|
|
||||||
theme.value = theme.value === 'dark' ? 'light' : 'dark'
|
|
||||||
localStorage.setItem(KEY, theme.value)
|
|
||||||
apply(theme.value)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ const contact = computed(() => site.contact || {})
|
|||||||
const powers = [
|
const powers = [
|
||||||
{ icon: 't2i', title: '文字生图', desc: '一句话出图,画幅与分辨率随模型可选。', tint: 'linear-gradient(135deg,#34d399,#2dd4bf)' },
|
{ icon: 't2i', title: '文字生图', desc: '一句话出图,画幅与分辨率随模型可选。', tint: 'linear-gradient(135deg,#34d399,#2dd4bf)' },
|
||||||
{ icon: 'i2i', title: '参考图生图', desc: '上传参考换风格、改构图、做变体。', tint: 'linear-gradient(135deg,#e879f9,#f472b6)' },
|
{ icon: 'i2i', title: '参考图生图', desc: '上传参考换风格、改构图、做变体。', tint: 'linear-gradient(135deg,#e879f9,#f472b6)' },
|
||||||
{ icon: 't2v', title: '文字生视频', desc: '一段描述生成短片,时长分辨率可选。', tint: 'linear-gradient(135deg,#38bdf8,#22d3ee)' },
|
{ icon: 't2v', title: '文字生视频', desc: '一段描述生成短片,时长分辨率可选。', tint: 'linear-gradient(135deg,#38bdf8,#52525b)' },
|
||||||
{ icon: 'i2v', title: '图生视频', desc: '给张参考图,让静态画面动起来。', tint: 'linear-gradient(135deg,#7c5cfc,#a855f7)' },
|
{ icon: 'i2v', title: '图生视频', desc: '给张参考图,让静态画面动起来。', tint: 'linear-gradient(135deg,#18181b,#3f3f46)' },
|
||||||
]
|
]
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -154,7 +154,7 @@ const powers = [
|
|||||||
box-shadow: var(--glass-shadow);
|
box-shadow: var(--glass-shadow);
|
||||||
transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
|
transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
|
||||||
}
|
}
|
||||||
.power-card:hover { transform: translateY(-3px); border-color: rgb(124 92 252 / 0.45); box-shadow: var(--glass-shadow-lg); }
|
.power-card:hover { transform: translateY(-3px); border-color: rgb(24 24 27 / 0.45); box-shadow: var(--glass-shadow-lg); }
|
||||||
.power-ico {
|
.power-ico {
|
||||||
width: 2.6rem;
|
width: 2.6rem;
|
||||||
height: 2.6rem;
|
height: 2.6rem;
|
||||||
@@ -162,7 +162,7 @@ const powers = [
|
|||||||
display: grid;
|
display: grid;
|
||||||
place-items: center;
|
place-items: center;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
box-shadow: 0 6px 16px rgb(124 92 252 / 0.28);
|
box-shadow: 0 6px 16px rgb(24 24 27 / 0.28);
|
||||||
}
|
}
|
||||||
.power-ico svg { width: 1.3rem; height: 1.3rem; }
|
.power-ico svg { width: 1.3rem; height: 1.3rem; }
|
||||||
@media (max-width: 768px) { .ab-cluster { display: none; } }
|
@media (max-width: 768px) { .ab-cluster { display: none; } }
|
||||||
|
|||||||
@@ -1119,7 +1119,7 @@ const saveLabel = computed(() => ({
|
|||||||
}
|
}
|
||||||
.cv-btn:hover:not(:disabled) {
|
.cv-btn:hover:not(:disabled) {
|
||||||
background: var(--hover);
|
background: var(--hover);
|
||||||
border-color: rgb(124 92 252 / 0.45);
|
border-color: rgb(24 24 27 / 0.45);
|
||||||
box-shadow: 0 4px 14px var(--accent-glow);
|
box-shadow: 0 4px 14px var(--accent-glow);
|
||||||
transform: translateY(-1px);
|
transform: translateY(-1px);
|
||||||
}
|
}
|
||||||
@@ -1136,13 +1136,13 @@ const saveLabel = computed(() => ({
|
|||||||
box-shadow: 0 4px 14px rgb(229 72 77 / 0.25);
|
box-shadow: 0 4px 14px rgb(229 72 77 / 0.25);
|
||||||
}
|
}
|
||||||
.cv-btn--accent {
|
.cv-btn--accent {
|
||||||
background: linear-gradient(120deg, rgb(124 92 252 / 0.16), rgb(168 85 247 / 0.14));
|
background: linear-gradient(120deg, rgb(24 24 27 / 0.16), rgb(168 85 247 / 0.14));
|
||||||
border-color: rgb(124 92 252 / 0.42);
|
border-color: rgb(24 24 27 / 0.42);
|
||||||
color: var(--m-orange);
|
color: var(--m-orange);
|
||||||
}
|
}
|
||||||
.cv-btn--accent:hover:not(:disabled) {
|
.cv-btn--accent:hover:not(:disabled) {
|
||||||
background: linear-gradient(120deg, rgb(124 92 252 / 0.26), rgb(168 85 247 / 0.22));
|
background: linear-gradient(120deg, rgb(24 24 27 / 0.26), rgb(168 85 247 / 0.22));
|
||||||
border-color: rgb(124 92 252 / 0.62);
|
border-color: rgb(24 24 27 / 0.62);
|
||||||
box-shadow: 0 4px 16px var(--accent-glow);
|
box-shadow: 0 4px 16px var(--accent-glow);
|
||||||
}
|
}
|
||||||
.cv-select,
|
.cv-select,
|
||||||
@@ -1157,8 +1157,8 @@ const saveLabel = computed(() => ({
|
|||||||
}
|
}
|
||||||
.cv-select:focus,
|
.cv-select:focus,
|
||||||
.cv-input:focus {
|
.cv-input:focus {
|
||||||
border-color: rgb(124 92 252 / 0.6);
|
border-color: rgb(24 24 27 / 0.6);
|
||||||
box-shadow: 0 0 0 3px rgb(124 92 252 / 0.18);
|
box-shadow: 0 0 0 3px rgb(24 24 27 / 0.18);
|
||||||
}
|
}
|
||||||
|
|
||||||
.cv-page {
|
.cv-page {
|
||||||
@@ -1225,7 +1225,7 @@ const saveLabel = computed(() => ({
|
|||||||
min-width: 46px;
|
min-width: 46px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background: var(--hover);
|
background: var(--hover);
|
||||||
border: 1px solid rgb(124 92 252 / 0.35);
|
border: 1px solid rgb(24 24 27 / 0.35);
|
||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
padding: 1px 8px;
|
padding: 1px 8px;
|
||||||
}
|
}
|
||||||
@@ -1266,9 +1266,9 @@ const saveLabel = computed(() => ({
|
|||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
color: var(--fg);
|
color: var(--fg);
|
||||||
border: 2px dashed rgb(34 211 238 / 0.6);
|
border: 2px dashed rgb(24 24 27 / 0.6);
|
||||||
border-radius: 18px;
|
border-radius: 18px;
|
||||||
background: rgb(34 211 238 / 0.1);
|
background: rgb(24 24 27 / 0.1);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
.cv-loading,
|
.cv-loading,
|
||||||
@@ -1318,11 +1318,11 @@ const saveLabel = computed(() => ({
|
|||||||
}
|
}
|
||||||
.cv-chip:hover {
|
.cv-chip:hover {
|
||||||
background: var(--hover);
|
background: var(--hover);
|
||||||
border-color: rgb(124 92 252 / 0.4);
|
border-color: rgb(24 24 27 / 0.4);
|
||||||
}
|
}
|
||||||
.cv-chip.is-on {
|
.cv-chip.is-on {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background: linear-gradient(120deg, #7c5cfc, #5f6cf8);
|
background: linear-gradient(120deg, #18181b, #27272a);
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
box-shadow: 0 4px 14px var(--accent-glow);
|
box-shadow: 0 4px 14px var(--accent-glow);
|
||||||
}
|
}
|
||||||
@@ -1332,7 +1332,7 @@ const saveLabel = computed(() => ({
|
|||||||
border: 1px solid var(--glass-border);
|
border: 1px solid var(--glass-border);
|
||||||
border-radius: 22px;
|
border-radius: 22px;
|
||||||
background:
|
background:
|
||||||
linear-gradient(160deg, rgb(124 92 252 / 0.06), transparent 40%),
|
linear-gradient(160deg, rgb(24 24 27 / 0.06), transparent 40%),
|
||||||
var(--surface);
|
var(--surface);
|
||||||
-webkit-backdrop-filter: blur(22px) saturate(1.15);
|
-webkit-backdrop-filter: blur(22px) saturate(1.15);
|
||||||
backdrop-filter: blur(22px) saturate(1.15);
|
backdrop-filter: blur(22px) saturate(1.15);
|
||||||
@@ -1341,8 +1341,8 @@ const saveLabel = computed(() => ({
|
|||||||
overflow: visible; /* 下拉面板要从输入框上方弹出,不能被裁切 */
|
overflow: visible; /* 下拉面板要从输入框上方弹出,不能被裁切 */
|
||||||
}
|
}
|
||||||
.cv-composer:focus-within {
|
.cv-composer:focus-within {
|
||||||
border-color: rgb(124 92 252 / 0.55);
|
border-color: rgb(24 24 27 / 0.55);
|
||||||
box-shadow: var(--glass-shadow-lg), 0 0 0 3px rgb(124 92 252 / 0.16), 0 0 42px var(--accent-glow);
|
box-shadow: var(--glass-shadow-lg), 0 0 0 3px rgb(24 24 27 / 0.16), 0 0 42px var(--accent-glow);
|
||||||
}
|
}
|
||||||
.cv-composer__refs {
|
.cv-composer__refs {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -1399,8 +1399,8 @@ const saveLabel = computed(() => ({
|
|||||||
width: 56px;
|
width: 56px;
|
||||||
height: 56px;
|
height: 56px;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
border: 1.5px dashed rgb(124 92 252 / 0.5);
|
border: 1.5px dashed rgb(24 24 27 / 0.5);
|
||||||
background: rgb(124 92 252 / 0.04);
|
background: rgb(24 24 27 / 0.04);
|
||||||
color: var(--m-orange);
|
color: var(--m-orange);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -1414,7 +1414,7 @@ const saveLabel = computed(() => ({
|
|||||||
}
|
}
|
||||||
.cv-refadd:hover {
|
.cv-refadd:hover {
|
||||||
border-color: var(--m-orange);
|
border-color: var(--m-orange);
|
||||||
background: rgb(124 92 252 / 0.1);
|
background: rgb(24 24 27 / 0.1);
|
||||||
transform: translateY(-1px);
|
transform: translateY(-1px);
|
||||||
box-shadow: 0 6px 16px var(--accent-glow);
|
box-shadow: 0 6px 16px var(--accent-glow);
|
||||||
}
|
}
|
||||||
@@ -1468,7 +1468,7 @@ const saveLabel = computed(() => ({
|
|||||||
padding: 10px;
|
padding: 10px;
|
||||||
border-radius: 11px;
|
border-radius: 11px;
|
||||||
border: 1px solid rgb(255 255 255 / 0.18);
|
border: 1px solid rgb(255 255 255 / 0.18);
|
||||||
background: linear-gradient(120deg, #7c5cfc, #5f6cf8 55%, #22d3ee 140%);
|
background: linear-gradient(120deg, #18181b, #27272a 55%, #52525b 140%);
|
||||||
color: #fff;
|
color: #fff;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
@@ -1593,14 +1593,14 @@ const saveLabel = computed(() => ({
|
|||||||
}
|
}
|
||||||
.cv-picker__grid img:hover {
|
.cv-picker__grid img:hover {
|
||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
border-color: rgb(124 92 252 / 0.55);
|
border-color: rgb(24 24 27 / 0.55);
|
||||||
box-shadow: 0 8px 20px var(--accent-glow);
|
box-shadow: 0 8px 20px var(--accent-glow);
|
||||||
}
|
}
|
||||||
.cv-picker__up {
|
.cv-picker__up {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
aspect-ratio: 1;
|
aspect-ratio: 1;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
border: 2px dashed rgb(124 92 252 / 0.45);
|
border: 2px dashed rgb(24 24 27 / 0.45);
|
||||||
background: transparent;
|
background: transparent;
|
||||||
color: var(--m-orange);
|
color: var(--m-orange);
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -1616,7 +1616,7 @@ const saveLabel = computed(() => ({
|
|||||||
.cv-picker__up:hover {
|
.cv-picker__up:hover {
|
||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
border-color: var(--m-orange);
|
border-color: var(--m-orange);
|
||||||
background: rgb(124 92 252 / 0.08);
|
background: rgb(24 24 27 / 0.08);
|
||||||
box-shadow: 0 8px 20px var(--accent-glow);
|
box-shadow: 0 8px 20px var(--accent-glow);
|
||||||
}
|
}
|
||||||
.cv-picker__up:disabled {
|
.cv-picker__up:disabled {
|
||||||
|
|||||||
@@ -279,7 +279,7 @@ onMounted(load)
|
|||||||
:class="!picked.has(s.id) && 'opacity-45'">
|
:class="!picked.has(s.id) && 'opacity-45'">
|
||||||
<div class="flex items-center gap-2.5 min-w-0">
|
<div class="flex items-center gap-2.5 min-w-0">
|
||||||
<span class="w-2 h-2 rounded-full shrink-0"
|
<span class="w-2 h-2 rounded-full shrink-0"
|
||||||
:class="s.kind === 'video' ? 'bg-sky-400' : s.kind === 'text' ? 'bg-amber-400' : 'bg-indigo-400'"></span>
|
:class="s.kind === 'video' ? 'bg-sky-400' : s.kind === 'text' ? 'bg-amber-400' : 'bg-zinc-500'"></span>
|
||||||
<code class="font-mono text-[13px] font-semibold text-white/90 truncate">{{ s.id }}</code>
|
<code class="font-mono text-[13px] font-semibold text-white/90 truncate">{{ s.id }}</code>
|
||||||
<span class="text-[11px] font-semibold text-white/40 shrink-0">{{ KIND_LABEL[s.kind] || s.kind }}</span>
|
<span class="text-[11px] font-semibold text-white/40 shrink-0">{{ KIND_LABEL[s.kind] || s.kind }}</span>
|
||||||
<button type="button" class="ml-auto sw" :class="picked.has(s.id) && 'sw-on'"
|
<button type="button" class="ml-auto sw" :class="picked.has(s.id) && 'sw-on'"
|
||||||
|
|||||||
@@ -656,7 +656,7 @@ html.dark .hint b { color: rgb(253 164 175); } /* rose — visible warning, no
|
|||||||
box-shadow: 0 1px 2px rgb(15 23 42 / 0.2);
|
box-shadow: 0 1px 2px rgb(15 23 42 / 0.2);
|
||||||
transition: transform 0.18s ease;
|
transition: transform 0.18s ease;
|
||||||
}
|
}
|
||||||
.sw:checked { background: #4f46e5; } /* sky-600 — matches btn-primary */
|
.sw:checked { background: #27272a; } /* sky-600 — matches btn-primary */
|
||||||
.sw:checked::after { transform: translateX(calc(2.25rem - 1.3rem)); }
|
.sw:checked::after { transform: translateX(calc(2.25rem - 1.3rem)); }
|
||||||
.sw:focus-visible { box-shadow: 0 0 0 3px rgb(236 91 19 / 0.3); }
|
.sw:focus-visible { box-shadow: 0 0 0 3px rgb(236 91 19 / 0.3); }
|
||||||
.sw:disabled { cursor: not-allowed; opacity: 0.55; }
|
.sw:disabled { cursor: not-allowed; opacity: 0.55; }
|
||||||
@@ -677,8 +677,8 @@ html.dark .num, html.dark .txt, html.dark .field {
|
|||||||
}
|
}
|
||||||
.num::placeholder, .txt::placeholder, .field::placeholder { color: var(--fg-faint); }
|
.num::placeholder, .txt::placeholder, .field::placeholder { color: var(--fg-faint); }
|
||||||
.num:focus, .txt:focus, .field:focus {
|
.num:focus, .txt:focus, .field:focus {
|
||||||
border-color: rgb(124 92 252 / 0.65);
|
border-color: rgb(24 24 27 / 0.65);
|
||||||
box-shadow: 0 0 0 3px rgb(124 92 252 / 0.18);
|
box-shadow: 0 0 0 3px rgb(24 24 27 / 0.18);
|
||||||
}
|
}
|
||||||
.num:disabled, .txt:disabled, .field:disabled { opacity: 0.45; cursor: not-allowed; }
|
.num:disabled, .txt:disabled, .field:disabled { opacity: 0.45; cursor: not-allowed; }
|
||||||
.num { width: 6rem; padding: 0.4rem 0.55rem; font-size: 0.8rem; text-align: right; -moz-appearance: textfield; appearance: textfield; }
|
.num { width: 6rem; padding: 0.4rem 0.55rem; font-size: 0.8rem; text-align: right; -moz-appearance: textfield; appearance: textfield; }
|
||||||
@@ -692,7 +692,7 @@ html.dark .num, html.dark .txt, html.dark .field {
|
|||||||
.btn-primary {
|
.btn-primary {
|
||||||
padding: 0.55rem 1.15rem; border-radius: 0.6rem;
|
padding: 0.55rem 1.15rem; border-radius: 0.6rem;
|
||||||
font-size: 0.8rem; font-weight: 800; color: white;
|
font-size: 0.8rem; font-weight: 800; color: white;
|
||||||
background: linear-gradient(120deg, #7c5cfc, #5f6cf8);
|
background: linear-gradient(120deg, #18181b, #27272a);
|
||||||
border: 1px solid rgb(255 255 255 / 0.16);
|
border: 1px solid rgb(255 255 255 / 0.16);
|
||||||
box-shadow: 0 6px 18px var(--accent-glow);
|
box-shadow: 0 6px 18px var(--accent-glow);
|
||||||
transition: filter 0.15s, transform 0.12s, box-shadow 0.15s, opacity 0.15s;
|
transition: filter 0.15s, transform 0.12s, box-shadow 0.15s, opacity 0.15s;
|
||||||
|
|||||||
@@ -739,7 +739,7 @@ html.dark .art { border-color: var(--ink-soft); }
|
|||||||
height: 40px;
|
height: 40px;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
background: rgba(24, 24, 27, 0.12);
|
background: rgba(24, 24, 27, 0.12);
|
||||||
color: #7c3aed;
|
color: #18181b;
|
||||||
}
|
}
|
||||||
.feature h3 {
|
.feature h3 {
|
||||||
margin-top: 16px;
|
margin-top: 16px;
|
||||||
|
|||||||
@@ -328,7 +328,7 @@ onUnmounted(() => window.removeEventListener('keydown', onKey))
|
|||||||
<span v-if="f.resolution" class="text-emerald-300/90">{{ f.resolution }}</span>
|
<span v-if="f.resolution" class="text-emerald-300/90">{{ f.resolution }}</span>
|
||||||
<span v-if="f.ratio" class="text-white/40">{{ f.ratio }}</span>
|
<span v-if="f.ratio" class="text-white/40">{{ f.ratio }}</span>
|
||||||
<span v-if="f.kind === 'video' && f.duration" class="text-rose-300/80">{{ f.duration }}</span>
|
<span v-if="f.kind === 'video' && f.duration" class="text-rose-300/80">{{ f.duration }}</span>
|
||||||
<span v-if="f.deai" class="text-[#a78bfa]">去AI</span>
|
<span v-if="f.deai" class="text-[#71717a]">去AI</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-[10px] text-white/35 mt-0.5 tabular-nums">{{ fmtSize(f.size) }} · {{ fmtTs(f.mtime) }}</div>
|
<div class="text-[10px] text-white/35 mt-0.5 tabular-nums">{{ fmtSize(f.size) }} · {{ fmtTs(f.mtime) }}</div>
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ function toast(m) {
|
|||||||
<section class="relative rounded-2xl p-7 md:p-8 overflow-hidden ink-card">
|
<section class="relative rounded-2xl p-7 md:p-8 overflow-hidden ink-card">
|
||||||
<div class="memphis-dots absolute inset-0 opacity-30 pointer-events-none"></div>
|
<div class="memphis-dots absolute inset-0 opacity-30 pointer-events-none"></div>
|
||||||
<div class="relative inline-grid w-11 h-11 rounded-xl text-white place-items-center"
|
<div class="relative inline-grid w-11 h-11 rounded-xl text-white place-items-center"
|
||||||
style="background: linear-gradient(135deg, #7c5cfc, #22d3ee); box-shadow: 0 8px 20px var(--accent-glow)">
|
style="background: linear-gradient(135deg, #18181b, #52525b); box-shadow: 0 8px 20px var(--accent-glow)">
|
||||||
<Icon name="accounts" class="w-5 h-5" />
|
<Icon name="accounts" class="w-5 h-5" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -114,7 +114,7 @@ function toast(m) {
|
|||||||
</button>
|
</button>
|
||||||
<button @click="copyInvite"
|
<button @click="copyInvite"
|
||||||
class="rounded-xl border border-white/20 text-white px-5 py-3 text-sm font-extrabold hover:-translate-y-0.5 active:translate-y-0.5 transition-all"
|
class="rounded-xl border border-white/20 text-white px-5 py-3 text-sm font-extrabold hover:-translate-y-0.5 active:translate-y-0.5 transition-all"
|
||||||
style="background: linear-gradient(120deg, #7c5cfc, #22d3ee); box-shadow: 0 8px 20px var(--accent-glow)">
|
style="background: linear-gradient(120deg, #18181b, #52525b); box-shadow: 0 8px 20px var(--accent-glow)">
|
||||||
复制链接
|
复制链接
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -327,7 +327,7 @@ const sourcePill = (s) => ({
|
|||||||
</template>
|
</template>
|
||||||
<template v-if="e.deai">
|
<template v-if="e.deai">
|
||||||
<span class="text-white/25 mx-1.5">·</span>
|
<span class="text-white/25 mx-1.5">·</span>
|
||||||
<span class="text-[#a78bfa]">去AI特征</span>
|
<span class="text-[#71717a]">去AI特征</span>
|
||||||
</template>
|
</template>
|
||||||
</td>
|
</td>
|
||||||
<td class="px-3 py-3.5 text-right text-xs tabular-nums align-middle whitespace-nowrap">
|
<td class="px-3 py-3.5 text-right text-xs tabular-nums align-middle whitespace-nowrap">
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ onMounted(loadModels)
|
|||||||
<div v-else-if="!filtered.length" class="flex flex-col items-center gap-3 text-white/40 py-20">
|
<div v-else-if="!filtered.length" class="flex flex-col items-center gap-3 text-white/40 py-20">
|
||||||
<span class="w-14 h-14 rounded-2xl bg-white/[0.04] grid place-items-center"><Icon name="models" class="w-6 h-6" /></span>
|
<span class="w-14 h-14 rounded-2xl bg-white/[0.04] grid place-items-center"><Icon name="models" class="w-6 h-6" /></span>
|
||||||
<span v-if="models.length" class="text-sm">没有匹配的模型</span>
|
<span v-if="models.length" class="text-sm">没有匹配的模型</span>
|
||||||
<router-link v-else to="/admin/channels" class="text-sm text-sky-300 underline underline-offset-2">还没有模型,先到「渠道管理」勾选上游模型自动导入</router-link>
|
<router-link v-else to="/admin/channels" class="text-sm text-sky-300 underline underline-offset-2">还没有模型,先到「渠道管理」添加渠道,保存后会自动同步上游模型</router-link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<table v-else class="w-full text-sm table-fixed">
|
<table v-else class="w-full text-sm table-fixed">
|
||||||
|
|||||||
@@ -1076,7 +1076,7 @@ onUnmounted(() => {
|
|||||||
<div class="pg-cap text-[11px] leading-tight font-medium line-clamp-2 transition-colors"
|
<div class="pg-cap text-[11px] leading-tight font-medium line-clamp-2 transition-colors"
|
||||||
:class="item.prompt ? 'pointer-events-auto cursor-pointer' : ''"
|
:class="item.prompt ? 'pointer-events-auto cursor-pointer' : ''"
|
||||||
:title="item.prompt ? '点击复制提示词' : ''" @click.stop="copyPrompt(item)">{{ item.prompt }}</div>
|
:title="item.prompt ? '点击复制提示词' : ''" @click.stop="copyPrompt(item)">{{ item.prompt }}</div>
|
||||||
<div class="pg-cap-sub text-[9px] mt-0.5 font-mono truncate">{{ item.model }}<span v-if="item.deai"> · <span class="text-[#a78bfa]">去AI</span></span><span v-if="item.elapsed_ms"> · {{ (item.elapsed_ms / 1000).toFixed(1) }}s</span></div>
|
<div class="pg-cap-sub text-[9px] mt-0.5 font-mono truncate">{{ item.model }}<span v-if="item.deai"> · <span class="text-[#71717a]">去AI</span></span><span v-if="item.elapsed_ms"> · {{ (item.elapsed_ms / 1000).toFixed(1) }}s</span></div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<!-- pending / running -->
|
<!-- pending / running -->
|
||||||
|
|||||||
@@ -273,7 +273,7 @@ async function recharge() {
|
|||||||
<section class="lg:col-span-2 card overflow-hidden">
|
<section class="lg:col-span-2 card overflow-hidden">
|
||||||
<div class="p-7 md:p-8 relative">
|
<div class="p-7 md:p-8 relative">
|
||||||
<div class="absolute -top-16 -right-16 w-48 h-48 rounded-full opacity-30 blur-3xl"
|
<div class="absolute -top-16 -right-16 w-48 h-48 rounded-full opacity-30 blur-3xl"
|
||||||
style="background: radial-gradient(circle,#8b5cf6,transparent 60%)"></div>
|
style="background: radial-gradient(circle,#27272a,transparent 60%)"></div>
|
||||||
<div class="relative grid md:grid-cols-[260px_1fr] gap-8 items-start">
|
<div class="relative grid md:grid-cols-[260px_1fr] gap-8 items-start">
|
||||||
<div>
|
<div>
|
||||||
<div class="inline-grid w-10 h-10 rounded-xl bg-orange-500/15 ring-1 ring-orange-400/30 grid place-items-center text-orange-300">
|
<div class="inline-grid w-10 h-10 rounded-xl bg-orange-500/15 ring-1 ring-orange-400/30 grid place-items-center text-orange-300">
|
||||||
|
|||||||
@@ -257,7 +257,7 @@ const params = (e) => {
|
|||||||
:title="e.error + ' — 点击复制'"
|
:title="e.error + ' — 点击复制'"
|
||||||
@click.stop="copyError(e)">⚠ {{ e.error }}</div>
|
@click.stop="copyError(e)">⚠ {{ e.error }}</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="px-3 py-3 align-middle text-xs text-slate-500 tabular-nums">{{ params(e) || '—' }}<span v-if="e.deai"> · <span class="text-[#a78bfa]">去AI特征</span></span></td>
|
<td class="px-3 py-3 align-middle text-xs text-slate-500 tabular-nums">{{ params(e) || '—' }}<span v-if="e.deai"> · <span class="text-[#71717a]">去AI特征</span></span></td>
|
||||||
<td class="px-3 py-3 align-middle text-right text-xs text-slate-700 tabular-nums">{{ e.cost ? points(e.cost) : '—' }}</td>
|
<td class="px-3 py-3 align-middle text-right text-xs text-slate-700 tabular-nums">{{ e.cost ? points(e.cost) : '—' }}</td>
|
||||||
<td class="px-3 py-3 align-middle text-right text-xs text-slate-500 tabular-nums">{{ e.elapsed_ms ? (e.elapsed_ms / 1000).toFixed(1) + 's' : '—' }}</td>
|
<td class="px-3 py-3 align-middle text-right text-xs text-slate-500 tabular-nums">{{ e.elapsed_ms ? (e.elapsed_ms / 1000).toFixed(1) + 's' : '—' }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@@ -361,7 +361,7 @@ onUnmounted(() => {
|
|||||||
<span v-if="e.resolution" class="text-emerald-300/90">{{ e.resolution }}</span>
|
<span v-if="e.resolution" class="text-emerald-300/90">{{ e.resolution }}</span>
|
||||||
<span v-if="e.ratio" class="text-white/40">{{ e.ratio }}</span>
|
<span v-if="e.ratio" class="text-white/40">{{ e.ratio }}</span>
|
||||||
<span v-if="e.kind === 'video' && e.duration" class="text-rose-300/80">{{ e.duration }}</span>
|
<span v-if="e.kind === 'video' && e.duration" class="text-rose-300/80">{{ e.duration }}</span>
|
||||||
<span v-if="e.deai" class="text-[#a78bfa]">去AI</span>
|
<span v-if="e.deai" class="text-[#71717a]">去AI</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-[10px] text-white/35 mt-0.5 tabular-nums">{{ fmtTs(e.ts) }}<span v-if="e.elapsed_ms"> · {{ fmtMs(e.elapsed_ms) }}</span></div>
|
<div class="text-[10px] text-white/35 mt-0.5 tabular-nums">{{ fmtTs(e.ts) }}<span v-if="e.elapsed_ms"> · {{ fmtMs(e.elapsed_ms) }}</span></div>
|
||||||
|
|||||||
Reference in New Issue
Block a user