Files
2026-03-18 22:00:41 +08:00

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>