style(ui): 全站 Memphis 换肤为玻璃拟态+极光渐变
设计 token 与中央类名保持不变,重写视觉:磨砂玻璃卡片、 紫→青渐变按钮、柔光阴影、发丝边框;emoji 图标换 SVG; 登录/支付/公告弹窗改为随主题的玻璃卡片。 Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
@@ -13,22 +13,24 @@ const html = computed(() => marked.parse(announcement.content.trim() || '暂无
|
||||
<div v-if="announcement.show"
|
||||
class="fixed inset-0 z-[80] bg-slate-950/70 backdrop-blur-sm flex items-center justify-center p-4"
|
||||
@click.self="dismissAnnouncement">
|
||||
<div class="w-full max-w-lg rounded-xl bg-white text-slate-800 border-[3px] border-[#111] shadow-[8px_8px_0_#111] overflow-hidden flex flex-col max-h-[80vh]">
|
||||
<div class="px-6 py-4 border-b-[2.5px] border-b-[#111] flex items-center justify-between gap-3 shrink-0">
|
||||
<div class="w-full max-w-lg rounded-2xl bg-[var(--menu-bg)] backdrop-blur-xl text-[color:var(--fg)] border border-[color:var(--glass-border)] shadow-[var(--glass-shadow-lg)] overflow-hidden flex flex-col max-h-[80vh]">
|
||||
<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">
|
||||
<span class="w-7 h-7 rounded-lg bg-[#fef08a] text-[#111] border-2 border-[#111] 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)">
|
||||
<Icon name="spark" class="w-4 h-4" />
|
||||
</span>
|
||||
<h2 class="text-base font-extrabold">公告</h2>
|
||||
</div>
|
||||
<button @click="dismissAnnouncement" class="text-slate-400 hover:text-slate-700 transition-colors">
|
||||
<button @click="dismissAnnouncement" class="text-[color:var(--fg-3)] hover:text-[color:var(--fg)] transition-colors">
|
||||
<Icon name="close" class="w-5 h-5" />
|
||||
</button>
|
||||
</div>
|
||||
<div class="ann-body px-6 py-5 overflow-y-auto" v-html="html"></div>
|
||||
<div class="px-6 py-4 border-t-[2.5px] border-t-[#111] 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"
|
||||
class="rounded-lg bg-[#ec5b13] text-white border-[2.5px] border-[#111] shadow-[3px_3px_0_#111] hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-[4px_4px_0_#111] active:translate-y-0.5 active:shadow-none px-5 py-2 text-sm font-extrabold 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)">
|
||||
我知道了
|
||||
</button>
|
||||
</div>
|
||||
@@ -42,21 +44,21 @@ const html = computed(() => marked.parse(announcement.content.trim() || '暂无
|
||||
.ann-fade-enter-from, .ann-fade-leave-to { opacity: 0; }
|
||||
|
||||
/* Minimal markdown typography for the announcement body. */
|
||||
.ann-body { font-size: 0.9rem; line-height: 1.65; color: rgb(51 65 85); }
|
||||
.ann-body :deep(h1) { font-size: 1.25rem; font-weight: 700; margin: 0.6em 0 0.4em; color: rgb(15 23 42); }
|
||||
.ann-body :deep(h2) { font-size: 1.1rem; font-weight: 700; margin: 0.6em 0 0.4em; color: rgb(15 23 42); }
|
||||
.ann-body :deep(h3) { font-size: 1rem; font-weight: 600; margin: 0.6em 0 0.3em; color: rgb(15 23 42); }
|
||||
.ann-body { font-size: 0.9rem; line-height: 1.65; color: var(--fg-2); }
|
||||
.ann-body :deep(h1) { font-size: 1.25rem; font-weight: 700; margin: 0.6em 0 0.4em; color: var(--fg); }
|
||||
.ann-body :deep(h2) { font-size: 1.1rem; font-weight: 700; margin: 0.6em 0 0.4em; color: var(--fg); }
|
||||
.ann-body :deep(h3) { font-size: 1rem; font-weight: 600; margin: 0.6em 0 0.3em; color: var(--fg); }
|
||||
.ann-body :deep(p) { margin: 0.5em 0; }
|
||||
.ann-body :deep(ul), .ann-body :deep(ol) { margin: 0.5em 0; padding-left: 1.4em; }
|
||||
.ann-body :deep(ul) { list-style: disc; }
|
||||
.ann-body :deep(ol) { list-style: decimal; }
|
||||
.ann-body :deep(li) { margin: 0.2em 0; }
|
||||
.ann-body :deep(a) { color: var(--m-orange); text-decoration: underline; }
|
||||
.ann-body :deep(strong) { font-weight: 700; color: rgb(15 23 42); }
|
||||
.ann-body :deep(code) { background: rgb(254 240 138 / 0.5); padding: 0.1em 0.35em; border-radius: 0.3rem; font-size: 0.85em; }
|
||||
.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(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(blockquote) { border-left: 3px solid var(--m-orange); padding-left: 0.9em; color: rgb(100 116 139); margin: 0.6em 0; }
|
||||
.ann-body :deep(hr) { border: none; border-top: 1px solid rgb(226 232 240); margin: 1em 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(hr) { border: none; border-top: 1px solid var(--hairline); margin: 1em 0; }
|
||||
.ann-body :deep(img) { max-width: 100%; border-radius: 0.5rem; margin: 0.5em 0; }
|
||||
</style>
|
||||
|
||||
@@ -164,9 +164,9 @@ async function submit() {
|
||||
<div class="absolute inset-0 bg-black/70 backdrop-blur-md" @click="closeLogin"></div>
|
||||
|
||||
<div class="card relative z-10 w-full max-w-[26rem]">
|
||||
<!-- ambient memphis crayon washes -->
|
||||
<div class="pointer-events-none absolute -top-24 -right-16 h-56 w-56 rounded-full bg-[#fef08a]/60 blur-3xl"></div>
|
||||
<div class="pointer-events-none absolute -bottom-24 -left-16 h-56 w-56 rounded-full bg-[#ffc1cc]/50 blur-3xl"></div>
|
||||
<!-- 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">
|
||||
<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"
|
||||
@@ -262,21 +262,22 @@ async function submit() {
|
||||
|
||||
<style scoped>
|
||||
.card {
|
||||
border-radius: 1.1rem;
|
||||
background: var(--surface);
|
||||
border-radius: 1.2rem;
|
||||
background: var(--menu-bg);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
backdrop-filter: blur(20px);
|
||||
color: var(--fg);
|
||||
border: 3px solid var(--ink);
|
||||
box-shadow: 10px 10px 0 var(--shadow-ink);
|
||||
border: 1px solid var(--glass-border);
|
||||
box-shadow: var(--glass-shadow-lg);
|
||||
overflow: hidden;
|
||||
}
|
||||
html.dark .card {
|
||||
background: #1c1d24;
|
||||
color: rgb(255 255 255 / 0.9);
|
||||
}
|
||||
|
||||
.logo-halo {
|
||||
position: relative;
|
||||
filter: drop-shadow(0 6px 0 rgb(236 91 19 / 0.35));
|
||||
filter: drop-shadow(0 6px 14px rgb(124 92 252 / 0.4));
|
||||
}
|
||||
|
||||
/* segmented tab control */
|
||||
@@ -284,22 +285,21 @@ html.dark .card {
|
||||
display: flex; gap: 0.3rem; padding: 0.3rem;
|
||||
border-radius: 0.7rem;
|
||||
background: var(--surface-2);
|
||||
border: 2px solid var(--ink);
|
||||
border: 1px solid var(--ink-soft);
|
||||
}
|
||||
.tab {
|
||||
flex: 1; padding: 0.45rem 0; border-radius: 0.5rem;
|
||||
font-size: 0.8125rem; font-weight: 700; color: var(--fg-3);
|
||||
border: 2px solid transparent;
|
||||
border: 1px solid transparent;
|
||||
transition: background 0.18s, color 0.18s, box-shadow 0.18s, border-color 0.18s;
|
||||
}
|
||||
.tab:hover { color: var(--fg); }
|
||||
.tab-on {
|
||||
color: #111;
|
||||
background: var(--m-yellow);
|
||||
border-color: var(--ink);
|
||||
box-shadow: 2px 2px 0 var(--shadow-ink);
|
||||
color: #fff;
|
||||
background: linear-gradient(120deg, #7c5cfc, #5f6cf8);
|
||||
border-color: transparent;
|
||||
box-shadow: 0 4px 14px var(--accent-glow);
|
||||
}
|
||||
html.dark .tab-on { color: #fff; background: var(--m-orange); }
|
||||
|
||||
/* icon-prefixed input */
|
||||
.lm-field { position: relative; }
|
||||
@@ -311,14 +311,14 @@ html.dark .tab-on { color: #fff; background: var(--m-orange); }
|
||||
.lm-field:focus-within .ic { color: var(--m-orange); }
|
||||
.fld {
|
||||
width: 100%; padding: 0.7rem 0.85rem 0.7rem 2.4rem; border-radius: 0.6rem;
|
||||
background: var(--surface); border: 2px solid var(--ink-soft);
|
||||
background: var(--surface); border: 1px solid var(--ink-soft);
|
||||
color: var(--fg); font-size: 0.875rem; outline: none;
|
||||
transition: border-color 0.15s, box-shadow 0.15s, background 0.15s;
|
||||
}
|
||||
html.dark .fld { background: rgb(255 255 255 / 0.05); }
|
||||
.fld:focus {
|
||||
border-color: var(--ink);
|
||||
box-shadow: 3px 3px 0 var(--m-orange);
|
||||
border-color: rgb(124 92 252 / 0.65);
|
||||
box-shadow: 0 0 0 3px rgb(124 92 252 / 0.18);
|
||||
}
|
||||
.fld::placeholder { color: var(--fg-faint); }
|
||||
/* Keep autofill on-theme in dark (otherwise it paints white/yellow). */
|
||||
@@ -344,13 +344,12 @@ html.dark .fld:-webkit-autofill:focus {
|
||||
min-width: 5.5rem; /* keep width stable between text / spinner */
|
||||
display: inline-flex; align-items: center; justify-content: center;
|
||||
font-size: 0.75rem; font-weight: 800; white-space: nowrap;
|
||||
color: #111;
|
||||
background: var(--m-yellow); border: 2px solid var(--ink);
|
||||
box-shadow: 2px 2px 0 var(--shadow-ink);
|
||||
color: var(--fg);
|
||||
background: var(--hover); border: 1px solid rgb(124 92 252 / 0.4);
|
||||
box-shadow: 0 2px 10px rgb(124 92 252 / 0.14);
|
||||
transition: background 0.15s, box-shadow 0.15s, transform 0.15s, opacity 0.15s;
|
||||
}
|
||||
html.dark .code-btn { color: #111; }
|
||||
.code-btn:hover:not(:disabled) { transform: translate(-1px, -1px); box-shadow: 3px 3px 0 var(--shadow-ink); }
|
||||
.code-btn:hover:not(:disabled) { transform: translateY(-1px); box-shadow: 0 4px 14px rgb(124 92 252 / 0.22); }
|
||||
.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
|
||||
never washes out to invisible white on the light card. */
|
||||
@@ -362,13 +361,13 @@ html.dark .code-btn { color: #111; }
|
||||
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;
|
||||
letter-spacing: 0.02em; color: white; margin-top: 0.35rem;
|
||||
background: var(--m-orange);
|
||||
border: 2.5px solid var(--ink);
|
||||
box-shadow: 4px 4px 0 var(--shadow-ink);
|
||||
background: linear-gradient(120deg, #7c5cfc, #5f6cf8 55%, #22d3ee 140%);
|
||||
border: 1px solid rgb(255 255 255 / 0.16);
|
||||
box-shadow: 0 8px 22px var(--accent-glow);
|
||||
transition: transform 0.13s, box-shadow 0.13s, filter 0.15s;
|
||||
}
|
||||
.btn-primary:hover:not(:disabled) { filter: brightness(1.06); transform: translate(-1px, -1px); box-shadow: 5px 5px 0 var(--shadow-ink); }
|
||||
.btn-primary:active:not(:disabled) { transform: scale(0.98) translateY(2px); box-shadow: 0 0 0 var(--shadow-ink); }
|
||||
.btn-primary:hover:not(:disabled) { filter: brightness(1.07); transform: translateY(-1px); box-shadow: 0 12px 30px var(--accent-glow); }
|
||||
.btn-primary:active:not(:disabled) { transform: scale(0.98) translateY(1px); box-shadow: 0 4px 12px var(--accent-glow); }
|
||||
.btn-primary:disabled { opacity: 0.6; cursor: not-allowed; }
|
||||
|
||||
.spinner {
|
||||
@@ -382,7 +381,7 @@ html.dark .code-btn { color: #111; }
|
||||
display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.85rem;
|
||||
padding: 0.6rem 0.75rem; border-radius: 0.6rem; font-size: 0.75rem; line-height: 1.4;
|
||||
color: #065f46; font-weight: 600;
|
||||
background: var(--m-mint); border: 2px solid var(--ink);
|
||||
background: rgb(52 211 153 / 0.14); border: 1px solid rgb(52 211 153 / 0.4);
|
||||
}
|
||||
html.dark .invite-banner { color: rgb(167 243 208); background: rgb(16 185 129 / 0.15); }
|
||||
.invite-banner svg { color: rgb(5 150 105); }
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// Vivid mark: an open spectrum ring (lens/aperture) around a play triangle,
|
||||
// with a shutter dot closing the gap — image + video in one glyph.
|
||||
// Transparent background so it reads on both the dark and light shells.
|
||||
// Colors follow the memphis crayon palette (orange / pink / blue).
|
||||
// Colors follow the aurora palette (violet / pink / cyan).
|
||||
// Each instance gets unique gradient ids (useId) so multiple logos on one
|
||||
// page don't share/clobber defs.
|
||||
import { useId } from 'vue'
|
||||
@@ -18,9 +18,9 @@ const gRing = `vring-${uid}`
|
||||
xmlns="http://www.w3.org/2000/svg" class="shrink-0">
|
||||
<defs>
|
||||
<linearGradient :id="gRing" x1="6" y1="6" x2="42" y2="42" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#ec5b13" />
|
||||
<stop offset="0.5" stop-color="#f472b6" />
|
||||
<stop offset="1" stop-color="#38bdf8" />
|
||||
<stop stop-color="#7c5cfc" />
|
||||
<stop offset="0.5" stop-color="#e879f9" />
|
||||
<stop offset="1" stop-color="#22d3ee" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
@@ -29,10 +29,10 @@ const gRing = `vring-${uid}`
|
||||
<circle r="17.5" fill="none" :stroke="`url(#${gRing})`" stroke-width="4.4"
|
||||
stroke-linecap="round" stroke-dasharray="84 32" transform="rotate(-58)" />
|
||||
<!-- play triangle = image + video -->
|
||||
<path d="M-3 -6.5 L8.5 0 L-3 6.5 Z" fill="#ec5b13" stroke="#111" stroke-width="1.4"
|
||||
<path d="M-3 -6.5 L8.5 0 L-3 6.5 Z" fill="#7c5cfc" stroke="#111" stroke-width="1.4"
|
||||
stroke-linejoin="round" />
|
||||
<!-- shutter dot -->
|
||||
<circle cx="13" cy="-13" r="4.2" fill="#fef08a" stroke="#111" stroke-width="1.6" />
|
||||
<circle cx="13" cy="-13" r="4.2" fill="#22d3ee" stroke="#111" stroke-width="1.6" />
|
||||
</g>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
@@ -103,31 +103,33 @@ onUnmounted(clearTimers)
|
||||
<transition name="pay-fade">
|
||||
<div v-if="payment.show" class="fixed inset-0 z-[85] bg-slate-950/70 backdrop-blur-sm flex items-center justify-center p-4"
|
||||
@click.self="!paid && finish()">
|
||||
<div class="w-full max-w-sm rounded-xl bg-white text-slate-800 border-[3px] border-[#111] shadow-[8px_8px_0_#111] overflow-hidden">
|
||||
<div class="px-5 py-4 border-b-[2.5px] border-b-[#111] flex items-center justify-between">
|
||||
<div class="w-full max-w-sm rounded-2xl bg-[var(--menu-bg)] backdrop-blur-xl text-[color:var(--fg)] border border-[color:var(--glass-border)] shadow-[var(--glass-shadow-lg)] overflow-hidden">
|
||||
<div class="px-5 py-4 border-b border-b-[color:var(--ink-soft)] flex items-center justify-between">
|
||||
<h2 class="text-base font-semibold">{{ paid ? '支付成功' : dead ? '支付超时' : (isJump ? '支付监控中' : '扫码支付') }}</h2>
|
||||
<button v-if="!paid" @click="finish" class="text-slate-400 hover:text-slate-700"><Icon name="close" class="w-5 h-5" /></button>
|
||||
<button v-if="!paid" @click="finish" class="text-[color:var(--fg-3)] hover:text-[color:var(--fg)] transition-colors"><Icon name="close" class="w-5 h-5" /></button>
|
||||
</div>
|
||||
|
||||
<!-- paid -->
|
||||
<div v-if="paid" class="px-6 py-10 text-center">
|
||||
<div class="w-16 h-16 mx-auto rounded-full bg-[#a7f3d0] text-emerald-700 border-[2.5px] border-[#111] shadow-[4px_4px_0_#111] grid place-items-center mb-4">
|
||||
<div class="w-16 h-16 mx-auto rounded-full text-white grid place-items-center mb-4"
|
||||
style="background: linear-gradient(135deg, #34d399, #2dd4bf); box-shadow: 0 10px 28px rgb(52 211 153 / 0.4)">
|
||||
<Icon name="spark" class="w-8 h-8" />
|
||||
</div>
|
||||
<p class="text-lg font-semibold text-slate-800">充值成功</p>
|
||||
<p class="text-sm text-slate-500 mt-1">已到账 <strong class="text-emerald-600">{{ order.points }}</strong> 积分</p>
|
||||
<p class="text-xs text-slate-400 mt-4">{{ closeIn }} 秒后自动关闭</p>
|
||||
<p class="text-lg font-semibold text-[color:var(--fg)]">充值成功</p>
|
||||
<p class="text-sm text-[color:var(--fg-3)] mt-1">已到账 <strong class="text-emerald-500">{{ order.points }}</strong> 积分</p>
|
||||
<p class="text-xs text-[color:var(--fg-faint)] mt-4">{{ closeIn }} 秒后自动关闭</p>
|
||||
</div>
|
||||
|
||||
<!-- expired / cancelled -->
|
||||
<div v-else-if="dead" class="px-6 py-10 text-center">
|
||||
<div class="w-16 h-16 mx-auto rounded-full bg-slate-100 text-slate-400 grid place-items-center mb-4">
|
||||
<div class="w-16 h-16 mx-auto rounded-full bg-[var(--surface-2)] text-[color:var(--fg-3)] grid place-items-center mb-4">
|
||||
<Icon name="close" class="w-8 h-8" />
|
||||
</div>
|
||||
<p class="text-lg font-semibold text-slate-700">支付超时</p>
|
||||
<p class="text-sm text-slate-500 mt-1">二维码已失效,订单已取消</p>
|
||||
<p class="text-xs text-slate-400 mt-1">如需充值请重新下单</p>
|
||||
<button @click="finish" class="mt-5 rounded-lg bg-[#ec5b13] text-white border-[2.5px] border-[#111] shadow-[3px_3px_0_#111] hover:-translate-y-0.5 active:translate-y-0.5 active:shadow-none px-5 py-2 text-sm font-extrabold transition-all">关闭</button>
|
||||
<p class="text-lg font-semibold text-[color:var(--fg)]">支付超时</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>
|
||||
<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>
|
||||
</div>
|
||||
|
||||
<!-- pending -->
|
||||
@@ -135,31 +137,31 @@ onUnmounted(clearTimers)
|
||||
<!-- qrcode: scan to pay -->
|
||||
<template v-if="!isJump">
|
||||
<div class="flex justify-center mb-3">
|
||||
<div class="w-[228px] h-[228px] rounded-xl border-[2.5px] border-[#111] shadow-[4px_4px_0_#111] grid place-items-center overflow-hidden bg-white p-3.5">
|
||||
<div class="w-[228px] h-[228px] rounded-xl border border-[color:var(--glass-border)] shadow-[var(--glass-shadow)] grid place-items-center overflow-hidden bg-white p-3.5">
|
||||
<img v-if="qrUrl" :src="qrUrl" alt="支付二维码" class="w-full h-full rounded-lg" />
|
||||
<span v-else class="text-xs text-slate-400">二维码生成中…</span>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-center text-xs text-slate-500 mb-4">请使用<strong class="text-slate-700">{{ methodLabel }}</strong>扫码支付</p>
|
||||
<p class="text-center text-xs text-[color:var(--fg-3)] mb-4">请使用<strong class="text-[color:var(--fg)]">{{ methodLabel }}</strong>扫码支付</p>
|
||||
</template>
|
||||
<!-- jump (no qrcode): the cashier opened in a new tab — just monitor -->
|
||||
<template v-else>
|
||||
<div class="flex flex-col items-center justify-center py-7 mb-2">
|
||||
<div class="w-12 h-12 rounded-full border-[3px] border-[#fecaca] border-t-[#ec5b13] animate-spin mb-3"></div>
|
||||
<p class="text-sm font-medium text-slate-700">支付监控中…</p>
|
||||
<p class="text-xs text-slate-400 mt-1">已打开支付页面,完成后自动到账</p>
|
||||
<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>
|
||||
<p class="text-sm font-medium text-[color:var(--fg)]">支付监控中…</p>
|
||||
<p class="text-xs text-[color:var(--fg-faint)] mt-1">已打开支付页面,完成后自动到账</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<dl class="text-sm space-y-2">
|
||||
<div class="flex justify-between"><dt class="text-slate-400">订单号</dt><dd class="font-mono text-xs text-slate-700">{{ order.id }}</dd></div>
|
||||
<div class="flex justify-between"><dt class="text-slate-400">状态</dt><dd class="text-amber-600 font-medium">{{ statusLabel }}</dd></div>
|
||||
<div class="flex justify-between"><dt class="text-slate-400">金额</dt><dd class="font-semibold text-slate-800">¥{{ order.amount }}</dd></div>
|
||||
<div class="flex justify-between"><dt class="text-slate-400">充值积分</dt><dd class="text-[#ec5b13] font-semibold">{{ order.points }}</dd></div>
|
||||
<div class="flex justify-between"><dt class="text-slate-400">下单时间</dt><dd class="text-xs text-slate-600">{{ fmtTime(order.created_at) }}</dd></div>
|
||||
<div class="flex justify-between"><dt class="text-slate-400">支付倒计时</dt><dd class="tabular-nums font-medium" :class="remaining > 0 ? 'text-slate-700' : 'text-rose-500'">{{ remaining > 0 ? mmss : '已超时' }}</dd></div>
|
||||
<div class="flex justify-between"><dt class="text-[color:var(--fg-faint)]">订单号</dt><dd class="font-mono text-xs text-[color:var(--fg)]">{{ order.id }}</dd></div>
|
||||
<div class="flex justify-between"><dt class="text-[color:var(--fg-faint)]">状态</dt><dd class="text-amber-500 font-medium">{{ statusLabel }}</dd></div>
|
||||
<div class="flex justify-between"><dt class="text-[color:var(--fg-faint)]">金额</dt><dd class="font-semibold text-[color:var(--fg)]">¥{{ order.amount }}</dd></div>
|
||||
<div class="flex justify-between"><dt class="text-[color:var(--fg-faint)]">充值积分</dt><dd class="text-[color:var(--m-orange)] font-semibold">{{ order.points }}</dd></div>
|
||||
<div class="flex justify-between"><dt class="text-[color:var(--fg-faint)]">下单时间</dt><dd class="text-xs text-[color:var(--fg-2)]">{{ fmtTime(order.created_at) }}</dd></div>
|
||||
<div class="flex justify-between"><dt class="text-[color:var(--fg-faint)]">支付倒计时</dt><dd class="tabular-nums font-medium" :class="remaining > 0 ? 'text-[color:var(--fg)]' : 'text-rose-500'">{{ remaining > 0 ? mmss : '已超时' }}</dd></div>
|
||||
</dl>
|
||||
<p class="text-[11px] text-slate-400 mt-4 text-center">支付完成后将自动到账,请勿关闭本窗口</p>
|
||||
<p class="text-[11px] text-[color:var(--fg-faint)] mt-4 text-center">支付完成后将自动到账,请勿关闭本窗口</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -90,8 +90,8 @@ onUnmounted(() => document.removeEventListener('mousedown', onDocClick))
|
||||
leave-from-class="opacity-100 translate-y-0"
|
||||
leave-to-class="opacity-0 -translate-y-1">
|
||||
<div v-if="open" ref="panel"
|
||||
class="absolute z-30 mt-2 w-full max-h-64 overflow-auto rounded-xl border-[2.5px] border-[color:var(--ink)]
|
||||
bg-[var(--menu-bg)] p-1.5 shadow-[5px_5px_0_var(--shadow-ink)]">
|
||||
class="absolute z-30 mt-2 w-full max-h-64 overflow-auto rounded-xl border border-[color:var(--glass-border)]
|
||||
bg-[var(--menu-bg)] backdrop-blur-xl p-1.5 shadow-[var(--glass-shadow-lg)]">
|
||||
<button v-for="(o, i) in options" :key="o.value" type="button"
|
||||
:data-idx="i" @click="pick(o)" @mouseenter="active = i"
|
||||
class="w-full flex items-center justify-between gap-2 rounded-lg px-3 py-2 text-left text-sm font-medium transition-colors"
|
||||
|
||||
@@ -153,18 +153,19 @@ defineExpose({ startEdit, commitNote })
|
||||
.cv-node {
|
||||
position: absolute;
|
||||
border-radius: 14px;
|
||||
border: 2.5px solid var(--ink);
|
||||
border: 1px solid var(--glass-border);
|
||||
overflow: hidden;
|
||||
contain: layout style paint;
|
||||
user-select: none;
|
||||
touch-action: none;
|
||||
cursor: grab;
|
||||
background: var(--surface);
|
||||
box-shadow: 5px 5px 0 var(--shadow-ink);
|
||||
transition: box-shadow 0.15s ease;
|
||||
background: var(--surface-solid);
|
||||
box-shadow: var(--glass-shadow);
|
||||
transition: box-shadow 0.15s ease, border-color 0.15s ease;
|
||||
}
|
||||
.cv-node.is-selected {
|
||||
box-shadow: 7px 7px 0 var(--m-orange);
|
||||
border-color: rgb(124 92 252 / 0.7);
|
||||
box-shadow: var(--glass-shadow-lg), 0 0 0 3px rgb(124 92 252 / 0.25), 0 10px 30px var(--accent-glow);
|
||||
}
|
||||
.cv-node:active {
|
||||
cursor: grabbing;
|
||||
@@ -188,19 +189,24 @@ defineExpose({ startEdit, commitNote })
|
||||
font-weight: 600;
|
||||
line-height: 1.35;
|
||||
color: var(--fg);
|
||||
background: var(--surface);
|
||||
border-top: 2.5px solid var(--ink);
|
||||
background: var(--surface-solid);
|
||||
border-top: 1px solid var(--ink-soft);
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* 笔记 = 孟菲斯黄贴纸 */
|
||||
/* 笔记 = 淡黄色贴纸 */
|
||||
.cv-node--note {
|
||||
background: var(--m-yellow);
|
||||
background: #fdf6c9;
|
||||
border-color: rgb(180 140 20 / 0.35);
|
||||
cursor: text;
|
||||
}
|
||||
html.dark .cv-node--note {
|
||||
background: rgb(250 204 21 / 0.14);
|
||||
border-color: rgb(250 204 21 / 0.35);
|
||||
}
|
||||
.cv-node--note:not(.is-editing) {
|
||||
cursor: grab;
|
||||
}
|
||||
@@ -217,6 +223,7 @@ defineExpose({ startEdit, commitNote })
|
||||
overflow: hidden;
|
||||
user-select: none;
|
||||
}
|
||||
html.dark .cv-node__note { color: rgb(255 255 255 / 0.88); }
|
||||
.is-editing .cv-node__note {
|
||||
user-select: text;
|
||||
cursor: text;
|
||||
@@ -229,6 +236,8 @@ defineExpose({ startEdit, commitNote })
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: var(--surface);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
backdrop-filter: blur(10px);
|
||||
border-style: dashed;
|
||||
color: var(--fg-2);
|
||||
font-size: 13px;
|
||||
@@ -266,8 +275,9 @@ defineExpose({ startEdit, commitNote })
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
border-radius: 50%;
|
||||
background: var(--m-orange);
|
||||
border: 2.5px solid var(--ink);
|
||||
background: linear-gradient(135deg, #7c5cfc, #22d3ee);
|
||||
border: 1.5px solid rgb(255 255 255 / 0.7);
|
||||
box-shadow: 0 2px 10px var(--accent-glow);
|
||||
opacity: 0;
|
||||
transition: opacity 0.12s;
|
||||
cursor: crosshair;
|
||||
@@ -286,8 +296,8 @@ defineExpose({ startEdit, commitNote })
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
border-radius: 4px;
|
||||
background: var(--m-blue);
|
||||
border: 2.5px solid var(--ink);
|
||||
background: var(--surface-solid);
|
||||
border: 1px solid var(--ink);
|
||||
cursor: nwse-resize;
|
||||
z-index: 3;
|
||||
}
|
||||
@@ -305,22 +315,28 @@ defineExpose({ startEdit, commitNote })
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 7px;
|
||||
border: 2.5px solid var(--ink);
|
||||
background: var(--m-yellow);
|
||||
color: #1a1a1a;
|
||||
border: 1px solid var(--glass-border);
|
||||
background: var(--menu-bg);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
backdrop-filter: blur(10px);
|
||||
color: var(--fg);
|
||||
font-size: 12px;
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
box-shadow: 2.5px 2.5px 0 var(--shadow-ink);
|
||||
box-shadow: var(--glass-shadow);
|
||||
display: grid;
|
||||
place-items: center;
|
||||
padding: 0;
|
||||
transition: transform 0.12s ease, background 0.12s ease, color 0.12s ease;
|
||||
}
|
||||
.cv-tools button:hover {
|
||||
transform: translate(1px, 1px);
|
||||
box-shadow: 1.5px 1.5px 0 var(--shadow-ink);
|
||||
transform: translateY(-1px);
|
||||
background: var(--hover);
|
||||
}
|
||||
.cv-tools__del {
|
||||
background: #ffb4ab !important;
|
||||
color: #e5484d;
|
||||
}
|
||||
.cv-tools__del:hover {
|
||||
background: rgb(229 72 77 / 0.14) !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -617,8 +617,8 @@ defineExpose({
|
||||
}
|
||||
.cv-marquee {
|
||||
position: absolute;
|
||||
border: 2px dashed var(--ink);
|
||||
background: color-mix(in srgb, var(--m-yellow) 35%, transparent);
|
||||
border: 2px dashed rgb(124 92 252 / 0.5);
|
||||
background: rgb(124 92 252 / 0.08);
|
||||
pointer-events: none;
|
||||
border-radius: 4px;
|
||||
}
|
||||
@@ -631,10 +631,12 @@ defineExpose({
|
||||
font-weight: 600;
|
||||
color: var(--fg-2);
|
||||
background: var(--surface);
|
||||
border: 2px solid var(--ink);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
backdrop-filter: blur(10px);
|
||||
border: 1px solid var(--glass-border);
|
||||
border-radius: 999px;
|
||||
padding: 3px 14px;
|
||||
box-shadow: 3px 3px 0 var(--shadow-ink);
|
||||
box-shadow: var(--glass-shadow);
|
||||
pointer-events: none;
|
||||
white-space: nowrap;
|
||||
max-width: 92%;
|
||||
|
||||
Reference in New Issue
Block a user