Files
WeFlow/public/splash.html
2026-05-07 19:46:37 +08:00

400 lines
11 KiB
HTML

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WeFlow</title>
<style>
:root {
--primary: #8b7355;
--primary-rgb: 139, 115, 85;
--on-primary: #ffffff;
--window-bg: transparent;
--card-bg: rgba(255, 255, 255, 0.96);
--card-bg-solid: #ffffff;
--card-border: rgba(0, 0, 0, 0.06);
--text-primary: #171717;
--text-secondary: #6f6f6f;
--text-tertiary: #9a9a9a;
--track-bg: rgba(0, 0, 0, 0.06);
--logo-surface: #f4f4f5;
--card-gloss-start: rgba(255, 255, 255, 0.62);
--card-gloss-end: rgba(255, 255, 255, 0);
--shadow: 0 30px 80px rgba(0, 0, 0, 0.18), 0 2px 10px rgba(0, 0, 0, 0.06);
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html,
body {
width: 100%;
height: 100%;
overflow: hidden;
background: var(--window-bg);
color: var(--text-primary);
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Microsoft YaHei", sans-serif;
-webkit-font-smoothing: antialiased;
user-select: none;
}
body {
display: grid;
place-items: center;
-webkit-app-region: drag;
}
.splash-shell {
width: calc(100% - 76px);
height: calc(100% - 72px);
min-width: 640px;
min-height: 360px;
position: relative;
overflow: hidden;
border-radius: 8px;
border: 1px solid var(--card-border);
background:
linear-gradient(180deg, var(--card-gloss-start) 0%, var(--card-gloss-end) 48%),
var(--card-bg);
box-shadow: var(--shadow);
isolation: isolate;
animation: shellIn 420ms cubic-bezier(0.22, 1, 0.36, 1) both;
}
.splash-shell::before {
content: "";
position: absolute;
inset: 0;
pointer-events: none;
background:
linear-gradient(90deg, transparent 0%, rgba(var(--primary-rgb), 0.035) 48%, transparent 100%),
linear-gradient(180deg, rgba(var(--primary-rgb), 0.045) 0%, transparent 32%);
opacity: 0.9;
z-index: -1;
}
.brand-stage {
position: absolute;
inset: 0;
display: grid;
place-items: center;
padding-bottom: 42px;
}
.brand-lockup {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
animation: contentIn 460ms cubic-bezier(0.22, 1, 0.36, 1) 80ms both;
}
.logo-tile {
width: 80px;
height: 80px;
display: grid;
place-items: center;
border-radius: 16px;
background: var(--logo-surface);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.8), 0 10px 24px rgba(0, 0, 0, 0.04);
margin-bottom: 25px;
overflow: hidden;
}
.logo {
width: 58px;
height: 58px;
object-fit: contain;
border-radius: 14px;
display: block;
}
.app-name {
font-size: 25px;
line-height: 1.2;
font-weight: 700;
letter-spacing: 0;
color: var(--text-primary);
margin-bottom: 10px;
}
.app-desc {
font-size: 14px;
line-height: 1.5;
font-weight: 400;
color: var(--text-secondary);
}
.status-row {
position: absolute;
left: 32px;
right: 32px;
bottom: 26px;
display: flex;
align-items: center;
justify-content: space-between;
gap: 20px;
color: var(--text-tertiary);
font-size: 12px;
line-height: 1.4;
font-variant-numeric: tabular-nums;
animation: contentIn 460ms cubic-bezier(0.22, 1, 0.36, 1) 160ms both;
}
.progress-text {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.version {
flex-shrink: 0;
font-family: "SFMono-Regular", Consolas, "Liberation Mono", monospace;
letter-spacing: 0;
opacity: 0.82;
}
.progress-track {
position: absolute;
left: 0;
right: 0;
bottom: 0;
height: 3px;
background: var(--track-bg);
overflow: hidden;
}
.progress-fill {
width: 0%;
min-width: 0;
height: 100%;
background: var(--primary);
border-radius: 0 999px 999px 0;
box-shadow: 0 0 18px rgba(var(--primary-rgb), 0.34);
transition: width 440ms cubic-bezier(0.22, 1, 0.36, 1);
position: relative;
overflow: hidden;
}
.progress-fill::after {
content: "";
position: absolute;
inset: 0;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.42), transparent);
opacity: 0;
transform: translateX(-100%);
animation: sweep 1200ms ease-out;
}
.progress-fill.waiting::before {
content: "";
position: absolute;
top: -4px;
right: -10px;
width: 22px;
height: 11px;
border-radius: 999px;
background: rgba(var(--primary-rgb), 0.7);
filter: blur(5px);
animation: waitingPulse 1300ms ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
.splash-shell,
.brand-lockup,
.status-row,
.progress-fill,
.progress-fill::after,
.progress-fill.waiting::before {
animation: none !important;
transition: none !important;
}
}
@keyframes shellIn {
from {
opacity: 0;
transform: translateY(8px) scale(0.985);
}
to {
opacity: 1;
transform: translateY(0) scale(1);
}
}
@keyframes contentIn {
from {
opacity: 0;
transform: translateY(8px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes sweep {
0% {
opacity: 0;
transform: translateX(-100%);
}
20%,
70% {
opacity: 1;
}
100% {
opacity: 0;
transform: translateX(100%);
}
}
@keyframes waitingPulse {
0%,
100% {
opacity: 0.32;
transform: scaleX(0.8);
}
50% {
opacity: 0.92;
transform: scaleX(1.45);
}
}
</style>
</head>
<body>
<main class="splash-shell" id="splash" role="status" aria-live="polite">
<section class="brand-stage">
<div class="brand-lockup">
<div class="logo-tile" aria-hidden="true">
<img class="logo" src="./logo.png" alt="">
</div>
<h1 class="app-name">WeFlow</h1>
<p class="app-desc">&#24494;&#20449;&#32842;&#22825;&#35760;&#24405;&#31649;&#29702;&#24037;&#20855;</p>
</div>
</section>
<div class="status-row">
<div class="progress-text" id="progressText">&#27491;&#22312;&#21551;&#21160;...</div>
<div class="version" id="versionText"></div>
</div>
<div class="progress-track" aria-hidden="true">
<div class="progress-fill" id="progressFill"></div>
</div>
</main>
<script>
var themePalettes = {
"cloud-dancer": {
light: { primary: "#8B7355", rgb: "139, 115, 85", onPrimary: "#ffffff" },
dark: { primary: "#C9A86C", rgb: "201, 168, 108", onPrimary: "#111111" }
},
"blossom-dream": {
light: { primary: "#D4849A", rgb: "212, 132, 154", onPrimary: "#ffffff" },
dark: { primary: "#D19EBB", rgb: "209, 158, 187", onPrimary: "#111111" }
},
"corundum-blue": {
light: { primary: "#4A6670", rgb: "74, 102, 112", onPrimary: "#ffffff" },
dark: { primary: "#6A9AAA", rgb: "106, 154, 170", onPrimary: "#111111" }
},
"kiwi-green": {
light: { primary: "#7A9A5C", rgb: "122, 154, 92", onPrimary: "#ffffff" },
dark: { primary: "#9ABA7C", rgb: "154, 186, 124", onPrimary: "#111111" }
},
"spicy-red": {
light: { primary: "#8B4049", rgb: "139, 64, 73", onPrimary: "#ffffff" },
dark: { primary: "#C06068", rgb: "192, 96, 104", onPrimary: "#ffffff" }
},
"teal-water": {
light: { primary: "#5A8A8A", rgb: "90, 138, 138", onPrimary: "#ffffff" },
dark: { primary: "#7ABAAA", rgb: "122, 186, 170", onPrimary: "#111111" }
},
"geist": {
light: { primary: "#444444", rgb: "68, 68, 68", onPrimary: "#ffffff" },
dark: { primary: "#ededed", rgb: "237, 237, 237", onPrimary: "#111111" }
}
};
function setVar(name, value) {
document.documentElement.style.setProperty(name, value);
}
function resolveMode(mode) {
if (mode === "dark" || mode === "light") return mode;
return window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
}
function applyTheme(themeId, mode) {
var palette = themePalettes[themeId] || themePalettes["cloud-dancer"];
var resolvedMode = resolveMode(mode);
var accent = palette[resolvedMode] || palette.light;
var isDark = resolvedMode === "dark";
setVar("--primary", accent.primary);
setVar("--primary-rgb", accent.rgb);
setVar("--on-primary", accent.onPrimary);
setVar("--window-bg", "transparent");
if (isDark) {
setVar("--card-bg", "rgba(31, 31, 31, 0.96)");
setVar("--card-bg-solid", "#1f1f1f");
setVar("--card-border", "rgba(255, 255, 255, 0.08)");
setVar("--text-primary", "#f1f1f1");
setVar("--text-secondary", "#b8b8b8");
setVar("--text-tertiary", "#858585");
setVar("--track-bg", "rgba(255, 255, 255, 0.09)");
setVar("--logo-surface", "#2b2b2b");
setVar("--card-gloss-start", "rgba(255, 255, 255, 0.035)");
setVar("--card-gloss-end", "rgba(255, 255, 255, 0)");
setVar("--shadow", "0 30px 80px rgba(0, 0, 0, 0.42), 0 2px 10px rgba(0, 0, 0, 0.24)");
} else {
setVar("--card-bg", "rgba(255, 255, 255, 0.96)");
setVar("--card-bg-solid", "#ffffff");
setVar("--card-border", "rgba(0, 0, 0, 0.06)");
setVar("--text-primary", "#171717");
setVar("--text-secondary", "#6f6f6f");
setVar("--text-tertiary", "#9a9a9a");
setVar("--track-bg", "rgba(0, 0, 0, 0.06)");
setVar("--logo-surface", "#f4f4f5");
setVar("--card-gloss-start", "rgba(255, 255, 255, 0.62)");
setVar("--card-gloss-end", "rgba(255, 255, 255, 0)");
setVar("--shadow", "0 30px 80px rgba(0, 0, 0, 0.18), 0 2px 10px rgba(0, 0, 0, 0.06)");
}
}
function updateProgress(percent, text, waiting) {
var fill = document.getElementById("progressFill");
var label = document.getElementById("progressText");
var safePercent = Math.max(0, Math.min(100, Number(percent) || 0));
if (fill) {
fill.style.width = safePercent + "%";
if (waiting) {
fill.classList.add("waiting");
} else {
fill.classList.remove("waiting");
fill.style.animation = "none";
fill.offsetHeight;
fill.style.animation = "";
}
}
if (label && text) label.textContent = text;
}
function setVersion(version) {
var el = document.getElementById("versionText");
if (!el) return;
var text = String(version || "").trim();
el.textContent = text ? "v" + text.replace(/^v/i, "") : "";
}
applyTheme("cloud-dancer", "light");
</script>
</body>
</html>