290 lines
6.9 KiB
HTML
290 lines
6.9 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>萌芽SSH</title>
|
|
<meta name="description" content="柔和渐变风格的 Web SSH 连接面板,支持多窗口终端。" />
|
|
<meta name="theme-color" content="#0f172a" />
|
|
<link rel="icon" href="/favicon.ico" />
|
|
<link rel="icon" type="image/png" sizes="192x192" href="/logo192.png" />
|
|
<link rel="apple-touch-icon" sizes="192x192" href="/logo192.png" />
|
|
<style>
|
|
:root {
|
|
color-scheme: dark;
|
|
--splash-bg: radial-gradient(
|
|
circle at top,
|
|
#1f2937 0,
|
|
#020617 55%,
|
|
#000 100%
|
|
);
|
|
--splash-ink: #e2e8f0;
|
|
--splash-accent: #22c55e;
|
|
--splash-accent-soft: rgba(34, 197, 94, 0.35);
|
|
--splash-glow: rgba(56, 189, 248, 0.18);
|
|
}
|
|
|
|
body {
|
|
margin: 0;
|
|
background: #020617;
|
|
}
|
|
|
|
#splash-screen {
|
|
position: fixed;
|
|
inset: 0;
|
|
z-index: 9999;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
text-align: center;
|
|
background: var(--splash-bg);
|
|
overflow: hidden;
|
|
transition: opacity 0.45s ease, visibility 0.45s ease;
|
|
}
|
|
|
|
#splash-screen::before {
|
|
content: "";
|
|
position: absolute;
|
|
inset: -20%;
|
|
background: radial-gradient(
|
|
circle at 20% 20%,
|
|
rgba(34, 197, 94, 0.18),
|
|
transparent 55%
|
|
),
|
|
radial-gradient(
|
|
circle at 80% 10%,
|
|
rgba(56, 189, 248, 0.2),
|
|
transparent 60%
|
|
),
|
|
radial-gradient(
|
|
circle at 70% 80%,
|
|
rgba(14, 116, 144, 0.25),
|
|
transparent 65%
|
|
);
|
|
opacity: 0.9;
|
|
animation: splashPulse 6s ease-in-out infinite;
|
|
}
|
|
|
|
#splash-screen::after {
|
|
content: "";
|
|
position: absolute;
|
|
width: 70vmax;
|
|
height: 70vmax;
|
|
border-radius: 50%;
|
|
background: radial-gradient(
|
|
circle,
|
|
var(--splash-glow),
|
|
transparent 65%
|
|
);
|
|
animation: splashGlow 7.5s ease-in-out infinite;
|
|
}
|
|
|
|
.splash-content {
|
|
position: relative;
|
|
z-index: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
gap: 6px;
|
|
padding: 24px;
|
|
color: var(--splash-ink);
|
|
font-family: "Avenir Next", "PingFang SC", "Microsoft YaHei", sans-serif;
|
|
}
|
|
|
|
.splash-logo {
|
|
position: relative;
|
|
width: 220px;
|
|
height: 220px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.splash-logo img {
|
|
width: 96px;
|
|
height: 96px;
|
|
border-radius: 22px;
|
|
box-shadow: 0 16px 40px rgba(15, 23, 42, 0.45),
|
|
0 0 30px rgba(34, 197, 94, 0.25);
|
|
animation: logoFloat 3.6s ease-in-out infinite;
|
|
background: rgba(15, 23, 42, 0.4);
|
|
}
|
|
|
|
.splash-ring {
|
|
position: absolute;
|
|
border-radius: 999px;
|
|
border: 1px solid var(--splash-accent-soft);
|
|
animation: ringPulse 3.6s ease-out infinite;
|
|
opacity: 0;
|
|
}
|
|
|
|
.splash-ring.ring-1 {
|
|
width: 120px;
|
|
height: 120px;
|
|
animation-delay: 0s;
|
|
}
|
|
|
|
.splash-ring.ring-2 {
|
|
width: 170px;
|
|
height: 170px;
|
|
animation-delay: 1.2s;
|
|
}
|
|
|
|
.splash-ring.ring-3 {
|
|
width: 220px;
|
|
height: 220px;
|
|
animation-delay: 2.4s;
|
|
}
|
|
|
|
.splash-title {
|
|
font-size: 28px;
|
|
font-weight: 700;
|
|
letter-spacing: 0.12em;
|
|
}
|
|
|
|
.splash-subtitle {
|
|
font-size: 14px;
|
|
color: #86efac;
|
|
letter-spacing: 0.3em;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.splash-dots {
|
|
display: flex;
|
|
gap: 8px;
|
|
margin-top: 14px;
|
|
}
|
|
|
|
.splash-dots span {
|
|
width: 10px;
|
|
height: 10px;
|
|
border-radius: 50%;
|
|
background: var(--splash-accent);
|
|
box-shadow: 0 0 12px rgba(34, 197, 94, 0.55);
|
|
animation: dotBounce 1.1s ease-in-out infinite;
|
|
}
|
|
|
|
.splash-dots span:nth-child(2) {
|
|
animation-delay: 0.15s;
|
|
}
|
|
|
|
.splash-dots span:nth-child(3) {
|
|
animation-delay: 0.3s;
|
|
}
|
|
|
|
#splash-screen.is-hidden {
|
|
opacity: 0;
|
|
visibility: hidden;
|
|
pointer-events: none;
|
|
}
|
|
|
|
body.splash-active #app {
|
|
opacity: 0;
|
|
}
|
|
|
|
@keyframes logoFloat {
|
|
0%,
|
|
100% {
|
|
transform: translateY(0);
|
|
}
|
|
50% {
|
|
transform: translateY(-8px);
|
|
}
|
|
}
|
|
|
|
@keyframes ringPulse {
|
|
0% {
|
|
transform: scale(0.65);
|
|
opacity: 0.45;
|
|
}
|
|
70% {
|
|
opacity: 0.15;
|
|
}
|
|
100% {
|
|
transform: scale(1.15);
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
@keyframes dotBounce {
|
|
0%,
|
|
100% {
|
|
transform: scale(0.7);
|
|
opacity: 0.6;
|
|
}
|
|
50% {
|
|
transform: scale(1.1);
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
@keyframes splashPulse {
|
|
0%,
|
|
100% {
|
|
opacity: 0.75;
|
|
transform: scale(1);
|
|
}
|
|
50% {
|
|
opacity: 1;
|
|
transform: scale(1.03);
|
|
}
|
|
}
|
|
|
|
@keyframes splashGlow {
|
|
0%,
|
|
100% {
|
|
opacity: 0.4;
|
|
transform: translate(-10%, -5%) scale(0.95);
|
|
}
|
|
50% {
|
|
opacity: 0.7;
|
|
transform: translate(10%, 5%) scale(1.05);
|
|
}
|
|
}
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
#splash-screen::before,
|
|
#splash-screen::after,
|
|
.splash-logo img,
|
|
.splash-ring,
|
|
.splash-dots span {
|
|
animation: none;
|
|
}
|
|
}
|
|
</style>
|
|
</head>
|
|
<body class="splash-active">
|
|
<div id="splash-screen" aria-live="polite">
|
|
<div class="splash-content">
|
|
<div class="splash-logo">
|
|
<span class="splash-ring ring-1"></span>
|
|
<span class="splash-ring ring-2"></span>
|
|
<span class="splash-ring ring-3"></span>
|
|
<img src="/logo192.png" alt="萌芽SSH Logo" />
|
|
</div>
|
|
<div class="splash-title">萌芽SSH</div>
|
|
<div class="splash-subtitle">加载中</div>
|
|
<div class="splash-dots" aria-hidden="true">
|
|
<span></span>
|
|
<span></span>
|
|
<span></span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="app"></div>
|
|
<script>
|
|
window.__hideSplash = () => {
|
|
const splash = document.getElementById("splash-screen");
|
|
if (!splash) return;
|
|
splash.classList.add("is-hidden");
|
|
document.body.classList.remove("splash-active");
|
|
window.setTimeout(() => {
|
|
splash.remove();
|
|
}, 500);
|
|
};
|
|
</script>
|
|
<script type="module" src="/src/main.js"></script>
|
|
</body>
|
|
</html>
|