-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathupdate-screen.html
More file actions
100 lines (86 loc) · 5.32 KB
/
Copy pathupdate-screen.html
File metadata and controls
100 lines (86 loc) · 5.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;">
<title>Howl</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
background: #020617;
color: #f1f5f9;
height: 100vh;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
position: relative;
-webkit-font-smoothing: antialiased;
}
#shader-canvas { position: fixed; inset: 0; width: 100%; height: 100%; z-index: 0; }
.vignette { position: fixed; inset: 0; background: radial-gradient(ellipse 75% 65% at 50% 48%, transparent 0%, rgba(0,0,0,0.55) 100%); pointer-events: none; z-index: 1; }
.noise { position: fixed; inset: 0; opacity: 0.018; background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); pointer-events: none; z-index: 2; }
.drag-region { position: fixed; top: 0; left: 0; right: 0; height: 38px; -webkit-app-region: drag; z-index: 100; }
.container {
position: relative; z-index: 10;
display: flex; flex-direction: column; align-items: center;
padding: 48px;
opacity: 0; transform: translateY(12px);
animation: fade-in 0.6s ease 0.3s forwards;
}
@keyframes fade-in { to { opacity: 1; transform: translateY(0); } }
.logo-wrap { position: relative; width: 80px; height: 80px; margin-bottom: 26px; }
.logo-glow { position: absolute; inset: -28px; border-radius: 50%; background: radial-gradient(circle, rgba(34,211,238,0.18) 0%, transparent 65%); animation: pulse-glow 4s ease-in-out infinite; }
@keyframes pulse-glow { 0%,100% { opacity: 0.4; transform: scale(0.92); } 50% { opacity: 1; transform: scale(1.08); } }
.logo { position: relative; width: 80px; height: 80px; border-radius: 24px; background: linear-gradient(135deg, rgba(34,211,238,0.12), rgba(34,211,238,0.03)); border: 1px solid rgba(34,211,238,0.15); display: flex; align-items: center; justify-content: center; backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px); }
.logo-letter { font-size: 40px; font-weight: 800; color: #22d3ee; line-height: 1; }
.brand-name { font-size: 12px; font-weight: 500; letter-spacing: 0.3em; text-transform: uppercase; color: rgba(241,245,249,0.4); margin-bottom: 3px; }
.version { font-size: 10px; color: rgba(241,245,249,0.18); letter-spacing: 0.06em; margin-bottom: 42px; }
.spinner { width: 28px; height: 28px; border: 2.5px solid rgba(34,211,238,0.15); border-top-color: #22d3ee; border-radius: 50%; animation: spin 0.8s linear infinite; margin-bottom: 18px; }
@keyframes spin { to { transform: rotate(360deg); } }
.status-text { font-size: 12px; color: rgba(241,245,249,0.4); letter-spacing: 0.03em; }
.status-subtitle { font-size: 11px; color: rgba(241,245,249,0.25); margin-top: 6px; }
.progress-section { width: 100%; max-width: 260px; display: flex; flex-direction: column; align-items: center; gap: 14px; }
.progress-track { width: 100%; height: 3px; border-radius: 2px; background: rgba(255,255,255,0.04); overflow: hidden; }
.progress-fill { height: 100%; border-radius: 2px; background: linear-gradient(90deg, #22d3ee, #06b6d4); width: 0%; transition: width 0.3s ease; box-shadow: 0 0 8px rgba(34,211,238,0.4); }
.progress-percent { font-size: 10px; color: rgba(241,245,249,0.18); font-variant-numeric: tabular-nums; }
.state { display: none; flex-direction: column; align-items: center; }
.state.active { display: flex; }
.state-enter { animation: fade-in 0.5s ease forwards; }
.state-enter-delay-1 { opacity: 0; animation: fade-in 0.5s ease 0.1s forwards; }
.state-enter-delay-2 { opacity: 0; animation: fade-in 0.5s ease 0.2s forwards; }
</style>
</head>
<body>
<canvas id="shader-canvas"></canvas>
<div class="vignette"></div>
<div class="noise"></div>
<div class="drag-region"></div>
<div class="container">
<div class="logo-wrap">
<div class="logo-glow"></div>
<div class="logo"><img src="public/howl-logo.png" alt="Howl" width="48" height="48" style="border-radius: 8px; object-fit: contain;" /></div>
</div>
<div class="brand-name">Howl</div>
<div class="version" id="version-text">v1.0.0</div>
<div class="state active" id="state-loading">
<div class="spinner state-enter"></div>
<div class="status-text state-enter-delay-1">Loading Howl...</div>
</div>
<div class="state" id="state-downloading">
<div class="progress-section">
<div class="status-text" id="download-status">Downloading update...</div>
<div class="progress-track"><div class="progress-fill" id="progress-fill"></div></div>
<div class="progress-percent" id="progress-percent">0%</div>
</div>
</div>
<div class="state" id="state-installing">
<div class="spinner state-enter"></div>
<div class="status-text state-enter-delay-1">Installing update...</div>
</div>
</div>
<script src="./update-screen.js"></script>
</body>
</html>